Add TLSv1.3 post-handshake authentication (PHA)
Add SSL_verify_client_post_handshake() for servers to initiate PHA Add SSL_force_post_handshake_auth() for clients that don't have certificates initially configured, but use a certificate callback. Update SSL_CTX_set_verify()/SSL_set_verify() mode: * Add SSL_VERIFY_POST_HANDSHAKE to postpone client authentication until after the initial handshake. * Update SSL_VERIFY_CLIENT_ONCE now only sends out one CertRequest regardless of when the certificate authentication takes place; either initial handshake, re-negotiation, or post-handshake authentication. Add 'RequestPostHandshake' and 'RequirePostHandshake' SSL_CONF options that add the SSL_VERIFY_POST_HANDSHAKE to the 'Request' and 'Require' options Add support to s_client: * Enabled automatically when cert is configured * Can be forced enabled via -force_pha Add support to s_server: * Use 'c' to invoke PHA in s_server * Remove some dead code Update documentation Update unit tests: * Illegal use of PHA extension * TLSv1.3 certificate tests DTLS and TLS behave ever-so-slightly differently. So, when DTLS1.3 is implemented, it's PHA support state machine may need to be different. Add a TODO and a #error Update handshake context to deal with PHA. The handshake context for TLSv1.3 post-handshake auth is up through the ClientFinish message, plus the CertificateRequest message. Subsequent Certificate, CertificateVerify, and Finish messages are based on this handshake context (not the Certificate message per se, but it's included after the hash). KeyUpdate, NewSessionTicket, and prior Certificate Request messages are not included in post-handshake authentication. After the ClientFinished message is processed, save off the digest state for future post-handshake authentication. When post-handshake auth occurs, copy over the saved handshake context into the "main" handshake digest. This effectively discards the any KeyUpdate or NewSessionTicket messages and any prior post-handshake authentication. This, of course, assumes that the ID-22 did not mean to include any previous post-handshake authentication into the new handshake transcript. This is implied by section 4.4.1 that lists messages only up to the first ClientFinished. Reviewed-by: Ben Kaduk <kaduk@mit.edu> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/4964)
This commit is contained in:
parent
633a8829ff
commit
9d75dce3e1
35 changed files with 1485 additions and 78 deletions
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)) {
|
||||
SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_WRONG_SSL_VERSION);
|
||||
return 0;
|
||||
}
|
||||
if (!ssl->server) {
|
||||
SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_NOT_SERVER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!SSL_is_init_finished(ssl)) {
|
||||
SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_STILL_IN_INIT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (ssl->post_handshake_auth) {
|
||||
case SSL_PHA_NONE:
|
||||
SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_EXTENSION_NOT_RECEIVED);
|
||||
return 0;
|
||||
default:
|
||||
case SSL_PHA_EXT_SENT:
|
||||
SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
case SSL_PHA_EXT_RECEIVED:
|
||||
break;
|
||||
case SSL_PHA_REQUEST_PENDING:
|
||||
SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_REQUEST_PENDING);
|
||||
return 0;
|
||||
case SSL_PHA_REQUESTED:
|
||||
SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_REQUEST_SENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssl->post_handshake_auth = SSL_PHA_REQUEST_PENDING;
|
||||
|
||||
/* checks verify_mode and algorithm_auth */
|
||||
if (!send_certificate_request(ssl)) {
|
||||
ssl->post_handshake_auth = SSL_PHA_EXT_RECEIVED; /* restore on error */
|
||||
SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_INVALID_CONFIG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ossl_statem_set_in_init(ssl, 1);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -402,6 +402,15 @@
|
|||
#define CERT_PRIVATE_KEY 2
|
||||
*/
|
||||
|
||||
/* Post-Handshake Authentication state */
|
||||
typedef enum {
|
||||
SSL_PHA_NONE = 0,
|
||||
SSL_PHA_EXT_SENT, /* client-side only: extension sent */
|
||||
SSL_PHA_EXT_RECEIVED, /* server-side only: extension received */
|
||||
SSL_PHA_REQUEST_PENDING, /* server-side only: request pending */
|
||||
SSL_PHA_REQUESTED /* request received by client, or sent by server */
|
||||
} SSL_PHA_STATE;
|
||||
|
||||
/* CipherSuite length. SSLv3 and all TLS versions. */
|
||||
# define TLS_CIPHER_LEN 2
|
||||
/* used to hold info on the particular ciphers used */
|
||||
|
@ -702,6 +711,7 @@ typedef enum tlsext_index_en {
|
|||
TLSEXT_IDX_signed_certificate_timestamp,
|
||||
TLSEXT_IDX_extended_master_secret,
|
||||
TLSEXT_IDX_signature_algorithms_cert,
|
||||
TLSEXT_IDX_post_handshake_auth,
|
||||
TLSEXT_IDX_signature_algorithms,
|
||||
TLSEXT_IDX_supported_versions,
|
||||
TLSEXT_IDX_psk_kex_modes,
|
||||
|
@ -1334,6 +1344,14 @@ struct ssl_st {
|
|||
int renegotiate;
|
||||
/* If sending a KeyUpdate is pending */
|
||||
int key_update;
|
||||
/* Post-handshake authentication state */
|
||||
SSL_PHA_STATE post_handshake_auth;
|
||||
int pha_forced;
|
||||
uint8_t* pha_context;
|
||||
size_t pha_context_len;
|
||||
int certreqs_sent;
|
||||
EVP_MD_CTX *pha_dgst; /* this is just the digest through ClientFinished */
|
||||
|
||||
# ifndef OPENSSL_NO_SRP
|
||||
/* ctx for SRP authentication */
|
||||
SRP_CTX srp_ctx;
|
||||
|
@ -2535,6 +2553,10 @@ __owur int srp_generate_server_master_secret(SSL *s);
|
|||
__owur int srp_generate_client_master_secret(SSL *s);
|
||||
__owur int srp_verify_server_param(SSL *s);
|
||||
|
||||
/* statem/statem_srvr.c */
|
||||
|
||||
__owur int send_certificate_request(SSL *s);
|
||||
|
||||
/* statem/extensions_cust.c */
|
||||
|
||||
custom_ext_method *custom_ext_find(const custom_ext_methods *exts,
|
||||
|
|
|
@ -56,6 +56,8 @@ static int final_sig_algs(SSL *s, unsigned int context, int sent);
|
|||
static int final_early_data(SSL *s, unsigned int context, int sent);
|
||||
static int final_maxfragmentlen(SSL *s, unsigned int context, int sent);
|
||||
|
||||
static int init_post_handshake_auth(SSL *s, unsigned int context);
|
||||
|
||||
/* Structure to define a built-in extension */
|
||||
typedef struct extensions_definition_st {
|
||||
/* The defined type for the extension */
|
||||
|
@ -289,6 +291,14 @@ static const EXTENSION_DEFINITION ext_defs[] = {
|
|||
/* We do not generate signature_algorithms_cert at present. */
|
||||
NULL, NULL, NULL
|
||||
},
|
||||
{
|
||||
TLSEXT_TYPE_post_handshake_auth,
|
||||
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ONLY,
|
||||
init_post_handshake_auth,
|
||||
tls_parse_ctos_post_handshake_auth, NULL,
|
||||
NULL, tls_construct_ctos_post_handshake_auth,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
TLSEXT_TYPE_signature_algorithms,
|
||||
SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST,
|
||||
|
@ -1653,3 +1663,10 @@ static int final_maxfragmentlen(SSL *s, unsigned int context, int sent)
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int init_post_handshake_auth(SSL *s, unsigned int context)
|
||||
{
|
||||
s->post_handshake_auth = SSL_PHA_NONE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1133,6 +1133,48 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context,
|
|||
#endif
|
||||
}
|
||||
|
||||
EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL *s, WPACKET *pkt,
|
||||
unsigned int context,
|
||||
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;
|
||||
}
|
||||
|
||||
/* construct extension - 0 length, no contents */
|
||||
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_post_handshake_auth)
|
||||
|| !WPACKET_start_sub_packet_u16(pkt)
|
||||
|| !WPACKET_close(pkt)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return EXT_RETURN_FAIL;
|
||||
}
|
||||
|
||||
s->post_handshake_auth = SSL_PHA_EXT_SENT;
|
||||
|
||||
return EXT_RETURN_SENT;
|
||||
#else
|
||||
return EXT_RETURN_NOT_SENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse the server's renegotiation binding and abort if it's not right
|
||||
*/
|
||||
|
|
|
@ -525,6 +525,7 @@ int SSL_extension_supported(unsigned int ext_type)
|
|||
case TLSEXT_TYPE_early_data:
|
||||
case TLSEXT_TYPE_certificate_authorities:
|
||||
case TLSEXT_TYPE_psk:
|
||||
case TLSEXT_TYPE_post_handshake_auth:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
|
|
|
@ -1161,6 +1161,20 @@ err:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tls_parse_ctos_post_handshake_auth(SSL *s, PACKET *pkt, unsigned int context,
|
||||
X509 *x, size_t chainidx)
|
||||
{
|
||||
if (PACKET_remaining(pkt) != 0) {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH,
|
||||
SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s->post_handshake_auth = SSL_PHA_EXT_RECEIVED;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the server's renegotiation binding
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
* Copyright 2005 Nokia. All rights reserved.
|
||||
*
|
||||
|
@ -160,6 +160,26 @@ static int ossl_statem_client13_read_transition(SSL *s, int mt)
|
|||
st->hand_state = TLS_ST_CR_KEY_UPDATE;
|
||||
return 1;
|
||||
}
|
||||
if (mt == SSL3_MT_CERTIFICATE_REQUEST) {
|
||||
#if DTLS_MAX_VERSION != DTLS1_2_VERSION
|
||||
# error TODO(DTLS1.3): Restore digest for PHA before adding message.
|
||||
#endif
|
||||
if (!SSL_IS_DTLS(s) && s->post_handshake_auth == SSL_PHA_EXT_SENT) {
|
||||
s->post_handshake_auth = SSL_PHA_REQUESTED;
|
||||
/*
|
||||
* In TLS, this is called before the message is added to the
|
||||
* digest. In DTLS, this is expected to be called after adding
|
||||
* to the digest. Either move the digest restore, or add the
|
||||
* message here after the swap, or do it after the clientFinished?
|
||||
*/
|
||||
if (!tls13_restore_handshake_digest_for_pha(s)) {
|
||||
/* SSLfatal() already called */
|
||||
return 0;
|
||||
}
|
||||
st->hand_state = TLS_ST_CR_CERT_REQ;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -375,6 +395,13 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s)
|
|||
* ossl_statem_client_write_transition().
|
||||
*/
|
||||
switch (st->hand_state) {
|
||||
case TLS_ST_CR_CERT_REQ:
|
||||
if (s->post_handshake_auth == SSL_PHA_REQUESTED) {
|
||||
st->hand_state = TLS_ST_CW_CERT;
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
}
|
||||
/* Fall through */
|
||||
|
||||
default:
|
||||
/* Shouldn't happen */
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
|
@ -798,11 +825,17 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst)
|
|||
return WORK_MORE_B;
|
||||
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
if (!s->method->ssl3_enc->change_cipher_state(s,
|
||||
SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
|
||||
if (!tls13_save_handshake_digest_for_pha(s)) {
|
||||
/* SSLfatal() already called */
|
||||
return WORK_ERROR;
|
||||
}
|
||||
if (s->post_handshake_auth != SSL_PHA_REQUESTED) {
|
||||
if (!s->method->ssl3_enc->change_cipher_state(s,
|
||||
SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
|
||||
/* SSLfatal() already called */
|
||||
return WORK_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2399,9 +2432,11 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
|
|||
OPENSSL_free(s->s3->tmp.ctype);
|
||||
s->s3->tmp.ctype = NULL;
|
||||
s->s3->tmp.ctype_len = 0;
|
||||
OPENSSL_free(s->pha_context);
|
||||
s->pha_context = NULL;
|
||||
|
||||
/* TODO(TLS1.3) need to process request context, for now ignore */
|
||||
if (!PACKET_get_length_prefixed_1(pkt, &reqctx)) {
|
||||
if (!PACKET_get_length_prefixed_1(pkt, &reqctx) ||
|
||||
!PACKET_memdup(&reqctx, &s->pha_context, &s->pha_context_len)) {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR,
|
||||
SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
|
||||
SSL_R_LENGTH_MISMATCH);
|
||||
|
@ -3332,6 +3367,7 @@ static int ssl3_check_client_certificate(SSL *s)
|
|||
if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT &&
|
||||
!tls1_check_chain(s, NULL, NULL, NULL, -2))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -3357,8 +3393,12 @@ WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst)
|
|||
}
|
||||
s->rwstate = SSL_NOTHING;
|
||||
}
|
||||
if (ssl3_check_client_certificate(s))
|
||||
if (ssl3_check_client_certificate(s)) {
|
||||
if (s->post_handshake_auth == SSL_PHA_REQUESTED) {
|
||||
return WORK_FINISHED_STOP;
|
||||
}
|
||||
return WORK_FINISHED_CONTINUE;
|
||||
}
|
||||
|
||||
/* Fall through to WORK_MORE_B */
|
||||
wst = WORK_MORE_B;
|
||||
|
@ -3403,6 +3443,8 @@ WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst)
|
|||
}
|
||||
}
|
||||
|
||||
if (s->post_handshake_auth == SSL_PHA_REQUESTED)
|
||||
return WORK_FINISHED_STOP;
|
||||
return WORK_FINISHED_CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -3414,14 +3456,19 @@ WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst)
|
|||
|
||||
int tls_construct_client_certificate(SSL *s, WPACKET *pkt)
|
||||
{
|
||||
/*
|
||||
* TODO(TLS1.3): For now we must put an empty context. Needs to be filled in
|
||||
* later
|
||||
*/
|
||||
if (SSL_IS_TLS13(s) && !WPACKET_put_bytes_u8(pkt, 0)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
if (s->pha_context == NULL) {
|
||||
/* no context available, add 0-length context */
|
||||
if (!WPACKET_put_bytes_u8(pkt, 0)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
} else if (!WPACKET_sub_memcpy_u8(pkt, s->pha_context, s->pha_context_len)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (!ssl3_output_cert_chain(s, pkt,
|
||||
(s->s3->tmp.cert_req == 2) ? NULL
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
|
@ -43,12 +43,15 @@ int ssl3_do_write(SSL *s, int type)
|
|||
/*
|
||||
* should not be done for 'Hello Request's, but in that case we'll
|
||||
* ignore the result anyway
|
||||
* TLS1.3 KeyUpdate and NewSessionTicket do not need to be added
|
||||
*/
|
||||
if (!ssl3_finish_mac(s,
|
||||
(unsigned char *)&s->init_buf->data[s->init_off],
|
||||
written))
|
||||
return -1;
|
||||
|
||||
if (!SSL_IS_TLS13(s) || (s->statem.hand_state != TLS_ST_SW_SESSION_TICKET
|
||||
&& s->statem.hand_state != TLS_ST_CW_KEY_UPDATE
|
||||
&& s->statem.hand_state != TLS_ST_SW_KEY_UPDATE))
|
||||
if (!ssl3_finish_mac(s,
|
||||
(unsigned char *)&s->init_buf->data[s->init_off],
|
||||
written))
|
||||
return -1;
|
||||
if (written == s->init_num) {
|
||||
if (s->msg_callback)
|
||||
s->msg_callback(1, s->version, type, s->init_buf->data,
|
||||
|
@ -504,7 +507,7 @@ int tls_construct_finished(SSL *s, WPACKET *pkt)
|
|||
size_t slen;
|
||||
|
||||
/* This is a real handshake so make sure we clean it up at the end */
|
||||
if (!s->server)
|
||||
if (!s->server && s->post_handshake_auth != SSL_PHA_REQUESTED)
|
||||
s->statem.cleanuphand = 1;
|
||||
|
||||
/*
|
||||
|
@ -741,8 +744,14 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt)
|
|||
|
||||
|
||||
/* This is a real handshake so make sure we clean it up at the end */
|
||||
if (s->server)
|
||||
s->statem.cleanuphand = 1;
|
||||
if (s->server) {
|
||||
if (s->post_handshake_auth != SSL_PHA_REQUESTED)
|
||||
s->statem.cleanuphand = 1;
|
||||
if (SSL_IS_TLS13(s) && !tls13_save_handshake_digest_for_pha(s)) {
|
||||
/* SSLfatal() already called */
|
||||
return MSG_PROCESS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In TLSv1.3 a Finished message signals a key change so the end of the
|
||||
|
@ -801,7 +810,8 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt)
|
|||
*/
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
if (s->server) {
|
||||
if (!s->method->ssl3_enc->change_cipher_state(s,
|
||||
if (s->post_handshake_auth != SSL_PHA_REQUESTED &&
|
||||
!s->method->ssl3_enc->change_cipher_state(s,
|
||||
SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_SERVER_READ)) {
|
||||
/* SSLfatal() already called */
|
||||
return MSG_PROCESS_ERROR;
|
||||
|
@ -1021,6 +1031,10 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop)
|
|||
s->init_num = 0;
|
||||
}
|
||||
|
||||
if (SSL_IS_TLS13(s) && !s->server
|
||||
&& s->post_handshake_auth == SSL_PHA_REQUESTED)
|
||||
s->post_handshake_auth = SSL_PHA_EXT_SENT;
|
||||
|
||||
if (s->statem.cleanuphand) {
|
||||
/* skipped if we just sent a HelloRequest */
|
||||
s->renegotiate = 0;
|
||||
|
@ -1237,18 +1251,24 @@ int tls_get_message_body(SSL *s, size_t *len)
|
|||
/*
|
||||
* We defer feeding in the HRR until later. We'll do it as part of
|
||||
* processing the message
|
||||
* The TLsv1.3 handshake transcript stops at the ClientFinished
|
||||
* message.
|
||||
*/
|
||||
#define SERVER_HELLO_RANDOM_OFFSET (SSL3_HM_HEADER_LENGTH + 2)
|
||||
if (s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO
|
||||
|| s->init_num < SERVER_HELLO_RANDOM_OFFSET + SSL3_RANDOM_SIZE
|
||||
|| memcmp(hrrrandom,
|
||||
s->init_buf->data + SERVER_HELLO_RANDOM_OFFSET,
|
||||
SSL3_RANDOM_SIZE) != 0) {
|
||||
if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
|
||||
s->init_num + SSL3_HM_HEADER_LENGTH)) {
|
||||
/* SSLfatal() already called */
|
||||
*len = 0;
|
||||
return 0;
|
||||
/* KeyUpdate and NewSessionTicket do not need to be added */
|
||||
if (!SSL_IS_TLS13(s) || (s->s3->tmp.message_type != SSL3_MT_NEWSESSION_TICKET
|
||||
&& s->s3->tmp.message_type != SSL3_MT_KEY_UPDATE)) {
|
||||
if (s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO
|
||||
|| s->init_num < SERVER_HELLO_RANDOM_OFFSET + SSL3_RANDOM_SIZE
|
||||
|| memcmp(hrrrandom,
|
||||
s->init_buf->data + SERVER_HELLO_RANDOM_OFFSET,
|
||||
SSL3_RANDOM_SIZE) != 0) {
|
||||
if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
|
||||
s->init_num + SSL3_HM_HEADER_LENGTH)) {
|
||||
/* SSLfatal() already called */
|
||||
*len = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (s->msg_callback)
|
||||
|
@ -2208,3 +2228,54 @@ size_t construct_key_exchange_tbs(SSL *s, unsigned char **ptbs,
|
|||
*ptbs = tbs;
|
||||
return tbslen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Saves the current handshake digest for Post-Handshake Auth,
|
||||
* Done after ClientFinished is processed, done exactly once
|
||||
*/
|
||||
int tls13_save_handshake_digest_for_pha(SSL *s)
|
||||
{
|
||||
if (s->pha_dgst == NULL) {
|
||||
if (!ssl3_digest_cached_records(s, 1))
|
||||
/* SSLfatal() already called */
|
||||
return 0;
|
||||
|
||||
s->pha_dgst = EVP_MD_CTX_new();
|
||||
if (s->pha_dgst == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
if (!EVP_MD_CTX_copy_ex(s->pha_dgst,
|
||||
s->s3->handshake_dgst)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restores the Post-Handshake Auth handshake digest
|
||||
* Done just before sending/processing the Cert Request
|
||||
*/
|
||||
int tls13_restore_handshake_digest_for_pha(SSL *s)
|
||||
{
|
||||
if (s->pha_dgst == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
if (!EVP_MD_CTX_copy_ex(s->s3->handshake_dgst,
|
||||
s->pha_dgst)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2015-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-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
|
||||
|
@ -235,6 +235,8 @@ int tls_parse_ctos_psk_kex_modes(SSL *s, PACKET *pkt, unsigned int context,
|
|||
X509 *x, size_t chainidx);
|
||||
int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
size_t chainidx);
|
||||
int tls_parse_ctos_post_handshake_auth(SSL *, PACKET *pkt, unsigned int context,
|
||||
X509 *x, size_t chainidx);
|
||||
|
||||
EXT_RETURN tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt,
|
||||
unsigned int context, X509 *x,
|
||||
|
@ -365,6 +367,9 @@ EXT_RETURN tls_construct_ctos_padding(SSL *s, WPACKET *pkt,
|
|||
size_t chainidx);
|
||||
EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context,
|
||||
X509 *x, size_t chainidx);
|
||||
EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL *s, WPACKET *pkt, unsigned int context,
|
||||
X509 *x, size_t chainidx);
|
||||
|
||||
int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, unsigned int context,
|
||||
X509 *x, size_t chainidx);
|
||||
int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, unsigned int context,
|
||||
|
@ -411,3 +416,6 @@ int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
|||
size_t chainidx);
|
||||
|
||||
int tls_handle_alpn(SSL *s);
|
||||
|
||||
int tls13_save_handshake_digest_for_pha(SSL *s);
|
||||
int tls13_restore_handshake_digest_for_pha(SSL *s);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
* Copyright 2005 Nokia. All rights reserved.
|
||||
*
|
||||
|
@ -107,6 +107,13 @@ static int ossl_statem_server13_read_transition(SSL *s, int mt)
|
|||
*/
|
||||
if (s->early_data_state == SSL_EARLY_DATA_READING)
|
||||
break;
|
||||
|
||||
if (mt == SSL3_MT_CERTIFICATE
|
||||
&& s->post_handshake_auth == SSL_PHA_REQUESTED) {
|
||||
st->hand_state = TLS_ST_SR_CERT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mt == SSL3_MT_KEY_UPDATE) {
|
||||
st->hand_state = TLS_ST_SR_KEY_UPDATE;
|
||||
return 1;
|
||||
|
@ -325,16 +332,22 @@ static int send_server_key_exchange(SSL *s)
|
|||
* 1: Yes
|
||||
* 0: No
|
||||
*/
|
||||
static int send_certificate_request(SSL *s)
|
||||
int send_certificate_request(SSL *s)
|
||||
{
|
||||
if (
|
||||
/* don't request cert unless asked for it: */
|
||||
s->verify_mode & SSL_VERIFY_PEER
|
||||
/*
|
||||
* if SSL_VERIFY_CLIENT_ONCE is set, don't request cert
|
||||
* during re-negotiation:
|
||||
* don't request if post-handshake-only unless doing
|
||||
* post-handshake in TLSv1.3:
|
||||
*/
|
||||
&& (s->s3->tmp.finish_md_len == 0 ||
|
||||
&& (!SSL_IS_TLS13(s) || !(s->verify_mode & SSL_VERIFY_POST_HANDSHAKE)
|
||||
|| s->post_handshake_auth == SSL_PHA_REQUEST_PENDING)
|
||||
/*
|
||||
* if SSL_VERIFY_CLIENT_ONCE is set, don't request cert
|
||||
* a second time:
|
||||
*/
|
||||
&& (s->certreqs_sent < 1 ||
|
||||
!(s->verify_mode & SSL_VERIFY_CLIENT_ONCE))
|
||||
/*
|
||||
* never request cert in anonymous ciphersuites (see
|
||||
|
@ -388,6 +401,10 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
|
|||
st->hand_state = TLS_ST_SW_KEY_UPDATE;
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
}
|
||||
if (s->post_handshake_auth == SSL_PHA_REQUEST_PENDING) {
|
||||
st->hand_state = TLS_ST_SW_CERT_REQ;
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
}
|
||||
/* Try to read from the client instead */
|
||||
return WRITE_TRAN_FINISHED;
|
||||
|
||||
|
@ -423,7 +440,12 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
|
|||
return WRITE_TRAN_CONTINUE;
|
||||
|
||||
case TLS_ST_SW_CERT_REQ:
|
||||
st->hand_state = TLS_ST_SW_CERT;
|
||||
if (s->post_handshake_auth == SSL_PHA_REQUEST_PENDING) {
|
||||
s->post_handshake_auth = SSL_PHA_REQUESTED;
|
||||
st->hand_state = TLS_ST_OK;
|
||||
} else {
|
||||
st->hand_state = TLS_ST_SW_CERT;
|
||||
}
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
|
||||
case TLS_ST_SW_CERT:
|
||||
|
@ -450,6 +472,8 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
|
|||
* and give the application the opportunity to delay sending the
|
||||
* session ticket?
|
||||
*/
|
||||
if (s->post_handshake_auth == SSL_PHA_REQUESTED)
|
||||
s->post_handshake_auth = SSL_PHA_EXT_RECEIVED;
|
||||
st->hand_state = TLS_ST_SW_SESSION_TICKET;
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
|
||||
|
@ -863,6 +887,13 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
|
|||
}
|
||||
break;
|
||||
|
||||
case TLS_ST_SW_CERT_REQ:
|
||||
if (s->post_handshake_auth == SSL_PHA_REQUEST_PENDING) {
|
||||
if (statem_flush(s) != 1)
|
||||
return WORK_MORE_A;
|
||||
}
|
||||
break;
|
||||
|
||||
case TLS_ST_SW_KEY_UPDATE:
|
||||
if (statem_flush(s) != 1)
|
||||
return WORK_MORE_A;
|
||||
|
@ -2702,12 +2733,30 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
|
|||
int tls_construct_certificate_request(SSL *s, WPACKET *pkt)
|
||||
{
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
/* TODO(TLS1.3) for now send empty request context */
|
||||
if (!WPACKET_put_bytes_u8(pkt, 0)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
/* Send random context when doing post-handshake auth */
|
||||
if (s->post_handshake_auth == SSL_PHA_REQUEST_PENDING) {
|
||||
OPENSSL_free(s->pha_context);
|
||||
s->pha_context_len = 32;
|
||||
if ((s->pha_context = OPENSSL_malloc(s->pha_context_len)) == NULL
|
||||
|| ssl_randbytes(s, s->pha_context, s->pha_context_len) <= 0
|
||||
|| !WPACKET_sub_memcpy_u8(pkt, s->pha_context, s->pha_context_len)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
/* reset the handshake hash back to just after the ClientFinished */
|
||||
if (!tls13_restore_handshake_digest_for_pha(s)) {
|
||||
/* SSLfatal() already called */
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (!WPACKET_put_bytes_u8(pkt, 0)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tls_construct_extensions(s, pkt,
|
||||
|
@ -2748,6 +2797,7 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt)
|
|||
}
|
||||
|
||||
done:
|
||||
s->certreqs_sent++;
|
||||
s->s3->tmp.cert_request = 1;
|
||||
return 1;
|
||||
}
|
||||
|
@ -3396,11 +3446,12 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
|
|||
int i;
|
||||
MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR;
|
||||
X509 *x = NULL;
|
||||
unsigned long l, llen;
|
||||
unsigned long l;
|
||||
const unsigned char *certstart, *certbytes;
|
||||
STACK_OF(X509) *sk = NULL;
|
||||
PACKET spkt, context;
|
||||
size_t chainidx;
|
||||
SSL_SESSION *new_sess = NULL;
|
||||
|
||||
if ((sk = sk_X509_new_null()) == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
|
||||
|
@ -3408,10 +3459,16 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
|
|||
goto err;
|
||||
}
|
||||
|
||||
/* TODO(TLS1.3): For now we ignore the context. We need to verify this */
|
||||
if ((SSL_IS_TLS13(s) && !PACKET_get_length_prefixed_1(pkt, &context))
|
||||
|| !PACKET_get_net_3(pkt, &llen)
|
||||
|| !PACKET_get_sub_packet(pkt, &spkt, llen)
|
||||
if (SSL_IS_TLS13(s) && (!PACKET_get_length_prefixed_1(pkt, &context)
|
||||
|| (s->pha_context == NULL && PACKET_remaining(&context) != 0)
|
||||
|| (s->pha_context != NULL &&
|
||||
!PACKET_equal(&context, s->pha_context, s->pha_context_len)))) {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
|
||||
SSL_R_INVALID_CONTEXT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!PACKET_get_length_prefixed_3(pkt, &spkt)
|
||||
|| PACKET_remaining(pkt) != 0) {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
|
||||
SSL_R_LENGTH_MISMATCH);
|
||||
|
@ -3516,6 +3573,35 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sessions must be immutable once they go into the session cache. Otherwise
|
||||
* we can get multi-thread problems. Therefore we don't "update" sessions,
|
||||
* we replace them with a duplicate. Here, we need to do this every time
|
||||
* a new certificate is received via post-handshake authentication, as the
|
||||
* session may have already gone into the session cache.
|
||||
*/
|
||||
|
||||
if (s->post_handshake_auth == SSL_PHA_REQUESTED) {
|
||||
int m = s->session_ctx->session_cache_mode;
|
||||
|
||||
if ((new_sess = ssl_session_dup(s->session, 0)) == 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
|
||||
SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (m & SSL_SESS_CACHE_SERVER) {
|
||||
/*
|
||||
* Remove the old session from the cache. We carry on if this fails
|
||||
*/
|
||||
SSL_CTX_remove_session(s->session_ctx, s->session);
|
||||
}
|
||||
|
||||
SSL_SESSION_free(s->session);
|
||||
s->session = new_sess;
|
||||
}
|
||||
|
||||
X509_free(s->session->peer);
|
||||
s->session->peer = sk_X509_shift(sk);
|
||||
s->session->verify_result = s->verify_result;
|
||||
|
@ -3523,6 +3609,9 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
|
|||
sk_X509_pop_free(s->session->peer_chain, X509_free);
|
||||
s->session->peer_chain = sk;
|
||||
|
||||
if (new_sess != NULL)
|
||||
ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
|
||||
|
||||
/*
|
||||
* Freeze the handshake buffer. For <TLS1.3 we do this after the CKE
|
||||
* message
|
||||
|
|
|
@ -481,7 +481,8 @@ static const ssl_trace_tbl ssl_exts_tbl[] = {
|
|||
{TLSEXT_TYPE_padding, "padding"},
|
||||
{TLSEXT_TYPE_encrypt_then_mac, "encrypt_then_mac"},
|
||||
{TLSEXT_TYPE_extended_master_secret, "extended_master_secret"},
|
||||
{TLSEXT_TYPE_early_data, "early_data"}
|
||||
{TLSEXT_TYPE_early_data, "early_data"},
|
||||
{TLSEXT_TYPE_post_handshake_auth, "post_handshake_auth"}
|
||||
};
|
||||
|
||||
static const ssl_trace_tbl ssl_groups_tbl[] = {
|
||||
|
|
|
@ -268,7 +268,7 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN
|
|||
DEPEND[cipherlist_test]=../libcrypto ../libssl libtestutil.a
|
||||
|
||||
INCLUDE[ssl_test_ctx.o]=../include
|
||||
INCLUDE[handshake_helper.o]=../include
|
||||
INCLUDE[handshake_helper.o]=.. ../include
|
||||
INCLUDE[ssltestlib.o]=.. ../include
|
||||
|
||||
SOURCE[x509aux]=x509aux.c
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <openssl/srp.h>
|
||||
#endif
|
||||
|
||||
#include "../ssl/ssl_locl.h"
|
||||
#include "internal/sockets.h"
|
||||
#include "internal/nelem.h"
|
||||
#include "handshake_helper.h"
|
||||
|
@ -674,6 +675,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);
|
||||
}
|
||||
|
||||
/* The status for each connection phase. */
|
||||
|
@ -848,7 +851,9 @@ static void do_reneg_setup_step(const SSL_TEST_CTX *test_ctx, PEER *peer)
|
|||
|| test_ctx->handshake_mode
|
||||
== SSL_TEST_HANDSHAKE_KEY_UPDATE_SERVER
|
||||
|| test_ctx->handshake_mode
|
||||
== SSL_TEST_HANDSHAKE_KEY_UPDATE_CLIENT)) {
|
||||
== SSL_TEST_HANDSHAKE_KEY_UPDATE_CLIENT
|
||||
|| test_ctx->handshake_mode
|
||||
== SSL_TEST_HANDSHAKE_POST_HANDSHAKE_AUTH)) {
|
||||
peer->status = PEER_TEST_FAILURE;
|
||||
return;
|
||||
}
|
||||
|
@ -929,6 +934,25 @@ static void do_reneg_setup_step(const SSL_TEST_CTX *test_ctx, PEER *peer)
|
|||
if (peer->status != PEER_SUCCESS)
|
||||
peer->status = PEER_ERROR;
|
||||
return;
|
||||
} else if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_POST_HANDSHAKE_AUTH) {
|
||||
if (SSL_is_server(peer->ssl)) {
|
||||
/* Make the server believe it's received the extension */
|
||||
if (test_ctx->extra.server.force_pha)
|
||||
peer->ssl->post_handshake_auth = SSL_PHA_EXT_RECEIVED;
|
||||
ret = SSL_verify_client_post_handshake(peer->ssl);
|
||||
if (!ret) {
|
||||
peer->status = PEER_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
do_handshake_step(peer);
|
||||
/*
|
||||
* This is a one step handshake. We shouldn't get anything other than
|
||||
* PEER_SUCCESS
|
||||
*/
|
||||
if (peer->status != PEER_SUCCESS)
|
||||
peer->status = PEER_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1004,25 +1028,41 @@ typedef enum {
|
|||
CONNECTION_DONE
|
||||
} connect_phase_t;
|
||||
|
||||
|
||||
static int renegotiate_op(const SSL_TEST_CTX *test_ctx)
|
||||
{
|
||||
switch (test_ctx->handshake_mode) {
|
||||
case SSL_TEST_HANDSHAKE_RENEG_SERVER:
|
||||
case SSL_TEST_HANDSHAKE_RENEG_CLIENT:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
static int post_handshake_op(const SSL_TEST_CTX *test_ctx)
|
||||
{
|
||||
switch (test_ctx->handshake_mode) {
|
||||
case SSL_TEST_HANDSHAKE_KEY_UPDATE_CLIENT:
|
||||
case SSL_TEST_HANDSHAKE_KEY_UPDATE_SERVER:
|
||||
case SSL_TEST_HANDSHAKE_POST_HANDSHAKE_AUTH:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static connect_phase_t next_phase(const SSL_TEST_CTX *test_ctx,
|
||||
connect_phase_t phase)
|
||||
{
|
||||
switch (phase) {
|
||||
case HANDSHAKE:
|
||||
if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RENEG_SERVER
|
||||
|| test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RENEG_CLIENT
|
||||
|| test_ctx->handshake_mode
|
||||
== SSL_TEST_HANDSHAKE_KEY_UPDATE_CLIENT
|
||||
|| test_ctx->handshake_mode
|
||||
== SSL_TEST_HANDSHAKE_KEY_UPDATE_SERVER)
|
||||
if (renegotiate_op(test_ctx) || post_handshake_op(test_ctx))
|
||||
return RENEG_APPLICATION_DATA;
|
||||
return APPLICATION_DATA;
|
||||
case RENEG_APPLICATION_DATA:
|
||||
return RENEG_SETUP;
|
||||
case RENEG_SETUP:
|
||||
if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_KEY_UPDATE_SERVER
|
||||
|| test_ctx->handshake_mode
|
||||
== SSL_TEST_HANDSHAKE_KEY_UPDATE_CLIENT)
|
||||
if (post_handshake_op(test_ctx))
|
||||
return APPLICATION_DATA;
|
||||
return RENEG_HANDSHAKE;
|
||||
case RENEG_HANDSHAKE:
|
||||
|
|
|
@ -89,6 +89,8 @@ $ENV{CTLOG_FILE} = srctop_file("test", "ct", "log_list.conf");
|
|||
checkhandshake::DEFAULT_EXTENSIONS],
|
||||
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK,
|
||||
checkhandshake::PSK_CLI_EXTENSION],
|
||||
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_POST_HANDSHAKE_AUTH,
|
||||
checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION],
|
||||
|
||||
[TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
|
||||
checkhandshake::DEFAULT_EXTENSIONS],
|
||||
|
@ -123,6 +125,8 @@ $ENV{CTLOG_FILE} = srctop_file("test", "ct", "log_list.conf");
|
|||
checkhandshake::DEFAULT_EXTENSIONS],
|
||||
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK,
|
||||
checkhandshake::PSK_CLI_EXTENSION],
|
||||
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_POST_HANDSHAKE_AUTH,
|
||||
checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION],
|
||||
|
||||
[TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
|
||||
checkhandshake::DEFAULT_EXTENSIONS],
|
||||
|
@ -214,7 +218,8 @@ $proxy->clientflags("-cert ".srctop_file("apps", "server.pem"));
|
|||
$proxy->serverflags("-Verify 5");
|
||||
$proxy->start();
|
||||
checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE,
|
||||
checkhandshake::DEFAULT_EXTENSIONS,
|
||||
checkhandshake::DEFAULT_EXTENSIONS |
|
||||
checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION,
|
||||
"Client auth handshake test");
|
||||
|
||||
#Test 7: Server name handshake (no client request)
|
||||
|
|
|
@ -28,7 +28,7 @@ map { s/\^// } @conf_files if $^O eq "VMS";
|
|||
|
||||
# We hard-code the number of tests to double-check that the globbing above
|
||||
# finds all files as expected.
|
||||
plan tests => 25; # = scalar @conf_srcs
|
||||
plan tests => 26; # = scalar @conf_srcs
|
||||
|
||||
# Some test results depend on the configuration of enabled protocols. We only
|
||||
# verify generated sources in the default configuration.
|
||||
|
@ -96,6 +96,7 @@ my %skip = (
|
|||
&& disabled("tls1_2")) || disabled("srp"),
|
||||
"24-padding.conf" => disabled("tls1_3"),
|
||||
"25-cipher.conf" => disabled("ec") || disabled("tls1_2"),
|
||||
"26-tls13_client_auth.conf" => disabled("tls1_3"),
|
||||
);
|
||||
|
||||
foreach my $conf (@conf_files) {
|
||||
|
|
476
test/ssl-tests/26-tls13_client_auth.conf
Normal file
476
test/ssl-tests/26-tls13_client_auth.conf
Normal file
|
@ -0,0 +1,476 @@
|
|||
# Generated with generate_ssl_tests.pl
|
||||
|
||||
num_tests = 14
|
||||
|
||||
test-0 = 0-server-auth-TLSv1.3
|
||||
test-1 = 1-client-auth-TLSv1.3-request
|
||||
test-2 = 2-client-auth-TLSv1.3-require-fail
|
||||
test-3 = 3-client-auth-TLSv1.3-require
|
||||
test-4 = 4-client-auth-TLSv1.3-require-non-empty-names
|
||||
test-5 = 5-client-auth-TLSv1.3-noroot
|
||||
test-6 = 6-client-auth-TLSv1.3-request-post-handshake
|
||||
test-7 = 7-client-auth-TLSv1.3-require-fail-post-handshake
|
||||
test-8 = 8-client-auth-TLSv1.3-require-post-handshake
|
||||
test-9 = 9-client-auth-TLSv1.3-require-non-empty-names-post-handshake
|
||||
test-10 = 10-client-auth-TLSv1.3-noroot-post-handshake
|
||||
test-11 = 11-client-auth-TLSv1.3-request-force-client-post-handshake
|
||||
test-12 = 12-client-auth-TLSv1.3-request-force-server-post-handshake
|
||||
test-13 = 13-client-auth-TLSv1.3-request-force-both-post-handshake
|
||||
# ===========================================================
|
||||
|
||||
[0-server-auth-TLSv1.3]
|
||||
ssl_conf = 0-server-auth-TLSv1.3-ssl
|
||||
|
||||
[0-server-auth-TLSv1.3-ssl]
|
||||
server = 0-server-auth-TLSv1.3-server
|
||||
client = 0-server-auth-TLSv1.3-client
|
||||
|
||||
[0-server-auth-TLSv1.3-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
|
||||
[0-server-auth-TLSv1.3-client]
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-0]
|
||||
ExpectedResult = Success
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[1-client-auth-TLSv1.3-request]
|
||||
ssl_conf = 1-client-auth-TLSv1.3-request-ssl
|
||||
|
||||
[1-client-auth-TLSv1.3-request-ssl]
|
||||
server = 1-client-auth-TLSv1.3-request-server
|
||||
client = 1-client-auth-TLSv1.3-request-client
|
||||
|
||||
[1-client-auth-TLSv1.3-request-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
VerifyMode = Request
|
||||
|
||||
[1-client-auth-TLSv1.3-request-client]
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-1]
|
||||
ExpectedResult = Success
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[2-client-auth-TLSv1.3-require-fail]
|
||||
ssl_conf = 2-client-auth-TLSv1.3-require-fail-ssl
|
||||
|
||||
[2-client-auth-TLSv1.3-require-fail-ssl]
|
||||
server = 2-client-auth-TLSv1.3-require-fail-server
|
||||
client = 2-client-auth-TLSv1.3-require-fail-client
|
||||
|
||||
[2-client-auth-TLSv1.3-require-fail-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
|
||||
VerifyMode = Require
|
||||
|
||||
[2-client-auth-TLSv1.3-require-fail-client]
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-2]
|
||||
ExpectedResult = ServerFail
|
||||
ExpectedServerAlert = HandshakeFailure
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[3-client-auth-TLSv1.3-require]
|
||||
ssl_conf = 3-client-auth-TLSv1.3-require-ssl
|
||||
|
||||
[3-client-auth-TLSv1.3-require-ssl]
|
||||
server = 3-client-auth-TLSv1.3-require-server
|
||||
client = 3-client-auth-TLSv1.3-require-client
|
||||
|
||||
[3-client-auth-TLSv1.3-require-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
ClientSignatureAlgorithms = PSS+SHA256
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
|
||||
VerifyMode = Request
|
||||
|
||||
[3-client-auth-TLSv1.3-require-client]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/ee-client-chain.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/ee-key.pem
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-3]
|
||||
ExpectedClientCANames = empty
|
||||
ExpectedClientCertType = RSA
|
||||
ExpectedClientSignHash = SHA256
|
||||
ExpectedClientSignType = RSA-PSS
|
||||
ExpectedResult = Success
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[4-client-auth-TLSv1.3-require-non-empty-names]
|
||||
ssl_conf = 4-client-auth-TLSv1.3-require-non-empty-names-ssl
|
||||
|
||||
[4-client-auth-TLSv1.3-require-non-empty-names-ssl]
|
||||
server = 4-client-auth-TLSv1.3-require-non-empty-names-server
|
||||
client = 4-client-auth-TLSv1.3-require-non-empty-names-client
|
||||
|
||||
[4-client-auth-TLSv1.3-require-non-empty-names-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
ClientCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
|
||||
ClientSignatureAlgorithms = PSS+SHA256
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
|
||||
VerifyMode = Request
|
||||
|
||||
[4-client-auth-TLSv1.3-require-non-empty-names-client]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/ee-client-chain.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/ee-key.pem
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-4]
|
||||
ExpectedClientCANames = ${ENV::TEST_CERTS_DIR}/root-cert.pem
|
||||
ExpectedClientCertType = RSA
|
||||
ExpectedClientSignHash = SHA256
|
||||
ExpectedClientSignType = RSA-PSS
|
||||
ExpectedResult = Success
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[5-client-auth-TLSv1.3-noroot]
|
||||
ssl_conf = 5-client-auth-TLSv1.3-noroot-ssl
|
||||
|
||||
[5-client-auth-TLSv1.3-noroot-ssl]
|
||||
server = 5-client-auth-TLSv1.3-noroot-server
|
||||
client = 5-client-auth-TLSv1.3-noroot-client
|
||||
|
||||
[5-client-auth-TLSv1.3-noroot-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
VerifyMode = Require
|
||||
|
||||
[5-client-auth-TLSv1.3-noroot-client]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/ee-client-chain.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/ee-key.pem
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-5]
|
||||
ExpectedResult = ServerFail
|
||||
ExpectedServerAlert = UnknownCA
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[6-client-auth-TLSv1.3-request-post-handshake]
|
||||
ssl_conf = 6-client-auth-TLSv1.3-request-post-handshake-ssl
|
||||
|
||||
[6-client-auth-TLSv1.3-request-post-handshake-ssl]
|
||||
server = 6-client-auth-TLSv1.3-request-post-handshake-server
|
||||
client = 6-client-auth-TLSv1.3-request-post-handshake-client
|
||||
|
||||
[6-client-auth-TLSv1.3-request-post-handshake-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
VerifyMode = RequestPostHandshake
|
||||
|
||||
[6-client-auth-TLSv1.3-request-post-handshake-client]
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-6]
|
||||
ExpectedResult = ServerFail
|
||||
HandshakeMode = PostHandshakeAuth
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[7-client-auth-TLSv1.3-require-fail-post-handshake]
|
||||
ssl_conf = 7-client-auth-TLSv1.3-require-fail-post-handshake-ssl
|
||||
|
||||
[7-client-auth-TLSv1.3-require-fail-post-handshake-ssl]
|
||||
server = 7-client-auth-TLSv1.3-require-fail-post-handshake-server
|
||||
client = 7-client-auth-TLSv1.3-require-fail-post-handshake-client
|
||||
|
||||
[7-client-auth-TLSv1.3-require-fail-post-handshake-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
|
||||
VerifyMode = RequirePostHandshake
|
||||
|
||||
[7-client-auth-TLSv1.3-require-fail-post-handshake-client]
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-7]
|
||||
ExpectedResult = ServerFail
|
||||
HandshakeMode = PostHandshakeAuth
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[8-client-auth-TLSv1.3-require-post-handshake]
|
||||
ssl_conf = 8-client-auth-TLSv1.3-require-post-handshake-ssl
|
||||
|
||||
[8-client-auth-TLSv1.3-require-post-handshake-ssl]
|
||||
server = 8-client-auth-TLSv1.3-require-post-handshake-server
|
||||
client = 8-client-auth-TLSv1.3-require-post-handshake-client
|
||||
|
||||
[8-client-auth-TLSv1.3-require-post-handshake-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
ClientSignatureAlgorithms = PSS+SHA256
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
|
||||
VerifyMode = RequestPostHandshake
|
||||
|
||||
[8-client-auth-TLSv1.3-require-post-handshake-client]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/ee-client-chain.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/ee-key.pem
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-8]
|
||||
ExpectedClientCANames = empty
|
||||
ExpectedClientCertType = RSA
|
||||
ExpectedClientSignHash = SHA256
|
||||
ExpectedClientSignType = RSA-PSS
|
||||
ExpectedResult = Success
|
||||
HandshakeMode = PostHandshakeAuth
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[9-client-auth-TLSv1.3-require-non-empty-names-post-handshake]
|
||||
ssl_conf = 9-client-auth-TLSv1.3-require-non-empty-names-post-handshake-ssl
|
||||
|
||||
[9-client-auth-TLSv1.3-require-non-empty-names-post-handshake-ssl]
|
||||
server = 9-client-auth-TLSv1.3-require-non-empty-names-post-handshake-server
|
||||
client = 9-client-auth-TLSv1.3-require-non-empty-names-post-handshake-client
|
||||
|
||||
[9-client-auth-TLSv1.3-require-non-empty-names-post-handshake-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
ClientCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
|
||||
ClientSignatureAlgorithms = PSS+SHA256
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
|
||||
VerifyMode = RequestPostHandshake
|
||||
|
||||
[9-client-auth-TLSv1.3-require-non-empty-names-post-handshake-client]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/ee-client-chain.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/ee-key.pem
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-9]
|
||||
ExpectedClientCANames = ${ENV::TEST_CERTS_DIR}/root-cert.pem
|
||||
ExpectedClientCertType = RSA
|
||||
ExpectedClientSignHash = SHA256
|
||||
ExpectedClientSignType = RSA-PSS
|
||||
ExpectedResult = Success
|
||||
HandshakeMode = PostHandshakeAuth
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[10-client-auth-TLSv1.3-noroot-post-handshake]
|
||||
ssl_conf = 10-client-auth-TLSv1.3-noroot-post-handshake-ssl
|
||||
|
||||
[10-client-auth-TLSv1.3-noroot-post-handshake-ssl]
|
||||
server = 10-client-auth-TLSv1.3-noroot-post-handshake-server
|
||||
client = 10-client-auth-TLSv1.3-noroot-post-handshake-client
|
||||
|
||||
[10-client-auth-TLSv1.3-noroot-post-handshake-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
VerifyMode = RequirePostHandshake
|
||||
|
||||
[10-client-auth-TLSv1.3-noroot-post-handshake-client]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/ee-client-chain.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/ee-key.pem
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-10]
|
||||
ExpectedResult = ServerFail
|
||||
ExpectedServerAlert = UnknownCA
|
||||
HandshakeMode = PostHandshakeAuth
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[11-client-auth-TLSv1.3-request-force-client-post-handshake]
|
||||
ssl_conf = 11-client-auth-TLSv1.3-request-force-client-post-handshake-ssl
|
||||
|
||||
[11-client-auth-TLSv1.3-request-force-client-post-handshake-ssl]
|
||||
server = 11-client-auth-TLSv1.3-request-force-client-post-handshake-server
|
||||
client = 11-client-auth-TLSv1.3-request-force-client-post-handshake-client
|
||||
|
||||
[11-client-auth-TLSv1.3-request-force-client-post-handshake-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
VerifyMode = RequestPostHandshake
|
||||
|
||||
[11-client-auth-TLSv1.3-request-force-client-post-handshake-client]
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-11]
|
||||
ExpectedResult = Success
|
||||
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
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[12-client-auth-TLSv1.3-request-force-server-post-handshake]
|
||||
ssl_conf = 12-client-auth-TLSv1.3-request-force-server-post-handshake-ssl
|
||||
|
||||
[12-client-auth-TLSv1.3-request-force-server-post-handshake-ssl]
|
||||
server = 12-client-auth-TLSv1.3-request-force-server-post-handshake-server
|
||||
client = 12-client-auth-TLSv1.3-request-force-server-post-handshake-client
|
||||
|
||||
[12-client-auth-TLSv1.3-request-force-server-post-handshake-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
VerifyMode = RequestPostHandshake
|
||||
|
||||
[12-client-auth-TLSv1.3-request-force-server-post-handshake-client]
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-12]
|
||||
ExpectedResult = ClientFail
|
||||
HandshakeMode = PostHandshakeAuth
|
||||
server = 12-client-auth-TLSv1.3-request-force-server-post-handshake-server-extra
|
||||
|
||||
[12-client-auth-TLSv1.3-request-force-server-post-handshake-server-extra]
|
||||
ForcePHA = Yes
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[13-client-auth-TLSv1.3-request-force-both-post-handshake]
|
||||
ssl_conf = 13-client-auth-TLSv1.3-request-force-both-post-handshake-ssl
|
||||
|
||||
[13-client-auth-TLSv1.3-request-force-both-post-handshake-ssl]
|
||||
server = 13-client-auth-TLSv1.3-request-force-both-post-handshake-server
|
||||
client = 13-client-auth-TLSv1.3-request-force-both-post-handshake-client
|
||||
|
||||
[13-client-auth-TLSv1.3-request-force-both-post-handshake-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
|
||||
VerifyMode = RequestPostHandshake
|
||||
|
||||
[13-client-auth-TLSv1.3-request-force-both-post-handshake-client]
|
||||
CipherString = DEFAULT
|
||||
MaxProtocol = TLSv1.3
|
||||
MinProtocol = TLSv1.3
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-13]
|
||||
ExpectedResult = Success
|
||||
HandshakeMode = PostHandshakeAuth
|
||||
server = 13-client-auth-TLSv1.3-request-force-both-post-handshake-server-extra
|
||||
client = 13-client-auth-TLSv1.3-request-force-both-post-handshake-client-extra
|
||||
|
||||
[13-client-auth-TLSv1.3-request-force-both-post-handshake-server-extra]
|
||||
ForcePHA = Yes
|
||||
|
||||
[13-client-auth-TLSv1.3-request-force-both-post-handshake-client-extra]
|
||||
ForcePHA = Yes
|
||||
|
||||
|
293
test/ssl-tests/26-tls13_client_auth.conf.in
Normal file
293
test/ssl-tests/26-tls13_client_auth.conf.in
Normal file
|
@ -0,0 +1,293 @@
|
|||
# -*- mode: perl; -*-
|
||||
# Copyright 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
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
|
||||
## Test TLSv1.3 certificate authentication
|
||||
## Similar to 04-client_auth.conf.in output, but specific for
|
||||
## TLSv1.3 and post-handshake authentication
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
package ssltests;
|
||||
use OpenSSL::Test::Utils;
|
||||
|
||||
our @tests = (
|
||||
{
|
||||
name => "server-auth-TLSv1.3",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success",
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "client-auth-TLSv1.3-request",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"VerifyMode" => "Request",
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success",
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "client-auth-TLSv1.3-require-fail",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"VerifyCAFile" => test_pem("root-cert.pem"),
|
||||
"VerifyMode" => "Require",
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "ServerFail",
|
||||
"ExpectedServerAlert" => "HandshakeFailure",
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "client-auth-TLSv1.3-require",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"ClientSignatureAlgorithms" => "PSS+SHA256",
|
||||
"VerifyCAFile" => test_pem("root-cert.pem"),
|
||||
"VerifyMode" => "Request",
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"Certificate" => test_pem("ee-client-chain.pem"),
|
||||
"PrivateKey" => test_pem("ee-key.pem"),
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success",
|
||||
"ExpectedClientCertType" => "RSA",
|
||||
"ExpectedClientSignType" => "RSA-PSS",
|
||||
"ExpectedClientSignHash" => "SHA256",
|
||||
"ExpectedClientCANames" => "empty"
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "client-auth-TLSv1.3-require-non-empty-names",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"ClientSignatureAlgorithms" => "PSS+SHA256",
|
||||
"ClientCAFile" => test_pem("root-cert.pem"),
|
||||
"VerifyCAFile" => test_pem("root-cert.pem"),
|
||||
"VerifyMode" => "Request",
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"Certificate" => test_pem("ee-client-chain.pem"),
|
||||
"PrivateKey" => test_pem("ee-key.pem"),
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success",
|
||||
"ExpectedClientCertType" => "RSA",
|
||||
"ExpectedClientSignType" => "RSA-PSS",
|
||||
"ExpectedClientSignHash" => "SHA256",
|
||||
"ExpectedClientCANames" => test_pem("root-cert.pem"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "client-auth-TLSv1.3-noroot",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"VerifyMode" => "Require",
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"Certificate" => test_pem("ee-client-chain.pem"),
|
||||
"PrivateKey" => test_pem("ee-key.pem"),
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "ServerFail",
|
||||
"ExpectedServerAlert" => "UnknownCA",
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "client-auth-TLSv1.3-request-post-handshake",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"VerifyMode" => "RequestPostHandshake",
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "ServerFail",
|
||||
"HandshakeMode" => "PostHandshakeAuth",
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "client-auth-TLSv1.3-require-fail-post-handshake",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"VerifyCAFile" => test_pem("root-cert.pem"),
|
||||
"VerifyMode" => "RequirePostHandshake",
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "ServerFail",
|
||||
"HandshakeMode" => "PostHandshakeAuth",
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "client-auth-TLSv1.3-require-post-handshake",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"ClientSignatureAlgorithms" => "PSS+SHA256",
|
||||
"VerifyCAFile" => test_pem("root-cert.pem"),
|
||||
"VerifyMode" => "RequestPostHandshake",
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"Certificate" => test_pem("ee-client-chain.pem"),
|
||||
"PrivateKey" => test_pem("ee-key.pem"),
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success",
|
||||
"HandshakeMode" => "PostHandshakeAuth",
|
||||
"ExpectedClientCertType" => "RSA",
|
||||
"ExpectedClientSignType" => "RSA-PSS",
|
||||
"ExpectedClientSignHash" => "SHA256",
|
||||
"ExpectedClientCANames" => "empty"
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "client-auth-TLSv1.3-require-non-empty-names-post-handshake",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"ClientSignatureAlgorithms" => "PSS+SHA256",
|
||||
"ClientCAFile" => test_pem("root-cert.pem"),
|
||||
"VerifyCAFile" => test_pem("root-cert.pem"),
|
||||
"VerifyMode" => "RequestPostHandshake",
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"Certificate" => test_pem("ee-client-chain.pem"),
|
||||
"PrivateKey" => test_pem("ee-key.pem"),
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success",
|
||||
"HandshakeMode" => "PostHandshakeAuth",
|
||||
"ExpectedClientCertType" => "RSA",
|
||||
"ExpectedClientSignType" => "RSA-PSS",
|
||||
"ExpectedClientSignHash" => "SHA256",
|
||||
"ExpectedClientCANames" => test_pem("root-cert.pem"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "client-auth-TLSv1.3-noroot-post-handshake",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"VerifyMode" => "RequirePostHandshake",
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"Certificate" => test_pem("ee-client-chain.pem"),
|
||||
"PrivateKey" => test_pem("ee-key.pem"),
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "ServerFail",
|
||||
"HandshakeMode" => "PostHandshakeAuth",
|
||||
"ExpectedServerAlert" => "UnknownCA",
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "client-auth-TLSv1.3-request-force-client-post-handshake",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"VerifyMode" => "RequestPostHandshake",
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
extra => {
|
||||
"ForcePHA" => "Yes",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success",
|
||||
"HandshakeMode" => "PostHandshakeAuth",
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "client-auth-TLSv1.3-request-force-server-post-handshake",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"VerifyMode" => "RequestPostHandshake",
|
||||
extra => {
|
||||
"ForcePHA" => "Yes",
|
||||
},
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "ClientFail",
|
||||
"HandshakeMode" => "PostHandshakeAuth",
|
||||
},
|
||||
},
|
||||
{
|
||||
name => "client-auth-TLSv1.3-request-force-both-post-handshake",
|
||||
server => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
"VerifyMode" => "RequestPostHandshake",
|
||||
extra => {
|
||||
"ForcePHA" => "Yes",
|
||||
},
|
||||
},
|
||||
client => {
|
||||
"MinProtocol" => "TLSv1.3",
|
||||
"MaxProtocol" => "TLSv1.3",
|
||||
extra => {
|
||||
"ForcePHA" => "Yes",
|
||||
},
|
||||
},
|
||||
test => {
|
||||
"ExpectedResult" => "Success",
|
||||
"HandshakeMode" => "PostHandshakeAuth",
|
||||
},
|
||||
},
|
||||
);
|
|
@ -369,6 +369,7 @@ static const test_enum ssl_handshake_modes[] = {
|
|||
{"RenegotiateClient", SSL_TEST_HANDSHAKE_RENEG_CLIENT},
|
||||
{"KeyUpdateServer", SSL_TEST_HANDSHAKE_KEY_UPDATE_SERVER},
|
||||
{"KeyUpdateClient", SSL_TEST_HANDSHAKE_KEY_UPDATE_CLIENT},
|
||||
{"PostHandshakeAuth", SSL_TEST_HANDSHAKE_POST_HANDSHAKE_AUTH},
|
||||
};
|
||||
|
||||
__owur static int parse_handshake_mode(SSL_TEST_CTX *test_ctx, const char *value)
|
||||
|
@ -622,6 +623,11 @@ __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 */
|
||||
|
||||
IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CLIENT_CONF, client, force_pha)
|
||||
IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_SERVER_CONF, server, force_pha)
|
||||
|
||||
/* Known test options and their corresponding parse methods. */
|
||||
|
||||
/* Top-level options. */
|
||||
|
@ -676,6 +682,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 },
|
||||
};
|
||||
|
||||
/* Nested server options. */
|
||||
|
@ -692,6 +699,7 @@ static const ssl_test_server_option ssl_test_server_options[] = {
|
|||
{ "CertStatus", &parse_certstatus },
|
||||
{ "SRPUser", &parse_server_srp_user },
|
||||
{ "SRPPassword", &parse_server_srp_password },
|
||||
{ "ForcePHA", &parse_server_force_pha },
|
||||
};
|
||||
|
||||
SSL_TEST_CTX *SSL_TEST_CTX_new()
|
||||
|
|
|
@ -73,7 +73,8 @@ typedef enum {
|
|||
SSL_TEST_HANDSHAKE_RENEG_SERVER,
|
||||
SSL_TEST_HANDSHAKE_RENEG_CLIENT,
|
||||
SSL_TEST_HANDSHAKE_KEY_UPDATE_SERVER,
|
||||
SSL_TEST_HANDSHAKE_KEY_UPDATE_CLIENT
|
||||
SSL_TEST_HANDSHAKE_KEY_UPDATE_CLIENT,
|
||||
SSL_TEST_HANDSHAKE_POST_HANDSHAKE_AUTH
|
||||
} ssl_handshake_mode_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -107,6 +108,8 @@ typedef struct {
|
|||
char *reneg_ciphers;
|
||||
char *srp_user;
|
||||
char *srp_password;
|
||||
/* Forced PHA */
|
||||
int force_pha;
|
||||
} SSL_TEST_CLIENT_CONF;
|
||||
|
||||
typedef struct {
|
||||
|
@ -122,6 +125,8 @@ typedef struct {
|
|||
/* An SRP user known to the server. */
|
||||
char *srp_user;
|
||||
char *srp_password;
|
||||
/* Forced PHA */
|
||||
int force_pha;
|
||||
} SSL_TEST_SERVER_CONF;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -3306,6 +3306,65 @@ end:
|
|||
return testresult;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_TLS1_3
|
||||
static int test_pha_key_update(void)
|
||||
{
|
||||
SSL_CTX *cctx = NULL, *sctx = NULL;
|
||||
SSL *clientssl = NULL, *serverssl = NULL;
|
||||
int testresult = 0;
|
||||
|
||||
if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
|
||||
TLS_client_method(),
|
||||
&sctx, &cctx, cert, privkey)))
|
||||
return 0;
|
||||
|
||||
if (!TEST_true(SSL_CTX_set_min_proto_version(sctx, TLS1_3_VERSION))
|
||||
|| !TEST_true(SSL_CTX_set_max_proto_version(sctx, TLS1_3_VERSION))
|
||||
|| !TEST_true(SSL_CTX_set_min_proto_version(cctx, TLS1_3_VERSION))
|
||||
|| !TEST_true(SSL_CTX_set_max_proto_version(cctx, TLS1_3_VERSION)))
|
||||
goto end;
|
||||
|
||||
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
|
||||
NULL, NULL)))
|
||||
goto end;
|
||||
|
||||
SSL_force_post_handshake_auth(clientssl);
|
||||
|
||||
if (!TEST_true(create_ssl_connection(serverssl, clientssl,
|
||||
SSL_ERROR_NONE)))
|
||||
goto end;
|
||||
|
||||
SSL_set_verify(serverssl, SSL_VERIFY_PEER, NULL);
|
||||
if (!TEST_true(SSL_verify_client_post_handshake(serverssl)))
|
||||
goto end;
|
||||
|
||||
if (!TEST_true(SSL_key_update(clientssl, SSL_KEY_UPDATE_NOT_REQUESTED)))
|
||||
goto end;
|
||||
|
||||
/* Start handshake on the server */
|
||||
if (!TEST_int_eq(SSL_do_handshake(serverssl), 1))
|
||||
goto end;
|
||||
|
||||
/* Starts with SSL_connect(), but it's really just SSL_do_handshake() */
|
||||
if (!TEST_true(create_ssl_connection(serverssl, clientssl,
|
||||
SSL_ERROR_NONE)))
|
||||
goto end;
|
||||
|
||||
SSL_shutdown(clientssl);
|
||||
SSL_shutdown(serverssl);
|
||||
|
||||
testresult = 1;
|
||||
|
||||
end:
|
||||
SSL_free(serverssl);
|
||||
SSL_free(clientssl);
|
||||
SSL_CTX_free(sctx);
|
||||
SSL_CTX_free(cctx);
|
||||
return testresult;
|
||||
}
|
||||
#endif
|
||||
|
||||
int setup_tests(void)
|
||||
{
|
||||
if (!TEST_ptr(cert = test_get_argument(0))
|
||||
|
@ -3352,6 +3411,7 @@ int setup_tests(void)
|
|||
ADD_TEST(test_tls13_psk);
|
||||
ADD_ALL_TESTS(test_custom_exts, 5);
|
||||
ADD_TEST(test_stateless);
|
||||
ADD_TEST(test_pha_key_update);
|
||||
#else
|
||||
ADD_ALL_TESTS(test_custom_exts, 3);
|
||||
#endif
|
||||
|
|
|
@ -474,3 +474,5 @@ SSL_CTX_set_tlsext_max_fragment_length 474 1_1_1 EXIST::FUNCTION:
|
|||
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:
|
||||
|
|
|
@ -79,6 +79,7 @@ use constant {
|
|||
EXT_SUPPORTED_VERSIONS => 43,
|
||||
EXT_COOKIE => 44,
|
||||
EXT_PSK_KEX_MODES => 45,
|
||||
EXT_POST_HANDSHAKE_AUTH => 49,
|
||||
EXT_SIG_ALGS_CERT => 50,
|
||||
EXT_RENEGOTIATE => 65281,
|
||||
EXT_NPN => 13172,
|
||||
|
|
|
@ -53,7 +53,8 @@ use constant {
|
|||
KEY_SHARE_SRV_EXTENSION => 0x00020000,
|
||||
PSK_KEX_MODES_EXTENSION => 0x00040000,
|
||||
KEY_SHARE_HRR_EXTENSION => 0x00080000,
|
||||
SUPPORTED_GROUPS_SRV_EXTENSION => 0x00100000
|
||||
SUPPORTED_GROUPS_SRV_EXTENSION => 0x00100000,
|
||||
POST_HANDSHAKE_AUTH_CLI_EXTENSION => 0x00200000
|
||||
};
|
||||
|
||||
our @handmessages = ();
|
||||
|
|
Loading…
Reference in a new issue