xref: /dragonfly/crypto/libressl/tls/tls_keypair.c (revision de0e0e4d)
1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: tls_keypair.c,v 1.8 2021/01/05 17:37:12 jsing Exp $ */
272c33676SMaxim Ag /*
372c33676SMaxim Ag  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
472c33676SMaxim Ag  *
572c33676SMaxim Ag  * Permission to use, copy, modify, and distribute this software for any
672c33676SMaxim Ag  * purpose with or without fee is hereby granted, provided that the above
772c33676SMaxim Ag  * copyright notice and this permission notice appear in all copies.
872c33676SMaxim Ag  *
972c33676SMaxim Ag  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1072c33676SMaxim Ag  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1172c33676SMaxim Ag  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1272c33676SMaxim Ag  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1372c33676SMaxim Ag  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1472c33676SMaxim Ag  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1572c33676SMaxim Ag  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1672c33676SMaxim Ag  */
1772c33676SMaxim Ag 
1872c33676SMaxim Ag #include <openssl/bio.h>
1972c33676SMaxim Ag #include <openssl/err.h>
2072c33676SMaxim Ag #include <openssl/pem.h>
2172c33676SMaxim Ag 
2272c33676SMaxim Ag #include <tls.h>
2372c33676SMaxim Ag 
2472c33676SMaxim Ag #include "tls_internal.h"
2572c33676SMaxim Ag 
2672c33676SMaxim Ag struct tls_keypair *
tls_keypair_new(void)2772c33676SMaxim Ag tls_keypair_new(void)
2872c33676SMaxim Ag {
2972c33676SMaxim Ag 	return calloc(1, sizeof(struct tls_keypair));
3072c33676SMaxim Ag }
3172c33676SMaxim Ag 
3272c33676SMaxim Ag static int
tls_keypair_pubkey_hash(struct tls_keypair * keypair,struct tls_error * error)3372c33676SMaxim Ag tls_keypair_pubkey_hash(struct tls_keypair *keypair, struct tls_error *error)
3472c33676SMaxim Ag {
3572c33676SMaxim Ag 	X509 *cert = NULL;
3672c33676SMaxim Ag 	int rv = -1;
3772c33676SMaxim Ag 
3872c33676SMaxim Ag 	free(keypair->pubkey_hash);
3972c33676SMaxim Ag 	keypair->pubkey_hash = NULL;
4072c33676SMaxim Ag 
4172c33676SMaxim Ag 	if (keypair->cert_mem == NULL) {
4272c33676SMaxim Ag 		rv = 0;
4372c33676SMaxim Ag 		goto done;
4472c33676SMaxim Ag 	}
4572c33676SMaxim Ag 
4672c33676SMaxim Ag 	if (tls_keypair_load_cert(keypair, error, &cert) == -1)
4772c33676SMaxim Ag 		goto err;
4872c33676SMaxim Ag 	if (tls_cert_pubkey_hash(cert, &keypair->pubkey_hash) == -1)
4972c33676SMaxim Ag 		goto err;
5072c33676SMaxim Ag 
5172c33676SMaxim Ag 	rv = 0;
5272c33676SMaxim Ag 
5372c33676SMaxim Ag  err:
5472c33676SMaxim Ag 	X509_free(cert);
5572c33676SMaxim Ag  done:
5672c33676SMaxim Ag 	return (rv);
5772c33676SMaxim Ag }
5872c33676SMaxim Ag 
5972c33676SMaxim Ag void
tls_keypair_clear_key(struct tls_keypair * keypair)6072c33676SMaxim Ag tls_keypair_clear_key(struct tls_keypair *keypair)
6172c33676SMaxim Ag {
6272c33676SMaxim Ag 	freezero(keypair->key_mem, keypair->key_len);
6372c33676SMaxim Ag 	keypair->key_mem = NULL;
6472c33676SMaxim Ag 	keypair->key_len = 0;
6572c33676SMaxim Ag }
6672c33676SMaxim Ag 
6772c33676SMaxim Ag int
tls_keypair_set_cert_file(struct tls_keypair * keypair,struct tls_error * error,const char * cert_file)6872c33676SMaxim Ag tls_keypair_set_cert_file(struct tls_keypair *keypair, struct tls_error *error,
6972c33676SMaxim Ag     const char *cert_file)
7072c33676SMaxim Ag {
7172c33676SMaxim Ag 	if (tls_config_load_file(error, "certificate", cert_file,
7272c33676SMaxim Ag 	    &keypair->cert_mem, &keypair->cert_len) == -1)
7372c33676SMaxim Ag 		return -1;
7472c33676SMaxim Ag 	return tls_keypair_pubkey_hash(keypair, error);
7572c33676SMaxim Ag }
7672c33676SMaxim Ag 
7772c33676SMaxim Ag int
tls_keypair_set_cert_mem(struct tls_keypair * keypair,struct tls_error * error,const uint8_t * cert,size_t len)7872c33676SMaxim Ag tls_keypair_set_cert_mem(struct tls_keypair *keypair, struct tls_error *error,
7972c33676SMaxim Ag     const uint8_t *cert, size_t len)
8072c33676SMaxim Ag {
8172c33676SMaxim Ag 	if (tls_set_mem(&keypair->cert_mem, &keypair->cert_len, cert, len) == -1)
8272c33676SMaxim Ag 		return -1;
8372c33676SMaxim Ag 	return tls_keypair_pubkey_hash(keypair, error);
8472c33676SMaxim Ag }
8572c33676SMaxim Ag 
8672c33676SMaxim Ag int
tls_keypair_set_key_file(struct tls_keypair * keypair,struct tls_error * error,const char * key_file)8772c33676SMaxim Ag tls_keypair_set_key_file(struct tls_keypair *keypair, struct tls_error *error,
8872c33676SMaxim Ag     const char *key_file)
8972c33676SMaxim Ag {
9072c33676SMaxim Ag 	tls_keypair_clear_key(keypair);
9172c33676SMaxim Ag 	return tls_config_load_file(error, "key", key_file,
9272c33676SMaxim Ag 	    &keypair->key_mem, &keypair->key_len);
9372c33676SMaxim Ag }
9472c33676SMaxim Ag 
9572c33676SMaxim Ag int
tls_keypair_set_key_mem(struct tls_keypair * keypair,struct tls_error * error,const uint8_t * key,size_t len)9672c33676SMaxim Ag tls_keypair_set_key_mem(struct tls_keypair *keypair, struct tls_error *error,
9772c33676SMaxim Ag     const uint8_t *key, size_t len)
9872c33676SMaxim Ag {
9972c33676SMaxim Ag 	tls_keypair_clear_key(keypair);
10072c33676SMaxim Ag 	return tls_set_mem(&keypair->key_mem, &keypair->key_len, key, len);
10172c33676SMaxim Ag }
10272c33676SMaxim Ag 
10372c33676SMaxim Ag int
tls_keypair_set_ocsp_staple_file(struct tls_keypair * keypair,struct tls_error * error,const char * ocsp_file)10472c33676SMaxim Ag tls_keypair_set_ocsp_staple_file(struct tls_keypair *keypair,
10572c33676SMaxim Ag     struct tls_error *error, const char *ocsp_file)
10672c33676SMaxim Ag {
10772c33676SMaxim Ag 	return tls_config_load_file(error, "ocsp", ocsp_file,
10872c33676SMaxim Ag 	    &keypair->ocsp_staple, &keypair->ocsp_staple_len);
10972c33676SMaxim Ag }
11072c33676SMaxim Ag 
11172c33676SMaxim Ag int
tls_keypair_set_ocsp_staple_mem(struct tls_keypair * keypair,struct tls_error * error,const uint8_t * staple,size_t len)11272c33676SMaxim Ag tls_keypair_set_ocsp_staple_mem(struct tls_keypair *keypair,
11372c33676SMaxim Ag     struct tls_error *error, const uint8_t *staple, size_t len)
11472c33676SMaxim Ag {
11572c33676SMaxim Ag 	return tls_set_mem(&keypair->ocsp_staple, &keypair->ocsp_staple_len,
11672c33676SMaxim Ag 	    staple, len);
11772c33676SMaxim Ag }
11872c33676SMaxim Ag 
11972c33676SMaxim Ag void
tls_keypair_free(struct tls_keypair * keypair)12072c33676SMaxim Ag tls_keypair_free(struct tls_keypair *keypair)
12172c33676SMaxim Ag {
12272c33676SMaxim Ag 	if (keypair == NULL)
12372c33676SMaxim Ag 		return;
12472c33676SMaxim Ag 
12572c33676SMaxim Ag 	tls_keypair_clear_key(keypair);
12672c33676SMaxim Ag 
12772c33676SMaxim Ag 	free(keypair->cert_mem);
12872c33676SMaxim Ag 	free(keypair->ocsp_staple);
12972c33676SMaxim Ag 	free(keypair->pubkey_hash);
13072c33676SMaxim Ag 
13172c33676SMaxim Ag 	free(keypair);
13272c33676SMaxim Ag }
13372c33676SMaxim Ag 
13472c33676SMaxim Ag int
tls_keypair_load_cert(struct tls_keypair * keypair,struct tls_error * error,X509 ** cert)13572c33676SMaxim Ag tls_keypair_load_cert(struct tls_keypair *keypair, struct tls_error *error,
13672c33676SMaxim Ag     X509 **cert)
13772c33676SMaxim Ag {
13872c33676SMaxim Ag 	char *errstr = "unknown";
13972c33676SMaxim Ag 	BIO *cert_bio = NULL;
140*de0e0e4dSAntonio Huete Jimenez 	unsigned long ssl_err;
14172c33676SMaxim Ag 	int rv = -1;
14272c33676SMaxim Ag 
14372c33676SMaxim Ag 	X509_free(*cert);
14472c33676SMaxim Ag 	*cert = NULL;
14572c33676SMaxim Ag 
14672c33676SMaxim Ag 	if (keypair->cert_mem == NULL) {
14772c33676SMaxim Ag 		tls_error_set(error, "keypair has no certificate");
14872c33676SMaxim Ag 		goto err;
14972c33676SMaxim Ag 	}
15072c33676SMaxim Ag 	if ((cert_bio = BIO_new_mem_buf(keypair->cert_mem,
15172c33676SMaxim Ag 	    keypair->cert_len)) == NULL) {
15272c33676SMaxim Ag 		tls_error_set(error, "failed to create certificate bio");
15372c33676SMaxim Ag 		goto err;
15472c33676SMaxim Ag 	}
15572c33676SMaxim Ag 	if ((*cert = PEM_read_bio_X509(cert_bio, NULL, tls_password_cb,
15672c33676SMaxim Ag 	    NULL)) == NULL) {
15772c33676SMaxim Ag 		if ((ssl_err = ERR_peek_error()) != 0)
15872c33676SMaxim Ag 			errstr = ERR_error_string(ssl_err, NULL);
15972c33676SMaxim Ag 		tls_error_set(error, "failed to load certificate: %s", errstr);
16072c33676SMaxim Ag 		goto err;
16172c33676SMaxim Ag 	}
16272c33676SMaxim Ag 
16372c33676SMaxim Ag 	rv = 0;
16472c33676SMaxim Ag 
16572c33676SMaxim Ag  err:
16672c33676SMaxim Ag 	BIO_free(cert_bio);
16772c33676SMaxim Ag 
16872c33676SMaxim Ag 	return (rv);
16972c33676SMaxim Ag }
170