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