Author: kotkov
Date: Wed Apr 19 18:35:12 2023
New Revision: 1909256

URL: http://svn.apache.org/viewvc?rev=1909256&view=rev
Log:
On the '1.3.x-r1901040' branch: Merge r1901040 from trunk (Fix 
test_ssl_handshake()
failure with OpenSSL 1.1.1i+).

Resolve the conflicts and adjust the change to the state of the 1.3.x branch,
where the corresponding SSL tests are located in test/test_context.c.

Modified:
    serf/branches/1.3.x-r1901040/   (props changed)
    serf/branches/1.3.x-r1901040/test/test_context.c

Propchange: serf/branches/1.3.x-r1901040/
------------------------------------------------------------------------------
  Merged /serf/trunk:r1901040

Modified: serf/branches/1.3.x-r1901040/test/test_context.c
URL: 
http://svn.apache.org/viewvc/serf/branches/1.3.x-r1901040/test/test_context.c?rev=1909256&r1=1909255&r2=1909256&view=diff
==============================================================================
--- serf/branches/1.3.x-r1901040/test/test_context.c (original)
+++ serf/branches/1.3.x-r1901040/test/test_context.c Wed Apr 19 18:35:12 2023
@@ -25,6 +25,8 @@
 #include <apr_strings.h>
 #include <apr_version.h>
 
+#include <openssl/opensslv.h>
+
 #include "serf.h"
 #include "serf_private.h"
 
@@ -1127,34 +1129,90 @@ static apr_status_t validate_rootcacert(
     return APR_SUCCESS;
 }
 
-static apr_status_t
-ssl_server_cert_cb_expect_failures(void *baton, int failures,
-                                   const serf_ssl_certificate_t *cert)
+static const char *format_cert_failures(int failures, apr_pool_t *pool)
 {
-    test_baton_t *tb = baton;
-    int expected_failures = *(int *)tb->user_baton;
+    const char *str = "";
 
-    tb->result_flags |= TEST_RESULT_SERVERCERTCB_CALLED;
+    if (failures & SERF_SSL_CERT_NOTYETVALID) {
+        str = apr_pstrcat(pool, str, *str ? "|" : "", "CERT_NOTYETVALID", 
NULL);
+        failures &= ~SERF_SSL_CERT_NOTYETVALID;
+    }
 
-    /* We expect an error from the certificate validation function. */
-    if (failures & expected_failures)
-        return APR_SUCCESS;
+    if (failures & SERF_SSL_CERT_EXPIRED) {
+        str = apr_pstrcat(pool, str, *str ? "|" : "", "CERT_EXPIRED", NULL);
+        failures &= ~SERF_SSL_CERT_EXPIRED;
+    }
+
+    if (failures & SERF_SSL_CERT_UNKNOWNCA) {
+        str = apr_pstrcat(pool, str, *str ? "|" : "", "CERT_UNKNOWNCA", NULL);
+        failures &= ~SERF_SSL_CERT_UNKNOWNCA;
+    }
+
+    if (failures & SERF_SSL_CERT_SELF_SIGNED) {
+        str = apr_pstrcat(pool, str, *str ? "|" : "", "CERT_SELF_SIGNED", 
NULL);
+        failures &= ~SERF_SSL_CERT_SELF_SIGNED;
+    }
+
+    if (failures & SERF_SSL_CERT_UNKNOWN_FAILURE) {
+        str = apr_pstrcat(pool, str, *str ? "|" : "", "CERT_UNKNOWN_FAILURE", 
NULL);
+        failures &= ~SERF_SSL_CERT_UNKNOWN_FAILURE;
+    }
+
+    if (failures & SERF_SSL_CERT_REVOKED) {
+        str = apr_pstrcat(pool, str, *str ? "|" : "", "CERT_REVOKED", NULL);
+        failures &= ~SERF_SSL_CERT_REVOKED;
+    }
+
+    if (failures) {
+        printf("Unexpected or unknown cert failure\n");
+        abort();
+    }
+
+    if (*str)
+        return str;
     else
-        return SERF_ERROR_ISSUE_IN_TESTSUITE;
+        return "NONE";
 }
 
