Skip to content

Commit

Permalink
Ignore subkeys that cannot be used for signing
Browse files Browse the repository at this point in the history
This ensures that a signature is only accepted if the subkey that made
it is actually allowed to sign.  Test 265 verifies that RPM ignores
subkeys that cannot sign.

A subkey is considered to be capable of signing if, and only if, its
subkey binding signature has a hashed key flags subpacket that contains
the flag 0x02.  RFC4880 requires that the subkey binding signature be
v4, which this requirement enforces implicitly.  RFC4880 also requires
that primary key binding signatures be present and checked.  This is not
yet implemented, but may be implemented later.

Fixes #1911.
  • Loading branch information
DemiMarie authored and pmatilai committed Mar 31, 2022
1 parent 598a771 commit a9cca03
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
48 changes: 47 additions & 1 deletion rpmio/rpmpgp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,31 @@ static int pgpVerifySelf(pgpDigParams key, pgpDigParams selfsig,
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,
Expand Down Expand Up @@ -1238,7 +1263,28 @@ int pgpPrtParamsSubkeys(const uint8_t *pkts, size_t pktlen,
pgpDigParamsFree(digps[count]);
continue;
}
count++;

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;
Expand Down
2 changes: 0 additions & 2 deletions tests/rpmsigdig.at
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,6 @@ UNW2iqnN3BA7guhOv6OMiROF1+I7Q5nWT63mQC7IgQ==
gpg(rpm.org RSA testkey <[email protected]>) = 4:4344591e1964c5fc-58e63918
gpg(1964c5fc) = 4:4344591e1964c5fc-58e63918
gpg(4344591e1964c5fc) = 4:4344591e1964c5fc-58e63918
gpg(f00650f8) = 4:185e6146f00650f8-58e63918
gpg(185e6146f00650f8) = 4:185e6146f00650f8-58e63918
],
[])
AT_CLEANUP
Expand Down

0 comments on commit a9cca03

Please sign in to comment.