rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

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