-static apr_status_t
-ssl_server_cert_cb_expect_allok(void *baton, int failures,
-                                const serf_ssl_certificate_t *cert)
+/* Logs failures in tb->user_baton, for later validation. */
+static apr_status_t ssl_server_cert_cb_log(void *baton, int failures,
+                                           const serf_ssl_certificate_t *cert)
 {
     test_baton_t *tb = baton;
+    const char *cert_str;
+
     tb->result_flags |= TEST_RESULT_SERVERCERTCB_CALLED;
 
-    /* No error expected, certificate is valid. */
-    if (failures)
-        return SERF_ERROR_ISSUE_IN_TESTSUITE;
-    else
-        return APR_SUCCESS;
+    if (cert) {
+        apr_hash_t *subject;
+        const char *common_name;
+        int depth;
+
+        subject = serf_ssl_cert_subject(cert, tb->pool);
+        if (!subject)
+            return SERF_ERROR_ISSUE_IN_TESTSUITE;
+
+        common_name = apr_hash_get(subject, "CN", APR_HASH_KEY_STRING);
+        depth = serf_ssl_cert_depth(cert);
+
+        cert_str = apr_psprintf(tb->pool, "(CN=%s, depth=%d)", common_name, 
depth);
+    } else {
+        cert_str = "(null)";
+    }
+
+    if (!tb->user_baton)
+        tb->user_baton = "";
+
+    tb->user_baton = apr_pstrcat(
+        tb->pool,
+        tb->user_baton,
+        "cert_cb: "
+        "failures = ", format_cert_failures(failures, tb->pool),
+        ", cert = ", cert_str,
+        "\n",
+        NULL);
+
+    return APR_SUCCESS;
 }
 
 static apr_status_t
@@ -1171,7 +1229,6 @@ static void test_ssl_handshake(CuTest *t
     test_baton_t *tb;
     handler_baton_t handler_ctx[1];
     const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
-    int expected_failures;
     apr_status_t status;
     test_server_message_t message_list[] = {
         {CHUNKED_REQUEST(1, "1")},
@@ -1194,20 +1251,34 @@ static void test_ssl_handshake(CuTest *t
                                      get_srcdir_file(test_pool, 
"test/server/serfserverkey.pem"),
                                      server_certs_srcdir(server_cert, 
test_pool),
                                      NULL, /* no client cert */
-                                     ssl_server_cert_cb_expect_failures,
+                                     ssl_server_cert_cb_log,
                                      test_pool);
     CuAssertIntEquals(tc, APR_SUCCESS, status);
 
-    /* This unknown failures is X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE, 
-       meaning the chain has only the server cert. A good candidate for its
-       own failure code. */
-    expected_failures = SERF_SSL_CERT_UNKNOWNCA;
-    tb->user_baton = &expected_failures;
-
     create_new_request(tb, &handler_ctx[0], "GET", "/", 1);
 
     test_helper_run_requests_expect_ok(tc, tb, num_requests, handler_ctx,
                                        test_pool);
+
+    /* OpenSSL 1.1.1i allows to continue verification for certificates with an
+       unknown CA. See https://github.com/openssl/openssl/issues/11297.
+
+       These unknown failures are X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
+       and X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE. The second one means 
that
+       the chain has only the server cert. A good candidate for its own failure
+       code. */
+#if OPENSSL_VERSION_NUMBER >= 0x1010109fL /* >= 1.1.1i */
+    CuAssertStrEquals(tc,
+        "cert_cb: failures = CERT_UNKNOWNCA, cert = (CN=localhost, depth=0)\n"
+        "cert_cb: failures = CERT_UNKNOWNCA, cert = (CN=localhost, depth=0)\n"
+        "cert_cb: failures = NONE, cert = (CN=localhost, depth=0)\n",
+        tb->user_baton);
+#else
+    CuAssertStrEquals(tc,
+        "cert_cb: failures = CERT_UNKNOWNCA, cert = (CN=localhost, depth=0)\n"
+        "cert_cb: failures = CERT_UNKNOWNCA, cert = (CN=localhost, depth=0)\n",
+        tb->user_baton);
+#endif
 }
 
 /* Set up the ssl context with the CA and root CA certificates needed for
@@ -1266,7 +1337,7 @@ static void test_ssl_trust_rootca(CuTest
                                      get_srcdir_file(test_pool, 
"test/server/serfserverkey.pem"),
                                      server_certs_srcdir(server_certs, 
test_pool),
                                      NULL, /* no client cert */
-                                     ssl_server_cert_cb_expect_allok,
+                                     ssl_server_cert_cb_log,
                                      test_pool);
     CuAssertIntEquals(tc, APR_SUCCESS, status);
 
