2 /** \ingroup rpmio signature
4 * Routines to handle RFC-2440 detached signatures.
8 #include "rpmio_internal.h"
12 /*@access pgpDigParams @*/
15 static int _debug = 0;
18 static int _print = 0;
20 /*@unchecked@*/ /*@null@*/
21 static pgpDig _dig = NULL;
23 /*@unchecked@*/ /*@null@*/
24 static pgpDigParams _digp = NULL;
26 struct pgpValTbl_s pgpSigTypeTbl[] = {
27 { PGPSIGTYPE_BINARY, "Binary document signature" },
28 { PGPSIGTYPE_TEXT, "Text document signature" },
29 { PGPSIGTYPE_STANDALONE, "Standalone signature" },
30 { PGPSIGTYPE_GENERIC_CERT, "Generic certification of a User ID and Public Key" },
31 { PGPSIGTYPE_PERSONA_CERT, "Persona certification of a User ID and Public Key" },
32 { PGPSIGTYPE_CASUAL_CERT, "Casual certification of a User ID and Public Key" },
33 { PGPSIGTYPE_POSITIVE_CERT, "Positive certification of a User ID and Public Key" },
34 { PGPSIGTYPE_SUBKEY_BINDING,"Subkey Binding Signature" },
35 { PGPSIGTYPE_SIGNED_KEY, "Signature directly on a key" },
36 { PGPSIGTYPE_KEY_REVOKE, "Key revocation signature" },
37 { PGPSIGTYPE_SUBKEY_REVOKE, "Subkey revocation signature" },
38 { PGPSIGTYPE_CERT_REVOKE, "Certification revocation signature" },
39 { PGPSIGTYPE_TIMESTAMP, "Timestamp signature" },
40 { -1, "Unknown signature type" },
43 struct pgpValTbl_s pgpPubkeyTbl[] = {
44 { PGPPUBKEYALGO_RSA, "RSA" },
45 { PGPPUBKEYALGO_RSA_ENCRYPT,"RSA(Encrypt-Only)" },
46 { PGPPUBKEYALGO_RSA_SIGN, "RSA(Sign-Only)" },
47 { PGPPUBKEYALGO_ELGAMAL_ENCRYPT,"Elgamal(Encrypt-Only)" },
48 { PGPPUBKEYALGO_DSA, "DSA" },
49 { PGPPUBKEYALGO_EC, "Elliptic Curve" },
50 { PGPPUBKEYALGO_ECDSA, "ECDSA" },
51 { PGPPUBKEYALGO_ELGAMAL, "Elgamal" },
52 { PGPPUBKEYALGO_DH, "Diffie-Hellman (X9.42)" },
53 { -1, "Unknown public key algorithm" },
56 struct pgpValTbl_s pgpSymkeyTbl[] = {
57 { PGPSYMKEYALGO_PLAINTEXT, "Plaintext" },
58 { PGPSYMKEYALGO_IDEA, "IDEA" },
59 { PGPSYMKEYALGO_TRIPLE_DES, "3DES" },
60 { PGPSYMKEYALGO_CAST5, "CAST5" },
61 { PGPSYMKEYALGO_BLOWFISH, "BLOWFISH" },
62 { PGPSYMKEYALGO_SAFER, "SAFER" },
63 { PGPSYMKEYALGO_DES_SK, "DES/SK" },
64 { PGPSYMKEYALGO_AES_128, "AES(128-bit key)" },
65 { PGPSYMKEYALGO_AES_192, "AES(192-bit key)" },
66 { PGPSYMKEYALGO_AES_256, "AES(256-bit key)" },
67 { PGPSYMKEYALGO_TWOFISH, "TWOFISH(256-bit key)" },
68 { PGPSYMKEYALGO_NOENCRYPT, "no encryption" },
69 { -1, "Unknown symmetric key algorithm" },
72 struct pgpValTbl_s pgpCompressionTbl[] = {
73 { PGPCOMPRESSALGO_NONE, "Uncompressed" },
74 { PGPCOMPRESSALGO_ZIP, "ZIP" },
75 { PGPCOMPRESSALGO_ZLIB, "ZLIB" },
76 { PGPCOMPRESSALGO_BZIP2, "BZIP2" },
77 { -1, "Unknown compression algorithm" },
80 struct pgpValTbl_s pgpHashTbl[] = {
81 { PGPHASHALGO_MD5, "MD5" },
82 { PGPHASHALGO_SHA1, "SHA1" },
83 { PGPHASHALGO_RIPEMD160, "RIPEMD160" },
84 { PGPHASHALGO_MD2, "MD2" },
85 { PGPHASHALGO_TIGER192, "TIGER192" },
86 { PGPHASHALGO_HAVAL_5_160, "HAVAL-5-160" },
87 { PGPHASHALGO_SHA256, "SHA256" },
88 { PGPHASHALGO_SHA384, "SHA384" },
89 { PGPHASHALGO_SHA512, "SHA512" },
90 { -1, "Unknown hash algorithm" },
93 /*@-exportlocal -exportheadervar@*/
94 /*@observer@*/ /*@unchecked@*/
95 struct pgpValTbl_s pgpKeyServerPrefsTbl[] = {
96 { 0x80, "No-modify" },
97 { -1, "Unknown key server preference" },
99 /*@=exportlocal =exportheadervar@*/
101 struct pgpValTbl_s pgpSubTypeTbl[] = {
102 { PGPSUBTYPE_SIG_CREATE_TIME,"signature creation time" },
103 { PGPSUBTYPE_SIG_EXPIRE_TIME,"signature expiration time" },
104 { PGPSUBTYPE_EXPORTABLE_CERT,"exportable certification" },
105 { PGPSUBTYPE_TRUST_SIG, "trust signature" },
106 { PGPSUBTYPE_REGEX, "regular expression" },
107 { PGPSUBTYPE_REVOCABLE, "revocable" },
108 { PGPSUBTYPE_KEY_EXPIRE_TIME,"key expiration time" },
109 { PGPSUBTYPE_ARR, "additional recipient request" },
110 { PGPSUBTYPE_PREFER_SYMKEY, "preferred symmetric algorithms" },
111 { PGPSUBTYPE_REVOKE_KEY, "revocation key" },
112 { PGPSUBTYPE_ISSUER_KEYID, "issuer key ID" },
113 { PGPSUBTYPE_NOTATION, "notation data" },
114 { PGPSUBTYPE_PREFER_HASH, "preferred hash algorithms" },
115 { PGPSUBTYPE_PREFER_COMPRESS,"preferred compression algorithms" },
116 { PGPSUBTYPE_KEYSERVER_PREFERS,"key server preferences" },
117 { PGPSUBTYPE_PREFER_KEYSERVER,"preferred key server" },
118 { PGPSUBTYPE_PRIMARY_USERID,"primary user id" },
119 { PGPSUBTYPE_POLICY_URL, "policy URL" },
120 { PGPSUBTYPE_KEY_FLAGS, "key flags" },
121 { PGPSUBTYPE_SIGNER_USERID, "signer's user id" },
122 { PGPSUBTYPE_REVOKE_REASON, "reason for revocation" },
123 { PGPSUBTYPE_FEATURES, "features" },
124 { PGPSUBTYPE_EMBEDDED_SIG, "embedded signature" },
126 { PGPSUBTYPE_INTERNAL_100, "internal subpkt type 100" },
127 { PGPSUBTYPE_INTERNAL_101, "internal subpkt type 101" },
128 { PGPSUBTYPE_INTERNAL_102, "internal subpkt type 102" },
129 { PGPSUBTYPE_INTERNAL_103, "internal subpkt type 103" },
130 { PGPSUBTYPE_INTERNAL_104, "internal subpkt type 104" },
131 { PGPSUBTYPE_INTERNAL_105, "internal subpkt type 105" },
132 { PGPSUBTYPE_INTERNAL_106, "internal subpkt type 106" },
133 { PGPSUBTYPE_INTERNAL_107, "internal subpkt type 107" },
134 { PGPSUBTYPE_INTERNAL_108, "internal subpkt type 108" },
135 { PGPSUBTYPE_INTERNAL_109, "internal subpkt type 109" },
136 { PGPSUBTYPE_INTERNAL_110, "internal subpkt type 110" },
137 { -1, "Unknown signature subkey type" },
140 struct pgpValTbl_s pgpTagTbl[] = {
141 { PGPTAG_PUBLIC_SESSION_KEY,"Public-Key Encrypted Session Key" },
142 { PGPTAG_SIGNATURE, "Signature" },
143 { PGPTAG_SYMMETRIC_SESSION_KEY,"Symmetric-Key Encrypted Session Key" },
144 { PGPTAG_ONEPASS_SIGNATURE, "One-Pass Signature" },
145 { PGPTAG_SECRET_KEY, "Secret Key" },
146 { PGPTAG_PUBLIC_KEY, "Public Key" },
147 { PGPTAG_SECRET_SUBKEY, "Secret Subkey" },
148 { PGPTAG_COMPRESSED_DATA, "Compressed Data" },
149 { PGPTAG_SYMMETRIC_DATA, "Symmetrically Encrypted Data" },
150 { PGPTAG_MARKER, "Marker" },
151 { PGPTAG_LITERAL_DATA, "Literal Data" },
152 { PGPTAG_TRUST, "Trust" },
153 { PGPTAG_USER_ID, "User ID" },
154 { PGPTAG_PUBLIC_SUBKEY, "Public Subkey" },
155 { PGPTAG_COMMENT_OLD, "Comment (from OpenPGP draft)" },
156 { PGPTAG_PHOTOID, "PGP's photo ID" },
157 { PGPTAG_ENCRYPTED_MDC, "Integrity protected encrypted data" },
158 { PGPTAG_MDC, "Manipulaion detection code packet" },
159 { PGPTAG_PRIVATE_60, "Private #60" },
160 { PGPTAG_COMMENT, "Comment" },
161 { PGPTAG_PRIVATE_62, "Private #62" },
162 { PGPTAG_CONTROL, "Control (GPG)" },
163 { -1, "Unknown packet tag" },
166 struct pgpValTbl_s pgpArmorTbl[] = {
167 { PGPARMOR_MESSAGE, "MESSAGE" },
168 { PGPARMOR_PUBKEY, "PUBLIC KEY BLOCK" },
169 { PGPARMOR_SIGNATURE, "SIGNATURE" },
170 { PGPARMOR_SIGNED_MESSAGE, "SIGNED MESSAGE" },
171 { PGPARMOR_FILE, "ARMORED FILE" },
172 { PGPARMOR_PRIVKEY, "PRIVATE KEY BLOCK" },
173 { PGPARMOR_SECKEY, "SECRET KEY BLOCK" },
174 { -1, "Unknown armor block" }
177 struct pgpValTbl_s pgpArmorKeyTbl[] = {
178 { PGPARMORKEY_VERSION, "Version: " },
179 { PGPARMORKEY_COMMENT, "Comment: " },
180 { PGPARMORKEY_MESSAGEID, "MessageID: " },
181 { PGPARMORKEY_HASH, "Hash: " },
182 { PGPARMORKEY_CHARSET, "Charset: " },
183 { -1, "Unknown armor key" }
187 * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
188 * @param p memory to free
189 * @return NULL always
191 /*@unused@*/ static inline /*@null@*/ void *
192 _free(/*@only@*/ /*@null@*/ /*@out@*/ const void * p)
195 if (p != NULL) free((void *)p);
199 static void pgpPrtNL(void)
200 /*@globals fileSystem @*/
201 /*@modifies fileSystem @*/
204 fprintf(stderr, "\n");
207 static void pgpPrtInt(const char *pre, int i)
208 /*@globals fileSystem @*/
209 /*@modifies fileSystem @*/
213 fprintf(stderr, "%s", pre);
214 fprintf(stderr, " %d", i);
217 static void pgpPrtStr(const char *pre, const char *s)
218 /*@globals fileSystem @*/
219 /*@modifies fileSystem @*/
223 fprintf(stderr, "%s", pre);
224 fprintf(stderr, " %s", s);
227 static void pgpPrtHex(const char *pre, const byte *p, unsigned int plen)
228 /*@globals fileSystem @*/
229 /*@modifies fileSystem @*/
233 fprintf(stderr, "%s", pre);
234 fprintf(stderr, " %s", pgpHexStr(p, plen));
237 void pgpPrtVal(const char * pre, pgpValTbl vs, byte val)
238 /*@globals fileSystem @*/
239 /*@modifies fileSystem @*/
243 fprintf(stderr, "%s", pre);
244 fprintf(stderr, "%s(%u)", pgpValStr(vs, val), (unsigned)val);
249 /*@unused@*/ static /*@observer@*/
250 const char * pgpMpiHex(const byte *p)
253 static char prbuf[2048];
255 t = pgpHexCvt(t, p+2, pgpMpiLen(p)-2);
261 * @return 0 on success
263 static int pgpHexSet(const char * pre, int lbits,
264 /*@out@*/ mpnumber * mpn, const byte * p, const byte * pend)
265 /*@globals fileSystem @*/
266 /*@modifies mpn, fileSystem @*/
268 unsigned int mbits = pgpMpiBits(p);
274 if ((p + ((mbits+7) >> 3)) > pend)
277 nbits = (lbits > mbits ? lbits : mbits);
278 nbytes = ((nbits + 7) >> 3);
279 t = xmalloc(2*nbytes+1);
280 ix = 2 * ((nbits - mbits) >> 3);
283 fprintf(stderr, "*** mbits %u nbits %u nbytes %u t %p[%d] ix %u\n", mbits, nbits, nbytes, t, (2*nbytes+1), ix);
284 if (ix > 0) memset(t, (int)'0', ix);
285 strcpy(t+ix, pgpMpiHex(p));
287 fprintf(stderr, "*** %s %s\n", pre, t);
288 (void) mpnsethex(mpn, t);
290 if (_debug && _print)
291 fprintf(stderr, "\t %s ", pre), mpfprintln(stderr, mpn->size, mpn->data);
296 int pgpPrtSubType(const byte *h, unsigned int hlen, pgpSigType sigtype)
303 i = pgpLen(p, &plen);
307 pgpPrtVal(" ", pgpSubTypeTbl, (p[0]&(~PGPSUBTYPE_CRITICAL)));
308 if (p[0] & PGPSUBTYPE_CRITICAL)
310 fprintf(stderr, " *CRITICAL*");
312 case PGPSUBTYPE_PREFER_SYMKEY: /* preferred symmetric algorithms */
313 for (i = 1; i < plen; i++)
314 pgpPrtVal(" ", pgpSymkeyTbl, p[i]);
315 /*@switchbreak@*/ break;
316 case PGPSUBTYPE_PREFER_HASH: /* preferred hash algorithms */
317 for (i = 1; i < plen; i++)
318 pgpPrtVal(" ", pgpHashTbl, p[i]);
319 /*@switchbreak@*/ break;
320 case PGPSUBTYPE_PREFER_COMPRESS:/* preferred compression algorithms */
321 for (i = 1; i < plen; i++)
322 pgpPrtVal(" ", pgpCompressionTbl, p[i]);
323 /*@switchbreak@*/ break;
324 case PGPSUBTYPE_KEYSERVER_PREFERS:/* key server preferences */
325 for (i = 1; i < plen; i++)
326 pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]);
327 /*@switchbreak@*/ break;
328 case PGPSUBTYPE_SIG_CREATE_TIME:
329 /*@-mods -mayaliasunique @*/
330 if (_digp && !(_digp->saved & PGPDIG_SAVED_TIME) &&
331 (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
333 _digp->saved |= PGPDIG_SAVED_TIME;
334 memcpy(_digp->time, p+1, sizeof(_digp->time));
336 /*@=mods =mayaliasunique @*/
338 case PGPSUBTYPE_SIG_EXPIRE_TIME:
339 case PGPSUBTYPE_KEY_EXPIRE_TIME:
340 if ((plen - 1) == 4) {
341 time_t t = pgpGrab(p+1, plen-1);
343 fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
345 pgpPrtHex("", p+1, plen-1);
346 /*@switchbreak@*/ break;
348 case PGPSUBTYPE_ISSUER_KEYID: /* issuer key ID */
349 /*@-mods -mayaliasunique @*/
350 if (_digp && !(_digp->saved & PGPDIG_SAVED_ID) &&
351 (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
353 _digp->saved |= PGPDIG_SAVED_ID;
354 memcpy(_digp->signid, p+1, sizeof(_digp->signid));
356 /*@=mods =mayaliasunique @*/
358 case PGPSUBTYPE_EXPORTABLE_CERT:
359 case PGPSUBTYPE_TRUST_SIG:
360 case PGPSUBTYPE_REGEX:
361 case PGPSUBTYPE_REVOCABLE:
363 case PGPSUBTYPE_REVOKE_KEY:
364 case PGPSUBTYPE_NOTATION:
365 case PGPSUBTYPE_PREFER_KEYSERVER:
366 case PGPSUBTYPE_PRIMARY_USERID:
367 case PGPSUBTYPE_POLICY_URL:
368 case PGPSUBTYPE_KEY_FLAGS:
369 case PGPSUBTYPE_SIGNER_USERID:
370 case PGPSUBTYPE_REVOKE_REASON:
371 case PGPSUBTYPE_FEATURES:
372 case PGPSUBTYPE_EMBEDDED_SIG:
373 case PGPSUBTYPE_INTERNAL_100:
374 case PGPSUBTYPE_INTERNAL_101:
375 case PGPSUBTYPE_INTERNAL_102:
376 case PGPSUBTYPE_INTERNAL_103:
377 case PGPSUBTYPE_INTERNAL_104:
378 case PGPSUBTYPE_INTERNAL_105:
379 case PGPSUBTYPE_INTERNAL_106:
380 case PGPSUBTYPE_INTERNAL_107:
381 case PGPSUBTYPE_INTERNAL_108:
382 case PGPSUBTYPE_INTERNAL_109:
383 case PGPSUBTYPE_INTERNAL_110:
385 pgpPrtHex("", p+1, plen-1);
386 /*@switchbreak@*/ break;
395 /*@-varuse =readonlytrans @*/
396 /*@observer@*/ /*@unchecked@*/
397 static const char * pgpSigRSA[] = {
402 /*@observer@*/ /*@unchecked@*/
403 static const char * pgpSigDSA[] = {
408 /*@=varuse =readonlytrans @*/
410 static int pgpPrtSigParams(/*@unused@*/ pgpTag tag, byte pubkey_algo, byte sigtype,
411 const byte *p, const byte *h, unsigned int hlen)
412 /*@globals fileSystem @*/
413 /*@modifies fileSystem @*/
415 const byte * pend = h + hlen;
418 for (i = 0; p < pend; i++, p += pgpMpiLen(p)) {
419 if (pubkey_algo == PGPPUBKEYALGO_RSA) {
422 (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
426 (void) mpnsethex(&_dig->c, pgpMpiHex(p));
427 if (_debug && _print)
428 fprintf(stderr, "\t m**d = "), mpfprintln(stderr, _dig->c.size, _dig->c.data);
429 /*@switchbreak@*/ break;
431 /*@switchbreak@*/ break;
434 pgpPrtStr("", pgpSigRSA[i]);
435 } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
438 (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
444 xx = pgpHexSet(pgpSigDSA[i], 160, &_dig->r, p, pend);
445 /*@switchbreak@*/ break;
447 xx = pgpHexSet(pgpSigDSA[i], 160, &_dig->s, p, pend);
448 /*@switchbreak@*/ break;
451 /*@switchbreak@*/ break;
455 pgpPrtStr("", pgpSigDSA[i]);
458 fprintf(stderr, "%7d", i);
460 pgpPrtStr("", pgpMpiStr(p));
467 int pgpPrtSig(pgpTag tag, const byte *h, unsigned int hlen)
469 /*@modifies *_digp @*/
478 { pgpPktSigV3 v = (pgpPktSigV3)h;
484 pgpPrtVal("V3 ", pgpTagTbl, tag);
485 pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
486 pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
487 pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
489 t = pgpGrab(v->time, sizeof(v->time));
491 fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
493 pgpPrtHex(" signer keyid", v->signid, sizeof(v->signid));
494 plen = pgpGrab(v->signhash16, sizeof(v->signhash16));
495 pgpPrtHex(" signhash16", v->signhash16, sizeof(v->signhash16));
498 if (_digp && _digp->pubkey_algo == 0) {
499 _digp->version = v->version;
500 _digp->hashlen = v->hashlen;
501 _digp->sigtype = v->sigtype;
502 _digp->hash = memcpy(xmalloc(v->hashlen), &v->sigtype, v->hashlen);
503 memcpy(_digp->time, v->time, sizeof(_digp->time));
504 memcpy(_digp->signid, v->signid, sizeof(_digp->signid));
505 _digp->pubkey_algo = v->pubkey_algo;
506 _digp->hash_algo = v->hash_algo;
507 memcpy(_digp->signhash16, v->signhash16, sizeof(_digp->signhash16));
510 p = ((byte *)v) + sizeof(*v);
511 rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen);
514 { pgpPktSigV4 v = (pgpPktSigV4)h;
516 pgpPrtVal("V4 ", pgpTagTbl, tag);
517 pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
518 pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
519 pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
523 plen = pgpGrab(v->hashlen, sizeof(v->hashlen));
524 p += sizeof(v->hashlen);
526 if ((p + plen) > (h + hlen))
529 if (_debug && _print)
530 fprintf(stderr, " hash[%u] -- %s\n", plen, pgpHexStr(p, plen));
531 if (_digp && _digp->pubkey_algo == 0) {
532 _digp->hashlen = sizeof(*v) + plen;
533 _digp->hash = memcpy(xmalloc(_digp->hashlen), v, _digp->hashlen);
535 (void) pgpPrtSubType(p, plen, v->sigtype);
541 if ((p + plen) > (h + hlen))
544 if (_debug && _print)
545 fprintf(stderr, " unhash[%u] -- %s\n", plen, pgpHexStr(p, plen));
546 (void) pgpPrtSubType(p, plen, v->sigtype);
550 pgpPrtHex(" signhash16", p, 2);
553 if (_digp && _digp->pubkey_algo == 0) {
554 _digp->version = v->version;
555 _digp->sigtype = v->sigtype;
556 _digp->pubkey_algo = v->pubkey_algo;
557 _digp->hash_algo = v->hash_algo;
558 memcpy(_digp->signhash16, p, sizeof(_digp->signhash16));
565 rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen);
574 /*@-varuse =readonlytrans @*/
575 /*@observer@*/ /*@unchecked@*/
576 static const char * pgpPublicRSA[] = {
583 /*@observer@*/ /*@unchecked@*/
584 static const char * pgpSecretRSA[] = {
593 /*@observer@*/ /*@unchecked@*/
594 static const char * pgpPublicDSA[] = {
603 /*@observer@*/ /*@unchecked@*/
604 static const char * pgpSecretDSA[] = {
610 /*@observer@*/ /*@unchecked@*/
611 static const char * pgpPublicELGAMAL[] = {
619 /*@observer@*/ /*@unchecked@*/
620 static const char * pgpSecretELGAMAL[] = {
625 /*@=varuse =readonlytrans @*/
627 static const byte * pgpPrtPubkeyParams(byte pubkey_algo,
628 /*@returned@*/ const byte *p, const byte *h, unsigned int hlen)
629 /*@globals fileSystem, internalState @*/
630 /*@modifies fileSystem, internalState @*/
634 for (i = 0; p < &h[hlen]; i++, p += pgpMpiLen(p)) {
635 if (pubkey_algo == PGPPUBKEYALGO_RSA) {
640 (void) mpbsethex(&_dig->rsa_pk.n, pgpMpiHex(p));
641 if (_debug && _print)
642 fprintf(stderr, "\t n = "), mpfprintln(stderr, _dig->rsa_pk.n.size, _dig->rsa_pk.n.modl);
643 /*@switchbreak@*/ break;
645 (void) mpnsethex(&_dig->rsa_pk.e, pgpMpiHex(p));
646 if (_debug && _print)
647 fprintf(stderr, "\t e = "), mpfprintln(stderr, _dig->rsa_pk.e.size, _dig->rsa_pk.e.data);
648 /*@switchbreak@*/ break;
650 /*@switchbreak@*/ break;
653 pgpPrtStr("", pgpPublicRSA[i]);
654 } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
659 (void) mpbsethex(&_dig->p, pgpMpiHex(p));
660 if (_debug && _print)
661 fprintf(stderr, "\t p = "), mpfprintln(stderr, _dig->p.size, _dig->p.modl);
662 /*@switchbreak@*/ break;
664 (void) mpbsethex(&_dig->q, pgpMpiHex(p));
665 if (_debug && _print)
666 fprintf(stderr, "\t q = "), mpfprintln(stderr, _dig->q.size, _dig->q.modl);
667 /*@switchbreak@*/ break;
669 (void) mpnsethex(&_dig->g, pgpMpiHex(p));
670 if (_debug && _print)
671 fprintf(stderr, "\t g = "), mpfprintln(stderr, _dig->g.size, _dig->g.data);
672 /*@switchbreak@*/ break;
674 (void) mpnsethex(&_dig->y, pgpMpiHex(p));
675 if (_debug && _print)
676 fprintf(stderr, "\t y = "), mpfprintln(stderr, _dig->y.size, _dig->y.data);
677 /*@switchbreak@*/ break;
679 /*@switchbreak@*/ break;
682 pgpPrtStr("", pgpPublicDSA[i]);
683 } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
685 pgpPrtStr("", pgpPublicELGAMAL[i]);
688 fprintf(stderr, "%7d", i);
690 pgpPrtStr("", pgpMpiStr(p));
697 static const byte * pgpPrtSeckeyParams(/*@unused@*/ byte pubkey_algo,
698 /*@returned@*/ const byte *p, const byte *h, unsigned int hlen)
699 /*@globals fileSystem @*/
700 /*@modifies fileSystem @*/
706 pgpPrtVal(" ", pgpSymkeyTbl, *p);
710 pgpPrtVal(" ", pgpSymkeyTbl, *p);
713 pgpPrtVal(" simple ", pgpHashTbl, p[2]);
715 /*@innerbreak@*/ break;
717 pgpPrtVal(" salted ", pgpHashTbl, p[2]);
718 pgpPrtHex("", p+3, 8);
720 /*@innerbreak@*/ break;
722 pgpPrtVal(" iterated/salted ", pgpHashTbl, p[2]);
723 /*@-shiftnegative -shiftimplementation @*/ /* FIX: unsigned cast */
724 i = (16 + (p[11] & 0xf)) << ((p[11] >> 4) + 6);
725 /*@=shiftnegative =shiftimplementation @*/
726 pgpPrtHex("", p+3, 8);
727 pgpPrtInt(" iter", i);
729 /*@innerbreak@*/ break;
733 pgpPrtVal(" ", pgpSymkeyTbl, *p);
734 pgpPrtHex(" IV", p+1, 8);
742 #ifdef NOTYET /* XXX encrypted MPI's need to be handled. */
743 for (i = 0; p < &h[hlen]; i++, p += pgpMpiLen(p)) {
744 if (pubkey_algo == PGPPUBKEYALGO_RSA) {
745 if (pgpSecretRSA[i] == NULL) break;
746 pgpPrtStr("", pgpSecretRSA[i]);
747 } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
748 if (pgpSecretDSA[i] == NULL) break;
749 pgpPrtStr("", pgpSecretDSA[i]);
750 } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
751 if (pgpSecretELGAMAL[i] == NULL) break;
752 pgpPrtStr("", pgpSecretELGAMAL[i]);
755 fprintf(stderr, "%7d", i);
757 pgpPrtStr("", pgpMpiStr(p));
761 pgpPrtHex(" secret", p, (hlen - (p - h) - 2));
763 p += (hlen - (p - h) - 2);
765 pgpPrtHex(" checksum", p, 2);
771 int pgpPrtKey(pgpTag tag, const byte *h, unsigned int hlen)
773 /*@modifies *_digp @*/
783 { pgpPktKeyV3 v = (pgpPktKeyV3)h;
784 pgpPrtVal("V3 ", pgpTagTbl, tag);
785 pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
786 t = pgpGrab(v->time, sizeof(v->time));
788 fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
789 plen = pgpGrab(v->valid, sizeof(v->valid));
791 fprintf(stderr, " valid %u days", plen);
794 if (_digp && _digp->tag == tag) {
795 _digp->version = v->version;
796 memcpy(_digp->time, v->time, sizeof(_digp->time));
797 _digp->pubkey_algo = v->pubkey_algo;
800 p = ((byte *)v) + sizeof(*v);
801 p = pgpPrtPubkeyParams(v->pubkey_algo, p, h, hlen);
805 { pgpPktKeyV4 v = (pgpPktKeyV4)h;
806 pgpPrtVal("V4 ", pgpTagTbl, tag);
807 pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
808 t = pgpGrab(v->time, sizeof(v->time));
810 fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
813 if (_digp && _digp->tag == tag) {
814 _digp->version = v->version;
815 memcpy(_digp->time, v->time, sizeof(_digp->time));
816 _digp->pubkey_algo = v->pubkey_algo;
819 p = ((byte *)v) + sizeof(*v);
820 p = pgpPrtPubkeyParams(v->pubkey_algo, p, h, hlen);
821 if (!(tag == PGPTAG_PUBLIC_KEY || tag == PGPTAG_PUBLIC_SUBKEY))
822 p = pgpPrtSeckeyParams(v->pubkey_algo, p, h, hlen);
833 int pgpPrtUserID(pgpTag tag, const byte *h, unsigned int hlen)
835 /*@modifies *_digp @*/
837 pgpPrtVal("", pgpTagTbl, tag);
839 fprintf(stderr, " \"%.*s\"", (int)hlen, (const char *)h);
843 _digp->userid = t = memcpy(xmalloc(hlen+1), h, hlen);
850 int pgpPrtComment(pgpTag tag, const byte *h, unsigned int hlen)
854 pgpPrtVal("", pgpTagTbl, tag);
856 fprintf(stderr, " ");
859 if (*h >= ' ' && *h <= 'z') {
861 fprintf(stderr, "%s", (const char *)h);
862 j = strlen((const char*)h);
876 int pgpPubkeyFingerprint(const byte * pkt, /*@unused@*/ unsigned int pktlen,
882 int rc = -1; /* assume failure. */
890 { pgpPktKeyV3 v = (pgpPktKeyV3) (pkt + 3);
892 s += sizeof(pkt[0]) + sizeof(pkt[1]) + sizeof(pkt[2]) + sizeof(*v);
893 switch (v->pubkey_algo) {
894 case PGPPUBKEYALGO_RSA:
895 s += (pgpMpiLen(s) - 8);
897 memmove(keyid, s, 8);
900 /*@innerbreak@*/ break;
901 default: /* TODO: md5 of mpi bodies (i.e. no length) */
902 /*@innerbreak@*/ break;
906 { pgpPktKeyV4 v = (pgpPktKeyV4) (pkt + 3);
910 s += sizeof(pkt[0]) + sizeof(pkt[1]) + sizeof(pkt[2]) + sizeof(*v);
911 switch (v->pubkey_algo) {
912 case PGPPUBKEYALGO_RSA:
913 for (i = 0; i < 2; i++)
915 /*@innerbreak@*/ break;
916 case PGPPUBKEYALGO_DSA:
917 for (i = 0; i < 4; i++)
919 /*@innerbreak@*/ break;
922 ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
923 (void) rpmDigestUpdate(ctx, pkt, (s-pkt));
924 (void) rpmDigestFinal(ctx, (void **)&SHA1, NULL, 0);
928 memmove(keyid, s, 8);
932 if (SHA1) free(SHA1);
938 int pgpPrtPkt(const byte *pkt, unsigned int pleft)
940 unsigned int val = *pkt;
945 unsigned int hlen = 0;
948 /* XXX can't deal with these. */
954 plen = pgpLen(pkt+1, &hlen);
956 tag = (val >> 2) & 0xf;
957 plen = (1 << (val & 0x3));
958 hlen = pgpGrab(pkt+1, plen);
961 pktlen = 1 + plen + hlen;
967 case PGPTAG_SIGNATURE:
968 rc = pgpPrtSig(tag, h, hlen);
970 case PGPTAG_PUBLIC_KEY:
971 /* Get the public key fingerprint. */
974 if (!pgpPubkeyFingerprint(pkt, pktlen, _digp->signid))
975 _digp->saved |= PGPDIG_SAVED_ID;
977 memset(_digp->signid, 0, sizeof(_digp->signid));
981 case PGPTAG_PUBLIC_SUBKEY:
982 rc = pgpPrtKey(tag, h, hlen);
984 case PGPTAG_SECRET_KEY:
985 case PGPTAG_SECRET_SUBKEY:
986 rc = pgpPrtKey(tag, h, hlen);
989 rc = pgpPrtUserID(tag, h, hlen);
992 case PGPTAG_COMMENT_OLD:
993 rc = pgpPrtComment(tag, h, hlen);
996 case PGPTAG_RESERVED:
997 case PGPTAG_PUBLIC_SESSION_KEY:
998 case PGPTAG_SYMMETRIC_SESSION_KEY:
999 case PGPTAG_COMPRESSED_DATA:
1000 case PGPTAG_SYMMETRIC_DATA:
1002 case PGPTAG_LITERAL_DATA:
1004 case PGPTAG_PHOTOID:
1005 case PGPTAG_ENCRYPTED_MDC:
1007 case PGPTAG_PRIVATE_60:
1008 case PGPTAG_PRIVATE_62:
1009 case PGPTAG_CONTROL:
1011 pgpPrtVal("", pgpTagTbl, tag);
1012 pgpPrtHex("", h, hlen);
1017 return (rc ? -1 : pktlen);
1020 pgpDig pgpNewDig(void)
1022 pgpDig dig = xcalloc(1, sizeof(*dig));
1027 void pgpCleanDig(pgpDig dig)
1031 dig->signature.userid = _free(dig->signature.userid);
1032 dig->pubkey.userid = _free(dig->pubkey.userid);
1033 dig->signature.hash = _free(dig->signature.hash);
1034 dig->pubkey.hash = _free(dig->pubkey.hash);
1035 /*@-unqualifiedtrans@*/ /* FIX: double indirection */
1036 for (i = 0; i < 4; i++) {
1037 dig->signature.params[i] = _free(dig->signature.params[i]);
1038 dig->pubkey.params[i] = _free(dig->pubkey.params[i]);
1040 /*@=unqualifiedtrans@*/
1042 memset(&dig->signature, 0, sizeof(dig->signature));
1043 memset(&dig->pubkey, 0, sizeof(dig->pubkey));
1045 dig->md5 = _free(dig->md5);
1046 dig->sha1 = _free(dig->sha1);
1051 (void) rsapkFree(&dig->rsa_pk);
1054 mpnfree(&dig->rsahm);
1062 pgpDig pgpFreeDig(/*@only@*/ /*@null@*/ pgpDig dig)
1067 /* DUmp the signature/pubkey data. */
1071 if (dig->hdrsha1ctx != NULL)
1072 (void) rpmDigestFinal(dig->hdrsha1ctx, NULL, NULL, 0);
1074 dig->hdrsha1ctx = NULL;
1077 if (dig->sha1ctx != NULL)
1078 (void) rpmDigestFinal(dig->sha1ctx, NULL, NULL, 0);
1080 dig->sha1ctx = NULL;
1092 if (dig->hdrmd5ctx != NULL)
1093 (void) rpmDigestFinal(dig->hdrmd5ctx, NULL, NULL, 0);
1095 dig->hdrmd5ctx = NULL;
1099 if (dig->md5ctx != NULL)
1100 (void) rpmDigestFinal(dig->md5ctx, NULL, NULL, 0);
1104 mpbfree(&dig->rsa_pk.n);
1105 mpnfree(&dig->rsa_pk.e);
1115 int pgpPrtPkts(const byte * pkts, unsigned int pktlen, pgpDig dig, int printing)
1116 /*@globals _dig, _digp, _print @*/
1117 /*@modifies _dig, _digp, *_digp, _print @*/
1119 unsigned int val = *pkts;
1126 if (dig != NULL && (val & 0x80)) {
1127 pgpTag tag = (val & 0x40) ? (val & 0x3f) : ((val >> 2) & 0xf);
1128 _digp = (tag == PGPTAG_SIGNATURE) ? &_dig->signature : &_dig->pubkey;
1133 for (p = pkts, pleft = pktlen; p < (pkts + pktlen); p += len, pleft -= len) {
1134 len = pgpPrtPkt(p, pleft);
1137 if (len > pleft) /* XXX shouldn't happen */
1144 pgpArmor pgpReadPkts(const char * fn, const byte ** pkt, size_t * pktlen)
1146 const byte * b = NULL;
1148 const char * enc = NULL;
1149 const char * crcenc = NULL;
1154 uint32_t crcpkt, crc;
1155 const char * armortype = NULL;
1158 pgpArmor ec = PGPARMOR_ERR_NO_BEGIN_PGP; /* XXX assume failure */
1161 rc = rpmioSlurp(fn, &b, &blen);
1162 if (rc || b == NULL || blen <= 0) {
1167 #ifdef NOTYET /* XXX ASCII Pubkeys only, please. */
1168 ec = 0; /* XXX fish out pkt type. */
1173 #define TOKEQ(_s, _tok) (!strncmp((_s), (_tok), sizeof(_tok)-1))
1175 for (t = (char *)b; t && *t; t = te) {
1176 if ((te = strchr(t, '\n')) == NULL)
1184 if (!TOKEQ(t, "-----BEGIN PGP "))
1186 t += sizeof("-----BEGIN PGP ")-1;
1188 rc = pgpValTok(pgpArmorTbl, t, te);
1190 ec = PGPARMOR_ERR_UNKNOWN_ARMOR_TYPE;
1193 if (rc != PGPARMOR_PUBKEY) /* XXX ASCII Pubkeys only, please. */
1197 t = te - (sizeof("-----\n")-1);
1198 if (!TOKEQ(t, "-----\n"))
1202 /*@switchbreak@*/ break;
1205 rc = pgpValTok(pgpArmorKeyTbl, t, te);
1212 enc = te; /* Start of encoded packets */
1214 /*@switchbreak@*/ break;
1219 *t++ = '\0'; /* Terminate encoded packets */
1220 crcenc = t; /* Start of encoded crc */
1222 /*@switchbreak@*/ break;
1225 if (!TOKEQ(t, "-----END PGP ")) {
1226 ec = PGPARMOR_ERR_NO_END_PGP;
1229 *t = '\0'; /* Terminate encoded crc */
1230 t += sizeof("-----END PGP ")-1;
1231 if (t >= te) continue;
1233 if (armortype == NULL) /* XXX can't happen */
1235 rc = strncmp(t, armortype, strlen(armortype));
1239 t += strlen(armortype);
1240 if (t >= te) continue;
1242 if (!TOKEQ(t, "-----")) {
1243 ec = PGPARMOR_ERR_NO_END_PGP;
1246 t += (sizeof("-----")-1);
1247 if (t >= te) continue;
1248 /* XXX permitting \r here is not RFC-2440 compliant <shrug> */
1249 if (!(*t == '\n' || *t == '\r')) continue;
1253 if (b64decode(crcenc, (void **)&crcdec, &crclen) != 0) {
1254 ec = PGPARMOR_ERR_CRC_DECODE;
1257 crcpkt = pgpGrab(crcdec, crclen);
1258 crcdec = _free(crcdec);
1261 if (b64decode(enc, (void **)&dec, &declen) != 0) {
1262 ec = PGPARMOR_ERR_BODY_DECODE;
1265 crc = pgpCRC(dec, declen);
1266 if (crcpkt != crc) {
1267 ec = PGPARMOR_ERR_CRC_CHECK;
1273 ec = PGPARMOR_PUBKEY; /* XXX ASCII Pubkeys only, please. */
1275 /*@notreached@*/ /*@switchbreak@*/ break;
1281 if (ec > PGPARMOR_NONE && pkt)
1291 char * pgpArmorWrap(int atype, const unsigned char * s, size_t ns)
1299 nt = ((ns + 2) / 3) * 4;
1301 /* Add additional bytes necessary for eol string(s). */
1302 if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
1303 lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
1304 if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
1306 nt += lc * strlen(b64encode_eolstr);
1310 nt += 512; /* XXX slop for armor and crc */
1313 val = t = xmalloc(nt + 1);
1315 t = stpcpy(t, "-----BEGIN PGP ");
1316 t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
1318 t = stpcpy( stpcpy(t, "-----\nVersion: rpm-"), VERSION);
1320 t = stpcpy(t, " (beecrypt-4.1.2)\n\n");
1322 if ((enc = b64encode(s, ns)) != NULL) {
1325 if ((enc = b64crc(s, ns)) != NULL) {
1332 t = stpcpy(t, "-----END PGP ");
1333 t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
1334 t = stpcpy(t, "-----\n");