Skip to content

Commit

Permalink
Add rpmGetSubkeys() and pgpPrtParamsSubkeys() for getting gpg subkeys.
Browse files Browse the repository at this point in the history
pgpPrtParamSubkeys() parses gpg packets to get gpg subkeys parameters.
rpmGetSubkeys() uses pgpPrtParamSubkeys() and it creates rpmPubkey
objects that can be insterted into rpm keyring.
  • Loading branch information
Lubos Kardos committed Jul 23, 2015
1 parent e31016d commit 355c9b0
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 2 deletions.
32 changes: 32 additions & 0 deletions rpmio/rpmkeyring.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,38 @@ rpmPubkey rpmPubkeyNew(const uint8_t *pkt, size_t pktlen)
return key;
}

rpmPubkey *rpmGetSubkeys(rpmPubkey mainkey, int *count)
{
rpmPubkey *subkeys = NULL;
pgpDigParams *pgpsubkeys = NULL;
int pgpsubkeysCount = 0;
int i;

if (!pgpPrtParamsSubkeys(mainkey->pkt, mainkey->pktlen, mainkey->pgpkey,
&pgpsubkeys, &pgpsubkeysCount)) {


subkeys = xmalloc(pgpsubkeysCount * sizeof(*subkeys));

for (i = 0; i < pgpsubkeysCount; i++) {
rpmPubkey subkey = xcalloc(1, sizeof(*subkey));
subkeys[i] = subkey;

/* Packets with all subkeys already stored in main key */
subkey->pkt = NULL;
subkey->pktlen = 0;

subkey->pgpkey = pgpsubkeys[i];
memcpy(subkey->keyid, pgpsubkeys[i]->signid, sizeof(subkey->keyid));
subkey->nrefs = 1;
pthread_rwlock_init(&subkey->lock, NULL);
}
}
*count = pgpsubkeysCount;

return subkeys;
}

rpmPubkey rpmPubkeyFree(rpmPubkey key)
{
if (key == NULL)
Expand Down
8 changes: 8 additions & 0 deletions rpmio/rpmkeyring.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ rpmKeyring rpmKeyringLink(rpmKeyring keyring);
*/
rpmPubkey rpmPubkeyNew(const uint8_t *pkt, size_t pktlen);

/** \ingroupt rpmkeyring
* Return array of subkeys belonging to maikey
* param mainkey main rpmPubkey
* param count count of returned subkeys
* @return an array of subkey's handles
*/
rpmPubkey *rpmGetSubkeys(rpmPubkey mainkey, int *count);

/** \ingroup rpmkeyring
* Create a new rpmPubkey from ASCII-armored pubkey file
* @param filename Path to pubkey file
Expand Down
62 changes: 60 additions & 2 deletions rpmio/rpmpgp.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,9 @@ static int pgpPrtPubkeyParams(uint8_t pubkey_algo,
rc = 0;

/* We can't handle more than one key at a time */
if (rc == 0 && keyp->alg == NULL && keyp->tag == PGPTAG_PUBLIC_KEY)
if (rc == 0 && keyp->alg == NULL && (keyp->tag == PGPTAG_PUBLIC_KEY ||
keyp->tag == PGPTAG_PUBLIC_SUBKEY))

keyp->alg = keyalg;
else
pgpDigAlgFree(keyalg);
Expand Down Expand Up @@ -697,7 +699,8 @@ static int pgpPrtKey(pgpTag tag, const uint8_t *h, size_t hlen,
fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
pgpPrtNL();

if (_digp->tag == tag) {
/* If _digp->hash is not NULL then signature is already loaded */
if (_digp->hash == NULL) {
_digp->version = v->version;
memcpy(_digp->time, v->time, sizeof(_digp->time));
_digp->pubkey_algo = v->pubkey_algo;
Expand Down Expand Up @@ -983,6 +986,61 @@ int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype,
return rc;
}

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] = xcalloc(1, sizeof(**digps));
digps[count]->tag = PGPTAG_PUBLIC_SUBKEY;
/* Copy UID from main key to subkey */
digps[count]->userid = xstrdup(mainkey->userid);

if(getFingerprint(pkt.body, pkt.blen, digps[count]->signid))
continue;

if(pgpPrtKey(pkt.tag, pkt.body, pkt.blen, digps[count])) {
pgpDigParamsFree(digps[count]);
continue;
}
count++;
}
}
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;
}

int pgpPrtPkts(const uint8_t * pkts, size_t pktlen, pgpDig dig, int printing)
{
int rc;
Expand Down
12 changes: 12 additions & 0 deletions rpmio/rpmpgp.h
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,18 @@ int pgpExtractPubkeyFingerprint(const char * b64pkt, pgpKeyID_t keyid);
int pgpPrtParams(const uint8_t *pkts, size_t pktlen, unsigned int pkttype,
pgpDigParams * ret);

/** \ingroup rpmpgp
* Parse subkey parameters from OpenPGP packet(s).
* @param pkts OpenPGP packet(s)
* @param pktlen OpenPGP packet(s) length (no. of bytes)
* @param mainkey parameters of main key
* @param subkeys array of subkey parameters (alloced)
* @param subkeysCount count of subkeys
* @return -1 on error, 0 on success
*/
int pgpPrtParamsSubkeys(const uint8_t *pkts, size_t pktlen,
pgpDigParams mainkey, pgpDigParams **subkeys,
int *subkeysCount);
/** \ingroup rpmpgp
* Print/parse a OpenPGP packet(s).
* @param pkts OpenPGP packet(s)
Expand Down

0 comments on commit 355c9b0

Please sign in to comment.