mirror of https://github.com/openssl/openssl.git
				
				
				
			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
					
				|  | @ -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,24 +1193,9 @@ 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) | ||||
|     if (!s->pha_enabled) | ||||
|         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; | ||||
|     } | ||||
| 
 | ||||
|     /* construct extension - 0 length, no contents */ | ||||
|     if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_post_handshake_auth) | ||||
|             || !WPACKET_start_sub_packet_u16(pkt) | ||||
|  |  | |||
|  | @ -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", | ||||
|  | @ -241,7 +250,7 @@ our @tests = ( | |||
|             "MinProtocol" => "TLSv1.3", | ||||
|             "MaxProtocol" => "TLSv1.3", | ||||
|             extra => { | ||||
| 		"ForcePHA" => "Yes", | ||||
|                 "EnablePHA" => "Yes", | ||||
|             }, | ||||
|         }, | ||||
|         test => { | ||||
|  | @ -282,7 +291,7 @@ our @tests = ( | |||
|             "MinProtocol" => "TLSv1.3", | ||||
|             "MaxProtocol" => "TLSv1.3", | ||||
|             extra => { | ||||
| 		"ForcePHA" => "Yes", | ||||
|                 "EnablePHA" => "Yes", | ||||
|             }, | ||||
|         }, | ||||
|         test => { | ||||
|  |  | |||
|  | @ -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 New Issue