1e71b7053SJung-uk Kim /* 2*b077aed3SPierre Pronchery * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. 3e71b7053SJung-uk Kim * 4*b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (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 /***************************************************************************** 11e71b7053SJung-uk Kim * * 12e71b7053SJung-uk Kim * These enums should be considered PRIVATE to the state machine. No * 13e71b7053SJung-uk Kim * non-state machine code should need to use these * 14e71b7053SJung-uk Kim * * 15e71b7053SJung-uk Kim *****************************************************************************/ 16e71b7053SJung-uk Kim /* 17e71b7053SJung-uk Kim * Valid return codes used for functions performing work prior to or after 18e71b7053SJung-uk Kim * sending or receiving a message 19e71b7053SJung-uk Kim */ 20e71b7053SJung-uk Kim typedef enum { 21e71b7053SJung-uk Kim /* Something went wrong */ 22e71b7053SJung-uk Kim WORK_ERROR, 23e71b7053SJung-uk Kim /* We're done working and there shouldn't be anything else to do after */ 24e71b7053SJung-uk Kim WORK_FINISHED_STOP, 25e71b7053SJung-uk Kim /* We're done working move onto the next thing */ 26e71b7053SJung-uk Kim WORK_FINISHED_CONTINUE, 27e71b7053SJung-uk Kim /* We're working on phase A */ 28e71b7053SJung-uk Kim WORK_MORE_A, 29e71b7053SJung-uk Kim /* We're working on phase B */ 30e71b7053SJung-uk Kim WORK_MORE_B, 31e71b7053SJung-uk Kim /* We're working on phase C */ 32e71b7053SJung-uk Kim WORK_MORE_C 33e71b7053SJung-uk Kim } WORK_STATE; 34e71b7053SJung-uk Kim 35e71b7053SJung-uk Kim /* Write transition return codes */ 36e71b7053SJung-uk Kim typedef enum { 37e71b7053SJung-uk Kim /* Something went wrong */ 38e71b7053SJung-uk Kim WRITE_TRAN_ERROR, 39e71b7053SJung-uk Kim /* A transition was successfully completed and we should continue */ 40e71b7053SJung-uk Kim WRITE_TRAN_CONTINUE, 41e71b7053SJung-uk Kim /* There is no more write work to be done */ 42e71b7053SJung-uk Kim WRITE_TRAN_FINISHED 43e71b7053SJung-uk Kim } WRITE_TRAN; 44e71b7053SJung-uk Kim 45e71b7053SJung-uk Kim /* Message flow states */ 46e71b7053SJung-uk Kim typedef enum { 47e71b7053SJung-uk Kim /* No handshake in progress */ 48e71b7053SJung-uk Kim MSG_FLOW_UNINITED, 49e71b7053SJung-uk Kim /* A permanent error with this connection */ 50e71b7053SJung-uk Kim MSG_FLOW_ERROR, 51e71b7053SJung-uk Kim /* We are reading messages */ 52e71b7053SJung-uk Kim MSG_FLOW_READING, 53e71b7053SJung-uk Kim /* We are writing messages */ 54e71b7053SJung-uk Kim MSG_FLOW_WRITING, 55e71b7053SJung-uk Kim /* Handshake has finished */ 56e71b7053SJung-uk Kim MSG_FLOW_FINISHED 57e71b7053SJung-uk Kim } MSG_FLOW_STATE; 58e71b7053SJung-uk Kim 59e71b7053SJung-uk Kim /* Read states */ 60e71b7053SJung-uk Kim typedef enum { 61e71b7053SJung-uk Kim READ_STATE_HEADER, 62e71b7053SJung-uk Kim READ_STATE_BODY, 63e71b7053SJung-uk Kim READ_STATE_POST_PROCESS 64e71b7053SJung-uk Kim } READ_STATE; 65e71b7053SJung-uk Kim 66e71b7053SJung-uk Kim /* Write states */ 67e71b7053SJung-uk Kim typedef enum { 68e71b7053SJung-uk Kim WRITE_STATE_TRANSITION, 69e71b7053SJung-uk Kim WRITE_STATE_PRE_WORK, 70e71b7053SJung-uk Kim WRITE_STATE_SEND, 71e71b7053SJung-uk Kim WRITE_STATE_POST_WORK 72e71b7053SJung-uk Kim } WRITE_STATE; 73e71b7053SJung-uk Kim 74e71b7053SJung-uk Kim typedef enum { 75e71b7053SJung-uk Kim /* The enc_write_ctx can be used normally */ 76e71b7053SJung-uk Kim ENC_WRITE_STATE_VALID, 77e71b7053SJung-uk Kim /* The enc_write_ctx cannot be used */ 78e71b7053SJung-uk Kim ENC_WRITE_STATE_INVALID, 79e71b7053SJung-uk Kim /* Write alerts in plaintext, but otherwise use the enc_write_ctx */ 80e71b7053SJung-uk Kim ENC_WRITE_STATE_WRITE_PLAIN_ALERTS 81e71b7053SJung-uk Kim } ENC_WRITE_STATES; 82e71b7053SJung-uk Kim 83e71b7053SJung-uk Kim typedef enum { 84e71b7053SJung-uk Kim /* The enc_read_ctx can be used normally */ 85e71b7053SJung-uk Kim ENC_READ_STATE_VALID, 86e71b7053SJung-uk Kim /* We may receive encrypted or plaintext alerts */ 87e71b7053SJung-uk Kim ENC_READ_STATE_ALLOW_PLAIN_ALERTS 88e71b7053SJung-uk Kim } ENC_READ_STATES; 89e71b7053SJung-uk Kim 90e71b7053SJung-uk Kim /***************************************************************************** 91e71b7053SJung-uk Kim * * 92e71b7053SJung-uk Kim * This structure should be considered "opaque" to anything outside of the * 93e71b7053SJung-uk Kim * state machine. No non-state machine code should be accessing the members * 94e71b7053SJung-uk Kim * of this structure. * 95e71b7053SJung-uk Kim * * 96e71b7053SJung-uk Kim *****************************************************************************/ 97e71b7053SJung-uk Kim 98e71b7053SJung-uk Kim struct ossl_statem_st { 99e71b7053SJung-uk Kim MSG_FLOW_STATE state; 100e71b7053SJung-uk Kim WRITE_STATE write_state; 101e71b7053SJung-uk Kim WORK_STATE write_state_work; 102e71b7053SJung-uk Kim READ_STATE read_state; 103e71b7053SJung-uk Kim WORK_STATE read_state_work; 104e71b7053SJung-uk Kim OSSL_HANDSHAKE_STATE hand_state; 105e71b7053SJung-uk Kim /* The handshake state requested by an API call (e.g. HelloRequest) */ 106e71b7053SJung-uk Kim OSSL_HANDSHAKE_STATE request_state; 107e71b7053SJung-uk Kim int in_init; 108e71b7053SJung-uk Kim int read_state_first_init; 109e71b7053SJung-uk Kim /* true when we are actually in SSL_accept() or SSL_connect() */ 110e71b7053SJung-uk Kim int in_handshake; 111e71b7053SJung-uk Kim /* 112e71b7053SJung-uk Kim * True when are processing a "real" handshake that needs cleaning up (not 113e71b7053SJung-uk Kim * just a HelloRequest or similar). 114e71b7053SJung-uk Kim */ 115e71b7053SJung-uk Kim int cleanuphand; 116e71b7053SJung-uk Kim /* Should we skip the CertificateVerify message? */ 117e71b7053SJung-uk Kim unsigned int no_cert_verify; 118e71b7053SJung-uk Kim int use_timer; 119e71b7053SJung-uk Kim ENC_WRITE_STATES enc_write_state; 120e71b7053SJung-uk Kim ENC_READ_STATES enc_read_state; 121e71b7053SJung-uk Kim }; 122e71b7053SJung-uk Kim typedef struct ossl_statem_st OSSL_STATEM; 123e71b7053SJung-uk Kim 124e71b7053SJung-uk Kim /***************************************************************************** 125e71b7053SJung-uk Kim * * 126e71b7053SJung-uk Kim * The following macros/functions represent the libssl internal API to the * 127e71b7053SJung-uk Kim * state machine. Any libssl code may call these functions/macros * 128e71b7053SJung-uk Kim * * 129e71b7053SJung-uk Kim *****************************************************************************/ 130e71b7053SJung-uk Kim 131e71b7053SJung-uk Kim __owur int ossl_statem_accept(SSL *s); 132e71b7053SJung-uk Kim __owur int ossl_statem_connect(SSL *s); 133e71b7053SJung-uk Kim void ossl_statem_clear(SSL *s); 134e71b7053SJung-uk Kim void ossl_statem_set_renegotiate(SSL *s); 135*b077aed3SPierre Pronchery void ossl_statem_send_fatal(SSL *s, int al); 136*b077aed3SPierre Pronchery void ossl_statem_fatal(SSL *s, int al, int reason, const char *fmt, ...); 137e71b7053SJung-uk Kim # define SSL_AD_NO_ALERT -1 138*b077aed3SPierre Pronchery # define SSLfatal_alert(s, al) ossl_statem_send_fatal((s), (al)) 139*b077aed3SPierre Pronchery # define SSLfatal(s, al, r) SSLfatal_data((s), (al), (r), NULL) 140*b077aed3SPierre Pronchery # define SSLfatal_data \ 141*b077aed3SPierre Pronchery (ERR_new(), \ 142*b077aed3SPierre Pronchery ERR_set_debug(OPENSSL_FILE, OPENSSL_LINE, OPENSSL_FUNC), \ 143*b077aed3SPierre Pronchery ossl_statem_fatal) 144e71b7053SJung-uk Kim 145e71b7053SJung-uk Kim int ossl_statem_in_error(const SSL *s); 146e71b7053SJung-uk Kim void ossl_statem_set_in_init(SSL *s, int init); 147e71b7053SJung-uk Kim int ossl_statem_get_in_handshake(SSL *s); 148e71b7053SJung-uk Kim void ossl_statem_set_in_handshake(SSL *s, int inhand); 149e71b7053SJung-uk Kim __owur int ossl_statem_skip_early_data(SSL *s); 150e71b7053SJung-uk Kim void ossl_statem_check_finish_init(SSL *s, int send); 151e71b7053SJung-uk Kim void ossl_statem_set_hello_verify_done(SSL *s); 152e71b7053SJung-uk Kim __owur int ossl_statem_app_data_allowed(SSL *s); 153e71b7053SJung-uk Kim __owur int ossl_statem_export_allowed(SSL *s); 154e71b7053SJung-uk Kim __owur int ossl_statem_export_early_allowed(SSL *s); 155e71b7053SJung-uk Kim 156e71b7053SJung-uk Kim /* Flush the write BIO */ 157e71b7053SJung-uk Kim int statem_flush(SSL *s); 158