]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Correct handling of "untrusted" certs
authorNick Porter <nick@portercomputing.co.uk>
Thu, 5 Dec 2024 13:06:51 +0000 (13:06 +0000)
committerNick Porter <nick@portercomputing.co.uk>
Thu, 5 Dec 2024 13:19:08 +0000 (13:19 +0000)
OpenSSL calls all certificates presented by a client that aren't in the
local trust store "untrusted".

Therefore when verifying a client certificate, that will always be
untrusted - so we only have untrusted CAs in the chain if there is more
than one untrusted certificate.

src/main/tls.c

index 244e303acc3d3ef1671e29db917787c9d2524abd..855de141fe48d2b7244aca44eabf9ea0695ceb26 100644 (file)
@@ -3306,23 +3306,29 @@ int cbtls_verify(int ok, X509_STORE_CTX *ctx)
                tls_session_t *ssn = SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_SSN);
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
                STACK_OF(X509)* untrusted = NULL;
+               int num_untrusted = X509_STORE_CTX_get_num_untrusted(ctx);
 #endif
 
                rad_assert(ssn != NULL);
 
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
                /*
-                *      See if there are any untrusted certificates.
-                *      If so, complain about them.
+                *      "Untrusted" certificates are those presented by the client
+                *      so we always expect there to be one.
+                *
+                *      If there's more than one, then the client is presenting
+                *      intermediate CAs as well.
                 */
-               untrusted = X509_STORE_CTX_get0_untrusted(ctx);
-               if (untrusted) {
+               if (num_untrusted > 1) {
+                       untrusted = X509_STORE_CTX_get0_untrusted(ctx);
                        if (conf->disallow_untrusted || RDEBUG_ENABLED2) {
                                int  i;
 
-                               WARN("Certificate chain - %i cert(s) untrusted",
-                                    X509_STORE_CTX_get_num_untrusted(ctx));
-                               for (i = sk_X509_num(untrusted); i > 0 ; i--) {
+                               WARN("Certificate chain - %i intermediate CA cert(s) untrusted",
+                                    num_untrusted - 1);
+                               if (!conf->disallow_untrusted) WARN("To forbid these certificates set 'reject_unknown_intermediate_ca'");
+
+                               for (i = num_untrusted; i > 1 ; i--) {
                                        X509 *this_cert = sk_X509_value(untrusted, i - 1);
 
                                        X509_NAME_oneline(X509_get_subject_name(this_cert), subject, sizeof(subject));