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