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