EVP_PKEY *pkdh = NULL;
unsigned char *encodedPoint = NULL;
size_t encodedlen = 0;
- int curve_id = 0;
+ int group_id = 0;
const SIGALG_LOOKUP *lu = s->s3.tmp.sigalg;
int i;
unsigned long type;
CERT *cert = s->cert;
EVP_PKEY *pkdhp = NULL;
- if (s->cert->dh_tmp_auto) {
- pkdh = ssl_get_auto_dh(s);
- if (pkdh == NULL) {
+ /* Get NID of appropriate shared FFDHE group */
+ group_id = tls1_shared_group(s, TLS1_GROUPS_RETURN_TMP_ID,
+ TLS1_GROUPS_FFDHE_GROUPS);
+ if (group_id != 0) {
+ /* Cache the group used in the SSL_SESSION */
+ s->session->kex_group = group_id;
+
+ s->s3.tmp.pkey = ssl_generate_pkey_group(s, group_id);
+ if (s->s3.tmp.pkey == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
- pkdhp = pkdh;
} else {
- pkdhp = cert->dh_tmp;
- }
+
+ if (s->cert->dh_tmp_auto) {
+ pkdh = ssl_get_auto_dh(s);
+ if (pkdh == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ pkdhp = pkdh;
+ } else {
+ pkdhp = cert->dh_tmp;
+ }
#if !defined(OPENSSL_NO_DEPRECATED_3_0)
- if ((pkdhp == NULL) && (s->cert->dh_tmp_cb != NULL)) {
- pkdh = ssl_dh_to_pkey(s->cert->dh_tmp_cb(SSL_CONNECTION_GET_USER_SSL(s),
- 0, 1024));
- if (pkdh == NULL) {
+ if ((pkdhp == NULL) && (s->cert->dh_tmp_cb != NULL)) {
+ pkdh = ssl_dh_to_pkey(s->cert->dh_tmp_cb(SSL_CONNECTION_GET_USER_SSL(s),
+ 0, 1024));
+ if (pkdh == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ pkdhp = pkdh;
+ }
+#endif
+ if (pkdhp == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_MISSING_TMP_DH_KEY);
+ goto err;
+ }
+ if (!ssl_security(s, SSL_SECOP_TMP_DH,
+ EVP_PKEY_get_security_bits(pkdhp), 0, pkdhp)) {
+ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_DH_KEY_TOO_SMALL);
+ goto err;
+ }
+ if (s->s3.tmp.pkey != NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
- pkdhp = pkdh;
- }
-#endif
- if (pkdhp == NULL) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_MISSING_TMP_DH_KEY);
- goto err;
- }
- if (!ssl_security(s, SSL_SECOP_TMP_DH,
- EVP_PKEY_get_security_bits(pkdhp), 0, pkdhp)) {
- SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_DH_KEY_TOO_SMALL);
- goto err;
- }
- if (s->s3.tmp.pkey != NULL) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- s->s3.tmp.pkey = ssl_generate_pkey(s, pkdhp);
- if (s->s3.tmp.pkey == NULL) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- goto err;
- }
+ s->s3.tmp.pkey = ssl_generate_pkey(s, pkdhp);
+ if (s->s3.tmp.pkey == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
- EVP_PKEY_free(pkdh);
- pkdh = NULL;
+ EVP_PKEY_free(pkdh);
+ pkdh = NULL;
+ }
/* These BIGNUMs need to be freed when we're finished */
freer = 1;
goto err;
}
- /* Get NID of appropriate shared curve */
- curve_id = tls1_shared_group(s, TLS1_GROUPS_RETURN_TMP_ID,
+ /* Get NID of appropriate shared ECDHE curve */
+ group_id = tls1_shared_group(s, TLS1_GROUPS_RETURN_TMP_ID,
TLS1_GROUPS_NON_FFDHE_GROUPS);
- if (curve_id == 0) {
+ if (group_id == 0) {
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
goto err;
}
/* Cache the group used in the SSL_SESSION */
- s->session->kex_group = curve_id;
+ s->session->kex_group = group_id;
/* Generate a new key for this curve */
- s->s3.tmp.pkey = ssl_generate_pkey_group(s, curve_id);
+ s->s3.tmp.pkey = ssl_generate_pkey_group(s, group_id);
if (s->s3.tmp.pkey == NULL) {
/* SSLfatal() already called */
goto err;
* point itself
*/
if (!WPACKET_put_bytes_u8(pkt, NAMED_CURVE_TYPE)
- || !WPACKET_put_bytes_u16(pkt, curve_id)
+ || !WPACKET_put_bytes_u16(pkt, group_id)
|| !WPACKET_sub_memcpy_u8(pkt, encodedPoint, encodedlen)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
return 1;
#endif
+ OSSL_PROVIDER *tlsprov = OSSL_PROVIDER_load(libctx, "tls-provider");
+
+ if (!TEST_ptr(tlsprov))
+ goto end;
+
if (idx >= 5 && idx <= 8) {
dhpkey = get_tmp_dh_params();
if (!TEST_ptr(dhpkey))
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")))
+ || !TEST_true(SSL_set_cipher_list(serverssl, "DHE-RSA-AES128-SHA"))
+ /* This is required so the server does not use RFC7919 groups */
+ || !TEST_true(SSL_set1_groups_list(clientssl, "xorgroup")))
goto end;
/*
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
EVP_PKEY_free(dhpkey);
+ OSSL_PROVIDER_unload(tlsprov);
return testresult;
}
*/
static int test_dh_auto(int idx)
{
+ OSSL_PROVIDER *tlsprov = OSSL_PROVIDER_load(libctx, "tls-provider");
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;
size_t expdhsize = 0;
const char *ciphersuite = "DHE-RSA-AES128-SHA";
+ if (!TEST_ptr(tlsprov))
+ goto end;
+
if (!TEST_ptr(sctx) || !TEST_ptr(cctx))
goto end;
|| !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_set_cipher_list(clientssl, ciphersuite))
+ /* This is required so the server does not use RFC7919 groups */
+ || !TEST_true(SSL_set1_groups_list(clientssl, "xorgroup")))
goto end;
/*
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
EVP_PKEY_free(tmpkey);
+ OSSL_PROVIDER_unload(tlsprov);
return testresult;
}
return testresult;
}
+/*
+ * Test the server will use the supported FFDHE group advertised by the client.
+ */
+static int test_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;
+ EVP_PKEY *tmpkey = NULL;
+ char *servergroups = "ffdhe2048:ffdhe3072:ffdhe4096:ffdhe6144:ffdhe8192";
+ char *clientgroup = NULL;
+ const char *ciphersuite = "DHE-RSA-AES128-SHA256";
+ char gname[10];
+ size_t gname_len;
+
+ if (!TEST_ptr(sctx) || !TEST_ptr(cctx))
+ goto end;
+
+ switch (idx) {
+ case 0:
+ clientgroup = "ffdhe2048";
+ break;
+ case 1:
+ clientgroup = "ffdhe3072";
+ break;
+ case 2:
+ clientgroup = "ffdhe4096";
+ break;
+ case 3:
+ clientgroup = "ffdhe6144";
+ break;
+ case 4:
+ clientgroup = "ffdhe8192";
+ 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, servergroups))
+ || !TEST_true(SSL_set1_groups_list(clientssl, clientgroup)))
+ goto end;
+
+ /*
+ * Send the server's first flight. At this point the server has created the
+ * temporary DH key but hasn't finished using it yet. Once used it is
+ * removed, so we cannot test it.
+ */
+ if (!TEST_int_le(SSL_connect(clientssl), 0)
+ || !TEST_int_le(SSL_accept(serverssl), 0))
+ goto end;
+
+ if (!TEST_int_gt(SSL_get_tmp_key(serverssl, &tmpkey), 0))
+ goto end;
+ if (!TEST_true(EVP_PKEY_get_group_name(tmpkey, gname, sizeof(gname), &gname_len))
+ || !TEST_str_eq(gname, clientgroup))
+ goto end;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ testresult = 1;
+
+end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ EVP_PKEY_free(tmpkey);
+
+ return testresult;
+}
#endif /* OPENSSL_NO_TLS1_3 */
+
#endif /* OPENSSL_NO_DH */
#endif /* OPENSSL_NO_TLS1_2 */
ADD_ALL_TESTS(test_dh_auto, 7);
#ifndef OPENSSL_NO_TLS1_3
ADD_ALL_TESTS(test_no_shared_ffdhe_group, 10);
+ ADD_ALL_TESTS(test_shared_ffdhe_group, 5);
#endif
#endif
#endif