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.2
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls/tls.h"
36 #include "tls/tls_handshake.h"
37 #include "tls/tls_client.h"
38 #include "tls/tls_client_fsm.h"
39 #include "tls/tls_common.h"
40 #include "tls/tls_record.h"
41 #include "tls/tls_misc.h"
42 #include "tls13/tls13_client.h"
44 #include "tls13/tls13_common.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  context->state == TLS_STATE_CLIENT_FINISHED_ACK ||
86  context->state == TLS_STATE_KEY_UPDATE_ACK)
87  {
88  //At this is point, the handshake is complete and the client starts
89  //to exchange application-layer data
90  break;
91  }
92 
93  //The TLS handshake is implemented as a state machine representing the
94  //current location in the protocol
95  switch(context->state)
96  {
97  //Initial state?
98  case TLS_STATE_INIT:
99  //TLS handshake initialization
100  error = tlsInitHandshake(context);
101  break;
102 
103  //Sending ClientHello message?
106  //When a client first connects to a server, it is required to send
107  //the ClientHello as its first message
108  error = tlsSendClientHello(context);
109  break;
110 
111  //Sending Certificate message?
113  //This is the first message the client can send after receiving a
114  //ServerHelloDone message. This message is only sent if the server
115  //requests a certificate
116  error = tlsSendCertificate(context);
117  break;
118 
119  //Sending CertificateVerify message?
121  //This message is used to provide explicit verification of a client
122  //certificate. This message is only sent following a client certificate
123  //that has signing capability. When sent, it must immediately follow
124  //the clientKeyExchange message
125  error = tlsSendCertificateVerify(context);
126  break;
127 
128  //Sending ChangeCipherSpec message?
131  //The ChangeCipherSpec message is sent by the client and to notify the
132  //server that subsequent records will be protected under the newly
133  //negotiated CipherSpec and keys
134  error = tlsSendChangeCipherSpec(context);
135  break;
136 
137  //Sending Finished message?
139  //A Finished message is always sent immediately after a ChangeCipherSpec
140  //message to verify that the key exchange and authentication processes
141  //were successful
142  error = tlsSendFinished(context);
143  break;
144 
145 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
146  //Sending ClientKeyExchange message?
148  //This message is always sent by the client. It must immediately
149  //follow the client certificate message, if it is sent. Otherwise,
150  //it must be the first message sent by the client after it receives
151  //the ServerHelloDone message
152  error = tlsSendClientKeyExchange(context);
153  break;
154 #endif
155 
156 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
157  //Sending EndOfEarlyData message?
159  //The EndOfEarlyData message indicates that all 0-RTT application
160  //data messages, if any, have been transmitted and that the following
161  //records are protected under handshake traffic keys
162  error = tls13SendEndOfEarlyData(context);
163  break;
164 
165  //Handshake traffic key generation?
167  //Compute handshake traffic keys
168  error = tls13GenerateHandshakeTrafficKeys(context);
169  break;
170 
171  //Server application traffic key generation?
173  //Compute server application traffic keys
174  error = tls13GenerateServerAppTrafficKeys(context);
175  break;
176 
177  //Client application traffic key generation?
179  //Compute client application traffic keys
180  error = tls13GenerateClientAppTrafficKeys(context);
181  break;
182 
183  //Sending KeyUpdate message?
185  //The KeyUpdate handshake message is used to indicate that the sender
186  //is updating its sending cryptographic keys
187  error = tls13SendKeyUpdate(context);
188  break;
189 #endif
190 
191  //Waiting for a message from the server?
204  //Receive server's message
205  error = tlsReceiveHandshakeMessage(context);
206  break;
207 
208  //Sending Alert message?
209  case TLS_STATE_CLOSING:
210  //Mark the TLS connection as closed
212  break;
213 
214  //TLS connection closed?
215  case TLS_STATE_CLOSED:
216  //Debug message
217  TRACE_WARNING("TLS handshake failure!\r\n");
218  //Report an error
219  error = ERROR_HANDSHAKE_FAILED;
220  break;
221 
222  //Invalid state?
223  default:
224  //Report an error
225  error = ERROR_UNEXPECTED_STATE;
226  break;
227  }
228 
229 #if (TLS_RTOS_SUPPORT == DISABLED)
230  //Force TLS to operate in non-blocking mode
231  if(error == NO_ERROR &&
232  context->state != TLS_STATE_APPLICATION_DATA &&
233  context->state != TLS_STATE_CLIENT_FINISHED_ACK &&
234  context->state != TLS_STATE_KEY_UPDATE_ACK)
235  {
236  error = ERROR_WOULD_BLOCK;
237  break;
238  }
239 #endif
240  }
241 
242  //Any error to report?
243  if(error)
244  {
245  //Send an alert message to the server, if applicable
246  tlsProcessError(context, error);
247  }
248 
249  //Return status code
250  return error;
251 }
252 
253 
254 /**
255  * @brief Parse server's handshake message
256  * @param[in] context Pointer to the TLS context
257  * @param[in] msgType Handshake message type
258  * @param[in] message Pointer to the handshake message to parse
259  * @param[in] length Length of the handshake messaged
260  * @return Error code
261  **/
262 
264  const void *message, size_t length)
265 {
266  error_t error;
267 
268  //Check handshake message type
269  switch(msgType)
270  {
271  //HelloRequest message received?
273  //HelloRequest is a simple notification that the client should begin the
274  //negotiation process anew
275  error = tlsParseHelloRequest(context, message, length);
276  break;
277 
278  //ServerHello message received?
280 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
281  //For backward compatibility with middleboxes the HelloRetryRequest
282  //message uses the same structure as the ServerHello, but with Random
283  //field set to a special value
285  {
286  //The server sends a HelloRetryRequest message if the ClientHello
287  //message does not contain sufficient information to proceed with
288  //the handshake
289  error = tls13ParseHelloRetryRequest(context, message, length);
290  }
291  else
292 #endif
293  {
294  //The server will send this message in response to a ClientHello
295  //message when it was able to find an acceptable set of algorithms
296  error = tlsParseServerHello(context, message, length);
297  }
298 
299  break;
300 
301  //Certificate message received?
303  //The server must send a Certificate message whenever the agreed-upon
304  //key exchange method uses certificates for authentication. This message
305  //will always immediately follow the ServerHello message
306  error = tlsParseCertificate(context, message, length);
307  break;
308 
309  //CertificateRequest message received?
311  //A non-anonymous server can optionally request a certificate from the
312  //client, if appropriate for the selected cipher suite. This message,
313  //if sent, will immediately follow the ServerKeyExchange message
314  error = tlsParseCertificateRequest(context, message, length);
315  break;
316 
317  //NewSessionTicket message received?
319 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
320  //TLS 1.3 currently selected?
321  if(context->version == TLS_VERSION_1_3)
322  {
323  //At any time after the server has received the client Finished
324  //message, it may send a NewSessionTicket message
325  error = tls13ParseNewSessionTicket(context, message, length);
326  }
327  else
328 #endif
329  {
330  //The NewSessionTicket message is sent by the server during the TLS
331  //handshake before the ChangeCipherSpec message
332  error = tlsParseNewSessionTicket(context, message, length);
333  }
334 
335  break;
336 
337  //Finished message received?
338  case TLS_TYPE_FINISHED:
339  //A Finished message is always sent immediately after a ChangeCipherSpec
340  //message to verify that the key exchange and authentication processes
341  //were successful
342  error = tlsParseFinished(context, message, length);
343  break;
344 
345 #if (DTLS_SUPPORT == ENABLED)
346  //HelloVerifyRequest message received?
348  //When the client sends its ClientHello message to the server, the server
349  //may respond with a HelloVerifyRequest message
350  error = dtlsParseHelloVerifyRequest(context, message, length);
351  break;
352 #endif
353 
354 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
355  //ServerKeyExchange message received?
357  //The ServerKeyExchange message is sent by the server only when the
358  //server Certificate message (if sent) does not contain enough data
359  //to allow the client to exchange a premaster secret
360  error = tlsParseServerKeyExchange(context, message, length);
361  break;
362 
363  //ServerHelloDone message received?
365  //The ServerHelloDone message is sent by the server to indicate the end
366  //of the ServerHello and associated messages
367  error = tlsParseServerHelloDone(context, message, length);
368  break;
369 #endif
370 
371 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
372  //EncryptedExtensions message received?
374  //The server sends the EncryptedExtensions message immediately after
375  //the ServerHello message. The EncryptedExtensions message contains
376  //extensions that can be protected
377  error = tls13ParseEncryptedExtensions(context, message, length);
378  break;
379 
380  //CertificateVerify message received?
382  //Servers must send this message when authenticating via a certificate.
383  //When sent, this message must appear immediately after the Certificate
384  //message
385  error = tlsParseCertificateVerify(context, message, length);
386  break;
387 
388  //KeyUpdate message received?
389  case TLS_TYPE_KEY_UPDATE:
390  //The KeyUpdate handshake message is used to indicate that the server
391  //is updating its sending cryptographic keys. This message can be sent
392  //by the server after it has sent a Finished message
393  error = tls13ParseKeyUpdate(context, message, length);
394  break;
395 #endif
396 
397  //Invalid handshake message received?
398  default:
399  //Report an error
400  error = ERROR_UNEXPECTED_MESSAGE;
401  }
402 
403  //Return status code
404  return error;
405 }
406 
407 #endif
error_t tlsParseHelloRequest(TlsContext *context, const TlsHelloRequest *message, size_t length)
Parse HelloRequest message.
Definition: tls_client.c:881
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:1570
@ TLS_TYPE_SERVER_HELLO_DONE
Definition: tls.h:1114
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:1572
Handshake message processing (TLS 1.3 client and server)
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1589
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:234
@ TLS_STATE_SERVER_APP_TRAFFIC_KEYS
Definition: tls.h:1587
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:445
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:631
@ TLS_STATE_CLIENT_HELLO
Definition: tls.h:1559
@ TLS_TYPE_CERTIFICATE
Definition: tls.h:1111
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:1564
@ TLS_STATE_KEY_UPDATE
Definition: tls.h:1592
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:1585
Helper functions for TLS 1.3 client.
#define TLS_VERSION_1_3
Definition: tls.h:98
@ TLS_TYPE_SERVER_HELLO
Definition: tls.h:1103
Handshake message processing (TLS client and server)
@ TLS_TYPE_ENCRYPTED_EXTENSIONS
Definition: tls.h:1108
TLS record protocol.
@ TLS_STATE_CLIENT_CERTIFICATE_VERIFY
Definition: tls.h:1576
@ TLS_TYPE_CERTIFICATE_VERIFY
Definition: tls.h:1115
@ TLS_STATE_SERVER_CHANGE_CIPHER_SPEC
Definition: tls.h:1583
@ TLS_STATE_SERVER_HELLO_3
Definition: tls.h:1566
error_t tls13GenerateServerAppTrafficKeys(TlsContext *context)
Compute server application traffic keys.
@ TLS_STATE_END_OF_EARLY_DATA
Definition: tls.h:1586
uint8_t length
Definition: tcp.h:375
@ TLS_STATE_CLIENT_APP_TRAFFIC_KEYS
Definition: tls.h:1580
@ TLS_TYPE_HELLO_VERIFY_REQUEST
Definition: tls.h:1104
@ TLS_STATE_NEW_SESSION_TICKET
Definition: tls.h:1581
@ TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC
Definition: tls.h:1577
error_t tlsParseCertificate(TlsContext *context, const TlsCertificate *message, size_t length)
Parse Certificate message.
Definition: tls_common.c:1039
TLS state machine (TLS client)
@ TLS_STATE_HANDSHAKE_TRAFFIC_KEYS
Definition: tls.h:1567
@ TLS_TYPE_SERVER_KEY_EXCHANGE
Definition: tls.h:1112
#define TRACE_WARNING(...)
Definition: debug.h:93
@ TLS_TYPE_NONE
Definition: tls.h:1084
@ TLS_STATE_CLIENT_HELLO_2
Definition: tls.h:1560
error_t tls13ParseKeyUpdate(TlsContext *context, const Tls13KeyUpdate *message, size_t length)
Parse KeyUpdate message.
Definition: tls13_common.c:185
@ TLS_STATE_CLOSING
Definition: tls.h:1594
@ TLS_STATE_SERVER_CERTIFICATE_VERIFY
Definition: tls.h:1571
uint8_t msgType
@ TLS_STATE_SERVER_CERTIFICATE
Definition: tls.h:1569
@ ERROR_UNEXPECTED_STATE
Definition: error.h:99
@ TLS_STATE_CLIENT_KEY_EXCHANGE
Definition: tls.h:1575
error_t tlsParseFinished(TlsContext *context, const TlsFinished *message, size_t length)
Parse Finished message.
Definition: tls_common.c:1464
@ TLS_TYPE_FINISHED
Definition: tls.h:1117
@ TLS_STATE_CLIENT_CERTIFICATE
Definition: tls.h:1574
@ TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC_2
Definition: tls.h:1578
@ TLS_STATE_ENCRYPTED_EXTENSIONS
Definition: tls.h:1568
error_t tls13ParseHelloRetryRequest(TlsContext *context, const Tls13HelloRetryRequest *message, size_t length)
Parse HelloRetryRequest message.
Definition: tls13_client.c:151
@ TLS_STATE_INIT
Definition: tls.h:1558
error_t tlsWriteProtocolData(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Write protocol data.
Definition: tls_record.c:54
@ TLS_STATE_CLIENT_FINISHED_ACK
Definition: tls.h:1590
error_t tlsParseServerHelloDone(TlsContext *context, const TlsServerHelloDone *message, size_t length)
Parse ServerHelloDone message.
Definition: tls_client.c:1849
error_t tlsParseServerHello(TlsContext *context, const TlsServerHello *message, size_t length)
Parse ServerHello message.
Definition: tls_client.c:966
@ TLS_TYPE_CERTIFICATE_REQUEST
Definition: tls.h:1113
error_t tlsSendFinished(TlsContext *context)
Send Finished message.
Definition: tls_common.c:387
TLS (Transport Layer Security)
error_t tlsParseCertificateVerify(TlsContext *context, const TlsCertificateVerify *message, size_t length)
Parse CertificateVerify message.
Definition: tls_common.c:1248
error_t tlsParseCertificateRequest(TlsContext *context, const TlsCertificateRequest *message, size_t length)
Parse CertificateRequest message.
Definition: tls_client.c:1545
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:1016
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:1105
void tlsChangeState(TlsContext *context, TlsState newState)
Update TLS state.
Definition: tls_misc.c:54
@ TLS_TYPE_HELLO_REQUEST
Definition: tls.h:1101
error_t tlsParseNewSessionTicket(TlsContext *context, const TlsNewSessionTicket *message, size_t length)
Parse NewSessionTicket message.
Definition: tls_client.c:1935
Handshake message processing (TLS client)
@ TLS_STATE_SERVER_HELLO_DONE
Definition: tls.h:1573
@ TLS_STATE_SERVER_HELLO_2
Definition: tls.h:1565
@ TLS_STATE_CLIENT_FINISHED
Definition: tls.h:1579
@ TLS_STATE_KEY_UPDATE_ACK
Definition: tls.h:1593
@ TLS_TYPE_KEY_UPDATE
Definition: tls.h:1121
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:1386
@ 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:1595