Commit 005a4d04 authored by Daiki Ueno's avatar Daiki Ueno
Browse files

cert auth: reject auth if no signature algorithm is usable in TLS 1.3



Previously, when there is no overlap between usable signature
algorithms and the "signature_algorithms" extension in Certificate
Request, the client failed in sending Certificate Verify, followed by
a connection close.  In TLS 1.3, it is possible to keep the connection
but reject the authentication by not sending Certificate Verify.
Signed-off-by: Daiki Ueno's avatarDaiki Ueno <dueno@redhat.com>
parent 344c77b7
......@@ -128,17 +128,20 @@ int _gnutls13_recv_certificate_request_int(gnutls_session_t session, gnutls_buff
{
int ret;
crt_req_ctx_st ctx;
gnutls_pcert_st *apr_cert_list;
gnutls_privkey_t apr_pkey;
int apr_cert_list_length;
_gnutls_handshake_log("HSK[%p]: parsing certificate request\n", session);
if (unlikely(session->security_parameters.entity == GNUTLS_SERVER))
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
/* if initial negotiation is complete, this is a post-handshake auth */
if (!session->internals.initial_negotiation_completed ||
session->security_parameters.entity == GNUTLS_SERVER) {
if (!session->internals.initial_negotiation_completed) {
if (buf->data[0] != 0) {
/* The context field must be empty during handshake */
ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
gnutls_assert();
goto cleanup;
return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
}
/* buf->length is positive */
......@@ -162,10 +165,8 @@ int _gnutls13_recv_certificate_request_int(gnutls_session_t session, gnutls_buff
ctx.session = session;
ret = _gnutls_extv_parse(&ctx, parse_cert_extension, buf->data, buf->length);
if (ret < 0) {
gnutls_assert();
goto cleanup;
}
if (ret < 0)
return gnutls_assert_val(ret);
/* The "signature_algorithms" extension MUST be specified */
if (!ctx.got_sig_algo)
......@@ -175,15 +176,28 @@ int _gnutls13_recv_certificate_request_int(gnutls_session_t session, gnutls_buff
ret = _gnutls_select_client_cert(session, ctx.rdn, ctx.rdn_size,
ctx.pk_algos, ctx.pk_algos_length);
if (ret < 0) {
gnutls_assert();
goto cleanup;
}
if (ret < 0)
return gnutls_assert_val(ret);
ret = 0;
ret = _gnutls_get_selected_cert(session, &apr_cert_list,
&apr_cert_list_length, &apr_pkey);
if (ret < 0)
return gnutls_assert_val(ret);
cleanup:
return ret;
if (apr_cert_list_length > 0) {
gnutls_sign_algorithm_t algo;
algo = _gnutls_session_get_sign_algo(session, &apr_cert_list[0], apr_pkey, 0);
if (algo == GNUTLS_SIGN_UNKNOWN) {
_gnutls_handshake_log("HSK[%p]: rejecting client auth because of no suitable signature algorithm\n", session);
_gnutls_selected_certs_deinit(session);
return gnutls_assert_val(0);
}
gnutls_sign_algorithm_set_client(session, algo);
}
return 0;
}
int _gnutls13_recv_certificate_request(gnutls_session_t session)
......
......@@ -187,14 +187,19 @@ int _gnutls13_send_certificate_verify(gnutls_session_t session, unsigned again)
}
}
algo = _gnutls_session_get_sign_algo(session, &apr_cert_list[0], apr_pkey, 0);
if (algo == GNUTLS_SIGN_UNKNOWN)
return gnutls_assert_val(GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY);
if (server) {
algo = _gnutls_session_get_sign_algo(session, &apr_cert_list[0], apr_pkey, 0);
if (algo == GNUTLS_SIGN_UNKNOWN)
return gnutls_assert_val(GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY);
if (server)
gnutls_sign_algorithm_set_server(session, algo);
else
gnutls_sign_algorithm_set_client(session, algo);
} else {
/* for client, signature algorithm is already
* determined from Certificate Request */
algo = gnutls_sign_algorithm_get_client(session);
if (unlikely(algo == GNUTLS_SIGN_UNKNOWN))
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
}
se = _gnutls_sign_to_entry(algo);
......
......@@ -135,7 +135,7 @@ void doit(void)
try_with_key_fail("TLS 1.3 with rsa-pss cert and rsa cli cert with only RSA-PSS sig algos",
"NORMAL:-VERS-ALL:+VERS-TLS1.3:-SIGN-ALL:+SIGN-RSA-PSS-SHA256:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA512",
GNUTLS_E_AGAIN, GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY,
GNUTLS_E_CERTIFICATE_REQUIRED, GNUTLS_E_SUCCESS,
&server_ca3_rsa_pss_cert, &server_ca3_rsa_pss_key, &cli_ca3_cert, &cli_ca3_key);
try_with_key_fail("TLS 1.3 with rsa encryption cert",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment