early-access version 2698
This commit is contained in:
29
externals/libressl/tls/CMakeLists.txt
vendored
29
externals/libressl/tls/CMakeLists.txt
vendored
@@ -7,6 +7,7 @@ set(
|
||||
tls_conninfo.c
|
||||
tls_keypair.c
|
||||
tls_server.c
|
||||
tls_signer.c
|
||||
tls_ocsp.c
|
||||
tls_peer.c
|
||||
tls_util.c
|
||||
@@ -29,16 +30,28 @@ else()
|
||||
add_definitions(-DTLS_DEFAULT_CA_FILE=\"${CMAKE_INSTALL_PREFIX}/etc/ssl/cert.pem\")
|
||||
endif()
|
||||
|
||||
add_library(tls ${TLS_SRC})
|
||||
target_include_directories(tls
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/tls.sym DESTINATION
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
if(LIBTLS_EXTRA_EXPORT)
|
||||
list(SORT LIBTLS_EXTRA_EXPORT)
|
||||
foreach(SYM IN LISTS LIBTLS_EXTRA_EXPORT)
|
||||
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/tls.sym "${SYM}\n")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
add_library(tls_obj OBJECT ${TLS_SRC})
|
||||
target_include_directories(tls_obj
|
||||
PRIVATE
|
||||
.
|
||||
../include/compat
|
||||
PUBLIC
|
||||
../include)
|
||||
|
||||
export_symbol(tls ${CMAKE_CURRENT_SOURCE_DIR}/tls.sym)
|
||||
target_link_libraries(tls ssl crypto ${PLATFORM_LIBS})
|
||||
add_library(tls $<TARGET_OBJECTS:tls_obj> $<TARGET_OBJECTS:ssl_obj>
|
||||
$<TARGET_OBJECTS:crypto_obj>)
|
||||
|
||||
export_symbol(tls ${CMAKE_CURRENT_BINARY_DIR}/tls.sym)
|
||||
target_link_libraries(tls ${PLATFORM_LIBS})
|
||||
if (WIN32)
|
||||
set(TLS_POSTFIX -${TLS_MAJOR_VERSION})
|
||||
endif()
|
||||
@@ -56,3 +69,11 @@ if(ENABLE_LIBRESSL_INSTALL)
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif(ENABLE_LIBRESSL_INSTALL)
|
||||
|
||||
# build static library for regression test
|
||||
if(BUILD_SHARED_LIBS)
|
||||
add_library(tls-static STATIC $<TARGET_OBJECTS:tls_obj>
|
||||
$<TARGET_OBJECTS:ssl_obj> $<TARGET_OBJECTS:crypto_obj>)
|
||||
target_link_libraries(tls-static ${PLATFORM_LIBS})
|
||||
endif()
|
||||
|
||||
|
2
externals/libressl/tls/VERSION
vendored
2
externals/libressl/tls/VERSION
vendored
@@ -1 +1 @@
|
||||
20:1:0
|
||||
25:0:0
|
||||
|
164
externals/libressl/tls/tls.c
vendored
164
externals/libressl/tls/tls.c
vendored
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tls.c,v 1.85 2020/05/24 15:12:54 jsing Exp $ */
|
||||
/* $OpenBSD: tls.c,v 1.94 2022/02/08 19:13:50 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
@@ -326,12 +326,131 @@ 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);
|
||||
}
|
||||
|
||||
static int
|
||||
tls_keypair_setup_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY *pkey)
|
||||
{
|
||||
RSA_METHOD *rsa_method;
|
||||
ECDSA_METHOD *ecdsa_method;
|
||||
RSA *rsa = NULL;
|
||||
EC_KEY *eckey = NULL;
|
||||
int ret = -1;
|
||||
|
||||
/* Only install the pubkey hash if fake private keys are used. */
|
||||
if (!ctx->config->skip_private_key_check)
|
||||
return (0);
|
||||
|
||||
if (keypair->pubkey_hash == NULL) {
|
||||
tls_set_errorx(ctx, "public key hash not set");
|
||||
goto err;
|
||||
}
|
||||
|
||||
switch (EVP_PKEY_id(pkey)) {
|
||||
case EVP_PKEY_RSA:
|
||||
if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL ||
|
||||
RSA_set_ex_data(rsa, 0, keypair->pubkey_hash) == 0) {
|
||||
tls_set_errorx(ctx, "RSA key setup failure");
|
||||
goto err;
|
||||
}
|
||||
if (ctx->config->sign_cb == NULL)
|
||||
break;
|
||||
if ((rsa_method = tls_signer_rsa_method()) == NULL ||
|
||||
RSA_set_ex_data(rsa, 1, ctx->config) == 0 ||
|
||||
RSA_set_method(rsa, rsa_method) == 0) {
|
||||
tls_set_errorx(ctx, "failed to setup RSA key");
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case EVP_PKEY_EC:
|
||||
if ((eckey = EVP_PKEY_get1_EC_KEY(pkey)) == NULL ||
|
||||
ECDSA_set_ex_data(eckey, 0, keypair->pubkey_hash) == 0) {
|
||||
tls_set_errorx(ctx, "EC key setup failure");
|
||||
goto err;
|
||||
}
|
||||
if (ctx->config->sign_cb == NULL)
|
||||
break;
|
||||
if ((ecdsa_method = tls_signer_ecdsa_method()) == NULL ||
|
||||
ECDSA_set_ex_data(eckey, 1, ctx->config) == 0 ||
|
||||
ECDSA_set_method(eckey, ecdsa_method) == 0) {
|
||||
tls_set_errorx(ctx, "failed to setup EC key");
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
tls_set_errorx(ctx, "incorrect key type");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
err:
|
||||
RSA_free(rsa);
|
||||
EC_KEY_free(eckey);
|
||||
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,38 +470,15 @@ 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");
|
||||
if (tls_keypair_to_pkey(ctx, keypair, &pkey) == -1)
|
||||
goto err;
|
||||
if (pkey != NULL) {
|
||||
if (tls_keypair_setup_pkey(ctx, keypair, pkey) == -1)
|
||||
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 (keypair->pubkey_hash != NULL) {
|
||||
RSA *rsa;
|
||||
/* XXX only RSA for now for relayd privsep */
|
||||
if ((rsa = EVP_PKEY_get1_RSA(pkey)) != NULL) {
|
||||
RSA_set_ex_data(rsa, 0, keypair->pubkey_hash);
|
||||
RSA_free(rsa);
|
||||
}
|
||||
}
|
||||
|
||||
if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) {
|
||||
tls_set_errorx(ctx, "failed to load private key");
|
||||
goto err;
|
||||
}
|
||||
BIO_free(bio);
|
||||
bio = NULL;
|
||||
EVP_PKEY_free(pkey);
|
||||
pkey = NULL;
|
||||
}
|
||||
@@ -397,9 +493,8 @@ tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx,
|
||||
|
||||
err:
|
||||
EVP_PKEY_free(pkey);
|
||||
BIO_free(bio);
|
||||
|
||||
return (1);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -444,7 +539,7 @@ tls_configure_ssl(struct tls *ctx, SSL_CTX *ssl_ctx)
|
||||
}
|
||||
|
||||
if (ctx->config->verify_time == 0) {
|
||||
X509_VERIFY_PARAM_set_flags(ssl_ctx->param,
|
||||
X509_VERIFY_PARAM_set_flags(SSL_CTX_get0_param(ssl_ctx),
|
||||
X509_V_FLAG_NO_CHECK_TIME);
|
||||
}
|
||||
|
||||
@@ -552,9 +647,8 @@ tls_configure_ssl_verify(struct tls *ctx, SSL_CTX *ssl_ctx, int verify)
|
||||
tls_set_error(ctx, "failed to add crl");
|
||||
goto err;
|
||||
}
|
||||
xi->crl = NULL;
|
||||
}
|
||||
X509_VERIFY_PARAM_set_flags(store->param,
|
||||
X509_STORE_set_flags(store,
|
||||
X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
|
||||
}
|
||||
|
||||
@@ -670,7 +764,7 @@ tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, const char *prefix)
|
||||
case SSL_ERROR_WANT_ACCEPT:
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
default:
|
||||
tls_set_ssl_errorx(ctx, "%s failed (%i)", prefix, ssl_err);
|
||||
tls_set_ssl_errorx(ctx, "%s failed (%d)", prefix, ssl_err);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
1
externals/libressl/tls/tls.sym
vendored
1
externals/libressl/tls/tls.sym
vendored
@@ -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
|
||||
|
65
externals/libressl/tls/tls_bio_cb.c
vendored
65
externals/libressl/tls/tls_bio_cb.c
vendored
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tls_bio_cb.c,v 1.19 2017/01/12 16:18:39 jsing Exp $ */
|
||||
/* $OpenBSD: tls_bio_cb.c,v 1.20 2022/01/10 23:39:48 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016 Tobias Pape <tobias@netshed.de>
|
||||
*
|
||||
@@ -29,19 +29,41 @@ static int bio_cb_read(BIO *bio, char *buf, int size);
|
||||
static int bio_cb_puts(BIO *bio, const char *str);
|
||||
static long bio_cb_ctrl(BIO *bio, int cmd, long num, void *ptr);
|
||||
|
||||
static BIO_METHOD bio_cb_method = {
|
||||
.type = BIO_TYPE_MEM,
|
||||
.name = "libtls_callbacks",
|
||||
.bwrite = bio_cb_write,
|
||||
.bread = bio_cb_read,
|
||||
.bputs = bio_cb_puts,
|
||||
.ctrl = bio_cb_ctrl,
|
||||
};
|
||||
static BIO_METHOD *bio_cb_method;
|
||||
|
||||
static pthread_mutex_t bio_cb_method_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static void
|
||||
bio_cb_method_init(void)
|
||||
{
|
||||
BIO_METHOD *bio_method;
|
||||
|
||||
if (bio_cb_method != NULL)
|
||||
return;
|
||||
|
||||
bio_method = BIO_meth_new(BIO_TYPE_MEM, "libtls_callbacks");
|
||||
if (bio_method == NULL)
|
||||
return;
|
||||
|
||||
BIO_meth_set_write(bio_method, bio_cb_write);
|
||||
BIO_meth_set_read(bio_method, bio_cb_read);
|
||||
BIO_meth_set_puts(bio_method, bio_cb_puts);
|
||||
BIO_meth_set_ctrl(bio_method, bio_cb_ctrl);
|
||||
|
||||
bio_cb_method = bio_method;
|
||||
}
|
||||
|
||||
static BIO_METHOD *
|
||||
bio_s_cb(void)
|
||||
{
|
||||
return (&bio_cb_method);
|
||||
if (bio_cb_method != NULL)
|
||||
return (bio_cb_method);
|
||||
|
||||
pthread_mutex_lock(&bio_cb_method_lock);
|
||||
bio_cb_method_init();
|
||||
pthread_mutex_unlock(&bio_cb_method_lock);
|
||||
|
||||
return (bio_cb_method);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -57,10 +79,10 @@ bio_cb_ctrl(BIO *bio, int cmd, long num, void *ptr)
|
||||
|
||||
switch (cmd) {
|
||||
case BIO_CTRL_GET_CLOSE:
|
||||
ret = (long)bio->shutdown;
|
||||
ret = (long)BIO_get_shutdown(bio);
|
||||
break;
|
||||
case BIO_CTRL_SET_CLOSE:
|
||||
bio->shutdown = (int)num;
|
||||
BIO_set_shutdown(bio, (int)num);
|
||||
break;
|
||||
case BIO_CTRL_DUP:
|
||||
case BIO_CTRL_FLUSH:
|
||||
@@ -69,7 +91,7 @@ bio_cb_ctrl(BIO *bio, int cmd, long num, void *ptr)
|
||||
case BIO_CTRL_GET:
|
||||
case BIO_CTRL_SET:
|
||||
default:
|
||||
ret = BIO_ctrl(bio->next_bio, cmd, num, ptr);
|
||||
ret = BIO_ctrl(BIO_next(bio), cmd, num, ptr);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
@@ -78,7 +100,7 @@ bio_cb_ctrl(BIO *bio, int cmd, long num, void *ptr)
|
||||
static int
|
||||
bio_cb_write(BIO *bio, const char *buf, int num)
|
||||
{
|
||||
struct tls *ctx = bio->ptr;
|
||||
struct tls *ctx = BIO_get_data(bio);
|
||||
int rv;
|
||||
|
||||
BIO_clear_retry_flags(bio);
|
||||
@@ -96,7 +118,7 @@ bio_cb_write(BIO *bio, const char *buf, int num)
|
||||
static int
|
||||
bio_cb_read(BIO *bio, char *buf, int size)
|
||||
{
|
||||
struct tls *ctx = bio->ptr;
|
||||
struct tls *ctx = BIO_get_data(bio);
|
||||
int rv;
|
||||
|
||||
BIO_clear_retry_flags(bio);
|
||||
@@ -115,8 +137,9 @@ int
|
||||
tls_set_cbs(struct tls *ctx, tls_read_cb read_cb, tls_write_cb write_cb,
|
||||
void *cb_arg)
|
||||
{
|
||||
int rv = -1;
|
||||
const BIO_METHOD *bio_cb;
|
||||
BIO *bio;
|
||||
int rv = -1;
|
||||
|
||||
if (read_cb == NULL || write_cb == NULL) {
|
||||
tls_set_errorx(ctx, "no callbacks provided");
|
||||
@@ -127,12 +150,16 @@ tls_set_cbs(struct tls *ctx, tls_read_cb read_cb, tls_write_cb write_cb,
|
||||
ctx->write_cb = write_cb;
|
||||
ctx->cb_arg = cb_arg;
|
||||
|
||||
if ((bio = BIO_new(bio_s_cb())) == NULL) {
|
||||
if ((bio_cb = bio_s_cb()) == NULL) {
|
||||
tls_set_errorx(ctx, "failed to create callback method");
|
||||
goto err;
|
||||
}
|
||||
if ((bio = BIO_new(bio_cb)) == NULL) {
|
||||
tls_set_errorx(ctx, "failed to create callback i/o");
|
||||
goto err;
|
||||
}
|
||||
bio->ptr = ctx;
|
||||
bio->init = 1;
|
||||
BIO_set_data(bio, ctx);
|
||||
BIO_set_init(bio, 1);
|
||||
|
||||
SSL_set_bio(ctx->ssl_conn, bio, bio);
|
||||
|
||||
|
34
externals/libressl/tls/tls_client.c
vendored
34
externals/libressl/tls/tls_client.c
vendored
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tls_client.c,v 1.45 2018/03/19 16:34:47 jsing Exp $ */
|
||||
/* $OpenBSD: tls_client.c,v 1.48 2021/10/21 08:38:11 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
@@ -74,11 +74,8 @@ tls_connect_servername(struct tls *ctx, const char *host, const char *port,
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* If port is NULL try to extract a port from the specified host,
|
||||
* otherwise use the default.
|
||||
*/
|
||||
if ((p = (char *)port) == NULL) {
|
||||
/* If port is NULL, try to extract a port from the specified host. */
|
||||
if (port == NULL) {
|
||||
ret = tls_host_port(host, &hs, &ps);
|
||||
if (ret == -1) {
|
||||
tls_set_errorx(ctx, "memory allocation failure");
|
||||
@@ -279,6 +276,7 @@ static int
|
||||
tls_connect_common(struct tls *ctx, const char *servername)
|
||||
{
|
||||
union tls_addr addrbuf;
|
||||
size_t servername_len;
|
||||
int rv = -1;
|
||||
|
||||
if ((ctx->flags & TLS_CLIENT) == 0) {
|
||||
@@ -291,6 +289,17 @@ tls_connect_common(struct tls *ctx, const char *servername)
|
||||
tls_set_errorx(ctx, "out of memory");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there's a trailing dot, remove it. While an FQDN includes
|
||||
* the terminating dot representing the zero-length label of
|
||||
* the root (RFC 8499, section 2), the SNI explicitly does not
|
||||
* include it (RFC 6066, section 3).
|
||||
*/
|
||||
servername_len = strlen(ctx->servername);
|
||||
if (servername_len > 0 &&
|
||||
ctx->servername[servername_len - 1] == '.')
|
||||
ctx->servername[servername_len - 1] = '\0';
|
||||
}
|
||||
|
||||
if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) {
|
||||
@@ -306,7 +315,7 @@ tls_connect_common(struct tls *ctx, const char *servername)
|
||||
goto err;
|
||||
|
||||
if (ctx->config->verify_name) {
|
||||
if (servername == NULL) {
|
||||
if (ctx->servername == NULL) {
|
||||
tls_set_errorx(ctx, "server name not specified");
|
||||
goto err;
|
||||
}
|
||||
@@ -350,13 +359,14 @@ tls_connect_common(struct tls *ctx, const char *servername)
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC4366 (SNI): Literal IPv4 and IPv6 addresses are not
|
||||
* RFC 6066 (SNI): Literal IPv4 and IPv6 addresses are not
|
||||
* permitted in "HostName".
|
||||
*/
|
||||
if (servername != NULL &&
|
||||
inet_pton(AF_INET, servername, &addrbuf) != 1 &&
|
||||
inet_pton(AF_INET6, servername, &addrbuf) != 1) {
|
||||
if (SSL_set_tlsext_host_name(ctx->ssl_conn, servername) == 0) {
|
||||
if (ctx->servername != NULL &&
|
||||
inet_pton(AF_INET, ctx->servername, &addrbuf) != 1 &&
|
||||
inet_pton(AF_INET6, ctx->servername, &addrbuf) != 1) {
|
||||
if (SSL_set_tlsext_host_name(ctx->ssl_conn,
|
||||
ctx->servername) == 0) {
|
||||
tls_set_errorx(ctx, "server name indication failure");
|
||||
goto err;
|
||||
}
|
||||
|
30
externals/libressl/tls/tls_config.c
vendored
30
externals/libressl/tls/tls_config.c
vendored
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tls_config.c,v 1.58 2020/01/20 08:39:21 jsing Exp $ */
|
||||
/* $OpenBSD: tls_config.c,v 1.65 2022/01/25 21:51:24 eric Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
@@ -179,6 +179,8 @@ tls_config_free(struct tls_config *config)
|
||||
free((char *)config->crl_mem);
|
||||
free(config->ecdhecurves);
|
||||
|
||||
pthread_mutex_destroy(&config->mutex);
|
||||
|
||||
free(config);
|
||||
}
|
||||
|
||||
@@ -351,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,
|
||||
@@ -378,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,
|
||||
@@ -718,7 +722,7 @@ tls_config_set_session_fd(struct tls_config *config, int session_fd)
|
||||
|
||||
if (sb.st_uid != getuid()) {
|
||||
tls_config_set_errorx(config, "session file has incorrect "
|
||||
"owner (uid %i != %i)", sb.st_uid, getuid());
|
||||
"owner (uid %u != %u)", sb.st_uid, getuid());
|
||||
return (-1);
|
||||
}
|
||||
mugo = sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO);
|
||||
@@ -733,6 +737,17 @@ tls_config_set_session_fd(struct tls_config *config, int session_fd)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
tls_config_set_sign_cb(struct tls_config *config, tls_sign_cb cb, void *cb_arg)
|
||||
{
|
||||
config->use_fake_private_key = 1;
|
||||
config->skip_private_key_check = 1;
|
||||
config->sign_cb = cb;
|
||||
config->sign_cb_arg = cb_arg;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
tls_config_set_verify_depth(struct tls_config *config, int verify_depth)
|
||||
{
|
||||
@@ -803,6 +818,13 @@ 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;
|
||||
config->skip_private_key_check = 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file)
|
||||
{
|
||||
|
5
externals/libressl/tls/tls_conninfo.c
vendored
5
externals/libressl/tls/tls_conninfo.c
vendored
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tls_conninfo.c,v 1.21 2019/11/02 13:37:59 jsing Exp $ */
|
||||
/* $OpenBSD: tls_conninfo.c,v 1.22 2021/01/05 15:57:38 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
|
||||
* Copyright (c) 2015 Bob Beck <beck@openbsd.org>
|
||||
@@ -112,9 +112,6 @@ tls_get_peer_cert_times(struct tls *ctx, time_t *notbefore,
|
||||
if (ctx->ssl_peer_cert == NULL)
|
||||
return (-1);
|
||||
|
||||
memset(&before_tm, 0, sizeof(before_tm));
|
||||
memset(&after_tm, 0, sizeof(after_tm));
|
||||
|
||||
if ((before = X509_get_notBefore(ctx->ssl_peer_cert)) == NULL)
|
||||
goto err;
|
||||
if ((after = X509_get_notAfter(ctx->ssl_peer_cert)) == NULL)
|
||||
|
31
externals/libressl/tls/tls_internal.h
vendored
31
externals/libressl/tls/tls_internal.h
vendored
@@ -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.80 2022/03/24 15:56:34 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
|
||||
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
|
||||
@@ -78,6 +78,10 @@ struct tls_ticket_key {
|
||||
time_t time;
|
||||
};
|
||||
|
||||
typedef int (*tls_sign_cb)(void *_cb_arg, const char *_pubkey_hash,
|
||||
const uint8_t *_input, size_t _input_len, int _padding_type,
|
||||
uint8_t **_out_signature, size_t *_out_signature_len);
|
||||
|
||||
struct tls_config {
|
||||
struct tls_error error;
|
||||
|
||||
@@ -111,6 +115,9 @@ struct tls_config {
|
||||
int verify_name;
|
||||
int verify_time;
|
||||
int skip_private_key_check;
|
||||
int use_fake_private_key;
|
||||
tls_sign_cb sign_cb;
|
||||
void *sign_cb_arg;
|
||||
};
|
||||
|
||||
struct tls_conninfo {
|
||||
@@ -290,9 +297,31 @@ int tls_cert_pubkey_hash(X509 *_cert, char **_hash);
|
||||
|
||||
int tls_password_cb(char *_buf, int _size, int _rwflag, void *_u);
|
||||
|
||||
RSA_METHOD *tls_signer_rsa_method(void);
|
||||
ECDSA_METHOD *tls_signer_ecdsa_method(void);
|
||||
|
||||
#define TLS_PADDING_NONE 0
|
||||
#define TLS_PADDING_RSA_PKCS1 1
|
||||
#define TLS_PADDING_RSA_X9_31 2
|
||||
|
||||
int tls_config_set_sign_cb(struct tls_config *_config, tls_sign_cb _cb,
|
||||
void *_cb_arg);
|
||||
|
||||
struct tls_signer* tls_signer_new(void);
|
||||
void tls_signer_free(struct tls_signer * _signer);
|
||||
const char *tls_signer_error(struct tls_signer * _signer);
|
||||
int tls_signer_add_keypair_file(struct tls_signer *_signer,
|
||||
const char *_cert_file, const char *_key_file);
|
||||
int tls_signer_add_keypair_mem(struct tls_signer *_signer, const uint8_t *_cert,
|
||||
size_t _cert_len, const uint8_t *_key, size_t _key_len);
|
||||
int tls_signer_sign(struct tls_signer *_signer, const char *_pubkey_hash,
|
||||
const uint8_t *_input, size_t _input_len, int _padding_type,
|
||||
uint8_t **_out_signature, size_t *_out_signature_len);
|
||||
|
||||
__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 */
|
||||
|
6
externals/libressl/tls/tls_keypair.c
vendored
6
externals/libressl/tls/tls_keypair.c
vendored
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tls_keypair.c,v 1.6 2018/04/07 16:35:34 jsing Exp $ */
|
||||
/* $OpenBSD: tls_keypair.c,v 1.8 2021/01/05 17:37:12 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
@@ -137,7 +137,7 @@ tls_keypair_load_cert(struct tls_keypair *keypair, struct tls_error *error,
|
||||
{
|
||||
char *errstr = "unknown";
|
||||
BIO *cert_bio = NULL;
|
||||
int ssl_err;
|
||||
unsigned long ssl_err;
|
||||
int rv = -1;
|
||||
|
||||
X509_free(*cert);
|
||||
@@ -155,7 +155,7 @@ tls_keypair_load_cert(struct tls_keypair *keypair, struct tls_error *error,
|
||||
if ((*cert = PEM_read_bio_X509(cert_bio, NULL, tls_password_cb,
|
||||
NULL)) == NULL) {
|
||||
if ((ssl_err = ERR_peek_error()) != 0)
|
||||
errstr = ERR_error_string(ssl_err, NULL);
|
||||
errstr = ERR_error_string(ssl_err, NULL);
|
||||
tls_error_set(error, "failed to load certificate: %s", errstr);
|
||||
goto err;
|
||||
}
|
||||
|
40
externals/libressl/tls/tls_ocsp.c
vendored
40
externals/libressl/tls/tls_ocsp.c
vendored
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tls_ocsp.c,v 1.19 2019/12/03 14:56:42 tb Exp $ */
|
||||
/* $OpenBSD: tls_ocsp.c,v 1.22 2021/10/31 16:39:32 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Marko Kreen <markokr@gmail.com>
|
||||
* Copyright (c) 2016 Bob Beck <beck@openbsd.org>
|
||||
@@ -128,30 +128,38 @@ tls_ocsp_get_certid(X509 *main_cert, STACK_OF(X509) *extra_certs,
|
||||
{
|
||||
X509_NAME *issuer_name;
|
||||
X509 *issuer;
|
||||
X509_STORE_CTX storectx;
|
||||
X509_OBJECT tmpobj;
|
||||
X509_STORE_CTX *storectx = NULL;
|
||||
X509_OBJECT *obj = NULL;
|
||||
OCSP_CERTID *cid = NULL;
|
||||
X509_STORE *store;
|
||||
|
||||
if ((issuer_name = X509_get_issuer_name(main_cert)) == NULL)
|
||||
return NULL;
|
||||
goto out;
|
||||
|
||||
if (extra_certs != NULL) {
|
||||
issuer = X509_find_by_subject(extra_certs, issuer_name);
|
||||
if (issuer != NULL)
|
||||
return OCSP_cert_to_id(NULL, main_cert, issuer);
|
||||
if (issuer != NULL) {
|
||||
cid = OCSP_cert_to_id(NULL, main_cert, issuer);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if ((store = SSL_CTX_get_cert_store(ssl_ctx)) == NULL)
|
||||
return NULL;
|
||||
if (X509_STORE_CTX_init(&storectx, store, main_cert, extra_certs) != 1)
|
||||
return NULL;
|
||||
if (X509_STORE_get_by_subject(&storectx, X509_LU_X509, issuer_name,
|
||||
&tmpobj) == 1) {
|
||||
cid = OCSP_cert_to_id(NULL, main_cert, tmpobj.data.x509);
|
||||
X509_OBJECT_free_contents(&tmpobj);
|
||||
}
|
||||
X509_STORE_CTX_cleanup(&storectx);
|
||||
goto out;
|
||||
if ((storectx = X509_STORE_CTX_new()) == NULL)
|
||||
goto out;
|
||||
if (X509_STORE_CTX_init(storectx, store, main_cert, extra_certs) != 1)
|
||||
goto out;
|
||||
if ((obj = X509_STORE_CTX_get_obj_by_subject(storectx, X509_LU_X509,
|
||||
issuer_name)) == NULL)
|
||||
goto out;
|
||||
|
||||
cid = OCSP_cert_to_id(NULL, main_cert, X509_OBJECT_get0_X509(obj));
|
||||
|
||||
out:
|
||||
X509_STORE_CTX_free(storectx);
|
||||
X509_OBJECT_free(obj);
|
||||
|
||||
return cid;
|
||||
}
|
||||
|
||||
@@ -218,7 +226,7 @@ tls_ocsp_verify_response(struct tls *ctx, OCSP_RESPONSE *resp)
|
||||
/* now verify */
|
||||
if (OCSP_basic_verify(br, ctx->ocsp->extra_certs,
|
||||
SSL_CTX_get_cert_store(ctx->ssl_ctx), flags) != 1) {
|
||||
tls_set_error(ctx, "ocsp verify failed");
|
||||
tls_set_errorx(ctx, "ocsp verify failed");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
34
externals/libressl/tls/tls_server.c
vendored
34
externals/libressl/tls/tls_server.c
vendored
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tls_server.c,v 1.45 2019/05/13 22:36:01 bcook Exp $ */
|
||||
/* $OpenBSD: tls_server.c,v 1.48 2022/01/19 11:10:55 inoguchi Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
@@ -109,7 +109,7 @@ tls_servername_cb(SSL *ssl, int *al, void *arg)
|
||||
inet_pton(AF_INET6, name, &addrbuf) == 1)
|
||||
return (SSL_TLSEXT_ERR_NOACK);
|
||||
|
||||
free((char *)conn_ctx->servername);
|
||||
free(conn_ctx->servername);
|
||||
if ((conn_ctx->servername = strdup(name)) == NULL)
|
||||
goto err;
|
||||
|
||||
@@ -133,7 +133,7 @@ tls_servername_cb(SSL *ssl, int *al, void *arg)
|
||||
* There is no way to tell libssl that an internal failure occurred.
|
||||
* The only option we have is to return a fatal alert.
|
||||
*/
|
||||
*al = TLS1_AD_INTERNAL_ERROR;
|
||||
*al = SSL_AD_INTERNAL_ERROR;
|
||||
return (SSL_TLSEXT_ERR_ALERT_FATAL);
|
||||
}
|
||||
|
||||
@@ -185,10 +185,16 @@ tls_server_ticket_cb(SSL *ssl, unsigned char *keyname, unsigned char *iv,
|
||||
|
||||
memcpy(keyname, key->key_name, sizeof(key->key_name));
|
||||
arc4random_buf(iv, EVP_MAX_IV_LENGTH);
|
||||
EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL,
|
||||
key->aes_key, iv);
|
||||
HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key),
|
||||
EVP_sha256(), NULL);
|
||||
if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL,
|
||||
key->aes_key, iv)) {
|
||||
tls_set_errorx(tls_ctx, "failed to init encrypt");
|
||||
return (-1);
|
||||
}
|
||||
if (!HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key),
|
||||
EVP_sha256(), NULL)) {
|
||||
tls_set_errorx(tls_ctx, "failed to init hmac");
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
} else {
|
||||
/* get key by name */
|
||||
@@ -196,10 +202,16 @@ tls_server_ticket_cb(SSL *ssl, unsigned char *keyname, unsigned char *iv,
|
||||
if (key == NULL)
|
||||
return (0);
|
||||
|
||||
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL,
|
||||
key->aes_key, iv);
|
||||
HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key),
|
||||
EVP_sha256(), NULL);
|
||||
if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL,
|
||||
key->aes_key, iv)) {
|
||||
tls_set_errorx(tls_ctx, "failed to init decrypt");
|
||||
return (-1);
|
||||
}
|
||||
if (!HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key),
|
||||
EVP_sha256(), NULL)) {
|
||||
tls_set_errorx(tls_ctx, "failed to init hmac");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* time to renew the ticket? is it the primary key? */
|
||||
if (key != &tls_ctx->config->ticket_keys[0])
|
||||
|
451
externals/libressl/tls/tls_signer.c
vendored
Executable file
451
externals/libressl/tls/tls_signer.c
vendored
Executable file
@@ -0,0 +1,451 @@
|
||||
/* $OpenBSD: tls_signer.c,v 1.4 2022/02/01 17:18:38 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2021 Eric Faurot <eric@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
#include "tls.h"
|
||||
#include "tls_internal.h"
|
||||
|
||||
struct tls_signer_key {
|
||||
char *hash;
|
||||
RSA *rsa;
|
||||
EC_KEY *ecdsa;
|
||||
struct tls_signer_key *next;
|
||||
};
|
||||
|
||||
struct tls_signer {
|
||||
struct tls_error error;
|
||||
struct tls_signer_key *keys;
|
||||
};
|
||||
|
||||
static pthread_mutex_t signer_method_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
struct tls_signer *
|
||||
tls_signer_new(void)
|
||||
{
|
||||
struct tls_signer *signer;
|
||||
|
||||
if ((signer = calloc(1, sizeof(*signer))) == NULL)
|
||||
return (NULL);
|
||||
|
||||
return (signer);
|
||||
}
|
||||
|
||||
void
|
||||
tls_signer_free(struct tls_signer *signer)
|
||||
{
|
||||
struct tls_signer_key *skey;
|
||||
|
||||
if (signer == NULL)
|
||||
return;
|
||||
|
||||
tls_error_clear(&signer->error);
|
||||
|
||||
while (signer->keys) {
|
||||
skey = signer->keys;
|
||||
signer->keys = skey->next;
|
||||
RSA_free(skey->rsa);
|
||||
EC_KEY_free(skey->ecdsa);
|
||||
free(skey->hash);
|
||||
free(skey);
|
||||
}
|
||||
|
||||
free(signer);
|
||||
}
|
||||
|
||||
const char *
|
||||
tls_signer_error(struct tls_signer *signer)
|
||||
{
|
||||
return (signer->error.msg);
|
||||
}
|
||||
|
||||
int
|
||||
tls_signer_add_keypair_mem(struct tls_signer *signer, const uint8_t *cert,
|
||||
size_t cert_len, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
struct tls_signer_key *skey = NULL;
|
||||
char *errstr = "unknown";
|
||||
int ssl_err;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
X509 *x509 = NULL;
|
||||
BIO *bio = NULL;
|
||||
char *hash = NULL;
|
||||
|
||||
/* Compute certificate hash */
|
||||
if ((bio = BIO_new_mem_buf(cert, cert_len)) == NULL) {
|
||||
tls_error_setx(&signer->error,
|
||||
"failed to create certificate bio");
|
||||
goto err;
|
||||
}
|
||||
if ((x509 = PEM_read_bio_X509(bio, NULL, tls_password_cb,
|
||||
NULL)) == NULL) {
|
||||
if ((ssl_err = ERR_peek_error()) != 0)
|
||||
errstr = ERR_error_string(ssl_err, NULL);
|
||||
tls_error_setx(&signer->error, "failed to load certificate: %s",
|
||||
errstr);
|
||||
goto err;
|
||||
}
|
||||
if (tls_cert_pubkey_hash(x509, &hash) == -1) {
|
||||
tls_error_setx(&signer->error,
|
||||
"failed to get certificate hash");
|
||||
goto err;
|
||||
}
|
||||
|
||||
X509_free(x509);
|
||||
x509 = NULL;
|
||||
BIO_free(bio);
|
||||
bio = NULL;
|
||||
|
||||
/* Read private key */
|
||||
if ((bio = BIO_new_mem_buf(key, key_len)) == NULL) {
|
||||
tls_error_setx(&signer->error, "failed to create key bio");
|
||||
goto err;
|
||||
}
|
||||
if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb,
|
||||
NULL)) == NULL) {
|
||||
tls_error_setx(&signer->error, "failed to read private key");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((skey = calloc(1, sizeof(*skey))) == NULL) {
|
||||
tls_error_set(&signer->error, "failed to create key entry");
|
||||
goto err;
|
||||
}
|
||||
skey->hash = hash;
|
||||
if ((skey->rsa = EVP_PKEY_get1_RSA(pkey)) == NULL &&
|
||||
(skey->ecdsa = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) {
|
||||
tls_error_setx(&signer->error, "unknown key type");
|
||||
goto err;
|
||||
}
|
||||
|
||||
skey->next = signer->keys;
|
||||
signer->keys = skey;
|
||||
EVP_PKEY_free(pkey);
|
||||
BIO_free(bio);
|
||||
|
||||
return (0);
|
||||
|
||||
err:
|
||||
EVP_PKEY_free(pkey);
|
||||
X509_free(x509);
|
||||
BIO_free(bio);
|
||||
free(hash);
|
||||
free(skey);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
tls_signer_add_keypair_file(struct tls_signer *signer, const char *cert_file,
|
||||
const char *key_file)
|
||||
{
|
||||
char *cert = NULL, *key = NULL;
|
||||
size_t cert_len, key_len;
|
||||
int rv = -1;
|
||||
|
||||
if (tls_config_load_file(&signer->error, "certificate", cert_file,
|
||||
&cert, &cert_len) == -1)
|
||||
goto err;
|
||||
|
||||
if (tls_config_load_file(&signer->error, "key", key_file, &key,
|
||||
&key_len) == -1)
|
||||
goto err;
|
||||
|
||||
rv = tls_signer_add_keypair_mem(signer, cert, cert_len, key, key_len);
|
||||
|
||||
err:
|
||||
free(cert);
|
||||
free(key);
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
tls_sign_rsa(struct tls_signer *signer, struct tls_signer_key *skey,
|
||||
const uint8_t *input, size_t input_len, int padding_type,
|
||||
uint8_t **out_signature, size_t *out_signature_len)
|
||||
{
|
||||
int rsa_padding, rsa_size, signature_len;
|
||||
char *signature = NULL;
|
||||
|
||||
*out_signature = NULL;
|
||||
*out_signature_len = 0;
|
||||
|
||||
if (padding_type == TLS_PADDING_NONE) {
|
||||
rsa_padding = RSA_NO_PADDING;
|
||||
} else if (padding_type == TLS_PADDING_RSA_PKCS1) {
|
||||
rsa_padding = RSA_PKCS1_PADDING;
|
||||
} else if (padding_type == TLS_PADDING_RSA_X9_31) {
|
||||
rsa_padding = RSA_X931_PADDING;
|
||||
} else {
|
||||
tls_error_setx(&signer->error, "invalid RSA padding type (%d)",
|
||||
padding_type);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (input_len > INT_MAX) {
|
||||
tls_error_setx(&signer->error, "input too large");
|
||||
return (-1);
|
||||
}
|
||||
if ((rsa_size = RSA_size(skey->rsa)) <= 0) {
|
||||
tls_error_setx(&signer->error, "invalid RSA size: %d",
|
||||
rsa_size);
|
||||
return (-1);
|
||||
}
|
||||
if ((signature = calloc(1, rsa_size)) == NULL) {
|
||||
tls_error_set(&signer->error, "RSA signature");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((signature_len = RSA_private_encrypt((int)input_len, input,
|
||||
signature, skey->rsa, rsa_padding)) <= 0) {
|
||||
/* XXX - include further details from libcrypto. */
|
||||
tls_error_setx(&signer->error, "RSA signing failed");
|
||||
free(signature);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
*out_signature = signature;
|
||||
*out_signature_len = (size_t)signature_len;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
tls_sign_ecdsa(struct tls_signer *signer, struct tls_signer_key *skey,
|
||||
const uint8_t *input, size_t input_len, int padding_type,
|
||||
uint8_t **out_signature, size_t *out_signature_len)
|
||||
{
|
||||
unsigned char *signature;
|
||||
int signature_len;
|
||||
|
||||
*out_signature = NULL;
|
||||
*out_signature_len = 0;
|
||||
|
||||
if (padding_type != TLS_PADDING_NONE) {
|
||||
tls_error_setx(&signer->error, "invalid ECDSA padding");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (input_len > INT_MAX) {
|
||||
tls_error_setx(&signer->error, "digest too large");
|
||||
return (-1);
|
||||
}
|
||||
if ((signature_len = ECDSA_size(skey->ecdsa)) <= 0) {
|
||||
tls_error_setx(&signer->error, "invalid ECDSA size: %d",
|
||||
signature_len);
|
||||
return (-1);
|
||||
}
|
||||
if ((signature = calloc(1, signature_len)) == NULL) {
|
||||
tls_error_set(&signer->error, "ECDSA signature");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (!ECDSA_sign(0, input, input_len, signature, &signature_len,
|
||||
skey->ecdsa)) {
|
||||
/* XXX - include further details from libcrypto. */
|
||||
tls_error_setx(&signer->error, "ECDSA signing failed");
|
||||
free(signature);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
*out_signature = signature;
|
||||
*out_signature_len = signature_len;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
tls_signer_sign(struct tls_signer *signer, const char *pubkey_hash,
|
||||
const uint8_t *input, size_t input_len, int padding_type,
|
||||
uint8_t **out_signature, size_t *out_signature_len)
|
||||
{
|
||||
struct tls_signer_key *skey;
|
||||
|
||||
*out_signature = NULL;
|
||||
*out_signature_len = 0;
|
||||
|
||||
for (skey = signer->keys; skey; skey = skey->next)
|
||||
if (!strcmp(pubkey_hash, skey->hash))
|
||||
break;
|
||||
|
||||
if (skey == NULL) {
|
||||
tls_error_setx(&signer->error, "key not found");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (skey->rsa != NULL)
|
||||
return tls_sign_rsa(signer, skey, input, input_len,
|
||||
padding_type, out_signature, out_signature_len);
|
||||
|
||||
if (skey->ecdsa != NULL)
|
||||
return tls_sign_ecdsa(signer, skey, input, input_len,
|
||||
padding_type, out_signature, out_signature_len);
|
||||
|
||||
tls_error_setx(&signer->error, "unknown key type");
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
tls_rsa_priv_enc(int from_len, const unsigned char *from, unsigned char *to,
|
||||
RSA *rsa, int rsa_padding)
|
||||
{
|
||||
struct tls_config *config;
|
||||
uint8_t *signature = NULL;
|
||||
size_t signature_len = 0;
|
||||
const char *pubkey_hash;
|
||||
int padding_type;
|
||||
|
||||
/*
|
||||
* This function is called via RSA_private_encrypt() and has to conform
|
||||
* to its calling convention/signature. The caller is required to
|
||||
* provide a 'to' buffer of at least RSA_size() bytes.
|
||||
*/
|
||||
|
||||
pubkey_hash = RSA_get_ex_data(rsa, 0);
|
||||
config = RSA_get_ex_data(rsa, 1);
|
||||
|
||||
if (pubkey_hash == NULL || config == NULL)
|
||||
goto err;
|
||||
|
||||
if (rsa_padding == RSA_NO_PADDING) {
|
||||
padding_type = TLS_PADDING_NONE;
|
||||
} else if (rsa_padding == RSA_PKCS1_PADDING) {
|
||||
padding_type = TLS_PADDING_RSA_PKCS1;
|
||||
} else if (rsa_padding == RSA_X931_PADDING) {
|
||||
padding_type = TLS_PADDING_RSA_X9_31;
|
||||
} else {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (from_len < 0)
|
||||
goto err;
|
||||
|
||||
if (config->sign_cb(config->sign_cb_arg, pubkey_hash, from, from_len,
|
||||
padding_type, &signature, &signature_len) == -1)
|
||||
goto err;
|
||||
|
||||
if (signature_len > INT_MAX || (int)signature_len > RSA_size(rsa))
|
||||
goto err;
|
||||
|
||||
memcpy(to, signature, signature_len);
|
||||
free(signature);
|
||||
|
||||
return ((int)signature_len);
|
||||
|
||||
err:
|
||||
free(signature);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
RSA_METHOD *
|
||||
tls_signer_rsa_method(void)
|
||||
{
|
||||
static RSA_METHOD *rsa_method = NULL;
|
||||
|
||||
pthread_mutex_lock(&signer_method_lock);
|
||||
|
||||
if (rsa_method != NULL)
|
||||
goto out;
|
||||
|
||||
rsa_method = RSA_meth_new("libtls RSA method", 0);
|
||||
if (rsa_method == NULL)
|
||||
goto out;
|
||||
|
||||
RSA_meth_set_priv_enc(rsa_method, tls_rsa_priv_enc);
|
||||
|
||||
out:
|
||||
pthread_mutex_unlock(&signer_method_lock);
|
||||
|
||||
return (rsa_method);
|
||||
}
|
||||
|
||||
static ECDSA_SIG *
|
||||
tls_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
|
||||
const BIGNUM *rp, EC_KEY *eckey)
|
||||
{
|
||||
struct tls_config *config;
|
||||
ECDSA_SIG *ecdsa_sig = NULL;
|
||||
uint8_t *signature = NULL;
|
||||
size_t signature_len = 0;
|
||||
const unsigned char *p;
|
||||
const char *pubkey_hash;
|
||||
|
||||
/*
|
||||
* This function is called via ECDSA_do_sign_ex() and has to conform
|
||||
* to its calling convention/signature.
|
||||
*/
|
||||
|
||||
pubkey_hash = ECDSA_get_ex_data(eckey, 0);
|
||||
config = ECDSA_get_ex_data(eckey, 1);
|
||||
|
||||
if (pubkey_hash == NULL || config == NULL)
|
||||
goto err;
|
||||
|
||||
if (dgst_len < 0)
|
||||
goto err;
|
||||
|
||||
if (config->sign_cb(config->sign_cb_arg, pubkey_hash, dgst, dgst_len,
|
||||
TLS_PADDING_NONE, &signature, &signature_len) == -1)
|
||||
goto err;
|
||||
|
||||
p = signature;
|
||||
if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &p, signature_len)) == NULL)
|
||||
goto err;
|
||||
|
||||
free(signature);
|
||||
|
||||
return (ecdsa_sig);
|
||||
|
||||
err:
|
||||
free(signature);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ECDSA_METHOD *
|
||||
tls_signer_ecdsa_method(void)
|
||||
{
|
||||
static ECDSA_METHOD *ecdsa_method = NULL;
|
||||
|
||||
pthread_mutex_lock(&signer_method_lock);
|
||||
|
||||
if (ecdsa_method != NULL)
|
||||
goto out;
|
||||
|
||||
ecdsa_method = calloc(1, sizeof(*ecdsa_method));
|
||||
if (ecdsa_method == NULL)
|
||||
goto out;
|
||||
|
||||
ecdsa_method->ecdsa_do_sign = tls_ecdsa_do_sign;
|
||||
ecdsa_method->name = strdup("libtls ECDSA method");
|
||||
if (ecdsa_method->name == NULL) {
|
||||
free(ecdsa_method);
|
||||
ecdsa_method = NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
pthread_mutex_unlock(&signer_method_lock);
|
||||
|
||||
return (ecdsa_method);
|
||||
}
|
4
externals/libressl/tls/tls_util.c
vendored
4
externals/libressl/tls/tls_util.c
vendored
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tls_util.c,v 1.14 2019/04/13 18:47:58 tb Exp $ */
|
||||
/* $OpenBSD: tls_util.c,v 1.15 2021/08/16 13:54:38 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
|
||||
* Copyright (c) 2014 Ted Unangst <tedu@openbsd.org>
|
||||
@@ -92,7 +92,7 @@ tls_host_port(const char *hostport, char **host, char **port)
|
||||
*p++ = '\0';
|
||||
}
|
||||
|
||||
/* Find the port seperator. */
|
||||
/* Find the port separator. */
|
||||
if ((p = strchr(p, ':')) == NULL)
|
||||
goto done;
|
||||
|
||||
|
Reference in New Issue
Block a user