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-2019 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 1.9.6
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 >= SSL_VERSION_3_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?
201  //Receive server's message
202  error = tlsReceiveHandshakeMessage(context);
203  break;
204 
205  //Sending Alert message?
206  case TLS_STATE_CLOSING:
207  //Mark the TLS connection as closed
208  context->state = TLS_STATE_CLOSED;
209  break;
210 
211  //TLS connection closed?
212  case TLS_STATE_CLOSED:
213  //Debug message
214  TRACE_WARNING("TLS handshake failure!\r\n");
215  //Report an error
216  error = ERROR_HANDSHAKE_FAILED;
217  break;
218 
219  //Invalid state?
220  default:
221  //Report an error
222  error = ERROR_UNEXPECTED_STATE;
223  break;
224  }
225  }
226 
227  //Any error to report?
228  if(error)
229  {
230  //Send an alert message to the server, if applicable
231  tlsProcessError(context, error);
232  }
233 
234  //Return status code
235  return error;
236 }
237 
238 
239 /**
240  * @brief Parse server's handshake message
241  * @param[in] context Pointer to the TLS context
242  * @param[in] msgType Handshake message type
243  * @param[in] message Pointer to the handshake message to parse
244  * @param[in] length Length of the handshake messaged
245  * @return Error code
246  **/
247 
249  const void *message, size_t length)
250 {
251  error_t error;
252 
253  //Check handshake message type
254  switch(msgType)
255  {
256  //HelloRequest message received?
258  //HelloRequest is a simple notification that the client should begin the
259  //negotiation process anew
260  error = tlsParseHelloRequest(context, message, length);
261  break;
262 
263  //ServerHello message received?
265 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
266  //For backward compatibility with middleboxes the HelloRetryRequest
267  //message uses the same structure as the ServerHello, but with Random
268  //field set to a special value
270  {
271  //The server sends a HelloRetryRequest message if the ClientHello
272  //message does not contain sufficient information to proceed with
273  //the handshake
274  error = tls13ParseHelloRetryRequest(context, message, length);
275  }
276  else
277 #endif
278  {
279  //The server will send this message in response to a ClientHello
280  //message when it was able to find an acceptable set of algorithms
281  error = tlsParseServerHello(context, message, length);
282  }
283  break;
284 
285  //Certificate message received?
287  //The server must send a Certificate message whenever the agreed-upon
288  //key exchange method uses certificates for authentication. This message
289  //will always immediately follow the ServerHello message
290  error = tlsParseCertificate(context, message, length);
291  break;
292 
293  //CertificateRequest message received?
295  //A non-anonymous server can optionally request a certificate from the
296  //client, if appropriate for the selected cipher suite. This message,
297  //if sent, will immediately follow the ServerKeyExchange message
298  error = tlsParseCertificateRequest(context, message, length);
299  break;
300 
301  //Finished message received?
302  case TLS_TYPE_FINISHED:
303  //A Finished message is always sent immediately after a ChangeCipherSpec
304  //message to verify that the key exchange and authentication processes
305  //were successful
306  error = tlsParseFinished(context, message, length);
307  break;
308 
309 #if (DTLS_SUPPORT == ENABLED)
310  //HelloVerifyRequest message received?
312  //When the client sends its ClientHello message to the server, the server
313  //may respond with a HelloVerifyRequest message
314  error = dtlsParseHelloVerifyRequest(context, message, length);
315  break;
316 #endif
317 
318 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
319  //ServerKeyExchange message received?
321  //The ServerKeyExchange message is sent by the server only when the
322  //server Certificate message (if sent) does not contain enough data
323  //to allow the client to exchange a premaster secret
324  error = tlsParseServerKeyExchange(context, message, length);
325  break;
326 
327  //ServerHelloDone message received?
329  //The ServerHelloDone message is sent by the server to indicate the end
330  //of the ServerHello and associated messages
331  error = tlsParseServerHelloDone(context, message, length);
332  break;
333 #endif
334 
335 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
336  //EncryptedExtensions message received?
338  //The server sends the EncryptedExtensions message immediately after
339  //the ServerHello message. The EncryptedExtensions message contains
340  //extensions that can be protected
341  error = tls13ParseEncryptedExtensions(context, message, length);
342  break;
343 
344  //CertificateVerify message received?
346  //Servers must send this message when authenticating via a certificate.
347  //When sent, this message must appear immediately after the Certificate
348  //message
349  error = tlsParseCertificateVerify(context, message, length);
350  break;
351 
352  //NewSessionTicket message received?
354  //At any time after the server has received the client Finished message,
355  //it may send a NewSessionTicket message
356  error = tls13ParseNewSessionTicket(context, message, length);
357  break;
358 
359  //KeyUpdate message received?
360  case TLS_TYPE_KEY_UPDATE:
361  //The KeyUpdate handshake message is used to indicate that the server
362  //is updating its sending cryptographic keys. This message can be sent
363  //by the server after it has sent a Finished message
364  error = tls13ParseKeyUpdate(context, message, length);
365  break;
366 #endif
367 
368  //Invalid handshake message received?
369  default:
370  //Report an error
371  error = ERROR_UNEXPECTED_MESSAGE;
372  }
373 
374  //Return status code
375  return error;
376 }
377 
378 #endif
error_t tlsParseHelloRequest(TlsContext *context, const TlsHelloRequest *message, size_t length)
Parse HelloRequest message.
Definition: tls_client.c:800
TLS helper functions.
uint8_t length
Definition: dtls_misc.h:149
error_t tls13GenerateHandshakeTrafficKeys(TlsContext *context)
error_t tls13ParseNewSessionTicket(TlsContext *context, const Tls13NewSessionTicket *message, size_t length)
error_t tlsSendChangeCipherSpec(TlsContext *context)
Send ChangeCipherSpec message.
Definition: tls_common.c:268
TLS handshake.
error_t tlsSendCertificate(TlsContext *context)
Send Certificate message.
Definition: tls_common.c:62
error_t tls13SendEndOfEarlyData(TlsContext *context)
error_t tlsPerformClientHandshake(TlsContext *context)
TLS client handshake.
Handshake message processing (TLS 1.3 client and server)
error_t tlsReceiveHandshakeMessage(TlsContext *context)
Receive peer's message.
error_t tls13GenerateClientAppTrafficKeys(TlsContext *context)
bool_t tls13IsHelloRetryRequest(const TlsServerHello *message, size_t length)
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:42
error_t tlsSendClientKeyExchange(TlsContext *context)
Send ClientKeyExchange message.
Definition: tls_client.c:233
error_t tls13SendKeyUpdate(TlsContext *context)
Helper functions for TLS 1.3 client.
Handshake message processing (TLS client and server)
TLS record protocol.
error_t tls13GenerateServerAppTrafficKeys(TlsContext *context)
error_t tlsParseCertificate(TlsContext *context, const TlsCertificate *message, size_t length)
Parse Certificate message.
Definition: tls_common.c:1231
TLS state machine (TLS client)
#define TRACE_WARNING(...)
Definition: debug.h:84
error_t tlsParseFinished(TlsContext *context, const TlsFinished *message, size_t length)
Parse Finished message.
Definition: tls_common.c:1656
error_t tlsWriteProtocolData(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Write protocol data.
Definition: tls_record.c:55
error_t tlsParseServerHelloDone(TlsContext *context, const TlsServerHelloDone *message, size_t length)
Parse ServerHelloDone message.
Definition: tls_client.c:1696
uint8_t msgType
Definition: dtls_misc.h:186
uint8_t message[]
Definition: chap.h:152
error_t tlsParseServerHello(TlsContext *context, const TlsServerHello *message, size_t length)
Parse ServerHello message.
Definition: tls_client.c:867
error_t tlsSendFinished(TlsContext *context)
Send Finished message.
Definition: tls_common.c:383
TLS (Transport Layer Security)
error_t tlsParseCertificateVerify(TlsContext *context, const TlsCertificateVerify *message, size_t length)
Parse CertificateVerify message.
Definition: tls_common.c:1432
error_t tlsParseCertificateRequest(TlsContext *context, const TlsCertificateRequest *message, size_t length)
Parse CertificateRequest message.
Definition: tls_client.c:1400
error_t tls13ParseEncryptedExtensions(TlsContext *context, const Tls13EncryptedExtensions *message, size_t length)
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:82
void tlsProcessError(TlsContext *context, error_t errorCode)
Translate an error code to an alert message.
Definition: tls_misc.c:56
Handshake message processing (TLS client)
error_t tls13ParseKeyUpdate(TlsContext *context, const Tls13KeyUpdate *message, size_t length)
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:323
error_t tlsParseServerKeyExchange(TlsContext *context, const TlsServerKeyExchange *message, size_t length)
Parse ServerKeyExchange message.
Definition: tls_client.c:1243
Success.
Definition: error.h:44
error_t tls13ParseHelloRetryRequest(TlsContext *context, const Tls13HelloRetryRequest *message, size_t length)
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:56