return 1;
}
+/*
+ * tls1_check_ffdhe_tmp_key - Check FFDHE temporary key compatibility
+ * @s: SSL connection
+ * @cid: Cipher ID we're considering using
+ *
+ * Checks that the kDHE cipher suite we're considering using
+ * is compatible with the client extensions.
+ *
+ * Returns 0 when the cipher can't be used or 1 when it can.
+ */
+int tls1_check_ffdhe_tmp_key(SSL_CONNECTION *s, unsigned long cid)
+{
+ const uint16_t *peer_groups;
+ size_t num_peer_groups;
+
+ /* If we have a shared FFDHE group, we can certainly use it. */
+ if (tls1_shared_group(s, 0, TLS1_GROUPS_FFDHE_GROUPS) != 0)
+ return 1;
+
+ /*
+ * Otherwise, we follow RFC 7919:
+ * If a compatible TLS server receives a Supported Groups extension from
+ * a client that includes any FFDHE group (i.e., any codepoint between
+ * 256 and 511, inclusive, even if unknown to the server), and if none
+ * of the client-proposed FFDHE groups are known and acceptable to the
+ * server, then the server MUST NOT select an FFDHE cipher suite.
+ */
+ tls1_get_peer_groups(s, &peer_groups, &num_peer_groups);
+ for (size_t i = 0; i < num_peer_groups; i++) {
+ if (is_ffdhe_group(peer_groups[i]))
+ return 0;
+ }
+
+ /*
+ * The client did not send any FFDHE groups, so we can use this ciphersuite
+ * using any group we like.
+ */
+ return 1;
+}
+
/*
* tls1_check_ec_tmp_key - Check EC temporary key compatibility
* @s: SSL connection
return testresult;
}
+
+#ifndef OPENSSL_NO_TLS1_3
+/*
+ * Test the server will reject FFDHE ciphersuites if no supported FFDHE group is
+ * advertised by the client.
+ */
+static int test_no_shared_ffdhe_group(int idx)
+{
+ SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, TLS_client_method());
+ SSL_CTX *sctx = SSL_CTX_new_ex(libctx, NULL, TLS_server_method());
+ SSL *clientssl = NULL, *serverssl = NULL;
+ int testresult = 0, ret, expected = 1;
+ char *clientgroup = NULL, *servergroup = NULL, *ciphersuite = NULL;
+ int want_error = SSL_ERROR_NONE;
+
+ if (!TEST_ptr(sctx) || !TEST_ptr(cctx))
+ goto end;
+
+ switch (idx) {
+ case 0:
+ clientgroup = "ffdhe2048";
+ servergroup = "ffdhe3072";
+ ciphersuite = "DHE-RSA-AES128-SHA256:AES128-SHA256";
+ break;
+ case 1:
+ clientgroup = "ffdhe3072";
+ servergroup = "ffdhe4096";
+ ciphersuite = "DHE-RSA-AES128-SHA256:AES128-SHA256";
+ break;
+ case 2:
+ clientgroup = "ffdhe4096";
+ servergroup = "ffdhe6144";
+ ciphersuite = "DHE-RSA-AES128-SHA256:AES128-SHA256";
+ break;
+ case 3:
+ clientgroup = "ffdhe6144";
+ servergroup = "ffdhe8192";
+ ciphersuite = "DHE-RSA-AES128-SHA256:AES128-SHA256";
+ break;
+ case 4:
+ clientgroup = "ffdhe8192";
+ servergroup = "ffdhe2048";
+ ciphersuite = "DHE-RSA-AES128-SHA256:AES128-SHA256";
+ break;
+ case 5:
+ clientgroup = "ffdhe2048";
+ servergroup = "ffdhe3072";
+ ciphersuite = "DHE-RSA-AES128-SHA256";
+ expected = 0;
+ want_error = SSL_ERROR_SSL;
+ break;
+ case 6:
+ clientgroup = "ffdhe3072";
+ servergroup = "ffdhe4096";
+ ciphersuite = "DHE-RSA-AES128-SHA256";
+ expected = 0;
+ want_error = SSL_ERROR_SSL;
+ break;
+ case 7:
+ clientgroup = "ffdhe4096";
+ servergroup = "ffdhe6144";
+ ciphersuite = "DHE-RSA-AES128-SHA256";
+ expected = 0;
+ want_error = SSL_ERROR_SSL;
+ break;
+ case 8:
+ clientgroup = "ffdhe6144";
+ servergroup = "ffdhe8192";
+ ciphersuite = "DHE-RSA-AES128-SHA256";
+ expected = 0;
+ want_error = SSL_ERROR_SSL;
+ break;
+ case 9:
+ clientgroup = "ffdhe8192";
+ servergroup = "ffdhe2048";
+ ciphersuite = "DHE-RSA-AES128-SHA256";
+ expected = 0;
+ want_error = SSL_ERROR_SSL;
+ break;
+ default:
+ TEST_error("Invalid text index");
+ goto end;
+ }
+
+ if (!TEST_true(create_ssl_ctx_pair(libctx, NULL,
+ NULL,
+ 0,
+ 0,
+ &sctx, &cctx, cert, privkey)))
+ goto end;
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL)))
+ goto end;
+
+ if (!TEST_true(SSL_set_dh_auto(serverssl, 1))
+ || !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, ciphersuite))
+ || !TEST_true(SSL_set_cipher_list(clientssl, ciphersuite))
+ || !TEST_true(SSL_set1_groups_list(serverssl, servergroup))
+ || !TEST_true(SSL_set1_groups_list(clientssl, clientgroup)))
+ goto end;
+
+ ret = create_ssl_connection(serverssl, clientssl, want_error);
+ if (!TEST_int_eq(expected, ret))
+ goto end;
+
+ if (expected <= 0) {
+ testresult = 1;
+ goto end;
+ }
+
+ /*
+ * Note that the server should not select the DHE ciphersuite if there are
+ * no shared FFDHE groups, so if it was selected, that is an error.
+ */
+ if (TEST_int_eq(TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
+ SSL_CIPHER_get_id(SSL_get_current_cipher(clientssl))))
+ goto end;
+
+ testresult = 1;
+
+end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+
+ return testresult;
+}
+
+#endif /* OPENSSL_NO_TLS1_3 */
#endif /* OPENSSL_NO_DH */
#endif /* OPENSSL_NO_TLS1_2 */
#ifndef OPENSSL_NO_DH
ADD_ALL_TESTS(test_set_tmp_dh, 11);
ADD_ALL_TESTS(test_dh_auto, 7);
+#ifndef OPENSSL_NO_TLS1_3
+ ADD_ALL_TESTS(test_no_shared_ffdhe_group, 10);
+#endif
#endif
#endif
#ifndef OSSL_NO_USABLE_TLS1_3