From ce8a3c9ba12d84f4538d5d55717d2967b69c02c9 Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Tue, 16 Mar 2021 22:12:05 -0400 Subject: [PATCH 2/2] Header signatures alone are not sufficient MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes how RPM handles packages that contain a header signature, but neither header+payload signature nor payload digests. Such packages are obviously not properly signed, but RPM previously accepted them. This could be used to confuse both ‘rpmkeys -K’ and DNF. Both would report that the package has been properly signed even when it has not. The included regression tests demonstrates the change in behavior. --- lib/rpmvs.c | 14 ++++-- .../RPMS/hello-2.0-1.x86_64-corrupted.rpm | Bin 0 -> 3216 bytes tests/rpmsigdig.at | 40 ++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 tests/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm diff --git a/lib/rpmvs.c b/lib/rpmvs.c index 7255069fc..d2f4f3170 100644 --- a/lib/rpmvs.c +++ b/lib/rpmvs.c @@ -451,7 +451,7 @@ int rpmvsVerify(struct rpmvs_s *sis, int type, { int failed = 0; int cont = 1; - int range = 0; + int range = 0, vfylevel = sis->vfylevel; int verified[3] = { 0, 0, 0 }; /* sort for consistency and rough "better comes first" semantics*/ @@ -478,6 +478,14 @@ int rpmvsVerify(struct rpmvs_s *sis, int type, } } + /* Unconditionally reject partially signed packages */ + if (verified[RPMSIG_SIGNATURE_TYPE]) + vfylevel |= RPMSIG_SIGNATURE_TYPE; + + /* Cannot verify payload if RPMVSF_NEEDPAYLOAD is set */ + if (sis->vsflags & RPMVSF_NEEDPAYLOAD) + range &= ~RPMSIG_PAYLOAD; + for (int i = 0; i < sis->nsigs && cont; i++) { struct rpmsinfo_s *sinfo = &sis->sigs[i]; int strength = (sinfo->type | sinfo->strength); @@ -490,11 +498,11 @@ int rpmvsVerify(struct rpmvs_s *sis, int type, sinfo->rc = RPMRC_NOTFOUND; } - if (sis->vfylevel & strength & RPMSIG_DIGEST_TYPE) { + if (vfylevel & strength & RPMSIG_DIGEST_TYPE) { int missing = (range & ~verified[RPMSIG_DIGEST_TYPE]); required |= (missing & sinfo->range); } - if (sis->vfylevel & strength & RPMSIG_SIGNATURE_TYPE) { + if (vfylevel & strength & RPMSIG_SIGNATURE_TYPE) { int missing = (range & ~verified[RPMSIG_SIGNATURE_TYPE]); required |= (missing & sinfo->range); } diff --git a/tests/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm b/tests/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm new file mode 100644 index 0000000000000000000000000000000000000000..2a6173ba04c2cfafb66a724fa3c021748189d8ca GIT binary patch literal 3216 zcmbVOeUKDK74N&-TL>Y66s8bEbObH#%AMVvkDU*=!#nQ#IN-QD2$u+#neLvuA+tN{ z%q)lLM!$N4oc(NJVANlg}msUUbgWASV&z*hZn^O-T zTuh#EY7LMxIzn-t>~JPSD5G7l;+)nq3DLiG`rxrreQFfe6eA9 ziZsk8>E_05e{A!~f?F1Mb&r2|8T;wA`!39@?aH0<4z(Se**|a1Pp)dy^z3VwZ~xq- zGmm_>_U2b^du8Q2{eQiqIJaWzjn5w#IrYYOCx`9ltM|P1&}semdmdeT_adXQ^Tm6A z*!SA8tz_S0YsQ17y^m}?e}G*rJlOWkmh&A4FTYEUvZc#+*e5m&u1p=1tiG3jv*x$2 zt7|X5I{c>#>rbaLJJ0Ws(=YJv-TLESJ@@T>3r{~YmQH``)Pg17_}W*WeD*K*AK6!_ zeSG2c_Px75^YrxdzwR>+d&;t6-<5MGUzG-rf8u1C1De-~D;+E;qMzh0l9lX}flH?Bqi$_IwcR zUiVk6R-1$N;_LirgPXALlTg7w>F)r7KM8|6A1W5`U(kTLixZ2(d)E1-}f4`uhcc7ZBxRg8vN=<=X`RJ0R-+l;HmWL^M7O%_~1V>%SpA>unAdY`Q@LK`#tY{yckLLv5a9r@)0AYN?Nx>Hh z`RjtCO>sQh4d;IV5cbe0?3ua~ILvQEU!i;{AdGL!0K%9Q_M^N55ay+p0iqo3f&4>) zpA)<#!6Yky+yV~sn_x~|ANU>TH{rfe|7yX}-pKm^aeNsN_tP)@TJ1N_K{=_e_8ks|fjLg>!BQtx2TDIp{ zro&wYGPP~kkfaTl+nT1ks={nd^-R+%n@SLp4{mbX(<= zQN>`60)GRBr#QN%QqGxHFsP$5Th%S4V7jVf8>$Qc09-R&&CL_Tv|P*Ns$x32Qts*vLHCG3=D8(gq0a z!0}7GB(;@`3F(M9n{p~y8Wz`*LGF3dU^rEZLm0Bt-Fbslma1juR5+8Sc@)DXA+kgx z4n25V@J{~MivEN9jCT|B0+d`ej_M7(zhr*$*1F-vg}Ul~N4(BI_%0(|n}){+HujO; z&dp?`r?Y!QPhDfq^-H;=6;C-4&#{pH2Y){*azx&wO7f&6m;ExA}tFlzV0 z2+SkLoK_>hG7J6XjNCoZyJ=)>pm%&?bkmlRuAX+7?(rGQ%a|}?AaTW^56I;xtZ-Th zBN>uOSb`PgvJ*MQ_BbxfZq@TRNc`QrU5Di(PQ!@Fla$KwF26#jI4FwCoW|{Fr5wag z4#Fgtcu9Z^$78(2nM|o7$wdP+6)V*eZ=ZzT$ftys{g6!V_RGW;2}({h$n~TpPnIxS zCpNA(Zu;C{|DK^<$sY;QNs0%RN4R!zuL`MkqiZfO*k6d$_T_aR00*_cz(6w$riD6$b*`tTBhqMwy6}T4#_sJ>Y7)e p%++<1a~HOUX;#IQXEDgyd53${fuv6BOW-}IzaMM0Yh`FJ{ui)exQ_q; literal 0 HcmV?d00001 diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index 35013d77e..340885758 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -404,11 +404,51 @@ runroot rpmkeys -Kv /tmp/${pkg} Payload SHA256 digest: BAD (Expected 84a7338287bf19715c4eed0243f5cdb447eeb0ade37b2af718d4060aefca2f7c != bea903609dceac36e1f26a983c493c98064d320fdfeb423034ed63d649b2c8dc) Payload SHA256 ALT digest: NOTFOUND V4 RSA/SHA256 Signature, key ID 1964c5fc: BAD + DSA signature: NOTFOUND MD5 digest: BAD (Expected 137ca1d8b35cca02a1854ba301c5432e != d662cd0d81601a7107312684ad1ddf38) ], []) AT_CLEANUP +# ------------------------------ +# Test pre-built corrupted package verification (corrupted payload) +AT_SETUP([rpmkeys -Kv 4]) +AT_KEYWORDS([rpmkeys digest signature]) +AT_CHECK([ +RPMDB_INIT[( + +dorpm () { + runroot rpmkeys --define '_pkgverify_level digest' \ + --define '_pkgverify_flags 0x10000' "$1" \ + /data/RPMS/hello-2.0-1.x86_64-corrupted.rpm + [ "$?" -eq 1 ] || exit 1 +} + +dorpm -K +dorpm -Kv +runroot rpmkeys --import /data/keys/rpm.org-rsa-2048-test.pub +dorpm -K +dorpm -Kv +)]], +[0], +[[/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm: digests SIGNATURES NOT OK +/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm: + Header V4 RSA/SHA256 Signature, key ID 1964c5fc: NOKEY + Header SHA256 digest: OK + MD5 digest: OK +/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm: DIGESTS SIGNATURES NOT OK +/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm: + Header V4 RSA/SHA256 Signature, key ID 1964c5fc: OK + Header SHA256 digest: OK + Payload SHA256 digest: NOTFOUND + Payload SHA256 ALT digest: NOTFOUND + RSA signature: NOTFOUND + DSA signature: NOTFOUND + MD5 digest: OK +]], +[]) +AT_CLEANUP + # ------------------------------ # Test --addsign AT_SETUP([rpmsign --addsign]) -- 2.30.2