1 /** \ingroup rpmio signature
2  * \file rpmio/rpmpgp.c
3  * Routines to handle RFC-2440 detached signatures.
4  */
5 
6 #include "system.h"
7 
8 #include <time.h>
9 #include <netinet/in.h>
10 #include <rpm/rpmstring.h>
11 #include <rpm/rpmlog.h>
12 #include <rpm/rpmbase64.h>
13 
14 #include "rpmio/digest.h"
15 #include "rpmio/rpmio_internal.h"	/* XXX rpmioSlurp */
16 
17 #include "debug.h"
18 
19 static int _print = 0;
20 
21 /** \ingroup rpmio
22  * Container for values parsed from an OpenPGP signature and public key.
23  */
24 struct pgpDig_s {
25     struct pgpDigParams_s * signature;
26     struct pgpDigParams_s * pubkey;
27 };
28 
29 typedef const struct pgpValTbl_s {
30     int val;
31     char const * const str;
32 } * pgpValTbl;
33 
34 static struct pgpValTbl_s const pgpSigTypeTbl[] = {
35     { PGPSIGTYPE_BINARY,	"Binary document signature" },
36     { PGPSIGTYPE_TEXT,		"Text document signature" },
37     { PGPSIGTYPE_STANDALONE,	"Standalone signature" },
38     { PGPSIGTYPE_GENERIC_CERT,	"Generic certification of a User ID and Public Key" },
39     { PGPSIGTYPE_PERSONA_CERT,	"Persona certification of a User ID and Public Key" },
40     { PGPSIGTYPE_CASUAL_CERT,	"Casual certification of a User ID and Public Key" },
41     { PGPSIGTYPE_POSITIVE_CERT,	"Positive certification of a User ID and Public Key" },
42     { PGPSIGTYPE_SUBKEY_BINDING,"Subkey Binding Signature" },
43     { PGPSIGTYPE_SIGNED_KEY,	"Signature directly on a key" },
44     { PGPSIGTYPE_KEY_REVOKE,	"Key revocation signature" },
45     { PGPSIGTYPE_SUBKEY_REVOKE,	"Subkey revocation signature" },
46     { PGPSIGTYPE_CERT_REVOKE,	"Certification revocation signature" },
47     { PGPSIGTYPE_TIMESTAMP,	"Timestamp signature" },
48     { -1,			"Unknown signature type" },
49 };
50 
51 static struct pgpValTbl_s const pgpPubkeyTbl[] = {
52     { PGPPUBKEYALGO_RSA,	"RSA" },
53     { PGPPUBKEYALGO_RSA_ENCRYPT,"RSA(Encrypt-Only)" },
54     { PGPPUBKEYALGO_RSA_SIGN,	"RSA(Sign-Only)" },
55     { PGPPUBKEYALGO_ELGAMAL_ENCRYPT,"Elgamal(Encrypt-Only)" },
56     { PGPPUBKEYALGO_DSA,	"DSA" },
57     { PGPPUBKEYALGO_EC,		"Elliptic Curve" },
58     { PGPPUBKEYALGO_ECDSA,	"ECDSA" },
59     { PGPPUBKEYALGO_ELGAMAL,	"Elgamal" },
60     { PGPPUBKEYALGO_DH,		"Diffie-Hellman (X9.42)" },
61     { PGPPUBKEYALGO_EDDSA,	"EdDSA" },
62     { -1,			"Unknown public key algorithm" },
63 };
64 
65 static struct pgpValTbl_s const pgpSymkeyTbl[] = {
66     { PGPSYMKEYALGO_PLAINTEXT,	"Plaintext" },
67     { PGPSYMKEYALGO_IDEA,	"IDEA" },
68     { PGPSYMKEYALGO_TRIPLE_DES,	"3DES" },
69     { PGPSYMKEYALGO_CAST5,	"CAST5" },
70     { PGPSYMKEYALGO_BLOWFISH,	"BLOWFISH" },
71     { PGPSYMKEYALGO_SAFER,	"SAFER" },
72     { PGPSYMKEYALGO_DES_SK,	"DES/SK" },
73     { PGPSYMKEYALGO_AES_128,	"AES(128-bit key)" },
74     { PGPSYMKEYALGO_AES_192,	"AES(192-bit key)" },
75     { PGPSYMKEYALGO_AES_256,	"AES(256-bit key)" },
76     { PGPSYMKEYALGO_TWOFISH,	"TWOFISH(256-bit key)" },
77     { PGPSYMKEYALGO_NOENCRYPT,	"no encryption" },
78     { -1,			"Unknown symmetric key algorithm" },
79 };
80 
81 static struct pgpValTbl_s const pgpCompressionTbl[] = {
82     { PGPCOMPRESSALGO_NONE,	"Uncompressed" },
83     { PGPCOMPRESSALGO_ZIP,	"ZIP" },
84     { PGPCOMPRESSALGO_ZLIB, 	"ZLIB" },
85     { PGPCOMPRESSALGO_BZIP2, 	"BZIP2" },
86     { -1,			"Unknown compression algorithm" },
87 };
88 
89 static struct pgpValTbl_s const pgpHashTbl[] = {
90     { PGPHASHALGO_MD5,		"MD5" },
91     { PGPHASHALGO_SHA1,		"SHA1" },
92     { PGPHASHALGO_RIPEMD160,	"RIPEMD160" },
93     { PGPHASHALGO_MD2,		"MD2" },
94     { PGPHASHALGO_TIGER192,	"TIGER192" },
95     { PGPHASHALGO_HAVAL_5_160,	"HAVAL-5-160" },
96     { PGPHASHALGO_SHA256,	"SHA256" },
97     { PGPHASHALGO_SHA384,	"SHA384" },
98     { PGPHASHALGO_SHA512,	"SHA512" },
99     { PGPHASHALGO_SHA224,	"SHA224" },
100     { -1,			"Unknown hash algorithm" },
101 };
102 
103 static struct pgpValTbl_s const pgpKeyServerPrefsTbl[] = {
104     { 0x80,			"No-modify" },
105     { -1,			"Unknown key server preference" },
106 };
107 
108 static struct pgpValTbl_s const pgpSubTypeTbl[] = {
109     { PGPSUBTYPE_SIG_CREATE_TIME,"signature creation time" },
110     { PGPSUBTYPE_SIG_EXPIRE_TIME,"signature expiration time" },
111     { PGPSUBTYPE_EXPORTABLE_CERT,"exportable certification" },
112     { PGPSUBTYPE_TRUST_SIG,	"trust signature" },
113     { PGPSUBTYPE_REGEX,		"regular expression" },
114     { PGPSUBTYPE_REVOCABLE,	"revocable" },
115     { PGPSUBTYPE_KEY_EXPIRE_TIME,"key expiration time" },
116     { PGPSUBTYPE_ARR,		"additional recipient request" },
117     { PGPSUBTYPE_PREFER_SYMKEY,	"preferred symmetric algorithms" },
118     { PGPSUBTYPE_REVOKE_KEY,	"revocation key" },
119     { PGPSUBTYPE_ISSUER_KEYID,	"issuer key ID" },
120     { PGPSUBTYPE_NOTATION,	"notation data" },
121     { PGPSUBTYPE_PREFER_HASH,	"preferred hash algorithms" },
122     { PGPSUBTYPE_PREFER_COMPRESS,"preferred compression algorithms" },
123     { PGPSUBTYPE_KEYSERVER_PREFERS,"key server preferences" },
124     { PGPSUBTYPE_PREFER_KEYSERVER,"preferred key server" },
125     { PGPSUBTYPE_PRIMARY_USERID,"primary user id" },
126     { PGPSUBTYPE_POLICY_URL,	"policy URL" },
127     { PGPSUBTYPE_KEY_FLAGS,	"key flags" },
128     { PGPSUBTYPE_SIGNER_USERID,	"signer's user id" },
129     { PGPSUBTYPE_REVOKE_REASON,	"reason for revocation" },
130     { PGPSUBTYPE_FEATURES,	"features" },
131     { PGPSUBTYPE_EMBEDDED_SIG,	"embedded signature" },
132 
133     { PGPSUBTYPE_INTERNAL_100,	"internal subpkt type 100" },
134     { PGPSUBTYPE_INTERNAL_101,	"internal subpkt type 101" },
135     { PGPSUBTYPE_INTERNAL_102,	"internal subpkt type 102" },
136     { PGPSUBTYPE_INTERNAL_103,	"internal subpkt type 103" },
137     { PGPSUBTYPE_INTERNAL_104,	"internal subpkt type 104" },
138     { PGPSUBTYPE_INTERNAL_105,	"internal subpkt type 105" },
139     { PGPSUBTYPE_INTERNAL_106,	"internal subpkt type 106" },
140     { PGPSUBTYPE_INTERNAL_107,	"internal subpkt type 107" },
141     { PGPSUBTYPE_INTERNAL_108,	"internal subpkt type 108" },
142     { PGPSUBTYPE_INTERNAL_109,	"internal subpkt type 109" },
143     { PGPSUBTYPE_INTERNAL_110,	"internal subpkt type 110" },
144     { -1,			"Unknown signature subkey type" },
145 };
146 
147 static struct pgpValTbl_s const pgpTagTbl[] = {
148     { PGPTAG_PUBLIC_SESSION_KEY,"Public-Key Encrypted Session Key" },
149     { PGPTAG_SIGNATURE,		"Signature" },
150     { PGPTAG_SYMMETRIC_SESSION_KEY,"Symmetric-Key Encrypted Session Key" },
151     { PGPTAG_ONEPASS_SIGNATURE,	"One-Pass Signature" },
152     { PGPTAG_SECRET_KEY,	"Secret Key" },
153     { PGPTAG_PUBLIC_KEY,	"Public Key" },
154     { PGPTAG_SECRET_SUBKEY,	"Secret Subkey" },
155     { PGPTAG_COMPRESSED_DATA,	"Compressed Data" },
156     { PGPTAG_SYMMETRIC_DATA,	"Symmetrically Encrypted Data" },
157     { PGPTAG_MARKER,		"Marker" },
158     { PGPTAG_LITERAL_DATA,	"Literal Data" },
159     { PGPTAG_TRUST,		"Trust" },
160     { PGPTAG_USER_ID,		"User ID" },
161     { PGPTAG_PUBLIC_SUBKEY,	"Public Subkey" },
162     { PGPTAG_COMMENT_OLD,	"Comment (from OpenPGP draft)" },
163     { PGPTAG_PHOTOID,		"PGP's photo ID" },
164     { PGPTAG_ENCRYPTED_MDC,	"Integrity protected encrypted data" },
165     { PGPTAG_MDC,		"Manipulaion detection code packet" },
166     { PGPTAG_PRIVATE_60,	"Private #60" },
167     { PGPTAG_COMMENT,		"Comment" },
168     { PGPTAG_PRIVATE_62,	"Private #62" },
169     { PGPTAG_CONTROL,		"Control (GPG)" },
170     { -1,			"Unknown packet tag" },
171 };
172 
173 static struct pgpValTbl_s const pgpArmorTbl[] = {
174     { PGPARMOR_MESSAGE,		"MESSAGE" },
175     { PGPARMOR_PUBKEY,		"PUBLIC KEY BLOCK" },
176     { PGPARMOR_SIGNATURE,	"SIGNATURE" },
177     { PGPARMOR_SIGNED_MESSAGE,	"SIGNED MESSAGE" },
178     { PGPARMOR_FILE,		"ARMORED FILE" },
179     { PGPARMOR_PRIVKEY,		"PRIVATE KEY BLOCK" },
180     { PGPARMOR_SECKEY,		"SECRET KEY BLOCK" },
181     { -1,			"Unknown armor block" }
182 };
183 
184 static struct pgpValTbl_s const pgpArmorKeyTbl[] = {
185     { PGPARMORKEY_VERSION,	"Version: " },
186     { PGPARMORKEY_COMMENT,	"Comment: " },
187     { PGPARMORKEY_MESSAGEID,	"MessageID: " },
188     { PGPARMORKEY_HASH,		"Hash: " },
189     { PGPARMORKEY_CHARSET,	"Charset: " },
190     { -1,			"Unknown armor key" }
191 };
192 
pgpPrtNL(void)193 static void pgpPrtNL(void)
194 {
195     if (!_print) return;
196     fprintf(stderr, "\n");
197 }
198 
pgpValStr(pgpValTbl vs,uint8_t val)199 static const char * pgpValStr(pgpValTbl vs, uint8_t val)
200 {
201     do {
202 	if (vs->val == val)
203 	    break;
204     } while ((++vs)->val != -1);
205     return vs->str;
206 }
207 
pgpValTable(pgpValType type)208 static pgpValTbl pgpValTable(pgpValType type)
209 {
210     switch (type) {
211     case PGPVAL_TAG:		return pgpTagTbl;
212     case PGPVAL_ARMORBLOCK:	return pgpArmorTbl;
213     case PGPVAL_ARMORKEY:	return pgpArmorKeyTbl;
214     case PGPVAL_SIGTYPE:	return pgpSigTypeTbl;
215     case PGPVAL_SUBTYPE:	return pgpSubTypeTbl;
216     case PGPVAL_PUBKEYALGO:	return pgpPubkeyTbl;
217     case PGPVAL_SYMKEYALGO:	return pgpSymkeyTbl;
218     case PGPVAL_COMPRESSALGO:	return pgpCompressionTbl;
219     case PGPVAL_HASHALGO: 	return pgpHashTbl;
220     case PGPVAL_SERVERPREFS:	return pgpKeyServerPrefsTbl;
221     default:
222 	break;
223     }
224     return NULL;
225 }
226 
pgpValString(pgpValType type,uint8_t val)227 const char * pgpValString(pgpValType type, uint8_t val)
228 {
229     pgpValTbl tbl = pgpValTable(type);
230     return (tbl != NULL) ? pgpValStr(tbl, val) : NULL;
231 }
232 
pgpPrtHex(const char * pre,const uint8_t * p,size_t plen)233 static void pgpPrtHex(const char *pre, const uint8_t *p, size_t plen)
234 {
235     char *hex = NULL;
236     if (!_print) return;
237     if (pre && *pre)
238 	fprintf(stderr, "%s", pre);
239     hex = pgpHexStr(p, plen);
240     fprintf(stderr, " %s", hex);
241     free(hex);
242 }
243 
pgpPrtVal(const char * pre,pgpValTbl vs,uint8_t val)244 static void pgpPrtVal(const char * pre, pgpValTbl vs, uint8_t val)
245 {
246     if (!_print) return;
247     if (pre && *pre)
248 	fprintf(stderr, "%s", pre);
249     fprintf(stderr, "%s(%u)", pgpValStr(vs, val), (unsigned)val);
250 }
251 
pgpPrtTime(const char * pre,const uint8_t * p,size_t plen)252 static void pgpPrtTime(const char * pre, const uint8_t *p, size_t plen)
253 {
254     if (!_print) return;
255     if (pre && *pre)
256 	fprintf(stderr, "%s", pre);
257     if (plen == 4) {
258 	char buf[1024];
259 	time_t t = pgpGrab(p, plen);
260 	struct tm _tm, *tms = localtime_r(&t, &_tm);
261 	if (strftime(buf, sizeof(buf), "%c", tms) > 0)
262 	    fprintf(stderr, " %-24.24s(0x%08x)", buf, (unsigned)t);
263     } else {
264 	pgpPrtHex("", p+1, plen-1);
265     }
266 }
267 
268 /** \ingroup rpmpgp
269  * Return hex formatted representation of a multiprecision integer.
270  * @param p		bytes
271  * @return		hex formatted string (malloc'ed)
272  */
273 static inline
pgpMpiStr(const uint8_t * p)274 char * pgpMpiStr(const uint8_t *p)
275 {
276     char *str = NULL;
277     char *hex = pgpHexStr(p+2, pgpMpiLen(p)-2);
278     rasprintf(&str, "[%4u]: %s", pgpGrab(p, (size_t) 2), hex);
279     free(hex);
280     return str;
281 }
282 
283 /** \ingroup rpmpgp
284  * Return value of an OpenPGP string.
285  * @param vs		table of (string,value) pairs
286  * @param s		string token to lookup
287  * @param se		end-of-string address
288  * @return		byte value
289  */
290 static inline
pgpValTok(pgpValTbl vs,const char * s,const char * se)291 int pgpValTok(pgpValTbl vs, const char * s, const char * se)
292 {
293     do {
294 	size_t vlen = strlen(vs->str);
295 	if (vlen <= (se-s) && rstreqn(s, vs->str, vlen))
296 	    break;
297     } while ((++vs)->val != -1);
298     return vs->val;
299 }
300 
301 /** \ingroup rpmpgp
302  * Decode length from 1, 2, or 5 octet body length encoding, used in
303  * new format packet headers and V4 signature subpackets.
304  * @param s		pointer to length encoding buffer
305  * @param slen		buffer size
306  * @retval *lenp	decoded length
307  * @return		no. of bytes used to encode the length, 0 on error
308  */
309 static inline
pgpLen(const uint8_t * s,size_t slen,size_t * lenp)310 size_t pgpLen(const uint8_t *s, size_t slen, size_t * lenp)
311 {
312     size_t dlen = 0;
313     size_t lenlen = 0;
314 
315     /*
316      * Callers can only ensure we'll always have the first byte, beyond
317      * that the required size is not known until we decode it so we need
318      * to check if we have enough bytes to read the size as we go.
319      */
320     if (*s < 192) {
321 	lenlen = 1;
322 	dlen = *s;
323     } else if (*s < 255 && slen > 2) {
324 	lenlen = 2;
325 	dlen = (((s[0]) - 192) << 8) + s[1] + 192;
326     } else if (slen > 5) {
327 	lenlen = 5;
328 	dlen = pgpGrab(s+1, 4);
329     }
330 
331     if (lenlen)
332 	*lenp = dlen;
333 
334     return lenlen;
335 }
336 
337 struct pgpPkt {
338     uint8_t tag;		/* decoded PGP tag */
339     const uint8_t *head;	/* pointer to start of packet (header) */
340     const uint8_t *body;	/* pointer to packet body */
341     size_t blen;		/* length of body in bytes */
342 };
343 
decodePkt(const uint8_t * p,size_t plen,struct pgpPkt * pkt)344 static int decodePkt(const uint8_t *p, size_t plen, struct pgpPkt *pkt)
345 {
346     int rc = -1; /* assume failure */
347 
348     /* Valid PGP packet header must always have two or more bytes in it */
349     if (p && plen >= 2 && p[0] & 0x80) {
350 	size_t lenlen = 0;
351 	size_t hlen = 0;
352 
353 	if (p[0] & 0x40) {
354 	    /* New format packet, body length encoding in second byte */
355 	    lenlen = pgpLen(p+1, plen-1, &pkt->blen);
356 	    pkt->tag = (p[0] & 0x3f);
357 	} else {
358 	    /* Old format packet, body length encoding in tag byte */
359 	    lenlen = (1 << (p[0] & 0x3));
360 	    if (plen > lenlen) {
361 		pkt->blen = pgpGrab(p+1, lenlen);
362 	    }
363 	    pkt->tag = (p[0] >> 2) & 0xf;
364 	}
365 	hlen = lenlen + 1;
366 
367 	/* Does the packet header and its body fit in our boundaries? */
368 	if (lenlen && (hlen + pkt->blen <= plen)) {
369 	    pkt->head = p;
370 	    pkt->body = pkt->head + hlen;
371 	    rc = 0;
372 	}
373     }
374 
375     return rc;
376 }
377 
378 #define CRC24_INIT	0xb704ce
379 #define CRC24_POLY	0x1864cfb
380 
381 /** \ingroup rpmpgp
382  * Return CRC of a buffer.
383  * @param octets	bytes
384  * @param len		no. of bytes
385  * @return		crc of buffer
386  */
387 static inline
pgpCRC(const uint8_t * octets,size_t len)388 unsigned int pgpCRC(const uint8_t *octets, size_t len)
389 {
390     unsigned int crc = CRC24_INIT;
391     size_t i;
392 
393     while (len--) {
394 	crc ^= (*octets++) << 16;
395 	for (i = 0; i < 8; i++) {
396 	    crc <<= 1;
397 	    if (crc & 0x1000000)
398 		crc ^= CRC24_POLY;
399 	}
400     }
401     return crc & 0xffffff;
402 }
403 
pgpVersion(const uint8_t * h,size_t hlen,uint8_t * version)404 static int pgpVersion(const uint8_t *h, size_t hlen, uint8_t *version)
405 {
406     if (hlen < 1)
407 	return -1;
408 
409     *version = h[0];
410     return 0;
411 }
412 
pgpPrtSubType(const uint8_t * h,size_t hlen,pgpSigType sigtype,pgpDigParams _digp)413 static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype,
414 			 pgpDigParams _digp)
415 {
416     const uint8_t *p = h;
417     size_t plen = 0, i;
418 
419     while (hlen > 0) {
420 	i = pgpLen(p, hlen, &plen);
421 	if (i == 0 || plen < 1 || i + plen > hlen)
422 	    break;
423 
424 	p += i;
425 	hlen -= i;
426 
427 	pgpPrtVal("    ", pgpSubTypeTbl, (p[0]&(~PGPSUBTYPE_CRITICAL)));
428 	if (p[0] & PGPSUBTYPE_CRITICAL)
429 	    if (_print)
430 		fprintf(stderr, " *CRITICAL*");
431 	switch (*p) {
432 	case PGPSUBTYPE_PREFER_SYMKEY:	/* preferred symmetric algorithms */
433 	    for (i = 1; i < plen; i++)
434 		pgpPrtVal(" ", pgpSymkeyTbl, p[i]);
435 	    break;
436 	case PGPSUBTYPE_PREFER_HASH:	/* preferred hash algorithms */
437 	    for (i = 1; i < plen; i++)
438 		pgpPrtVal(" ", pgpHashTbl, p[i]);
439 	    break;
440 	case PGPSUBTYPE_PREFER_COMPRESS:/* preferred compression algorithms */
441 	    for (i = 1; i < plen; i++)
442 		pgpPrtVal(" ", pgpCompressionTbl, p[i]);
443 	    break;
444 	case PGPSUBTYPE_KEYSERVER_PREFERS:/* key server preferences */
445 	    for (i = 1; i < plen; i++)
446 		pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]);
447 	    break;
448 	case PGPSUBTYPE_SIG_CREATE_TIME:
449 	    if (!(_digp->saved & PGPDIG_SAVED_TIME) &&
450 		(sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
451 	    {
452 		if (plen-1 != sizeof(_digp->time))
453 		    break;
454 		_digp->saved |= PGPDIG_SAVED_TIME;
455 		_digp->time = pgpGrab(p+1, sizeof(_digp->time));
456 	    }
457 	case PGPSUBTYPE_SIG_EXPIRE_TIME:
458 	case PGPSUBTYPE_KEY_EXPIRE_TIME:
459 	    pgpPrtTime(" ", p+1, plen-1);
460 	    break;
461 
462 	case PGPSUBTYPE_ISSUER_KEYID:	/* issuer key ID */
463 	    if (!(_digp->saved & PGPDIG_SAVED_ID) &&
464 		(sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
465 	    {
466 		if (plen-1 != sizeof(_digp->signid))
467 		    break;
468 		_digp->saved |= PGPDIG_SAVED_ID;
469 		memcpy(_digp->signid, p+1, sizeof(_digp->signid));
470 	    }
471 	case PGPSUBTYPE_EXPORTABLE_CERT:
472 	case PGPSUBTYPE_TRUST_SIG:
473 	case PGPSUBTYPE_REGEX:
474 	case PGPSUBTYPE_REVOCABLE:
475 	case PGPSUBTYPE_ARR:
476 	case PGPSUBTYPE_REVOKE_KEY:
477 	case PGPSUBTYPE_NOTATION:
478 	case PGPSUBTYPE_PREFER_KEYSERVER:
479 	case PGPSUBTYPE_PRIMARY_USERID:
480 	case PGPSUBTYPE_POLICY_URL:
481 	case PGPSUBTYPE_KEY_FLAGS:
482 	case PGPSUBTYPE_SIGNER_USERID:
483 	case PGPSUBTYPE_REVOKE_REASON:
484 	case PGPSUBTYPE_FEATURES:
485 	case PGPSUBTYPE_EMBEDDED_SIG:
486 	case PGPSUBTYPE_INTERNAL_100:
487 	case PGPSUBTYPE_INTERNAL_101:
488 	case PGPSUBTYPE_INTERNAL_102:
489 	case PGPSUBTYPE_INTERNAL_103:
490 	case PGPSUBTYPE_INTERNAL_104:
491 	case PGPSUBTYPE_INTERNAL_105:
492 	case PGPSUBTYPE_INTERNAL_106:
493 	case PGPSUBTYPE_INTERNAL_107:
494 	case PGPSUBTYPE_INTERNAL_108:
495 	case PGPSUBTYPE_INTERNAL_109:
496 	case PGPSUBTYPE_INTERNAL_110:
497 	default:
498 	    pgpPrtHex("", p+1, plen-1);
499 	    break;
500 	}
501 	pgpPrtNL();
502 	p += plen;
503 	hlen -= plen;
504     }
505     return (hlen != 0); /* non-zero hlen is an error */
506 }
507 
pgpDigAlgFree(pgpDigAlg alg)508 pgpDigAlg pgpDigAlgFree(pgpDigAlg alg)
509 {
510     if (alg) {
511 	if (alg->free)
512 	    alg->free(alg);
513 	free(alg);
514     }
515     return NULL;
516 }
517 
pgpPrtSigParams(pgpTag tag,uint8_t pubkey_algo,uint8_t sigtype,const uint8_t * p,const uint8_t * h,size_t hlen,pgpDigParams sigp)518 static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo, uint8_t sigtype,
519 		const uint8_t *p, const uint8_t *h, size_t hlen,
520 		pgpDigParams sigp)
521 {
522     int rc = 1; /* assume failure */
523     const uint8_t * pend = h + hlen;
524     int i;
525     pgpDigAlg sigalg = pgpSignatureNew(pubkey_algo);
526 
527     for (i = 0; i < sigalg->mpis && p + 2 <= pend; i++) {
528 	int mpil = pgpMpiLen(p);
529 	if (p + mpil > pend)
530 	    break;
531 	if (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT) {
532 	    if (sigalg->setmpi(sigalg, i, p))
533 		break;
534 	}
535 	p += mpil;
536     }
537 
538     /* Does the size and number of MPI's match our expectations? */
539     if (p == pend && i == sigalg->mpis)
540 	rc = 0;
541 
542     /* We can't handle more than one sig at a time */
543     if (rc == 0 && sigp->alg == NULL && sigp->tag == PGPTAG_SIGNATURE)
544 	sigp->alg = sigalg;
545     else
546 	pgpDigAlgFree(sigalg);
547 
548     return rc;
549 }
550 
pgpGet(const uint8_t * s,size_t nbytes,const uint8_t * send,unsigned int * valp)551 static int pgpGet(const uint8_t *s, size_t nbytes, const uint8_t *send,
552 		  unsigned int *valp)
553 {
554     int rc = -1;
555 
556     if (s + nbytes <= send) {
557 	*valp = pgpGrab(s, nbytes);
558 	rc = 0;
559     }
560 
561     return rc;
562 }
563 
pgpPrtSig(pgpTag tag,const uint8_t * h,size_t hlen,pgpDigParams _digp)564 static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
565 		     pgpDigParams _digp)
566 {
567     uint8_t version = 0;
568     uint8_t * p;
569     unsigned int plen;
570     int rc = 1;
571 
572     if (pgpVersion(h, hlen, &version))
573 	return rc;
574 
575     switch (version) {
576     case 3:
577     {   pgpPktSigV3 v = (pgpPktSigV3)h;
578 
579 	if (hlen <= sizeof(*v) || v->hashlen != 5)
580 	    return 1;
581 
582 	pgpPrtVal("V3 ", pgpTagTbl, tag);
583 	pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
584 	pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
585 	pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
586 	pgpPrtNL();
587 	pgpPrtTime(" ", v->time, sizeof(v->time));
588 	pgpPrtNL();
589 	pgpPrtHex(" signer keyid", v->signid, sizeof(v->signid));
590 	plen = pgpGrab(v->signhash16, sizeof(v->signhash16));
591 	pgpPrtHex(" signhash16", v->signhash16, sizeof(v->signhash16));
592 	pgpPrtNL();
593 
594 	if (_digp->pubkey_algo == 0) {
595 	    _digp->version = v->version;
596 	    _digp->hashlen = v->hashlen;
597 	    _digp->sigtype = v->sigtype;
598 	    _digp->hash = memcpy(xmalloc(v->hashlen), &v->sigtype, v->hashlen);
599 	    _digp->time = pgpGrab(v->time, sizeof(v->time));
600 	    memcpy(_digp->signid, v->signid, sizeof(_digp->signid));
601 	    _digp->pubkey_algo = v->pubkey_algo;
602 	    _digp->hash_algo = v->hash_algo;
603 	    memcpy(_digp->signhash16, v->signhash16, sizeof(_digp->signhash16));
604 	}
605 
606 	p = ((uint8_t *)v) + sizeof(*v);
607 	rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp);
608     }	break;
609     case 4:
610     {   pgpPktSigV4 v = (pgpPktSigV4)h;
611 
612 	if (hlen <= sizeof(*v))
613 	    return 1;
614 
615 	pgpPrtVal("V4 ", pgpTagTbl, tag);
616 	pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
617 	pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
618 	pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
619 	pgpPrtNL();
620 
621 	p = &v->hashlen[0];
622 	if (pgpGet(v->hashlen, sizeof(v->hashlen), h + hlen, &plen))
623 	    return 1;
624 	p += sizeof(v->hashlen);
625 
626 	if ((p + plen) > (h + hlen))
627 	    return 1;
628 
629 	if (_digp->pubkey_algo == 0) {
630 	    _digp->hashlen = sizeof(*v) + plen;
631 	    _digp->hash = memcpy(xmalloc(_digp->hashlen), v, _digp->hashlen);
632 	}
633 	if (pgpPrtSubType(p, plen, v->sigtype, _digp))
634 	    return 1;
635 	p += plen;
636 
637 	if (pgpGet(p, 2, h + hlen, &plen))
638 	    return 1;
639 	p += 2;
640 
641 	if ((p + plen) > (h + hlen))
642 	    return 1;
643 
644 	if (pgpPrtSubType(p, plen, v->sigtype, _digp))
645 	    return 1;
646 	p += plen;
647 
648 	if (pgpGet(p, 2, h + hlen, &plen))
649 	    return 1;
650 	pgpPrtHex(" signhash16", p, 2);
651 	pgpPrtNL();
652 
653 	if (_digp->pubkey_algo == 0) {
654 	    _digp->version = v->version;
655 	    _digp->sigtype = v->sigtype;
656 	    _digp->pubkey_algo = v->pubkey_algo;
657 	    _digp->hash_algo = v->hash_algo;
658 	    memcpy(_digp->signhash16, p, sizeof(_digp->signhash16));
659 	}
660 
661 	p += 2;
662 	if (p > (h + hlen))
663 	    return 1;
664 
665 	rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp);
666     }	break;
667     default:
668 	rpmlog(RPMLOG_WARNING, _("Unsupported version of key: V%d\n"), version);
669 	rc = 1;
670 	break;
671     }
672     return rc;
673 }
674 
pgpHexStr(const uint8_t * p,size_t plen)675 char * pgpHexStr(const uint8_t *p, size_t plen)
676 {
677     char *t, *str;
678     str = t = xmalloc(plen * 2 + 1);
679     static char const hex[] = "0123456789abcdef";
680     while (plen-- > 0) {
681 	size_t i;
682 	i = *p++;
683 	*t++ = hex[ (i >> 4) & 0xf ];
684 	*t++ = hex[ (i     ) & 0xf ];
685     }
686     *t = '\0';
687     return str;
688 }
689 
690 static uint8_t curve_oids[] = {
691     PGPCURVE_NIST_P_256,	0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
692     PGPCURVE_NIST_P_384,	0x05, 0x2b, 0x81, 0x04, 0x00, 0x22,
693     PGPCURVE_NIST_P_521,	0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
694     PGPCURVE_BRAINPOOL_P256R1,	0x09, 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07,
695     PGPCURVE_BRAINPOOL_P512R1,	0x09, 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0d,
696     PGPCURVE_ED25519,		0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01,
697     PGPCURVE_CURVE25519,	0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01,
698     0,
699 };
700 
pgpCurveByOid(const uint8_t * p,int l)701 static int pgpCurveByOid(const uint8_t *p, int l)
702 {
703     uint8_t *curve;
704     for (curve = curve_oids; *curve; curve += 2 + curve[1])
705         if (l == (int)curve[1] && !memcmp(p, curve + 2, l))
706             return (int)curve[0];
707     return 0;
708 }
709 
pgpPrtPubkeyParams(uint8_t pubkey_algo,const uint8_t * p,const uint8_t * h,size_t hlen,pgpDigParams keyp)710 static int pgpPrtPubkeyParams(uint8_t pubkey_algo,
711 		const uint8_t *p, const uint8_t *h, size_t hlen,
712 		pgpDigParams keyp)
713 {
714     int rc = 1;
715     const uint8_t *pend = h + hlen;
716     int i, curve = 0;
717     pgpDigAlg keyalg;
718     if (pubkey_algo == PGPPUBKEYALGO_EDDSA) {
719 	int len = p + 1 < pend ? p[0] : 0;
720 	if (len == 0 || len == 0xff || p + 1 + len > pend)
721 	    goto exit;
722 	curve = pgpCurveByOid(p + 1, len);
723 	p += len + 1;
724     }
725     keyalg = pgpPubkeyNew(pubkey_algo, curve);
726     for (i = 0; i < keyalg->mpis && p + 2 <= pend; i++) {
727 	int mpil = pgpMpiLen(p);
728 	if (p + mpil > pend)
729 	    break;
730 	if (keyalg->setmpi(keyalg, i, p))
731 	    break;
732 	p += mpil;
733     }
734 
735     /* Does the size and number of MPI's match our expectations? */
736     if (p == pend && i == keyalg->mpis)
737 	rc = 0;
738 
739     /* We can't handle more than one key at a time */
740     if (rc == 0 && keyp->alg == NULL && (keyp->tag == PGPTAG_PUBLIC_KEY ||
741 	keyp->tag == PGPTAG_PUBLIC_SUBKEY))
742 
743 	keyp->alg = keyalg;
744     else
745 	pgpDigAlgFree(keyalg);
746 
747 exit:
748     return rc;
749 }
750 
pgpPrtKey(pgpTag tag,const uint8_t * h,size_t hlen,pgpDigParams _digp)751 static int pgpPrtKey(pgpTag tag, const uint8_t *h, size_t hlen,
752 		     pgpDigParams _digp)
753 {
754     uint8_t version = 0;
755     const uint8_t * p = NULL;
756     int rc = 1;
757 
758     if (pgpVersion(h, hlen, &version))
759 	return rc;
760 
761     /* We only permit V4 keys, V3 keys are long long since deprecated */
762     switch (version) {
763     case 4:
764     {   pgpPktKeyV4 v = (pgpPktKeyV4)h;
765 
766 	if (hlen > sizeof(*v)) {
767 	    pgpPrtVal("V4 ", pgpTagTbl, tag);
768 	    pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
769 	    pgpPrtTime(" ", v->time, sizeof(v->time));
770 	    pgpPrtNL();
771 
772 	    /* If _digp->hash is not NULL then signature is already loaded */
773 	    if (_digp->hash == NULL) {
774 		_digp->version = v->version;
775 		_digp->time = pgpGrab(v->time, sizeof(v->time));
776 		_digp->pubkey_algo = v->pubkey_algo;
777 	    }
778 
779 	    p = ((uint8_t *)v) + sizeof(*v);
780 	    rc = pgpPrtPubkeyParams(v->pubkey_algo, p, h, hlen, _digp);
781 	}
782     }	break;
783     default:
784 	rpmlog(RPMLOG_WARNING, _("Unsupported version of key: V%d\n"), h[0]);
785     }
786     return rc;
787 }
788 
pgpPrtUserID(pgpTag tag,const uint8_t * h,size_t hlen,pgpDigParams _digp)789 static int pgpPrtUserID(pgpTag tag, const uint8_t *h, size_t hlen,
790 			pgpDigParams _digp)
791 {
792     pgpPrtVal("", pgpTagTbl, tag);
793     if (_print)
794 	fprintf(stderr, " \"%.*s\"", (int)hlen, (const char *)h);
795     pgpPrtNL();
796     free(_digp->userid);
797     _digp->userid = memcpy(xmalloc(hlen+1), h, hlen);
798     _digp->userid[hlen] = '\0';
799     return 0;
800 }
801 
pgpPubkeyFingerprint(const uint8_t * h,size_t hlen,uint8_t ** fp,size_t * fplen)802 int pgpPubkeyFingerprint(const uint8_t *h, size_t hlen,
803 			  uint8_t **fp, size_t *fplen)
804 {
805     int rc = -1; /* assume failure */
806     const uint8_t *se;
807     const uint8_t *pend = h + hlen;
808     uint8_t version = 0;
809 
810     if (pgpVersion(h, hlen, &version))
811 	return rc;
812 
813     /* We only permit V4 keys, V3 keys are long long since deprecated */
814     switch (version) {
815     case 4:
816       {	pgpPktKeyV4 v = (pgpPktKeyV4) (h);
817 	int mpis = -1;
818 
819 	/* Packet must be larger than v to have room for the required MPIs */
820 	if (hlen > sizeof(*v)) {
821 	    switch (v->pubkey_algo) {
822 	    case PGPPUBKEYALGO_RSA:
823 		mpis = 2;
824 		break;
825 	    case PGPPUBKEYALGO_DSA:
826 		mpis = 4;
827 		break;
828 	    case PGPPUBKEYALGO_EDDSA:
829 		mpis = 1;
830 		break;
831 	    }
832 	}
833 
834 	se = (uint8_t *)(v + 1);
835 	/* EdDSA has a curve id before the MPIs */
836 	if (v->pubkey_algo == PGPPUBKEYALGO_EDDSA) {
837 	    if (se < pend && se[0] != 0x00 && se[0] != 0xff)
838 		se += 1 + se[0];
839 	    else
840 		se = pend;      /* error out when reading the MPI */
841 	}
842 	while (se < pend && mpis-- > 0)
843 	    se += pgpMpiLen(se);
844 
845 	/* Does the size and number of MPI's match our expectations? */
846 	if (se == pend && mpis == 0) {
847 	    DIGEST_CTX ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
848 	    uint8_t *d = NULL;
849 	    size_t dlen = 0;
850 	    int i = se - h;
851 	    uint8_t in[3] = { 0x99, (i >> 8), i };
852 
853 	    (void) rpmDigestUpdate(ctx, in, 3);
854 	    (void) rpmDigestUpdate(ctx, h, i);
855 	    (void) rpmDigestFinal(ctx, (void **)&d, &dlen, 0);
856 
857 	    if (dlen == 20) {
858 		rc = 0;
859 		*fp = d;
860 		*fplen = dlen;
861 	    } else {
862 		free(d);
863 	    }
864 	}
865 
866       }	break;
867     default:
868 	rpmlog(RPMLOG_WARNING, _("Unsupported version of key: V%d\n"), version);
869     }
870     return rc;
871 }
872 
getKeyID(const uint8_t * h,size_t hlen,pgpKeyID_t keyid)873 static int getKeyID(const uint8_t *h, size_t hlen, pgpKeyID_t keyid)
874 {
875     uint8_t *fp = NULL;
876     size_t fplen = 0;
877     int rc = pgpPubkeyFingerprint(h, hlen, &fp, &fplen);
878     if (fp && fplen > 8) {
879 	memcpy(keyid, (fp + (fplen-8)), 8);
880 	free(fp);
881     }
882     return rc;
883 }
884 
pgpPubkeyKeyID(const uint8_t * pkt,size_t pktlen,pgpKeyID_t keyid)885 int pgpPubkeyKeyID(const uint8_t * pkt, size_t pktlen, pgpKeyID_t keyid)
886 {
887     struct pgpPkt p;
888 
889     if (decodePkt(pkt, pktlen, &p))
890 	return -1;
891 
892     return getKeyID(p.body, p.blen, keyid);
893 }
894 
pgpPrtPkt(struct pgpPkt * p,pgpDigParams _digp)895 static int pgpPrtPkt(struct pgpPkt *p, pgpDigParams _digp)
896 {
897     int rc = 0;
898 
899     switch (p->tag) {
900     case PGPTAG_SIGNATURE:
901 	rc = pgpPrtSig(p->tag, p->body, p->blen, _digp);
902 	break;
903     case PGPTAG_PUBLIC_KEY:
904 	/* Get the public key Key ID. */
905 	if (!getKeyID(p->body, p->blen, _digp->signid))
906 	    _digp->saved |= PGPDIG_SAVED_ID;
907 	else
908 	    memset(_digp->signid, 0, sizeof(_digp->signid));
909 	rc = pgpPrtKey(p->tag, p->body, p->blen, _digp);
910 	break;
911     case PGPTAG_USER_ID:
912 	rc = pgpPrtUserID(p->tag, p->body, p->blen, _digp);
913 	break;
914     case PGPTAG_RESERVED:
915 	rc = -1;
916 	break;
917     case PGPTAG_COMMENT:
918     case PGPTAG_COMMENT_OLD:
919     case PGPTAG_PUBLIC_SUBKEY:
920     case PGPTAG_SECRET_KEY:
921     case PGPTAG_SECRET_SUBKEY:
922     case PGPTAG_PUBLIC_SESSION_KEY:
923     case PGPTAG_SYMMETRIC_SESSION_KEY:
924     case PGPTAG_COMPRESSED_DATA:
925     case PGPTAG_SYMMETRIC_DATA:
926     case PGPTAG_MARKER:
927     case PGPTAG_LITERAL_DATA:
928     case PGPTAG_TRUST:
929     case PGPTAG_PHOTOID:
930     case PGPTAG_ENCRYPTED_MDC:
931     case PGPTAG_MDC:
932     case PGPTAG_PRIVATE_60:
933     case PGPTAG_PRIVATE_62:
934     case PGPTAG_CONTROL:
935     default:
936 	pgpPrtVal("", pgpTagTbl, p->tag);
937 	pgpPrtHex("", p->body, p->blen);
938 	pgpPrtNL();
939 	break;
940     }
941 
942     return rc;
943 }
944 
pgpNewDig(void)945 pgpDig pgpNewDig(void)
946 {
947     pgpDig dig = xcalloc(1, sizeof(*dig));
948 
949     return dig;
950 }
951 
pgpDigParamsFree(pgpDigParams digp)952 pgpDigParams pgpDigParamsFree(pgpDigParams digp)
953 {
954     if (digp) {
955 	pgpDigAlgFree(digp->alg);
956 	free(digp->userid);
957 	free(digp->hash);
958 	memset(digp, 0, sizeof(*digp));
959 	free(digp);
960     }
961     return NULL;
962 }
963 
pgpCleanDig(pgpDig dig)964 void pgpCleanDig(pgpDig dig)
965 {
966     if (dig != NULL) {
967 	pgpDigParamsFree(dig->signature);
968 	pgpDigParamsFree(dig->pubkey);
969 	memset(dig, 0, sizeof(*dig));
970     }
971     return;
972 }
973 
pgpFreeDig(pgpDig dig)974 pgpDig pgpFreeDig(pgpDig dig)
975 {
976     if (dig != NULL) {
977 
978 	/* DUmp the signature/pubkey data. */
979 	pgpCleanDig(dig);
980 	dig = _free(dig);
981     }
982     return dig;
983 }
984 
pgpDigGetParams(pgpDig dig,unsigned int pkttype)985 pgpDigParams pgpDigGetParams(pgpDig dig, unsigned int pkttype)
986 {
987     pgpDigParams params = NULL;
988     if (dig) {
989 	switch (pkttype) {
990 	case PGPTAG_SIGNATURE:
991 	    params = dig->signature;
992 	    break;
993 	case PGPTAG_PUBLIC_KEY:
994 	    params = dig->pubkey;
995 	    break;
996 	}
997     }
998     return params;
999 }
1000 
pgpDigParamsCmp(pgpDigParams p1,pgpDigParams p2)1001 int pgpDigParamsCmp(pgpDigParams p1, pgpDigParams p2)
1002 {
1003     int rc = 1; /* assume different, eg if either is NULL */
1004     if (p1 && p2) {
1005 	/* XXX Should we compare something else too? */
1006 	if (p1->tag != p2->tag)
1007 	    goto exit;
1008 	if (p1->hash_algo != p2->hash_algo)
1009 	    goto exit;
1010 	if (p1->pubkey_algo != p2->pubkey_algo)
1011 	    goto exit;
1012 	if (p1->version != p2->version)
1013 	    goto exit;
1014 	if (p1->sigtype != p2->sigtype)
1015 	    goto exit;
1016 	if (memcmp(p1->signid, p2->signid, sizeof(p1->signid)) != 0)
1017 	    goto exit;
1018 	if (p1->userid && p2->userid && strcmp(p1->userid, p2->userid) != 0)
1019 	    goto exit;
1020 
1021 	/* Parameters match ... at least for our purposes */
1022 	rc = 0;
1023     }
1024 exit:
1025     return rc;
1026 }
1027 
pgpDigParamsAlgo(pgpDigParams digp,unsigned int algotype)1028 unsigned int pgpDigParamsAlgo(pgpDigParams digp, unsigned int algotype)
1029 {
1030     unsigned int algo = 0; /* assume failure */
1031     if (digp) {
1032 	switch (algotype) {
1033 	case PGPVAL_PUBKEYALGO:
1034 	    algo = digp->pubkey_algo;
1035 	    break;
1036 	case PGPVAL_HASHALGO:
1037 	    algo = digp->hash_algo;
1038 	    break;
1039 	}
1040     }
1041     return algo;
1042 }
1043 
pgpPrtParams(const uint8_t * pkts,size_t pktlen,unsigned int pkttype,pgpDigParams * ret)1044 int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype,
1045 		 pgpDigParams * ret)
1046 {
1047     const uint8_t *p = pkts;
1048     const uint8_t *pend = pkts + pktlen;
1049     pgpDigParams digp = NULL;
1050     struct pgpPkt pkt;
1051     int rc = -1; /* assume failure */
1052 
1053     while (p < pend) {
1054 	if (decodePkt(p, (pend - p), &pkt))
1055 	    break;
1056 
1057 	if (digp == NULL) {
1058 	    if (pkttype && pkt.tag != pkttype) {
1059 		break;
1060 	    } else {
1061 		digp = xcalloc(1, sizeof(*digp));
1062 		digp->tag = pkt.tag;
1063 	    }
1064 	}
1065 
1066 	if (pgpPrtPkt(&pkt, digp))
1067 	    break;
1068 
1069 	p += (pkt.body - pkt.head) + pkt.blen;
1070     }
1071 
1072     rc = (digp && (p == pend)) ? 0 : -1;
1073 
1074     if (ret && rc == 0) {
1075 	*ret = digp;
1076     } else {
1077 	pgpDigParamsFree(digp);
1078     }
1079     return rc;
1080 }
1081 
pgpPrtParamsSubkeys(const uint8_t * pkts,size_t pktlen,pgpDigParams mainkey,pgpDigParams ** subkeys,int * subkeysCount)1082 int pgpPrtParamsSubkeys(const uint8_t *pkts, size_t pktlen,
1083 			pgpDigParams mainkey, pgpDigParams **subkeys,
1084 			int *subkeysCount)
1085 {
1086     const uint8_t *p = pkts;
1087     const uint8_t *pend = pkts + pktlen;
1088     pgpDigParams *digps = NULL;
1089     int count = 0;
1090     int alloced = 10;
1091     struct pgpPkt pkt;
1092     int rc, i;
1093 
1094     digps = xmalloc(alloced * sizeof(*digps));
1095 
1096     while (p < pend) {
1097 	if (decodePkt(p, (pend - p), &pkt))
1098 	    break;
1099 
1100 	p += (pkt.body - pkt.head) + pkt.blen;
1101 
1102 	if (pkt.tag == PGPTAG_PUBLIC_SUBKEY) {
1103 	    if (count == alloced) {
1104 		alloced <<= 1;
1105 		digps = xrealloc(digps, alloced * sizeof(*digps));
1106 	    }
1107 
1108 	    digps[count] = xcalloc(1, sizeof(**digps));
1109 	    digps[count]->tag = PGPTAG_PUBLIC_SUBKEY;
1110 	    /* Copy UID from main key to subkey */
1111 	    digps[count]->userid = xstrdup(mainkey->userid);
1112 
1113 	    if (getKeyID(pkt.body, pkt.blen, digps[count]->signid)) {
1114 		pgpDigParamsFree(digps[count]);
1115 		continue;
1116 	    }
1117 
1118 	    if (pgpPrtKey(pkt.tag, pkt.body, pkt.blen, digps[count])) {
1119 		pgpDigParamsFree(digps[count]);
1120 		continue;
1121 	    }
1122 	    count++;
1123 	}
1124     }
1125     rc = (p == pend) ? 0 : -1;
1126 
1127     if (rc == 0) {
1128 	*subkeys = xrealloc(digps, count * sizeof(*digps));
1129 	*subkeysCount = count;
1130     } else {
1131 	for (i = 0; i < count; i++)
1132 	    pgpDigParamsFree(digps[i]);
1133 	free(digps);
1134     }
1135 
1136     return rc;
1137 }
1138 
pgpPrtPkts(const uint8_t * pkts,size_t pktlen,pgpDig dig,int printing)1139 int pgpPrtPkts(const uint8_t * pkts, size_t pktlen, pgpDig dig, int printing)
1140 {
1141     int rc;
1142     pgpDigParams digp = NULL;
1143 
1144     _print = printing;
1145 
1146     rc = pgpPrtParams(pkts, pktlen, 0, &digp);
1147 
1148     if (dig && rc == 0) {
1149 	if (digp->tag == PGPTAG_SIGNATURE) {
1150 	    pgpDigParamsFree(dig->signature);
1151 	    dig->signature = digp;
1152 	} else {
1153 	    pgpDigParamsFree(dig->pubkey);
1154 	    dig->pubkey = digp;
1155 	}
1156     } else {
1157 	pgpDigParamsFree(digp);
1158     }
1159 
1160     return rc;
1161 }
1162 
pgpIdentItem(pgpDigParams digp)1163 char *pgpIdentItem(pgpDigParams digp)
1164 {
1165     char *id = NULL;
1166     if (digp) {
1167 
1168 	char *signid = pgpHexStr(digp->signid+4, sizeof(digp->signid)-4);
1169 	rasprintf(&id, _("V%d %s/%s %s, key ID %s"),
1170 			digp->version,
1171 			pgpValStr(pgpPubkeyTbl, digp->pubkey_algo),
1172 			pgpValStr(pgpHashTbl, digp->hash_algo),
1173 			pgpValStr(pgpTagTbl, digp->tag),
1174 			signid);
1175 	free(signid);
1176     } else {
1177 	id = xstrdup(_("(none)"));
1178     }
1179     return id;
1180 }
1181 
pgpVerifySignature(pgpDigParams key,pgpDigParams sig,DIGEST_CTX hashctx)1182 rpmRC pgpVerifySignature(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx)
1183 {
1184     DIGEST_CTX ctx = rpmDigestDup(hashctx);
1185     uint8_t *hash = NULL;
1186     size_t hashlen = 0;
1187     rpmRC res = RPMRC_FAIL; /* assume failure */
1188 
1189     if (sig == NULL || ctx == NULL)
1190 	goto exit;
1191 
1192     if (sig->hash != NULL)
1193 	rpmDigestUpdate(ctx, sig->hash, sig->hashlen);
1194 
1195     if (sig->version == 4) {
1196 	/* V4 trailer is six octets long (rfc4880) */
1197 	uint8_t trailer[6];
1198 	uint32_t nb = sig->hashlen;
1199 	nb = htonl(nb);
1200 	trailer[0] = sig->version;
1201 	trailer[1] = 0xff;
1202 	memcpy(trailer+2, &nb, 4);
1203 	rpmDigestUpdate(ctx, trailer, sizeof(trailer));
1204     }
1205 
1206     rpmDigestFinal(ctx, (void **)&hash, &hashlen, 0);
1207 
1208     /* Compare leading 16 bits of digest for quick check. */
1209     if (hash == NULL || memcmp(hash, sig->signhash16, 2) != 0)
1210 	goto exit;
1211 
1212     /*
1213      * If we have a key, verify the signature for real. Otherwise we've
1214      * done all we can, return NOKEY to indicate "looks okay but dunno."
1215      */
1216     if (key && key->alg) {
1217 	pgpDigAlg sa = sig->alg;
1218 	pgpDigAlg ka = key->alg;
1219 	if (sa && sa->verify) {
1220 	    if (sa->verify(ka, sa, hash, hashlen, sig->hash_algo) == 0) {
1221 		res = RPMRC_OK;
1222 	    }
1223 	}
1224     } else {
1225 	res = RPMRC_NOKEY;
1226     }
1227 
1228 exit:
1229     free(hash);
1230     return res;
1231 
1232 }
1233 
pgpVerifySig(pgpDig dig,DIGEST_CTX hashctx)1234 rpmRC pgpVerifySig(pgpDig dig, DIGEST_CTX hashctx)
1235 {
1236     if (dig == NULL || hashctx == NULL)
1237 	return RPMRC_FAIL;
1238 
1239     return pgpVerifySignature(pgpDigGetParams(dig, PGPTAG_PUBLIC_KEY),
1240 			      pgpDigGetParams(dig, PGPTAG_SIGNATURE), hashctx);
1241 }
1242 
decodePkts(uint8_t * b,uint8_t ** pkt,size_t * pktlen)1243 static pgpArmor decodePkts(uint8_t *b, uint8_t **pkt, size_t *pktlen)
1244 {
1245     const char * enc = NULL;
1246     const char * crcenc = NULL;
1247     uint8_t * dec;
1248     uint8_t * crcdec;
1249     size_t declen;
1250     size_t crclen;
1251     uint32_t crcpkt, crc;
1252     const char * armortype = NULL;
1253     char * t, * te;
1254     int pstate = 0;
1255     pgpArmor ec = PGPARMOR_ERR_NO_BEGIN_PGP;	/* XXX assume failure */
1256 
1257 #define	TOKEQ(_s, _tok)	(rstreqn((_s), (_tok), sizeof(_tok)-1))
1258 
1259     for (t = (char *)b; t && *t; t = te) {
1260 	int rc;
1261 	if ((te = strchr(t, '\n')) == NULL)
1262 	    te = t + strlen(t);
1263 	else
1264 	    te++;
1265 
1266 	switch (pstate) {
1267 	case 0:
1268 	    armortype = NULL;
1269 	    if (!TOKEQ(t, "-----BEGIN PGP "))
1270 		continue;
1271 	    t += sizeof("-----BEGIN PGP ")-1;
1272 
1273 	    rc = pgpValTok(pgpArmorTbl, t, te);
1274 	    if (rc < 0) {
1275 		ec = PGPARMOR_ERR_UNKNOWN_ARMOR_TYPE;
1276 		goto exit;
1277 	    }
1278 	    if (rc != PGPARMOR_PUBKEY)	/* XXX ASCII Pubkeys only, please. */
1279 		continue;
1280 
1281 	    armortype = pgpValStr(pgpArmorTbl, rc);
1282 	    t += strlen(armortype);
1283 	    if (!TOKEQ(t, "-----"))
1284 		continue;
1285 	    t += sizeof("-----")-1;
1286 	    if (*t != '\n' && *t != '\r')
1287 		continue;
1288 	    *t = '\0';
1289 	    pstate++;
1290 	    break;
1291 	case 1:
1292 	    enc = NULL;
1293 	    rc = pgpValTok(pgpArmorKeyTbl, t, te);
1294 	    if (rc >= 0)
1295 		continue;
1296 	    if (*t != '\n' && *t != '\r') {
1297 		pstate = 0;
1298 		continue;
1299 	    }
1300 	    enc = te;		/* Start of encoded packets */
1301 	    pstate++;
1302 	    break;
1303 	case 2:
1304 	    crcenc = NULL;
1305 	    if (*t != '=')
1306 		continue;
1307 	    *t++ = '\0';	/* Terminate encoded packets */
1308 	    crcenc = t;		/* Start of encoded crc */
1309 	    pstate++;
1310 	    break;
1311 	case 3:
1312 	    pstate = 0;
1313 	    if (!TOKEQ(t, "-----END PGP ")) {
1314 		ec = PGPARMOR_ERR_NO_END_PGP;
1315 		goto exit;
1316 	    }
1317 	    *t = '\0';		/* Terminate encoded crc */
1318 	    t += sizeof("-----END PGP ")-1;
1319 	    if (t >= te) continue;
1320 
1321 	    if (armortype == NULL) /* XXX can't happen */
1322 		continue;
1323 	    if (!rstreqn(t, armortype, strlen(armortype)))
1324 		continue;
1325 
1326 	    t += strlen(armortype);
1327 	    if (t >= te) continue;
1328 
1329 	    if (!TOKEQ(t, "-----")) {
1330 		ec = PGPARMOR_ERR_NO_END_PGP;
1331 		goto exit;
1332 	    }
1333 	    t += (sizeof("-----")-1);
1334 	    /* Handle EOF without EOL here, *t == '\0' at EOF */
1335 	    if (*t && (t >= te)) continue;
1336 	    /* XXX permitting \r here is not RFC-2440 compliant <shrug> */
1337 	    if (!(*t == '\n' || *t == '\r' || *t == '\0')) continue;
1338 
1339 	    crcdec = NULL;
1340 	    crclen = 0;
1341 	    if (rpmBase64Decode(crcenc, (void **)&crcdec, &crclen) != 0) {
1342 		ec = PGPARMOR_ERR_CRC_DECODE;
1343 		goto exit;
1344 	    }
1345 	    crcpkt = pgpGrab(crcdec, crclen);
1346 	    crcdec = _free(crcdec);
1347 	    dec = NULL;
1348 	    declen = 0;
1349 	    if (rpmBase64Decode(enc, (void **)&dec, &declen) != 0) {
1350 		ec = PGPARMOR_ERR_BODY_DECODE;
1351 		goto exit;
1352 	    }
1353 	    crc = pgpCRC(dec, declen);
1354 	    if (crcpkt != crc) {
1355 		ec = PGPARMOR_ERR_CRC_CHECK;
1356 		goto exit;
1357 	    }
1358 	    if (pkt) *pkt = dec;
1359 	    if (pktlen) *pktlen = declen;
1360 	    ec = PGPARMOR_PUBKEY;	/* XXX ASCII Pubkeys only, please. */
1361 	    goto exit;
1362 	    break;
1363 	}
1364     }
1365     ec = PGPARMOR_NONE;
1366 
1367 exit:
1368     return ec;
1369 }
1370 
pgpReadPkts(const char * fn,uint8_t ** pkt,size_t * pktlen)1371 pgpArmor pgpReadPkts(const char * fn, uint8_t ** pkt, size_t * pktlen)
1372 {
1373     uint8_t * b = NULL;
1374     ssize_t blen;
1375     pgpArmor ec = PGPARMOR_ERR_NO_BEGIN_PGP;	/* XXX assume failure */
1376     int rc = rpmioSlurp(fn, &b, &blen);
1377     if (rc == 0 && b != NULL && blen > 0) {
1378 	ec = decodePkts(b, pkt, pktlen);
1379     }
1380     free(b);
1381     return ec;
1382 }
1383 
pgpParsePkts(const char * armor,uint8_t ** pkt,size_t * pktlen)1384 pgpArmor pgpParsePkts(const char *armor, uint8_t ** pkt, size_t * pktlen)
1385 {
1386     pgpArmor ec = PGPARMOR_ERR_NO_BEGIN_PGP;	/* XXX assume failure */
1387     if (armor && strlen(armor) > 0) {
1388 	uint8_t *b = (uint8_t*) xstrdup(armor);
1389 	ec = decodePkts(b, pkt, pktlen);
1390 	free(b);
1391     }
1392     return ec;
1393 }
1394 
pgpPubKeyCertLen(const uint8_t * pkts,size_t pktslen,size_t * certlen)1395 int pgpPubKeyCertLen(const uint8_t *pkts, size_t pktslen, size_t *certlen)
1396 {
1397     const uint8_t *p = pkts;
1398     const uint8_t *pend = pkts + pktslen;
1399     struct pgpPkt pkt;
1400 
1401     while (p < pend) {
1402 	if (decodePkt(p, (pend - p), &pkt))
1403 	    return -1;
1404 
1405 	if (pkt.tag == PGPTAG_PUBLIC_KEY && pkts != p) {
1406 	    *certlen = p - pkts;
1407 	    return 0;
1408 	}
1409 
1410 	p += (pkt.body - pkt.head) + pkt.blen;
1411     }
1412 
1413     *certlen = pktslen;
1414 
1415     return 0;
1416 }
1417 
pgpArmorWrap(int atype,const unsigned char * s,size_t ns)1418 char * pgpArmorWrap(int atype, const unsigned char * s, size_t ns)
1419 {
1420     char *buf = NULL, *val = NULL;
1421     char *enc = rpmBase64Encode(s, ns, -1);
1422     char *crc = rpmBase64CRC(s, ns);
1423     const char *valstr = pgpValStr(pgpArmorTbl, atype);
1424 
1425     if (crc != NULL && enc != NULL) {
1426 	rasprintf(&buf, "%s=%s", enc, crc);
1427     }
1428     free(crc);
1429     free(enc);
1430 
1431     rasprintf(&val, "-----BEGIN PGP %s-----\nVersion: rpm-" VERSION " (NSS-3)\n\n"
1432 		    "%s\n-----END PGP %s-----\n",
1433 		    valstr, buf != NULL ? buf : "", valstr);
1434 
1435     free(buf);
1436     return val;
1437 }
1438 
1439