]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add a test for the various ways of setting temporary DH params
authorMatt Caswell <matt@openssl.org>
Wed, 21 Oct 2020 15:00:48 +0000 (16:00 +0100)
committerMatt Caswell <matt@openssl.org>
Wed, 18 Nov 2020 14:14:53 +0000 (14:14 +0000)
We support a number of different ways of setting temporary DH params. We
should test that they all work correctly.

Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13368)

test/dtlstest.c
test/sslapitest.c
test/sslcorrupttest.c
test/ssltestlib.c

index 1ac2850fd754a6310509be68aa79e5ccd32102de..efdf842e2db449db69880356149789b06de606a5 100644 (file)
@@ -162,6 +162,9 @@ static int test_dtls_drop_records(int idx)
                                        &sctx, &cctx, cert, privkey)))
         return 0;
 
+    if (!TEST_true(SSL_CTX_set_dh_auto(sctx, 1)))
+        goto end;
+
     if (idx >= TOTAL_FULL_HAND_RECORDS) {
         /* We're going to do a resumption handshake. Get a session first. */
         if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
index b87b07e2707ef487d914f4b61e048a3435cb2249..6b49d2a250f33bb4ed7553a2b6063c15b0b04345 100644 (file)
@@ -30,6 +30,7 @@
 #include <openssl/core_names.h>
 #include <openssl/core_dispatch.h>
 #include <openssl/provider.h>
+#include <openssl/param_build.h>
 
 #include "ssltestlib.h"
 #include "testutil.h"
@@ -6374,6 +6375,9 @@ static int test_info_callback(int tst)
                                        privkey)))
         goto end;
 
+    if (!TEST_true(SSL_CTX_set_dh_auto(sctx, 1)))
+        goto end;
+
     /*
      * For even numbered tests we check the server callbacks. For odd numbers we
      * check the client.
@@ -8045,7 +8049,197 @@ static int test_ssl_dup(void)
 
     return testresult;
 }
-#endif
+
+# ifndef OPENSSL_NO_DH
+
+static EVP_PKEY *tmp_dh_params = NULL;
+
+/* Helper function for the test_set_tmp_dh() tests */
+static EVP_PKEY *get_tmp_dh_params(void)
+{
+    if (tmp_dh_params == NULL) {
+        BIGNUM *p = NULL;
+        OSSL_PARAM_BLD *tmpl = NULL;
+        EVP_PKEY_CTX *pctx = NULL;
+        OSSL_PARAM *params = NULL;
+        EVP_PKEY *dhpkey = NULL;
+
+        p = BN_get_rfc3526_prime_2048(NULL);
+        if (!TEST_ptr(p))
+            goto end;
+
+        pctx = EVP_PKEY_CTX_new_from_name(libctx, "DH", NULL);
+        if (!TEST_ptr(pctx)
+                || !TEST_true(EVP_PKEY_key_fromdata_init(pctx)))
+            goto end;
+
+        tmpl = OSSL_PARAM_BLD_new();
+        if (!TEST_ptr(tmpl)
+                || !TEST_true(OSSL_PARAM_BLD_push_BN(tmpl,
+                                                        OSSL_PKEY_PARAM_FFC_P,
+                                                        p))
+                || !TEST_true(OSSL_PARAM_BLD_push_uint(tmpl,
+                                                        OSSL_PKEY_PARAM_FFC_G,
+                                                        2)))
+            goto end;
+
+        params = OSSL_PARAM_BLD_to_param(tmpl);
+        if (!TEST_ptr(params)
+                || !TEST_true(EVP_PKEY_fromdata(pctx, &dhpkey, params)))
+            goto end;
+
+        tmp_dh_params = dhpkey;
+    end:
+        BN_free(p);
+        EVP_PKEY_CTX_free(pctx);
+        OSSL_PARAM_BLD_free(tmpl);
+        OSSL_PARAM_BLD_free_params(params);
+    }
+
+    if (!EVP_PKEY_up_ref(tmp_dh_params))
+        return NULL;
+
+    return tmp_dh_params;
+}
+
+#  ifndef OPENSSL_NO_DEPRECATED
+/* Callback used by test_set_tmp_dh() */
+static DH *tmp_dh_callback(SSL *s, int is_export, int keylen)
+{
+    EVP_PKEY *dhpkey = get_tmp_dh_params();
+    DH *ret = NULL;
+
+    if (!TEST_ptr(dhpkey))
+        return NULL;
+
+    ret = EVP_PKEY_get0_DH(dhpkey);
+
+    EVP_PKEY_free(dhpkey);
+
+    return ret;
+}
+#  endif
+
+/*
+ * Test the various methods for setting temporary DH parameters
+ *
+ * Test  0: Default (no auto) setting
+ * Test  1: Explicit SSL_CTX auto off
+ * Test  2: Explicit SSL auto off
+ * Test  3: Explicit SSL_CTX auto on
+ * Test  4: Explicit SSL auto on
+ * Test  5: Explicit SSL_CTX auto off, custom DH params via EVP_PKEY
+ * Test  6: Explicit SSL auto off, custom DH params via EVP_PKEY
+ *
+ * The following are testing deprecated APIs, so we only run them if available
+ * Test  7: Explicit SSL_CTX auto off, custom DH params via DH
+ * Test  8: Explicit SSL auto off, custom DH params via DH
+ * Test  9: Explicit SSL_CTX auto off, custom DH params via callback
+ * Test 10: Explicit SSL auto off, custom DH params via callback
+ */
+static int test_set_tmp_dh(int idx)
+{
+    SSL_CTX *cctx = NULL, *sctx = NULL;
+    SSL *clientssl = NULL, *serverssl = NULL;
+    int testresult = 0;
+    int dhauto = (idx == 3 || idx == 4) ? 1 : 0;
+    int expected = (idx <= 2) ? 0 : 1;
+    EVP_PKEY *dhpkey = NULL;
+#  ifndef OPENSSL_NO_DEPRECATED_3_0
+    DH *dh = NULL;
+#  else
+
+    if (idx >= 7)
+        return 1;
+#  endif
+
+    if (idx >= 5 && idx <= 8) {
+        dhpkey = get_tmp_dh_params();
+        if (!TEST_ptr(dhpkey))
+            goto end;
+    }
+#  ifndef OPENSSL_NO_DEPRECATED_3_0
+    if (idx == 7 || idx == 8) {
+        dh = EVP_PKEY_get0_DH(dhpkey);
+        if (!TEST_ptr(dh))
+            goto end;
+    }
+#  endif
+
+    if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
+                                       TLS_client_method(),
+                                       0,
+                                       0,
+                                       &sctx, &cctx, cert, privkey)))
+        goto end;
+
+    if ((idx & 1) == 1) {
+        if (!TEST_true(SSL_CTX_set_dh_auto(sctx, dhauto)))
+            goto end;
+    }
+
+    if (idx == 5) {
+        if (!TEST_true(SSL_CTX_set0_tmp_dh_pkey(sctx, dhpkey)))
+            goto end;
+        dhpkey = NULL;
+    }
+#  ifndef OPENSSL_NO_DEPRECATED_3_0
+    else if (idx == 7) {
+        if (!TEST_true(SSL_CTX_set_tmp_dh(sctx, dh)))
+            goto end;
+    } else if (idx == 9) {
+        SSL_CTX_set_tmp_dh_callback(sctx, tmp_dh_callback);
+    }
+#  endif
+
+    if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+                                      NULL, NULL)))
+        goto end;
+
+    if ((idx & 1) == 0 && idx != 0) {
+        if (!TEST_true(SSL_set_dh_auto(serverssl, dhauto)))
+            goto end;
+    }
+    if (idx == 6) {
+        if (!TEST_true(SSL_set0_tmp_dh_pkey(serverssl, dhpkey)))
+            goto end;
+        dhpkey = NULL;
+    }
+#  ifndef OPENSSL_NO_DEPRECATED_3_0
+    else if (idx == 8) {
+        if (!TEST_true(SSL_set_tmp_dh(serverssl, dh)))
+            goto end;
+    } else if (idx == 10) {
+        SSL_set_tmp_dh_callback(serverssl, tmp_dh_callback);
+    }
+#  endif
+
+    if (!TEST_true(SSL_set_min_proto_version(serverssl, TLS1_2_VERSION))
+            || !TEST_true(SSL_set_max_proto_version(serverssl, TLS1_2_VERSION))
+            || !TEST_true(SSL_set_cipher_list(serverssl, "DHE-RSA-AES128-SHA")))
+        goto end;
+
+    /*
+     * If autoon then we should succeed. Otherwise we expect failure because
+     * there are no parameters
+     */
+    if (!TEST_int_eq(create_ssl_connection(serverssl, clientssl,
+                                           SSL_ERROR_NONE), expected))
+        goto end;
+
+    testresult = 1;
+
+ end:
+    SSL_free(serverssl);
+    SSL_free(clientssl);
+    SSL_CTX_free(sctx);
+    SSL_CTX_free(cctx);
+    EVP_PKEY_free(dhpkey);
+
+    return testresult;
+}
+# endif /* OPENSSL_NO_DH */
+#endif /* OPENSSL_NO_TLS1_2 */
 
 OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config\n")
 
