summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/s_cb.c1
-rw-r--r--apps/s_client.c9
-rw-r--r--apps/s_server.c13
-rw-r--r--crypto/err/openssl.txt17
-rw-r--r--doc/man1/s_client.pod6
-rw-r--r--doc/man3/SSL_CONF_cmd.pod12
-rw-r--r--doc/man3/SSL_CTX_set_verify.pod67
-rw-r--r--include/openssl/ssl.h5
-rw-r--r--include/openssl/sslerr.h12
-rw-r--r--include/openssl/tls1.h1
-rw-r--r--ssl/ssl_conf.c7
-rw-r--r--ssl/ssl_err.c19
-rw-r--r--ssl/ssl_lib.c54
-rw-r--r--ssl/ssl_locl.h22
-rw-r--r--ssl/statem/extensions.c17
-rw-r--r--ssl/statem/extensions_clnt.c42
-rw-r--r--ssl/statem/extensions_cust.c1
-rw-r--r--ssl/statem/extensions_srvr.c14
-rw-r--r--ssl/statem/statem_clnt.c75
-rw-r--r--ssl/statem/statem_lib.c111
-rw-r--r--ssl/statem/statem_locl.h10
-rw-r--r--ssl/statem/statem_srvr.c121
-rw-r--r--ssl/t1_trce.c3
-rw-r--r--test/build.info2
-rw-r--r--test/handshake_helper.c60
-rw-r--r--test/recipes/70-test_tls13messages.t7
-rw-r--r--test/recipes/80-test_ssl_new.t3
-rw-r--r--test/ssl-tests/26-tls13_client_auth.conf476
-rw-r--r--test/ssl-tests/26-tls13_client_auth.conf.in293
-rw-r--r--test/ssl_test_ctx.c8
-rw-r--r--test/ssl_test_ctx.h7
-rw-r--r--test/sslapitest.c60
-rw-r--r--util/libssl.num2
-rw-r--r--util/perl/TLSProxy/Message.pm1
-rw-r--r--util/perl/checkhandshake.pm3
35 files changed, 1484 insertions, 77 deletions
diff --git a/apps/s_cb.c b/apps/s_cb.c
index 575fb048c0..8d51d7439d 100644
--- a/apps/s_cb.c
+++ b/apps/s_cb.c
@@ -666,6 +666,7 @@ static STRINT_PAIR tlsext_types[] = {
{"psk", TLSEXT_TYPE_psk},
{"psk kex modes", TLSEXT_TYPE_psk_kex_modes},
{"certificate authorities", TLSEXT_TYPE_certificate_authorities},
+ {"post handshake auth", TLSEXT_TYPE_post_handshake_auth},
{NULL}
};
diff --git a/apps/s_client.c b/apps/s_client.c
index 774345e256..ca2bd0d9b4 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -602,6 +602,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_R_ENUM
} OPTION_CHOICE;
@@ -788,6 +789,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"},
{NULL, OPT_EOF, 0x00, NULL}
};
@@ -958,6 +960,7 @@ int s_client_main(int argc, char **argv)
int isdtls = 0;
#endif
char *psksessf = NULL;
+ int force_pha = 0;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
@@ -1469,6 +1472,9 @@ 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;
+ break;
}
}
if (count4or6 >= 2) {
@@ -1904,6 +1910,9 @@ int s_client_main(int argc, char **argv)
if (con == NULL)
goto end;
+ if (force_pha)
+ SSL_force_post_handshake_auth(con);
+
if (sess_in != NULL) {
SSL_SESSION *sess;
BIO *stmp = BIO_new_file(sess_in, "r");
diff --git a/apps/s_server.c b/apps/s_server.c
index d57eefb2d2..a0e72b3c64 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -2501,6 +2501,19 @@ static int sv_body(int s, int stype, int prot, unsigned char *context)
i = 0;
continue;
}
+ if (buf[0] == 'c' && ((buf[1] == '\n') || (buf[1] == '\r'))) {
+ SSL_set_verify(con, SSL_VERIFY_PEER, NULL);
+ i = SSL_verify_client_post_handshake(con);
+ if (i == 0) {
+ printf("Failed to initiate request\n");
+ ERR_print_errors(bio_err);
+ } else {
+ i = SSL_do_handshake(con);
+ printf("SSL_do_handshake -> %d\n", i);
+ i = 0;
+ }
+ continue;
+ }
if (buf[0] == 'P') {
static const char *str = "Lets print some clear text\n";
BIO_write(SSL_get_wbio(con), str, strlen(str));
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index ed706da904..fb3be57208 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -1,4 +1,4 @@
-# Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the OpenSSL license (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
@@ -1192,6 +1192,7 @@ SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1:205:SSL_use_RSAPrivateKey_ASN1
SSL_F_SSL_USE_RSAPRIVATEKEY_FILE:206:SSL_use_RSAPrivateKey_file
SSL_F_SSL_VALIDATE_CT:400:ssl_validate_ct
SSL_F_SSL_VERIFY_CERT_CHAIN:207:ssl_verify_cert_chain
+SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE:616:SSL_verify_client_post_handshake
SSL_F_SSL_WRITE:208:SSL_write
SSL_F_SSL_WRITE_EARLY_DATA:526:SSL_write_early_data
SSL_F_SSL_WRITE_EARLY_FINISH:527:*
@@ -1205,6 +1206,10 @@ SSL_F_TLS13_ENC:609:tls13_enc
SSL_F_TLS13_FINAL_FINISH_MAC:605:tls13_final_finish_mac
SSL_F_TLS13_GENERATE_SECRET:591:tls13_generate_secret
SSL_F_TLS13_HKDF_EXPAND:561:tls13_hkdf_expand
+SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA:617:\
+ tls13_restore_handshake_digest_for_pha
+SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA:618:\
+ tls13_save_handshake_digest_for_pha
SSL_F_TLS13_SETUP_KEY_BLOCK:441:tls13_setup_key_block
SSL_F_TLS1_CHANGE_CIPHER_STATE:209:tls1_change_cipher_state
SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS:341:*
@@ -1247,6 +1252,8 @@ SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE:470:tls_construct_ctos_key_share
SSL_F_TLS_CONSTRUCT_CTOS_MAXFRAGMENTLEN:549:tls_construct_ctos_maxfragmentlen
SSL_F_TLS_CONSTRUCT_CTOS_NPN:471:tls_construct_ctos_npn
SSL_F_TLS_CONSTRUCT_CTOS_PADDING:472:tls_construct_ctos_padding
+SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH:619:\
+ tls_construct_ctos_post_handshake_auth
SSL_F_TLS_CONSTRUCT_CTOS_PSK:501:tls_construct_ctos_psk
SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES:509:tls_construct_ctos_psk_kex_modes
SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE:473:tls_construct_ctos_renegotiate
@@ -1315,6 +1322,7 @@ SSL_F_TLS_PARSE_CTOS_EC_PT_FORMATS:569:tls_parse_ctos_ec_pt_formats
SSL_F_TLS_PARSE_CTOS_EMS:570:tls_parse_ctos_ems
SSL_F_TLS_PARSE_CTOS_KEY_SHARE:463:tls_parse_ctos_key_share
SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN:571:tls_parse_ctos_maxfragmentlen
+SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH:620:tls_parse_ctos_post_handshake_auth
SSL_F_TLS_PARSE_CTOS_PSK:505:tls_parse_ctos_psk
SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES:572:tls_parse_ctos_psk_kex_modes
SSL_F_TLS_PARSE_CTOS_RENEGOTIATE:464:tls_parse_ctos_renegotiate
@@ -2446,6 +2454,7 @@ SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST:151:error in received cipher list
SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN:204:error setting tlsa base domain
SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE:194:exceeds max fragment size
SSL_R_EXCESSIVE_MESSAGE_SIZE:152:excessive message size
+SSL_R_EXTENSION_NOT_RECEIVED:279:extension not received
SSL_R_EXTRA_DATA_IN_MESSAGE:153:extra data in message
SSL_R_EXT_LENGTH_MISMATCH:163:ext length mismatch
SSL_R_FAILED_TO_INIT_ASYNC:405:failed to init async
@@ -2466,7 +2475,9 @@ SSL_R_INVALID_CCS_MESSAGE:260:invalid ccs message
SSL_R_INVALID_CERTIFICATE_OR_ALG:238:invalid certificate or alg
SSL_R_INVALID_COMMAND:280:invalid command
SSL_R_INVALID_COMPRESSION_ALGORITHM:341:invalid compression algorithm
+SSL_R_INVALID_CONFIG:283:invalid config
SSL_R_INVALID_CONFIGURATION_NAME:113:invalid configuration name
+SSL_R_INVALID_CONTEXT:282:invalid context
SSL_R_INVALID_CT_VALIDATION_TYPE:212:invalid ct validation type
SSL_R_INVALID_KEY_UPDATE_TYPE:120:invalid key update type
SSL_R_INVALID_MAX_EARLY_DATA:174:invalid max early data
@@ -2495,6 +2506,7 @@ SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION:209:missing supported groups extension
SSL_R_MISSING_TMP_DH_KEY:171:missing tmp dh key
SSL_R_MISSING_TMP_ECDH_KEY:311:missing tmp ecdh key
SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary
+SSL_R_NOT_SERVER:284:not server
SSL_R_NO_APPLICATION_PROTOCOL:235:no application protocol
SSL_R_NO_CERTIFICATES_RETURNED:176:no certificates returned
SSL_R_NO_CERTIFICATE_ASSIGNED:177:no certificate assigned
@@ -2534,6 +2546,7 @@ SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE:199:peer did not return a certificate
SSL_R_PEM_NAME_BAD_PREFIX:391:pem name bad prefix
SSL_R_PEM_NAME_TOO_SHORT:392:pem name too short
SSL_R_PIPELINE_FAILURE:406:pipeline failure
+SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR:278:post handshake auth encoding err
SSL_R_PROTOCOL_IS_SHUTDOWN:207:protocol is shutdown
SSL_R_PSK_IDENTITY_NOT_FOUND:223:psk identity not found
SSL_R_PSK_NO_CLIENT_CB:224:psk no client cb
@@ -2545,6 +2558,8 @@ SSL_R_RECORD_TOO_SMALL:298:record too small
SSL_R_RENEGOTIATE_EXT_TOO_LONG:335:renegotiate ext too long
SSL_R_RENEGOTIATION_ENCODING_ERR:336:renegotiation encoding err
SSL_R_RENEGOTIATION_MISMATCH:337:renegotiation mismatch
+SSL_R_REQUEST_PENDING:285:request pending
+SSL_R_REQUEST_SENT:286:request sent
SSL_R_REQUIRED_CIPHER_MISSING:215:required cipher missing
SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING:342:\
required compression algorithm missing
diff --git a/doc/man1/s_client.pod b/doc/man1/s_client.pod
index 1d9dd39656..4f0f01c3db 100644
--- a/doc/man1/s_client.pod
+++ b/doc/man1/s_client.pod
@@ -118,6 +118,7 @@ B<openssl> B<s_client>
[B<-ctlogfile>]
[B<-keylogfile file>]
[B<-early_data file>]
+[B<-force_pha>]
[B<target>]
=head1 DESCRIPTION
@@ -621,6 +622,11 @@ 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>
+
+For TLSv1.3 only, always send the Post-Handshake Authentication extension,
+whether or not a certificate has been provided via B<-cert>.
+
=item B<[target]>
Rather than providing B<-connect>, the target hostname and optional port may
diff --git a/doc/man3/SSL_CONF_cmd.pod b/doc/man3/SSL_CONF_cmd.pod
index 06b98bd416..27317e0652 100644
--- a/doc/man3/SSL_CONF_cmd.pod
+++ b/doc/man3/SSL_CONF_cmd.pod
@@ -435,6 +435,18 @@ occurs if the client does not present a certificate. Servers only.
B<Once> requests a certificate from a client only on the initial connection:
not when renegotiating. Servers only.
+B<RequestPostHandshake> configures the connection to support requests but does
+not require a certificate from the client post-handshake. A certificate will
+not be requested during the initial handshake. The server application must
+provide a mechanism to request a certificate post-handshake. Servers only.
+TLSv1.3 only.
+
+B<RequiresPostHandshake> configures the connection to support requests and
+requires a certificate from the client post-handshake: an error occurs if the
+client does not present a certificate. A certificate will not be requested
+during the initial handshake. The server application must provide a mechanism
+to request a certificate post-handshake. Servers only. TLSv1.3 only.
+
=item B<ClientCAFile>, B<ClientCAPath>
A file or directory of certificates in PEM format whose names are used as the
diff --git a/doc/man3/SSL_CTX_set_verify.pod b/doc/man3/SSL_CTX_set_verify.pod
index 9e634dd91d..c9b4daf42a 100644
--- a/doc/man3/SSL_CTX_set_verify.pod
+++ b/doc/man3/SSL_CTX_set_verify.pod
@@ -5,7 +5,9 @@
SSL_get_ex_data_X509_STORE_CTX_idx,
SSL_CTX_set_verify, SSL_set_verify,
SSL_CTX_set_verify_depth, SSL_set_verify_depth,
-SSL_verify_cb
+SSL_verify_cb,
+SSL_verify_client_post_handshake,
+SSL_force_post_handshake_auth
- set peer certificate verification parameters
=head1 SYNOPSIS
@@ -15,11 +17,14 @@ SSL_verify_cb
typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx);
void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, SSL_verify_cb verify_callback);
- void SSL_set_verify(SSL *s, int mode, SSL_verify_cb verify_callback);
+ void SSL_set_verify(SSL *ssl, int mode, SSL_verify_cb verify_callback);
SSL_get_ex_data_X509_STORE_CTX_idx(void);
void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth);
- void SSL_set_verify_depth(SSL *s, int depth);
+ 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);
=head1 DESCRIPTION
@@ -43,6 +48,16 @@ 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_verify_client_post_handshake() causes a Certificate Request message to be
+sent by a server on the given B<ssl> connection. The SSL_VERIFY_PEER flag must
+be set, the SSL_VERIFY_POST_HANDSHAKE flag is optional.
+
=head1 NOTES
The verification of certificates can be controlled by a set of logically
@@ -69,7 +84,8 @@ fails, the TLS/SSL handshake is
immediately terminated with an alert message containing the reason for
the verification failure.
The behaviour can be controlled by the additional
-SSL_VERIFY_FAIL_IF_NO_PEER_CERT and SSL_VERIFY_CLIENT_ONCE flags.
+SSL_VERIFY_FAIL_IF_NO_PEER_CERT, SSL_VERIFY_CLIENT_ONCE and
+SSL_VERIFY_POST_HANDSHAKE flags.
B<Client mode:> the server certificate is verified. If the verification process
fails, the TLS/SSL handshake is
@@ -87,9 +103,22 @@ B<Client mode:> ignored
=item SSL_VERIFY_CLIENT_ONCE
-B<Server mode:> only request a client certificate on the initial TLS/SSL
-handshake. Do not ask for a client certificate again in case of a
-renegotiation. This flag must be used together with SSL_VERIFY_PEER.
+B<Server mode:> only request a client certificate once during the
+connection. Do not ask for a client certificate again during
+renegotiation or post-authentication if a certificate was requested
+during the initial handshake. This flag must be used together with
+SSL_VERIFY_PEER.
+
+B<Client mode:> ignored
+
+=item SSL_VERIFY_POST_HANDSHAKE
+
+B<Server mode:> the server will not send a client certificate request
+during the initial handshake, but will send the request via
+SSL_verify_client_post_handshake(). This allows the SSL_CTX or SSL
+to be configured for post-handshake peer verification before the
+handshake occurs. This flag must be used together with
+SSL_VERIFY_PEER. TLSv1.3 only; no effect on pre-TLSv1.3 connections.
B<Client mode:> ignored
@@ -154,6 +183,20 @@ Its return value is identical to B<preverify_ok>, so that any verification
failure will lead to a termination of the TLS/SSL handshake with an
alert message, if SSL_VERIFY_PEER is set.
+After calling SSL_force_post_handshake_auth(), the client will need to add a
+certificate to its configuration before it can successfully authenticate. This
+must be called before SSL_connect().
+
+SSL_verify_client_post_handshake() requires that verify flags have been
+previously set, and that a client sent the post-handshake authentication
+extension. When the client returns a certificate the verify callback will be
+invoked. A write operation must take place for the Certificate Request to be
+sent to the client, this can be done with SSL_do_handshake() or SSL_write_ex().
+Only one certificate request may be outstanding at any time.
+
+When post-handshake authentication occurs, a refreshed B<NewSessionTicket>
+message is sent to the client.
+
=head1 BUGS
In client mode, it is not checked whether the SSL_VERIFY_PEER flag
@@ -165,6 +208,10 @@ required.
The SSL*_set_verify*() functions do not provide diagnostic information.
+The SSL_verify_client_post_handshake() function returns 1 if the request
+succeeded, and 0 if the request failed. The error stack can be examined
+to determine the failure reason.
+
=head1 EXAMPLES
The following code sequence realizes an example B<verify_callback> function
@@ -288,8 +335,14 @@ L<SSL_CTX_load_verify_locations(3)>,
L<SSL_get_peer_certificate(3)>,
L<SSL_CTX_set_cert_verify_callback(3)>,
L<SSL_get_ex_data_X509_STORE_CTX_idx(3)>,
+L<SSL_CTX_set_client_cert_cb(3)>,
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.
+
=head1 COPYRIGHT
Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved.
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 97d2e46248..9c45b90075 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1052,13 +1052,14 @@ size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
/*
- * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options are
+ * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 3 options are
* 'ored' with SSL_VERIFY_PEER if they are desired
*/
# define SSL_VERIFY_NONE 0x00
# define SSL_VERIFY_PEER 0x01
# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
# define SSL_VERIFY_CLIENT_ONCE 0x04
+# define SSL_VERIFY_POST_HANDSHAKE 0x08
# define OpenSSL_add_ssl_algorithms() SSL_library_init()
# if OPENSSL_API_COMPAT < 0x10100000L
@@ -1850,6 +1851,8 @@ int SSL_renegotiate(SSL *s);
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);
__owur const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx);
__owur const SSL_METHOD *SSL_get_ssl_method(SSL *s);
diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h
index ec81ba3f03..a84a62d30f 100644
--- a/include/openssl/sslerr.h
+++ b/include/openssl/sslerr.h
@@ -241,6 +241,7 @@ int ERR_load_SSL_strings(void);
# define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206
# define SSL_F_SSL_VALIDATE_CT 400
# define SSL_F_SSL_VERIFY_CERT_CHAIN 207
+# define SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE 616
# define SSL_F_SSL_WRITE 208
# define SSL_F_SSL_WRITE_EARLY_DATA 526
# define SSL_F_SSL_WRITE_EARLY_FINISH 527
@@ -254,6 +255,8 @@ int ERR_load_SSL_strings(void);
# define SSL_F_TLS13_FINAL_FINISH_MAC 605
# define SSL_F_TLS13_GENERATE_SECRET 591
# define SSL_F_TLS13_HKDF_EXPAND 561
+# define SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA 617
+# define SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA 618
# define SSL_F_TLS13_SETUP_KEY_BLOCK 441
# define SSL_F_TLS1_CHANGE_CIPHER_STATE 209
# define SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS 341
@@ -295,6 +298,7 @@ int ERR_load_SSL_strings(void);
# define SSL_F_TLS_CONSTRUCT_CTOS_MAXFRAGMENTLEN 549
# define SSL_F_TLS_CONSTRUCT_CTOS_NPN 471
# define SSL_F_TLS_CONSTRUCT_CTOS_PADDING 472
+# define SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH 619
# define SSL_F_TLS_CONSTRUCT_CTOS_PSK 501
# define SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES 509
# define SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE 473
@@ -358,6 +362,7 @@ int ERR_load_SSL_strings(void);
# define SSL_F_TLS_PARSE_CTOS_EMS 570
# define SSL_F_TLS_PARSE_CTOS_KEY_SHARE 463
# define SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN 571
+# define SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH 620
# define SSL_F_TLS_PARSE_CTOS_PSK 505
# define SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES 572
# define SSL_F_TLS_PARSE_CTOS_RENEGOTIATE 464
@@ -522,6 +527,7 @@ int ERR_load_SSL_strings(void);
# define SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN 204
# define SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE 194
# define SSL_R_EXCESSIVE_MESSAGE_SIZE 152
+# define SSL_R_EXTENSION_NOT_RECEIVED 279
# define SSL_R_EXTRA_DATA_IN_MESSAGE 153
# define SSL_R_EXT_LENGTH_MISMATCH 163
# define SSL_R_FAILED_TO_INIT_ASYNC 405
@@ -542,7 +548,9 @@ int ERR_load_SSL_strings(void);
# define SSL_R_INVALID_CERTIFICATE_OR_ALG 238
# define SSL_R_INVALID_COMMAND 280
# define SSL_R_INVALID_COMPRESSION_ALGORITHM 341
+# define SSL_R_INVALID_CONFIG 283
# define SSL_R_INVALID_CONFIGURATION_NAME 113
+# define SSL_R_INVALID_CONTEXT 282
# define SSL_R_INVALID_CT_VALIDATION_TYPE 212
# define SSL_R_INVALID_KEY_UPDATE_TYPE 120
# define SSL_R_INVALID_MAX_EARLY_DATA 174
@@ -571,6 +579,7 @@ int ERR_load_SSL_strings(void);
# define SSL_R_MISSING_TMP_DH_KEY 171
# define SSL_R_MISSING_TMP_ECDH_KEY 311
# define SSL_R_NOT_ON_RECORD_BOUNDARY 182
+# define SSL_R_NOT_SERVER 284
# define SSL_R_NO_APPLICATION_PROTOCOL 235
# define SSL_R_NO_CERTIFICATES_RETURNED 176
# define SSL_R_NO_CERTIFICATE_ASSIGNED 177
@@ -608,6 +617,7 @@ int ERR_load_SSL_strings(void);
# define SSL_R_PEM_NAME_BAD_PREFIX 391
# define SSL_R_PEM_NAME_TOO_SHORT 392
# define SSL_R_PIPELINE_FAILURE 406
+# define SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR 278
# define SSL_R_PROTOCOL_IS_SHUTDOWN 207
# define SSL_R_PSK_IDENTITY_NOT_FOUND 223
# define SSL_R_PSK_NO_CLIENT_CB 224
@@ -619,6 +629,8 @@ int ERR_load_SSL_strings(void);
# define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335
# define SSL_R_RENEGOTIATION_ENCODING_ERR 336
# define SSL_R_RENEGOTIATION_MISMATCH 337
+# define SSL_R_REQUEST_PENDING 285
+# define SSL_R_REQUEST_SENT 286
# define SSL_R_REQUIRED_CIPHER_MISSING 215
# define SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING 342
# define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345
diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
index 434e327f76..1253352d50 100644
--- a/include/openssl/tls1.h
+++ b/include/openssl/tls1.h
@@ -146,6 +146,7 @@ extern "C" {
# define TLSEXT_TYPE_cookie 44
# define TLSEXT_TYPE_psk_kex_modes 45
# define TLSEXT_TYPE_certificate_authorities 47
+# define TLSEXT_TYPE_post_handshake_auth 49
# define TLSEXT_TYPE_signature_algorithms_cert 50
# define TLSEXT_TYPE_key_share 51
diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c
index 0cd8ace437..cb4ff8daad 100644
--- a/ssl/ssl_conf.c
+++ b/ssl/ssl_conf.c
@@ -386,7 +386,12 @@ static int cmd_VerifyMode(SSL_CONF_CTX *cctx, const char *value)
SSL_FLAG_VFY_SRV("Request", SSL_VERIFY_PEER),
SSL_FLAG_VFY_SRV("Require",
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
- SSL_FLAG_VFY_SRV("Once", SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE)
+ SSL_FLAG_VFY_SRV("Once", SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE),
+ SSL_FLAG_VFY_SRV("RequestPostHandshake",
+ SSL_VERIFY_PEER | SSL_VERIFY_POST_HANDSHAKE),
+ SSL_FLAG_VFY_SRV("RequirePostHandshake",
+ SSL_VERIFY_PEER | SSL_VERIFY_POST_HANDSHAKE |
+ SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
};
if (value == NULL)
return -3;
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 746678cb39..f0bde60994 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -351,6 +351,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_VALIDATE_CT, 0), "ssl_validate_ct"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_VERIFY_CERT_CHAIN, 0),
"ssl_verify_cert_chain"},
+ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, 0),
+ "SSL_verify_client_post_handshake"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_WRITE, 0), "SSL_write"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_WRITE_EARLY_DATA, 0),
"SSL_write_early_data"},
@@ -369,6 +371,10 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS13_GENERATE_SECRET, 0),
"tls13_generate_secret"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS13_HKDF_EXPAND, 0), "tls13_hkdf_expand"},
+ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA, 0),
+ "tls13_restore_handshake_digest_for_pha"},
+ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA, 0),
+ "tls13_save_handshake_digest_for_pha"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS13_SETUP_KEY_BLOCK, 0),
"tls13_setup_key_block"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_CHANGE_CIPHER_STATE, 0),
@@ -441,6 +447,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
"tls_construct_ctos_npn"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_PADDING, 0),
"tls_construct_ctos_padding"},
+ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH, 0),
+ "tls_construct_ctos_post_handshake_auth"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_PSK, 0),
"tls_construct_ctos_psk"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES, 0),
@@ -557,6 +565,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
"tls_parse_ctos_key_share"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN, 0),
"tls_parse_ctos_maxfragmentlen"},
+ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH, 0),
+ "tls_parse_ctos_post_handshake_auth"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_PSK, 0), "tls_parse_ctos_psk"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES, 0),
"tls_parse_ctos_psk_kex_modes"},
@@ -832,6 +842,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
"exceeds max fragment size"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EXCESSIVE_MESSAGE_SIZE),
"excessive message size"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EXTENSION_NOT_RECEIVED),
+ "extension not received"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EXTRA_DATA_IN_MESSAGE),
"extra data in message"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EXT_LENGTH_MISMATCH),
@@ -868,8 +880,10 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_COMMAND), "invalid command"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_COMPRESSION_ALGORITHM),
"invalid compression algorithm"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CONFIG), "invalid config"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CONFIGURATION_NAME),
"invalid configuration name"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CONTEXT), "invalid context"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CT_VALIDATION_TYPE),
"invalid ct validation type"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_KEY_UPDATE_TYPE),
@@ -919,6 +933,7 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
"missing tmp ecdh key"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_ON_RECORD_BOUNDARY),
"not on record boundary"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_SERVER), "not server"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_APPLICATION_PROTOCOL),
"no application protocol"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CERTIFICATES_RETURNED),
@@ -978,6 +993,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
"pem name bad prefix"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PEM_NAME_TOO_SHORT), "pem name too short"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PIPELINE_FAILURE), "pipeline failure"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR),
+ "post handshake auth encoding err"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PROTOCOL_IS_SHUTDOWN),
"protocol is shutdown"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PSK_IDENTITY_NOT_FOUND),
@@ -996,6 +1013,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
"renegotiation encoding err"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RENEGOTIATION_MISMATCH),
"renegotiation mismatch"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_REQUEST_PENDING), "request pending"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_REQUEST_SENT), "request sent"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_REQUIRED_CIPHER_MISSING),
"required cipher missing"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING),
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 270d4de593..5a5fbad1f6 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1186,6 +1186,8 @@ void SSL_free(SSL *s)
OPENSSL_free(s->ext.alpn);
OPENSSL_free(s->ext.tls13_cookie);
OPENSSL_free(s->clienthello);
+ OPENSSL_free(s->pha_context);
+ EVP_MD_CTX_free(s->pha_dgst);
sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free);
@@ -5318,3 +5320,55 @@ int SSL_stateless(SSL *s)
return 0;
}
+
+void SSL_force_post_handshake_auth(SSL *ssl)
+{
+ ssl->pha_forced = 1;
+}
+
+int SSL_verify_client_post_handshake(SSL *ssl)
+{
+ if (!SSL_IS_TLS13(ssl)) {