LCOV - code coverage report
Current view: top level - tls - s2n_handshake_io.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 532 540 98.5 %
Date: 2025-12-31 08:28:16 Functions: 27 29 93.1 %
Branches: 549 792 69.3 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License").
       5                 :            :  * You may not use this file except in compliance with the License.
       6                 :            :  * A copy of the License is located at
       7                 :            :  *
       8                 :            :  *  http://aws.amazon.com/apache2.0
       9                 :            :  *
      10                 :            :  * or in the "license" file accompanying this file. This file is distributed
      11                 :            :  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
      12                 :            :  * express or implied. See the License for the specific language governing
      13                 :            :  * permissions and limitations under the License.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include <errno.h>
      17                 :            : #include <sys/param.h>
      18                 :            : 
      19                 :            : #include "api/s2n.h"
      20                 :            : #include "crypto/s2n_fips.h"
      21                 :            : #include "error/s2n_errno.h"
      22                 :            : #include "stuffer/s2n_stuffer.h"
      23                 :            : #include "tls/s2n_alerts.h"
      24                 :            : #include "tls/s2n_async_pkey.h"
      25                 :            : #include "tls/s2n_cipher_suites.h"
      26                 :            : #include "tls/s2n_connection.h"
      27                 :            : #include "tls/s2n_kex.h"
      28                 :            : #include "tls/s2n_post_handshake.h"
      29                 :            : #include "tls/s2n_record.h"
      30                 :            : #include "tls/s2n_resume.h"
      31                 :            : #include "tls/s2n_tls.h"
      32                 :            : #include "tls/s2n_tls13.h"
      33                 :            : #include "tls/s2n_tls13_handshake.h"
      34                 :            : #include "tls/s2n_tls13_key_schedule.h"
      35                 :            : #include "utils/s2n_bitmap.h"
      36                 :            : #include "utils/s2n_events.h"
      37                 :            : #include "utils/s2n_random.h"
      38                 :            : #include "utils/s2n_safety.h"
      39                 :            : #include "utils/s2n_socket.h"
      40                 :            : 
      41                 :            : /* clang-format off */
      42                 :            : struct s2n_handshake_action {
      43                 :            :     uint8_t record_type;
      44                 :            :     uint8_t message_type;
      45                 :            :     char writer;                /* 'S' or 'C' for server or client, 'B' for both */
      46                 :            :     int (*handler[2]) (struct s2n_connection * conn);
      47                 :            : };
      48                 :            : 
      49                 :            : static int s2n_always_fail_send(struct s2n_connection *conn)
      50                 :          0 : {
      51                 :            :     /* This state should never be sending a handshake message. */
      52         [ #  # ]:          0 :     POSIX_BAIL(S2N_ERR_HANDSHAKE_UNREACHABLE);
      53                 :          0 : }
      54                 :            : 
      55                 :            : static int s2n_always_fail_recv(struct s2n_connection *conn)
      56                 :          0 : {
      57                 :            :     /* This state should never have an incoming handshake message. */
      58         [ #  # ]:          0 :     POSIX_BAIL(S2N_ERR_HANDSHAKE_UNREACHABLE);
      59                 :          0 : }
      60                 :            : 
      61                 :            : /* Client and Server handlers for each message type we support.
      62                 :            :  * See http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-7 for the list of handshake message types
      63                 :            :  */
      64                 :            : static struct s2n_handshake_action state_machine[] = {
      65                 :            :     /* message_type_t           = {Record type   Message type     Writer S2N_SERVER                S2N_CLIENT }  */
      66                 :            :     [CLIENT_HELLO]              = {TLS_HANDSHAKE, TLS_CLIENT_HELLO, 'C', {s2n_establish_session, s2n_client_hello_send}},
      67                 :            :     [SERVER_HELLO]              = {TLS_HANDSHAKE, TLS_SERVER_HELLO, 'S', {s2n_server_hello_send, s2n_server_hello_recv}},
      68                 :            :     [SERVER_NEW_SESSION_TICKET] = {TLS_HANDSHAKE, TLS_SERVER_NEW_SESSION_TICKET,'S', {s2n_server_nst_send, s2n_server_nst_recv}},
      69                 :            :     [SERVER_CERT]               = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'S', {s2n_server_cert_send, s2n_server_cert_recv}},
      70                 :            :     [SERVER_CERT_STATUS]        = {TLS_HANDSHAKE, TLS_SERVER_CERT_STATUS, 'S', {s2n_server_status_send, s2n_server_status_recv}},
      71                 :            :     [SERVER_KEY]                = {TLS_HANDSHAKE, TLS_SERVER_KEY, 'S', {s2n_server_key_send, s2n_server_key_recv}},
      72                 :            :     [SERVER_CERT_REQ]           = {TLS_HANDSHAKE, TLS_CERT_REQ, 'S', {s2n_cert_req_send, s2n_cert_req_recv}},
      73                 :            :     [SERVER_HELLO_DONE]         = {TLS_HANDSHAKE, TLS_SERVER_HELLO_DONE, 'S', {s2n_server_done_send, s2n_server_done_recv}},
      74                 :            :     [CLIENT_CERT]               = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'C', {s2n_client_cert_recv, s2n_client_cert_send}},
      75                 :            :     [CLIENT_KEY]                = {TLS_HANDSHAKE, TLS_CLIENT_KEY, 'C', {s2n_client_key_recv, s2n_client_key_send}},
      76                 :            :     [CLIENT_CERT_VERIFY]        = {TLS_HANDSHAKE, TLS_CERT_VERIFY, 'C', {s2n_client_cert_verify_recv, s2n_client_cert_verify_send}},
      77                 :            :     [CLIENT_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'C', {s2n_client_ccs_recv, s2n_ccs_send}},
      78                 :            :     [CLIENT_NPN]                = {TLS_HANDSHAKE, TLS_NPN, 'C', {s2n_next_protocol_recv, s2n_next_protocol_send}},
      79                 :            :     [CLIENT_FINISHED]           = {TLS_HANDSHAKE, TLS_FINISHED, 'C', {s2n_client_finished_recv, s2n_client_finished_send}},
      80                 :            :     [SERVER_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'S', {s2n_ccs_send, s2n_server_ccs_recv}},
      81                 :            :     [SERVER_FINISHED]           = {TLS_HANDSHAKE, TLS_FINISHED, 'S', {s2n_server_finished_send, s2n_server_finished_recv}},
      82                 :            :     [APPLICATION_DATA]          = {TLS_APPLICATION_DATA, 0, 'B', {s2n_always_fail_send, s2n_always_fail_recv}},
      83                 :            : };
      84                 :            : 
      85                 :            : /*
      86                 :            :  * Client and Server handlers for TLS1.3.
      87                 :            :  */
      88                 :            : static struct s2n_handshake_action tls13_state_machine[] = {
      89                 :            :     /* message_type_t           = {Record type, Message type, Writer, {Server handler, client handler} }  */
      90                 :            :     [CLIENT_HELLO]              = {TLS_HANDSHAKE, TLS_CLIENT_HELLO, 'C', {s2n_establish_session, s2n_client_hello_send}},
      91                 :            :     [SERVER_HELLO]              = {TLS_HANDSHAKE, TLS_SERVER_HELLO, 'S', {s2n_server_hello_send, s2n_server_hello_recv}},
      92                 :            :     [HELLO_RETRY_MSG]           = {TLS_HANDSHAKE, TLS_SERVER_HELLO, 'S', {s2n_server_hello_retry_send, s2n_server_hello_retry_recv}},
      93                 :            :     [ENCRYPTED_EXTENSIONS]      = {TLS_HANDSHAKE, TLS_ENCRYPTED_EXTENSIONS, 'S', {s2n_encrypted_extensions_send, s2n_encrypted_extensions_recv}},
      94                 :            :     [SERVER_CERT_REQ]           = {TLS_HANDSHAKE, TLS_CERT_REQ, 'S', {s2n_tls13_cert_req_send, s2n_tls13_cert_req_recv}},
      95                 :            :     [SERVER_CERT]               = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'S', {s2n_server_cert_send, s2n_server_cert_recv}},
      96                 :            :     [SERVER_CERT_VERIFY]        = {TLS_HANDSHAKE, TLS_CERT_VERIFY, 'S', {s2n_tls13_cert_verify_send, s2n_tls13_cert_verify_recv}},
      97                 :            :     [SERVER_FINISHED]           = {TLS_HANDSHAKE, TLS_FINISHED, 'S', {s2n_tls13_server_finished_send, s2n_tls13_server_finished_recv}},
      98                 :            : 
      99                 :            :     [CLIENT_CERT]               = {TLS_HANDSHAKE, TLS_CERTIFICATE, 'C', {s2n_client_cert_recv, s2n_client_cert_send}},
     100                 :            :     [CLIENT_CERT_VERIFY]        = {TLS_HANDSHAKE, TLS_CERT_VERIFY, 'C', {s2n_tls13_cert_verify_recv, s2n_tls13_cert_verify_send}},
     101                 :            :     [CLIENT_FINISHED]           = {TLS_HANDSHAKE, TLS_FINISHED, 'C', {s2n_tls13_client_finished_recv, s2n_tls13_client_finished_send}},
     102                 :            :     [END_OF_EARLY_DATA]         = {TLS_HANDSHAKE, TLS_END_OF_EARLY_DATA, 'C', {s2n_end_of_early_data_recv, s2n_end_of_early_data_send}},
     103                 :            : 
     104                 :            :     /* Not used by TLS1.3, except to maintain middlebox compatibility */
     105                 :            :     [CLIENT_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'C', {s2n_basic_ccs_recv, s2n_ccs_send}},
     106                 :            :     [SERVER_CHANGE_CIPHER_SPEC] = {TLS_CHANGE_CIPHER_SPEC, 0, 'S', {s2n_ccs_send, s2n_basic_ccs_recv}},
     107                 :            : 
     108                 :            :     [APPLICATION_DATA]          = {TLS_APPLICATION_DATA, 0, 'B', {s2n_always_fail_send, s2n_always_fail_recv}},
     109                 :            : };
     110                 :            : 
     111                 :            : #define MESSAGE_NAME_ENTRY(msg) [msg] = #msg
     112                 :            : 
     113                 :            : static const char *message_names[] = {
     114                 :            :     MESSAGE_NAME_ENTRY(CLIENT_HELLO),
     115                 :            :     MESSAGE_NAME_ENTRY(SERVER_HELLO),
     116                 :            :     MESSAGE_NAME_ENTRY(ENCRYPTED_EXTENSIONS),
     117                 :            :     MESSAGE_NAME_ENTRY(SERVER_NEW_SESSION_TICKET),
     118                 :            :     MESSAGE_NAME_ENTRY(SERVER_CERT),
     119                 :            :     MESSAGE_NAME_ENTRY(SERVER_CERT_STATUS),
     120                 :            :     MESSAGE_NAME_ENTRY(SERVER_CERT_VERIFY),
     121                 :            :     MESSAGE_NAME_ENTRY(SERVER_KEY),
     122                 :            :     MESSAGE_NAME_ENTRY(SERVER_CERT_REQ),
     123                 :            :     MESSAGE_NAME_ENTRY(SERVER_HELLO_DONE),
     124                 :            :     MESSAGE_NAME_ENTRY(CLIENT_CERT),
     125                 :            :     MESSAGE_NAME_ENTRY(CLIENT_KEY),
     126                 :            :     MESSAGE_NAME_ENTRY(CLIENT_CERT_VERIFY),
     127                 :            :     MESSAGE_NAME_ENTRY(CLIENT_CHANGE_CIPHER_SPEC),
     128                 :            :     MESSAGE_NAME_ENTRY(CLIENT_FINISHED),
     129                 :            :     MESSAGE_NAME_ENTRY(SERVER_CHANGE_CIPHER_SPEC),
     130                 :            :     MESSAGE_NAME_ENTRY(SERVER_FINISHED),
     131                 :            :     MESSAGE_NAME_ENTRY(HELLO_RETRY_MSG),
     132                 :            :     MESSAGE_NAME_ENTRY(END_OF_EARLY_DATA),
     133                 :            :     MESSAGE_NAME_ENTRY(APPLICATION_DATA),
     134                 :            :     MESSAGE_NAME_ENTRY(CLIENT_NPN),
     135                 :            : };
     136                 :            : 
     137                 :            : /* We support different ordering of TLS Handshake messages, depending on what is being negotiated. There's also a dummy "INITIAL" handshake
     138                 :            :  * that everything starts out as until we know better.
     139                 :            :  */
     140                 :            : 
     141                 :            : static message_type_t handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] = {
     142                 :            :     [INITIAL] = {
     143                 :            :             CLIENT_HELLO,
     144                 :            :             SERVER_HELLO
     145                 :            :     },
     146                 :            : 
     147                 :            :     [NEGOTIATED] = {
     148                 :            :             CLIENT_HELLO,
     149                 :            :             SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     150                 :            :             CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     151                 :            :             APPLICATION_DATA
     152                 :            :     },
     153                 :            : 
     154                 :            :     [NEGOTIATED | WITH_NPN ] = {
     155                 :            :             CLIENT_HELLO,
     156                 :            :             SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     157                 :            :             CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     158                 :            :             APPLICATION_DATA
     159                 :            :     },
     160                 :            : 
     161                 :            :     [NEGOTIATED | WITH_SESSION_TICKET ] = {
     162                 :            :             CLIENT_HELLO,
     163                 :            :             SERVER_HELLO, SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     164                 :            :             CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     165                 :            :             APPLICATION_DATA},
     166                 :            : 
     167                 :            :     [NEGOTIATED | WITH_SESSION_TICKET | WITH_NPN ] = {
     168                 :            :             CLIENT_HELLO,
     169                 :            :             SERVER_HELLO, SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     170                 :            :             CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     171                 :            :             APPLICATION_DATA},
     172                 :            : 
     173                 :            :     [NEGOTIATED | FULL_HANDSHAKE ] = {
     174                 :            :             CLIENT_HELLO,
     175                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE,
     176                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     177                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     178                 :            :             APPLICATION_DATA
     179                 :            :     },
     180                 :            : 
     181                 :            :     [NEGOTIATED | FULL_HANDSHAKE | WITH_NPN ] = {
     182                 :            :             CLIENT_HELLO,
     183                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE,
     184                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     185                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     186                 :            :             APPLICATION_DATA
     187                 :            :     },
     188                 :            : 
     189                 :            :     [NEGOTIATED | FULL_HANDSHAKE | WITH_SESSION_TICKET ] = {
     190                 :            :             CLIENT_HELLO,
     191                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE,
     192                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     193                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     194                 :            :             APPLICATION_DATA
     195                 :            :     },
     196                 :            : 
     197                 :            :     [NEGOTIATED | FULL_HANDSHAKE | WITH_SESSION_TICKET | WITH_NPN ] = {
     198                 :            :             CLIENT_HELLO,
     199                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_HELLO_DONE,
     200                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     201                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     202                 :            :             APPLICATION_DATA
     203                 :            :     },
     204                 :            : 
     205                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY ] = {
     206                 :            :             CLIENT_HELLO,
     207                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE,
     208                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     209                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     210                 :            :             APPLICATION_DATA
     211                 :            :     },
     212                 :            : 
     213                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | WITH_NPN ] = {
     214                 :            :             CLIENT_HELLO,
     215                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE,
     216                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     217                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     218                 :            :             APPLICATION_DATA
     219                 :            :     },
     220                 :            : 
     221                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | WITH_SESSION_TICKET ] = {
     222                 :            :             CLIENT_HELLO,
     223                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE,
     224                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     225                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     226                 :            :             APPLICATION_DATA
     227                 :            :     },
     228                 :            : 
     229                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | WITH_SESSION_TICKET | WITH_NPN ] = {
     230                 :            :             CLIENT_HELLO,
     231                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_HELLO_DONE,
     232                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     233                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     234                 :            :             APPLICATION_DATA
     235                 :            :     },
     236                 :            : 
     237                 :            :     [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS ] ={
     238                 :            :             CLIENT_HELLO,
     239                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE,
     240                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     241                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     242                 :            :             APPLICATION_DATA
     243                 :            :     },
     244                 :            : 
     245                 :            :     [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | WITH_NPN ] ={
     246                 :            :             CLIENT_HELLO,
     247                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE,
     248                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     249                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     250                 :            :             APPLICATION_DATA
     251                 :            :     },
     252                 :            : 
     253                 :            :     [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | WITH_SESSION_TICKET ] = {
     254                 :            :             CLIENT_HELLO,
     255                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE,
     256                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     257                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     258                 :            :             APPLICATION_DATA
     259                 :            :     },
     260                 :            : 
     261                 :            :     [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | WITH_SESSION_TICKET | WITH_NPN ] = {
     262                 :            :             CLIENT_HELLO,
     263                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_HELLO_DONE,
     264                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     265                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     266                 :            :             APPLICATION_DATA
     267                 :            :     },
     268                 :            : 
     269                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS ] = {
     270                 :            :             CLIENT_HELLO,
     271                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE,
     272                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     273                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     274                 :            :             APPLICATION_DATA
     275                 :            :     },
     276                 :            : 
     277                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | WITH_NPN ] = {
     278                 :            :             CLIENT_HELLO,
     279                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE,
     280                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     281                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     282                 :            :             APPLICATION_DATA
     283                 :            :     },
     284                 :            : 
     285                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS  | WITH_SESSION_TICKET ] ={
     286                 :            :             CLIENT_HELLO,
     287                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE,
     288                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     289                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     290                 :            :             APPLICATION_DATA
     291                 :            :     },
     292                 :            : 
     293                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS  | WITH_SESSION_TICKET | WITH_NPN ] ={
     294                 :            :             CLIENT_HELLO,
     295                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_HELLO_DONE,
     296                 :            :             CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     297                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     298                 :            :             APPLICATION_DATA
     299                 :            :     },
     300                 :            : 
     301                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH] = {
     302                 :            :             CLIENT_HELLO,
     303                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     304                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     305                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     306                 :            :             APPLICATION_DATA
     307                 :            :     },
     308                 :            : 
     309                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH| WITH_NPN ] = {
     310                 :            :             CLIENT_HELLO,
     311                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     312                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     313                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     314                 :            :             APPLICATION_DATA
     315                 :            :     },
     316                 :            : 
     317                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT ] = {
     318                 :            :             CLIENT_HELLO,
     319                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     320                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     321                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     322                 :            :             APPLICATION_DATA
     323                 :            :     },
     324                 :            : 
     325                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | WITH_NPN ] = {
     326                 :            :             CLIENT_HELLO,
     327                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     328                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     329                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     330                 :            :             APPLICATION_DATA
     331                 :            :     },
     332                 :            : 
     333                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | WITH_SESSION_TICKET] = {
     334                 :            :             CLIENT_HELLO,
     335                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     336                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     337                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     338                 :            :             APPLICATION_DATA
     339                 :            :     },
     340                 :            : 
     341                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | WITH_SESSION_TICKET | WITH_NPN ] = {
     342                 :            :             CLIENT_HELLO,
     343                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     344                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     345                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     346                 :            :             APPLICATION_DATA
     347                 :            :     },
     348                 :            : 
     349                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
     350                 :            :             CLIENT_HELLO,
     351                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     352                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     353                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     354                 :            :             APPLICATION_DATA
     355                 :            :     },
     356                 :            : 
     357                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET | WITH_NPN ] = {
     358                 :            :             CLIENT_HELLO,
     359                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     360                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     361                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     362                 :            :             APPLICATION_DATA
     363                 :            :     },
     364                 :            : 
     365                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH] = {
     366                 :            :            CLIENT_HELLO,
     367                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     368                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     369                 :            :            SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     370                 :            :            APPLICATION_DATA
     371                 :            :     },
     372                 :            : 
     373                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | WITH_NPN ] = {
     374                 :            :            CLIENT_HELLO,
     375                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     376                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     377                 :            :            SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     378                 :            :            APPLICATION_DATA
     379                 :            :     },
     380                 :            : 
     381                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT ] = {
     382                 :            :            CLIENT_HELLO,
     383                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     384                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     385                 :            :            SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     386                 :            :            APPLICATION_DATA
     387                 :            :     },
     388                 :            : 
     389                 :            :    [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT | WITH_NPN ] = {
     390                 :            :            CLIENT_HELLO,
     391                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     392                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     393                 :            :            SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     394                 :            :            APPLICATION_DATA
     395                 :            :     },
     396                 :            : 
     397                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | WITH_SESSION_TICKET] = {
     398                 :            :            CLIENT_HELLO,
     399                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     400                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     401                 :            :            SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     402                 :            :            APPLICATION_DATA
     403                 :            :     },
     404                 :            : 
     405                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | WITH_SESSION_TICKET | WITH_NPN ] = {
     406                 :            :            CLIENT_HELLO,
     407                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     408                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     409                 :            :            SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     410                 :            :            APPLICATION_DATA
     411                 :            :     },
     412                 :            : 
     413                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
     414                 :            :            CLIENT_HELLO,
     415                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     416                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     417                 :            :            SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     418                 :            :            APPLICATION_DATA
     419                 :            :     },
     420                 :            : 
     421                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET | WITH_NPN ] = {
     422                 :            :            CLIENT_HELLO,
     423                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     424                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     425                 :            :            SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     426                 :            :            APPLICATION_DATA
     427                 :            :     },
     428                 :            : 
     429                 :            :     [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH] = {
     430                 :            :            CLIENT_HELLO,
     431                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     432                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     433                 :            :            SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     434                 :            :            APPLICATION_DATA
     435                 :            :     },
     436                 :            : 
     437                 :            :     [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | WITH_NPN ] = {
     438                 :            :            CLIENT_HELLO,
     439                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     440                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     441                 :            :            SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     442                 :            :            APPLICATION_DATA
     443                 :            :     },
     444                 :            : 
     445                 :            :     [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT ] = {
     446                 :            :            CLIENT_HELLO,
     447                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     448                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     449                 :            :            SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     450                 :            :            APPLICATION_DATA
     451                 :            :     },
     452                 :            : 
     453                 :            :     [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_NPN ] = {
     454                 :            :            CLIENT_HELLO,
     455                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     456                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     457                 :            :            SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     458                 :            :            APPLICATION_DATA
     459                 :            :     },
     460                 :            : 
     461                 :            :     [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET] = {
     462                 :            :            CLIENT_HELLO,
     463                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     464                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     465                 :            :            SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     466                 :            :            APPLICATION_DATA
     467                 :            :     },
     468                 :            : 
     469                 :            :     [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET | WITH_NPN ] = {
     470                 :            :            CLIENT_HELLO,
     471                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     472                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     473                 :            :            SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     474                 :            :            APPLICATION_DATA
     475                 :            :     },
     476                 :            : 
     477                 :            :     [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
     478                 :            :            CLIENT_HELLO,
     479                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     480                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     481                 :            :            SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     482                 :            :            APPLICATION_DATA
     483                 :            :     },
     484                 :            : 
     485                 :            :     [NEGOTIATED | FULL_HANDSHAKE | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET | WITH_NPN ] = {
     486                 :            :            CLIENT_HELLO,
     487                 :            :            SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     488                 :            :            CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     489                 :            :            SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     490                 :            :            APPLICATION_DATA
     491                 :            :     },
     492                 :            : 
     493                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH ] = {
     494                 :            :             CLIENT_HELLO,
     495                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     496                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     497                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     498                 :            :             APPLICATION_DATA
     499                 :            :     },
     500                 :            : 
     501                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | WITH_NPN ] = {
     502                 :            :             CLIENT_HELLO,
     503                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     504                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     505                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     506                 :            :             APPLICATION_DATA
     507                 :            :     },
     508                 :            : 
     509                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT ] = {
     510                 :            :             CLIENT_HELLO,
     511                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     512                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     513                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     514                 :            :             APPLICATION_DATA
     515                 :            :     },
     516                 :            : 
     517                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_NPN ] = {
     518                 :            :             CLIENT_HELLO,
     519                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     520                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     521                 :            :             SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     522                 :            :             APPLICATION_DATA
     523                 :            :     },
     524                 :            : 
     525                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET ] = {
     526                 :            :             CLIENT_HELLO,
     527                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     528                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     529                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     530                 :            :             APPLICATION_DATA
     531                 :            :     },
     532                 :            : 
     533                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | WITH_SESSION_TICKET | WITH_NPN ] = {
     534                 :            :             CLIENT_HELLO,
     535                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     536                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CERT_VERIFY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     537                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     538                 :            :             APPLICATION_DATA
     539                 :            :     },
     540                 :            : 
     541                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET ] = {
     542                 :            :             CLIENT_HELLO,
     543                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     544                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     545                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     546                 :            :             APPLICATION_DATA
     547                 :            :     },
     548                 :            : 
     549                 :            :     [NEGOTIATED | FULL_HANDSHAKE | TLS12_PERFECT_FORWARD_SECRECY | OCSP_STATUS | CLIENT_AUTH | NO_CLIENT_CERT | WITH_SESSION_TICKET | WITH_NPN ] = {
     550                 :            :             CLIENT_HELLO,
     551                 :            :             SERVER_HELLO, SERVER_CERT, SERVER_CERT_STATUS, SERVER_KEY, SERVER_CERT_REQ, SERVER_HELLO_DONE,
     552                 :            :             CLIENT_CERT, CLIENT_KEY, CLIENT_CHANGE_CIPHER_SPEC, CLIENT_NPN, CLIENT_FINISHED,
     553                 :            :             SERVER_NEW_SESSION_TICKET, SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED,
     554                 :            :             APPLICATION_DATA
     555                 :            :     },
     556                 :            : };
     557                 :            : 
     558                 :            : /*
     559                 :            :  * This selection of handshakes resembles the standard set, but with changes made to support tls1.3.
     560                 :            :  *
     561                 :            :  * The CHANGE_CIPHER_SPEC messages are included only for middlebox compatibility.
     562                 :            :  * See https://tools.ietf.org/html/rfc8446#appendix-D.4
     563                 :            :  */
     564                 :            : static message_type_t tls13_handshakes[S2N_HANDSHAKES_COUNT][S2N_MAX_HANDSHAKE_LENGTH] = {
     565                 :            :     [INITIAL] = {
     566                 :            :             CLIENT_HELLO,
     567                 :            :             SERVER_HELLO
     568                 :            :     },
     569                 :            : 
     570                 :            :     [INITIAL | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
     571                 :            :             CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
     572                 :            :             SERVER_HELLO
     573                 :            :     },
     574                 :            : 
     575                 :            :     [INITIAL | HELLO_RETRY_REQUEST] = {
     576                 :            :             CLIENT_HELLO,
     577                 :            :             HELLO_RETRY_MSG
     578                 :            :     },
     579                 :            : 
     580                 :            :     [INITIAL | HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
     581                 :            :             CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
     582                 :            :             HELLO_RETRY_MSG
     583                 :            :     },
     584                 :            : 
     585                 :            :     [NEGOTIATED] = {
     586                 :            :             CLIENT_HELLO,
     587                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
     588                 :            :             CLIENT_FINISHED,
     589                 :            :             APPLICATION_DATA
     590                 :            :     },
     591                 :            : 
     592                 :            :     [NEGOTIATED | WITH_EARLY_DATA] = {
     593                 :            :             CLIENT_HELLO,
     594                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
     595                 :            :             END_OF_EARLY_DATA, CLIENT_FINISHED,
     596                 :            :             APPLICATION_DATA
     597                 :            :     },
     598                 :            : 
     599                 :            :     [NEGOTIATED | MIDDLEBOX_COMPAT] = {
     600                 :            :             CLIENT_HELLO,
     601                 :            :             SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
     602                 :            :             CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     603                 :            :             APPLICATION_DATA
     604                 :            :     },
     605                 :            : 
     606                 :            :     [NEGOTIATED | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
     607                 :            :             CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
     608                 :            :             SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
     609                 :            :             CLIENT_FINISHED,
     610                 :            :             APPLICATION_DATA
     611                 :            :     },
     612                 :            : 
     613                 :            :     [NEGOTIATED | MIDDLEBOX_COMPAT | WITH_EARLY_DATA] = {
     614                 :            :             CLIENT_HELLO,
     615                 :            :             SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
     616                 :            :             CLIENT_CHANGE_CIPHER_SPEC, END_OF_EARLY_DATA, CLIENT_FINISHED,
     617                 :            :             APPLICATION_DATA
     618                 :            :     },
     619                 :            : 
     620                 :            :     [NEGOTIATED | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS | WITH_EARLY_DATA] = {
     621                 :            :             CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
     622                 :            :             SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
     623                 :            :             END_OF_EARLY_DATA, CLIENT_FINISHED,
     624                 :            :             APPLICATION_DATA
     625                 :            :     },
     626                 :            : 
     627                 :            :     [NEGOTIATED | HELLO_RETRY_REQUEST] = {
     628                 :            :             CLIENT_HELLO,
     629                 :            :             HELLO_RETRY_MSG,
     630                 :            :             CLIENT_HELLO,
     631                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
     632                 :            :             CLIENT_FINISHED,
     633                 :            :             APPLICATION_DATA
     634                 :            :     },
     635                 :            : 
     636                 :            :     [NEGOTIATED | HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT] = {
     637                 :            :             CLIENT_HELLO,
     638                 :            :             HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
     639                 :            :             CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
     640                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
     641                 :            :             CLIENT_FINISHED,
     642                 :            :             APPLICATION_DATA
     643                 :            :     },
     644                 :            : 
     645                 :            :     [NEGOTIATED | HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
     646                 :            :             CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
     647                 :            :             HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
     648                 :            :             CLIENT_HELLO,
     649                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_FINISHED,
     650                 :            :             CLIENT_FINISHED,
     651                 :            :             APPLICATION_DATA
     652                 :            :     },
     653                 :            : 
     654                 :            :     [NEGOTIATED | FULL_HANDSHAKE] = {
     655                 :            :             CLIENT_HELLO,
     656                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     657                 :            :             CLIENT_FINISHED,
     658                 :            :             APPLICATION_DATA
     659                 :            :     },
     660                 :            : 
     661                 :            :     [NEGOTIATED | FULL_HANDSHAKE | MIDDLEBOX_COMPAT] = {
     662                 :            :             CLIENT_HELLO,
     663                 :            :             SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     664                 :            :             CLIENT_CHANGE_CIPHER_SPEC, CLIENT_FINISHED,
     665                 :            :             APPLICATION_DATA
     666                 :            :     },
     667                 :            : 
     668                 :            :     [NEGOTIATED | FULL_HANDSHAKE | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
     669                 :            :             CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
     670                 :            :             SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     671                 :            :             CLIENT_FINISHED,
     672                 :            :             APPLICATION_DATA
     673                 :            :     },
     674                 :            : 
     675                 :            :     [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST] = {
     676                 :            :             CLIENT_HELLO,
     677                 :            :             HELLO_RETRY_MSG,
     678                 :            :             CLIENT_HELLO,
     679                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     680                 :            :             CLIENT_FINISHED,
     681                 :            :             APPLICATION_DATA
     682                 :            :     },
     683                 :            : 
     684                 :            :     [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT] = {
     685                 :            :             CLIENT_HELLO,
     686                 :            :             HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
     687                 :            :             CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
     688                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     689                 :            :             CLIENT_FINISHED,
     690                 :            :             APPLICATION_DATA
     691                 :            :     },
     692                 :            : 
     693                 :            :     [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
     694                 :            :             CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
     695                 :            :             HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
     696                 :            :             CLIENT_HELLO,
     697                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     698                 :            :             CLIENT_FINISHED,
     699                 :            :             APPLICATION_DATA
     700                 :            :     },
     701                 :            : 
     702                 :            :     [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH] = {
     703                 :            :             CLIENT_HELLO,
     704                 :            :             HELLO_RETRY_MSG,
     705                 :            :             CLIENT_HELLO,
     706                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     707                 :            :             CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
     708                 :            :             APPLICATION_DATA
     709                 :            :     },
     710                 :            : 
     711                 :            :     [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | MIDDLEBOX_COMPAT] = {
     712                 :            :             CLIENT_HELLO,
     713                 :            :             HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
     714                 :            :             CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
     715                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     716                 :            :             CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
     717                 :            :             APPLICATION_DATA
     718                 :            :     },
     719                 :            : 
     720                 :            :     [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
     721                 :            :             CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
     722                 :            :             HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
     723                 :            :             CLIENT_HELLO,
     724                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     725                 :            :             CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
     726                 :            :             APPLICATION_DATA
     727                 :            :     },
     728                 :            : 
     729                 :            :     [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | NO_CLIENT_CERT] = {
     730                 :            :             CLIENT_HELLO,
     731                 :            :             HELLO_RETRY_MSG,
     732                 :            :             CLIENT_HELLO,
     733                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     734                 :            :             CLIENT_CERT, CLIENT_FINISHED,
     735                 :            :             APPLICATION_DATA
     736                 :            :     },
     737                 :            : 
     738                 :            :     [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | NO_CLIENT_CERT | MIDDLEBOX_COMPAT] = {
     739                 :            :             CLIENT_HELLO,
     740                 :            :             HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
     741                 :            :             CLIENT_CHANGE_CIPHER_SPEC, CLIENT_HELLO,
     742                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     743                 :            :             CLIENT_CERT, CLIENT_FINISHED,
     744                 :            :             APPLICATION_DATA
     745                 :            :     },
     746                 :            : 
     747                 :            :     [NEGOTIATED | FULL_HANDSHAKE | HELLO_RETRY_REQUEST | CLIENT_AUTH | NO_CLIENT_CERT | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
     748                 :            :             CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
     749                 :            :             HELLO_RETRY_MSG, SERVER_CHANGE_CIPHER_SPEC,
     750                 :            :             CLIENT_HELLO,
     751                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     752                 :            :             CLIENT_CERT, CLIENT_FINISHED,
     753                 :            :             APPLICATION_DATA
     754                 :            :     },
     755                 :            : 
     756                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH] = {
     757                 :            :             CLIENT_HELLO,
     758                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     759                 :            :             CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
     760                 :            :             APPLICATION_DATA
     761                 :            :     },
     762                 :            : 
     763                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | MIDDLEBOX_COMPAT] = {
     764                 :            :             CLIENT_HELLO,
     765                 :            :             SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     766                 :            :             CLIENT_CHANGE_CIPHER_SPEC, CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
     767                 :            :             APPLICATION_DATA
     768                 :            :     },
     769                 :            : 
     770                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
     771                 :            :             CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
     772                 :            :             SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     773                 :            :             CLIENT_CERT, CLIENT_CERT_VERIFY, CLIENT_FINISHED,
     774                 :            :             APPLICATION_DATA
     775                 :            :     },
     776                 :            : 
     777                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT] = {
     778                 :            :             CLIENT_HELLO,
     779                 :            :             SERVER_HELLO, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     780                 :            :             CLIENT_CERT, CLIENT_FINISHED,
     781                 :            :             APPLICATION_DATA
     782                 :            :     },
     783                 :            : 
     784                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | MIDDLEBOX_COMPAT] = {
     785                 :            :             CLIENT_HELLO,
     786                 :            :             SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     787                 :            :             CLIENT_CHANGE_CIPHER_SPEC, CLIENT_CERT, CLIENT_FINISHED,
     788                 :            :             APPLICATION_DATA
     789                 :            :     },
     790                 :            : 
     791                 :            :     [NEGOTIATED | FULL_HANDSHAKE | CLIENT_AUTH | NO_CLIENT_CERT | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS] = {
     792                 :            :             CLIENT_HELLO, CLIENT_CHANGE_CIPHER_SPEC,
     793                 :            :             SERVER_HELLO, SERVER_CHANGE_CIPHER_SPEC, ENCRYPTED_EXTENSIONS, SERVER_CERT_REQ, SERVER_CERT, SERVER_CERT_VERIFY, SERVER_FINISHED,
     794                 :            :             CLIENT_CERT, CLIENT_FINISHED,
     795                 :            :             APPLICATION_DATA
     796                 :            :     },
     797                 :            : };
     798                 :            : /* clang-format on */
     799                 :            : 
     800                 :            : #define MAX_HANDSHAKE_TYPE_LEN 142
     801                 :            : static char handshake_type_str[S2N_HANDSHAKES_COUNT][MAX_HANDSHAKE_TYPE_LEN] = { 0 };
     802                 :            : 
     803                 :            : static const char *tls12_handshake_type_names[] = {
     804                 :            :     "NEGOTIATED|",
     805                 :            :     "FULL_HANDSHAKE|",
     806                 :            :     "CLIENT_AUTH|",
     807                 :            :     "NO_CLIENT_CERT|",
     808                 :            :     "TLS12_PERFECT_FORWARD_SECRECY|",
     809                 :            :     "OCSP_STATUS|",
     810                 :            :     "WITH_SESSION_TICKET|",
     811                 :            :     "WITH_NPN|",
     812                 :            : };
     813                 :            : 
     814                 :            : static const char *tls13_handshake_type_names[] = {
     815                 :            :     "NEGOTIATED|",
     816                 :            :     "FULL_HANDSHAKE|",
     817                 :            :     "CLIENT_AUTH|",
     818                 :            :     "NO_CLIENT_CERT|",
     819                 :            :     "HELLO_RETRY_REQUEST|",
     820                 :            :     "MIDDLEBOX_COMPAT|",
     821                 :            :     "WITH_EARLY_DATA|",
     822                 :            :     "EARLY_CLIENT_CCS|",
     823                 :            : };
     824                 :            : 
     825                 :    3142271 : #define IS_TLS13_HANDSHAKE(conn) ((conn)->handshake.state_machine == S2N_STATE_MACHINE_TLS13)
     826                 :            : 
     827                 :     967276 : #define ACTIVE_STATE_MACHINE(conn) (IS_TLS13_HANDSHAKE(conn) ? tls13_state_machine : state_machine)
     828                 :    2124674 : #define ACTIVE_HANDSHAKES(conn)    (IS_TLS13_HANDSHAKE(conn) ? tls13_handshakes : handshakes)
     829                 :            : 
     830                 :    2124674 : #define ACTIVE_MESSAGE(conn) ACTIVE_HANDSHAKES(conn)[(conn)->handshake.handshake_type][(conn)->handshake.message_number]
     831                 :            : 
     832                 :     967276 : #define ACTIVE_STATE(conn) ACTIVE_STATE_MACHINE(conn)[ACTIVE_MESSAGE((conn))]
     833                 :            : 
     834                 :            : #define CCS_STATE(conn) (((conn)->mode == S2N_CLIENT) ?                 \
     835                 :            :                 ACTIVE_STATE_MACHINE(conn)[SERVER_CHANGE_CIPHER_SPEC] : \
     836                 :            :                 ACTIVE_STATE_MACHINE(conn)[CLIENT_CHANGE_CIPHER_SPEC])
     837                 :            : 
     838                 :     176909 : #define EXPECTED_RECORD_TYPE(conn)  ACTIVE_STATE(conn).record_type
     839                 :      67614 : #define EXPECTED_MESSAGE_TYPE(conn) ACTIVE_STATE(conn).message_type
     840                 :            : 
     841                 :     358172 : #define CONNECTION_WRITER(conn)    (conn->mode == S2N_CLIENT ? 'C' : 'S')
     842                 :     257918 : #define CONNECTION_IS_WRITER(conn) (ACTIVE_STATE(conn).writer == CONNECTION_WRITER(conn))
     843                 :            : 
     844                 :            : /* Only used in our test cases. */
     845                 :            : message_type_t s2n_conn_get_current_message_type(const struct s2n_connection *conn)
     846                 :     831152 : {
     847         [ +  + ]:     831152 :     return ACTIVE_MESSAGE(conn);
     848                 :     831152 : }
     849                 :            : 
     850                 :            : static int s2n_advance_message(struct s2n_connection *conn)
     851                 :     100254 : {
     852                 :            :     /* Get the mode: 'C'lient or 'S'erver */
     853 [ +  + ][ +  + ]:     100254 :     char previous_writer = ACTIVE_STATE(conn).writer;
     854         [ +  + ]:     100254 :     char this_mode = CONNECTION_WRITER(conn);
     855                 :            : 
     856                 :            :     /* Actually advance the message number */
     857                 :     100254 :     conn->handshake.message_number++;
     858                 :            : 
     859                 :            :     /* When reading and using TLS1.3, skip optional change_cipher_spec states. */
     860 [ +  + ][ +  + ]:     100254 :     if (ACTIVE_STATE(conn).writer != this_mode && EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC && IS_TLS13_HANDSHAKE(conn)) {
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
                 [ +  + ]
     861                 :       8258 :         conn->handshake.message_number++;
     862                 :       8258 :     }
     863                 :            : 
     864                 :            :     /* Set TCP_QUICKACK to avoid artificial delay during the handshake */
     865         [ -  + ]:     100254 :     POSIX_GUARD(s2n_socket_quickack(conn));
     866                 :            : 
     867                 :            :     /* If optimized io hasn't been enabled or if the caller started out with a corked socket,
     868                 :            :      * we don't mess with it
     869                 :            :      */
     870 [ +  + ][ -  + ]:     100254 :     if (!conn->corked_io || s2n_socket_was_corked(conn)) {
     871                 :      99914 :         return S2N_SUCCESS;
     872                 :      99914 :     }
     873                 :            : 
     874                 :            :     /* Are we changing I/O directions */
     875 [ +  + ][ +  + ]:        340 :     if (ACTIVE_STATE(conn).writer == previous_writer || ACTIVE_STATE(conn).writer == 'A') {
         [ +  + ][ +  + ]
         [ +  + ][ -  + ]
     876                 :        206 :         return S2N_SUCCESS;
     877                 :        206 :     }
     878                 :            : 
     879                 :            :     /* We're the new writer */
     880 [ +  + ][ +  + ]:        134 :     if (ACTIVE_STATE(conn).writer == this_mode) {
                 [ +  + ]
     881         [ +  - ]:         62 :         if (s2n_connection_is_managed_corked(conn)) {
     882                 :            :             /* Set TCP_CORK/NOPUSH */
     883         [ -  + ]:         62 :             POSIX_GUARD(s2n_socket_write_cork(conn));
     884                 :         62 :         }
     885                 :            : 
     886                 :         62 :         return S2N_SUCCESS;
     887                 :         62 :     }
     888                 :            : 
     889                 :            :     /* We're the new reader, or we reached the "B" writer stage indicating that
     890                 :            :        we're at the application data stage  - uncork the data */
     891         [ +  - ]:         72 :     if (s2n_connection_is_managed_corked(conn)) {
     892         [ -  + ]:         72 :         POSIX_GUARD(s2n_socket_write_uncork(conn));
     893                 :         72 :     }
     894                 :            : 
     895                 :         72 :     return S2N_SUCCESS;
     896                 :         72 : }
     897                 :            : 
     898                 :            : int s2n_generate_new_client_session_id(struct s2n_connection *conn)
     899                 :       4766 : {
     900         [ +  + ]:       4766 :     if (conn->mode == S2N_SERVER) {
     901                 :       2422 :         struct s2n_blob session_id = { 0 };
     902         [ -  + ]:       2422 :         POSIX_GUARD(s2n_blob_init(&session_id, conn->session_id, S2N_TLS_SESSION_ID_MAX_LEN));
     903                 :            : 
     904                 :            :         /* Generate a new session id */
     905         [ -  + ]:       2422 :         POSIX_GUARD_RESULT(s2n_get_public_random_data(&session_id));
     906                 :       2422 :         conn->session_id_len = S2N_TLS_SESSION_ID_MAX_LEN;
     907                 :       2422 :     }
     908                 :            : 
     909                 :       4766 :     return S2N_SUCCESS;
     910                 :       4766 : }
     911                 :            : 
     912                 :            : /* Lets the server flag whether a HelloRetryRequest is needed while processing extensions */
     913                 :            : int s2n_set_hello_retry_required(struct s2n_connection *conn)
     914                 :       2021 : {
     915 [ -  + ][ #  # ]:       2021 :     POSIX_ENSURE_REF(conn);
     916                 :            : 
     917 [ +  - ][ +  + ]:       2021 :     POSIX_ENSURE(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_INVALID_HELLO_RETRY);
     918         [ -  + ]:       2020 :     POSIX_GUARD_RESULT(s2n_handshake_type_set_tls13_flag(conn, HELLO_RETRY_REQUEST));
     919                 :            : 
     920                 :            :     /* HelloRetryRequests also indicate rejection of early data.
     921                 :            :      *
     922                 :            :      *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.10
     923                 :            :      *# A server which receives an "early_data" extension MUST behave in one
     924                 :            :      *# of three ways:
     925                 :            :      *
     926                 :            :      *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.10
     927                 :            :      *# -  Request that the client send another ClientHello by responding
     928                 :            :      *#    with a HelloRetryRequest.
     929                 :            :      **/
     930         [ +  + ]:       2020 :     if (conn->early_data_state == S2N_EARLY_DATA_REQUESTED) {
     931         [ -  + ]:        916 :         POSIX_GUARD_RESULT(s2n_connection_set_early_data_state(conn, S2N_EARLY_DATA_REJECTED));
     932                 :        916 :     }
     933                 :            : 
     934                 :       2020 :     return S2N_SUCCESS;
     935                 :       2020 : }
     936                 :            : 
     937                 :            : bool s2n_is_hello_retry_message(struct s2n_connection *conn)
     938                 :      45163 : {
     939 [ +  - ][ +  - ]:      45163 :     return (conn != NULL && s2n_result_is_ok(s2n_handshake_validate(&(conn->handshake))) && ACTIVE_MESSAGE(conn) == HELLO_RETRY_MSG);
         [ +  + ][ +  + ]
     940                 :      45163 : }
     941                 :            : 
     942                 :            : bool s2n_is_hello_retry_handshake(struct s2n_connection *conn)
     943                 :      92024 : {
     944                 :      92024 :     return IS_HELLO_RETRY_HANDSHAKE(conn);
     945                 :      92024 : }
     946                 :            : 
     947                 :            : static S2N_RESULT s2n_conn_set_tls13_handshake_type(struct s2n_connection *conn)
     948                 :      10335 : {
     949 [ -  + ][ #  # ]:      10335 :     RESULT_ENSURE_REF(conn);
     950                 :            : 
     951                 :            :     /* Most handshake type flags should be reset before we calculate the handshake type,
     952                 :            :      * in order to handle changes during retries.
     953                 :            :      * However, flags that have already affected the message order must be kept to avoid
     954                 :            :      * rewriting the past.
     955                 :            :      */
     956                 :      10335 :     conn->handshake.handshake_type &= (HELLO_RETRY_REQUEST | MIDDLEBOX_COMPAT | EARLY_CLIENT_CCS);
     957                 :            : 
     958                 :            :     /* A handshake type has been negotiated */
     959         [ -  + ]:      10335 :     RESULT_GUARD(s2n_handshake_type_set_flag(conn, NEGOTIATED));
     960                 :            : 
     961         [ +  + ]:      10335 :     if (conn->psk_params.chosen_psk == NULL) {
     962         [ -  + ]:       8683 :         RESULT_GUARD(s2n_handshake_type_set_flag(conn, FULL_HANDSHAKE));
     963                 :       8683 :     }
     964                 :            : 
     965         [ +  + ]:      10335 :     if (conn->early_data_state == S2N_EARLY_DATA_ACCEPTED) {
     966                 :         46 :         conn->handshake.handshake_type |= WITH_EARLY_DATA;
     967                 :         46 :     }
     968                 :            : 
     969                 :      10335 :     s2n_cert_auth_type client_cert_auth_type;
     970         [ -  + ]:      10335 :     RESULT_GUARD_POSIX(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
     971                 :            : 
     972 [ +  + ][ +  + ]:      10335 :     if (conn->mode == S2N_CLIENT && client_cert_auth_type == S2N_CERT_AUTH_REQUIRED
     973         [ +  + ]:      10335 :             && IS_FULL_HANDSHAKE(conn)) {
     974                 :            :         /* If we're a client, and Client Auth is REQUIRED, then the Client must expect the CLIENT_CERT_REQ Message */
     975         [ -  + ]:         43 :         RESULT_GUARD(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
     976 [ +  + ][ +  + ]:      10292 :     } else if (conn->mode == S2N_SERVER && client_cert_auth_type != S2N_CERT_AUTH_NONE
     977         [ +  + ]:      10292 :             && IS_FULL_HANDSHAKE(conn)) {
     978                 :            :         /* If we're a server, and Client Auth is REQUIRED or OPTIONAL, then the server must send the CLIENT_CERT_REQ Message*/
     979         [ -  + ]:         98 :         RESULT_GUARD(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
     980                 :         98 :     }
     981                 :            : 
     982         [ +  + ]:      10335 :     if (s2n_is_middlebox_compat_enabled(conn)) {
     983         [ -  + ]:      10318 :         RESULT_GUARD(s2n_handshake_type_set_tls13_flag(conn, MIDDLEBOX_COMPAT));
     984                 :      10318 :     }
     985                 :            : 
     986                 :      10335 :     return S2N_RESULT_OK;
     987                 :      10335 : }
     988                 :            : 
     989                 :            : static S2N_RESULT s2n_validate_ems_status(struct s2n_connection *conn)
     990                 :         13 : {
     991 [ -  + ][ #  # ]:         13 :     RESULT_ENSURE_REF(conn);
     992                 :            : 
     993                 :         13 :     s2n_extension_type_id ems_ext_id = 0;
     994         [ -  + ]:         13 :     RESULT_GUARD_POSIX(s2n_extension_supported_iana_value_to_id(TLS_EXTENSION_EMS, &ems_ext_id));
     995                 :         13 :     bool ems_extension_recv = S2N_CBIT_TEST(conn->extension_requests_received, ems_ext_id);
     996                 :            : 
     997                 :            :     /**
     998                 :            :      *= https://www.rfc-editor.org/rfc/rfc7627#section-5.3
     999                 :            :      *# If the original session used the "extended_master_secret"
    1000                 :            :      *# extension but the new ClientHello does not contain it, the server
    1001                 :            :      *# MUST abort the abbreviated handshake.
    1002                 :            :      **/
    1003         [ +  + ]:         13 :     if (conn->ems_negotiated) {
    1004 [ +  - ][ +  + ]:         11 :         RESULT_ENSURE(ems_extension_recv, S2N_ERR_MISSING_EXTENSION);
    1005                 :         11 :     }
    1006                 :            : 
    1007                 :            :     /* Since we're discarding the resumption ticket, ignore EMS value from the ticket */
    1008                 :         11 :     conn->ems_negotiated = ems_extension_recv;
    1009                 :            : 
    1010                 :         11 :     return S2N_RESULT_OK;
    1011                 :         13 : }
    1012                 :            : 
    1013                 :            : int s2n_conn_set_handshake_type(struct s2n_connection *conn)
    1014                 :      15356 : {
    1015 [ #  # ][ -  + ]:      15356 :     POSIX_ENSURE_REF(conn);
    1016 [ -  + ][ #  # ]:      15356 :     POSIX_ENSURE_REF(conn->secure);
    1017                 :            : 
    1018         [ -  + ]:      15356 :     POSIX_GUARD_RESULT(s2n_conn_choose_state_machine(conn, conn->actual_protocol_version));
    1019                 :            : 
    1020         [ +  + ]:      15356 :     if (IS_TLS13_HANDSHAKE(conn)) {
    1021         [ -  + ]:      10534 :         POSIX_GUARD_RESULT(s2n_conn_set_tls13_handshake_type(conn));
    1022                 :      10534 :         return S2N_SUCCESS;
    1023                 :      10534 :     }
    1024                 :            : 
    1025         [ -  + ]:       4822 :     POSIX_GUARD_RESULT(s2n_handshake_type_reset(conn));
    1026                 :            : 
    1027                 :            :     /* A handshake type has been negotiated */
    1028         [ -  + ]:       4822 :     POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, NEGOTIATED));
    1029                 :            : 
    1030                 :       4822 :     s2n_cert_auth_type client_cert_auth_type;
    1031         [ -  + ]:       4822 :     POSIX_GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
    1032                 :            : 
    1033 [ +  + ][ +  + ]:       4822 :     if (conn->mode == S2N_CLIENT && client_cert_auth_type == S2N_CERT_AUTH_REQUIRED) {
    1034                 :            :         /* If we're a client, and Client Auth is REQUIRED, then the Client must expect the CLIENT_CERT_REQ Message */
    1035         [ -  + ]:         60 :         POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
    1036 [ +  + ][ +  + ]:       4762 :     } else if (conn->mode == S2N_SERVER && client_cert_auth_type != S2N_CERT_AUTH_NONE) {
    1037                 :            :         /* If we're a server, and Client Auth is REQUIRED or OPTIONAL, then the server must send the CLIENT_CERT_REQ Message*/
    1038         [ -  + ]:        113 :         POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
    1039                 :        113 :     }
    1040                 :            : 
    1041         [ +  + ]:       4822 :     if (conn->npn_negotiated) {
    1042         [ -  + ]:          4 :         POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, WITH_NPN));
    1043                 :          4 :     }
    1044                 :            : 
    1045         [ +  + ]:       4822 :     if (conn->config->use_tickets) {
    1046         [ +  + ]:        122 :         if (conn->session_ticket_status == S2N_DECRYPT_TICKET) {
    1047                 :            :             /* We reuse the session if a valid TLS12 ticket is provided.
    1048                 :            :              * Otherwise, we will perform a full handshake and then generate
    1049                 :            :              * a new session ticket. */
    1050         [ +  + ]:         29 :             if (s2n_result_is_ok(s2n_resume_decrypt_session(conn, &conn->client_ticket_to_decrypt))) {
    1051                 :         23 :                 return S2N_SUCCESS;
    1052                 :         23 :             }
    1053                 :            : 
    1054         [ +  + ]:          6 :             POSIX_GUARD_RESULT(s2n_validate_ems_status(conn));
    1055                 :            : 
    1056                 :            :             /* Set up the handshake to send a session ticket since a valid ticket was not provided */
    1057         [ +  + ]:          5 :             if (s2n_result_is_ok(s2n_config_is_encrypt_key_available(conn->config))) {
    1058                 :          3 :                 conn->session_ticket_status = S2N_NEW_TICKET;
    1059         [ -  + ]:          3 :                 POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, WITH_SESSION_TICKET));
    1060                 :          3 :             }
    1061                 :            : 
    1062                 :            :             /* If a session ticket is presented by the client, then skip lookup in Session ID server cache */
    1063                 :          5 :             goto skip_cache_lookup;
    1064                 :          5 :         }
    1065                 :            : 
    1066         [ +  + ]:         93 :         if (conn->session_ticket_status == S2N_NEW_TICKET) {
    1067         [ -  + ]:         35 :             POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, WITH_SESSION_TICKET));
    1068                 :         35 :         }
    1069                 :         93 :     }
    1070                 :            : 
    1071                 :            :     /* If a TLS session is resumed, the Server should respond in its ServerHello with the same SessionId the
    1072                 :            :      * Client sent in the ClientHello. */
    1073 [ +  - ][ +  + ]:       4793 :     if (conn->actual_protocol_version <= S2N_TLS12 && conn->mode == S2N_SERVER && s2n_allowed_to_cache_connection(conn)) {
                 [ +  + ]
    1074                 :         16 :         int r = s2n_resume_from_cache(conn);
    1075 [ +  + ][ +  + ]:         16 :         if (r == S2N_SUCCESS || (r < S2N_SUCCESS && S2N_ERROR_IS_BLOCKING(s2n_errno))) {
                 [ +  - ]
    1076                 :          9 :             return r;
    1077                 :          9 :         }
    1078         [ +  + ]:          7 :         POSIX_GUARD_RESULT(s2n_validate_ems_status(conn));
    1079                 :          7 :     }
    1080                 :            : 
    1081                 :       4788 : skip_cache_lookup:
    1082 [ +  + ][ +  + ]:       4788 :     if (conn->mode == S2N_CLIENT && conn->client_session_resumed == 1) {
    1083                 :         22 :         return S2N_SUCCESS;
    1084                 :         22 :     }
    1085                 :            : 
    1086                 :            :     /* If we're doing full handshake, generate a new session id. */
    1087         [ -  + ]:       4766 :     POSIX_GUARD(s2n_generate_new_client_session_id(conn));
    1088                 :            : 
    1089                 :            :     /* If we get this far, it's a full handshake */
    1090         [ -  + ]:       4766 :     POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, FULL_HANDSHAKE));
    1091                 :            : 
    1092                 :       4766 :     bool is_ephemeral = false;
    1093         [ -  + ]:       4766 :     POSIX_GUARD_RESULT(s2n_kex_is_ephemeral(conn->secure->cipher_suite->key_exchange_alg, &is_ephemeral));
    1094         [ +  + ]:       4766 :     if (is_ephemeral) {
    1095         [ -  + ]:       1757 :         POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, TLS12_PERFECT_FORWARD_SECRECY));
    1096                 :       1757 :     }
    1097                 :            : 
    1098 [ +  + ][ +  - ]:       4766 :     if (s2n_server_can_send_ocsp(conn) || s2n_server_sent_ocsp(conn)) {
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
    1099         [ -  + ]:          5 :         POSIX_GUARD_RESULT(s2n_handshake_type_set_tls12_flag(conn, OCSP_STATUS));
    1100                 :          5 :     }
    1101                 :            : 
    1102                 :       4766 :     return S2N_SUCCESS;
    1103                 :       4766 : }
    1104                 :            : 
    1105                 :            : int s2n_conn_set_handshake_no_client_cert(struct s2n_connection *conn)
    1106                 :         69 : {
    1107                 :         69 :     s2n_cert_auth_type client_cert_auth_type;
    1108         [ -  + ]:         69 :     POSIX_GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
    1109 [ +  - ][ +  + ]:         69 :     POSIX_ENSURE(client_cert_auth_type == S2N_CERT_AUTH_OPTIONAL, S2N_ERR_MISSING_CLIENT_CERT);
    1110                 :            : 
    1111         [ -  + ]:         60 :     POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, NO_CLIENT_CERT));
    1112                 :            : 
    1113                 :         60 :     return S2N_SUCCESS;
    1114                 :         60 : }
    1115                 :            : 
    1116                 :            : S2N_RESULT s2n_conn_choose_state_machine(struct s2n_connection *conn, uint8_t protocol_version)
    1117                 :      32822 : {
    1118 [ -  + ][ #  # ]:      32822 :     RESULT_ENSURE_REF(conn);
    1119                 :            : 
    1120                 :            :     /* This should never be called before we know what version we're on */
    1121 [ #  # ][ -  + ]:      32822 :     RESULT_ENSURE_NE(protocol_version, S2N_UNKNOWN_PROTOCOL_VERSION);
    1122                 :            : 
    1123         [ +  + ]:      32822 :     if (protocol_version == S2N_TLS13) {
    1124                 :            :         /* State machine should not change once set */
    1125 [ #  # ][ -  + ]:      26145 :         RESULT_ENSURE_NE(conn->handshake.state_machine, S2N_STATE_MACHINE_TLS12);
    1126                 :      26145 :         conn->handshake.state_machine = S2N_STATE_MACHINE_TLS13;
    1127                 :      26145 :     } else {
    1128                 :            :         /* State machine should not change once set */
    1129 [ #  # ][ -  + ]:       6677 :         RESULT_ENSURE_NE(conn->handshake.state_machine, S2N_STATE_MACHINE_TLS13);
    1130                 :       6677 :         conn->handshake.state_machine = S2N_STATE_MACHINE_TLS12;
    1131                 :       6677 :     }
    1132                 :            : 
    1133                 :      32822 :     return S2N_RESULT_OK;
    1134                 :      32822 : }
    1135                 :            : 
    1136                 :            : const char *s2n_connection_get_last_message_name(struct s2n_connection *conn)
    1137                 :        362 : {
    1138 [ #  # ][ -  + ]:        362 :     PTR_ENSURE_REF(conn);
    1139         [ -  + ]:        362 :     PTR_GUARD_RESULT(s2n_handshake_validate(&(conn->handshake)));
    1140         [ +  + ]:        362 :     return message_names[ACTIVE_MESSAGE(conn)];
    1141                 :        362 : }
    1142                 :            : 
    1143                 :            : const char *s2n_connection_get_handshake_type_name(struct s2n_connection *conn)
    1144                 :       3861 : {
    1145 [ -  + ][ #  # ]:       3861 :     PTR_ENSURE_REF(conn);
    1146 [ -  + ][ +  - ]:       3861 :     PTR_PRECONDITION(s2n_handshake_validate(&(conn->handshake)));
    1147                 :            : 
    1148                 :       3861 :     uint32_t handshake_type = conn->handshake.handshake_type;
    1149                 :            : 
    1150         [ +  + ]:       3861 :     if (handshake_type == INITIAL) {
    1151                 :         88 :         return "INITIAL";
    1152                 :         88 :     }
    1153                 :            : 
    1154                 :       3773 :     const char **handshake_type_names = tls13_handshake_type_names;
    1155                 :       3773 :     size_t handshake_type_names_len = s2n_array_len(tls13_handshake_type_names);
    1156         [ +  + ]:       3773 :     if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) {
    1157                 :       2810 :         handshake_type_names = tls12_handshake_type_names;
    1158                 :       2810 :         handshake_type_names_len = s2n_array_len(tls12_handshake_type_names);
    1159                 :       2810 :     }
    1160                 :            : 
    1161                 :            :     /* Not all handshake strings will be created already. If the handshake string
    1162                 :            :      * is not null, we can just return the handshake. Otherwise we have to compute
    1163                 :            :      * it down below. */
    1164         [ +  + ]:       3773 :     if (handshake_type_str[handshake_type][0] != '\0') {
    1165                 :       3690 :         return handshake_type_str[handshake_type];
    1166                 :       3690 :     }
    1167                 :            : 
    1168                 :            :     /* Compute handshake_type_str[handshake_type] by concatenating
    1169                 :            :      * each applicable handshake_type.
    1170                 :            :      *
    1171                 :            :      * Unit tests enforce that the elements of handshake_type_str are always
    1172                 :            :      * long enough to contain the longest possible valid handshake_type, but
    1173                 :            :      * for safety we still handle the case where we need to truncate.
    1174                 :            :      */
    1175                 :         83 :     char *p = handshake_type_str[handshake_type];
    1176                 :         83 :     size_t remaining = sizeof(handshake_type_str[0]);
    1177         [ +  + ]:        747 :     for (size_t i = 0; i < handshake_type_names_len; i++) {
    1178         [ +  + ]:        664 :         if (handshake_type & (1 << i)) {
    1179                 :        366 :             size_t bytes_to_copy = MIN(remaining, strlen(handshake_type_names[i]));
    1180 [ -  + ][ #  # ]:        366 :             PTR_CHECKED_MEMCPY(p, handshake_type_names[i], bytes_to_copy);
                 [ +  - ]
    1181                 :        366 :             p[bytes_to_copy] = '\0';
    1182                 :        366 :             p += bytes_to_copy;
    1183                 :        366 :             remaining -= bytes_to_copy;
    1184                 :        366 :         }
    1185                 :        664 :     }
    1186                 :            : 
    1187 [ +  - ][ +  - ]:         83 :     if (p != handshake_type_str[handshake_type] && '|' == *(p - 1)) {
    1188                 :         83 :         *(p - 1) = '\0';
    1189                 :         83 :     }
    1190                 :            : 
    1191                 :         83 :     return handshake_type_str[handshake_type];
    1192                 :         83 : }
    1193                 :            : 
    1194                 :            : S2N_RESULT s2n_handshake_message_send(struct s2n_connection *conn, uint8_t content_type, s2n_blocked_status *blocked)
    1195                 :     118195 : {
    1196 [ #  # ][ -  + ]:     118195 :     RESULT_ENSURE_REF(conn);
    1197                 :     118195 :     struct s2n_stuffer *in = &conn->handshake.io;
    1198                 :            : 
    1199                 :     118195 :     uint32_t size = s2n_stuffer_data_available(in);
    1200         [ +  + ]:     118195 :     if (size == 0) {
    1201                 :      50930 :         return S2N_RESULT_OK;
    1202                 :      50930 :     }
    1203                 :            : 
    1204         [ +  + ]:      67265 :     if (s2n_connection_is_quic_enabled(conn)) {
    1205         [ -  + ]:         50 :         RESULT_GUARD(s2n_quic_write_handshake_message(conn));
    1206         [ +  + ]:         50 :         RESULT_GUARD_POSIX(s2n_flush(conn, blocked));
    1207                 :         49 :         return S2N_RESULT_OK;
    1208                 :         50 :     }
    1209                 :            : 
    1210                 :      67215 :     struct iovec iov = { 0 };
    1211                 :      67215 :     iov.iov_len = size;
    1212                 :      67215 :     iov.iov_base = s2n_stuffer_raw_read(in, size);
    1213 [ -  + ][ #  # ]:      67215 :     RESULT_ENSURE_REF(iov.iov_base);
    1214         [ -  + ]:      67215 :     RESULT_GUARD_POSIX(s2n_stuffer_rewind_read(in, size));
    1215                 :            : 
    1216                 :      67215 :     uint32_t total_bytes_written = 0;
    1217         [ +  + ]:     125298 :     while (total_bytes_written < size) {
    1218                 :      68840 :         int bytes_written = s2n_record_writev(conn, content_type, &iov, 1,
    1219                 :      68840 :                 total_bytes_written, size - total_bytes_written);
    1220         [ -  + ]:      68840 :         RESULT_GUARD_POSIX(bytes_written);
    1221                 :      68840 :         total_bytes_written += bytes_written;
    1222         [ -  + ]:      68840 :         RESULT_GUARD_POSIX(s2n_stuffer_skip_read(in, bytes_written));
    1223         [ +  + ]:      68840 :         RESULT_GUARD_POSIX(s2n_flush(conn, blocked));
    1224                 :      68840 :     }
    1225                 :      56458 :     return S2N_RESULT_OK;
    1226                 :      67215 : }
    1227                 :            : 
    1228                 :            : /* Writing is relatively straight forward, simply write each message out as a record,
    1229                 :            :  * we may fragment a message across multiple records, but we never coalesce multiple
    1230                 :            :  * messages into single records.
    1231                 :            :  * Precondition: secure outbound I/O has already been flushed
    1232                 :            :  */
    1233                 :            : static int s2n_handshake_write_io(struct s2n_connection *conn)
    1234                 :      65507 : {
    1235 [ +  + ][ +  + ]:      65507 :     uint8_t record_type = EXPECTED_RECORD_TYPE(conn);
    1236                 :      65507 :     s2n_blocked_status blocked = S2N_NOT_BLOCKED;
    1237                 :            : 
    1238                 :            :     /* Populate handshake.io with header/payload for the current state, once.
    1239                 :            :      * Check wiped instead of s2n_stuffer_data_available to differentiate between the initial call
    1240                 :            :      * to s2n_handshake_write_io and a repeated call after an EWOULDBLOCK.
    1241                 :            :      */
    1242         [ +  + ]:      65507 :     if (s2n_stuffer_is_wiped(&conn->handshake.io)) {
    1243         [ +  + ]:      55725 :         if (record_type == TLS_HANDSHAKE) {
    1244 [ -  + ][ +  + ]:      44591 :             POSIX_GUARD(s2n_handshake_write_header(&conn->handshake.io, ACTIVE_STATE(conn).message_type));
                 [ +  + ]
    1245                 :      44591 :         }
    1246 [ +  + ][ +  + ]:      55725 :         POSIX_GUARD(ACTIVE_STATE(conn).handler[conn->mode](conn));
                 [ +  + ]
    1247         [ +  + ]:      55615 :         if (record_type == TLS_HANDSHAKE) {
    1248         [ -  + ]:      44481 :             POSIX_GUARD(s2n_handshake_finish_header(&conn->handshake.io));
    1249                 :      44481 :         }
    1250                 :      55615 :     }
    1251                 :            : 
    1252         [ +  + ]:      65397 :     POSIX_GUARD_RESULT(s2n_handshake_message_send(conn, record_type, &blocked));
    1253         [ +  + ]:      55675 :     if (record_type == TLS_HANDSHAKE) {
    1254         [ -  + ]:      44541 :         POSIX_GUARD_RESULT(s2n_handshake_transcript_update(conn));
    1255                 :      44541 :     }
    1256                 :            : 
    1257                 :            :     /* We're done sending the last record, reset everything */
    1258         [ -  + ]:      55675 :     POSIX_GUARD(s2n_stuffer_wipe(&conn->out));
    1259         [ -  + ]:      55675 :     POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
    1260                 :            : 
    1261                 :            :     /* Update the secrets, if necessary */
    1262         [ -  + ]:      55675 :     POSIX_GUARD_RESULT(s2n_tls13_secrets_update(conn));
    1263         [ -  + ]:      55675 :     POSIX_GUARD_RESULT(s2n_tls13_key_schedule_update(conn));
    1264                 :            : 
    1265                 :            :     /* Advance the state machine */
    1266         [ -  + ]:      55675 :     POSIX_GUARD(s2n_advance_message(conn));
    1267                 :            : 
    1268                 :      55675 :     return S2N_SUCCESS;
    1269                 :      55675 : }
    1270                 :            : 
    1271                 :            : /*
    1272                 :            :  * Returns:
    1273                 :            :  *  1  - more data is needed to complete the handshake message.
    1274                 :            :  *  0  - we read the whole handshake message.
    1275                 :            :  * -1  - error processing the handshake message.
    1276                 :            :  */
    1277                 :            : static int s2n_read_full_handshake_message(struct s2n_connection *conn, uint8_t *message_type)
    1278                 :      51170 : {
    1279                 :      51170 :     uint32_t current_handshake_data = s2n_stuffer_data_available(&conn->handshake.io);
    1280         [ +  + ]:      51170 :     if (current_handshake_data < TLS_HANDSHAKE_HEADER_LENGTH) {
    1281                 :            :         /* The message may be so badly fragmented that we don't even read the full header, take
    1282                 :            :          * what we can and then continue to the next record read iteration.
    1283                 :            :          */
    1284         [ +  + ]:      41177 :         if (s2n_stuffer_data_available(&conn->in) < (TLS_HANDSHAKE_HEADER_LENGTH - current_handshake_data)) {
    1285         [ -  + ]:        116 :             POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
    1286                 :        116 :             return 1;
    1287                 :        116 :         }
    1288                 :            : 
    1289                 :            :         /* Get the remainder of the header */
    1290         [ -  + ]:      41061 :         POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, (TLS_HANDSHAKE_HEADER_LENGTH - current_handshake_data)));
    1291                 :      41061 :     }
    1292                 :            : 
    1293                 :      51054 :     uint32_t handshake_message_length = 0;
    1294         [ -  + ]:      51054 :     POSIX_GUARD_RESULT(s2n_handshake_parse_header(&conn->handshake.io, message_type, &handshake_message_length));
    1295                 :            : 
    1296 [ +  + ][ +  - ]:      51054 :     S2N_ERROR_IF(handshake_message_length > S2N_MAXIMUM_HANDSHAKE_MESSAGE_LENGTH, S2N_ERR_BAD_MESSAGE);
    1297                 :            : 
    1298                 :      51053 :     uint32_t bytes_to_take = handshake_message_length - s2n_stuffer_data_available(&conn->handshake.io);
    1299                 :      51053 :     bytes_to_take = MIN(bytes_to_take, s2n_stuffer_data_available(&conn->in));
    1300                 :            : 
    1301                 :            :     /* If the record is handshake data, add it to the handshake buffer */
    1302         [ -  + ]:      51053 :     POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, bytes_to_take));
    1303                 :            : 
    1304                 :            :     /* If we have the whole handshake message, then success */
    1305         [ +  + ]:      51053 :     if (s2n_stuffer_data_available(&conn->handshake.io) == handshake_message_length) {
    1306                 :      41098 :         return 0;
    1307                 :      41098 :     }
    1308                 :            : 
    1309                 :            :     /* We don't have the whole message, so we'll need to go again */
    1310         [ -  + ]:       9955 :     POSIX_GUARD(s2n_stuffer_reread(&conn->handshake.io));
    1311                 :            : 
    1312                 :       9955 :     return 1;
    1313                 :       9955 : }
    1314                 :            : 
    1315                 :            : static int s2n_handshake_handle_sslv2(struct s2n_connection *conn)
    1316                 :          3 : {
    1317 [ -  + ][ -  + ]:          3 :     S2N_ERROR_IF(ACTIVE_MESSAGE(conn) != CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
                 [ #  # ]
    1318                 :            : 
    1319                 :            :     /* Add the message to our handshake hashes */
    1320                 :          3 :     struct s2n_blob hashed = { 0 };
    1321         [ -  + ]:          3 :     POSIX_GUARD(s2n_blob_init(&hashed, conn->header_in.blob.data + 2, 3));
    1322         [ -  + ]:          3 :     POSIX_GUARD(s2n_conn_update_handshake_hashes(conn, &hashed));
    1323                 :            : 
    1324                 :          3 :     hashed.data = conn->in.blob.data;
    1325                 :          3 :     hashed.size = s2n_stuffer_data_available(&conn->in);
    1326         [ -  + ]:          3 :     POSIX_GUARD(s2n_conn_update_handshake_hashes(conn, &hashed));
    1327                 :            : 
    1328                 :            :     /* Handle an SSLv2 client hello */
    1329         [ -  + ]:          3 :     POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
    1330                 :          3 :     conn->client_hello.sslv2 = true;
    1331                 :            :     /* Execute the state machine handler */
    1332 [ -  + ][ -  + ]:          3 :     int r = ACTIVE_STATE(conn).handler[conn->mode](conn);
    1333         [ -  + ]:          3 :     POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
    1334                 :            : 
    1335                 :            :     /* We're done with the record, wipe it */
    1336         [ -  + ]:          3 :     POSIX_GUARD_RESULT(s2n_record_wipe(conn));
    1337                 :            : 
    1338 [ -  + ][ +  - ]:          3 :     WITH_ERROR_BLINDING(conn, POSIX_GUARD(r));
    1339                 :            : 
    1340                 :            :     /* Advance the state machine */
    1341         [ -  + ]:          3 :     POSIX_GUARD(s2n_advance_message(conn));
    1342                 :            : 
    1343                 :          3 :     return S2N_SUCCESS;
    1344                 :          3 : }
    1345                 :            : 
    1346                 :            : static int s2n_try_delete_session_cache(struct s2n_connection *conn)
    1347                 :       2550 : {
    1348 [ -  + ][ #  # ]:       2550 :     POSIX_ENSURE_REF(conn);
    1349                 :            : 
    1350         [ +  + ]:       2550 :     if (s2n_allowed_to_cache_connection(conn) > 0) {
    1351                 :          2 :         conn->config->cache_delete(conn, conn->config->cache_delete_data, conn->session_id, conn->session_id_len);
    1352                 :          2 :     }
    1353                 :            : 
    1354                 :       2550 :     return S2N_SUCCESS;
    1355                 :       2550 : }
    1356                 :            : 
    1357                 :            : static S2N_RESULT s2n_finish_read(struct s2n_connection *conn)
    1358                 :      40954 : {
    1359 [ #  # ][ -  + ]:      40954 :     RESULT_ENSURE_REF(conn);
    1360                 :            : 
    1361         [ -  + ]:      40954 :     RESULT_GUARD(s2n_handshake_transcript_update(conn));
    1362         [ -  + ]:      40954 :     RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->handshake.io));
    1363         [ -  + ]:      40954 :     RESULT_GUARD(s2n_tls13_secrets_update(conn));
    1364         [ -  + ]:      40954 :     RESULT_GUARD(s2n_tls13_key_schedule_update(conn));
    1365         [ -  + ]:      40954 :     RESULT_GUARD_POSIX(s2n_advance_message(conn));
    1366                 :      40954 :     return S2N_RESULT_OK;
    1367                 :      40954 : }
    1368                 :            : 
    1369                 :            : static S2N_RESULT s2n_handshake_app_data_recv(struct s2n_connection *conn)
    1370                 :         89 : {
    1371         [ +  + ]:         89 :     if (conn->early_data_expected) {
    1372         [ -  + ]:         63 :         RESULT_GUARD(s2n_early_data_validate_recv(conn));
    1373         [ +  - ]:         63 :         RESULT_BAIL(S2N_ERR_EARLY_DATA_BLOCKED);
    1374                 :         63 :     }
    1375                 :            : 
    1376         [ +  + ]:         26 :     if (conn->handshake.renegotiation) {
    1377         [ -  + ]:         25 :         RESULT_GUARD(s2n_renegotiate_validate(conn));
    1378                 :            :         /* During renegotiation, Application Data may only be received until
    1379                 :            :          * the server acknowledges the new handshake with a ServerHello.
    1380                 :            :          */
    1381 [ +  - ][ +  + ]:         25 :         RESULT_ENSURE(ACTIVE_MESSAGE(conn) == SERVER_HELLO, S2N_ERR_BAD_MESSAGE);
                 [ -  + ]
    1382         [ +  - ]:         20 :         RESULT_BAIL(S2N_ERR_APP_DATA_BLOCKED);
    1383                 :         20 :     }
    1384                 :            : 
    1385         [ +  - ]:          1 :     RESULT_BAIL(S2N_ERR_BAD_MESSAGE);
    1386                 :          1 : }
    1387                 :            : 
    1388                 :            : static int s2n_handshake_message_process(struct s2n_connection *conn, uint8_t record_type)
    1389                 :      51234 : {
    1390 [ -  + ][ #  # ]:      51234 :     POSIX_ENSURE_REF(conn);
    1391                 :            : 
    1392                 :      51234 :     uint8_t message_type = 0;
    1393         [ +  + ]:      92122 :     while (s2n_stuffer_data_available(&conn->in)) {
    1394                 :            :         /* We're done with negotiating but we have trailing data in this record. Bail on the handshake. */
    1395 [ -  + ][ +  + ]:      51170 :         S2N_ERROR_IF(EXPECTED_RECORD_TYPE(conn) == TLS_APPLICATION_DATA, S2N_ERR_BAD_MESSAGE);
         [ +  + ][ #  # ]
    1396                 :      51170 :         int r = 0;
    1397         [ +  + ]:      51170 :         POSIX_GUARD((r = s2n_read_full_handshake_message(conn, &message_type)));
    1398                 :            : 
    1399                 :            :         /* Do we need more data? This happens for message fragmentation */
    1400         [ +  + ]:      51169 :         if (r == 1) {
    1401                 :            :             /* Break out of this inner loop, but since we're not changing the state, the
    1402                 :            :              * outer loop in s2n_handshake_io() will read another record.
    1403                 :            :              */
    1404         [ -  + ]:      10071 :             POSIX_GUARD_RESULT(s2n_record_wipe(conn));
    1405                 :      10071 :             return S2N_SUCCESS;
    1406                 :      10071 :         }
    1407                 :            : 
    1408         [ +  + ]:      41098 :         if (conn->mode == S2N_CLIENT) {
    1409                 :      26535 :             s2n_cert_auth_type client_cert_auth_type = { 0 };
    1410         [ -  + ]:      26535 :             POSIX_GUARD(s2n_connection_get_client_auth_type(conn, &client_cert_auth_type));
    1411                 :            :             /* If client auth is optional, we initially assume it will not be requested.
    1412                 :            :              * If we received a request, switch to a client auth handshake.
    1413                 :            :              */
    1414 [ +  + ][ +  + ]:      26535 :             if (client_cert_auth_type != S2N_CERT_AUTH_REQUIRED && message_type == TLS_CERT_REQ) {
    1415 [ +  - ][ +  + ]:        101 :                 POSIX_ENSURE(client_cert_auth_type == S2N_CERT_AUTH_OPTIONAL, S2N_ERR_UNEXPECTED_CERT_REQUEST);
    1416 [ -  + ][ #  # ]:         93 :                 POSIX_ENSURE(IS_FULL_HANDSHAKE(conn), S2N_ERR_HANDSHAKE_STATE);
    1417         [ -  + ]:         93 :                 POSIX_GUARD_RESULT(s2n_handshake_type_set_flag(conn, CLIENT_AUTH));
    1418                 :         93 :             }
    1419                 :            : 
    1420                 :            :             /* According to rfc6066 section 8, the server may choose not to send a "CertificateStatus"
    1421                 :            :              * message even if it has sent a "status_request" extension in the ServerHello message.
    1422                 :            :              */
    1423 [ +  + ][ +  + ]:      26527 :             if (EXPECTED_MESSAGE_TYPE(conn) == TLS_SERVER_CERT_STATUS
                 [ +  + ]
    1424         [ -  + ]:      26527 :                     && message_type != TLS_SERVER_CERT_STATUS) {
    1425         [ #  # ]:          0 :                 POSIX_GUARD_RESULT(s2n_handshake_type_unset_tls12_flag(conn, OCSP_STATUS));
    1426                 :          0 :             }
    1427                 :      26527 :         }
    1428                 :            : 
    1429                 :            :         /*
    1430                 :            :          *= https://www.rfc-editor.org/rfc/rfc5246#section-7.4
    1431                 :            :          *# The one message that is not bound by these ordering rules
    1432                 :            :          *# is the HelloRequest message, which can be sent at any time, but which
    1433                 :            :          *# SHOULD be ignored by the client if it arrives in the middle of a handshake.
    1434                 :            :          */
    1435         [ +  + ]:      41090 :         if (message_type == TLS_HELLO_REQUEST) {
    1436         [ +  + ]:          3 :             POSIX_GUARD_RESULT(s2n_client_hello_request_validate(conn));
    1437         [ -  + ]:          2 :             POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
    1438                 :          2 :             continue;
    1439                 :          2 :         }
    1440                 :            : 
    1441                 :            :         /* Check for missing Certificate Requests to surface a more specific error */
    1442 [ +  + ][ +  + ]:      41087 :         if (EXPECTED_MESSAGE_TYPE(conn) == TLS_CERT_REQ) {
                 [ +  + ]
    1443 [ #  # ][ -  + ]:        186 :             POSIX_ENSURE(message_type == TLS_CERT_REQ,
    1444                 :        186 :                     S2N_ERR_MISSING_CERT_REQUEST);
    1445                 :        186 :         }
    1446                 :            : 
    1447 [ -  + ][ #  # ]:      41087 :         POSIX_ENSURE(record_type == EXPECTED_RECORD_TYPE(conn), S2N_ERR_BAD_MESSAGE);
         [ +  + ][ +  + ]
    1448 [ +  + ][ +  - ]:      41087 :         POSIX_ENSURE(message_type == EXPECTED_MESSAGE_TYPE(conn), S2N_ERR_BAD_MESSAGE);
         [ +  + ][ +  + ]
    1449 [ -  + ][ #  # ]:      41084 :         POSIX_ENSURE(!CONNECTION_IS_WRITER(conn), S2N_ERR_BAD_MESSAGE);
         [ +  + ][ +  + ]
                 [ +  + ]
    1450                 :            : 
    1451                 :            :         /* Call the relevant handler */
    1452 [ +  + ][ +  + ]:      41084 :         WITH_ERROR_BLINDING(conn, POSIX_GUARD(ACTIVE_STATE(conn).handler[conn->mode](conn)));
         [ +  + ][ +  - ]
    1453                 :            : 
    1454                 :            :         /* Advance the state machine */
    1455         [ -  + ]:      40886 :         POSIX_GUARD_RESULT(s2n_finish_read(conn));
    1456                 :      40886 :     }
    1457                 :            : 
    1458                 :            :     /* We're done with the record, wipe it */
    1459         [ -  + ]:      40952 :     POSIX_GUARD_RESULT(s2n_record_wipe(conn));
    1460                 :            : 
    1461                 :      40952 :     return S2N_SUCCESS;
    1462                 :      40952 : }
    1463                 :            : 
    1464                 :            : /* Reading is a little more complicated than writing as the TLS RFCs allow content
    1465                 :            :  * types to be interleaved at the record layer. We may get an alert message
    1466                 :            :  * during the handshake phase, or messages of types that we don't support (e.g.
    1467                 :            :  * HEARTBEAT messages), or during renegotiations we may even get application
    1468                 :            :  * data messages that need to be handled by the application.
    1469                 :            :  */
    1470                 :            : static int s2n_handshake_read_io(struct s2n_connection *conn)
    1471                 :     187158 : {
    1472                 :     187158 :     uint8_t record_type = 0;
    1473                 :     187158 :     int isSSLv2 = 0;
    1474                 :            : 
    1475                 :            :     /* Fill conn->in stuffer necessary for the handshake.
    1476                 :            :      * If using TCP, read a record. If using QUIC, read a message. */
    1477         [ +  + ]:     187158 :     if (s2n_connection_is_quic_enabled(conn)) {
    1478                 :         62 :         record_type = TLS_HANDSHAKE;
    1479                 :         62 :         uint8_t message_type = 0;
    1480         [ +  + ]:         62 :         POSIX_GUARD_RESULT(s2n_quic_read_handshake_message(conn, &message_type));
    1481                 :     187096 :     } else {
    1482                 :     187096 :         int r = s2n_read_full_record(conn, &record_type, &isSSLv2);
    1483                 :            : 
    1484                 :            :         /**
    1485                 :            :          *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.10
    1486                 :            :          *# If the client attempts a 0-RTT handshake but the server
    1487                 :            :          *# rejects it, the server will generally not have the 0-RTT record
    1488                 :            :          *# protection keys and must instead use trial decryption (either with
    1489                 :            :          *# the 1-RTT handshake keys or by looking for a cleartext ClientHello in
    1490                 :            :          *# the case of a HelloRetryRequest) to find the first non-0-RTT message.
    1491                 :            :          *#
    1492                 :            :          *# If the server chooses to accept the "early_data" extension, then it
    1493                 :            :          *# MUST comply with the same error-handling requirements specified for
    1494                 :            :          *# all records when processing early data records.  Specifically, if the
    1495                 :            :          *# server fails to decrypt a 0-RTT record following an accepted
    1496                 :            :          *# "early_data" extension, it MUST terminate the connection with a
    1497                 :            :          *# "bad_record_mac" alert as per Section 5.2.
    1498                 :            :          */
    1499 [ +  + ][ +  + ]:     187096 :         if ((r < S2N_SUCCESS) && (s2n_errno == S2N_ERR_EARLY_DATA_TRIAL_DECRYPT)) {
    1500         [ -  + ]:        505 :             POSIX_GUARD(s2n_stuffer_reread(&conn->in));
    1501         [ +  + ]:        505 :             POSIX_GUARD_RESULT(s2n_early_data_record_bytes(conn, s2n_stuffer_data_available(&conn->in)));
    1502         [ -  + ]:        504 :             POSIX_GUARD_RESULT(s2n_record_wipe(conn));
    1503                 :        504 :             return S2N_SUCCESS;
    1504                 :        504 :         }
    1505         [ +  + ]:     186591 :         POSIX_GUARD(r);
    1506                 :     186591 :     }
    1507                 :            : 
    1508         [ +  + ]:      63853 :     if (isSSLv2) {
    1509 [ -  + ][ #  # ]:          3 :         S2N_ERROR_IF(record_type != SSLv2_CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
    1510         [ -  + ]:          3 :         POSIX_GUARD(s2n_handshake_handle_sslv2(conn));
    1511                 :          3 :     }
    1512                 :            : 
    1513                 :            :     /* Now we have a record, but it could be a partial fragment of a message, or it might
    1514                 :            :      * contain several messages.
    1515                 :            :      */
    1516                 :            : 
    1517         [ +  + ]:      63853 :     if (record_type == TLS_APPLICATION_DATA) {
    1518         [ +  - ]:         89 :         POSIX_GUARD_RESULT(s2n_handshake_app_data_recv(conn));
    1519         [ +  + ]:      63764 :     } else if (record_type == TLS_CHANGE_CIPHER_SPEC) {
    1520                 :            :         /* TLS1.3 can receive unexpected CCS messages at any point in the handshake
    1521                 :            :          * due to a peer operating in middlebox compatibility mode.
    1522                 :            :          * However, when operating in QUIC mode, S2N should not accept ANY CCS messages,
    1523                 :            :          * including these unexpected ones.*/
    1524 [ +  + ][ -  + ]:      11081 :         if (!IS_TLS13_HANDSHAKE(conn) || s2n_connection_is_quic_enabled(conn)) {
    1525 [ #  # ][ -  + ]:       3622 :             POSIX_ENSURE(EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC, S2N_ERR_BAD_MESSAGE);
         [ -  + ][ -  + ]
    1526 [ -  + ][ #  # ]:       3622 :             POSIX_ENSURE(!CONNECTION_IS_WRITER(conn), S2N_ERR_BAD_MESSAGE);
         [ -  + ][ -  + ]
                 [ +  + ]
    1527                 :       3622 :         }
    1528                 :            : 
    1529 [ -  + ][ #  # ]:      11081 :         S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) != 1, S2N_ERR_BAD_MESSAGE);
    1530                 :            : 
    1531         [ -  + ]:      11081 :         POSIX_GUARD(s2n_stuffer_copy(&conn->in, &conn->handshake.io, s2n_stuffer_data_available(&conn->in)));
    1532 [ -  + ][ +  + ]:      11081 :         POSIX_GUARD(CCS_STATE(conn).handler[conn->mode](conn));
         [ +  + ][ +  + ]
    1533         [ -  + ]:      11081 :         POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
    1534                 :            : 
    1535                 :            :         /* We're done with the record, wipe it */
    1536         [ -  + ]:      11081 :         POSIX_GUARD_RESULT(s2n_record_wipe(conn));
    1537                 :            : 
    1538                 :            :         /* Advance the state machine if this was an expected message */
    1539 [ +  + ][ +  + ]:      11081 :         if (EXPECTED_RECORD_TYPE(conn) == TLS_CHANGE_CIPHER_SPEC && !CONNECTION_IS_WRITER(conn)) {
         [ +  + ][ -  + ]
         [ -  + ][ +  + ]
                 [ +  - ]
    1540         [ -  + ]:       3622 :             POSIX_GUARD(s2n_advance_message(conn));
    1541                 :       3622 :         }
    1542                 :            : 
    1543                 :      11081 :         return S2N_SUCCESS;
    1544         [ +  + ]:      52683 :     } else if (record_type != TLS_HANDSHAKE) {
    1545         [ +  + ]:       1517 :         if (record_type == TLS_ALERT) {
    1546         [ +  + ]:       1511 :             POSIX_GUARD(s2n_process_alert_fragment(conn));
    1547                 :       1511 :         }
    1548                 :            : 
    1549                 :            :         /* Ignore record types that we don't support */
    1550                 :            : 
    1551                 :            :         /* We're done with the record, wipe it */
    1552         [ -  + ]:         11 :         POSIX_GUARD_RESULT(s2n_record_wipe(conn));
    1553                 :         11 :         return S2N_SUCCESS;
    1554                 :         11 :     }
    1555                 :            : 
    1556                 :            :     /* Record is a handshake message */
    1557 [ -  + ][ #  # ]:      51166 :     S2N_ERROR_IF(s2n_stuffer_data_available(&conn->in) == 0, S2N_ERR_BAD_MESSAGE);
    1558         [ +  + ]:      51166 :     POSIX_GUARD(s2n_handshake_message_process(conn, record_type));
    1559                 :            : 
    1560                 :      50955 :     return S2N_SUCCESS;
    1561                 :      51166 : }
    1562                 :            : 
    1563                 :            : static int s2n_handle_retry_state(struct s2n_connection *conn)
    1564                 :        249 : {
    1565                 :            :     /* If we were blocked reading or writing a record, then the handler is waiting on
    1566                 :            :      * external data. The handler will know how to continue, so we should call the
    1567                 :            :      * handler right away. We aren't going to read more handshake data yet or proceed
    1568                 :            :      * to the next handler because the current message has not finished processing. */
    1569                 :        249 :     s2n_errno = S2N_ERR_OK;
    1570 [ +  + ][ +  + ]:        249 :     const int r = ACTIVE_STATE(conn).handler[conn->mode](conn);
    1571                 :            : 
    1572 [ +  + ][ +  + ]:        249 :     if (r < S2N_SUCCESS && S2N_ERROR_IS_BLOCKING(s2n_errno)) {
    1573                 :            :         /* If the handler is still waiting for data, return control to the caller. */
    1574                 :        109 :         S2N_ERROR_PRESERVE_ERRNO();
    1575                 :        109 :     }
    1576                 :            : 
    1577                 :            :     /* Resume the handshake */
    1578                 :        140 :     conn->handshake.paused = false;
    1579                 :            : 
    1580 [ +  + ][ +  + ]:        140 :     if (CONNECTION_IS_WRITER(conn)) {
         [ +  + ][ +  + ]
    1581         [ -  + ]:         67 :         POSIX_GUARD(r);
    1582                 :            : 
    1583                 :            :         /* If we're the writer and handler just finished, update the record header if
    1584                 :            :          * needed and let the s2n_handshake_write_io write the data to the socket */
    1585 [ +  - ][ +  + ]:         67 :         if (EXPECTED_RECORD_TYPE(conn) == TLS_HANDSHAKE) {
                 [ +  + ]
    1586         [ -  + ]:         67 :             POSIX_GUARD(s2n_handshake_finish_header(&conn->handshake.io));
    1587                 :         67 :         }
    1588                 :         73 :     } else {
    1589 [ +  + ][ +  - ]:         73 :         if (r < S2N_SUCCESS && conn->session_id_len) {
    1590                 :          5 :             s2n_try_delete_session_cache(conn);
    1591                 :          5 :         }
    1592 [ +  + ][ +  - ]:         73 :         WITH_ERROR_BLINDING(conn, POSIX_GUARD(r));
    1593                 :            : 
    1594                 :            :         /* The read handler processed the message successfully, we are done with this
    1595                 :            :          * message. Advance the state machine. */
    1596         [ -  + ]:         68 :         POSIX_GUARD_RESULT(s2n_finish_read(conn));
    1597                 :            : 
    1598                 :            :         /* We may need to handle remaining handshake messages in the record */
    1599         [ -  + ]:         68 :         POSIX_GUARD(s2n_handshake_message_process(conn, TLS_HANDSHAKE));
    1600                 :         68 :     }
    1601                 :            : 
    1602                 :        135 :     return S2N_SUCCESS;
    1603                 :        140 : }
    1604                 :            : 
    1605                 :            : static S2N_RESULT s2n_set_blocked_error_from_errno(struct s2n_connection *conn, s2n_blocked_status *blocked)
    1606                 :     134537 : {
    1607 [ #  # ][ -  + ]:     134537 :     RESULT_ENSURE_REF(conn);
    1608 [ #  # ][ -  + ]:     134537 :     RESULT_ENSURE_REF(blocked);
    1609                 :            : 
    1610         [ +  + ]:     134537 :     if (s2n_errno == S2N_ERR_ASYNC_BLOCKED) {
    1611                 :        253 :         *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
    1612                 :        253 :         conn->handshake.paused = true;
    1613         [ +  + ]:     134284 :     } else if (s2n_errno == S2N_ERR_EARLY_DATA_BLOCKED) {
    1614                 :        103 :         *blocked = S2N_BLOCKED_ON_EARLY_DATA;
    1615                 :        103 :     }
    1616                 :            : 
    1617                 :     134537 :     return S2N_RESULT_OK;
    1618                 :     134537 : }
    1619                 :            : 
    1620                 :            : bool s2n_handshake_is_complete(struct s2n_connection *conn)
    1621                 :     295702 : {
    1622                 :            :     /* A deserialized connection implies that the handshake is complete because
    1623                 :            :      * connections cannot be serialized before completing the handshake. */
    1624 [ +  - ][ +  + ]:     295702 :     return conn && (ACTIVE_STATE(conn).writer == 'B' || conn->deserialized_conn);
         [ +  + ][ +  + ]
                 [ +  + ]
    1625                 :     295702 : }
    1626                 :            : 
    1627                 :            : int s2n_negotiate_impl(struct s2n_connection *conn, s2n_blocked_status *blocked)
    1628                 :     171950 : {
    1629 [ -  + ][ #  # ]:     171950 :     POSIX_ENSURE_REF(conn);
    1630 [ +  + ][ +  - ]:     171950 :     POSIX_ENSURE_REF(blocked);
    1631                 :            : 
    1632 [ +  + ][ +  + ]:     291597 :     while (!s2n_handshake_is_complete(conn) && ACTIVE_MESSAGE(conn) != conn->handshake.end_of_messages) {
                 [ +  + ]
    1633                 :     275394 :         errno = 0;
    1634                 :     275394 :         s2n_errno = S2N_ERR_OK;
    1635                 :            : 
    1636                 :            :         /* Flush any pending I/O or alert messages */
    1637         [ +  + ]:     275394 :         POSIX_GUARD(s2n_flush(conn, blocked));
    1638                 :            : 
    1639 [ +  - ][ +  + ]:     255935 :         POSIX_ENSURE(s2n_connection_check_io_status(conn, S2N_IO_FULL_DUPLEX), S2N_ERR_CLOSED);
    1640                 :            : 
    1641                 :            :         /* If the handshake was paused, retry the current message */
    1642         [ +  + ]:     254431 :         if (conn->handshake.paused) {
    1643                 :        275 :             *blocked = S2N_BLOCKED_ON_APPLICATION_INPUT;
    1644                 :        275 :             const int retry_result = s2n_handle_retry_state(conn);
    1645         [ +  + ]:        275 :             if (retry_result != S2N_SUCCESS) {
    1646         [ -  + ]:        137 :                 POSIX_GUARD_RESULT(s2n_set_blocked_error_from_errno(conn, blocked));
    1647                 :        137 :                 S2N_ERROR_PRESERVE_ERRNO();
    1648                 :        137 :             }
    1649                 :            : 
    1650                 :        138 :             continue;
    1651                 :        275 :         }
    1652                 :            : 
    1653 [ +  + ][ +  + ]:     254156 :         if (CONNECTION_IS_WRITER(conn)) {
         [ +  + ][ +  + ]
    1654                 :      66185 :             *blocked = S2N_BLOCKED_ON_WRITE;
    1655                 :      66185 :             const int write_result = s2n_handshake_write_io(conn);
    1656                 :            : 
    1657         [ +  + ]:      66185 :             if (write_result < S2N_SUCCESS) {
    1658         [ +  + ]:       9839 :                 if (!S2N_ERROR_IS_BLOCKING(s2n_errno)) {
    1659                 :            :                     /* Non-retryable write error. The peer might have sent an alert. Try and read it. */
    1660                 :         13 :                     const int write_errno = errno;
    1661                 :         13 :                     const int write_s2n_errno = s2n_errno;
    1662                 :         13 :                     struct s2n_debug_info write_s2n_debug_info = _s2n_debug_info;
    1663                 :            : 
    1664 [ +  - ][ +  + ]:         13 :                     if (s2n_handshake_read_io(conn) < 0 && s2n_errno == S2N_ERR_ALERT) {
    1665                 :            :                         /* s2n_handshake_read_io has set s2n_errno */
    1666                 :          1 :                         S2N_ERROR_PRESERVE_ERRNO();
    1667                 :         12 :                     } else {
    1668                 :            :                         /* Let the write error take precedence if we didn't read an alert. */
    1669                 :         12 :                         errno = write_errno;
    1670                 :         12 :                         s2n_errno = write_s2n_errno;
    1671                 :         12 :                         _s2n_debug_info = write_s2n_debug_info;
    1672                 :         12 :                         S2N_ERROR_PRESERVE_ERRNO();
    1673                 :         12 :                     }
    1674                 :         13 :                 }
    1675                 :            : 
    1676         [ -  + ]:       9826 :                 POSIX_GUARD_RESULT(s2n_set_blocked_error_from_errno(conn, blocked));
    1677                 :            : 
    1678                 :       9826 :                 S2N_ERROR_PRESERVE_ERRNO();
    1679                 :       9826 :             }
    1680                 :     187971 :         } else {
    1681                 :     187971 :             *blocked = S2N_BLOCKED_ON_READ;
    1682                 :     187971 :             const int read_result = s2n_handshake_read_io(conn);
    1683                 :            : 
    1684         [ +  + ]:     187971 :             if (read_result < S2N_SUCCESS) {
    1685                 :            :                 /* One blocking condition is waiting on the session resumption cache. */
    1686                 :            :                 /* So we don't want to delete anything if we are blocked. */
    1687 [ +  + ][ +  + ]:     124807 :                 if (!S2N_ERROR_IS_BLOCKING(s2n_errno) && conn->session_id_len) {
    1688                 :       2567 :                     s2n_try_delete_session_cache(conn);
    1689                 :       2567 :                 }
    1690                 :            : 
    1691         [ -  + ]:     124807 :                 POSIX_GUARD_RESULT(s2n_set_blocked_error_from_errno(conn, blocked));
    1692                 :            : 
    1693                 :     124807 :                 S2N_ERROR_PRESERVE_ERRNO();
    1694                 :     124807 :             }
    1695                 :     187971 :         }
    1696                 :     254156 :     }
    1697                 :            : 
    1698 [ +  + ][ +  + ]:      16203 :     if (ACTIVE_STATE(conn).writer == 'B') {
                 [ +  + ]
    1699                 :            :         /* Clean up handshake secrets */
    1700         [ -  + ]:      10876 :         POSIX_GUARD_RESULT(s2n_tls13_secrets_clean(conn));
    1701                 :            : 
    1702                 :            :         /* Send any pending post-handshake messages */
    1703         [ -  + ]:      10876 :         POSIX_GUARD(s2n_post_handshake_send(conn, blocked));
    1704                 :            : 
    1705                 :            :         /* If the handshake has just ended, free up memory */
    1706         [ -  + ]:      10876 :         POSIX_GUARD(s2n_stuffer_resize(&conn->handshake.io, 0));
    1707                 :      10876 :     }
    1708                 :            : 
    1709                 :      16203 :     *blocked = S2N_NOT_BLOCKED;
    1710                 :            : 
    1711                 :      16203 :     return S2N_SUCCESS;
    1712                 :      16203 : }
    1713                 :            : 
    1714                 :            : int s2n_negotiate(struct s2n_connection *conn, s2n_blocked_status *blocked)
    1715                 :     171952 : {
    1716 [ +  - ][ +  + ]:     171952 :     POSIX_ENSURE_REF(conn);
    1717 [ +  - ][ +  + ]:     171951 :     POSIX_ENSURE(!conn->negotiate_in_use, S2N_ERR_REENTRANCY);
    1718                 :     171950 :     conn->negotiate_in_use = true;
    1719                 :            : 
    1720                 :            :     /* We use the default monotonic clock so that we can avoid referencing any
    1721                 :            :      * item on the config until after the client hello callback is invoked. */
    1722                 :     171950 :     uint64_t negotiate_start = 0;
    1723         [ -  + ]:     171950 :     POSIX_GUARD(s2n_default_monotonic_clock(NULL, &negotiate_start));
    1724         [ +  + ]:     171950 :     if (conn->handshake_event.handshake_start_ns == 0) {
    1725                 :      14090 :         conn->handshake_event.handshake_start_ns = negotiate_start;
    1726                 :      14090 :     }
    1727                 :            : 
    1728                 :     171950 :     int result = s2n_negotiate_impl(conn, blocked);
    1729                 :            : 
    1730                 :            :     /* finish up sending and receiving */
    1731         [ -  + ]:     171950 :     POSIX_GUARD_RESULT(s2n_connection_dynamic_free_in_buffer(conn));
    1732         [ -  + ]:     171950 :     POSIX_GUARD_RESULT(s2n_connection_dynamic_free_out_buffer(conn));
    1733                 :            : 
    1734                 :     171950 :     uint64_t negotiate_end = 0;
    1735         [ -  + ]:     171950 :     POSIX_GUARD(s2n_default_monotonic_clock(NULL, &negotiate_end));
    1736                 :     171950 :     conn->handshake_event.handshake_time_ns += negotiate_end - negotiate_start;
    1737                 :            : 
    1738         [ +  + ]:     171950 :     if (result == S2N_SUCCESS) {
    1739                 :      16203 :         conn->handshake_event.handshake_end_ns = negotiate_end;
    1740         [ -  + ]:      16203 :         POSIX_GUARD_RESULT(s2n_event_handshake_populate(conn, &conn->handshake_event));
    1741         [ -  + ]:      16203 :         POSIX_GUARD_RESULT(s2n_event_handshake_send(conn, &conn->handshake_event));
    1742                 :      16203 :     }
    1743                 :            : 
    1744                 :     171950 :     conn->negotiate_in_use = false;
    1745                 :     171950 :     return result;
    1746                 :     171950 : }

Generated by: LCOV version 1.14