1c7da899bSchristos /* 2*b0d17251Schristos * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. 3c7da899bSchristos * 4*b0d17251Schristos * Licensed under the Apache License 2.0 (the "License"). You may not use 5c7da899bSchristos * this file except in compliance with the License. You can obtain a copy 6c7da899bSchristos * in the file LICENSE in the source distribution or at 7c7da899bSchristos * https://www.openssl.org/source/license.html 8c7da899bSchristos */ 9c7da899bSchristos 10c7da899bSchristos /***************************************************************************** 11c7da899bSchristos * * 12c7da899bSchristos * These enums should be considered PRIVATE to the state machine. No * 13c7da899bSchristos * non-state machine code should need to use these * 14c7da899bSchristos * * 15c7da899bSchristos *****************************************************************************/ 16c7da899bSchristos /* 17c7da899bSchristos * Valid return codes used for functions performing work prior to or after 18c7da899bSchristos * sending or receiving a message 19c7da899bSchristos */ 20c7da899bSchristos typedef enum { 21c7da899bSchristos /* Something went wrong */ 22c7da899bSchristos WORK_ERROR, 23c7da899bSchristos /* We're done working and there shouldn't be anything else to do after */ 24c7da899bSchristos WORK_FINISHED_STOP, 25c7da899bSchristos /* We're done working move onto the next thing */ 26c7da899bSchristos WORK_FINISHED_CONTINUE, 27c7da899bSchristos /* We're working on phase A */ 28c7da899bSchristos WORK_MORE_A, 29c7da899bSchristos /* We're working on phase B */ 3013d40330Schristos WORK_MORE_B, 3113d40330Schristos /* We're working on phase C */ 3213d40330Schristos WORK_MORE_C 33c7da899bSchristos } WORK_STATE; 34c7da899bSchristos 35c7da899bSchristos /* Write transition return codes */ 36c7da899bSchristos typedef enum { 37c7da899bSchristos /* Something went wrong */ 38c7da899bSchristos WRITE_TRAN_ERROR, 39c7da899bSchristos /* A transition was successfully completed and we should continue */ 40c7da899bSchristos WRITE_TRAN_CONTINUE, 41c7da899bSchristos /* There is no more write work to be done */ 42c7da899bSchristos WRITE_TRAN_FINISHED 43c7da899bSchristos } WRITE_TRAN; 44c7da899bSchristos 45c7da899bSchristos /* Message flow states */ 46c7da899bSchristos typedef enum { 47c7da899bSchristos /* No handshake in progress */ 48c7da899bSchristos MSG_FLOW_UNINITED, 49c7da899bSchristos /* A permanent error with this connection */ 50c7da899bSchristos MSG_FLOW_ERROR, 51c7da899bSchristos /* We are reading messages */ 52c7da899bSchristos MSG_FLOW_READING, 53c7da899bSchristos /* We are writing messages */ 54c7da899bSchristos MSG_FLOW_WRITING, 55c7da899bSchristos /* Handshake has finished */ 56c7da899bSchristos MSG_FLOW_FINISHED 57c7da899bSchristos } MSG_FLOW_STATE; 58c7da899bSchristos 59c7da899bSchristos /* Read states */ 60c7da899bSchristos typedef enum { 61c7da899bSchristos READ_STATE_HEADER, 62c7da899bSchristos READ_STATE_BODY, 63c7da899bSchristos READ_STATE_POST_PROCESS 64c7da899bSchristos } READ_STATE; 65c7da899bSchristos 66c7da899bSchristos /* Write states */ 67c7da899bSchristos typedef enum { 68c7da899bSchristos WRITE_STATE_TRANSITION, 69c7da899bSchristos WRITE_STATE_PRE_WORK, 70c7da899bSchristos WRITE_STATE_SEND, 71c7da899bSchristos WRITE_STATE_POST_WORK 72c7da899bSchristos } WRITE_STATE; 73c7da899bSchristos 7413d40330Schristos typedef enum { 7513d40330Schristos /* The enc_write_ctx can be used normally */ 7613d40330Schristos ENC_WRITE_STATE_VALID, 7713d40330Schristos /* The enc_write_ctx cannot be used */ 7813d40330Schristos ENC_WRITE_STATE_INVALID, 7913d40330Schristos /* Write alerts in plaintext, but otherwise use the enc_write_ctx */ 8013d40330Schristos ENC_WRITE_STATE_WRITE_PLAIN_ALERTS 8113d40330Schristos } ENC_WRITE_STATES; 8213d40330Schristos 8313d40330Schristos typedef enum { 8413d40330Schristos /* The enc_read_ctx can be used normally */ 8513d40330Schristos ENC_READ_STATE_VALID, 8613d40330Schristos /* We may receive encrypted or plaintext alerts */ 8713d40330Schristos ENC_READ_STATE_ALLOW_PLAIN_ALERTS 8813d40330Schristos } ENC_READ_STATES; 8913d40330Schristos 90c7da899bSchristos /***************************************************************************** 91c7da899bSchristos * * 92c7da899bSchristos * This structure should be considered "opaque" to anything outside of the * 93c7da899bSchristos * state machine. No non-state machine code should be accessing the members * 94c7da899bSchristos * of this structure. * 95c7da899bSchristos * * 96c7da899bSchristos *****************************************************************************/ 97c7da899bSchristos 98c7da899bSchristos struct ossl_statem_st { 99c7da899bSchristos MSG_FLOW_STATE state; 100c7da899bSchristos WRITE_STATE write_state; 101c7da899bSchristos WORK_STATE write_state_work; 102c7da899bSchristos READ_STATE read_state; 103c7da899bSchristos WORK_STATE read_state_work; 104c7da899bSchristos OSSL_HANDSHAKE_STATE hand_state; 10513d40330Schristos /* The handshake state requested by an API call (e.g. HelloRequest) */ 10613d40330Schristos OSSL_HANDSHAKE_STATE request_state; 107c7da899bSchristos int in_init; 108c7da899bSchristos int read_state_first_init; 109c7da899bSchristos /* true when we are actually in SSL_accept() or SSL_connect() */ 110c7da899bSchristos int in_handshake; 11113d40330Schristos /* 11213d40330Schristos * True when are processing a "real" handshake that needs cleaning up (not 11313d40330Schristos * just a HelloRequest or similar). 11413d40330Schristos */ 11513d40330Schristos int cleanuphand; 116c7da899bSchristos /* Should we skip the CertificateVerify message? */ 117c7da899bSchristos unsigned int no_cert_verify; 118c7da899bSchristos int use_timer; 11913d40330Schristos ENC_WRITE_STATES enc_write_state; 12013d40330Schristos ENC_READ_STATES enc_read_state; 121c7da899bSchristos }; 122c7da899bSchristos typedef struct ossl_statem_st OSSL_STATEM; 123c7da899bSchristos 124c7da899bSchristos /***************************************************************************** 125c7da899bSchristos * * 126c7da899bSchristos * The following macros/functions represent the libssl internal API to the * 127c7da899bSchristos * state machine. Any libssl code may call these functions/macros * 128c7da899bSchristos * * 129c7da899bSchristos *****************************************************************************/ 130c7da899bSchristos 131c7da899bSchristos __owur int ossl_statem_accept(SSL *s); 132c7da899bSchristos __owur int ossl_statem_connect(SSL *s); 133c7da899bSchristos void ossl_statem_clear(SSL *s); 134c7da899bSchristos void ossl_statem_set_renegotiate(SSL *s); 135*b0d17251Schristos void ossl_statem_send_fatal(SSL *s, int al); 136*b0d17251Schristos void ossl_statem_fatal(SSL *s, int al, int reason, const char *fmt, ...); 13713d40330Schristos # define SSL_AD_NO_ALERT -1 138*b0d17251Schristos # define SSLfatal_alert(s, al) ossl_statem_send_fatal((s), (al)) 139*b0d17251Schristos # define SSLfatal(s, al, r) SSLfatal_data((s), (al), (r), NULL) 140*b0d17251Schristos # define SSLfatal_data \ 141*b0d17251Schristos (ERR_new(), \ 142*b0d17251Schristos ERR_set_debug(OPENSSL_FILE, OPENSSL_LINE, OPENSSL_FUNC), \ 143*b0d17251Schristos ossl_statem_fatal) 14413d40330Schristos 145c7da899bSchristos int ossl_statem_in_error(const SSL *s); 146c7da899bSchristos void ossl_statem_set_in_init(SSL *s, int init); 147c7da899bSchristos int ossl_statem_get_in_handshake(SSL *s); 148c7da899bSchristos void ossl_statem_set_in_handshake(SSL *s, int inhand); 14913d40330Schristos __owur int ossl_statem_skip_early_data(SSL *s); 15013d40330Schristos void ossl_statem_check_finish_init(SSL *s, int send); 151c7da899bSchristos void ossl_statem_set_hello_verify_done(SSL *s); 152c7da899bSchristos __owur int ossl_statem_app_data_allowed(SSL *s); 15313d40330Schristos __owur int ossl_statem_export_allowed(SSL *s); 15413d40330Schristos __owur int ossl_statem_export_early_allowed(SSL *s); 15513d40330Schristos 15613d40330Schristos /* Flush the write BIO */ 15713d40330Schristos int statem_flush(SSL *s); 158