@@ -1274,6 +1345,9 @@ static void test_ssl_trust_rootca(CuTest
 
     test_helper_run_requests_expect_ok(tc, tb, num_requests, handler_ctx,
                                        test_pool);
+    CuAssertStrEquals(tc,
+        "cert_cb: failures = NONE, cert = (CN=localhost, depth=0)\n",
+        tb->user_baton);
 }
 
 /* Validate that when the application rejects the cert, the context loop
@@ -1366,7 +1440,7 @@ chain_rootca_callback_conn_setup(apr_soc
         return status;
 
     serf_ssl_server_cert_chain_callback_set(tb->ssl_context,
-                                            ssl_server_cert_cb_expect_allok,
+                                            ssl_server_cert_cb_log,
                                             cert_chain_cb,
                                             tb);
 
@@ -1400,7 +1474,7 @@ static void test_ssl_certificate_chain_w
                                      get_srcdir_file(test_pool, 
"test/server/serfserverkey.pem"),
                                      server_certs_srcdir(server_certs, 
test_pool),
                                      NULL, /* no client cert */
-                                     ssl_server_cert_cb_expect_allok,
+                                     ssl_server_cert_cb_log,
                                      test_pool);
     CuAssertIntEquals(tc, APR_SUCCESS, status);
 
@@ -1408,8 +1482,9 @@ static void test_ssl_certificate_chain_w
 
     test_helper_run_requests_expect_ok(tc, tb, num_requests,
                                        handler_ctx, test_pool);
-
-    CuAssertTrue(tc, tb->result_flags & TEST_RESULT_SERVERCERTCB_CALLED);
+    CuAssertStrEquals(tc,
+        "cert_cb: failures = NONE, cert = (CN=localhost, depth=0)\n",
+        tb->user_baton);
     CuAssertTrue(tc, tb->result_flags & TEST_RESULT_SERVERCERTCHAINCB_CALLED);
 }
 
@@ -1442,7 +1517,7 @@ chain_callback_conn_setup(apr_socket_t *
         return status;
 
     serf_ssl_server_cert_chain_callback_set(tb->ssl_context,
-                                            ssl_server_cert_cb_expect_allok,
+                                            ssl_server_cert_cb_log,
                                             cert_chain_all_certs_cb,
                                             tb);
 
@@ -1475,7 +1550,7 @@ static void test_ssl_certificate_chain_a
                                      get_srcdir_file(test_pool, 
"test/server/serfserverkey.pem"),
                                      server_certs_srcdir(all_server_certs, 
test_pool),
                                      NULL, /* no client cert */
-                                     ssl_server_cert_cb_expect_allok,
+                                     ssl_server_cert_cb_log,
                                      test_pool);
     CuAssertIntEquals(tc, APR_SUCCESS, status);
 
@@ -1484,7 +1559,10 @@ static void test_ssl_certificate_chain_a
     test_helper_run_requests_expect_ok(tc, tb, num_requests,
                                        handler_ctx, test_pool);
 
