15fff9558SSimon J. Gerraty /*-
25fff9558SSimon J. Gerraty  * Copyright (c) 2018, Juniper Networks, Inc.
35fff9558SSimon J. Gerraty  *
45fff9558SSimon J. Gerraty  * Redistribution and use in source and binary forms, with or without
55fff9558SSimon J. Gerraty  * modification, are permitted provided that the following conditions
65fff9558SSimon J. Gerraty  * are met:
75fff9558SSimon J. Gerraty  * 1. Redistributions of source code must retain the above copyright
85fff9558SSimon J. Gerraty  *    notice, this list of conditions and the following disclaimer.
95fff9558SSimon J. Gerraty  * 2. Redistributions in binary form must reproduce the above copyright
105fff9558SSimon J. Gerraty  *    notice, this list of conditions and the following disclaimer in the
115fff9558SSimon J. Gerraty  *    documentation and/or other materials provided with the distribution.
125fff9558SSimon J. Gerraty  *
135fff9558SSimon J. Gerraty  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
145fff9558SSimon J. Gerraty  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
155fff9558SSimon J. Gerraty  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
165fff9558SSimon J. Gerraty  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
175fff9558SSimon J. Gerraty  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
185fff9558SSimon J. Gerraty  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
195fff9558SSimon J. Gerraty  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
205fff9558SSimon J. Gerraty  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
215fff9558SSimon J. Gerraty  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
225fff9558SSimon J. Gerraty  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
235fff9558SSimon J. Gerraty  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
245fff9558SSimon J. Gerraty  */
255fff9558SSimon J. Gerraty 
265fff9558SSimon J. Gerraty #include <sys/cdefs.h>
275fff9558SSimon J. Gerraty #include "../libsecureboot-priv.h"
285fff9558SSimon J. Gerraty 
295fff9558SSimon J. Gerraty #include "decode.h"
305fff9558SSimon J. Gerraty #include "packet.h"
315fff9558SSimon J. Gerraty 
325fff9558SSimon J. Gerraty /**
335fff9558SSimon J. Gerraty  * @brief decode user-id packet
345fff9558SSimon J. Gerraty  *
355fff9558SSimon J. Gerraty  * This is trivial
365fff9558SSimon J. Gerraty  *
375fff9558SSimon J. Gerraty  * @sa rfc4880:5.11
385fff9558SSimon J. Gerraty  */
395fff9558SSimon J. Gerraty ssize_t
decode_user(int tag,unsigned char ** pptr,size_t len,OpenPGP_user * user)405fff9558SSimon J. Gerraty decode_user(int tag, unsigned char **pptr, size_t len, OpenPGP_user *user)
415fff9558SSimon J. Gerraty {
425fff9558SSimon J. Gerraty 	char *cp;
435fff9558SSimon J. Gerraty 
445fff9558SSimon J. Gerraty 	if (tag == 13) {
455fff9558SSimon J. Gerraty 		user->id = malloc(len + 1);
465fff9558SSimon J. Gerraty 		strncpy(user->id, (char *)*pptr, len);
475fff9558SSimon J. Gerraty 		user->id[len] = '\0';
485fff9558SSimon J. Gerraty 		user->name = user->id;
495fff9558SSimon J. Gerraty 		cp = strchr(user->id, '<');
505fff9558SSimon J. Gerraty 		if (cp > user->id) {
515fff9558SSimon J. Gerraty 			user->id = strdup(user->id);
525fff9558SSimon J. Gerraty 			cp[-1] = '\0';
535fff9558SSimon J. Gerraty 		}
545fff9558SSimon J. Gerraty 	}
555fff9558SSimon J. Gerraty 	*pptr += len;
565fff9558SSimon J. Gerraty 	return ((ssize_t)len);
575fff9558SSimon J. Gerraty }
585fff9558SSimon J. Gerraty 
595fff9558SSimon J. Gerraty /**
605fff9558SSimon J. Gerraty  * @brief decode a key packet
615fff9558SSimon J. Gerraty  *
625fff9558SSimon J. Gerraty  * We only really support v4 and RSA
635fff9558SSimon J. Gerraty  *
645fff9558SSimon J. Gerraty  * @sa rfc4880:5.5.1.1
655fff9558SSimon J. Gerraty  */
665fff9558SSimon J. Gerraty ssize_t
decode_key(int tag,unsigned char ** pptr,size_t len,OpenPGP_key * key)675fff9558SSimon J. Gerraty decode_key(int tag, unsigned char **pptr, size_t len, OpenPGP_key *key)
685fff9558SSimon J. Gerraty {
695fff9558SSimon J. Gerraty 	unsigned char *ptr;
705fff9558SSimon J. Gerraty 	int version;
715fff9558SSimon J. Gerraty #ifdef USE_BEARSSL
725fff9558SSimon J. Gerraty 	br_sha1_context mctx;
735fff9558SSimon J. Gerraty 	unsigned char mdata[br_sha512_SIZE];
745fff9558SSimon J. Gerraty 	size_t mlen;
755fff9558SSimon J. Gerraty #else
765fff9558SSimon J. Gerraty 	RSA *rsa = NULL;
775fff9558SSimon J. Gerraty 	const EVP_MD *md = NULL;
785fff9558SSimon J. Gerraty 	EVP_MD_CTX mctx;
795fff9558SSimon J. Gerraty 	unsigned char mdata[EVP_MAX_MD_SIZE];
805fff9558SSimon J. Gerraty 	unsigned int mlen;
815fff9558SSimon J. Gerraty #endif
825fff9558SSimon J. Gerraty 
835fff9558SSimon J. Gerraty 	if (tag != 6)
845fff9558SSimon J. Gerraty 		return (-1);
855fff9558SSimon J. Gerraty 
865fff9558SSimon J. Gerraty 	key->key = NULL;
875fff9558SSimon J. Gerraty 	ptr = *pptr;
885fff9558SSimon J. Gerraty 	version = *ptr;
895fff9558SSimon J. Gerraty 	if (version == 4) {		/* all we support really */
905fff9558SSimon J. Gerraty 		/* comput key fingerprint and id @sa rfc4880:12.2 */
915fff9558SSimon J. Gerraty 		mdata[0] = 0x99;	/* rfc4880: 12.2.a.1 */
925fff9558SSimon J. Gerraty 		mdata[1] = (len >> 8) & 0xff;
935fff9558SSimon J. Gerraty 		mdata[2] = len & 0xff;
945fff9558SSimon J. Gerraty 
955fff9558SSimon J. Gerraty #ifdef USE_BEARSSL
965fff9558SSimon J. Gerraty 		br_sha1_init(&mctx);
975fff9558SSimon J. Gerraty 		br_sha1_update(&mctx, mdata, 3);
985fff9558SSimon J. Gerraty 		br_sha1_update(&mctx, ptr, len);
995fff9558SSimon J. Gerraty 		br_sha1_out(&mctx, mdata);
1005fff9558SSimon J. Gerraty 		mlen = br_sha1_SIZE;
1015fff9558SSimon J. Gerraty #else
1025fff9558SSimon J. Gerraty 		md = EVP_get_digestbyname("sha1");
1035fff9558SSimon J. Gerraty 		EVP_DigestInit(&mctx, md);
1045fff9558SSimon J. Gerraty 		EVP_DigestUpdate(&mctx, mdata, 3);
1055fff9558SSimon J. Gerraty 		EVP_DigestUpdate(&mctx, ptr, len);
1065fff9558SSimon J. Gerraty 		mlen = (unsigned int)sizeof(mdata);
1075fff9558SSimon J. Gerraty 		EVP_DigestFinal(&mctx, mdata, &mlen);
1085fff9558SSimon J. Gerraty #endif
1095fff9558SSimon J. Gerraty 		key->id = octets2hex(&mdata[mlen - 8], 8);
1105fff9558SSimon J. Gerraty 	}
1115fff9558SSimon J. Gerraty 	ptr += 1;			/* done with version */
1125fff9558SSimon J. Gerraty 	ptr += 4;			/* skip ctime */
1135fff9558SSimon J. Gerraty 	if (version == 3)
1145fff9558SSimon J. Gerraty 		ptr += 2;		/* valid days */
1155fff9558SSimon J. Gerraty 	key->sig_alg = *ptr++;
1165fff9558SSimon J. Gerraty 	if (key->sig_alg == 1) {	/* RSA */
1175fff9558SSimon J. Gerraty #ifdef USE_BEARSSL
1185fff9558SSimon J. Gerraty 		key->key = NEW(br_rsa_public_key);
1195fff9558SSimon J. Gerraty 		if (!key->key)
1205fff9558SSimon J. Gerraty 			goto oops;
1215fff9558SSimon J. Gerraty 		key->key->n = mpi2bn(&ptr, &key->key->nlen);
1225fff9558SSimon J. Gerraty 		key->key->e = mpi2bn(&ptr, &key->key->elen);
1235fff9558SSimon J. Gerraty #else
1245fff9558SSimon J. Gerraty 		rsa = RSA_new();
1255fff9558SSimon J. Gerraty 		if (!rsa)
1265fff9558SSimon J. Gerraty 			goto oops;
1275fff9558SSimon J. Gerraty 		rsa->n = mpi2bn(&ptr);
1285fff9558SSimon J. Gerraty 		rsa->e = mpi2bn(&ptr);
1295fff9558SSimon J. Gerraty 		key->key = EVP_PKEY_new();
1305fff9558SSimon J. Gerraty 		if (!key->key || !rsa->n || !rsa->e) {
1315fff9558SSimon J. Gerraty 			goto oops;
1325fff9558SSimon J. Gerraty 		}
1335fff9558SSimon J. Gerraty 		if (!EVP_PKEY_set1_RSA(key->key, rsa))
1345fff9558SSimon J. Gerraty 			goto oops;
1355fff9558SSimon J. Gerraty #endif
1365fff9558SSimon J. Gerraty 	}
1375fff9558SSimon J. Gerraty 	/* we are done */
1385fff9558SSimon J. Gerraty 	return ((ssize_t)len);
1395fff9558SSimon J. Gerraty oops:
1405fff9558SSimon J. Gerraty #ifdef USE_BEARSSL
1415fff9558SSimon J. Gerraty 	free(key->key);
1425fff9558SSimon J. Gerraty 	key->key = NULL;
1435fff9558SSimon J. Gerraty #else
1445fff9558SSimon J. Gerraty 	if (rsa)
1455fff9558SSimon J. Gerraty 		RSA_free(rsa);
1465fff9558SSimon J. Gerraty 	if (key->key) {
1475fff9558SSimon J. Gerraty 		EVP_PKEY_free(key->key);
1485fff9558SSimon J. Gerraty 		key->key = NULL;
1495fff9558SSimon J. Gerraty 	}
1505fff9558SSimon J. Gerraty #endif
1515fff9558SSimon J. Gerraty 	return (-1);
1525fff9558SSimon J. Gerraty }
1535fff9558SSimon J. Gerraty 
1545fff9558SSimon J. Gerraty static OpenPGP_key *
load_key_buf(unsigned char * buf,size_t nbytes)1555fff9558SSimon J. Gerraty load_key_buf(unsigned char *buf, size_t nbytes)
1565fff9558SSimon J. Gerraty {
1575fff9558SSimon J. Gerraty 	unsigned char *data = NULL;
1585fff9558SSimon J. Gerraty 	unsigned char *ptr;
1595fff9558SSimon J. Gerraty 	ssize_t rc;
1605fff9558SSimon J. Gerraty 	int tag;
1615fff9558SSimon J. Gerraty 	OpenPGP_key *key;
1625fff9558SSimon J. Gerraty 
1635fff9558SSimon J. Gerraty 	if (!buf)
1645fff9558SSimon J. Gerraty 		return (NULL);
1655fff9558SSimon J. Gerraty 
1665fff9558SSimon J. Gerraty 	initialize();
1675fff9558SSimon J. Gerraty 
1685fff9558SSimon J. Gerraty 	if (!(buf[0] & OPENPGP_TAG_ISTAG)) {
169e5ec655dSSimon J. Gerraty 		/* Note: we do *not* free data */
1705fff9558SSimon J. Gerraty 		data = dearmor((char *)buf, nbytes, &nbytes);
1715fff9558SSimon J. Gerraty 		ptr = data;
1725fff9558SSimon J. Gerraty 	} else
1735fff9558SSimon J. Gerraty 		ptr = buf;
1745fff9558SSimon J. Gerraty 	key = NEW(OpenPGP_key);
1755fff9558SSimon J. Gerraty 	if (key) {
1765fff9558SSimon J. Gerraty 		rc = decode_packet(0, &ptr, nbytes, (decoder_t)decode_key,
1775fff9558SSimon J. Gerraty 		    key);
1785fff9558SSimon J. Gerraty 		if (rc < 0) {
1795fff9558SSimon J. Gerraty 			free(key);
1805fff9558SSimon J. Gerraty 			key = NULL;
1815fff9558SSimon J. Gerraty 		} else if (rc > 8) {
1825fff9558SSimon J. Gerraty 			int isnew, ltype;
1835fff9558SSimon J. Gerraty 
1845fff9558SSimon J. Gerraty 			tag = decode_tag(ptr, &isnew, &ltype);
1855fff9558SSimon J. Gerraty 			if (tag == 13) {
1865fff9558SSimon J. Gerraty 				key->user = NEW(OpenPGP_user);
1875fff9558SSimon J. Gerraty 				rc = decode_packet(0, &ptr, (size_t)rc,
1885fff9558SSimon J. Gerraty 				    (decoder_t)decode_user, key->user);
1895fff9558SSimon J. Gerraty 			}
1905fff9558SSimon J. Gerraty 		}
1915fff9558SSimon J. Gerraty 	}
1925fff9558SSimon J. Gerraty 	return (key);
1935fff9558SSimon J. Gerraty }
1945fff9558SSimon J. Gerraty 
1955fff9558SSimon J. Gerraty static LIST_HEAD(, OpenPGP_key_) trust_list;
1965fff9558SSimon J. Gerraty 
1975fff9558SSimon J. Gerraty /**
1985fff9558SSimon J. Gerraty  * @brief add a key to our list
1995fff9558SSimon J. Gerraty  */
2005fff9558SSimon J. Gerraty void
openpgp_trust_add(OpenPGP_key * key)2015fff9558SSimon J. Gerraty openpgp_trust_add(OpenPGP_key *key)
2025fff9558SSimon J. Gerraty {
2035fff9558SSimon J. Gerraty 	static int once = 0;
2045fff9558SSimon J. Gerraty 
2055fff9558SSimon J. Gerraty 	if (!once) {
2065fff9558SSimon J. Gerraty 		once = 1;
2075fff9558SSimon J. Gerraty 
2085fff9558SSimon J. Gerraty 		LIST_INIT(&trust_list);
2095fff9558SSimon J. Gerraty 	}
210f9510887SSimon J. Gerraty 	if (key && openpgp_trust_get(key->id) == NULL) {
211f9510887SSimon J. Gerraty 		if (ve_anchor_verbose_get())
212f9510887SSimon J. Gerraty 			printf("openpgp_trust_add(%s)\n", key->id);
2135fff9558SSimon J. Gerraty 		LIST_INSERT_HEAD(&trust_list, key, entries);
2145fff9558SSimon J. Gerraty 	}
215e5ec655dSSimon J. Gerraty }
2165fff9558SSimon J. Gerraty 
2175fff9558SSimon J. Gerraty /**
218f9510887SSimon J. Gerraty  * @brief add trust anchor from buf
219f9510887SSimon J. Gerraty  */
220f9510887SSimon J. Gerraty int
openpgp_trust_add_buf(unsigned char * buf,size_t nbytes)221f9510887SSimon J. Gerraty openpgp_trust_add_buf(unsigned char *buf, size_t nbytes)
222f9510887SSimon J. Gerraty {
223f9510887SSimon J. Gerraty 	OpenPGP_key *key;
224f9510887SSimon J. Gerraty 
225f9510887SSimon J. Gerraty 	if ((key = load_key_buf(buf, nbytes))) {
226f9510887SSimon J. Gerraty 		openpgp_trust_add(key);
227f9510887SSimon J. Gerraty 	}
228f9510887SSimon J. Gerraty 	return (key != NULL);
229f9510887SSimon J. Gerraty }
230f9510887SSimon J. Gerraty 
231f9510887SSimon J. Gerraty 
232f9510887SSimon J. Gerraty /**
233f9510887SSimon J. Gerraty  * @brief if keyID is in our list clobber it
234f9510887SSimon J. Gerraty  *
235f9510887SSimon J. Gerraty  * @return true if keyID removed
236f9510887SSimon J. Gerraty  */
237f9510887SSimon J. Gerraty int
openpgp_trust_revoke(const char * keyID)238f9510887SSimon J. Gerraty openpgp_trust_revoke(const char *keyID)
239f9510887SSimon J. Gerraty {
240f9510887SSimon J. Gerraty 	OpenPGP_key *key, *tkey;
241f9510887SSimon J. Gerraty 
242f9510887SSimon J. Gerraty 	openpgp_trust_add(NULL);	/* initialize if needed */
243f9510887SSimon J. Gerraty 
244f9510887SSimon J. Gerraty 	LIST_FOREACH(key, &trust_list, entries) {
245f9510887SSimon J. Gerraty 		if (strcmp(key->id, keyID) == 0) {
246f9510887SSimon J. Gerraty 			tkey = key;
247f9510887SSimon J. Gerraty 			LIST_REMOVE(tkey, entries);
248f9510887SSimon J. Gerraty 			printf("openpgp_trust_revoke(%s)\n", key->id);
249f9510887SSimon J. Gerraty 			memset(key, 0, sizeof(OpenPGP_key));
250f9510887SSimon J. Gerraty 			free(key);
251f9510887SSimon J. Gerraty 			return (1);
252f9510887SSimon J. Gerraty 		}
253f9510887SSimon J. Gerraty 	}
254f9510887SSimon J. Gerraty 	return (0);
255f9510887SSimon J. Gerraty }
256f9510887SSimon J. Gerraty 
257f9510887SSimon J. Gerraty /**
2585fff9558SSimon J. Gerraty  * @brief if keyID is in our list return the key
2595fff9558SSimon J. Gerraty  *
2605fff9558SSimon J. Gerraty  * @return key or NULL
2615fff9558SSimon J. Gerraty  */
2625fff9558SSimon J. Gerraty OpenPGP_key *
openpgp_trust_get(const char * keyID)2635fff9558SSimon J. Gerraty openpgp_trust_get(const char *keyID)
2645fff9558SSimon J. Gerraty {
2655fff9558SSimon J. Gerraty 	OpenPGP_key *key;
2665fff9558SSimon J. Gerraty 
2675fff9558SSimon J. Gerraty 	openpgp_trust_add(NULL);	/* initialize if needed */
2685fff9558SSimon J. Gerraty 
2695fff9558SSimon J. Gerraty 	LIST_FOREACH(key, &trust_list, entries) {
2705fff9558SSimon J. Gerraty 		if (strcmp(key->id, keyID) == 0)
2715fff9558SSimon J. Gerraty 			return (key);
2725fff9558SSimon J. Gerraty 	}
2735fff9558SSimon J. Gerraty 	return (NULL);
2745fff9558SSimon J. Gerraty }
2755fff9558SSimon J. Gerraty 
2765fff9558SSimon J. Gerraty /**
2775fff9558SSimon J. Gerraty  * @brief load a key from file
2785fff9558SSimon J. Gerraty  */
2795fff9558SSimon J. Gerraty OpenPGP_key *
load_key_file(const char * kfile)2805fff9558SSimon J. Gerraty load_key_file(const char *kfile)
2815fff9558SSimon J. Gerraty {
2825fff9558SSimon J. Gerraty 	unsigned char *data = NULL;
2835fff9558SSimon J. Gerraty 	size_t n;
2845fff9558SSimon J. Gerraty 	OpenPGP_key *key;
2855fff9558SSimon J. Gerraty 
2865fff9558SSimon J. Gerraty 	data = read_file(kfile, &n);
2875fff9558SSimon J. Gerraty 	key = load_key_buf(data, n);
2885fff9558SSimon J. Gerraty 	free(data);
2895fff9558SSimon J. Gerraty 	openpgp_trust_add(key);
2905fff9558SSimon J. Gerraty 	return (key);
2915fff9558SSimon J. Gerraty }
2925fff9558SSimon J. Gerraty 
293f9510887SSimon J. Gerraty #ifdef HAVE_TA_ASC_H
2945fff9558SSimon J. Gerraty #include <ta_asc.h>
295f9510887SSimon J. Gerraty #endif
2965fff9558SSimon J. Gerraty 
2975fff9558SSimon J. Gerraty #ifndef _STANDALONE
2985fff9558SSimon J. Gerraty /* we can lookup keyID in filesystem */
2995fff9558SSimon J. Gerraty 
3005fff9558SSimon J. Gerraty static const char *trust_store[] = {
3015fff9558SSimon J. Gerraty 	"/var/db/trust",
3025fff9558SSimon J. Gerraty 	"/etc/db/trust",
3035fff9558SSimon J. Gerraty 	NULL,
3045fff9558SSimon J. Gerraty };
3055fff9558SSimon J. Gerraty 
3065fff9558SSimon J. Gerraty /**
3075fff9558SSimon J. Gerraty  * @brief lookup key id in trust store
3085fff9558SSimon J. Gerraty  *
3095fff9558SSimon J. Gerraty  */
3105fff9558SSimon J. Gerraty static OpenPGP_key *
load_trusted_key_id(const char * keyID)3115fff9558SSimon J. Gerraty load_trusted_key_id(const char *keyID)
3125fff9558SSimon J. Gerraty {
3135fff9558SSimon J. Gerraty 	char kfile[MAXPATHLEN];
3145fff9558SSimon J. Gerraty 	const char **tp;
3155fff9558SSimon J. Gerraty 	size_t n;
3165fff9558SSimon J. Gerraty 
3175fff9558SSimon J. Gerraty 	for (tp = trust_store; *tp; tp++) {
3185fff9558SSimon J. Gerraty 		n = (size_t)snprintf(kfile, sizeof(kfile), "%s/%s", *tp, keyID);
3195fff9558SSimon J. Gerraty 		if (n >= sizeof(kfile))
3205fff9558SSimon J. Gerraty 			return (NULL);
3215fff9558SSimon J. Gerraty 		if (access(kfile, R_OK) == 0) {
3225fff9558SSimon J. Gerraty 			return (load_key_file(kfile));
3235fff9558SSimon J. Gerraty 		}
3245fff9558SSimon J. Gerraty 	}
3255fff9558SSimon J. Gerraty 	return (NULL);
3265fff9558SSimon J. Gerraty }
3275fff9558SSimon J. Gerraty #endif
3285fff9558SSimon J. Gerraty 
3295fff9558SSimon J. Gerraty /**
3305fff9558SSimon J. Gerraty  * @brief return key if trusted
3315fff9558SSimon J. Gerraty  */
3325fff9558SSimon J. Gerraty OpenPGP_key *
load_key_id(const char * keyID)3335fff9558SSimon J. Gerraty load_key_id(const char *keyID)
3345fff9558SSimon J. Gerraty {
3355fff9558SSimon J. Gerraty 	OpenPGP_key *key;
3365fff9558SSimon J. Gerraty 
3375fff9558SSimon J. Gerraty 	key = openpgp_trust_get(keyID);
3385fff9558SSimon J. Gerraty #ifndef _STANDALONE
3395fff9558SSimon J. Gerraty 	if (!key)
3405fff9558SSimon J. Gerraty 		key = load_trusted_key_id(keyID);
3415fff9558SSimon J. Gerraty #endif
342e5ec655dSSimon J. Gerraty 	DEBUG_PRINTF(2, ("load_key_id(%s): %s\n", keyID, key ? "found" : "nope"));
3435fff9558SSimon J. Gerraty 	return (key);
3445fff9558SSimon J. Gerraty }
3455fff9558SSimon J. Gerraty 
3465fff9558SSimon J. Gerraty /**
3479bee6a60SSimon J. Gerraty  * @brief initialize our internal trust store if any
3489bee6a60SSimon J. Gerraty  */
3499bee6a60SSimon J. Gerraty int
openpgp_trust_init(void)3509bee6a60SSimon J. Gerraty openpgp_trust_init(void)
3519bee6a60SSimon J. Gerraty {
3529bee6a60SSimon J. Gerraty 	static int once = -1;
3539bee6a60SSimon J. Gerraty #ifdef HAVE_TA_ASC
3549bee6a60SSimon J. Gerraty 	OpenPGP_key *key;
3559bee6a60SSimon J. Gerraty 	const char **tp;
3569bee6a60SSimon J. Gerraty 	char *cp;
3579bee6a60SSimon J. Gerraty 	size_t n;
3589bee6a60SSimon J. Gerraty #endif
3599bee6a60SSimon J. Gerraty 
3609bee6a60SSimon J. Gerraty 	if (once < 0) {
3619bee6a60SSimon J. Gerraty 		once = 0;
3629bee6a60SSimon J. Gerraty #ifdef HAVE_TA_ASC
3639bee6a60SSimon J. Gerraty 		for (tp = ta_ASC; *tp; tp++) {
3649bee6a60SSimon J. Gerraty 			if ((cp = strdup(*tp))) {
3659bee6a60SSimon J. Gerraty 				n = strlen(cp);
3669bee6a60SSimon J. Gerraty 				key = load_key_buf((unsigned char *)cp, n);
3679bee6a60SSimon J. Gerraty 				free(cp);
3689bee6a60SSimon J. Gerraty 				if (key) {
3699bee6a60SSimon J. Gerraty 					openpgp_trust_add(key);
3709bee6a60SSimon J. Gerraty 					once++;
3719bee6a60SSimon J. Gerraty 				}
3729bee6a60SSimon J. Gerraty 			}
3739bee6a60SSimon J. Gerraty 		}
3749bee6a60SSimon J. Gerraty #endif
375f9510887SSimon J. Gerraty 	}
3769bee6a60SSimon J. Gerraty 	return (once);
3779bee6a60SSimon J. Gerraty }
3789bee6a60SSimon J. Gerraty 
3799bee6a60SSimon J. Gerraty /**
3805fff9558SSimon J. Gerraty  * @brief test that we can verify a signature
3815fff9558SSimon J. Gerraty  *
3825fff9558SSimon J. Gerraty  * Unlike X.509 certificates, we only support RSA keys
3835fff9558SSimon J. Gerraty  * so we stop after first successful signature verification
3845fff9558SSimon J. Gerraty  * (which should also be the first attempt ;-)
3855fff9558SSimon J. Gerraty  */
3865fff9558SSimon J. Gerraty int
openpgp_self_tests(void)3875fff9558SSimon J. Gerraty openpgp_self_tests(void)
3885fff9558SSimon J. Gerraty {
3895fff9558SSimon J. Gerraty 	static int rc = -1;		/* remember result */
3905fff9558SSimon J. Gerraty #ifdef HAVE_VC_ASC
3915fff9558SSimon J. Gerraty 	const char **vp, **tp;
3925fff9558SSimon J. Gerraty 	char *fdata, *sdata = NULL;
3935fff9558SSimon J. Gerraty 	size_t fbytes, sbytes;
3945fff9558SSimon J. Gerraty 
3959bee6a60SSimon J. Gerraty 	if (openpgp_trust_init() > 0) {
3965fff9558SSimon J. Gerraty 		for (tp = ta_ASC, vp = vc_ASC; *tp && *vp && rc; tp++, vp++) {
3975fff9558SSimon J. Gerraty 			if ((fdata = strdup(*tp)) &&
3985fff9558SSimon J. Gerraty 			    (sdata = strdup(*vp))) {
3995fff9558SSimon J. Gerraty 				fbytes = strlen(fdata);
4005fff9558SSimon J. Gerraty 				sbytes = strlen(sdata);
4015fff9558SSimon J. Gerraty 				rc = openpgp_verify("ta_ASC",
4025fff9558SSimon J. Gerraty 				    (unsigned char *)fdata, fbytes,
4035fff9558SSimon J. Gerraty 				    (unsigned char *)sdata, sbytes, 0);
4045fff9558SSimon J. Gerraty 				printf("Testing verify OpenPGP signature:\t\t%s\n",
4055fff9558SSimon J. Gerraty 				    rc ? "Failed" : "Passed");
4065fff9558SSimon J. Gerraty 			}
4075fff9558SSimon J. Gerraty 			free(fdata);
4085fff9558SSimon J. Gerraty 			free(sdata);
4095fff9558SSimon J. Gerraty 		}
4109bee6a60SSimon J. Gerraty 	}
4115fff9558SSimon J. Gerraty #endif
4125fff9558SSimon J. Gerraty 	return (rc);
4135fff9558SSimon J. Gerraty }
414