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.50 2011/06/25 00:37:44 agc 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, unsigned 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 		(void) pgp_getpassphrase(decrypt->passfp, pass, sizeof(pass));
248 		*content->skey_passphrase.passphrase = netpgp_strdup(pass);
249 		pgp_forget(pass, (unsigned)sizeof(pass));
250 		return PGP_KEEP_MEMORY;
251 
252 	case PGP_PARSER_ERRCODE:
253 		switch (content->errcode.errcode) {
254 		case PGP_E_P_MPI_FORMAT_ERROR:
255 			/* Generally this means a bad passphrase */
256 			fprintf(stderr, "Bad passphrase!\n");
257 			return PGP_RELEASE_MEMORY;
258 
259 		case PGP_E_P_PACKET_CONSUMED:
260 			/* And this is because of an error we've accepted */
261 			return PGP_RELEASE_MEMORY;
262 		default:
263 			break;
264 		}
265 		(void) fprintf(stderr, "parse error: %s\n",
266 				pgp_errcode(content->errcode.errcode));
267 		return PGP_FINISHED;
268 
269 	case PGP_PARSER_ERROR:
270 		fprintf(stderr, "parse error: %s\n", content->error);
271 		return PGP_FINISHED;
272 
273 	case PGP_PTAG_CT_SECRET_KEY:
274 		if ((decrypt->seckey = calloc(1, sizeof(*decrypt->seckey))) == NULL) {
275 			(void) fprintf(stderr, "decrypt_cb: bad alloc\n");
276 			return PGP_FINISHED;
277 		}
278 		decrypt->seckey->checkhash = calloc(1, PGP_CHECKHASH_SIZE);
279 		*decrypt->seckey = content->seckey;
280 		return PGP_KEEP_MEMORY;
281 
282 	case PGP_PARSER_PACKET_END:
283 		/* nothing to do */
284 		break;
285 
286 	default:
287 		fprintf(stderr, "Unexpected tag %d (0x%x)\n", pkt->tag,
288 			pkt->tag);
289 		return PGP_FINISHED;
290 	}
291 
292 	return PGP_RELEASE_MEMORY;
293 }
294 
295 /**
296 \ingroup Core_Keys
297 \brief Decrypts secret key from given keydata with given passphrase
298 \param key Key from which to get secret key
299 \param passphrase Passphrase to use to decrypt secret key
300 \return secret key
301 */
302 pgp_seckey_t *
303 pgp_decrypt_seckey(const pgp_key_t *key, void *passfp)
304 {
305 	pgp_stream_t	*stream;
306 	const int	 printerrors = 1;
307 	decrypt_t	 decrypt;
308 
309 	(void) memset(&decrypt, 0x0, sizeof(decrypt));
310 	decrypt.key = key;
311 	decrypt.passfp = passfp;
312 	stream = pgp_new(sizeof(*stream));
313 	pgp_keydata_reader_set(stream, key);
314 	pgp_set_callback(stream, decrypt_cb, &decrypt);
315 	stream->readinfo.accumulate = 1;
316 	pgp_parse(stream, !printerrors);
317 	return decrypt.seckey;
318 }
319 
320 /**
321 \ingroup Core_Keys
322 \brief Set secret key in content
323 \param content Content to be set
324 \param key Keydata to get secret key from
325 */
326 void
327 pgp_set_seckey(pgp_contents_t *cont, const pgp_key_t *key)
328 {
329 	*cont->get_seckey.seckey = &key->key.seckey;
330 }
331 
332 /**
333 \ingroup Core_Keys
334 \brief Get Key ID from keydata
335 \param key Keydata to get Key ID from
336 \return Pointer to Key ID inside keydata
337 */
338 const uint8_t *
339 pgp_get_key_id(const pgp_key_t *key)
340 {
341 	return key->sigid;
342 }
343 
344 /**
345 \ingroup Core_Keys
346 \brief How many User IDs in this key?
347 \param key Keydata to check
348 \return Num of user ids
349 */
350 unsigned
351 pgp_get_userid_count(const pgp_key_t *key)
352 {
353 	return key->uidc;
354 }
355 
356 /**
357 \ingroup Core_Keys
358 \brief Get indexed user id from key
359 \param key Key to get user id from
360 \param index Which key to get
361 \return Pointer to requested user id
362 */
363 const uint8_t *
364 pgp_get_userid(const pgp_key_t *key, unsigned subscript)
365 {
366 	return key->uids[subscript];
367 }
368 
369 /**
370    \ingroup HighLevel_Supported
371    \brief Checks whether key's algorithm and type are supported by OpenPGP::SDK
372    \param keydata Key to be checked
373    \return 1 if key algorithm and type are supported by OpenPGP::SDK; 0 if not
374 */
375 
376 unsigned
377 pgp_is_key_supported(const pgp_key_t *key)
378 {
379 	if (key->type == PGP_PTAG_CT_PUBLIC_KEY) {
380 		switch(key->key.pubkey.alg) {
381 		case PGP_PKA_RSA:
382 		case PGP_PKA_DSA:
383 		case PGP_PKA_ELGAMAL:
384 			return 1;
385 		default:
386 			break;
387 		}
388 	}
389 	return 0;
390 }
391 
392 /* \todo check where userid pointers are copied */
393 /**
394 \ingroup Core_Keys
395 \brief Copy user id, including contents
396 \param dst Destination User ID
397 \param src Source User ID
398 \note If dst already has a userid, it will be freed.
399 */
400 static uint8_t *
401 copy_userid(uint8_t **dst, const uint8_t *src)
402 {
403 	size_t          len;
404 
405 	len = strlen((const char *) src);
406 	if (*dst) {
407 		free(*dst);
408 	}
409 	if ((*dst = calloc(1, len + 1)) == NULL) {
410 		(void) fprintf(stderr, "copy_userid: bad alloc\n");
411 	} else {
412 		(void) memcpy(*dst, src, len);
413 	}
414 	return *dst;
415 }
416 
417 /* \todo check where pkt pointers are copied */
418 /**
419 \ingroup Core_Keys
420 \brief Copy packet, including contents
421 \param dst Destination packet
422 \param src Source packet
423 \note If dst already has a packet, it will be freed.
424 */
425 static pgp_subpacket_t *
426 copy_packet(pgp_subpacket_t *dst, const pgp_subpacket_t *src)
427 {
428 	if (dst->raw) {
429 		free(dst->raw);
430 	}
431 	if ((dst->raw = calloc(1, src->length)) == NULL) {
432 		(void) fprintf(stderr, "copy_packet: bad alloc\n");
433 	} else {
434 		dst->length = src->length;
435 		(void) memcpy(dst->raw, src->raw, src->length);
436 	}
437 	return dst;
438 }
439 
440 /**
441 \ingroup Core_Keys
442 \brief Add User ID to key
443 \param key Key to which to add User ID
444 \param userid User ID to add
445 \return Pointer to new User ID
446 */
447 uint8_t  *
448 pgp_add_userid(pgp_key_t *key, const uint8_t *userid)
449 {
450 	uint8_t  **uidp;
451 
452 	EXPAND_ARRAY(key, uid);
453 	/* initialise new entry in array */
454 	uidp = &key->uids[key->uidc++];
455 	*uidp = NULL;
456 	/* now copy it */
457 	return copy_userid(uidp, userid);
458 }
459 
460 void print_packet_hex(const pgp_subpacket_t *pkt);
461 
462 /**
463 \ingroup Core_Keys
464 \brief Add packet to key
465 \param keydata Key to which to add packet
466 \param packet Packet to add
467 \return Pointer to new packet
468 */
469 pgp_subpacket_t   *
470 pgp_add_subpacket(pgp_key_t *keydata, const pgp_subpacket_t *packet)
471 {
472 	pgp_subpacket_t   *subpktp;
473 
474 	EXPAND_ARRAY(keydata, packet);
475 	/* initialise new entry in array */
476 	subpktp = &keydata->packets[keydata->packetc++];
477 	subpktp->length = 0;
478 	subpktp->raw = NULL;
479 	/* now copy it */
480 	return copy_packet(subpktp, packet);
481 }
482 
483 /**
484 \ingroup Core_Keys
485 \brief Add selfsigned User ID to key
486 \param keydata Key to which to add user ID
487 \param userid Self-signed User ID to add
488 \return 1 if OK; else 0
489 */
490 unsigned
491 pgp_add_selfsigned_userid(pgp_key_t *key, uint8_t *userid)
492 {
493 	pgp_create_sig_t	*sig;
494 	pgp_subpacket_t	 sigpacket;
495 	pgp_memory_t		*mem_userid = NULL;
496 	pgp_output_t		*useridoutput = NULL;
497 	pgp_memory_t		*mem_sig = NULL;
498 	pgp_output_t		*sigoutput = NULL;
499 
500 	/*
501          * create signature packet for this userid
502          */
503 
504 	/* create userid pkt */
505 	pgp_setup_memory_write(&useridoutput, &mem_userid, 128);
506 	pgp_write_struct_userid(useridoutput, userid);
507 
508 	/* create sig for this pkt */
509 	sig = pgp_create_sig_new();
510 	pgp_sig_start_key_sig(sig, &key->key.seckey.pubkey, userid, PGP_CERT_POSITIVE);
511 	pgp_add_time(sig, (int64_t)time(NULL), "birth");
512 	pgp_add_issuer_keyid(sig, key->sigid);
513 	pgp_add_primary_userid(sig, 1);
514 	pgp_end_hashed_subpkts(sig);
515 
516 	pgp_setup_memory_write(&sigoutput, &mem_sig, 128);
517 	pgp_write_sig(sigoutput, sig, &key->key.seckey.pubkey, &key->key.seckey);
518 
519 	/* add this packet to key */
520 	sigpacket.length = pgp_mem_len(mem_sig);
521 	sigpacket.raw = pgp_mem_data(mem_sig);
522 
523 	/* add userid to key */
524 	(void) pgp_add_userid(key, userid);
525 	(void) pgp_add_subpacket(key, &sigpacket);
526 
527 	/* cleanup */
528 	pgp_create_sig_delete(sig);
529 	pgp_output_delete(useridoutput);
530 	pgp_output_delete(sigoutput);
531 	pgp_memory_free(mem_userid);
532 	pgp_memory_free(mem_sig);
533 
534 	return 1;
535 }
536 
537 /**
538 \ingroup Core_Keys
539 \brief Initialise pgp_key_t
540 \param keydata Keydata to initialise
541 \param type PGP_PTAG_CT_PUBLIC_KEY or PGP_PTAG_CT_SECRET_KEY
542 */
543 void
544 pgp_keydata_init(pgp_key_t *keydata, const pgp_content_enum type)
545 {
546 	if (keydata->type != PGP_PTAG_CT_RESERVED) {
547 		(void) fprintf(stderr,
548 			"pgp_keydata_init: wrong keydata type\n");
549 	} else if (type != PGP_PTAG_CT_PUBLIC_KEY &&
550 		   type != PGP_PTAG_CT_SECRET_KEY) {
551 		(void) fprintf(stderr, "pgp_keydata_init: wrong type\n");
552 	} else {
553 		keydata->type = type;
554 	}
555 }
556 
557 /* used to point to data during keyring read */
558 typedef struct keyringcb_t {
559 	pgp_keyring_t		*keyring;	/* the keyring we're reading */
560 } keyringcb_t;
561 
562 
563 static pgp_cb_ret_t
564 cb_keyring_read(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
565 {
566 	pgp_keyring_t	*keyring;
567 	pgp_revoke_t	*revocation;
568 	pgp_key_t	*key;
569 	keyringcb_t	*cb;
570 
571 	cb = pgp_callback_arg(cbinfo);
572 	keyring = cb->keyring;
573 	switch (pkt->tag) {
574 	case PGP_PARSER_PTAG:
575 	case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
576 		/* we get these because we didn't prompt */
577 		break;
578 	case PGP_PTAG_CT_SIGNATURE_HEADER:
579 		key = &keyring->keys[keyring->keyc - 1];
580 		EXPAND_ARRAY(key, subsig);
581 		key->subsigs[key->subsigc].uid = key->uidc - 1;
582 		(void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig,
583 				sizeof(pkt->u.sig));
584 		key->subsigc += 1;
585 		break;
586 	case PGP_PTAG_CT_SIGNATURE:
587 		key = &keyring->keys[keyring->keyc - 1];
588 		EXPAND_ARRAY(key, subsig);
589 		key->subsigs[key->subsigc].uid = key->uidc - 1;
590 		(void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig,
591 				sizeof(pkt->u.sig));
592 		key->subsigc += 1;
593 		break;
594 	case PGP_PTAG_CT_TRUST:
595 		key = &keyring->keys[keyring->keyc - 1];
596 		key->subsigs[key->subsigc - 1].trustlevel = pkt->u.ss_trust.level;
597 		key->subsigs[key->subsigc - 1].trustamount = pkt->u.ss_trust.amount;
598 		break;
599 	case PGP_PTAG_SS_KEY_EXPIRY:
600 		EXPAND_ARRAY(keyring, key);
601 		if (keyring->keyc > 0) {
602 			keyring->keys[keyring->keyc - 1].key.pubkey.duration = pkt->u.ss_time;
603 		}
604 		break;
605 	case PGP_PTAG_SS_ISSUER_KEY_ID:
606 		key = &keyring->keys[keyring->keyc - 1];
607 		(void) memcpy(&key->subsigs[key->subsigc - 1].sig.info.signer_id,
608 			      pkt->u.ss_issuer,
609 			      sizeof(pkt->u.ss_issuer));
610 		key->subsigs[key->subsigc - 1].sig.info.signer_id_set = 1;
611 		break;
612 	case PGP_PTAG_SS_CREATION_TIME:
613 		key = &keyring->keys[keyring->keyc - 1];
614 		key->subsigs[key->subsigc - 1].sig.info.birthtime = pkt->u.ss_time;
615 		key->subsigs[key->subsigc - 1].sig.info.birthtime_set = 1;
616 		break;
617 	case PGP_PTAG_SS_EXPIRATION_TIME:
618 		key = &keyring->keys[keyring->keyc - 1];
619 		key->subsigs[key->subsigc - 1].sig.info.duration = pkt->u.ss_time;
620 		key->subsigs[key->subsigc - 1].sig.info.duration_set = 1;
621 		break;
622 	case PGP_PTAG_SS_PRIMARY_USER_ID:
623 		key = &keyring->keys[keyring->keyc - 1];
624 		key->uid0 = key->uidc - 1;
625 		break;
626 	case PGP_PTAG_SS_REVOCATION_REASON:
627 		key = &keyring->keys[keyring->keyc - 1];
628 		if (key->uidc == 0) {
629 			/* revoke whole key */
630 			key->revoked = 1;
631 			revocation = &key->revocation;
632 		} else {
633 			/* revoke the user id */
634 			EXPAND_ARRAY(key, revoke);
635 			revocation = &key->revokes[key->revokec];
636 			key->revokes[key->revokec].uid = key->uidc - 1;
637 			key->revokec += 1;
638 		}
639 		revocation->code = pkt->u.ss_revocation.code;
640 		revocation->reason = netpgp_strdup(pgp_show_ss_rr_code(pkt->u.ss_revocation.code));
641 		break;
642 	case PGP_PTAG_CT_SIGNATURE_FOOTER:
643 	case PGP_PARSER_ERRCODE:
644 		break;
645 
646 	default:
647 		break;
648 	}
649 
650 	return PGP_RELEASE_MEMORY;
651 }
652 
653 /**
654    \ingroup HighLevel_KeyringRead
655 
656    \brief Reads a keyring from a file
657 
658    \param keyring Pointer to an existing pgp_keyring_t struct
659    \param armour 1 if file is armoured; else 0
660    \param filename Filename of keyring to be read
661 
662    \return pgp 1 if OK; 0 on error
663 
664    \note Keyring struct must already exist.
665 
666    \note Can be used with either a public or secret keyring.
667 
668    \note You must call pgp_keyring_free() after usage to free alloc-ed memory.
669 
670    \note If you call this twice on the same keyring struct, without calling
671    pgp_keyring_free() between these calls, you will introduce a memory leak.
672 
673    \sa pgp_keyring_read_from_mem()
674    \sa pgp_keyring_free()
675 
676 */
677 
678 unsigned
679 pgp_keyring_fileread(pgp_keyring_t *keyring,
680 			const unsigned armour,
681 			const char *filename)
682 {
683 	pgp_stream_t	*stream;
684 	keyringcb_t	 cb;
685 	unsigned	 res = 1;
686 	int		 fd;
687 
688 	(void) memset(&cb, 0x0, sizeof(cb));
689 	cb.keyring = keyring;
690 	stream = pgp_new(sizeof(*stream));
691 
692 	/* add this for the moment, */
693 	/*
694 	 * \todo need to fix the problems with reading signature subpackets
695 	 * later
696 	 */
697 
698 	/* pgp_parse_options(parse,PGP_PTAG_SS_ALL,PGP_PARSE_RAW); */
699 	pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
700 
701 #ifdef O_BINARY
702 	fd = open(filename, O_RDONLY | O_BINARY);
703 #else
704 	fd = open(filename, O_RDONLY);
705 #endif
706 	if (fd < 0) {
707 		pgp_stream_delete(stream);
708 		perror(filename);
709 		return 0;
710 	}
711 #ifdef USE_MMAP_FOR_FILES
712 	pgp_reader_set_mmap(stream, fd);
713 #else
714 	pgp_reader_set_fd(stream, fd);
715 #endif
716 
717 	pgp_set_callback(stream, cb_keyring_read, &cb);
718 
719 	if (armour) {
720 		pgp_reader_push_dearmour(stream);
721 	}
722 	res = pgp_parse_and_accumulate(keyring, stream);
723 	pgp_print_errors(pgp_stream_get_errors(stream));
724 
725 	if (armour) {
726 		pgp_reader_pop_dearmour(stream);
727 	}
728 
729 	(void)close(fd);
730 
731 	pgp_stream_delete(stream);
732 
733 	return res;
734 }
735 
736 /**
737    \ingroup HighLevel_KeyringRead
738 
739    \brief Reads a keyring from memory
740 
741    \param keyring Pointer to existing pgp_keyring_t struct
742    \param armour 1 if file is armoured; else 0
743    \param mem Pointer to a pgp_memory_t struct containing keyring to be read
744 
745    \return pgp 1 if OK; 0 on error
746 
747    \note Keyring struct must already exist.
748 
749    \note Can be used with either a public or secret keyring.
750 
751    \note You must call pgp_keyring_free() after usage to free alloc-ed memory.
752 
753    \note If you call this twice on the same keyring struct, without calling
754    pgp_keyring_free() between these calls, you will introduce a memory leak.
755 
756    \sa pgp_keyring_fileread
757    \sa pgp_keyring_free
758 */
759 unsigned
760 pgp_keyring_read_from_mem(pgp_io_t *io,
761 				pgp_keyring_t *keyring,
762 				const unsigned armour,
763 				pgp_memory_t *mem)
764 {
765 	pgp_stream_t	*stream;
766 	const unsigned	 noaccum = 0;
767 	keyringcb_t	 cb;
768 	unsigned	 res;
769 
770 	(void) memset(&cb, 0x0, sizeof(cb));
771 	cb.keyring = keyring;
772 	stream = pgp_new(sizeof(*stream));
773 	pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
774 	pgp_setup_memory_read(io, &stream, mem, &cb, cb_keyring_read,
775 					noaccum);
776 	if (armour) {
777 		pgp_reader_push_dearmour(stream);
778 	}
779 	res = (unsigned)pgp_parse_and_accumulate(keyring, stream);
780 	pgp_print_errors(pgp_stream_get_errors(stream));
781 	if (armour) {
782 		pgp_reader_pop_dearmour(stream);
783 	}
784 	/* don't call teardown_memory_read because memory was passed in */
785 	pgp_stream_delete(stream);
786 	return res;
787 }
788 
789 /**
790    \ingroup HighLevel_KeyringRead
791 
792    \brief Frees keyring's contents (but not keyring itself)
793 
794    \param keyring Keyring whose data is to be freed
795 
796    \note This does not free keyring itself, just the memory alloc-ed in it.
797  */
798 void
799 pgp_keyring_free(pgp_keyring_t *keyring)
800 {
801 	(void)free(keyring->keys);
802 	keyring->keys = NULL;
803 	keyring->keyc = keyring->keyvsize = 0;
804 }
805 
806 /**
807    \ingroup HighLevel_KeyringFind
808 
809    \brief Finds key in keyring from its Key ID
810 
811    \param keyring Keyring to be searched
812    \param keyid ID of required key
813 
814    \return Pointer to key, if found; NULL, if not found
815 
816    \note This returns a pointer to the key inside the given keyring,
817    not a copy.  Do not free it after use.
818 
819 */
820 const pgp_key_t *
821 pgp_getkeybyid(pgp_io_t *io, const pgp_keyring_t *keyring,
822 			   const uint8_t *keyid, unsigned *from, pgp_pubkey_t **pubkey)
823 {
824 	uint8_t	nullid[PGP_KEY_ID_SIZE];
825 
826 	(void) memset(nullid, 0x0, sizeof(nullid));
827 	for ( ; keyring && *from < keyring->keyc; *from += 1) {
828 		if (pgp_get_debug_level(__FILE__)) {
829 			hexdump(io->errs, "keyring keyid", keyring->keys[*from].sigid, PGP_KEY_ID_SIZE);
830 			hexdump(io->errs, "keyid", keyid, PGP_KEY_ID_SIZE);
831 		}
832 		if (memcmp(keyring->keys[*from].sigid, keyid, PGP_KEY_ID_SIZE) == 0 ||
833 		    memcmp(&keyring->keys[*from].sigid[PGP_KEY_ID_SIZE / 2],
834 				keyid, PGP_KEY_ID_SIZE / 2) == 0) {
835 			if (pubkey) {
836 				*pubkey = &keyring->keys[*from].key.pubkey;
837 			}
838 			return &keyring->keys[*from];
839 		}
840 		if (memcmp(&keyring->keys[*from].encid, nullid, sizeof(nullid)) == 0) {
841 			continue;
842 		}
843 		if (memcmp(&keyring->keys[*from].encid, keyid, PGP_KEY_ID_SIZE) == 0 ||
844 		    memcmp(&keyring->keys[*from].encid[PGP_KEY_ID_SIZE / 2], keyid, PGP_KEY_ID_SIZE / 2) == 0) {
845 			if (pubkey) {
846 				*pubkey = &keyring->keys[*from].enckey;
847 			}
848 			return &keyring->keys[*from];
849 		}
850 	}
851 	return NULL;
852 }
853 
854 /* convert a string keyid into a binary keyid */
855 static void
856 str2keyid(const char *userid, uint8_t *keyid, size_t len)
857 {
858 	static const char	*uppers = "0123456789ABCDEF";
859 	static const char	*lowers = "0123456789abcdef";
860 	const char		*hi;
861 	const char		*lo;
862 	uint8_t			 hichar;
863 	uint8_t			 lochar;
864 	size_t			 j;
865 	int			 i;
866 
867 	for (i = 0, j = 0 ; j < len && userid[i] && userid[i + 1] ; i += 2, j++) {
868 		if ((hi = strchr(uppers, userid[i])) == NULL) {
869 			if ((hi = strchr(lowers, userid[i])) == NULL) {
870 				break;
871 			}
872 			hichar = (uint8_t)(hi - lowers);
873 		} else {
874 			hichar = (uint8_t)(hi - uppers);
875 		}
876 		if ((lo = strchr(uppers, userid[i + 1])) == NULL) {
877 			if ((lo = strchr(lowers, userid[i + 1])) == NULL) {
878 				break;
879 			}
880 			lochar = (uint8_t)(lo - lowers);
881 		} else {
882 			lochar = (uint8_t)(lo - uppers);
883 		}
884 		keyid[j] = (hichar << 4) | (lochar);
885 	}
886 	keyid[j] = 0x0;
887 }
888 
889 /* return the next key which matches, starting searching at *from */
890 static const pgp_key_t *
891 getkeybyname(pgp_io_t *io,
892 			const pgp_keyring_t *keyring,
893 			const char *name,
894 			unsigned *from)
895 {
896 	const pgp_key_t	*kp;
897 	uint8_t			**uidp;
898 	unsigned    	 	 i = 0;
899 	pgp_key_t		*keyp;
900 	unsigned		 savedstart;
901 	regex_t			 r;
902 	uint8_t		 	 keyid[PGP_KEY_ID_SIZE + 1];
903 	size_t          	 len;
904 
905 	if (!keyring || !name || !from) {
906 		return NULL;
907 	}
908 	len = strlen(name);
909 	if (pgp_get_debug_level(__FILE__)) {
910 		(void) fprintf(io->outs, "[%u] name '%s', len %zu\n",
911 			*from, name, len);
912 	}
913 	/* first try name as a keyid */
914 	(void) memset(keyid, 0x0, sizeof(keyid));
915 	str2keyid(name, keyid, sizeof(keyid));
916 	if (pgp_get_debug_level(__FILE__)) {
917 		hexdump(io->outs, "keyid", keyid, 4);
918 	}
919 	savedstart = *from;
920 	if ((kp = pgp_getkeybyid(io, keyring, keyid, from, NULL)) != NULL) {
921 		return kp;
922 	}
923 	*from = savedstart;
924 	if (pgp_get_debug_level(__FILE__)) {
925 		(void) fprintf(io->outs, "regex match '%s' from %u\n",
926 			name, *from);
927 	}
928 	/* match on full name or email address as a NOSUB, ICASE regexp */
929 	(void) regcomp(&r, name, REG_EXTENDED | REG_ICASE);
930 	for (keyp = &keyring->keys[*from]; *from < keyring->keyc; *from += 1, keyp++) {
931 		uidp = keyp->uids;
932 		for (i = 0 ; i < keyp->uidc; i++, uidp++) {
933 			if (regexec(&r, (char *)*uidp, 0, NULL, 0) == 0) {
934 				if (pgp_get_debug_level(__FILE__)) {
935 					(void) fprintf(io->outs,
936 						"MATCHED keyid \"%s\" len %" PRIsize "u\n",
937 					       (char *) *uidp, len);
938 				}
939 				regfree(&r);
940 				return keyp;
941 			}
942 		}
943 	}
944 	regfree(&r);
945 	return NULL;
946 }
947 
948 /**
949    \ingroup HighLevel_KeyringFind
950 
951    \brief Finds key from its User ID
952 
953    \param keyring Keyring to be searched
954    \param userid User ID of required key
955 
956    \return Pointer to Key, if found; NULL, if not found
957 
958    \note This returns a pointer to the key inside the keyring, not a
959    copy.  Do not free it.
960 
961 */
962 const pgp_key_t *
963 pgp_getkeybyname(pgp_io_t *io,
964 			const pgp_keyring_t *keyring,
965 			const char *name)
966 {
967 	unsigned	from;
968 
969 	from = 0;
970 	return getkeybyname(io, keyring, name, &from);
971 }
972 
973 const pgp_key_t *
974 pgp_getnextkeybyname(pgp_io_t *io,
975 			const pgp_keyring_t *keyring,
976 			const char *name,
977 			unsigned *n)
978 {
979 	return getkeybyname(io, keyring, name, n);
980 }
981 
982 /**
983    \ingroup HighLevel_KeyringList
984 
985    \brief Prints all keys in keyring to stdout.
986 
987    \param keyring Keyring to use
988 
989    \return none
990 */
991 int
992 pgp_keyring_list(pgp_io_t *io, const pgp_keyring_t *keyring, const int psigs)
993 {
994 	pgp_key_t		*key;
995 	unsigned		 n;
996 
997 	(void) fprintf(io->res, "%u key%s\n", keyring->keyc,
998 		(keyring->keyc == 1) ? "" : "s");
999 	for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
1000 		if (pgp_is_key_secret(key)) {
1001 			pgp_print_keydata(io, keyring, key, "sec",
1002 				&key->key.seckey.pubkey, 0);
1003 		} else {
1004 			pgp_print_keydata(io, keyring, key, "signature ", &key->key.pubkey, psigs);
1005 		}
1006 		(void) fputc('\n', io->res);
1007 	}
1008 	return 1;
1009 }
1010 
1011 int
1012 pgp_keyring_json(pgp_io_t *io, const pgp_keyring_t *keyring, mj_t *obj, const int psigs)
1013 {
1014 	pgp_key_t		*key;
1015 	unsigned		 n;
1016 
1017 	(void) memset(obj, 0x0, sizeof(*obj));
1018 	mj_create(obj, "array");
1019 	obj->size = keyring->keyvsize;
1020 	if (pgp_get_debug_level(__FILE__)) {
1021 		(void) fprintf(io->errs, "pgp_keyring_json: vsize %u\n", obj->size);
1022 	}
1023 	if ((obj->value.v = calloc(sizeof(*obj->value.v), obj->size)) == NULL) {
1024 		(void) fprintf(io->errs, "calloc failure\n");
1025 		return 0;
1026 	}
1027 	for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
1028 		if (pgp_is_key_secret(key)) {
1029 			pgp_sprint_mj(io, keyring, key, &obj->value.v[obj->c],
1030 				"sec", &key->key.seckey.pubkey, psigs);
1031 		} else {
1032 			pgp_sprint_mj(io, keyring, key, &obj->value.v[obj->c],
1033 				"signature ", &key->key.pubkey, psigs);
1034 		}
1035 		if (obj->value.v[obj->c].type != 0) {
1036 			obj->c += 1;
1037 		}
1038 	}
1039 	if (pgp_get_debug_level(__FILE__)) {
1040 		char	*s;
1041 
1042 		mj_asprint(&s, obj, MJ_JSON_ENCODE);
1043 		(void) fprintf(stderr, "pgp_keyring_json: '%s'\n", s);
1044 		free(s);
1045 	}
1046 	return 1;
1047 }
1048 
1049 
1050 /* this interface isn't right - hook into callback for getting passphrase */
1051 char *
1052 pgp_export_key(pgp_io_t *io, const pgp_key_t *keydata, uint8_t *passphrase)
1053 {
1054 	pgp_output_t	*output;
1055 	pgp_memory_t	*mem;
1056 	char		*cp;
1057 
1058 	__PGP_USED(io);
1059 	pgp_setup_memory_write(&output, &mem, 128);
1060 	if (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) {
1061 		pgp_write_xfer_pubkey(output, keydata, 1);
1062 	} else {
1063 		pgp_write_xfer_seckey(output, keydata, passphrase,
1064 					strlen((char *)passphrase), 1);
1065 	}
1066 	cp = netpgp_strdup(pgp_mem_data(mem));
1067 	pgp_teardown_memory_write(output, mem);
1068 	return cp;
1069 }
1070 
1071 /* add a key to a public keyring */
1072 int
1073 pgp_add_to_pubring(pgp_keyring_t *keyring, const pgp_pubkey_t *pubkey, pgp_content_enum tag)
1074 {
1075 	pgp_key_t	*key;
1076 	time_t		 duration;
1077 
1078 	if (pgp_get_debug_level(__FILE__)) {
1079 		fprintf(stderr, "pgp_add_to_pubring (type %u)\n", tag);
1080 	}
1081 	switch(tag) {
1082 	case PGP_PTAG_CT_PUBLIC_KEY:
1083 		EXPAND_ARRAY(keyring, key);
1084 		key = &keyring->keys[keyring->keyc++];
1085 		duration = key->key.pubkey.duration;
1086 		(void) memset(key, 0x0, sizeof(*key));
1087 		key->type = tag;
1088 		pgp_keyid(key->sigid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
1089 		pgp_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype);
1090 		key->key.pubkey = *pubkey;
1091 		key->key.pubkey.duration = duration;
1092 		return 1;
1093 	case PGP_PTAG_CT_PUBLIC_SUBKEY:
1094 		/* subkey is not the first */
1095 		key = &keyring->keys[keyring->keyc - 1];
1096 		pgp_keyid(key->encid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
1097 		duration = key->key.pubkey.duration;
1098 		(void) memcpy(&key->enckey, pubkey, sizeof(key->enckey));
1099 		key->enckey.duration = duration;
1100 		return 1;
1101 	default:
1102 		return 0;
1103 	}
1104 }
1105 
1106 /* add a key to a secret keyring */
1107 int
1108 pgp_add_to_secring(pgp_keyring_t *keyring, const pgp_seckey_t *seckey)
1109 {
1110 	const pgp_pubkey_t	*pubkey;
1111 	pgp_key_t		*key;
1112 
1113 	if (pgp_get_debug_level(__FILE__)) {
1114 		fprintf(stderr, "pgp_add_to_secring\n");
1115 	}
1116 	if (keyring->keyc > 0) {
1117 		key = &keyring->keys[keyring->keyc - 1];
1118 		if (pgp_get_debug_level(__FILE__) &&
1119 		    key->key.pubkey.alg == PGP_PKA_DSA &&
1120 		    seckey->pubkey.alg == PGP_PKA_ELGAMAL) {
1121 			fprintf(stderr, "pgp_add_to_secring: found elgamal seckey\n");
1122 		}
1123 	}
1124 	EXPAND_ARRAY(keyring, key);
1125 	key = &keyring->keys[keyring->keyc++];
1126 	(void) memset(key, 0x0, sizeof(*key));
1127 	pubkey = &seckey->pubkey;
1128 	pgp_keyid(key->sigid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
1129 	pgp_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype);
1130 	key->type = PGP_PTAG_CT_SECRET_KEY;
1131 	key->key.seckey = *seckey;
1132 	if (pgp_get_debug_level(__FILE__)) {
1133 		fprintf(stderr, "pgp_add_to_secring: keyc %u\n", keyring->keyc);
1134 	}
1135 	return 1;
1136 }
1137 
1138 /* append one keyring to another */
1139 int
1140 pgp_append_keyring(pgp_keyring_t *keyring, pgp_keyring_t *newring)
1141 {
1142 	unsigned	i;
1143 
1144 	for (i = 0 ; i < newring->keyc ; i++) {
1145 		EXPAND_ARRAY(keyring, key);
1146 		(void) memcpy(&keyring->keys[keyring->keyc], &newring->keys[i],
1147 				sizeof(newring->keys[i]));
1148 		keyring->keyc += 1;
1149 	}
1150 	return 1;
1151 }
1152