-    CuAssertTrue(tc, tb->result_flags & TEST_RESULT_SERVERCERTCB_CALLED);
+    CuAssertStrEquals(tc,
+        "cert_cb: failures = CERT_SELF_SIGNED, cert = (CN=Serf Root CA, 
depth=2)\n"
+        "cert_cb: failures = NONE, cert = (CN=localhost, depth=0)\n",
+        tb->user_baton);
     CuAssertTrue(tc, tb->result_flags & TEST_RESULT_SERVERCERTCHAINCB_CALLED);
 }
 
@@ -1739,7 +1817,6 @@ static void test_ssl_expired_server_cert
     test_baton_t *tb;
     handler_baton_t handler_ctx[1];
     const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
-    int expected_failures;
     apr_status_t status;
     test_server_message_t message_list[] = {
         {CHUNKED_REQUEST(1, "1")},
@@ -1764,18 +1841,19 @@ static void test_ssl_expired_server_cert
                                      get_srcdir_file(test_pool, 
"test/server/serfserverkey.pem"),
                                      server_certs_srcdir(expired_server_certs, 
test_pool),
                                      NULL, /* no client cert */
-                                     ssl_server_cert_cb_expect_failures,
+                                     ssl_server_cert_cb_log,
                                      test_pool);
     CuAssertIntEquals(tc, APR_SUCCESS, status);
 
-    expected_failures = SERF_SSL_CERT_SELF_SIGNED |
-                        SERF_SSL_CERT_EXPIRED;
-    tb->user_baton = &expected_failures;
-
     create_new_request(tb, &handler_ctx[0], "GET", "/", 1);
 
     test_helper_run_requests_expect_ok(tc, tb, num_requests, handler_ctx,
                                        test_pool);
+    CuAssertStrEquals(tc,
+        "cert_cb: failures = CERT_SELF_SIGNED, cert = (CN=Serf Root CA, 
depth=2)\n"
+        "cert_cb: failures = CERT_EXPIRED, cert = (CN=localhost, depth=0)\n"
+        "cert_cb: failures = CERT_EXPIRED, cert = (CN=localhost, depth=0)\n",
+        tb->user_baton);
 }
 
 /* Validate that the expired certificate is reported as failure in the
@@ -1785,7 +1863,6 @@ static void test_ssl_future_server_cert(
     test_baton_t *tb;
     handler_baton_t handler_ctx[1];
     const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
-    int expected_failures;
     apr_status_t status;
     test_server_message_t message_list[] = {
         {CHUNKED_REQUEST(1, "1")},
@@ -1810,18 +1887,19 @@ static void test_ssl_future_server_cert(
                                      get_srcdir_file(test_pool, 
"test/server/serfserverkey.pem"),
                                      server_certs_srcdir(future_server_certs, 
test_pool),
                                      NULL, /* no client cert */
-                                     ssl_server_cert_cb_expect_failures,
+                                     ssl_server_cert_cb_log,
                                      test_pool);
     CuAssertIntEquals(tc, APR_SUCCESS, status);
 
-    expected_failures = SERF_SSL_CERT_SELF_SIGNED |
-                        SERF_SSL_CERT_NOTYETVALID;
-    tb->user_baton = &expected_failures;
-
     create_new_request(tb, &handler_ctx[0], "GET", "/", 1);
 
     test_helper_run_requests_expect_ok(tc, tb, num_requests, handler_ctx,
                                        test_pool);
+    CuAssertStrEquals(tc,
+        "cert_cb: failures = CERT_SELF_SIGNED, cert = (CN=Serf Root CA, 
depth=2)\n"
+        "cert_cb: failures = CERT_NOTYETVALID, cert = (CN=localhost, 
depth=0)\n"
+        "cert_cb: failures = CERT_NOTYETVALID, cert = (CN=localhost, 
depth=0)\n",
+        tb->user_baton);
 }
 
 


Reply via email to