1 /** \ingroup rpmio signature
3 * Routines to handle RFC-2440 detached signatures.
8 #include <rpm/rpmstring.h>
10 #include "rpmio/digest.h"
11 #include "rpmio/rpmio_internal.h" /* XXX rpmioSlurp */
16 static int _debug = 0;
18 static int _print = 0;
20 static int _crypto_initialized = 0;
22 static pgpDig _dig = NULL;
24 static pgpDigParams _digp = NULL;
26 struct pgpValTbl_s const 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 const 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 const 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 const 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 const 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 struct pgpValTbl_s const pgpKeyServerPrefsTbl[] = {
94 { 0x80, "No-modify" },
95 { -1, "Unknown key server preference" },
98 struct pgpValTbl_s const pgpSubTypeTbl[] = {
99 { PGPSUBTYPE_SIG_CREATE_TIME,"signature creation time" },
100 { PGPSUBTYPE_SIG_EXPIRE_TIME,"signature expiration time" },
101 { PGPSUBTYPE_EXPORTABLE_CERT,"exportable certification" },
102 { PGPSUBTYPE_TRUST_SIG, "trust signature" },
103 { PGPSUBTYPE_REGEX, "regular expression" },
104 { PGPSUBTYPE_REVOCABLE, "revocable" },
105 { PGPSUBTYPE_KEY_EXPIRE_TIME,"key expiration time" },
106 { PGPSUBTYPE_ARR, "additional recipient request" },
107 { PGPSUBTYPE_PREFER_SYMKEY, "preferred symmetric algorithms" },
108 { PGPSUBTYPE_REVOKE_KEY, "revocation key" },
109 { PGPSUBTYPE_ISSUER_KEYID, "issuer key ID" },
110 { PGPSUBTYPE_NOTATION, "notation data" },
111 { PGPSUBTYPE_PREFER_HASH, "preferred hash algorithms" },
112 { PGPSUBTYPE_PREFER_COMPRESS,"preferred compression algorithms" },
113 { PGPSUBTYPE_KEYSERVER_PREFERS,"key server preferences" },
114 { PGPSUBTYPE_PREFER_KEYSERVER,"preferred key server" },
115 { PGPSUBTYPE_PRIMARY_USERID,"primary user id" },
116 { PGPSUBTYPE_POLICY_URL, "policy URL" },
117 { PGPSUBTYPE_KEY_FLAGS, "key flags" },
118 { PGPSUBTYPE_SIGNER_USERID, "signer's user id" },
119 { PGPSUBTYPE_REVOKE_REASON, "reason for revocation" },
120 { PGPSUBTYPE_FEATURES, "features" },
121 { PGPSUBTYPE_EMBEDDED_SIG, "embedded signature" },
123 { PGPSUBTYPE_INTERNAL_100, "internal subpkt type 100" },
124 { PGPSUBTYPE_INTERNAL_101, "internal subpkt type 101" },
125 { PGPSUBTYPE_INTERNAL_102, "internal subpkt type 102" },
126 { PGPSUBTYPE_INTERNAL_103, "internal subpkt type 103" },
127 { PGPSUBTYPE_INTERNAL_104, "internal subpkt type 104" },
128 { PGPSUBTYPE_INTERNAL_105, "internal subpkt type 105" },
129 { PGPSUBTYPE_INTERNAL_106, "internal subpkt type 106" },
130 { PGPSUBTYPE_INTERNAL_107, "internal subpkt type 107" },
131 { PGPSUBTYPE_INTERNAL_108, "internal subpkt type 108" },
132 { PGPSUBTYPE_INTERNAL_109, "internal subpkt type 109" },
133 { PGPSUBTYPE_INTERNAL_110, "internal subpkt type 110" },
134 { -1, "Unknown signature subkey type" },
137 struct pgpValTbl_s const pgpTagTbl[] = {
138 { PGPTAG_PUBLIC_SESSION_KEY,"Public-Key Encrypted Session Key" },
139 { PGPTAG_SIGNATURE, "Signature" },
140 { PGPTAG_SYMMETRIC_SESSION_KEY,"Symmetric-Key Encrypted Session Key" },
141 { PGPTAG_ONEPASS_SIGNATURE, "One-Pass Signature" },
142 { PGPTAG_SECRET_KEY, "Secret Key" },
143 { PGPTAG_PUBLIC_KEY, "Public Key" },
144 { PGPTAG_SECRET_SUBKEY, "Secret Subkey" },
145 { PGPTAG_COMPRESSED_DATA, "Compressed Data" },
146 { PGPTAG_SYMMETRIC_DATA, "Symmetrically Encrypted Data" },
147 { PGPTAG_MARKER, "Marker" },
148 { PGPTAG_LITERAL_DATA, "Literal Data" },
149 { PGPTAG_TRUST, "Trust" },
150 { PGPTAG_USER_ID, "User ID" },
151 { PGPTAG_PUBLIC_SUBKEY, "Public Subkey" },
152 { PGPTAG_COMMENT_OLD, "Comment (from OpenPGP draft)" },
153 { PGPTAG_PHOTOID, "PGP's photo ID" },
154 { PGPTAG_ENCRYPTED_MDC, "Integrity protected encrypted data" },
155 { PGPTAG_MDC, "Manipulaion detection code packet" },
156 { PGPTAG_PRIVATE_60, "Private #60" },
157 { PGPTAG_COMMENT, "Comment" },
158 { PGPTAG_PRIVATE_62, "Private #62" },
159 { PGPTAG_CONTROL, "Control (GPG)" },
160 { -1, "Unknown packet tag" },
163 struct pgpValTbl_s const pgpArmorTbl[] = {
164 { PGPARMOR_MESSAGE, "MESSAGE" },
165 { PGPARMOR_PUBKEY, "PUBLIC KEY BLOCK" },
166 { PGPARMOR_SIGNATURE, "SIGNATURE" },
167 { PGPARMOR_SIGNED_MESSAGE, "SIGNED MESSAGE" },
168 { PGPARMOR_FILE, "ARMORED FILE" },
169 { PGPARMOR_PRIVKEY, "PRIVATE KEY BLOCK" },
170 { PGPARMOR_SECKEY, "SECRET KEY BLOCK" },
171 { -1, "Unknown armor block" }
174 struct pgpValTbl_s const pgpArmorKeyTbl[] = {
175 { PGPARMORKEY_VERSION, "Version: " },
176 { PGPARMORKEY_COMMENT, "Comment: " },
177 { PGPARMORKEY_MESSAGEID, "MessageID: " },
178 { PGPARMORKEY_HASH, "Hash: " },
179 { PGPARMORKEY_CHARSET, "Charset: " },
180 { -1, "Unknown armor key" }
183 static void pgpPrtNL(void)
186 fprintf(stderr, "\n");
189 static void pgpPrtInt(const char *pre, int i)
193 fprintf(stderr, "%s", pre);
194 fprintf(stderr, " %d", i);
197 static void pgpPrtStr(const char *pre, const char *s)
201 fprintf(stderr, "%s", pre);
202 fprintf(stderr, " %s", s);
205 static void pgpPrtHex(const char *pre, const uint8_t *p, size_t plen)
210 fprintf(stderr, "%s", pre);
211 hex = pgpHexStr(p, plen);
212 fprintf(stderr, " %s", hex);
216 void pgpPrtVal(const char * pre, pgpValTbl vs, uint8_t val)
220 fprintf(stderr, "%s", pre);
221 fprintf(stderr, "%s(%u)", pgpValStr(vs, val), (unsigned)val);
225 * @return 0 on success
227 static int pgpMpiSet(const char * pre, int lbits,
228 void *dest, const uint8_t * p, const uint8_t * pend)
230 unsigned int mbits = pgpMpiBits(p);
236 if ((p + ((mbits+7) >> 3)) > pend)
242 nbits = (lbits > mbits ? lbits : mbits);
243 nbytes = ((nbits + 7) >> 3);
244 ix = (nbits - mbits) >> 3;
247 fprintf(stderr, "*** mbits %u nbits %u nbytes %zu ix %u\n", mbits, nbits, nbytes, ix);
248 if (ix > 0) memset(t, '\0', ix);
249 memcpy(t+ix, p+2, nbytes-ix);
251 fprintf(stderr, "*** %s %s\n", pre, pgpHexStr(dest, nbytes));
257 * @return NULL on error
259 static SECItem *pgpMpiItem(PRArenaPool *arena, SECItem *item, const uint8_t *p)
261 size_t nbytes = pgpMpiLen(p)-2;
264 if ((item=SECITEM_AllocItem(arena, item, nbytes)) == NULL)
268 item->data = PORT_ArenaGrow(arena, item->data, item->len, nbytes);
270 item->data = PORT_Realloc(item->data, nbytes);
272 if (item->data == NULL) {
274 SECITEM_FreeItem(item, PR_TRUE);
279 memcpy(item->data, p+2, nbytes);
285 static SECKEYPublicKey *pgpNewPublicKey(KeyType type)
288 SECKEYPublicKey *key;
290 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
294 key = PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
297 PORT_FreeArena(arena, PR_FALSE);
302 key->pkcs11ID = CK_INVALID_HANDLE;
303 key->pkcs11Slot = NULL;
308 static SECKEYPublicKey *pgpNewRSAKey(void)
310 return pgpNewPublicKey(rsaKey);
313 static SECKEYPublicKey *pgpNewDSAKey(void)
315 return pgpNewPublicKey(dsaKey);
318 int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype)
320 const uint8_t *p = h;
324 i = pgpLen(p, &plen);
328 pgpPrtVal(" ", pgpSubTypeTbl, (p[0]&(~PGPSUBTYPE_CRITICAL)));
329 if (p[0] & PGPSUBTYPE_CRITICAL)
331 fprintf(stderr, " *CRITICAL*");
333 case PGPSUBTYPE_PREFER_SYMKEY: /* preferred symmetric algorithms */
334 for (i = 1; i < plen; i++)
335 pgpPrtVal(" ", pgpSymkeyTbl, p[i]);
337 case PGPSUBTYPE_PREFER_HASH: /* preferred hash algorithms */
338 for (i = 1; i < plen; i++)
339 pgpPrtVal(" ", pgpHashTbl, p[i]);
341 case PGPSUBTYPE_PREFER_COMPRESS:/* preferred compression algorithms */
342 for (i = 1; i < plen; i++)
343 pgpPrtVal(" ", pgpCompressionTbl, p[i]);
345 case PGPSUBTYPE_KEYSERVER_PREFERS:/* key server preferences */
346 for (i = 1; i < plen; i++)
347 pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]);
349 case PGPSUBTYPE_SIG_CREATE_TIME:
350 if (_digp && !(_digp->saved & PGPDIG_SAVED_TIME) &&
351 (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
353 _digp->saved |= PGPDIG_SAVED_TIME;
354 memcpy(_digp->time, p+1, sizeof(_digp->time));
356 case PGPSUBTYPE_SIG_EXPIRE_TIME:
357 case PGPSUBTYPE_KEY_EXPIRE_TIME:
358 if ((plen - 1) == 4) {
359 time_t t = pgpGrab(p+1, plen-1);
361 fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
363 pgpPrtHex("", p+1, plen-1);
366 case PGPSUBTYPE_ISSUER_KEYID: /* issuer key ID */
367 if (_digp && !(_digp->saved & PGPDIG_SAVED_ID) &&
368 (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
370 _digp->saved |= PGPDIG_SAVED_ID;
371 memcpy(_digp->signid, p+1, sizeof(_digp->signid));
373 case PGPSUBTYPE_EXPORTABLE_CERT:
374 case PGPSUBTYPE_TRUST_SIG:
375 case PGPSUBTYPE_REGEX:
376 case PGPSUBTYPE_REVOCABLE:
378 case PGPSUBTYPE_REVOKE_KEY:
379 case PGPSUBTYPE_NOTATION:
380 case PGPSUBTYPE_PREFER_KEYSERVER:
381 case PGPSUBTYPE_PRIMARY_USERID:
382 case PGPSUBTYPE_POLICY_URL:
383 case PGPSUBTYPE_KEY_FLAGS:
384 case PGPSUBTYPE_SIGNER_USERID:
385 case PGPSUBTYPE_REVOKE_REASON:
386 case PGPSUBTYPE_FEATURES:
387 case PGPSUBTYPE_EMBEDDED_SIG:
388 case PGPSUBTYPE_INTERNAL_100:
389 case PGPSUBTYPE_INTERNAL_101:
390 case PGPSUBTYPE_INTERNAL_102:
391 case PGPSUBTYPE_INTERNAL_103:
392 case PGPSUBTYPE_INTERNAL_104:
393 case PGPSUBTYPE_INTERNAL_105:
394 case PGPSUBTYPE_INTERNAL_106:
395 case PGPSUBTYPE_INTERNAL_107:
396 case PGPSUBTYPE_INTERNAL_108:
397 case PGPSUBTYPE_INTERNAL_109:
398 case PGPSUBTYPE_INTERNAL_110:
400 pgpPrtHex("", p+1, plen-1);
410 static const char * const pgpSigRSA[] = {
415 static const char * const pgpSigDSA[] = {
421 #ifndef DSA_SUBPRIME_LEN
422 #define DSA_SUBPRIME_LEN 20
425 static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo, uint8_t sigtype,
426 const uint8_t *p, const uint8_t *h, size_t hlen)
428 const uint8_t * pend = h + hlen;
431 unsigned char dsabuf[2*DSA_SUBPRIME_LEN];
435 dsaraw.data = dsabuf;
436 dsaraw.len = sizeof(dsabuf);
438 for (i = 0; p < pend; i++, p += pgpMpiLen(p)) {
439 if (pubkey_algo == PGPPUBKEYALGO_RSA) {
442 (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
446 _dig->rsasig = pgpMpiItem(NULL, _dig->rsasig, p);
447 if (_dig->rsasig == NULL)
454 pgpPrtStr("", pgpSigRSA[i]);
455 } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
458 (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
464 memset(dsaraw.data, '\0', 2*DSA_SUBPRIME_LEN);
466 xx = pgpMpiSet(pgpSigDSA[i], DSA_SUBPRIME_LEN*8, dsaraw.data, p, pend);
469 xx = pgpMpiSet(pgpSigDSA[i], DSA_SUBPRIME_LEN*8, dsaraw.data + DSA_SUBPRIME_LEN, p, pend);
470 if (_dig->dsasig != NULL)
471 SECITEM_FreeItem(_dig->dsasig, PR_FALSE);
472 else if ((_dig->dsasig=SECITEM_AllocItem(NULL, NULL, 0)) == NULL) {
476 if (DSAU_EncodeDerSig(_dig->dsasig, &dsaraw) != SECSuccess)
485 pgpPrtStr("", pgpSigDSA[i]);
488 fprintf(stderr, "%7zd", i);
499 int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen)
501 uint8_t version = h[0];
508 { pgpPktSigV3 v = (pgpPktSigV3)h;
514 pgpPrtVal("V3 ", pgpTagTbl, tag);
515 pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
516 pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
517 pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
519 t = pgpGrab(v->time, sizeof(v->time));
521 fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
523 pgpPrtHex(" signer keyid", v->signid, sizeof(v->signid));
524 plen = pgpGrab(v->signhash16, sizeof(v->signhash16));
525 pgpPrtHex(" signhash16", v->signhash16, sizeof(v->signhash16));
528 if (_digp && _digp->pubkey_algo == 0) {
529 _digp->version = v->version;
530 _digp->hashlen = v->hashlen;
531 _digp->sigtype = v->sigtype;
532 _digp->hash = memcpy(xmalloc(v->hashlen), &v->sigtype, v->hashlen);
533 memcpy(_digp->time, v->time, sizeof(_digp->time));
534 memcpy(_digp->signid, v->signid, sizeof(_digp->signid));
535 _digp->pubkey_algo = v->pubkey_algo;
536 _digp->hash_algo = v->hash_algo;
537 memcpy(_digp->signhash16, v->signhash16, sizeof(_digp->signhash16));
540 p = ((uint8_t *)v) + sizeof(*v);
541 rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen);
544 { pgpPktSigV4 v = (pgpPktSigV4)h;
546 pgpPrtVal("V4 ", pgpTagTbl, tag);
547 pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
548 pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
549 pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
553 plen = pgpGrab(v->hashlen, sizeof(v->hashlen));
554 p += sizeof(v->hashlen);
556 if ((p + plen) > (h + hlen))
559 if (_debug && _print)
560 fprintf(stderr, " hash[%zu] -- %s\n", plen, pgpHexStr(p, plen));
561 if (_digp && _digp->pubkey_algo == 0) {
562 _digp->hashlen = sizeof(*v) + plen;
563 _digp->hash = memcpy(xmalloc(_digp->hashlen), v, _digp->hashlen);
565 (void) pgpPrtSubType(p, plen, v->sigtype);
571 if ((p + plen) > (h + hlen))
574 if (_debug && _print)
575 fprintf(stderr, " unhash[%zu] -- %s\n", plen, pgpHexStr(p, plen));
576 (void) pgpPrtSubType(p, plen, v->sigtype);
580 pgpPrtHex(" signhash16", p, 2);
583 if (_digp && _digp->pubkey_algo == 0) {
584 _digp->version = v->version;
585 _digp->sigtype = v->sigtype;
586 _digp->pubkey_algo = v->pubkey_algo;
587 _digp->hash_algo = v->hash_algo;
588 memcpy(_digp->signhash16, p, sizeof(_digp->signhash16));
595 rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen);
604 static const char * const pgpPublicRSA[] = {
611 static const char * const pgpSecretRSA[] = {
620 static const char * const pgpPublicDSA[] = {
629 static const char * const pgpSecretDSA[] = {
635 static const char * const pgpPublicELGAMAL[] = {
643 static const char * const pgpSecretELGAMAL[] = {
649 char * pgpHexStr(const uint8_t *p, size_t plen)
652 str = t = xmalloc(plen * 2 + 1);
653 static char const hex[] = "0123456789abcdef";
657 *t++ = hex[ (i >> 4) & 0xf ];
658 *t++ = hex[ (i ) & 0xf ];
664 static const uint8_t * pgpPrtPubkeyParams(uint8_t pubkey_algo,
665 const uint8_t *p, const uint8_t *h, size_t hlen)
669 for (i = 0; p < &h[hlen]; i++, p += pgpMpiLen(p)) {
671 if (pubkey_algo == PGPPUBKEYALGO_RSA) {
674 if (_dig->rsa == NULL) {
675 _dig->rsa = pgpNewRSAKey();
676 if (_dig->rsa == NULL)
677 break; /* error abort? */
681 pgpMpiItem(_dig->rsa->arena, &_dig->rsa->u.rsa.modulus, p);
684 pgpMpiItem(_dig->rsa->arena, &_dig->rsa->u.rsa.publicExponent, p);
690 pgpPrtStr("", pgpPublicRSA[i]);
691 } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
694 if (_dig->dsa == NULL) {
695 _dig->dsa = pgpNewDSAKey();
696 if (_dig->dsa == NULL)
697 break; /* error abort? */
701 pgpMpiItem(_dig->dsa->arena, &_dig->dsa->u.dsa.params.prime, p);
704 pgpMpiItem(_dig->dsa->arena, &_dig->dsa->u.dsa.params.subPrime, p);
707 pgpMpiItem(_dig->dsa->arena, &_dig->dsa->u.dsa.params.base, p);
710 pgpMpiItem(_dig->dsa->arena, &_dig->dsa->u.dsa.publicValue, p);
716 pgpPrtStr("", pgpPublicDSA[i]);
717 } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
719 pgpPrtStr("", pgpPublicELGAMAL[i]);
722 fprintf(stderr, "%7zd", i);
733 static const uint8_t * pgpPrtSeckeyParams(uint8_t pubkey_algo,
734 const uint8_t *p, const uint8_t *h, size_t hlen)
740 pgpPrtVal(" ", pgpSymkeyTbl, *p);
744 pgpPrtVal(" ", pgpSymkeyTbl, *p);
747 pgpPrtVal(" simple ", pgpHashTbl, p[2]);
751 pgpPrtVal(" salted ", pgpHashTbl, p[2]);
752 pgpPrtHex("", p+3, 8);
756 pgpPrtVal(" iterated/salted ", pgpHashTbl, p[2]);
757 /* FIX: unsigned cast */
758 i = (16 + (p[11] & 0xf)) << ((p[11] >> 4) + 6);
759 pgpPrtHex("", p+3, 8);
760 pgpPrtInt(" iter", i);
766 pgpPrtVal(" ", pgpSymkeyTbl, *p);
767 pgpPrtHex(" IV", p+1, 8);
775 #ifdef NOTYET /* XXX encrypted MPI's need to be handled. */
776 for (i = 0; p < &h[hlen]; i++, p += pgpMpiLen(p)) {
778 if (pubkey_algo == PGPPUBKEYALGO_RSA) {
779 if (pgpSecretRSA[i] == NULL) break;
780 pgpPrtStr("", pgpSecretRSA[i]);
781 } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
782 if (pgpSecretDSA[i] == NULL) break;
783 pgpPrtStr("", pgpSecretDSA[i]);
784 } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
785 if (pgpSecretELGAMAL[i] == NULL) break;
786 pgpPrtStr("", pgpSecretELGAMAL[i]);
789 fprintf(stderr, "%7d", i);
797 pgpPrtHex(" secret", p, (hlen - (p - h) - 2));
799 p += (hlen - (p - h) - 2);
801 pgpPrtHex(" checksum", p, 2);
807 int pgpPrtKey(pgpTag tag, const uint8_t *h, size_t hlen)
809 uint8_t version = *h;
817 { pgpPktKeyV3 v = (pgpPktKeyV3)h;
818 pgpPrtVal("V3 ", pgpTagTbl, tag);
819 pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
820 t = pgpGrab(v->time, sizeof(v->time));
822 fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
823 plen = pgpGrab(v->valid, sizeof(v->valid));
825 fprintf(stderr, " valid %zu days", plen);
828 if (_digp && _digp->tag == tag) {
829 _digp->version = v->version;
830 memcpy(_digp->time, v->time, sizeof(_digp->time));
831 _digp->pubkey_algo = v->pubkey_algo;
834 p = ((uint8_t *)v) + sizeof(*v);
835 p = pgpPrtPubkeyParams(v->pubkey_algo, p, h, hlen);
839 { pgpPktKeyV4 v = (pgpPktKeyV4)h;
840 pgpPrtVal("V4 ", pgpTagTbl, tag);
841 pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
842 t = pgpGrab(v->time, sizeof(v->time));
844 fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
847 if (_digp && _digp->tag == tag) {
848 _digp->version = v->version;
849 memcpy(_digp->time, v->time, sizeof(_digp->time));
850 _digp->pubkey_algo = v->pubkey_algo;
853 p = ((uint8_t *)v) + sizeof(*v);
854 p = pgpPrtPubkeyParams(v->pubkey_algo, p, h, hlen);
855 if (!(tag == PGPTAG_PUBLIC_KEY || tag == PGPTAG_PUBLIC_SUBKEY))
856 p = pgpPrtSeckeyParams(v->pubkey_algo, p, h, hlen);
866 int pgpPrtUserID(pgpTag tag, const uint8_t *h, size_t hlen)
868 pgpPrtVal("", pgpTagTbl, tag);
870 fprintf(stderr, " \"%.*s\"", (int)hlen, (const char *)h);
874 _digp->userid = t = memcpy(xmalloc(hlen+1), h, hlen);
880 int pgpPrtComment(pgpTag tag, const uint8_t *h, size_t hlen)
884 pgpPrtVal("", pgpTagTbl, tag);
886 fprintf(stderr, " ");
889 if (*h >= ' ' && *h <= 'z') {
891 fprintf(stderr, "%s", (const char *)h);
892 j = strlen((const char*)h);
906 int pgpPubkeyFingerprint(const uint8_t * pkt, size_t pktlen, pgpKeyID_t keyid)
908 unsigned int val = *pkt;
911 const uint8_t *se, *h;
913 int rc = -1; /* assume failure. */
920 plen = pgpLen(pkt+1, &hlen);
922 tag = (val >> 2) & 0xf;
923 plen = (1 << (val & 0x3));
924 hlen = pgpGrab(pkt+1, plen);
926 if (pktlen > 0 && 1 + plen + hlen > pktlen)
933 { pgpPktKeyV3 v = (pgpPktKeyV3) (h);
934 se = (uint8_t *)(v + 1);
935 switch (v->pubkey_algo) {
936 case PGPPUBKEYALGO_RSA:
938 memmove(keyid, (se-8), 8);
941 default: /* TODO: md5 of mpi bodies (i.e. no length) */
946 { pgpPktKeyV4 v = (pgpPktKeyV4) (h);
951 se = (uint8_t *)(v + 1);
952 switch (v->pubkey_algo) {
953 case PGPPUBKEYALGO_RSA:
954 for (i = 0; i < 2; i++)
957 case PGPPUBKEYALGO_DSA:
958 for (i = 0; i < 4; i++)
963 ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
964 (void) rpmDigestUpdate(ctx, pkt, (se-pkt));
965 (void) rpmDigestFinal(ctx, (void **)&d, &dlen, 0);
967 memmove(keyid, (d + (dlen-8)), 8);
976 int pgpExtractPubkeyFingerprint(const char * b64pkt, pgpKeyID_t keyid)
981 if (b64decode(b64pkt, (void **)&pkt, &pktlen))
982 return -1; /* on error */
983 (void) pgpPubkeyFingerprint(pkt, pktlen, keyid);
985 return sizeof(keyid); /* no. of bytes of pubkey signid */
988 int pgpPrtPkt(const uint8_t *pkt, size_t pleft)
990 unsigned int val = *pkt;
998 /* XXX can't deal with these. */
1004 plen = pgpLen(pkt+1, &hlen);
1006 tag = (val >> 2) & 0xf;
1007 plen = (1 << (val & 0x3));
1008 hlen = pgpGrab(pkt+1, plen);
1011 pktlen = 1 + plen + hlen;
1017 case PGPTAG_SIGNATURE:
1018 rc = pgpPrtSig(tag, h, hlen);
1020 case PGPTAG_PUBLIC_KEY:
1021 /* Get the public key fingerprint. */
1023 if (!pgpPubkeyFingerprint(pkt, pktlen, _digp->signid))
1024 _digp->saved |= PGPDIG_SAVED_ID;
1026 memset(_digp->signid, 0, sizeof(_digp->signid));
1028 case PGPTAG_PUBLIC_SUBKEY:
1029 rc = pgpPrtKey(tag, h, hlen);
1031 case PGPTAG_SECRET_KEY:
1032 case PGPTAG_SECRET_SUBKEY:
1033 rc = pgpPrtKey(tag, h, hlen);
1035 case PGPTAG_USER_ID:
1036 rc = pgpPrtUserID(tag, h, hlen);
1038 case PGPTAG_COMMENT:
1039 case PGPTAG_COMMENT_OLD:
1040 rc = pgpPrtComment(tag, h, hlen);
1043 case PGPTAG_RESERVED:
1044 case PGPTAG_PUBLIC_SESSION_KEY:
1045 case PGPTAG_SYMMETRIC_SESSION_KEY:
1046 case PGPTAG_COMPRESSED_DATA:
1047 case PGPTAG_SYMMETRIC_DATA:
1049 case PGPTAG_LITERAL_DATA:
1051 case PGPTAG_PHOTOID:
1052 case PGPTAG_ENCRYPTED_MDC:
1054 case PGPTAG_PRIVATE_60:
1055 case PGPTAG_PRIVATE_62:
1056 case PGPTAG_CONTROL:
1058 pgpPrtVal("", pgpTagTbl, tag);
1059 pgpPrtHex("", h, hlen);
1064 return (rc ? -1 : pktlen);
1067 pgpDig pgpNewDig(void)
1069 pgpDig dig = xcalloc(1, sizeof(*dig));
1074 void pgpCleanDig(pgpDig dig)
1078 dig->signature.userid = _free(dig->signature.userid);
1079 dig->pubkey.userid = _free(dig->pubkey.userid);
1080 dig->signature.hash = _free(dig->signature.hash);
1081 dig->pubkey.hash = _free(dig->pubkey.hash);
1082 /* FIX: double indirection */
1083 for (i = 0; i < 4; i++) {
1084 dig->signature.params[i] = _free(dig->signature.params[i]);
1085 dig->pubkey.params[i] = _free(dig->pubkey.params[i]);
1088 memset(&dig->signature, 0, sizeof(dig->signature));
1089 memset(&dig->pubkey, 0, sizeof(dig->pubkey));
1091 dig->md5 = _free(dig->md5);
1092 dig->sha1 = _free(dig->sha1);
1094 if (dig->dsa != NULL) {
1095 SECKEY_DestroyPublicKey(dig->dsa);
1099 if (dig->dsasig != NULL) {
1100 SECITEM_ZfreeItem(dig->dsasig, PR_TRUE);
1104 if (dig->rsa != NULL) {
1105 SECKEY_DestroyPublicKey(dig->rsa);
1109 if (dig->rsasig != NULL) {
1110 SECITEM_ZfreeItem(dig->rsasig, PR_TRUE);
1118 pgpDig pgpFreeDig(pgpDig dig)
1122 /* DUmp the signature/pubkey data. */
1125 if (dig->hdrsha1ctx != NULL)
1126 (void) rpmDigestFinal(dig->hdrsha1ctx, NULL, NULL, 0);
1127 dig->hdrsha1ctx = NULL;
1129 if (dig->sha1ctx != NULL)
1130 (void) rpmDigestFinal(dig->sha1ctx, NULL, NULL, 0);
1131 dig->sha1ctx = NULL;
1134 if (dig->hdrmd5ctx != NULL)
1135 (void) rpmDigestFinal(dig->hdrmd5ctx, NULL, NULL, 0);
1136 dig->hdrmd5ctx = NULL;
1139 if (dig->md5ctx != NULL)
1140 (void) rpmDigestFinal(dig->md5ctx, NULL, NULL, 0);
1148 int pgpPrtPkts(const uint8_t * pkts, size_t pktlen, pgpDig dig, int printing)
1150 unsigned int val = *pkts;
1157 if (dig != NULL && (val & 0x80)) {
1158 pgpTag tag = (val & 0x40) ? (val & 0x3f) : ((val >> 2) & 0xf);
1159 _digp = (tag == PGPTAG_SIGNATURE) ? &_dig->signature : &_dig->pubkey;
1164 for (p = pkts, pleft = pktlen; p < (pkts + pktlen); p += len, pleft -= len) {
1165 len = pgpPrtPkt(p, pleft);
1168 if (len > pleft) /* XXX shouldn't happen */
1174 pgpArmor pgpReadPkts(const char * fn, uint8_t ** pkt, size_t * pktlen)
1178 const char * enc = NULL;
1179 const char * crcenc = NULL;
1184 uint32_t crcpkt, crc;
1185 const char * armortype = NULL;
1188 pgpArmor ec = PGPARMOR_ERR_NO_BEGIN_PGP; /* XXX assume failure */
1191 rc = rpmioSlurp(fn, &b, &blen);
1192 if (rc || b == NULL || blen <= 0) {
1197 #ifdef NOTYET /* XXX ASCII Pubkeys only, please. */
1198 ec = 0; /* XXX fish out pkt type. */
1203 #define TOKEQ(_s, _tok) (!strncmp((_s), (_tok), sizeof(_tok)-1))
1205 for (t = (char *)b; t && *t; t = te) {
1206 if ((te = strchr(t, '\n')) == NULL)
1214 if (!TOKEQ(t, "-----BEGIN PGP "))
1216 t += sizeof("-----BEGIN PGP ")-1;
1218 rc = pgpValTok(pgpArmorTbl, t, te);
1220 ec = PGPARMOR_ERR_UNKNOWN_ARMOR_TYPE;
1223 if (rc != PGPARMOR_PUBKEY) /* XXX ASCII Pubkeys only, please. */
1227 t = te - (sizeof("-----\n")-1);
1228 if (!TOKEQ(t, "-----\n"))
1235 rc = pgpValTok(pgpArmorKeyTbl, t, te);
1242 enc = te; /* Start of encoded packets */
1249 *t++ = '\0'; /* Terminate encoded packets */
1250 crcenc = t; /* Start of encoded crc */
1255 if (!TOKEQ(t, "-----END PGP ")) {
1256 ec = PGPARMOR_ERR_NO_END_PGP;
1259 *t = '\0'; /* Terminate encoded crc */
1260 t += sizeof("-----END PGP ")-1;
1261 if (t >= te) continue;
1263 if (armortype == NULL) /* XXX can't happen */
1265 rc = strncmp(t, armortype, strlen(armortype));
1269 t += strlen(armortype);
1270 if (t >= te) continue;
1272 if (!TOKEQ(t, "-----")) {
1273 ec = PGPARMOR_ERR_NO_END_PGP;
1276 t += (sizeof("-----")-1);
1277 if (t >= te) continue;
1278 /* XXX permitting \r here is not RFC-2440 compliant <shrug> */
1279 if (!(*t == '\n' || *t == '\r')) continue;
1283 if (b64decode(crcenc, (void **)&crcdec, &crclen) != 0) {
1284 ec = PGPARMOR_ERR_CRC_DECODE;
1287 crcpkt = pgpGrab(crcdec, crclen);
1288 crcdec = _free(crcdec);
1291 if (b64decode(enc, (void **)&dec, &declen) != 0) {
1292 ec = PGPARMOR_ERR_BODY_DECODE;
1295 crc = pgpCRC(dec, declen);
1296 if (crcpkt != crc) {
1297 ec = PGPARMOR_ERR_CRC_CHECK;
1303 ec = PGPARMOR_PUBKEY; /* XXX ASCII Pubkeys only, please. */
1311 if (ec > PGPARMOR_NONE && pkt)
1320 char * pgpArmorWrap(int atype, const unsigned char * s, size_t ns)
1322 char *buf = NULL, *val = NULL;
1323 char *enc = b64encode(s, ns, -1);
1324 char *crc = b64crc(s, ns);
1325 const char *valstr = pgpValStr(pgpArmorTbl, atype);
1327 if (crc != NULL && enc != NULL) {
1328 rasprintf(&buf, "%s=%s", enc, crc);
1333 rasprintf(&val, "-----BEGIN PGP %s-----\nVersion: rpm-" VERSION " (NSS-3)\n\n"
1334 "%s-----END PGP %s-----\n",
1335 valstr, buf != NULL ? buf : "", valstr);
1341 int rpmInitCrypto(void) {
1344 if (!_crypto_initialized && NSS_NoDB_Init(NULL) != SECSuccess) {
1347 _crypto_initialized = 1;
1353 int rpmFreeCrypto(void)
1356 if (_crypto_initialized) {
1357 rc = (NSS_Shutdown() != SECSuccess);
1358 _crypto_initialized = 0;