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-2024 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.4.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 
228  //Any error to report?
229  if(error)
230  {
231  //Send an alert message to the server, if applicable
232  tlsProcessError(context, error);
233  }
234 
235  //Return status code
236  return error;
237 }
238 
239 
240 /**
241  * @brief Parse server's handshake message
242  * @param[in] context Pointer to the TLS context
243  * @param[in] msgType Handshake message type
244  * @param[in] message Pointer to the handshake message to parse
245  * @param[in] length Length of the handshake messaged
246  * @return Error code
247  **/
248 
250  const void *message, size_t length)
251 {
252  error_t error;
253 
254  //Check handshake message type
255  switch(msgType)
256  {
257  //HelloRequest message received?
259  //HelloRequest is a simple notification that the client should begin the
260  //negotiation process anew
261  error = tlsParseHelloRequest(context, message, length);
262  break;
263 
264  //ServerHello message received?
266 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
267  //For backward compatibility with middleboxes the HelloRetryRequest
268  //message uses the same structure as the ServerHello, but with Random
269  //field set to a special value
271  {
272  //The server sends a HelloRetryRequest message if the ClientHello
273  //message does not contain sufficient information to proceed with
274  //the handshake
275  error = tls13ParseHelloRetryRequest(context, message, length);
276  }
277  else
278 #endif
279  {
280  //The server will send this message in response to a ClientHello
281  //message when it was able to find an acceptable set of algorithms
282  error = tlsParseServerHello(context, message, length);
283  }
284 
285  break;
286 
287  //Certificate message received?
289  //The server must send a Certificate message whenever the agreed-upon
290  //key exchange method uses certificates for authentication. This message
291  //will always immediately follow the ServerHello message
292  error = tlsParseCertificate(context, message, length);
293  break;
294 
295  //CertificateRequest message received?
297  //A non-anonymous server can optionally request a certificate from the
298  //client, if appropriate for the selected cipher suite. This message,
299  //if sent, will immediately follow the ServerKeyExchange message
300  error = tlsParseCertificateRequest(context, message, length);
301  break;
302 
303  //NewSessionTicket message received?
305 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
306  //TLS 1.3 currently selected?
307  if(context->version == TLS_VERSION_1_3)
308  {
309  //At any time after the server has received the client Finished
310  //message, it may send a NewSessionTicket message
311  error = tls13ParseNewSessionTicket(context, message, length);
312  }
313  else
314 #endif
315  {
316  //The NewSessionTicket message is sent by the server during the TLS
317  //handshake before the ChangeCipherSpec message
318  error = tlsParseNewSessionTicket(context, message, length);
319  }
320 
321  break;
322 
323  //Finished message received?
324  case TLS_TYPE_FINISHED:
325  //A Finished message is always sent immediately after a ChangeCipherSpec
326  //message to verify that the key exchange and authentication processes
327  //were successful
328  error = tlsParseFinished(context, message, length);
329  break;
330 
331 #if (DTLS_SUPPORT == ENABLED)
332  //HelloVerifyRequest message received?
334  //When the client sends its ClientHello message to the server, the server
335  //may respond with a HelloVerifyRequest message
336  error = dtlsParseHelloVerifyRequest(context, message, length);
337  break;
338 #endif
339 
340 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
341  //ServerKeyExchange message received?
343  //The ServerKeyExchange message is sent by the server only when the
344  //server Certificate message (if sent) does not contain enough data
345  //to allow the client to exchange a premaster secret
346  error = tlsParseServerKeyExchange(context, message, length);
347  break;
348 
349  //ServerHelloDone message received?
351  //The ServerHelloDone message is sent by the server to indicate the end
352  //of the ServerHello and associated messages
353  error = tlsParseServerHelloDone(context, message, length);
354  break;
355 #endif
356 
357 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
358  //EncryptedExtensions message received?
360  //The server sends the EncryptedExtensions message immediately after
361  //the ServerHello message. The EncryptedExtensions message contains
362  //extensions that can be protected
363  error = tls13ParseEncryptedExtensions(context, message, length);
364  break;
365 
366  //CertificateVerify message received?
368  //Servers must send this message when authenticating via a certificate.
369  //When sent, this message must appear immediately after the Certificate
370  //message
371  error = tlsParseCertificateVerify(context, message, length);
372  break;
373 
374  //KeyUpdate message received?
375  case TLS_TYPE_KEY_UPDATE:
376  //The KeyUpdate handshake message is used to indicate that the server
377  //is updating its sending cryptographic keys. This message can be sent
378  //by the server after it has sent a Finished message
379  error = tls13ParseKeyUpdate(context, message, length);
380  break;
381 #endif
382 
383  //Invalid handshake message received?
384  default:
385  //Report an error
386  error = ERROR_UNEXPECTED_MESSAGE;
387  }
388 
389  //Return status code
390  return error;
391 }
392 
393 #endif
error_t tlsParseHelloRequest(TlsContext *context, const TlsHelloRequest *message, size_t length)
Parse HelloRequest message.
Definition: tls_client.c:872
TLS helper functions.
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:1467
@ TLS_TYPE_SERVER_HELLO_DONE
Definition: tls.h:1053
error_t tlsSendCertificate(TlsContext *context)
Send Certificate message.
Definition: tls_common.c:66
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:194
uint8_t message[]
Definition: chap.h:154
error_t tlsPerformClientHandshake(TlsContext *context)
TLS client handshake.
@ TLS_STATE_CERTIFICATE_REQUEST
Definition: tls.h:1469
Handshake message processing (TLS 1.3 client and server)
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1485
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:233
@ TLS_STATE_SERVER_APP_TRAFFIC_KEYS
Definition: tls.h:1482
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:420
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:599
@ TLS_STATE_CLIENT_HELLO
Definition: tls.h:1456
@ TLS_TYPE_CERTIFICATE
Definition: tls.h:1050
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:1461
@ TLS_STATE_KEY_UPDATE
Definition: tls.h:1484
error_t tls13SendEndOfEarlyData(TlsContext *context)
Send EndOfEarlyData message.
Definition: tls13_client.c:67
#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:261
@ TLS_STATE_SERVER_FINISHED
Definition: tls.h:1480
Helper functions for TLS 1.3 client.
#define TLS_VERSION_1_3
Definition: tls.h:97
@ TLS_TYPE_SERVER_HELLO
Definition: tls.h:1042
Handshake message processing (TLS client and server)
@ TLS_TYPE_ENCRYPTED_EXTENSIONS
Definition: tls.h:1047
TLS record protocol.
@ TLS_STATE_CLIENT_CERTIFICATE_VERIFY
Definition: tls.h:1473
@ TLS_TYPE_CERTIFICATE_VERIFY
Definition: tls.h:1054
@ TLS_STATE_SERVER_CHANGE_CIPHER_SPEC
Definition: tls.h:1478
@ TLS_STATE_SERVER_HELLO_3
Definition: tls.h:1463
error_t tls13GenerateServerAppTrafficKeys(TlsContext *context)
Compute server application traffic keys.
@ TLS_STATE_END_OF_EARLY_DATA
Definition: tls.h:1481
uint8_t length
Definition: tcp.h:368
@ TLS_STATE_CLIENT_APP_TRAFFIC_KEYS
Definition: tls.h:1477
@ TLS_TYPE_HELLO_VERIFY_REQUEST
Definition: tls.h:1043
@ TLS_STATE_NEW_SESSION_TICKET
Definition: tls.h:1483
@ TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC
Definition: tls.h:1474
error_t tlsParseCertificate(TlsContext *context, const TlsCertificate *message, size_t length)
Parse Certificate message.
Definition: tls_common.c:1018
TLS state machine (TLS client)
@ TLS_STATE_HANDSHAKE_TRAFFIC_KEYS
Definition: tls.h:1464
@ TLS_TYPE_SERVER_KEY_EXCHANGE
Definition: tls.h:1051
#define TRACE_WARNING(...)
Definition: debug.h:85
@ TLS_TYPE_NONE
Definition: tls.h:1023
@ TLS_STATE_CLIENT_HELLO_2
Definition: tls.h:1457
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:1486
@ TLS_STATE_SERVER_CERTIFICATE_VERIFY
Definition: tls.h:1468
uint8_t msgType
@ TLS_STATE_SERVER_CERTIFICATE
Definition: tls.h:1466
@ ERROR_UNEXPECTED_STATE
Definition: error.h:99
@ TLS_STATE_CLIENT_KEY_EXCHANGE
Definition: tls.h:1472
error_t tlsParseFinished(TlsContext *context, const TlsFinished *message, size_t length)
Parse Finished message.
Definition: tls_common.c:1455
@ TLS_TYPE_FINISHED
Definition: tls.h:1056
@ TLS_STATE_CLIENT_CERTIFICATE
Definition: tls.h:1471
@ TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC_2
Definition: tls.h:1475
@ TLS_STATE_ENCRYPTED_EXTENSIONS
Definition: tls.h:1465
error_t tls13ParseHelloRetryRequest(TlsContext *context, const Tls13HelloRetryRequest *message, size_t length)
Parse HelloRetryRequest message.
Definition: tls13_client.c:152
@ TLS_STATE_INIT
Definition: tls.h:1455
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:1828
error_t tlsParseServerHello(TlsContext *context, const TlsServerHello *message, size_t length)
Parse ServerHello message.
Definition: tls_client.c:957
@ TLS_TYPE_CERTIFICATE_REQUEST
Definition: tls.h:1052
error_t tlsSendFinished(TlsContext *context)
Send Finished message.
Definition: tls_common.c:394
TLS (Transport Layer Security)
error_t tlsParseCertificateVerify(TlsContext *context, const TlsCertificateVerify *message, size_t length)
Parse CertificateVerify message.
Definition: tls_common.c:1227
error_t tlsParseCertificateRequest(TlsContext *context, const TlsCertificateRequest *message, size_t length)
Parse CertificateRequest message.
Definition: tls_client.c:1524
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:956
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:1044
void tlsChangeState(TlsContext *context, TlsState newState)
Update TLS state.
Definition: tls_misc.c:54
@ TLS_TYPE_HELLO_REQUEST
Definition: tls.h:1040
error_t tlsParseNewSessionTicket(TlsContext *context, const TlsNewSessionTicket *message, size_t length)
Parse NewSessionTicket message.
Definition: tls_client.c:1914
Handshake message processing (TLS client)
@ TLS_STATE_SERVER_HELLO_DONE
Definition: tls.h:1470
@ TLS_STATE_SERVER_HELLO_2
Definition: tls.h:1462
@ TLS_STATE_CLIENT_FINISHED
Definition: tls.h:1476
@ TLS_TYPE_KEY_UPDATE
Definition: tls.h:1060
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:1365
@ 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:57
error_t tls13SendKeyUpdate(TlsContext *context)
Send KeyUpdate message.
Definition: tls13_common.c:57
@ TLS_STATE_CLOSED
Definition: tls.h:1487