source: trunk/third/rpm/rpmio/rpmpgp.c @ 19079

Revision 19079, 36.3 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19078, which included commits to RCS files with non-trunk default branches.
Line 
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@*/
15static int _debug = 0;
16
17/*@unchecked@*/
18static int _print = 0;
19
20/*@unchecked@*/ /*@null@*/
21static pgpDig _dig = NULL;
22
23/*@unchecked@*/ /*@null@*/
24static pgpDigParams _digp = NULL;
25
26#ifdef  DYING
27/* This is the unarmored RPM-GPG-KEY public key. */
28const char * redhatPubKeyDSA = "\
29mQGiBDfqVDgRBADBKr3Bl6PO8BQ0H8sJoD6p9U7Yyl7pjtZqioviPwXP+DCWd4u8\n\
30HQzcxAZ57m8ssA1LK1Fx93coJhDzM130+p5BG9mYSWShLabR3N1KXdXQYYcowTOM\n\
31GxdwYRGr1Spw8QydLhjVfU1VSl4xt6bupPbWJbyjkg5Z3P7BlUOUJmrx3wCgobNV\n\
32EDGaWYJcch5z5B1of/41G8kEAKii6q7Gu/vhXXnLS6m15oNnPVybyngiw/23dKjS\n\
33ZVG7rKANEK2mxg1VB+vc/uUc4k49UxJJfCZg1gu1sPFV3GSa+Y/7jsiLktQvCiLP\n\
34lncQt1dV+ENmHR5BdIDPWDzKBVbgWnSDnqQ6KrZ7T6AlZ74VMpjGxxkWU6vV2xsW\n\
35XCLPA/9P/vtImA8CZN3jxGgtK5GGtDNJ/cMhhuv5tnfwFg4b/VGo2Jr8mhLUqoIb\n\
36E6zeGAmZbUpdckDco8D5fiFmqTf5+++pCEpJLJkkzel/32N2w4qzPrcRMCiBURES\n\
37PjCLd4Y5rPoU8E4kOHc/4BuHN903tiCsCPloCrWsQZ7UdxfQ5LQiUmVkIEhhdCwg\n\
38SW5jIDxzZWN1cml0eUByZWRoYXQuY29tPohVBBMRAgAVBQI36lQ4AwsKAwMVAwID\n\
39FgIBAheAAAoJECGRgM3bQqYOsBQAnRVtg7B25Hm11PHcpa8FpeddKiq2AJ9aO8sB\n\
40XmLDmPOEFI75mpTrKYHF6rkCDQQ36lRyEAgAokgI2xJ+3bZsk8jRA8ORIX8DH05U\n\
41lMH27qFYzLbT6npXwXYIOtVn0K2/iMDj+oEB1Aa2au4OnddYaLWp06v3d+XyS0t+\n\
425ab2ZfIQzdh7wCwxqRkzR+/H5TLYbMG+hvtTdylfqIX0WEfoOXMtWEGSVwyUsnM3\n\
43Jy3LOi48rQQSCKtCAUdV20FoIGWhwnb/gHU1BnmES6UdQujFBE6EANqPhp0coYoI\n\
44hHJ2oIO8ujQItvvNaU88j/s/izQv5e7MXOgVSjKe/WX3s2JtB/tW7utpy12wh1J+\n\
45JsFdbLV/t8CozUTpJgx5mVA3RKlxjTA+On+1IEUWioB+iVfT7Ov/0kcAzwADBQf9\n\
46E4SKCWRand8K0XloMYgmipxMhJNnWDMLkokvbMNTUoNpSfRoQJ9EheXDxwMpTPwK\n\
47ti/PYrrL2J11P2ed0x7zm8v3gLrY0cue1iSba+8glY+p31ZPOr5ogaJw7ZARgoS8\n\
48BwjyRymXQp+8Dete0TELKOL2/itDOPGHW07SsVWOR6cmX4VlRRcWB5KejaNvdrE5\n\
494XFtOd04NMgWI63uqZc4zkRa+kwEZtmbz3tHSdRCCE+Y7YVP6IUf/w6YPQFQriWY\n\
50FiA6fD10eB+BlIUqIw80VgjsBKmCwvKkn4jg8kibXgj4/TzQSx77uYokw1EqQ2wk\n\
51OZoaEtcubsNMquuLCMWijYhGBBgRAgAGBQI36lRyAAoJECGRgM3bQqYOhyYAnj7h\n\
52VDY/FJAGqmtZpwVp9IlitW5tAJ4xQApr/jNFZCTksnI+4O1765F7tA==\n\
53";
54
55/* This is the unarmored RPM-PGP-KEY public key. */
56const char * redhatPubKeyRSA = "\
57mQCNAzEpXjUAAAEEAKG4/V9oUSiDc9wIge6Bmg6erDGCLzmFyioAho8kDIJSrcmi\n\
58F9qTdPq+fj726pgW1iSb0Y7syZn9Y2lgQm5HkPODfNi8eWyTFSxbr8ygosLRClTP\n\
59xqHVhtInGrfZNLoSpv1LdWOme0yOpOQJnghdOMzKXpgf5g84vaUg6PHLopv5AAUR\n\
60tCpSZWQgSGF0IFNvZnR3YXJlLCBJbmMuIDxyZWRoYXRAcmVkaGF0LmNvbT6JAJUD\n\
61BRAyA5tUoyDApfg4JKEBAUzSA/9QdcVsu955vVyZDk8uvOXWV0X3voT9B3aYMFvj\n\
62UNHUD6F1VFruwQHVKbGJEq1o5MOA6OXKR3vJZStXEMF47TWXJfQaflgl8ywZTH5W\n\
63+eMlKau6Nr0labUV3lmsAE4Vsgu8NCkzIrp2wNVbeW2ZAXtrKswV+refLquUhp7l\n\
64wMpH9IkAdQMFEDGttkRNdXhbO1TgGQEBAGoC/j6C22PqXIyqZc6fG6J6Jl/T5kFG\n\
65xH1pKIzua5WCDDugAgnuOJgywa4pegT4UqwEZiMTAlwT6dmG1CXgKB+5V7lnCjDc\n\
66JZLni0iztoe08ig6fJrjNGXljf7KYXzgwBftQokAlQMFEDMQzo2MRVM9rfPulQEB\n\
67pLoD/1/MWv3u0Paiu14XRvDrBaJ7BmG2/48bA5vKOzpvvoNRO95YS7ZEtqErXA7Y\n\
68DRO8+C8f6PAILMk7kCk4lNMscS/ZRzu5+J8cv4ejsFvxgJBBU3Zgp8AWdWOpvZ0I\n\
69wW//HoDUGhOxlEtymljIMFBkj4SysHWhCBUfA9Xy86kouTJQiQCVAwUQMxDOQ50a\n\
70feTWLUSJAQFnYQQAkt9nhMTeioREB1DvJt+vsFyOj//o3ThqK5ySEP3dgj62iaQp\n\
71JrBmAe5XZPw25C/TXAf+x27H8h2QbKgq49VtsElFexc6wO+uq85fAPDdyE+2XyNE\n\
72njGZkY/TP2F/jTB0sAwJO+xFCHmSYkcBjzxK/2LMD+O7rwp2UCUhhl9QhhqJAJUD\n\
73BRAx5na6pSDo8cuim/kBARmjA/4lDVnV2h9KiNabp9oE38wmGgu5m5XgUHW8L6du\n\
74iQDnwO5IgXN2vDpKGxbgtwv6iYYmGd8IRQ66uJvOsxSv3OR7J7LkCHuI2b/s0AZn\n\
75c79DZaJ2ChUCZlbNQBMeEdrFWif9NopY+d5+2tby1onu9XOFMMvomxL3NhctElYR\n\
76HC8Xw4kAlQMFEDHmdTtURTdEKY1MpQEBEtEEAMZbp1ZFrjiHkj2aLFC1S8dGRbSH\n\
77GUdnLP9qLPFgmWekp9E0o8ZztALGVdqPfPF3N/JJ+AL4IMrfojd7+eZKw36Mdvtg\n\
78dPI+Oz4sxHDbDynZ2qspD9Om5yYuxuz/Xq+9nO2IlsAnEYw3ag3cxat0kvxpOPRe\n\
79Yy+vFpgfDNizr3MgiQBVAwUQMXNMXCjtrosVMemRAQEDnwH7BsJrnnh91nI54LAK\n\
80Gcq3pr8ld0PAtWJmNRGQvUlpEMXUSnu59j2P1ogPNjL3PqKdVxk5Jqgcr8TPQMf3\n\
81V4fqXokAlQMFEDFy+8YiEmsRQ3LyzQEB+TwD/03QDslXLg5F3zj4zf0yI6ikT0be\n\
825OhZv2pnkb80qgdHzFRxBOYmSoueRKdQJASd8F9ue4b3bmf/Y7ikiY0DblvxcXB2\n\
83sz1Pu8i2Zn9u8SKuxNIoVvM8/STRVkgPfvL5QjAWMHT9Wvg81XcI2yXJzrt/2f2g\n\
84mNpWIvVOOT85rVPIiQCVAwUQMVPRlBlzviMjNHElAQG1nwP/fpVX6nKRWJCSFeB7\n\
85leZ4lb+y1uMsMVv0n7agjJVw13SXaA267y7VWCBlnhsCemxEugqEIkI4lu/1mgtw\n\
86WPWSE0BOIVjj0AA8zp2T0H3ZCCMbiFAFJ1P2Gq2rKr8QrOb/08oH1lEzyz0j/jKh\n\
87qiXAxdlB1wojQB6yLbHvTIe3rZGJAHUDBRAxKetfzauiKSJ6LJEBAed/AvsEiGgj\n\
88TQzhsZcUuRNrQpV0cDGH9Mpril7P7K7yFIzju8biB+Cu6nEknSOHlMLl8usObVlk\n\
89d8Wf14soHC7SjItiGSKtI8JhauzBJPl6fDDeyHGsJKo9f9adKeBMCipCFOuJAJUD\n\
90BRAxKeqWRHFTaIK/x+0BAY6eA/4m5X4gs1UwOUIRnljo9a0cVs6ITL554J9vSCYH\n\
91Zzd87kFwdf5W1Vd82HIkRzcr6cp33E3IDkRzaQCMVw2me7HePP7+4Ry2q3EeZMbm\n\
92NE++VzkxjikzpRb2+F5nGB2UdsElkgbXinswebiuOwOrocLbz6JFdDsJPcT5gVfi\n\
93z15FuA==\n\
94";
95#endif  /* DYING */
96
97struct 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
114struct 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
127struct 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
142struct pgpValTbl_s pgpCompressionTbl[] = {
143    { PGPCOMPRESSALGO_NONE,     "Uncompressed" },
144    { PGPCOMPRESSALGO_ZIP,      "ZIP" },
145    { PGPCOMPRESSALGO_ZLIB,     "ZLIB" },
146    { -1,                       "Unknown compression algorithm" },
147};
148
149struct 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@*/
161struct pgpValTbl_s pgpKeyServerPrefsTbl[] = {
162    { 0x80,                     "No-modify" },
163    { -1,                       "Unknown key server preference" },
164};
165/*@=exportlocal =exportheadervar@*/
166
167struct 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
203struct 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
229struct 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
240struct 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
262static void pgpPrtNL(void)
263        /*@globals fileSystem @*/
264        /*@modifies fileSystem @*/
265{
266    if (!_print) return;
267    fprintf(stderr, "\n");
268}
269
270static 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
280static 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
290static 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
300void 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@*/
313const 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 */
326static 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
345if (_debug)
346fprintf(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));
349if (_debug)
350fprintf(stderr, "*** %s %s\n", pre, t);
351    mp32nsethex(mpn, t);
352    t = _free(t);
353if (_debug && _print)
354fprintf(stderr, "\t %s ", pre), mp32println(stderr, mpn->size, mpn->data);
355    return 0;
356}
357/*@=boundswrite@*/
358
359int 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@*/
455static const char * pgpSigRSA[] = {
456    " m**d =",
457    NULL,
458};
459
460/*@observer@*/ /*@unchecked@*/
461static const char * pgpSigDSA[] = {
462    "    r =",
463    "    s =",
464    NULL,
465};
466/*@=varuse =readonlytrans @*/
467
468static 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));
486if (_debug && _print)
487fprintf(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
529int 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
591if (_debug && _print)
592fprintf(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
608if (_debug && _print)
609fprintf(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@*/
642static const char * pgpPublicRSA[] = {
643    "    n =",
644    "    e =",
645    NULL,
646};
647
648/*@observer@*/ /*@unchecked@*/
649static const char * pgpSecretRSA[] = {
650    "    d =",
651    "    p =",
652    "    q =",
653    "    u =",
654    NULL,
655};
656
657/*@observer@*/ /*@unchecked@*/
658static const char * pgpPublicDSA[] = {
659    "    p =",
660    "    q =",
661    "    g =",
662    "    y =",
663    NULL,
664};
665
666/*@observer@*/ /*@unchecked@*/
667static const char * pgpSecretDSA[] = {
668    "    x =",
669    NULL,
670};
671
672/*@observer@*/ /*@unchecked@*/
673static const char * pgpPublicELGAMAL[] = {
674    "    p =",
675    "    g =",
676    "    y =",
677    NULL,
678};
679
680/*@observer@*/ /*@unchecked@*/
681static const char * pgpSecretELGAMAL[] = {
682    "    x =",
683    NULL,
684};
685/*@=varuse =readonlytrans @*/
686
687static 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                    }
716if (_debug && _print)
717fprintf(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));
721if (_debug && _print)
722fprintf(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));
737if (_debug && _print)
738fprintf(stderr, "\t     p = "),  mp32println(stderr, _dig->p.size, _dig->p.modl);
739                    /*@switchbreak@*/ break;
740                case 1:         /* q */
741                    mp32bsethex(&_dig->q, pgpMpiHex(p));
742if (_debug && _print)
743fprintf(stderr, "\t     q = "),  mp32println(stderr, _dig->q.size, _dig->q.modl);
744                    /*@switchbreak@*/ break;
745                case 2:         /* g */
746                    mp32nsethex(&_dig->g, pgpMpiHex(p));
747if (_debug && _print)
748fprintf(stderr, "\t     g = "),  mp32println(stderr, _dig->g.size, _dig->g.data);
749                    /*@switchbreak@*/ break;
750                case 3:         /* y */
751                    mp32nsethex(&_dig->y, pgpMpiHex(p));
752if (_debug && _print)
753fprintf(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
776static 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
850int 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@*/
914int 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
931int 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
957int 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
1029pgpDig pgpNewDig(void)
1030{
1031    pgpDig dig = xcalloc(1, sizeof(*dig));
1032    return dig;
1033}
1034
1035/*@-boundswrite@*/
1036void 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
1071pgpDig 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
1124int 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@*/
1153pgpArmor 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
1266exit:
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
1277char * 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@*/
Note: See TracBrowser for help on using the repository browser.