xref: /netbsd-src/crypto/external/bsd/openssl/dist/ssl/statem/statem.h (revision b0d1725196a7921d003d2c66a14f186abda4176b)
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