Line data Source code
1 : /* keybox-openpgp.c - OpenPGP key parsing
2 : * Copyright (C) 2001, 2003, 2011 Free Software Foundation, Inc.
3 : *
4 : * This file is part of GnuPG.
5 : *
6 : * GnuPG is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation; either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * GnuPG is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License
17 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : /* This is a simple OpenPGP parser suitable for all OpenPGP key
21 : material. It just provides the functionality required to build and
22 : parse an KBX OpenPGP key blob. Thus it is not a complete parser.
23 : However it is self-contained and optimized for fast in-memory
24 : parsing. Note that we don't support old ElGamal v3 keys
25 : anymore. */
26 :
27 : #include <config.h>
28 : #include <stdlib.h>
29 : #include <stdio.h>
30 : #include <string.h>
31 : #include <errno.h>
32 : #include <assert.h>
33 :
34 : #include "keybox-defs.h"
35 :
36 : #include <gcrypt.h>
37 :
38 : #include "../common/openpgpdefs.h"
39 : #include "host2net.h"
40 :
41 : /* Assume a valid OpenPGP packet at the address pointed to by BUFBTR
42 : which has a maximum length as stored at BUFLEN. Return the header
43 : information of that packet and advance the pointer stored at BUFPTR
44 : to the next packet; also adjust the length stored at BUFLEN to
45 : match the remaining bytes. If there are no more packets, store NULL
46 : at BUFPTR. Return an non-zero error code on failure or the
47 : following data on success:
48 :
49 : R_DATAPKT = Pointer to the begin of the packet data.
50 : R_DATALEN = Length of this data. This has already been checked to fit
51 : into the buffer.
52 : R_PKTTYPE = The packet type.
53 : R_NTOTAL = The total number of bytes of this packet
54 :
55 : Note that these values are only updated on success.
56 : */
57 : static gpg_error_t
58 486 : next_packet (unsigned char const **bufptr, size_t *buflen,
59 : unsigned char const **r_data, size_t *r_datalen, int *r_pkttype,
60 : size_t *r_ntotal)
61 : {
62 486 : const unsigned char *buf = *bufptr;
63 486 : size_t len = *buflen;
64 : int c, ctb, pkttype;
65 : unsigned long pktlen;
66 :
67 486 : if (!len)
68 0 : return gpg_error (GPG_ERR_NO_DATA);
69 :
70 486 : ctb = *buf++; len--;
71 486 : if ( !(ctb & 0x80) )
72 0 : return gpg_error (GPG_ERR_INV_PACKET); /* Invalid CTB. */
73 :
74 486 : if ((ctb & 0x40)) /* New style (OpenPGP) CTB. */
75 : {
76 0 : pkttype = (ctb & 0x3f);
77 0 : if (!len)
78 0 : return gpg_error (GPG_ERR_INV_PACKET); /* No 1st length byte. */
79 0 : c = *buf++; len--;
80 0 : if (pkttype == PKT_COMPRESSED)
81 0 : return gpg_error (GPG_ERR_UNEXPECTED); /* ... packet in a keyblock. */
82 0 : if ( c < 192 )
83 0 : pktlen = c;
84 0 : else if ( c < 224 )
85 : {
86 0 : pktlen = (c - 192) * 256;
87 0 : if (!len)
88 0 : return gpg_error (GPG_ERR_INV_PACKET); /* No 2nd length byte. */
89 0 : c = *buf++; len--;
90 0 : pktlen += c + 192;
91 : }
92 0 : else if (c == 255)
93 : {
94 0 : if (len <4 )
95 0 : return gpg_error (GPG_ERR_INV_PACKET); /* No length bytes. */
96 0 : pktlen = buf32_to_ulong (buf);
97 0 : buf += 4;
98 0 : len -= 4;
99 : }
100 : else /* Partial length encoding is not allowed for key packets. */
101 0 : return gpg_error (GPG_ERR_UNEXPECTED);
102 : }
103 : else /* Old style CTB. */
104 : {
105 : int lenbytes;
106 :
107 486 : pktlen = 0;
108 486 : pkttype = (ctb>>2)&0xf;
109 486 : lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
110 486 : if (!lenbytes) /* Not allowed in key packets. */
111 0 : return gpg_error (GPG_ERR_UNEXPECTED);
112 486 : if (len < lenbytes)
113 0 : return gpg_error (GPG_ERR_INV_PACKET); /* Not enough length bytes. */
114 1121 : for (; lenbytes; lenbytes--)
115 : {
116 635 : pktlen <<= 8;
117 635 : pktlen |= *buf++; len--;
118 : }
119 : }
120 :
121 : /* Do some basic sanity check. */
122 486 : switch (pkttype)
123 : {
124 : case PKT_SIGNATURE:
125 : case PKT_SECRET_KEY:
126 : case PKT_PUBLIC_KEY:
127 : case PKT_SECRET_SUBKEY:
128 : case PKT_MARKER:
129 : case PKT_RING_TRUST:
130 : case PKT_USER_ID:
131 : case PKT_PUBLIC_SUBKEY:
132 : case PKT_OLD_COMMENT:
133 : case PKT_ATTRIBUTE:
134 : case PKT_COMMENT:
135 : case PKT_GPG_CONTROL:
136 486 : break; /* Okay these are allowed packets. */
137 : default:
138 0 : return gpg_error (GPG_ERR_UNEXPECTED);
139 : }
140 :
141 486 : if (pkttype == 63 && pktlen == 0xFFFFFFFF)
142 : /* Sometimes the decompressing layer enters an error state in
143 : which it simply outputs 0xff for every byte read. If we have a
144 : stream of 0xff bytes, then it will be detected as a new format
145 : packet with type 63 and a 4-byte encoded length that is 4G-1.
146 : Since packets with type 63 are private and we use them as a
147 : control packet, which won't be 4 GB, we reject such packets as
148 : invalid. */
149 0 : return gpg_error (GPG_ERR_INV_PACKET);
150 :
151 486 : if (pktlen > len)
152 0 : return gpg_error (GPG_ERR_INV_PACKET); /* Packet length header too long. */
153 :
154 486 : *r_data = buf;
155 486 : *r_datalen = pktlen;
156 486 : *r_pkttype = pkttype;
157 486 : *r_ntotal = (buf - *bufptr) + pktlen;
158 :
159 486 : *bufptr = buf + pktlen;
160 486 : *buflen = len - pktlen;
161 486 : if (!*buflen)
162 66 : *bufptr = NULL;
163 :
164 486 : return 0;
165 : }
166 :
167 :
168 : /* Parse a key packet and store the information in KI. */
169 : static gpg_error_t
170 124 : parse_key (const unsigned char *data, size_t datalen,
171 : struct _keybox_openpgp_key_info *ki)
172 : {
173 : gpg_error_t err;
174 124 : const unsigned char *data_start = data;
175 : int i, version, algorithm;
176 : size_t n;
177 : int npkey;
178 : unsigned char hashbuffer[768];
179 124 : const unsigned char *mpi_n = NULL;
180 124 : size_t mpi_n_len = 0, mpi_e_len = 0;
181 : gcry_md_hd_t md;
182 124 : int is_ecc = 0;
183 :
184 124 : if (datalen < 5)
185 0 : return gpg_error (GPG_ERR_INV_PACKET);
186 124 : version = *data++; datalen--;
187 124 : if (version < 2 || version > 4 )
188 0 : return gpg_error (GPG_ERR_INV_PACKET); /* Invalid version. */
189 :
190 : /*timestamp = ((data[0]<<24)|(data[1]<<16)|(data[2]<<8)|(data[3]));*/
191 124 : data +=4; datalen -=4;
192 :
193 124 : if (version < 4)
194 : {
195 0 : if (datalen < 2)
196 0 : return gpg_error (GPG_ERR_INV_PACKET);
197 0 : data +=2; datalen -= 2;
198 : }
199 :
200 124 : if (!datalen)
201 0 : return gpg_error (GPG_ERR_INV_PACKET);
202 124 : algorithm = *data++; datalen--;
203 :
204 124 : switch (algorithm)
205 : {
206 : case PUBKEY_ALGO_RSA:
207 : case PUBKEY_ALGO_RSA_E:
208 : case PUBKEY_ALGO_RSA_S:
209 32 : npkey = 2;
210 32 : break;
211 : case PUBKEY_ALGO_ELGAMAL_E:
212 : case PUBKEY_ALGO_ELGAMAL:
213 40 : npkey = 3;
214 40 : break;
215 : case PUBKEY_ALGO_DSA:
216 40 : npkey = 4;
217 40 : break;
218 : case PUBKEY_ALGO_ECDH:
219 5 : npkey = 3;
220 5 : is_ecc = 1;
221 5 : break;
222 : case PUBKEY_ALGO_ECDSA:
223 : case PUBKEY_ALGO_EDDSA:
224 7 : npkey = 2;
225 7 : is_ecc = 1;
226 7 : break;
227 : default: /* Unknown algorithm. */
228 0 : return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
229 : }
230 :
231 124 : ki->algo = algorithm;
232 :
233 497 : for (i=0; i < npkey; i++ )
234 : {
235 : unsigned int nbits, nbytes;
236 :
237 373 : if (datalen < 2)
238 0 : return gpg_error (GPG_ERR_INV_PACKET);
239 :
240 373 : if (is_ecc && (i == 0 || i == 2))
241 : {
242 17 : nbytes = data[0];
243 17 : if (nbytes < 2 || nbytes > 254)
244 0 : return gpg_error (GPG_ERR_INV_PACKET);
245 17 : nbytes++; /* The size byte itself. */
246 34 : if (datalen < nbytes)
247 0 : return gpg_error (GPG_ERR_INV_PACKET);
248 : }
249 : else
250 : {
251 356 : nbits = ((data[0]<<8)|(data[1]));
252 356 : data += 2;
253 356 : datalen -= 2;
254 356 : nbytes = (nbits+7) / 8;
255 356 : if (datalen < nbytes)
256 0 : return gpg_error (GPG_ERR_INV_PACKET);
257 : /* For use by v3 fingerprint calculation we need to know the RSA
258 : modulus and exponent. */
259 356 : if (i==0)
260 : {
261 112 : mpi_n = data;
262 112 : mpi_n_len = nbytes;
263 : }
264 244 : else if (i==1)
265 124 : mpi_e_len = nbytes;
266 : }
267 :
268 373 : data += nbytes; datalen -= nbytes;
269 : }
270 124 : n = data - data_start;
271 :
272 124 : if (version < 4)
273 : {
274 : /* We do not support any other algorithm than RSA in v3
275 : packets. */
276 0 : if (algorithm < 1 || algorithm > 3)
277 0 : return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
278 :
279 0 : err = gcry_md_open (&md, GCRY_MD_MD5, 0);
280 0 : if (err)
281 0 : return err; /* Oops */
282 0 : gcry_md_write (md, mpi_n, mpi_n_len);
283 0 : gcry_md_write (md, mpi_n+mpi_n_len+2, mpi_e_len);
284 0 : memcpy (ki->fpr, gcry_md_read (md, 0), 16);
285 0 : gcry_md_close (md);
286 0 : ki->fprlen = 16;
287 :
288 0 : if (mpi_n_len < 8)
289 : {
290 : /* Moduli less than 64 bit are out of the specs scope. Zero
291 : them out because this is what gpg does too. */
292 0 : memset (ki->keyid, 0, 8);
293 : }
294 : else
295 0 : memcpy (ki->keyid, mpi_n + mpi_n_len - 8, 8);
296 : }
297 : else
298 : {
299 : /* Its a pitty that we need to prefix the buffer with the tag
300 : and a length header: We can't simply pass it to the fast
301 : hashing function for that reason. It might be a good idea to
302 : have a scatter-gather enabled hash function. What we do here
303 : is to use a static buffer if this one is large enough and
304 : only use the regular hash functions if this buffer is not
305 : large enough. */
306 124 : if ( 3 + n < sizeof hashbuffer )
307 : {
308 124 : hashbuffer[0] = 0x99; /* CTB */
309 124 : hashbuffer[1] = (n >> 8); /* 2 byte length header. */
310 124 : hashbuffer[2] = n;
311 124 : memcpy (hashbuffer + 3, data_start, n);
312 124 : gcry_md_hash_buffer (GCRY_MD_SHA1, ki->fpr, hashbuffer, 3 + n);
313 : }
314 : else
315 : {
316 0 : err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
317 0 : if (err)
318 0 : return err; /* Oops */
319 0 : gcry_md_putc (md, 0x99 ); /* CTB */
320 0 : gcry_md_putc (md, (n >> 8) ); /* 2 byte length header. */
321 0 : gcry_md_putc (md, n );
322 0 : gcry_md_write (md, data_start, n);
323 0 : memcpy (ki->fpr, gcry_md_read (md, 0), 20);
324 0 : gcry_md_close (md);
325 : }
326 124 : ki->fprlen = 20;
327 124 : memcpy (ki->keyid, ki->fpr+12, 8);
328 : }
329 :
330 124 : return 0;
331 : }
332 :
333 :
334 :
335 : /* The caller must pass the address of an INFO structure which will
336 : get filled on success with information pertaining to the OpenPGP
337 : keyblock IMAGE of length IMAGELEN. Note that a caller does only
338 : need to release this INFO structure if the function returns
339 : success. If NPARSED is not NULL the actual number of bytes parsed
340 : will be stored at this address. */
341 : gpg_error_t
342 66 : _keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
343 : size_t *nparsed, keybox_openpgp_info_t info)
344 : {
345 66 : gpg_error_t err = 0;
346 : const unsigned char *image_start, *data;
347 : size_t n, datalen;
348 : int pkttype;
349 66 : int first = 1;
350 66 : int read_error = 0;
351 66 : struct _keybox_openpgp_key_info *k, **ktail = NULL;
352 66 : struct _keybox_openpgp_uid_info *u, **utail = NULL;
353 :
354 66 : memset (info, 0, sizeof *info);
355 66 : if (nparsed)
356 66 : *nparsed = 0;
357 :
358 66 : image_start = image;
359 618 : while (image)
360 : {
361 486 : err = next_packet (&image, &imagelen, &data, &datalen, &pkttype, &n);
362 486 : if (err)
363 : {
364 0 : read_error = 1;
365 0 : break;
366 : }
367 :
368 486 : if (first)
369 : {
370 66 : if (pkttype == PKT_PUBLIC_KEY)
371 : ;
372 0 : else if (pkttype == PKT_SECRET_KEY)
373 0 : info->is_secret = 1;
374 : else
375 : {
376 0 : err = gpg_error (GPG_ERR_UNEXPECTED);
377 0 : if (nparsed)
378 0 : *nparsed += n;
379 0 : break;
380 : }
381 66 : first = 0;
382 : }
383 420 : else if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY)
384 : break; /* Next keyblock encountered - ready. */
385 :
386 486 : if (nparsed)
387 486 : *nparsed += n;
388 :
389 486 : if (pkttype == PKT_SIGNATURE)
390 : {
391 : /* For now we only count the total number of signatures. */
392 282 : info->nsigs++;
393 : }
394 204 : else if (pkttype == PKT_USER_ID)
395 : {
396 80 : info->nuids++;
397 80 : if (info->nuids == 1)
398 : {
399 66 : info->uids.off = data - image_start;
400 66 : info->uids.len = datalen;
401 66 : utail = &info->uids.next;
402 : }
403 : else
404 : {
405 14 : u = xtrycalloc (1, sizeof *u);
406 14 : if (!u)
407 : {
408 0 : err = gpg_error_from_syserror ();
409 0 : break;
410 : }
411 14 : u->off = data - image_start;
412 14 : u->len = datalen;
413 14 : *utail = u;
414 14 : utail = &u->next;
415 : }
416 : }
417 124 : else if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY)
418 : {
419 66 : err = parse_key (data, datalen, &info->primary);
420 132 : if (err)
421 0 : break;
422 : }
423 58 : else if( pkttype == PKT_PUBLIC_SUBKEY && datalen && *data == '#' )
424 : {
425 : /* Early versions of GnuPG used old PGP comment packets;
426 : * luckily all those comments are prefixed by a hash
427 : * sign - ignore these packets. */
428 : }
429 58 : else if (pkttype == PKT_PUBLIC_SUBKEY || pkttype == PKT_SECRET_SUBKEY)
430 : {
431 58 : info->nsubkeys++;
432 58 : if (info->nsubkeys == 1)
433 : {
434 52 : err = parse_key (data, datalen, &info->subkeys);
435 52 : if (err)
436 : {
437 0 : info->nsubkeys--;
438 : /* We ignore subkeys with unknown algorithms. */
439 0 : if (gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM
440 0 : || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM)
441 0 : err = 0;
442 0 : if (err)
443 0 : break;
444 : }
445 : else
446 52 : ktail = &info->subkeys.next;
447 : }
448 : else
449 : {
450 6 : k = xtrycalloc (1, sizeof *k);
451 6 : if (!k)
452 : {
453 0 : err = gpg_error_from_syserror ();
454 0 : break;
455 : }
456 6 : err = parse_key (data, datalen, k);
457 6 : if (err)
458 : {
459 0 : xfree (k);
460 0 : info->nsubkeys--;
461 : /* We ignore subkeys with unknown algorithms. */
462 0 : if (gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM
463 0 : || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM)
464 0 : err = 0;
465 0 : if (err)
466 0 : break;
467 : }
468 : else
469 : {
470 6 : *ktail = k;
471 6 : ktail = &k->next;
472 : }
473 : }
474 : }
475 : }
476 :
477 66 : if (err)
478 : {
479 0 : _keybox_destroy_openpgp_info (info);
480 0 : if (!read_error)
481 : {
482 : /* Packet parsing worked, thus we should be able to skip the
483 : rest of the keyblock. */
484 0 : while (image)
485 : {
486 0 : if (next_packet (&image, &imagelen,
487 : &data, &datalen, &pkttype, &n) )
488 0 : break; /* Another error - stop here. */
489 :
490 0 : if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY)
491 : break; /* Next keyblock encountered - ready. */
492 :
493 0 : if (nparsed)
494 0 : *nparsed += n;
495 : }
496 : }
497 : }
498 :
499 66 : return err;
500 : }
501 :
502 :
503 : /* Release any malloced data in INFO but not INFO itself! */
504 : void
505 66 : _keybox_destroy_openpgp_info (keybox_openpgp_info_t info)
506 : {
507 : struct _keybox_openpgp_key_info *k, *k2;
508 : struct _keybox_openpgp_uid_info *u, *u2;
509 :
510 66 : assert (!info->primary.next);
511 72 : for (k=info->subkeys.next; k; k = k2)
512 : {
513 6 : k2 = k->next;
514 6 : xfree (k);
515 : }
516 :
517 80 : for (u=info->uids.next; u; u = u2)
518 : {
519 14 : u2 = u->next;
520 14 : xfree (u);
521 : }
522 66 : }
|