rpm  4.5
rpmpgp.c
Go to the documentation of this file.
1 /*@-boundsread@*/
7 #include "system.h"
8 #include "rpmio_internal.h"
9 #include "debug.h"
10 
11 /*@access pgpDig @*/
12 /*@access pgpDigParams @*/
13 /*@access pgpPkt @*/
14 
15 /*@unchecked@*/
16 static int _debug = 0;
17 
18 /*@unchecked@*/
19 static int _print = 0;
20 
21 /*@unchecked@*/ /*@null@*/
22 static pgpDig _dig = NULL;
23 
24 /*@unchecked@*/ /*@null@*/
25 static pgpDigParams _digp = NULL;
26 
27 #ifdef DYING
28 /* This is the unarmored RPM-GPG-KEY public key. */
29 const char * redhatPubKeyDSA = "\
30 mQGiBDfqVDgRBADBKr3Bl6PO8BQ0H8sJoD6p9U7Yyl7pjtZqioviPwXP+DCWd4u8\n\
31 HQzcxAZ57m8ssA1LK1Fx93coJhDzM130+p5BG9mYSWShLabR3N1KXdXQYYcowTOM\n\
32 GxdwYRGr1Spw8QydLhjVfU1VSl4xt6bupPbWJbyjkg5Z3P7BlUOUJmrx3wCgobNV\n\
33 EDGaWYJcch5z5B1of/41G8kEAKii6q7Gu/vhXXnLS6m15oNnPVybyngiw/23dKjS\n\
34 ZVG7rKANEK2mxg1VB+vc/uUc4k49UxJJfCZg1gu1sPFV3GSa+Y/7jsiLktQvCiLP\n\
35 lncQt1dV+ENmHR5BdIDPWDzKBVbgWnSDnqQ6KrZ7T6AlZ74VMpjGxxkWU6vV2xsW\n\
36 XCLPA/9P/vtImA8CZN3jxGgtK5GGtDNJ/cMhhuv5tnfwFg4b/VGo2Jr8mhLUqoIb\n\
37 E6zeGAmZbUpdckDco8D5fiFmqTf5+++pCEpJLJkkzel/32N2w4qzPrcRMCiBURES\n\
38 PjCLd4Y5rPoU8E4kOHc/4BuHN903tiCsCPloCrWsQZ7UdxfQ5LQiUmVkIEhhdCwg\n\
39 SW5jIDxzZWN1cml0eUByZWRoYXQuY29tPohVBBMRAgAVBQI36lQ4AwsKAwMVAwID\n\
40 FgIBAheAAAoJECGRgM3bQqYOsBQAnRVtg7B25Hm11PHcpa8FpeddKiq2AJ9aO8sB\n\
41 XmLDmPOEFI75mpTrKYHF6rkCDQQ36lRyEAgAokgI2xJ+3bZsk8jRA8ORIX8DH05U\n\
42 lMH27qFYzLbT6npXwXYIOtVn0K2/iMDj+oEB1Aa2au4OnddYaLWp06v3d+XyS0t+\n\
43 5ab2ZfIQzdh7wCwxqRkzR+/H5TLYbMG+hvtTdylfqIX0WEfoOXMtWEGSVwyUsnM3\n\
44 Jy3LOi48rQQSCKtCAUdV20FoIGWhwnb/gHU1BnmES6UdQujFBE6EANqPhp0coYoI\n\
45 hHJ2oIO8ujQItvvNaU88j/s/izQv5e7MXOgVSjKe/WX3s2JtB/tW7utpy12wh1J+\n\
46 JsFdbLV/t8CozUTpJgx5mVA3RKlxjTA+On+1IEUWioB+iVfT7Ov/0kcAzwADBQf9\n\
47 E4SKCWRand8K0XloMYgmipxMhJNnWDMLkokvbMNTUoNpSfRoQJ9EheXDxwMpTPwK\n\
48 ti/PYrrL2J11P2ed0x7zm8v3gLrY0cue1iSba+8glY+p31ZPOr5ogaJw7ZARgoS8\n\
49 BwjyRymXQp+8Dete0TELKOL2/itDOPGHW07SsVWOR6cmX4VlRRcWB5KejaNvdrE5\n\
50 4XFtOd04NMgWI63uqZc4zkRa+kwEZtmbz3tHSdRCCE+Y7YVP6IUf/w6YPQFQriWY\n\
51 FiA6fD10eB+BlIUqIw80VgjsBKmCwvKkn4jg8kibXgj4/TzQSx77uYokw1EqQ2wk\n\
52 OZoaEtcubsNMquuLCMWijYhGBBgRAgAGBQI36lRyAAoJECGRgM3bQqYOhyYAnj7h\n\
53 VDY/FJAGqmtZpwVp9IlitW5tAJ4xQApr/jNFZCTksnI+4O1765F7tA==\n\
54 ";
55 
56 /* This is the unarmored RPM-PGP-KEY public key. */
57 const char * redhatPubKeyRSA = "\
58 mQCNAzEpXjUAAAEEAKG4/V9oUSiDc9wIge6Bmg6erDGCLzmFyioAho8kDIJSrcmi\n\
59 F9qTdPq+fj726pgW1iSb0Y7syZn9Y2lgQm5HkPODfNi8eWyTFSxbr8ygosLRClTP\n\
60 xqHVhtInGrfZNLoSpv1LdWOme0yOpOQJnghdOMzKXpgf5g84vaUg6PHLopv5AAUR\n\
61 tCpSZWQgSGF0IFNvZnR3YXJlLCBJbmMuIDxyZWRoYXRAcmVkaGF0LmNvbT6JAJUD\n\
62 BRAyA5tUoyDApfg4JKEBAUzSA/9QdcVsu955vVyZDk8uvOXWV0X3voT9B3aYMFvj\n\
63 UNHUD6F1VFruwQHVKbGJEq1o5MOA6OXKR3vJZStXEMF47TWXJfQaflgl8ywZTH5W\n\
64 +eMlKau6Nr0labUV3lmsAE4Vsgu8NCkzIrp2wNVbeW2ZAXtrKswV+refLquUhp7l\n\
65 wMpH9IkAdQMFEDGttkRNdXhbO1TgGQEBAGoC/j6C22PqXIyqZc6fG6J6Jl/T5kFG\n\
66 xH1pKIzua5WCDDugAgnuOJgywa4pegT4UqwEZiMTAlwT6dmG1CXgKB+5V7lnCjDc\n\
67 JZLni0iztoe08ig6fJrjNGXljf7KYXzgwBftQokAlQMFEDMQzo2MRVM9rfPulQEB\n\
68 pLoD/1/MWv3u0Paiu14XRvDrBaJ7BmG2/48bA5vKOzpvvoNRO95YS7ZEtqErXA7Y\n\
69 DRO8+C8f6PAILMk7kCk4lNMscS/ZRzu5+J8cv4ejsFvxgJBBU3Zgp8AWdWOpvZ0I\n\
70 wW//HoDUGhOxlEtymljIMFBkj4SysHWhCBUfA9Xy86kouTJQiQCVAwUQMxDOQ50a\n\
71 feTWLUSJAQFnYQQAkt9nhMTeioREB1DvJt+vsFyOj//o3ThqK5ySEP3dgj62iaQp\n\
72 JrBmAe5XZPw25C/TXAf+x27H8h2QbKgq49VtsElFexc6wO+uq85fAPDdyE+2XyNE\n\
73 njGZkY/TP2F/jTB0sAwJO+xFCHmSYkcBjzxK/2LMD+O7rwp2UCUhhl9QhhqJAJUD\n\
74 BRAx5na6pSDo8cuim/kBARmjA/4lDVnV2h9KiNabp9oE38wmGgu5m5XgUHW8L6du\n\
75 iQDnwO5IgXN2vDpKGxbgtwv6iYYmGd8IRQ66uJvOsxSv3OR7J7LkCHuI2b/s0AZn\n\
76 c79DZaJ2ChUCZlbNQBMeEdrFWif9NopY+d5+2tby1onu9XOFMMvomxL3NhctElYR\n\
77 HC8Xw4kAlQMFEDHmdTtURTdEKY1MpQEBEtEEAMZbp1ZFrjiHkj2aLFC1S8dGRbSH\n\
78 GUdnLP9qLPFgmWekp9E0o8ZztALGVdqPfPF3N/JJ+AL4IMrfojd7+eZKw36Mdvtg\n\
79 dPI+Oz4sxHDbDynZ2qspD9Om5yYuxuz/Xq+9nO2IlsAnEYw3ag3cxat0kvxpOPRe\n\
80 Yy+vFpgfDNizr3MgiQBVAwUQMXNMXCjtrosVMemRAQEDnwH7BsJrnnh91nI54LAK\n\
81 Gcq3pr8ld0PAtWJmNRGQvUlpEMXUSnu59j2P1ogPNjL3PqKdVxk5Jqgcr8TPQMf3\n\
82 V4fqXokAlQMFEDFy+8YiEmsRQ3LyzQEB+TwD/03QDslXLg5F3zj4zf0yI6ikT0be\n\
83 5OhZv2pnkb80qgdHzFRxBOYmSoueRKdQJASd8F9ue4b3bmf/Y7ikiY0DblvxcXB2\n\
84 sz1Pu8i2Zn9u8SKuxNIoVvM8/STRVkgPfvL5QjAWMHT9Wvg81XcI2yXJzrt/2f2g\n\
85 mNpWIvVOOT85rVPIiQCVAwUQMVPRlBlzviMjNHElAQG1nwP/fpVX6nKRWJCSFeB7\n\
86 leZ4lb+y1uMsMVv0n7agjJVw13SXaA267y7VWCBlnhsCemxEugqEIkI4lu/1mgtw\n\
87 WPWSE0BOIVjj0AA8zp2T0H3ZCCMbiFAFJ1P2Gq2rKr8QrOb/08oH1lEzyz0j/jKh\n\
88 qiXAxdlB1wojQB6yLbHvTIe3rZGJAHUDBRAxKetfzauiKSJ6LJEBAed/AvsEiGgj\n\
89 TQzhsZcUuRNrQpV0cDGH9Mpril7P7K7yFIzju8biB+Cu6nEknSOHlMLl8usObVlk\n\
90 d8Wf14soHC7SjItiGSKtI8JhauzBJPl6fDDeyHGsJKo9f9adKeBMCipCFOuJAJUD\n\
91 BRAxKeqWRHFTaIK/x+0BAY6eA/4m5X4gs1UwOUIRnljo9a0cVs6ITL554J9vSCYH\n\
92 Zzd87kFwdf5W1Vd82HIkRzcr6cp33E3IDkRzaQCMVw2me7HePP7+4Ry2q3EeZMbm\n\
93 NE++VzkxjikzpRb2+F5nGB2UdsElkgbXinswebiuOwOrocLbz6JFdDsJPcT5gVfi\n\
94 z15FuA==\n\
95 ";
96 #endif /* DYING */
97 
98 struct pgpPkt_s {
100  unsigned int pktlen;
101  const byte *h;
102  unsigned int hlen;
103 };
104 
106  { PGPSIGTYPE_BINARY, "Binary document signature" },
107  { PGPSIGTYPE_TEXT, "Text document signature" },
108  { PGPSIGTYPE_STANDALONE, "Standalone signature" },
109  { PGPSIGTYPE_GENERIC_CERT, "Generic certification of a User ID and Public Key" },
110  { PGPSIGTYPE_PERSONA_CERT, "Personal certification of a User ID and Public Key" },
111  { PGPSIGTYPE_CASUAL_CERT, "Casual certification of a User ID and Public Key" },
112  { PGPSIGTYPE_POSITIVE_CERT, "Positive certification of a User ID and Public Key" },
113  { PGPSIGTYPE_SUBKEY_BINDING,"Subkey Binding Signature" },
114  { PGPSIGTYPE_SIGNED_KEY, "Signature directly on a key" },
115  { PGPSIGTYPE_KEY_REVOKE, "Key revocation signature" },
116  { PGPSIGTYPE_SUBKEY_REVOKE, "Subkey revocation signature" },
117  { PGPSIGTYPE_CERT_REVOKE, "Certification revocation signature" },
118  { PGPSIGTYPE_TIMESTAMP, "Timestamp signature" },
119  { -1, "Unknown signature type" },
120 };
121 
123  { PGPPUBKEYALGO_RSA, "RSA" },
124  { PGPPUBKEYALGO_RSA_ENCRYPT,"RSA(Encrypt-Only)" },
125  { PGPPUBKEYALGO_RSA_SIGN, "RSA(Sign-Only)" },
126  { PGPPUBKEYALGO_ELGAMAL_ENCRYPT,"Elgamal(Encrypt-Only)" },
127  { PGPPUBKEYALGO_DSA, "DSA" },
128  { PGPPUBKEYALGO_EC, "Elliptic Curve" },
129  { PGPPUBKEYALGO_ECDSA, "ECDSA" },
130  { PGPPUBKEYALGO_ELGAMAL, "Elgamal" },
131  { PGPPUBKEYALGO_DH, "Diffie-Hellman (X9.42)" },
132  { -1, "Unknown public key algorithm" },
133 };
134 
136  { PGPSYMKEYALGO_PLAINTEXT, "Plaintext" },
137  { PGPSYMKEYALGO_IDEA, "IDEA" },
138  { PGPSYMKEYALGO_TRIPLE_DES, "3DES" },
139  { PGPSYMKEYALGO_CAST5, "CAST5" },
140  { PGPSYMKEYALGO_BLOWFISH, "BLOWFISH" },
141  { PGPSYMKEYALGO_SAFER, "SAFER" },
142  { PGPSYMKEYALGO_DES_SK, "DES/SK" },
143  { PGPSYMKEYALGO_AES_128, "AES(128-bit key)" },
144  { PGPSYMKEYALGO_AES_192, "AES(192-bit key)" },
145  { PGPSYMKEYALGO_AES_256, "AES(256-bit key)" },
146  { PGPSYMKEYALGO_TWOFISH, "TWOFISH(256-bit key)" },
147  { PGPSYMKEYALGO_NOENCRYPT, "no encryption" },
148  { -1, "Unknown symmetric key algorithm" },
149 };
150 
152  { PGPCOMPRESSALGO_NONE, "Uncompressed" },
153  { PGPCOMPRESSALGO_ZIP, "ZIP" },
154  { PGPCOMPRESSALGO_ZLIB, "ZLIB" },
155  { PGPCOMPRESSALGO_BZIP2, "BZIP2" },
156  { -1, "Unknown compression algorithm" },
157 };
158 
160  { PGPHASHALGO_MD5, "MD5" },
161  { PGPHASHALGO_SHA1, "SHA1" },
162  { PGPHASHALGO_RIPEMD160, "RIPEMD160" },
163  { PGPHASHALGO_MD2, "MD2" },
164  { PGPHASHALGO_TIGER192, "TIGER192" },
165  { PGPHASHALGO_HAVAL_5_160, "HAVAL-5-160" },
166  { PGPHASHALGO_SHA256, "SHA256" },
167  { PGPHASHALGO_SHA384, "SHA384" },
168  { PGPHASHALGO_SHA512, "SHA512" },
169  { -1, "Unknown hash algorithm" },
170 };
171 
172 /*@-exportlocal -exportheadervar@*/
173 /*@observer@*/ /*@unchecked@*/
175  { 0x80, "No-modify" },
176  { -1, "Unknown key server preference" },
177 };
178 /*@=exportlocal =exportheadervar@*/
179 
181  { PGPSUBTYPE_SIG_CREATE_TIME,"signature creation time" },
182  { PGPSUBTYPE_SIG_EXPIRE_TIME,"signature expiration time" },
183  { PGPSUBTYPE_EXPORTABLE_CERT,"exportable certification" },
184  { PGPSUBTYPE_TRUST_SIG, "trust signature" },
185  { PGPSUBTYPE_REGEX, "regular expression" },
186  { PGPSUBTYPE_REVOCABLE, "revocable" },
187  { PGPSUBTYPE_KEY_EXPIRE_TIME,"key expiration time" },
188  { PGPSUBTYPE_ARR, "additional recipient request" },
189  { PGPSUBTYPE_PREFER_SYMKEY, "preferred symmetric algorithms" },
190  { PGPSUBTYPE_REVOKE_KEY, "revocation key" },
191  { PGPSUBTYPE_ISSUER_KEYID, "issuer key ID" },
192  { PGPSUBTYPE_NOTATION, "notation data" },
193  { PGPSUBTYPE_PREFER_HASH, "preferred hash algorithms" },
194  { PGPSUBTYPE_PREFER_COMPRESS,"preferred compression algorithms" },
195  { PGPSUBTYPE_KEYSERVER_PREFERS,"key server preferences" },
196  { PGPSUBTYPE_PREFER_KEYSERVER,"preferred key server" },
197  { PGPSUBTYPE_PRIMARY_USERID,"primary user id" },
198  { PGPSUBTYPE_POLICY_URL, "policy URL" },
199  { PGPSUBTYPE_KEY_FLAGS, "key flags" },
200  { PGPSUBTYPE_SIGNER_USERID, "signer's user id" },
201  { PGPSUBTYPE_REVOKE_REASON, "reason for revocation" },
202  { PGPSUBTYPE_FEATURES, "features" },
203  { PGPSUBTYPE_EMBEDDED_SIG, "embedded signature" },
204 
205  { PGPSUBTYPE_INTERNAL_100, "internal subpkt type 100" },
206  { PGPSUBTYPE_INTERNAL_101, "internal subpkt type 101" },
207  { PGPSUBTYPE_INTERNAL_102, "internal subpkt type 102" },
208  { PGPSUBTYPE_INTERNAL_103, "internal subpkt type 103" },
209  { PGPSUBTYPE_INTERNAL_104, "internal subpkt type 104" },
210  { PGPSUBTYPE_INTERNAL_105, "internal subpkt type 105" },
211  { PGPSUBTYPE_INTERNAL_106, "internal subpkt type 106" },
212  { PGPSUBTYPE_INTERNAL_107, "internal subpkt type 107" },
213  { PGPSUBTYPE_INTERNAL_108, "internal subpkt type 108" },
214  { PGPSUBTYPE_INTERNAL_109, "internal subpkt type 109" },
215  { PGPSUBTYPE_INTERNAL_110, "internal subpkt type 110" },
216  { -1, "Unknown signature subkey type" },
217 };
218 
219 struct pgpValTbl_s pgpTagTbl[] = {
220  { PGPTAG_PUBLIC_SESSION_KEY,"Public-Key Encrypted Session Key" },
221  { PGPTAG_SIGNATURE, "Signature" },
222  { PGPTAG_SYMMETRIC_SESSION_KEY,"Symmetric-Key Encrypted Session Key" },
223  { PGPTAG_ONEPASS_SIGNATURE, "One-Pass Signature" },
224  { PGPTAG_SECRET_KEY, "Secret Key" },
225  { PGPTAG_PUBLIC_KEY, "Public Key" },
226  { PGPTAG_SECRET_SUBKEY, "Secret Subkey" },
227  { PGPTAG_COMPRESSED_DATA, "Compressed Data" },
228  { PGPTAG_SYMMETRIC_DATA, "Symmetrically Encrypted Data" },
229  { PGPTAG_MARKER, "Marker" },
230  { PGPTAG_LITERAL_DATA, "Literal Data" },
231  { PGPTAG_TRUST, "Trust" },
232  { PGPTAG_USER_ID, "User ID" },
233  { PGPTAG_PUBLIC_SUBKEY, "Public Subkey" },
234  { PGPTAG_COMMENT_OLD, "Comment (from OpenPGP draft)" },
235  { PGPTAG_PHOTOID, "PGP's photo ID" },
236  { PGPTAG_ENCRYPTED_MDC, "Integrity protected encrypted data" },
237  { PGPTAG_MDC, "Manipulaion detection code packet" },
238  { PGPTAG_PRIVATE_60, "Private #60" },
239  { PGPTAG_COMMENT, "Comment" },
240  { PGPTAG_PRIVATE_62, "Private #62" },
241  { PGPTAG_CONTROL, "Control (GPG)" },
242  { -1, "Unknown packet tag" },
243 };
244 
246  { PGPARMOR_MESSAGE, "MESSAGE" },
247  { PGPARMOR_PUBKEY, "PUBLIC KEY BLOCK" },
248  { PGPARMOR_SIGNATURE, "SIGNATURE" },
249  { PGPARMOR_SIGNED_MESSAGE, "SIGNED MESSAGE" },
250  { PGPARMOR_FILE, "ARMORED FILE" },
251  { PGPARMOR_PRIVKEY, "PRIVATE KEY BLOCK" },
252  { PGPARMOR_SECKEY, "SECRET KEY BLOCK" },
253  { -1, "Unknown armor block" }
254 };
255 
257  { PGPARMORKEY_VERSION, "Version: " },
258  { PGPARMORKEY_COMMENT, "Comment: " },
259  { PGPARMORKEY_MESSAGEID, "MessageID: " },
260  { PGPARMORKEY_HASH, "Hash: " },
261  { PGPARMORKEY_CHARSET, "Charset: " },
262  { -1, "Unknown armor key" }
263 };
264 
265 static void pgpPrtNL(void)
266  /*@globals fileSystem @*/
267  /*@modifies fileSystem @*/
268 {
269  if (!_print) return;
270  fprintf(stderr, "\n");
271 }
272 
273 static void pgpPrtInt(const char *pre, int i)
274  /*@globals fileSystem @*/
275  /*@modifies fileSystem @*/
276 {
277  if (!_print) return;
278  if (pre && *pre)
279  fprintf(stderr, "%s", pre);
280  fprintf(stderr, " %d", i);
281 }
282 
283 static void pgpPrtStr(const char *pre, const char *s)
284  /*@globals fileSystem @*/
285  /*@modifies fileSystem @*/
286 {
287  if (!_print) return;
288  if (pre && *pre)
289  fprintf(stderr, "%s", pre);
290  fprintf(stderr, " %s", s);
291 }
292 
293 static void pgpPrtHex(const char *pre, const byte *p, unsigned int plen)
294  /*@globals fileSystem @*/
295  /*@modifies fileSystem @*/
296 {
297  if (!_print) return;
298  if (pre && *pre)
299  fprintf(stderr, "%s", pre);
300  fprintf(stderr, " %s", pgpHexStr(p, plen));
301 }
302 
303 void pgpPrtVal(const char * pre, pgpValTbl vs, byte val)
304  /*@globals fileSystem @*/
305  /*@modifies fileSystem @*/
306 {
307  if (!_print) return;
308  if (pre && *pre)
309  fprintf(stderr, "%s", pre);
310  fprintf(stderr, "%s(%u)", pgpValStr(vs, val), (unsigned)val);
311 }
312 
315 /*@unused@*/ static /*@observer@*/
316 const char * pgpMpiHex(const byte *p)
317  /*@*/
318 {
319  static char prbuf[2048];
320  char *t = prbuf;
321  t = pgpHexCvt(t, p+2, pgpMpiLen(p)-2);
322  return prbuf;
323 }
324 
325 /*@-boundswrite@*/
329 static int pgpHexSet(const char * pre, int lbits,
330  /*@out@*/ mpnumber * mpn, const byte * p, const byte * pend)
331  /*@globals fileSystem @*/
332  /*@modifies mpn, fileSystem @*/
333 {
334  unsigned int mbits = pgpMpiBits(p);
335  unsigned int nbits;
336  unsigned int nbytes;
337  char * t;
338  unsigned int ix;
339 
340  if ((p + ((mbits+7) >> 3)) > pend)
341  return 1;
342 
343  nbits = (lbits > mbits ? lbits : mbits);
344  nbytes = ((nbits + 7) >> 3);
345  t = xmalloc(2*nbytes+1);
346  ix = 2 * ((nbits - mbits) >> 3);
347 
348 if (_debug)
349 fprintf(stderr, "*** mbits %u nbits %u nbytes %u t %p[%d] ix %u\n", mbits, nbits, nbytes, t, (2*nbytes+1), ix);
350  if (ix > 0) memset(t, (int)'0', ix);
351  strcpy(t+ix, pgpMpiHex(p));
352 if (_debug)
353 fprintf(stderr, "*** %s %s\n", pre, t);
354  (void) mpnsethex(mpn, t);
355  t = _free(t);
356 if (_debug && _print)
357 fprintf(stderr, "\t %s ", pre), mpfprintln(stderr, mpn->size, mpn->data);
358  return 0;
359 }
360 /*@=boundswrite@*/
361 
362 int pgpPrtSubType(const byte *h, unsigned int hlen, pgpSigType sigtype)
363 {
364  const byte *p = h;
365  unsigned plen;
366  int i;
367 
368  while (hlen > 0) {
369  i = pgpLen(p, &plen);
370  p += i;
371  hlen -= i;
372 
373  pgpPrtVal(" ", pgpSubTypeTbl, (p[0]&(~PGPSUBTYPE_CRITICAL)));
374  if (p[0] & PGPSUBTYPE_CRITICAL)
375  if (_print)
376  fprintf(stderr, " *CRITICAL*");
377  switch (*p) {
378  case PGPSUBTYPE_PREFER_SYMKEY: /* preferred symmetric algorithms */
379  for (i = 1; i < plen; i++)
380  pgpPrtVal(" ", pgpSymkeyTbl, p[i]);
381  /*@switchbreak@*/ break;
382  case PGPSUBTYPE_PREFER_HASH: /* preferred hash algorithms */
383  for (i = 1; i < plen; i++)
384  pgpPrtVal(" ", pgpHashTbl, p[i]);
385  /*@switchbreak@*/ break;
386  case PGPSUBTYPE_PREFER_COMPRESS:/* preferred compression algorithms */
387  for (i = 1; i < plen; i++)
388  pgpPrtVal(" ", pgpCompressionTbl, p[i]);
389  /*@switchbreak@*/ break;
390  case PGPSUBTYPE_KEYSERVER_PREFERS:/* key server preferences */
391  for (i = 1; i < plen; i++)
392  pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]);
393  /*@switchbreak@*/ break;
395 /*@-mods -mayaliasunique @*/
396  if (_digp && !(_digp->saved & PGPDIG_SAVED_TIME) &&
397  (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
398  {
399  _digp->saved |= PGPDIG_SAVED_TIME;
400  memcpy(_digp->time, p+1, sizeof(_digp->time));
401  }
402 /*@=mods =mayaliasunique @*/
403  /*@fallthrough@*/
406  if ((plen - 1) == 4) {
407  time_t t = pgpGrab(p+1, plen-1);
408  if (_print)
409  fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
410  } else
411  pgpPrtHex("", p+1, plen-1);
412  /*@switchbreak@*/ break;
413 
414  case PGPSUBTYPE_ISSUER_KEYID: /* issuer key ID */
415 /*@-mods -mayaliasunique @*/
416  if (_digp && !(_digp->saved & PGPDIG_SAVED_ID) &&
417  (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
418  {
419  _digp->saved |= PGPDIG_SAVED_ID;
420  memcpy(_digp->signid, p+1, sizeof(_digp->signid));
421  }
422 /*@=mods =mayaliasunique @*/
423  /*@fallthrough@*/
426  case PGPSUBTYPE_REGEX:
428  case PGPSUBTYPE_ARR:
430  case PGPSUBTYPE_NOTATION:
437  case PGPSUBTYPE_FEATURES:
450  default:
451  pgpPrtHex("", p+1, plen-1);
452  /*@switchbreak@*/ break;
453  }
454  pgpPrtNL();
455  p += plen;
456  hlen -= plen;
457  }
458  return 0;
459 }
460 
461 /*@-varuse =readonlytrans @*/
462 /*@observer@*/ /*@unchecked@*/
463 static const char * pgpSigRSA[] = {
464  " m**d =",
465  NULL,
466 };
467 
468 /*@observer@*/ /*@unchecked@*/
469 static const char * pgpSigDSA[] = {
470  " r =",
471  " s =",
472  NULL,
473 };
474 /*@=varuse =readonlytrans @*/
475 
476 static int pgpPrtSigParams(const pgpPkt pp, byte pubkey_algo, byte sigtype,
477  const byte *p)
478  /*@globals fileSystem @*/
479  /*@modifies fileSystem @*/
480 {
481  const byte * pend = pp->h + pp->hlen;
482  int i;
483 
484  for (i = 0; p < pend; i++, p += pgpMpiLen(p)) {
485  if (pubkey_algo == PGPPUBKEYALGO_RSA) {
486  if (i >= 1) break;
487  if (_dig &&
488  (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
489  {
490  switch (i) {
491  case 0: /* m**d */
492  (void) mpnsethex(&_dig->c, pgpMpiHex(p));
493 if (_debug && _print)
494 fprintf(stderr, "\t m**d = "), mpfprintln(stderr, _dig->c.size, _dig->c.data);
495  /*@switchbreak@*/ break;
496  default:
497  /*@switchbreak@*/ break;
498  }
499  }
500  pgpPrtStr("", pgpSigRSA[i]);
501  } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
502  if (i >= 2) break;
503  if (_dig &&
504  (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
505  {
506  int xx;
507  xx = 0;
508  switch (i) {
509  case 0: /* r */
510  xx = pgpHexSet(pgpSigDSA[i], 160, &_dig->r, p, pend);
511  /*@switchbreak@*/ break;
512  case 1: /* s */
513  xx = pgpHexSet(pgpSigDSA[i], 160, &_dig->s, p, pend);
514  /*@switchbreak@*/ break;
515  default:
516  xx = 1;
517  /*@switchbreak@*/ break;
518  }
519  if (xx) return xx;
520  }
521  pgpPrtStr("", pgpSigDSA[i]);
522  } else {
523  if (_print)
524  fprintf(stderr, "%7d", i);
525  }
526  pgpPrtStr("", pgpMpiStr(p));
527  pgpPrtNL();
528  }
529 
530  return 0;
531 }
532 
533 int pgpPrtSig(const pgpPkt pp)
534  /*@globals _digp @*/
535  /*@modifies *_digp @*/
536 {
537  byte version = pp->h[0];
538  byte * p;
539  unsigned plen;
540  int rc;
541 
542  switch (version) {
543  case 3:
544  { pgpPktSigV3 v = (pgpPktSigV3)pp->h;
545  time_t t;
546 
547  if (v->hashlen != 5)
548  return 1;
549 
550  pgpPrtVal("V3 ", pgpTagTbl, pp->tag);
551  pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
552  pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
553  pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
554  pgpPrtNL();
555  t = pgpGrab(v->time, sizeof(v->time));
556  if (_print)
557  fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
558  pgpPrtNL();
559  pgpPrtHex(" signer keyid", v->signid, sizeof(v->signid));
560  plen = pgpGrab(v->signhash16, sizeof(v->signhash16));
561  pgpPrtHex(" signhash16", v->signhash16, sizeof(v->signhash16));
562  pgpPrtNL();
563 
564  if (_digp && _digp->pubkey_algo == 0) {
565  _digp->version = v->version;
566  _digp->hashlen = v->hashlen;
567  _digp->sigtype = v->sigtype;
568  _digp->hash = memcpy(xmalloc(v->hashlen), &v->sigtype, v->hashlen);
569  memcpy(_digp->time, v->time, sizeof(_digp->time));
570  memcpy(_digp->signid, v->signid, sizeof(_digp->signid));
571  _digp->pubkey_algo = v->pubkey_algo;
572  _digp->hash_algo = v->hash_algo;
573  memcpy(_digp->signhash16, v->signhash16, sizeof(_digp->signhash16));
574  }
575 
576  p = ((byte *)v) + sizeof(*v);
577  rc = pgpPrtSigParams(pp, v->pubkey_algo, v->sigtype, p);
578  } break;
579  case 4:
580  { pgpPktSigV4 v = (pgpPktSigV4)pp->h;
581 
582  pgpPrtVal("V4 ", pgpTagTbl, pp->tag);
583  pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
584  pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
585  pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
586  pgpPrtNL();
587 
588  p = &v->hashlen[0];
589  plen = pgpGrab(v->hashlen, sizeof(v->hashlen));
590  p += sizeof(v->hashlen);
591 
592  if ((p + plen) > (pp->h + pp->hlen))
593  return 1;
594 
595 if (_debug && _print)
596 fprintf(stderr, " hash[%u] -- %s\n", plen, pgpHexStr(p, plen));
597  if (_digp && _digp->pubkey_algo == 0) {
598  _digp->hashlen = sizeof(*v) + plen;
599  _digp->hash = memcpy(xmalloc(_digp->hashlen), v, _digp->hashlen);
600  }
601  (void) pgpPrtSubType(p, plen, v->sigtype);
602  p += plen;
603 
604  plen = pgpGrab(p,2);
605  p += 2;
606 
607  if ((p + plen) > (pp->h + pp->hlen))
608  return 1;
609 
610 if (_debug && _print)
611 fprintf(stderr, " unhash[%u] -- %s\n", plen, pgpHexStr(p, plen));
612  (void) pgpPrtSubType(p, plen, v->sigtype);
613  p += plen;
614 
615  plen = pgpGrab(p,2);
616  pgpPrtHex(" signhash16", p, 2);
617  pgpPrtNL();
618 
619  if (_digp && _digp->pubkey_algo == 0) {
620  _digp->version = v->version;
621  _digp->sigtype = v->sigtype;
622  _digp->pubkey_algo = v->pubkey_algo;
623  _digp->hash_algo = v->hash_algo;
624  memcpy(_digp->signhash16, p, sizeof(_digp->signhash16));
625  }
626 
627  p += 2;
628  if (p > (pp->h + pp->hlen))
629  return 1;
630 
631  rc = pgpPrtSigParams(pp, v->pubkey_algo, v->sigtype, p);
632  } break;
633  default:
634  rc = 1;
635  break;
636  }
637  return rc;
638 }
639 
640 /*@-varuse =readonlytrans @*/
641 /*@observer@*/ /*@unchecked@*/
642 static const char * pgpPublicRSA[] = {
643  " n =",
644  " e =",
645  NULL,
646 };
647 
648 #ifdef NOTYET
649 /*@observer@*/ /*@unchecked@*/
650 static const char * pgpSecretRSA[] = {
651  " d =",
652  " p =",
653  " q =",
654  " u =",
655  NULL,
656 };
657 #endif
658 
659 /*@observer@*/ /*@unchecked@*/
660 static const char * pgpPublicDSA[] = {
661  " p =",
662  " q =",
663  " g =",
664  " y =",
665  NULL,
666 };
667 
668 #ifdef NOTYET
669 /*@observer@*/ /*@unchecked@*/
670 static const char * pgpSecretDSA[] = {
671  " x =",
672  NULL,
673 };
674 #endif
675 
676 /*@observer@*/ /*@unchecked@*/
677 static const char * pgpPublicELGAMAL[] = {
678  " p =",
679  " g =",
680  " y =",
681  NULL,
682 };
683 
684 #ifdef NOTYET
685 /*@observer@*/ /*@unchecked@*/
686 static const char * pgpSecretELGAMAL[] = {
687  " x =",
688  NULL,
689 };
690 #endif
691 /*@=varuse =readonlytrans @*/
692 
693 static const byte * pgpPrtPubkeyParams(const pgpPkt pp, byte pubkey_algo,
694  /*@returned@*/ const byte *p)
695  /*@globals fileSystem, internalState @*/
696  /*@modifies fileSystem, internalState @*/
697 {
698  int i;
699 
700  for (i = 0; p < &pp->h[pp->hlen]; i++, p += pgpMpiLen(p)) {
701  if (pubkey_algo == PGPPUBKEYALGO_RSA) {
702  if (i >= 2) break;
703  if (_dig) {
704  switch (i) {
705  case 0: /* n */
706  (void) mpbsethex(&_dig->rsa_pk.n, pgpMpiHex(p));
707 if (_debug && _print)
708 fprintf(stderr, "\t n = "), mpfprintln(stderr, _dig->rsa_pk.n.size, _dig->rsa_pk.n.modl);
709  /*@switchbreak@*/ break;
710  case 1: /* e */
711  (void) mpnsethex(&_dig->rsa_pk.e, pgpMpiHex(p));
712 if (_debug && _print)
713 fprintf(stderr, "\t e = "), mpfprintln(stderr, _dig->rsa_pk.e.size, _dig->rsa_pk.e.data);
714  /*@switchbreak@*/ break;
715  default:
716  /*@switchbreak@*/ break;
717  }
718  }
719  pgpPrtStr("", pgpPublicRSA[i]);
720  } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
721  if (i >= 4) break;
722  if (_dig) {
723  switch (i) {
724  case 0: /* p */
725  (void) mpbsethex(&_dig->p, pgpMpiHex(p));
726 if (_debug && _print)
727 fprintf(stderr, "\t p = "), mpfprintln(stderr, _dig->p.size, _dig->p.modl);
728  /*@switchbreak@*/ break;
729  case 1: /* q */
730  (void) mpbsethex(&_dig->q, pgpMpiHex(p));
731 if (_debug && _print)
732 fprintf(stderr, "\t q = "), mpfprintln(stderr, _dig->q.size, _dig->q.modl);
733  /*@switchbreak@*/ break;
734  case 2: /* g */
735  (void) mpnsethex(&_dig->g, pgpMpiHex(p));
736 if (_debug && _print)
737 fprintf(stderr, "\t g = "), mpfprintln(stderr, _dig->g.size, _dig->g.data);
738  /*@switchbreak@*/ break;
739  case 3: /* y */
740  (void) mpnsethex(&_dig->y, pgpMpiHex(p));
741 if (_debug && _print)
742 fprintf(stderr, "\t y = "), mpfprintln(stderr, _dig->y.size, _dig->y.data);
743  /*@switchbreak@*/ break;
744  default:
745  /*@switchbreak@*/ break;
746  }
747  }
748  pgpPrtStr("", pgpPublicDSA[i]);
749  } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
750  if (i >= 3) break;
751  pgpPrtStr("", pgpPublicELGAMAL[i]);
752  } else {
753  if (_print)
754  fprintf(stderr, "%7d", i);
755  }
756  pgpPrtStr("", pgpMpiStr(p));
757  pgpPrtNL();
758  }
759 
760  return p;
761 }
762 
763 static const byte * pgpPrtSeckeyParams(const pgpPkt pp, /*@unused@*/ byte pubkey_algo,
764  /*@returned@*/ const byte *p)
765  /*@globals fileSystem @*/
766  /*@modifies fileSystem @*/
767 {
768  int i;
769 
770  switch (*p) {
771  case 0:
772  pgpPrtVal(" ", pgpSymkeyTbl, *p);
773  break;
774  case 255:
775  p++;
776  pgpPrtVal(" ", pgpSymkeyTbl, *p);
777  switch (p[1]) {
778  case 0x00:
779  pgpPrtVal(" simple ", pgpHashTbl, p[2]);
780  p += 2;
781  /*@innerbreak@*/ break;
782  case 0x01:
783  pgpPrtVal(" salted ", pgpHashTbl, p[2]);
784  pgpPrtHex("", p+3, 8);
785  p += 10;
786  /*@innerbreak@*/ break;
787  case 0x03:
788  pgpPrtVal(" iterated/salted ", pgpHashTbl, p[2]);
789  /*@-shiftnegative -shiftimplementation @*/ /* FIX: unsigned cast */
790  i = (16 + (p[11] & 0xf)) << ((p[11] >> 4) + 6);
791  /*@=shiftnegative =shiftimplementation @*/
792  pgpPrtHex("", p+3, 8);
793  pgpPrtInt(" iter", i);
794  p += 11;
795  /*@innerbreak@*/ break;
796  }
797  break;
798  default:
799  pgpPrtVal(" ", pgpSymkeyTbl, *p);
800  pgpPrtHex(" IV", p+1, 8);
801  p += 8;
802  break;
803  }
804  pgpPrtNL();
805 
806  p++;
807 
808 #ifdef NOTYET /* XXX encrypted MPI's need to be handled. */
809  for (i = 0; p < &pp->h[pp->hlen]; i++, p += pgpMpiLen(p)) {
810  if (pubkey_algo == PGPPUBKEYALGO_RSA) {
811  if (pgpSecretRSA[i] == NULL) break;
812  pgpPrtStr("", pgpSecretRSA[i]);
813  } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
814  if (pgpSecretDSA[i] == NULL) break;
815  pgpPrtStr("", pgpSecretDSA[i]);
816  } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
817  if (pgpSecretELGAMAL[i] == NULL) break;
818  pgpPrtStr("", pgpSecretELGAMAL[i]);
819  } else {
820  if (_print)
821  fprintf(stderr, "%7d", i);
822  }
823  pgpPrtStr("", pgpMpiStr(p));
824  pgpPrtNL();
825  }
826 #else
827  pgpPrtHex(" secret", p, (pp->hlen - (p - pp->h) - 2));
828  pgpPrtNL();
829  p += (pp->hlen - (p - pp->h) - 2);
830 #endif
831  pgpPrtHex(" checksum", p, 2);
832  pgpPrtNL();
833 
834  return p;
835 }
836 
837 int pgpPrtKey(const pgpPkt pp)
838  /*@globals _digp @*/
839  /*@modifies *_digp @*/
840 {
841  byte version = pp->h[0];
842  const byte * p;
843  unsigned plen;
844  time_t t;
845  int rc;
846 
847  switch (version) {
848  case 3:
849  { pgpPktKeyV3 v = (pgpPktKeyV3)pp->h;
850  pgpPrtVal("V3 ", pgpTagTbl, pp->tag);
851  pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
852  t = pgpGrab(v->time, sizeof(v->time));
853  if (_print)
854  fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
855  plen = pgpGrab(v->valid, sizeof(v->valid));
856  if (plen != 0)
857  fprintf(stderr, " valid %u days", plen);
858  pgpPrtNL();
859 
860  if (_digp && _digp->tag == pp->tag) {
861  _digp->version = v->version;
862  memcpy(_digp->time, v->time, sizeof(_digp->time));
863  _digp->pubkey_algo = v->pubkey_algo;
864  }
865 
866  p = ((byte *)v) + sizeof(*v);
867  p = pgpPrtPubkeyParams(pp, v->pubkey_algo, p);
868  rc = 0;
869  } break;
870  case 4:
871  { pgpPktKeyV4 v = (pgpPktKeyV4)pp->h;
872  pgpPrtVal("V4 ", pgpTagTbl, pp->tag);
873  pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
874  t = pgpGrab(v->time, sizeof(v->time));
875  if (_print)
876  fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
877  pgpPrtNL();
878 
879  if (_digp && _digp->tag == pp->tag) {
880  _digp->version = v->version;
881  memcpy(_digp->time, v->time, sizeof(_digp->time));
882  _digp->pubkey_algo = v->pubkey_algo;
883  }
884 
885  p = ((byte *)v) + sizeof(*v);
886  p = pgpPrtPubkeyParams(pp, v->pubkey_algo, p);
887  if (!(pp->tag == PGPTAG_PUBLIC_KEY || pp->tag == PGPTAG_PUBLIC_SUBKEY))
888  p = pgpPrtSeckeyParams(pp, v->pubkey_algo, p);
889  rc = 0;
890  } break;
891  default:
892  rc = 1;
893  break;
894  }
895  return rc;
896 }
897 
898 /*@-boundswrite@*/
899 int pgpPrtUserID(const pgpPkt pp)
900  /*@globals _digp @*/
901  /*@modifies *_digp @*/
902 {
903  pgpPrtVal("", pgpTagTbl, pp->tag);
904  if (_print)
905  fprintf(stderr, " \"%.*s\"", (int)pp->hlen, (const char *)pp->h);
906  pgpPrtNL();
907  if (_digp) {
908  char * t = memcpy(xmalloc(pp->hlen+1), pp->h, pp->hlen);
909  t[pp->hlen] = '\0';
910  _digp->userid = _free(_digp->userid);
911  _digp->userid = t;
912  }
913  return 0;
914 }
915 /*@=boundswrite@*/
916 
917 int pgpPrtComment(const pgpPkt pp)
918 {
919  const byte * h = pp->h;
920  int i = pp->hlen;
921 
922  pgpPrtVal("", pgpTagTbl, pp->tag);
923  if (_print)
924  fprintf(stderr, " ");
925  while (i > 0) {
926  int j;
927  if (*h >= ' ' && *h <= 'z') {
928  j = 0;
929  while (j < i && h[j] != '\0')
930  j++;
931  while (j < i && h[j] == '\0')
932  j++;
933  if (_print && j)
934  fprintf(stderr, "%.*s", (int)strlen((const char *)h), (const char *)h);
935  } else {
936  pgpPrtHex("", h, i);
937  j = i;
938  }
939  i -= j;
940  h += j;
941  }
942  pgpPrtNL();
943  return 0;
944 }
945 
946 int pgpPktLen(const byte *pkt, unsigned int pleft, pgpPkt pp)
947 {
948  unsigned int val = *pkt;
949  unsigned int plen;
950 
951  memset(pp, 0, sizeof(*pp));
952  /* XXX can't deal with these. */
953  if (!(val & 0x80))
954  return -1;
955 
956  if (val & 0x40) {
957  pp->tag = (val & 0x3f);
958  plen = pgpLen(pkt+1, &pp->hlen);
959  } else {
960  pp->tag = (val >> 2) & 0xf;
961  plen = (1 << (val & 0x3));
962  pp->hlen = pgpGrab(pkt+1, plen);
963  }
964 
965  pp->pktlen = 1 + plen + pp->hlen;
966  if (pleft > 0 && pp->pktlen > pleft)
967  return -1;
968 
969 /*@-assignexpose@*/
970  pp->h = pkt + 1 + plen;
971 /*@=assignexpose@*/
972 
973  return pp->pktlen;
974 }
975 
976 int pgpPubkeyFingerprint(const byte * pkt, unsigned int pktlen, byte * keyid)
977 {
978  pgpPkt pp = alloca(sizeof(*pp));
979  int rc = pgpPktLen(pkt, pktlen, pp);
980  const byte *se;
981  int i;
982 
983  /* Pubkeys only please. */
984  if (pp->tag != PGPTAG_PUBLIC_KEY)
985  return -1;
986 
987  /* Choose the correct keyid. */
988  switch (pp->h[0]) {
989  default: return -1;
990  case 3:
991  { pgpPktKeyV3 v = (pgpPktKeyV3) (pp->h);
992  se = (byte *)(v + 1);
993  switch (v->pubkey_algo) {
994  default: return -1;
995  case PGPPUBKEYALGO_RSA:
996  se += pgpMpiLen(se);
997  memmove(keyid, (se-8), 8);
998  /*@innerbreak@*/ break;
999  }
1000  } break;
1001  case 4:
1002  { pgpPktKeyV4 v = (pgpPktKeyV4) (pp->h);
1003  byte * d = NULL;
1004  size_t dlen = 0;
1005 
1006  se = (byte *)(v + 1);
1007  switch (v->pubkey_algo) {
1008  default: return -1;
1009  case PGPPUBKEYALGO_RSA:
1010  for (i = 0; i < 2; i++)
1011  se += pgpMpiLen(se);
1012  /*@innerbreak@*/ break;
1013  case PGPPUBKEYALGO_DSA:
1014  for (i = 0; i < 4; i++)
1015  se += pgpMpiLen(se);
1016  /*@innerbreak@*/ break;
1017  }
1019  (void) rpmDigestUpdate(ctx, pkt, (se-pkt));
1020  (void) rpmDigestFinal(ctx, &d, &dlen, 0);
1021  }
1022 
1023 /*@-boundswrite@*/
1024  memmove(keyid, (d + (dlen-8)), 8);
1025 /*@=boundswrite@*/
1026  d = _free(d);
1027  } break;
1028  }
1029  rc = 0;
1030  return rc;
1031 }
1032 
1033 int pgpExtractPubkeyFingerprint(const char * b64pkt, byte * keyid)
1034 {
1035  const byte * pkt;
1036  ssize_t pktlen;
1037 
1038  if (b64decode(b64pkt, (void **)&pkt, &pktlen))
1039  return -1; /* on error */
1040  (void) pgpPubkeyFingerprint(pkt, pktlen, keyid);
1041  pkt = _free(pkt);
1042  return 8; /* no. of bytes of pubkey signid */
1043 }
1044 
1045 int pgpPrtPkt(const byte *pkt, unsigned int pleft)
1046 {
1047  pgpPkt pp = alloca(sizeof(*pp));
1048  int rc = pgpPktLen(pkt, pleft, pp);
1049 
1050  if (rc < 0)
1051  return rc;
1052 
1053  switch (pp->tag) {
1054  case PGPTAG_SIGNATURE:
1055  rc = pgpPrtSig(pp);
1056  break;
1057  case PGPTAG_PUBLIC_KEY:
1058  /* Get the public key fingerprint. */
1059  if (_digp) {
1060 /*@-mods@*/
1061  if (!pgpPubkeyFingerprint(pkt, pp->pktlen, _digp->signid))
1062  _digp->saved |= PGPDIG_SAVED_ID;
1063  else
1064  memset(_digp->signid, 0, sizeof(_digp->signid));
1065 /*@=mods@*/
1066  }
1067  /*@fallthrough@*/
1068  case PGPTAG_PUBLIC_SUBKEY:
1069  rc = pgpPrtKey(pp);
1070  break;
1071  case PGPTAG_SECRET_KEY:
1072  case PGPTAG_SECRET_SUBKEY:
1073  rc = pgpPrtKey(pp);
1074  break;
1075  case PGPTAG_USER_ID:
1076  rc = pgpPrtUserID(pp);
1077  break;
1078  case PGPTAG_COMMENT:
1079  case PGPTAG_COMMENT_OLD:
1080  rc = pgpPrtComment(pp);
1081  break;
1082 
1083  case PGPTAG_RESERVED:
1087  case PGPTAG_SYMMETRIC_DATA:
1088  case PGPTAG_MARKER:
1089  case PGPTAG_LITERAL_DATA:
1090  case PGPTAG_TRUST:
1091  case PGPTAG_PHOTOID:
1092  case PGPTAG_ENCRYPTED_MDC:
1093  case PGPTAG_MDC:
1094  case PGPTAG_PRIVATE_60:
1095  case PGPTAG_PRIVATE_62:
1096  case PGPTAG_CONTROL:
1097  default:
1098  pgpPrtVal("", pgpTagTbl, pp->tag);
1099  pgpPrtHex("", pp->h, pp->hlen);
1100  pgpPrtNL();
1101  rc = 0;
1102  break;
1103  }
1104 
1105  return (rc ? -1 : pp->pktlen);
1106 }
1107 
1109 {
1110  pgpDig dig = xcalloc(1, sizeof(*dig));
1111  return dig;
1112 }
1113 
1114 /*@-boundswrite@*/
1116 {
1117  if (dig != NULL) {
1118  int i;
1119  dig->signature.userid = _free(dig->signature.userid);
1120  dig->pubkey.userid = _free(dig->pubkey.userid);
1121  dig->ppkts = _free(dig->ppkts);
1122  dig->npkts = 0;
1123  dig->signature.hash = _free(dig->signature.hash);
1124  dig->pubkey.hash = _free(dig->pubkey.hash);
1125  /*@-unqualifiedtrans@*/ /* FIX: double indirection */
1126  for (i = 0; i < 4; i++) {
1127  dig->signature.params[i] = _free(dig->signature.params[i]);
1128  dig->pubkey.params[i] = _free(dig->pubkey.params[i]);
1129  }
1130  /*@=unqualifiedtrans@*/
1131 
1132  memset(&dig->signature, 0, sizeof(dig->signature));
1133  memset(&dig->pubkey, 0, sizeof(dig->pubkey));
1134 
1135  dig->md5 = _free(dig->md5);
1136  dig->sha1 = _free(dig->sha1);
1137  mpnfree(&dig->hm);
1138  mpnfree(&dig->r);
1139  mpnfree(&dig->s);
1140 
1141  (void) rsapkFree(&dig->rsa_pk);
1142  mpnfree(&dig->m);
1143  mpnfree(&dig->c);
1144  mpnfree(&dig->rsahm);
1145  }
1146 /*@-nullstate@*/
1147  return;
1148 /*@=nullstate@*/
1149 }
1150 /*@=boundswrite@*/
1151 
1152 pgpDig pgpFreeDig(/*@only@*/ /*@null@*/ pgpDig dig)
1153  /*@modifies dig @*/
1154 {
1155  if (dig != NULL) {
1156 
1157  /* DUmp the signature/pubkey data. */
1158  pgpCleanDig(dig);
1159 
1160  /*@-branchstate@*/
1161  if (dig->hdrsha1ctx != NULL)
1162  (void) rpmDigestFinal(dig->hdrsha1ctx, NULL, NULL, 0);
1163  /*@=branchstate@*/
1164  dig->hdrsha1ctx = NULL;
1165 
1166  /*@-branchstate@*/
1167  if (dig->sha1ctx != NULL)
1168  (void) rpmDigestFinal(dig->sha1ctx, NULL, NULL, 0);
1169  /*@=branchstate@*/
1170  dig->sha1ctx = NULL;
1171 
1172  mpbfree(&dig->p);
1173  mpbfree(&dig->q);
1174  mpnfree(&dig->g);
1175  mpnfree(&dig->y);
1176  mpnfree(&dig->hm);
1177  mpnfree(&dig->r);
1178  mpnfree(&dig->s);
1179 
1180 #ifdef NOTYET
1181  /*@-branchstate@*/
1182  if (dig->hdrmd5ctx != NULL)
1183  (void) rpmDigestFinal(dig->hdrmd5ctx, NULL, NULL, 0);
1184  /*@=branchstate@*/
1185  dig->hdrmd5ctx = NULL;
1186 #endif
1187 
1188  /*@-branchstate@*/
1189  if (dig->md5ctx != NULL)
1190  (void) rpmDigestFinal(dig->md5ctx, NULL, NULL, 0);
1191  /*@=branchstate@*/
1192  dig->md5ctx = NULL;
1193 
1194  mpbfree(&dig->rsa_pk.n);
1195  mpnfree(&dig->rsa_pk.e);
1196  mpnfree(&dig->m);
1197  mpnfree(&dig->c);
1198  mpnfree(&dig->hm);
1199 
1200  dig = _free(dig);
1201  }
1202  return dig;
1203 }
1204 
1205 static int pgpGrabPkts(const byte * pkts, unsigned int pktlen,
1206  /*@out@*/ byte *** pppkts, /*@out@*/ int * pnpkts)
1207  /*@modifies *pppkts, *pnpkts @*/
1208 {
1209  pgpPkt pp = alloca(sizeof(*pp));
1210  const byte *p;
1211  unsigned int pleft;
1212  int len;
1213  int npkts = 0;
1214  byte ** ppkts;
1215 
1216  for (p = pkts, pleft = pktlen; p < (pkts + pktlen); p += len, pleft -= len) {
1217  if (pgpPktLen(p, pleft, pp) < 0)
1218  return -1;
1219  len = pp->pktlen;
1220  npkts++;
1221  }
1222  if (npkts <= 0)
1223  return -2;
1224 
1225  ppkts = xcalloc(npkts, sizeof(*ppkts));
1226 
1227  npkts = 0;
1228  for (p = pkts, pleft = pktlen; p < (pkts + pktlen); p += len, pleft -= len) {
1229 
1230  if (pgpPktLen(p, pleft, pp) < 0)
1231  return -1;
1232  len = pp->pktlen;
1233  ppkts[npkts++] = (byte *) p;
1234  }
1235 
1236 /*@-branchstate@*/
1237  if (pppkts != NULL)
1238  *pppkts = ppkts;
1239  else
1240  ppkts = _free(ppkts);
1241 /*@=branchstate@*/
1242 
1243  if (pnpkts != NULL)
1244  *pnpkts = npkts;
1245 
1246  return 0;
1247 }
1248 
1249 int pgpPrtPkts(const byte * pkts, unsigned int pktlen, pgpDig dig, int printing)
1250  /*@globals _dig, _digp, _print @*/
1251  /*@modifies _dig, _digp, *_digp, _print @*/
1252 {
1253  pgpPkt pp = alloca(sizeof(*pp));
1254  unsigned int val = *pkts;
1255  unsigned int pleft;
1256  int len;
1257  byte ** ppkts = NULL;
1258  int npkts;
1259  int i;
1260 
1261  _print = printing;
1262  _dig = dig;
1263  if (dig != NULL && (val & 0x80)) {
1264  pgpTag tag = (val & 0x40) ? (val & 0x3f) : ((val >> 2) & 0xf);
1265  _digp = (tag == PGPTAG_SIGNATURE) ? &_dig->signature : &_dig->pubkey;
1266  _digp->tag = tag;
1267  } else
1268  _digp = NULL;
1269 
1270  if (pgpGrabPkts(pkts, pktlen, &ppkts, &npkts) || ppkts == NULL)
1271  return -1;
1272 
1273  if (ppkts != NULL)
1274  for (i = 0, pleft = pktlen; i < npkts; i++, pleft -= len) {
1275  len = pgpPktLen(ppkts[i], pleft, pp);
1276  len = pgpPrtPkt(ppkts[i], pp->pktlen);
1277  }
1278 
1279 /*@-branchstate@*/
1280  if (dig != NULL) {
1281  dig->ppkts = _free(dig->ppkts); /* XXX memory leak plugged. */
1282  dig->ppkts = ppkts;
1283  dig->npkts = npkts;
1284  } else
1285  ppkts = _free(ppkts);
1286 /*@=branchstate@*/
1287 
1288  return 0;
1289 }
1290 
1291 /*@-boundswrite@*/
1292 pgpArmor pgpReadPkts(const char * fn, const byte ** pkt, size_t * pktlen)
1293 {
1294  const byte * b = NULL;
1295  ssize_t blen;
1296  const char * enc = NULL;
1297  const char * crcenc = NULL;
1298  byte * dec;
1299  byte * crcdec;
1300  size_t declen;
1301  size_t crclen;
1302  uint32_t crcpkt, crc;
1303  const char * armortype = NULL;
1304  char * t, * te;
1305  int pstate = 0;
1306  pgpArmor ec = PGPARMOR_ERR_NO_BEGIN_PGP; /* XXX assume failure */
1307  int rc;
1308 
1309  rc = rpmioSlurp(fn, &b, &blen);
1310  if (rc || b == NULL || blen <= 0) {
1311  goto exit;
1312  }
1313 
1314  if (pgpIsPkt(b)) {
1315 #ifdef NOTYET /* XXX ASCII Pubkeys only, please. */
1316  ec = 0; /* XXX fish out pkt type. */
1317 #endif
1318  goto exit;
1319  }
1320 
1321 #define TOKEQ(_s, _tok) (!strncmp((_s), (_tok), sizeof(_tok)-1))
1322 
1323  for (t = (char *)b; t && *t; t = te) {
1324  if ((te = strchr(t, '\n')) == NULL)
1325  te = t + strlen(t);
1326  else
1327  te++;
1328 
1329  switch (pstate) {
1330  case 0:
1331  armortype = NULL;
1332  if (!TOKEQ(t, "-----BEGIN PGP "))
1333  continue;
1334  t += sizeof("-----BEGIN PGP ")-1;
1335 
1336  rc = pgpValTok(pgpArmorTbl, t, te);
1337  if (rc < 0) {
1339  goto exit;
1340  }
1341  if (rc != PGPARMOR_PUBKEY) /* XXX ASCII Pubkeys only, please. */
1342  continue;
1343  armortype = t;
1344 
1345  t = strchr(t, '\n');
1346  if (t == NULL)
1347  continue;
1348  if (t[-1] == '\r')
1349  --t;
1350  t -= (sizeof("-----")-1);
1351  if (!TOKEQ(t, "-----"))
1352  continue;
1353  *t = '\0';
1354  pstate++;
1355  /*@switchbreak@*/ break;
1356  case 1:
1357  enc = NULL;
1358  rc = pgpValTok(pgpArmorKeyTbl, t, te);
1359  if (rc >= 0)
1360  continue;
1361  if (!(*t == '\n' || *t == '\r')) {
1362  pstate = 0;
1363  continue;
1364  }
1365  enc = te; /* Start of encoded packets */
1366  pstate++;
1367  /*@switchbreak@*/ break;
1368  case 2:
1369  crcenc = NULL;
1370  if (*t != '=')
1371  continue;
1372  *t++ = '\0'; /* Terminate encoded packets */
1373  crcenc = t; /* Start of encoded crc */
1374  pstate++;
1375  /*@switchbreak@*/ break;
1376  case 3:
1377  pstate = 0;
1378  if (!TOKEQ(t, "-----END PGP ")) {
1380  goto exit;
1381  }
1382  *t = '\0'; /* Terminate encoded crc */
1383  t += sizeof("-----END PGP ")-1;
1384  if (t >= te) continue;
1385 
1386  if (armortype == NULL) /* XXX can't happen */
1387  continue;
1388  rc = strncmp(t, armortype, strlen(armortype));
1389  if (rc)
1390  continue;
1391 
1392  t += strlen(armortype);
1393  if (t >= te) continue;
1394 
1395  if (!TOKEQ(t, "-----")) {
1397  goto exit;
1398  }
1399  t += (sizeof("-----")-1);
1400  if (t >= te) continue;
1401  /* XXX permitting \r here is not RFC-2440 compliant <shrug> */
1402  if (!(*t == '\n' || *t == '\r')) continue;
1403 
1404  crcdec = NULL;
1405  crclen = 0;
1406  if (b64decode(crcenc, (void **)&crcdec, &crclen) != 0) {
1408  goto exit;
1409  }
1410  crcpkt = pgpGrab(crcdec, crclen);
1411  crcdec = _free(crcdec);
1412  dec = NULL;
1413  declen = 0;
1414  if (b64decode(enc, (void **)&dec, &declen) != 0) {
1416  goto exit;
1417  }
1418  crc = pgpCRC(dec, declen);
1419  if (crcpkt != crc) {
1421  goto exit;
1422  }
1423  b = _free(b);
1424  b = dec;
1425  blen = declen;
1426  ec = PGPARMOR_PUBKEY; /* XXX ASCII Pubkeys only, please. */
1427  goto exit;
1428  /*@notreached@*/ /*@switchbreak@*/ break;
1429  }
1430  }
1431  ec = PGPARMOR_NONE;
1432 
1433 exit:
1434  if (ec > PGPARMOR_NONE && pkt)
1435  *pkt = b;
1436  else if (b != NULL)
1437  b = _free(b);
1438  if (pktlen)
1439  *pktlen = blen;
1440  return ec;
1441 }
1442 /*@=boundswrite@*/
1443 
1444 char * pgpArmorWrap(int atype, const unsigned char * s, size_t ns)
1445 {
1446  const char * enc;
1447  char * t;
1448  size_t nt;
1449  char * val;
1450  int lc;
1451 
1452  nt = ((ns + 2) / 3) * 4;
1453  /*@-globs@*/
1454  /* Add additional bytes necessary for eol string(s). */
1455  if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
1456  lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
1457  if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
1458  ++lc;
1459  nt += lc * strlen(b64encode_eolstr);
1460  }
1461  /*@=globs@*/
1462 
1463  nt += 512; /* XXX slop for armor and crc */
1464 
1465 /*@-boundswrite@*/
1466  val = t = xmalloc(nt + 1);
1467  *t = '\0';
1468  t = stpcpy(t, "-----BEGIN PGP ");
1469  t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
1470  /*@-globs@*/
1471  t = stpcpy( stpcpy(t, "-----\nVersion: rpm-"), VERSION);
1472  /*@=globs@*/
1473  t = stpcpy(t, " (beecrypt-4.1.2)\n\n");
1474 
1475  if ((enc = b64encode(s, ns)) != NULL) {
1476  t = stpcpy(t, enc);
1477  enc = _free(enc);
1478  if ((enc = b64crc(s, ns)) != NULL) {
1479  *t++ = '=';
1480  t = stpcpy(t, enc);
1481  enc = _free(enc);
1482  }
1483  }
1484 
1485  t = stpcpy(t, "-----END PGP ");
1486  t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
1487  t = stpcpy(t, "-----\n");
1488 /*@=boundswrite@*/
1489 
1490  return val;
1491 }
1492 
1493 /*@=boundsread@*/