@@ -8252,6 +8446,9 @@ int setup_tests(void)
 #endif
 #ifndef OPENSSL_NO_TLS1_2
     ADD_TEST(test_ssl_dup);
+# ifndef OPENSSL_NO_DH
+    ADD_ALL_TESTS(test_set_tmp_dh, 11);
+# endif
 #endif
     return 1;
 
@@ -8265,6 +8462,9 @@ int setup_tests(void)
 
 void cleanup_tests(void)
 {
+# ifndef OPENSSL_NO_DH
+    EVP_PKEY_free(tmp_dh_params);
+#endif
     OPENSSL_free(cert);
     OPENSSL_free(privkey);
     OPENSSL_free(cert2);
index ca9e8bfd731a9c5fb965442dfe17fa21b48c25df..97d235c8ad742aef62ab2e351b78e62c42c9ba03 100644 (file)
@@ -202,7 +202,8 @@ static int test_ssl_corrupt(int testidx)
                                        &sctx, &cctx, cert, privkey)))
         return 0;
 
-    if (!TEST_true(SSL_CTX_set_cipher_list(cctx, cipher_list[testidx]))
+    if (!TEST_true(SSL_CTX_set_dh_auto(sctx, 1))
+            || !TEST_true(SSL_CTX_set_cipher_list(cctx, cipher_list[testidx]))
             || !TEST_true(SSL_CTX_set_ciphersuites(cctx, ""))
             || !TEST_ptr(ciphers = SSL_CTX_get_ciphers(cctx))
             || !TEST_int_eq(sk_SSL_CIPHER_num(ciphers), 1)
index 734d1e936b547e8cb65080398cfdeb276e5e5d49..1fbe51763bc614623d83aa5981df3f12da3c0ed4 100644 (file)
@@ -731,10 +731,6 @@ const SSL_METHOD *cm,
             goto err;
     }
 
-#ifndef OPENSSL_NO_DH
-    SSL_CTX_set_dh_auto(serverctx, 1);
-#endif
-
     *sctx = serverctx;
     if (cctx != NULL)
         *cctx = clientctx;