Provide a function to send a KeyUpdate message
This implements the server side KeyUpdate sending capability as well. Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2609)
This commit is contained in:
parent
25b802bb85
commit
44c04a2e06
9 changed files with 86 additions and 15 deletions
|
@ -825,6 +825,14 @@ DEFINE_STACK_OF(SSL_COMP)
|
|||
# define SSL_CTX_set_app_data(ctx,arg) (SSL_CTX_set_ex_data(ctx,0,(char *)arg))
|
||||
DEPRECATEDIN_1_1_0(void SSL_set_debug(SSL *s, int debug))
|
||||
|
||||
/* TLSv1.3 KeyUpdate message types */
|
||||
typedef enum {
|
||||
/* -1 used so that this is an invalid value for the on-the-wire protocol */
|
||||
SSL_KEY_UPDATE_NONE = -1,
|
||||
/* Values as defined for the on-the-wire protocol */
|
||||
SSL_KEY_UPDATE_NOT_REQUESTED = 0,
|
||||
SSL_KEY_UPDATE_REQUESTED = 1
|
||||
} SSL_KEY_UPDATE;
|
||||
|
||||
/*
|
||||
* The valid handshake states (one for each type message sent and one for each
|
||||
|
@ -882,7 +890,9 @@ typedef enum {
|
|||
TLS_ST_SW_CERT_VRFY,
|
||||
TLS_ST_CR_HELLO_REQ,
|
||||
TLS_ST_SW_HELLO_RETRY_REQUEST,
|
||||
TLS_ST_CR_HELLO_RETRY_REQUEST
|
||||
TLS_ST_CR_HELLO_RETRY_REQUEST,
|
||||
TLS_ST_SW_KEY_UPDATE,
|
||||
TLS_ST_CW_KEY_UPDATE
|
||||
} OSSL_HANDSHAKE_STATE;
|
||||
|
||||
/*
|
||||
|
@ -1650,6 +1660,7 @@ __owur STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s);
|
|||
__owur STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s);
|
||||
|
||||
__owur int SSL_do_handshake(SSL *s);
|
||||
int SSL_key_update(SSL *s, SSL_KEY_UPDATE updatetype);
|
||||
int SSL_renegotiate(SSL *s);
|
||||
int SSL_renegotiate_abbreviated(SSL *s);
|
||||
__owur int SSL_renegotiate_pending(SSL *s);
|
||||
|
@ -2195,6 +2206,7 @@ int ERR_load_SSL_strings(void);
|
|||
# define SSL_F_SSL_GET_SERVER_CERT_INDEX 322
|
||||
# define SSL_F_SSL_GET_SIGN_PKEY 183
|
||||
# define SSL_F_SSL_INIT_WBIO_BUFFER 184
|
||||
# define SSL_F_SSL_KEY_UPDATE 515
|
||||
# define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185
|
||||
# define SSL_F_SSL_LOG_MASTER_SECRET 498
|
||||
# define SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE 499
|
||||
|
@ -2210,6 +2222,7 @@ int ERR_load_SSL_strings(void);
|
|||
# define SSL_F_SSL_PEEK_EX 432
|
||||
# define SSL_F_SSL_READ 223
|
||||
# define SSL_F_SSL_READ_EX 434
|
||||
# define SSL_F_SSL_RENEGOTIATE 516
|
||||
# define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT 320
|
||||
# define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT 321
|
||||
# define SSL_F_SSL_SESSION_DUP 348
|
||||
|
@ -2305,6 +2318,7 @@ int ERR_load_SSL_strings(void);
|
|||
# define SSL_F_TLS_CONSTRUCT_FINISHED 359
|
||||
# define SSL_F_TLS_CONSTRUCT_HELLO_REQUEST 373
|
||||
# define SSL_F_TLS_CONSTRUCT_HELLO_RETRY_REQUEST 510
|
||||
# define SSL_F_TLS_CONSTRUCT_KEY_UPDATE 517
|
||||
# define SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET 428
|
||||
# define SSL_F_TLS_CONSTRUCT_NEXT_PROTO 426
|
||||
# define SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE 490
|
||||
|
@ -2472,6 +2486,7 @@ int ERR_load_SSL_strings(void);
|
|||
# define SSL_R_INVALID_COMPRESSION_ALGORITHM 341
|
||||
# define SSL_R_INVALID_CONFIGURATION_NAME 113
|
||||
# define SSL_R_INVALID_CT_VALIDATION_TYPE 212
|
||||
# define SSL_R_INVALID_KEY_UPDATE_TYPE 120
|
||||
# define SSL_R_INVALID_NULL_CMD_NAME 385
|
||||
# define SSL_R_INVALID_SEQUENCE_NUMBER 402
|
||||
# define SSL_R_INVALID_SERVERINFO_DATA 388
|
||||
|
@ -2578,6 +2593,7 @@ int ERR_load_SSL_strings(void);
|
|||
# define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 303
|
||||
# define SSL_R_SSL_SESSION_ID_TOO_LONG 408
|
||||
# define SSL_R_SSL_SESSION_VERSION_MISMATCH 210
|
||||
# define SSL_R_STILL_IN_INIT 121
|
||||
# define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049
|
||||
# define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050
|
||||
# define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021
|
||||
|
|
|
@ -287,6 +287,7 @@ extern "C" {
|
|||
# define SSL3_MT_CLIENT_KEY_EXCHANGE 16
|
||||
# define SSL3_MT_FINISHED 20
|
||||
# define SSL3_MT_CERTIFICATE_STATUS 22
|
||||
# define SSL3_MT_KEY_UPDATE 24
|
||||
# ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
# define SSL3_MT_NEXT_PROTO 67
|
||||
# endif
|
||||
|
|
|
@ -179,6 +179,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
|
|||
{ERR_FUNC(SSL_F_SSL_GET_SERVER_CERT_INDEX), "ssl_get_server_cert_index"},
|
||||
{ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY), "ssl_get_sign_pkey"},
|
||||
{ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "ssl_init_wbio_buffer"},
|
||||
{ERR_FUNC(SSL_F_SSL_KEY_UPDATE), "SSL_key_update"},
|
||||
{ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"},
|
||||
{ERR_FUNC(SSL_F_SSL_LOG_MASTER_SECRET), "ssl_log_master_secret"},
|
||||
{ERR_FUNC(SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE),
|
||||
|
@ -201,6 +202,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
|
|||
{ERR_FUNC(SSL_F_SSL_PEEK_EX), "SSL_peek_ex"},
|
||||
{ERR_FUNC(SSL_F_SSL_READ), "SSL_read"},
|
||||
{ERR_FUNC(SSL_F_SSL_READ_EX), "SSL_read_ex"},
|
||||
{ERR_FUNC(SSL_F_SSL_RENEGOTIATE), "SSL_renegotiate"},
|
||||
{ERR_FUNC(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT),
|
||||
"ssl_scan_clienthello_tlsext"},
|
||||
{ERR_FUNC(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT),
|
||||
|
@ -333,6 +335,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
|
|||
"tls_construct_hello_request"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_HELLO_RETRY_REQUEST),
|
||||
"tls_construct_hello_retry_request"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_KEY_UPDATE), "tls_construct_key_update"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET),
|
||||
"tls_construct_new_session_ticket"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_NEXT_PROTO), "tls_construct_next_proto"},
|
||||
|
@ -568,6 +571,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
|
|||
"invalid configuration name"},
|
||||
{ERR_REASON(SSL_R_INVALID_CT_VALIDATION_TYPE),
|
||||
"invalid ct validation type"},
|
||||
{ERR_REASON(SSL_R_INVALID_KEY_UPDATE_TYPE), "invalid key update type"},
|
||||
{ERR_REASON(SSL_R_INVALID_NULL_CMD_NAME), "invalid null cmd name"},
|
||||
{ERR_REASON(SSL_R_INVALID_SEQUENCE_NUMBER), "invalid sequence number"},
|
||||
{ERR_REASON(SSL_R_INVALID_SERVERINFO_DATA), "invalid serverinfo data"},
|
||||
|
@ -715,6 +719,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
|
|||
{ERR_REASON(SSL_R_SSL_SESSION_ID_TOO_LONG), "ssl session id too long"},
|
||||
{ERR_REASON(SSL_R_SSL_SESSION_VERSION_MISMATCH),
|
||||
"ssl session version mismatch"},
|
||||
{ERR_REASON(SSL_R_STILL_IN_INIT), "still in init"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_ACCESS_DENIED),
|
||||
"tlsv1 alert access denied"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_DECODE_ERROR), "tlsv1 alert decode error"},
|
||||
|
|
|
@ -471,6 +471,8 @@ int SSL_clear(SSL *s)
|
|||
clear_ciphers(s);
|
||||
s->first_packet = 0;
|
||||
|
||||
s->key_update = SSL_KEY_UPDATE_NONE;
|
||||
|
||||
/* Reset DANE verification result state */
|
||||
s->dane.mdpth = -1;
|
||||
s->dane.pdpth = -1;
|
||||
|
@ -639,6 +641,8 @@ SSL *SSL_new(SSL_CTX *ctx)
|
|||
|
||||
s->method = ctx->method;
|
||||
|
||||
s->key_update = SSL_KEY_UPDATE_NONE;
|
||||
|
||||
if (!s->method->ssl_new(s))
|
||||
goto err;
|
||||
|
||||
|
@ -1714,14 +1718,37 @@ int SSL_shutdown(SSL *s)
|
|||
}
|
||||
}
|
||||
|
||||
int SSL_key_update(SSL *s, SSL_KEY_UPDATE updatetype)
|
||||
{
|
||||
if (!SSL_IS_TLS13(s)) {
|
||||
SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_WRONG_SSL_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (updatetype != SSL_KEY_UPDATE_NOT_REQUESTED
|
||||
&& updatetype != SSL_KEY_UPDATE_REQUESTED) {
|
||||
SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_INVALID_KEY_UPDATE_TYPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!SSL_is_init_finished(s)) {
|
||||
SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_STILL_IN_INIT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ossl_statem_set_in_init(s, 1);
|
||||
|
||||
s->key_update = updatetype;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_renegotiate(SSL *s)
|
||||
{
|
||||
/*
|
||||
* TODO(TLS1.3): Return an error for now. Perhaps we should do a KeyUpdate
|
||||
* instead when we support that?
|
||||
*/
|
||||
if (SSL_IS_TLS13(s))
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
SSLerr(SSL_F_SSL_RENEGOTIATE, SSL_R_WRONG_SSL_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (s->renegotiate == 0)
|
||||
s->renegotiate = 1;
|
||||
|
@ -1733,10 +1760,6 @@ int SSL_renegotiate(SSL *s)
|
|||
|
||||
int SSL_renegotiate_abbreviated(SSL *s)
|
||||
{
|
||||
/*
|
||||
* TODO(TLS1.3): Return an error for now. Perhaps we should do a KeyUpdate
|
||||
* instead when we support that?
|
||||
*/
|
||||
if (SSL_IS_TLS13(s))
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -1172,6 +1172,8 @@ struct ssl_st {
|
|||
* (i.e. not just sending a HelloRequest)
|
||||
*/
|
||||
int renegotiate;
|
||||
/* If sending a KeyUpdate is pending */
|
||||
SSL_KEY_UPDATE key_update;
|
||||
# ifndef OPENSSL_NO_SRP
|
||||
/* ctx for SRP authentication */
|
||||
SRP_CTX srp_ctx;
|
||||
|
|
|
@ -495,6 +495,19 @@ int tls_construct_finished(SSL *s, WPACKET *pkt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tls_construct_key_update(SSL *s, WPACKET *pkt)
|
||||
{
|
||||
if (!WPACKET_put_bytes_u8(pkt, s->key_update)) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_KEY_UPDATE, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 1;
|
||||
err:
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
/*
|
||||
* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
|
||||
|
|
|
@ -111,6 +111,7 @@ __owur int tls_construct_change_cipher_spec(SSL *s, WPACKET *pkt);
|
|||
__owur int dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt);
|
||||
|
||||
__owur int tls_construct_finished(SSL *s, WPACKET *pkt);
|
||||
__owur int tls_construct_key_update(SSL *s, WPACKET *pkt);
|
||||
__owur WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs);
|
||||
__owur WORK_STATE dtls_wait_for_dry(SSL *s);
|
||||
|
||||
|
|
|
@ -393,11 +393,6 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
|
|||
{
|
||||
OSSL_STATEM *st = &s->statem;
|
||||
|
||||
/*
|
||||
* TODO(TLS1.3): This is still based on the TLSv1.2 state machine. Over time
|
||||
* we will update this to look more like real TLSv1.3
|
||||
*/
|
||||
|
||||
/*
|
||||
* No case for TLS_ST_BEFORE, because at that stage we have not negotiated
|
||||
* TLSv1.3 yet, so that is handled by ossl_statem_server_write_transition()
|
||||
|
@ -408,6 +403,13 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
|
|||
/* Shouldn't happen */
|
||||
return WRITE_TRAN_ERROR;
|
||||
|
||||
case TLS_ST_OK:
|
||||
if (s->key_update != SSL_KEY_UPDATE_NONE) {
|
||||
st->hand_state = TLS_ST_SW_KEY_UPDATE;
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
}
|
||||
return WRITE_TRAN_ERROR;
|
||||
|
||||
case TLS_ST_SR_CLNT_HELLO:
|
||||
if (s->hello_retry_request)
|
||||
st->hand_state = TLS_ST_SW_HELLO_RETRY_REQUEST;
|
||||
|
@ -459,6 +461,7 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
|
|||
st->hand_state = TLS_ST_SW_SESSION_TICKET;
|
||||
return WRITE_TRAN_CONTINUE;
|
||||
|
||||
case TLS_ST_SW_KEY_UPDATE:
|
||||
case TLS_ST_SW_SESSION_TICKET:
|
||||
st->hand_state = TLS_ST_OK;
|
||||
ossl_statem_set_in_init(s, 0);
|
||||
|
@ -822,6 +825,7 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
|
|||
}
|
||||
break;
|
||||
|
||||
case TLS_ST_SW_KEY_UPDATE:
|
||||
case TLS_ST_SW_SESSION_TICKET:
|
||||
if (SSL_IS_TLS13(s) && statem_flush(s) != 1)
|
||||
return WORK_MORE_A;
|
||||
|
@ -923,6 +927,11 @@ int ossl_statem_server_construct_message(SSL *s, WPACKET *pkt,
|
|||
*confunc = tls_construct_hello_retry_request;
|
||||
*mt = SSL3_MT_HELLO_RETRY_REQUEST;
|
||||
break;
|
||||
|
||||
case TLS_ST_SW_KEY_UPDATE:
|
||||
*confunc = tls_construct_key_update;
|
||||
*mt = SSL3_MT_KEY_UPDATE;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -413,3 +413,4 @@ SSL_COMP_get0_name 413 1_1_0d EXIST::FUNCTION:
|
|||
SSL_CTX_set_keylog_callback 414 1_1_1 EXIST::FUNCTION:
|
||||
SSL_CTX_get_keylog_callback 415 1_1_1 EXIST::FUNCTION:
|
||||
SSL_get_peer_signature_type_nid 416 1_1_1 EXIST::FUNCTION:
|
||||
SSL_key_update 417 1_1_1 EXIST::FUNCTION:
|
||||
|
|
Loading…
Reference in a new issue