xref: /openbsd/lib/libtls/tls_keypair.c (revision 2974e8f1)
1*2974e8f1Sjsing /* $OpenBSD: tls_keypair.c,v 1.5 2018/02/10 04:57:35 jsing Exp $ */
2bb4cb1b0Sjsing /*
3bb4cb1b0Sjsing  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4bb4cb1b0Sjsing  *
5bb4cb1b0Sjsing  * Permission to use, copy, modify, and distribute this software for any
6bb4cb1b0Sjsing  * purpose with or without fee is hereby granted, provided that the above
7bb4cb1b0Sjsing  * copyright notice and this permission notice appear in all copies.
8bb4cb1b0Sjsing  *
9bb4cb1b0Sjsing  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10bb4cb1b0Sjsing  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11bb4cb1b0Sjsing  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12bb4cb1b0Sjsing  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13bb4cb1b0Sjsing  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14bb4cb1b0Sjsing  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15bb4cb1b0Sjsing  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16bb4cb1b0Sjsing  */
17bb4cb1b0Sjsing 
18bb4cb1b0Sjsing #include <openssl/bio.h>
19bb4cb1b0Sjsing #include <openssl/err.h>
20bb4cb1b0Sjsing #include <openssl/pem.h>
21bb4cb1b0Sjsing 
22bb4cb1b0Sjsing #include <tls.h>
23bb4cb1b0Sjsing 
24bb4cb1b0Sjsing #include "tls_internal.h"
25bb4cb1b0Sjsing 
26bb4cb1b0Sjsing struct tls_keypair *
27bb4cb1b0Sjsing tls_keypair_new(void)
28bb4cb1b0Sjsing {
29bb4cb1b0Sjsing 	return calloc(1, sizeof(struct tls_keypair));
30bb4cb1b0Sjsing }
31bb4cb1b0Sjsing 
32*2974e8f1Sjsing static void
33bb4cb1b0Sjsing tls_keypair_clear_key(struct tls_keypair *keypair)
34bb4cb1b0Sjsing {
35bb4cb1b0Sjsing 	freezero(keypair->key_mem, keypair->key_len);
36bb4cb1b0Sjsing 	keypair->key_mem = NULL;
37bb4cb1b0Sjsing 	keypair->key_len = 0;
38bb4cb1b0Sjsing }
39bb4cb1b0Sjsing 
40*2974e8f1Sjsing static int
41*2974e8f1Sjsing tls_keypair_pubkey_hash(struct tls_keypair *keypair, struct tls_error *error)
42*2974e8f1Sjsing {
43*2974e8f1Sjsing 	X509 *cert = NULL;
44*2974e8f1Sjsing 	int rv = -1;
45*2974e8f1Sjsing 
46*2974e8f1Sjsing 	free(keypair->pubkey_hash);
47*2974e8f1Sjsing 	keypair->pubkey_hash = NULL;
48*2974e8f1Sjsing 
49*2974e8f1Sjsing 	if (keypair->cert_mem == NULL) {
50*2974e8f1Sjsing 		rv = 0;
51*2974e8f1Sjsing 		goto done;
52*2974e8f1Sjsing 	}
53*2974e8f1Sjsing 
54*2974e8f1Sjsing 	if (tls_keypair_load_cert(keypair, error, &cert) == -1)
55*2974e8f1Sjsing 		goto err;
56*2974e8f1Sjsing 	if (tls_cert_pubkey_hash(cert, &keypair->pubkey_hash) == -1)
57*2974e8f1Sjsing 		goto err;
58*2974e8f1Sjsing 
59*2974e8f1Sjsing 	rv = 0;
60*2974e8f1Sjsing 
61*2974e8f1Sjsing  err:
62*2974e8f1Sjsing 	X509_free(cert);
63*2974e8f1Sjsing  done:
64*2974e8f1Sjsing 	return (rv);
65*2974e8f1Sjsing }
66*2974e8f1Sjsing 
67bb4cb1b0Sjsing int
68bb4cb1b0Sjsing tls_keypair_set_cert_file(struct tls_keypair *keypair, struct tls_error *error,
69bb4cb1b0Sjsing     const char *cert_file)
70bb4cb1b0Sjsing {
71*2974e8f1Sjsing 	if (tls_config_load_file(error, "certificate", cert_file,
72*2974e8f1Sjsing 	    &keypair->cert_mem, &keypair->cert_len) == -1)
73*2974e8f1Sjsing 		return -1;
74*2974e8f1Sjsing 	return tls_keypair_pubkey_hash(keypair, error);
75bb4cb1b0Sjsing }
76bb4cb1b0Sjsing 
77bb4cb1b0Sjsing int
78*2974e8f1Sjsing tls_keypair_set_cert_mem(struct tls_keypair *keypair, struct tls_error *error,
79*2974e8f1Sjsing     const uint8_t *cert, size_t len)
80bb4cb1b0Sjsing {
81*2974e8f1Sjsing 	if (tls_set_mem(&keypair->cert_mem, &keypair->cert_len, cert, len) == -1)
82*2974e8f1Sjsing 		return -1;
83*2974e8f1Sjsing 	return tls_keypair_pubkey_hash(keypair, error);
84bb4cb1b0Sjsing }
85bb4cb1b0Sjsing 
86bb4cb1b0Sjsing int
87bb4cb1b0Sjsing tls_keypair_set_key_file(struct tls_keypair *keypair, struct tls_error *error,
88bb4cb1b0Sjsing     const char *key_file)
89bb4cb1b0Sjsing {
90bb4cb1b0Sjsing 	tls_keypair_clear_key(keypair);
91bb4cb1b0Sjsing 	return tls_config_load_file(error, "key", key_file,
92bb4cb1b0Sjsing 	    &keypair->key_mem, &keypair->key_len);
93bb4cb1b0Sjsing }
94bb4cb1b0Sjsing 
95bb4cb1b0Sjsing int
96*2974e8f1Sjsing tls_keypair_set_key_mem(struct tls_keypair *keypair, struct tls_error *error,
97*2974e8f1Sjsing     const uint8_t *key, size_t len)
98bb4cb1b0Sjsing {
99bb4cb1b0Sjsing 	tls_keypair_clear_key(keypair);
100bb4cb1b0Sjsing 	return tls_set_mem(&keypair->key_mem, &keypair->key_len, key, len);
101bb4cb1b0Sjsing }
102bb4cb1b0Sjsing 
103bb4cb1b0Sjsing int
104bb4cb1b0Sjsing tls_keypair_set_ocsp_staple_file(struct tls_keypair *keypair,
105bb4cb1b0Sjsing     struct tls_error *error, const char *ocsp_file)
106bb4cb1b0Sjsing {
107bb4cb1b0Sjsing 	return tls_config_load_file(error, "ocsp", ocsp_file,
108bb4cb1b0Sjsing 	    &keypair->ocsp_staple, &keypair->ocsp_staple_len);
109bb4cb1b0Sjsing }
110bb4cb1b0Sjsing 
111bb4cb1b0Sjsing int
112bb4cb1b0Sjsing tls_keypair_set_ocsp_staple_mem(struct tls_keypair *keypair,
113*2974e8f1Sjsing     struct tls_error *error, const uint8_t *staple, size_t len)
114bb4cb1b0Sjsing {
115bb4cb1b0Sjsing 	return tls_set_mem(&keypair->ocsp_staple, &keypair->ocsp_staple_len,
116bb4cb1b0Sjsing 	    staple, len);
117bb4cb1b0Sjsing }
118bb4cb1b0Sjsing 
119bb4cb1b0Sjsing void
120bb4cb1b0Sjsing tls_keypair_clear(struct tls_keypair *keypair)
121bb4cb1b0Sjsing {
122*2974e8f1Sjsing 	struct tls_error error;
123*2974e8f1Sjsing 
124*2974e8f1Sjsing 	tls_keypair_set_cert_mem(keypair, &error, NULL, 0);
125*2974e8f1Sjsing 	tls_keypair_set_key_mem(keypair, &error, NULL, 0);
126*2974e8f1Sjsing 	tls_keypair_set_ocsp_staple_mem(keypair, &error, NULL, 0);
12705729e6fSjsing 
12805729e6fSjsing 	free(keypair->pubkey_hash);
12905729e6fSjsing 	keypair->pubkey_hash = NULL;
130bb4cb1b0Sjsing }
131bb4cb1b0Sjsing 
132bb4cb1b0Sjsing void
133bb4cb1b0Sjsing tls_keypair_free(struct tls_keypair *keypair)
134bb4cb1b0Sjsing {
135bb4cb1b0Sjsing 	if (keypair == NULL)
136bb4cb1b0Sjsing 		return;
137bb4cb1b0Sjsing 
138bb4cb1b0Sjsing 	tls_keypair_clear(keypair);
139bb4cb1b0Sjsing 
140bb4cb1b0Sjsing 	free(keypair);
141bb4cb1b0Sjsing }
142bb4cb1b0Sjsing 
143bb4cb1b0Sjsing int
144bb4cb1b0Sjsing tls_keypair_load_cert(struct tls_keypair *keypair, struct tls_error *error,
145bb4cb1b0Sjsing     X509 **cert)
146bb4cb1b0Sjsing {
147bb4cb1b0Sjsing 	char *errstr = "unknown";
148bb4cb1b0Sjsing 	BIO *cert_bio = NULL;
149bb4cb1b0Sjsing 	int ssl_err;
150bb4cb1b0Sjsing 	int rv = -1;
151bb4cb1b0Sjsing 
152bb4cb1b0Sjsing 	X509_free(*cert);
153bb4cb1b0Sjsing 	*cert = NULL;
154bb4cb1b0Sjsing 
155bb4cb1b0Sjsing 	if (keypair->cert_mem == NULL) {
156bb4cb1b0Sjsing 		tls_error_set(error, "keypair has no certificate");
157bb4cb1b0Sjsing 		goto err;
158bb4cb1b0Sjsing 	}
159bb4cb1b0Sjsing 	if ((cert_bio = BIO_new_mem_buf(keypair->cert_mem,
160bb4cb1b0Sjsing 	    keypair->cert_len)) == NULL) {
161bb4cb1b0Sjsing 		tls_error_set(error, "failed to create certificate bio");
162bb4cb1b0Sjsing 		goto err;
163bb4cb1b0Sjsing 	}
164bb4cb1b0Sjsing 	if ((*cert = PEM_read_bio_X509(cert_bio, NULL, tls_password_cb,
165bb4cb1b0Sjsing 	    NULL)) == NULL) {
166bb4cb1b0Sjsing 		if ((ssl_err = ERR_peek_error()) != 0)
167bb4cb1b0Sjsing 		    errstr = ERR_error_string(ssl_err, NULL);
168bb4cb1b0Sjsing 		tls_error_set(error, "failed to load certificate: %s", errstr);
169bb4cb1b0Sjsing 		goto err;
170bb4cb1b0Sjsing 	}
171bb4cb1b0Sjsing 
172bb4cb1b0Sjsing 	rv = 0;
173bb4cb1b0Sjsing 
174bb4cb1b0Sjsing  err:
175bb4cb1b0Sjsing 	BIO_free(cert_bio);
176bb4cb1b0Sjsing 
177bb4cb1b0Sjsing 	return (rv);
178bb4cb1b0Sjsing }
179