rpm  5.4.15
rpmhkp.c
Go to the documentation of this file.
1 #include "system.h"
2 
3 #define _RPMHKP_INTERNAL
4 #include <rpmhkp.h>
5 
6 #define _RPMPGP_INTERNAL
7 #include <rpmpgp.h>
8 
9 #include <rpmlog.h>
10 #include <rpmmacro.h>
11 
12 #include "debug.h"
13 
14 #ifdef __cplusplus
15 GENfree(rpmuint8_t **)
16 #endif /* __cplusplus */
17 
18 /*@unchecked@*/
20 
21 /*@unchecked@*/ /*@relnull@*/
23 
24 struct _filter_s _rpmhkp_awol = {};
25 struct _filter_s _rpmhkp_crl = {};
26 
27 typedef struct _Astats_s {
28  size_t good;
29  size_t bad;
30 } _Astats;
31 
32 typedef struct _BAstats_s {
39  size_t lookups;
40  size_t certs;
41  size_t sigs;
42  size_t expired;
43  size_t pubbound;
44  size_t subbound;
45  size_t pubrevoked;
46  size_t subrevoked;
47  size_t filtered;
48  size_t keyexpired;
49 } _BAstats;
50 
52 
53 /* XXX renaming work-in-progress */
54 #define SUM _rpmhkp_stats
55 
57 #define SPEW(_list) if (_rpmhkp_spew) fprintf _list
58 #if 0
59 #define DESPEW(_list) fprintf _list
60 #else
61 #define DESPEW(_list) SPEW(_list)
62 #endif
63 #define HKPDEBUG(_list) if (_rpmhkp_debug) fprintf _list
64 
66 
67 /*==============================================================*/
68 
69 static rpmhkp rpmhkpI(void)
70  /*@globals _rpmhkpI @*/
71  /*@modifies _rpmhkpI @*/
72 {
73  if (_rpmhkpI == NULL)
74  _rpmhkpI = rpmhkpNew(NULL, 0);
75  return _rpmhkpI;
76 }
77 
78 static void rpmhkpFini(void * _hkp)
79  /*@globals fileSystem @*/
80  /*@modifies *_hkp, fileSystem @*/
81 {
82  rpmhkp hkp = (rpmhkp) _hkp;
83 
84 assert(hkp);
85  hkp->pkt = _free(hkp->pkt);
86  hkp->pktlen = 0;
87  hkp->pkts = _free(hkp->pkts);
88  hkp->npkts = 0;
89  hkp->awol = rpmbfFree(hkp->awol);
90  hkp->crl = rpmbfFree(hkp->crl);
91 }
92 
93 /*@unchecked@*/ /*@only@*/ /*@null@*/
95 
96 static rpmhkp rpmhkpGetPool(/*@null@*/ rpmioPool pool)
97  /*@globals _rpmhkpPool, fileSystem @*/
98  /*@modifies pool, _rpmhkpPool, fileSystem @*/
99 {
100  rpmhkp hkp;
101 
102  if (_rpmhkpPool == NULL) {
103  _rpmhkpPool = rpmioNewPool("hkp", sizeof(*hkp), -1, _rpmhkp_debug,
104  NULL, NULL, rpmhkpFini);
105  pool = _rpmhkpPool;
106  }
107  hkp = (rpmhkp) rpmioGetPool(pool, sizeof(*hkp));
108  memset(((char *)hkp)+sizeof(hkp->_item), 0, sizeof(*hkp)-sizeof(hkp->_item));
109  return hkp;
110 }
111 
112 rpmhkp rpmhkpNew(const rpmuint8_t * keyid, uint32_t flags)
113 {
114  static int oneshot;
115  rpmhkp hkp;
116 
117  if (!oneshot) {
118  _rpmhkp_awol.n = 100000;
119  _rpmhkp_awol.e = 1.0e-4;
120  rpmbfParams(_rpmhkp_awol.n, _rpmhkp_awol.e,
121  &_rpmhkp_awol.m, &_rpmhkp_awol.k);
122  _rpmhkp_awol.bf = rpmbfNew(_rpmhkp_awol.m, _rpmhkp_awol.k, 0);
123  _rpmhkp_crl.n = 100000;
124  _rpmhkp_crl.e = 1.0e-4;
125  rpmbfParams(_rpmhkp_crl.n, _rpmhkp_crl.e,
126  &_rpmhkp_crl.m, &_rpmhkp_crl.k);
127  _rpmhkp_crl.bf = rpmbfNew(_rpmhkp_crl.m, _rpmhkp_crl.k, 0);
128  oneshot++;
129  }
130 
131  /* XXX watchout for recursive call. */
132  hkp = (flags & 0x80000000) ? rpmhkpI() : rpmhkpGetPool(_rpmhkpPool);
133 
134 hkp->pkt = NULL;
135 hkp->pktlen = 0;
136 hkp->pkts = NULL;
137 hkp->npkts = 0;
138 
139 hkp->pubx = -1;
140 hkp->uidx = -1;
141 hkp->subx = -1;
142 hkp->sigx = -1;
143 
144  if (keyid)
145  memcpy(hkp->keyid, keyid, sizeof(hkp->keyid));
146  else
147  memset(hkp->keyid, 0, sizeof(hkp->keyid));
148  memset(hkp->subid, 0, sizeof(hkp->subid));
149  memset(hkp->signid, 0, sizeof(hkp->signid));
150 
151 hkp->tvalid = 0;
152 hkp->uvalidx = -1;
153 
154  /* XXX watchout for recursive call. */
155  if (_rpmhkp_awol.bf && hkp->awol == NULL)
156  hkp->awol = rpmbfLink(_rpmhkp_awol.bf);
157  if (_rpmhkp_crl.bf && hkp->crl == NULL)
158  hkp->crl = rpmbfLink(_rpmhkp_crl.bf);
159 
160  return rpmhkpLink(hkp);
161 }
162 
163 /*==============================================================*/
164 
165 #ifdef DYING
166 struct pgpPkt_s {
167  pgpTag tag;
168  unsigned int pktlen;
169  union {
170  const rpmuint8_t * h;
171  const pgpPktKeyV3 j;
172  const pgpPktKeyV4 k;
173  const pgpPktSigV3 r;
174  const pgpPktSigV4 s;
175  const pgpPktUid * u;
176  } u;
177  unsigned int hlen;
178 };
179 #endif
180 
181 static const rpmuint8_t * pgpGrabSubTagVal(const rpmuint8_t * h, size_t hlen,
182  rpmuint8_t subtag, /*@null@*/ size_t * tlenp)
183 {
184  const rpmuint8_t * p = h;
185  const rpmuint8_t * pend = h + hlen;
186  unsigned plen = 0;
187  unsigned len;
188  rpmuint8_t stag;
189 
190  if (tlenp)
191  *tlenp = 0;
192 
193  while (p < pend) {
194  len = pgpLen(p, &plen);
195  p += len;
196 
197  stag = (*p & ~PGPSUBTYPE_CRITICAL);
198 
199  if (stag == subtag) {
200 SPEW((stderr, "\tSUBTAG %02X %p[%2u]\t%s\n", stag, p+1, plen-1, pgpHexStr(p+1, plen-1)));
201  if (tlenp)
202  *tlenp = plen-1;
203  return p+1;
204  }
205  p += plen;
206  }
207  return NULL;
208 }
209 
210 static const rpmuint8_t * ppSigHash(pgpPkt pp, size_t * plen)
211 {
212  const rpmuint8_t * p = NULL;
213 
214 assert(pp->tag == PGPTAG_SIGNATURE);
215  switch (pp->u.h[0]) {
216  case 4:
217  *plen = pgpGrab(pp->u.s->hashlen, sizeof(pp->u.s->hashlen));
218  p = pp->u.h + sizeof(*pp->u.s);
219  break;
220  }
221  return p;
222 }
223 
224 static const rpmuint8_t * ppSigUnhash(pgpPkt pp, size_t * plen)
225 {
226  const rpmuint8_t * p = NULL;
227 
228 assert(pp->tag == PGPTAG_SIGNATURE);
229  switch (pp->u.h[0]) {
230  case 4:
231  p = pp->u.h + sizeof(*pp->u.s);
232  p += pgpGrab(pp->u.s->hashlen, sizeof(pp->u.s->hashlen));
233  *plen = pgpGrab(p, 2);
234  p += 2;
235  break;
236  }
237  return p;
238 }
239 
240 static const rpmuint8_t * ppSignid(pgpPkt pp)
241 {
242  const rpmuint8_t * p = NULL;
243  size_t nunhash = 0;
244  const rpmuint8_t * punhash;
245  size_t tlen = 0;
246 
247 assert(pp->tag == PGPTAG_SIGNATURE);
248  switch (pp->u.h[0]) {
249  case 3: p = pp->u.r->signid; break;
250  case 4:
251  punhash = ppSigUnhash(pp, &nunhash);
252  p = pgpGrabSubTagVal(punhash, nunhash, PGPSUBTYPE_ISSUER_KEYID, &tlen);
253 assert(p == NULL || tlen == 8);
254  break;
255  }
256  return p;
257 }
258 
260 {
261  const rpmuint8_t * p = NULL;
262  size_t nhash = 0;
263  const rpmuint8_t * phash;
264  size_t tlen = 0;
265  rpmuint32_t sigtime = 0;
266 
267 assert(pp->tag == PGPTAG_SIGNATURE);
268  switch (pp->u.h[0]) {
269  case 3: sigtime = pgpGrab(pp->u.r->time, sizeof(pp->u.r->time)); break;
270  case 4:
271  phash = ppSigHash(pp, &nhash);
272  p = pgpGrabSubTagVal(phash, nhash, PGPSUBTYPE_SIG_CREATE_TIME, &tlen);
273  if (p) sigtime = pgpGrab(p, 4);
274  break;
275  }
276  return sigtime;
277 }
278 
280 {
281  rpmuint8_t sigtype = 0;
282 assert(pp->tag == PGPTAG_SIGNATURE);
283  switch (pp->u.h[0]) {
284  case 3: sigtype = pp->u.r->sigtype; break;
285  case 4: sigtype = pp->u.s->sigtype; break;
286  }
287  return sigtype;
288 }
289 
290 /*==============================================================*/
291 static const char * rpmhkpEscape(const char * keyname)
292 {
293  /* essentially curl_escape() */
294  /* XXX doubles as hex encode string */
295  static char ok[] =
296  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
297  const char * s;
298  char * t, *te;
299  size_t nb = 0;
300 
301  for (s = keyname; *s; s++)
302  nb += (strchr(ok, *s) == NULL ? 4 : 1);
303 
304  te = t = (char *) xmalloc(nb + 1);
305  for (s = keyname; *s; s++) {
306  if (strchr(ok, *s) == NULL) {
307  *te++ = '%'; /* XXX extra '%' macro expansion escaping. */
308  *te++ = '%';
309  *te++ = ok[(*s >> 4) & 0x0f];
310  *te++ = ok[(*s ) & 0x0f];
311  } else
312  *te++ = *s;
313  }
314  *te = '\0';
315  return t;
316 }
317 
318 rpmhkp rpmhkpLookup(const char * keyname)
319 {
320  const char * kn = rpmhkpEscape(keyname);
321  /* XXX the "0x" is sometimes in macro and sometimes in keyname. */
322  const char * fn = rpmExpand("%{_hkp_keyserver_query}", kn, NULL);
323  rpmhkp hkp = NULL;
324  pgpArmor pa;
325  int rc = 1; /* assume failure */
326 
327 HKPDEBUG((stderr, "--> %s(%s)\n", __FUNCTION__, keyname));
328 
329  /* Are hkp:// lookups disabled? */
330  if (fn && *fn && *fn == '%')
331  goto exit;
332 
333  SUM.lookups++;
334 
335  hkp = rpmhkpNew(NULL, 0);
336 
337  /* Strip off the base64 and verify the crc32. */
338  pa = pgpReadPkts(fn, &hkp->pkt, &hkp->pktlen);
339  if (pa == PGPARMOR_ERROR || pa == PGPARMOR_NONE
340  || hkp->pkt == NULL || hkp->pktlen == 0)
341  goto exit;
342 
343  /* Split the result into packet array. */
344  rc = pgpGrabPkts(hkp->pkt, hkp->pktlen, &hkp->pkts, &hkp->npkts);
345 
346  /* XXX make sure this works with lazy web-of-trust loading. */
347  /* XXX make sure 1st entry is a PUB. */
348  /* XXX sloppy queries have multiple PUB's */
349  if (!rc)
350  (void) pgpPubkeyFingerprint(hkp->pkt, hkp->pktlen, hkp->keyid);
351 
352 exit:
353  if (rc && hkp)
354  hkp = rpmhkpFree(hkp);
355  fn = _free(fn);
356  kn = _free(kn);
357 
358 HKPDEBUG((stderr, "<-- %s(%s) hkp %p\n", __FUNCTION__, keyname, hkp));
359 
360  return hkp;
361 }
362 
364  int keyx, rpmuint8_t pubkey_algo)
365 {
366  pgpDigParams pubp = pgpGetPubkey(dig);
367  pgpPkt pp = (pgpPkt) alloca(sizeof(*pp));
368  /* XXX "best effort" use primary pubkey if keyx is bogus */
369  int ix = (keyx >= 0 && keyx < hkp->npkts) ? keyx : 0;
370  size_t pleft = hkp->pktlen - (hkp->pkts[ix] - hkp->pkt);
371  int len = pgpPktLen(hkp->pkts[ix], pleft, pp);
372  const rpmuint8_t * p;
373  int rc = 0; /* assume success */
374 len = len;
375 
376 HKPDEBUG((stderr, "--> %s(%p,%p,%d,%u) ix %d V%u\n", __FUNCTION__, hkp, dig, keyx, pubkey_algo, ix, pp->u.h[0]));
377 
378  pubp->tag = pp->tag;
379  if (pp->u.h[0] == 3
380  && (pubkey_algo == 0 || pubkey_algo == pp->u.j->pubkey_algo))
381  {
382  pubp->version = pp->u.j->version;
383  memcpy(pubp->time, pp->u.j->time, sizeof(pubp->time));
384  pubp->pubkey_algo = pp->u.j->pubkey_algo;
385  p = ((rpmuint8_t *)pp->u.j) + sizeof(*pp->u.j);
386  p = pgpPrtPubkeyParams(dig, pp, (pgpPubkeyAlgo)pp->u.j->pubkey_algo, p);
387  } else
388  if (pp->u.h[0] == 4
389  && (pubkey_algo == 0 || pubkey_algo == pp->u.k->pubkey_algo))
390  {
391  pubp->version = pp->u.k->version;
392  memcpy(pubp->time, pp->u.k->time, sizeof(pubp->time));
393  pubp->pubkey_algo = pp->u.k->pubkey_algo;
394  p = ((rpmuint8_t *)pp->u.k) + sizeof(*pp->u.k);
395  p = pgpPrtPubkeyParams(dig, pp, (pgpPubkeyAlgo)pp->u.k->pubkey_algo, p);
396  } else
397  rc = -1;
398 
399 HKPDEBUG((stderr, "<-- %s(%p,%p,%d,%u) rc %d\n", __FUNCTION__, hkp, dig, keyx, pubkey_algo, rc));
400 
401  return rc;
402 }
403 
405  const rpmuint8_t * signid, rpmuint8_t pubkey_algo)
406 {
407  pgpDigParams sigp = pgpGetSignature(dig);
408  int keyx = -1; /* assume notfound (in this cert) */
409 int xx;
410 
411 HKPDEBUG((stderr, "--> %s(%p,%p,%p,%u)\n", __FUNCTION__, hkp, dig, signid, pubkey_algo));
412 
413  /* Try to load matching pubkey. */
414  if (hkp->pubx >= 0 && hkp->pubx < hkp->npkts
415  && !memcmp(hkp->keyid, signid, sizeof(hkp->keyid))) {
416  if (!rpmhkpLoadKey(hkp, dig, hkp->pubx, sigp->pubkey_algo))
417  keyx = hkp->pubx;
418  goto exit;
419  }
420 
421  /* Try to load matching subkey. */
422  if (hkp->subx >= 0 && hkp->subx < hkp->npkts
423  && !memcmp(hkp->subid, signid, sizeof(hkp->subid))) {
424  if (!rpmhkpLoadKey(hkp, dig, hkp->subx, sigp->pubkey_algo))
425  keyx = hkp->subx;
426  goto exit;
427  }
428 
429  /* Avoid repeating known signid lookup failures in awol list. */
430  if (hkp->awol && rpmbfChk(hkp->awol, signid, 8)) {
431  keyx = -2;
432  SUM.AWOL.good++;
433  goto exit;
434  }
435 
436  /* Try to retrieve the pubkey. */
437  { char * keyname = rpmExpand("0x", pgpHexStr(signid, 8), NULL);
438  rpmhkp ohkp = rpmhkpLookup(keyname);
439 
440  keyname = _free(keyname); /* XXX coverity #1035902 */
441  /* Add failed lookups to awol list. */
442  if (ohkp == NULL) {
443  xx = rpmbfAdd(hkp->awol, signid, 8);
444 DESPEW((stderr, "\tAWOL\n"));
445  SUM.AWOL.bad++;
446  keyx = -2;
447  goto exit;
448  }
449  if (rpmhkpLoadKey(ohkp, dig, 0, sigp->pubkey_algo))
450  keyx = -2; /* XXX skip V2 certs */
451  ohkp = rpmhkpFree(ohkp);
452  }
453 
454 exit:
455 
456 HKPDEBUG((stderr, "<-- %s(%p,%p,%p,%u) keyx %d\n", __FUNCTION__, hkp, dig, signid, pubkey_algo, keyx));
457 
458  return keyx;
459 }
460 
462 {
463  pgpDigParams sigp = pgpGetSignature(dig);
464  const rpmuint8_t * p = NULL;
465 int rc;
466 
467  sigp->version = pp->u.h[0];
468 
469  if (pp->u.h[0] == 3) {
470  sigp->version = pp->u.r->version;
471  sigp->pubkey_algo = pp->u.r->pubkey_algo;
472  sigp->hash_algo = pp->u.r->hash_algo;
473  sigp->sigtype = pp->u.r->sigtype;
474  memcpy(sigp->time, pp->u.r->time, sizeof(sigp->time));
475  memset(sigp->expire, 0, sizeof(sigp->expire));
476  sigp->hashlen = (size_t)pp->u.r->hashlen;
477 assert(sigp->hashlen == 5);
478  sigp->hash = ((const rpmuint8_t *)&pp->u.r->hashlen) + 1;
479  memcpy(sigp->signid, pp->u.r->signid, sizeof(sigp->signid));
480  memcpy(sigp->signhash16, pp->u.r->signhash16, sizeof(sigp->signhash16));
481 
482 /* XXX set pointer to signature parameters. */
483 p = ((rpmuint8_t *)pp->u.r) + sizeof(*pp->u.r);
484 
485  }
486 
487  if (pp->u.h[0] == 4) {
488  const rpmuint8_t * phash;
489  size_t nhash;
490  const rpmuint8_t * punhash;
491  size_t nunhash;
492  size_t tlen;
493 
494  sigp->pubkey_algo = pp->u.s->pubkey_algo;
495  sigp->hash_algo = pp->u.s->hash_algo;
496  sigp->sigtype = pp->u.s->sigtype;
497 
498  phash = ((const rpmuint8_t *)pp->u.s) + sizeof(*pp->u.s);
499  nhash = pgpGrab(pp->u.s->hashlen, sizeof(pp->u.s->hashlen));
500  sigp->hash = (const rpmuint8_t *)pp->u.s;
501  sigp->hashlen = sizeof(*pp->u.s) + nhash;
502 
503  nunhash = pgpGrab(phash+nhash, 2);
504  punhash = phash + nhash + 2;
505  memcpy(sigp->signhash16, punhash+nunhash, sizeof(sigp->signhash16));
506 
507 #ifdef DYING
508 tlen = 0;
509 p = pgpGrabSubTagVal(phash, nhash, PGPSUBTYPE_SIG_TARGET, &tlen);
510 if (p) fprintf(stderr, "*** SIG_TARGET %s\n", pgpHexStr(p, tlen));
511 tlen = 0;
512 p = pgpGrabSubTagVal(phash, nhash, PGPSUBTYPE_EMBEDDED_SIG, &tlen);
513 if (p) fprintf(stderr, "*** EMBEDDED_SIG %s\n", pgpHexStr(p, tlen));
514 tlen = 0;
515 p = pgpGrabSubTagVal(phash, nhash, PGPSUBTYPE_REVOKE_KEY, &tlen);
516 if (p) fprintf(stderr, "*** REVOKE_KEY %02X %02X %s\n", p[0], p[1], pgpHexStr(p+2, tlen-2));
517 tlen = 0;
518 p = pgpGrabSubTagVal(phash, nhash, PGPSUBTYPE_REVOKE_REASON, &tlen);
519 if (p) fprintf(stderr, "*** REVOKE_REASON %02X %s\n", *p, p+1);
520 #endif
521 
522  tlen = 0;
523  p = pgpGrabSubTagVal(phash, nhash, PGPSUBTYPE_SIG_CREATE_TIME, &tlen);
524  if (p) memcpy(sigp->time, p, sizeof(sigp->time));
525  else memset(sigp->time, 0, sizeof(sigp->time));
526 
527  tlen = 0;
528  p = pgpGrabSubTagVal(phash, nhash, PGPSUBTYPE_SIG_EXPIRE_TIME, &tlen);
529  if (p) memcpy(sigp->expire, p, sizeof(sigp->expire));
530  else memset(sigp->expire, 0, sizeof(sigp->expire));
531 
532  /* XXX only on self-signature. */
533  tlen = 0;
534  p = pgpGrabSubTagVal(phash, nhash, PGPSUBTYPE_KEY_EXPIRE_TIME, &tlen);
535  if (p) memcpy(sigp->keyexpire, p, sizeof(sigp->keyexpire));
536  else memset(sigp->keyexpire, 0, sizeof(sigp->keyexpire));
537 
538  tlen = 0;
539  p = pgpGrabSubTagVal(punhash, nunhash, PGPSUBTYPE_ISSUER_KEYID, &tlen);
540 
541 /* Certain (some @pgp.com) signatures are missing signature keyid packet. */
542 if (hkp && (p == NULL || tlen != 8)) p = hkp->keyid;
543 
544  if (p) memcpy(sigp->signid, p, sizeof(sigp->signid));
545  else memset(sigp->signid, 0, sizeof(sigp->signid));
546 
547 /* XXX set pointer to signature parameters. */
548 p = punhash + nunhash + 2;
549 
550  }
551 
552  /* XXX Load signature paramaters. */
553  pgpPrtSigParams(dig, pp,
554  (pgpPubkeyAlgo)sigp->pubkey_algo, (pgpSigType)sigp->sigtype, p);
555 
556 rc = 0;
557 HKPDEBUG((stderr, "<-- %s(%p,%p,%p) rc %d V%u\n", __FUNCTION__, hkp, dig, pp, rc, sigp->version));
558 
559  return rc;
560 }
561 
562 int rpmhkpUpdate(DIGEST_CTX ctx, const void * data, size_t len)
563 {
564  int rc = rpmDigestUpdate(ctx, data, len);
565 SPEW((stderr, "*** Update(%5u): %s\n", (unsigned)len, pgpHexStr((const rpmuint8_t *)data, len)));
566  return rc;
567 }
568 
569 static DIGEST_CTX rpmhkpHashKey(rpmhkp hkp, int ix, pgpHashAlgo dalgo)
570 {
572  pgpPkt pp = (pgpPkt) alloca(sizeof(*pp));
573 
574 assert(ix >= 0 && ix < hkp->npkts);
575 switch (*hkp->pkts[ix]) {
576 default: fprintf(stderr, "*** %s: %02X\n", __FUNCTION__, *hkp->pkts[ix]);
577 case 0x99: case 0x98: case 0xb9: case 0xb8: break;
578 }
579  (void) pgpPktLen(hkp->pkts[ix], hkp->pktlen, pp);
580 
581  hkp->goop[0] = 0x99; /* XXX correct for revocation? */
582  hkp->goop[1] = (pp->hlen >> 8) & 0xff;
583  hkp->goop[2] = (pp->hlen ) & 0xff;
584  rpmhkpUpdate(ctx, hkp->goop, 3);
585  rpmhkpUpdate(ctx, pp->u.h, pp->hlen);
586 
587 HKPDEBUG((stderr, "<-- %s(%p,%d,%u) ctx %p\n", __FUNCTION__, hkp, ix, dalgo, ctx));
588 
589  return ctx;
590 }
591 
592 static DIGEST_CTX rpmhkpHashUid(rpmhkp hkp, int ix, pgpHashAlgo dalgo)
593 {
594  DIGEST_CTX ctx = rpmhkpHashKey(hkp, hkp->pubx, dalgo);
595  pgpPkt pp = (pgpPkt) alloca(sizeof(*pp));
596 
597 assert(ix > 0 && ix < hkp->npkts);
598 switch (*hkp->pkts[ix]) {
599 default: fprintf(stderr, "*** %s: %02X\n", __FUNCTION__, *hkp->pkts[ix]);
600 case 0xb4: break;
601 }
602  (void) pgpPktLen(hkp->pkts[ix], hkp->pktlen, pp);
603 
604  hkp->goop[0] = *hkp->pkts[ix];
605  hkp->goop[1] = (pp->hlen >> 24) & 0xff;
606  hkp->goop[2] = (pp->hlen >> 16) & 0xff;
607  hkp->goop[3] = (pp->hlen >> 8) & 0xff;
608  hkp->goop[4] = (pp->hlen ) & 0xff;
609  rpmhkpUpdate(ctx, hkp->goop, 5);
610  rpmhkpUpdate(ctx, pp->u.h, pp->hlen);
611 
612 HKPDEBUG((stderr, "<-- %s(%p,%d,%u) ctx %p\n", __FUNCTION__, hkp, ix, dalgo, ctx));
613 
614  return ctx;
615 }
616 
617 static DIGEST_CTX rpmhkpHashSubkey(rpmhkp hkp, int ix, pgpHashAlgo dalgo)
618 {
619  DIGEST_CTX ctx = rpmhkpHashKey(hkp, hkp->pubx, dalgo);
620  pgpPkt pp = (pgpPkt) alloca(sizeof(*pp));
621 
622 assert(ix > 0 && ix < hkp->npkts);
623 switch (*hkp->pkts[ix]) {
624 default: fprintf(stderr, "*** %s: %02X\n", __FUNCTION__, *hkp->pkts[ix]);
625 case 0xb9: case 0xb8: break;
626 }
627  (void) pgpPktLen(hkp->pkts[ix], hkp->pktlen, pp);
628 
629  hkp->goop[0] = 0x99;
630  hkp->goop[1] = (pp->hlen >> 8) & 0xff;
631  hkp->goop[2] = (pp->hlen ) & 0xff;
632  rpmhkpUpdate(ctx, hkp->goop, 3);
633  rpmhkpUpdate(ctx, pp->u.h, pp->hlen);
634 
635 HKPDEBUG((stderr, "<-- %s(%p,%d,%u) ctx %p\n", __FUNCTION__, hkp, ix, dalgo, ctx));
636 
637  return ctx;
638 }
639 
640 static DIGEST_CTX rpmhkpHash(rpmhkp hkp, int keyx,
641  pgpSigType sigtype, pgpHashAlgo dalgo)
642 {
643  DIGEST_CTX ctx = NULL;
644 
645 HKPDEBUG((stderr, "--> %s(%p,%d,%u,%u)\n", __FUNCTION__, hkp, keyx, sigtype, dalgo));
646 
647  switch (sigtype) {
648  case PGPSIGTYPE_BINARY:
649  case PGPSIGTYPE_TEXT:
651  default:
652  break;
657  if (hkp->pubx >= 0 && hkp->uidx >= 0)
658  ctx = rpmhkpHashUid(hkp, hkp->uidx, dalgo);
659  break;
661  if (hkp->pubx >= 0 && hkp->subx >= 0)
662  ctx = rpmhkpHashSubkey(hkp, hkp->subx, dalgo);
663  break;
665  if (hkp->pubx >= 0)
666  ctx = rpmhkpHashSubkey(hkp, hkp->pubx, dalgo);
667  break;
669  /* XXX search for signid amongst the packets? */
670  break;
672  /* XXX only primary key */
673  /* XXX authorized revocation key too. */
674  if (hkp->pubx >= 0)
675  ctx = rpmhkpHashKey(hkp, hkp->pubx, dalgo);
676  break;
678  /* XXX only primary key */
679  /* XXX authorized revocation key too. */
680  if (hkp->pubx >= 0 && hkp->subx >= 0)
681  ctx = rpmhkpHashKey(hkp, hkp->subx, dalgo);
682  break;
685  case PGPSIGTYPE_CONFIRM:
686  break;
687  }
688 
689 HKPDEBUG((stderr, "<-- %s(%p,%d,%u,%u) ctx %p\n", __FUNCTION__, hkp, keyx, sigtype, dalgo, ctx));
690 
691  return ctx;
692 }
693 
694 static int rpmhkpVerifyHash(rpmhkp hkp, pgpDig dig, DIGEST_CTX ctx)
695 {
696  pgpDigParams sigp = pgpGetSignature(dig);
697  const char * dname = xstrdup(rpmDigestName(ctx));
698  rpmuint8_t * digest = NULL;
699  size_t digestlen = 0;
700  int rc = rpmDigestFinal(ctx, &digest, &digestlen, 0);
701 
702 HKPDEBUG((stderr, "--> %s(%p,%p,%p)\n", __FUNCTION__, hkp, dig, ctx));
703 
704  rc = memcmp(sigp->signhash16, digest, sizeof(sigp->signhash16));
705 
706 if (rc)
707 SPEW((stderr, "\t%s\t%s\n", dname, pgpHexStr(digest, digestlen)));
708 SPEW((stderr, "%s\t%s\n", (!rc ? "\tGOOD" : "------> BAD"), pgpHexStr(sigp->signhash16, sizeof(sigp->signhash16))));
709 
710  if (rc)
711  SUM.HASH.bad++;
712  else
713  SUM.HASH.good++;
714 
715  digest = _free(digest);
716  digestlen = 0;
717  dname = _free(dname);
718 
719 HKPDEBUG((stderr, "<-- %s(%p,%p,%p) rc %d\n", __FUNCTION__, hkp, dig, ctx, rc));
720  return rc;
721 }
722 
724 {
725  pgpDigParams sigp = pgpGetSignature(dig);
726  int rc = 0; /* XXX assume failure */
727 
728 HKPDEBUG((stderr, "--> %s(%p,%p,%p)\n", __FUNCTION__, hkp, dig, ctx));
729 
730  switch (sigp->pubkey_algo) {
731  case PGPPUBKEYALGO_RSA:
732  if (pgpImplSetRSA(ctx, dig, sigp)) {
733 DESPEW((stderr, "------> BAD\t%s\n", pgpHexStr(sigp->signhash16, 2)));
734  SUM.HASH.bad++;
735  goto exit;
736  }
737  if (!pgpImplVerify(dig)) {
738 DESPEW((stderr, "------> BAD\tV%u %s-%s\n",
739  sigp->version,
740  _pgpPubkeyAlgo2Name(sigp->pubkey_algo),
741  _pgpHashAlgo2Name(sigp->hash_algo)));
742  SUM.RSA.bad++;
743  } else {
744 DESPEW((stderr, "\tGOOD\tV%u %s-%s\n",
745  sigp->version,
746  _pgpPubkeyAlgo2Name(sigp->pubkey_algo),
747  _pgpHashAlgo2Name(sigp->hash_algo)));
748  SUM.RSA.good++;
749  rc = 1;
750  }
751  break;
752  case PGPPUBKEYALGO_DSA:
753  if (pgpImplSetDSA(ctx, dig, sigp)) {
754 DESPEW((stderr, "------> BAD\t%s\n", pgpHexStr(sigp->signhash16, 2)));
755  SUM.HASH.bad++;
756  goto exit;
757  }
758  if (!pgpImplVerify(dig)) {
759 DESPEW((stderr, "------> BAD\tV%u %s-%s\n",
760  sigp->version,
761  _pgpPubkeyAlgo2Name(sigp->pubkey_algo),
762  _pgpHashAlgo2Name(sigp->hash_algo)));
763  SUM.DSA.bad++;
764  } else {
765 DESPEW((stderr, "\tGOOD\tV%u %s-%s\n",
766  sigp->version,
767  _pgpPubkeyAlgo2Name(sigp->pubkey_algo),
768  _pgpHashAlgo2Name(sigp->hash_algo)));
769  SUM.DSA.good++;
770  rc = 1;
771  }
772  break;
773  case PGPPUBKEYALGO_ECDSA:
774  if (pgpImplSetECDSA(ctx, dig, sigp)) {
775 DESPEW((stderr, "------> BAD\t%s\n", pgpHexStr(sigp->signhash16, 2)));
776  SUM.HASH.bad++;
777  goto exit;
778  }
779  if (!pgpImplVerify(dig)) {
780 DESPEW((stderr, "------> BAD\tV%u %s-%s\n",
781  sigp->version,
782  _pgpPubkeyAlgo2Name(sigp->pubkey_algo),
783  _pgpHashAlgo2Name(sigp->hash_algo)));
784  SUM.ECDSA.bad++;
785  } else {
786 DESPEW((stderr, "\tGOOD\tV%u %s-%s\n",
787  sigp->version,
788  _pgpPubkeyAlgo2Name(sigp->pubkey_algo),
789  _pgpHashAlgo2Name(sigp->hash_algo)));
790  SUM.ECDSA.good++;
791  rc = 1;
792  }
793  break;
794  }
795 
796 exit:
797 HKPDEBUG((stderr, "<-- %s(%p,%p,%p) rc %d\n", __FUNCTION__, hkp, dig, ctx, rc));
798  return rc;
799 }
800 
801 static int rpmhkpVerify(rpmhkp hkp, pgpPkt pp)
802 {
804  pgpDigParams sigp = pgpGetSignature(dig);
805  pgpDigParams pubp = pgpGetPubkey(dig);
806  DIGEST_CTX ctx = NULL;
807  int keyx;
808  int rc = 1; /* assume failure */
809 int xx;
810 
811 HKPDEBUG((stderr, "--> %s(%p,%p)\n", __FUNCTION__, hkp, pp));
812 
813  SUM.sigs++;
814 
815  /* XXX Load signature paramaters. */
816  xx = rpmhkpLoadSignature(hkp, dig, pp);
817 
818  /* Ignore expired signatures. */
819  { time_t expire = pgpGrab(sigp->expire, sizeof(sigp->expire));
820  time_t ctime = pgpGrab(sigp->time, sizeof(sigp->time));
821  if (expire && (expire + ctime) < time(NULL)) {
822  SUM.expired++;
823  goto exit;
824  }
825  }
826 
827  /*
828  * Skip PGP Global Directory Verification signatures.
829  * http://www.kfwebs.net/articles/article/17/GPG-mass-cleaning-and-the-PGP-Corp.-Global-Directory
830  */
831  if (pgpGrab(sigp->signid+4, 4) == 0xCA57AD7C
832  || (hkp->crl && rpmbfChk(hkp->crl, sigp->signid, 8))) {
833  SUM.filtered++;
834  goto exit;
835  }
836 
837  rpmlog(_rpmhkp_lvl, " SIG: %08X %08X V%u %s-%s %s\n",
838  pgpGrab(sigp->signid, 4), pgpGrab(sigp->signid+4, 4),
839  sigp->version,
840  _pgpPubkeyAlgo2Name(sigp->pubkey_algo),
841  _pgpHashAlgo2Name(sigp->hash_algo),
842  _pgpSigType2Name(sigp->sigtype)
843  );
844 
845  /* XXX Load pubkey paramaters. */
846  keyx = rpmhkpFindKey(hkp, dig, sigp->signid, sigp->pubkey_algo);
847  if (keyx == -2) /* XXX AWOL */
848  goto exit;
849 
850  /* Ignore expired keys (self-certs only). */
851  { time_t keyexpire = pgpGrab(sigp->keyexpire, sizeof(sigp->keyexpire));
852  time_t keyctime = pgpGrab(pubp->time, sizeof(pubp->time));
853  if (keyexpire && (keyexpire + keyctime) < time(NULL)) {
854  SUM.keyexpired++;
855  goto exit;
856  }
857  }
858 
859  ctx = rpmhkpHash(hkp, keyx,
860  (pgpSigType)sigp->sigtype, (pgpHashAlgo)sigp->hash_algo);
861 
862  if (ctx) {
863 
864  if (sigp->hash)
865  rpmhkpUpdate(ctx, sigp->hash, sigp->hashlen);
866 
867  if (sigp->version == 4) {
868  hkp->goop[0] = sigp->version;
869  hkp->goop[1] = (rpmuint8_t)0xff;
870  hkp->goop[2] = (sigp->hashlen >> 24) & 0xff;
871  hkp->goop[3] = (sigp->hashlen >> 16) & 0xff;
872  hkp->goop[4] = (sigp->hashlen >> 8) & 0xff;
873  hkp->goop[5] = (sigp->hashlen ) & 0xff;
874  rpmhkpUpdate(ctx, hkp->goop, 6);
875  }
876 
877  switch (sigp->pubkey_algo) {
878  /* XXX handle only RSA/DSA? */
879  case PGPPUBKEYALGO_RSA:
880  case PGPPUBKEYALGO_DSA:
881  case PGPPUBKEYALGO_ECDSA:
882  /* XXX don't fuss V3 signatures for validation yet. */
883  if (sigp->version == 4) {
884  rc = rpmhkpVerifySignature(hkp, dig, ctx);
885  break;
886  }
887  /*@fallthrough@*/
888  default:
889  rc = rpmhkpVerifyHash(hkp, dig, ctx);
890  break;
891  }
892  ctx = NULL;
893  }
894 
895 exit:
896  dig = pgpDigFree(dig);
897 HKPDEBUG((stderr, "<-- %s(%p,%p) rc %d\n", __FUNCTION__, hkp, pp, rc));
898  return rc; /* XXX 1 on success */
899 }
900 
901 rpmRC rpmhkpValidate(rpmhkp hkp, const char * keyname)
902 {
903  pgpPkt pp = (pgpPkt) alloca(sizeof(*pp));
904  size_t pleft;
905  rpmRC rc = RPMRC_NOKEY; /* assume failure */
906  int xx;
907  int i;
908 const rpmuint8_t * signid;
909 rpmuint32_t thistime;
910 
911 char tbuf[BUFSIZ];
912 char * t, * te;
913 te = t = tbuf;
914 *te = '\0';
915 
916  /*Reset all the temporary variables*/
917  hkp->pubx = -1;
918  hkp->uidx = -1;
919  hkp->subx = -1;
920  hkp->sigx = -1;
921  hkp->tvalid = 0;
922  hkp->uvalidx = -1;
923 
924 HKPDEBUG((stderr, "--> %s(%p,%s)\n", __FUNCTION__, hkp, keyname));
925 
926  /* Do a lazy lookup before validating. */
927  if (hkp == NULL && keyname && *keyname) {
928  if ((hkp = rpmhkpLookup(keyname)) == NULL) {
929  rc = RPMRC_NOTFOUND;
930  return rc;
931  }
932  } else
933  if ((hkp = rpmhkpLink(hkp)) == NULL)
934  return rc;
935 
936  SUM.certs++;
937 assert(hkp->pkts);
938 
939  pleft = hkp->pktlen;
940 HKPDEBUG((stderr, "\tpkts %p[%u] pleft %u\n", hkp->pkts, (unsigned)hkp->npkts, (unsigned)pleft));
941  for (i = 0; i < hkp->npkts; i++) {
942  xx = pgpPktLen(hkp->pkts[i], pleft, pp);
943 assert(xx > 0);
944  pleft -= pp->pktlen;
945 SPEW((stderr, "%6d %p[%3u] %02X %s\n", i, hkp->pkts[i], (unsigned)pp->pktlen, *hkp->pkts[i], _pgpTag2Name(pp->tag)));
946 SPEW((stderr, "\t%s\n", pgpHexStr(hkp->pkts[i], pp->pktlen)));
947 
948  switch (pp->tag) {
949  default:
950  break;
951  case PGPTAG_PUBLIC_KEY:
952  hkp->pubx = i;
953  /* XXX sloppy hkp:// queries can/will have multiple PUB's */
954  xx = pgpPubkeyFingerprint(hkp->pkts[i], pp->pktlen, hkp->keyid);
955  sprintf(te, " PUB: %08X %08X",
956  pgpGrab(hkp->keyid, 4), pgpGrab(hkp->keyid+4, 4));
957  te += strlen(te);
958  if (pp->u.h[0] == 3) {
959  sprintf(te, " V%u %s", pp->u.j->version,
960  _pgpPubkeyAlgo2Name(pp->u.j->pubkey_algo));
961  te += strlen(te);
962  if (pp->u.j->valid[0] || pp->u.j->valid[1]) {
963  rpmuint32_t days =
964  pgpGrab(pp->u.j->valid, sizeof(pp->u.j->valid));
965  time_t expired =
966  pgpGrab(pp->u.j->time, 4) + (24 * 60 * 60 * days);
967  if (expired < time(NULL)) {
968  sprintf(te, " EXPIRED");
969  te += strlen(te);
970  /* XXX handle V3 expired */
971  }
972  }
973  }
974  if (pp->u.h[0] == 4) {
975  sprintf(te, " V%u %s", pp->u.k->version,
976  _pgpPubkeyAlgo2Name(pp->u.k->pubkey_algo));
977  te += strlen(te);
978  }
979  rpmlog(_rpmhkp_lvl, "%s\n", t);
980  te = t = tbuf;
981 
982  break;
983  case PGPTAG_USER_ID:
984  hkp->uidx = i;
985  break;
987  hkp->subx = i;
988  xx = pgpPubkeyFingerprint(hkp->pkts[i], pp->pktlen, hkp->subid);
989  sprintf(te, " SUB: %08X %08X",
990  pgpGrab(hkp->keyid, 4), pgpGrab(hkp->keyid+4, 4));
991  te += strlen(te);
992  if (pp->u.h[0] == 3) {
993  sprintf(te, " V%u %s", pp->u.j->version,
994  _pgpPubkeyAlgo2Name(pp->u.j->pubkey_algo));
995  te += strlen(te);
996  if (pp->u.j->valid[0] || pp->u.j->valid[1]) {
997  rpmuint32_t days =
998  pgpGrab(pp->u.j->valid, sizeof(pp->u.j->valid));
999  time_t expired =
1000  pgpGrab(pp->u.j->time, 4) + (24 * 60 * 60 * days);
1001  if (expired < time(NULL)) {
1002  sprintf(te, " EXPIRED");
1003  te += strlen(te);
1004  /* XXX handle V3 expired */
1005  }
1006  }
1007  }
1008  if (pp->u.h[0] == 4) {
1009  sprintf(te, " V%u %s", pp->u.k->version,
1010  _pgpPubkeyAlgo2Name(pp->u.k->pubkey_algo));
1011  te += strlen(te);
1012  }
1013  rpmlog(_rpmhkp_lvl, "%s\n", t);
1014  te = t = tbuf;
1015  break;
1016  case PGPTAG_SIGNATURE:
1017  switch (ppSigType(pp)) {
1018  case PGPSIGTYPE_BINARY:
1019  case PGPSIGTYPE_TEXT:
1020  case PGPSIGTYPE_STANDALONE:
1021  default:
1022  break;
1026  break;
1028  signid = ppSignid(pp);
1029  /* XXX treat missing issuer as "this" pubkey signature. */
1030  if (signid && memcmp(hkp->keyid, signid, sizeof(hkp->keyid)))
1031  break;
1032  hkp->sigx = i;
1033  if (!rpmhkpVerify(hkp, pp)) { /* XXX 1 on success */
1034  if (rc == RPMRC_NOKEY) rc = RPMRC_FAIL;
1035  break;
1036  }
1037  thistime = ppSigTime(pp);
1038  if (thistime < hkp->tvalid)
1039  break;
1040  hkp->tvalid = thistime;
1041  hkp->uvalidx = hkp->uidx;
1042  break;
1044  if (!rpmhkpVerify(hkp, pp)) { /* XXX 1 on success */
1045  if (rc == RPMRC_NOKEY) rc = RPMRC_FAIL;
1046  break;
1047  }
1048  SUM.subbound++;
1049  if (rc == RPMRC_NOKEY) rc = RPMRC_OK;
1050  break;
1052  if (!rpmhkpVerify(hkp, pp)) { /* XXX 1 on success */
1053  if (rc == RPMRC_NOKEY) rc = RPMRC_FAIL;
1054  break;
1055  }
1056  SUM.pubbound++;
1057  if (rc == RPMRC_NOKEY) rc = RPMRC_OK;
1058  break;
1059  case PGPSIGTYPE_KEY_REVOKE:
1060  if (!rpmhkpVerify(hkp, pp)) /* XXX 1 on success */
1061  break;
1062  SUM.pubrevoked++;
1063  if (rc == RPMRC_NOKEY) rc = RPMRC_NOTTRUSTED;
1064  if (hkp->crl)
1065  xx = rpmbfAdd(hkp->crl, hkp->keyid, sizeof(hkp->keyid));
1066  goto exit; /* XXX stop validating revoked cert. */
1067  /*@notreached@*/ break;
1069  if (!rpmhkpVerify(hkp, pp)) /* XXX 1 on success */
1070  break;
1071  SUM.subrevoked++;
1072 #ifdef NOTYET /* XXX subid not loaded correctly yet. */
1073  if (rc == RPMRC_NOKEY) rc = RPMRC_NOTTRUSTED;
1074  if (hkp->crl)
1075  xx = rpmbfAdd(hkp->crl, hkp->subid, sizeof(hkp->subid));
1076 #endif
1077  break;
1078  case PGPSIGTYPE_SIGNED_KEY:
1080  case PGPSIGTYPE_TIMESTAMP:
1081  case PGPSIGTYPE_CONFIRM:
1082  break;
1083  }
1084  break;
1085  }
1086  }
1087 
1088 exit:
1089  if ((hkp->uvalidx >= 0 && hkp->uvalidx < hkp->npkts) && hkp->tvalid > 0) {
1090  char user[256+1];
1091  size_t nuser;
1092  pgpPktUid * u;
1093  xx = pgpPktLen(hkp->pkts[hkp->uvalidx], hkp->pktlen, pp);
1094  /* XXX append a NUL avoiding encoding issues. */
1095  nuser = (pp->hlen > sizeof(user)-1 ? sizeof(user)-1 : pp->hlen);
1096  memset(user, 0, sizeof(user));
1097  u = (pgpPktUid *) pp->u.h;
1098  memcpy(user, u->userid, nuser);
1099  user[nuser] = '\0';
1100  rpmlog(_rpmhkp_lvl, " UID: %s\n", user);
1101  /* Some POSITIVE cert succeeded, so mark OK. */
1102  rc = RPMRC_OK;
1103  }
1104 
1105  hkp = rpmhkpFree(hkp);
1106 HKPDEBUG((stderr, "<-- %s(%p,%s) rc %d\n", __FUNCTION__, hkp, keyname, rc));
1107 
1108  return rc;
1109 }
1110 
1111 void _rpmhkpPrintStats(FILE * fp)
1112 {
1113  if (fp == NULL) fp = stderr;
1114  fprintf(fp, "============\n");
1115  fprintf(fp, " LOOKUPS:%10u\n", (unsigned) SUM.lookups);
1116  fprintf(fp, " PUBKEYS:%10u\n", (unsigned) SUM.certs);
1117  fprintf(fp, " SIGNATURES:%10u\n", (unsigned) SUM.sigs);
1118  fprintf(fp, " PUB bound:%10u\trevoked:%10u\texpired:%10u\n",
1119  (unsigned) SUM.pubbound,
1120  (unsigned) SUM.pubrevoked,
1121  (unsigned) SUM.keyexpired);
1122  fprintf(fp, " SUB bound:%10u\trevoked:%10u\n",
1123  (unsigned) SUM.subbound,
1124  (unsigned) SUM.subrevoked);
1125  fprintf(fp, " expired:%10u\n", (unsigned) SUM.expired);
1126  fprintf(fp, " filtered:%10u\n", (unsigned) SUM.filtered);
1127  fprintf(fp, " RSA:%10u:%-10u\n",
1128  (unsigned) SUM.RSA.good, (unsigned) (SUM.RSA.good+SUM.RSA.bad));
1129  fprintf(fp, " DSA:%10u:%-10u\n",
1130  (unsigned) SUM.DSA.good, (unsigned) (SUM.DSA.good+SUM.DSA.bad));
1131  fprintf(fp, "ECDSA:%10u:%-10u\n",
1132  (unsigned) SUM.ECDSA.good, (unsigned) (SUM.ECDSA.good+SUM.ECDSA.bad));
1133  fprintf(fp, " HASH:%10u:%-10u\n",
1134  (unsigned) SUM.HASH.good, (unsigned) (SUM.HASH.good+SUM.HASH.bad));
1135  fprintf(fp, " AWOL:%10u:%-10u\n",
1136  (unsigned) SUM.AWOL.good, (unsigned) (SUM.AWOL.good+SUM.AWOL.bad));
1137  fprintf(fp, " SKIP:%10u:%-10u\n",
1138  (unsigned) SUM.SKIP.good, (unsigned) (SUM.SKIP.good+SUM.SKIP.bad));
1139 }
1140 
1141 void _rpmhkpDumpDigParams(const char * msg, pgpDigParams sigp, FILE * fp)
1142 {
1143  if (fp == NULL) fp = stderr;
1144  fprintf(fp, "%s: %p\n", msg, sigp);
1145  fprintf(fp, "\t userid: %s\n", sigp->userid);
1146  fprintf(fp, "\t hash: %p[%u]\n", sigp->hash, (unsigned) sigp->hashlen);
1147  fprintf(fp, "\t tag: %02X\n", sigp->tag);
1148  fprintf(fp, "\t version: %02X\n", sigp->version);
1149  fprintf(fp, "\t time: %08X\n",
1150  pgpGrab(sigp->time, sizeof(sigp->time)));
1151  fprintf(fp, "\tpubkey_algo: %02X %s\n",
1152  sigp->pubkey_algo, _pgpPubkeyAlgo2Name(sigp->pubkey_algo));
1153  fprintf(fp, "\t hash_algo: %02X %s\n",
1154  sigp->hash_algo, _pgpHashAlgo2Name(sigp->hash_algo));
1155  fprintf(fp, "\t sigtype: %02X %s\n",
1156  sigp->sigtype, _pgpSigType2Name(sigp->sigtype));
1157  fprintf(fp, "\t signhash16: %04X\n",
1158  pgpGrab(sigp->signhash16, sizeof(sigp->signhash16)));
1159  fprintf(fp, "\t signid: %08X %08X\n",
1160  pgpGrab(sigp->signid, 4), pgpGrab(sigp->signid+4, 4));
1161  fprintf(fp, "\t saved: %02X\n", sigp->saved);
1162 }
1163 
1164 void _rpmhkpDumpDig(const char * msg, pgpDig dig, FILE * fp)
1165 {
1166  if (fp == NULL) fp = stderr;
1167  fprintf(fp, "%s: dig %p\n", msg, dig);
1168 
1169  fprintf(fp, "\t build_sign: %s\n", dig->build_sign);
1170  fprintf(fp, "\tpubkey_algo: %s\n", dig->pubkey_algoN);
1171  fprintf(fp, "\t hash_algo: %s\n", dig->hash_algoN);
1172 
1173  fprintf(fp, "\t sigtag: 0x%08x\n", dig->sigtag);
1174  fprintf(fp, "\t sigtype: 0x%08x\n", dig->sigtype);
1175  fprintf(fp, "\t sig: %p[%u]\n", dig->sig, (unsigned) dig->siglen);
1176  fprintf(fp, "\t vsflags: 0x%08x\n", dig->vsflags);
1177  fprintf(fp, "\t findPubkey: %p\n", dig->findPubkey);
1178  fprintf(fp, "\t _ts: %p\n", dig->_ts);
1179  fprintf(fp, "\t ppkts: %p[%u]\n", dig->ppkts, dig->npkts);
1180  fprintf(fp, "\t nbytes: 0x%08x\n", (unsigned) dig->nbytes);
1181 
1182  fprintf(fp, "\t hsha: %p\n", dig->hsha);
1183  fprintf(fp, "\t hdsa: %p\n", dig->hdsa);
1184  fprintf(fp, "\t sha1: %p[%u]\n", dig->sha1, (unsigned) dig->sha1len);
1185 
1186  fprintf(fp, "\t hecdsa: %p\n", dig->hecdsa);
1187 
1188  fprintf(fp, "\t md5ctx: %p\n", dig->md5ctx);
1189  fprintf(fp, "\t hrsa: %p\n", dig->hrsa);
1190  fprintf(fp, "\t md5: %p[%u]\n", dig->md5, (unsigned) dig->md5len);
1191  fprintf(fp, "\t impl: %p\n", dig->impl);
1192 
1193  _rpmhkpDumpDigParams("PUB", pgpGetPubkey(dig), fp);
1194  _rpmhkpDumpDigParams("SIG", pgpGetSignature(dig), fp);
1195 }
rpmuint8_t userid[1]
Definition: rpmpgp.h:942
void _rpmhkpDumpDig(const char *msg, pgpDig dig, FILE *fp)
Definition: rpmhkp.c:1164
pgpDigParams pgpGetPubkey(pgpDig dig)
Return OpenPGP pubkey parameters.
Definition: rpmpgp.c:1397
5.5.1.
Definition: rpmpgp.h:681
const rpmuint8_t * pgpPrtPubkeyParams(pgpDig dig, const pgpPkt pp, pgpPubkeyAlgo pubkey_algo, const rpmuint8_t *p)
Definition: rpmpgp.c:715
static const rpmuint8_t * ppSigHash(pgpPkt pp, size_t *plen)
Definition: rpmhkp.c:210
int rpmhkpFindKey(rpmhkp hkp, pgpDig dig, const rpmuint8_t *signid, rpmuint8_t pubkey_algo)
Definition: rpmhkp.c:404
rpmRC rpmhkpValidate(rpmhkp hkp, const char *keyname)
Retrieve/Validate binding and certification signatures on a pubkey.
Definition: rpmhkp.c:901
pgpDig pgpDigFree(pgpDig dig)
Destroy a container for parsed OpenPGP packates.
const char const char size_t len
Definition: bson.h:823
size_t pubbound
Definition: rpmhkp.c:43
struct _BAstats_s _BAstats
int pgpPktLen(const rpmuint8_t *pkt, size_t pleft, pgpPkt pp)
Definition: rpmpgp.c:999
OpenPGP constants and structures from RFC-2440.
size_t subrevoked
Definition: rpmhkp.c:46
rpmhkp _rpmhkpI
Definition: rpmhkp.c:22
size_t lookups
Definition: rpmhkp.c:39
size_t keyexpired
Definition: rpmhkp.c:48
rpmbf rpmbfNew(size_t m, size_t k, unsigned flags)
Create a Bloom filter.
Definition: rpmbf.c:52
static const char * _pgpTag2Name(uint32_t tag)
Definition: rpmpgp.h:1170
char * xstrdup(const char *str)
Definition: rpmmalloc.c:321
struct pgpDigParams_s * pgpDigParams
Definition: rpmiotypes.h:101
static unsigned int pgpLen(const rpmuint8_t *s, unsigned int *lenp)
Return length of an OpenPGP packet.
Definition: rpmpgp.h:1053
DIGEST_CTX rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
Initialize digest context.
Definition: digest.c:247
5.11.
Definition: rpmpgp.h:941
#define PGPARMOR_ERROR
Definition: rpmpgp.h:956
static unsigned int pgpGrab(const rpmuint8_t *s, size_t nbytes)
Return (native-endian) integer from big-endian representation.
Definition: rpmpgp.h:1036
const char int time
Definition: bson.h:1005
enum pgpHashAlgo_e pgpHashAlgo
9.4.
rpmhkp rpmhkpNew(const rpmuint8_t *keyid, uint32_t flags)
Create a new hkp handle.
Definition: rpmhkp.c:112
rpmhkp rpmhkpLookup(const char *keyname)
Retrieve a pubkey from a SKS server.
Definition: rpmhkp.c:318
5.2.3.
Definition: rpmpgp.h:376
_Astats ECDSA
Definition: rpmhkp.c:35
enum pgpSigType_e pgpSigType
5.2.1.
static void rpmlog(int code, const char *fmt,...)
Definition: rpmlog.h:299
static int rpmhkpVerify(rpmhkp hkp, pgpPkt pp)
Definition: rpmhkp.c:801
rpmhkp rpmhkpFree(rpmhkp hkp)
Destroy a hkp handle.
#define HKPDEBUG(_list)
Definition: rpmhkp.c:63
#define SUM
Definition: rpmhkp.c:54
static int pgpImplSetDSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Definition: rpmpgp.h:1785
5.2.2.
Definition: rpmpgp.h:344
size_t filtered
Definition: rpmhkp.c:47
size_t bad
Definition: rpmhkp.c:29
struct _filter_s _rpmhkp_crl
Definition: rpmhkp.c:25
_Astats AWOL
Definition: rpmhkp.c:37
static rpmuint8_t ppSigType(pgpPkt pp)
Definition: rpmhkp.c:279
static int rpmhkpVerifyHash(rpmhkp hkp, pgpDig dig, DIGEST_CTX ctx)
Definition: rpmhkp.c:694
void rpmbfParams(size_t n, double e, size_t *mp, size_t *kp)
Return optimal {m, k} for given n and e.
Definition: rpmbf.c:202
char * alloca()
Yet Another syslog(3) API clone.
pgpArmor pgpReadPkts(const char *fn, rpmuint8_t **pkt, size_t *pktlen)
Parse armored OpenPGP packets from a file.
Definition: rpmpgp.c:1739
unsigned int rpmuint32_t
Definition: rpmiotypes.h:28
static DIGEST_CTX rpmhkpHashUid(rpmhkp hkp, int ix, pgpHashAlgo dalgo)
Definition: rpmhkp.c:592
static const rpmuint8_t * ppSigUnhash(pgpPkt pp, size_t *plen)
Definition: rpmhkp.c:224
int rpmDigestUpdate(DIGEST_CTX ctx, const void *data, size_t len)
Update context with next plain text buffer.
Definition: digest.c:986
static rpmuint32_t ppSigTime(pgpPkt pp)
Definition: rpmhkp.c:259
rpmbf rpmbfFree(rpmbf bf)
Destroy a Bloom filter.
static const char * _pgpPubkeyAlgo2Name(uint32_t algo)
Definition: rpmpgp.h:1191
rpmioItem rpmioGetPool(rpmioPool pool, size_t size)
Get unused item from pool, or alloc a new item.
Definition: rpmmalloc.c:220
size_t subbound
Definition: rpmhkp.c:44
_Astats RSA
Definition: rpmhkp.c:33
int pgpPrtSigParams(pgpDig dig, const pgpPkt pp, pgpPubkeyAlgo pubkey_algo, pgpSigType sigtype, const rpmuint8_t *p)
Definition: rpmpgp.c:449
_Astats SKIP
Definition: rpmhkp.c:38
static rpmhkp rpmhkpGetPool(rpmioPool pool)
Definition: rpmhkp.c:96
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
Definition: rpmiotypes.h:26
static DIGEST_CTX rpmhkpHash(rpmhkp hkp, int keyx, pgpSigType sigtype, pgpHashAlgo dalgo)
Definition: rpmhkp.c:640
int rpmhkpUpdate(DIGEST_CTX ctx, const void *data, size_t len)
Definition: rpmhkp.c:562
const char const bson * data
Definition: mongo.h:463
struct pgpPkt_s * pgpPkt
Definition: rpmiotypes.h:93
pgpDigParams pgpGetSignature(pgpDig dig)
Return OpenPGP signature parameters.
Definition: rpmpgp.c:1392
size_t good
Definition: rpmhkp.c:28
void _rpmhkpDumpDigParams(const char *msg, pgpDigParams sigp, FILE *fp)
Definition: rpmhkp.c:1141
Digest private data.
Definition: digest.c:130
const char const char * user
Definition: mongo.h:828
struct pgpDig_s * pgpDig
Definition: rpmiotypes.h:97
rpmioPool _rpmhkpPool
Definition: rpmhkp.c:94
static int pgpImplSetECDSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Definition: rpmpgp.h:1803
static const rpmuint8_t * ppSignid(pgpPkt pp)
Definition: rpmhkp.c:240
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
Definition: macro.c:3238
static DIGEST_CTX rpmhkpHashSubkey(rpmhkp hkp, int ix, pgpHashAlgo dalgo)
Definition: rpmhkp.c:617
struct _filter_s _rpmhkp_awol
Definition: rpmhkp.c:24
size_t sigs
Definition: rpmhkp.c:41
#define SPEW(_list)
Definition: rpmhkp.c:57
const char const bson int mongo_write_concern int flags
Definition: mongo.h:485
static int rpmhkpVerifySignature(rpmhkp hkp, pgpDig dig, DIGEST_CTX ctx)
Definition: rpmhkp.c:723
static int pgpImplSetRSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Definition: rpmpgp.h:1776
static const char * _pgpHashAlgo2Name(uint32_t algo)
Definition: rpmpgp.h:1184
static const char * rpmhkpEscape(const char *keyname)
Definition: rpmhkp.c:291
int pgpGrabPkts(const rpmuint8_t *pkts, size_t pktlen, rpmuint8_t ***pppkts, int *pnpkts)
Return array of packet pointers.
Definition: rpmpgp.c:1472
enum pgpPubkeyAlgo_e pgpPubkeyAlgo
9.1.
int _rpmhkp_debug
Definition: rpmhkp.c:19
enum rpmRC_e rpmRC
RPM return codes.
pgpDig pgpDigNew(pgpVSFlags vsflags, pgpPubkeyAlgo pubkey_algo)
Create a container for parsed OpenPGP packates.
Definition: rpmpgp.c:1314
rpmhkp rpmhkpLink(rpmhkp hkp)
Reference a hkp handle instance.
void _rpmhkpPrintStats(FILE *fp)
Display hkp usage statistics.
Definition: rpmhkp.c:1111
const char const int i
Definition: bson.h:778
_Astats HASH
Definition: rpmhkp.c:36
size_t expired
Definition: rpmhkp.c:42
int _rpmhkp_spew
Definition: rpmhkp.c:56
struct _Astats_s _Astats
rpmioPool rpmioNewPool(const char *name, size_t size, int limit, int flags, char *(*dbg)(void *item), void(*init)(void *item), void(*fini)(void *item))
Create a memory pool.
Definition: rpmmalloc.c:109
int pgpPubkeyFingerprint(const rpmuint8_t *pkt, size_t pktlen, rpmuint8_t *keyid)
Print/parse an OpenPGP subtype packet.
Definition: rpmpgp.c:1029
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:756
_Astats DSA
Definition: rpmhkp.c:34
const char * rpmDigestName(DIGEST_CTX ctx)
Return digest name.
Definition: digest.c:201
static int pgpImplVerify(pgpDig dig)
Definition: rpmpgp.h:1856
int rpmbfAdd(rpmbf bf, const void *_s, size_t ns)
Add item to a Bloom filter.
Definition: rpmbf.c:68
enum pgpArmor_e pgpArmor
enum pgpTag_e pgpTag
4.3.
rpmbf rpmbfLink(rpmbf bf)
Reference a Bloom filter instance.
static const char * _pgpSigType2Name(uint32_t sigtype)
Definition: rpmpgp.h:1177
int rpmhkpLoadKey(rpmhkp hkp, pgpDig dig, int keyx, rpmuint8_t pubkey_algo)
Definition: rpmhkp.c:363
int rpmDigestFinal(DIGEST_CTX ctx, void *datap, size_t *lenp, int asAscii)
Return digest and destroy context.
Definition: digest.c:1000
static void rpmhkpFini(void *_hkp)
Definition: rpmhkp.c:78
static const rpmuint8_t * pgpGrabSubTagVal(const rpmuint8_t *h, size_t hlen, rpmuint8_t subtag, size_t *tlenp)
Definition: rpmhkp.c:181
#define xmalloc
Definition: system.h:32
struct rpmhkp_s * rpmhkp
Definition: rpmhkp.h:11
size_t certs
Definition: rpmhkp.c:40
static char * pgpHexStr(const rpmuint8_t *p, size_t plen)
Return hex formatted representation of bytes.
Definition: rpmpgp.h:1124
static rpmhkp rpmhkpI(void)
Definition: rpmhkp.c:69
The version 4 format is similar to the version 3 format except for the absence of a validity period...
Definition: rpmpgp.h:719
size_t pubrevoked
Definition: rpmhkp.c:45
int rpmhkpLoadSignature(rpmhkp hkp, pgpDig dig, pgpPkt pp)
Definition: rpmhkp.c:461
#define DESPEW(_list)
Definition: rpmhkp.c:61
static DIGEST_CTX rpmhkpHashKey(rpmhkp hkp, int ix, pgpHashAlgo dalgo)
Definition: rpmhkp.c:569
_BAstats _rpmhkp_stats
Definition: rpmhkp.c:51
int _rpmhkp_lvl
Definition: rpmhkp.c:65
int j
Definition: mongo.h:438
int rpmbfChk(rpmbf bf, const void *_s, size_t ns)
Check for item in a Bloom filter.
Definition: rpmbf.c:90