From 3cad28715bcdcf1bc92171bc560cb24ea87d9d74 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Wed, 13 Jul 2011 16:05:34 +0300 Subject: [PATCH] Fix crash on PGP packets/armors with more than one key (RhBug:667582) - While OpenPGP permits arbitrary number of keys per packet/armor, we can't handle more than one, error out early. The poor user wont get much of a clue as to what went wrong, but thats still better than crashing and burning. - Return NULL from pgpPrtPubkeyParams() on errors and pass it onwards from pgpPrtKey() which propagates it up to callers. Besides the crash, this also fixes the error path from pgpNewPublicKey() failures. --- rpmio/rpmpgp.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c index 8b7442d..ebd126c 100644 --- a/rpmio/rpmpgp.c +++ b/rpmio/rpmpgp.c @@ -834,6 +834,10 @@ static const uint8_t * pgpPrtPubkeyParams(uint8_t pubkey_algo, { size_t i; + /* XXX we can't handle more than one key in a packet, error out */ + if (_dig && _dig->keydata) + return NULL; + for (i = 0; p < &h[hlen]; i++, p += pgpMpiLen(p)) { char * mpi; if (pubkey_algo == PGPPUBKEYALGO_RSA) { @@ -842,7 +846,7 @@ static const uint8_t * pgpPrtPubkeyParams(uint8_t pubkey_algo, if (_dig->keydata == NULL) { _dig->keydata = pgpNewPublicKey(rsaKey); if (_dig->keydata == NULL) - break; /* error abort? */ + return NULL; } switch (i) { case 0: /* n */ @@ -862,7 +866,7 @@ static const uint8_t * pgpPrtPubkeyParams(uint8_t pubkey_algo, if (_dig->keydata == NULL) { _dig->keydata = pgpNewPublicKey(dsaKey); if (_dig->keydata == NULL) - break; /* error abort? */ + return NULL; } switch (i) { case 0: /* p */ @@ -1002,7 +1006,7 @@ static int pgpPrtKey(pgpTag tag, const uint8_t *h, size_t hlen, p = ((uint8_t *)v) + sizeof(*v); p = pgpPrtPubkeyParams(v->pubkey_algo, p, h, hlen, _dig); - rc = 0; + rc = (p == NULL); } break; case 4: { pgpPktKeyV4 v = (pgpPktKeyV4)h; @@ -1023,7 +1027,7 @@ static int pgpPrtKey(pgpTag tag, const uint8_t *h, size_t hlen, p = pgpPrtPubkeyParams(v->pubkey_algo, p, h, hlen, _dig); if (!(tag == PGPTAG_PUBLIC_KEY || tag == PGPTAG_PUBLIC_SUBKEY)) p = pgpPrtSeckeyParams(v->pubkey_algo, p, h, hlen); - rc = 0; + rc = (p == NULL); } break; default: rc = 1; -- 2.7.4