Bug Summary

File:rpmio/rpmpgp.c
Warning:line 364, column 22
The right operand of '+' is a garbage value

Annotated Source Code

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