xref: /minix3/crypto/external/bsd/netpgp/dist/src/lib/keyring.c (revision ebfedea0ce5bbe81e252ddf32d732e40fb633fae)
1*ebfedea0SLionel Sambuc /*-
2*ebfedea0SLionel Sambuc  * Copyright (c) 2009 The NetBSD Foundation, Inc.
3*ebfedea0SLionel Sambuc  * All rights reserved.
4*ebfedea0SLionel Sambuc  *
5*ebfedea0SLionel Sambuc  * This code is derived from software contributed to The NetBSD Foundation
6*ebfedea0SLionel Sambuc  * by Alistair Crooks (agc@NetBSD.org)
7*ebfedea0SLionel Sambuc  *
8*ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
9*ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
10*ebfedea0SLionel Sambuc  * are met:
11*ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
12*ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
13*ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
14*ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
15*ebfedea0SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
16*ebfedea0SLionel Sambuc  *
17*ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18*ebfedea0SLionel Sambuc  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19*ebfedea0SLionel Sambuc  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20*ebfedea0SLionel Sambuc  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21*ebfedea0SLionel Sambuc  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*ebfedea0SLionel Sambuc  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*ebfedea0SLionel Sambuc  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*ebfedea0SLionel Sambuc  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25*ebfedea0SLionel Sambuc  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26*ebfedea0SLionel Sambuc  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27*ebfedea0SLionel Sambuc  * POSSIBILITY OF SUCH DAMAGE.
28*ebfedea0SLionel Sambuc  */
29*ebfedea0SLionel Sambuc /*
30*ebfedea0SLionel Sambuc  * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
31*ebfedea0SLionel Sambuc  * All rights reserved.
32*ebfedea0SLionel Sambuc  * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
33*ebfedea0SLionel Sambuc  * their moral rights under the UK Copyright Design and Patents Act 1988 to
34*ebfedea0SLionel Sambuc  * be recorded as the authors of this copyright work.
35*ebfedea0SLionel Sambuc  *
36*ebfedea0SLionel Sambuc  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37*ebfedea0SLionel Sambuc  * use this file except in compliance with the License.
38*ebfedea0SLionel Sambuc  *
39*ebfedea0SLionel Sambuc  * You may obtain a copy of the License at
40*ebfedea0SLionel Sambuc  *     http://www.apache.org/licenses/LICENSE-2.0
41*ebfedea0SLionel Sambuc  *
42*ebfedea0SLionel Sambuc  * Unless required by applicable law or agreed to in writing, software
43*ebfedea0SLionel Sambuc  * distributed under the License is distributed on an "AS IS" BASIS,
44*ebfedea0SLionel Sambuc  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45*ebfedea0SLionel Sambuc  *
46*ebfedea0SLionel Sambuc  * See the License for the specific language governing permissions and
47*ebfedea0SLionel Sambuc  * limitations under the License.
48*ebfedea0SLionel Sambuc  */
49*ebfedea0SLionel Sambuc 
50*ebfedea0SLionel Sambuc /** \file
51*ebfedea0SLionel Sambuc  */
52*ebfedea0SLionel Sambuc #include "config.h"
53*ebfedea0SLionel Sambuc 
54*ebfedea0SLionel Sambuc #ifdef HAVE_SYS_CDEFS_H
55*ebfedea0SLionel Sambuc #include <sys/cdefs.h>
56*ebfedea0SLionel Sambuc #endif
57*ebfedea0SLionel Sambuc 
58*ebfedea0SLionel Sambuc #if defined(__NetBSD__)
59*ebfedea0SLionel Sambuc __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
60*ebfedea0SLionel Sambuc __RCSID("$NetBSD: keyring.c,v 1.50 2011/06/25 00:37:44 agc Exp $");
61*ebfedea0SLionel Sambuc #endif
62*ebfedea0SLionel Sambuc 
63*ebfedea0SLionel Sambuc #ifdef HAVE_FCNTL_H
64*ebfedea0SLionel Sambuc #include <fcntl.h>
65*ebfedea0SLionel Sambuc #endif
66*ebfedea0SLionel Sambuc 
67*ebfedea0SLionel Sambuc #include <regex.h>
68*ebfedea0SLionel Sambuc #include <stdlib.h>
69*ebfedea0SLionel Sambuc #include <string.h>
70*ebfedea0SLionel Sambuc 
71*ebfedea0SLionel Sambuc #ifdef HAVE_TERMIOS_H
72*ebfedea0SLionel Sambuc #include <termios.h>
73*ebfedea0SLionel Sambuc #endif
74*ebfedea0SLionel Sambuc 
75*ebfedea0SLionel Sambuc #ifdef HAVE_UNISTD_H
76*ebfedea0SLionel Sambuc #include <unistd.h>
77*ebfedea0SLionel Sambuc #endif
78*ebfedea0SLionel Sambuc 
79*ebfedea0SLionel Sambuc #include "types.h"
80*ebfedea0SLionel Sambuc #include "keyring.h"
81*ebfedea0SLionel Sambuc #include "packet-parse.h"
82*ebfedea0SLionel Sambuc #include "signature.h"
83*ebfedea0SLionel Sambuc #include "netpgpsdk.h"
84*ebfedea0SLionel Sambuc #include "readerwriter.h"
85*ebfedea0SLionel Sambuc #include "netpgpdefs.h"
86*ebfedea0SLionel Sambuc #include "packet.h"
87*ebfedea0SLionel Sambuc #include "crypto.h"
88*ebfedea0SLionel Sambuc #include "validate.h"
89*ebfedea0SLionel Sambuc #include "netpgpdefs.h"
90*ebfedea0SLionel Sambuc #include "netpgpdigest.h"
91*ebfedea0SLionel Sambuc 
92*ebfedea0SLionel Sambuc 
93*ebfedea0SLionel Sambuc 
94*ebfedea0SLionel Sambuc /**
95*ebfedea0SLionel Sambuc    \ingroup HighLevel_Keyring
96*ebfedea0SLionel Sambuc 
97*ebfedea0SLionel Sambuc    \brief Creates a new pgp_key_t struct
98*ebfedea0SLionel Sambuc 
99*ebfedea0SLionel Sambuc    \return A new pgp_key_t struct, initialised to zero.
100*ebfedea0SLionel Sambuc 
101*ebfedea0SLionel Sambuc    \note The returned pgp_key_t struct must be freed after use with pgp_keydata_free.
102*ebfedea0SLionel Sambuc */
103*ebfedea0SLionel Sambuc 
104*ebfedea0SLionel Sambuc pgp_key_t  *
pgp_keydata_new(void)105*ebfedea0SLionel Sambuc pgp_keydata_new(void)
106*ebfedea0SLionel Sambuc {
107*ebfedea0SLionel Sambuc 	return calloc(1, sizeof(pgp_key_t));
108*ebfedea0SLionel Sambuc }
109*ebfedea0SLionel Sambuc 
110*ebfedea0SLionel Sambuc 
111*ebfedea0SLionel Sambuc /**
112*ebfedea0SLionel Sambuc  \ingroup HighLevel_Keyring
113*ebfedea0SLionel Sambuc 
114*ebfedea0SLionel Sambuc  \brief Frees keydata and its memory
115*ebfedea0SLionel Sambuc 
116*ebfedea0SLionel Sambuc  \param keydata Key to be freed.
117*ebfedea0SLionel Sambuc 
118*ebfedea0SLionel Sambuc  \note This frees the keydata itself, as well as any other memory alloc-ed by it.
119*ebfedea0SLionel Sambuc */
120*ebfedea0SLionel Sambuc void
pgp_keydata_free(pgp_key_t * keydata)121*ebfedea0SLionel Sambuc pgp_keydata_free(pgp_key_t *keydata)
122*ebfedea0SLionel Sambuc {
123*ebfedea0SLionel Sambuc 	unsigned        n;
124*ebfedea0SLionel Sambuc 
125*ebfedea0SLionel Sambuc 	for (n = 0; n < keydata->uidc; ++n) {
126*ebfedea0SLionel Sambuc 		pgp_userid_free(&keydata->uids[n]);
127*ebfedea0SLionel Sambuc 	}
128*ebfedea0SLionel Sambuc 	free(keydata->uids);
129*ebfedea0SLionel Sambuc 	keydata->uids = NULL;
130*ebfedea0SLionel Sambuc 	keydata->uidc = 0;
131*ebfedea0SLionel Sambuc 
132*ebfedea0SLionel Sambuc 	for (n = 0; n < keydata->packetc; ++n) {
133*ebfedea0SLionel Sambuc 		pgp_subpacket_free(&keydata->packets[n]);
134*ebfedea0SLionel Sambuc 	}
135*ebfedea0SLionel Sambuc 	free(keydata->packets);
136*ebfedea0SLionel Sambuc 	keydata->packets = NULL;
137*ebfedea0SLionel Sambuc 	keydata->packetc = 0;
138*ebfedea0SLionel Sambuc 
139*ebfedea0SLionel Sambuc 	if (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) {
140*ebfedea0SLionel Sambuc 		pgp_pubkey_free(&keydata->key.pubkey);
141*ebfedea0SLionel Sambuc 	} else {
142*ebfedea0SLionel Sambuc 		pgp_seckey_free(&keydata->key.seckey);
143*ebfedea0SLionel Sambuc 	}
144*ebfedea0SLionel Sambuc 
145*ebfedea0SLionel Sambuc 	free(keydata);
146*ebfedea0SLionel Sambuc }
147*ebfedea0SLionel Sambuc 
148*ebfedea0SLionel Sambuc /**
149*ebfedea0SLionel Sambuc  \ingroup HighLevel_KeyGeneral
150*ebfedea0SLionel Sambuc 
151*ebfedea0SLionel Sambuc  \brief Returns the public key in the given keydata.
152*ebfedea0SLionel Sambuc  \param keydata
153*ebfedea0SLionel Sambuc 
154*ebfedea0SLionel Sambuc   \return Pointer to public key
155*ebfedea0SLionel Sambuc 
156*ebfedea0SLionel Sambuc   \note This is not a copy, do not free it after use.
157*ebfedea0SLionel Sambuc */
158*ebfedea0SLionel Sambuc 
159*ebfedea0SLionel Sambuc const pgp_pubkey_t *
pgp_get_pubkey(const pgp_key_t * keydata)160*ebfedea0SLionel Sambuc pgp_get_pubkey(const pgp_key_t *keydata)
161*ebfedea0SLionel Sambuc {
162*ebfedea0SLionel Sambuc 	return (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) ?
163*ebfedea0SLionel Sambuc 				&keydata->key.pubkey :
164*ebfedea0SLionel Sambuc 				&keydata->key.seckey.pubkey;
165*ebfedea0SLionel Sambuc }
166*ebfedea0SLionel Sambuc 
167*ebfedea0SLionel Sambuc /**
168*ebfedea0SLionel Sambuc \ingroup HighLevel_KeyGeneral
169*ebfedea0SLionel Sambuc 
170*ebfedea0SLionel Sambuc \brief Check whether this is a secret key or not.
171*ebfedea0SLionel Sambuc */
172*ebfedea0SLionel Sambuc 
173*ebfedea0SLionel Sambuc unsigned
pgp_is_key_secret(const pgp_key_t * data)174*ebfedea0SLionel Sambuc pgp_is_key_secret(const pgp_key_t *data)
175*ebfedea0SLionel Sambuc {
176*ebfedea0SLionel Sambuc 	return data->type != PGP_PTAG_CT_PUBLIC_KEY;
177*ebfedea0SLionel Sambuc }
178*ebfedea0SLionel Sambuc 
179*ebfedea0SLionel Sambuc /**
180*ebfedea0SLionel Sambuc  \ingroup HighLevel_KeyGeneral
181*ebfedea0SLionel Sambuc 
182*ebfedea0SLionel Sambuc  \brief Returns the secret key in the given keydata.
183*ebfedea0SLionel Sambuc 
184*ebfedea0SLionel Sambuc  \note This is not a copy, do not free it after use.
185*ebfedea0SLionel Sambuc 
186*ebfedea0SLionel Sambuc  \note This returns a const.  If you need to be able to write to this
187*ebfedea0SLionel Sambuc  pointer, use pgp_get_writable_seckey
188*ebfedea0SLionel Sambuc */
189*ebfedea0SLionel Sambuc 
190*ebfedea0SLionel Sambuc const pgp_seckey_t *
pgp_get_seckey(const pgp_key_t * data)191*ebfedea0SLionel Sambuc pgp_get_seckey(const pgp_key_t *data)
192*ebfedea0SLionel Sambuc {
193*ebfedea0SLionel Sambuc 	return (data->type == PGP_PTAG_CT_SECRET_KEY) ?
194*ebfedea0SLionel Sambuc 				&data->key.seckey : NULL;
195*ebfedea0SLionel Sambuc }
196*ebfedea0SLionel Sambuc 
197*ebfedea0SLionel Sambuc /**
198*ebfedea0SLionel Sambuc  \ingroup HighLevel_KeyGeneral
199*ebfedea0SLionel Sambuc 
200*ebfedea0SLionel Sambuc   \brief Returns the secret key in the given keydata.
201*ebfedea0SLionel Sambuc 
202*ebfedea0SLionel Sambuc   \note This is not a copy, do not free it after use.
203*ebfedea0SLionel Sambuc 
204*ebfedea0SLionel Sambuc   \note If you do not need to be able to modify this key, there is an
205*ebfedea0SLionel Sambuc   equivalent read-only function pgp_get_seckey.
206*ebfedea0SLionel Sambuc */
207*ebfedea0SLionel Sambuc 
208*ebfedea0SLionel Sambuc pgp_seckey_t *
pgp_get_writable_seckey(pgp_key_t * data)209*ebfedea0SLionel Sambuc pgp_get_writable_seckey(pgp_key_t *data)
210*ebfedea0SLionel Sambuc {
211*ebfedea0SLionel Sambuc 	return (data->type == PGP_PTAG_CT_SECRET_KEY) ?
212*ebfedea0SLionel Sambuc 				&data->key.seckey : NULL;
213*ebfedea0SLionel Sambuc }
214*ebfedea0SLionel Sambuc 
215*ebfedea0SLionel Sambuc /* utility function to zero out memory */
216*ebfedea0SLionel Sambuc void
pgp_forget(void * vp,unsigned size)217*ebfedea0SLionel Sambuc pgp_forget(void *vp, unsigned size)
218*ebfedea0SLionel Sambuc {
219*ebfedea0SLionel Sambuc 	(void) memset(vp, 0x0, size);
220*ebfedea0SLionel Sambuc }
221*ebfedea0SLionel Sambuc 
222*ebfedea0SLionel Sambuc typedef struct {
223*ebfedea0SLionel Sambuc 	FILE			*passfp;
224*ebfedea0SLionel Sambuc 	const pgp_key_t	*key;
225*ebfedea0SLionel Sambuc 	char			*passphrase;
226*ebfedea0SLionel Sambuc 	pgp_seckey_t		*seckey;
227*ebfedea0SLionel Sambuc } decrypt_t;
228*ebfedea0SLionel Sambuc 
229*ebfedea0SLionel Sambuc static pgp_cb_ret_t
decrypt_cb(const pgp_packet_t * pkt,pgp_cbdata_t * cbinfo)230*ebfedea0SLionel Sambuc decrypt_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
231*ebfedea0SLionel Sambuc {
232*ebfedea0SLionel Sambuc 	const pgp_contents_t	*content = &pkt->u;
233*ebfedea0SLionel Sambuc 	decrypt_t		*decrypt;
234*ebfedea0SLionel Sambuc 	char			 pass[MAX_PASSPHRASE_LENGTH];
235*ebfedea0SLionel Sambuc 
236*ebfedea0SLionel Sambuc 	decrypt = pgp_callback_arg(cbinfo);
237*ebfedea0SLionel Sambuc 	switch (pkt->tag) {
238*ebfedea0SLionel Sambuc 	case PGP_PARSER_PTAG:
239*ebfedea0SLionel Sambuc 	case PGP_PTAG_CT_USER_ID:
240*ebfedea0SLionel Sambuc 	case PGP_PTAG_CT_SIGNATURE:
241*ebfedea0SLionel Sambuc 	case PGP_PTAG_CT_SIGNATURE_HEADER:
242*ebfedea0SLionel Sambuc 	case PGP_PTAG_CT_SIGNATURE_FOOTER:
243*ebfedea0SLionel Sambuc 	case PGP_PTAG_CT_TRUST:
244*ebfedea0SLionel Sambuc 		break;
245*ebfedea0SLionel Sambuc 
246*ebfedea0SLionel Sambuc 	case PGP_GET_PASSPHRASE:
247*ebfedea0SLionel Sambuc 		(void) pgp_getpassphrase(decrypt->passfp, pass, sizeof(pass));
248*ebfedea0SLionel Sambuc 		*content->skey_passphrase.passphrase = netpgp_strdup(pass);
249*ebfedea0SLionel Sambuc 		pgp_forget(pass, (unsigned)sizeof(pass));
250*ebfedea0SLionel Sambuc 		return PGP_KEEP_MEMORY;
251*ebfedea0SLionel Sambuc 
252*ebfedea0SLionel Sambuc 	case PGP_PARSER_ERRCODE:
253*ebfedea0SLionel Sambuc 		switch (content->errcode.errcode) {
254*ebfedea0SLionel Sambuc 		case PGP_E_P_MPI_FORMAT_ERROR:
255*ebfedea0SLionel Sambuc 			/* Generally this means a bad passphrase */
256*ebfedea0SLionel Sambuc 			fprintf(stderr, "Bad passphrase!\n");
257*ebfedea0SLionel Sambuc 			return PGP_RELEASE_MEMORY;
258*ebfedea0SLionel Sambuc 
259*ebfedea0SLionel Sambuc 		case PGP_E_P_PACKET_CONSUMED:
260*ebfedea0SLionel Sambuc 			/* And this is because of an error we've accepted */
261*ebfedea0SLionel Sambuc 			return PGP_RELEASE_MEMORY;
262*ebfedea0SLionel Sambuc 		default:
263*ebfedea0SLionel Sambuc 			break;
264*ebfedea0SLionel Sambuc 		}
265*ebfedea0SLionel Sambuc 		(void) fprintf(stderr, "parse error: %s\n",
266*ebfedea0SLionel Sambuc 				pgp_errcode(content->errcode.errcode));
267*ebfedea0SLionel Sambuc 		return PGP_FINISHED;
268*ebfedea0SLionel Sambuc 
269*ebfedea0SLionel Sambuc 	case PGP_PARSER_ERROR:
270*ebfedea0SLionel Sambuc 		fprintf(stderr, "parse error: %s\n", content->error);
271*ebfedea0SLionel Sambuc 		return PGP_FINISHED;
272*ebfedea0SLionel Sambuc 
273*ebfedea0SLionel Sambuc 	case PGP_PTAG_CT_SECRET_KEY:
274*ebfedea0SLionel Sambuc 		if ((decrypt->seckey = calloc(1, sizeof(*decrypt->seckey))) == NULL) {
275*ebfedea0SLionel Sambuc 			(void) fprintf(stderr, "decrypt_cb: bad alloc\n");
276*ebfedea0SLionel Sambuc 			return PGP_FINISHED;
277*ebfedea0SLionel Sambuc 		}
278*ebfedea0SLionel Sambuc 		decrypt->seckey->checkhash = calloc(1, PGP_CHECKHASH_SIZE);
279*ebfedea0SLionel Sambuc 		*decrypt->seckey = content->seckey;
280*ebfedea0SLionel Sambuc 		return PGP_KEEP_MEMORY;
281*ebfedea0SLionel Sambuc 
282*ebfedea0SLionel Sambuc 	case PGP_PARSER_PACKET_END:
283*ebfedea0SLionel Sambuc 		/* nothing to do */
284*ebfedea0SLionel Sambuc 		break;
285*ebfedea0SLionel Sambuc 
286*ebfedea0SLionel Sambuc 	default:
287*ebfedea0SLionel Sambuc 		fprintf(stderr, "Unexpected tag %d (0x%x)\n", pkt->tag,
288*ebfedea0SLionel Sambuc 			pkt->tag);
289*ebfedea0SLionel Sambuc 		return PGP_FINISHED;
290*ebfedea0SLionel Sambuc 	}
291*ebfedea0SLionel Sambuc 
292*ebfedea0SLionel Sambuc 	return PGP_RELEASE_MEMORY;
293*ebfedea0SLionel Sambuc }
294*ebfedea0SLionel Sambuc 
295*ebfedea0SLionel Sambuc /**
296*ebfedea0SLionel Sambuc \ingroup Core_Keys
297*ebfedea0SLionel Sambuc \brief Decrypts secret key from given keydata with given passphrase
298*ebfedea0SLionel Sambuc \param key Key from which to get secret key
299*ebfedea0SLionel Sambuc \param passphrase Passphrase to use to decrypt secret key
300*ebfedea0SLionel Sambuc \return secret key
301*ebfedea0SLionel Sambuc */
302*ebfedea0SLionel Sambuc pgp_seckey_t *
pgp_decrypt_seckey(const pgp_key_t * key,void * passfp)303*ebfedea0SLionel Sambuc pgp_decrypt_seckey(const pgp_key_t *key, void *passfp)
304*ebfedea0SLionel Sambuc {
305*ebfedea0SLionel Sambuc 	pgp_stream_t	*stream;
306*ebfedea0SLionel Sambuc 	const int	 printerrors = 1;
307*ebfedea0SLionel Sambuc 	decrypt_t	 decrypt;
308*ebfedea0SLionel Sambuc 
309*ebfedea0SLionel Sambuc 	(void) memset(&decrypt, 0x0, sizeof(decrypt));
310*ebfedea0SLionel Sambuc 	decrypt.key = key;
311*ebfedea0SLionel Sambuc 	decrypt.passfp = passfp;
312*ebfedea0SLionel Sambuc 	stream = pgp_new(sizeof(*stream));
313*ebfedea0SLionel Sambuc 	pgp_keydata_reader_set(stream, key);
314*ebfedea0SLionel Sambuc 	pgp_set_callback(stream, decrypt_cb, &decrypt);
315*ebfedea0SLionel Sambuc 	stream->readinfo.accumulate = 1;
316*ebfedea0SLionel Sambuc 	pgp_parse(stream, !printerrors);
317*ebfedea0SLionel Sambuc 	return decrypt.seckey;
318*ebfedea0SLionel Sambuc }
319*ebfedea0SLionel Sambuc 
320*ebfedea0SLionel Sambuc /**
321*ebfedea0SLionel Sambuc \ingroup Core_Keys
322*ebfedea0SLionel Sambuc \brief Set secret key in content
323*ebfedea0SLionel Sambuc \param content Content to be set
324*ebfedea0SLionel Sambuc \param key Keydata to get secret key from
325*ebfedea0SLionel Sambuc */
326*ebfedea0SLionel Sambuc void
pgp_set_seckey(pgp_contents_t * cont,const pgp_key_t * key)327*ebfedea0SLionel Sambuc pgp_set_seckey(pgp_contents_t *cont, const pgp_key_t *key)
328*ebfedea0SLionel Sambuc {
329*ebfedea0SLionel Sambuc 	*cont->get_seckey.seckey = &key->key.seckey;
330*ebfedea0SLionel Sambuc }
331*ebfedea0SLionel Sambuc 
332*ebfedea0SLionel Sambuc /**
333*ebfedea0SLionel Sambuc \ingroup Core_Keys
334*ebfedea0SLionel Sambuc \brief Get Key ID from keydata
335*ebfedea0SLionel Sambuc \param key Keydata to get Key ID from
336*ebfedea0SLionel Sambuc \return Pointer to Key ID inside keydata
337*ebfedea0SLionel Sambuc */
338*ebfedea0SLionel Sambuc const uint8_t *
pgp_get_key_id(const pgp_key_t * key)339*ebfedea0SLionel Sambuc pgp_get_key_id(const pgp_key_t *key)
340*ebfedea0SLionel Sambuc {
341*ebfedea0SLionel Sambuc 	return key->sigid;
342*ebfedea0SLionel Sambuc }
343*ebfedea0SLionel Sambuc 
344*ebfedea0SLionel Sambuc /**
345*ebfedea0SLionel Sambuc \ingroup Core_Keys
346*ebfedea0SLionel Sambuc \brief How many User IDs in this key?
347*ebfedea0SLionel Sambuc \param key Keydata to check
348*ebfedea0SLionel Sambuc \return Num of user ids
349*ebfedea0SLionel Sambuc */
350*ebfedea0SLionel Sambuc unsigned
pgp_get_userid_count(const pgp_key_t * key)351*ebfedea0SLionel Sambuc pgp_get_userid_count(const pgp_key_t *key)
352*ebfedea0SLionel Sambuc {
353*ebfedea0SLionel Sambuc 	return key->uidc;
354*ebfedea0SLionel Sambuc }
355*ebfedea0SLionel Sambuc 
356*ebfedea0SLionel Sambuc /**
357*ebfedea0SLionel Sambuc \ingroup Core_Keys
358*ebfedea0SLionel Sambuc \brief Get indexed user id from key
359*ebfedea0SLionel Sambuc \param key Key to get user id from
360*ebfedea0SLionel Sambuc \param index Which key to get
361*ebfedea0SLionel Sambuc \return Pointer to requested user id
362*ebfedea0SLionel Sambuc */
363*ebfedea0SLionel Sambuc const uint8_t *
pgp_get_userid(const pgp_key_t * key,unsigned subscript)364*ebfedea0SLionel Sambuc pgp_get_userid(const pgp_key_t *key, unsigned subscript)
365*ebfedea0SLionel Sambuc {
366*ebfedea0SLionel Sambuc 	return key->uids[subscript];
367*ebfedea0SLionel Sambuc }
368*ebfedea0SLionel Sambuc 
369*ebfedea0SLionel Sambuc /**
370*ebfedea0SLionel Sambuc    \ingroup HighLevel_Supported
371*ebfedea0SLionel Sambuc    \brief Checks whether key's algorithm and type are supported by OpenPGP::SDK
372*ebfedea0SLionel Sambuc    \param keydata Key to be checked
373*ebfedea0SLionel Sambuc    \return 1 if key algorithm and type are supported by OpenPGP::SDK; 0 if not
374*ebfedea0SLionel Sambuc */
375*ebfedea0SLionel Sambuc 
376*ebfedea0SLionel Sambuc unsigned
pgp_is_key_supported(const pgp_key_t * key)377*ebfedea0SLionel Sambuc pgp_is_key_supported(const pgp_key_t *key)
378*ebfedea0SLionel Sambuc {
379*ebfedea0SLionel Sambuc 	if (key->type == PGP_PTAG_CT_PUBLIC_KEY) {
380*ebfedea0SLionel Sambuc 		switch(key->key.pubkey.alg) {
381*ebfedea0SLionel Sambuc 		case PGP_PKA_RSA:
382*ebfedea0SLionel Sambuc 		case PGP_PKA_DSA:
383*ebfedea0SLionel Sambuc 		case PGP_PKA_ELGAMAL:
384*ebfedea0SLionel Sambuc 			return 1;
385*ebfedea0SLionel Sambuc 		default:
386*ebfedea0SLionel Sambuc 			break;
387*ebfedea0SLionel Sambuc 		}
388*ebfedea0SLionel Sambuc 	}
389*ebfedea0SLionel Sambuc 	return 0;
390*ebfedea0SLionel Sambuc }
391*ebfedea0SLionel Sambuc 
392*ebfedea0SLionel Sambuc /* \todo check where userid pointers are copied */
393*ebfedea0SLionel Sambuc /**
394*ebfedea0SLionel Sambuc \ingroup Core_Keys
395*ebfedea0SLionel Sambuc \brief Copy user id, including contents
396*ebfedea0SLionel Sambuc \param dst Destination User ID
397*ebfedea0SLionel Sambuc \param src Source User ID
398*ebfedea0SLionel Sambuc \note If dst already has a userid, it will be freed.
399*ebfedea0SLionel Sambuc */
400*ebfedea0SLionel Sambuc static uint8_t *
copy_userid(uint8_t ** dst,const uint8_t * src)401*ebfedea0SLionel Sambuc copy_userid(uint8_t **dst, const uint8_t *src)
402*ebfedea0SLionel Sambuc {
403*ebfedea0SLionel Sambuc 	size_t          len;
404*ebfedea0SLionel Sambuc 
405*ebfedea0SLionel Sambuc 	len = strlen((const char *) src);
406*ebfedea0SLionel Sambuc 	if (*dst) {
407*ebfedea0SLionel Sambuc 		free(*dst);
408*ebfedea0SLionel Sambuc 	}
409*ebfedea0SLionel Sambuc 	if ((*dst = calloc(1, len + 1)) == NULL) {
410*ebfedea0SLionel Sambuc 		(void) fprintf(stderr, "copy_userid: bad alloc\n");
411*ebfedea0SLionel Sambuc 	} else {
412*ebfedea0SLionel Sambuc 		(void) memcpy(*dst, src, len);
413*ebfedea0SLionel Sambuc 	}
414*ebfedea0SLionel Sambuc 	return *dst;
415*ebfedea0SLionel Sambuc }
416*ebfedea0SLionel Sambuc 
417*ebfedea0SLionel Sambuc /* \todo check where pkt pointers are copied */
418*ebfedea0SLionel Sambuc /**
419*ebfedea0SLionel Sambuc \ingroup Core_Keys
420*ebfedea0SLionel Sambuc \brief Copy packet, including contents
421*ebfedea0SLionel Sambuc \param dst Destination packet
422*ebfedea0SLionel Sambuc \param src Source packet
423*ebfedea0SLionel Sambuc \note If dst already has a packet, it will be freed.
424*ebfedea0SLionel Sambuc */
425*ebfedea0SLionel Sambuc static pgp_subpacket_t *
copy_packet(pgp_subpacket_t * dst,const pgp_subpacket_t * src)426*ebfedea0SLionel Sambuc copy_packet(pgp_subpacket_t *dst, const pgp_subpacket_t *src)
427*ebfedea0SLionel Sambuc {
428*ebfedea0SLionel Sambuc 	if (dst->raw) {
429*ebfedea0SLionel Sambuc 		free(dst->raw);
430*ebfedea0SLionel Sambuc 	}
431*ebfedea0SLionel Sambuc 	if ((dst->raw = calloc(1, src->length)) == NULL) {
432*ebfedea0SLionel Sambuc 		(void) fprintf(stderr, "copy_packet: bad alloc\n");
433*ebfedea0SLionel Sambuc 	} else {
434*ebfedea0SLionel Sambuc 		dst->length = src->length;
435*ebfedea0SLionel Sambuc 		(void) memcpy(dst->raw, src->raw, src->length);
436*ebfedea0SLionel Sambuc 	}
437*ebfedea0SLionel Sambuc 	return dst;
438*ebfedea0SLionel Sambuc }
439*ebfedea0SLionel Sambuc 
440*ebfedea0SLionel Sambuc /**
441*ebfedea0SLionel Sambuc \ingroup Core_Keys
442*ebfedea0SLionel Sambuc \brief Add User ID to key
443*ebfedea0SLionel Sambuc \param key Key to which to add User ID
444*ebfedea0SLionel Sambuc \param userid User ID to add
445*ebfedea0SLionel Sambuc \return Pointer to new User ID
446*ebfedea0SLionel Sambuc */
447*ebfedea0SLionel Sambuc uint8_t  *
pgp_add_userid(pgp_key_t * key,const uint8_t * userid)448*ebfedea0SLionel Sambuc pgp_add_userid(pgp_key_t *key, const uint8_t *userid)
449*ebfedea0SLionel Sambuc {
450*ebfedea0SLionel Sambuc 	uint8_t  **uidp;
451*ebfedea0SLionel Sambuc 
452*ebfedea0SLionel Sambuc 	EXPAND_ARRAY(key, uid);
453*ebfedea0SLionel Sambuc 	/* initialise new entry in array */
454*ebfedea0SLionel Sambuc 	uidp = &key->uids[key->uidc++];
455*ebfedea0SLionel Sambuc 	*uidp = NULL;
456*ebfedea0SLionel Sambuc 	/* now copy it */
457*ebfedea0SLionel Sambuc 	return copy_userid(uidp, userid);
458*ebfedea0SLionel Sambuc }
459*ebfedea0SLionel Sambuc 
460*ebfedea0SLionel Sambuc void print_packet_hex(const pgp_subpacket_t *pkt);
461*ebfedea0SLionel Sambuc 
462*ebfedea0SLionel Sambuc /**
463*ebfedea0SLionel Sambuc \ingroup Core_Keys
464*ebfedea0SLionel Sambuc \brief Add packet to key
465*ebfedea0SLionel Sambuc \param keydata Key to which to add packet
466*ebfedea0SLionel Sambuc \param packet Packet to add
467*ebfedea0SLionel Sambuc \return Pointer to new packet
468*ebfedea0SLionel Sambuc */
469*ebfedea0SLionel Sambuc pgp_subpacket_t   *
pgp_add_subpacket(pgp_key_t * keydata,const pgp_subpacket_t * packet)470*ebfedea0SLionel Sambuc pgp_add_subpacket(pgp_key_t *keydata, const pgp_subpacket_t *packet)
471*ebfedea0SLionel Sambuc {
472*ebfedea0SLionel Sambuc 	pgp_subpacket_t   *subpktp;
473*ebfedea0SLionel Sambuc 
474*ebfedea0SLionel Sambuc 	EXPAND_ARRAY(keydata, packet);
475*ebfedea0SLionel Sambuc 	/* initialise new entry in array */
476*ebfedea0SLionel Sambuc 	subpktp = &keydata->packets[keydata->packetc++];
477*ebfedea0SLionel Sambuc 	subpktp->length = 0;
478*ebfedea0SLionel Sambuc 	subpktp->raw = NULL;
479*ebfedea0SLionel Sambuc 	/* now copy it */
480*ebfedea0SLionel Sambuc 	return copy_packet(subpktp, packet);
481*ebfedea0SLionel Sambuc }
482*ebfedea0SLionel Sambuc 
483*ebfedea0SLionel Sambuc /**
484*ebfedea0SLionel Sambuc \ingroup Core_Keys
485*ebfedea0SLionel Sambuc \brief Add selfsigned User ID to key
486*ebfedea0SLionel Sambuc \param keydata Key to which to add user ID
487*ebfedea0SLionel Sambuc \param userid Self-signed User ID to add
488*ebfedea0SLionel Sambuc \return 1 if OK; else 0
489*ebfedea0SLionel Sambuc */
490*ebfedea0SLionel Sambuc unsigned
pgp_add_selfsigned_userid(pgp_key_t * key,uint8_t * userid)491*ebfedea0SLionel Sambuc pgp_add_selfsigned_userid(pgp_key_t *key, uint8_t *userid)
492*ebfedea0SLionel Sambuc {
493*ebfedea0SLionel Sambuc 	pgp_create_sig_t	*sig;
494*ebfedea0SLionel Sambuc 	pgp_subpacket_t	 sigpacket;
495*ebfedea0SLionel Sambuc 	pgp_memory_t		*mem_userid = NULL;
496*ebfedea0SLionel Sambuc 	pgp_output_t		*useridoutput = NULL;
497*ebfedea0SLionel Sambuc 	pgp_memory_t		*mem_sig = NULL;
498*ebfedea0SLionel Sambuc 	pgp_output_t		*sigoutput = NULL;
499*ebfedea0SLionel Sambuc 
500*ebfedea0SLionel Sambuc 	/*
501*ebfedea0SLionel Sambuc          * create signature packet for this userid
502*ebfedea0SLionel Sambuc          */
503*ebfedea0SLionel Sambuc 
504*ebfedea0SLionel Sambuc 	/* create userid pkt */
505*ebfedea0SLionel Sambuc 	pgp_setup_memory_write(&useridoutput, &mem_userid, 128);
506*ebfedea0SLionel Sambuc 	pgp_write_struct_userid(useridoutput, userid);
507*ebfedea0SLionel Sambuc 
508*ebfedea0SLionel Sambuc 	/* create sig for this pkt */
509*ebfedea0SLionel Sambuc 	sig = pgp_create_sig_new();
510*ebfedea0SLionel Sambuc 	pgp_sig_start_key_sig(sig, &key->key.seckey.pubkey, userid, PGP_CERT_POSITIVE);
511*ebfedea0SLionel Sambuc 	pgp_add_time(sig, (int64_t)time(NULL), "birth");
512*ebfedea0SLionel Sambuc 	pgp_add_issuer_keyid(sig, key->sigid);
513*ebfedea0SLionel Sambuc 	pgp_add_primary_userid(sig, 1);
514*ebfedea0SLionel Sambuc 	pgp_end_hashed_subpkts(sig);
515*ebfedea0SLionel Sambuc 
516*ebfedea0SLionel Sambuc 	pgp_setup_memory_write(&sigoutput, &mem_sig, 128);
517*ebfedea0SLionel Sambuc 	pgp_write_sig(sigoutput, sig, &key->key.seckey.pubkey, &key->key.seckey);
518*ebfedea0SLionel Sambuc 
519*ebfedea0SLionel Sambuc 	/* add this packet to key */
520*ebfedea0SLionel Sambuc 	sigpacket.length = pgp_mem_len(mem_sig);
521*ebfedea0SLionel Sambuc 	sigpacket.raw = pgp_mem_data(mem_sig);
522*ebfedea0SLionel Sambuc 
523*ebfedea0SLionel Sambuc 	/* add userid to key */
524*ebfedea0SLionel Sambuc 	(void) pgp_add_userid(key, userid);
525*ebfedea0SLionel Sambuc 	(void) pgp_add_subpacket(key, &sigpacket);
526*ebfedea0SLionel Sambuc 
527*ebfedea0SLionel Sambuc 	/* cleanup */
528*ebfedea0SLionel Sambuc 	pgp_create_sig_delete(sig);
529*ebfedea0SLionel Sambuc 	pgp_output_delete(useridoutput);
530*ebfedea0SLionel Sambuc 	pgp_output_delete(sigoutput);
531*ebfedea0SLionel Sambuc 	pgp_memory_free(mem_userid);
532*ebfedea0SLionel Sambuc 	pgp_memory_free(mem_sig);
533*ebfedea0SLionel Sambuc 
534*ebfedea0SLionel Sambuc 	return 1;
535*ebfedea0SLionel Sambuc }
536*ebfedea0SLionel Sambuc 
537*ebfedea0SLionel Sambuc /**
538*ebfedea0SLionel Sambuc \ingroup Core_Keys
539*ebfedea0SLionel Sambuc \brief Initialise pgp_key_t
540*ebfedea0SLionel Sambuc \param keydata Keydata to initialise
541*ebfedea0SLionel Sambuc \param type PGP_PTAG_CT_PUBLIC_KEY or PGP_PTAG_CT_SECRET_KEY
542*ebfedea0SLionel Sambuc */
543*ebfedea0SLionel Sambuc void
pgp_keydata_init(pgp_key_t * keydata,const pgp_content_enum type)544*ebfedea0SLionel Sambuc pgp_keydata_init(pgp_key_t *keydata, const pgp_content_enum type)
545*ebfedea0SLionel Sambuc {
546*ebfedea0SLionel Sambuc 	if (keydata->type != PGP_PTAG_CT_RESERVED) {
547*ebfedea0SLionel Sambuc 		(void) fprintf(stderr,
548*ebfedea0SLionel Sambuc 			"pgp_keydata_init: wrong keydata type\n");
549*ebfedea0SLionel Sambuc 	} else if (type != PGP_PTAG_CT_PUBLIC_KEY &&
550*ebfedea0SLionel Sambuc 		   type != PGP_PTAG_CT_SECRET_KEY) {
551*ebfedea0SLionel Sambuc 		(void) fprintf(stderr, "pgp_keydata_init: wrong type\n");
552*ebfedea0SLionel Sambuc 	} else {
553*ebfedea0SLionel Sambuc 		keydata->type = type;
554*ebfedea0SLionel Sambuc 	}
555*ebfedea0SLionel Sambuc }
556*ebfedea0SLionel Sambuc 
557*ebfedea0SLionel Sambuc /* used to point to data during keyring read */
558*ebfedea0SLionel Sambuc typedef struct keyringcb_t {
559*ebfedea0SLionel Sambuc 	pgp_keyring_t		*keyring;	/* the keyring we're reading */
560*ebfedea0SLionel Sambuc } keyringcb_t;
561*ebfedea0SLionel Sambuc 
562*ebfedea0SLionel Sambuc 
563*ebfedea0SLionel Sambuc static pgp_cb_ret_t
cb_keyring_read(const pgp_packet_t * pkt,pgp_cbdata_t * cbinfo)564*ebfedea0SLionel Sambuc cb_keyring_read(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
565*ebfedea0SLionel Sambuc {
566*ebfedea0SLionel Sambuc 	pgp_keyring_t	*keyring;
567*ebfedea0SLionel Sambuc 	pgp_revoke_t	*revocation;
568*ebfedea0SLionel Sambuc 	pgp_key_t	*key;
569*ebfedea0SLionel Sambuc 	keyringcb_t	*cb;
570*ebfedea0SLionel Sambuc 
571*ebfedea0SLionel Sambuc 	cb = pgp_callback_arg(cbinfo);
572*ebfedea0SLionel Sambuc 	keyring = cb->keyring;
573*ebfedea0SLionel Sambuc 	switch (pkt->tag) {
574*ebfedea0SLionel Sambuc 	case PGP_PARSER_PTAG:
575*ebfedea0SLionel Sambuc 	case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
576*ebfedea0SLionel Sambuc 		/* we get these because we didn't prompt */
577*ebfedea0SLionel Sambuc 		break;
578*ebfedea0SLionel Sambuc 	case PGP_PTAG_CT_SIGNATURE_HEADER:
579*ebfedea0SLionel Sambuc 		key = &keyring->keys[keyring->keyc - 1];
580*ebfedea0SLionel Sambuc 		EXPAND_ARRAY(key, subsig);
581*ebfedea0SLionel Sambuc 		key->subsigs[key->subsigc].uid = key->uidc - 1;
582*ebfedea0SLionel Sambuc 		(void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig,
583*ebfedea0SLionel Sambuc 				sizeof(pkt->u.sig));
584*ebfedea0SLionel Sambuc 		key->subsigc += 1;
585*ebfedea0SLionel Sambuc 		break;
586*ebfedea0SLionel Sambuc 	case PGP_PTAG_CT_SIGNATURE:
587*ebfedea0SLionel Sambuc 		key = &keyring->keys[keyring->keyc - 1];
588*ebfedea0SLionel Sambuc 		EXPAND_ARRAY(key, subsig);
589*ebfedea0SLionel Sambuc 		key->subsigs[key->subsigc].uid = key->uidc - 1;
590*ebfedea0SLionel Sambuc 		(void) memcpy(&key->subsigs[key->subsigc].sig, &pkt->u.sig,
591*ebfedea0SLionel Sambuc 				sizeof(pkt->u.sig));
592*ebfedea0SLionel Sambuc 		key->subsigc += 1;
593*ebfedea0SLionel Sambuc 		break;
594*ebfedea0SLionel Sambuc 	case PGP_PTAG_CT_TRUST:
595*ebfedea0SLionel Sambuc 		key = &keyring->keys[keyring->keyc - 1];
596*ebfedea0SLionel Sambuc 		key->subsigs[key->subsigc - 1].trustlevel = pkt->u.ss_trust.level;
597*ebfedea0SLionel Sambuc 		key->subsigs[key->subsigc - 1].trustamount = pkt->u.ss_trust.amount;
598*ebfedea0SLionel Sambuc 		break;
599*ebfedea0SLionel Sambuc 	case PGP_PTAG_SS_KEY_EXPIRY:
600*ebfedea0SLionel Sambuc 		EXPAND_ARRAY(keyring, key);
601*ebfedea0SLionel Sambuc 		if (keyring->keyc > 0) {
602*ebfedea0SLionel Sambuc 			keyring->keys[keyring->keyc - 1].key.pubkey.duration = pkt->u.ss_time;
603*ebfedea0SLionel Sambuc 		}
604*ebfedea0SLionel Sambuc 		break;
605*ebfedea0SLionel Sambuc 	case PGP_PTAG_SS_ISSUER_KEY_ID:
606*ebfedea0SLionel Sambuc 		key = &keyring->keys[keyring->keyc - 1];
607*ebfedea0SLionel Sambuc 		(void) memcpy(&key->subsigs[key->subsigc - 1].sig.info.signer_id,
608*ebfedea0SLionel Sambuc 			      pkt->u.ss_issuer,
609*ebfedea0SLionel Sambuc 			      sizeof(pkt->u.ss_issuer));
610*ebfedea0SLionel Sambuc 		key->subsigs[key->subsigc - 1].sig.info.signer_id_set = 1;
611*ebfedea0SLionel Sambuc 		break;
612*ebfedea0SLionel Sambuc 	case PGP_PTAG_SS_CREATION_TIME:
613*ebfedea0SLionel Sambuc 		key = &keyring->keys[keyring->keyc - 1];
614*ebfedea0SLionel Sambuc 		key->subsigs[key->subsigc - 1].sig.info.birthtime = pkt->u.ss_time;
615*ebfedea0SLionel Sambuc 		key->subsigs[key->subsigc - 1].sig.info.birthtime_set = 1;
616*ebfedea0SLionel Sambuc 		break;
617*ebfedea0SLionel Sambuc 	case PGP_PTAG_SS_EXPIRATION_TIME:
618*ebfedea0SLionel Sambuc 		key = &keyring->keys[keyring->keyc - 1];
619*ebfedea0SLionel Sambuc 		key->subsigs[key->subsigc - 1].sig.info.duration = pkt->u.ss_time;
620*ebfedea0SLionel Sambuc 		key->subsigs[key->subsigc - 1].sig.info.duration_set = 1;
621*ebfedea0SLionel Sambuc 		break;
622*ebfedea0SLionel Sambuc 	case PGP_PTAG_SS_PRIMARY_USER_ID:
623*ebfedea0SLionel Sambuc 		key = &keyring->keys[keyring->keyc - 1];
624*ebfedea0SLionel Sambuc 		key->uid0 = key->uidc - 1;
625*ebfedea0SLionel Sambuc 		break;
626*ebfedea0SLionel Sambuc 	case PGP_PTAG_SS_REVOCATION_REASON:
627*ebfedea0SLionel Sambuc 		key = &keyring->keys[keyring->keyc - 1];
628*ebfedea0SLionel Sambuc 		if (key->uidc == 0) {
629*ebfedea0SLionel Sambuc 			/* revoke whole key */
630*ebfedea0SLionel Sambuc 			key->revoked = 1;
631*ebfedea0SLionel Sambuc 			revocation = &key->revocation;
632*ebfedea0SLionel Sambuc 		} else {
633*ebfedea0SLionel Sambuc 			/* revoke the user id */
634*ebfedea0SLionel Sambuc 			EXPAND_ARRAY(key, revoke);
635*ebfedea0SLionel Sambuc 			revocation = &key->revokes[key->revokec];
636*ebfedea0SLionel Sambuc 			key->revokes[key->revokec].uid = key->uidc - 1;
637*ebfedea0SLionel Sambuc 			key->revokec += 1;
638*ebfedea0SLionel Sambuc 		}
639*ebfedea0SLionel Sambuc 		revocation->code = pkt->u.ss_revocation.code;
640*ebfedea0SLionel Sambuc 		revocation->reason = netpgp_strdup(pgp_show_ss_rr_code(pkt->u.ss_revocation.code));
641*ebfedea0SLionel Sambuc 		break;
642*ebfedea0SLionel Sambuc 	case PGP_PTAG_CT_SIGNATURE_FOOTER:
643*ebfedea0SLionel Sambuc 	case PGP_PARSER_ERRCODE:
644*ebfedea0SLionel Sambuc 		break;
645*ebfedea0SLionel Sambuc 
646*ebfedea0SLionel Sambuc 	default:
647*ebfedea0SLionel Sambuc 		break;
648*ebfedea0SLionel Sambuc 	}
649*ebfedea0SLionel Sambuc 
650*ebfedea0SLionel Sambuc 	return PGP_RELEASE_MEMORY;
651*ebfedea0SLionel Sambuc }
652*ebfedea0SLionel Sambuc 
653*ebfedea0SLionel Sambuc /**
654*ebfedea0SLionel Sambuc    \ingroup HighLevel_KeyringRead
655*ebfedea0SLionel Sambuc 
656*ebfedea0SLionel Sambuc    \brief Reads a keyring from a file
657*ebfedea0SLionel Sambuc 
658*ebfedea0SLionel Sambuc    \param keyring Pointer to an existing pgp_keyring_t struct
659*ebfedea0SLionel Sambuc    \param armour 1 if file is armoured; else 0
660*ebfedea0SLionel Sambuc    \param filename Filename of keyring to be read
661*ebfedea0SLionel Sambuc 
662*ebfedea0SLionel Sambuc    \return pgp 1 if OK; 0 on error
663*ebfedea0SLionel Sambuc 
664*ebfedea0SLionel Sambuc    \note Keyring struct must already exist.
665*ebfedea0SLionel Sambuc 
666*ebfedea0SLionel Sambuc    \note Can be used with either a public or secret keyring.
667*ebfedea0SLionel Sambuc 
668*ebfedea0SLionel Sambuc    \note You must call pgp_keyring_free() after usage to free alloc-ed memory.
669*ebfedea0SLionel Sambuc 
670*ebfedea0SLionel Sambuc    \note If you call this twice on the same keyring struct, without calling
671*ebfedea0SLionel Sambuc    pgp_keyring_free() between these calls, you will introduce a memory leak.
672*ebfedea0SLionel Sambuc 
673*ebfedea0SLionel Sambuc    \sa pgp_keyring_read_from_mem()
674*ebfedea0SLionel Sambuc    \sa pgp_keyring_free()
675*ebfedea0SLionel Sambuc 
676*ebfedea0SLionel Sambuc */
677*ebfedea0SLionel Sambuc 
678*ebfedea0SLionel Sambuc unsigned
pgp_keyring_fileread(pgp_keyring_t * keyring,const unsigned armour,const char * filename)679*ebfedea0SLionel Sambuc pgp_keyring_fileread(pgp_keyring_t *keyring,
680*ebfedea0SLionel Sambuc 			const unsigned armour,
681*ebfedea0SLionel Sambuc 			const char *filename)
682*ebfedea0SLionel Sambuc {
683*ebfedea0SLionel Sambuc 	pgp_stream_t	*stream;
684*ebfedea0SLionel Sambuc 	keyringcb_t	 cb;
685*ebfedea0SLionel Sambuc 	unsigned	 res = 1;
686*ebfedea0SLionel Sambuc 	int		 fd;
687*ebfedea0SLionel Sambuc 
688*ebfedea0SLionel Sambuc 	(void) memset(&cb, 0x0, sizeof(cb));
689*ebfedea0SLionel Sambuc 	cb.keyring = keyring;
690*ebfedea0SLionel Sambuc 	stream = pgp_new(sizeof(*stream));
691*ebfedea0SLionel Sambuc 
692*ebfedea0SLionel Sambuc 	/* add this for the moment, */
693*ebfedea0SLionel Sambuc 	/*
694*ebfedea0SLionel Sambuc 	 * \todo need to fix the problems with reading signature subpackets
695*ebfedea0SLionel Sambuc 	 * later
696*ebfedea0SLionel Sambuc 	 */
697*ebfedea0SLionel Sambuc 
698*ebfedea0SLionel Sambuc 	/* pgp_parse_options(parse,PGP_PTAG_SS_ALL,PGP_PARSE_RAW); */
699*ebfedea0SLionel Sambuc 	pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
700*ebfedea0SLionel Sambuc 
701*ebfedea0SLionel Sambuc #ifdef O_BINARY
702*ebfedea0SLionel Sambuc 	fd = open(filename, O_RDONLY | O_BINARY);
703*ebfedea0SLionel Sambuc #else
704*ebfedea0SLionel Sambuc 	fd = open(filename, O_RDONLY);
705*ebfedea0SLionel Sambuc #endif
706*ebfedea0SLionel Sambuc 	if (fd < 0) {
707*ebfedea0SLionel Sambuc 		pgp_stream_delete(stream);
708*ebfedea0SLionel Sambuc 		perror(filename);
709*ebfedea0SLionel Sambuc 		return 0;
710*ebfedea0SLionel Sambuc 	}
711*ebfedea0SLionel Sambuc #ifdef USE_MMAP_FOR_FILES
712*ebfedea0SLionel Sambuc 	pgp_reader_set_mmap(stream, fd);
713*ebfedea0SLionel Sambuc #else
714*ebfedea0SLionel Sambuc 	pgp_reader_set_fd(stream, fd);
715*ebfedea0SLionel Sambuc #endif
716*ebfedea0SLionel Sambuc 
717*ebfedea0SLionel Sambuc 	pgp_set_callback(stream, cb_keyring_read, &cb);
718*ebfedea0SLionel Sambuc 
719*ebfedea0SLionel Sambuc 	if (armour) {
720*ebfedea0SLionel Sambuc 		pgp_reader_push_dearmour(stream);
721*ebfedea0SLionel Sambuc 	}
722*ebfedea0SLionel Sambuc 	res = pgp_parse_and_accumulate(keyring, stream);
723*ebfedea0SLionel Sambuc 	pgp_print_errors(pgp_stream_get_errors(stream));
724*ebfedea0SLionel Sambuc 
725*ebfedea0SLionel Sambuc 	if (armour) {
726*ebfedea0SLionel Sambuc 		pgp_reader_pop_dearmour(stream);
727*ebfedea0SLionel Sambuc 	}
728*ebfedea0SLionel Sambuc 
729*ebfedea0SLionel Sambuc 	(void)close(fd);
730*ebfedea0SLionel Sambuc 
731*ebfedea0SLionel Sambuc 	pgp_stream_delete(stream);
732*ebfedea0SLionel Sambuc 
733*ebfedea0SLionel Sambuc 	return res;
734*ebfedea0SLionel Sambuc }
735*ebfedea0SLionel Sambuc 
736*ebfedea0SLionel Sambuc /**
737*ebfedea0SLionel Sambuc    \ingroup HighLevel_KeyringRead
738*ebfedea0SLionel Sambuc 
739*ebfedea0SLionel Sambuc    \brief Reads a keyring from memory
740*ebfedea0SLionel Sambuc 
741*ebfedea0SLionel Sambuc    \param keyring Pointer to existing pgp_keyring_t struct
742*ebfedea0SLionel Sambuc    \param armour 1 if file is armoured; else 0
743*ebfedea0SLionel Sambuc    \param mem Pointer to a pgp_memory_t struct containing keyring to be read
744*ebfedea0SLionel Sambuc 
745*ebfedea0SLionel Sambuc    \return pgp 1 if OK; 0 on error
746*ebfedea0SLionel Sambuc 
747*ebfedea0SLionel Sambuc    \note Keyring struct must already exist.
748*ebfedea0SLionel Sambuc 
749*ebfedea0SLionel Sambuc    \note Can be used with either a public or secret keyring.
750*ebfedea0SLionel Sambuc 
751*ebfedea0SLionel Sambuc    \note You must call pgp_keyring_free() after usage to free alloc-ed memory.
752*ebfedea0SLionel Sambuc 
753*ebfedea0SLionel Sambuc    \note If you call this twice on the same keyring struct, without calling
754*ebfedea0SLionel Sambuc    pgp_keyring_free() between these calls, you will introduce a memory leak.
755*ebfedea0SLionel Sambuc 
756*ebfedea0SLionel Sambuc    \sa pgp_keyring_fileread
757*ebfedea0SLionel Sambuc    \sa pgp_keyring_free
758*ebfedea0SLionel Sambuc */
759*ebfedea0SLionel Sambuc unsigned
pgp_keyring_read_from_mem(pgp_io_t * io,pgp_keyring_t * keyring,const unsigned armour,pgp_memory_t * mem)760*ebfedea0SLionel Sambuc pgp_keyring_read_from_mem(pgp_io_t *io,
761*ebfedea0SLionel Sambuc 				pgp_keyring_t *keyring,
762*ebfedea0SLionel Sambuc 				const unsigned armour,
763*ebfedea0SLionel Sambuc 				pgp_memory_t *mem)
764*ebfedea0SLionel Sambuc {
765*ebfedea0SLionel Sambuc 	pgp_stream_t	*stream;
766*ebfedea0SLionel Sambuc 	const unsigned	 noaccum = 0;
767*ebfedea0SLionel Sambuc 	keyringcb_t	 cb;
768*ebfedea0SLionel Sambuc 	unsigned	 res;
769*ebfedea0SLionel Sambuc 
770*ebfedea0SLionel Sambuc 	(void) memset(&cb, 0x0, sizeof(cb));
771*ebfedea0SLionel Sambuc 	cb.keyring = keyring;
772*ebfedea0SLionel Sambuc 	stream = pgp_new(sizeof(*stream));
773*ebfedea0SLionel Sambuc 	pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
774*ebfedea0SLionel Sambuc 	pgp_setup_memory_read(io, &stream, mem, &cb, cb_keyring_read,
775*ebfedea0SLionel Sambuc 					noaccum);
776*ebfedea0SLionel Sambuc 	if (armour) {
777*ebfedea0SLionel Sambuc 		pgp_reader_push_dearmour(stream);
778*ebfedea0SLionel Sambuc 	}
779*ebfedea0SLionel Sambuc 	res = (unsigned)pgp_parse_and_accumulate(keyring, stream);
780*ebfedea0SLionel Sambuc 	pgp_print_errors(pgp_stream_get_errors(stream));
781*ebfedea0SLionel Sambuc 	if (armour) {
782*ebfedea0SLionel Sambuc 		pgp_reader_pop_dearmour(stream);
783*ebfedea0SLionel Sambuc 	}
784*ebfedea0SLionel Sambuc 	/* don't call teardown_memory_read because memory was passed in */
785*ebfedea0SLionel Sambuc 	pgp_stream_delete(stream);
786*ebfedea0SLionel Sambuc 	return res;
787*ebfedea0SLionel Sambuc }
788*ebfedea0SLionel Sambuc 
789*ebfedea0SLionel Sambuc /**
790*ebfedea0SLionel Sambuc    \ingroup HighLevel_KeyringRead
791*ebfedea0SLionel Sambuc 
792*ebfedea0SLionel Sambuc    \brief Frees keyring's contents (but not keyring itself)
793*ebfedea0SLionel Sambuc 
794*ebfedea0SLionel Sambuc    \param keyring Keyring whose data is to be freed
795*ebfedea0SLionel Sambuc 
796*ebfedea0SLionel Sambuc    \note This does not free keyring itself, just the memory alloc-ed in it.
797*ebfedea0SLionel Sambuc  */
798*ebfedea0SLionel Sambuc void
pgp_keyring_free(pgp_keyring_t * keyring)799*ebfedea0SLionel Sambuc pgp_keyring_free(pgp_keyring_t *keyring)
800*ebfedea0SLionel Sambuc {
801*ebfedea0SLionel Sambuc 	(void)free(keyring->keys);
802*ebfedea0SLionel Sambuc 	keyring->keys = NULL;
803*ebfedea0SLionel Sambuc 	keyring->keyc = keyring->keyvsize = 0;
804*ebfedea0SLionel Sambuc }
805*ebfedea0SLionel Sambuc 
806*ebfedea0SLionel Sambuc /**
807*ebfedea0SLionel Sambuc    \ingroup HighLevel_KeyringFind
808*ebfedea0SLionel Sambuc 
809*ebfedea0SLionel Sambuc    \brief Finds key in keyring from its Key ID
810*ebfedea0SLionel Sambuc 
811*ebfedea0SLionel Sambuc    \param keyring Keyring to be searched
812*ebfedea0SLionel Sambuc    \param keyid ID of required key
813*ebfedea0SLionel Sambuc 
814*ebfedea0SLionel Sambuc    \return Pointer to key, if found; NULL, if not found
815*ebfedea0SLionel Sambuc 
816*ebfedea0SLionel Sambuc    \note This returns a pointer to the key inside the given keyring,
817*ebfedea0SLionel Sambuc    not a copy.  Do not free it after use.
818*ebfedea0SLionel Sambuc 
819*ebfedea0SLionel Sambuc */
820*ebfedea0SLionel Sambuc const pgp_key_t *
pgp_getkeybyid(pgp_io_t * io,const pgp_keyring_t * keyring,const uint8_t * keyid,unsigned * from,pgp_pubkey_t ** pubkey)821*ebfedea0SLionel Sambuc pgp_getkeybyid(pgp_io_t *io, const pgp_keyring_t *keyring,
822*ebfedea0SLionel Sambuc 			   const uint8_t *keyid, unsigned *from, pgp_pubkey_t **pubkey)
823*ebfedea0SLionel Sambuc {
824*ebfedea0SLionel Sambuc 	uint8_t	nullid[PGP_KEY_ID_SIZE];
825*ebfedea0SLionel Sambuc 
826*ebfedea0SLionel Sambuc 	(void) memset(nullid, 0x0, sizeof(nullid));
827*ebfedea0SLionel Sambuc 	for ( ; keyring && *from < keyring->keyc; *from += 1) {
828*ebfedea0SLionel Sambuc 		if (pgp_get_debug_level(__FILE__)) {
829*ebfedea0SLionel Sambuc 			hexdump(io->errs, "keyring keyid", keyring->keys[*from].sigid, PGP_KEY_ID_SIZE);
830*ebfedea0SLionel Sambuc 			hexdump(io->errs, "keyid", keyid, PGP_KEY_ID_SIZE);
831*ebfedea0SLionel Sambuc 		}
832*ebfedea0SLionel Sambuc 		if (memcmp(keyring->keys[*from].sigid, keyid, PGP_KEY_ID_SIZE) == 0 ||
833*ebfedea0SLionel Sambuc 		    memcmp(&keyring->keys[*from].sigid[PGP_KEY_ID_SIZE / 2],
834*ebfedea0SLionel Sambuc 				keyid, PGP_KEY_ID_SIZE / 2) == 0) {
835*ebfedea0SLionel Sambuc 			if (pubkey) {
836*ebfedea0SLionel Sambuc 				*pubkey = &keyring->keys[*from].key.pubkey;
837*ebfedea0SLionel Sambuc 			}
838*ebfedea0SLionel Sambuc 			return &keyring->keys[*from];
839*ebfedea0SLionel Sambuc 		}
840*ebfedea0SLionel Sambuc 		if (memcmp(&keyring->keys[*from].encid, nullid, sizeof(nullid)) == 0) {
841*ebfedea0SLionel Sambuc 			continue;
842*ebfedea0SLionel Sambuc 		}
843*ebfedea0SLionel Sambuc 		if (memcmp(&keyring->keys[*from].encid, keyid, PGP_KEY_ID_SIZE) == 0 ||
844*ebfedea0SLionel Sambuc 		    memcmp(&keyring->keys[*from].encid[PGP_KEY_ID_SIZE / 2], keyid, PGP_KEY_ID_SIZE / 2) == 0) {
845*ebfedea0SLionel Sambuc 			if (pubkey) {
846*ebfedea0SLionel Sambuc 				*pubkey = &keyring->keys[*from].enckey;
847*ebfedea0SLionel Sambuc 			}
848*ebfedea0SLionel Sambuc 			return &keyring->keys[*from];
849*ebfedea0SLionel Sambuc 		}
850*ebfedea0SLionel Sambuc 	}
851*ebfedea0SLionel Sambuc 	return NULL;
852*ebfedea0SLionel Sambuc }
853*ebfedea0SLionel Sambuc 
854*ebfedea0SLionel Sambuc /* convert a string keyid into a binary keyid */
855*ebfedea0SLionel Sambuc static void
str2keyid(const char * userid,uint8_t * keyid,size_t len)856*ebfedea0SLionel Sambuc str2keyid(const char *userid, uint8_t *keyid, size_t len)
857*ebfedea0SLionel Sambuc {
858*ebfedea0SLionel Sambuc 	static const char	*uppers = "0123456789ABCDEF";
859*ebfedea0SLionel Sambuc 	static const char	*lowers = "0123456789abcdef";
860*ebfedea0SLionel Sambuc 	const char		*hi;
861*ebfedea0SLionel Sambuc 	const char		*lo;
862*ebfedea0SLionel Sambuc 	uint8_t			 hichar;
863*ebfedea0SLionel Sambuc 	uint8_t			 lochar;
864*ebfedea0SLionel Sambuc 	size_t			 j;
865*ebfedea0SLionel Sambuc 	int			 i;
866*ebfedea0SLionel Sambuc 
867*ebfedea0SLionel Sambuc 	for (i = 0, j = 0 ; j < len && userid[i] && userid[i + 1] ; i += 2, j++) {
868*ebfedea0SLionel Sambuc 		if ((hi = strchr(uppers, userid[i])) == NULL) {
869*ebfedea0SLionel Sambuc 			if ((hi = strchr(lowers, userid[i])) == NULL) {
870*ebfedea0SLionel Sambuc 				break;
871*ebfedea0SLionel Sambuc 			}
872*ebfedea0SLionel Sambuc 			hichar = (uint8_t)(hi - lowers);
873*ebfedea0SLionel Sambuc 		} else {
874*ebfedea0SLionel Sambuc 			hichar = (uint8_t)(hi - uppers);
875*ebfedea0SLionel Sambuc 		}
876*ebfedea0SLionel Sambuc 		if ((lo = strchr(uppers, userid[i + 1])) == NULL) {
877*ebfedea0SLionel Sambuc 			if ((lo = strchr(lowers, userid[i + 1])) == NULL) {
878*ebfedea0SLionel Sambuc 				break;
879*ebfedea0SLionel Sambuc 			}
880*ebfedea0SLionel Sambuc 			lochar = (uint8_t)(lo - lowers);
881*ebfedea0SLionel Sambuc 		} else {
882*ebfedea0SLionel Sambuc 			lochar = (uint8_t)(lo - uppers);
883*ebfedea0SLionel Sambuc 		}
884*ebfedea0SLionel Sambuc 		keyid[j] = (hichar << 4) | (lochar);
885*ebfedea0SLionel Sambuc 	}
886*ebfedea0SLionel Sambuc 	keyid[j] = 0x0;
887*ebfedea0SLionel Sambuc }
888*ebfedea0SLionel Sambuc 
889*ebfedea0SLionel Sambuc /* return the next key which matches, starting searching at *from */
890*ebfedea0SLionel Sambuc static const pgp_key_t *
getkeybyname(pgp_io_t * io,const pgp_keyring_t * keyring,const char * name,unsigned * from)891*ebfedea0SLionel Sambuc getkeybyname(pgp_io_t *io,
892*ebfedea0SLionel Sambuc 			const pgp_keyring_t *keyring,
893*ebfedea0SLionel Sambuc 			const char *name,
894*ebfedea0SLionel Sambuc 			unsigned *from)
895*ebfedea0SLionel Sambuc {
896*ebfedea0SLionel Sambuc 	const pgp_key_t	*kp;
897*ebfedea0SLionel Sambuc 	uint8_t			**uidp;
898*ebfedea0SLionel Sambuc 	unsigned    	 	 i = 0;
899*ebfedea0SLionel Sambuc 	pgp_key_t		*keyp;
900*ebfedea0SLionel Sambuc 	unsigned		 savedstart;
901*ebfedea0SLionel Sambuc 	regex_t			 r;
902*ebfedea0SLionel Sambuc 	uint8_t		 	 keyid[PGP_KEY_ID_SIZE + 1];
903*ebfedea0SLionel Sambuc 	size_t          	 len;
904*ebfedea0SLionel Sambuc 
905*ebfedea0SLionel Sambuc 	if (!keyring || !name || !from) {
906*ebfedea0SLionel Sambuc 		return NULL;
907*ebfedea0SLionel Sambuc 	}
908*ebfedea0SLionel Sambuc 	len = strlen(name);
909*ebfedea0SLionel Sambuc 	if (pgp_get_debug_level(__FILE__)) {
910*ebfedea0SLionel Sambuc 		(void) fprintf(io->outs, "[%u] name '%s', len %zu\n",
911*ebfedea0SLionel Sambuc 			*from, name, len);
912*ebfedea0SLionel Sambuc 	}
913*ebfedea0SLionel Sambuc 	/* first try name as a keyid */
914*ebfedea0SLionel Sambuc 	(void) memset(keyid, 0x0, sizeof(keyid));
915*ebfedea0SLionel Sambuc 	str2keyid(name, keyid, sizeof(keyid));
916*ebfedea0SLionel Sambuc 	if (pgp_get_debug_level(__FILE__)) {
917*ebfedea0SLionel Sambuc 		hexdump(io->outs, "keyid", keyid, 4);
918*ebfedea0SLionel Sambuc 	}
919*ebfedea0SLionel Sambuc 	savedstart = *from;
920*ebfedea0SLionel Sambuc 	if ((kp = pgp_getkeybyid(io, keyring, keyid, from, NULL)) != NULL) {
921*ebfedea0SLionel Sambuc 		return kp;
922*ebfedea0SLionel Sambuc 	}
923*ebfedea0SLionel Sambuc 	*from = savedstart;
924*ebfedea0SLionel Sambuc 	if (pgp_get_debug_level(__FILE__)) {
925*ebfedea0SLionel Sambuc 		(void) fprintf(io->outs, "regex match '%s' from %u\n",
926*ebfedea0SLionel Sambuc 			name, *from);
927*ebfedea0SLionel Sambuc 	}
928*ebfedea0SLionel Sambuc 	/* match on full name or email address as a NOSUB, ICASE regexp */
929*ebfedea0SLionel Sambuc 	(void) regcomp(&r, name, REG_EXTENDED | REG_ICASE);
930*ebfedea0SLionel Sambuc 	for (keyp = &keyring->keys[*from]; *from < keyring->keyc; *from += 1, keyp++) {
931*ebfedea0SLionel Sambuc 		uidp = keyp->uids;
932*ebfedea0SLionel Sambuc 		for (i = 0 ; i < keyp->uidc; i++, uidp++) {
933*ebfedea0SLionel Sambuc 			if (regexec(&r, (char *)*uidp, 0, NULL, 0) == 0) {
934*ebfedea0SLionel Sambuc 				if (pgp_get_debug_level(__FILE__)) {
935*ebfedea0SLionel Sambuc 					(void) fprintf(io->outs,
936*ebfedea0SLionel Sambuc 						"MATCHED keyid \"%s\" len %" PRIsize "u\n",
937*ebfedea0SLionel Sambuc 					       (char *) *uidp, len);
938*ebfedea0SLionel Sambuc 				}
939*ebfedea0SLionel Sambuc 				regfree(&r);
940*ebfedea0SLionel Sambuc 				return keyp;
941*ebfedea0SLionel Sambuc 			}
942*ebfedea0SLionel Sambuc 		}
943*ebfedea0SLionel Sambuc 	}
944*ebfedea0SLionel Sambuc 	regfree(&r);
945*ebfedea0SLionel Sambuc 	return NULL;
946*ebfedea0SLionel Sambuc }
947*ebfedea0SLionel Sambuc 
948*ebfedea0SLionel Sambuc /**
949*ebfedea0SLionel Sambuc    \ingroup HighLevel_KeyringFind
950*ebfedea0SLionel Sambuc 
951*ebfedea0SLionel Sambuc    \brief Finds key from its User ID
952*ebfedea0SLionel Sambuc 
953*ebfedea0SLionel Sambuc    \param keyring Keyring to be searched
954*ebfedea0SLionel Sambuc    \param userid User ID of required key
955*ebfedea0SLionel Sambuc 
956*ebfedea0SLionel Sambuc    \return Pointer to Key, if found; NULL, if not found
957*ebfedea0SLionel Sambuc 
958*ebfedea0SLionel Sambuc    \note This returns a pointer to the key inside the keyring, not a
959*ebfedea0SLionel Sambuc    copy.  Do not free it.
960*ebfedea0SLionel Sambuc 
961*ebfedea0SLionel Sambuc */
962*ebfedea0SLionel Sambuc const pgp_key_t *
pgp_getkeybyname(pgp_io_t * io,const pgp_keyring_t * keyring,const char * name)963*ebfedea0SLionel Sambuc pgp_getkeybyname(pgp_io_t *io,
964*ebfedea0SLionel Sambuc 			const pgp_keyring_t *keyring,
965*ebfedea0SLionel Sambuc 			const char *name)
966*ebfedea0SLionel Sambuc {
967*ebfedea0SLionel Sambuc 	unsigned	from;
968*ebfedea0SLionel Sambuc 
969*ebfedea0SLionel Sambuc 	from = 0;
970*ebfedea0SLionel Sambuc 	return getkeybyname(io, keyring, name, &from);
971*ebfedea0SLionel Sambuc }
972*ebfedea0SLionel Sambuc 
973*ebfedea0SLionel Sambuc const pgp_key_t *
pgp_getnextkeybyname(pgp_io_t * io,const pgp_keyring_t * keyring,const char * name,unsigned * n)974*ebfedea0SLionel Sambuc pgp_getnextkeybyname(pgp_io_t *io,
975*ebfedea0SLionel Sambuc 			const pgp_keyring_t *keyring,
976*ebfedea0SLionel Sambuc 			const char *name,
977*ebfedea0SLionel Sambuc 			unsigned *n)
978*ebfedea0SLionel Sambuc {
979*ebfedea0SLionel Sambuc 	return getkeybyname(io, keyring, name, n);
980*ebfedea0SLionel Sambuc }
981*ebfedea0SLionel Sambuc 
982*ebfedea0SLionel Sambuc /**
983*ebfedea0SLionel Sambuc    \ingroup HighLevel_KeyringList
984*ebfedea0SLionel Sambuc 
985*ebfedea0SLionel Sambuc    \brief Prints all keys in keyring to stdout.
986*ebfedea0SLionel Sambuc 
987*ebfedea0SLionel Sambuc    \param keyring Keyring to use
988*ebfedea0SLionel Sambuc 
989*ebfedea0SLionel Sambuc    \return none
990*ebfedea0SLionel Sambuc */
991*ebfedea0SLionel Sambuc int
pgp_keyring_list(pgp_io_t * io,const pgp_keyring_t * keyring,const int psigs)992*ebfedea0SLionel Sambuc pgp_keyring_list(pgp_io_t *io, const pgp_keyring_t *keyring, const int psigs)
993*ebfedea0SLionel Sambuc {
994*ebfedea0SLionel Sambuc 	pgp_key_t		*key;
995*ebfedea0SLionel Sambuc 	unsigned		 n;
996*ebfedea0SLionel Sambuc 
997*ebfedea0SLionel Sambuc 	(void) fprintf(io->res, "%u key%s\n", keyring->keyc,
998*ebfedea0SLionel Sambuc 		(keyring->keyc == 1) ? "" : "s");
999*ebfedea0SLionel Sambuc 	for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
1000*ebfedea0SLionel Sambuc 		if (pgp_is_key_secret(key)) {
1001*ebfedea0SLionel Sambuc 			pgp_print_keydata(io, keyring, key, "sec",
1002*ebfedea0SLionel Sambuc 				&key->key.seckey.pubkey, 0);
1003*ebfedea0SLionel Sambuc 		} else {
1004*ebfedea0SLionel Sambuc 			pgp_print_keydata(io, keyring, key, "signature ", &key->key.pubkey, psigs);
1005*ebfedea0SLionel Sambuc 		}
1006*ebfedea0SLionel Sambuc 		(void) fputc('\n', io->res);
1007*ebfedea0SLionel Sambuc 	}
1008*ebfedea0SLionel Sambuc 	return 1;
1009*ebfedea0SLionel Sambuc }
1010*ebfedea0SLionel Sambuc 
1011*ebfedea0SLionel Sambuc int
pgp_keyring_json(pgp_io_t * io,const pgp_keyring_t * keyring,mj_t * obj,const int psigs)1012*ebfedea0SLionel Sambuc pgp_keyring_json(pgp_io_t *io, const pgp_keyring_t *keyring, mj_t *obj, const int psigs)
1013*ebfedea0SLionel Sambuc {
1014*ebfedea0SLionel Sambuc 	pgp_key_t		*key;
1015*ebfedea0SLionel Sambuc 	unsigned		 n;
1016*ebfedea0SLionel Sambuc 
1017*ebfedea0SLionel Sambuc 	(void) memset(obj, 0x0, sizeof(*obj));
1018*ebfedea0SLionel Sambuc 	mj_create(obj, "array");
1019*ebfedea0SLionel Sambuc 	obj->size = keyring->keyvsize;
1020*ebfedea0SLionel Sambuc 	if (pgp_get_debug_level(__FILE__)) {
1021*ebfedea0SLionel Sambuc 		(void) fprintf(io->errs, "pgp_keyring_json: vsize %u\n", obj->size);
1022*ebfedea0SLionel Sambuc 	}
1023*ebfedea0SLionel Sambuc 	if ((obj->value.v = calloc(sizeof(*obj->value.v), obj->size)) == NULL) {
1024*ebfedea0SLionel Sambuc 		(void) fprintf(io->errs, "calloc failure\n");
1025*ebfedea0SLionel Sambuc 		return 0;
1026*ebfedea0SLionel Sambuc 	}
1027*ebfedea0SLionel Sambuc 	for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
1028*ebfedea0SLionel Sambuc 		if (pgp_is_key_secret(key)) {
1029*ebfedea0SLionel Sambuc 			pgp_sprint_mj(io, keyring, key, &obj->value.v[obj->c],
1030*ebfedea0SLionel Sambuc 				"sec", &key->key.seckey.pubkey, psigs);
1031*ebfedea0SLionel Sambuc 		} else {
1032*ebfedea0SLionel Sambuc 			pgp_sprint_mj(io, keyring, key, &obj->value.v[obj->c],
1033*ebfedea0SLionel Sambuc 				"signature ", &key->key.pubkey, psigs);
1034*ebfedea0SLionel Sambuc 		}
1035*ebfedea0SLionel Sambuc 		if (obj->value.v[obj->c].type != 0) {
1036*ebfedea0SLionel Sambuc 			obj->c += 1;
1037*ebfedea0SLionel Sambuc 		}
1038*ebfedea0SLionel Sambuc 	}
1039*ebfedea0SLionel Sambuc 	if (pgp_get_debug_level(__FILE__)) {
1040*ebfedea0SLionel Sambuc 		char	*s;
1041*ebfedea0SLionel Sambuc 
1042*ebfedea0SLionel Sambuc 		mj_asprint(&s, obj, MJ_JSON_ENCODE);
1043*ebfedea0SLionel Sambuc 		(void) fprintf(stderr, "pgp_keyring_json: '%s'\n", s);
1044*ebfedea0SLionel Sambuc 		free(s);
1045*ebfedea0SLionel Sambuc 	}
1046*ebfedea0SLionel Sambuc 	return 1;
1047*ebfedea0SLionel Sambuc }
1048*ebfedea0SLionel Sambuc 
1049*ebfedea0SLionel Sambuc 
1050*ebfedea0SLionel Sambuc /* this interface isn't right - hook into callback for getting passphrase */
1051*ebfedea0SLionel Sambuc char *
pgp_export_key(pgp_io_t * io,const pgp_key_t * keydata,uint8_t * passphrase)1052*ebfedea0SLionel Sambuc pgp_export_key(pgp_io_t *io, const pgp_key_t *keydata, uint8_t *passphrase)
1053*ebfedea0SLionel Sambuc {
1054*ebfedea0SLionel Sambuc 	pgp_output_t	*output;
1055*ebfedea0SLionel Sambuc 	pgp_memory_t	*mem;
1056*ebfedea0SLionel Sambuc 	char		*cp;
1057*ebfedea0SLionel Sambuc 
1058*ebfedea0SLionel Sambuc 	__PGP_USED(io);
1059*ebfedea0SLionel Sambuc 	pgp_setup_memory_write(&output, &mem, 128);
1060*ebfedea0SLionel Sambuc 	if (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) {
1061*ebfedea0SLionel Sambuc 		pgp_write_xfer_pubkey(output, keydata, 1);
1062*ebfedea0SLionel Sambuc 	} else {
1063*ebfedea0SLionel Sambuc 		pgp_write_xfer_seckey(output, keydata, passphrase,
1064*ebfedea0SLionel Sambuc 					strlen((char *)passphrase), 1);
1065*ebfedea0SLionel Sambuc 	}
1066*ebfedea0SLionel Sambuc 	cp = netpgp_strdup(pgp_mem_data(mem));
1067*ebfedea0SLionel Sambuc 	pgp_teardown_memory_write(output, mem);
1068*ebfedea0SLionel Sambuc 	return cp;
1069*ebfedea0SLionel Sambuc }
1070*ebfedea0SLionel Sambuc 
1071*ebfedea0SLionel Sambuc /* add a key to a public keyring */
1072*ebfedea0SLionel Sambuc int
pgp_add_to_pubring(pgp_keyring_t * keyring,const pgp_pubkey_t * pubkey,pgp_content_enum tag)1073*ebfedea0SLionel Sambuc pgp_add_to_pubring(pgp_keyring_t *keyring, const pgp_pubkey_t *pubkey, pgp_content_enum tag)
1074*ebfedea0SLionel Sambuc {
1075*ebfedea0SLionel Sambuc 	pgp_key_t	*key;
1076*ebfedea0SLionel Sambuc 	time_t		 duration;
1077*ebfedea0SLionel Sambuc 
1078*ebfedea0SLionel Sambuc 	if (pgp_get_debug_level(__FILE__)) {
1079*ebfedea0SLionel Sambuc 		fprintf(stderr, "pgp_add_to_pubring (type %u)\n", tag);
1080*ebfedea0SLionel Sambuc 	}
1081*ebfedea0SLionel Sambuc 	switch(tag) {
1082*ebfedea0SLionel Sambuc 	case PGP_PTAG_CT_PUBLIC_KEY:
1083*ebfedea0SLionel Sambuc 		EXPAND_ARRAY(keyring, key);
1084*ebfedea0SLionel Sambuc 		key = &keyring->keys[keyring->keyc++];
1085*ebfedea0SLionel Sambuc 		duration = key->key.pubkey.duration;
1086*ebfedea0SLionel Sambuc 		(void) memset(key, 0x0, sizeof(*key));
1087*ebfedea0SLionel Sambuc 		key->type = tag;
1088*ebfedea0SLionel Sambuc 		pgp_keyid(key->sigid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
1089*ebfedea0SLionel Sambuc 		pgp_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype);
1090*ebfedea0SLionel Sambuc 		key->key.pubkey = *pubkey;
1091*ebfedea0SLionel Sambuc 		key->key.pubkey.duration = duration;
1092*ebfedea0SLionel Sambuc 		return 1;
1093*ebfedea0SLionel Sambuc 	case PGP_PTAG_CT_PUBLIC_SUBKEY:
1094*ebfedea0SLionel Sambuc 		/* subkey is not the first */
1095*ebfedea0SLionel Sambuc 		key = &keyring->keys[keyring->keyc - 1];
1096*ebfedea0SLionel Sambuc 		pgp_keyid(key->encid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
1097*ebfedea0SLionel Sambuc 		duration = key->key.pubkey.duration;
1098*ebfedea0SLionel Sambuc 		(void) memcpy(&key->enckey, pubkey, sizeof(key->enckey));
1099*ebfedea0SLionel Sambuc 		key->enckey.duration = duration;
1100*ebfedea0SLionel Sambuc 		return 1;
1101*ebfedea0SLionel Sambuc 	default:
1102*ebfedea0SLionel Sambuc 		return 0;
1103*ebfedea0SLionel Sambuc 	}
1104*ebfedea0SLionel Sambuc }
1105*ebfedea0SLionel Sambuc 
1106*ebfedea0SLionel Sambuc /* add a key to a secret keyring */
1107*ebfedea0SLionel Sambuc int
pgp_add_to_secring(pgp_keyring_t * keyring,const pgp_seckey_t * seckey)1108*ebfedea0SLionel Sambuc pgp_add_to_secring(pgp_keyring_t *keyring, const pgp_seckey_t *seckey)
1109*ebfedea0SLionel Sambuc {
1110*ebfedea0SLionel Sambuc 	const pgp_pubkey_t	*pubkey;
1111*ebfedea0SLionel Sambuc 	pgp_key_t		*key;
1112*ebfedea0SLionel Sambuc 
1113*ebfedea0SLionel Sambuc 	if (pgp_get_debug_level(__FILE__)) {
1114*ebfedea0SLionel Sambuc 		fprintf(stderr, "pgp_add_to_secring\n");
1115*ebfedea0SLionel Sambuc 	}
1116*ebfedea0SLionel Sambuc 	if (keyring->keyc > 0) {
1117*ebfedea0SLionel Sambuc 		key = &keyring->keys[keyring->keyc - 1];
1118*ebfedea0SLionel Sambuc 		if (pgp_get_debug_level(__FILE__) &&
1119*ebfedea0SLionel Sambuc 		    key->key.pubkey.alg == PGP_PKA_DSA &&
1120*ebfedea0SLionel Sambuc 		    seckey->pubkey.alg == PGP_PKA_ELGAMAL) {
1121*ebfedea0SLionel Sambuc 			fprintf(stderr, "pgp_add_to_secring: found elgamal seckey\n");
1122*ebfedea0SLionel Sambuc 		}
1123*ebfedea0SLionel Sambuc 	}
1124*ebfedea0SLionel Sambuc 	EXPAND_ARRAY(keyring, key);
1125*ebfedea0SLionel Sambuc 	key = &keyring->keys[keyring->keyc++];
1126*ebfedea0SLionel Sambuc 	(void) memset(key, 0x0, sizeof(*key));
1127*ebfedea0SLionel Sambuc 	pubkey = &seckey->pubkey;
1128*ebfedea0SLionel Sambuc 	pgp_keyid(key->sigid, PGP_KEY_ID_SIZE, pubkey, keyring->hashtype);
1129*ebfedea0SLionel Sambuc 	pgp_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype);
1130*ebfedea0SLionel Sambuc 	key->type = PGP_PTAG_CT_SECRET_KEY;
1131*ebfedea0SLionel Sambuc 	key->key.seckey = *seckey;
1132*ebfedea0SLionel Sambuc 	if (pgp_get_debug_level(__FILE__)) {
1133*ebfedea0SLionel Sambuc 		fprintf(stderr, "pgp_add_to_secring: keyc %u\n", keyring->keyc);
1134*ebfedea0SLionel Sambuc 	}
1135*ebfedea0SLionel Sambuc 	return 1;
1136*ebfedea0SLionel Sambuc }
1137*ebfedea0SLionel Sambuc 
1138*ebfedea0SLionel Sambuc /* append one keyring to another */
1139*ebfedea0SLionel Sambuc int
pgp_append_keyring(pgp_keyring_t * keyring,pgp_keyring_t * newring)1140*ebfedea0SLionel Sambuc pgp_append_keyring(pgp_keyring_t *keyring, pgp_keyring_t *newring)
1141*ebfedea0SLionel Sambuc {
1142*ebfedea0SLionel Sambuc 	unsigned	i;
1143*ebfedea0SLionel Sambuc 
1144*ebfedea0SLionel Sambuc 	for (i = 0 ; i < newring->keyc ; i++) {
1145*ebfedea0SLionel Sambuc 		EXPAND_ARRAY(keyring, key);
1146*ebfedea0SLionel Sambuc 		(void) memcpy(&keyring->keys[keyring->keyc], &newring->keys[i],
1147*ebfedea0SLionel Sambuc 				sizeof(newring->keys[i]));
1148*ebfedea0SLionel Sambuc 		keyring->keyc += 1;
1149*ebfedea0SLionel Sambuc 	}
1150*ebfedea0SLionel Sambuc 	return 1;
1151*ebfedea0SLionel Sambuc }
1152