1e71b7053SJung-uk Kim /* 2e71b7053SJung-uk Kim * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. 3e71b7053SJung-uk Kim * 4e71b7053SJung-uk Kim * Licensed under the OpenSSL license (the "License"). You may not use 5e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy 6e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at 7e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html 8e71b7053SJung-uk Kim */ 9e71b7053SJung-uk Kim 10e71b7053SJung-uk Kim #include "internal/cryptlib.h" 11e71b7053SJung-uk Kim #include <openssl/rand.h> 12e71b7053SJung-uk Kim #include "../ssl_locl.h" 13e71b7053SJung-uk Kim #include "statem_locl.h" 14e71b7053SJung-uk Kim #include <assert.h> 15e71b7053SJung-uk Kim 16e71b7053SJung-uk Kim /* 17e71b7053SJung-uk Kim * This file implements the SSL/TLS/DTLS state machines. 18e71b7053SJung-uk Kim * 19e71b7053SJung-uk Kim * There are two primary state machines: 20e71b7053SJung-uk Kim * 21e71b7053SJung-uk Kim * 1) Message flow state machine 22e71b7053SJung-uk Kim * 2) Handshake state machine 23e71b7053SJung-uk Kim * 24e71b7053SJung-uk Kim * The Message flow state machine controls the reading and sending of messages 25e71b7053SJung-uk Kim * including handling of non-blocking IO events, flushing of the underlying 26e71b7053SJung-uk Kim * write BIO, handling unexpected messages, etc. It is itself broken into two 27e71b7053SJung-uk Kim * separate sub-state machines which control reading and writing respectively. 28e71b7053SJung-uk Kim * 29e71b7053SJung-uk Kim * The Handshake state machine keeps track of the current SSL/TLS handshake 30e71b7053SJung-uk Kim * state. Transitions of the handshake state are the result of events that 31e71b7053SJung-uk Kim * occur within the Message flow state machine. 32e71b7053SJung-uk Kim * 33e71b7053SJung-uk Kim * Overall it looks like this: 34e71b7053SJung-uk Kim * 35e71b7053SJung-uk Kim * --------------------------------------------- ------------------- 36e71b7053SJung-uk Kim * | | | | 37e71b7053SJung-uk Kim * | Message flow state machine | | | 38e71b7053SJung-uk Kim * | | | | 39e71b7053SJung-uk Kim * | -------------------- -------------------- | Transition | Handshake state | 40e71b7053SJung-uk Kim * | | MSG_FLOW_READING | | MSG_FLOW_WRITING | | Event | machine | 41e71b7053SJung-uk Kim * | | sub-state | | sub-state | |----------->| | 42e71b7053SJung-uk Kim * | | machine for | | machine for | | | | 43e71b7053SJung-uk Kim * | | reading messages | | writing messages | | | | 44e71b7053SJung-uk Kim * | -------------------- -------------------- | | | 45e71b7053SJung-uk Kim * | | | | 46e71b7053SJung-uk Kim * --------------------------------------------- ------------------- 47e71b7053SJung-uk Kim * 48e71b7053SJung-uk Kim */ 49e71b7053SJung-uk Kim 50e71b7053SJung-uk Kim /* Sub state machine return values */ 51e71b7053SJung-uk Kim typedef enum { 52e71b7053SJung-uk Kim /* Something bad happened or NBIO */ 53e71b7053SJung-uk Kim SUB_STATE_ERROR, 54e71b7053SJung-uk Kim /* Sub state finished go to the next sub state */ 55e71b7053SJung-uk Kim SUB_STATE_FINISHED, 56e71b7053SJung-uk Kim /* Sub state finished and handshake was completed */ 57e71b7053SJung-uk Kim SUB_STATE_END_HANDSHAKE 58e71b7053SJung-uk Kim } SUB_STATE_RETURN; 59e71b7053SJung-uk Kim 60e71b7053SJung-uk Kim static int state_machine(SSL *s, int server); 61e71b7053SJung-uk Kim static void init_read_state_machine(SSL *s); 62e71b7053SJung-uk Kim static SUB_STATE_RETURN read_state_machine(SSL *s); 63e71b7053SJung-uk Kim static void init_write_state_machine(SSL *s); 64e71b7053SJung-uk Kim static SUB_STATE_RETURN write_state_machine(SSL *s); 65e71b7053SJung-uk Kim 66e71b7053SJung-uk Kim OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl) 67e71b7053SJung-uk Kim { 68e71b7053SJung-uk Kim return ssl->statem.hand_state; 69e71b7053SJung-uk Kim } 70e71b7053SJung-uk Kim 71e71b7053SJung-uk Kim int SSL_in_init(const SSL *s) 72e71b7053SJung-uk Kim { 73e71b7053SJung-uk Kim return s->statem.in_init; 74e71b7053SJung-uk Kim } 75e71b7053SJung-uk Kim 76e71b7053SJung-uk Kim int SSL_is_init_finished(const SSL *s) 77e71b7053SJung-uk Kim { 78e71b7053SJung-uk Kim return !(s->statem.in_init) && (s->statem.hand_state == TLS_ST_OK); 79e71b7053SJung-uk Kim } 80e71b7053SJung-uk Kim 81e71b7053SJung-uk Kim int SSL_in_before(const SSL *s) 82e71b7053SJung-uk Kim { 83e71b7053SJung-uk Kim /* 84e71b7053SJung-uk Kim * Historically being "in before" meant before anything had happened. In the 85e71b7053SJung-uk Kim * current code though we remain in the "before" state for a while after we 86e71b7053SJung-uk Kim * have started the handshake process (e.g. as a server waiting for the 87e71b7053SJung-uk Kim * first message to arrive). There "in before" is taken to mean "in before" 88e71b7053SJung-uk Kim * and not started any handshake process yet. 89e71b7053SJung-uk Kim */ 90e71b7053SJung-uk Kim return (s->statem.hand_state == TLS_ST_BEFORE) 91e71b7053SJung-uk Kim && (s->statem.state == MSG_FLOW_UNINITED); 92e71b7053SJung-uk Kim } 93e71b7053SJung-uk Kim 94e71b7053SJung-uk Kim /* 95e71b7053SJung-uk Kim * Clear the state machine state and reset back to MSG_FLOW_UNINITED 96e71b7053SJung-uk Kim */ 97e71b7053SJung-uk Kim void ossl_statem_clear(SSL *s) 98e71b7053SJung-uk Kim { 99e71b7053SJung-uk Kim s->statem.state = MSG_FLOW_UNINITED; 100e71b7053SJung-uk Kim s->statem.hand_state = TLS_ST_BEFORE; 101e71b7053SJung-uk Kim s->statem.in_init = 1; 102e71b7053SJung-uk Kim s->statem.no_cert_verify = 0; 103e71b7053SJung-uk Kim } 104e71b7053SJung-uk Kim 105e71b7053SJung-uk Kim /* 106e71b7053SJung-uk Kim * Set the state machine up ready for a renegotiation handshake 107e71b7053SJung-uk Kim */ 108e71b7053SJung-uk Kim void ossl_statem_set_renegotiate(SSL *s) 109e71b7053SJung-uk Kim { 110e71b7053SJung-uk Kim s->statem.in_init = 1; 111e71b7053SJung-uk Kim s->statem.request_state = TLS_ST_SW_HELLO_REQ; 112e71b7053SJung-uk Kim } 113e71b7053SJung-uk Kim 114e71b7053SJung-uk Kim /* 115e71b7053SJung-uk Kim * Put the state machine into an error state and send an alert if appropriate. 116e71b7053SJung-uk Kim * This is a permanent error for the current connection. 117e71b7053SJung-uk Kim */ 118e71b7053SJung-uk Kim void ossl_statem_fatal(SSL *s, int al, int func, int reason, const char *file, 119e71b7053SJung-uk Kim int line) 120e71b7053SJung-uk Kim { 121*c9cf7b5cSJung-uk Kim ERR_put_error(ERR_LIB_SSL, func, reason, file, line); 122e71b7053SJung-uk Kim /* We shouldn't call SSLfatal() twice. Once is enough */ 123*c9cf7b5cSJung-uk Kim if (s->statem.in_init && s->statem.state == MSG_FLOW_ERROR) 124*c9cf7b5cSJung-uk Kim return; 125e71b7053SJung-uk Kim s->statem.in_init = 1; 126e71b7053SJung-uk Kim s->statem.state = MSG_FLOW_ERROR; 127e71b7053SJung-uk Kim if (al != SSL_AD_NO_ALERT 128e71b7053SJung-uk Kim && s->statem.enc_write_state != ENC_WRITE_STATE_INVALID) 129e71b7053SJung-uk Kim ssl3_send_alert(s, SSL3_AL_FATAL, al); 130e71b7053SJung-uk Kim } 131e71b7053SJung-uk Kim 132e71b7053SJung-uk Kim /* 133e71b7053SJung-uk Kim * This macro should only be called if we are already expecting to be in 134e71b7053SJung-uk Kim * a fatal error state. We verify that we are, and set it if not (this would 135e71b7053SJung-uk Kim * indicate a bug). 136e71b7053SJung-uk Kim */ 137e71b7053SJung-uk Kim #define check_fatal(s, f) \ 138e71b7053SJung-uk Kim do { \ 139e71b7053SJung-uk Kim if (!ossl_assert((s)->statem.in_init \ 140e71b7053SJung-uk Kim && (s)->statem.state == MSG_FLOW_ERROR)) \ 141e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_INTERNAL_ERROR, (f), \ 142e71b7053SJung-uk Kim SSL_R_MISSING_FATAL); \ 143e71b7053SJung-uk Kim } while (0) 144e71b7053SJung-uk Kim 145e71b7053SJung-uk Kim /* 146e71b7053SJung-uk Kim * Discover whether the current connection is in the error state. 147e71b7053SJung-uk Kim * 148e71b7053SJung-uk Kim * Valid return values are: 149e71b7053SJung-uk Kim * 1: Yes 150e71b7053SJung-uk Kim * 0: No 151e71b7053SJung-uk Kim */ 152e71b7053SJung-uk Kim int ossl_statem_in_error(const SSL *s) 153e71b7053SJung-uk Kim { 154e71b7053SJung-uk Kim if (s->statem.state == MSG_FLOW_ERROR) 155e71b7053SJung-uk Kim return 1; 156e71b7053SJung-uk Kim 157e71b7053SJung-uk Kim return 0; 158e71b7053SJung-uk Kim } 159e71b7053SJung-uk Kim 160e71b7053SJung-uk Kim void ossl_statem_set_in_init(SSL *s, int init) 161e71b7053SJung-uk Kim { 162e71b7053SJung-uk Kim s->statem.in_init = init; 163e71b7053SJung-uk Kim } 164e71b7053SJung-uk Kim 165e71b7053SJung-uk Kim int ossl_statem_get_in_handshake(SSL *s) 166e71b7053SJung-uk Kim { 167e71b7053SJung-uk Kim return s->statem.in_handshake; 168e71b7053SJung-uk Kim } 169e71b7053SJung-uk Kim 170e71b7053SJung-uk Kim void ossl_statem_set_in_handshake(SSL *s, int inhand) 171e71b7053SJung-uk Kim { 172e71b7053SJung-uk Kim if (inhand) 173e71b7053SJung-uk Kim s->statem.in_handshake++; 174e71b7053SJung-uk Kim else 175e71b7053SJung-uk Kim s->statem.in_handshake--; 176e71b7053SJung-uk Kim } 177e71b7053SJung-uk Kim 178e71b7053SJung-uk Kim /* Are we in a sensible state to skip over unreadable early data? */ 179e71b7053SJung-uk Kim int ossl_statem_skip_early_data(SSL *s) 180e71b7053SJung-uk Kim { 181e71b7053SJung-uk Kim if (s->ext.early_data != SSL_EARLY_DATA_REJECTED) 182e71b7053SJung-uk Kim return 0; 183e71b7053SJung-uk Kim 184e71b7053SJung-uk Kim if (!s->server 185e71b7053SJung-uk Kim || s->statem.hand_state != TLS_ST_EARLY_DATA 186e71b7053SJung-uk Kim || s->hello_retry_request == SSL_HRR_COMPLETE) 187e71b7053SJung-uk Kim return 0; 188e71b7053SJung-uk Kim 189e71b7053SJung-uk Kim return 1; 190e71b7053SJung-uk Kim } 191e71b7053SJung-uk Kim 192e71b7053SJung-uk Kim /* 193e71b7053SJung-uk Kim * Called when we are in SSL_read*(), SSL_write*(), or SSL_accept() 194e71b7053SJung-uk Kim * /SSL_connect()/SSL_do_handshake(). Used to test whether we are in an early 195e71b7053SJung-uk Kim * data state and whether we should attempt to move the handshake on if so. 196e71b7053SJung-uk Kim * |sending| is 1 if we are attempting to send data (SSL_write*()), 0 if we are 197e71b7053SJung-uk Kim * attempting to read data (SSL_read*()), or -1 if we are in SSL_do_handshake() 198e71b7053SJung-uk Kim * or similar. 199e71b7053SJung-uk Kim */ 200e71b7053SJung-uk Kim void ossl_statem_check_finish_init(SSL *s, int sending) 201e71b7053SJung-uk Kim { 202e71b7053SJung-uk Kim if (sending == -1) { 203e71b7053SJung-uk Kim if (s->statem.hand_state == TLS_ST_PENDING_EARLY_DATA_END 204e71b7053SJung-uk Kim || s->statem.hand_state == TLS_ST_EARLY_DATA) { 205e71b7053SJung-uk Kim ossl_statem_set_in_init(s, 1); 206e71b7053SJung-uk Kim if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) { 207e71b7053SJung-uk Kim /* 208e71b7053SJung-uk Kim * SSL_connect() or SSL_do_handshake() has been called directly. 209e71b7053SJung-uk Kim * We don't allow any more writing of early data. 210e71b7053SJung-uk Kim */ 211e71b7053SJung-uk Kim s->early_data_state = SSL_EARLY_DATA_FINISHED_WRITING; 212e71b7053SJung-uk Kim } 213e71b7053SJung-uk Kim } 214e71b7053SJung-uk Kim } else if (!s->server) { 215e71b7053SJung-uk Kim if ((sending && (s->statem.hand_state == TLS_ST_PENDING_EARLY_DATA_END 216e71b7053SJung-uk Kim || s->statem.hand_state == TLS_ST_EARLY_DATA) 217e71b7053SJung-uk Kim && s->early_data_state != SSL_EARLY_DATA_WRITING) 218e71b7053SJung-uk Kim || (!sending && s->statem.hand_state == TLS_ST_EARLY_DATA)) { 219e71b7053SJung-uk Kim ossl_statem_set_in_init(s, 1); 220e71b7053SJung-uk Kim /* 221e71b7053SJung-uk Kim * SSL_write() has been called directly. We don't allow any more 222e71b7053SJung-uk Kim * writing of early data. 223e71b7053SJung-uk Kim */ 224e71b7053SJung-uk Kim if (sending && s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) 225e71b7053SJung-uk Kim s->early_data_state = SSL_EARLY_DATA_FINISHED_WRITING; 226e71b7053SJung-uk Kim } 227e71b7053SJung-uk Kim } else { 228e71b7053SJung-uk Kim if (s->early_data_state == SSL_EARLY_DATA_FINISHED_READING 229e71b7053SJung-uk Kim && s->statem.hand_state == TLS_ST_EARLY_DATA) 230e71b7053SJung-uk Kim ossl_statem_set_in_init(s, 1); 231e71b7053SJung-uk Kim } 232e71b7053SJung-uk Kim } 233e71b7053SJung-uk Kim 234e71b7053SJung-uk Kim void ossl_statem_set_hello_verify_done(SSL *s) 235e71b7053SJung-uk Kim { 236e71b7053SJung-uk Kim s->statem.state = MSG_FLOW_UNINITED; 237e71b7053SJung-uk Kim s->statem.in_init = 1; 238e71b7053SJung-uk Kim /* 239e71b7053SJung-uk Kim * This will get reset (briefly) back to TLS_ST_BEFORE when we enter 240e71b7053SJung-uk Kim * state_machine() because |state| is MSG_FLOW_UNINITED, but until then any 241e71b7053SJung-uk Kim * calls to SSL_in_before() will return false. Also calls to 242e71b7053SJung-uk Kim * SSL_state_string() and SSL_state_string_long() will return something 243e71b7053SJung-uk Kim * sensible. 244e71b7053SJung-uk Kim */ 245e71b7053SJung-uk Kim s->statem.hand_state = TLS_ST_SR_CLNT_HELLO; 246e71b7053SJung-uk Kim } 247e71b7053SJung-uk Kim 248e71b7053SJung-uk Kim int ossl_statem_connect(SSL *s) 249e71b7053SJung-uk Kim { 250e71b7053SJung-uk Kim return state_machine(s, 0); 251e71b7053SJung-uk Kim } 252e71b7053SJung-uk Kim 253e71b7053SJung-uk Kim int ossl_statem_accept(SSL *s) 254e71b7053SJung-uk Kim { 255e71b7053SJung-uk Kim return state_machine(s, 1); 256e71b7053SJung-uk Kim } 257e71b7053SJung-uk Kim 258e71b7053SJung-uk Kim typedef void (*info_cb) (const SSL *, int, int); 259e71b7053SJung-uk Kim 260e71b7053SJung-uk Kim static info_cb get_callback(SSL *s) 261e71b7053SJung-uk Kim { 262e71b7053SJung-uk Kim if (s->info_callback != NULL) 263e71b7053SJung-uk Kim return s->info_callback; 264e71b7053SJung-uk Kim else if (s->ctx->info_callback != NULL) 265e71b7053SJung-uk Kim return s->ctx->info_callback; 266e71b7053SJung-uk Kim 267e71b7053SJung-uk Kim return NULL; 268e71b7053SJung-uk Kim } 269e71b7053SJung-uk Kim 270e71b7053SJung-uk Kim /* 271e71b7053SJung-uk Kim * The main message flow state machine. We start in the MSG_FLOW_UNINITED or 272e71b7053SJung-uk Kim * MSG_FLOW_FINISHED state and finish in MSG_FLOW_FINISHED. Valid states and 273e71b7053SJung-uk Kim * transitions are as follows: 274e71b7053SJung-uk Kim * 275e71b7053SJung-uk Kim * MSG_FLOW_UNINITED MSG_FLOW_FINISHED 276e71b7053SJung-uk Kim * | | 277e71b7053SJung-uk Kim * +-----------------------+ 278e71b7053SJung-uk Kim * v 279e71b7053SJung-uk Kim * MSG_FLOW_WRITING <---> MSG_FLOW_READING 280e71b7053SJung-uk Kim * | 281e71b7053SJung-uk Kim * V 282e71b7053SJung-uk Kim * MSG_FLOW_FINISHED 283e71b7053SJung-uk Kim * | 284e71b7053SJung-uk Kim * V 285e71b7053SJung-uk Kim * [SUCCESS] 286e71b7053SJung-uk Kim * 287e71b7053SJung-uk Kim * We may exit at any point due to an error or NBIO event. If an NBIO event 288e71b7053SJung-uk Kim * occurs then we restart at the point we left off when we are recalled. 289e71b7053SJung-uk Kim * MSG_FLOW_WRITING and MSG_FLOW_READING have sub-state machines associated with them. 290e71b7053SJung-uk Kim * 291e71b7053SJung-uk Kim * In addition to the above there is also the MSG_FLOW_ERROR state. We can move 292e71b7053SJung-uk Kim * into that state at any point in the event that an irrecoverable error occurs. 293e71b7053SJung-uk Kim * 294e71b7053SJung-uk Kim * Valid return values are: 295e71b7053SJung-uk Kim * 1: Success 296e71b7053SJung-uk Kim * <=0: NBIO or error 297e71b7053SJung-uk Kim */ 298e71b7053SJung-uk Kim static int state_machine(SSL *s, int server) 299e71b7053SJung-uk Kim { 300e71b7053SJung-uk Kim BUF_MEM *buf = NULL; 301e71b7053SJung-uk Kim void (*cb) (const SSL *ssl, int type, int val) = NULL; 302e71b7053SJung-uk Kim OSSL_STATEM *st = &s->statem; 303e71b7053SJung-uk Kim int ret = -1; 304e71b7053SJung-uk Kim int ssret; 305e71b7053SJung-uk Kim 306e71b7053SJung-uk Kim if (st->state == MSG_FLOW_ERROR) { 307e71b7053SJung-uk Kim /* Shouldn't have been called if we're already in the error state */ 308e71b7053SJung-uk Kim return -1; 309e71b7053SJung-uk Kim } 310e71b7053SJung-uk Kim 311e71b7053SJung-uk Kim ERR_clear_error(); 312e71b7053SJung-uk Kim clear_sys_error(); 313e71b7053SJung-uk Kim 314e71b7053SJung-uk Kim cb = get_callback(s); 315e71b7053SJung-uk Kim 316e71b7053SJung-uk Kim st->in_handshake++; 317e71b7053SJung-uk Kim if (!SSL_in_init(s) || SSL_in_before(s)) { 318e71b7053SJung-uk Kim /* 319e71b7053SJung-uk Kim * If we are stateless then we already called SSL_clear() - don't do 320e71b7053SJung-uk Kim * it again and clear the STATELESS flag itself. 321e71b7053SJung-uk Kim */ 322e71b7053SJung-uk Kim if ((s->s3->flags & TLS1_FLAGS_STATELESS) == 0 && !SSL_clear(s)) 323e71b7053SJung-uk Kim return -1; 324e71b7053SJung-uk Kim } 325e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP 326e71b7053SJung-uk Kim if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s))) { 327e71b7053SJung-uk Kim /* 328e71b7053SJung-uk Kim * Notify SCTP BIO socket to enter handshake mode and prevent stream 329e71b7053SJung-uk Kim * identifier other than 0. 330e71b7053SJung-uk Kim */ 331e71b7053SJung-uk Kim BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, 332e71b7053SJung-uk Kim st->in_handshake, NULL); 333e71b7053SJung-uk Kim } 334e71b7053SJung-uk Kim #endif 335e71b7053SJung-uk Kim 336e71b7053SJung-uk Kim /* Initialise state machine */ 337e71b7053SJung-uk Kim if (st->state == MSG_FLOW_UNINITED 338e71b7053SJung-uk Kim || st->state == MSG_FLOW_FINISHED) { 339e71b7053SJung-uk Kim if (st->state == MSG_FLOW_UNINITED) { 340e71b7053SJung-uk Kim st->hand_state = TLS_ST_BEFORE; 341e71b7053SJung-uk Kim st->request_state = TLS_ST_BEFORE; 342e71b7053SJung-uk Kim } 343e71b7053SJung-uk Kim 344e71b7053SJung-uk Kim s->server = server; 345e71b7053SJung-uk Kim if (cb != NULL) 346e71b7053SJung-uk Kim cb(s, SSL_CB_HANDSHAKE_START, 1); 347e71b7053SJung-uk Kim 348e71b7053SJung-uk Kim /* 349e71b7053SJung-uk Kim * Fatal errors in this block don't send an alert because we have 350e71b7053SJung-uk Kim * failed to even initialise properly. Sending an alert is probably 351e71b7053SJung-uk Kim * doomed to failure. 352e71b7053SJung-uk Kim */ 353e71b7053SJung-uk Kim 354e71b7053SJung-uk Kim if (SSL_IS_DTLS(s)) { 355e71b7053SJung-uk Kim if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00) && 356e71b7053SJung-uk Kim (server || (s->version & 0xff00) != (DTLS1_BAD_VER & 0xff00))) { 357e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, 358e71b7053SJung-uk Kim ERR_R_INTERNAL_ERROR); 359e71b7053SJung-uk Kim goto end; 360e71b7053SJung-uk Kim } 361e71b7053SJung-uk Kim } else { 362e71b7053SJung-uk Kim if ((s->version >> 8) != SSL3_VERSION_MAJOR) { 363e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, 364e71b7053SJung-uk Kim ERR_R_INTERNAL_ERROR); 365e71b7053SJung-uk Kim goto end; 366e71b7053SJung-uk Kim } 367e71b7053SJung-uk Kim } 368e71b7053SJung-uk Kim 369e71b7053SJung-uk Kim if (!ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL)) { 370e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, 371e71b7053SJung-uk Kim ERR_R_INTERNAL_ERROR); 372e71b7053SJung-uk Kim goto end; 373e71b7053SJung-uk Kim } 374e71b7053SJung-uk Kim 375e71b7053SJung-uk Kim if (s->init_buf == NULL) { 376e71b7053SJung-uk Kim if ((buf = BUF_MEM_new()) == NULL) { 377e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, 378e71b7053SJung-uk Kim ERR_R_INTERNAL_ERROR); 379e71b7053SJung-uk Kim goto end; 380e71b7053SJung-uk Kim } 381e71b7053SJung-uk Kim if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { 382e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, 383e71b7053SJung-uk Kim ERR_R_INTERNAL_ERROR); 384e71b7053SJung-uk Kim goto end; 385e71b7053SJung-uk Kim } 386e71b7053SJung-uk Kim s->init_buf = buf; 387e71b7053SJung-uk Kim buf = NULL; 388e71b7053SJung-uk Kim } 389e71b7053SJung-uk Kim 390e71b7053SJung-uk Kim if (!ssl3_setup_buffers(s)) { 391e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, 392e71b7053SJung-uk Kim ERR_R_INTERNAL_ERROR); 393e71b7053SJung-uk Kim goto end; 394e71b7053SJung-uk Kim } 395e71b7053SJung-uk Kim s->init_num = 0; 396e71b7053SJung-uk Kim 397e71b7053SJung-uk Kim /* 398e71b7053SJung-uk Kim * Should have been reset by tls_process_finished, too. 399e71b7053SJung-uk Kim */ 400e71b7053SJung-uk Kim s->s3->change_cipher_spec = 0; 401e71b7053SJung-uk Kim 402e71b7053SJung-uk Kim /* 403e71b7053SJung-uk Kim * Ok, we now need to push on a buffering BIO ...but not with 404e71b7053SJung-uk Kim * SCTP 405e71b7053SJung-uk Kim */ 406e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP 407e71b7053SJung-uk Kim if (!SSL_IS_DTLS(s) || !BIO_dgram_is_sctp(SSL_get_wbio(s))) 408e71b7053SJung-uk Kim #endif 409e71b7053SJung-uk Kim if (!ssl_init_wbio_buffer(s)) { 410e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, 411e71b7053SJung-uk Kim ERR_R_INTERNAL_ERROR); 412e71b7053SJung-uk Kim goto end; 413e71b7053SJung-uk Kim } 414e71b7053SJung-uk Kim 415e71b7053SJung-uk Kim if ((SSL_in_before(s)) 416e71b7053SJung-uk Kim || s->renegotiate) { 417e71b7053SJung-uk Kim if (!tls_setup_handshake(s)) { 418e71b7053SJung-uk Kim /* SSLfatal() already called */ 419e71b7053SJung-uk Kim goto end; 420e71b7053SJung-uk Kim } 421e71b7053SJung-uk Kim 422e71b7053SJung-uk Kim if (SSL_IS_FIRST_HANDSHAKE(s)) 423e71b7053SJung-uk Kim st->read_state_first_init = 1; 424e71b7053SJung-uk Kim } 425e71b7053SJung-uk Kim 426e71b7053SJung-uk Kim st->state = MSG_FLOW_WRITING; 427e71b7053SJung-uk Kim init_write_state_machine(s); 428e71b7053SJung-uk Kim } 429e71b7053SJung-uk Kim 430e71b7053SJung-uk Kim while (st->state != MSG_FLOW_FINISHED) { 431e71b7053SJung-uk Kim if (st->state == MSG_FLOW_READING) { 432e71b7053SJung-uk Kim ssret = read_state_machine(s); 433e71b7053SJung-uk Kim if (ssret == SUB_STATE_FINISHED) { 434e71b7053SJung-uk Kim st->state = MSG_FLOW_WRITING; 435e71b7053SJung-uk Kim init_write_state_machine(s); 436e71b7053SJung-uk Kim } else { 437e71b7053SJung-uk Kim /* NBIO or error */ 438e71b7053SJung-uk Kim goto end; 439e71b7053SJung-uk Kim } 440e71b7053SJung-uk Kim } else if (st->state == MSG_FLOW_WRITING) { 441e71b7053SJung-uk Kim ssret = write_state_machine(s); 442e71b7053SJung-uk Kim if (ssret == SUB_STATE_FINISHED) { 443e71b7053SJung-uk Kim st->state = MSG_FLOW_READING; 444e71b7053SJung-uk Kim init_read_state_machine(s); 445e71b7053SJung-uk Kim } else if (ssret == SUB_STATE_END_HANDSHAKE) { 446e71b7053SJung-uk Kim st->state = MSG_FLOW_FINISHED; 447e71b7053SJung-uk Kim } else { 448e71b7053SJung-uk Kim /* NBIO or error */ 449e71b7053SJung-uk Kim goto end; 450e71b7053SJung-uk Kim } 451e71b7053SJung-uk Kim } else { 452e71b7053SJung-uk Kim /* Error */ 453e71b7053SJung-uk Kim check_fatal(s, SSL_F_STATE_MACHINE); 454e71b7053SJung-uk Kim SSLerr(SSL_F_STATE_MACHINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 455e71b7053SJung-uk Kim goto end; 456e71b7053SJung-uk Kim } 457e71b7053SJung-uk Kim } 458e71b7053SJung-uk Kim 459e71b7053SJung-uk Kim ret = 1; 460e71b7053SJung-uk Kim 461e71b7053SJung-uk Kim end: 462e71b7053SJung-uk Kim st->in_handshake--; 463e71b7053SJung-uk Kim 464e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP 465e71b7053SJung-uk Kim if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s))) { 466e71b7053SJung-uk Kim /* 467e71b7053SJung-uk Kim * Notify SCTP BIO socket to leave handshake mode and allow stream 468e71b7053SJung-uk Kim * identifier other than 0. 469e71b7053SJung-uk Kim */ 470e71b7053SJung-uk Kim BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, 471e71b7053SJung-uk Kim st->in_handshake, NULL); 472e71b7053SJung-uk Kim } 473e71b7053SJung-uk Kim #endif 474e71b7053SJung-uk Kim 475e71b7053SJung-uk Kim BUF_MEM_free(buf); 476e71b7053SJung-uk Kim if (cb != NULL) { 477e71b7053SJung-uk Kim if (server) 478e71b7053SJung-uk Kim cb(s, SSL_CB_ACCEPT_EXIT, ret); 479e71b7053SJung-uk Kim else 480e71b7053SJung-uk Kim cb(s, SSL_CB_CONNECT_EXIT, ret); 481e71b7053SJung-uk Kim } 482e71b7053SJung-uk Kim return ret; 483e71b7053SJung-uk Kim } 484e71b7053SJung-uk Kim 485e71b7053SJung-uk Kim /* 486e71b7053SJung-uk Kim * Initialise the MSG_FLOW_READING sub-state machine 487e71b7053SJung-uk Kim */ 488e71b7053SJung-uk Kim static void init_read_state_machine(SSL *s) 489e71b7053SJung-uk Kim { 490e71b7053SJung-uk Kim OSSL_STATEM *st = &s->statem; 491e71b7053SJung-uk Kim 492e71b7053SJung-uk Kim st->read_state = READ_STATE_HEADER; 493e71b7053SJung-uk Kim } 494e71b7053SJung-uk Kim 495e71b7053SJung-uk Kim static int grow_init_buf(SSL *s, size_t size) { 496e71b7053SJung-uk Kim 497e71b7053SJung-uk Kim size_t msg_offset = (char *)s->init_msg - s->init_buf->data; 498e71b7053SJung-uk Kim 499e71b7053SJung-uk Kim if (!BUF_MEM_grow_clean(s->init_buf, (int)size)) 500e71b7053SJung-uk Kim return 0; 501e71b7053SJung-uk Kim 502e71b7053SJung-uk Kim if (size < msg_offset) 503e71b7053SJung-uk Kim return 0; 504e71b7053SJung-uk Kim 505e71b7053SJung-uk Kim s->init_msg = s->init_buf->data + msg_offset; 506e71b7053SJung-uk Kim 507e71b7053SJung-uk Kim return 1; 508e71b7053SJung-uk Kim } 509e71b7053SJung-uk Kim 510e71b7053SJung-uk Kim /* 511e71b7053SJung-uk Kim * This function implements the sub-state machine when the message flow is in 512e71b7053SJung-uk Kim * MSG_FLOW_READING. The valid sub-states and transitions are: 513e71b7053SJung-uk Kim * 514e71b7053SJung-uk Kim * READ_STATE_HEADER <--+<-------------+ 515e71b7053SJung-uk Kim * | | | 516e71b7053SJung-uk Kim * v | | 517e71b7053SJung-uk Kim * READ_STATE_BODY -----+-->READ_STATE_POST_PROCESS 518e71b7053SJung-uk Kim * | | 519e71b7053SJung-uk Kim * +----------------------------+ 520e71b7053SJung-uk Kim * v 521e71b7053SJung-uk Kim * [SUB_STATE_FINISHED] 522e71b7053SJung-uk Kim * 523e71b7053SJung-uk Kim * READ_STATE_HEADER has the responsibility for reading in the message header 524e71b7053SJung-uk Kim * and transitioning the state of the handshake state machine. 525e71b7053SJung-uk Kim * 526e71b7053SJung-uk Kim * READ_STATE_BODY reads in the rest of the message and then subsequently 527e71b7053SJung-uk Kim * processes it. 528e71b7053SJung-uk Kim * 529e71b7053SJung-uk Kim * READ_STATE_POST_PROCESS is an optional step that may occur if some post 530e71b7053SJung-uk Kim * processing activity performed on the message may block. 531e71b7053SJung-uk Kim * 532e71b7053SJung-uk Kim * Any of the above states could result in an NBIO event occurring in which case 533e71b7053SJung-uk Kim * control returns to the calling application. When this function is recalled we 534e71b7053SJung-uk Kim * will resume in the same state where we left off. 535e71b7053SJung-uk Kim */ 536e71b7053SJung-uk Kim static SUB_STATE_RETURN read_state_machine(SSL *s) 537e71b7053SJung-uk Kim { 538e71b7053SJung-uk Kim OSSL_STATEM *st = &s->statem; 539e71b7053SJung-uk Kim int ret, mt; 540e71b7053SJung-uk Kim size_t len = 0; 541e71b7053SJung-uk Kim int (*transition) (SSL *s, int mt); 542e71b7053SJung-uk Kim PACKET pkt; 543e71b7053SJung-uk Kim MSG_PROCESS_RETURN(*process_message) (SSL *s, PACKET *pkt); 544e71b7053SJung-uk Kim WORK_STATE(*post_process_message) (SSL *s, WORK_STATE wst); 545e71b7053SJung-uk Kim size_t (*max_message_size) (SSL *s); 546e71b7053SJung-uk Kim void (*cb) (const SSL *ssl, int type, int val) = NULL; 547e71b7053SJung-uk Kim 548e71b7053SJung-uk Kim cb = get_callback(s); 549e71b7053SJung-uk Kim 550e71b7053SJung-uk Kim if (s->server) { 551e71b7053SJung-uk Kim transition = ossl_statem_server_read_transition; 552e71b7053SJung-uk Kim process_message = ossl_statem_server_process_message; 553e71b7053SJung-uk Kim max_message_size = ossl_statem_server_max_message_size; 554e71b7053SJung-uk Kim post_process_message = ossl_statem_server_post_process_message; 555e71b7053SJung-uk Kim } else { 556e71b7053SJung-uk Kim transition = ossl_statem_client_read_transition; 557e71b7053SJung-uk Kim process_message = ossl_statem_client_process_message; 558e71b7053SJung-uk Kim max_message_size = ossl_statem_client_max_message_size; 559e71b7053SJung-uk Kim post_process_message = ossl_statem_client_post_process_message; 560e71b7053SJung-uk Kim } 561e71b7053SJung-uk Kim 562e71b7053SJung-uk Kim if (st->read_state_first_init) { 563e71b7053SJung-uk Kim s->first_packet = 1; 564e71b7053SJung-uk Kim st->read_state_first_init = 0; 565e71b7053SJung-uk Kim } 566e71b7053SJung-uk Kim 567e71b7053SJung-uk Kim while (1) { 568e71b7053SJung-uk Kim switch (st->read_state) { 569e71b7053SJung-uk Kim case READ_STATE_HEADER: 570e71b7053SJung-uk Kim /* Get the state the peer wants to move to */ 571e71b7053SJung-uk Kim if (SSL_IS_DTLS(s)) { 572e71b7053SJung-uk Kim /* 573e71b7053SJung-uk Kim * In DTLS we get the whole message in one go - header and body 574e71b7053SJung-uk Kim */ 575e71b7053SJung-uk Kim ret = dtls_get_message(s, &mt, &len); 576e71b7053SJung-uk Kim } else { 577e71b7053SJung-uk Kim ret = tls_get_message_header(s, &mt); 578e71b7053SJung-uk Kim } 579e71b7053SJung-uk Kim 580e71b7053SJung-uk Kim if (ret == 0) { 581e71b7053SJung-uk Kim /* Could be non-blocking IO */ 582e71b7053SJung-uk Kim return SUB_STATE_ERROR; 583e71b7053SJung-uk Kim } 584e71b7053SJung-uk Kim 585e71b7053SJung-uk Kim if (cb != NULL) { 586e71b7053SJung-uk Kim /* Notify callback of an impending state change */ 587e71b7053SJung-uk Kim if (s->server) 588e71b7053SJung-uk Kim cb(s, SSL_CB_ACCEPT_LOOP, 1); 589e71b7053SJung-uk Kim else 590e71b7053SJung-uk Kim cb(s, SSL_CB_CONNECT_LOOP, 1); 591e71b7053SJung-uk Kim } 592e71b7053SJung-uk Kim /* 593e71b7053SJung-uk Kim * Validate that we are allowed to move to the new state and move 594e71b7053SJung-uk Kim * to that state if so 595e71b7053SJung-uk Kim */ 596e71b7053SJung-uk Kim if (!transition(s, mt)) 597e71b7053SJung-uk Kim return SUB_STATE_ERROR; 598e71b7053SJung-uk Kim 599e71b7053SJung-uk Kim if (s->s3->tmp.message_size > max_message_size(s)) { 600e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_READ_STATE_MACHINE, 601e71b7053SJung-uk Kim SSL_R_EXCESSIVE_MESSAGE_SIZE); 602e71b7053SJung-uk Kim return SUB_STATE_ERROR; 603e71b7053SJung-uk Kim } 604e71b7053SJung-uk Kim 605e71b7053SJung-uk Kim /* dtls_get_message already did this */ 606e71b7053SJung-uk Kim if (!SSL_IS_DTLS(s) 607e71b7053SJung-uk Kim && s->s3->tmp.message_size > 0 608e71b7053SJung-uk Kim && !grow_init_buf(s, s->s3->tmp.message_size 609e71b7053SJung-uk Kim + SSL3_HM_HEADER_LENGTH)) { 610e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_READ_STATE_MACHINE, 611e71b7053SJung-uk Kim ERR_R_BUF_LIB); 612e71b7053SJung-uk Kim return SUB_STATE_ERROR; 613e71b7053SJung-uk Kim } 614e71b7053SJung-uk Kim 615e71b7053SJung-uk Kim st->read_state = READ_STATE_BODY; 616e71b7053SJung-uk Kim /* Fall through */ 617e71b7053SJung-uk Kim 618e71b7053SJung-uk Kim case READ_STATE_BODY: 619e71b7053SJung-uk Kim if (!SSL_IS_DTLS(s)) { 620e71b7053SJung-uk Kim /* We already got this above for DTLS */ 621e71b7053SJung-uk Kim ret = tls_get_message_body(s, &len); 622e71b7053SJung-uk Kim if (ret == 0) { 623e71b7053SJung-uk Kim /* Could be non-blocking IO */ 624e71b7053SJung-uk Kim return SUB_STATE_ERROR; 625e71b7053SJung-uk Kim } 626e71b7053SJung-uk Kim } 627e71b7053SJung-uk Kim 628e71b7053SJung-uk Kim s->first_packet = 0; 629e71b7053SJung-uk Kim if (!PACKET_buf_init(&pkt, s->init_msg, len)) { 630e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_READ_STATE_MACHINE, 631e71b7053SJung-uk Kim ERR_R_INTERNAL_ERROR); 632e71b7053SJung-uk Kim return SUB_STATE_ERROR; 633e71b7053SJung-uk Kim } 634e71b7053SJung-uk Kim ret = process_message(s, &pkt); 635e71b7053SJung-uk Kim 636e71b7053SJung-uk Kim /* Discard the packet data */ 637e71b7053SJung-uk Kim s->init_num = 0; 638e71b7053SJung-uk Kim 639e71b7053SJung-uk Kim switch (ret) { 640e71b7053SJung-uk Kim case MSG_PROCESS_ERROR: 641e71b7053SJung-uk Kim check_fatal(s, SSL_F_READ_STATE_MACHINE); 642e71b7053SJung-uk Kim return SUB_STATE_ERROR; 643e71b7053SJung-uk Kim 644e71b7053SJung-uk Kim case MSG_PROCESS_FINISHED_READING: 645e71b7053SJung-uk Kim if (SSL_IS_DTLS(s)) { 646e71b7053SJung-uk Kim dtls1_stop_timer(s); 647e71b7053SJung-uk Kim } 648e71b7053SJung-uk Kim return SUB_STATE_FINISHED; 649e71b7053SJung-uk Kim 650e71b7053SJung-uk Kim case MSG_PROCESS_CONTINUE_PROCESSING: 651e71b7053SJung-uk Kim st->read_state = READ_STATE_POST_PROCESS; 652e71b7053SJung-uk Kim st->read_state_work = WORK_MORE_A; 653e71b7053SJung-uk Kim break; 654e71b7053SJung-uk Kim 655e71b7053SJung-uk Kim default: 656e71b7053SJung-uk Kim st->read_state = READ_STATE_HEADER; 657e71b7053SJung-uk Kim break; 658e71b7053SJung-uk Kim } 659e71b7053SJung-uk Kim break; 660e71b7053SJung-uk Kim 661e71b7053SJung-uk Kim case READ_STATE_POST_PROCESS: 662e71b7053SJung-uk Kim st->read_state_work = post_process_message(s, st->read_state_work); 663e71b7053SJung-uk Kim switch (st->read_state_work) { 664e71b7053SJung-uk Kim case WORK_ERROR: 665e71b7053SJung-uk Kim check_fatal(s, SSL_F_READ_STATE_MACHINE); 666e71b7053SJung-uk Kim /* Fall through */ 667e71b7053SJung-uk Kim case WORK_MORE_A: 668e71b7053SJung-uk Kim case WORK_MORE_B: 669e71b7053SJung-uk Kim case WORK_MORE_C: 670e71b7053SJung-uk Kim return SUB_STATE_ERROR; 671e71b7053SJung-uk Kim 672e71b7053SJung-uk Kim case WORK_FINISHED_CONTINUE: 673e71b7053SJung-uk Kim st->read_state = READ_STATE_HEADER; 674e71b7053SJung-uk Kim break; 675e71b7053SJung-uk Kim 676e71b7053SJung-uk Kim case WORK_FINISHED_STOP: 677e71b7053SJung-uk Kim if (SSL_IS_DTLS(s)) { 678e71b7053SJung-uk Kim dtls1_stop_timer(s); 679e71b7053SJung-uk Kim } 680e71b7053SJung-uk Kim return SUB_STATE_FINISHED; 681e71b7053SJung-uk Kim } 682e71b7053SJung-uk Kim break; 683e71b7053SJung-uk Kim 684e71b7053SJung-uk Kim default: 685e71b7053SJung-uk Kim /* Shouldn't happen */ 686e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_READ_STATE_MACHINE, 687e71b7053SJung-uk Kim ERR_R_INTERNAL_ERROR); 688e71b7053SJung-uk Kim return SUB_STATE_ERROR; 689e71b7053SJung-uk Kim } 690e71b7053SJung-uk Kim } 691e71b7053SJung-uk Kim } 692e71b7053SJung-uk Kim 693e71b7053SJung-uk Kim /* 694e71b7053SJung-uk Kim * Send a previously constructed message to the peer. 695e71b7053SJung-uk Kim */ 696e71b7053SJung-uk Kim static int statem_do_write(SSL *s) 697e71b7053SJung-uk Kim { 698e71b7053SJung-uk Kim OSSL_STATEM *st = &s->statem; 699e71b7053SJung-uk Kim 700e71b7053SJung-uk Kim if (st->hand_state == TLS_ST_CW_CHANGE 701e71b7053SJung-uk Kim || st->hand_state == TLS_ST_SW_CHANGE) { 702e71b7053SJung-uk Kim if (SSL_IS_DTLS(s)) 703e71b7053SJung-uk Kim return dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC); 704e71b7053SJung-uk Kim else 705e71b7053SJung-uk Kim return ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC); 706e71b7053SJung-uk Kim } else { 707e71b7053SJung-uk Kim return ssl_do_write(s); 708e71b7053SJung-uk Kim } 709e71b7053SJung-uk Kim } 710e71b7053SJung-uk Kim 711e71b7053SJung-uk Kim /* 712e71b7053SJung-uk Kim * Initialise the MSG_FLOW_WRITING sub-state machine 713e71b7053SJung-uk Kim */ 714e71b7053SJung-uk Kim static void init_write_state_machine(SSL *s) 715e71b7053SJung-uk Kim { 716e71b7053SJung-uk Kim OSSL_STATEM *st = &s->statem; 717e71b7053SJung-uk Kim 718e71b7053SJung-uk Kim st->write_state = WRITE_STATE_TRANSITION; 719e71b7053SJung-uk Kim } 720e71b7053SJung-uk Kim 721e71b7053SJung-uk Kim /* 722e71b7053SJung-uk Kim * This function implements the sub-state machine when the message flow is in 723e71b7053SJung-uk Kim * MSG_FLOW_WRITING. The valid sub-states and transitions are: 724e71b7053SJung-uk Kim * 725e71b7053SJung-uk Kim * +-> WRITE_STATE_TRANSITION ------> [SUB_STATE_FINISHED] 726e71b7053SJung-uk Kim * | | 727e71b7053SJung-uk Kim * | v 728e71b7053SJung-uk Kim * | WRITE_STATE_PRE_WORK -----> [SUB_STATE_END_HANDSHAKE] 729e71b7053SJung-uk Kim * | | 730e71b7053SJung-uk Kim * | v 731e71b7053SJung-uk Kim * | WRITE_STATE_SEND 732e71b7053SJung-uk Kim * | | 733e71b7053SJung-uk Kim * | v 734e71b7053SJung-uk Kim * | WRITE_STATE_POST_WORK 735e71b7053SJung-uk Kim * | | 736e71b7053SJung-uk Kim * +-------------+ 737e71b7053SJung-uk Kim * 738e71b7053SJung-uk Kim * WRITE_STATE_TRANSITION transitions the state of the handshake state machine 739e71b7053SJung-uk Kim 740e71b7053SJung-uk Kim * WRITE_STATE_PRE_WORK performs any work necessary to prepare the later 741e71b7053SJung-uk Kim * sending of the message. This could result in an NBIO event occurring in 742e71b7053SJung-uk Kim * which case control returns to the calling application. When this function 743e71b7053SJung-uk Kim * is recalled we will resume in the same state where we left off. 744e71b7053SJung-uk Kim * 745e71b7053SJung-uk Kim * WRITE_STATE_SEND sends the message and performs any work to be done after 746e71b7053SJung-uk Kim * sending. 747e71b7053SJung-uk Kim * 748e71b7053SJung-uk Kim * WRITE_STATE_POST_WORK performs any work necessary after the sending of the 749e71b7053SJung-uk Kim * message has been completed. As for WRITE_STATE_PRE_WORK this could also 750e71b7053SJung-uk Kim * result in an NBIO event. 751e71b7053SJung-uk Kim */ 752e71b7053SJung-uk Kim static SUB_STATE_RETURN write_state_machine(SSL *s) 753e71b7053SJung-uk Kim { 754e71b7053SJung-uk Kim OSSL_STATEM *st = &s->statem; 755e71b7053SJung-uk Kim int ret; 756e71b7053SJung-uk Kim WRITE_TRAN(*transition) (SSL *s); 757e71b7053SJung-uk Kim WORK_STATE(*pre_work) (SSL *s, WORK_STATE wst); 758e71b7053SJung-uk Kim WORK_STATE(*post_work) (SSL *s, WORK_STATE wst); 759e71b7053SJung-uk Kim int (*get_construct_message_f) (SSL *s, WPACKET *pkt, 760e71b7053SJung-uk Kim int (**confunc) (SSL *s, WPACKET *pkt), 761e71b7053SJung-uk Kim int *mt); 762e71b7053SJung-uk Kim void (*cb) (const SSL *ssl, int type, int val) = NULL; 763e71b7053SJung-uk Kim int (*confunc) (SSL *s, WPACKET *pkt); 764e71b7053SJung-uk Kim int mt; 765e71b7053SJung-uk Kim WPACKET pkt; 766e71b7053SJung-uk Kim 767e71b7053SJung-uk Kim cb = get_callback(s); 768e71b7053SJung-uk Kim 769e71b7053SJung-uk Kim if (s->server) { 770e71b7053SJung-uk Kim transition = ossl_statem_server_write_transition; 771e71b7053SJung-uk Kim pre_work = ossl_statem_server_pre_work; 772e71b7053SJung-uk Kim post_work = ossl_statem_server_post_work; 773e71b7053SJung-uk Kim get_construct_message_f = ossl_statem_server_construct_message; 774e71b7053SJung-uk Kim } else { 775e71b7053SJung-uk Kim transition = ossl_statem_client_write_transition; 776e71b7053SJung-uk Kim pre_work = ossl_statem_client_pre_work; 777e71b7053SJung-uk Kim post_work = ossl_statem_client_post_work; 778e71b7053SJung-uk Kim get_construct_message_f = ossl_statem_client_construct_message; 779e71b7053SJung-uk Kim } 780e71b7053SJung-uk Kim 781e71b7053SJung-uk Kim while (1) { 782e71b7053SJung-uk Kim switch (st->write_state) { 783e71b7053SJung-uk Kim case WRITE_STATE_TRANSITION: 784e71b7053SJung-uk Kim if (cb != NULL) { 785e71b7053SJung-uk Kim /* Notify callback of an impending state change */ 786e71b7053SJung-uk Kim if (s->server) 787e71b7053SJung-uk Kim cb(s, SSL_CB_ACCEPT_LOOP, 1); 788e71b7053SJung-uk Kim else 789e71b7053SJung-uk Kim cb(s, SSL_CB_CONNECT_LOOP, 1); 790e71b7053SJung-uk Kim } 791e71b7053SJung-uk Kim switch (transition(s)) { 792e71b7053SJung-uk Kim case WRITE_TRAN_CONTINUE: 793e71b7053SJung-uk Kim st->write_state = WRITE_STATE_PRE_WORK; 794e71b7053SJung-uk Kim st->write_state_work = WORK_MORE_A; 795e71b7053SJung-uk Kim break; 796e71b7053SJung-uk Kim 797e71b7053SJung-uk Kim case WRITE_TRAN_FINISHED: 798e71b7053SJung-uk Kim return SUB_STATE_FINISHED; 799e71b7053SJung-uk Kim break; 800e71b7053SJung-uk Kim 801e71b7053SJung-uk Kim case WRITE_TRAN_ERROR: 802e71b7053SJung-uk Kim check_fatal(s, SSL_F_WRITE_STATE_MACHINE); 803e71b7053SJung-uk Kim return SUB_STATE_ERROR; 804e71b7053SJung-uk Kim } 805e71b7053SJung-uk Kim break; 806e71b7053SJung-uk Kim 807e71b7053SJung-uk Kim case WRITE_STATE_PRE_WORK: 808e71b7053SJung-uk Kim switch (st->write_state_work = pre_work(s, st->write_state_work)) { 809e71b7053SJung-uk Kim case WORK_ERROR: 810e71b7053SJung-uk Kim check_fatal(s, SSL_F_WRITE_STATE_MACHINE); 811e71b7053SJung-uk Kim /* Fall through */ 812e71b7053SJung-uk Kim case WORK_MORE_A: 813e71b7053SJung-uk Kim case WORK_MORE_B: 814e71b7053SJung-uk Kim case WORK_MORE_C: 815e71b7053SJung-uk Kim return SUB_STATE_ERROR; 816e71b7053SJung-uk Kim 817e71b7053SJung-uk Kim case WORK_FINISHED_CONTINUE: 818e71b7053SJung-uk Kim st->write_state = WRITE_STATE_SEND; 819e71b7053SJung-uk Kim break; 820e71b7053SJung-uk Kim 821e71b7053SJung-uk Kim case WORK_FINISHED_STOP: 822e71b7053SJung-uk Kim return SUB_STATE_END_HANDSHAKE; 823e71b7053SJung-uk Kim } 824e71b7053SJung-uk Kim if (!get_construct_message_f(s, &pkt, &confunc, &mt)) { 825e71b7053SJung-uk Kim /* SSLfatal() already called */ 826e71b7053SJung-uk Kim return SUB_STATE_ERROR; 827e71b7053SJung-uk Kim } 828e71b7053SJung-uk Kim if (mt == SSL3_MT_DUMMY) { 829e71b7053SJung-uk Kim /* Skip construction and sending. This isn't a "real" state */ 830e71b7053SJung-uk Kim st->write_state = WRITE_STATE_POST_WORK; 831e71b7053SJung-uk Kim st->write_state_work = WORK_MORE_A; 832e71b7053SJung-uk Kim break; 833e71b7053SJung-uk Kim } 834e71b7053SJung-uk Kim if (!WPACKET_init(&pkt, s->init_buf) 835e71b7053SJung-uk Kim || !ssl_set_handshake_header(s, &pkt, mt)) { 836e71b7053SJung-uk Kim WPACKET_cleanup(&pkt); 837e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_WRITE_STATE_MACHINE, 838e71b7053SJung-uk Kim ERR_R_INTERNAL_ERROR); 839e71b7053SJung-uk Kim return SUB_STATE_ERROR; 840e71b7053SJung-uk Kim } 841e71b7053SJung-uk Kim if (confunc != NULL && !confunc(s, &pkt)) { 842e71b7053SJung-uk Kim WPACKET_cleanup(&pkt); 843e71b7053SJung-uk Kim check_fatal(s, SSL_F_WRITE_STATE_MACHINE); 844e71b7053SJung-uk Kim return SUB_STATE_ERROR; 845e71b7053SJung-uk Kim } 846e71b7053SJung-uk Kim if (!ssl_close_construct_packet(s, &pkt, mt) 847e71b7053SJung-uk Kim || !WPACKET_finish(&pkt)) { 848e71b7053SJung-uk Kim WPACKET_cleanup(&pkt); 849e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_WRITE_STATE_MACHINE, 850e71b7053SJung-uk Kim ERR_R_INTERNAL_ERROR); 851e71b7053SJung-uk Kim return SUB_STATE_ERROR; 852e71b7053SJung-uk Kim } 853e71b7053SJung-uk Kim 854e71b7053SJung-uk Kim /* Fall through */ 855e71b7053SJung-uk Kim 856e71b7053SJung-uk Kim case WRITE_STATE_SEND: 857e71b7053SJung-uk Kim if (SSL_IS_DTLS(s) && st->use_timer) { 858e71b7053SJung-uk Kim dtls1_start_timer(s); 859e71b7053SJung-uk Kim } 860e71b7053SJung-uk Kim ret = statem_do_write(s); 861e71b7053SJung-uk Kim if (ret <= 0) { 862e71b7053SJung-uk Kim return SUB_STATE_ERROR; 863e71b7053SJung-uk Kim } 864e71b7053SJung-uk Kim st->write_state = WRITE_STATE_POST_WORK; 865e71b7053SJung-uk Kim st->write_state_work = WORK_MORE_A; 866e71b7053SJung-uk Kim /* Fall through */ 867e71b7053SJung-uk Kim 868e71b7053SJung-uk Kim case WRITE_STATE_POST_WORK: 869e71b7053SJung-uk Kim switch (st->write_state_work = post_work(s, st->write_state_work)) { 870e71b7053SJung-uk Kim case WORK_ERROR: 871e71b7053SJung-uk Kim check_fatal(s, SSL_F_WRITE_STATE_MACHINE); 872e71b7053SJung-uk Kim /* Fall through */ 873e71b7053SJung-uk Kim case WORK_MORE_A: 874e71b7053SJung-uk Kim case WORK_MORE_B: 875e71b7053SJung-uk Kim case WORK_MORE_C: 876e71b7053SJung-uk Kim return SUB_STATE_ERROR; 877e71b7053SJung-uk Kim 878e71b7053SJung-uk Kim case WORK_FINISHED_CONTINUE: 879e71b7053SJung-uk Kim st->write_state = WRITE_STATE_TRANSITION; 880e71b7053SJung-uk Kim break; 881e71b7053SJung-uk Kim 882e71b7053SJung-uk Kim case WORK_FINISHED_STOP: 883e71b7053SJung-uk Kim return SUB_STATE_END_HANDSHAKE; 884e71b7053SJung-uk Kim } 885e71b7053SJung-uk Kim break; 886e71b7053SJung-uk Kim 887e71b7053SJung-uk Kim default: 888e71b7053SJung-uk Kim SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_WRITE_STATE_MACHINE, 889e71b7053SJung-uk Kim ERR_R_INTERNAL_ERROR); 890e71b7053SJung-uk Kim return SUB_STATE_ERROR; 891e71b7053SJung-uk Kim } 892e71b7053SJung-uk Kim } 893e71b7053SJung-uk Kim } 894e71b7053SJung-uk Kim 895e71b7053SJung-uk Kim /* 896e71b7053SJung-uk Kim * Flush the write BIO 897e71b7053SJung-uk Kim */ 898e71b7053SJung-uk Kim int statem_flush(SSL *s) 899e71b7053SJung-uk Kim { 900e71b7053SJung-uk Kim s->rwstate = SSL_WRITING; 901e71b7053SJung-uk Kim if (BIO_flush(s->wbio) <= 0) { 902e71b7053SJung-uk Kim return 0; 903e71b7053SJung-uk Kim } 904e71b7053SJung-uk Kim s->rwstate = SSL_NOTHING; 905e71b7053SJung-uk Kim 906e71b7053SJung-uk Kim return 1; 907e71b7053SJung-uk Kim } 908e71b7053SJung-uk Kim 909e71b7053SJung-uk Kim /* 910e71b7053SJung-uk Kim * Called by the record layer to determine whether application data is 911e71b7053SJung-uk Kim * allowed to be received in the current handshake state or not. 912e71b7053SJung-uk Kim * 913e71b7053SJung-uk Kim * Return values are: 914e71b7053SJung-uk Kim * 1: Yes (application data allowed) 915e71b7053SJung-uk Kim * 0: No (application data not allowed) 916e71b7053SJung-uk Kim */ 917e71b7053SJung-uk Kim int ossl_statem_app_data_allowed(SSL *s) 918e71b7053SJung-uk Kim { 919e71b7053SJung-uk Kim OSSL_STATEM *st = &s->statem; 920e71b7053SJung-uk Kim 921e71b7053SJung-uk Kim if (st->state == MSG_FLOW_UNINITED) 922e71b7053SJung-uk Kim return 0; 923e71b7053SJung-uk Kim 924e71b7053SJung-uk Kim if (!s->s3->in_read_app_data || (s->s3->total_renegotiations == 0)) 925e71b7053SJung-uk Kim return 0; 926e71b7053SJung-uk Kim 927e71b7053SJung-uk Kim if (s->server) { 928e71b7053SJung-uk Kim /* 929e71b7053SJung-uk Kim * If we're a server and we haven't got as far as writing our 930e71b7053SJung-uk Kim * ServerHello yet then we allow app data 931e71b7053SJung-uk Kim */ 932e71b7053SJung-uk Kim if (st->hand_state == TLS_ST_BEFORE 933e71b7053SJung-uk Kim || st->hand_state == TLS_ST_SR_CLNT_HELLO) 934e71b7053SJung-uk Kim return 1; 935e71b7053SJung-uk Kim } else { 936e71b7053SJung-uk Kim /* 937e71b7053SJung-uk Kim * If we're a client and we haven't read the ServerHello yet then we 938e71b7053SJung-uk Kim * allow app data 939e71b7053SJung-uk Kim */ 940e71b7053SJung-uk Kim if (st->hand_state == TLS_ST_CW_CLNT_HELLO) 941e71b7053SJung-uk Kim return 1; 942e71b7053SJung-uk Kim } 943e71b7053SJung-uk Kim 944e71b7053SJung-uk Kim return 0; 945e71b7053SJung-uk Kim } 946e71b7053SJung-uk Kim 947e71b7053SJung-uk Kim /* 948e71b7053SJung-uk Kim * This function returns 1 if TLS exporter is ready to export keying 949e71b7053SJung-uk Kim * material, or 0 if otherwise. 950e71b7053SJung-uk Kim */ 951e71b7053SJung-uk Kim int ossl_statem_export_allowed(SSL *s) 952e71b7053SJung-uk Kim { 953e71b7053SJung-uk Kim return s->s3->previous_server_finished_len != 0 954e71b7053SJung-uk Kim && s->statem.hand_state != TLS_ST_SW_FINISHED; 955e71b7053SJung-uk Kim } 956e71b7053SJung-uk Kim 957e71b7053SJung-uk Kim /* 958e71b7053SJung-uk Kim * Return 1 if early TLS exporter is ready to export keying material, 959e71b7053SJung-uk Kim * or 0 if otherwise. 960e71b7053SJung-uk Kim */ 961e71b7053SJung-uk Kim int ossl_statem_export_early_allowed(SSL *s) 962e71b7053SJung-uk Kim { 963e71b7053SJung-uk Kim /* 964e71b7053SJung-uk Kim * The early exporter secret is only present on the server if we 965e71b7053SJung-uk Kim * have accepted early_data. It is present on the client as long 966e71b7053SJung-uk Kim * as we have sent early_data. 967e71b7053SJung-uk Kim */ 968e71b7053SJung-uk Kim return s->ext.early_data == SSL_EARLY_DATA_ACCEPTED 969e71b7053SJung-uk Kim || (!s->server && s->ext.early_data != SSL_EARLY_DATA_NOT_SENT); 970e71b7053SJung-uk Kim } 971