summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubos Kardos <lkardos@redhat.com>2015-07-21 16:01:46 +0200
committerLubos Kardos <lkardos@redhat.com>2015-07-23 10:55:03 +0200
commit355c9b069f25d3a9c3dc224fb39a90522c04ca28 (patch)
treeabe99c9606e93d8b795754370c10858c62d87fc5
parente31016d3c65e4b3c8ad0ffdb31e259f0ad7f8802 (diff)
downloadrpm-355c9b069f25d3a9c3dc224fb39a90522c04ca28.tar.gz
Add rpmGetSubkeys() and pgpPrtParamsSubkeys() for getting gpg subkeys.
pgpPrtParamSubkeys() parses gpg packets to get gpg subkeys parameters. rpmGetSubkeys() uses pgpPrtParamSubkeys() and it creates rpmPubkey objects that can be insterted into rpm keyring.
-rw-r--r--rpmio/rpmkeyring.c32
-rw-r--r--rpmio/rpmkeyring.h8
-rw-r--r--rpmio/rpmpgp.c62
-rw-r--r--rpmio/rpmpgp.h12
4 files changed, 112 insertions, 2 deletions
diff --git a/rpmio/rpmkeyring.c b/rpmio/rpmkeyring.c
index 368a1ec13..0333ea95a 100644
--- a/rpmio/rpmkeyring.c
+++ b/rpmio/rpmkeyring.c
@@ -152,6 +152,38 @@ exit:
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)
diff --git a/rpmio/rpmkeyring.h b/rpmio/rpmkeyring.h
index 9fcab5feb..e8767de03 100644
--- a/rpmio/rpmkeyring.h
+++ b/rpmio/rpmkeyring.h
@@ -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
diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
index cf97773cd..f02065003 100644
--- a/rpmio/rpmpgp.c
+++ b/rpmio/rpmpgp.c
@@ -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);
@@ -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;
@@ -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;
diff --git a/rpmio/rpmpgp.h b/rpmio/rpmpgp.h
index e4966ed4c..718fb5bee 100644
--- a/rpmio/rpmpgp.h
+++ b/rpmio/rpmpgp.h
@@ -1000,6 +1000,18 @@ 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)
* @param pktlen OpenPGP packet(s) length (no. of bytes)