From 5cfc3e8593445846d247c25d72646d6f5d567265 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Tue, 12 May 2020 13:00:13 +0200 Subject: [PATCH] Fixed #6148: multiple ceritificate purposes OpenSSL certificate verification can only check a single purpose. Run the checks with all allowed purposes and accept any. --- libfreerdp/crypto/crypto.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/libfreerdp/crypto/crypto.c b/libfreerdp/crypto/crypto.c index 0920e356e..4507578ab 100644 --- a/libfreerdp/crypto/crypto.c +++ b/libfreerdp/crypto/crypto.c @@ -797,6 +797,8 @@ static int verify_cb(int ok, X509_STORE_CTX* csc) BOOL x509_verify_certificate(CryptoCert cert, const char* certificate_store_path) { + size_t i; + const int purposes[3] = { X509_PURPOSE_SSL_SERVER, X509_PURPOSE_SSL_CLIENT, X509_PURPOSE_ANY }; X509_STORE_CTX* csc; BOOL status = FALSE; X509_STORE* cert_ctx = NULL; @@ -831,23 +833,32 @@ BOOL x509_verify_certificate(CryptoCert cert, const char* certificate_store_path X509_LOOKUP_add_dir(lookup, certificate_store_path, X509_FILETYPE_PEM); } - csc = X509_STORE_CTX_new(); - - if (csc == NULL) - goto end; - X509_STORE_set_flags(cert_ctx, 0); - if (!X509_STORE_CTX_init(csc, cert_ctx, cert->px509, cert->px509chain)) - goto end; + for (i = 0; i < ARRAYSIZE(purposes); i++) + { + int rc = -1; + int purpose = purposes[i]; + csc = X509_STORE_CTX_new(); - X509_STORE_CTX_set_purpose(csc, X509_PURPOSE_ANY); - X509_STORE_CTX_set_verify_cb(csc, verify_cb); + if (csc == NULL) + goto skip; + if (!X509_STORE_CTX_init(csc, cert_ctx, cert->px509, cert->px509chain)) + goto skip; - if (X509_verify_cert(csc) == 1) - status = TRUE; + X509_STORE_CTX_set_purpose(csc, purpose); + X509_STORE_CTX_set_verify_cb(csc, verify_cb); + + rc = X509_verify_cert(csc); + skip: + X509_STORE_CTX_free(csc); + if (rc == 1) + { + status = TRUE; + break; + } + } - X509_STORE_CTX_free(csc); X509_STORE_free(cert_ctx); end: return status;