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
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, unsigned 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		(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*/
302pgp_seckey_t *
303pgp_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*/
326void
327pgp_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*/
338const uint8_t *
339pgp_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*/
350unsigned
351pgp_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*/
363const uint8_t *
364pgp_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
376unsigned
377pgp_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*/
400static uint8_t *
401copy_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*/
425static pgp_subpacket_t *
426copy_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*/
447uint8_t  *
448pgp_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
460void 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*/
469pgp_subpacket_t   *
470pgp_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*/
490unsigned
491pgp_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*/
543void
544pgp_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 */
558typedef struct keyringcb_t {
559	pgp_keyring_t		*keyring;	/* the keyring we're reading */
560} keyringcb_t;
561
562
563static pgp_cb_ret_t
564cb_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
678unsigned
679pgp_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*/
759unsigned
760pgp_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 */
798void
799pgp_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*/
820const pgp_key_t *
821pgp_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 */
855static void
856str2keyid(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 */
890static const pgp_key_t *
891getkeybyname(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*/
962const pgp_key_t *
963pgp_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
973const pgp_key_t *
974pgp_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*/
991int
992pgp_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
1011int
1012pgp_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 */
1051char *
1052pgp_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 */
1072int
1073pgp_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 */
1107int
1108pgp_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 */
1139int
1140pgp_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