xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
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.57 2020/10/14 05:19:41 jhigh 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 		dst->length = 0;
460 	} else {
461 		dst->length = src->length;
462 		(void) memcpy(dst->raw, src->raw, src->length);
463 	}
464 	dst->tag = src->tag;
465 	return dst;
466 }
467 
468 /**
469 \ingroup Core_Keys
470 \brief Add User ID to key
471 \param key Key to which to add User ID
472 \param userid User ID to add
473 \return Pointer to new User ID
474 */
475 uint8_t  *
476 pgp_add_userid(pgp_key_t *key, const uint8_t *userid)
477 {
478 	uint8_t  **uidp;
479 
480 	EXPAND_ARRAY(key, uid);
481 	/* initialise new entry in array */
482 	uidp = &key->uids[key->uidc++];
483 	*uidp = NULL;
484 	/* now copy it */
485 	return copy_userid(uidp, userid);
486 }
487 
488 void print_packet_hex(const pgp_subpacket_t *pkt);
489 
490 /**
491 \ingroup Core_Keys
492 \brief Add packet to key
493 \param keydata Key to which to add packet
494 \param packet Packet to add
495 \return Pointer to new packet
496 */
497 pgp_subpacket_t   *
498 pgp_add_subpacket(pgp_key_t *keydata, const pgp_subpacket_t *packet)
499 {
500 	pgp_subpacket_t   *subpktp;
501 
502 	EXPAND_ARRAY(keydata, packet);
503 	/* initialise new entry in array */
504 	subpktp = &keydata->packets[keydata->packetc++];
505 	subpktp->raw = NULL;
506 	/* now copy it */
507 	return copy_packet(subpktp, packet);
508 }
509 
510 /**
511 \ingroup Core_Keys
512 \brief Add selfsigned User ID to key
513 \param keydata Key to which to add user ID
514 \param userid Self-signed User ID to add
515 \return 1 if OK; else 0
516 */
517 unsigned
518 pgp_add_selfsigned_userid(pgp_key_t *key, uint8_t *userid)
519 {
520 	pgp_create_sig_t	*sig;
521 	pgp_subpacket_t	 sigpacket;
522 	pgp_memory_t		*mem_userid = NULL;
523 	pgp_output_t		*useridoutput = NULL;
524 	pgp_memory_t		*mem_sig = NULL;
525 	pgp_output_t		*sigoutput = NULL;
526 
527 	/*
528          * create signature packet for this userid
529          */
530 
531 	/* create userid pkt */
532 	pgp_setup_memory_write(&useridoutput, &mem_userid, 128);
533 	pgp_write_struct_userid(useridoutput, userid);
534 
535 	/* create sig for this pkt */
536 	sig = pgp_create_sig_new();
537 	pgp_sig_start_key_sig(sig, &key->key.seckey.pubkey, userid, PGP_CERT_POSITIVE);
538 	pgp_add_time(sig, (int64_t)time(NULL), "birth");
539 	pgp_add_issuer_keyid(sig, key->sigid);
540 	pgp_add_primary_userid(sig, 1);
541 	pgp_end_hashed_subpkts(sig);
542 
543 	pgp_setup_memory_write(&sigoutput, &mem_sig, 128);
544 	pgp_write_sig(sigoutput, sig, &key->key.seckey.pubkey, &key->key.seckey);
545 
546 	/* add this packet to key */
547 	sigpacket.length = pgp_mem_len(mem_sig);
548 	sigpacket.raw = pgp_mem_data(mem_sig);
549 	sigpacket.tag = PGP_PTAG_CT_SIGNATURE;
550 
551 	/* add userid to key */
552 	(void) pgp_add_userid(key, userid);
553 	(void) pgp_add_subpacket(key, &sigpacket);
554 
555 	/* cleanup */
556 	pgp_create_sig_delete(sig);
557 	pgp_output_delete(useridoutput);
558 	pgp_output_delete(sigoutput);
559 	pgp_memory_free(mem_userid);
560 	pgp_memory_free(mem_sig);
561 
562 	return 1;
563 }
564 
565 /**
566 \ingroup Core_Keys
567 \brief Initialise pgp_key_t
568 \param keydata Keydata to initialise
569 \param type PGP_PTAG_CT_PUBLIC_KEY or PGP_PTAG_CT_SECRET_KEY
570 */
571 void
572 pgp_keydata_init(pgp_key_t *keydata, const pgp_content_enum type)
573 {
574 	if (keydata->type != PGP_PTAG_CT_RESERVED) {
575 		(void) fprintf(stderr,
576 			"pgp_keydata_init: wrong keydata type\n");
577 	} else if (type != PGP_PTAG_CT_PUBLIC_KEY &&
578 		   type != PGP_PTAG_CT_SECRET_KEY) {
579 		(void) fprintf(stderr, "pgp_keydata_init: wrong type\n");
580 	} else {
581 		keydata->type = type;
582 	}
583 }
584 
585 /* used to point to data during keyring read */
586 typedef struct keyringcb_t {
587 	pgp_keyring_t		*keyring;	/* the keyring we're reading */
588 } keyringcb_t;
589 
590 
591 static pgp_cb_ret_t
592 cb_keyring_read(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
593 {
594 	pgp_keyring_t	*keyring;
595 	pgp_revoke_t	*revocation;
596 	pgp_key_t	*key;
597 	keyringcb_t	*cb;
598 
599 	cb = pgp_callback_arg(cbinfo);
600 	keyring = cb->keyring;
601 	key = keyring->keyc > 0 ? &keyring->keys[keyring->keyc - 1] : NULL;
602 
603 	switch (pkt->tag) {
604 	case PGP_PARSER_PTAG:
605 	case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
606 		/* we get these because we didn't prompt */
607 		break;
608 	case PGP_PTAG_CT_SIGNATURE_HEADER:
609 		EXPAND_ARRAY(key, subsig);
610 		key->subsigs[key->subsigc].uid = key->uidc - 1;
611 		(void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig,
612 				sizeof(pkt->u.sig));
613 		key->subsigc += 1;
614 		break;
615 	case PGP_PTAG_CT_SIGNATURE:
616 		EXPAND_ARRAY(key, subsig);
617 		key->subsigs[key->subsigc].uid = key->uidc - 1;
618 		(void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig,
619 				sizeof(pkt->u.sig));
620 		key->subsigc += 1;
621 		break;
622 	case PGP_PTAG_CT_TRUST:
623 		EXPAND_ARRAY(key, subsig);
624 		key->subsigs[key->subsigc].trustlevel = pkt->u.ss_trust.level;
625 		key->subsigs[key->subsigc].trustamount = pkt->u.ss_trust.amount;
626 
627 		key->subsigc += 1;
628 
629 		break;
630 	case PGP_PTAG_SS_KEY_EXPIRY:
631 		EXPAND_ARRAY(keyring, key);
632 		if (keyring->keyc > 0) {
633 			keyring->keys[keyring->keyc - 1].key.pubkey.duration = pkt->u.ss_time;
634 		}
635 		break;
636 	case PGP_PTAG_SS_ISSUER_KEY_ID:
637 		(void) memcpy(&key->subsigs[key->subsigc - 1].sig.info.signer_id,
638 			      pkt->u.ss_issuer,
639 			      sizeof(pkt->u.ss_issuer));
640 		key->subsigs[key->subsigc - 1].sig.info.signer_id_set = 1;
641 		break;
642 	case PGP_PTAG_SS_CREATION_TIME:
643 		key->subsigs[key->subsigc - 1].sig.info.birthtime = pkt->u.ss_time;
644 		key->subsigs[key->subsigc - 1].sig.info.birthtime_set = 1;
645 		break;
646 	case PGP_PTAG_SS_EXPIRATION_TIME:
647 		key->subsigs[key->subsigc - 1].sig.info.duration = pkt->u.ss_time;
648 		key->subsigs[key->subsigc - 1].sig.info.duration_set = 1;
649 		break;
650 	case PGP_PTAG_SS_PRIMARY_USER_ID:
651 		key->uid0 = key->uidc - 1;
652 		break;
653 	case PGP_PTAG_SS_REVOCATION_REASON:
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 	default:
672 		break;
673 	}
674 	return PGP_RELEASE_MEMORY;
675 }
676 
677 /**
678    \ingroup HighLevel_KeyringRead
679 
680    \brief Reads a keyring from a file
681 
682    \param keyring Pointer to an existing pgp_keyring_t struct
683    \param armour 1 if file is armoured; else 0
684    \param filename Filename of keyring to be read
685 
686    \return pgp 1 if OK; 0 on error
687 
688    \note Keyring struct must already exist.
689 
690    \note Can be used with either a public or secret keyring.
691 
692    \note You must call pgp_keyring_free() after usage to free alloc-ed memory.
693 
694    \note If you call this twice on the same keyring struct, without calling
695    pgp_keyring_free() between these calls, you will introduce a memory leak.
696 
697    \sa pgp_keyring_read_from_mem()
698    \sa pgp_keyring_free()
699 
700 */
701 
702 unsigned
703 pgp_keyring_fileread(pgp_keyring_t *keyring,
704 			const unsigned armour,
705 			const char *filename)
706 {
707 	pgp_stream_t	*stream;
708 	keyringcb_t	 cb;
709 	unsigned	 res = 1;
710 	int		 fd;
711 
712 	(void) memset(&cb, 0x0, sizeof(cb));
713 	cb.keyring = keyring;
714 	stream = pgp_new(sizeof(*stream));
715 
716 	/* add this for the moment, */
717 	/*
718 	 * \todo need to fix the problems with reading signature subpackets
719 	 * later
720 	 */
721 
722 	/* pgp_parse_options(parse,PGP_PTAG_SS_ALL,PGP_PARSE_RAW); */
723 	pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
724 
725 #ifdef O_BINARY
726 	fd = open(filename, O_RDONLY | O_BINARY);
727 #else
728 	fd = open(filename, O_RDONLY);
729 #endif
730 	if (fd < 0) {
731 		pgp_stream_delete(stream);
732 		perror(filename);
733 		return 0;
734 	}
735 #ifdef USE_MMAP_FOR_FILES
736 	pgp_reader_set_mmap(stream, fd);
737 #else
738 	pgp_reader_set_fd(stream, fd);
739 #endif
740 
741 	pgp_set_callback(stream, cb_keyring_read, &cb);
742 
743 	if (armour) {
744 		pgp_reader_push_dearmour(stream);
745 	}
746 	res = pgp_parse_and_accumulate(keyring, stream);
747 	pgp_print_errors(pgp_stream_get_errors(stream));
748 
749 	if (armour) {
750 		pgp_reader_pop_dearmour(stream);
751 	}
752 
753 	(void)close(fd);
754 
755 	pgp_stream_delete(stream);
756 
757 	return res;
758 }
759 
760 /**
761    \ingroup HighLevel_KeyringRead
762 
763    \brief Reads a keyring from memory
764 
765    \param keyring Pointer to existing pgp_keyring_t struct
766    \param armour 1 if file is armoured; else 0
767    \param mem Pointer to a pgp_memory_t struct containing keyring to be read
768 
769    \return pgp 1 if OK; 0 on error
770 
771    \note Keyring struct must already exist.
772 
773    \note Can be used with either a public or secret keyring.
774 
775    \note You must call pgp_keyring_free() after usage to free alloc-ed memory.
776 
777    \note If you call this twice on the same keyring struct, without calling
778    pgp_keyring_free() between these calls, you will introduce a memory leak.
779 
780    \sa pgp_keyring_fileread
781    \sa pgp_keyring_free
782 */
783 unsigned
784 pgp_keyring_read_from_mem(pgp_io_t *io,
785 				pgp_keyring_t *keyring,
786 				const unsigned armour,
787 				pgp_memory_t *mem)
788 {
789 	pgp_stream_t	*stream;
790 	const unsigned	 noaccum = 0;
791 	keyringcb_t	 cb;
792 	unsigned	 res;
793 
794 	(void) memset(&cb, 0x0, sizeof(cb));
795 	cb.keyring = keyring;
796 	stream = pgp_new(sizeof(*stream));
797 	pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
798 	pgp_setup_memory_read(io, &stream, mem, &cb, cb_keyring_read,
799 					noaccum);
800 	if (armour) {
801 		pgp_reader_push_dearmour(stream);
802 	}
803 	res = (unsigned)pgp_parse_and_accumulate(keyring, stream);
804 	pgp_print_errors(pgp_stream_get_errors(stream));
805 	if (armour) {
806 		pgp_reader_pop_dearmour(stream);
807 	}
808 	/* don't call teardown_memory_read because memory was passed in */
809 	pgp_stream_delete(stream);
810 	return res;
811 }
812 
813 /**
814    \ingroup HighLevel_KeyringWrite
815 
816    \brief Writes a keyring to a file
817 
818    \param keyring Pointer to an existing pgp_keyring_t struct
819    \param armour 1 if file is armoured; else 0
820    \param filename Filename of keyring to be written
821 
822    \return pgp 1 if OK; 0 on error
823 
824    \note Keyring struct must already exist.
825 
826    \note Can be used with either a public or secret keyring.
827 */
828 
829 unsigned
830 pgp_keyring_filewrite(pgp_keyring_t *keyring,
831 			unsigned armour,
832 			const char *filename,
833 			uint8_t *passphrase)
834 {
835 	pgp_output_t		*output;
836 	int			fd;
837 	unsigned	 	res = 1;
838 	pgp_key_t		*key;
839 	unsigned	 	n;
840 	unsigned	 	keyc = (keyring != NULL) ? keyring->keyc : 0;
841 	char 			*cp;
842 	pgp_content_enum	type;
843 	pgp_armor_type_t	atype;
844 	char			keyid[PGP_KEY_ID_SIZE * 3];
845 
846 	fd = pgp_setup_file_write(&output, filename, 1);
847 	if (fd < 0) {
848 		perror(filename);
849 		return 0;
850 	}
851 
852 	type = keyring->keyc > 0 ? keyring->keys->type : PGP_PTAG_CT_PUBLIC_KEY;
853 
854 	if (armour) {
855 		if (type == PGP_PTAG_CT_PUBLIC_KEY)
856 			atype = PGP_PGP_PUBLIC_KEY_BLOCK;
857 		else
858 			atype = PGP_PGP_PRIVATE_KEY_BLOCK;
859 		pgp_writer_push_armoured(output, atype);
860 	}
861 	for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
862 		/* write only keys of a single type */
863 		if (key->type != type) {
864 			(void) fprintf(stderr, "ERROR: skip key %d\n", n);
865 			continue;
866 		}
867 		if (key->type == PGP_PTAG_CT_PUBLIC_KEY) {
868 			pgp_write_xfer_pubkey(output, key, 0);
869 		} else {
870 			pgp_write_xfer_seckey(output, key, passphrase,
871 					strlen((char *)passphrase), 0);
872 		}
873 	}
874 	if (armour) {
875 		pgp_writer_info_finalise(&output->errors, &output->writer);
876 		pgp_writer_pop(output);
877 	}
878 
879 	pgp_teardown_file_write(output, fd);
880 
881 	return res;
882 }
883 
884 /**
885    \ingroup HighLevel_KeyringRead
886 
887    \brief Frees keyring's contents (but not keyring itself)
888 
889    \param keyring Keyring whose data is to be freed
890 
891    \note This does not free keyring itself, just the memory alloc-ed in it.
892  */
893 void
894 pgp_keyring_free(pgp_keyring_t *keyring)
895 {
896 	(void)free(keyring->keys);
897 	keyring->keys = NULL;
898 	keyring->keyc = keyring->keyvsize = 0;
899 }
900 
901 /**
902    \ingroup HighLevel_KeyringFind
903 
904    \brief Finds key in keyring from its Key ID
905 
906    \param keyring Keyring to be searched
907    \param keyid ID of required key
908 
909    \return Pointer to key, if found; NULL, if not found
910 
911    \note This returns a pointer to the key inside the given keyring,
912    not a copy.  Do not free it after use.
913 
914 */
915 const pgp_key_t *
916 pgp_getkeybyid(pgp_io_t *io, const pgp_keyring_t *keyring,
917 			   const uint8_t *keyid, unsigned *from, pgp_pubkey_t **pubkey)
918 {
919 	uint8_t	nullid[PGP_KEY_ID_SIZE];
920 
921 	(void) memset(nullid, 0x0, sizeof(nullid));
922 	for ( ; keyring && *from < keyring->keyc; *from += 1) {
923 		if (pgp_get_debug_level(__FILE__)) {
924 			hexdump(io->errs, "keyring keyid", keyring->keys[*from].sigid, PGP_KEY_ID_SIZE);
925 			hexdump(io->errs, "keyid", keyid, PGP_KEY_ID_SIZE);
926 		}
927 		if (memcmp(keyring->keys[*from].sigid, keyid, PGP_KEY_ID_SIZE) == 0 ||
928 		    memcmp(&keyring->keys[*from].sigid[PGP_KEY_ID_SIZE / 2],
929 				keyid, PGP_KEY_ID_SIZE / 2) == 0) {
930 			if (pubkey) {
931 				*pubkey = &keyring->keys[*from].key.pubkey;
932 			}
933 			return &keyring->keys[*from];
934 		}
935 		if (memcmp(&keyring->keys[*from].encid, nullid, sizeof(nullid)) == 0) {
936 			continue;
937 		}
938 		if (memcmp(&keyring->keys[*from].encid, keyid, PGP_KEY_ID_SIZE) == 0 ||
939 		    memcmp(&keyring->keys[*from].encid[PGP_KEY_ID_SIZE / 2], keyid, PGP_KEY_ID_SIZE / 2) == 0) {
940 			if (pubkey) {
941 				*pubkey = &keyring->keys[*from].enckey;
942 			}
943 			return &keyring->keys[*from];
944 		}
945 	}
946 	return NULL;
947 }
948 
949 /* convert a string keyid into a binary keyid */
950 static void
951 str2keyid(const char *userid, uint8_t *keyid, size_t len)
952 {
953 	static const char	*uppers = "0123456789ABCDEF";
954 	static const char	*lowers = "0123456789abcdef";
955 	const char		*hi;
956 	const char		*lo;
957 	uint8_t			 hichar;
958 	uint8_t			 lochar;
959 	size_t			 j;
960 	int			 i;
961 
962 	for (i = 0, j = 0 ; j < len && userid[i] && userid[i + 1] ; i += 2, j++) {
963 		if ((hi = strchr(uppers, userid[i])) == NULL) {
964 			if ((hi = strchr(lowers, userid[i])) == NULL) {
965 				break;
966 			}
967 			hichar = (uint8_t)(hi - lowers);
968 		} else {
969 			hichar = (uint8_t)(hi - uppers);
970 		}
971 		if ((lo = strchr(uppers, userid[i + 1])) == NULL) {
972 			if ((lo = strchr(lowers, userid[i + 1])) == NULL) {
973 				break;
974 			}
975 			lochar = (uint8_t)(lo - lowers);
976 		} else {
977 			lochar = (uint8_t)(lo - uppers);
978 		}
979 		keyid[j] = (hichar << 4) | (lochar);
980 	}
981 	keyid[j] = 0x0;
982 }
983 
984 /* return the next key which matches, starting searching at *from */
985 static const pgp_key_t *
986 getkeybyname(pgp_io_t *io,
987 			const pgp_keyring_t *keyring,
988 			const char *name,
989 			unsigned *from)
990 {
991 	const pgp_key_t	*kp;
992 	uint8_t			**uidp;
993 	unsigned    	 	 i = 0;
994 	pgp_key_t		*keyp;
995 	unsigned		 savedstart;
996 	regex_t			 r;
997 	uint8_t		 	 keyid[PGP_KEY_ID_SIZE + 1];
998 	size_t          	 len;
999 
1000 	if (!keyring || !name || !from) {
1001 		return NULL;
1002 	}
1003 	len = strlen(name);
1004 	if (pgp_get_debug_level(__FILE__)) {
1005 		(void) fprintf(io->outs, "[%u] name '%s', len %zu\n",
1006 			*from, name, len);
1007 	}
1008 	/* first try name as a keyid */
1009 	(void) memset(keyid, 0x0, sizeof(keyid));
1010 	str2keyid(name, keyid, sizeof(keyid));
1011 	if (pgp_get_debug_level(__FILE__)) {
1012 		hexdump(io->outs, "keyid", keyid, 4);
1013 	}
1014 	savedstart = *from;
1015 	if ((kp = pgp_getkeybyid(io, keyring, keyid, from, NULL)) != NULL) {
1016 		return kp;
1017 	}
1018 	*from = savedstart;
1019 	if (pgp_get_debug_level(__FILE__)) {
1020 		(void) fprintf(io->outs, "regex match '%s' from %u\n",
1021 			name, *from);
1022 	}
1023 	/* match on full name or email address as a NOSUB, ICASE regexp */
1024 	(void) regcomp(&r, name, REG_EXTENDED | REG_ICASE);
1025 	for (keyp = &keyring->keys[*from]; *from < keyring->keyc; *from += 1, keyp++) {
1026 		uidp = keyp->uids;
1027 		for (i = 0 ; i < keyp->uidc; i++, uidp++) {
1028 			if (regexec(&r, (char *)*uidp, 0, NULL, 0) == 0) {
1029 				if (pgp_get_debug_level(__FILE__)) {
1030 					(void) fprintf(io->outs,
1031 						"MATCHED keyid \"%s\" len %" PRIsize "u\n",
1032 					       (char *) *uidp, len);
1033 				}
1034 				regfree(&r);
1035 				return keyp;
1036 			}
1037 		}
1038 	}
1039 	regfree(&r);
1040 	return NULL;
1041 }
1042 
1043 /**
1044    \ingroup HighLevel_KeyringFind
1045 
1046    \brief Finds key from its User ID
1047 
1048    \param keyring Keyring to be searched
1049    \param userid User ID of required key
1050 
1051    \return Pointer to Key, if found; NULL, if not found
1052 
1053    \note This returns a pointer to the key inside the keyring, not a
1054    copy.  Do not free it.
1055 
1056 */
1057 const pgp_key_t *
1058 pgp_getkeybyname(pgp_io_t *io,
1059 			const pgp_keyring_t *keyring,
1060 			const char *name)
1061 {
1062 	unsigned	from;
1063 
1064 	from = 0;
1065 	return getkeybyname(io, keyring, name, &from);
1066 }
1067 
1068 const pgp_key_t *
1069 pgp_getnextkeybyname(pgp_io_t *io,
1070 			const pgp_keyring_t *keyring,
1071 			const char *name,
1072 			unsigned *n)
1073 {
1074 	return getkeybyname(io, keyring, name, n);
1075 }
1076 
1077 /**
1078    \ingroup HighLevel_KeyringList
1079 
1080    \brief Prints all keys in keyring to stdout.
1081 
1082    \param keyring Keyring to use
1083 
1084    \return none
1085 */
1086 int
1087 pgp_keyring_list(pgp_io_t *io, const pgp_keyring_t *keyring, const int psigs)
1088 {
1089 	pgp_key_t		*key;
1090 	unsigned		 n;
1091 	unsigned		 keyc = (keyring != NULL) ? keyring->keyc : 0;
1092 
1093 	(void) fprintf(io->res, "%u key%s\n", keyc, (keyc == 1) ? "" : "s");
1094 	if (keyring == NULL) {
1095 		return 1;
1096 	}
1097 	for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
1098 		if (pgp_is_key_secret(key)) {
1099 			pgp_print_keydata(io, keyring, key, "sec",
1100 				&key->key.seckey.pubkey, 0);
1101 		} else {
1102 			pgp_print_keydata(io, keyring, key, "pub",
1103 				&key->key.pubkey, psigs);
1104 		}
1105 		(void) fputc('\n', io->res);
1106 	}
1107 	return 1;
1108 }
1109 
1110 int
1111 pgp_keyring_json(pgp_io_t *io, const pgp_keyring_t *keyring, mj_t *obj, const int psigs)
1112 {
1113 	pgp_key_t		*key;
1114 	unsigned		 n;
1115 
1116 	(void) memset(obj, 0x0, sizeof(*obj));
1117 	mj_create(obj, "array");
1118 	obj->size = keyring->keyvsize;
1119 	if (pgp_get_debug_level(__FILE__)) {
1120 		(void) fprintf(io->errs, "pgp_keyring_json: vsize %u\n", obj->size);
1121 	}
1122 	if ((obj->value.v = calloc(sizeof(*obj->value.v), obj->size)) == NULL) {
1123 		(void) fprintf(io->errs, "calloc failure\n");
1124 		return 0;
1125 	}
1126 	for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
1127 		if (pgp_is_key_secret(key)) {
1128 			pgp_sprint_mj(io, keyring, key, &obj->value.v[obj->c],
1129 				"sec", &key->key.seckey.pubkey, psigs);
1130 		} else {
1131 			pgp_sprint_mj(io, keyring, key, &obj->value.v[obj->c],
1132 				"pub", &key->key.pubkey, psigs);
1133 		}
1134 		if (obj->value.v[obj->c].type != 0) {
1135 			obj->c += 1;
1136 		}
1137 	}
1138 	if (pgp_get_debug_level(__FILE__)) {
1139 		char	*s;
1140 
1141 		mj_asprint(&s, obj, MJ_JSON_ENCODE);
1142 		(void) fprintf(stderr, "pgp_keyring_json: '%s'\n", s);
1143 		free(s);
1144 	}
1145 	return 1;
1146 }
1147 
1148 
1149 /* this interface isn't right - hook into callback for getting passphrase */
1150 char *
1151 pgp_export_key(pgp_io_t *io, const pgp_key_t *keydata, uint8_t *passphrase)
1152 {
1153 	pgp_output_t	*output;
1154 	pgp_memory_t	*mem;
1155 	char		*cp;
1156 
1157 	__PGP_USED(io);
1158 	pgp_setup_memory_write(&output, &mem, 128);
1159 	if (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) {
1160 		pgp_write_xfer_pubkey(output, keydata, 1);
1161 	} else {
1162 		pgp_write_xfer_seckey(output, keydata, passphrase,
1163 					strlen((char *)passphrase), 1);
1164 	}
1165 	cp = netpgp_strdup(pgp_mem_data(mem));
1166 	pgp_teardown_memory_write(output, mem);
1167 	return cp;
1168 }
1169 
1170 /* add a key to a public keyring */
1171 int
1172 pgp_add_to_pubring(pgp_keyring_t *keyring, const pgp_pubkey_t *pubkey, pgp_content_enum tag)
1173 {
1174 	pgp_key_t	*key;
1175 	time_t		 duration;
1176 
1177 	if (pgp_get_debug_level(__FILE__)) {
1178 		fprintf(stderr, "pgp_add_to_pubring (type %u)\n", tag);
1179 	}
1180 	switch(tag) {
1181 	case PGP_PTAG_CT_PUBLIC_KEY:
1182 		EXPAND_ARRAY(keyring, key);
1183 		key = &keyring->keys[keyring->keyc++];
1184 		duration = key->key.pubkey.duration;
1185 		(void) memset(key, 0x0, sizeof(*key));
1186 		key->type = tag;
1187 		pgp_keyid(key->sigid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
1188 		pgp_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype);
1189 		key->key.pubkey = *pubkey;
1190 		key->key.pubkey.duration = duration;
1191 		return 1;
1192 	case PGP_PTAG_CT_PUBLIC_SUBKEY:
1193 		/* subkey is not the first */
1194 		key = &keyring->keys[keyring->keyc - 1];
1195 		pgp_keyid(key->encid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
1196 		duration = key->key.pubkey.duration;
1197 		(void) memcpy(&key->enckey, pubkey, sizeof(key->enckey));
1198 		key->enckey.duration = duration;
1199 		return 1;
1200 	default:
1201 		return 0;
1202 	}
1203 }
1204 
1205 /* add a key to a secret keyring */
1206 int
1207 pgp_add_to_secring(pgp_keyring_t *keyring, const pgp_seckey_t *seckey)
1208 {
1209 	const pgp_pubkey_t	*pubkey;
1210 	pgp_key_t		*key;
1211 
1212 	if (pgp_get_debug_level(__FILE__)) {
1213 		fprintf(stderr, "pgp_add_to_secring\n");
1214 	}
1215 	if (keyring->keyc > 0) {
1216 		key = &keyring->keys[keyring->keyc - 1];
1217 		if (pgp_get_debug_level(__FILE__) &&
1218 		    key->key.pubkey.alg == PGP_PKA_DSA &&
1219 		    seckey->pubkey.alg == PGP_PKA_ELGAMAL) {
1220 			fprintf(stderr, "pgp_add_to_secring: found elgamal seckey\n");
1221 		}
1222 	}
1223 	EXPAND_ARRAY(keyring, key);
1224 	key = &keyring->keys[keyring->keyc++];
1225 	(void) memset(key, 0x0, sizeof(*key));
1226 	pubkey = &seckey->pubkey;
1227 	pgp_keyid(key->sigid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
1228 	pgp_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype);
1229 	key->type = PGP_PTAG_CT_SECRET_KEY;
1230 	key->key.seckey = *seckey;
1231 	if (pgp_get_debug_level(__FILE__)) {
1232 		fprintf(stderr, "pgp_add_to_secring: keyc %u\n", keyring->keyc);
1233 	}
1234 	return 1;
1235 }
1236 
1237 /* append one keyring to another */
1238 int
1239 pgp_append_keyring(pgp_keyring_t *keyring, pgp_keyring_t *newring)
1240 {
1241 	unsigned	i;
1242 
1243 	for (i = 0 ; i < newring->keyc ; i++) {
1244 		EXPAND_ARRAY(keyring, key);
1245 		(void) memcpy(&keyring->keys[keyring->keyc], &newring->keys[i],
1246 				sizeof(newring->keys[i]));
1247 		keyring->keyc += 1;
1248 	}
1249 	return 1;
1250 }
1251