| 
									
										
										
										
											2016-05-18 02:18:30 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2023-09-07 16:59:15 +08:00
										 |  |  |  * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-12-06 20:08:51 +08:00
										 |  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							| 
									
										
										
										
											2016-05-18 02:18:30 +08:00
										 |  |  |  * this file except in compliance with the License.  You can obtain a copy | 
					
						
							|  |  |  |  * in the file LICENSE in the source distribution or at | 
					
						
							|  |  |  |  * https://www.openssl.org/source/license.html
 | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-06-29 20:48:57 +08:00
										 |  |  | #ifndef OSSL_INTERNAL_STATEM_H
 | 
					
						
							|  |  |  | # define OSSL_INTERNAL_STATEM_H
 | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  *                                                                           * | 
					
						
							| 
									
										
										
										
											2016-03-11 04:34:48 +08:00
										 |  |  |  * These enums should be considered PRIVATE to the state machine. No         * | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  |  * non-state machine code should need to use these                           * | 
					
						
							|  |  |  |  *                                                                           * | 
					
						
							|  |  |  |  *****************************************************************************/ | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Valid return codes used for functions performing work prior to or after | 
					
						
							|  |  |  |  * sending or receiving a message | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-10-26 19:46:33 +08:00
										 |  |  | typedef enum { | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  |     /* Something went wrong */ | 
					
						
							|  |  |  |     WORK_ERROR, | 
					
						
							|  |  |  |     /* We're done working and there shouldn't be anything else to do after */ | 
					
						
							|  |  |  |     WORK_FINISHED_STOP, | 
					
						
							|  |  |  |     /* We're done working move onto the next thing */ | 
					
						
							|  |  |  |     WORK_FINISHED_CONTINUE, | 
					
						
							|  |  |  |     /* We're working on phase A */ | 
					
						
							|  |  |  |     WORK_MORE_A, | 
					
						
							|  |  |  |     /* We're working on phase B */ | 
					
						
							| 
									
										
										
										
											2017-02-07 05:33:28 +08:00
										 |  |  |     WORK_MORE_B, | 
					
						
							|  |  |  |     /* We're working on phase C */ | 
					
						
							|  |  |  |     WORK_MORE_C | 
					
						
							| 
									
										
										
										
											2015-10-26 19:46:33 +08:00
										 |  |  | } WORK_STATE; | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Write transition return codes */ | 
					
						
							| 
									
										
										
										
											2015-10-26 19:46:33 +08:00
										 |  |  | typedef enum { | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  |     /* Something went wrong */ | 
					
						
							|  |  |  |     WRITE_TRAN_ERROR, | 
					
						
							|  |  |  |     /* A transition was successfully completed and we should continue */ | 
					
						
							|  |  |  |     WRITE_TRAN_CONTINUE, | 
					
						
							|  |  |  |     /* There is no more write work to be done */ | 
					
						
							|  |  |  |     WRITE_TRAN_FINISHED | 
					
						
							| 
									
										
										
										
											2015-10-26 19:46:33 +08:00
										 |  |  | } WRITE_TRAN; | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Message flow states */ | 
					
						
							| 
									
										
										
										
											2015-10-26 19:46:33 +08:00
										 |  |  | typedef enum { | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  |     /* No handshake in progress */ | 
					
						
							|  |  |  |     MSG_FLOW_UNINITED, | 
					
						
							|  |  |  |     /* A permanent error with this connection */ | 
					
						
							|  |  |  |     MSG_FLOW_ERROR, | 
					
						
							|  |  |  |     /* We are reading messages */ | 
					
						
							|  |  |  |     MSG_FLOW_READING, | 
					
						
							|  |  |  |     /* We are writing messages */ | 
					
						
							|  |  |  |     MSG_FLOW_WRITING, | 
					
						
							|  |  |  |     /* Handshake has finished */ | 
					
						
							|  |  |  |     MSG_FLOW_FINISHED | 
					
						
							| 
									
										
										
										
											2015-10-26 19:46:33 +08:00
										 |  |  | } MSG_FLOW_STATE; | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Read states */ | 
					
						
							| 
									
										
										
										
											2015-10-26 19:46:33 +08:00
										 |  |  | typedef enum { | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  |     READ_STATE_HEADER, | 
					
						
							|  |  |  |     READ_STATE_BODY, | 
					
						
							|  |  |  |     READ_STATE_POST_PROCESS | 
					
						
							| 
									
										
										
										
											2015-10-26 19:46:33 +08:00
										 |  |  | } READ_STATE; | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Write states */ | 
					
						
							| 
									
										
										
										
											2015-10-26 19:46:33 +08:00
										 |  |  | typedef enum { | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  |     WRITE_STATE_TRANSITION, | 
					
						
							|  |  |  |     WRITE_STATE_PRE_WORK, | 
					
						
							|  |  |  |     WRITE_STATE_SEND, | 
					
						
							|  |  |  |     WRITE_STATE_POST_WORK | 
					
						
							| 
									
										
										
										
											2015-10-26 19:46:33 +08:00
										 |  |  | } WRITE_STATE; | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-12 20:27:21 +08:00
										 |  |  | typedef enum { | 
					
						
							|  |  |  |     CON_FUNC_ERROR = 0, | 
					
						
							|  |  |  |     CON_FUNC_SUCCESS, | 
					
						
							|  |  |  |     CON_FUNC_DONT_SEND | 
					
						
							|  |  |  | } CON_FUNC_RETURN; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-02 23:52:21 +08:00
										 |  |  | typedef int (*ossl_statem_mutate_handshake_cb)(const unsigned char *msgin, | 
					
						
							| 
									
										
										
										
											2022-12-02 22:38:46 +08:00
										 |  |  |                                                size_t inlen, | 
					
						
							|  |  |  |                                                unsigned char **msgout, | 
					
						
							|  |  |  |                                                size_t *outlen, | 
					
						
							|  |  |  |                                                void *arg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef void (*ossl_statem_finish_mutate_handshake_cb)(void *arg); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  *                                                                           * | 
					
						
							|  |  |  |  * This structure should be considered "opaque" to anything outside of the   * | 
					
						
							|  |  |  |  * state machine. No non-state machine code should be accessing the members  * | 
					
						
							|  |  |  |  * of this structure.                                                        * | 
					
						
							|  |  |  |  *                                                                           * | 
					
						
							|  |  |  |  *****************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-05 17:58:52 +08:00
										 |  |  | struct ossl_statem_st { | 
					
						
							| 
									
										
										
										
											2015-10-26 19:46:33 +08:00
										 |  |  |     MSG_FLOW_STATE state; | 
					
						
							|  |  |  |     WRITE_STATE write_state; | 
					
						
							|  |  |  |     WORK_STATE write_state_work; | 
					
						
							|  |  |  |     READ_STATE read_state; | 
					
						
							|  |  |  |     WORK_STATE read_state_work; | 
					
						
							| 
									
										
										
										
											2015-10-05 17:18:06 +08:00
										 |  |  |     OSSL_HANDSHAKE_STATE hand_state; | 
					
						
							| 
									
										
										
										
											2017-01-10 22:58:17 +08:00
										 |  |  |     /* The handshake state requested by an API call (e.g. HelloRequest) */ | 
					
						
							|  |  |  |     OSSL_HANDSHAKE_STATE request_state; | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  |     int in_init; | 
					
						
							|  |  |  |     int read_state_first_init; | 
					
						
							| 
									
										
										
										
											2015-10-22 20:57:18 +08:00
										 |  |  |     /* true when we are actually in SSL_accept() or SSL_connect() */ | 
					
						
							|  |  |  |     int in_handshake; | 
					
						
							| 
									
										
										
										
											2017-01-11 07:02:28 +08:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * True when are processing a "real" handshake that needs cleaning up (not | 
					
						
							|  |  |  |      * just a HelloRequest or similar). | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     int cleanuphand; | 
					
						
							| 
									
										
										
										
											2015-10-05 17:44:41 +08:00
										 |  |  |     /* Should we skip the CertificateVerify message? */ | 
					
						
							|  |  |  |     unsigned int no_cert_verify; | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  |     int use_timer; | 
					
						
							| 
									
										
										
										
											2022-12-02 22:38:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Test harness message mutator callbacks */ | 
					
						
							|  |  |  |     ossl_statem_mutate_handshake_cb mutate_handshake_cb; | 
					
						
							|  |  |  |     ossl_statem_finish_mutate_handshake_cb finish_mutate_handshake_cb; | 
					
						
							|  |  |  |     void *mutatearg; | 
					
						
							|  |  |  |     unsigned int write_in_progress : 1; | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2015-10-05 17:58:52 +08:00
										 |  |  | typedef struct ossl_statem_st OSSL_STATEM; | 
					
						
							| 
									
										
										
										
											2015-09-11 17:48:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |  *                                                                           * | 
					
						
							|  |  |  |  * The following macros/functions represent the libssl internal API to the   * | 
					
						
							|  |  |  |  * state machine. Any libssl code may call these functions/macros            * | 
					
						
							|  |  |  |  *                                                                           * | 
					
						
							|  |  |  |  *****************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-02 22:38:46 +08:00
										 |  |  | typedef struct ssl_connection_st SSL_CONNECTION; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-05 17:39:54 +08:00
										 |  |  | __owur int ossl_statem_accept(SSL *s); | 
					
						
							|  |  |  | __owur int ossl_statem_connect(SSL *s); | 
					
						
							| 
									
										
										
										
											2022-10-12 14:03:08 +08:00
										 |  |  | OSSL_HANDSHAKE_STATE ossl_statem_get_state(SSL_CONNECTION *s); | 
					
						
							| 
									
										
										
										
											2022-06-20 23:11:28 +08:00
										 |  |  | void ossl_statem_clear(SSL_CONNECTION *s); | 
					
						
							|  |  |  | void ossl_statem_set_renegotiate(SSL_CONNECTION *s); | 
					
						
							|  |  |  | void ossl_statem_send_fatal(SSL_CONNECTION *s, int al); | 
					
						
							|  |  |  | void ossl_statem_fatal(SSL_CONNECTION *s, int al, int reason, | 
					
						
							|  |  |  |                        const char *fmt, ...); | 
					
						
							| 
									
										
										
										
											2020-11-21 06:07:56 +08:00
										 |  |  | # define SSLfatal_alert(s, al) ossl_statem_send_fatal((s), (al))
 | 
					
						
							| 
									
										
										
										
											2020-11-04 21:36:38 +08:00
										 |  |  | # define SSLfatal(s, al, r) SSLfatal_data((s), (al), (r), NULL)
 | 
					
						
							|  |  |  | # define SSLfatal_data                                          \
 | 
					
						
							|  |  |  |     (ERR_new(),                                                 \ | 
					
						
							|  |  |  |      ERR_set_debug(OPENSSL_FILE, OPENSSL_LINE, OPENSSL_FUNC),   \ | 
					
						
							|  |  |  |      ossl_statem_fatal) | 
					
						
							| 
									
										
										
										
											2017-11-24 00:21:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-20 23:11:28 +08:00
										 |  |  | int ossl_statem_in_error(const SSL_CONNECTION *s); | 
					
						
							|  |  |  | void ossl_statem_set_in_init(SSL_CONNECTION *s, int init); | 
					
						
							|  |  |  | int ossl_statem_get_in_handshake(SSL_CONNECTION *s); | 
					
						
							|  |  |  | void ossl_statem_set_in_handshake(SSL_CONNECTION *s, int inhand); | 
					
						
							|  |  |  | __owur int ossl_statem_skip_early_data(SSL_CONNECTION *s); | 
					
						
							|  |  |  | void ossl_statem_check_finish_init(SSL_CONNECTION *s, int send); | 
					
						
							|  |  |  | void ossl_statem_set_hello_verify_done(SSL_CONNECTION *s); | 
					
						
							|  |  |  | __owur int ossl_statem_app_data_allowed(SSL_CONNECTION *s); | 
					
						
							|  |  |  | __owur int ossl_statem_export_allowed(SSL_CONNECTION *s); | 
					
						
							|  |  |  | __owur int ossl_statem_export_early_allowed(SSL_CONNECTION *s); | 
					
						
							| 
									
										
										
										
											2017-11-27 23:20:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Flush the write BIO */ | 
					
						
							| 
									
										
										
										
											2022-06-20 23:11:28 +08:00
										 |  |  | int statem_flush(SSL_CONNECTION *s); | 
					
						
							| 
									
										
										
										
											2022-12-02 22:38:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | int ossl_statem_set_mutator(SSL *s, | 
					
						
							|  |  |  |                             ossl_statem_mutate_handshake_cb mutate_handshake_cb, | 
					
						
							|  |  |  |                             ossl_statem_finish_mutate_handshake_cb finish_mutate_handshake_cb, | 
					
						
							|  |  |  |                             void *mutatearg); | 
					
						
							| 
									
										
										
										
											2023-06-26 20:47:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif
 |