mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 01:49:11 +00:00
cert files can contain the full chain of trust, so load all certs in every case for verification
This commit is contained in:
parent
4b6de608c2
commit
5e36cc655c
@ -909,46 +909,22 @@ signal_cb(int signo, int what, void *v)
|
||||
}
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
static X509 *
|
||||
load_cert(const char *file)
|
||||
{
|
||||
X509 *x509 = NULL;
|
||||
BIO *cert = NULL;
|
||||
debug_decl(load_cert, SUDO_DEBUG_UTIL)
|
||||
|
||||
if ((cert = BIO_new(BIO_s_file())) == NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to allocate new BIO object for certificate: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (BIO_read_filename(cert, file) <= 0) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to read certificate file: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
x509 = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
|
||||
|
||||
exit:
|
||||
if (cert)
|
||||
BIO_free(cert);
|
||||
|
||||
debug_return_ptr(x509);
|
||||
}
|
||||
|
||||
static bool
|
||||
check_cert(X509_STORE *ca_store_ctx, SSL_CTX *ctx, const char *cert_file)
|
||||
verify_server_cert(SSL_CTX *ctx, const struct logsrvd_tls_config *tls_config)
|
||||
{
|
||||
bool ret = false;
|
||||
X509_STORE_CTX *store_ctx = NULL;
|
||||
X509 *x509 = NULL;
|
||||
debug_decl(check_cert, SUDO_DEBUG_UTIL)
|
||||
X509_STORE *ca_store;
|
||||
STACK_OF(X509) *chain_certs;
|
||||
X509 *x509;
|
||||
debug_decl(verify_server_cert, SUDO_DEBUG_UTIL)
|
||||
|
||||
if ((x509 = load_cert(cert_file)) == NULL)
|
||||
if ((x509 = SSL_CTX_get0_certificate(ctx)) == NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to get X509 object from SSL_CTX: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((store_ctx = X509_STORE_CTX_new()) == NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
@ -957,9 +933,17 @@ check_cert(X509_STORE *ca_store_ctx, SSL_CTX *ctx, const char *cert_file)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
X509_STORE_set_flags(ca_store_ctx, X509_V_FLAG_X509_STRICT);
|
||||
if (!SSL_CTX_get0_chain_certs(ctx, &chain_certs)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to get chain certs: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!X509_STORE_CTX_init(store_ctx, ca_store_ctx, x509, 0)) {
|
||||
if ((ca_store = SSL_CTX_get_cert_store(ctx)) != NULL)
|
||||
X509_STORE_set_flags(ca_store, X509_V_FLAG_X509_STRICT);
|
||||
|
||||
if (!X509_STORE_CTX_init(store_ctx, ca_store, x509, chain_certs)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to initialize X509_STORE_CTX object: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
@ -968,61 +952,14 @@ check_cert(X509_STORE *ca_store_ctx, SSL_CTX *ctx, const char *cert_file)
|
||||
|
||||
if (X509_verify_cert(store_ctx) <= 0) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to verify cert: %s",
|
||||
"unable to verify cert %s: %s", tls_config->cert_path,
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* everything is good, use this server certificate during TLS handshakes */
|
||||
if (!SSL_CTX_use_certificate(ctx, x509)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to load cert to the ssl context: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
ret = true;
|
||||
exit:
|
||||
X509_STORE_CTX_free(store_ctx);
|
||||
X509_free(x509);
|
||||
|
||||
debug_return_bool(ret);
|
||||
}
|
||||
|
||||
static bool
|
||||
verify_server_cert(SSL_CTX *ctx, const struct logsrvd_tls_config *tls_config)
|
||||
{
|
||||
bool ret = false;
|
||||
X509_STORE *ca_store_ctx = NULL;
|
||||
X509_LOOKUP *x509_lookup = NULL;
|
||||
debug_decl(verify_server_cert, SUDO_DEBUG_UTIL)
|
||||
|
||||
if ((ca_store_ctx = X509_STORE_new()) == NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to allocate X509_STORE object for CA bundle: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((x509_lookup = X509_STORE_add_lookup(ca_store_ctx, X509_LOOKUP_file())) == NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to set lookup method: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!X509_LOOKUP_load_file(x509_lookup, tls_config->cacert_path, X509_FILETYPE_PEM)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to load CA bundle file: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = check_cert(ca_store_ctx, ctx, tls_config->cert_path);
|
||||
|
||||
exit:
|
||||
X509_STORE_free(ca_store_ctx);
|
||||
|
||||
debug_return_bool(ret);
|
||||
}
|
||||
@ -1116,30 +1053,40 @@ init_tls_server_context(void)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* verify server certification against the CA bundle file */
|
||||
if (SSL_CTX_use_certificate_chain_file(ctx, tls_config->cert_path) <= 0) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to load cert %s: %s", tls_config->cert_path,
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (tls_config->cacert_path != NULL) {
|
||||
STACK_OF(X509_NAME) *cacerts =
|
||||
SSL_load_client_CA_file(tls_config->cacert_path);
|
||||
if (cacerts == NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"calling SSL_load_client_CA_file() failed: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto bad;
|
||||
} else {
|
||||
SSL_CTX_set_client_CA_list(ctx, cacerts);
|
||||
|
||||
/* set the location of the CA bundle file for verification */
|
||||
if (SSL_CTX_load_verify_locations(ctx, tls_config->cacert_path, NULL) <= 0) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"calling SSL_CTX_load_verify_locations() failed: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!verify_server_cert(ctx, tls_config)) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* if peer authentication is enabled, verify client cert during TLS handshake */
|
||||
if (tls_config->check_peer) {
|
||||
X509 *cacert = load_cert(tls_config->cacert_path);
|
||||
|
||||
/* server will send the name of the CA to the client during the handshake */
|
||||
if (SSL_CTX_add_client_CA(ctx, cacert) <= 0) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"calling SSL_CTX_add_client_CA() failed: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
}
|
||||
|
||||
/* sets the location of the CA bundle file for verification purposes */
|
||||
if (SSL_CTX_load_verify_locations(ctx, tls_config->cacert_path, NULL) <= 0) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"calling SSL_CTX_load_verify_locations() failed: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
}
|
||||
|
||||
/* server will send a client certificate request to the peer during the handshake */
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
|
||||
}
|
||||
|
||||
@ -1148,13 +1095,13 @@ init_tls_server_context(void)
|
||||
|
||||
if (!SSL_CTX_use_PrivateKey_file(ctx, pkey, SSL_FILETYPE_PEM)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to load key file: %s",
|
||||
"unable to load key file %s: %s", pkey,
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto bad;
|
||||
}
|
||||
if (!SSL_CTX_check_private_key(ctx)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to verify key file: %s",
|
||||
"unable to verify key file %s: %s", pkey,
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto bad;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user