Fixed #6148: multiple ceritificate purposes
authorakallabeth <akallabeth@posteo.net>
Tue, 12 May 2020 11:00:13 +0000 (13:00 +0200)
committerakallabeth <akallabeth@posteo.net>
Mon, 18 May 2020 14:41:11 +0000 (16:41 +0200)
OpenSSL certificate verification can only check a single purpose.
Run the checks with all allowed purposes and accept any.

(cherry picked from commit f3063a589d908a087a295b9217bc5fa34a80fb36)

libfreerdp/crypto/crypto.c

index 0920e35..4507578 100644 (file)
@@ -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;