Skip to content

Commit

Permalink
Before importing an OpenPGP certificate, lint it
Browse files Browse the repository at this point in the history
When importing an OpenPGP certificate, lint the certificate to show
the user possible issues.  Fail if the certificate is completely
unusable.  Using the Sequoia backend, this yields, for instance:

  $ ./rpmkeys --import tests/data/keys/alice-revoked-subkey.asc
  Certificate B3A771BFEB04E625:
    Subkey 1F71177215217EE0 was revoked: Key material has been compromised, it was the maid
    Certificate does not have any usable signing keys

Fixes #1974.
  • Loading branch information
nwalfield committed May 4, 2022
1 parent 610209e commit 7cd6e6a
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
26 changes: 26 additions & 0 deletions include/rpm/rpmpgp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,32 @@ pgpArmor pgpParsePkts(const char *armor, uint8_t ** pkt, size_t * pktlen);
*/
int pgpPubKeyCertLen(const uint8_t *pkts, size_t pktslen, size_t *certlen);

/** \ingroup rpmpgp
* Lints the certificate.
*
* There are four cases:
*
* The packets do not describe a certificate: returns an error and
* sets *explanation to NULL.
*
* The packets describe a certificate and the certificate is
* completely unusable: returns an error and sets *explanation to a
* human readable explanation.
*
* The packets describe a certificate and some components are not
* usable: returns success, and sets *explanation to a human readable
* explanation.
*
* The packets describe a certificate and there are no lints: returns
* success, and sets *explanation to NULL.
*
* @param pkts OpenPGP pointer to a buffer with certificates
* @param pktslen length of the buffer with certificates
* @param[out] explanation An optional lint to display to the user.
* @return RPMRC_OK on success
*/
rpmRC pgpPubKeyLint(const uint8_t *pkts, size_t pktslen, char **explanation);

/** \ingroup rpmpgp
* Wrap a OpenPGP packets in ascii armor for transport.
* @param atype type of armor
Expand Down
10 changes: 10 additions & 0 deletions lib/rpmts.c
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,7 @@ rpmRC rpmtsImportPubkey(const rpmts ts, const unsigned char * pkt, size_t pktlen
{
Header h = NULL;
rpmRC rc = RPMRC_FAIL; /* assume failure */
char *lints = NULL;
rpmPubkey pubkey = NULL;
rpmPubkey *subkeys = NULL;
int subkeysCount = 0;
Expand All @@ -615,6 +616,15 @@ rpmRC rpmtsImportPubkey(const rpmts ts, const unsigned char * pkt, size_t pktlen
if (txn == NULL)
return rc;

rc = pgpPubKeyLint(pkt, pktlen, &lints);
if (lints) {
fprintf(stderr, "%s\n", lints);
free(lints);
}
if (rc) {
goto exit;
}

/* XXX keyring wont load if sigcheck disabled, force it temporarily */
rpmtsSetVSFlags(ts, (oflags & ~RPMVSF_MASK_NOSIGNATURES));
keyring = rpmtsGetKeyring(ts, 1);
Expand Down
6 changes: 6 additions & 0 deletions rpmio/rpmpgp_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1345,3 +1345,9 @@ char * pgpArmorWrap(int atype, const unsigned char * s, size_t ns)
free(buf);
return val;
}

rpmRC pgpPubKeyLint(const uint8_t *pkts, size_t pktslen, char **explanation)
{
*explanation = NULL;
return RPMRC_OK;
}

0 comments on commit 7cd6e6a

Please sign in to comment.