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@*/ |
---|