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-2026 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.6.0
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?
105  //When a client first connects to a server, it is required to send
106  //the ClientHello as its first message
107  error = tlsSendClientHello(context);
108  break;
109 
110  //Sending Certificate message?
112  //This is the first message the client can send after receiving a
113  //ServerHelloDone message. This message is only sent if the server
114  //requests a certificate
115  error = tlsSendCertificate(context);
116  break;
117 
118  //Sending CertificateVerify message?
120  //This message is used to provide explicit verification of a client
121  //certificate. This message is only sent following a client certificate
122  //that has signing capability. When sent, it must immediately follow
123  //the clientKeyExchange message
124  error = tlsSendCertificateVerify(context);
125  break;
126 
127  //Sending ChangeCipherSpec message?
130  //The ChangeCipherSpec message is sent by the client and to notify the
131  //server that subsequent records will be protected under the newly
132  //negotiated CipherSpec and keys
133  error = tlsSendChangeCipherSpec(context);
134  break;
135 
136  //Sending Finished message?
138  //A Finished message is always sent immediately after a ChangeCipherSpec
139  //message to verify that the key exchange and authentication processes
140  //were successful
141  error = tlsSendFinished(context);
142  break;
143 
144 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
145  //Sending ClientKeyExchange message?
147  //This message is always sent by the client. It must immediately
148  //follow the client certificate message, if it is sent. Otherwise,
149  //it must be the first message sent by the client after it receives
150  //the ServerHelloDone message
151  error = tlsSendClientKeyExchange(context);
152  break;
153 #endif
154 
155 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
156  //Sending EndOfEarlyData message?
158  //The EndOfEarlyData message indicates that all 0-RTT application
159  //data messages, if any, have been transmitted and that the following
160  //records are protected under handshake traffic keys
161  error = tls13SendEndOfEarlyData(context);
162  break;
163 
164  //Handshake traffic key generation?
166  //Compute handshake traffic keys
167  error = tls13GenerateHandshakeTrafficKeys(context);
168  break;
169 
170  //Server application traffic key generation?
172  //Compute server application traffic keys
173  error = tls13GenerateServerAppTrafficKeys(context);
174  break;
175 
176  //Client application traffic key generation?
178  //Compute client application traffic keys
179  error = tls13GenerateClientAppTrafficKeys(context);
180  break;
181 
182  //Sending KeyUpdate message?
184  //The KeyUpdate handshake message is used to indicate that the sender
185  //is updating its sending cryptographic keys
186  error = tls13SendKeyUpdate(context);
187  break;
188 #endif
189 
190  //Waiting for a message from the server?
203  //Receive server's message
204  error = tlsReceiveHandshakeMessage(context);
205  break;
206 
207  //Sending Alert message?
208  case TLS_STATE_CLOSING:
209  //Mark the TLS connection as closed
211  break;
212 
213  //TLS connection closed?
214  case TLS_STATE_CLOSED:
215  //Debug message
216  TRACE_WARNING("TLS handshake failure!\r\n");
217  //Report an error
218  error = ERROR_HANDSHAKE_FAILED;
219  break;
220 
221  //Invalid state?
222  default:
223  //Report an error
224  error = ERROR_UNEXPECTED_STATE;
225  break;
226  }
227 
228 #if (TLS_RTOS_SUPPORT == DISABLED)
229  //Force TLS to operate in non-blocking mode
230  if(error == NO_ERROR && context->state < TLS_STATE_APPLICATION_DATA)
231  {
232  error = ERROR_WOULD_BLOCK;
233  break;
234  }
235 #endif
236  }
237 
238  //Any error to report?
239  if(error)
240  {
241  //Send an alert message to the server, if applicable
242  tlsProcessError(context, error);
243  }
244 
245  //Return status code
246  return error;
247 }
248 
249 
250 /**
251  * @brief Parse server's handshake message
252  * @param[in] context Pointer to the TLS context
253  * @param[in] msgType Handshake message type
254  * @param[in] message Pointer to the handshake message to parse
255  * @param[in] length Length of the handshake messaged
256  * @return Error code
257  **/
258 
260  const void *message, size_t length)
261 {
262  error_t error;
263 
264  //Check handshake message type
265  switch(msgType)
266  {
267  //HelloRequest message received?
269  //HelloRequest is a simple notification that the client should begin the
270  //negotiation process anew
271  error = tlsParseHelloRequest(context, message, length);
272  break;
273 
274  //ServerHello message received?
276 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
277  //For backward compatibility with middleboxes the HelloRetryRequest
278  //message uses the same structure as the ServerHello, but with Random
279  //field set to a special value
281  {
282  //The server sends a HelloRetryRequest message if the ClientHello
283  //message does not contain sufficient information to proceed with
284  //the handshake
285  error = tls13ParseHelloRetryRequest(context, message, length);
286  }
287  else
288 #endif
289  {
290  //The server will send this message in response to a ClientHello
291  //message when it was able to find an acceptable set of algorithms
292  error = tlsParseServerHello(context, message, length);
293  }
294 
295  break;
296 
297  //Certificate message received?
299  //The server must send a Certificate message whenever the agreed-upon
300  //key exchange method uses certificates for authentication. This message
301  //will always immediately follow the ServerHello message
302  error = tlsParseCertificate(context, message, length);
303  break;
304 
305  //CertificateRequest message received?
307  //A non-anonymous server can optionally request a certificate from the
308  //client, if appropriate for the selected cipher suite. This message,
309  //if sent, will immediately follow the ServerKeyExchange message
310  error = tlsParseCertificateRequest(context, message, length);
311  break;
312 
313  //NewSessionTicket message received?
315 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
316  //TLS 1.3 currently selected?
317  if(context->version == TLS_VERSION_1_3)
318  {
319  //At any time after the server has received the client Finished
320  //message, it may send a NewSessionTicket message
321  error = tls13ParseNewSessionTicket(context, message, length);
322  }
323  else
324 #endif
325  {
326  //The NewSessionTicket message is sent by the server during the TLS
327  //handshake before the ChangeCipherSpec message
328  error = tlsParseNewSessionTicket(context, message, length);
329  }
330 
331  break;
332 
333  //Finished message received?
334  case TLS_TYPE_FINISHED:
335  //A Finished message is always sent immediately after a ChangeCipherSpec
336  //message to verify that the key exchange and authentication processes
337  //were successful
338  error = tlsParseFinished(context, message, length);
339  break;
340 
341 #if (DTLS_SUPPORT == ENABLED)
342  //HelloVerifyRequest message received?
344  //When the client sends its ClientHello message to the server, the server
345  //may respond with a HelloVerifyRequest message
346  error = dtlsParseHelloVerifyRequest(context, message, length);
347  break;
348 #endif
349 
350 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
351  //ServerKeyExchange message received?
353  //The ServerKeyExchange message is sent by the server only when the
354  //server Certificate message (if sent) does not contain enough data
355  //to allow the client to exchange a premaster secret
356  error = tlsParseServerKeyExchange(context, message, length);
357  break;
358 
359  //ServerHelloDone message received?
361  //The ServerHelloDone message is sent by the server to indicate the end
362  //of the ServerHello and associated messages
363  error = tlsParseServerHelloDone(context, message, length);
364  break;
365 #endif
366 
367 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
368  //EncryptedExtensions message received?
370  //The server sends the EncryptedExtensions message immediately after
371  //the ServerHello message. The EncryptedExtensions message contains
372  //extensions that can be protected
373  error = tls13ParseEncryptedExtensions(context, message, length);
374  break;
375 
376  //CertificateVerify message received?
378  //Servers must send this message when authenticating via a certificate.
379  //When sent, this message must appear immediately after the Certificate
380  //message
381  error = tlsParseCertificateVerify(context, message, length);
382  break;
383 
384  //KeyUpdate message received?
385  case TLS_TYPE_KEY_UPDATE:
386  //The KeyUpdate handshake message is used to indicate that the server
387  //is updating its sending cryptographic keys. This message can be sent
388  //by the server after it has sent a Finished message
389  error = tls13ParseKeyUpdate(context, message, length);
390  break;
391 #endif
392 
393  //Invalid handshake message received?
394  default:
395  //Report an error
396  error = ERROR_UNEXPECTED_MESSAGE;
397  }
398 
399  //Return status code
400  return error;
401 }
402 
403 #endif
error_t tlsParseHelloRequest(TlsContext *context, const TlsHelloRequest *message, size_t length)
Parse HelloRequest message.
Definition: tls_client.c:880
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:1554
@ 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:1556
Handshake message processing (TLS 1.3 client and server)
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1572
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:234
@ TLS_STATE_SERVER_APP_TRAFFIC_KEYS
Definition: tls.h:1569
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:434
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:623
@ TLS_STATE_CLIENT_HELLO
Definition: tls.h:1542
@ 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:1548
@ TLS_STATE_KEY_UPDATE
Definition: tls.h:1571
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:238
@ TLS_STATE_SERVER_FINISHED
Definition: tls.h:1567
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:1560
@ TLS_TYPE_CERTIFICATE_VERIFY
Definition: tls.h:1098
@ TLS_STATE_SERVER_CHANGE_CIPHER_SPEC
Definition: tls.h:1565
@ TLS_STATE_SERVER_HELLO_3
Definition: tls.h:1550
error_t tls13GenerateServerAppTrafficKeys(TlsContext *context)
Compute server application traffic keys.
@ TLS_STATE_END_OF_EARLY_DATA
Definition: tls.h:1568
uint8_t length
Definition: tcp.h:375
@ TLS_STATE_CLIENT_APP_TRAFFIC_KEYS
Definition: tls.h:1564
@ TLS_TYPE_HELLO_VERIFY_REQUEST
Definition: tls.h:1087
@ TLS_STATE_NEW_SESSION_TICKET
Definition: tls.h:1570
@ TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC
Definition: tls.h:1561
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:1551
@ 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:1543
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:1573
@ TLS_STATE_SERVER_CERTIFICATE_VERIFY
Definition: tls.h:1555
uint8_t msgType
@ TLS_STATE_SERVER_CERTIFICATE
Definition: tls.h:1553
@ ERROR_UNEXPECTED_STATE
Definition: error.h:99
@ TLS_STATE_CLIENT_KEY_EXCHANGE
Definition: tls.h:1559
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:1558
@ TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC_2
Definition: tls.h:1562
@ TLS_STATE_ENCRYPTED_EXTENSIONS
Definition: tls.h:1552
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:1541
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:1837
error_t tlsParseServerHello(TlsContext *context, const TlsServerHello *message, size_t length)
Parse ServerHello message.
Definition: tls_client.c:965
@ 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:1533
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:999
TLS 1.3 key schedule.
@ TLS_STATE_CLIENT_HELLO_3
Definition: tls.h:1544
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:1923
Handshake message processing (TLS client)
@ TLS_STATE_SERVER_HELLO_DONE
Definition: tls.h:1557
@ TLS_STATE_SERVER_HELLO_2
Definition: tls.h:1549
@ TLS_STATE_CLIENT_FINISHED
Definition: tls.h:1563
@ 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:363
error_t tlsParseServerKeyExchange(TlsContext *context, const TlsServerKeyExchange *message, size_t length)
Parse ServerKeyExchange message.
Definition: tls_client.c:1374
@ 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:1574