Skip to content

Commit

Permalink
Iterate over all certificates in a trusted cert BIO, not just the fir…
Browse files Browse the repository at this point in the history
…st (#522)

Previously the code which loaded a trusted certificate from file only
assumed that there was a single certificate in that file, meaning that
using a certificate bundle for certificate verification would not work.

This fix allows the driver to read multiple trusted certificates out
of a BIO and provision them in the trusted certificate store.

Co-authored-by: Max Dymond <[email protected]>
  • Loading branch information
kw217 and maxdymond authored Mar 28, 2022
1 parent bf1ff08 commit 88aa754
Showing 1 changed file with 25 additions and 20 deletions.
45 changes: 25 additions & 20 deletions src/ssl/ssl_openssl_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,22 +240,6 @@ static int SSL_CTX_use_certificate_chain_bio(SSL_CTX* ctx, BIO* in) {
return ret;
}

static X509* load_cert(const char* cert, size_t cert_size) {
BIO* bio = BIO_new_mem_buf(const_cast<char*>(cert), cert_size);
if (bio == NULL) {
return NULL;
}

X509* x509 = PEM_read_bio_X509(bio, NULL, pem_password_callback, NULL);
if (x509 == NULL) {
ssl_log_errors("Unable to load certificate");
}

BIO_free_all(bio);

return x509;
}

static EVP_PKEY* load_key(const char* key, size_t key_size, const char* password) {
BIO* bio = BIO_new_mem_buf(const_cast<char*>(key), key_size);
if (bio == NULL) {
Expand Down Expand Up @@ -568,13 +552,34 @@ SslSession* OpenSslContext::create_session(const Address& address, const String&
}

CassError OpenSslContext::add_trusted_cert(const char* cert, size_t cert_length) {
X509* x509 = load_cert(cert, cert_length);
if (x509 == NULL) {
BIO* bio = BIO_new_mem_buf(const_cast<char*>(cert), cert_length);
if (bio == NULL) {
return CASS_ERROR_SSL_INVALID_CERT;
}

X509_STORE_add_cert(trusted_store_, x509);
X509_free(x509);
int num_certs = 0;

// Iterate over the bio, reading out as many certificates as possible.
for (X509* cert = PEM_read_bio_X509(bio, NULL, pem_password_callback, NULL);
cert != NULL;
cert = PEM_read_bio_X509(bio, NULL, pem_password_callback, NULL))
{
X509_STORE_add_cert(trusted_store_, cert);
X509_free(cert);
num_certs++;
}

// Retrieve and discard the error tht terminated the loop,
// so it doesn't cause the next PEM operation to fail mysteriously.
ERR_get_error();

BIO_free_all(bio);

// If no certificates were read from the bio, that is an error.
if (num_certs == 0) {
ssl_log_errors("Unable to load certificate(s)");
return CASS_ERROR_SSL_INVALID_CERT;
}

return CASS_OK;
}
Expand Down

0 comments on commit 88aa754

Please sign in to comment.