tls_client_extensions.c
Go to the documentation of this file.
1 /**
2  * @file tls_client_extensions.c
3  * @brief Formatting and parsing of extensions (TLS client)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2026 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneSSL Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.6.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls.h"
36 #include "tls_cipher_suites.h"
37 #include "tls_client_extensions.h"
38 #include "tls_client_misc.h"
39 #include "tls_extensions.h"
40 #include "tls_ffdhe.h"
41 #include "tls_misc.h"
42 #include "debug.h"
43 
44 //Check TLS library configuration
45 #if (TLS_SUPPORT == ENABLED && TLS_CLIENT_SUPPORT == ENABLED)
46 
47 //List of supported ECDHE or FFDHE groups
48 const uint16_t tlsSupportedGroups[] =
49 {
81 };
82 
83 
84 /**
85  * @brief Format SupportedVersions extension
86  * @param[in] context Pointer to the TLS context
87  * @param[in] p Output stream where to write the SupportedVersions extension
88  * @param[out] written Total number of bytes that have been written
89  * @return Error code
90  **/
91 
93  uint8_t *p, size_t *written)
94 {
95  size_t n = 0;
96 
97 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
98  //In TLS 1.2, the client can indicate its version preferences in the
99  //SupportedVersions extension, in preference to the legacy_version field
100  //of the ClientHello
101  if(context->versionMax >= TLS_VERSION_1_2)
102  {
103  TlsExtension *extension;
104  TlsSupportedVersionList *supportedVersionList;
105 
106  //Add the SupportedVersions extension
107  extension = (TlsExtension *) p;
108  //Type of the extension
109  extension->type = HTONS(TLS_EXT_SUPPORTED_VERSIONS);
110 
111  //Point to the extension data field
112  supportedVersionList = (TlsSupportedVersionList *) extension->value;
113 
114  //The extension contains a list of supported versions in preference
115  //order, with the most preferred version first
116  n = 0;
117 
118 #if (DTLS_SUPPORT == ENABLED)
119  //DTLS protocol?
120  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
121  {
122  //Check whether DTLS 1.3 is supported
123  if(context->versionMax >= TLS_VERSION_1_3 &&
124  context->versionMin <= TLS_VERSION_1_3)
125  {
126  supportedVersionList->value[n++] = HTONS(DTLS_VERSION_1_3);
127  }
128 
129  //Check whether DTLS 1.2 is supported
130  if(context->versionMax >= TLS_VERSION_1_2 &&
131  context->versionMin <= TLS_VERSION_1_2)
132  {
133  supportedVersionList->value[n++] = HTONS(DTLS_VERSION_1_2);
134  }
135 
136  //Check whether DTLS 1.0 is supported
137  if(context->versionMax >= TLS_VERSION_1_1 &&
138  context->versionMin <= TLS_VERSION_1_1)
139  {
140  supportedVersionList->value[n++] = HTONS(DTLS_VERSION_1_0);
141  }
142  }
143  else
144 #endif
145  //TLS protocol?
146  {
147  //Check whether TLS 1.3 is supported
148  if(context->versionMax >= TLS_VERSION_1_3 &&
149  context->versionMin <= TLS_VERSION_1_3)
150  {
151  supportedVersionList->value[n++] = HTONS(TLS_VERSION_1_3);
152  }
153 
154  //Check whether TLS 1.2 is supported
155  if(context->versionMax >= TLS_VERSION_1_2 &&
156  context->versionMin <= TLS_VERSION_1_2)
157  {
158  supportedVersionList->value[n++] = HTONS(TLS_VERSION_1_2);
159  }
160 
161  //Check whether TLS 1.1 is supported
162  if(context->versionMax >= TLS_VERSION_1_1 &&
163  context->versionMin <= TLS_VERSION_1_1)
164  {
165  supportedVersionList->value[n++] = HTONS(TLS_VERSION_1_1);
166  }
167 
168  //Check whether TLS 1.0 is supported
169  if(context->versionMax >= TLS_VERSION_1_0 &&
170  context->versionMin <= TLS_VERSION_1_0)
171  {
172  supportedVersionList->value[n++] = HTONS(TLS_VERSION_1_0);
173  }
174  }
175 
176  //Compute the length, in bytes, of the list
177  n *= sizeof(uint16_t);
178  //Fix the length of the list
179  supportedVersionList->length = (uint8_t) n;
180 
181  //Consider the length field that precedes the list
182  n += sizeof(TlsSupportedVersionList);
183  //Fix the length of the extension
184  extension->length = htons(n);
185 
186  //Compute the length, in bytes, of the SupportedVersions extension
187  n += sizeof(TlsExtension);
188  }
189 #endif
190 
191  //Total number of bytes that have been written
192  *written = n;
193 
194  //Successful processing
195  return NO_ERROR;
196 }
197 
198 
199 /**
200  * @brief Format SNI extension
201  * @param[in] context Pointer to the TLS context
202  * @param[in] p Output stream where to write the ServerName extension
203  * @param[out] written Total number of bytes that have been written
204  * @return Error code
205  **/
206 
208  uint8_t *p, size_t *written)
209 {
210  size_t n = 0;
211 
212 #if (TLS_SNI_SUPPORT == ENABLED)
213  //In order to provide the server name, clients may include a ServerName
214  //extension
215  if(context->serverName != NULL)
216  {
217  //Determine the length of the server name
218  n = osStrlen(context->serverName);
219 
220  //The server name must be a valid DNS hostname
221  if(tlsCheckDnsHostname(context->serverName, n))
222  {
223  TlsExtension *extension;
224  TlsServerNameList *serverNameList;
225  TlsServerName *serverName;
226 
227  //Add SNI (Server Name Indication) extension
228  extension = (TlsExtension *) p;
229  //Type of the extension
230  extension->type = HTONS(TLS_EXT_SERVER_NAME);
231 
232  //Point to the list of server names
233  serverNameList = (TlsServerNameList *) extension->value;
234  //In practice, current client implementations only send one name
235  serverName = (TlsServerName *) serverNameList->value;
236 
237  //Fill in the type and the length fields
238  serverName->type = TLS_NAME_TYPE_HOSTNAME;
239  serverName->length = htons(n);
240  //Copy server name
241  osMemcpy(serverName->hostname, context->serverName, n);
242 
243  //Compute the length, in byte, of the structure
244  n += sizeof(TlsServerName);
245  //Fix the length of the list
246  serverNameList->length = htons(n);
247 
248  //Consider the 2-byte length field that precedes the list
249  n += sizeof(TlsServerNameList);
250  //Fix the length of the extension
251  extension->length = htons(n);
252 
253  //Compute the length, in bytes, of the ServerName extension
254  n += sizeof(TlsExtension);
255  }
256  else
257  {
258  //The server name is not a valid DNS hostname
259  n = 0;
260  }
261  }
262 #endif
263 
264  //Total number of bytes that have been written
265  *written = n;
266 
267  //Successful processing
268  return NO_ERROR;
269 }
270 
271 
272 /**
273  * @brief Format MaxFragmentLength extension
274  * @param[in] context Pointer to the TLS context
275  * @param[in] p Output stream where to write the MaxFragmentLength extension
276  * @param[out] written Total number of bytes that have been written
277  * @return Error code
278  **/
279 
281  uint8_t *p, size_t *written)
282 {
283  size_t n = 0;
284 
285 #if (TLS_MAX_FRAG_LEN_SUPPORT == ENABLED)
286  //In order to negotiate smaller maximum fragment lengths, clients may
287  //include a MaxFragmentLength extension
288  if(context->maxFragLen == 512 || context->maxFragLen == 1024 ||
289  context->maxFragLen == 2048 || context->maxFragLen == 4096)
290  {
291  TlsExtension *extension;
292 
293  //Add the MaxFragmentLength extension
294  extension = (TlsExtension *) p;
295  //Type of the extension
296  extension->type = HTONS(TLS_EXT_MAX_FRAGMENT_LENGTH);
297 
298  //Set the maximum fragment length
299  switch(context->maxFragLen)
300  {
301  case 512:
302  extension->value[0] = TLS_MAX_FRAGMENT_LENGTH_512;
303  break;
304 
305  case 1024:
306  extension->value[0] = TLS_MAX_FRAGMENT_LENGTH_1024;
307  break;
308 
309  case 2048:
310  extension->value[0] = TLS_MAX_FRAGMENT_LENGTH_2048;
311  break;
312 
313  default:
314  extension->value[0] = TLS_MAX_FRAGMENT_LENGTH_4096;
315  break;
316  }
317 
318  //The extension data field contains a single byte
319  n = sizeof(uint8_t);
320  //Fix the length of the extension
321  extension->length = htons(n);
322 
323  //Compute the length, in bytes, of the MaxFragmentLength extension
324  n += sizeof(TlsExtension);
325  }
326 #endif
327 
328  //Total number of bytes that have been written
329  *written = n;
330 
331  //Successful processing
332  return NO_ERROR;
333 }
334 
335 
336 /**
337  * @brief Format RecordSizeLimit extension
338  * @param[in] context Pointer to the TLS context
339  * @param[in] p Output stream where to write the RecordSizeLimit extension
340  * @param[out] written Total number of bytes that have been written
341  * @return Error code
342  **/
343 
345  uint8_t *p, size_t *written)
346 {
347  size_t n = 0;
348 
349 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
350  size_t recordSizeLimit;
351  TlsExtension *extension;
352 
353  //Add the RecordSizeLimit extension
354  extension = (TlsExtension *) p;
355  //Type of the extension
356  extension->type = HTONS(TLS_EXT_RECORD_SIZE_LIMIT);
357 
358  //An endpoint must not send a value higher than the protocol-defined
359  //maximum record size (refer to RFC 8449, section 4)
360  recordSizeLimit = MIN(context->rxBufferMaxLen, TLS_MAX_RECORD_LENGTH);
361 
362  //Check whether TLS 1.3 is supported
363  if(context->versionMax >= TLS_VERSION_1_3)
364  {
365  //The value includes the content type and padding added in TLS 1.3
366  recordSizeLimit++;
367  }
368 
369  //The value of RecordSizeLimit is the maximum size of record in octets
370  //that the endpoint is willing to receive
371  STORE16BE(recordSizeLimit, extension->value);
372 
373  //The extension data field contains a 16-bit unsigned integer
374  n = sizeof(uint16_t);
375  //Fix the length of the extension
376  extension->length = htons(n);
377 
378  //Compute the length, in bytes, of the RecordSizeLimit extension
379  n += sizeof(TlsExtension);
380 #endif
381 
382  //Total number of bytes that have been written
383  *written = n;
384 
385  //Successful processing
386  return NO_ERROR;
387 }
388 
389 
390 /**
391  * @brief Format TrustedCaKeys extension
392  * @param[in] context Pointer to the TLS context
393  * @param[in] p Output stream where to write the TrustedCaKeys extension
394  * @param[out] written Total number of bytes that have been written
395  * @return Error code
396  **/
397 
399  size_t *written)
400 {
401  error_t error;
402  size_t n;
403 
404  //Initialize status code
405  error = NO_ERROR;
406  //Initialize length field
407  n = 0;
408 
409 #if (TLS_TRUSTED_CA_KEYS_SUPPORT == ENABLED)
410  //The TrustedCaKeys extension is optional
411  if(context->trustedCaKeysEnabled && context->versionMin <= TLS_VERSION_1_2)
412  {
413  TlsExtension *extension;
414 
415  //Add the TrustedCaKeys extension
416  extension = (TlsExtension *) p;
417  //Type of the extension
418  extension->type = HTONS(TLS_EXT_TRUSTED_CA_KEYS);
419 
420  //"TrustedAuthorities" provides a list of CA root key identifiers that
421  //the client possesses (refer to RFC 6066, section 6)
422  error = tlsFormatTrustedAuthorities(context, extension->value, &n);
423 
424  //Check status code
425  if(!error)
426  {
427  //The list must contains at least one CA root key identifier
428  if(n > sizeof(TlsTrustedAuthorities))
429  {
430  //Fix the length of the extension
431  extension->length = htons(n);
432 
433  //Compute the length, in bytes, of the TrustedCaKeys extension
434  n += sizeof(TlsExtension);
435  }
436  else
437  {
438  //The list of distinguished names is empty
439  n = 0;
440  }
441  }
442  }
443 #endif
444 
445  //Total number of bytes that have been written
446  *written = n;
447 
448  //Return status code
449  return error;
450 }
451 
452 
453 /**
454  * @brief Format SupportedGroups extension
455  * @param[in] context Pointer to the TLS context
456  * @param[in] p Output stream where to write the SupportedGroups extension
457  * @param[out] written Total number of bytes that have been written
458  * @return Error code
459  **/
460 
462  size_t *written)
463 {
464  size_t n = 0;
465 
466 #if (TLS_ECDH_SUPPORT == ENABLED || TLS_FFDHE_SUPPORT == ENABLED || \
467  TLS_MLKEM_SUPPORT == ENABLED || TLS_HYBRID_SUPPORT == ENABLED)
468  uint_t i;
469  uint_t numSupportedGroups;
470  const uint16_t *supportedGroups;
471  TlsExtension *extension;
472  TlsSupportedGroupList *supportedGroupList;
473 
474  //Add the SupportedGroups extension
475  extension = (TlsExtension *) p;
476  //Type of the extension
477  extension->type = HTONS(TLS_EXT_SUPPORTED_GROUPS);
478 
479  //Point to the list of supported groups
480  supportedGroupList = (TlsSupportedGroupList *) extension->value;
481 
482  //Any preferred ECDHE or FFDHE groups?
483  if(context->numSupportedGroups > 0)
484  {
485  //Point to the list of preferred named groups
486  supportedGroups = context->supportedGroups;
487  numSupportedGroups = context->numSupportedGroups;
488  }
489  else
490  {
491  //Point to the list of default named groups
492  supportedGroups = tlsSupportedGroups;
493  numSupportedGroups = arraysize(tlsSupportedGroups);
494  }
495 
496  //The groups are ordered according to client's preferences
497  n = 0;
498 
499  //Loop through the list of named groups
500  for(i = 0; i < numSupportedGroups; i++)
501  {
502 #if (TLS_FFDHE_SUPPORT == ENABLED)
503  //Finite field group?
504  if(tlsGetFfdheGroup(context, supportedGroups[i]) != NULL)
505  {
506  //Any Diffie-Hellman cipher suite proposed by the client?
507  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_DH) != 0 ||
508  (context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
509  {
510  //Add the current named group to the list
511  supportedGroupList->value[n++] = htons(supportedGroups[i]);
512  }
513  }
514  else
515 #endif
516 #if (TLS_ECDH_SUPPORT == ENABLED)
517  //Elliptic curve group?
518  if(tlsGetCurve(context, supportedGroups[i]) != NULL)
519  {
520  //SM2 elliptic curve?
521  if(supportedGroups[i] == TLS_GROUP_CURVE_SM2)
522  {
523  //Any ShangMi cipher suite proposed by the client?
524  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_SM) != 0)
525  {
526  //Add the current named group to the list
527  supportedGroupList->value[n++] = htons(supportedGroups[i]);
528  }
529  }
530  else
531  {
532  //Any ECDH cipher suite proposed by the client?
533  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_ECDH) != 0 ||
534  (context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
535  {
536  //Add the current named group to the list
537  supportedGroupList->value[n++] = htons(supportedGroups[i]);
538  }
539  }
540  }
541  else
542 #endif
543 #if (TLS_MLKEM_SUPPORT == ENABLED)
544  //ML-KEM key exchange method?
545  if(tls13GetMlkemAlgo(context, supportedGroups[i]) != NULL)
546  {
547  //Any TLS 1.3 cipher suite proposed by the client?
548  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
549  {
550  //Add the current named group to the list
551  supportedGroupList->value[n++] = htons(supportedGroups[i]);
552  }
553  }
554  else
555 #endif
556 #if (TLS_HYBRID_SUPPORT == ENABLED)
557  //Hybrid key exchange method?
558  if(tls13GetTraditionalAlgo(context, supportedGroups[i]) != NULL &&
559  tls13GetNextGenAlgo(context, supportedGroups[i]) != NULL)
560  {
561  //Any TLS 1.3 cipher suite proposed by the client?
562  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
563  {
564  //Add the current named group to the list
565  supportedGroupList->value[n++] = htons(supportedGroups[i]);
566  }
567  }
568  else
569 #endif
570  //Unknown group?
571  {
572  //Discard current named group
573  }
574  }
575 
576  //If the client supports and wants ECDHE and FFDHE key exchanges, it must
577  //use a single SupportedGroups extension to include all supported groups
578  //(both ECDHE and FFDHE groups)
579  if(n > 0)
580  {
581  //Compute the length, in bytes, of the list
582  n *= 2;
583  //Fix the length of the list
584  supportedGroupList->length = htons(n);
585 
586  //Consider the 2-byte length field that precedes the list
587  n += sizeof(TlsSupportedGroupList);
588  //Fix the length of the extension
589  extension->length = htons(n);
590 
591  //Compute the length, in bytes, of the SupportedGroups extension
592  n += sizeof(TlsExtension);
593  }
594 #endif
595 
596  //Total number of bytes that have been written
597  *written = n;
598 
599  //Successful processing
600  return NO_ERROR;
601 }
602 
603 
604 /**
605  * @brief Format EcPointFormats extension
606  * @param[in] context Pointer to the TLS context
607  * @param[in] p Output stream where to write the EcPointFormats extension
608  * @param[out] written Total number of bytes that have been written
609  * @return Error code
610  **/
611 
613  uint8_t *p, size_t *written)
614 {
615  size_t n = 0;
616 
617 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
618  //TLS 1.3 has removed point format negotiation in favor of a single point
619  //format for each curve (refer to RFC 8446, section 1.2)
620  if(context->versionMin <= TLS_VERSION_1_2)
621  {
622 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
623  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
624  //A client that proposes ECC cipher suites in its ClientHello message
625  //should send the EcPointFormats extension
626  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_ECDH) != 0)
627  {
628  TlsExtension *extension;
629  TlsEcPointFormatList *ecPointFormatList;
630 
631  //Add the EcPointFormats extension
632  extension = (TlsExtension *) p;
633  //Type of the extension
634  extension->type = HTONS(TLS_EXT_EC_POINT_FORMATS);
635 
636  //Point to the list of supported EC point formats
637  ecPointFormatList = (TlsEcPointFormatList *) extension->value;
638  //Items in the list are ordered according to client's preferences
639  n = 0;
640 
641  //The client can parse only the uncompressed point format...
642  ecPointFormatList->value[n++] = TLS_EC_POINT_FORMAT_UNCOMPRESSED;
643  //Fix the length of the list
644  ecPointFormatList->length = (uint8_t) n;
645 
646  //Consider the length field that precedes the list
647  n += sizeof(TlsEcPointFormatList);
648  //Fix the length of the extension
649  extension->length = htons(n);
650 
651  //Compute the length, in bytes, of the EcPointFormats extension
652  n += sizeof(TlsExtension);
653  }
654 #endif
655  }
656 #endif
657 
658  //Total number of bytes that have been written
659  *written = n;
660 
661  //Successful processing
662  return NO_ERROR;
663 }
664 
665 
666 /**
667  * @brief Format ALPN extension
668  * @param[in] context Pointer to the TLS context
669  * @param[in] p Output stream where to write the ALPN extension
670  * @param[out] written Total number of bytes that have been written
671  * @return Error code
672  **/
673 
675  uint8_t *p, size_t *written)
676 {
677  size_t n = 0;
678 
679 #if (TLS_ALPN_SUPPORT == ENABLED)
680  //The ALPN extension contains the list of protocols advertised by the
681  //client, in descending order of preference
682  if(context->protocolList != NULL)
683  {
684  uint_t i;
685  uint_t j;
686  TlsExtension *extension;
687  TlsProtocolName *protocolName;
688  TlsProtocolNameList *protocolNameList;
689 
690  //Add ALPN (Application-Layer Protocol Negotiation) extension
691  extension = (TlsExtension *) p;
692  //Type of the extension
693  extension->type = HTONS(TLS_EXT_ALPN);
694 
695  //Point to the list of protocol names
696  protocolNameList = (TlsProtocolNameList *) extension->value;
697 
698  //Move back to the beginning of the list
699  i = 0;
700  j = 0;
701  n = 0;
702 
703  //Parse the list of supported protocols
704  do
705  {
706  //Delimiter character found?
707  if(context->protocolList[i] == ',' || context->protocolList[i] == '\0')
708  {
709  //Discard empty tokens
710  if((i - j) > 0)
711  {
712  //Point to the protocol name
713  protocolName = (TlsProtocolName *) (protocolNameList->value + n);
714 
715  //Fill in the length field
716  protocolName->length = i - j;
717  //Copy protocol name
718  osMemcpy(protocolName->value, context->protocolList + j, i - j);
719 
720  //Adjust the length of the list
721  n += sizeof(TlsProtocolName) + i - j;
722  }
723 
724  //Move to the next token
725  j = i + 1;
726  }
727 
728  //Loop until the NULL character is reached
729  } while(context->protocolList[i++] != '\0');
730 
731  //Fix the length of the list
732  protocolNameList->length = htons(n);
733 
734  //Consider the 2-byte length field that precedes the list
735  n += sizeof(TlsProtocolNameList);
736  //Fix the length of the extension
737  extension->length = htons(n);
738 
739  //Compute the length, in bytes, of the ALPN extension
740  n += sizeof(TlsExtension);
741  }
742 #endif
743 
744  //Total number of bytes that have been written
745  *written = n;
746 
747  //Successful processing
748  return NO_ERROR;
749 }
750 
751 
752 /**
753  * @brief Format ClientCertType extension
754  * @param[in] context Pointer to the TLS context
755  * @param[in] p Output stream where to write the ClientCertType extension
756  * @param[out] written Total number of bytes that have been written
757  * @return Error code
758  **/
759 
761  uint8_t *p, size_t *written)
762 {
763  size_t n = 0;
764 
765 #if (TLS_RAW_PUBLIC_KEY_SUPPORT == ENABLED)
766  TlsExtension *extension;
767  TlsCertTypeList *clientCertTypeList;
768 
769  //Add the ClientCertType extension
770  extension = (TlsExtension *) p;
771  //Type of the extension
772  extension->type = HTONS(TLS_EXT_CLIENT_CERT_TYPE);
773 
774  //The ClientCertType extension in the ClientHello indicates the certificate
775  //types the client is able to provide to the server, when requested using a
776  //CertificateRequest message
777  clientCertTypeList = (TlsCertTypeList *) extension->value;
778 
779  //The ClientCertType extension carries a list of supported certificate
780  //types, sorted by client preference
781  n = 0;
782 
783  //Raw public key type
784  clientCertTypeList->value[n++] = TLS_CERT_FORMAT_RAW_PUBLIC_KEY;
785  //X.509 certificate type
786  clientCertTypeList->value[n++] = TLS_CERT_FORMAT_X509;
787 
788  //Fix the length of the list
789  clientCertTypeList->length = (uint8_t) n;
790 
791  //Consider the length field that precedes the list
792  n += sizeof(TlsCertTypeList);
793  //Fix the length of the extension
794  extension->length = htons(n);
795 
796  //Compute the length, in bytes, of the ClientCertType extension
797  n += sizeof(TlsExtension);
798 #endif
799 
800  //Total number of bytes that have been written
801  *written = n;
802 
803  //Successful processing
804  return NO_ERROR;
805 }
806 
807 
808 /**
809  * @brief Format ServerCertType extension
810  * @param[in] context Pointer to the TLS context
811  * @param[in] p Output stream where to write the ServerCertType extension
812  * @param[out] written Total number of bytes that have been written
813  * @return Error code
814  **/
815 
817  uint8_t *p, size_t *written)
818 {
819  size_t n = 0;
820 
821 #if (TLS_RAW_PUBLIC_KEY_SUPPORT == ENABLED)
822  //Ensure the client is able to process raw public keys
823  if(context->rpkVerifyCallback != NULL)
824  {
825  TlsExtension *extension;
826  TlsCertTypeList *serverCertTypeList;
827 
828  //Add the ServerCertType extension
829  extension = (TlsExtension *) p;
830  //Type of the extension
831  extension->type = HTONS(TLS_EXT_SERVER_CERT_TYPE);
832 
833  //The ServerCertType extension in the ClientHello indicates the types of
834  //certificates the client is able to process when provided by the server
835  //in a subsequent certificate payload
836  serverCertTypeList = (TlsCertTypeList *) extension->value;
837 
838  //The ServerCertType extension carries a list of supported certificate
839  //types, sorted by client preference
840  n = 0;
841 
842  //Raw public key type
843  serverCertTypeList->value[n++] = TLS_CERT_FORMAT_RAW_PUBLIC_KEY;
844  //X.509 certificate type
845  serverCertTypeList->value[n++] = TLS_CERT_FORMAT_X509;
846 
847  //Fix the length of the list
848  serverCertTypeList->length = (uint8_t) n;
849 
850  //Consider the length field that precedes the list
851  n += sizeof(TlsCertTypeList);
852  //Fix the length of the extension
853  extension->length = htons(n);
854 
855  //Compute the length, in bytes, of the ServerCertType extension
856  n += sizeof(TlsExtension);
857  }
858 #endif
859 
860  //Total number of bytes that have been written
861  *written = n;
862 
863  //Successful processing
864  return NO_ERROR;
865 }
866 
867 
868 /**
869  * @brief Format EncryptThenMac extension
870  * @param[in] context Pointer to the TLS context
871  * @param[in] p Output stream where to write the EncryptThenMac extension
872  * @param[out] written Total number of bytes that have been written
873  * @return Error code
874  **/
875 
877  uint8_t *p, size_t *written)
878 {
879  size_t n = 0;
880 
881 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
882  //In versions of TLS prior to TLS 1.3, this extension is used to negotiate
883  //encrypt-then-MAC construction rather than the default MAC-then-encrypt
884  if(context->versionMax >= TLS_VERSION_1_0 &&
885  context->versionMin <= TLS_VERSION_1_2)
886  {
887 #if (TLS_ENCRYPT_THEN_MAC_SUPPORT == ENABLED)
888  TlsExtension *extension;
889 
890  //Add the EncryptThenMac extension
891  extension = (TlsExtension *) p;
892  //Type of the extension
893  extension->type = HTONS(TLS_EXT_ENCRYPT_THEN_MAC);
894 
895  //The extension data field of this extension shall be empty (refer to
896  //RFC 7366, section 2)
897  extension->length = HTONS(0);
898 
899  //Compute the length, in bytes, of the EncryptThenMac extension
900  n = sizeof(TlsExtension);
901 #endif
902  }
903 #endif
904 
905  //Total number of bytes that have been written
906  *written = n;
907 
908  //Successful processing
909  return NO_ERROR;
910 }
911 
912 
913 /**
914  * @brief Format ExtendedMasterSecret extension
915  * @param[in] context Pointer to the TLS context
916  * @param[in] p Output stream where to write the ExtendedMasterSecret extension
917  * @param[out] written Total number of bytes that have been written
918  * @return Error code
919  **/
920 
922  uint8_t *p, size_t *written)
923 {
924  size_t n = 0;
925 
926 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
927  //Implementations which support both TLS 1.3 and earlier versions should
928  //indicate the use of the ExtendedMasterSecret extension whenever TLS 1.3
929  //is used (refer to RFC 8446, appendix D)
930  if(context->versionMax >= TLS_VERSION_1_0 &&
931  context->versionMin <= TLS_VERSION_1_2)
932  {
933 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
934  TlsExtension *extension;
935 
936  //Add the ExtendedMasterSecret extension
937  extension = (TlsExtension *) p;
938  //Type of the extension
939  extension->type = HTONS(TLS_EXT_EXTENDED_MASTER_SECRET);
940 
941  //The extension data field of this extension is empty
942  extension->length = HTONS(0);
943 
944  //Compute the length, in bytes, of the ExtendedMasterSecret extension
945  n = sizeof(TlsExtension);
946 #endif
947  }
948 #endif
949 
950  //Total number of bytes that have been written
951  *written = n;
952 
953  //Successful processing
954  return NO_ERROR;
955 }
956 
957 
958 /**
959  * @brief Format SessionTicket extension
960  * @param[in] context Pointer to the TLS context
961  * @param[in] p Output stream where to write the SessionTicket extension
962  * @param[out] written Total number of bytes that have been written
963  * @return Error code
964  **/
965 
967  uint8_t *p, size_t *written)
968 {
969  size_t n = 0;
970 
971 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
972  //In versions of TLS prior to TLS 1.3, the SessionTicket extension is used
973  //to resume a TLS session without requiring session-specific state at the
974  //TLS server
975  if(context->versionMin <= TLS_VERSION_1_2)
976  {
977 #if (TLS_TICKET_SUPPORT == ENABLED)
978  //Check whether session ticket mechanism is enabled
979  if(context->sessionTicketEnabled)
980  {
981  TlsExtension *extension;
982 
983  //Add the SessionTicket extension
984  extension = (TlsExtension *) p;
985  //Type of the extension
986  extension->type = HTONS(TLS_EXT_SESSION_TICKET);
987 
988  //Valid ticket?
989  if(tlsIsTicketValid(context))
990  {
991  //If the client possesses a ticket that it wants to use to resume
992  //a session, then it includes the ticket in the SessionTicket
993  //extension in the ClientHello
994  osMemcpy(extension->value, context->ticket, context->ticketLen);
995 
996  //The extension_data field of SessionTicket extension contains the
997  //ticket
998  n = context->ticketLen;
999  }
1000  else
1001  {
1002  //If the client does not have a ticket and is prepared to receive
1003  //one in the NewSessionTicket handshake message, then it must
1004  //include a zero-length ticket in the SessionTicket extension
1005  n = 0;
1006  }
1007 
1008  //Set the length of the extension
1009  extension->length = htons(n);
1010 
1011  //Compute the length, in bytes, of the SessionTicket extension
1012  n += sizeof(TlsExtension);
1013  }
1014 #endif
1015  }
1016 #endif
1017 
1018  //Total number of bytes that have been written
1019  *written = n;
1020 
1021  //Successful processing
1022  return NO_ERROR;
1023 }
1024 
1025 
1026 /**
1027  * @brief Format RenegotiationInfo extension
1028  * @param[in] context Pointer to the TLS context
1029  * @param[in] p Output stream where to write the RenegotiationInfo extension
1030  * @param[out] written Total number of bytes that have been written
1031  * @return Error code
1032  **/
1033 
1035  uint8_t *p, size_t *written)
1036 {
1037  size_t n = 0;
1038 
1039 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
1040  //TLS 1.3 forbids renegotiation
1041  if(context->versionMin <= TLS_VERSION_1_2)
1042  {
1043 #if (TLS_SECURE_RENEGOTIATION_SUPPORT == ENABLED)
1044  //Check whether secure renegotiation is enabled
1045  if(context->secureRenegoEnabled)
1046  {
1047  //During secure renegotiation, the client must include the
1048  //RenegotiationInfo extension containing the saved client_verify_data
1049  if(context->secureRenegoFlag)
1050  {
1051  TlsExtension *extension;
1052  TlsRenegoInfo *renegoInfo;
1053 
1054  //Determine the length of the verify data
1055  n = context->clientVerifyDataLen;
1056 
1057  //Add the RenegotiationInfo extension
1058  extension = (TlsExtension *) p;
1059  //Type of the extension
1060  extension->type = HTONS(TLS_EXT_RENEGOTIATION_INFO);
1061 
1062  //Point to the renegotiated_connection field
1063  renegoInfo = (TlsRenegoInfo *) extension->value;
1064  //Set the length of the verify data
1065  renegoInfo->length = (uint8_t) n;
1066 
1067  //Copy the verify data from the Finished message sent by the client
1068  //on the immediately previous handshake
1069  osMemcpy(renegoInfo->value, context->clientVerifyData, n);
1070 
1071  //Consider the length field that precedes the renegotiated_connection
1072  //field
1073  n += sizeof(TlsRenegoInfo);
1074  //Fix the length of the extension
1075  extension->length = htons(n);
1076 
1077  //Compute the length, in bytes, of the RenegotiationInfo extension
1078  n += sizeof(TlsExtension);
1079  }
1080  }
1081 #endif
1082  }
1083 #endif
1084 
1085  //Total number of bytes that have been written
1086  *written = n;
1087 
1088  //Successful processing
1089  return NO_ERROR;
1090 }
1091 
1092 
1093 /**
1094  * @brief Format ClientHello Padding extension
1095  * @param[in] context Pointer to the TLS context
1096  * @param[in] clientHelloLen Actual length of the ClientHello message
1097  * @param[in] p Output stream where to write the ClientHello Padding extension
1098  * @param[out] written Total number of bytes that have been written
1099  * @return Error code
1100  **/
1101 
1103  size_t clientHelloLen, uint8_t *p, size_t *written)
1104 {
1105  size_t n = 0;
1106 
1107 #if (TLS_CLIENT_HELLO_PADDING_SUPPORT == ENABLED)
1108  //TLS protocol?
1109  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM)
1110  {
1111  TlsExtension *extension;
1112 
1113  //After building a ClientHello as normal, the client can add four bytes
1114  //to the length and test whether the resulting length falls into the
1115  //range 256 to 511 (refer to RFC 7685, section 4)
1116  clientHelloLen += sizeof(TlsHandshake);
1117 
1118  //Check the resulting length
1119  if(clientHelloLen >= 256 && clientHelloLen < 512)
1120  {
1121  //The ClientHello Padding extension will be added in order to push
1122  //the length to (at least) 512 bytes
1123  extension = (TlsExtension *) p;
1124 
1125  //Type of the extension
1126  extension->type = HTONS(TLS_EXT_PADDING);
1127 
1128  //Calculate the length of the padding
1129  if((clientHelloLen + sizeof(TlsExtension)) < 512)
1130  {
1131  n = 512 - sizeof(TlsExtension) - clientHelloLen;
1132  }
1133  else
1134  {
1135  n = 0;
1136  }
1137 
1138  //The padding string consists of an arbitrary number of zero bytes
1139  osMemset(extension->value, 0, n);
1140  //Set the length of the extension
1141  extension->length = htons(n);
1142 
1143  //Compute the length, in bytes, of the padding extension
1144  n += sizeof(TlsExtension);
1145  }
1146  }
1147 #endif
1148 
1149  //Total number of bytes that have been written
1150  *written = n;
1151 
1152  //Successful processing
1153  return NO_ERROR;
1154 }
1155 
1156 
1157 /**
1158  * @brief Parse SNI extension
1159  * @param[in] context Pointer to the TLS context
1160  * @param[in] serverNameList Pointer to the ServerName extension
1161  * @return Error code
1162  **/
1163 
1165  const TlsServerNameList *serverNameList)
1166 {
1167 #if (TLS_SNI_SUPPORT == ENABLED)
1168  //SNI extension found?
1169  if(serverNameList != NULL)
1170  {
1171  //If a client receives an extension type in the ServerHello that it did
1172  //not request in the associated ClientHello, it must abort the handshake
1173  //with an unsupported_extension fatal alert
1174  if(context->serverName == NULL)
1176  }
1177 #endif
1178 
1179  //Successful processing
1180  return NO_ERROR;
1181 }
1182 
1183 
1184 /**
1185  * @brief Parse MaxFragmentLength extension
1186  * @param[in] context Pointer to the TLS context
1187  * @param[in] maxFragLen Pointer to the MaxFragmentLength extension
1188  * @return Error code
1189  **/
1190 
1192  const TlsExtension *maxFragLen)
1193 {
1194 #if (TLS_MAX_FRAG_LEN_SUPPORT == ENABLED)
1195  //MaxFragmentLength extension found?
1196  if(maxFragLen != NULL)
1197  {
1198  size_t n;
1199 
1200  //Retrieve the value advertised by the server
1201  switch(maxFragLen->value[0])
1202  {
1204  n = 512;
1205  break;
1206 
1208  n = 1024;
1209  break;
1210 
1212  n = 2048;
1213  break;
1214 
1216  n = 4096;
1217  break;
1218 
1219  default:
1220  n = 0;
1221  break;
1222  }
1223 
1224  //If a client receives a maximum fragment length negotiation response
1225  //that differs from the length it requested, it must also abort the
1226  //handshake with an illegal_parameter alert
1227  if(n != context->maxFragLen)
1228  return ERROR_ILLEGAL_PARAMETER;
1229  }
1230 #endif
1231 
1232  //Successful processing
1233  return NO_ERROR;
1234 }
1235 
1236 
1237 /**
1238  * @brief Parse RecordSizeLimit extension
1239  * @param[in] context Pointer to the TLS context
1240  * @param[in] recordSizeLimit Pointer to the RecordSizeLimit extension
1241  * @return Error code
1242  **/
1243 
1245  const TlsExtension *recordSizeLimit)
1246 {
1247 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
1248  //RecordSizeLimit extension found?
1249  if(recordSizeLimit != NULL)
1250  {
1251  uint16_t n;
1252 
1253  //The value of RecordSizeLimit is the maximum size of record in octets
1254  //that the peer is willing to receive
1255  n = LOAD16BE(recordSizeLimit->value);
1256 
1257  //Endpoints must not send a RecordSizeLimit extension with a value
1258  //smaller than 64
1259  if(n < 64)
1260  {
1261  //An endpoint must treat receipt of a smaller value as a fatal error
1262  //and generate an illegal_parameter alert
1263  return ERROR_ILLEGAL_PARAMETER;
1264  }
1265 
1266  //TLS 1.3 currently selected?
1267  if(context->version == TLS_VERSION_1_3)
1268  {
1269  //The value includes the content type and padding added in TLS 1.3
1270  n--;
1271  }
1272 
1273  //The peer can include any limit up to the protocol-defined limit for
1274  //maximum record size. Even if a larger value is provided by a peer, an
1275  //endpoint must not send records larger than the protocol-defined limit
1276  context->recordSizeLimit = MIN(n, TLS_MAX_RECORD_LENGTH);
1277 
1278  //The RecordSizeLimit extension has been successfully negotiated
1279  context->recordSizeLimitExtReceived = TRUE;
1280  }
1281  else
1282  {
1283  //If this extension is not negotiated, endpoints can send records of any
1284  //size permitted by the protocol or other negotiated extensions
1285  context->recordSizeLimit = TLS_MAX_RECORD_LENGTH;
1286 
1287  //The RecordSizeLimit extension is not supported by the server
1288  context->recordSizeLimitExtReceived = FALSE;
1289  }
1290 #endif
1291 
1292  //Successful processing
1293  return NO_ERROR;
1294 }
1295 
1296 
1297 /**
1298  * @brief Parse EcPointFormats extension
1299  * @param[in] context Pointer to the TLS context
1300  * @param[in] ecPointFormatList Pointer to the EcPointFormats extension
1301  * @return Error code
1302  **/
1303 
1305  const TlsEcPointFormatList *ecPointFormatList)
1306 {
1307  error_t error;
1308 
1309  //Initialize status code
1310  error = NO_ERROR;
1311 
1312 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
1313  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
1314  //EcPointFormats extension found?
1315  if(ecPointFormatList != NULL)
1316  {
1317  uint_t i;
1318 
1319  //Loop through the list of supported EC point formats
1320  for(i = 0; i < ecPointFormatList->length; i++)
1321  {
1322  //Uncompressed point format?
1323  if(ecPointFormatList->value[i] == TLS_EC_POINT_FORMAT_UNCOMPRESSED)
1324  {
1325  break;
1326  }
1327  }
1328 
1329  //If the EcPointFormats extension is sent, it must contain the value 0
1330  //as one of the items in the list of point formats (refer to RFC 4492,
1331  //section 5.2)
1332  if(i >= ecPointFormatList->length)
1333  {
1334  //Report an error
1335  error = ERROR_ILLEGAL_PARAMETER;
1336  }
1337  }
1338 #endif
1339 
1340  //Return status code
1341  return error;
1342 }
1343 
1344 
1345 /**
1346  * @brief Parse ALPN extension
1347  * @param[in] context Pointer to the TLS context
1348  * @param[in] protocolNameList Pointer to the ALPN extension
1349  * @return Error code
1350  **/
1351 
1353  const TlsProtocolNameList *protocolNameList)
1354 {
1355 #if (TLS_ALPN_SUPPORT == ENABLED)
1356  //ALPN extension found?
1357  if(protocolNameList != NULL)
1358  {
1359  size_t length;
1360  const TlsProtocolName *protocolName;
1361 
1362  //If a client receives an extension type in the ServerHello that it
1363  //did not request in the associated ClientHello, it must abort the
1364  //handshake with an unsupported_extension fatal alert
1365  if(context->protocolList == NULL)
1367 
1368  //Retrieve the length of the list
1369  length = ntohs(protocolNameList->length);
1370 
1371  //The list must not be be empty
1372  if(length == 0)
1373  return ERROR_DECODING_FAILED;
1374 
1375  //Point to the selected protocol
1376  protocolName = (TlsProtocolName *) protocolNameList->value;
1377 
1378  //The list must contain exactly one protocol name
1379  if(length < sizeof(TlsProtocolName))
1380  return ERROR_DECODING_FAILED;
1381  if(length != (sizeof(TlsProtocolName) + protocolName->length))
1382  return ERROR_DECODING_FAILED;
1383 
1384  //Retrieve the length of the protocol name
1385  length -= sizeof(TlsProtocolName);
1386 
1387  //Empty strings must not be included in the list
1388  if(length == 0)
1389  return ERROR_DECODING_FAILED;
1390 
1391  //Check whether the protocol is supported by the client
1392  if(!tlsIsAlpnProtocolSupported(context, protocolName->value, length))
1393  {
1394  //Report an error if unknown ALPN protocols are disallowed
1395  if(!context->unknownProtocolsAllowed)
1396  return ERROR_ILLEGAL_PARAMETER;
1397  }
1398 
1399  //Sanity check
1400  if(context->selectedProtocol != NULL)
1401  {
1402  //Release memory
1403  tlsFreeMem(context->selectedProtocol);
1404  context->selectedProtocol = NULL;
1405  }
1406 
1407  //Allocate a memory block to hold the protocol name
1408  context->selectedProtocol = tlsAllocMem(length + 1);
1409  //Failed to allocate memory?
1410  if(context->selectedProtocol == NULL)
1411  return ERROR_OUT_OF_MEMORY;
1412 
1413  //Save protocol name
1414  osMemcpy(context->selectedProtocol, protocolName->value, length);
1415  //Properly terminate the string with a NULL character
1416  context->selectedProtocol[length] = '\0';
1417  }
1418 #endif
1419 
1420  //Successful processing
1421  return NO_ERROR;
1422 }
1423 
1424 
1425 /**
1426  * @brief Parse ClientCertType extension
1427  * @param[in] context Pointer to the TLS context
1428  * @param[in] clientCertType Pointer to the ClientCertType extension
1429  * @return Error code
1430  **/
1431 
1433  const TlsExtension *clientCertType)
1434 {
1435 #if (TLS_RAW_PUBLIC_KEY_SUPPORT == ENABLED)
1436  //ClientCertType extension found?
1437  if(clientCertType != NULL)
1438  {
1439  //The value conveyed in the extension must be selected from one of the
1440  //values provided in the ClientCertType extension sent in the ClientHello
1441  if(clientCertType->value[0] != TLS_CERT_FORMAT_X509 &&
1442  clientCertType->value[0] != TLS_CERT_FORMAT_RAW_PUBLIC_KEY)
1443  {
1444  return ERROR_ILLEGAL_PARAMETER;
1445  }
1446 
1447  //The ClientCertType extension in the ServerHello indicates the type
1448  //of certificates the client is requested to provide in a subsequent
1449  //certificate payload
1450  context->certFormat = (TlsCertificateFormat) clientCertType->value[0];
1451  }
1452 #endif
1453 
1454  //Successful processing
1455  return NO_ERROR;
1456 }
1457 
1458 
1459 /**
1460  * @brief Parse ServerCertType extension
1461  * @param[in] context Pointer to the TLS context
1462  * @param[in] serverCertType Pointer to the ServerCertType extension
1463  * @return Error code
1464  **/
1465 
1467  const TlsExtension *serverCertType)
1468 {
1469 #if (TLS_RAW_PUBLIC_KEY_SUPPORT == ENABLED)
1470  //ServerCertType extension found?
1471  if(serverCertType != NULL)
1472  {
1473  //If a client receives an extension type in the ServerHello that it did
1474  //not request in the associated ClientHello, it must abort the handshake
1475  //with an unsupported_extension fatal alert
1476  if(context->rpkVerifyCallback == NULL &&
1477  serverCertType->value[0] != TLS_CERT_FORMAT_X509)
1478  {
1480  }
1481 
1482  //The value conveyed in the extension must be selected from one of the
1483  //values provided in the ServerCertType extension sent in the ClientHello
1484  if(serverCertType->value[0] != TLS_CERT_FORMAT_X509 &&
1485  serverCertType->value[0] != TLS_CERT_FORMAT_RAW_PUBLIC_KEY)
1486  {
1487  return ERROR_ILLEGAL_PARAMETER;
1488  }
1489 
1490  //With the ServerCertType extension in the ServerHello, the TLS server
1491  //indicates the certificate type carried in the certificate payload
1492  context->peerCertFormat = (TlsCertificateFormat) serverCertType->value[0];
1493  }
1494 #endif
1495 
1496  //Successful processing
1497  return NO_ERROR;
1498 }
1499 
1500 
1501 /**
1502  * @brief Parse EncryptThenMac extension
1503  * @param[in] context Pointer to the TLS context
1504  * @param[in] encryptThenMac Pointer to the EncryptThenMac extension
1505  * @return Error code
1506  **/
1507 
1509  const TlsExtension *encryptThenMac)
1510 {
1511 #if (TLS_ENCRYPT_THEN_MAC_SUPPORT == ENABLED)
1512  //EncryptThenMac extension found?
1513  if(encryptThenMac != NULL)
1514  {
1515  //If a server receives an encrypt-then-MAC request extension from a
1516  //client and then selects a stream or AEAD ciphersuite, it must not send
1517  //an encrypt-then-MAC response extension back to the client (refer to
1518  //RFC 7366, section 3)
1519  if(context->cipherSuite.cipherMode != CIPHER_MODE_CBC)
1520  return ERROR_HANDSHAKE_FAILED;
1521 
1522  //Use encrypt-then-MAC construction rather than the default
1523  //MAC-then-encrypt
1524  context->etmExtReceived = TRUE;
1525  }
1526  else
1527  {
1528  //Use default MAC-then-encrypt construction
1529  context->etmExtReceived = FALSE;
1530  }
1531 #endif
1532 
1533  //Successful processing
1534  return NO_ERROR;
1535 }
1536 
1537 
1538 /**
1539  * @brief Parse ExtendedMasterSecret extension
1540  * @param[in] context Pointer to the TLS context
1541  * @param[in] extendedMasterSecret Pointer to the ExtendedMasterSecret extension
1542  * @return Error code
1543  **/
1544 
1547 {
1548 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
1549  //ExtendedMasterSecret extension found?
1550  if(extendedMasterSecret != NULL)
1551  {
1552  //Abbreviated handshake?
1553  if(context->resume)
1554  {
1555  //If the original session did not use the ExtendedMasterSecret
1556  //extension but the new ServerHello contains the extension, the
1557  //client must abort the handshake
1558  if(!context->emsExtReceived)
1559  return ERROR_HANDSHAKE_FAILED;
1560  }
1561 
1562  //A valid ExtendedMasterSecret extension has been received
1563  context->emsExtReceived = TRUE;
1564  }
1565  else
1566  {
1567  //Abbreviated handshake?
1568  if(context->resume)
1569  {
1570  //If the original session used the ExtendedMasterSecret extension
1571  //but the new ServerHello does not contain the extension, the client
1572  //must abort the handshake
1573  if(context->emsExtReceived)
1574  return ERROR_HANDSHAKE_FAILED;
1575  }
1576 
1577  //The ServerHello does not contain any ExtendedMasterSecret extension
1578  context->emsExtReceived = FALSE;
1579  }
1580 #endif
1581 
1582  //Successful processing
1583  return NO_ERROR;
1584 }
1585 
1586 
1587 /**
1588  * @brief Parse SessionTicket extension
1589  * @param[in] context Pointer to the TLS context
1590  * @param[in] sessionTicket Pointer to the SessionTicket extension
1591  * @return Error code
1592  **/
1593 
1595  const TlsExtension *sessionTicket)
1596 {
1597 #if (TLS_TICKET_SUPPORT == ENABLED)
1598  //SessionTicket extension found?
1599  if(sessionTicket != NULL)
1600  {
1601  //If a client receives an extension type in the ServerHello that it did
1602  //not request in the associated ClientHello, it must abort the handshake
1603  //with an unsupported_extension fatal alert
1604  if(!context->sessionTicketEnabled)
1606 
1607  //The server uses the SessionTicket extension to indicate to the client
1608  //that it will send a new session ticket using the NewSessionTicket
1609  //handshake message
1610  context->sessionTicketExtReceived = TRUE;
1611  }
1612  else
1613  {
1614  //The ServerHello does not contain any SessionTicket extension
1615  context->sessionTicketExtReceived = FALSE;
1616  }
1617 #endif
1618 
1619  //Successful processing
1620  return NO_ERROR;
1621 }
1622 
1623 
1624 /**
1625  * @brief Parse RenegotiationInfo extension
1626  * @param[in] context Pointer to the TLS context
1627  * @param[in] extensions ServerHello extensions offered by the server
1628  * @return Error code
1629  **/
1630 
1633 {
1634 #if (TLS_SECURE_RENEGOTIATION_SUPPORT == ENABLED)
1635  //Initial handshake?
1636  if(context->clientVerifyDataLen == 0)
1637  {
1638  //RenegotiationInfo extension found?
1639  if(extensions->renegoInfo != NULL)
1640  {
1641  //If the extension is present, set the secure_renegotiation flag to TRUE
1642  context->secureRenegoFlag = TRUE;
1643 
1644  //Verify that the length of the renegotiated_connection field is zero
1645  if(extensions->renegoInfo->length != 0)
1646  {
1647  //If it is not, the client must abort the handshake by sending a
1648  //fatal handshake failure alert
1649  return ERROR_HANDSHAKE_FAILED;
1650  }
1651  }
1652  else
1653  {
1654  //If the extension is not present, the server does not support secure
1655  //renegotiation
1656  context->secureRenegoFlag = FALSE;
1657  }
1658  }
1659  //Secure renegotiation?
1660  else
1661  {
1662  //RenegotiationInfo extension found?
1663  if(extensions->renegoInfo != NULL)
1664  {
1665  //Check the length of the renegotiated_connection field
1666  if(extensions->renegoInfo->length != (context->clientVerifyDataLen +
1667  context->serverVerifyDataLen))
1668  {
1669  //The client must abort the handshake
1670  return ERROR_HANDSHAKE_FAILED;
1671  }
1672 
1673  //The client must verify that the first half of the field is equal to
1674  //the saved client_verify_data value
1675  if(osMemcmp(extensions->renegoInfo->value, context->clientVerifyData,
1676  context->clientVerifyDataLen))
1677  {
1678  //If it is not, the client must abort the handshake
1679  return ERROR_HANDSHAKE_FAILED;
1680  }
1681 
1682  //The client must verify that the second half of the field is equal to
1683  //the saved server_verify_data value
1684  if(osMemcmp(extensions->renegoInfo->value + context->clientVerifyDataLen,
1685  context->serverVerifyData, context->serverVerifyDataLen))
1686  {
1687  //If it is not, the client must abort the handshake
1688  return ERROR_HANDSHAKE_FAILED;
1689  }
1690 
1691 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
1692  //ExtendedMasterSecret extension found?
1693  if(extensions->extendedMasterSecret != NULL)
1694  {
1695  //If the initial handshake did not use the ExtendedMasterSecret
1696  //extension but the new ServerHello contains the extension, the
1697  //client must abort the handshake
1698  if(!context->emsExtReceived)
1699  return ERROR_HANDSHAKE_FAILED;
1700  }
1701  else
1702  {
1703  //If the initial handshake used the ExtendedMasterSecret extension
1704  //but the new ServerHello does not contain the extension, the
1705  //client must abort the handshake
1706  if(context->emsExtReceived)
1707  return ERROR_HANDSHAKE_FAILED;
1708  }
1709 #endif
1710  }
1711  else
1712  {
1713  //If the RenegotiationInfo extension is not present, the client
1714  //must abort the handshake
1715  return ERROR_HANDSHAKE_FAILED;
1716  }
1717  }
1718 #endif
1719 
1720  //Successful processing
1721  return NO_ERROR;
1722 }
1723 
1724 #endif
@ TLS_GROUP_X25519_MLKEM768
Definition: tls.h:1503
@ TLS_GROUP_BRAINPOOLP512R1_TLS13
Definition: tls.h:1484
#define TLS_MAX_RECORD_LENGTH
Definition: tls.h:977
#define tlsAllocMem(size)
Definition: tls.h:888
@ TLS_EXT_MAX_FRAGMENT_LENGTH
Definition: tls.h:1351
#define htons(value)
Definition: cpu_endian.h:413
Parsing and checking of TLS extensions.
@ TLS_CERT_FORMAT_RAW_PUBLIC_KEY
Definition: tls.h:1223
TLS helper functions.
TlsServerName
Definition: tls.h:1729
uint8_t extensions[]
Definition: ntp_common.h:213
@ TLS_GROUP_BRAINPOOLP256R1_TLS13
Definition: tls.h:1482
@ TLS_GROUP_SECP160R2
Definition: tls.h:1468
TLS cipher suites.
@ CIPHER_MODE_CBC
Definition: crypto.h:1063
error_t tlsFormatClientSupportedVersionsExtension(TlsContext *context, uint8_t *p, size_t *written)
Format SupportedVersions extension.
error_t tlsFormatClientEcPointFormatsExtension(TlsContext *context, uint8_t *p, size_t *written)
Format EcPointFormats extension.
@ ERROR_ILLEGAL_PARAMETER
Definition: error.h:244
const EcCurve * tlsGetCurve(TlsContext *context, uint16_t namedCurve)
Get the EC domain parameters that match the specified named curve.
Definition: tls_misc.c:1392
@ TLS_EXT_SUPPORTED_VERSIONS
Definition: tls.h:1387
uint8_t p
Definition: ndp.h:300
Helper functions for TLS client.
@ TLS_GROUP_SECP256K1
Definition: tls.h:1473
#define TRUE
Definition: os_port.h:50
@ TLS_GROUP_SECP256R1
Definition: tls.h:1474
bool_t tlsIsAlpnProtocolSupported(TlsContext *context, const char_t *protocol, size_t length)
Check whether the specified ALPN protocol is supported.
TlsEcPointFormatList
Definition: tls.h:1784
@ TLS_GROUP_CURVE_SM2
Definition: tls.h:1492
@ TLS_GROUP_SECP224K1
Definition: tls.h:1471
error_t tlsParseServerRecordSizeLimitExtension(TlsContext *context, const TlsExtension *recordSizeLimit)
Parse RecordSizeLimit extension.
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:1000
TlsRenegoInfo
Definition: tls.h:1806
error_t tlsFormatClientSessionTicketExtension(TlsContext *context, uint8_t *p, size_t *written)
Format SessionTicket extension.
#define osMemcmp(p1, p2, length)
Definition: os_port.h:156
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:234
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
error_t tlsParseServerSniExtension(TlsContext *context, const TlsServerNameList *serverNameList)
Parse SNI extension.
error_t tlsParseClientCertTypeExtension(TlsContext *context, const TlsExtension *clientCertType)
Parse ClientCertType extension.
error_t tlsFormatTrustedAuthorities(TlsContext *context, uint8_t *p, size_t *written)
Format the list of trusted authorities.
#define osStrlen(s)
Definition: os_port.h:168
TlsProtocolNameList
Definition: tls.h:1762
TlsExtension
Definition: tls.h:1695
@ TLS_GROUP_BRAINPOOLP256R1
Definition: tls.h:1477
@ TLS_EXT_SESSION_TICKET
Definition: tls.h:1383
@ TLS_GROUP_X448
Definition: tls.h:1481
@ TLS_CIPHER_SUITE_TYPE_TLS13
@ TLS_GROUP_FFDHE6144
Definition: tls.h:1496
@ TLS_MAX_FRAGMENT_LENGTH_4096
Definition: tls.h:1428
error_t tlsFormatSupportedGroupsExtension(TlsContext *context, uint8_t *p, size_t *written)
Format SupportedGroups extension.
error_t tlsFormatClientSniExtension(TlsContext *context, uint8_t *p, size_t *written)
Format SNI extension.
bool_t extendedMasterSecret
Extended master secret computation.
Definition: tls.h:2010
@ TLS_CIPHER_SUITE_TYPE_SM
#define DTLS_SUPPORT
Definition: dtls_misc.h:41
@ TLS_EXT_SERVER_NAME
Definition: tls.h:1350
error_t tlsParseServerEtmExtension(TlsContext *context, const TlsExtension *encryptThenMac)
Parse EncryptThenMac extension.
@ TLS_GROUP_CURVE_SM2_MLKEM768
Definition: tls.h:1505
error_t tlsFormatTrustedCaKeysExtension(TlsContext *context, uint8_t *p, size_t *written)
Format TrustedCaKeys extension.
@ TLS_EXT_TRUSTED_CA_KEYS
Definition: tls.h:1353
#define DTLS_VERSION_1_0
Definition: dtls_misc.h:35
TlsHandshake
Definition: tls.h:1876
#define FALSE
Definition: os_port.h:46
error_t tlsParseServerMaxFragLenExtension(TlsContext *context, const TlsExtension *maxFragLen)
Parse MaxFragmentLength extension.
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
@ ERROR_UNSUPPORTED_EXTENSION
Definition: error.h:246
TlsCertificateFormat
Certificate formats.
Definition: tls.h:1220
@ TLS_EXT_CLIENT_CERT_TYPE
Definition: tls.h:1369
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
error_t tlsParseServerCertTypeExtension(TlsContext *context, const TlsExtension *serverCertType)
Parse ServerCertType extension.
@ TLS_EXT_EXTENDED_MASTER_SECRET
Definition: tls.h:1373
error_t tlsFormatClientRenegoInfoExtension(TlsContext *context, uint8_t *p, size_t *written)
Format RenegotiationInfo extension.
error_t tlsFormatClientEtmExtension(TlsContext *context, uint8_t *p, size_t *written)
Format EncryptThenMac extension.
@ TLS_GROUP_SECP256R1_MLKEM768
Definition: tls.h:1502
@ TLS_EXT_SUPPORTED_GROUPS
Definition: tls.h:1360
#define TLS_VERSION_1_2
Definition: tls.h:96
const KemAlgo * tls13GetMlkemAlgo(TlsContext *context, uint16_t namedGroup)
Get the ML-KEM algorithm that matches the specified named group.
Definition: tls13_misc.c:1176
@ TLS_EXT_RENEGOTIATION_INFO
Definition: tls.h:1405
const KemAlgo * tls13GetNextGenAlgo(TlsContext *context, uint16_t namedGroup)
Get the next-gen algorithm used by the hybrid key exchange method.
Definition: tls13_misc.c:1319
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
error_t tlsParseServerSessionTicketExtension(TlsContext *context, const TlsExtension *sessionTicket)
Parse SessionTicket extension.
@ TLS_EXT_ENCRYPT_THEN_MAC
Definition: tls.h:1372
@ TLS_GROUP_FFDHE4096
Definition: tls.h:1495
@ TLS_CIPHER_SUITE_TYPE_ECDH
bool_t tlsCheckDnsHostname(const char_t *name, size_t length)
DNS hostname verification.
Definition: tls_misc.c:1737
#define TLS_VERSION_1_3
Definition: tls.h:97
TlsServerNameList
Definition: tls.h:1740
@ TLS_MAX_FRAGMENT_LENGTH_2048
Definition: tls.h:1427
@ TLS_GROUP_SECP384R1
Definition: tls.h:1475
@ TLS_GROUP_SECP192K1
Definition: tls.h:1469
error_t tlsFormatClientAlpnExtension(TlsContext *context, uint8_t *p, size_t *written)
Format ALPN extension.
TlsProtocolName
Definition: tls.h:1751
error_t tlsParseServerEcPointFormatsExtension(TlsContext *context, const TlsEcPointFormatList *ecPointFormatList)
Parse EcPointFormats extension.
@ TLS_EC_POINT_FORMAT_UNCOMPRESSED
Definition: tls.h:1517
uint8_t length
Definition: tcp.h:375
@ TLS_GROUP_BRAINPOOLP512R1
Definition: tls.h:1479
@ TLS_GROUP_FFDHE2048
Definition: tls.h:1493
const TlsFfdheGroup * tlsGetFfdheGroup(TlsContext *context, uint16_t namedGroup)
Get the FFDHE parameters that match the specified named group.
Definition: tls_ffdhe.c:314
#define MIN(a, b)
Definition: os_port.h:63
@ TLS_GROUP_MLKEM512
Definition: tls.h:1499
#define ENABLED
Definition: os_port.h:37
@ TLS_EXT_EC_POINT_FORMATS
Definition: tls.h:1361
@ TLS_GROUP_SECP521R1
Definition: tls.h:1476
@ TLS_GROUP_SECP192R1
Definition: tls.h:1470
@ TLS_EXT_ALPN
Definition: tls.h:1366
@ TLS_GROUP_FFDHE3072
Definition: tls.h:1494
Hello extensions.
Definition: tls.h:2257
@ TLS_GROUP_SECP160R1
Definition: tls.h:1467
@ TLS_GROUP_BRAINPOOLP384R1_TLS13
Definition: tls.h:1483
Formatting and parsing of extensions (TLS client)
#define ntohs(value)
Definition: cpu_endian.h:421
error_t tlsFormatClientHelloPaddingExtension(TlsContext *context, size_t clientHelloLen, uint8_t *p, size_t *written)
Format ClientHello Padding extension.
@ TLS_GROUP_SECP224R1
Definition: tls.h:1472
#define TLS_VERSION_1_1
Definition: tls.h:95
error_t tlsParseServerEmsExtension(TlsContext *context, const TlsExtension *extendedMasterSecret)
Parse ExtendedMasterSecret extension.
@ TLS_EXT_PADDING
Definition: tls.h:1371
#define HTONS(value)
Definition: cpu_endian.h:410
@ TLS_GROUP_MLKEM1024
Definition: tls.h:1501
uint8_t n
#define DTLS_VERSION_1_3
Definition: dtls_misc.h:37
@ TLS_CIPHER_SUITE_TYPE_DH
#define TLS_VERSION_1_0
Definition: tls.h:94
error_t tlsFormatClientEmsExtension(TlsContext *context, uint8_t *p, size_t *written)
Format ExtendedMasterSecret extension.
@ TLS_EXT_SERVER_CERT_TYPE
Definition: tls.h:1370
@ TLS_NAME_TYPE_HOSTNAME
Definition: tls.h:1415
@ TLS_MAX_FRAGMENT_LENGTH_1024
Definition: tls.h:1426
const uint16_t tlsSupportedGroups[]
error_t tlsFormatClientCertTypeListExtension(TlsContext *context, uint8_t *p, size_t *written)
Format ClientCertType extension.
TLS (Transport Layer Security)
TlsTrustedAuthorities
Definition: tls.h:1683
@ TLS_GROUP_X25519
Definition: tls.h:1480
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:999
error_t tlsParseServerRenegoInfoExtension(TlsContext *context, const TlsHelloExtensions *extensions)
Parse RenegotiationInfo extension.
error_t tlsFormatClientRecordSizeLimitExtension(TlsContext *context, uint8_t *p, size_t *written)
Format RecordSizeLimit extension.
const EcCurve * tls13GetTraditionalAlgo(TlsContext *context, uint16_t namedGroup)
Get the traditional algorithm used by the hybrid key exchange method.
Definition: tls13_misc.c:1244
FFDHE key exchange.
error_t tlsParseServerAlpnExtension(TlsContext *context, const TlsProtocolNameList *protocolNameList)
Parse ALPN extension.
error_t tlsFormatServerCertTypeListExtension(TlsContext *context, uint8_t *p, size_t *written)
Format ServerCertType extension.
@ ERROR_DECODING_FAILED
Definition: error.h:242
unsigned int uint_t
Definition: compiler_port.h:57
#define LOAD16BE(p)
Definition: cpu_endian.h:186
#define osMemset(p, value, length)
Definition: os_port.h:138
@ TLS_GROUP_MLKEM768
Definition: tls.h:1500
TlsSupportedGroupList
Definition: tls.h:1773
#define tlsFreeMem(p)
Definition: tls.h:893
TlsSupportedVersionList
Definition: tls.h:1717
#define DTLS_VERSION_1_2
Definition: dtls_misc.h:36
@ TLS_GROUP_FFDHE8192
Definition: tls.h:1497
TlsCertTypeList
Definition: tls.h:1795
@ NO_ERROR
Success.
Definition: error.h:44
@ TLS_EXT_RECORD_SIZE_LIMIT
Definition: tls.h:1377
Debugging facilities.
@ TLS_CERT_FORMAT_X509
Definition: tls.h:1221
@ TLS_GROUP_BRAINPOOLP384R1
Definition: tls.h:1478
@ TLS_MAX_FRAGMENT_LENGTH_512
Definition: tls.h:1425
#define arraysize(a)
Definition: os_port.h:71
bool_t tlsIsTicketValid(TlsContext *context)
Check whether a session ticket is valid.
@ TLS_GROUP_SECP384R1_MLKEM1024
Definition: tls.h:1504
error_t tlsFormatClientMaxFragLenExtension(TlsContext *context, uint8_t *p, size_t *written)
Format MaxFragmentLength extension.