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