xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*-
2  * Copyright (c) 2009 The NetBSD Foundation, Inc.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to The NetBSD Foundation
6  * by Alistair Crooks (agc@NetBSD.org)
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 /*
30  * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
31  * All rights reserved.
32  * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
33  * their moral rights under the UK Copyright Design and Patents Act 1988 to
34  * be recorded as the authors of this copyright work.
35  *
36  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37  * use this file except in compliance with the License.
38  *
39  * You may obtain a copy of the License at
40  *     http://www.apache.org/licenses/LICENSE-2.0
41  *
42  * Unless required by applicable law or agreed to in writing, software
43  * distributed under the License is distributed on an "AS IS" BASIS,
44  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45  *
46  * See the License for the specific language governing permissions and
47  * limitations under the License.
48  */
49 
50 /** \file
51  */
52 #include "config.h"
53 
54 #ifdef HAVE_SYS_CDEFS_H
55 #include <sys/cdefs.h>
56 #endif
57 
58 #if defined(__NetBSD__)
59 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
60 __RCSID("$NetBSD: keyring.c,v 1.55 2017/03/27 21:19:12 khorben Exp $");
61 #endif
62 
63 #ifdef HAVE_FCNTL_H
64 #include <fcntl.h>
65 #endif
66 
67 #include <regex.h>
68 #include <stdlib.h>
69 #include <string.h>
70 
71 #ifdef HAVE_TERMIOS_H
72 #include <termios.h>
73 #endif
74 
75 #ifdef HAVE_UNISTD_H
76 #include <unistd.h>
77 #endif
78 
79 #include "types.h"
80 #include "keyring.h"
81 #include "packet-parse.h"
82 #include "signature.h"
83 #include "netpgpsdk.h"
84 #include "readerwriter.h"
85 #include "netpgpdefs.h"
86 #include "packet.h"
87 #include "crypto.h"
88 #include "validate.h"
89 #include "netpgpdefs.h"
90 #include "netpgpdigest.h"
91 
92 
93 
94 /**
95    \ingroup HighLevel_Keyring
96 
97    \brief Creates a new pgp_key_t struct
98 
99    \return A new pgp_key_t struct, initialised to zero.
100 
101    \note The returned pgp_key_t struct must be freed after use with pgp_keydata_free.
102 */
103 
104 pgp_key_t  *
105 pgp_keydata_new(void)
106 {
107 	return calloc(1, sizeof(pgp_key_t));
108 }
109 
110 
111 /**
112  \ingroup HighLevel_Keyring
113 
114  \brief Frees keydata and its memory
115 
116  \param keydata Key to be freed.
117 
118  \note This frees the keydata itself, as well as any other memory alloc-ed by it.
119 */
120 void
121 pgp_keydata_free(pgp_key_t *keydata)
122 {
123 	unsigned        n;
124 
125 	for (n = 0; n < keydata->uidc; ++n) {
126 		pgp_userid_free(&keydata->uids[n]);
127 	}
128 	free(keydata->uids);
129 	keydata->uids = NULL;
130 	keydata->uidc = 0;
131 
132 	for (n = 0; n < keydata->packetc; ++n) {
133 		pgp_subpacket_free(&keydata->packets[n]);
134 	}
135 	free(keydata->packets);
136 	keydata->packets = NULL;
137 	keydata->packetc = 0;
138 
139 	if (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) {
140 		pgp_pubkey_free(&keydata->key.pubkey);
141 	} else {
142 		pgp_seckey_free(&keydata->key.seckey);
143 	}
144 
145 	free(keydata);
146 }
147 
148 /**
149  \ingroup HighLevel_KeyGeneral
150 
151  \brief Returns the public key in the given keydata.
152  \param keydata
153 
154   \return Pointer to public key
155 
156   \note This is not a copy, do not free it after use.
157 */
158 
159 const pgp_pubkey_t *
160 pgp_get_pubkey(const pgp_key_t *keydata)
161 {
162 	return (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) ?
163 				&keydata->key.pubkey :
164 				&keydata->key.seckey.pubkey;
165 }
166 
167 /**
168 \ingroup HighLevel_KeyGeneral
169 
170 \brief Check whether this is a secret key or not.
171 */
172 
173 unsigned
174 pgp_is_key_secret(const pgp_key_t *data)
175 {
176 	return data->type != PGP_PTAG_CT_PUBLIC_KEY;
177 }
178 
179 /**
180  \ingroup HighLevel_KeyGeneral
181 
182  \brief Returns the secret key in the given keydata.
183 
184  \note This is not a copy, do not free it after use.
185 
186  \note This returns a const.  If you need to be able to write to this
187  pointer, use pgp_get_writable_seckey
188 */
189 
190 const pgp_seckey_t *
191 pgp_get_seckey(const pgp_key_t *data)
192 {
193 	return (data->type == PGP_PTAG_CT_SECRET_KEY) ?
194 				&data->key.seckey : NULL;
195 }
196 
197 /**
198  \ingroup HighLevel_KeyGeneral
199 
200   \brief Returns the secret key in the given keydata.
201 
202   \note This is not a copy, do not free it after use.
203 
204   \note If you do not need to be able to modify this key, there is an
205   equivalent read-only function pgp_get_seckey.
206 */
207 
208 pgp_seckey_t *
209 pgp_get_writable_seckey(pgp_key_t *data)
210 {
211 	return (data->type == PGP_PTAG_CT_SECRET_KEY) ?
212 				&data->key.seckey : NULL;
213 }
214 
215 /* utility function to zero out memory */
216 void
217 pgp_forget(void *vp, size_t size)
218 {
219 	(void) memset(vp, 0x0, size);
220 }
221 
222 typedef struct {
223 	FILE			*passfp;
224 	const pgp_key_t	*key;
225 	char			*passphrase;
226 	pgp_seckey_t		*seckey;
227 } decrypt_t;
228 
229 static pgp_cb_ret_t
230 decrypt_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
231 {
232 	const pgp_contents_t	*content = &pkt->u;
233 	decrypt_t		*decrypt;
234 	char			 pass[MAX_PASSPHRASE_LENGTH];
235 
236 	decrypt = pgp_callback_arg(cbinfo);
237 	switch (pkt->tag) {
238 	case PGP_PARSER_PTAG:
239 	case PGP_PTAG_CT_USER_ID:
240 	case PGP_PTAG_CT_SIGNATURE:
241 	case PGP_PTAG_CT_SIGNATURE_HEADER:
242 	case PGP_PTAG_CT_SIGNATURE_FOOTER:
243 	case PGP_PTAG_CT_TRUST:
244 		break;
245 
246 	case PGP_GET_PASSPHRASE:
247 		if (pgp_getpassphrase(decrypt->passfp, pass, sizeof(pass)) == 0) {
248 			pass[0] = '\0';
249 		}
250 		*content->skey_passphrase.passphrase = netpgp_strdup(pass);
251 		pgp_forget(pass, sizeof(pass));
252 		return PGP_KEEP_MEMORY;
253 
254 	case PGP_PARSER_ERRCODE:
255 		switch (content->errcode.errcode) {
256 		case PGP_E_P_MPI_FORMAT_ERROR:
257 			/* Generally this means a bad passphrase */
258 			fprintf(stderr, "Bad passphrase!\n");
259 			return PGP_RELEASE_MEMORY;
260 
261 		case PGP_E_P_PACKET_CONSUMED:
262 			/* And this is because of an error we've accepted */
263 			return PGP_RELEASE_MEMORY;
264 		default:
265 			break;
266 		}
267 		(void) fprintf(stderr, "parse error: %s\n",
268 				pgp_errcode(content->errcode.errcode));
269 		return PGP_FINISHED;
270 
271 	case PGP_PARSER_ERROR:
272 		fprintf(stderr, "parse error: %s\n", content->error);
273 		return PGP_FINISHED;
274 
275 	case PGP_PTAG_CT_SECRET_KEY:
276 		if ((decrypt->seckey = calloc(1, sizeof(*decrypt->seckey))) == NULL) {
277 			(void) fprintf(stderr, "decrypt_cb: bad alloc\n");
278 			return PGP_FINISHED;
279 		}
280 		decrypt->seckey->checkhash = calloc(1, PGP_CHECKHASH_SIZE);
281 		*decrypt->seckey = content->seckey;
282 		return PGP_KEEP_MEMORY;
283 
284 	case PGP_PARSER_PACKET_END:
285 		/* nothing to do */
286 		break;
287 
288 	default:
289 		fprintf(stderr, "Unexpected tag %d (0x%x)\n", pkt->tag,
290 			pkt->tag);
291 		return PGP_FINISHED;
292 	}
293 
294 	return PGP_RELEASE_MEMORY;
295 }
296 
297 static pgp_cb_ret_t
298 decrypt_cb_empty(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
299 {
300 	const pgp_contents_t	*content = &pkt->u;
301 
302 	switch (pkt->tag) {
303 	case PGP_GET_PASSPHRASE:
304 		*content->skey_passphrase.passphrase = netpgp_strdup("");
305 		return PGP_KEEP_MEMORY;
306 	default:
307 		return decrypt_cb(pkt, cbinfo);
308 	}
309 }
310 
311 /**
312 \ingroup Core_Keys
313 \brief Decrypts secret key from given keydata with given passphrase
314 \param key Key from which to get secret key
315 \param passphrase Passphrase to use to decrypt secret key
316 \return secret key
317 */
318 pgp_seckey_t *
319 pgp_decrypt_seckey(const pgp_key_t *key, FILE *passfp)
320 {
321 	pgp_stream_t	*stream;
322 	const int	 printerrors = 1;
323 	decrypt_t	 decrypt;
324 
325 	/* XXX first try with an empty passphrase */
326 	(void) memset(&decrypt, 0x0, sizeof(decrypt));
327 	decrypt.key = key;
328 	stream = pgp_new(sizeof(*stream));
329 	pgp_keydata_reader_set(stream, key);
330 	pgp_set_callback(stream, decrypt_cb_empty, &decrypt);
331 	stream->readinfo.accumulate = 1;
332 	pgp_parse(stream, !printerrors);
333 	if (decrypt.seckey != NULL) {
334 		return decrypt.seckey;
335 	}
336 	/* ask for a passphrase */
337 	decrypt.passfp = passfp;
338 	stream = pgp_new(sizeof(*stream));
339 	pgp_keydata_reader_set(stream, key);
340 	pgp_set_callback(stream, decrypt_cb, &decrypt);
341 	stream->readinfo.accumulate = 1;
342 	pgp_parse(stream, !printerrors);
343 	return decrypt.seckey;
344 }
345 
346 /**
347 \ingroup Core_Keys
348 \brief Set secret key in content
349 \param content Content to be set
350 \param key Keydata to get secret key from
351 */
352 void
353 pgp_set_seckey(pgp_contents_t *cont, const pgp_key_t *key)
354 {
355 	*cont->get_seckey.seckey = &key->key.seckey;
356 }
357 
358 /**
359 \ingroup Core_Keys
360 \brief Get Key ID from keydata
361 \param key Keydata to get Key ID from
362 \return Pointer to Key ID inside keydata
363 */
364 const uint8_t *
365 pgp_get_key_id(const pgp_key_t *key)
366 {
367 	return key->sigid;
368 }
369 
370 /**
371 \ingroup Core_Keys
372 \brief How many User IDs in this key?
373 \param key Keydata to check
374 \return Num of user ids
375 */
376 unsigned
377 pgp_get_userid_count(const pgp_key_t *key)
378 {
379 	return key->uidc;
380 }
381 
382 /**
383 \ingroup Core_Keys
384 \brief Get indexed user id from key
385 \param key Key to get user id from
386 \param index Which key to get
387 \return Pointer to requested user id
388 */
389 const uint8_t *
390 pgp_get_userid(const pgp_key_t *key, unsigned subscript)
391 {
392 	return key->uids[subscript];
393 }
394 
395 /**
396    \ingroup HighLevel_Supported
397    \brief Checks whether key's algorithm and type are supported by OpenPGP::SDK
398    \param keydata Key to be checked
399    \return 1 if key algorithm and type are supported by OpenPGP::SDK; 0 if not
400 */
401 
402 unsigned
403 pgp_is_key_supported(const pgp_key_t *key)
404 {
405 	if (key->type == PGP_PTAG_CT_PUBLIC_KEY) {
406 		switch(key->key.pubkey.alg) {
407 		case PGP_PKA_RSA:
408 		case PGP_PKA_DSA:
409 		case PGP_PKA_ELGAMAL:
410 			return 1;
411 		default:
412 			break;
413 		}
414 	}
415 	return 0;
416 }
417 
418 /* \todo check where userid pointers are copied */
419 /**
420 \ingroup Core_Keys
421 \brief Copy user id, including contents
422 \param dst Destination User ID
423 \param src Source User ID
424 \note If dst already has a userid, it will be freed.
425 */
426 static uint8_t *
427 copy_userid(uint8_t **dst, const uint8_t *src)
428 {
429 	size_t          len;
430 
431 	len = strlen((const char *) src);
432 	if (*dst) {
433 		free(*dst);
434 	}
435 	if ((*dst = calloc(1, len + 1)) == NULL) {
436 		(void) fprintf(stderr, "copy_userid: bad alloc\n");
437 	} else {
438 		(void) memcpy(*dst, src, len);
439 	}
440 	return *dst;
441 }
442 
443 /* \todo check where pkt pointers are copied */
444 /**
445 \ingroup Core_Keys
446 \brief Copy packet, including contents
447 \param dst Destination packet
448 \param src Source packet
449 \note If dst already has a packet, it will be freed.
450 */
451 static pgp_subpacket_t *
452 copy_packet(pgp_subpacket_t *dst, const pgp_subpacket_t *src)
453 {
454 	if (dst->raw) {
455 		free(dst->raw);
456 	}
457 	if ((dst->raw = calloc(1, src->length)) == NULL) {
458 		(void) fprintf(stderr, "copy_packet: bad alloc\n");
459 	} else {
460 		dst->length = src->length;
461 		(void) memcpy(dst->raw, src->raw, src->length);
462 	}
463 	return dst;
464 }
465 
466 /**
467 \ingroup Core_Keys
468 \brief Add User ID to key
469 \param key Key to which to add User ID
470 \param userid User ID to add
471 \return Pointer to new User ID
472 */
473 uint8_t  *
474 pgp_add_userid(pgp_key_t *key, const uint8_t *userid)
475 {
476 	uint8_t  **uidp;
477 
478 	EXPAND_ARRAY(key, uid);
479 	/* initialise new entry in array */
480 	uidp = &key->uids[key->uidc++];
481 	*uidp = NULL;
482 	/* now copy it */
483 	return copy_userid(uidp, userid);
484 }
485 
486 void print_packet_hex(const pgp_subpacket_t *pkt);
487 
488 /**
489 \ingroup Core_Keys
490 \brief Add packet to key
491 \param keydata Key to which to add packet
492 \param packet Packet to add
493 \return Pointer to new packet
494 */
495 pgp_subpacket_t   *
496 pgp_add_subpacket(pgp_key_t *keydata, const pgp_subpacket_t *packet)
497 {
498 	pgp_subpacket_t   *subpktp;
499 
500 	EXPAND_ARRAY(keydata, packet);
501 	/* initialise new entry in array */
502 	subpktp = &keydata->packets[keydata->packetc++];
503 	subpktp->length = 0;
504 	subpktp->raw = NULL;
505 	/* now copy it */
506 	return copy_packet(subpktp, packet);
507 }
508 
509 /**
510 \ingroup Core_Keys
511 \brief Add selfsigned User ID to key
512 \param keydata Key to which to add user ID
513 \param userid Self-signed User ID to add
514 \return 1 if OK; else 0
515 */
516 unsigned
517 pgp_add_selfsigned_userid(pgp_key_t *key, uint8_t *userid)
518 {
519 	pgp_create_sig_t	*sig;
520 	pgp_subpacket_t	 sigpacket;
521 	pgp_memory_t		*mem_userid = NULL;
522 	pgp_output_t		*useridoutput = NULL;
523 	pgp_memory_t		*mem_sig = NULL;
524 	pgp_output_t		*sigoutput = NULL;
525 
526 	/*
527          * create signature packet for this userid
528          */
529 
530 	/* create userid pkt */
531 	pgp_setup_memory_write(&useridoutput, &mem_userid, 128);
532 	pgp_write_struct_userid(useridoutput, userid);
533 
534 	/* create sig for this pkt */
535 	sig = pgp_create_sig_new();
536 	pgp_sig_start_key_sig(sig, &key->key.seckey.pubkey, userid, PGP_CERT_POSITIVE);
537 	pgp_add_time(sig, (int64_t)time(NULL), "birth");
538 	pgp_add_issuer_keyid(sig, key->sigid);
539 	pgp_add_primary_userid(sig, 1);
540 	pgp_end_hashed_subpkts(sig);
541 
542 	pgp_setup_memory_write(&sigoutput, &mem_sig, 128);
543 	pgp_write_sig(sigoutput, sig, &key->key.seckey.pubkey, &key->key.seckey);
544 
545 	/* add this packet to key */
546 	sigpacket.length = pgp_mem_len(mem_sig);
547 	sigpacket.raw = pgp_mem_data(mem_sig);
548 
549 	/* add userid to key */
550 	(void) pgp_add_userid(key, userid);
551 	(void) pgp_add_subpacket(key, &sigpacket);
552 
553 	/* cleanup */
554 	pgp_create_sig_delete(sig);
555 	pgp_output_delete(useridoutput);
556 	pgp_output_delete(sigoutput);
557 	pgp_memory_free(mem_userid);
558 	pgp_memory_free(mem_sig);
559 
560 	return 1;
561 }
562 
563 /**
564 \ingroup Core_Keys
565 \brief Initialise pgp_key_t
566 \param keydata Keydata to initialise
567 \param type PGP_PTAG_CT_PUBLIC_KEY or PGP_PTAG_CT_SECRET_KEY
568 */
569 void
570 pgp_keydata_init(pgp_key_t *keydata, const pgp_content_enum type)
571 {
572 	if (keydata->type != PGP_PTAG_CT_RESERVED) {
573 		(void) fprintf(stderr,
574 			"pgp_keydata_init: wrong keydata type\n");
575 	} else if (type != PGP_PTAG_CT_PUBLIC_KEY &&
576 		   type != PGP_PTAG_CT_SECRET_KEY) {
577 		(void) fprintf(stderr, "pgp_keydata_init: wrong type\n");
578 	} else {
579 		keydata->type = type;
580 	}
581 }
582 
583 /* used to point to data during keyring read */
584 typedef struct keyringcb_t {
585 	pgp_keyring_t		*keyring;	/* the keyring we're reading */
586 } keyringcb_t;
587 
588 
589 static pgp_cb_ret_t
590 cb_keyring_read(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
591 {
592 	pgp_keyring_t	*keyring;
593 	pgp_revoke_t	*revocation;
594 	pgp_key_t	*key;
595 	keyringcb_t	*cb;
596 
597 	cb = pgp_callback_arg(cbinfo);
598 	keyring = cb->keyring;
599 	switch (pkt->tag) {
600 	case PGP_PARSER_PTAG:
601 	case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
602 		/* we get these because we didn't prompt */
603 		break;
604 	case PGP_PTAG_CT_SIGNATURE_HEADER:
605 		key = &keyring->keys[keyring->keyc - 1];
606 		EXPAND_ARRAY(key, subsig);
607 		key->subsigs[key->subsigc].uid = key->uidc - 1;
608 		(void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig,
609 				sizeof(pkt->u.sig));
610 		key->subsigc += 1;
611 		break;
612 	case PGP_PTAG_CT_SIGNATURE:
613 		key = &keyring->keys[keyring->keyc - 1];
614 		EXPAND_ARRAY(key, subsig);
615 		key->subsigs[key->subsigc].uid = key->uidc - 1;
616 		(void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig,
617 				sizeof(pkt->u.sig));
618 		key->subsigc += 1;
619 		break;
620 	case PGP_PTAG_CT_TRUST:
621 		key = &keyring->keys[keyring->keyc - 1];
622 		key->subsigs[key->subsigc - 1].trustlevel = pkt->u.ss_trust.level;
623 		key->subsigs[key->subsigc - 1].trustamount = pkt->u.ss_trust.amount;
624 		break;
625 	case PGP_PTAG_SS_KEY_EXPIRY:
626 		EXPAND_ARRAY(keyring, key);
627 		if (keyring->keyc > 0) {
628 			keyring->keys[keyring->keyc - 1].key.pubkey.duration = pkt->u.ss_time;
629 		}
630 		break;
631 	case PGP_PTAG_SS_ISSUER_KEY_ID:
632 		key = &keyring->keys[keyring->keyc - 1];
633 		(void) memcpy(&key->subsigs[key->subsigc - 1].sig.info.signer_id,
634 			      pkt->u.ss_issuer,
635 			      sizeof(pkt->u.ss_issuer));
636 		key->subsigs[key->subsigc - 1].sig.info.signer_id_set = 1;
637 		break;
638 	case PGP_PTAG_SS_CREATION_TIME:
639 		key = &keyring->keys[keyring->keyc - 1];
640 		key->subsigs[key->subsigc - 1].sig.info.birthtime = pkt->u.ss_time;
641 		key->subsigs[key->subsigc - 1].sig.info.birthtime_set = 1;
642 		break;
643 	case PGP_PTAG_SS_EXPIRATION_TIME:
644 		key = &keyring->keys[keyring->keyc - 1];
645 		key->subsigs[key->subsigc - 1].sig.info.duration = pkt->u.ss_time;
646 		key->subsigs[key->subsigc - 1].sig.info.duration_set = 1;
647 		break;
648 	case PGP_PTAG_SS_PRIMARY_USER_ID:
649 		key = &keyring->keys[keyring->keyc - 1];
650 		key->uid0 = key->uidc - 1;
651 		break;
652 	case PGP_PTAG_SS_REVOCATION_REASON:
653 		key = &keyring->keys[keyring->keyc - 1];
654 		if (key->uidc == 0) {
655 			/* revoke whole key */
656 			key->revoked = 1;
657 			revocation = &key->revocation;
658 		} else {
659 			/* revoke the user id */
660 			EXPAND_ARRAY(key, revoke);
661 			revocation = &key->revokes[key->revokec];
662 			key->revokes[key->revokec].uid = key->uidc - 1;
663 			key->revokec += 1;
664 		}
665 		revocation->code = pkt->u.ss_revocation.code;
666 		revocation->reason = netpgp_strdup(pgp_show_ss_rr_code(pkt->u.ss_revocation.code));
667 		break;
668 	case PGP_PTAG_CT_SIGNATURE_FOOTER:
669 	case PGP_PARSER_ERRCODE:
670 		break;
671 
672 	default:
673 		break;
674 	}
675 
676 	return PGP_RELEASE_MEMORY;
677 }
678 
679 /**
680    \ingroup HighLevel_KeyringRead
681 
682    \brief Reads a keyring from a file
683 
684    \param keyring Pointer to an existing pgp_keyring_t struct
685    \param armour 1 if file is armoured; else 0
686    \param filename Filename of keyring to be read
687 
688    \return pgp 1 if OK; 0 on error
689 
690    \note Keyring struct must already exist.
691 
692    \note Can be used with either a public or secret keyring.
693 
694    \note You must call pgp_keyring_free() after usage to free alloc-ed memory.
695 
696    \note If you call this twice on the same keyring struct, without calling
697    pgp_keyring_free() between these calls, you will introduce a memory leak.
698 
699    \sa pgp_keyring_read_from_mem()
700    \sa pgp_keyring_free()
701 
702 */
703 
704 unsigned
705 pgp_keyring_fileread(pgp_keyring_t *keyring,
706 			const unsigned armour,
707 			const char *filename)
708 {
709 	pgp_stream_t	*stream;
710 	keyringcb_t	 cb;
711 	unsigned	 res = 1;
712 	int		 fd;
713 
714 	(void) memset(&cb, 0x0, sizeof(cb));
715 	cb.keyring = keyring;
716 	stream = pgp_new(sizeof(*stream));
717 
718 	/* add this for the moment, */
719 	/*
720 	 * \todo need to fix the problems with reading signature subpackets
721 	 * later
722 	 */
723 
724 	/* pgp_parse_options(parse,PGP_PTAG_SS_ALL,PGP_PARSE_RAW); */
725 	pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
726 
727 #ifdef O_BINARY
728 	fd = open(filename, O_RDONLY | O_BINARY);
729 #else
730 	fd = open(filename, O_RDONLY);
731 #endif
732 	if (fd < 0) {
733 		pgp_stream_delete(stream);
734 		perror(filename);
735 		return 0;
736 	}
737 #ifdef USE_MMAP_FOR_FILES
738 	pgp_reader_set_mmap(stream, fd);
739 #else
740 	pgp_reader_set_fd(stream, fd);
741 #endif
742 
743 	pgp_set_callback(stream, cb_keyring_read, &cb);
744 
745 	if (armour) {
746 		pgp_reader_push_dearmour(stream);
747 	}
748 	res = pgp_parse_and_accumulate(keyring, stream);
749 	pgp_print_errors(pgp_stream_get_errors(stream));
750 
751 	if (armour) {
752 		pgp_reader_pop_dearmour(stream);
753 	}
754 
755 	(void)close(fd);
756 
757 	pgp_stream_delete(stream);
758 
759 	return res;
760 }
761 
762 /**
763    \ingroup HighLevel_KeyringRead
764 
765    \brief Reads a keyring from memory
766 
767    \param keyring Pointer to existing pgp_keyring_t struct
768    \param armour 1 if file is armoured; else 0
769    \param mem Pointer to a pgp_memory_t struct containing keyring to be read
770 
771    \return pgp 1 if OK; 0 on error
772 
773    \note Keyring struct must already exist.
774 
775    \note Can be used with either a public or secret keyring.
776 
777    \note You must call pgp_keyring_free() after usage to free alloc-ed memory.
778 
779    \note If you call this twice on the same keyring struct, without calling
780    pgp_keyring_free() between these calls, you will introduce a memory leak.
781 
782    \sa pgp_keyring_fileread
783    \sa pgp_keyring_free
784 */
785 unsigned
786 pgp_keyring_read_from_mem(pgp_io_t *io,
787 				pgp_keyring_t *keyring,
788 				const unsigned armour,
789 				pgp_memory_t *mem)
790 {
791 	pgp_stream_t	*stream;
792 	const unsigned	 noaccum = 0;
793 	keyringcb_t	 cb;
794 	unsigned	 res;
795 
796 	(void) memset(&cb, 0x0, sizeof(cb));
797 	cb.keyring = keyring;
798 	stream = pgp_new(sizeof(*stream));
799 	pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
800 	pgp_setup_memory_read(io, &stream, mem, &cb, cb_keyring_read,
801 					noaccum);
802 	if (armour) {
803 		pgp_reader_push_dearmour(stream);
804 	}
805 	res = (unsigned)pgp_parse_and_accumulate(keyring, stream);
806 	pgp_print_errors(pgp_stream_get_errors(stream));
807 	if (armour) {
808 		pgp_reader_pop_dearmour(stream);
809 	}
810 	/* don't call teardown_memory_read because memory was passed in */
811 	pgp_stream_delete(stream);
812 	return res;
813 }
814 
815 /**
816    \ingroup HighLevel_KeyringRead
817 
818    \brief Frees keyring's contents (but not keyring itself)
819 
820    \param keyring Keyring whose data is to be freed
821 
822    \note This does not free keyring itself, just the memory alloc-ed in it.
823  */
824 void
825 pgp_keyring_free(pgp_keyring_t *keyring)
826 {
827 	(void)free(keyring->keys);
828 	keyring->keys = NULL;
829 	keyring->keyc = keyring->keyvsize = 0;
830 }
831 
832 /**
833    \ingroup HighLevel_KeyringFind
834 
835    \brief Finds key in keyring from its Key ID
836 
837    \param keyring Keyring to be searched
838    \param keyid ID of required key
839 
840    \return Pointer to key, if found; NULL, if not found
841 
842    \note This returns a pointer to the key inside the given keyring,
843    not a copy.  Do not free it after use.
844 
845 */
846 const pgp_key_t *
847 pgp_getkeybyid(pgp_io_t *io, const pgp_keyring_t *keyring,
848 			   const uint8_t *keyid, unsigned *from, pgp_pubkey_t **pubkey)
849 {
850 	uint8_t	nullid[PGP_KEY_ID_SIZE];
851 
852 	(void) memset(nullid, 0x0, sizeof(nullid));
853 	for ( ; keyring && *from < keyring->keyc; *from += 1) {
854 		if (pgp_get_debug_level(__FILE__)) {
855 			hexdump(io->errs, "keyring keyid", keyring->keys[*from].sigid, PGP_KEY_ID_SIZE);
856 			hexdump(io->errs, "keyid", keyid, PGP_KEY_ID_SIZE);
857 		}
858 		if (memcmp(keyring->keys[*from].sigid, keyid, PGP_KEY_ID_SIZE) == 0 ||
859 		    memcmp(&keyring->keys[*from].sigid[PGP_KEY_ID_SIZE / 2],
860 				keyid, PGP_KEY_ID_SIZE / 2) == 0) {
861 			if (pubkey) {
862 				*pubkey = &keyring->keys[*from].key.pubkey;
863 			}
864 			return &keyring->keys[*from];
865 		}
866 		if (memcmp(&keyring->keys[*from].encid, nullid, sizeof(nullid)) == 0) {
867 			continue;
868 		}
869 		if (memcmp(&keyring->keys[*from].encid, keyid, PGP_KEY_ID_SIZE) == 0 ||
870 		    memcmp(&keyring->keys[*from].encid[PGP_KEY_ID_SIZE / 2], keyid, PGP_KEY_ID_SIZE / 2) == 0) {
871 			if (pubkey) {
872 				*pubkey = &keyring->keys[*from].enckey;
873 			}
874 			return &keyring->keys[*from];
875 		}
876 	}
877 	return NULL;
878 }
879 
880 /* convert a string keyid into a binary keyid */
881 static void
882 str2keyid(const char *userid, uint8_t *keyid, size_t len)
883 {
884 	static const char	*uppers = "0123456789ABCDEF";
885 	static const char	*lowers = "0123456789abcdef";
886 	const char		*hi;
887 	const char		*lo;
888 	uint8_t			 hichar;
889 	uint8_t			 lochar;
890 	size_t			 j;
891 	int			 i;
892 
893 	for (i = 0, j = 0 ; j < len && userid[i] && userid[i + 1] ; i += 2, j++) {
894 		if ((hi = strchr(uppers, userid[i])) == NULL) {
895 			if ((hi = strchr(lowers, userid[i])) == NULL) {
896 				break;
897 			}
898 			hichar = (uint8_t)(hi - lowers);
899 		} else {
900 			hichar = (uint8_t)(hi - uppers);
901 		}
902 		if ((lo = strchr(uppers, userid[i + 1])) == NULL) {
903 			if ((lo = strchr(lowers, userid[i + 1])) == NULL) {
904 				break;
905 			}
906 			lochar = (uint8_t)(lo - lowers);
907 		} else {
908 			lochar = (uint8_t)(lo - uppers);
909 		}
910 		keyid[j] = (hichar << 4) | (lochar);
911 	}
912 	keyid[j] = 0x0;
913 }
914 
915 /* return the next key which matches, starting searching at *from */
916 static const pgp_key_t *
917 getkeybyname(pgp_io_t *io,
918 			const pgp_keyring_t *keyring,
919 			const char *name,
920 			unsigned *from)
921 {
922 	const pgp_key_t	*kp;
923 	uint8_t			**uidp;
924 	unsigned    	 	 i = 0;
925 	pgp_key_t		*keyp;
926 	unsigned		 savedstart;
927 	regex_t			 r;
928 	uint8_t		 	 keyid[PGP_KEY_ID_SIZE + 1];
929 	size_t          	 len;
930 
931 	if (!keyring || !name || !from) {
932 		return NULL;
933 	}
934 	len = strlen(name);
935 	if (pgp_get_debug_level(__FILE__)) {
936 		(void) fprintf(io->outs, "[%u] name '%s', len %zu\n",
937 			*from, name, len);
938 	}
939 	/* first try name as a keyid */
940 	(void) memset(keyid, 0x0, sizeof(keyid));
941 	str2keyid(name, keyid, sizeof(keyid));
942 	if (pgp_get_debug_level(__FILE__)) {
943 		hexdump(io->outs, "keyid", keyid, 4);
944 	}
945 	savedstart = *from;
946 	if ((kp = pgp_getkeybyid(io, keyring, keyid, from, NULL)) != NULL) {
947 		return kp;
948 	}
949 	*from = savedstart;
950 	if (pgp_get_debug_level(__FILE__)) {
951 		(void) fprintf(io->outs, "regex match '%s' from %u\n",
952 			name, *from);
953 	}
954 	/* match on full name or email address as a NOSUB, ICASE regexp */
955 	(void) regcomp(&r, name, REG_EXTENDED | REG_ICASE);
956 	for (keyp = &keyring->keys[*from]; *from < keyring->keyc; *from += 1, keyp++) {
957 		uidp = keyp->uids;
958 		for (i = 0 ; i < keyp->uidc; i++, uidp++) {
959 			if (regexec(&r, (char *)*uidp, 0, NULL, 0) == 0) {
960 				if (pgp_get_debug_level(__FILE__)) {
961 					(void) fprintf(io->outs,
962 						"MATCHED keyid \"%s\" len %" PRIsize "u\n",
963 					       (char *) *uidp, len);
964 				}
965 				regfree(&r);
966 				return keyp;
967 			}
968 		}
969 	}
970 	regfree(&r);
971 	return NULL;
972 }
973 
974 /**
975    \ingroup HighLevel_KeyringFind
976 
977    \brief Finds key from its User ID
978 
979    \param keyring Keyring to be searched
980    \param userid User ID of required key
981 
982    \return Pointer to Key, if found; NULL, if not found
983 
984    \note This returns a pointer to the key inside the keyring, not a
985    copy.  Do not free it.
986 
987 */
988 const pgp_key_t *
989 pgp_getkeybyname(pgp_io_t *io,
990 			const pgp_keyring_t *keyring,
991 			const char *name)
992 {
993 	unsigned	from;
994 
995 	from = 0;
996 	return getkeybyname(io, keyring, name, &from);
997 }
998 
999 const pgp_key_t *
1000 pgp_getnextkeybyname(pgp_io_t *io,
1001 			const pgp_keyring_t *keyring,
1002 			const char *name,
1003 			unsigned *n)
1004 {
1005 	return getkeybyname(io, keyring, name, n);
1006 }
1007 
1008 /**
1009    \ingroup HighLevel_KeyringList
1010 
1011    \brief Prints all keys in keyring to stdout.
1012 
1013    \param keyring Keyring to use
1014 
1015    \return none
1016 */
1017 int
1018 pgp_keyring_list(pgp_io_t *io, const pgp_keyring_t *keyring, const int psigs)
1019 {
1020 	pgp_key_t		*key;
1021 	unsigned		 n;
1022 	unsigned		 keyc = (keyring != NULL) ? keyring->keyc : 0;
1023 
1024 	(void) fprintf(io->res, "%u key%s\n", keyc, (keyc == 1) ? "" : "s");
1025 	if (keyring == NULL) {
1026 		return 1;
1027 	}
1028 	for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
1029 		if (pgp_is_key_secret(key)) {
1030 			pgp_print_keydata(io, keyring, key, "sec",
1031 				&key->key.seckey.pubkey, 0);
1032 		} else {
1033 			pgp_print_keydata(io, keyring, key, "signature ", &key->key.pubkey, psigs);
1034 		}
1035 		(void) fputc('\n', io->res);
1036 	}
1037 	return 1;
1038 }
1039 
1040 int
1041 pgp_keyring_json(pgp_io_t *io, const pgp_keyring_t *keyring, mj_t *obj, const int psigs)
1042 {
1043 	pgp_key_t		*key;
1044 	unsigned		 n;
1045 
1046 	(void) memset(obj, 0x0, sizeof(*obj));
1047 	mj_create(obj, "array");
1048 	obj->size = keyring->keyvsize;
1049 	if (pgp_get_debug_level(__FILE__)) {
1050 		(void) fprintf(io->errs, "pgp_keyring_json: vsize %u\n", obj->size);
1051 	}
1052 	if ((obj->value.v = calloc(sizeof(*obj->value.v), obj->size)) == NULL) {
1053 		(void) fprintf(io->errs, "calloc failure\n");
1054 		return 0;
1055 	}
1056 	for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
1057 		if (pgp_is_key_secret(key)) {
1058 			pgp_sprint_mj(io, keyring, key, &obj->value.v[obj->c],
1059 				"sec", &key->key.seckey.pubkey, psigs);
1060 		} else {
1061 			pgp_sprint_mj(io, keyring, key, &obj->value.v[obj->c],
1062 				"signature ", &key->key.pubkey, psigs);
1063 		}
1064 		if (obj->value.v[obj->c].type != 0) {
1065 			obj->c += 1;
1066 		}
1067 	}
1068 	if (pgp_get_debug_level(__FILE__)) {
1069 		char	*s;
1070 
1071 		mj_asprint(&s, obj, MJ_JSON_ENCODE);
1072 		(void) fprintf(stderr, "pgp_keyring_json: '%s'\n", s);
1073 		free(s);
1074 	}
1075 	return 1;
1076 }
1077 
1078 
1079 /* this interface isn't right - hook into callback for getting passphrase */
1080 char *
1081 pgp_export_key(pgp_io_t *io, const pgp_key_t *keydata, uint8_t *passphrase)
1082 {
1083 	pgp_output_t	*output;
1084 	pgp_memory_t	*mem;
1085 	char		*cp;
1086 
1087 	__PGP_USED(io);
1088 	pgp_setup_memory_write(&output, &mem, 128);
1089 	if (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) {
1090 		pgp_write_xfer_pubkey(output, keydata, 1);
1091 	} else {
1092 		pgp_write_xfer_seckey(output, keydata, passphrase,
1093 					strlen((char *)passphrase), 1);
1094 	}
1095 	cp = netpgp_strdup(pgp_mem_data(mem));
1096 	pgp_teardown_memory_write(output, mem);
1097 	return cp;
1098 }
1099 
1100 /* add a key to a public keyring */
1101 int
1102 pgp_add_to_pubring(pgp_keyring_t *keyring, const pgp_pubkey_t *pubkey, pgp_content_enum tag)
1103 {
1104 	pgp_key_t	*key;
1105 	time_t		 duration;
1106 
1107 	if (pgp_get_debug_level(__FILE__)) {
1108 		fprintf(stderr, "pgp_add_to_pubring (type %u)\n", tag);
1109 	}
1110 	switch(tag) {
1111 	case PGP_PTAG_CT_PUBLIC_KEY:
1112 		EXPAND_ARRAY(keyring, key);
1113 		key = &keyring->keys[keyring->keyc++];
1114 		duration = key->key.pubkey.duration;
1115 		(void) memset(key, 0x0, sizeof(*key));
1116 		key->type = tag;
1117 		pgp_keyid(key->sigid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
1118 		pgp_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype);
1119 		key->key.pubkey = *pubkey;
1120 		key->key.pubkey.duration = duration;
1121 		return 1;
1122 	case PGP_PTAG_CT_PUBLIC_SUBKEY:
1123 		/* subkey is not the first */
1124 		key = &keyring->keys[keyring->keyc - 1];
1125 		pgp_keyid(key->encid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
1126 		duration = key->key.pubkey.duration;
1127 		(void) memcpy(&key->enckey, pubkey, sizeof(key->enckey));
1128 		key->enckey.duration = duration;
1129 		return 1;
1130 	default:
1131 		return 0;
1132 	}
1133 }
1134 
1135 /* add a key to a secret keyring */
1136 int
1137 pgp_add_to_secring(pgp_keyring_t *keyring, const pgp_seckey_t *seckey)
1138 {
1139 	const pgp_pubkey_t	*pubkey;
1140 	pgp_key_t		*key;
1141 
1142 	if (pgp_get_debug_level(__FILE__)) {
1143 		fprintf(stderr, "pgp_add_to_secring\n");
1144 	}
1145 	if (keyring->keyc > 0) {
1146 		key = &keyring->keys[keyring->keyc - 1];
1147 		if (pgp_get_debug_level(__FILE__) &&
1148 		    key->key.pubkey.alg == PGP_PKA_DSA &&
1149 		    seckey->pubkey.alg == PGP_PKA_ELGAMAL) {
1150 			fprintf(stderr, "pgp_add_to_secring: found elgamal seckey\n");
1151 		}
1152 	}
1153 	EXPAND_ARRAY(keyring, key);
1154 	key = &keyring->keys[keyring->keyc++];
1155 	(void) memset(key, 0x0, sizeof(*key));
1156 	pubkey = &seckey->pubkey;
1157 	pgp_keyid(key->sigid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
1158 	pgp_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype);
1159 	key->type = PGP_PTAG_CT_SECRET_KEY;
1160 	key->key.seckey = *seckey;
1161 	if (pgp_get_debug_level(__FILE__)) {
1162 		fprintf(stderr, "pgp_add_to_secring: keyc %u\n", keyring->keyc);
1163 	}
1164 	return 1;
1165 }
1166 
1167 /* append one keyring to another */
1168 int
1169 pgp_append_keyring(pgp_keyring_t *keyring, pgp_keyring_t *newring)
1170 {
1171 	unsigned	i;
1172 
1173 	for (i = 0 ; i < newring->keyc ; i++) {
1174 		EXPAND_ARRAY(keyring, key);
1175 		(void) memcpy(&keyring->keys[keyring->keyc], &newring->keys[i],
1176 				sizeof(newring->keys[i]));
1177 		keyring->keyc += 1;
1178 	}
1179 	return 1;
1180 }
1181