rpm  5.2.1
rpmpgp.c
Go to the documentation of this file.
1 
6 #include "system.h"
7 
8 #define _RPMIOB_INTERNAL
9 #include <rpmiotypes.h>
10 
11 #include <rpmio.h>
12 
13 #define _RPMPGP_INTERNAL
14 #include <rpmbc.h> /* XXX still needs base64 goop */
15 #if defined(WITH_NSS)
16 #include <rpmnss.h>
17 #endif
18 #include "debug.h"
19 
20 /*@access pgpDig @*/
21 /*@access pgpDigParams @*/
22 /*@access pgpPkt @*/
23 /*@access rpmiob @*/
24 
25 /*@unchecked@*/
26 int _pgp_debug = 0;
27 
28 /*@unchecked@*/
29 int _pgp_print = 0;
30 
31 /*@unchecked@*/
33  /* explicit selection (order DOES NOT matter here) */
34 #if defined(USE_CRYPTO_BEECRYPT) && defined(WITH_BEECRYPT)
36 #elif defined(USE_CRYPTO_GCRYPT) && defined(WITH_GCRYPT)
38 #elif defined(USE_CRYPTO_NSS) && defined(WITH_NSS)
40 #elif defined(USE_CRYPTO_OPENSSL) && defined(WITH_SSL)
42  /* implict selection (order DOES matter) */
43 #elif defined(WITH_BEECRYPT)
45 #elif defined(WITH_GCRYPT)
47 #elif defined(WITH_NSS)
49 #elif defined(WITH_SSL)
51 #else
52 #error INTERNAL ERROR: no suitable Cryptography library available
53 #endif
54 
55 /*@unchecked@*/ /*@refcounted@*/ /*@relnull@*/
56 static pgpDig _dig = NULL;
57 
58 /*@unchecked@*/ /*@null@*/
59 static pgpDigParams _digp = NULL;
60 
61 struct pgpPkt_s {
63  unsigned int pktlen;
64  const rpmuint8_t * h;
65  unsigned int hlen;
66 };
67 
69  { PGPSIGTYPE_BINARY, "Binary document signature" },
70  { PGPSIGTYPE_TEXT, "Text document signature" },
71  { PGPSIGTYPE_STANDALONE, "Standalone signature" },
72  { PGPSIGTYPE_GENERIC_CERT, "Generic certification of a User ID and Public Key" },
73  { PGPSIGTYPE_PERSONA_CERT, "Personal certification of a User ID and Public Key" },
74  { PGPSIGTYPE_CASUAL_CERT, "Casual certification of a User ID and Public Key" },
75  { PGPSIGTYPE_POSITIVE_CERT, "Positive certification of a User ID and Public Key" },
76  { PGPSIGTYPE_SUBKEY_BINDING,"Subkey Binding Signature" },
77  { PGPSIGTYPE_SIGNED_KEY, "Signature directly on a key" },
78  { PGPSIGTYPE_KEY_REVOKE, "Key revocation signature" },
79  { PGPSIGTYPE_SUBKEY_REVOKE, "Subkey revocation signature" },
80  { PGPSIGTYPE_CERT_REVOKE, "Certification revocation signature" },
81  { PGPSIGTYPE_TIMESTAMP, "Timestamp signature" },
82  { PGPSIGTYPE_CONFIRM, "Third-Party Confirmation signature" },
83  { -1, "Unknown signature type" },
84 };
85 
87  { PGPPUBKEYALGO_RSA, "RSA" },
88  { PGPPUBKEYALGO_RSA_ENCRYPT,"RSA(Encrypt-Only)" },
89  { PGPPUBKEYALGO_RSA_SIGN, "RSA(Sign-Only)" },
90  { PGPPUBKEYALGO_ELGAMAL_ENCRYPT,"Elgamal(Encrypt-Only)" },
91  { PGPPUBKEYALGO_DSA, "DSA" },
92  { PGPPUBKEYALGO_EC, "Elliptic Curve" },
93  { PGPPUBKEYALGO_ECDSA, "ECDSA" },
94  { PGPPUBKEYALGO_ELGAMAL, "Elgamal" },
95  { PGPPUBKEYALGO_DH, "Diffie-Hellman (X9.42)" },
96  { -1, "Unknown public key algorithm" },
97 };
98 
100  { PGPSYMKEYALGO_PLAINTEXT, "Plaintext" },
101  { PGPSYMKEYALGO_IDEA, "IDEA" },
102  { PGPSYMKEYALGO_TRIPLE_DES, "3DES" },
103  { PGPSYMKEYALGO_CAST5, "CAST5" },
104  { PGPSYMKEYALGO_BLOWFISH, "BLOWFISH" },
105  { PGPSYMKEYALGO_SAFER, "SAFER" },
106  { PGPSYMKEYALGO_DES_SK, "DES/SK" },
107  { PGPSYMKEYALGO_AES_128, "AES(128-bit key)" },
108  { PGPSYMKEYALGO_AES_192, "AES(192-bit key)" },
109  { PGPSYMKEYALGO_AES_256, "AES(256-bit key)" },
110  { PGPSYMKEYALGO_TWOFISH, "TWOFISH(256-bit key)" },
111  { PGPSYMKEYALGO_NOENCRYPT, "no encryption" },
112  { -1, "Unknown symmetric key algorithm" },
113 };
114 
116  { PGPCOMPRESSALGO_NONE, "Uncompressed" },
117  { PGPCOMPRESSALGO_ZIP, "ZIP" },
118  { PGPCOMPRESSALGO_ZLIB, "ZLIB" },
119  { PGPCOMPRESSALGO_BZIP2, "BZIP2" },
120  { -1, "Unknown compression algorithm" },
121 };
122 
124  { PGPHASHALGO_MD5, "MD5" },
125  { PGPHASHALGO_SHA1, "SHA1" },
126  { PGPHASHALGO_RIPEMD160, "RIPEMD160" },
127  { PGPHASHALGO_MD2, "MD2" },
128  { PGPHASHALGO_TIGER192, "TIGER192" },
129  { PGPHASHALGO_HAVAL_5_160, "HAVAL-5-160" },
130  { PGPHASHALGO_SHA224, "SHA224" },
131  { PGPHASHALGO_SHA256, "SHA256" },
132  { PGPHASHALGO_SHA384, "SHA384" },
133  { PGPHASHALGO_SHA512, "SHA512" },
134  { -1, "Unknown hash algorithm" },
135 };
136 
137 /*@-exportlocal -exportheadervar@*/
138 /*@observer@*/ /*@unchecked@*/
140  { 0x80, "No-modify" },
141  { -1, "Unknown key server preference" },
142 };
143 /*@=exportlocal =exportheadervar@*/
144 
146  { PGPSUBTYPE_SIG_CREATE_TIME,"signature creation time" },
147  { PGPSUBTYPE_SIG_EXPIRE_TIME,"signature expiration time" },
148  { PGPSUBTYPE_EXPORTABLE_CERT,"exportable certification" },
149  { PGPSUBTYPE_TRUST_SIG, "trust signature" },
150  { PGPSUBTYPE_REGEX, "regular expression" },
151  { PGPSUBTYPE_REVOCABLE, "revocable" },
152  { PGPSUBTYPE_KEY_EXPIRE_TIME,"key expiration time" },
153  { PGPSUBTYPE_ARR, "additional recipient request" },
154  { PGPSUBTYPE_PREFER_SYMKEY, "preferred symmetric algorithms" },
155  { PGPSUBTYPE_REVOKE_KEY, "revocation key" },
156  { PGPSUBTYPE_ISSUER_KEYID, "issuer key ID" },
157  { PGPSUBTYPE_NOTATION, "notation data" },
158  { PGPSUBTYPE_PREFER_HASH, "preferred hash algorithms" },
159  { PGPSUBTYPE_PREFER_COMPRESS,"preferred compression algorithms" },
160  { PGPSUBTYPE_KEYSERVER_PREFERS,"key server preferences" },
161  { PGPSUBTYPE_PREFER_KEYSERVER,"preferred key server" },
162  { PGPSUBTYPE_PRIMARY_USERID,"primary user id" },
163  { PGPSUBTYPE_POLICY_URL, "policy URL" },
164  { PGPSUBTYPE_KEY_FLAGS, "key flags" },
165  { PGPSUBTYPE_SIGNER_USERID, "signer's user id" },
166  { PGPSUBTYPE_REVOKE_REASON, "reason for revocation" },
167  { PGPSUBTYPE_FEATURES, "features" },
168  { PGPSUBTYPE_SIG_TARGET, "signature target" },
169  { PGPSUBTYPE_EMBEDDED_SIG, "embedded signature" },
170 
171  { PGPSUBTYPE_INTERNAL_100, "internal subpkt type 100" },
172  { PGPSUBTYPE_INTERNAL_101, "internal subpkt type 101" },
173  { PGPSUBTYPE_INTERNAL_102, "internal subpkt type 102" },
174  { PGPSUBTYPE_INTERNAL_103, "internal subpkt type 103" },
175  { PGPSUBTYPE_INTERNAL_104, "internal subpkt type 104" },
176  { PGPSUBTYPE_INTERNAL_105, "internal subpkt type 105" },
177  { PGPSUBTYPE_INTERNAL_106, "internal subpkt type 106" },
178  { PGPSUBTYPE_INTERNAL_107, "internal subpkt type 107" },
179  { PGPSUBTYPE_INTERNAL_108, "internal subpkt type 108" },
180  { PGPSUBTYPE_INTERNAL_109, "internal subpkt type 109" },
181  { PGPSUBTYPE_INTERNAL_110, "internal subpkt type 110" },
182  { -1, "Unknown signature subkey type" },
183 };
184 
185 struct pgpValTbl_s pgpTagTbl[] = {
186  { PGPTAG_PUBLIC_SESSION_KEY,"Public-Key Encrypted Session Key" },
187  { PGPTAG_SIGNATURE, "Signature" },
188  { PGPTAG_SYMMETRIC_SESSION_KEY,"Symmetric-Key Encrypted Session Key" },
189  { PGPTAG_ONEPASS_SIGNATURE, "One-Pass Signature" },
190  { PGPTAG_SECRET_KEY, "Secret Key" },
191  { PGPTAG_PUBLIC_KEY, "Public Key" },
192  { PGPTAG_SECRET_SUBKEY, "Secret Subkey" },
193  { PGPTAG_COMPRESSED_DATA, "Compressed Data" },
194  { PGPTAG_SYMMETRIC_DATA, "Symmetrically Encrypted Data" },
195  { PGPTAG_MARKER, "Marker" },
196  { PGPTAG_LITERAL_DATA, "Literal Data" },
197  { PGPTAG_TRUST, "Trust" },
198  { PGPTAG_USER_ID, "User ID" },
199  { PGPTAG_PUBLIC_SUBKEY, "Public Subkey" },
200  { PGPTAG_COMMENT_OLD, "Comment (from OpenPGP draft)" },
201  { PGPTAG_PHOTOID, "PGP's photo ID" },
202  { PGPTAG_ENCRYPTED_MDC, "Integrity protected encrypted data" },
203  { PGPTAG_MDC, "Manipulaion detection code packet" },
204  { PGPTAG_PRIVATE_60, "Private #60" },
205  { PGPTAG_COMMENT, "Comment" },
206  { PGPTAG_PRIVATE_62, "Private #62" },
207  { PGPTAG_CONTROL, "Control (GPG)" },
208  { -1, "Unknown packet tag" },
209 };
210 
212  { PGPARMOR_MESSAGE, "MESSAGE" },
213  { PGPARMOR_PUBKEY, "PUBLIC KEY BLOCK" },
214  { PGPARMOR_SIGNATURE, "SIGNATURE" },
215  { PGPARMOR_SIGNED_MESSAGE, "SIGNED MESSAGE" },
216  { PGPARMOR_FILE, "ARMORED FILE" },
217  { PGPARMOR_PRIVKEY, "PRIVATE KEY BLOCK" },
218  { PGPARMOR_SECKEY, "SECRET KEY BLOCK" },
219  { -1, "Unknown armor block" }
220 };
221 
223  { PGPARMORKEY_VERSION, "Version: " },
224  { PGPARMORKEY_COMMENT, "Comment: " },
225  { PGPARMORKEY_MESSAGEID, "MessageID: " },
226  { PGPARMORKEY_HASH, "Hash: " },
227  { PGPARMORKEY_CHARSET, "Charset: " },
228  { -1, "Unknown armor key" }
229 };
230 
231 static void pgpPrtNL(void)
232  /*@globals fileSystem @*/
233  /*@modifies fileSystem @*/
234 {
235  if (!_pgp_print) return;
236  fprintf(stderr, "\n");
237 }
238 
239 static void pgpPrtInt(const char *pre, int i)
240  /*@globals fileSystem @*/
241  /*@modifies fileSystem @*/
242 {
243  if (!_pgp_print) return;
244  if (pre && *pre)
245  fprintf(stderr, "%s", pre);
246  fprintf(stderr, " %d", i);
247 }
248 
249 static void pgpPrtStr(const char *pre, const char *s)
250  /*@globals fileSystem @*/
251  /*@modifies fileSystem @*/
252 {
253  if (!_pgp_print) return;
254  if (pre && *pre)
255  fprintf(stderr, "%s", pre);
256  fprintf(stderr, " %s", s);
257 }
258 
259 static void pgpPrtHex(const char *pre, const rpmuint8_t * p, size_t plen)
260  /*@globals fileSystem @*/
261  /*@modifies fileSystem @*/
262 {
263  if (!_pgp_print) return;
264  if (pre && *pre)
265  fprintf(stderr, "%s", pre);
266  fprintf(stderr, " %s", pgpHexStr(p, plen));
267 }
268 
269 void pgpPrtVal(const char * pre, pgpValTbl vs, rpmuint8_t val)
270  /*@globals fileSystem @*/
271  /*@modifies fileSystem @*/
272 {
273  if (!_pgp_print) return;
274  if (pre && *pre)
275  fprintf(stderr, "%s", pre);
276  fprintf(stderr, "%s(%u)", pgpValStr(vs, val), (unsigned)val);
277 }
278 
279 int pgpPrtSubType(const rpmuint8_t * h, size_t hlen, pgpSigType sigtype)
280 {
281  const rpmuint8_t * p = h;
282  unsigned plen;
283  unsigned i;
284 
285  while (hlen > 0) {
286  i = pgpLen(p, &plen);
287  p += i;
288  hlen -= i;
289 
290  pgpPrtVal(" ", pgpSubTypeTbl, (p[0]&(~PGPSUBTYPE_CRITICAL)));
291  if ((p[0] & PGPSUBTYPE_CRITICAL) != (rpmuint8_t)0)
292  if (_pgp_print)
293  fprintf(stderr, " *CRITICAL*");
294  switch (*p) {
295  case PGPSUBTYPE_PREFER_SYMKEY: /* preferred symmetric algorithms */
296  for (i = 1; i < plen; i++)
297  pgpPrtVal(" ", pgpSymkeyTbl, p[i]);
298  /*@switchbreak@*/ break;
299  case PGPSUBTYPE_PREFER_HASH: /* preferred hash algorithms */
300  for (i = 1; i < plen; i++)
301  pgpPrtVal(" ", pgpHashTbl, p[i]);
302  /*@switchbreak@*/ break;
303  case PGPSUBTYPE_PREFER_COMPRESS:/* preferred compression algorithms */
304  for (i = 1; i < plen; i++)
305  pgpPrtVal(" ", pgpCompressionTbl, p[i]);
306  /*@switchbreak@*/ break;
307  case PGPSUBTYPE_KEYSERVER_PREFERS:/* key server preferences */
308  for (i = 1; i < plen; i++)
309  pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]);
310  /*@switchbreak@*/ break;
312 /*@-mods -mayaliasunique @*/
313  if (_digp && !(_digp->saved & PGPDIG_SAVED_TIME) &&
314  (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
315  {
316  _digp->saved |= PGPDIG_SAVED_TIME;
317  memcpy(_digp->time, p+1, sizeof(_digp->time));
318  }
319 /*@=mods =mayaliasunique @*/
320  /*@fallthrough@*/
323  if ((plen - 1) == 4) {
324  time_t t = pgpGrab(p+1, plen-1);
325  if (_pgp_print)
326  fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
327  } else
328  pgpPrtHex("", p+1, plen-1);
329  /*@switchbreak@*/ break;
330 
331  case PGPSUBTYPE_ISSUER_KEYID: /* issuer key ID */
332 /*@-mods -mayaliasunique @*/
333  if (_digp && !(_digp->saved & PGPDIG_SAVED_ID) &&
334  (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
335  {
336  _digp->saved |= PGPDIG_SAVED_ID;
337  memcpy(_digp->signid, p+1, sizeof(_digp->signid));
338  }
339 /*@=mods =mayaliasunique @*/
340  /*@fallthrough@*/
343  case PGPSUBTYPE_REGEX:
345  case PGPSUBTYPE_ARR:
347  case PGPSUBTYPE_NOTATION:
354  case PGPSUBTYPE_FEATURES:
368  default:
369  pgpPrtHex("", p+1, plen-1);
370  /*@switchbreak@*/ break;
371  }
372  pgpPrtNL();
373  p += plen;
374  hlen -= plen;
375  }
376  return 0;
377 }
378 
379 /*@-varuse =readonlytrans -nullassign @*/
380 /*@observer@*/ /*@unchecked@*/
381 static const char * pgpSigRSA[] = {
382  " m**d =",
383  NULL,
384 };
385 
386 /*@observer@*/ /*@unchecked@*/
387 static const char * pgpSigDSA[] = {
388  " r =",
389  " s =",
390  NULL,
391 };
392 /*@=varuse =readonlytrans =nullassign @*/
393 
394 static int pgpPrtSigParams(const pgpPkt pp, pgpPubkeyAlgo pubkey_algo,
395  pgpSigType sigtype, const rpmuint8_t * p)
396  /*@globals fileSystem @*/
397  /*@modifies fileSystem @*/
398 {
399  const rpmuint8_t * pend = pp->h + pp->hlen;
400  int xx;
401  int i;
402 
403  for (i = 0; p < pend; i++, p += pgpMpiLen(p)) {
404  if (pubkey_algo == PGPPUBKEYALGO_RSA) {
405  if (i >= 1) break;
406  if (_dig &&
407  (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
408  {
409  xx = 0;
410  switch (i) {
411  case 0: /* m**d */
412  xx = pgpImplMpiItem(pgpSigRSA[i], _dig, 10+i, p, pend);
413  /*@switchbreak@*/ break;
414  default:
415  xx = 1;
416  /*@switchbreak@*/ break;
417  }
418  if (xx) return xx;
419  }
420  pgpPrtStr("", pgpSigRSA[i]);
421  } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
422  if (i >= 2) break;
423  if (_dig &&
424  (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
425  {
426  xx = 0;
427  switch (i) {
428  case 0: /* r */
429  xx = pgpImplMpiItem(pgpSigDSA[i], _dig, 20+i, p, pend);
430  /*@switchbreak@*/ break;
431  case 1: /* s */
432  xx = pgpImplMpiItem(pgpSigDSA[i], _dig, 20+i, p, pend);
433  /*@switchbreak@*/ break;
434  default:
435  xx = 1;
436  /*@switchbreak@*/ break;
437  }
438  if (xx) return xx;
439  }
440  pgpPrtStr("", pgpSigDSA[i]);
441  } else {
442  if (_pgp_print)
443  fprintf(stderr, "%7d", i);
444  }
445  pgpPrtStr("", pgpMpiStr(p));
446  pgpPrtNL();
447  }
448 
449  return 0;
450 }
451 
452 int pgpPrtSig(const pgpPkt pp)
453  /*@globals _digp @*/
454  /*@modifies *_digp @*/
455 {
456  rpmuint8_t version = pp->h[0];
457  rpmuint8_t * p;
458  unsigned plen;
459  int rc;
460 
461  switch (version) {
462  case 3:
463  { pgpPktSigV3 v = (pgpPktSigV3)pp->h;
464  time_t t;
465 
466  if (v->hashlen != (rpmuint8_t)5)
467  return 1;
468 
469  pgpPrtVal("V3 ", pgpTagTbl, (rpmuint8_t)pp->tag);
470  pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
471  pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
472  pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
473  pgpPrtNL();
474  t = pgpGrab(v->time, sizeof(v->time));
475  if (_pgp_print)
476  fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
477  pgpPrtNL();
478  pgpPrtHex(" signer keyid", v->signid, sizeof(v->signid));
479  plen = pgpGrab(v->signhash16, sizeof(v->signhash16));
480  pgpPrtHex(" signhash16", v->signhash16, sizeof(v->signhash16));
481  pgpPrtNL();
482 
483  if (_digp && _digp->pubkey_algo == (rpmuint8_t)0) {
484  _digp->version = v->version;
485  _digp->hashlen = (size_t) v->hashlen;
486  _digp->sigtype = v->sigtype;
487  _digp->hash = memcpy(xmalloc(_digp->hashlen), &v->sigtype, _digp->hashlen);
488  memcpy(_digp->time, v->time, sizeof(_digp->time));
489  memcpy(_digp->signid, v->signid, sizeof(_digp->signid));
490  _digp->pubkey_algo = v->pubkey_algo;
491  _digp->hash_algo = v->hash_algo;
492  memcpy(_digp->signhash16, v->signhash16, sizeof(_digp->signhash16));
493  }
494 
495  p = ((rpmuint8_t *)v) + sizeof(*v);
497  (pgpSigType)v->sigtype, p);
498  } break;
499  case 4:
500  { pgpPktSigV4 v = (pgpPktSigV4)pp->h;
501 
502  pgpPrtVal("V4 ", pgpTagTbl, (rpmuint8_t)pp->tag);
503  pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
504  pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
505  pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
506  pgpPrtNL();
507 
508  p = &v->hashlen[0];
509  plen = pgpGrab(v->hashlen, sizeof(v->hashlen));
510  p += sizeof(v->hashlen);
511 
512  if ((p + plen) > (pp->h + pp->hlen))
513  return 1;
514 
515 if (_pgp_debug && _pgp_print)
516 fprintf(stderr, " hash[%u] -- %s\n", plen, pgpHexStr(p, plen));
517  if (_digp && _digp->pubkey_algo == (rpmuint8_t)0) {
518  _digp->hashlen = sizeof(*v) + plen;
519  _digp->hash = memcpy(xmalloc(_digp->hashlen), v, _digp->hashlen);
520  }
521  (void) pgpPrtSubType(p, plen, (pgpSigType)v->sigtype);
522  p += plen;
523 
524  plen = pgpGrab(p,2);
525  p += 2;
526 
527  if ((p + plen) > (pp->h + pp->hlen))
528  return 1;
529 
530 if (_pgp_debug && _pgp_print)
531 fprintf(stderr, " unhash[%u] -- %s\n", plen, pgpHexStr(p, plen));
532  (void) pgpPrtSubType(p, plen, (pgpSigType)v->sigtype);
533  p += plen;
534 
535  plen = pgpGrab(p,2);
536  pgpPrtHex(" signhash16", p, 2);
537  pgpPrtNL();
538 
539  if (_digp && _digp->pubkey_algo == (rpmuint8_t)0) {
540  _digp->version = v->version;
541  _digp->sigtype = v->sigtype;
542  _digp->pubkey_algo = v->pubkey_algo;
543  _digp->hash_algo = v->hash_algo;
544  memcpy(_digp->signhash16, p, sizeof(_digp->signhash16));
545  }
546 
547  p += 2;
548  if (p > (pp->h + pp->hlen))
549  return 1;
550 
552  (pgpSigType)v->sigtype, p);
553  } break;
554  default:
555  rc = 1;
556  break;
557  }
558  return rc;
559 }
560 
561 /*@-varuse =readonlytrans -nullassign @*/
562 /*@observer@*/ /*@unchecked@*/
563 static const char * pgpPublicRSA[] = {
564  " n =",
565  " e =",
566  NULL,
567 };
568 
569 #ifdef NOTYET
570 /*@observer@*/ /*@unchecked@*/
571 static const char * pgpSecretRSA[] = {
572  " d =",
573  " p =",
574  " q =",
575  " u =",
576  NULL,
577 };
578 #endif
579 
580 /*@observer@*/ /*@unchecked@*/
581 static const char * pgpPublicDSA[] = {
582  " p =",
583  " q =",
584  " g =",
585  " y =",
586  NULL,
587 };
588 
589 #ifdef NOTYET
590 /*@observer@*/ /*@unchecked@*/
591 static const char * pgpSecretDSA[] = {
592  " x =",
593  NULL,
594 };
595 #endif
596 
597 /*@observer@*/ /*@unchecked@*/
598 static const char * pgpPublicELGAMAL[] = {
599  " p =",
600  " g =",
601  " y =",
602  NULL,
603 };
604 
605 #ifdef NOTYET
606 /*@observer@*/ /*@unchecked@*/
607 static const char * pgpSecretELGAMAL[] = {
608  " x =",
609  NULL,
610 };
611 #endif
612 /*@=varuse =readonlytrans =nullassign @*/
613 
614 static const rpmuint8_t * pgpPrtPubkeyParams(const pgpPkt pp,
615  pgpPubkeyAlgo pubkey_algo, /*@returned@*/ const rpmuint8_t * p)
616  /*@globals fileSystem, internalState @*/
617  /*@modifies fileSystem, internalState @*/
618 {
619  int i;
620 
621  for (i = 0; p < &pp->h[pp->hlen]; i++, p += pgpMpiLen(p)) {
622  if (pubkey_algo == PGPPUBKEYALGO_RSA) {
623  if (i >= 2) break;
624  if (_dig) {
625  switch (i) {
626  case 0: /* n */
627  (void) pgpImplMpiItem(pgpPublicRSA[i], _dig, 30+i, p, NULL);
628  /*@switchbreak@*/ break;
629  case 1: /* e */
630  (void) pgpImplMpiItem(pgpPublicRSA[i], _dig, 30+i, p, NULL);
631  /*@switchbreak@*/ break;
632  default:
633  /*@switchbreak@*/ break;
634  }
635  }
636  pgpPrtStr("", pgpPublicRSA[i]);
637  } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
638  if (i >= 4) break;
639  if (_dig) {
640  switch (i) {
641  case 0: /* p */
642  (void) pgpImplMpiItem(pgpPublicDSA[i], _dig, 40+i, p, NULL);
643  /*@switchbreak@*/ break;
644  case 1: /* q */
645  (void) pgpImplMpiItem(pgpPublicDSA[i], _dig, 40+i, p, NULL);
646  /*@switchbreak@*/ break;
647  case 2: /* g */
648  (void) pgpImplMpiItem(pgpPublicDSA[i], _dig, 40+i, p, NULL);
649  /*@switchbreak@*/ break;
650  case 3: /* y */
651  (void) pgpImplMpiItem(pgpPublicDSA[i], _dig, 40+i, p, NULL);
652  /*@switchbreak@*/ break;
653  default:
654  /*@switchbreak@*/ break;
655  }
656  }
657  pgpPrtStr("", pgpPublicDSA[i]);
658  } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
659  if (i >= 3) break;
660  pgpPrtStr("", pgpPublicELGAMAL[i]);
661  } else {
662  if (_pgp_print)
663  fprintf(stderr, "%7d", i);
664  }
665  pgpPrtStr("", pgpMpiStr(p));
666  pgpPrtNL();
667  }
668 
669  return p;
670 }
671 
672 static const rpmuint8_t * pgpPrtSeckeyParams(const pgpPkt pp,
673  /*@unused@*/ rpmuint8_t pubkey_algo,
674  /*@returned@*/ const rpmuint8_t *p)
675  /*@globals fileSystem @*/
676  /*@modifies fileSystem @*/
677 {
678  int i;
679 
680  switch (*p) {
681  case 0:
682  pgpPrtVal(" ", pgpSymkeyTbl, *p);
683  break;
684  case 255:
685  p++;
686  pgpPrtVal(" ", pgpSymkeyTbl, *p);
687  switch (p[1]) {
688  case 0x00:
689  pgpPrtVal(" simple ", pgpHashTbl, p[2]);
690  p += 2;
691  /*@innerbreak@*/ break;
692  case 0x01:
693  pgpPrtVal(" salted ", pgpHashTbl, p[2]);
694  pgpPrtHex("", p+3, 8);
695  p += 10;
696  /*@innerbreak@*/ break;
697  case 0x03:
698  pgpPrtVal(" iterated/salted ", pgpHashTbl, p[2]);
699  i = (16 + ((unsigned)p[11] & 0xf)) << (((unsigned)p[11] >> 4U) + 6);
700  pgpPrtHex("", p+3, 8);
701  pgpPrtInt(" iter", i);
702  p += 11;
703  /*@innerbreak@*/ break;
704  }
705  break;
706  default:
707  pgpPrtVal(" ", pgpSymkeyTbl, *p);
708  pgpPrtHex(" IV", p+1, 8);
709  p += 8;
710  break;
711  }
712  pgpPrtNL();
713 
714  p++;
715 
716 #ifdef NOTYET /* XXX encrypted MPI's need to be handled. */
717  for (i = 0; p < &pp->h[pp->hlen]; i++, p += pgpMpiLen(p)) {
718  if (pubkey_algo == PGPPUBKEYALGO_RSA) {
719  if (pgpSecretRSA[i] == NULL) break;
720  pgpPrtStr("", pgpSecretRSA[i]);
721  } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
722  if (pgpSecretDSA[i] == NULL) break;
723  pgpPrtStr("", pgpSecretDSA[i]);
724  } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
725  if (pgpSecretELGAMAL[i] == NULL) break;
726  pgpPrtStr("", pgpSecretELGAMAL[i]);
727  } else {
728  if (_pgp_print)
729  fprintf(stderr, "%7d", i);
730  }
731  pgpPrtStr("", pgpMpiStr(p));
732  pgpPrtNL();
733  }
734 #else
735  pgpPrtHex(" secret", p, (pp->hlen - (p - pp->h) - 2));
736  pgpPrtNL();
737  p += (pp->hlen - (p - pp->h) - 2);
738 #endif
739  pgpPrtHex(" checksum", p, 2);
740  pgpPrtNL();
741 
742  return p;
743 }
744 
745 int pgpPrtKey(const pgpPkt pp)
746  /*@globals _digp @*/
747  /*@modifies *_digp @*/
748 {
749  rpmuint8_t version = pp->h[0];
750  const rpmuint8_t * p;
751  unsigned plen;
752  time_t t;
753  int rc;
754 
755  switch (version) {
756  case 3:
757  { pgpPktKeyV3 v = (pgpPktKeyV3)pp->h;
758  pgpPrtVal("V3 ", pgpTagTbl, (rpmuint8_t)pp->tag);
759  pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
760  t = pgpGrab(v->time, sizeof(v->time));
761  if (_pgp_print)
762  fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
763  plen = pgpGrab(v->valid, sizeof(v->valid));
764  if (plen != 0)
765  fprintf(stderr, " valid %u days", plen);
766  pgpPrtNL();
767 
768  if (_digp && _digp->tag == (rpmuint8_t)pp->tag) {
769  _digp->version = v->version;
770  memcpy(_digp->time, v->time, sizeof(_digp->time));
771  _digp->pubkey_algo = v->pubkey_algo;
772  }
773 
774  p = ((rpmuint8_t *)v) + sizeof(*v);
776  rc = 0;
777  } break;
778  case 4:
779  { pgpPktKeyV4 v = (pgpPktKeyV4)pp->h;
780  pgpPrtVal("V4 ", pgpTagTbl, (rpmuint8_t)pp->tag);
781  pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
782  t = pgpGrab(v->time, sizeof(v->time));
783  if (_pgp_print)
784  fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
785  pgpPrtNL();
786 
787  if (_digp && _digp->tag == (rpmuint8_t)pp->tag) {
788  _digp->version = v->version;
789  memcpy(_digp->time, v->time, sizeof(_digp->time));
790  _digp->pubkey_algo = v->pubkey_algo;
791  }
792 
793  p = ((rpmuint8_t *)v) + sizeof(*v);
795  if (!(pp->tag == PGPTAG_PUBLIC_KEY || pp->tag == PGPTAG_PUBLIC_SUBKEY))
796  p = pgpPrtSeckeyParams(pp, v->pubkey_algo, p);
797  rc = 0;
798  } break;
799  default:
800  rc = 1;
801  break;
802  }
803  return rc;
804 }
805 
806 int pgpPrtUserID(const pgpPkt pp)
807  /*@globals _digp @*/
808  /*@modifies *_digp @*/
809 {
810  pgpPrtVal("", pgpTagTbl, (rpmuint8_t)pp->tag);
811  if (_pgp_print)
812  fprintf(stderr, " \"%.*s\"", (int)pp->hlen, (const char *)pp->h);
813  pgpPrtNL();
814  if (_digp) {
815  char * t = memcpy(xmalloc(pp->hlen+1), pp->h, pp->hlen);
816  t[pp->hlen] = '\0';
817  _digp->userid = _free(_digp->userid);
818  _digp->userid = t;
819  }
820  return 0;
821 }
822 
823 int pgpPrtComment(const pgpPkt pp)
824 {
825  const rpmuint8_t * h = pp->h;
826  int i = pp->hlen;
827 
828  pgpPrtVal("", pgpTagTbl, (rpmuint8_t)pp->tag);
829  if (_pgp_print)
830  fprintf(stderr, " ");
831  while (i > 0) {
832  int j;
833  if (*h >= (rpmuint8_t)' ' && *h <= (rpmuint8_t)'z') {
834  j = 0;
835  while (j < i && h[j] != (rpmuint8_t)'\0')
836  j++;
837  while (j < i && h[j] == (rpmuint8_t)'\0')
838  j++;
839  if (_pgp_print && j)
840  fprintf(stderr, "%.*s", (int)strlen((const char *)h), (const char *)h);
841  } else {
842  pgpPrtHex("", h, i);
843  j = i;
844  }
845  i -= j;
846  h += j;
847  }
848  pgpPrtNL();
849  return 0;
850 }
851 
852 int pgpPktLen(const rpmuint8_t *pkt, size_t pleft, pgpPkt pp)
853 {
854  unsigned int val = (unsigned int)*pkt;
855  unsigned int plen;
856 
857  memset(pp, 0, sizeof(*pp));
858  /* XXX can't deal with these. */
859  if (!(val & 0x80))
860  return -1;
861 
862  if (val & 0x40) {
863  pp->tag = (val & 0x3f);
864  plen = pgpLen(pkt+1, &pp->hlen);
865  } else {
866  pp->tag = (val >> 2) & 0xf;
867  plen = (1 << (val & 0x3));
868  pp->hlen = pgpGrab(pkt+1, plen);
869  }
870 
871  pp->pktlen = 1 + plen + pp->hlen;
872  if (pleft > 0 && pp->pktlen > (unsigned)pleft)
873  return -1;
874 
875 /*@-assignexpose -temptrans @*/
876  pp->h = pkt + 1 + plen;
877 /*@=assignexpose =temptrans @*/
878 
879  return pp->pktlen;
880 }
881 
882 int pgpPubkeyFingerprint(const rpmuint8_t * pkt, size_t pktlen, rpmuint8_t * keyid)
883 {
884  pgpPkt pp = alloca(sizeof(*pp));
885  int rc = pgpPktLen(pkt, pktlen, pp);
886  const rpmuint8_t * se;
887  int i;
888 
889  /* Pubkeys only please. */
890  if (pp->tag != PGPTAG_PUBLIC_KEY)
891  return -1;
892 
893  /* Choose the correct keyid. */
894  switch (pp->h[0]) {
895  default: return -1;
896  case 3:
897  { pgpPktKeyV3 v = (pgpPktKeyV3) (pp->h);
898  se = (rpmuint8_t *)(v + 1);
899  switch (v->pubkey_algo) {
900  default: return -1;
901  case PGPPUBKEYALGO_RSA:
902  se += pgpMpiLen(se);
903  memmove(keyid, (se-8), 8);
904  /*@innerbreak@*/ break;
905  }
906  } break;
907  case 4:
908  { pgpPktKeyV4 v = (pgpPktKeyV4) (pp->h);
909  rpmuint8_t * d = NULL;
910  size_t dlen = 0;
911 
912  se = (rpmuint8_t *)(v + 1);
913  switch (v->pubkey_algo) {
914  default: return -1;
915  case PGPPUBKEYALGO_RSA:
916  for (i = 0; i < 2; i++)
917  se += pgpMpiLen(se);
918  /*@innerbreak@*/ break;
919  case PGPPUBKEYALGO_DSA:
920  for (i = 0; i < 4; i++)
921  se += pgpMpiLen(se);
922  /*@innerbreak@*/ break;
923  }
925  (void) rpmDigestUpdate(ctx, pkt, (se-pkt));
926  (void) rpmDigestFinal(ctx, &d, &dlen, 0);
927  }
928 
929  memmove(keyid, (d + (dlen-8)), 8);
930  d = _free(d);
931  } break;
932  }
933  rc = 0;
934  return rc;
935 }
936 
937 int pgpExtractPubkeyFingerprint(const char * b64pkt, rpmuint8_t * keyid)
938 {
939  const rpmuint8_t * pkt;
940  size_t pktlen;
941 
942  if (b64decode(b64pkt, (void **)&pkt, &pktlen))
943  return -1; /* on error */
944  (void) pgpPubkeyFingerprint(pkt, (unsigned int)pktlen, keyid);
945  pkt = _free(pkt);
946  return 8; /* no. of bytes of pubkey signid */
947 }
948 
949 int pgpPrtPkt(const rpmuint8_t * pkt, size_t pleft)
950 {
951  pgpPkt pp = alloca(sizeof(*pp));
952  int rc = pgpPktLen(pkt, pleft, pp);
953 
954  if (rc < 0)
955  return rc;
956 
957  switch (pp->tag) {
958  case PGPTAG_SIGNATURE:
959  rc = pgpPrtSig(pp);
960  break;
961  case PGPTAG_PUBLIC_KEY:
962  /* Get the public key fingerprint. */
963  if (_digp) {
964 /*@-mods@*/
965  if (!pgpPubkeyFingerprint(pkt, pp->pktlen, _digp->signid))
966  _digp->saved |= PGPDIG_SAVED_ID;
967  else
968  memset(_digp->signid, 0, sizeof(_digp->signid));
969 /*@=mods@*/
970  }
971  /*@fallthrough@*/
973  rc = pgpPrtKey(pp);
974  break;
975  case PGPTAG_SECRET_KEY:
977  rc = pgpPrtKey(pp);
978  break;
979  case PGPTAG_USER_ID:
980  rc = pgpPrtUserID(pp);
981  break;
982  case PGPTAG_COMMENT:
983  case PGPTAG_COMMENT_OLD:
984  rc = pgpPrtComment(pp);
985  break;
986 
987  case PGPTAG_RESERVED:
992  case PGPTAG_MARKER:
993  case PGPTAG_LITERAL_DATA:
994  case PGPTAG_TRUST:
995  case PGPTAG_PHOTOID:
997  case PGPTAG_MDC:
998  case PGPTAG_PRIVATE_60:
999  case PGPTAG_PRIVATE_62:
1000  case PGPTAG_CONTROL:
1001  default:
1002  pgpPrtVal("", pgpTagTbl, (rpmuint8_t)pp->tag);
1003  pgpPrtHex("", pp->h, pp->hlen);
1004  pgpPrtNL();
1005  rc = 0;
1006  break;
1007  }
1008 
1009  return (rc ? -1 : (int)pp->pktlen);
1010 }
1011 
1012 /*@unchecked@*/
1014 
1016 {
1017  if (dig != NULL) {
1018  int i;
1019  dig->signature.userid = _free(dig->signature.userid);
1020  dig->pubkey.userid = _free(dig->pubkey.userid);
1021  memset(&dig->dops, 0, sizeof(dig->dops));
1022  memset(&dig->sops, 0, sizeof(dig->sops));
1023  dig->ppkts = _free(dig->ppkts);
1024  dig->npkts = 0;
1025  dig->signature.hash = _free(dig->signature.hash);
1026  dig->pubkey.hash = _free(dig->pubkey.hash);
1027  /*@-unqualifiedtrans@*/ /* FIX: double indirection */
1028  for (i = 0; i < 4; i++) {
1029  dig->signature.params[i] = _free(dig->signature.params[i]);
1030  dig->pubkey.params[i] = _free(dig->pubkey.params[i]);
1031  }
1032  /*@=unqualifiedtrans@*/
1033 
1034  memset(&dig->signature, 0, sizeof(dig->signature));
1035  memset(&dig->pubkey, 0, sizeof(dig->pubkey));
1036 
1037  dig->md5 = _free(dig->md5);
1038  dig->sha1 = _free(dig->sha1);
1039 
1040  pgpImplClean(dig->impl);
1041 
1042  }
1043 /*@-nullstate@*/
1044  return;
1045 /*@=nullstate@*/
1046 }
1047 
1048 static void pgpDigFini(void * __dig)
1049  /*@globals fileSystem, internalState @*/
1050  /*@modifies __dig, fileSystem, internalState @*/
1051 {
1052  pgpDig dig = __dig;
1053 
1054  /* Lose the header tag data. */
1055  /* XXX this free should be done somewhere else. */
1056  dig->sig = _free(dig->sig);
1057 
1058  /* XXX there's a recursion here ... release and reacquire the lock */
1059 #ifndef BUGGY
1060  yarnRelease(dig->_item.use);
1061 #endif
1062  /* Dump the signature/pubkey data. */
1063  pgpDigClean(dig);
1064 #ifndef BUGGY
1065  yarnPossess(dig->_item.use);
1066 #endif
1067 
1068  if (dig->hdrsha1ctx != NULL)
1069  (void) rpmDigestFinal(dig->hdrsha1ctx, NULL, NULL, 0);
1070  dig->hdrsha1ctx = NULL;
1071 
1072  if (dig->sha1ctx != NULL)
1073  (void) rpmDigestFinal(dig->sha1ctx, NULL, NULL, 0);
1074  dig->sha1ctx = NULL;
1075 
1076 #ifdef NOTYET
1077  if (dig->hdrmd5ctx != NULL)
1078  (void) rpmDigestFinal(dig->hdrmd5ctx, NULL, NULL, 0);
1079  dig->hdrmd5ctx = NULL;
1080 #endif
1081 
1082  if (dig->md5ctx != NULL)
1083  (void) rpmDigestFinal(dig->md5ctx, NULL, NULL, 0);
1084  dig->md5ctx = NULL;
1085 
1086  dig->impl = pgpImplFree(dig->impl);
1087 
1088 }
1089 
1090 /*@unchecked@*/ /*@only@*/ /*@null@*/
1092 
1093 static pgpDig digGetPool(/*@null@*/ rpmioPool pool)
1094  /*@globals _digPool, fileSystem @*/
1095  /*@modifies pool, _digPool, fileSystem @*/
1096 {
1097  pgpDig dig;
1098 
1099  if (_digPool == NULL) {
1100  _digPool = rpmioNewPool("dig", sizeof(*dig), -1, _pgp_debug,
1101  NULL, NULL, pgpDigFini);
1102  pool = _digPool;
1103  }
1104  return (pgpDig) rpmioGetPool(pool, sizeof(*dig));
1105 }
1106 
1108 {
1109  pgpDig dig = digGetPool(_digPool);
1110  dig->vsflags = pgpDigVSFlags;
1111  dig->impl = pgpImplInit();
1112  return pgpDigLink(dig, "pgpDigNew");
1113 }
1114 
1116 {
1117  return (dig ? &dig->signature : NULL);
1118 }
1119 
1121 {
1122  return (dig ? &dig->pubkey : NULL);
1123 }
1124 
1126 {
1127  return (dig ? dig->sigtag : 0);
1128 }
1129 
1131 {
1132  return (dig ? dig->sigtype : 0);
1133 }
1134 
1135 const void * pgpGetSig(pgpDig dig)
1136 {
1137  return (dig ? dig->sig : NULL);
1138 }
1139 
1141 {
1142  return (dig ? dig->siglen : 0);
1143 }
1144 
1146  rpmuint32_t sigtag, rpmuint32_t sigtype, const void * sig, rpmuint32_t siglen)
1147 {
1148  if (dig != NULL) {
1149  dig->sigtag = sigtag;
1150  dig->sigtype = (sig ? sigtype : 0);
1151 /*@-assignexpose -kepttrans@*/
1152  dig->sig = sig;
1153 /*@=assignexpose =kepttrans@*/
1154  dig->siglen = siglen;
1155  }
1156  return 0;
1157 }
1158 
1159 void * pgpStatsAccumulator(pgpDig dig, int opx)
1160 {
1161  void * sw = NULL;
1162  switch (opx) {
1163  case 10: /* RPMTS_OP_DIGEST */
1164  sw = &dig->dops;
1165  break;
1166  case 11: /* RPMTS_OP_SIGNATURE */
1167  sw = &dig->sops;
1168  break;
1169  }
1170  return sw;
1171 }
1172 
1174  int (*findPubkey) (void *ts, /*@null@*/ void *dig), void * _ts)
1175 {
1176  if (dig) {
1177 /*@-assignexpose@*/
1178  dig->findPubkey = findPubkey;
1179 /*@=assignexpose@*/
1180 /*@-dependenttrans@*/
1181  dig->_ts = _ts;
1182 /*@=dependenttrans@*/
1183  }
1184  return 0;
1185 }
1186 
1188 {
1189  int rc = 1; /* XXX RPMRC_NOTFOUND */
1190  if (dig && dig->findPubkey && dig->_ts)
1191  rc = (*dig->findPubkey) (dig->_ts, dig);
1192  return rc;
1193 }
1194 
1195 static int pgpGrabPkts(const rpmuint8_t * pkts, size_t pktlen,
1196  /*@out@*/ rpmuint8_t *** pppkts, /*@out@*/ int * pnpkts)
1197  /*@modifies *pppkts, *pnpkts @*/
1198 {
1199  pgpPkt pp = alloca(sizeof(*pp));
1200  const rpmuint8_t * p;
1201  size_t pleft;
1202  size_t len;
1203  int npkts = 0;
1204  rpmuint8_t ** ppkts;
1205 
1206  for (p = pkts, pleft = pktlen; p < (pkts + pktlen); p += len, pleft -= len) {
1207  if (pgpPktLen(p, pleft, pp) < 0)
1208  return -1;
1209  len = pp->pktlen;
1210  npkts++;
1211  }
1212  if (npkts <= 0)
1213  return -2;
1214 
1215  ppkts = xcalloc(npkts, sizeof(*ppkts));
1216 
1217  npkts = 0;
1218  for (p = pkts, pleft = pktlen; p < (pkts + pktlen); p += len, pleft -= len) {
1219 
1220  if (pgpPktLen(p, pleft, pp) < 0)
1221  return -1;
1222  len = pp->pktlen;
1223  ppkts[npkts++] = (rpmuint8_t *) p;
1224  }
1225 
1226  if (pppkts != NULL)
1227  *pppkts = ppkts;
1228  else
1229  ppkts = _free(ppkts);
1230 
1231  if (pnpkts != NULL)
1232  *pnpkts = npkts;
1233 
1234  return 0;
1235 }
1236 
1237 /*@-globstate -incondefs -nullderef @*/ /* _dig annotations are not correct. */
1238 int pgpPrtPkts(const rpmuint8_t * pkts, size_t pktlen, pgpDig dig, int printing)
1239  /*@globals _dig, _digp, _pgp_print @*/
1240  /*@modifies _dig, _digp, *_digp, _pgp_print @*/
1241 {
1242  pgpPkt pp = alloca(sizeof(*pp));
1243  unsigned int val = (unsigned int)*pkts;
1244  size_t pleft;
1245  int len;
1246  rpmuint8_t ** ppkts = NULL;
1247  int npkts;
1248  int i;
1249 
1250  _pgp_print = printing;
1251  _dig = pgpDigLink(dig, "pgpPrtPkts");
1252  if (dig != NULL && (val & 0x80)) {
1253  pgpTag tag = (val & 0x40) ? (val & 0x3f) : ((val >> 2) & 0xf);
1254  _digp = (tag == PGPTAG_SIGNATURE) ? &_dig->signature : &_dig->pubkey;
1255  _digp->tag = (rpmuint8_t)tag;
1256  } else
1257  _digp = NULL;
1258 
1259  if (pgpGrabPkts(pkts, pktlen, &ppkts, &npkts) || ppkts == NULL) {
1260  _dig = pgpDigFree(_dig, "pgpPrtPkts");
1261  return -1;
1262  }
1263 
1264  if (ppkts != NULL)
1265  for (i = 0, pleft = pktlen; i < npkts; i++, pleft -= len) {
1266  len = pgpPktLen(ppkts[i], pleft, pp);
1267  len = pgpPrtPkt(ppkts[i], pp->pktlen);
1268  }
1269 
1270  if (dig != NULL) {
1271  dig->ppkts = _free(dig->ppkts); /* XXX memory leak plugged. */
1272  dig->ppkts = ppkts;
1273  dig->npkts = npkts;
1274  } else
1275  ppkts = _free(ppkts);
1276 
1277  _dig = pgpDigFree(_dig, "pgpPrtPkts");
1278  return 0;
1279 }
1280 /*@=globstate =incondefs =nullderef @*/
1281 
1282 pgpArmor pgpReadPkts(const char * fn, rpmuint8_t ** pkt, size_t * pktlen)
1283 {
1284  rpmiob iob = NULL;
1285  const char * enc = NULL;
1286  const char * crcenc = NULL;
1287  rpmuint8_t * dec;
1288  rpmuint8_t * crcdec;
1289  size_t declen;
1290  size_t crclen;
1291  rpmuint32_t crcpkt, crc;
1292  const char * armortype = NULL;
1293  char * t, * te;
1294  int pstate = 0;
1295  pgpArmor ec = PGPARMOR_ERR_NO_BEGIN_PGP; /* XXX assume failure */
1296  pgpTag tag = 0;
1297  int rc;
1298 
1299  rc = rpmiobSlurp(fn, &iob);
1300  if (rc || iob == NULL)
1301  goto exit;
1302 
1303  /* Read unarmored packets. */
1304  if (pgpIsPkt(iob->b, &tag)) {
1305  switch (tag) {
1306  default: ec = PGPARMOR_NONE; break;
1307  case PGPTAG_PUBLIC_KEY: ec = PGPARMOR_PUBKEY; break;
1308  case PGPTAG_SIGNATURE: ec = PGPARMOR_SIGNATURE; break;
1309 #ifdef NOTYET
1310  case PGPTAG_SECRET_KEY: ec = PGPARMOR_SECKEY; break;
1311  case PGPTAG_FOO: ec = PGPARMOR_MESSAGE; break;
1312  case PGPTAG_FOO: ec = PGPARMOR_SIGNED_MESSAGE; break;
1313  case PGPTAG_FOO: ec = PGPARMOR_FILE; break;
1314  case PGPTAG_FOO: ec = PGPARMOR_PRIVKEY; break;
1315 #endif
1316  }
1317  /* Truncate blen to actual no. of octets in packet. */
1318  if (ec != PGPARMOR_NONE) {
1319  pgpPkt pp = alloca(sizeof(*pp));
1320  iob->blen = pgpPktLen(iob->b, iob->blen, pp);
1321  }
1322  goto exit;
1323  }
1324 
1325 #define TOKEQ(_s, _tok) (!strncmp((_s), (_tok), sizeof(_tok)-1))
1326 
1327  /* Read armored packets, converting to binary. */
1328  for (t = (char *)iob->b; t && *t; t = te) {
1329  if ((te = strchr(t, '\n')) == NULL)
1330  te = t + strlen(t);
1331  else
1332  te++;
1333 
1334  switch (pstate) {
1335  case 0:
1336  armortype = NULL;
1337  if (!TOKEQ(t, "-----BEGIN PGP "))
1338  continue;
1339  t += sizeof("-----BEGIN PGP ")-1;
1340 
1341  rc = pgpValTok(pgpArmorTbl, t, te);
1342  if (rc < 0) {
1344  goto exit;
1345  }
1346  /* XXX Ignore clear signed message start. */
1347  if (rc == PGPARMOR_SIGNED_MESSAGE)
1348  continue;
1349  ec = rc; /* Save the packet type as exit code. */
1350  armortype = t;
1351 
1352  t = strchr(t, '\n');
1353  if (t == NULL)
1354  continue;
1355  if (t[-1] == '\r')
1356  --t;
1357  t -= (sizeof("-----")-1);
1358  if (!TOKEQ(t, "-----"))
1359  continue;
1360  *t = '\0';
1361  pstate++;
1362  /*@switchbreak@*/ break;
1363  case 1:
1364  enc = NULL;
1365  rc = pgpValTok(pgpArmorKeyTbl, t, te);
1366  if (rc >= 0)
1367  continue;
1368  if (!(*t == '\n' || *t == '\r')) {
1369  pstate = 0;
1370  continue;
1371  }
1372  enc = te; /* Start of encoded packets */
1373  pstate++;
1374  /*@switchbreak@*/ break;
1375  case 2:
1376  crcenc = NULL;
1377  if (*t != '=')
1378  continue;
1379  *t++ = '\0'; /* Terminate encoded packets */
1380  crcenc = t; /* Start of encoded crc */
1381  pstate++;
1382  /*@switchbreak@*/ break;
1383  case 3:
1384  pstate = 0;
1385  if (!TOKEQ(t, "-----END PGP ")) {
1387  goto exit;
1388  }
1389  *t = '\0'; /* Terminate encoded crc */
1390  t += sizeof("-----END PGP ")-1;
1391  if (t >= te) continue;
1392 
1393  if (armortype == NULL) /* XXX can't happen */
1394  continue;
1395  rc = strncmp(t, armortype, strlen(armortype));
1396  if (rc)
1397  continue;
1398 
1399  t += strlen(armortype);
1400  if (t >= te) continue;
1401 
1402  if (!TOKEQ(t, "-----")) {
1404  goto exit;
1405  }
1406  t += (sizeof("-----")-1);
1407  if (t >= te) continue;
1408  /* XXX permitting \r here is not RFC-2440 compliant <shrug> */
1409  if (!(*t == '\n' || *t == '\r')) continue;
1410 
1411  crcdec = NULL;
1412  crclen = 0;
1413  if (b64decode(crcenc, (void **)&crcdec, &crclen) != 0) {
1415  goto exit;
1416  }
1417  crcpkt = pgpGrab(crcdec, crclen);
1418  crcdec = _free(crcdec);
1419  dec = NULL;
1420  declen = 0;
1421  if (b64decode(enc, (void **)&dec, &declen) != 0) {
1423  goto exit;
1424  }
1425  crc = pgpCRC(dec, declen);
1426  if (crcpkt != crc) {
1428  goto exit;
1429  }
1430  iob->b = _free(iob->b);
1431  iob->b = dec;
1432  iob->blen = declen;
1433  goto exit;
1434  /*@notreached@*/ /*@switchbreak@*/ break;
1435  }
1436  }
1437  ec = PGPARMOR_NONE;
1438 
1439 exit:
1440  if (ec > PGPARMOR_NONE) {
1441  if (pkt) *pkt = iob->b;
1442  if (pktlen) *pktlen = iob->blen;
1443  iob->b = NULL; /* XXX iob->b has been stolen */
1444  } else {
1445  if (pkt) *pkt = NULL;
1446  if (pktlen) *pktlen = 0;
1447  }
1448  iob = rpmiobFree(iob);
1449  return ec;
1450 }
1451 
1452 char * pgpArmorWrap(rpmuint8_t atype, const unsigned char * s, size_t ns)
1453 {
1454  const char * enc;
1455  char * t;
1456  size_t nt;
1457  char * val;
1458  int lc;
1459 
1460  nt = ((ns + 2) / 3) * 4;
1461  /*@-globs@*/
1462  /* Add additional bytes necessary for eol string(s). */
1463  if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
1464  lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
1465  if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
1466  ++lc;
1467  nt += lc * strlen(b64encode_eolstr);
1468  }
1469  /*@=globs@*/
1470 
1471  nt += 512; /* XXX slop for armor and crc */
1472 
1473  val = t = xmalloc(nt + 1);
1474  *t = '\0';
1475  t = stpcpy(t, "-----BEGIN PGP ");
1476  t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
1477  /*@-globs@*/
1478  t = stpcpy( stpcpy(t, "-----\nVersion: RPM "), VERSION);
1479  /*@=globs@*/
1480  t = stpcpy(t, " (BeeCrypt)\n\n");
1481 
1482  if ((enc = b64encode(s, ns)) != NULL) {
1483  t = stpcpy(t, enc);
1484  enc = _free(enc);
1485  if ((enc = b64crc(s, ns)) != NULL) {
1486  *t++ = '=';
1487  t = stpcpy(t, enc);
1488  enc = _free(enc);
1489  }
1490  }
1491 
1492  t = stpcpy(t, "-----END PGP ");
1493  t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
1494  t = stpcpy(t, "-----\n");
1495 
1496 /*@-globstate@*/ /* XXX b64encode_eolstr needs annotation. */
1497  return val;
1498 /*@=globstate@*/
1499 }
1500 
1501 pgpHashAlgo pgpHashAlgoStringToNumber(const char *name, size_t name_len)
1502 {
1503  size_t i;
1504 
1505  if (name == NULL)
1506  return -1;
1507  if (name_len == 0)
1508  name_len = strlen(name);
1509  for (i = 0; i < sizeof(pgpHashTbl)/sizeof(pgpHashTbl[0]); i++)
1510  if (xstrncasecmp(name, pgpHashTbl[i].str, name_len) == 0)
1511  return pgpHashTbl[i].val;
1512  return PGPHASHALGO_ERROR;
1513 }
1514