1 /* keybox-openpgp.c - OpenPGP key parsing
2 * Copyright (C) 2001, 2003 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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 2 of the License, or
9 * (at your option) any later version.
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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 /* This is a simple OpenPGP parser suitable for all OpenPGP key
23 material. It just provides the functionality required to build and
24 parse an KBX OpenPGP key blob. Thus it is not a complete parser.
25 However it is self-contained and optimized for fast in-memory
26 parsing. Note that we don't support old ElGamal v3 keys
36 #include "keybox-defs.h"
44 PKT_PUBKEY_ENC
=1, /* public key encrypted packet */
45 PKT_SIGNATURE
=2, /* secret key encrypted packet */
46 PKT_SYMKEY_ENC
=3, /* session key packet (OpenPGP)*/
47 PKT_ONEPASS_SIG
=4, /* one pass sig packet (OpenPGP)*/
48 PKT_SECRET_KEY
=5, /* secret key */
49 PKT_PUBLIC_KEY
=6, /* public key */
50 PKT_SECRET_SUBKEY
=7, /* secret subkey (OpenPGP) */
51 PKT_COMPRESSED
=8, /* compressed data packet */
52 PKT_ENCRYPTED
=9, /* conventional encrypted data */
53 PKT_MARKER
=10, /* marker packet (OpenPGP) */
54 PKT_PLAINTEXT
=11, /* plaintext data with filename and mode */
55 PKT_RING_TRUST
=12, /* keyring trust packet */
56 PKT_USER_ID
=13, /* user id packet */
57 PKT_PUBLIC_SUBKEY
=14, /* public subkey (OpenPGP) */
58 PKT_OLD_COMMENT
=16, /* comment packet from an OpenPGP draft */
59 PKT_ATTRIBUTE
=17, /* PGP's attribute packet */
60 PKT_ENCRYPTED_MDC
=18, /* integrity protected encrypted data */
61 PKT_MDC
=19, /* manipulation detection code packet */
62 PKT_COMMENT
=61, /* new comment packet (private) */
63 PKT_GPG_CONTROL
=63 /* internal control packet */
68 /* Assume a valid OpenPGP packet at the address pointed to by BUFBTR
69 which is of amaximum length as stored at BUFLEN. Return the header
70 information of that packet and advance the pointer stored at BUFPTR
71 to the next packet; also adjust the length stored at BUFLEN to
72 match the remaining bytes. If there are no more packets, store NULL
73 at BUFPTR. Return an non-zero error code on failure or the
74 follwing data on success:
76 R_DATAPKT = Pointer to the begin of the packet data.
77 R_DATALEN = Length of this data. This has already been checked to fit
79 R_PKTTYPE = The packet type.
80 R_NTOTAL = The total number of bytes of this packet
82 Note that these values are only updated on success.
85 next_packet (unsigned char const **bufptr
, size_t *buflen
,
86 unsigned char const **r_data
, size_t *r_datalen
, int *r_pkttype
,
89 const unsigned char *buf
= *bufptr
;
95 return gpg_error (GPG_ERR_NO_DATA
);
99 return gpg_error (GPG_ERR_INV_PACKET
); /* Invalid CTB. */
102 if ((ctb
& 0x40)) /* New style (OpenPGP) CTB. */
104 pkttype
= (ctb
& 0x3f);
106 return gpg_error (GPG_ERR_INV_PACKET
); /* No 1st length byte. */
108 if (pkttype
== PKT_COMPRESSED
)
109 return gpg_error (GPG_ERR_UNEXPECTED
); /* ... packet in a keyblock. */
114 pktlen
= (c
- 192) * 256;
116 return gpg_error (GPG_ERR_INV_PACKET
); /* No 2nd length byte. */
123 return gpg_error (GPG_ERR_INV_PACKET
); /* No length bytes. */
124 pktlen
= (*buf
++) << 24;
125 pktlen
|= (*buf
++) << 16;
126 pktlen
|= (*buf
++) << 8;
130 else /* Partial length encoding is not allowed for key packets. */
131 return gpg_error (GPG_ERR_UNEXPECTED
);
133 else /* Old style CTB. */
138 pkttype
= (ctb
>>2)&0xf;
139 lenbytes
= ((ctb
&3)==3)? 0 : (1<<(ctb
& 3));
140 if (!lenbytes
) /* Not allowed in key packets. */
141 return gpg_error (GPG_ERR_UNEXPECTED
);
143 return gpg_error (GPG_ERR_INV_PACKET
); /* Not enough length bytes. */
144 for (; lenbytes
; lenbytes
--)
147 pktlen
|= *buf
++; len
--;
151 /* Do some basic sanity check. */
157 case PKT_SECRET_SUBKEY
:
161 case PKT_PUBLIC_SUBKEY
:
162 case PKT_OLD_COMMENT
:
165 case PKT_GPG_CONTROL
:
166 break; /* Okay these are allowed packets. */
168 return gpg_error (GPG_ERR_UNEXPECTED
);
171 if (pktlen
== 0xffffffff)
172 return gpg_error (GPG_ERR_INV_PACKET
);
175 return gpg_error (GPG_ERR_INV_PACKET
); /* Packet length header too long. */
179 *r_pkttype
= pkttype
;
180 *r_ntotal
= (buf
- *bufptr
) + pktlen
;
182 *bufptr
= buf
+ pktlen
;
183 *buflen
= len
- pktlen
;
191 /* Parse a key packet and store the ionformation in KI. */
193 parse_key (const unsigned char *data
, size_t datalen
,
194 struct _keybox_openpgp_key_info
*ki
)
197 const unsigned char *data_start
= data
;
198 int i
, version
, algorithm
;
200 unsigned long timestamp
, expiredate
;
202 unsigned char hashbuffer
[768];
203 const unsigned char *mpi_n
= NULL
;
204 size_t mpi_n_len
= 0, mpi_e_len
= 0;
208 return gpg_error (GPG_ERR_INV_PACKET
);
209 version
= *data
++; datalen
--;
210 if (version
< 2 || version
> 4 )
211 return gpg_error (GPG_ERR_INV_PACKET
); /* Invalid version. */
213 timestamp
= ((data
[0]<<24)|(data
[1]<<16)|(data
[2]<<8)|(data
[3]));
214 data
+=4; datalen
-=4;
218 unsigned short ndays
;
221 return gpg_error (GPG_ERR_INV_PACKET
);
222 ndays
= ((data
[0]<<8)|(data
[1]));
223 data
+=2; datalen
-= 2;
225 expiredate
= ndays
? (timestamp
+ ndays
* 86400L) : 0;
228 expiredate
= 0; /* This is stored in the self-signature. */
231 return gpg_error (GPG_ERR_INV_PACKET
);
232 algorithm
= *data
++; datalen
--;
242 case 20: /* Elgamal */
248 default: /* Unknown algorithm. */
249 return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM
);
252 for (i
=0; i
< npkey
; i
++ )
254 unsigned int nbits
, nbytes
;
257 return gpg_error (GPG_ERR_INV_PACKET
);
258 nbits
= ((data
[0]<<8)|(data
[1]));
259 data
+= 2; datalen
-=2;
260 nbytes
= (nbits
+7) / 8;
261 if (datalen
< nbytes
)
262 return gpg_error (GPG_ERR_INV_PACKET
);
263 /* For use by v3 fingerprint calculation we need to know the RSA
264 modulus and exponent. */
273 data
+= nbytes
; datalen
-= nbytes
;
275 n
= data
- data_start
;
279 /* We do not support any other algorithm than RSA in v3
281 if (algorithm
< 1 || algorithm
> 3)
282 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM
);
284 err
= gcry_md_open (&md
, GCRY_MD_MD5
, 0);
286 return err
; /* Oops */
287 gcry_md_write (md
, mpi_n
, mpi_n_len
);
288 gcry_md_write (md
, mpi_n
+mpi_n_len
+2, mpi_e_len
);
289 memcpy (ki
->fpr
, gcry_md_read (md
, 0), 16);
295 /* Moduli less than 64 bit are out of the specs scope. Zero
296 them out becuase this is what gpg does too. */
297 memset (ki
->keyid
, 0, 8);
300 memcpy (ki
->keyid
, mpi_n
+ mpi_n_len
- 8, 8);
304 /* Its a pitty that we need to prefix the buffer with the tag
305 and a length header: We can't simply pass it to the fast
306 hashing fucntion for that reason. It might be a good idea to
307 have a scatter-gather enabled hash function. What we do here
308 is to use a static buffer if this one is large enough and
309 only use the regular hash fucntions if this buffer is not
311 if ( 3 + n
< sizeof hashbuffer
)
313 hashbuffer
[0] = 0x99; /* CTB */
314 hashbuffer
[1] = (n
>> 8); /* 2 byte length header. */
316 memcpy (hashbuffer
+ 3, data_start
, n
);
317 gcry_md_hash_buffer (GCRY_MD_SHA1
, ki
->fpr
, hashbuffer
, 3 + n
);
321 err
= gcry_md_open (&md
, GCRY_MD_SHA1
, 0);
323 return err
; /* Oops */
324 gcry_md_putc (md
, 0x99 ); /* CTB */
325 gcry_md_putc (md
, (n
>> 8) ); /* 2 byte length header. */
326 gcry_md_putc (md
, n
);
327 gcry_md_write (md
, data_start
, n
);
328 memcpy (ki
->fpr
, gcry_md_read (md
, 0), 20);
332 memcpy (ki
->keyid
, ki
->fpr
+12, 8);
340 /* The caller must pass the address of an INFO structure which will
341 get filled on success with information pertaining to the OpenPGP
342 keyblock IMAGE of length IMAGELEN. Note that a caller does only
343 need to release this INFO structure when the function returns
344 success. If NPARSED is not NULL the actual number of bytes parsed
345 will be stored at this address. */
347 _keybox_parse_openpgp (const unsigned char *image
, size_t imagelen
,
349 keybox_openpgp_info_t info
)
352 const unsigned char *image_start
, *data
;
356 struct _keybox_openpgp_key_info
*k
, **ktail
= NULL
;
357 struct _keybox_openpgp_uid_info
*u
, **utail
= NULL
;
359 memset (info
, 0, sizeof *info
);
366 err
= next_packet (&image
, &imagelen
, &data
, &datalen
, &pkttype
, &n
);
372 if (pkttype
== PKT_PUBLIC_KEY
)
374 else if (pkttype
== PKT_SECRET_KEY
)
378 err
= gpg_error (GPG_ERR_UNEXPECTED
);
383 else if (pkttype
== PKT_PUBLIC_KEY
|| pkttype
== PKT_SECRET_KEY
)
384 break; /* Next keyblock encountered - ready. */
389 if (pkttype
== PKT_SIGNATURE
)
391 /* For now we only count the total number of signatures. */
394 else if (pkttype
== PKT_USER_ID
)
397 if (info
->nuids
== 1)
399 info
->uids
.off
= data
- image_start
;
400 info
->uids
.len
= datalen
;
401 utail
= &info
->uids
.next
;
405 u
= xtrycalloc (1, sizeof *u
);
408 err
= gpg_error_from_errno (errno
);
411 u
->off
= data
- image_start
;
417 else if (pkttype
== PKT_PUBLIC_KEY
|| pkttype
== PKT_SECRET_KEY
)
419 err
= parse_key (data
, datalen
, &info
->primary
);
423 else if( pkttype
== PKT_PUBLIC_SUBKEY
&& datalen
&& *data
== '#' )
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. */
429 else if (pkttype
== PKT_PUBLIC_SUBKEY
|| pkttype
== PKT_SECRET_SUBKEY
)
432 if (info
->nsubkeys
== 1)
434 err
= parse_key (data
, datalen
, &info
->subkeys
);
438 if (gpg_err_code (err
) != GPG_ERR_UNKNOWN_ALGORITHM
)
440 /* We ignore subkeys with unknown algorithms. */
443 ktail
= &info
->subkeys
.next
;
447 k
= xtrycalloc (1, sizeof *k
);
450 err
= gpg_error_from_errno (errno
);
453 err
= parse_key (data
, datalen
, k
);
458 if (gpg_err_code (err
) != GPG_ERR_UNKNOWN_ALGORITHM
)
460 /* We ignore subkeys with unknown algorithms. */
473 _keybox_destroy_openpgp_info (info
);
475 && (gpg_err_code (err
) == GPG_ERR_UNSUPPORTED_ALGORITHM
476 || gpg_err_code (err
) == GPG_ERR_UNKNOWN_ALGORITHM
))
478 /* We are able to skip to the end of this keyblock. */
481 if (next_packet (&image
, &imagelen
,
482 &data
, &datalen
, &pkttype
, &n
) )
483 break; /* Another error - stop here. */
485 if (pkttype
== PKT_PUBLIC_KEY
|| pkttype
== PKT_SECRET_KEY
)
486 break; /* Next keyblock encountered - ready. */
498 /* Release any malloced data in INFO but not INFO itself! */
500 _keybox_destroy_openpgp_info (keybox_openpgp_info_t info
)
502 struct _keybox_openpgp_key_info
*k
, *k2
;
503 struct _keybox_openpgp_uid_info
*u
, *u2
;
505 assert (!info
->primary
.next
);
506 for (k
=info
->subkeys
.next
; k
; k
= k2
)
512 for (u
=info
->uids
.next
; u
; u
= u2
)