Change Post Handshake auth so that it is opt-in
Having post handshake auth automatically switched on breaks some applications written for TLSv1.2. This changes things so that an explicit function call is required for a client to indicate support for post-handshake auth. Fixes #6933. Reviewed-by: Tim Hudson <tjh@openssl.org> (Merged from https://github.com/openssl/openssl/pull/6938)
This commit is contained in:
parent
756510c102
commit
32097b33bd
15 changed files with 73 additions and 66 deletions
|
@ -595,7 +595,7 @@ typedef enum OPTION_choice {
|
|||
OPT_CT, OPT_NOCT, OPT_CTLOG_FILE,
|
||||
#endif
|
||||
OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME,
|
||||
OPT_FORCE_PHA,
|
||||
OPT_ENABLE_PHA,
|
||||
OPT_R_ENUM
|
||||
} OPTION_CHOICE;
|
||||
|
||||
|
@ -786,7 +786,7 @@ const OPTIONS s_client_options[] = {
|
|||
#endif
|
||||
{"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"},
|
||||
{"early_data", OPT_EARLY_DATA, '<', "File to send as early data"},
|
||||
{"force_pha", OPT_FORCE_PHA, '-', "Force-enable post-handshake-authentication"},
|
||||
{"enable_pha", OPT_ENABLE_PHA, '-', "Enable post-handshake-authentication"},
|
||||
{NULL, OPT_EOF, 0x00, NULL}
|
||||
};
|
||||
|
||||
|
@ -975,7 +975,7 @@ int s_client_main(int argc, char **argv)
|
|||
int isdtls = 0;
|
||||
#endif
|
||||
char *psksessf = NULL;
|
||||
int force_pha = 0;
|
||||
int enable_pha = 0;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_ZERO(&writefds);
|
||||
|
@ -1492,8 +1492,8 @@ int s_client_main(int argc, char **argv)
|
|||
case OPT_EARLY_DATA:
|
||||
early_data_file = opt_arg();
|
||||
break;
|
||||
case OPT_FORCE_PHA:
|
||||
force_pha = 1;
|
||||
case OPT_ENABLE_PHA:
|
||||
enable_pha = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1944,8 +1944,8 @@ int s_client_main(int argc, char **argv)
|
|||
if (con == NULL)
|
||||
goto end;
|
||||
|
||||
if (force_pha)
|
||||
SSL_force_post_handshake_auth(con);
|
||||
if (enable_pha)
|
||||
SSL_set_post_handshake_auth(con, 1);
|
||||
|
||||
if (sess_in != NULL) {
|
||||
SSL_SESSION *sess;
|
||||
|
|
|
@ -134,7 +134,7 @@ B<openssl> B<s_client>
|
|||
[B<-ctlogfile>]
|
||||
[B<-keylogfile file>]
|
||||
[B<-early_data file>]
|
||||
[B<-force_pha>]
|
||||
[B<-enable_pha>]
|
||||
[B<target>]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
@ -700,10 +700,10 @@ Reads the contents of the specified file and attempts to send it as early data
|
|||
to the server. This will only work with resumed sessions that support early
|
||||
data and when the server accepts the early data.
|
||||
|
||||
=item B<-force_pha>
|
||||
=item B<-enable_pha>
|
||||
|
||||
For TLSv1.3 only, always send the Post-Handshake Authentication extension,
|
||||
whether or not a certificate has been provided via B<-cert>.
|
||||
For TLSv1.3 only, send the Post-Handshake Authentication extension. This will
|
||||
happen whether or not a certificate has been provided via B<-cert>.
|
||||
|
||||
=item B<[target]>
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ SSL_CTX_set_verify, SSL_set_verify,
|
|||
SSL_CTX_set_verify_depth, SSL_set_verify_depth,
|
||||
SSL_verify_cb,
|
||||
SSL_verify_client_post_handshake,
|
||||
SSL_force_post_handshake_auth
|
||||
SSL_set_post_handshake_auth
|
||||
- set peer certificate verification parameters
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
@ -24,7 +24,7 @@ SSL_force_post_handshake_auth
|
|||
void SSL_set_verify_depth(SSL *ssl, int depth);
|
||||
|
||||
int SSL_verify_client_post_handshake(SSL *ssl);
|
||||
void SSL_force_post_handshake_auth(SSL *ssl);
|
||||
void SSL_set_post_handshake_auth(SSL *ssl, int val);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
@ -48,11 +48,12 @@ verification that shall be allowed for B<ctx>.
|
|||
SSL_set_verify_depth() sets the maximum B<depth> for the certificate chain
|
||||
verification that shall be allowed for B<ssl>.
|
||||
|
||||
SSL_force_post_handshake_auth() forces the Post-Handshake Authentication
|
||||
extension to be added to the ClientHello regardless of certificate configuration
|
||||
at the time of the initial handshake, such that post-handshake authentication
|
||||
can be requested by the server. A certificate callback will need to be set via
|
||||
SSL_CTX_set_client_cert_cb() if no certificate is provided at initialization.
|
||||
SSL_set_post_handshake_auth() enables the Post-Handshake Authentication
|
||||
extension to be added to the ClientHello such that post-handshake authentication
|
||||
can be requested by the server. If B<val> is 0 then the extension is not sent,
|
||||
otherwise it is. By default the extension is not sent. A certificate callback
|
||||
will need to be set via SSL_CTX_set_client_cert_cb() if no certificate is
|
||||
provided at initialization.
|
||||
|
||||
SSL_verify_client_post_handshake() causes a CertificateRequest message to be
|
||||
sent by a server on the given B<ssl> connection. The SSL_VERIFY_PEER flag must
|
||||
|
@ -341,7 +342,7 @@ L<CRYPTO_get_ex_new_index(3)>
|
|||
=head1 HISTORY
|
||||
|
||||
The SSL_VERIFY_POST_HANDSHAKE option, and the SSL_verify_client_post_handshake()
|
||||
and SSL_force_post_handshake_auth() functions were added in OpenSSL 1.1.1.
|
||||
and SSL_set_post_handshake_auth() functions were added in OpenSSL 1.1.1.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
|
|
|
@ -1898,7 +1898,7 @@ int SSL_renegotiate_abbreviated(SSL *s);
|
|||
__owur int SSL_renegotiate_pending(SSL *s);
|
||||
int SSL_shutdown(SSL *s);
|
||||
__owur int SSL_verify_client_post_handshake(SSL *s);
|
||||
void SSL_force_post_handshake_auth(SSL *s);
|
||||
void SSL_set_post_handshake_auth(SSL *s, int val);
|
||||
|
||||
__owur const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx);
|
||||
__owur const SSL_METHOD *SSL_get_ssl_method(SSL *s);
|
||||
|
|
|
@ -5455,9 +5455,9 @@ int SSL_stateless(SSL *s)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void SSL_force_post_handshake_auth(SSL *ssl)
|
||||
void SSL_set_post_handshake_auth(SSL *ssl, int val)
|
||||
{
|
||||
ssl->pha_forced = 1;
|
||||
ssl->pha_enabled = val;
|
||||
}
|
||||
|
||||
int SSL_verify_client_post_handshake(SSL *ssl)
|
||||
|
|
|
@ -1391,7 +1391,7 @@ struct ssl_st {
|
|||
int key_update;
|
||||
/* Post-handshake authentication state */
|
||||
SSL_PHA_STATE post_handshake_auth;
|
||||
int pha_forced;
|
||||
int pha_enabled;
|
||||
uint8_t* pha_context;
|
||||
size_t pha_context_len;
|
||||
int certreqs_sent;
|
||||
|
|
|
@ -1193,23 +1193,8 @@ EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL *s, WPACKET *pkt,
|
|||
X509 *x, size_t chainidx)
|
||||
{
|
||||
#ifndef OPENSSL_NO_TLS1_3
|
||||
if (!s->pha_forced) {
|
||||
int i, n = 0;
|
||||
|
||||
/* check for cert, if present, we can do post-handshake auth */
|
||||
if (s->cert == NULL)
|
||||
return EXT_RETURN_NOT_SENT;
|
||||
|
||||
for (i = 0; i < SSL_PKEY_NUM; i++) {
|
||||
if (s->cert->pkeys[i].x509 != NULL
|
||||
&& s->cert->pkeys[i].privatekey != NULL)
|
||||
n++;
|
||||
}
|
||||
|
||||
/* no identity certificates, so no extension */
|
||||
if (n == 0)
|
||||
return EXT_RETURN_NOT_SENT;
|
||||
}
|
||||
if (!s->pha_enabled)
|
||||
return EXT_RETURN_NOT_SENT;
|
||||
|
||||
/* construct extension - 0 length, no contents */
|
||||
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_post_handshake_auth)
|
||||
|
|
|
@ -726,8 +726,8 @@ static void configure_handshake_ssl(SSL *server, SSL *client,
|
|||
if (extra->client.servername != SSL_TEST_SERVERNAME_NONE)
|
||||
SSL_set_tlsext_host_name(client,
|
||||
ssl_servername_name(extra->client.servername));
|
||||
if (extra->client.force_pha)
|
||||
SSL_force_post_handshake_auth(client);
|
||||
if (extra->client.enable_pha)
|
||||
SSL_set_post_handshake_auth(client, 1);
|
||||
}
|
||||
|
||||
/* The status for each connection phase. */
|
||||
|
|
|
@ -214,7 +214,7 @@ SKIP: {
|
|||
|
||||
#Test 6: A client auth handshake
|
||||
$proxy->clear();
|
||||
$proxy->clientflags("-cert ".srctop_file("apps", "server.pem"));
|
||||
$proxy->clientflags("-enable_pha -cert ".srctop_file("apps", "server.pem"));
|
||||
$proxy->serverflags("-Verify 5");
|
||||
$proxy->start();
|
||||
checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE,
|
||||
|
|
|
@ -299,6 +299,10 @@ ExpectedClientSignHash = SHA256
|
|||
ExpectedClientSignType = RSA-PSS
|
||||
ExpectedResult = Success
|
||||
HandshakeMode = PostHandshakeAuth
|
||||
client = 8-client-auth-TLSv1.3-require-post-handshake-client-extra
|
||||
|
||||
[8-client-auth-TLSv1.3-require-post-handshake-client-extra]
|
||||
EnablePHA = Yes
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
@ -337,6 +341,10 @@ ExpectedClientSignHash = SHA256
|
|||
ExpectedClientSignType = RSA-PSS
|
||||
ExpectedResult = Success
|
||||
HandshakeMode = PostHandshakeAuth
|
||||
client = 9-client-auth-TLSv1.3-require-non-empty-names-post-handshake-client-extra
|
||||
|
||||
[9-client-auth-TLSv1.3-require-non-empty-names-post-handshake-client-extra]
|
||||
EnablePHA = Yes
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
@ -369,6 +377,10 @@ VerifyMode = Peer
|
|||
ExpectedResult = ServerFail
|
||||
ExpectedServerAlert = UnknownCA
|
||||
HandshakeMode = PostHandshakeAuth
|
||||
client = 10-client-auth-TLSv1.3-noroot-post-handshake-client-extra
|
||||
|
||||
[10-client-auth-TLSv1.3-noroot-post-handshake-client-extra]
|
||||
EnablePHA = Yes
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
@ -401,7 +413,7 @@ HandshakeMode = PostHandshakeAuth
|
|||
client = 11-client-auth-TLSv1.3-request-force-client-post-handshake-client-extra
|
||||
|
||||
[11-client-auth-TLSv1.3-request-force-client-post-handshake-client-extra]
|
||||
ForcePHA = Yes
|
||||
EnablePHA = Yes
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
@ -471,6 +483,6 @@ client = 13-client-auth-TLSv1.3-request-force-both-post-handshake-client-extra
|
|||
ForcePHA = Yes
|
||||
|
||||
[13-client-auth-TLSv1.3-request-force-both-post-handshake-client-extra]
|
||||
ForcePHA = Yes
|
||||
EnablePHA = Yes
|
||||
|
||||
|
||||
|
|
|
@ -176,6 +176,9 @@ our @tests = (
|
|||
"MaxProtocol" => "TLSv1.3",
|
||||
"Certificate" => test_pem("ee-client-chain.pem"),
|
||||
"PrivateKey" => test_pem("ee-key.pem"),
|
||||
extra => {
|
||||
"EnablePHA" => "Yes",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success",
|
||||
|
@ -201,6 +204,9 @@ our @tests = (
|
|||
"MaxProtocol" => "TLSv1.3",
|
||||
"Certificate" => test_pem("ee-client-chain.pem"),
|
||||
"PrivateKey" => test_pem("ee-key.pem"),
|
||||
extra => {
|
||||
"EnablePHA" => "Yes",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success",
|
||||
|
@ -223,6 +229,9 @@ our @tests = (
|
|||
"MaxProtocol" => "TLSv1.3",
|
||||
"Certificate" => test_pem("ee-client-chain.pem"),
|
||||
"PrivateKey" => test_pem("ee-key.pem"),
|
||||
extra => {
|
||||
"EnablePHA" => "Yes",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "ServerFail",
|
||||
|
@ -240,9 +249,9 @@ our @tests = (
|
|||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
extra => {
|
||||
"ForcePHA" => "Yes",
|
||||
},
|
||||
extra => {
|
||||
"EnablePHA" => "Yes",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success",
|
||||
|
@ -255,9 +264,9 @@ our @tests = (
|
|||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"VerifyMode" => "RequestPostHandshake",
|
||||
extra => {
|
||||
"ForcePHA" => "Yes",
|
||||
},
|
||||
extra => {
|
||||
"ForcePHA" => "Yes",
|
||||
},
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
|
@ -274,16 +283,16 @@ our @tests = (
|
|||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"VerifyMode" => "RequestPostHandshake",
|
||||
extra => {
|
||||
"ForcePHA" => "Yes",
|
||||
},
|
||||
extra => {
|
||||
"ForcePHA" => "Yes",
|
||||
},
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
extra => {
|
||||
"ForcePHA" => "Yes",
|
||||
},
|
||||
extra => {
|
||||
"EnablePHA" => "Yes",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success",
|
||||
|
|
|
@ -629,9 +629,9 @@ __owur static int parse_expected_client_ca_names(SSL_TEST_CTX *test_ctx,
|
|||
|
||||
IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_cipher)
|
||||
|
||||
/* Client and Server ForcePHA */
|
||||
/* Client and Server PHA */
|
||||
|
||||
IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CLIENT_CONF, client, force_pha)
|
||||
IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CLIENT_CONF, client, enable_pha)
|
||||
IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_SERVER_CONF, server, force_pha)
|
||||
|
||||
/* Known test options and their corresponding parse methods. */
|
||||
|
@ -689,7 +689,7 @@ static const ssl_test_client_option ssl_test_client_options[] = {
|
|||
{ "SRPUser", &parse_client_srp_user },
|
||||
{ "SRPPassword", &parse_client_srp_password },
|
||||
{ "MaxFragmentLenExt", &parse_max_fragment_len_mode },
|
||||
{ "ForcePHA", &parse_client_force_pha },
|
||||
{ "EnablePHA", &parse_client_enable_pha },
|
||||
};
|
||||
|
||||
/* Nested server options. */
|
||||
|
|
|
@ -108,8 +108,8 @@ typedef struct {
|
|||
char *reneg_ciphers;
|
||||
char *srp_user;
|
||||
char *srp_password;
|
||||
/* Forced PHA */
|
||||
int force_pha;
|
||||
/* PHA enabled */
|
||||
int enable_pha;
|
||||
} SSL_TEST_CLIENT_CONF;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -1270,7 +1270,7 @@ static int check_resumption(int idx, SSL_CTX *sctx, SSL_CTX *cctx, int succ)
|
|||
|| !TEST_true(SSL_set_session(clientssl, sesscache[i])))
|
||||
goto end;
|
||||
|
||||
SSL_force_post_handshake_auth(clientssl);
|
||||
SSL_set_post_handshake_auth(clientssl, 1);
|
||||
|
||||
if (!TEST_true(create_ssl_connection(serverssl, clientssl,
|
||||
SSL_ERROR_NONE)))
|
||||
|
@ -1377,7 +1377,7 @@ static int test_tickets(int stateful, int idx)
|
|||
&clientssl, NULL, NULL)))
|
||||
goto end;
|
||||
|
||||
SSL_force_post_handshake_auth(clientssl);
|
||||
SSL_set_post_handshake_auth(clientssl, 1);
|
||||
|
||||
if (!TEST_true(create_ssl_connection(serverssl, clientssl,
|
||||
SSL_ERROR_NONE))
|
||||
|
@ -4336,7 +4336,7 @@ static int test_pha_key_update(void)
|
|||
NULL, NULL)))
|
||||
goto end;
|
||||
|
||||
SSL_force_post_handshake_auth(clientssl);
|
||||
SSL_set_post_handshake_auth(clientssl, 1);
|
||||
|
||||
if (!TEST_true(create_ssl_connection(serverssl, clientssl,
|
||||
SSL_ERROR_NONE)))
|
||||
|
|
|
@ -475,7 +475,7 @@ SSL_set_tlsext_max_fragment_length 475 1_1_1 EXIST::FUNCTION:
|
|||
SSL_SESSION_get_max_fragment_length 476 1_1_1 EXIST::FUNCTION:
|
||||
SSL_stateless 477 1_1_1 EXIST::FUNCTION:
|
||||
SSL_verify_client_post_handshake 478 1_1_1 EXIST::FUNCTION:
|
||||
SSL_force_post_handshake_auth 479 1_1_1 EXIST::FUNCTION:
|
||||
SSL_set_post_handshake_auth 479 1_1_1 EXIST::FUNCTION:
|
||||
SSL_export_keying_material_early 480 1_1_1 EXIST::FUNCTION:
|
||||
SSL_CTX_use_cert_and_key 481 1_1_1 EXIST::FUNCTION:
|
||||
SSL_use_cert_and_key 482 1_1_1 EXIST::FUNCTION:
|
||||
|
|
Loading…
Reference in a new issue