tls_client_fsm.c
Go to the documentation of this file.
1 /**
2  * @file tls_client_fsm.c
3  * @brief TLS state machine (TLS client)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneSSL Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.5.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls.h"
36 #include "tls_handshake.h"
37 #include "tls_client.h"
38 #include "tls_client_fsm.h"
39 #include "tls_common.h"
40 #include "tls_record.h"
41 #include "tls_misc.h"
42 #include "tls13_client.h"
43 #include "tls13_client_misc.h"
44 #include "tls13_common.h"
45 #include "tls13_key_material.h"
46 #include "debug.h"
47 
48 //Check TLS library configuration
49 #if (TLS_SUPPORT == ENABLED && TLS_CLIENT_SUPPORT == ENABLED)
50 
51 
52 /**
53  * @brief TLS client handshake
54  * @param[in] context Pointer to the TLS context
55  * @return Error code
56  **/
57 
59 {
60  error_t error;
61 
62  //Initialize status code
63  error = NO_ERROR;
64 
65  //Wait for the handshake to complete
66  while(!error)
67  {
68  //TLS protocol?
69  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM)
70  {
71  //Check current state
72  if(context->state != TLS_STATE_INIT &&
73  context->state != TLS_STATE_CLOSED)
74  {
75  //Flush send buffer
76  error = tlsWriteProtocolData(context, NULL, 0, TLS_TYPE_NONE);
77  //Any error to report?
78  if(error)
79  break;
80  }
81  }
82 
83  //Check whether the handshake is complete
84  if(context->state == TLS_STATE_APPLICATION_DATA)
85  {
86  //At this is point, the handshake is complete and the client starts
87  //to exchange application-layer data
88  break;
89  }
90 
91  //The TLS handshake is implemented as a state machine representing the
92  //current location in the protocol
93  switch(context->state)
94  {
95  //Initial state?
96  case TLS_STATE_INIT:
97  //TLS handshake initialization
98  error = tlsInitHandshake(context);
99  break;
100 
101  //Sending ClientHello message?
104  //When a client first connects to a server, it is required to send
105  //the ClientHello as its first message
106  error = tlsSendClientHello(context);
107  break;
108 
109  //Sending Certificate message?
111  //This is the first message the client can send after receiving a
112  //ServerHelloDone message. This message is only sent if the server
113  //requests a certificate
114  error = tlsSendCertificate(context);
115  break;
116 
117  //Sending CertificateVerify message?
119  //This message is used to provide explicit verification of a client
120  //certificate. This message is only sent following a client certificate
121  //that has signing capability. When sent, it must immediately follow
122  //the clientKeyExchange message
123  error = tlsSendCertificateVerify(context);
124  break;
125 
126  //Sending ChangeCipherSpec message?
129  //The ChangeCipherSpec message is sent by the client and to notify the
130  //server that subsequent records will be protected under the newly
131  //negotiated CipherSpec and keys
132  error = tlsSendChangeCipherSpec(context);
133  break;
134 
135  //Sending Finished message?
137  //A Finished message is always sent immediately after a ChangeCipherSpec
138  //message to verify that the key exchange and authentication processes
139  //were successful
140  error = tlsSendFinished(context);
141  break;
142 
143 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
144  //Sending ClientKeyExchange message?
146  //This message is always sent by the client. It must immediately
147  //follow the client certificate message, if it is sent. Otherwise,
148  //it must be the first message sent by the client after it receives
149  //the ServerHelloDone message
150  error = tlsSendClientKeyExchange(context);
151  break;
152 #endif
153 
154 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
155  //Sending EndOfEarlyData message?
157  //The EndOfEarlyData message indicates that all 0-RTT application
158  //data messages, if any, have been transmitted and that the following
159  //records are protected under handshake traffic keys
160  error = tls13SendEndOfEarlyData(context);
161  break;
162 
163  //Handshake traffic key generation?
165  //Compute handshake traffic keys
166  error = tls13GenerateHandshakeTrafficKeys(context);
167  break;
168 
169  //Server application traffic key generation?
171  //Compute server application traffic keys
172  error = tls13GenerateServerAppTrafficKeys(context);
173  break;
174 
175  //Client application traffic key generation?
177  //Compute client application traffic keys
178  error = tls13GenerateClientAppTrafficKeys(context);
179  break;
180 
181  //Sending KeyUpdate message?
183  //The KeyUpdate handshake message is used to indicate that the sender
184  //is updating its sending cryptographic keys
185  error = tls13SendKeyUpdate(context);
186  break;
187 #endif
188 
189  //Waiting for a message from the server?
202  //Receive server's message
203  error = tlsReceiveHandshakeMessage(context);
204  break;
205 
206  //Sending Alert message?
207  case TLS_STATE_CLOSING:
208  //Mark the TLS connection as closed
210  break;
211 
212  //TLS connection closed?
213  case TLS_STATE_CLOSED:
214  //Debug message
215  TRACE_WARNING("TLS handshake failure!\r\n");
216  //Report an error
217  error = ERROR_HANDSHAKE_FAILED;
218  break;
219 
220  //Invalid state?
221  default:
222  //Report an error
223  error = ERROR_UNEXPECTED_STATE;
224  break;
225  }
226 
227 #if (TLS_RTOS_SUPPORT == DISABLED)
228  //Force TLS to operate in non-blocking mode
229  if(error == NO_ERROR && context->state < TLS_STATE_APPLICATION_DATA)
230  {
231  error = ERROR_WOULD_BLOCK;
232  break;
233  }
234 #endif
235  }
236 
237  //Any error to report?
238  if(error)
239  {
240  //Send an alert message to the server, if applicable
241  tlsProcessError(context, error);
242  }
243 
244  //Return status code
245  return error;
246 }
247 
248 
249 /**
250  * @brief Parse server's handshake message
251  * @param[in] context Pointer to the TLS context
252  * @param[in] msgType Handshake message type
253  * @param[in] message Pointer to the handshake message to parse
254  * @param[in] length Length of the handshake messaged
255  * @return Error code
256  **/
257 
259  const void *message, size_t length)
260 {
261  error_t error;
262 
263  //Check handshake message type
264  switch(msgType)
265  {
266  //HelloRequest message received?
268  //HelloRequest is a simple notification that the client should begin the
269  //negotiation process anew
270  error = tlsParseHelloRequest(context, message, length);
271  break;
272 
273  //ServerHello message received?
275 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
276  //For backward compatibility with middleboxes the HelloRetryRequest
277  //message uses the same structure as the ServerHello, but with Random
278  //field set to a special value
280  {
281  //The server sends a HelloRetryRequest message if the ClientHello
282  //message does not contain sufficient information to proceed with
283  //the handshake
284  error = tls13ParseHelloRetryRequest(context, message, length);
285  }
286  else
287 #endif
288  {
289  //The server will send this message in response to a ClientHello
290  //message when it was able to find an acceptable set of algorithms
291  error = tlsParseServerHello(context, message, length);
292  }
293 
294  break;
295 
296  //Certificate message received?
298  //The server must send a Certificate message whenever the agreed-upon
299  //key exchange method uses certificates for authentication. This message
300  //will always immediately follow the ServerHello message
301  error = tlsParseCertificate(context, message, length);
302  break;
303 
304  //CertificateRequest message received?
306  //A non-anonymous server can optionally request a certificate from the
307  //client, if appropriate for the selected cipher suite. This message,
308  //if sent, will immediately follow the ServerKeyExchange message
309  error = tlsParseCertificateRequest(context, message, length);
310  break;
311 
312  //NewSessionTicket message received?
314 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
315  //TLS 1.3 currently selected?
316  if(context->version == TLS_VERSION_1_3)
317  {
318  //At any time after the server has received the client Finished
319  //message, it may send a NewSessionTicket message
320  error = tls13ParseNewSessionTicket(context, message, length);
321  }
322  else
323 #endif
324  {
325  //The NewSessionTicket message is sent by the server during the TLS
326  //handshake before the ChangeCipherSpec message
327  error = tlsParseNewSessionTicket(context, message, length);
328  }
329 
330  break;
331 
332  //Finished message received?
333  case TLS_TYPE_FINISHED:
334  //A Finished message is always sent immediately after a ChangeCipherSpec
335  //message to verify that the key exchange and authentication processes
336  //were successful
337  error = tlsParseFinished(context, message, length);
338  break;
339 
340 #if (DTLS_SUPPORT == ENABLED)
341  //HelloVerifyRequest message received?
343  //When the client sends its ClientHello message to the server, the server
344  //may respond with a HelloVerifyRequest message
345  error = dtlsParseHelloVerifyRequest(context, message, length);
346  break;
347 #endif
348 
349 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
350  //ServerKeyExchange message received?
352  //The ServerKeyExchange message is sent by the server only when the
353  //server Certificate message (if sent) does not contain enough data
354  //to allow the client to exchange a premaster secret
355  error = tlsParseServerKeyExchange(context, message, length);
356  break;
357 
358  //ServerHelloDone message received?
360  //The ServerHelloDone message is sent by the server to indicate the end
361  //of the ServerHello and associated messages
362  error = tlsParseServerHelloDone(context, message, length);
363  break;
364 #endif
365 
366 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
367  //EncryptedExtensions message received?
369  //The server sends the EncryptedExtensions message immediately after
370  //the ServerHello message. The EncryptedExtensions message contains
371  //extensions that can be protected
372  error = tls13ParseEncryptedExtensions(context, message, length);
373  break;
374 
375  //CertificateVerify message received?
377  //Servers must send this message when authenticating via a certificate.
378  //When sent, this message must appear immediately after the Certificate
379  //message
380  error = tlsParseCertificateVerify(context, message, length);
381  break;
382 
383  //KeyUpdate message received?
384  case TLS_TYPE_KEY_UPDATE:
385  //The KeyUpdate handshake message is used to indicate that the server
386  //is updating its sending cryptographic keys. This message can be sent
387  //by the server after it has sent a Finished message
388  error = tls13ParseKeyUpdate(context, message, length);
389  break;
390 #endif
391 
392  //Invalid handshake message received?
393  default:
394  //Report an error
395  error = ERROR_UNEXPECTED_MESSAGE;
396  }
397 
398  //Return status code
399  return error;
400 }
401 
402 #endif
error_t tlsParseHelloRequest(TlsContext *context, const TlsHelloRequest *message, size_t length)
Parse HelloRequest message.
Definition: tls_client.c:886
TLS helper functions.
@ ERROR_WOULD_BLOCK
Definition: error.h:96
error_t tls13GenerateHandshakeTrafficKeys(TlsContext *context)
Compute handshake traffic keys.
error_t tlsSendChangeCipherSpec(TlsContext *context)
Send ChangeCipherSpec message.
Definition: tls_common.c:273
TLS handshake.
@ TLS_STATE_SERVER_KEY_EXCHANGE
Definition: tls.h:1550
@ TLS_TYPE_SERVER_HELLO_DONE
Definition: tls.h:1097
error_t tlsSendCertificate(TlsContext *context)
Send Certificate message.
Definition: tls_common.c:66
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
uint8_t message[]
Definition: chap.h:154
error_t tlsPerformClientHandshake(TlsContext *context)
TLS client handshake.
@ TLS_STATE_CERTIFICATE_REQUEST
Definition: tls.h:1552
Handshake message processing (TLS 1.3 client and server)
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1568
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:234
@ TLS_STATE_SERVER_APP_TRAFFIC_KEYS
Definition: tls.h:1565
error_t tlsReceiveHandshakeMessage(TlsContext *context)
Receive peer's message.
error_t tls13ParseEncryptedExtensions(TlsContext *context, const Tls13EncryptedExtensions *message, size_t length)
Parse EncryptedExtensions message.
Definition: tls13_client.c:423
error_t tls13GenerateClientAppTrafficKeys(TlsContext *context)
Compute client application traffic keys.
error_t tls13ParseNewSessionTicket(TlsContext *context, const Tls13NewSessionTicket *message, size_t length)
Parse NewSessionTicket message.
Definition: tls13_client.c:612
@ TLS_STATE_CLIENT_HELLO
Definition: tls.h:1539
@ TLS_TYPE_CERTIFICATE
Definition: tls.h:1094
bool_t tls13IsHelloRetryRequest(const TlsServerHello *message, size_t length)
Check whether an incoming ServerHello message is a HelloRetryRequest.
@ TLS_STATE_SERVER_HELLO
Definition: tls.h:1544
@ TLS_STATE_KEY_UPDATE
Definition: tls.h:1567
error_t tls13SendEndOfEarlyData(TlsContext *context)
Send EndOfEarlyData message.
Definition: tls13_client.c:68
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
error_t tlsSendClientKeyExchange(TlsContext *context)
Send ClientKeyExchange message.
Definition: tls_client.c:241
@ TLS_STATE_SERVER_FINISHED
Definition: tls.h:1563
Helper functions for TLS 1.3 client.
#define TLS_VERSION_1_3
Definition: tls.h:97
@ TLS_TYPE_SERVER_HELLO
Definition: tls.h:1086
Handshake message processing (TLS client and server)
@ TLS_TYPE_ENCRYPTED_EXTENSIONS
Definition: tls.h:1091
TLS record protocol.
@ TLS_STATE_CLIENT_CERTIFICATE_VERIFY
Definition: tls.h:1556
@ TLS_TYPE_CERTIFICATE_VERIFY
Definition: tls.h:1098
@ TLS_STATE_SERVER_CHANGE_CIPHER_SPEC
Definition: tls.h:1561
@ TLS_STATE_SERVER_HELLO_3
Definition: tls.h:1546
error_t tls13GenerateServerAppTrafficKeys(TlsContext *context)
Compute server application traffic keys.
@ TLS_STATE_END_OF_EARLY_DATA
Definition: tls.h:1564
uint8_t length
Definition: tcp.h:375
@ TLS_STATE_CLIENT_APP_TRAFFIC_KEYS
Definition: tls.h:1560
@ TLS_TYPE_HELLO_VERIFY_REQUEST
Definition: tls.h:1087
@ TLS_STATE_NEW_SESSION_TICKET
Definition: tls.h:1566
@ TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC
Definition: tls.h:1557
error_t tlsParseCertificate(TlsContext *context, const TlsCertificate *message, size_t length)
Parse Certificate message.
Definition: tls_common.c:1054
TLS state machine (TLS client)
@ TLS_STATE_HANDSHAKE_TRAFFIC_KEYS
Definition: tls.h:1547
@ TLS_TYPE_SERVER_KEY_EXCHANGE
Definition: tls.h:1095
#define TRACE_WARNING(...)
Definition: debug.h:93
@ TLS_TYPE_NONE
Definition: tls.h:1067
@ TLS_STATE_CLIENT_HELLO_2
Definition: tls.h:1540
error_t tls13ParseKeyUpdate(TlsContext *context, const Tls13KeyUpdate *message, size_t length)
Parse KeyUpdate message.
Definition: tls13_common.c:178
@ TLS_STATE_CLOSING
Definition: tls.h:1569
@ TLS_STATE_SERVER_CERTIFICATE_VERIFY
Definition: tls.h:1551
uint8_t msgType
@ TLS_STATE_SERVER_CERTIFICATE
Definition: tls.h:1549
@ ERROR_UNEXPECTED_STATE
Definition: error.h:99
@ TLS_STATE_CLIENT_KEY_EXCHANGE
Definition: tls.h:1555
error_t tlsParseFinished(TlsContext *context, const TlsFinished *message, size_t length)
Parse Finished message.
Definition: tls_common.c:1491
@ TLS_TYPE_FINISHED
Definition: tls.h:1100
@ TLS_STATE_CLIENT_CERTIFICATE
Definition: tls.h:1554
@ TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC_2
Definition: tls.h:1558
@ TLS_STATE_ENCRYPTED_EXTENSIONS
Definition: tls.h:1548
error_t tls13ParseHelloRetryRequest(TlsContext *context, const Tls13HelloRetryRequest *message, size_t length)
Parse HelloRetryRequest message.
Definition: tls13_client.c:154
@ TLS_STATE_INIT
Definition: tls.h:1538
error_t tlsWriteProtocolData(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Write protocol data.
Definition: tls_record.c:54
error_t tlsParseServerHelloDone(TlsContext *context, const TlsServerHelloDone *message, size_t length)
Parse ServerHelloDone message.
Definition: tls_client.c:1843
error_t tlsParseServerHello(TlsContext *context, const TlsServerHello *message, size_t length)
Parse ServerHello message.
Definition: tls_client.c:971
@ TLS_TYPE_CERTIFICATE_REQUEST
Definition: tls.h:1096
error_t tlsSendFinished(TlsContext *context)
Send Finished message.
Definition: tls_common.c:402
TLS (Transport Layer Security)
error_t tlsParseCertificateVerify(TlsContext *context, const TlsCertificateVerify *message, size_t length)
Parse CertificateVerify message.
Definition: tls_common.c:1263
error_t tlsParseCertificateRequest(TlsContext *context, const TlsCertificateRequest *message, size_t length)
Parse CertificateRequest message.
Definition: tls_client.c:1539
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:999
TLS 1.3 key schedule.
error_t tlsParseServerHandshakeMessage(TlsContext *context, uint8_t msgType, const void *message, size_t length)
Parse server's handshake message.
error_t tlsSendClientHello(TlsContext *context)
Send ClientHello message.
Definition: tls_client.c:81
void tlsProcessError(TlsContext *context, error_t errorCode)
Translate an error code to an alert message.
Definition: tls_misc.c:74
@ TLS_TYPE_NEW_SESSION_TICKET
Definition: tls.h:1088
void tlsChangeState(TlsContext *context, TlsState newState)
Update TLS state.
Definition: tls_misc.c:54
@ TLS_TYPE_HELLO_REQUEST
Definition: tls.h:1084
error_t tlsParseNewSessionTicket(TlsContext *context, const TlsNewSessionTicket *message, size_t length)
Parse NewSessionTicket message.
Definition: tls_client.c:1929
Handshake message processing (TLS client)
@ TLS_STATE_SERVER_HELLO_DONE
Definition: tls.h:1553
@ TLS_STATE_SERVER_HELLO_2
Definition: tls.h:1545
@ TLS_STATE_CLIENT_FINISHED
Definition: tls.h:1559
@ TLS_TYPE_KEY_UPDATE
Definition: tls.h:1104
Handshake message processing (TLS 1.3 client)
error_t dtlsParseHelloVerifyRequest(TlsContext *context, const DtlsHelloVerifyRequest *message, size_t length)
Parse HelloVerifyRequest message.
Definition: dtls_misc.c:329
error_t tlsParseServerKeyExchange(TlsContext *context, const TlsServerKeyExchange *message, size_t length)
Parse ServerKeyExchange message.
Definition: tls_client.c:1380
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
error_t tlsSendCertificateVerify(TlsContext *context)
Send CertificateVerify message.
Definition: tls_common.c:192
error_t tlsInitHandshake(TlsContext *context)
TLS handshake initialization.
Definition: tls_handshake.c:58
error_t tls13SendKeyUpdate(TlsContext *context)
Send KeyUpdate message.
Definition: tls13_common.c:57
@ TLS_STATE_CLOSED
Definition: tls.h:1570