summaryrefslogtreecommitdiffstats
path: root/lib/libtls
diff options
context:
space:
mode:
authoreric <eric@openbsd.org>2021-01-21 19:09:10 +0000
committereric <eric@openbsd.org>2021-01-21 19:09:10 +0000
commit15339a8c6b46d6aea4f5df0384c38a8aef15f986 (patch)
treed41e970b6bc1645a9aa37f725a58dc9f9ea35b26 /lib/libtls
parentMop up unused dtls1_build_sequence_number() function. (diff)
downloadwireguard-openbsd-15339a8c6b46d6aea4f5df0384c38a8aef15f986.tar.xz
wireguard-openbsd-15339a8c6b46d6aea4f5df0384c38a8aef15f986.zip
Allow setting a keypair on a tls context without specifying the private
key, and fake it internally with the certificate public key instead. It makes it easier for privsep engines like relayd that don't have to use bogus keys anymore. ok beck@ tb@ jsing@
Diffstat (limited to 'lib/libtls')
-rw-r--r--lib/libtls/Symbols.list1
-rw-r--r--lib/libtls/tls.c84
-rw-r--r--lib/libtls/tls_config.c14
-rw-r--r--lib/libtls/tls_internal.h4
4 files changed, 77 insertions, 26 deletions
diff --git a/lib/libtls/Symbols.list b/lib/libtls/Symbols.list
index e3fcb67fb3f..42c039d2945 100644
--- a/lib/libtls/Symbols.list
+++ b/lib/libtls/Symbols.list
@@ -45,6 +45,7 @@ tls_config_set_session_lifetime
tls_config_set_session_fd
tls_config_set_verify_depth
tls_config_skip_private_key_check
+tls_config_use_fake_private_key
tls_config_verify
tls_config_verify_client
tls_config_verify_client_optional
diff --git a/lib/libtls/tls.c b/lib/libtls/tls.c
index 3d6723bbd9c..02ddf447fb3 100644
--- a/lib/libtls/tls.c
+++ b/lib/libtls/tls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.c,v 1.85 2020/05/24 15:12:54 jsing Exp $ */
+/* $OpenBSD: tls.c,v 1.86 2021/01/21 19:09:10 eric Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
@@ -326,12 +326,69 @@ tls_cert_pubkey_hash(X509 *cert, char **hash)
return (rv);
}
+static int
+tls_keypair_to_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY **pkey)
+{
+ BIO *bio = NULL;
+ X509 *x509 = NULL;
+ char *mem;
+ size_t len;
+ int ret = -1;
+
+ *pkey = NULL;
+
+ if (ctx->config->use_fake_private_key) {
+ mem = keypair->cert_mem;
+ len = keypair->cert_len;
+ } else {
+ mem = keypair->key_mem;
+ len = keypair->key_len;
+ }
+
+ if (mem == NULL)
+ return (0);
+
+ if (len > INT_MAX) {
+ tls_set_errorx(ctx, ctx->config->use_fake_private_key ?
+ "cert too long" : "key too long");
+ goto err;
+ }
+
+ if ((bio = BIO_new_mem_buf(mem, len)) == NULL) {
+ tls_set_errorx(ctx, "failed to create buffer");
+ goto err;
+ }
+
+ if (ctx->config->use_fake_private_key) {
+ if ((x509 = PEM_read_bio_X509(bio, NULL, tls_password_cb,
+ NULL)) == NULL) {
+ tls_set_errorx(ctx, "failed to read X509 certificate");
+ goto err;
+ }
+ if ((*pkey = X509_get_pubkey(x509)) == NULL) {
+ tls_set_errorx(ctx, "failed to retrieve pubkey");
+ goto err;
+ }
+ } else {
+ if ((*pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb,
+ NULL)) == NULL) {
+ tls_set_errorx(ctx, "failed to read private key");
+ goto err;
+ }
+ }
+
+ ret = 0;
+ err:
+ BIO_free(bio);
+ X509_free(x509);
+ return (ret);
+}
+
int
tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx,
struct tls_keypair *keypair, int required)
{
EVP_PKEY *pkey = NULL;
- BIO *bio = NULL;
if (!required &&
keypair->cert_mem == NULL &&
@@ -351,23 +408,9 @@ tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx,
}
}
- if (keypair->key_mem != NULL) {
- if (keypair->key_len > INT_MAX) {
- tls_set_errorx(ctx, "key too long");
- goto err;
- }
-
- if ((bio = BIO_new_mem_buf(keypair->key_mem,
- keypair->key_len)) == NULL) {
- tls_set_errorx(ctx, "failed to create buffer");
- goto err;
- }
- if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb,
- NULL)) == NULL) {
- tls_set_errorx(ctx, "failed to read private key");
- goto err;
- }
-
+ if (tls_keypair_to_pkey(ctx, keypair, &pkey) == -1)
+ goto err;
+ if (pkey != NULL) {
if (keypair->pubkey_hash != NULL) {
RSA *rsa;
/* XXX only RSA for now for relayd privsep */
@@ -381,8 +424,6 @@ tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx,
tls_set_errorx(ctx, "failed to load private key");
goto err;
}
- BIO_free(bio);
- bio = NULL;
EVP_PKEY_free(pkey);
pkey = NULL;
}
@@ -397,7 +438,6 @@ tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx,
err:
EVP_PKEY_free(pkey);
- BIO_free(bio);
return (1);
}
diff --git a/lib/libtls/tls_config.c b/lib/libtls/tls_config.c
index 7a0d6d8adf2..e3e90aaa007 100644
--- a/lib/libtls/tls_config.c
+++ b/lib/libtls/tls_config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_config.c,v 1.61 2020/12/22 13:07:54 bcook Exp $ */
+/* $OpenBSD: tls_config.c,v 1.62 2021/01/21 19:09:10 eric Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
@@ -353,7 +353,8 @@ tls_config_add_keypair_file_internal(struct tls_config *config,
return (-1);
if (tls_keypair_set_cert_file(keypair, &config->error, cert_file) != 0)
goto err;
- if (tls_keypair_set_key_file(keypair, &config->error, key_file) != 0)
+ if (key_file != NULL &&
+ tls_keypair_set_key_file(keypair, &config->error, key_file) != 0)
goto err;
if (ocsp_file != NULL &&
tls_keypair_set_ocsp_staple_file(keypair, &config->error,
@@ -380,7 +381,8 @@ tls_config_add_keypair_mem_internal(struct tls_config *config, const uint8_t *ce
return (-1);
if (tls_keypair_set_cert_mem(keypair, &config->error, cert, cert_len) != 0)
goto err;
- if (tls_keypair_set_key_mem(keypair, &config->error, key, key_len) != 0)
+ if (key != NULL &&
+ tls_keypair_set_key_mem(keypair, &config->error, key, key_len) != 0)
goto err;
if (staple != NULL &&
tls_keypair_set_ocsp_staple_mem(keypair, &config->error, staple,
@@ -805,6 +807,12 @@ tls_config_skip_private_key_check(struct tls_config *config)
config->skip_private_key_check = 1;
}
+void
+tls_config_use_fake_private_key(struct tls_config *config)
+{
+ config->use_fake_private_key = 1;
+}
+
int
tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file)
{
diff --git a/lib/libtls/tls_internal.h b/lib/libtls/tls_internal.h
index 1dd5f45dddb..5487b123ec6 100644
--- a/lib/libtls/tls_internal.h
+++ b/lib/libtls/tls_internal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_internal.h,v 1.77 2019/11/16 21:39:52 beck Exp $ */
+/* $OpenBSD: tls_internal.h,v 1.78 2021/01/21 19:09:10 eric Exp $ */
/*
* Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -111,6 +111,7 @@ struct tls_config {
int verify_name;
int verify_time;
int skip_private_key_check;
+ int use_fake_private_key;
};
struct tls_conninfo {
@@ -294,5 +295,6 @@ __END_HIDDEN_DECLS
/* XXX this function is not fully hidden so relayd can use it */
void tls_config_skip_private_key_check(struct tls_config *config);
+void tls_config_use_fake_private_key(struct tls_config *config);
#endif /* HEADER_TLS_INTERNAL_H */