- *pktlp = bp - buf;
- return buf;
-}
-
-static void
-parsekeydata(Solvable *s, Repodata *data, unsigned char *p, int pl)
-{
- int x, tag, l;
- unsigned char keyid[8];
- unsigned int kcr = 0, maxex = 0;
- unsigned char *pubkey = 0;
- unsigned char *userid = 0;
-#if 0
- int pubkeyl = 0;
- int useridl = 0;
-#endif
-
- for (; pl; p += l, pl -= l)
- {
- x = *p++;
- pl--;
- if (!(x & 128) || pl <= 0)
- return;
- if ((x & 64) == 0)
- {
- /* old format */
- tag = (x & 0x3c) >> 2;
- x &= 3;
- if (x == 3)
- return;
- l = 1 << x;
- if (pl < l)
- return;
- x = 0;
- while (l--)
- {
- x = x << 8 | *p++;
- pl--;
- }
- l = x;
- }
- else
- {
- tag = (x & 0x3f);
- x = *p++;
- pl--;
- if (x < 192)
- l = x;
- else if (x >= 192 && x < 224)
- {
- if (pl <= 0)
- return;
- l = ((x - 192) << 8) + *p++ + 192;
- pl--;
- }
- else if (x == 255)
- {
- if (pl <= 4)
- return;
- l = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
- p += 4;
- pl -= 4;
- }
- else
- return;
- }
- if (pl < l)
- return;
- if (tag == 6)
- {
- pubkey = solv_realloc(pubkey, l);
- if (l)
- memcpy(pubkey, p, l);
-#if 0
- pubkeyl = l;
-#endif
- kcr = 0;
- if (p[0] == 3)
- {
- unsigned int ex;
- void *h;
- kcr = p[1] << 24 | p[2] << 16 | p[3] << 8 | p[4];
- ex = 0;
- if (p[5] || p[6])
- {
- ex = kcr + 24*3600 * (p[5] << 8 | p[6]);
- if (ex > maxex)
- maxex = ex;
- }
- memset(keyid, 0, 8);
- if (p[7] == 1) /* RSA */
- {
- int i, ql;
- unsigned char fp[16];
- char fpx[32 + 1];
- unsigned char *q;
-
- ql = ((p[8] << 8 | p[9]) + 7) / 8;
- memcpy(keyid, p + 10 + ql - 8, 8);
- h = solv_chksum_create(REPOKEY_TYPE_MD5);
- solv_chksum_add(h, p + 10, ql);
- q = p + 10 + ql;
- ql = ((q[0] << 8 | q[1]) + 7) / 8;
- solv_chksum_add(h, q + 2, ql);
- solv_chksum_free(h, fp);
- for (i = 0; i < 16; i++)
- sprintf(fpx + i * 2, "%02x", fp[i]);
- setutf8string(data, s - s->repo->pool->solvables, PUBKEY_FINGERPRINT, fpx);
- }
- }
- else if (p[0] == 4)
- {
- int i;
- void *h;
- unsigned char hdr[3];
- unsigned char fp[20];
- char fpx[40 + 1];
-
- kcr = p[1] << 24 | p[2] << 16 | p[3] << 8 | p[4];
- hdr[0] = 0x99;
- hdr[1] = l >> 8;
- hdr[2] = l;
- h = solv_chksum_create(REPOKEY_TYPE_SHA1);
- solv_chksum_add(h, hdr, 3);
- solv_chksum_add(h, p, l);
- solv_chksum_free(h, fp);
- for (i = 0; i < 20; i++)
- sprintf(fpx + i * 2, "%02x", fp[i]);
- setutf8string(data, s - s->repo->pool->solvables, PUBKEY_FINGERPRINT, fpx);
- memcpy(keyid, fp + 12, 8);
- }
- }
- if (tag == 2)
- {
- if (p[0] == 3 && p[1] == 5)
- {
-#if 0
- Id htype = 0;
-#endif
- /* printf("V3 signature packet\n"); */
- if (l < 17)
- continue;
- if (p[2] != 0x10 && p[2] != 0x11 && p[2] != 0x12 && p[2] != 0x13 && p[2] != 0x1f)
- continue;
- if (!memcmp(keyid, p + 6, 8))
- {
- /* printf("SELF SIG\n"); */
- }
- else
- {
- /* printf("OTHER SIG\n"); */
- }
-#if 0
- if (p[16] == 1)
- htype = REPOKEY_TYPE_MD5;
- else if (p[16] == 2)
- htype = REPOKEY_TYPE_SHA1;
- else if (p[16] == 8)
- htype = REPOKEY_TYPE_SHA256;
- if (htype)
- {
- void *h = solv_chksum_create(htype);
- unsigned char b[3], *cs;
-
- b[0] = 0x99;
- b[1] = pubkeyl >> 8;
- b[2] = pubkeyl;
- solv_chksum_add(h, b, 3);
- solv_chksum_add(h, pubkey, pubkeyl);
- if (p[2] >= 0x10 && p[2] <= 0x13)
- solv_chksum_add(h, userid, useridl);
- solv_chksum_add(h, p + 2, 5);
- cs = solv_chksum_get(h, 0);
- solv_chksum_free(h, 0);
- }
-#endif
- }
- if (p[0] == 4)
- {
- int j, ql, haveissuer;
- unsigned char *q;
- unsigned int ex = 0;
-#if 0
- unsigned int scr = 0;
-#endif
- unsigned char issuer[8];
-
- /* printf("V4 signature packet\n"); */
- if (l < 6)
- continue;
- if (p[1] != 0x10 && p[1] != 0x11 && p[1] != 0x12 && p[1] != 0x13 && p[1] != 0x1f)
- continue;
- haveissuer = 0;
- ex = 0;
- q = p + 4;
- for (j = 0; q && j < 2; j++)
- {
- if (q + 2 > p + l)
- {
- q = 0;
- break;
- }
- ql = q[0] << 8 | q[1];
- q += 2;
- if (q + ql > p + l)
- {
- q = 0;
- break;
- }
- while (ql)
- {
- int sl;
- x = *q++;
- ql--;
- if (x < 192)
- sl = x;
- else if (x == 255)
- {
- if (ql < 4)
- {
- q = 0;
- break;
- }
- sl = q[0] << 24 | q[1] << 16 | q[2] << 8 | q[3];
- q += 4;
- ql -= 4;
- }
- else
- {
- if (ql < 1)
- {
- q = 0;
- break;
- }
- sl = ((x - 192) << 8) + *q++ + 192;
- ql--;
- }
- if (ql < sl)
- {
- q = 0;
- break;
- }
- x = q[0] & 127;
- /* printf("%d SIGSUB %d %d\n", j, x, sl); */
- if (x == 16 && sl == 9 && !haveissuer)
- {
- memcpy(issuer, q + 1, 8);
- haveissuer = 1;
- }
-#if 0
- if (x == 2 && j == 0)
- scr = q[1] << 24 | q[2] << 16 | q[3] << 8 | q[4];
-#endif
- if (x == 9 && j == 0)
- ex = q[1] << 24 | q[2] << 16 | q[3] << 8 | q[4];
- q += sl;
- ql -= sl;
- }
- }
- if (ex)
- ex += kcr;
- if (haveissuer)
- {
-#if 0
- Id htype = 0;
- if (p[3] == 1)
- htype = REPOKEY_TYPE_MD5;
- else if (p[3] == 2)
- htype = REPOKEY_TYPE_SHA1;
- else if (p[3] == 8)
- htype = REPOKEY_TYPE_SHA256;
- if (htype && pubkeyl)
- {
- void *h = solv_chksum_create(htype);
- unsigned char b[6], *cs;
- unsigned int hl;
-
- b[0] = 0x99;
- b[1] = pubkeyl >> 8;
- b[2] = pubkeyl;
- solv_chksum_add(h, b, 3);
- solv_chksum_add(h, pubkey, pubkeyl);
- if (p[1] >= 0x10 && p[1] <= 0x13)
- {
- b[0] = 0xb4;
- b[1] = useridl >> 24;
- b[2] = useridl >> 16;
- b[3] = useridl >> 8;
- b[4] = useridl;
- solv_chksum_add(h, b, 5);
- solv_chksum_add(h, userid, useridl);
- }
- hl = 6 + (p[4] << 8 | p[5]);
- solv_chksum_add(h, p, hl);
- b[0] = 4;
- b[1] = 0xff;
- b[2] = hl >> 24;
- b[3] = hl >> 16;
- b[4] = hl >> 8;
- b[5] = hl;
- solv_chksum_add(h, b, 6);
- cs = solv_chksum_get(h, 0);
- solv_chksum_free(h, 0);
- }
-#endif
- if (!memcmp(keyid, issuer, 8))
- {
- /* printf("SELF SIG cr %d ex %d\n", cr, ex); */
- if (ex > maxex)
- maxex = ex;
- }
- else
- {
- /* printf("OTHER SIG cr %d ex %d\n", cr, ex); */
- }
- }
- }
- }
- if (tag == 13)
- {
- userid = solv_realloc(userid, l);
- if (l)
- memcpy(userid, p, l);
-#if 0
- useridl = l;
-#endif
- }
- }
- if (maxex)
- repodata_set_num(data, s - s->repo->pool->solvables, PUBKEY_EXPIRES, maxex);
- solv_free(pubkey);
- solv_free(userid);
-}
-
-/* this is private to rpm, but rpm lacks an interface to retrieve
- * the values. Sigh. */
-struct pgpDigParams_s {
- const char * userid;
- const unsigned char * hash;
- const char * params[4];
- unsigned char tag;
- unsigned char version; /*!< version number. */
- unsigned char time[4]; /*!< time that the key was created. */
- unsigned char pubkey_algo; /*!< public key algorithm. */
- unsigned char hash_algo;
- unsigned char sigtype;
- unsigned char hashlen;
- unsigned char signhash16[2];
- unsigned char signid[8];
- unsigned char saved;
-};
-
-struct pgpDig_s {
- struct pgpDigParams_s signature;
- struct pgpDigParams_s pubkey;
-};
-
-static int
-pubkey2solvable(Solvable *s, Repodata *data, char *pubkey)
-{
- Pool *pool = s->repo->pool;
- unsigned char *pkts;
- unsigned int btime;
- int pktsl, i;
- pgpDig dig = 0;
- char keyid[16 + 1];
- char evrbuf[8 + 1 + 8 + 1];
-
- pkts = unarmor(pubkey, &pktsl);
- if (!pkts)
- return 0;
- setutf8string(data, s - s->repo->pool->solvables, SOLVABLE_DESCRIPTION, pubkey);
- parsekeydata(s, data, pkts, pktsl);
- /* only rpm knows how to do the release calculation, we don't dare
- * to recreate all the bugs */
-#ifndef RPM5
- dig = pgpNewDig();
-#else
- dig = pgpDigNew(RPMVSF_DEFAULT, 0);
-#endif
- (void) pgpPrtPkts(pkts, pktsl, dig, 0);
- btime = dig->pubkey.time[0] << 24 | dig->pubkey.time[1] << 16 | dig->pubkey.time[2] << 8 | dig->pubkey.signid[3];
- sprintf(evrbuf, "%02x%02x%02x%02x-%02x%02x%02x%02x", dig->pubkey.signid[4], dig->pubkey.signid[5], dig->pubkey.signid[6], dig->pubkey.signid[7], dig->pubkey.time[0], dig->pubkey.time[1], dig->pubkey.time[2], dig->pubkey.time[3]);
- repodata_set_num(data, s - s->repo->pool->solvables, SOLVABLE_BUILDTIME, btime);
-
- s->name = pool_str2id(pool, "gpg-pubkey", 1);
- s->evr = pool_str2id(pool, evrbuf, 1);
- s->arch = 1;
- for (i = 0; i < 8; i++)
- sprintf(keyid + 2 * i, "%02x", dig->pubkey.signid[i]);
- repodata_set_str(data, s - s->repo->pool->solvables, PUBKEY_KEYID, keyid);
- if (dig->pubkey.userid)
- setutf8string(data, s - s->repo->pool->solvables, SOLVABLE_SUMMARY, dig->pubkey.userid);
-#ifndef RPM5
- (void)pgpFreeDig(dig);