diff --git a/rpmio/rpmpgp_internal.c b/rpmio/rpmpgp_internal.c index ce1d3c27d9..edf30141b9 100644 --- a/rpmio/rpmpgp_internal.c +++ b/rpmio/rpmpgp_internal.c @@ -570,7 +570,7 @@ static int pgpCurveByOid(const uint8_t *p, int l) static int isKey(pgpDigParams keyp) { - return keyp->tag == PGPTAG_PUBLIC_KEY || keyp->tag == PGPTAG_PUBLIC_SUBKEY; + return keyp->tag == PGPTAG_PUBLIC_KEY; } static int pgpPrtPubkeyParams(uint8_t pubkey_algo, @@ -889,77 +889,6 @@ static pgpDigParams pgpDigParamsNew(uint8_t tag) return digp; } -static int hashKey(DIGEST_CTX hash, const struct pgpPkt *pkt, int exptag) -{ - int rc = -1; - if (pkt->tag == exptag) { - uint8_t head[] = { - 0x99, - (pkt->blen >> 8), - (pkt->blen ), - }; - - rpmDigestUpdate(hash, head, 3); - rpmDigestUpdate(hash, pkt->body, pkt->blen); - rc = 0; - } - return rc; -} - -static int pgpVerifySelf(pgpDigParams key, pgpDigParams selfsig, - const struct pgpPkt *all, int i) -{ - int rc = -1; - DIGEST_CTX hash = NULL; - - switch (selfsig->sigtype) { - case PGPSIGTYPE_SUBKEY_BINDING: - hash = rpmDigestInit(selfsig->hash_algo, 0); - if (hash) { - rc = hashKey(hash, &all[0], PGPTAG_PUBLIC_KEY); - if (!rc) - rc = hashKey(hash, &all[i-1], PGPTAG_PUBLIC_SUBKEY); - } - break; - default: - /* ignore types we can't handle */ - rc = 0; - break; - } - - if (hash && rc == 0) - rc = pgpVerifySignature(key, selfsig, hash); - - rpmDigestFinal(hash, NULL, NULL, 0); - - return rc; -} - -static int parseSubkeySig(const struct pgpPkt *pkt, uint8_t tag, - pgpDigParams *params_p) { - pgpDigParams params = *params_p = NULL; /* assume failure */ - - if (pkt->tag != PGPTAG_SIGNATURE) - goto fail; - - params = pgpDigParamsNew(tag); - - if (pgpPrtSig(tag, pkt->body, pkt->blen, params)) - goto fail; - - if (params->sigtype != PGPSIGTYPE_SUBKEY_BINDING && - params->sigtype != PGPSIGTYPE_SUBKEY_REVOKE) - { - goto fail; - } - - *params_p = params; - return 0; -fail: - pgpDigParamsFree(params); - return -1; -} - static const size_t RPM_MAX_OPENPGP_BYTES = 65535; /* max number of bytes in a key */ int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype, @@ -968,19 +897,13 @@ int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype, const uint8_t *p = pkts; const uint8_t *pend = pkts + pktlen; pgpDigParams digp = NULL; - pgpDigParams selfsig = NULL; - int i = 0; - int alloced = 16; /* plenty for normal cases */ + struct pgpPkt _pkt, *pkt = &_pkt; int rc = -1; /* assume failure */ - int expect = 0; - int prevtag = 0; if (pktlen > RPM_MAX_OPENPGP_BYTES) return rc; /* reject absurdly large data */ - struct pgpPkt *all = xmalloc(alloced * sizeof(*all)); while (p < pend) { - struct pgpPkt *pkt = &all[i]; if (decodePkt(p, (pend - p), pkt)) break; @@ -993,48 +916,16 @@ int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype, } else if (pkt->tag == PGPTAG_PUBLIC_KEY) break; - if (expect) { - if (pkt->tag != expect) - break; - selfsig = pgpDigParamsNew(pkt->tag); - } - - if (pgpPrtPkt(pkt, selfsig ? selfsig : digp)) + if (pgpPrtPkt(pkt, digp)) break; - if (selfsig) { - /* subkeys must be followed by binding signature */ - int xx = 1; /* assume failure */ - - if (!(prevtag == PGPTAG_PUBLIC_SUBKEY && - selfsig->sigtype != PGPSIGTYPE_SUBKEY_BINDING)) - xx = pgpVerifySelf(digp, selfsig, all, i); - - selfsig = pgpDigParamsFree(selfsig); - if (xx) - break; - expect = 0; - } - - if (pkt->tag == PGPTAG_PUBLIC_SUBKEY) - expect = PGPTAG_SIGNATURE; - prevtag = pkt->tag; - - i++; p += (pkt->body - pkt->head) + pkt->blen; if (pkttype == PGPTAG_SIGNATURE) break; - - if (alloced <= i) { - alloced *= 2; - all = xrealloc(all, alloced * sizeof(*all)); - } } - rc = (digp && (p == pend) && expect == 0) ? 0 : -1; + rc = (digp && (p == pend)) ? 0 : -1; - free(all); - selfsig = pgpDigParamsFree(selfsig); if (ret && rc == 0) { *ret = digp; } else { @@ -1047,77 +938,10 @@ int pgpPrtParamsSubkeys(const uint8_t *pkts, size_t pktlen, pgpDigParams mainkey, pgpDigParams **subkeys, int *subkeysCount) { - const uint8_t *p = pkts; - const uint8_t *pend = pkts + pktlen; - pgpDigParams *digps = NULL; - int count = 0; - int alloced = 10; - struct pgpPkt pkt; - int rc, i; - - digps = xmalloc(alloced * sizeof(*digps)); - - while (p < pend) { - if (decodePkt(p, (pend - p), &pkt)) - break; - - p += (pkt.body - pkt.head) + pkt.blen; - - if (pkt.tag == PGPTAG_PUBLIC_SUBKEY) { - if (count == alloced) { - alloced <<= 1; - digps = xrealloc(digps, alloced * sizeof(*digps)); - } - - digps[count] = pgpDigParamsNew(PGPTAG_PUBLIC_SUBKEY); - /* Copy UID from main key to subkey */ - digps[count]->userid = xstrdup(mainkey->userid); - - if (getKeyID(pkt.body, pkt.blen, digps[count]->signid)) { - pgpDigParamsFree(digps[count]); - continue; - } - - if (pgpPrtKey(pkt.tag, pkt.body, pkt.blen, digps[count])) { - pgpDigParamsFree(digps[count]); - continue; - } - - pgpDigParams subkey_sig = NULL; - if (decodePkt(p, pend - p, &pkt) || - parseSubkeySig(&pkt, 0, &subkey_sig)) - { - pgpDigParamsFree(digps[count]); - break; - } - - /* Is the subkey revoked or incapable of signing? */ - int ignore = subkey_sig->sigtype != PGPSIGTYPE_SUBKEY_BINDING || - !((subkey_sig->saved & PGPDIG_SIG_HAS_KEY_FLAGS) && - (subkey_sig->key_flags & 0x02)); - if (ignore) { - pgpDigParamsFree(digps[count]); - } else { - digps[count]->key_flags = subkey_sig->key_flags; - digps[count]->saved |= PGPDIG_SIG_HAS_KEY_FLAGS; - count++; - } - p += (pkt.body - pkt.head) + pkt.blen; - pgpDigParamsFree(subkey_sig); - } - } - rc = (p == pend) ? 0 : -1; - - if (rc == 0) { - *subkeys = xrealloc(digps, count * sizeof(*digps)); - *subkeysCount = count; - } else { - for (i = 0; i < count; i++) - pgpDigParamsFree(digps[i]); - free(digps); - } - - return rc; + /* We don't support subkeys due their complexities */ + *subkeys = NULL; + *subkeysCount = 0; + return 0; } rpmRC pgpVerifySignature(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx) diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index 92d1f4337c..e594adc9a4 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -510,61 +510,35 @@ Checking package after importing key, no signature: []) AT_CLEANUP -AT_SETUP([rpmkeys --import invalid keys]) -AT_KEYWORDS([rpmkeys import]) -RPMDB_INIT - # The following certificates include subkeys with errors. In general, # all subkeys should be returned whether they are valid or not. Keys # should only be rejected when verifying a signature. This is because # a key's validity depends on the current time. Thus, the time to # check for validity is when the key is used, not when it is imported. -# The internal OpenPGP implementation checks for validity when the key -# is imported; other implementations should not do this. +AT_SETUP([rpmkeys --import invalid keys]) +AT_KEYWORDS([rpmkeys import]) +RPMDB_INIT + AT_CHECK_UNQUOTED([ runroot rpmkeys --quiet --import /data/keys/CVE-2021-3521-badbind.asc -echo exit code: $? >&2 ], -[ignore], +[0], [], -[`if test x$PGP = xinternal; -then - echo 'error: /data/keys/CVE-2021-3521-badbind.asc: key 1 import failed.' - echo exit code: 1 -else - echo exit code: 0 -fi`] -) +[]) AT_CHECK_UNQUOTED([ runroot rpmkeys --quiet --import /data/keys/CVE-2021-3521-nosubsig.asc -echo exit code: $? >&2 ], -[ignore], +[0], [], -[`if test x$PGP = xinternal; -then - echo 'error: /data/keys/CVE-2021-3521-nosubsig.asc: key 1 import failed.' - echo exit code: 1 -else - echo exit code: 0 -fi`] -) +[]) AT_CHECK_UNQUOTED([ runroot rpmkeys --quiet --import /data/keys/CVE-2021-3521-nosubsig-last.asc -echo exit code: $? >&2 ], -[ignore], +[0], [], -[`if test x$PGP = xinternal; -then - echo 'error: /data/keys/CVE-2021-3521-nosubsig-last.asc: key 1 import failed.' - echo exit code: 1 -else - echo exit code: 0 -fi`] -) +[]) AT_CLEANUP # ----------------------------------------- @@ -627,20 +601,16 @@ gpg(a72b7d4f62837bea) = 4:a72b7d4f62837bea-62553e62 []) AT_CLEANUP -# The internal OpenPGP parser rejects the key. The Sequoia parser -# just ignores the invalid components and imports the rest. This test -# checks the behavior of the internal parser. +# The key has invalid components but those should be just ignored. AT_SETUP([rpmkeys type confusion]) -AT_SKIP_IF([test x$PGP != xinternal]) AT_CHECK([ RPMDB_INIT runroot rpmkeys --import /data/keys/type-confusion.asc ], -[1], +[0], [], -[error: /data/keys/type-confusion.asc: key 1 import failed.] -) +[]) AT_CLEANUP # ------------------------------