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