tls.c
Go to the documentation of this file.
1 /**
2  * @file tls.c
3  * @brief TLS (Transport Layer Security)
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  * @section Description
28  *
29  * The TLS protocol provides communications security over the Internet. The
30  * protocol allows client/server applications to communicate in a way that
31  * is designed to prevent eavesdropping, tampering, or message forgery
32  *
33  * @author Oryx Embedded SARL (www.oryx-embedded.com)
34  * @version 1.9.6
35  **/
36 
37 //Switch to the appropriate trace level
38 #define TRACE_LEVEL TLS_TRACE_LEVEL
39 
40 //Dependencies
41 #include <string.h>
42 #include <ctype.h>
43 #include "tls.h"
44 #include "tls_handshake.h"
45 #include "tls_common.h"
46 #include "tls_certificate.h"
47 #include "tls_transcript_hash.h"
48 #include "tls_record.h"
49 #include "tls_misc.h"
50 #include "tls13_client_misc.h"
51 #include "dtls_record.h"
52 #include "pkix/pem_import.h"
53 #include "pkix/x509_cert_parse.h"
54 #include "debug.h"
55 
56 //Check TLS library configuration
57 #if (TLS_SUPPORT == ENABLED)
58 
59 
60 /**
61  * @brief TLS context initialization
62  * @return Handle referencing the fully initialized TLS context
63  **/
64 
66 {
67  TlsContext *context;
68 
69  //Allocate a memory buffer to hold the TLS context
70  context = tlsAllocMem(sizeof(TlsContext));
71 
72  //Successful memory allocation?
73  if(context != NULL)
74  {
75  //Clear TLS context
76  memset(context, 0, sizeof(TlsContext));
77 
78  //Default state
79  context->state = TLS_STATE_INIT;
80  //Default transport protocol
81  context->transportProtocol = TLS_TRANSPORT_PROTOCOL_STREAM;
82  //Default operation mode
83  context->entity = TLS_CONNECTION_END_CLIENT;
84  //Default client authentication mode
85  context->clientAuthMode = TLS_CLIENT_AUTH_NONE;
86 
87  //Minimum and maximum versions accepted by the implementation
88  context->versionMin = TLS_MIN_VERSION;
89  context->versionMax = TLS_MAX_VERSION;
90 
91  //Default record layer version number
92  context->version = TLS_MIN_VERSION;
93  context->encryptionEngine.version = TLS_MIN_VERSION;
94 
95 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
96  //Select default named group
98  {
99  context->preferredGroup = TLS_GROUP_ECDH_X25519;
100  }
101  else if(tls13IsGroupSupported(context, TLS_GROUP_SECP256R1))
102  {
103  context->preferredGroup = TLS_GROUP_SECP256R1;
104  }
105  else
106  {
107  context->preferredGroup = TLS_GROUP_NONE;
108  }
109 #endif
110 
111 #if (DTLS_SUPPORT == ENABLED)
112  //Default PMTU
113  context->pmtu = DTLS_DEFAULT_PMTU;
114  //Default timeout
115  context->timeout = INFINITE_DELAY;
116 #endif
117 
118 #if (DTLS_SUPPORT == ENABLED && DTLS_REPLAY_DETECTION_SUPPORT == ENABLED)
119  //Anti-replay mechanism is enabled by default
120  context->replayDetectionEnabled = TRUE;
121 #endif
122 
123 #if (TLS_DH_SUPPORT == ENABLED)
124  //Initialize Diffie-Hellman context
125  dhInit(&context->dhContext);
126 #endif
127 
128 #if (TLS_ECDH_SUPPORT == ENABLED)
129  //Initialize ECDH context
130  ecdhInit(&context->ecdhContext);
131 #endif
132 
133 #if (TLS_RSA_SUPPORT == ENABLED)
134  //Initialize peer's RSA public key
135  rsaInitPublicKey(&context->peerRsaPublicKey);
136 #endif
137 
138 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
139  //Initialize peer's DSA public key
140  dsaInitPublicKey(&context->peerDsaPublicKey);
141 #endif
142 
143 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_EDDSA_SIGN_SUPPORT == ENABLED)
144  //Initialize peer's EC domain parameters
145  ecInitDomainParameters(&context->peerEcParams);
146  //Initialize peer's EC public key
147  ecInit(&context->peerEcPublicKey);
148 #endif
149 
150  //Maximum number of plaintext data the TX and RX buffers can hold
151  context->txBufferMaxLen = TLS_MAX_RECORD_LENGTH;
152  context->rxBufferMaxLen = TLS_MAX_RECORD_LENGTH;
153 
154 #if (TLS_MAX_FRAG_LEN_SUPPORT == ENABLED)
155  //Maximum fragment length
156  context->maxFragLen = TLS_MAX_RECORD_LENGTH;
157 #endif
158 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
159  //Maximum record size the peer is willing to receive
160  context->recordSizeLimit = TLS_MAX_RECORD_LENGTH;
161 #endif
162 
163 #if (DTLS_SUPPORT == ENABLED)
164  //Calculate the required size for the TX buffer
165  context->txBufferSize = context->txBufferMaxLen + sizeof(DtlsRecord) +
167 
168  //Calculate the required size for the RX buffer
169  context->rxBufferSize = context->rxBufferMaxLen + sizeof(DtlsRecord) +
171 #else
172  //Calculate the required size for the TX buffer
173  context->txBufferSize = context->txBufferMaxLen + sizeof(TlsRecord) +
175 
176  //Calculate the required size for the RX buffer
177  context->rxBufferSize = context->rxBufferMaxLen + sizeof(TlsRecord) +
179 #endif
180  }
181 
182  //Return a pointer to the freshly created TLS context
183  return context;
184 }
185 
186 
187 /**
188  * @brief Retrieve current state
189  * @param[in] context Pointer to the TLS context
190  * @return Current TLS state
191  **/
192 
194 {
195  TlsState state;
196 
197  //Valid TLS context?
198  if(context != NULL)
199  state = context->state;
200  else
201  state = TLS_STATE_INIT;
202 
203  //Return current state
204  return state;
205 }
206 
207 
208 /**
209  * @brief Set socket send and receive callbacks
210  * @param[in] context Pointer to the TLS context
211  * @param[in] socketSendCallback Send callback function
212  * @param[in] socketReceiveCallback Receive callback function
213  * @param[in] handle Socket handle
214  * @return Error code
215  **/
216 
218  TlsSocketSendCallback socketSendCallback,
219  TlsSocketReceiveCallback socketReceiveCallback, TlsSocketHandle handle)
220 {
221  //Invalid TLS context?
222  if(context == NULL)
224 
225  //Check parameters
226  if(socketSendCallback == NULL || socketReceiveCallback == NULL)
228 
229  //Save send and receive callback functions
230  context->socketSendCallback = socketSendCallback;
231  context->socketReceiveCallback = socketReceiveCallback;
232 
233  //This socket handle will be directly passed to the callback functions
234  context->socketHandle = handle;
235 
236  //Successful processing
237  return NO_ERROR;
238 }
239 
240 
241 /**
242  * @brief Set minimum and maximum versions permitted
243  * @param[in] context Pointer to the TLS context
244  * @param[in] versionMin Minimum version accepted by the TLS implementation
245  * @param[in] versionMax Maximum version accepted by the TLS implementation
246  * @return Error code
247  **/
248 
249 error_t tlsSetVersion(TlsContext *context, uint16_t versionMin,
250  uint16_t versionMax)
251 {
252  //Invalid TLS context?
253  if(context == NULL)
255 
256  //Check parameters
257  if(versionMin < TLS_MIN_VERSION || versionMax > TLS_MAX_VERSION)
259  if(versionMin > versionMax)
261 
262  //Minimum version accepted by the implementation
263  context->versionMin = versionMin;
264  //Maximum version accepted by the implementation
265  context->versionMax = versionMax;
266 
267  //Default record layer version number
268  context->version = context->versionMin;
269  context->encryptionEngine.version = context->versionMin;
270 
271  //Successful processing
272  return NO_ERROR;
273 }
274 
275 
276 /**
277  * @brief Set the transport protocol to be used
278  * @param[in] context Pointer to the TLS context
279  * @param[in] transportProtocol Transport protocol to be used
280  * @return Error code
281  **/
282 
284  TlsTransportProtocol transportProtocol)
285 {
286  //Invalid TLS context?
287  if(context == NULL)
289 
290  //Check parameters
291  if(transportProtocol != TLS_TRANSPORT_PROTOCOL_STREAM &&
292  transportProtocol != TLS_TRANSPORT_PROTOCOL_DATAGRAM)
293  {
295  }
296 
297  //Set transport protocol
298  context->transportProtocol = transportProtocol;
299 
300  //Successful processing
301  return NO_ERROR;
302 }
303 
304 
305 /**
306  * @brief Set operation mode (client or server)
307  * @param[in] context Pointer to the TLS context
308  * @param[in] entity Specifies whether this entity is considered a client or a server
309  * @return Error code
310  **/
311 
313 {
314  //Invalid TLS context?
315  if(context == NULL)
317 
318  //Check parameters
319  if(entity != TLS_CONNECTION_END_CLIENT && entity != TLS_CONNECTION_END_SERVER)
321 
322  //Check whether TLS operates as a client or a server
323  context->entity = entity;
324 
325  //Successful processing
326  return NO_ERROR;
327 }
328 
329 
330 /**
331  * @brief Set the pseudo-random number generator to be used
332  * @param[in] context Pointer to the TLS context
333  * @param[in] prngAlgo PRNG algorithm
334  * @param[in] prngContext Pointer to the PRNG context
335  * @return Error code
336  **/
337 
338 error_t tlsSetPrng(TlsContext *context, const PrngAlgo *prngAlgo, void *prngContext)
339 {
340  //Invalid TLS context?
341  if(context == NULL)
343 
344  //Check parameters
345  if(prngAlgo == NULL || prngContext == NULL)
347 
348  //PRNG algorithm that will be used to generate random numbers
349  context->prngAlgo = prngAlgo;
350  //PRNG context
351  context->prngContext = prngContext;
352 
353  //Successful processing
354  return NO_ERROR;
355 }
356 
357 
358 /**
359  * @brief Set the server name
360  * @param[in] context Pointer to the TLS context
361  * @param[in] serverName Fully qualified domain name of the server
362  * @return Error code
363  **/
364 
365 error_t tlsSetServerName(TlsContext *context, const char_t *serverName)
366 {
367  size_t i;
368  size_t length;
369 
370  //Check parameters
371  if(context == NULL || serverName == NULL)
373 
374  //Retrieve the length of the server name
375  length = strlen(serverName);
376 
377  //Check whether the server name has already been configured
378  if(context->serverName != NULL)
379  {
380  //Release memory
381  tlsFreeMem(context->serverName);
382  context->serverName = NULL;
383  }
384 
385  //Valid server name?
386  if(length > 0)
387  {
388  //Allocate a memory block to hold the hostname
389  context->serverName = tlsAllocMem(length + 1);
390  //Failed to allocate memory?
391  if(context->serverName == NULL)
392  return ERROR_OUT_OF_MEMORY;
393 
394  //Convert the hostname into lowercase
395  for(i = 0; i < length; i++)
396  context->serverName[i] = tolower((uint8_t) serverName[i]);
397 
398  //Properly terminate the string with a NULL character
399  context->serverName[length] = '\0';
400  }
401 
402  //Successful processing
403  return NO_ERROR;
404 }
405 
406 
407 /**
408  * @brief Get the server name
409  * @param[in] context Pointer to the TLS context
410  * @return Fully qualified domain name of the server
411  **/
412 
414 {
415  static const char_t defaultServerName[] = "";
416 
417  //Valid protocol name?
418  if(context != NULL && context->serverName != NULL)
419  {
420  //Return the fully qualified domain name of the server
421  return context->serverName;
422  }
423  else
424  {
425  //Return an empty string
426  return defaultServerName;
427  }
428 }
429 
430 
431 /**
432  * @brief Set session cache
433  * @param[in] context Pointer to the TLS context
434  * @param[in] cache Session cache that will be used to save/resume TLS sessions
435  * @return Error code
436  **/
437 
439 {
440  //Check parameters
441  if(context == NULL)
443 
444  //The cache will be used to save/resume TLS sessions
445  context->cache = cache;
446 
447  //Successful processing
448  return NO_ERROR;
449 }
450 
451 
452 /**
453  * @brief Set client authentication mode (for servers only)
454  * @param[in] context Pointer to the TLS context
455  * @param[in] mode Client authentication mode
456  * @return Error code
457  **/
458 
460 {
461  //Invalid TLS context?
462  if(context == NULL)
464 
465  //Save client authentication mode
466  context->clientAuthMode = mode;
467 
468  //Successful processing
469  return NO_ERROR;
470 }
471 
472 
473 /**
474  * @brief Set TLS buffer size
475  * @param[in] context Pointer to the TLS context
476  * @param[in] txBufferSize TX buffer size
477  * @param[in] rxBufferSize RX buffer size
478  * @return Error code
479  **/
480 
481 error_t tlsSetBufferSize(TlsContext *context, size_t txBufferSize,
482  size_t rxBufferSize)
483 {
484  //Invalid TLS context?
485  if(context == NULL)
487 
488  //Check parameters
489  if(txBufferSize < TLS_MIN_RECORD_LENGTH ||
490  rxBufferSize < TLS_MIN_RECORD_LENGTH)
491  {
493  }
494 
495  //Maximum number of plaintext data the TX and RX buffers can hold
496  context->txBufferMaxLen = txBufferSize;
497  context->rxBufferMaxLen = rxBufferSize;
498 
499 #if (DTLS_SUPPORT == ENABLED)
500  //Calculate the required size for the TX buffer
501  context->txBufferSize = txBufferSize + sizeof(DtlsRecord) +
503 
504  //Calculate the required size for the RX buffer
505  context->rxBufferSize = rxBufferSize + sizeof(DtlsRecord) +
507 #else
508  //Calculate the required size for the TX buffer
509  context->txBufferSize = txBufferSize + sizeof(TlsRecord) +
511 
512  //Calculate the required size for the RX buffer
513  context->rxBufferSize = rxBufferSize + sizeof(TlsRecord) +
515 #endif
516 
517  //Successful processing
518  return NO_ERROR;
519 }
520 
521 
522 /**
523  * @brief Set maximum fragment length
524  * @param[in] context Pointer to the TLS context
525  * @param[in] maxFragLen Maximum fragment length
526  * @return Error code
527  **/
528 
529 error_t tlsSetMaxFragmentLength(TlsContext *context, size_t maxFragLen)
530 {
531 #if (TLS_MAX_FRAG_LEN_SUPPORT == ENABLED)
532  //Invalid TLS context?
533  if(context == NULL)
535 
536  //Make sure the specified value is acceptable (ref to RFC 6066, section 4)
537  if(maxFragLen != 512 && maxFragLen != 1024 &&
538  maxFragLen != 2048 && maxFragLen != 4096 &&
539  maxFragLen != 16384)
540  {
542  }
543 
544  //Set maximum fragment length
545  context->maxFragLen = maxFragLen;
546 
547  //Successful processing
548  return NO_ERROR;
549 #else
550  //Not implemented
551  return ERROR_NOT_IMPLEMENTED;
552 #endif
553 }
554 
555 
556 /**
557  * @brief Specify the list of allowed cipher suites
558  * @param[in] context Pointer to the TLS context
559  * @param[in] cipherSuites List of allowed cipher suites (most preferred first)
560  * @param[in] length Number of cipher suites in the list
561  * @return Error code
562  **/
563 
564 error_t tlsSetCipherSuites(TlsContext *context, const uint16_t *cipherSuites,
565  uint_t length)
566 {
567  //Invalid TLS context?
568  if(context == NULL)
570 
571  //Check parameters
572  if(cipherSuites == NULL && length != 0)
574 
575  //Restrict the cipher suites that can be used
576  context->cipherSuites = cipherSuites;
577  context->numCipherSuites = length;
578 
579  //Successful processing
580  return NO_ERROR;
581 }
582 
583 
584 /**
585  * @brief Specify the list of allowed ECDHE and FFDHE groups
586  * @param[in] context Pointer to the TLS context
587  * @param[in] groups List of named groups
588  * @param[in] length Number of named groups in the list
589  * @return Error code
590  **/
591 
592 error_t tlsSetSupportedGroups(TlsContext *context, const uint16_t *groups,
593  uint_t length)
594 {
595  //Invalid TLS context?
596  if(context == NULL)
598 
599  //Check parameters
600  if(groups == NULL && length != 0)
602 
603  //Restrict the named groups that can be used
604  context->supportedGroups = groups;
605  context->numSupportedGroups = length;
606 
607  //Successful processing
608  return NO_ERROR;
609 }
610 
611 
612 /**
613  * @brief Specify the preferred ECDHE or FFDHE group
614  * @param[in] context Pointer to the TLS context
615  * @param[in] group Preferred ECDHE or FFDHE named group
616  * @return Error code
617  **/
618 
620 {
621 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
622  //Invalid TLS context?
623  if(context == NULL)
625 
626  //Save the preferred named group
627  context->preferredGroup = group;
628 
629  //Successful processing
630  return NO_ERROR;
631 #else
632  //Not implemented
633  return ERROR_NOT_IMPLEMENTED;
634 #endif
635 }
636 
637 
638 /**
639  * @brief Import Diffie-Hellman parameters
640  * @param[in] context Pointer to the TLS context
641  * @param[in] params PEM structure that holds Diffie-Hellman parameters
642  * @param[in] length Total length of the DER structure
643  * @return Error code
644  **/
645 
646 error_t tlsSetDhParameters(TlsContext *context, const char_t *params,
647  size_t length)
648 {
649 #if (TLS_DH_SUPPORT == ENABLED)
650  //Invalid TLS context?
651  if(context == NULL)
653 
654  //Check parameters
655  if(params == NULL && length != 0)
657 
658  //Decode the PEM structure that holds Diffie-Hellman parameters
659  return pemImportDhParameters(params, length, &context->dhContext.params);
660 #else
661  //Diffie-Hellman is not implemented
662  return ERROR_NOT_IMPLEMENTED;
663 #endif
664 }
665 
666 
667 /**
668  * @brief Register ECDH key agreement callback function
669  * @param[in] context Pointer to the TLS context
670  * @param[in] ecdhCallback ECDH callback function
671  * @return Error code
672  **/
673 
675 {
676 #if (TLS_ECC_CALLBACK_SUPPORT == ENABLED)
677  //Check parameters
678  if(context == NULL || ecdhCallback == NULL)
680 
681  //Save the ECDH key agreement callback function
682  context->ecdhCallback = ecdhCallback;
683 
684  //Successful processing
685  return NO_ERROR;
686 #else
687  //PSK key exchange is not implemented
688  return ERROR_NOT_IMPLEMENTED;
689 #endif
690 }
691 
692 
693 /**
694  * @brief ECDSA signature generation callback function
695  * @param[in] context Pointer to the TLS context
696  * @param[in] ecdsaSignCallback ECDSA signature generation callback function
697  * @return Error code
698  **/
699 
701  TlsEcdsaSignCallback ecdsaSignCallback)
702 {
703 #if (TLS_ECC_CALLBACK_SUPPORT == ENABLED)
704  //Check parameters
705  if(context == NULL || ecdsaSignCallback == NULL)
707 
708  //Save the ECDSA signature generation callback function
709  context->ecdsaSignCallback = ecdsaSignCallback;
710 
711  //Successful processing
712  return NO_ERROR;
713 #else
714  //PSK key exchange is not implemented
715  return ERROR_NOT_IMPLEMENTED;
716 #endif
717 }
718 
719 
720 /**
721  * @brief Register ECDSA signature verification callback function
722  * @param[in] context Pointer to the TLS context
723  * @param[in] ecdsaVerifyCallback ECDSA signature verification callback function
724  * @return Error code
725  **/
726 
728  TlsEcdsaVerifyCallback ecdsaVerifyCallback)
729 {
730 #if (TLS_ECC_CALLBACK_SUPPORT == ENABLED)
731  //Check parameters
732  if(context == NULL || ecdsaVerifyCallback == NULL)
734 
735  //Save the ECDSA signature verification callback function
736  context->ecdsaVerifyCallback = ecdsaVerifyCallback;
737 
738  //Successful processing
739  return NO_ERROR;
740 #else
741  //PSK key exchange is not implemented
742  return ERROR_NOT_IMPLEMENTED;
743 #endif
744 }
745 
746 
747 /**
748  * @brief Register key logging callback function (for debugging purpose only)
749  * @param[in] context Pointer to the TLS context
750  * @param[in] keyLogCallback Key logging callback function
751  * @return Error code
752  **/
753 
755  TlsKeyLogCallback keyLogCallback)
756 {
757 #if (TLS_KEY_LOG_SUPPORT == ENABLED)
758  //Check parameters
759  if(context == NULL || keyLogCallback == NULL)
761 
762  //Save the key logging callback function
763  context->keyLogCallback = keyLogCallback;
764 
765  //Successful processing
766  return NO_ERROR;
767 #else
768  //Key logging is not implemented
769  return ERROR_NOT_IMPLEMENTED;
770 #endif
771 }
772 
773 
774 /**
775  * @brief Allow unknown ALPN protocols
776  * @param[in] context Pointer to the TLS context
777  * @param[in] allowed Specifies whether unknown ALPN protocols are allowed
778  * @return Error code
779  **/
780 
782 {
783 #if (TLS_ALPN_SUPPORT == ENABLED)
784  //Invalid TLS context?
785  if(context == NULL)
787 
788  //Allow or disallow unknown ALPN protocols
789  context->unknownProtocolsAllowed = allowed;
790 
791  //Successful processing
792  return NO_ERROR;
793 #else
794  //ALPN is not implemented
795  return ERROR_NOT_IMPLEMENTED;
796 #endif
797 }
798 
799 
800 /**
801  * @brief Set the list of supported ALPN protocols
802  * @param[in] context Pointer to the TLS context
803  * @param[in] protocolList Comma-delimited list of supported protocols
804  * @return Error code
805  **/
806 
807 error_t tlsSetAlpnProtocolList(TlsContext *context, const char_t *protocolList)
808 {
809 #if (TLS_ALPN_SUPPORT == ENABLED)
810  size_t length;
811 
812  //Check parameters
813  if(context == NULL || protocolList == NULL)
815 
816  //Retrieve the length of the list
817  length = strlen(protocolList);
818 
819  //Check whether the list of supported protocols has already been configured
820  if(context->protocolList != NULL)
821  {
822  //Release memory
823  tlsFreeMem(context->protocolList);
824  context->protocolList = NULL;
825  }
826 
827  //Check whether the list of protocols is valid
828  if(length > 0)
829  {
830  //Allocate a memory block to hold the list
831  context->protocolList = tlsAllocMem(length + 1);
832  //Failed to allocate memory?
833  if(context->protocolList == NULL)
834  return ERROR_OUT_OF_MEMORY;
835 
836  //Save the list of supported protocols
837  strcpy(context->protocolList, protocolList);
838  }
839 
840  //Successful processing
841  return NO_ERROR;
842 #else
843  //ALPN is not implemented
844  return ERROR_NOT_IMPLEMENTED;
845 #endif
846 }
847 
848 
849 /**
850  * @brief Get the name of the selected ALPN protocol
851  * @param[in] context Pointer to the TLS context
852  * @return Pointer to the protocol name
853  **/
854 
856 {
857  static const char_t defaultProtocolName[] = "";
858 
859 #if (TLS_ALPN_SUPPORT == ENABLED)
860  //Valid protocol name?
861  if(context != NULL && context->selectedProtocol != NULL)
862  {
863  //Return the name of the selected protocol
864  return context->selectedProtocol;
865  }
866  else
867 #endif
868  {
869  //Return an empty string
870  return defaultProtocolName;
871  }
872 }
873 
874 
875 /**
876  * @brief Set the pre-shared key to be used
877  * @param[in] context Pointer to the TLS context
878  * @param[in] psk Pointer to the pre-shared key
879  * @param[in] length Length of the pre-shared key, in bytes
880  * @return Error code
881  **/
882 
883 error_t tlsSetPsk(TlsContext *context, const uint8_t *psk, size_t length)
884 {
885 #if (TLS_PSK_SUPPORT == ENABLED)
886  //Invalid TLS context?
887  if(context == NULL)
889 
890  //Check parameters
891  if(psk == NULL && length != 0)
893 
894  //Check whether the pre-shared key has already been configured
895  if(context->psk != NULL)
896  {
897  //Release memory
898  memset(context->psk, 0, context->pskLen);
899  tlsFreeMem(context->psk);
900  context->psk = NULL;
901  context->pskLen = 0;
902  }
903 
904  //Valid PSK?
905  if(length > 0)
906  {
907  //Allocate a memory block to hold the pre-shared key
908  context->psk = tlsAllocMem(length);
909  //Failed to allocate memory?
910  if(context->psk == NULL)
911  return ERROR_OUT_OF_MEMORY;
912 
913  //Save the pre-shared key
914  memcpy(context->psk, psk, length);
915  //Save the length of the key
916  context->pskLen = length;
917  }
918 
919 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
920  //For externally established PSKs, the hash algorithm must be set when the
921  //PSK is established, or default to SHA-256 if no such algorithm is defined
922  context->pskHashAlgo = TLS_HASH_ALGO_SHA256;
923 
924  //The cipher suite must be provisioned along with the key
925  context->pskCipherSuite = 0;
926 #endif
927 
928  //Successful processing
929  return NO_ERROR;
930 #else
931  //PSK key exchange is not implemented
932  return ERROR_NOT_IMPLEMENTED;
933 #endif
934 }
935 
936 
937 /**
938  * @brief Set the PSK identity to be used by the client
939  * @param[in] context Pointer to the TLS context
940  * @param[in] pskIdentity NULL-terminated string that contains the PSK identity
941  * @return Error code
942  **/
943 
944 error_t tlsSetPskIdentity(TlsContext *context, const char_t *pskIdentity)
945 {
946 #if (TLS_PSK_SUPPORT == ENABLED)
947  size_t length;
948 
949  //Check parameters
950  if(context == NULL || pskIdentity == NULL)
952 
953  //Retrieve the length of the PSK identity
954  length = strlen(pskIdentity);
955 
956  //Check whether the PSK identity has already been configured
957  if(context->pskIdentity != NULL)
958  {
959  //Release memory
960  tlsFreeMem(context->pskIdentity);
961  context->pskIdentity = NULL;
962  }
963 
964  //Valid PSK identity?
965  if(length > 0)
966  {
967  //Allocate a memory block to hold the PSK identity
968  context->pskIdentity = tlsAllocMem(length + 1);
969  //Failed to allocate memory?
970  if(context->pskIdentity == NULL)
971  return ERROR_OUT_OF_MEMORY;
972 
973  //Save the PSK identity
974  strcpy(context->pskIdentity, pskIdentity);
975  }
976 
977  //Successful processing
978  return NO_ERROR;
979 #else
980  //PSK key exchange is not implemented
981  return ERROR_NOT_IMPLEMENTED;
982 #endif
983 }
984 
985 
986 /**
987  * @brief Set the PSK identity hint to be used by the server
988  * @param[in] context Pointer to the TLS context
989  * @param[in] pskIdentityHint NULL-terminated string that contains the PSK identity hint
990  * @return Error code
991  **/
992 
993 error_t tlsSetPskIdentityHint(TlsContext *context, const char_t *pskIdentityHint)
994 {
995 #if (TLS_PSK_SUPPORT == ENABLED)
996  size_t length;
997 
998  //Check parameters
999  if(context == NULL || pskIdentityHint == NULL)
1000  return ERROR_INVALID_PARAMETER;
1001 
1002  //Retrieve the length of the PSK identity hint
1003  length = strlen(pskIdentityHint);
1004 
1005  //Check whether the PSK identity hint has already been configured
1006  if(context->pskIdentityHint != NULL)
1007  {
1008  //Release memory
1009  tlsFreeMem(context->pskIdentityHint);
1010  context->pskIdentityHint = NULL;
1011  }
1012 
1013  //Valid PSK identity hint?
1014  if(length > 0)
1015  {
1016  //Allocate a memory block to hold the PSK identity hint
1017  context->pskIdentityHint = tlsAllocMem(length + 1);
1018  //Failed to allocate memory?
1019  if(context->pskIdentityHint == NULL)
1020  return ERROR_OUT_OF_MEMORY;
1021 
1022  //Save the PSK identity hint
1023  strcpy(context->pskIdentityHint, pskIdentityHint);
1024  }
1025 
1026  //Successful processing
1027  return NO_ERROR;
1028 #else
1029  //PSK key exchange is not implemented
1030  return ERROR_NOT_IMPLEMENTED;
1031 #endif
1032 }
1033 
1034 
1035 /**
1036  * @brief Register the PSK callback function
1037  * @param[in] context Pointer to the TLS context
1038  * @param[in] pskCallback PSK callback function
1039  * @return Error code
1040  **/
1041 
1043 {
1044 #if (TLS_PSK_SUPPORT == ENABLED)
1045  //Check parameters
1046  if(context == NULL || pskCallback == NULL)
1047  return ERROR_INVALID_PARAMETER;
1048 
1049  //Save the PSK callback function
1050  context->pskCallback = pskCallback;
1051 
1052  //Successful processing
1053  return NO_ERROR;
1054 #else
1055  //PSK key exchange is not implemented
1056  return ERROR_NOT_IMPLEMENTED;
1057 #endif
1058 }
1059 
1060 
1061 /**
1062  * @brief Register the raw public key verification callback function
1063  * @param[in] context Pointer to the TLS context
1064  * @param[in] rpkVerifyCallback RPK verification callback function
1065  * @return Error code
1066  **/
1067 
1069  TlsRpkVerifyCallback rpkVerifyCallback)
1070 {
1071 #if (TLS_RAW_PUBLIC_KEY_SUPPORT == ENABLED)
1072  //Check parameters
1073  if(context == NULL || rpkVerifyCallback == NULL)
1074  return ERROR_INVALID_PARAMETER;
1075 
1076  //Save the raw public key verification callback function
1077  context->rpkVerifyCallback = rpkVerifyCallback;
1078 
1079  //Successful processing
1080  return NO_ERROR;
1081 #else
1082  //Raw public keys are not implemented
1083  return ERROR_NOT_IMPLEMENTED;
1084 #endif
1085 }
1086 
1087 
1088 /**
1089  * @brief Import a trusted CA list
1090  * @param[in] context Pointer to the TLS context
1091  * @param[in] trustedCaList List of trusted CA (PEM format)
1092  * @param[in] length Total length of the list
1093  * @return Error code
1094  **/
1095 
1097  const char_t *trustedCaList, size_t length)
1098 {
1099  //Invalid TLS context?
1100  if(context == NULL)
1101  return ERROR_INVALID_PARAMETER;
1102 
1103  //Check parameters
1104  if(trustedCaList == NULL && length != 0)
1105  return ERROR_INVALID_PARAMETER;
1106 
1107  //Save the list of trusted CA
1108  context->trustedCaList = trustedCaList;
1109  context->trustedCaListLen = length;
1110 
1111  //Successful processing
1112  return NO_ERROR;
1113 }
1114 
1115 
1116 /**
1117  * @brief Import a certificate and the corresponding private key
1118  * @param[in] context Pointer to the TLS context
1119  * @param[in] certChain Certificate chain (PEM format)
1120  * @param[in] certChainLen Total length of the certificate chain
1121  * @param[in] privateKey Private key (PEM format)
1122  * @param[in] privateKeyLen Total length of the private key
1123  * @return Error code
1124  **/
1125 
1126 error_t tlsAddCertificate(TlsContext *context, const char_t *certChain,
1127  size_t certChainLen, const char_t *privateKey, size_t privateKeyLen)
1128 {
1129  error_t error;
1130  uint8_t *derCert;
1131  size_t derCertLen;
1132  X509CertificateInfo *certInfo;
1133  TlsCertificateType certType;
1134  TlsSignatureAlgo certSignAlgo;
1135  TlsHashAlgo certHashAlgo;
1136  TlsNamedGroup namedCurve;
1137 
1138  //Invalid TLS context?
1139  if(context == NULL)
1140  return ERROR_INVALID_PARAMETER;
1141 
1142  //Check whether the certificate chain is valid
1143  if(certChain == NULL || certChainLen == 0)
1144  return ERROR_INVALID_PARAMETER;
1145 
1146  //The private key is optional
1147  if(privateKey == NULL && privateKeyLen != 0)
1148  return ERROR_INVALID_PARAMETER;
1149 
1150  //Make sure there is enough room to add the certificate
1151  if(context->numCerts >= TLS_MAX_CERTIFICATES)
1152  return ERROR_OUT_OF_RESOURCES;
1153 
1154  //Initialize variables
1155  derCert = NULL;
1156  certInfo = NULL;
1157 
1158  //Start of exception handling block
1159  do
1160  {
1161  //The first pass calculates the length of the DER-encoded certificate
1162  error = pemImportCertificate(certChain, certChainLen, NULL, &derCertLen,
1163  NULL);
1164  //Any error to report?
1165  if(error)
1166  break;
1167 
1168  //Allocate a memory buffer to hold the DER-encoded certificate
1169  derCert = tlsAllocMem(derCertLen);
1170  //Failed to allocate memory?
1171  if(derCert == NULL)
1172  {
1173  error = ERROR_OUT_OF_MEMORY;
1174  break;
1175  }
1176 
1177  //The second pass decodes the PEM certificate
1178  error = pemImportCertificate(certChain, certChainLen, derCert,
1179  &derCertLen, NULL);
1180  //Any error to report?
1181  if(error)
1182  break;
1183 
1184  //Allocate a memory buffer to store X.509 certificate info
1185  certInfo = tlsAllocMem(sizeof(X509CertificateInfo));
1186  //Failed to allocate memory?
1187  if(certInfo == NULL)
1188  {
1189  error = ERROR_OUT_OF_MEMORY;
1190  break;
1191  }
1192 
1193  //Parse X.509 certificate
1194  error = x509ParseCertificate(derCert, derCertLen, certInfo);
1195  //Failed to parse the X.509 certificate?
1196  if(error)
1197  break;
1198 
1199  //Retrieve the signature algorithm that has been used to sign the
1200  //certificate
1201  error = tlsGetCertificateType(certInfo, &certType, &certSignAlgo,
1202  &certHashAlgo, &namedCurve);
1203  //The specified signature algorithm is not supported?
1204  if(error)
1205  break;
1206 
1207  //End of exception handling block
1208  } while(0);
1209 
1210  //Valid certificate?
1211  if(!error)
1212  {
1213  //Point to the structure that describes the certificate
1214  TlsCertDesc *cert = &context->certs[context->numCerts];
1215 
1216  //Save the certificate chain and the corresponding private key
1217  cert->certChain = certChain;
1218  cert->certChainLen = certChainLen;
1219  cert->privateKey = privateKey;
1220  cert->privateKeyLen = privateKeyLen;
1221  cert->type = certType;
1222  cert->signAlgo = certSignAlgo;
1223  cert->hashAlgo = certHashAlgo;
1224  cert->namedCurve = namedCurve;
1225 
1226  //Update the number of certificates
1227  context->numCerts++;
1228  }
1229 
1230  //Release previously allocated memory
1231  tlsFreeMem(derCert);
1232  tlsFreeMem(certInfo);
1233 
1234  //Return status code
1235  return error;
1236 }
1237 
1238 
1239 /**
1240  * @brief Set certificate verification callback
1241  * @param[in] context Pointer to the TLS context
1242  * @param[in] certVerifyCallback Certificate verification callback
1243  * @param[in] param An opaque pointer passed to the callback function
1244  * @return Error code
1245  **/
1246 
1248  TlsCertVerifyCallback certVerifyCallback, void *param)
1249 {
1250  //Invalid TLS context?
1251  if(context == NULL)
1252  return ERROR_INVALID_PARAMETER;
1253 
1254  //Save certificate verification callback
1255  context->certVerifyCallback = certVerifyCallback;
1256 
1257  //This opaque pointer will be directly passed to the callback function
1258  context->certVerifyParam = param;
1259 
1260  //Successful processing
1261  return NO_ERROR;
1262 }
1263 
1264 
1265 /**
1266  * @brief Enable secure renegotiation
1267  * @param[in] context Pointer to the TLS context
1268  * @param[in] enabled Specifies whether secure renegotiation is allowed
1269  * @return Error code
1270  **/
1271 
1273 {
1274 #if (TLS_SECURE_RENEGOTIATION_SUPPORT == ENABLED)
1275  //Invalid TLS context?
1276  if(context == NULL)
1277  return ERROR_INVALID_PARAMETER;
1278 
1279  //Enable or disable secure renegotiation
1280  context->secureRenegoEnabled = enabled;
1281 
1282  //Successful processing
1283  return NO_ERROR;
1284 #else
1285  //Secure renegotiation is not implemented
1286  return ERROR_NOT_IMPLEMENTED;
1287 #endif
1288 }
1289 
1290 
1291 /**
1292  * @brief Perform fallback retry (for clients only)
1293  * @param[in] context Pointer to the TLS context
1294  * @param[in] enabled Specifies whether FALLBACK_SCSV is enabled
1295  * @return Error code
1296  **/
1297 
1299 {
1300 #if (TLS_FALLBACK_SCSV_SUPPORT == ENABLED)
1301  //Invalid TLS context?
1302  if(context == NULL)
1303  return ERROR_INVALID_PARAMETER;
1304 
1305  //Enable or disable support for FALLBACK_SCSV
1306  context->fallbackScsvEnabled = enabled;
1307 
1308  //Successful processing
1309  return NO_ERROR;
1310 #else
1311  //Not implemented
1312  return ERROR_NOT_IMPLEMENTED;
1313 #endif
1314 }
1315 
1316 
1317 /**
1318  * @brief Set ticket encryption/decryption callbacks
1319  * @param[in] context Pointer to the TLS context
1320  * @param[in] ticketEncryptCallback Ticket encryption callback function
1321  * @param[in] ticketDecryptCallback Ticket decryption callback function
1322  * @param[in] param An opaque pointer passed to the callback functions
1323  * @return Error code
1324  **/
1325 
1327  TlsTicketEncryptCallback ticketEncryptCallback,
1328  TlsTicketDecryptCallback ticketDecryptCallback, void *param)
1329 {
1330 #if (TLS_TICKET_SUPPORT == ENABLED)
1331  //Invalid TLS context?
1332  if(context == NULL)
1333  return ERROR_INVALID_PARAMETER;
1334 
1335  //Save ticket encryption/decryption callback functions
1336  context->ticketEncryptCallback = ticketEncryptCallback;
1337  context->ticketDecryptCallback = ticketDecryptCallback;
1338 
1339  //This opaque pointer will be directly passed to the callback functions
1340  context->ticketParam = param;
1341 
1342  //Successful processing
1343  return NO_ERROR;
1344 #else
1345  //Session ticket mechanism is not implemented
1346  return ERROR_NOT_IMPLEMENTED;
1347 #endif
1348 }
1349 
1350 
1351 /**
1352  * @brief Set PMTU value (for DTLS only)
1353  * @param[in] context Pointer to the TLS context
1354  * @param[in] pmtu PMTU value
1355  * @return Error code
1356  **/
1357 
1358 error_t tlsSetPmtu(TlsContext *context, size_t pmtu)
1359 {
1360 #if (DTLS_SUPPORT == ENABLED)
1361  //Invalid TLS context?
1362  if(context == NULL)
1363  return ERROR_INVALID_PARAMETER;
1364 
1365  //Make sure the PMTU value is acceptable
1366  if(pmtu < DTLS_MIN_PMTU)
1367  return ERROR_INVALID_PARAMETER;
1368 
1369  //Save PMTU value
1370  context->pmtu = pmtu;
1371 
1372  //Successful processing
1373  return NO_ERROR;
1374 #else
1375  //DTLS is not implemented
1376  return ERROR_NOT_IMPLEMENTED;
1377 #endif
1378 }
1379 
1380 
1381 /**
1382  * @brief Set timeout for blocking calls (for DTLS only)
1383  * @param[in] context Pointer to the TLS context
1384  * @param[in] timeout Maximum time to wait
1385  * @return Error code
1386  **/
1387 
1389 {
1390 #if (DTLS_SUPPORT == ENABLED)
1391  //Invalid TLS context?
1392  if(context == NULL)
1393  return ERROR_INVALID_PARAMETER;
1394 
1395  //Save timeout value
1396  context->timeout = timeout;
1397 
1398  //Successful processing
1399  return NO_ERROR;
1400 #else
1401  //DTLS is not implemented
1402  return ERROR_NOT_IMPLEMENTED;
1403 #endif
1404 }
1405 
1406 
1407 /**
1408  * @brief Set cookie generation/verification callbacks (for DTLS only)
1409  * @param[in] context Pointer to the TLS context
1410  * @param[in] cookieGenerateCallback Cookie generation callback function
1411  * @param[in] cookieVerifyCallback Cookie verification callback function
1412  * @param[in] param An opaque pointer passed to the callback functions
1413  * @return Error code
1414  **/
1415 
1417  DtlsCookieGenerateCallback cookieGenerateCallback,
1418  DtlsCookieVerifyCallback cookieVerifyCallback, void *param)
1419 {
1420 #if (DTLS_SUPPORT == ENABLED)
1421  //Invalid TLS context?
1422  if(context == NULL)
1423  return ERROR_INVALID_PARAMETER;
1424 
1425  //Check parameters
1426  if(cookieGenerateCallback == NULL || cookieVerifyCallback == NULL)
1427  return ERROR_INVALID_PARAMETER;
1428 
1429  //Save cookie generation/verification callback functions
1430  context->cookieGenerateCallback = cookieGenerateCallback;
1431  context->cookieVerifyCallback = cookieVerifyCallback;
1432 
1433  //This opaque pointer will be directly passed to the callback functions
1434  context->cookieParam = param;
1435 
1436  //Successful processing
1437  return NO_ERROR;
1438 #else
1439  //DTLS is not implemented
1440  return ERROR_NOT_IMPLEMENTED;
1441 #endif
1442 }
1443 
1444 
1445 /**
1446  * @brief Enable anti-replay mechanism (for DTLS only)
1447  * @param[in] context Pointer to the TLS context
1448  * @param[in] enabled Specifies whether anti-replay protection is enabled
1449  * @return Error code
1450  **/
1451 
1453 {
1454 #if (DTLS_SUPPORT == ENABLED && DTLS_REPLAY_DETECTION_SUPPORT == ENABLED)
1455  //Invalid TLS context?
1456  if(context == NULL)
1457  return ERROR_INVALID_PARAMETER;
1458 
1459  //Enable or disable anti-replay mechanism
1460  context->replayDetectionEnabled = enabled;
1461 
1462  //Successful processing
1463  return NO_ERROR;
1464 #else
1465  //Anti-replay mechanism is not implemented
1466  return ERROR_NOT_IMPLEMENTED;
1467 #endif
1468 }
1469 
1470 
1471 /**
1472  * @brief Send the maximum amount of 0-RTT data the server can accept
1473  * @param[in] context Pointer to the TLS context
1474  * @param[in] maxEarlyDataSize Maximum amount of 0-RTT data that the client
1475  * is allowed to send
1476  * @return Error code
1477  **/
1478 
1479 
1480 error_t tlsSetMaxEarlyDataSize(TlsContext *context, size_t maxEarlyDataSize)
1481 {
1482 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1483  //Invalid TLS context?
1484  if(context == NULL)
1485  return ERROR_INVALID_PARAMETER;
1486 
1487  //Save the maximum amount of 0-RTT data that the client is allowed to send
1488  context->maxEarlyDataSize = maxEarlyDataSize;
1489 
1490  //Successful processing
1491  return NO_ERROR;
1492 #else
1493  //Not implemented
1494  return ERROR_NOT_IMPLEMENTED;
1495 #endif
1496 }
1497 
1498 
1499 /**
1500  * @brief Send early data to the remote TLS server
1501  * @param[in] context Pointer to the TLS context
1502  * @param[in] data Pointer to a buffer containing the data to be transmitted
1503  * @param[in] length Number of bytes to be transmitted
1504  * @param[out] written Actual number of bytes written (optional parameter)
1505  * @param[in] flags Set of flags that influences the behavior of this function
1506  * @return Error code
1507  **/
1508 
1510  size_t length, size_t *written, uint_t flags)
1511 {
1512 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3 && \
1513  TLS_CLIENT_SUPPORT == ENABLED && TLS13_EARLY_DATA_SUPPORT == ENABLED)
1514  size_t n;
1515  error_t error;
1516 
1517  //Invalid TLS context?
1518  if(context == NULL)
1519  return ERROR_INVALID_PARAMETER;
1520 
1521  //Check parameters
1522  if(data == NULL && length != 0)
1523  return ERROR_INVALID_PARAMETER;
1524 
1525  //Check operation mode
1526  if(context->entity != TLS_CONNECTION_END_CLIENT)
1527  return ERROR_FAILURE;
1528 
1529  //Make sure TLS 1.3 is supported by the client
1530  if(context->versionMax < TLS_VERSION_1_3)
1531  return ERROR_FAILURE;
1532 
1533  //Check transport protocol
1534  if(context->transportProtocol != TLS_TRANSPORT_PROTOCOL_STREAM)
1535  return ERROR_FAILURE;
1536 
1537  //Ensure the send/receive functions are properly registered
1538  if(context->socketSendCallback == NULL || context->socketReceiveCallback == NULL)
1539  return ERROR_NOT_CONFIGURED;
1540 
1541  //Verify that the PRNG is properly set
1542  if(context->prngAlgo == NULL || context->prngContext == NULL)
1543  return ERROR_NOT_CONFIGURED;
1544 
1545 #if (DTLS_SUPPORT == ENABLED)
1546  //Save current time
1547  context->startTime = osGetSystemTime();
1548 #endif
1549 
1550  //Send 0-RTT data
1551  error = tls13SendEarlyData(context, data, length, &n);
1552 
1553  //Total number of data that have been written
1554  if(written != NULL)
1555  *written = n;
1556 
1557  //Return status code
1558  return error;
1559 #else
1560  //Not implemented
1561  return ERROR_NOT_IMPLEMENTED;
1562 #endif
1563 }
1564 
1565 
1566 /**
1567  * @brief Initiate the TLS handshake
1568  * @param[in] context Pointer to the TLS context
1569  * @return Error code
1570  **/
1571 
1573 {
1574  error_t error;
1575 
1576  //Invalid TLS context?
1577  if(context == NULL)
1578  return ERROR_INVALID_PARAMETER;
1579 
1580  //Ensure the send/receive functions are properly registered
1581  if(context->socketSendCallback == NULL || context->socketReceiveCallback == NULL)
1582  return ERROR_NOT_CONFIGURED;
1583 
1584  //Verify that the PRNG is properly set
1585  if(context->prngAlgo == NULL || context->prngContext == NULL)
1586  return ERROR_NOT_CONFIGURED;
1587 
1588 #if (DTLS_SUPPORT == ENABLED)
1589  //Save current time
1590  context->startTime = osGetSystemTime();
1591 #endif
1592 
1593 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3 && \
1594  TLS_CLIENT_SUPPORT == ENABLED && TLS13_EARLY_DATA_SUPPORT == ENABLED)
1595  //Any 0-RTT data sent by the client?
1596  if(context->entity == TLS_CONNECTION_END_CLIENT &&
1597  context->state == TLS_STATE_EARLY_DATA)
1598  {
1599  //Save current sequence number
1600  context->earlyDataSeqNum = context->encryptionEngine.seqNum;
1601  //Wait for a ServerHello message
1602  context->state = TLS_STATE_SERVER_HELLO_3;
1603  }
1604 #endif
1605 
1606  //Perform TLS handshake
1607  error = tlsPerformHandshake(context);
1608  //Return status code
1609  return error;
1610 }
1611 
1612 
1613 /**
1614  * @brief Check whether the server has accepted or rejected the early data
1615  * @param[in] context Pointer to the TLS context
1616  * @return TLS_EARLY_DATA_ACCEPTED if the early data was accepted, else
1617  * TLS_EARLY_DATA_REJECT if the early data was rejected
1618  **/
1619 
1621 {
1622  TlsEarlyDataStatus status;
1623 
1624  //Initialize early data status
1625  status = TLS_EARLY_DATA_REJECTED;
1626 
1627 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3 && \
1628  TLS_CLIENT_SUPPORT == ENABLED && TLS13_EARLY_DATA_SUPPORT == ENABLED)
1629  //Make sure the TLS context is valid
1630  if(context != NULL)
1631  {
1632  //Client mode?
1633  if(context->entity == TLS_CONNECTION_END_CLIENT)
1634  {
1635  //Any 0-RTT data sent by the client?
1636  if(context->earlyDataEnabled)
1637  {
1638  //Check whether the server has accepted or rejected the early data
1639  if(context->earlyDataExtReceived && !context->earlyDataRejected)
1640  {
1641  status = TLS_EARLY_DATA_ACCEPTED;
1642  }
1643  }
1644  }
1645  }
1646 #endif
1647 
1648  //Return early data status
1649  return status;
1650 }
1651 
1652 
1653 /**
1654  * @brief Send application data to the remote host using TLS
1655  * @param[in] context Pointer to the TLS context
1656  * @param[in] data Pointer to a buffer containing the data to be transmitted
1657  * @param[in] length Number of bytes to be transmitted
1658  * @param[out] written Actual number of bytes written (optional parameter)
1659  * @param[in] flags Set of flags that influences the behavior of this function
1660  * @return Error code
1661  **/
1662 
1663 error_t tlsWrite(TlsContext *context, const void *data,
1664  size_t length, size_t *written, uint_t flags)
1665 {
1666  error_t error;
1667  size_t n;
1668  size_t totalLength;
1669 
1670  //Invalid TLS context?
1671  if(context == NULL)
1672  return ERROR_INVALID_PARAMETER;
1673 
1674  //Check parameters
1675  if(data == NULL && length != 0)
1676  return ERROR_INVALID_PARAMETER;
1677 
1678  //Ensure the send/receive functions are properly registered
1679  if(context->socketSendCallback == NULL || context->socketReceiveCallback == NULL)
1680  return ERROR_NOT_CONFIGURED;
1681 
1682 #if (DTLS_SUPPORT == ENABLED)
1683  //Save current time
1684  context->startTime = osGetSystemTime();
1685 #endif
1686 
1687  //Initialize status code
1688  error = NO_ERROR;
1689 
1690  //Actual number of bytes written
1691  totalLength = 0;
1692 
1693  //Send as much data as possible
1694  while(totalLength < length)
1695  {
1696  //Check current state
1697  if(context->state < TLS_STATE_APPLICATION_DATA)
1698  {
1699  //Perform TLS handshake
1700  error = tlsConnect(context);
1701  }
1702  else if(context->state == TLS_STATE_APPLICATION_DATA)
1703  {
1704 #if (DTLS_SUPPORT == ENABLED)
1705  //DTLS protocol?
1706  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1707  {
1708  //Length of the payload data
1709  n = length;
1710 
1711  //Send a datagram
1712  error = dtlsWriteProtocolData(context, data, n,
1714  }
1715  else
1716 #endif
1717  //TLS protocol?
1718  {
1719  //Calculate the number of bytes to write at a time
1720  n = MIN(length - totalLength, context->txBufferMaxLen);
1721  //The record length must not exceed 16384 bytes
1723 
1724 #if (TLS_MAX_FRAG_LEN_SUPPORT == ENABLED)
1725  //Do not exceed the negotiated maximum fragment length
1726  n = MIN(n, context->maxFragLen);
1727 #endif
1728 
1729 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
1730  //Maximum record size the peer is willing to receive
1731  n = MIN(n, context->recordSizeLimit);
1732 #endif
1733 
1734 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_0)
1735  //The 1/n-1 record splitting technique is a workaround for the
1736  //BEAST attack
1737  if(context->version <= TLS_VERSION_1_0 &&
1738  context->cipherSuite.cipherMode == CIPHER_MODE_CBC &&
1739  context->txLastRecordLen != 1 &&
1740  totalLength == 0)
1741  {
1742  n = 1;
1743  }
1744 #endif
1745  //Send application data
1746  error = tlsWriteProtocolData(context, data, n,
1748  }
1749 
1750  //Check status code
1751  if(!error)
1752  {
1753 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_0)
1754  //Save the length of the TLS record
1755  context->txLastRecordLen = n;
1756 #endif
1757  //Advance data pointer
1758  data = (uint8_t *) data + n;
1759  //Update byte counter
1760  totalLength += n;
1761  }
1762  else
1763  {
1764  //Send an alert message to the peer, if applicable
1765  tlsProcessError(context, error);
1766  }
1767  }
1768  else
1769  {
1770  //The connection has not yet been established
1771  error = ERROR_NOT_CONNECTED;
1772  }
1773 
1774  //Any error to report?
1775  if(error)
1776  break;
1777  }
1778 
1779  //Total number of data that have been written
1780  if(written != NULL)
1781  *written = totalLength;
1782 
1783  //Return status code
1784  return error;
1785 }
1786 
1787 
1788 /**
1789  * @brief Receive application data from a the remote host using TLS
1790  * @param[in] context Pointer to the TLS context
1791  * @param[out] data Buffer into which received data will be placed
1792  * @param[in] size Maximum number of bytes that can be received
1793  * @param[out] received Number of bytes that have been received
1794  * @param[in] flags Set of flags that influences the behavior of this function
1795  * @return Error code
1796  **/
1797 
1798 error_t tlsRead(TlsContext *context, void *data,
1799  size_t size, size_t *received, uint_t flags)
1800 {
1801  error_t error;
1802  size_t i;
1803  size_t n;
1804  uint8_t *p;
1805  TlsContentType contentType;
1806 
1807  //Invalid TLS context?
1808  if(context == NULL)
1809  return ERROR_INVALID_PARAMETER;
1810 
1811  //Check parameters
1812  if(data == NULL || received == NULL)
1813  return ERROR_INVALID_PARAMETER;
1814 
1815  //Ensure the send/receive functions are properly registered
1816  if(context->socketSendCallback == NULL || context->socketReceiveCallback == NULL)
1817  return ERROR_NOT_CONFIGURED;
1818 
1819 #if (DTLS_SUPPORT == ENABLED)
1820  //Save current time
1821  context->startTime = osGetSystemTime();
1822 #endif
1823 
1824  //Initialize status code
1825  error = NO_ERROR;
1826 
1827  //No data has been read yet
1828  *received = 0;
1829 
1830  //Read as much data as possible
1831  while(*received < size)
1832  {
1833  //Check current state
1834  if(context->state < TLS_STATE_APPLICATION_DATA)
1835  {
1836  //Perform TLS handshake
1837  error = tlsConnect(context);
1838  }
1839  else if(context->state == TLS_STATE_APPLICATION_DATA)
1840  {
1841 #if (DTLS_SUPPORT == ENABLED)
1842  //DTLS protocol?
1843  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1844  {
1845  //Receive a datagram
1846  error = dtlsReadProtocolData(context, &p, &n, &contentType);
1847  }
1848  else
1849 #endif
1850  //TLS protocol?
1851  {
1852  //The record layer receives uninterpreted data from higher layers
1853  error = tlsReadProtocolData(context, &p, &n, &contentType);
1854  }
1855 
1856  //Check status code
1857  if(!error)
1858  {
1859  //Application data received?
1860  if(contentType == TLS_TYPE_APPLICATION_DATA)
1861  {
1862 #if (DTLS_SUPPORT == ENABLED)
1863  //DTLS protocol?
1864  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1865  {
1866  //Make sure the user buffer is large enough to hold the whole
1867  //datagram
1868  if(n > size)
1869  {
1870  //Report an error
1871  error = ERROR_BUFFER_OVERFLOW;
1872  }
1873  else
1874  {
1875  //Copy data to user buffer
1876  memcpy(data, p, n);
1877  //Total number of data that have been read
1878  *received = n;
1879  }
1880 
1881  //If the TLS_FLAG_PEEK flag is set, the data is copied into
1882  //the buffer but is not removed from the receive queue
1883  if(!(flags & TLS_FLAG_PEEK))
1884  {
1885  //Flush receive buffer
1886  context->rxBufferPos = 0;
1887  context->rxBufferLen = 0;
1888  }
1889 
1890  //We are done
1891  break;
1892  }
1893  else
1894 #endif
1895  //TLS protocol?
1896  {
1897  //Limit the number of bytes to read at a time
1898  n = MIN(n, size - *received);
1899 
1900  //The TLS_FLAG_BREAK_CHAR flag causes the function to stop reading
1901  //data as soon as the specified break character is encountered
1903  {
1904  //Retrieve the break character code
1905  char_t c = LSB(flags);
1906 
1907  //Search for the specified break character
1908  for(i = 0; i < n && p[i] != c; i++);
1909  //Adjust the number of data to read
1910  n = MIN(n, i + 1);
1911 
1912  //Copy data to user buffer
1913  memcpy(data, p, n);
1914  //Total number of data that have been read
1915  *received += n;
1916 
1917  //Advance data pointer
1918  context->rxBufferPos += n;
1919  //Number of bytes still pending in the receive buffer
1920  context->rxBufferLen -= n;
1921 
1922  //Check whether a break character has been found
1923  if(n > 0 && p[n - 1] == c)
1924  break;
1925  }
1926  else
1927  {
1928  //Copy data to user buffer
1929  memcpy(data, p, n);
1930  //Total number of data that have been read
1931  *received += n;
1932 
1933  //Advance data pointer
1934  context->rxBufferPos += n;
1935  //Number of bytes still pending in the receive buffer
1936  context->rxBufferLen -= n;
1937 
1938  //The TLS_FLAG_WAIT_ALL flag causes the function to return
1939  //only when the requested number of bytes have been read
1940  if(!(flags & TLS_FLAG_WAIT_ALL))
1941  break;
1942  }
1943 
1944  //Advance data pointer
1945  data = (uint8_t *) data + n;
1946  }
1947  }
1948  //Handshake message received?
1949  else if(contentType == TLS_TYPE_HANDSHAKE)
1950  {
1951  //Advance data pointer
1952  context->rxBufferPos += n;
1953  //Number of bytes still pending in the receive buffer
1954  context->rxBufferLen -= n;
1955 
1956  //Parse handshake message
1957  error = tlsParseHandshakeMessage(context, p, n);
1958  }
1959  //Alert message received?
1960  else if(contentType == TLS_TYPE_ALERT)
1961  {
1962  //Advance data pointer
1963  context->rxBufferPos += n;
1964  //Number of bytes still pending in the receive buffer
1965  context->rxBufferLen -= n;
1966 
1967  //Parse Alert message
1968  error = tlsParseAlert(context, (TlsAlert *) p, n);
1969  }
1970  //An inappropriate message was received?
1971  else
1972  {
1973  //Report an error
1974  error = ERROR_UNEXPECTED_MESSAGE;
1975  }
1976  }
1977 
1978  //Any error to report?
1979  if(error)
1980  {
1981  //Send an alert message to the peer, if applicable
1982  tlsProcessError(context, error);
1983  }
1984  }
1985  else if(context->state == TLS_STATE_CLOSING ||
1986  context->state == TLS_STATE_CLOSED)
1987  {
1988  //Check whether a fatal alert message has been sent or received
1989  if(context->fatalAlertSent || context->fatalAlertReceived)
1990  {
1991  //Alert messages with a level of fatal result in the immediate
1992  //termination of the connection
1993  error = ERROR_FAILURE;
1994  }
1995  else
1996  {
1997  //The user must be satisfied with data already on hand
1998  if(*received > 0)
1999  {
2000  //Some data are pending in the receive buffer
2001  error = NO_ERROR;
2002  break;
2003  }
2004  else
2005  {
2006  //The receive buffer is empty
2007  error = ERROR_END_OF_STREAM;
2008  }
2009  }
2010  }
2011  else
2012  {
2013  //The connection has not yet been established
2014  error = ERROR_NOT_CONNECTED;
2015  }
2016 
2017  //Any error to report?
2018  if(error)
2019  break;
2020  }
2021 
2022  //Return status code
2023  return error;
2024 }
2025 
2026 
2027 /**
2028  * @brief Check whether some data is ready for transmission
2029  * @param[in] context Pointer to the TLS context
2030  * @return The function returns TRUE if some data is ready for transmission.
2031  * Otherwise, FALSE is returned
2032  **/
2033 
2035 {
2036  bool_t ready;
2037 
2038  //Initialize flag
2039  ready = FALSE;
2040 
2041  //Make sure the TLS context is valid
2042  if(context != NULL)
2043  {
2044  //TLS protocol?
2045  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM)
2046  {
2047  //Check whether some data is pending in the transmit buffer
2048  if(context->txBufferPos < context->txBufferLen)
2049  {
2050  ready = TRUE;
2051  }
2052  }
2053  }
2054 
2055  //The function returns TRUE if some data is ready for transmission
2056  return ready;
2057 }
2058 
2059 
2060 /**
2061  * @brief Check whether some data is available in the receive buffer
2062  * @param[in] context Pointer to the TLS context
2063  * @return The function returns TRUE if some data is pending and can be read
2064  * immediately without blocking. Otherwise, FALSE is returned
2065  **/
2066 
2068 {
2069  bool_t ready;
2070 
2071  //Initialize flag
2072  ready = FALSE;
2073 
2074  //Make sure the TLS context is valid
2075  if(context != NULL)
2076  {
2077 #if (DTLS_SUPPORT == ENABLED)
2078  //DTLS protocol?
2079  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
2080  {
2081  //Check whether a datagram is pending in the receive buffer
2082  if(context->rxBufferLen > 0 ||
2083  context->rxRecordLen > 0 ||
2084  context->rxDatagramLen > 0)
2085  {
2086  ready = TRUE;
2087  }
2088  }
2089  else
2090 #endif
2091  //TLS protocol?
2092  {
2093  //Check whether some data is pending in the receive buffer
2094  if(context->rxBufferLen > 0)
2095  {
2096  ready = TRUE;
2097  }
2098  }
2099  }
2100 
2101  //The function returns TRUE if some data can be read immediately
2102  //without blocking
2103  return ready;
2104 }
2105 
2106 
2107 /**
2108  * @brief Gracefully close TLS session
2109  * @param[in] context Pointer to the TLS context
2110  **/
2111 
2113 {
2114  //Either party may initiate a close by sending a close_notify alert
2115  return tlsShutdownEx(context, FALSE);
2116 }
2117 
2118 
2119 /**
2120  * @brief Gracefully close TLS session
2121  * @param[in] context Pointer to the TLS context
2122  * @param[in] waitForCloseNotify Wait for the close notify alert from the peer
2123  **/
2124 
2125 error_t tlsShutdownEx(TlsContext *context, bool_t waitForCloseNotify)
2126 {
2127  error_t error;
2128  size_t n;
2129  uint8_t *p;
2130  TlsContentType contentType;
2131 
2132  //Invalid TLS context?
2133  if(context == NULL)
2134  return ERROR_INVALID_PARAMETER;
2135 
2136  //Ensure the send/receive functions are properly registered
2137  if(context->socketSendCallback == NULL || context->socketReceiveCallback == NULL)
2138  return ERROR_NOT_CONFIGURED;
2139 
2140 #if (DTLS_SUPPORT == ENABLED)
2141  //Save current time
2142  context->startTime = osGetSystemTime();
2143 #endif
2144 
2145  //Initialize status code
2146  error = NO_ERROR;
2147 
2148  //Wait for the TLS session to be closed
2149  while(context->state != TLS_STATE_CLOSED)
2150  {
2151  //Check current state
2152  if(context->state == TLS_STATE_APPLICATION_DATA)
2153  {
2154  //TLS protocol?
2155  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM)
2156  {
2157  //Flush send buffer
2158  error = tlsWriteProtocolData(context, NULL, 0, TLS_TYPE_NONE);
2159  }
2160 
2161  //Check status code
2162  if(!error)
2163  {
2164  //Either party may initiate a close by sending a close_notify alert
2165  context->state = TLS_STATE_CLOSING;
2166  }
2167  }
2168  else if(context->state == TLS_STATE_CLOSING)
2169  {
2170  //TLS protocol?
2171  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM)
2172  {
2173  //Flush send buffer
2174  error = tlsWriteProtocolData(context, NULL, 0, TLS_TYPE_NONE);
2175  }
2176 
2177  //Check status code
2178  if(!error)
2179  {
2180  //Unless some other fatal alert has been transmitted, each party
2181  //is required to send a close_notify alert before closing the
2182  //write side of the connection
2183  if(context->fatalAlertSent || context->fatalAlertReceived)
2184  {
2185  //Close the connection immediately
2186  context->state = TLS_STATE_CLOSED;
2187  }
2188  else if(!context->closeNotifySent)
2189  {
2190  //Notifies the recipient that the sender will not send any
2191  //more messages on this connection
2192  error = tlsSendAlert(context, TLS_ALERT_LEVEL_WARNING,
2194  }
2195  else if(!context->closeNotifyReceived && waitForCloseNotify)
2196  {
2197 #if (DTLS_SUPPORT == ENABLED)
2198  //DTLS protocol?
2199  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
2200  {
2201  //Wait for the responding close_notify alert
2202  error = dtlsReadProtocolData(context, &p, &n, &contentType);
2203  }
2204  else
2205 #endif
2206  //TLS protocol?
2207  {
2208  //Wait for the responding close_notify alert
2209  error = tlsReadProtocolData(context, &p, &n, &contentType);
2210  }
2211 
2212  //Check status code
2213  if(!error)
2214  {
2215  //Advance data pointer
2216  context->rxBufferPos += n;
2217  //Number of bytes still pending in the receive buffer
2218  context->rxBufferLen -= n;
2219 
2220  //Application data received?
2221  if(contentType == TLS_TYPE_APPLICATION_DATA)
2222  {
2223  //Discard application data
2224  }
2225  //Alert message received?
2226  else if(contentType == TLS_TYPE_ALERT)
2227  {
2228  //Parse Alert message
2229  error = tlsParseAlert(context, (TlsAlert *) p, n);
2230  }
2231  else if(contentType == TLS_TYPE_HANDSHAKE)
2232  {
2233  //Parse handshake message
2234  error = tlsParseHandshakeMessage(context, p, n);
2235  }
2236  //An inappropriate message was received?
2237  else
2238  {
2239  //Report an error
2240  error = ERROR_UNEXPECTED_MESSAGE;
2241  }
2242  }
2243  }
2244  else
2245  {
2246  //The connection is closed
2247  context->state = TLS_STATE_CLOSED;
2248  }
2249  }
2250  }
2251  else
2252  {
2253  //Report an error
2254  error = ERROR_NOT_CONNECTED;
2255  }
2256 
2257  //Any error to report?
2258  if(error)
2259  break;
2260  }
2261 
2262  //Return status code
2263  return error;
2264 }
2265 
2266 
2267 /**
2268  * @brief Release TLS context
2269  * @param[in] context Pointer to the TLS context
2270  **/
2271 
2272 void tlsFree(TlsContext *context)
2273 {
2274  //Valid TLS context?
2275  if(context != NULL)
2276  {
2277  //Release server name
2278  if(context->serverName != NULL)
2279  {
2280  tlsFreeMem(context->serverName);
2281  }
2282 
2283  //Release cookie
2284  if(context->cookie != NULL)
2285  {
2286  memset(context->cookie, 0, context->cookieLen);
2287  tlsFreeMem(context->cookie);
2288  }
2289 
2290  //Release send buffer
2291  if(context->txBuffer != NULL)
2292  {
2293  memset(context->txBuffer, 0, context->txBufferSize);
2294  tlsFreeMem(context->txBuffer);
2295  }
2296 
2297  //Release receive buffer
2298  if(context->rxBuffer != NULL)
2299  {
2300  memset(context->rxBuffer, 0, context->rxBufferSize);
2301  tlsFreeMem(context->rxBuffer);
2302  }
2303 
2304  //Release transcript hash context
2305  tlsFreeTranscriptHash(context);
2306 
2307 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
2308  //Release session ticket (TLS 1.3)
2309  if(context->ticket != NULL)
2310  {
2311  tlsFreeMem(context->ticket);
2312  }
2313 
2314  //Release the ALPN protocol associated with the ticket
2315  if(context->ticketAlpn != NULL)
2316  {
2317  tlsFreeMem(context->ticketAlpn);
2318  }
2319 #endif
2320 
2321 #if (TLS_DH_SUPPORT == ENABLED)
2322  //Release Diffie-Hellman context
2323  dhFree(&context->dhContext);
2324 #endif
2325 
2326 #if (TLS_ECDH_SUPPORT == ENABLED)
2327  //Release ECDH context
2328  ecdhFree(&context->ecdhContext);
2329 #endif
2330 
2331 #if (TLS_RSA_SUPPORT == ENABLED)
2332  //Release peer's RSA public key
2333  rsaFreePublicKey(&context->peerRsaPublicKey);
2334 #endif
2335 
2336 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
2337  //Release peer's DSA public key
2338  dsaFreePublicKey(&context->peerDsaPublicKey);
2339 #endif
2340 
2341 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_EDDSA_SIGN_SUPPORT == ENABLED)
2342  //Release peer's EC domain parameters
2343  ecFreeDomainParameters(&context->peerEcParams);
2344  //Release peer's EC public key
2345  ecFree(&context->peerEcPublicKey);
2346 #endif
2347 
2348 #if (TLS_PSK_SUPPORT == ENABLED)
2349  //Release the pre-shared key
2350  if(context->psk != NULL)
2351  {
2352  memset(context->psk, 0, context->pskLen);
2353  tlsFreeMem(context->psk);
2354  }
2355 
2356  //Release the PSK identity
2357  if(context->pskIdentity != NULL)
2358  {
2359  tlsFreeMem(context->pskIdentity);
2360  }
2361 
2362  //Release the PSK identity hint
2363  if(context->pskIdentityHint != NULL)
2364  {
2365  tlsFreeMem(context->pskIdentityHint);
2366  }
2367 #endif
2368 
2369 #if (TLS_ALPN_SUPPORT == ENABLED)
2370  //Release the list of supported ALPN protocols
2371  if(context->protocolList != NULL)
2372  {
2373  tlsFreeMem(context->protocolList);
2374  }
2375 
2376  //Release the selected ALPN protocol
2377  if(context->selectedProtocol != NULL)
2378  {
2379  tlsFreeMem(context->selectedProtocol);
2380  }
2381 #endif
2382 
2383  //Release encryption engine
2384  tlsFreeEncryptionEngine(&context->encryptionEngine);
2385  //Release decryption engine
2386  tlsFreeEncryptionEngine(&context->decryptionEngine);
2387 
2388 #if (DTLS_SUPPORT == ENABLED)
2389  //Release previous encryption engine
2390  tlsFreeEncryptionEngine(&context->prevEncryptionEngine);
2391 #endif
2392 
2393  //Clear the TLS context before freeing memory
2394  memset(context, 0, sizeof(TlsContext));
2395  tlsFreeMem(context);
2396  }
2397 }
2398 
2399 
2400 /**
2401  * @brief Initialize session state
2402  * @param[in] session Pointer to the session state
2403  * @return Error code
2404  **/
2405 
2407 {
2408  //Make sure the session state is valid
2409  if(session == NULL)
2410  return ERROR_INVALID_PARAMETER;
2411 
2412  //Erase session state
2413  memset(session, 0, sizeof(TlsSessionState));
2414 
2415  //Sucessful initialization
2416  return NO_ERROR;
2417 }
2418 
2419 
2420 /**
2421  * @brief Save TLS session
2422  * @param[in] context Pointer to the TLS context
2423  * @param[out] session Pointer to the session state
2424  * @return Error code
2425  **/
2426 
2428  TlsSessionState *session)
2429 {
2430  //Check parameters
2431  if(context == NULL || session == NULL)
2432  return ERROR_INVALID_PARAMETER;
2433 
2434  //Release previous session state
2435  tlsFreeSessionState(session);
2436 
2437 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
2438  //SSL 3.0, TLS 1.0, TLS 1.1 or TLS 1.2 currently selected?
2439  if(context->version >= SSL_VERSION_3_0 && context->version <= TLS_VERSION_1_2)
2440  {
2441  //Valid session parameters?
2442  if(context->cipherSuite.identifier != 0 &&
2443  context->sessionIdLen > 0)
2444  {
2445  //Get current time
2446  session->timestamp = osGetSystemTime();
2447 
2448  //Save session parameters
2449  session->version = context->version;
2450  session->cipherSuite = context->cipherSuite.identifier;
2451 
2452  //Save session identifier
2453  memcpy(session->sessionId, context->sessionId, context->sessionIdLen);
2454  session->sessionIdLen = context->sessionIdLen;
2455 
2456  //Save master secret
2457  memcpy(session->secret, context->masterSecret, TLS_MASTER_SECRET_SIZE);
2458 
2459 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
2460  //Extended master secret computation
2461  session->extendedMasterSecret = context->extendedMasterSecretExtReceived;
2462 #endif
2463 
2464 #if (TLS_SNI_SUPPORT == ENABLED)
2465  //Any ServerName extension received by the server?
2466  if(context->entity == TLS_CONNECTION_END_SERVER &&
2467  context->serverName != NULL)
2468  {
2469  size_t n;
2470 
2471  //Retrieve the length of the server name
2472  n = strlen(context->serverName);
2473 
2474  //Allocate a memory block to hold the server name
2475  session->serverName = tlsAllocMem(n + 1);
2476  //Failed to allocate memory?
2477  if(session->serverName == NULL)
2478  {
2479  //Clean up side effects
2480  tlsFreeSessionState(session);
2481  //Report an error
2482  return ERROR_OUT_OF_MEMORY;
2483  }
2484 
2485  //Copy the server name
2486  strcpy(session->serverName, context->serverName);
2487  }
2488 #endif
2489  }
2490  }
2491  else
2492 #endif
2493 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
2494  //TLS 1.3 currently selected?
2495  if(context->version == TLS_VERSION_1_3)
2496  {
2497  //Valid session parameters?
2498  if(context->cipherSuite.identifier != 0 &&
2499  context->cipherSuite.prfHashAlgo != NULL &&
2500  context->ticketLen > 0)
2501  {
2502  const HashAlgo *hashAlgo;
2503 
2504  //Point to the cipher suite hash algorithm
2505  hashAlgo = context->cipherSuite.prfHashAlgo;
2506 
2507  //Allocate a memory block to hold the ticket
2508  session->ticket = tlsAllocMem(context->ticketLen);
2509  //Failed to allocate memory?
2510  if(session->ticket == NULL)
2511  return ERROR_OUT_OF_MEMORY;
2512 
2513  //Get current time
2514  session->timestamp = osGetSystemTime();
2515 
2516  //Save session parameters
2517  session->version = context->version;
2518  session->cipherSuite = context->cipherSuite.identifier;
2519  session->ticketTimestamp = context->ticketTimestamp;
2520  session->ticketLifetime = context->ticketLifetime;
2521  session->ticketAgeAdd = context->ticketAgeAdd;
2522  session->maxEarlyDataSize = context->maxEarlyDataSize;
2523 
2524  //Copy session ticket
2525  memcpy(session->ticket, context->ticket, context->ticketLen);
2526  session->ticketLen = context->ticketLen;
2527 
2528  //Each PSK established via the ticket mechanism is associated with
2529  //a single hash algorithm
2530  if(hashAlgo == tlsGetHashAlgo(TLS_HASH_ALGO_SHA256))
2531  session->ticketHashAlgo = TLS_HASH_ALGO_SHA256;
2532  else if(hashAlgo == tlsGetHashAlgo(TLS_HASH_ALGO_SHA384))
2533  session->ticketHashAlgo = TLS_HASH_ALGO_SHA384;
2534  else
2535  session->ticketHashAlgo = TLS_HASH_ALGO_NONE;
2536 
2537  //Copy ticket PSK
2538  memcpy(session->secret, context->ticketPsk, hashAlgo->digestSize);
2539 
2540 #if (TLS_ALPN_SUPPORT == ENABLED)
2541  //Valid ALPN protocol?
2542  if(context->selectedProtocol != NULL)
2543  {
2544  size_t n;
2545 
2546  //Retrieve the length of the ALPN protocol
2547  n = strlen(context->selectedProtocol);
2548 
2549  //Allocate a memory block to hold the ALPN protocol
2550  session->ticketAlpn = tlsAllocMem(n + 1);
2551  //Failed to allocate memory?
2552  if(session->ticketAlpn == NULL)
2553  {
2554  //Clean up side effects
2555  tlsFreeSessionState(session);
2556  //Report an error
2557  return ERROR_OUT_OF_MEMORY;
2558  }
2559 
2560  //Copy the ALPN protocol associated with the ticket
2561  strcpy(session->ticketAlpn, context->selectedProtocol);
2562  }
2563 #endif
2564  }
2565  }
2566  else
2567 #endif
2568  //Invalid TLS version?
2569  {
2570  //Do not save session state
2571  }
2572 
2573  //Successful processing
2574  return NO_ERROR;
2575 }
2576 
2577 
2578 /**
2579  * @brief Restore TLS session
2580  * @param[in] context Pointer to the TLS context
2581  * @param[in] session Pointer to the session state to be restored
2582  * @return Error code
2583  **/
2584 
2586  const TlsSessionState *session)
2587 {
2588  //Check parameters
2589  if(context == NULL || session == NULL)
2590  return ERROR_INVALID_PARAMETER;
2591 
2592 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
2593  //SSL 3.0, TLS 1.0, TLS 1.1 or TLS 1.2 currently selected?
2594  if(session->version >= SSL_VERSION_3_0 && session->version <= TLS_VERSION_1_2)
2595  {
2596  //Valid session state?
2597  if(session->cipherSuite != 0 && session->sessionIdLen > 0)
2598  {
2599  //Restore session parameters
2600  context->version = session->version;
2601  context->cipherSuite.identifier = session->cipherSuite;
2602 
2603  //Restore session identifier
2604  memcpy(context->sessionId, session->sessionId, session->sessionIdLen);
2605  context->sessionIdLen = session->sessionIdLen;
2606 
2607  //Restore master secret
2608  memcpy(context->masterSecret, session->secret, TLS_MASTER_SECRET_SIZE);
2609 
2610 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
2611  //Extended master secret computation
2612  context->extendedMasterSecretExtReceived = session->extendedMasterSecret;
2613 #endif
2614  }
2615  }
2616  else
2617 #endif
2618 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
2619  //TLS 1.3 currently selected?
2620  if(session->version == TLS_VERSION_1_3)
2621  {
2622  //Valid ticket?
2623  if(session->cipherSuite != 0 && session->ticketLen > 0)
2624  {
2625  //Restore session parameters
2626  context->version = session->version;
2627  context->ticketCipherSuite = session->cipherSuite;
2628  context->ticketHashAlgo = session->ticketHashAlgo;
2629  context->ticketTimestamp = session->ticketTimestamp;
2630  context->ticketLifetime = session->ticketLifetime;
2631  context->ticketAgeAdd = session->ticketAgeAdd;
2632  context->maxEarlyDataSize = session->maxEarlyDataSize;
2633  context->sessionIdLen = 0;
2634 
2635  //Release existing session ticket, if any
2636  if(context->ticket != NULL)
2637  {
2638  memset(context->ticket, 0, context->ticketLen);
2639  tlsFreeMem(context->ticket);
2640  context->ticket = NULL;
2641  context->ticketLen = 0;
2642  }
2643 
2644  //Allocate a memory block to hold the ticket
2645  context->ticket = tlsAllocMem(session->ticketLen);
2646  //Failed to allocate memory?
2647  if(context->ticket == NULL)
2648  return ERROR_OUT_OF_MEMORY;
2649 
2650  //Copy session ticket
2651  memcpy(context->ticket, session->ticket, session->ticketLen);
2652  context->ticketLen = session->ticketLen;
2653 
2654  //Each PSK established via the ticket mechanism is associated with
2655  //a single hash algorithm
2656  if(session->ticketHashAlgo == TLS_HASH_ALGO_SHA256)
2657  context->ticketPskLen = SHA256_DIGEST_SIZE;
2658  else if(session->ticketHashAlgo == TLS_HASH_ALGO_SHA384)
2659  context->ticketPskLen = SHA384_DIGEST_SIZE;
2660  else
2661  context->ticketPskLen = 0;
2662 
2663  //Copy ticket PSK
2664  memcpy(context->ticketPsk, session->secret, context->ticketPskLen);
2665 
2666 #if (TLS_ALPN_SUPPORT == ENABLED)
2667  //Release ALPN protocol, if any
2668  if(context->ticketAlpn != NULL)
2669  {
2670  tlsFreeMem(context->ticketAlpn);
2671  context->ticketAlpn = NULL;
2672  }
2673 
2674  //Valid ALPN protocol?
2675  if(session->ticketAlpn != NULL)
2676  {
2677  size_t n;
2678 
2679  //Retrieve the length of the ALPN protocol
2680  n = strlen(session->ticketAlpn);
2681 
2682  //Allocate a memory block to hold the ALPN protocol
2683  context->ticketAlpn = tlsAllocMem(n + 1);
2684  //Failed to allocate memory?
2685  if(context->ticketAlpn == NULL)
2686  return ERROR_OUT_OF_MEMORY;
2687 
2688  //Copy the ALPN protocol associated with the ticket
2689  strcpy(context->ticketAlpn, session->ticketAlpn);
2690  }
2691 #endif
2692  }
2693  }
2694  else
2695 #endif
2696  //Invalid TLS version?
2697  {
2698  //Do not restore session state
2699  }
2700 
2701  //Successful processing
2702  return NO_ERROR;
2703 }
2704 
2705 
2706 /**
2707  * @brief Properly dispose a session state
2708  * @param[in] session Pointer to the session state to be released
2709  **/
2710 
2712 {
2713  //Make sure the session state is valid
2714  if(session != NULL)
2715  {
2716 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
2717  //Release session ticket
2718  if(session->ticket != NULL)
2719  {
2720  tlsFreeMem(session->ticket);
2721  }
2722 
2723  //Release the ALPN protocol associated with the ticket
2724  if(session->ticketAlpn != NULL)
2725  {
2726  tlsFreeMem(session->ticketAlpn);
2727  }
2728 #endif
2729 
2730 #if (TLS_SNI_SUPPORT == ENABLED)
2731  //Release server name
2732  if(session->serverName != NULL)
2733  {
2734  tlsFreeMem(session->serverName);
2735  }
2736 #endif
2737 
2738  //Erase session state
2739  memset(session, 0, sizeof(TlsSessionState));
2740  }
2741 }
2742 
2743 #endif
TlsContext * tlsInit(void)
TLS context initialization.
Definition: tls.c:65
error_t tlsSetSupportedGroups(TlsContext *context, const uint16_t *groups, uint_t length)
Specify the list of allowed ECDHE and FFDHE groups.
Definition: tls.c:592
#define TLS_MAX_RECORD_LENGTH
Definition: tls.h:830
#define tlsAllocMem(size)
Definition: tls.h:757
TLS helper functions.
X.509 certificate parsing.
uint8_t length
Definition: dtls_misc.h:149
error_t tlsEnableSecureRenegotiation(TlsContext *context, bool_t enabled)
Enable secure renegotiation.
Definition: tls.c:1272
error_t tlsSetConnectionEnd(TlsContext *context, TlsConnectionEnd entity)
Set operation mode (client or server)
Definition: tls.c:312
error_t tlsSetMaxEarlyDataSize(TlsContext *context, size_t maxEarlyDataSize)
Send the maximum amount of 0-RTT data the server can accept.
Definition: tls.c:1480
int bool_t
Definition: compiler_port.h:49
void rsaFreePublicKey(RsaPublicKey *key)
Release an RSA public key.
Definition: rsa.c:118
error_t tlsSetTransportProtocol(TlsContext *context, TlsTransportProtocol transportProtocol)
Set the transport protocol to be used.
Definition: tls.c:283
error_t(* TlsTicketEncryptCallback)(TlsContext *context, const uint8_t *plaintext, size_t plaintextLen, uint8_t *ciphertext, size_t *ciphertextLen, void *param)
Ticket encryption callback function.
Definition: tls.h:1764
@ TLS_ALERT_CLOSE_NOTIFY
Definition: tls.h:972
@ CIPHER_MODE_CBC
Definition: crypto.h:1082
#define DTLS_DEFAULT_PMTU
Definition: dtls_misc.h:47
error_t(* TlsEcdsaVerifyCallback)(TlsContext *context, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature verification callback function.
Definition: tls.h:1797
Common interface for pseudo-random number generators.
Definition: crypto.h:1168
error_t tlsPerformHandshake(TlsContext *context)
Perform TLS handshake.
TLS handshake.
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:140
uint8_t secret[48]
Master secret (TLS 1.2) or ticket PSK (TLS 1.3)
Definition: tls.h:1839
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
void ecInitDomainParameters(EcDomainParameters *params)
Initialize EC domain parameters.
Definition: ec.c:55
@ TLS_EARLY_DATA_REJECTED
Definition: tls.h:884
error_t tlsSetPskIdentityHint(TlsContext *context, const char_t *pskIdentityHint)
Set the PSK identity hint to be used by the server.
Definition: tls.c:993
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:192
TlsState
TLS FSM states.
Definition: tls.h:1287
uint8_t p
Definition: ndp.h:298
error_t tlsSetEcdhCallback(TlsContext *context, TlsEcdhCallback ecdhCallback)
Register ECDH key agreement callback function.
Definition: tls.c:674
TlsConnectionEnd
TLS connection end.
Definition: tls.h:859
systime_t timestamp
Time stamp to manage entry lifetime.
Definition: tls.h:1838
error_t tlsSetCertificateVerifyCallback(TlsContext *context, TlsCertVerifyCallback certVerifyCallback, void *param)
Set certificate verification callback.
Definition: tls.c:1247
#define TRUE
Definition: os_port.h:50
error_t(* DtlsCookieGenerateCallback)(TlsContext *context, const DtlsClientParameters *clientParams, uint8_t *cookie, size_t *length, void *param)
DTLS cookie generation callback function.
Definition: dtls_misc.h:235
@ TLS_GROUP_SECP256R1
Definition: tls.h:1230
@ TLS_TYPE_HANDSHAKE
Definition: tls.h:919
size_t digestSize
Definition: crypto.h:1135
error_t(* TlsSocketReceiveCallback)(TlsSocketHandle handle, void *data, size_t size, size_t *received, uint_t flags)
Socket receive callback function.
Definition: tls.h:1732
TlsHashAlgo hashAlgo
Hash algorithm used to sign the end entity certificate.
Definition: tls.h:1885
error_t tlsSetCache(TlsContext *context, TlsCache *cache)
Set session cache.
Definition: tls.c:438
TlsCertificateType type
End entity certificate type.
Definition: tls.h:1883
X.509 certificate.
Definition: x509_common.h:920
@ ERROR_OUT_OF_RESOURCES
Definition: error.h:64
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:851
void ecdhFree(EcdhContext *context)
Release ECDH context.
Definition: ecdh.c:67
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1319
TlsHashAlgo
Hash algorithms.
Definition: tls.h:1092
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
error_t tlsSetEcdsaSignCallback(TlsContext *context, TlsEcdsaSignCallback ecdsaSignCallback)
ECDSA signature generation callback function.
Definition: tls.c:700
@ ERROR_NOT_CONFIGURED
Definition: error.h:215
error_t tlsEnableReplayDetection(TlsContext *context, bool_t enabled)
Enable anti-replay mechanism (for DTLS only)
Definition: tls.c:1452
Session cache.
Definition: tls.h:1865
error_t tlsShutdownEx(TlsContext *context, bool_t waitForCloseNotify)
Gracefully close TLS session.
Definition: tls.c:2125
@ ERROR_END_OF_STREAM
Definition: error.h:208
error_t tlsSetPmtu(TlsContext *context, size_t pmtu)
Set PMTU value (for DTLS only)
Definition: tls.c:1358
void ecFreeDomainParameters(EcDomainParameters *params)
Release EC domain parameters.
Definition: ec.c:75
void tlsFreeSessionState(TlsSessionState *session)
Properly dispose a session state.
Definition: tls.c:2711
error_t(* TlsSocketSendCallback)(TlsSocketHandle handle, const void *data, size_t length, size_t *written, uint_t flags)
Socket send callback function.
Definition: tls.h:1724
#define DTLS_MIN_PMTU
Definition: dtls_misc.h:54
error_t tlsRestoreSessionState(TlsContext *context, const TlsSessionState *session)
Restore TLS session.
Definition: tls.c:2585
@ TLS_HASH_ALGO_NONE
Definition: tls.h:1094
error_t tlsSetVersion(TlsContext *context, uint16_t versionMin, uint16_t versionMax)
Set minimum and maximum versions permitted.
Definition: tls.c:249
error_t(* TlsRpkVerifyCallback)(TlsContext *context, const uint8_t *rawPublicKey, size_t rawPublicKeyLen)
Raw public key verification callback function.
Definition: tls.h:1756
error_t tlsEnableFallbackScsv(TlsContext *context, bool_t enabled)
Perform fallback retry (for clients only)
Definition: tls.c:1298
@ TLS_ALERT_LEVEL_WARNING
Definition: tls.h:961
error_t tlsSetMaxFragmentLength(TlsContext *context, size_t maxFragLen)
Set maximum fragment length.
Definition: tls.c:529
uint16_t cipherSuite
Cipher suite identifier.
Definition: tls.h:1837
const char_t * tlsGetServerName(TlsContext *context)
Get the server name.
Definition: tls.c:413
error_t tlsShutdown(TlsContext *context)
Gracefully close TLS session.
Definition: tls.c:2112
size_t certChainLen
Length of the certificate chain.
Definition: tls.h:1880
#define FALSE
Definition: os_port.h:46
error_t tlsSetPsk(TlsContext *context, const uint8_t *psk, size_t length)
Set the pre-shared key to be used.
Definition: tls.c:883
error_t pemImportCertificate(const char_t *input, size_t inputLen, uint8_t *output, size_t *outputLen, size_t *consumed)
Decode a PEM file containing a certificate.
Definition: pem_import.c:60
bool_t tls13IsGroupSupported(TlsContext *context, uint16_t namedGroup)
__start_packed struct @58 DtlsRecord
DTLS record.
error_t tlsSendAlert(TlsContext *context, uint8_t level, uint8_t description)
Send Alert message.
Definition: tls_common.c:480
error_t tlsParseAlert(TlsContext *context, const TlsAlert *message, size_t length)
Parse Alert message.
Definition: tls_common.c:1772
PEM file import functions.
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
@ TLS_FLAG_PEEK
Definition: tls.h:895
@ TLS_GROUP_ECDH_X25519
Definition: tls.h:1236
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:42
DTLS record protocol.
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:862
#define TLS_MIN_RECORD_LENGTH
Definition: tls.h:828
void tlsFreeEncryptionEngine(TlsEncryptionEngine *encryptionEngine)
Release encryption engine.
Definition: tls_misc.c:592
TlsClientAuthMode
Client authentication mode.
Definition: tls.h:870
const HashAlgo * tlsGetHashAlgo(uint8_t hashAlgoId)
Get the hash algorithm that matches the specified identifier.
Definition: tls_misc.c:829
error_t tlsSetTicketCallbacks(TlsContext *context, TlsTicketEncryptCallback ticketEncryptCallback, TlsTicketDecryptCallback ticketDecryptCallback, void *param)
Set ticket encryption/decryption callbacks.
Definition: tls.c:1326
#define TLS_VERSION_1_2
Definition: tls.h:94
@ TLS_FLAG_WAIT_ALL
Definition: tls.h:896
@ TLS_GROUP_NONE
Definition: tls.h:1207
error_t tlsSetTimeout(TlsContext *context, systime_t timeout)
Set timeout for blocking calls (for DTLS only)
Definition: tls.c:1388
error_t(* TlsEcdhCallback)(TlsContext *context)
ECDH key agreement callback function.
Definition: tls.h:1782
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define TLS_MAX_VERSION
Definition: tls.h:127
TlsEarlyDataStatus tlsGetEarlyDataStatus(TlsContext *context)
Check whether the server has accepted or rejected the early data.
Definition: tls.c:1620
void ecInit(EcPoint *r)
Initialize elliptic curve point.
Definition: ec.c:156
#define TLS_MIN_VERSION
Definition: tls.h:120
@ TLS_TYPE_APPLICATION_DATA
Definition: tls.h:920
Helper functions for TLS 1.3 client.
error_t tlsAddCertificate(TlsContext *context, const char_t *certChain, size_t certChainLen, const char_t *privateKey, size_t privateKeyLen)
Import a certificate and the corresponding private key.
Definition: tls.c:1126
@ TLS_TYPE_ALERT
Definition: tls.h:918
#define TLS_VERSION_1_3
Definition: tls.h:95
@ TLS_STATE_EARLY_DATA
Definition: tls.h:1292
Handshake message processing (TLS client and server)
@ TLS_HASH_ALGO_SHA384
Definition: tls.h:1099
void dhFree(DhContext *context)
Release Diffie-Hellman context.
Definition: dh.c:71
bool_t tlsIsTxReady(TlsContext *context)
Check whether some data is ready for transmission.
Definition: tls.c:2034
error_t tlsSetPreferredGroup(TlsContext *context, uint16_t group)
Specify the preferred ECDHE or FFDHE group.
Definition: tls.c:619
TLS record protocol.
#define TLS_MAX_CERTIFICATES
Definition: tls.h:239
error_t tls13SendEarlyData(TlsContext *context, const void *data, size_t length, size_t *written)
error_t tlsReadProtocolData(TlsContext *context, uint8_t **data, size_t *length, TlsContentType *contentType)
Read protocol data.
Definition: tls_record.c:158
#define SSL_VERSION_3_0
Definition: tls.h:91
@ TLS_STATE_SERVER_HELLO_3
Definition: tls.h:1297
@ TLS_HASH_ALGO_SHA256
Definition: tls.h:1098
error_t dtlsWriteProtocolData(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Write protocol data.
Definition: dtls_record.c:60
error_t tlsSaveSessionState(const TlsContext *context, TlsSessionState *session)
Save TLS session.
Definition: tls.c:2427
#define LSB(x)
Definition: os_port.h:54
error_t tlsRead(TlsContext *context, void *data, size_t size, size_t *received, uint_t flags)
Receive application data from a the remote host using TLS.
Definition: tls.c:1798
@ TLS_CLIENT_AUTH_NONE
Definition: tls.h:872
#define MIN(a, b)
Definition: os_port.h:62
__start_packed struct @89 TlsAlert
Alert message.
error_t tlsSetKeyLogCallback(TlsContext *context, TlsKeyLogCallback keyLogCallback)
Register key logging callback function (for debugging purpose only)
Definition: tls.c:754
#define SHA384_DIGEST_SIZE
Definition: sha384.h:41
error_t tlsWriteEarlyData(TlsContext *context, const void *data, size_t length, size_t *written, uint_t flags)
Send early data to the remote TLS server.
Definition: tls.c:1509
TlsCertificateType
Certificate types.
Definition: tls.h:1069
error_t tlsSetServerName(TlsContext *context, const char_t *serverName)
Set the server name.
Definition: tls.c:365
#define TLS_MASTER_SECRET_SIZE
Definition: tls.h:836
size_t privateKeyLen
Length of the private key.
Definition: tls.h:1882
Certificate descriptor.
Definition: tls.h:1877
Transcript hash calculation.
@ TLS_FLAG_BREAK_CHAR
Definition: tls.h:897
char_t * serverName
ServerName extension.
Definition: tls.h:1856
error_t tlsSetRpkVerifyCallback(TlsContext *context, TlsRpkVerifyCallback rpkVerifyCallback)
Register the raw public key verification callback function.
Definition: tls.c:1068
error_t tlsSetEcdsaVerifyCallback(TlsContext *context, TlsEcdsaVerifyCallback ecdsaVerifyCallback)
Register ECDSA signature verification callback function.
Definition: tls.c:727
bool_t tlsIsRxReady(TlsContext *context)
Check whether some data is available in the receive buffer.
Definition: tls.c:2067
uint16_t group
Definition: tls13_misc.h:205
uint8_t flags
Definition: tcp.h:314
@ TLS_TYPE_NONE
Definition: tls.h:916
void ecdhInit(EcdhContext *context)
Initialize ECDH context.
Definition: ecdh.c:50
error_t(* TlsEcdsaSignCallback)(TlsContext *context, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation callback function.
Definition: tls.h:1789
TlsSignatureAlgo signAlgo
Signature algorithm used to sign the end entity certificate.
Definition: tls.h:1884
char char_t
Definition: compiler_port.h:43
TlsContentType
Content type.
Definition: tls.h:914
@ TLS_STATE_CLOSING
Definition: tls.h:1320
@ TLS_EARLY_DATA_ACCEPTED
Definition: tls.h:885
error_t dtlsReadProtocolData(TlsContext *context, uint8_t **data, size_t *length, TlsContentType *contentType)
Read protocol data.
Definition: dtls_record.c:132
error_t tlsSetBufferSize(TlsContext *context, size_t txBufferSize, size_t rxBufferSize)
Set TLS buffer size.
Definition: tls.c:481
TLS session state.
Definition: tls.h:1834
@ ERROR_NOT_CONNECTED
Definition: error.h:79
uint8_t n
error_t tlsParseHandshakeMessage(TlsContext *context, const uint8_t *message, size_t length)
Parse handshake message.
TlsTransportProtocol
TLS transport protocols.
Definition: tls.h:848
TlsState tlsGetState(TlsContext *context)
Retrieve current state.
Definition: tls.c:193
error_t(* DtlsCookieVerifyCallback)(TlsContext *context, const DtlsClientParameters *clientParams, const uint8_t *cookie, size_t length, void *param)
DTLS cookie verification callback function.
Definition: dtls_misc.h:244
#define TLS_VERSION_1_0
Definition: tls.h:92
@ TLS_STATE_INIT
Definition: tls.h:1289
error_t tlsSetPskCallback(TlsContext *context, TlsPskCallback pskCallback)
Register the PSK callback function.
Definition: tls.c:1042
error_t tlsWriteProtocolData(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Write protocol data.
Definition: tls_record.c:55
error_t tlsSetSocketCallbacks(TlsContext *context, TlsSocketSendCallback socketSendCallback, TlsSocketReceiveCallback socketReceiveCallback, TlsSocketHandle handle)
Set socket send and receive callbacks.
Definition: tls.c:217
error_t tlsSetCipherSuites(TlsContext *context, const uint16_t *cipherSuites, uint_t length)
Specify the list of allowed cipher suites.
Definition: tls.c:564
TlsSignatureAlgo
Signature algorithms.
Definition: tls.h:1109
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:861
Certificate handling.
__start_packed struct @83 TlsRecord
TLS record.
error_t tlsWrite(TlsContext *context, const void *data, size_t length, size_t *written, uint_t flags)
Send application data to the remote host using TLS.
Definition: tls.c:1663
TLS (Transport Layer Security)
uint16_t version
TLS protocol version.
Definition: tls.h:1836
error_t tlsSetAlpnProtocolList(TlsContext *context, const char_t *protocolList)
Set the list of supported ALPN protocols.
Definition: tls.c:807
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:850
error_t x509ParseCertificate(const uint8_t *data, size_t length, X509CertificateInfo *certInfo)
Parse a X.509 certificate.
uint8_t mode
Definition: ntp_common.h:149
void tlsFree(TlsContext *context)
Release TLS context.
Definition: tls.c:2272
const char_t * certChain
End entity certificate chain (PEM format)
Definition: tls.h:1879
Common interface for hash algorithms.
Definition: crypto.h:1128
error_t(* TlsPskCallback)(TlsContext *context, const uint8_t *pskIdentity, size_t pskIdentityLen)
Pre-shared key callback function.
Definition: tls.h:1740
error_t tlsSetClientAuthMode(TlsContext *context, TlsClientAuthMode mode)
Set client authentication mode (for servers only)
Definition: tls.c:459
const char_t * tlsGetAlpnProtocol(TlsContext *context)
Get the name of the selected ALPN protocol.
Definition: tls.c:855
void tlsProcessError(TlsContext *context, error_t errorCode)
Translate an error code to an alert message.
Definition: tls_misc.c:56
error_t tlsAllowUnknownAlpnProtocols(TlsContext *context, bool_t allowed)
Allow unknown ALPN protocols.
Definition: tls.c:781
TlsNamedGroup
Named groups.
Definition: tls.h:1205
error_t tlsSetCookieCallbacks(TlsContext *context, DtlsCookieGenerateCallback cookieGenerateCallback, DtlsCookieVerifyCallback cookieVerifyCallback, void *param)
Set cookie generation/verification callbacks (for DTLS only)
Definition: tls.c:1416
const char_t * privateKey
Private key (PEM format)
Definition: tls.h:1881
void(* TlsKeyLogCallback)(TlsContext *context, const char_t *key)
Key logging callback function (for debugging purpose only)
Definition: tls.h:1805
error_t tlsSetPrng(TlsContext *context, const PrngAlgo *prngAlgo, void *prngContext)
Set the pseudo-random number generator to be used.
Definition: tls.c:338
error_t(* TlsCertVerifyCallback)(TlsContext *context, const X509CertificateInfo *certInfo, uint_t pathLen, void *param)
Certificate verification callback function.
Definition: tls.h:1748
unsigned int uint_t
Definition: compiler_port.h:45
uint8_t data[]
Definition: dtls_misc.h:176
void ecFree(EcPoint *r)
Release an elliptic curve point.
Definition: ec.c:170
#define tlsFreeMem(p)
Definition: tls.h:762
#define TLS_MAX_RECORD_OVERHEAD
Definition: tls.h:832
error_t tlsSetTrustedCaList(TlsContext *context, const char_t *trustedCaList, size_t length)
Import a trusted CA list.
Definition: tls.c:1096
#define SHA256_DIGEST_SIZE
Definition: sha256.h:40
error_t pemImportDhParameters(const char_t *input, size_t length, DhParameters *params)
Decode a PEM file containing Diffie-Hellman parameters.
Definition: pem_import.c:148
error_t tlsInitSessionState(TlsSessionState *session)
Initialize session state.
Definition: tls.c:2406
error_t(* TlsTicketDecryptCallback)(TlsContext *context, const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *plaintext, size_t *plaintextLen, void *param)
Ticket decryption callback function.
Definition: tls.h:1773
void dhInit(DhContext *context)
Initialize Diffie-Hellman context.
Definition: dh.c:54
error_t tlsSetPskIdentity(TlsContext *context, const char_t *pskIdentity)
Set the PSK identity to be used by the client.
Definition: tls.c:944
error_t tlsConnect(TlsContext *context)
Initiate the TLS handshake.
Definition: tls.c:1572
void dsaFreePublicKey(DsaPublicKey *key)
Release a DSA public key.
Definition: dsa.c:92
uint32_t systime_t
Definition: compiler_port.h:46
TlsNamedGroup namedCurve
Named curve used to generate the EC public key.
Definition: tls.h:1886
void dsaInitPublicKey(DsaPublicKey *key)
Initialize a DSA public key.
Definition: dsa.c:77
error_t tlsSetDhParameters(TlsContext *context, const char_t *params, size_t length)
Import Diffie-Hellman parameters.
Definition: tls.c:646
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t c
Definition: ndp.h:513
Debugging facilities.
void rsaInitPublicKey(RsaPublicKey *key)
Initialize an RSA public key.
Definition: rsa.c:105
void * TlsSocketHandle
Socket handle.
Definition: tls.h:1717
TlsEarlyDataStatus
Early data status.
Definition: tls.h:882
void tlsFreeTranscriptHash(TlsContext *context)
Release transcript hash context.
#define INFINITE_DELAY
Definition: os_port.h:74
error_t tlsGetCertificateType(const X509CertificateInfo *certInfo, TlsCertificateType *certType, TlsSignatureAlgo *certSignAlgo, TlsHashAlgo *certHashAlgo, TlsNamedGroup *namedCurve)
Retrieve the certificate type.
systime_t osGetSystemTime(void)
Retrieve system time.
@ TLS_STATE_CLOSED
Definition: tls.h:1321