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