Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Please login to access the resource
SUSE:SLE-15-SP4:Update
rpm
verifybindingsig.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File verifybindingsig.diff of Package rpm
--- rpmio/digest.h.orig 2024-04-29 09:11:59.251170068 +0000 +++ rpmio/digest.h 2024-04-29 10:54:13.168416920 +0000 @@ -33,12 +33,13 @@ struct pgpDigParams_s { uint8_t hash_algo; uint8_t sigtype; - uint8_t hashlen; + uint32_t hashlen; uint8_t signhash16[2]; pgpKeyID_t signid; uint8_t saved; #define PGPDIG_SAVED_TIME (1 << 0) #define PGPDIG_SAVED_ID (1 << 1) + uint8_t key_flags; pgpDigAlg alg; }; --- rpmio/rpmpgp.c.orig 2024-04-29 09:11:10.259240666 +0000 +++ rpmio/rpmpgp.c 2024-04-29 09:36:15.612510965 +0000 @@ -16,6 +16,8 @@ #include "debug.h" +static rpmRC pgpVerifySignatureRaw(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx); + static int _print = 0; /** \ingroup rpmio @@ -412,7 +414,7 @@ static int pgpVersion(const uint8_t *h, } static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype, - pgpDigParams _digp) + pgpDigParams _digp, int hashed) { const uint8_t *p = h; size_t plen = 0, i; @@ -449,6 +451,8 @@ static int pgpPrtSubType(const uint8_t * pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]); break; case PGPSUBTYPE_SIG_CREATE_TIME: + if (!hashed) + break; impl = *p; if (!(_digp->saved & PGPDIG_SAVED_TIME) && (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE)) @@ -478,8 +482,15 @@ static int pgpPrtSubType(const uint8_t * pgpPrtHex("", p+1, plen-1); break; - case PGPSUBTYPE_PRIMARY_USERID: case PGPSUBTYPE_KEY_FLAGS: + if (!hashed) + break; + impl = *p; /* accept critical packet */ + _digp->key_flags = plen >= 2 ? p[1] : 0; + pgpPrtHex("", p+1, plen-1); + break; + + case PGPSUBTYPE_PRIMARY_USERID: case PGPSUBTYPE_EMBEDDED_SIG: impl = *p; /* accept critical packet */ pgpPrtHex("", p+1, plen-1); @@ -550,7 +561,7 @@ static int pgpPrtSigParams(pgpTag tag, u int mpil = pgpMpiLen(p); if (pend - p < mpil) break; - if (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT) { + if (sigp->tag == PGPTAG_SIGNATURE) { if (sigalg->setmpi(sigalg, i, p)) break; } @@ -657,7 +668,7 @@ static int pgpPrtSig(pgpTag tag, const u _digp->hashlen = sizeof(*v) + plen; _digp->hash = memcpy(xmalloc(_digp->hashlen), v, _digp->hashlen); } - if (pgpPrtSubType(p, plen, v->sigtype, _digp)) + if (pgpPrtSubType(p, plen, v->sigtype, _digp, 1)) return 1; p += plen; @@ -668,7 +679,7 @@ static int pgpPrtSig(pgpTag tag, const u if ((p + plen) > hend) return 1; - if (pgpPrtSubType(p, plen, v->sigtype, _digp)) + if (pgpPrtSubType(p, plen, v->sigtype, _digp, 0)) return 1; p += plen; @@ -1068,13 +1079,52 @@ unsigned int pgpDigParamsAlgo(pgpDigPara return algo; } +static void hashKey(DIGEST_CTX hash, const struct pgpPkt *pkt) +{ + uint8_t head[] = { + 0x99, + (pkt->blen >> 8), + (pkt->blen ) + }; + rpmDigestUpdate(hash, head, 3); + rpmDigestUpdate(hash, pkt->body, pkt->blen); +} + +static int verifySubkeyBindingSignature(pgpDigParams digp, struct pgpPkt *mainpkt, struct pgpPkt *subkeypkt, struct pgpPkt *sigpkt) +{ + int rc = -1; /* assume failure */ + pgpDigParams sigdigp = NULL; + DIGEST_CTX hash = NULL; + + if (mainpkt->tag != PGPTAG_PUBLIC_KEY || subkeypkt->tag != PGPTAG_PUBLIC_SUBKEY || sigpkt->tag != PGPTAG_SIGNATURE) + goto exit; + sigdigp = xcalloc(1, sizeof(*sigdigp)); + sigdigp->tag = PGPTAG_SIGNATURE; + if (pgpPrtPkt(sigpkt, sigdigp)) + goto exit; + if (sigdigp->sigtype != PGPSIGTYPE_SUBKEY_BINDING) + goto exit; + hash = rpmDigestInit(sigdigp->hash_algo, 0); + if (!hash) + goto exit; + hashKey(hash, mainpkt); + hashKey(hash, subkeypkt); + if (pgpVerifySignatureRaw(digp, sigdigp, hash) == RPMRC_OK) + rc = 0; +exit: + if (hash) + rpmDigestFinal(hash, NULL, NULL, 0); + pgpDigParamsFree(sigdigp); + return rc; +} + int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype, pgpDigParams * ret) { const uint8_t *p = pkts; const uint8_t *pend = pkts + pktlen; pgpDigParams digp = NULL; - struct pgpPkt pkt; + struct pgpPkt mainpkt, pkt; int rc = -1; /* assume failure */ while (p < pend) { @@ -1087,6 +1137,7 @@ int pgpPrtParams(const uint8_t * pkts, s } else { digp = xcalloc(1, sizeof(*digp)); digp->tag = pkt.tag; + mainpkt = pkt; } } @@ -1096,6 +1147,17 @@ int pgpPrtParams(const uint8_t * pkts, s p += (pkt.body - pkt.head) + pkt.blen; if (pkttype == PGPTAG_SIGNATURE) break; + if (pkt.tag == PGPTAG_PUBLIC_SUBKEY) { + /* make sure that a binding signature follows and verify it */ + struct pgpPkt sigpkt; + if (p == pend || decodePkt(p, (pend - p), &sigpkt)) { + digp = pgpDigParamsFree(digp); + break; + } + if (verifySubkeyBindingSignature(digp, &mainpkt, &pkt, &sigpkt)) + break; + p += (sigpkt.body - sigpkt.head) + sigpkt.blen; + } } rc = (digp && (p == pend)) ? 0 : -1; @@ -1137,7 +1199,7 @@ int pgpPrtParamsSubkeys(const uint8_t *p digps[count] = xcalloc(1, sizeof(**digps)); digps[count]->tag = PGPTAG_PUBLIC_SUBKEY; /* Copy UID from main key to subkey */ - digps[count]->userid = xstrdup(mainkey->userid); + digps[count]->userid = mainkey->userid ? xstrdup(mainkey->userid) : NULL; if (getKeyID(pkt.body, pkt.blen, digps[count]->signid)) { pgpDigParamsFree(digps[count]); @@ -1148,6 +1210,17 @@ int pgpPrtParamsSubkeys(const uint8_t *p pgpDigParamsFree(digps[count]); continue; } + /* check key flags from following binding signature */ + if (p == pend || decodePkt(p, (pend - p), &pkt) || pkt.tag != PGPTAG_SIGNATURE || pgpPrtPkt(&pkt, digps[count])) { + pgpDigParamsFree(digps[count]); + continue; + } + if (!(digps[count]->key_flags & 0x02)) { + /* not a signing subkey */ + pgpDigParamsFree(digps[count]); + continue; + } + count++; } } @@ -1208,7 +1281,7 @@ char *pgpIdentItem(pgpDigParams digp) return id; } -rpmRC pgpVerifySignature(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx) +static rpmRC pgpVerifySignatureRaw(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx) { DIGEST_CTX ctx = rpmDigestDup(hashctx); uint8_t *hash = NULL; @@ -1260,6 +1333,13 @@ exit: } +rpmRC pgpVerifySignature(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx) +{ + if (!sig || sig->tag != PGPTAG_SIGNATURE || (sig->sigtype != PGPSIGTYPE_BINARY && sig->sigtype != PGPSIGTYPE_TEXT && sig->sigtype != PGPSIGTYPE_STANDALONE)) + return RPMRC_FAIL; + return pgpVerifySignatureRaw(key, sig, hashctx); +} + rpmRC pgpVerifySig(pgpDig dig, DIGEST_CTX hashctx) { if (dig == NULL || hashctx == NULL)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor