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