x509_cert_validate.c
Go to the documentation of this file.
1 /**
2  * @file x509_cert_validate.c
3  * @brief X.509 certificate validation
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO 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.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/crypto.h"
36 #include "pkix/x509_cert_parse.h"
39 #include "pkix/x509_sign_verify.h"
40 #include "debug.h"
41 
42 //Check crypto library configuration
43 #if (X509_SUPPORT == ENABLED)
44 
45 
46 /**
47  * @brief X.509 certificate validation
48  * @param[in] certInfo X.509 certificate to be verified
49  * @param[in] issuerCertInfo Issuer's certificate
50  * @param[in] pathLen Certificate path length
51  * @return Error code
52  **/
53 
55  const X509CertInfo *issuerCertInfo, uint_t pathLen)
56 {
57  error_t error;
58  time_t currentTime;
60 
61  //Check parameters
62  if(certInfo == NULL || issuerCertInfo == NULL)
64 
65  //Retrieve current time
66  currentTime = getCurrentUnixTime();
67 
68  //Any real-time clock implemented?
69  if(currentTime != 0)
70  {
71  DateTime currentDate;
72  const X509Validity *validity;
73 
74  //Convert Unix timestamp to date
75  convertUnixTimeToDate(currentTime, &currentDate);
76 
77  //The certificate validity period is the time interval during which the
78  //CA warrants that it will maintain information about the status of the
79  //certificate
80  validity = &certInfo->tbsCert.validity;
81 
82  //Check the validity period
83  if(compareDateTime(&currentDate, &validity->notBefore) < 0 ||
84  compareDateTime(&currentDate, &validity->notAfter) > 0)
85  {
86  //The certificate has expired or is not yet valid
88  }
89  }
90 
91  //Make sure that the subject and issuer names chain correctly
92  if(!x509CompareName(certInfo->tbsCert.issuer.raw.value,
93  certInfo->tbsCert.issuer.raw.length,
94  issuerCertInfo->tbsCert.subject.raw.value,
95  issuerCertInfo->tbsCert.subject.raw.length))
96  {
97  //Report an error
98  return ERROR_BAD_CERTIFICATE;
99  }
100 
101  //Point to the X.509 extensions of the issuer certificate
102  extensions = &issuerCertInfo->tbsCert.extensions;
103 
104  //X.509 version 3 certificate?
105  if(issuerCertInfo->tbsCert.version >= X509_VERSION_3)
106  {
107  //Ensure that the issuer certificate is a CA certificate
108  if(!extensions->basicConstraints.cA)
109  return ERROR_BAD_CERTIFICATE;
110  }
111 
112  //Where pathLenConstraint does not appear, no limit is imposed
113  if(extensions->basicConstraints.pathLenConstraint >= 0)
114  {
115  //The pathLenConstraint field gives the maximum number of non-self-issued
116  //intermediate certificates that may follow this certificate in a valid
117  //certification path
118  if(pathLen > (uint_t) extensions->basicConstraints.pathLenConstraint)
119  return ERROR_BAD_CERTIFICATE;
120  }
121 
122  //Check if the keyUsage extension is present
123  if(extensions->keyUsage.bitmap != 0)
124  {
125  //If the keyUsage extension is present, then the subject public key must
126  //not be used to verify signatures on certificates unless the keyCertSign
127  //bit is set (refer to RFC 5280, section 4.2.1.3)
128  if((extensions->keyUsage.bitmap & X509_KEY_USAGE_KEY_CERT_SIGN) == 0)
129  return ERROR_BAD_CERTIFICATE;
130  }
131 
132  //The ASN.1 DER-encoded tbsCertificate is used as the input to the signature
133  //function
134  error = x509VerifySignature(&certInfo->tbsCert.raw, &certInfo->signatureAlgo,
135  &issuerCertInfo->tbsCert.subjectPublicKeyInfo, &certInfo->signatureValue);
136 
137  //Return status code
138  return error;
139 }
140 
141 
142 /**
143  * @brief Check whether the certificate matches the specified FQDN
144  * @param[in] certInfo Pointer to the X.509 certificate
145  * @param[in] fqdn NULL-terminated string that contains the fully-qualified domain name
146  * @return Error code
147  **/
148 
150  const char_t *fqdn)
151 {
152  error_t error;
153  bool_t res;
154  uint_t i;
155  size_t n;
156  size_t length;
157  const uint8_t *data;
158  const X509Extensions *extensions;
159  X509GeneralName generalName;
160 
161  //Point to the X.509 extensions of the CA certificate
162  extensions = &certInfo->tbsCert.extensions;
163 
164  //Valid FQDN name provided?
165  if(fqdn != NULL)
166  {
167  //Initialize flag
168  res = FALSE;
169 
170  //Total number of valid DNS names found in the SubjectAltName extension
171  i = 0;
172 
173  //Valid SubjectAltName extension?
174  if(extensions->subjectAltName.raw.length > 0)
175  {
176  //The subject alternative name extension allows identities to be bound
177  //to the subject of the certificate. These identities may be included
178  //in addition to or in place of the identity in the subject field of
179  //the certificate
180  data = extensions->subjectAltName.raw.value;
181  length = extensions->subjectAltName.raw.length;
182 
183  //Loop through the list of subject alternative names
184  while(!res && length > 0)
185  {
186  //Parse GeneralName field
187  error = x509ParseGeneralName(data, length, &n, &generalName);
188  //Failed to decode ASN.1 tag?
189  if(error)
190  return error;
191 
192  //DNS name or IP address?
193  if(generalName.type == X509_GENERAL_NAME_TYPE_DNS)
194  {
195  //Check whether the alternative name matches the specified string
196  res = x509CompareSubjectName(generalName.value,
197  generalName.length, fqdn);
198 
199  //Increment counter
200  i++;
201  }
202  else if(generalName.type == X509_GENERAL_NAME_TYPE_IP_ADDRESS)
203  {
204  //Check whether the IP address matches the specified string
205  res = x509CompareIpAddr((uint8_t *) generalName.value,
206  generalName.length, fqdn);
207 
208  //Increment counter
209  i++;
210  }
211  else
212  {
213  //Unknown general name type
214  }
215 
216  //Next item
217  data += n;
218  length -= n;
219  }
220  }
221 
222  //No match?
223  if(!res)
224  {
225  //The implementation must not seek a match for a reference identifier
226  //of CN-ID if the presented identifiers include a DNS-ID, SRV-ID or
227  //URI-ID (refer to RFC 6125, section 6.4.4)
228  if(i == 0 && certInfo->tbsCert.subject.commonName.length > 0)
229  {
230  //The implementation may as a last resort check the CN-ID for a match
232  certInfo->tbsCert.subject.commonName.length, fqdn);
233  }
234  }
235 
236  //Check whether the subject name matches the specified FQDN
237  error = res ? NO_ERROR : ERROR_INVALID_NAME;
238  }
239  else
240  {
241  //If no valid FQDN name is provided, then the subject name of the
242  //certificate is not verified
243  error = NO_ERROR;
244  }
245 
246  //Return status code
247  return error;
248 }
249 
250 
251 /**
252  * @brief Check name constraints
253  * @param[in] subjectName Subject name to be verified
254  * @param[in] certInfo Pointer to the CA certificate
255  * @return Error code
256  **/
257 
259  const X509CertInfo *certInfo)
260 {
261  error_t error;
262  bool_t match;
263  size_t m;
264  size_t n;
265  size_t length;
266  const uint8_t *data;
267  const X509Extensions *extensions;
268  X509GeneralName subtree;
269 
270  //Initialize error code
271  error = NO_ERROR;
272 
273  //Point to the X.509 extensions of the CA certificate
274  extensions = &certInfo->tbsCert.extensions;
275 
276  //Valid subject name provided?
277  if(subjectName != NULL)
278  {
279  //Point to the list of excluded name subtrees
280  data = extensions->nameConstraints.excludedSubtrees.value;
281  length = extensions->nameConstraints.excludedSubtrees.length;
282 
283  //Loop through the names constraints
284  while(length > 0)
285  {
286  //Parse GeneralSubtree field
287  error = x509ParseGeneralSubtree(data, length, &n, &subtree);
288  //Failed to decode ASN.1 tag?
289  if(error)
290  break;
291 
292  //Initialize flag
293  match = FALSE;
294 
295  //Check name type
296  if(subtree.type == X509_GENERAL_NAME_TYPE_DNS)
297  {
298  //Check whether the subject name matches the subtree
299  match = x509CompareSubtree(subjectName, subtree.value,
300  subtree.length);
301  }
302  else if(subtree.type == X509_GENERAL_NAME_TYPE_DIRECTORY)
303  {
304  X509Name name;
305 
306  //Parse distinguished name
307  error = x509ParseName((uint8_t *) subtree.value, subtree.length,
308  &m, &name);
309  //Failed to decode ASN.1 structure?
310  if(error)
311  break;
312 
313  //Valid common name?
314  if(name.commonName.value != NULL)
315  {
316  //Check whether the subject name matches the subtree
317  match = x509CompareSubtree(subjectName, name.commonName.value,
318  name.commonName.length);
319  }
320  }
321  else
322  {
323  //Just for sanity
324  }
325 
326  //Any match?
327  if(match)
328  {
329  //The subject name is not acceptable
330  error = ERROR_INVALID_NAME;
331  break;
332  }
333 
334  //Next item
335  data += n;
336  length -= n;
337  }
338 
339  //Any name matching a restriction in the excludedSubtrees field is
340  //invalid regardless of information appearing in the permittedSubtrees
341  //(Refer to RFC 5280, section 4.2.1.10)
342  if(!error)
343  {
344  //Point to the list of permitted name subtrees
345  data = extensions->nameConstraints.permittedSubtrees.value;
346  length = extensions->nameConstraints.permittedSubtrees.length;
347 
348  //Loop through the names constraints
349  while(length > 0)
350  {
351  //Parse GeneralSubtree field
352  error = x509ParseGeneralSubtree(data, length, &n, &subtree);
353  //Failed to decode ASN.1 tag?
354  if(error)
355  break;
356 
357  //Initialize flag
358  match = FALSE;
359 
360  //Check name type
361  if(subtree.type == X509_GENERAL_NAME_TYPE_DNS)
362  {
363  //Check whether the subject name matches the subtree
364  match = x509CompareSubtree(subjectName, subtree.value,
365  subtree.length);
366  }
367  else if(subtree.type == X509_GENERAL_NAME_TYPE_DIRECTORY)
368  {
369  X509Name name;
370 
371  //Parse distinguished name
372  error = x509ParseName((uint8_t *) subtree.value, subtree.length,
373  &m, &name);
374  //Failed to decode ASN.1 structure?
375  if(error)
376  break;
377 
378  //Valid common name?
379  if(name.commonName.value != NULL)
380  {
381  //Check whether the subject name matches the subtree
382  match = x509CompareSubtree(subjectName, name.commonName.value,
383  name.commonName.length);
384  }
385  }
386  else
387  {
388  //Just for sanity
389  }
390 
391  //Any match?
392  if(match)
393  {
394  //The subject name is acceptable
395  error = NO_ERROR;
396  break;
397  }
398  else
399  {
400  //The subject name does not match the current field
401  error = ERROR_INVALID_NAME;
402  }
403 
404  //Next item
405  data += n;
406  length -= n;
407  }
408  }
409  }
410  else
411  {
412  //If no valid subject name is provided, then the name constraints
413  //are not verified
414  }
415 
416  //Return status code
417  return error;
418 }
419 
420 
421 /**
422  * @brief Compare distinguished names
423  * @param[in] name1 Pointer to the first distinguished name
424  * @param[in] nameLen1 Length of the first distinguished name
425  * @param[in] name2 Pointer to the second distinguished name
426  * @param[in] nameLen2 Length of the second distinguished name
427  * @return Comparison result
428  **/
429 
430 bool_t x509CompareName(const uint8_t *name1, size_t nameLen1,
431  const uint8_t *name2, size_t nameLen2)
432 {
433  //Compare the length of the distinguished names
434  if(nameLen1 != nameLen2)
435  return FALSE;
436 
437  //Compare the contents of the distinguished names
438  if(osMemcmp(name1, name2, nameLen1))
439  return FALSE;
440 
441  //The distinguished names match
442  return TRUE;
443 }
444 
445 
446 /**
447  * @brief Check whether the subject name matches the specified FQDN
448  * @param[in] subjectName Subject name
449  * @param[in] subjectNameLen Length of the subject name
450  * @param[in] fqdn NULL-terminated string that contains the fully-qualified domain name
451  * @return TRUE if the subject name matches the specified FQDN, else FALSE
452  **/
453 
454 bool_t x509CompareSubjectName(const char_t *subjectName, size_t subjectNameLen,
455  const char_t *fqdn)
456 {
457  size_t i;
458  size_t j;
459  size_t fqdnLen;
460 
461  //Retrieve the length of the FQDN
462  fqdnLen = osStrlen(fqdn);
463 
464  //Initialize variables
465  i = 0;
466  j = 0;
467 
468  //Parse the subject name
469  while(i < subjectNameLen && j < fqdnLen)
470  {
471  //Wildcard name found?
472  if(subjectName[i] == '*')
473  {
474  //The implementation should not attempt to match a presented
475  //identifier in which the wildcard character comprises a label other
476  //than the left-most label (refer to RFC 6125, section 6.4.3)
477  if(i != 0)
478  {
479  break;
480  }
481 
482  //The implementation should not compare against anything but the
483  //left-most label of the reference identifier
484  if(fqdn[j] == '.')
485  {
486  i++;
487  }
488  else
489  {
490  j++;
491  }
492  }
493  else
494  {
495  //Perform case insensitive character comparison
496  if(osTolower(subjectName[i]) != fqdn[j])
497  {
498  break;
499  }
500 
501  //Compare next characters
502  i++;
503  j++;
504  }
505  }
506 
507  //Check whether the subject name matches the specified FQDN
508  if(i == subjectNameLen && j == fqdnLen)
509  {
510  return TRUE;
511  }
512  else
513  {
514  return FALSE;
515  }
516 }
517 
518 
519 /**
520  * @brief Compare a subject name against the specified subtree
521  * @param[in] subjectName NULL-terminated string that contains the subject name
522  * @param[in] subtree Pointer to the subtree
523  * @param[in] subtreeLen Length of the subtree
524  * @return Comparison result
525  **/
526 
527 bool_t x509CompareSubtree(const char_t *subjectName, const char_t *subtree,
528  size_t subtreeLen)
529 {
530  int_t i;
531  int_t j;
532 
533  //Point to the last character of the subtree
534  i = subtreeLen - 1;
535  //Point to the last character of the subject name
536  j = osStrlen(subjectName) - 1;
537 
538  //Parse the subtree
539  while(i >= 0 && j >= 0)
540  {
541  //Perform case insensitive character comparison
542  if(osTolower(subtree[i]) != subjectName[j])
543  {
544  break;
545  }
546 
547  //The constraint may specify a host or a domain
548  if(subtree[i] == '.' && i == 0)
549  {
550  //When the constraint begins with a period, it may be expanded with
551  //one or more labels (refer to RFC 5280, section 4.2.1.10)
552  i = -1;
553  j = -1;
554  }
555  else
556  {
557  //Compare previous characters
558  i--;
559  j--;
560  }
561  }
562 
563  //Check whether the subject name matches the specified subtree
564  if(i < 0 && j < 0)
565  {
566  return TRUE;
567  }
568  else
569  {
570  return FALSE;
571  }
572 }
573 
574 
575 /**
576  * @brief Check whether the IP address matches the specified string
577  * @param[in] ipAddr Binary representation of the IP address
578  * @param[in] ipAddrLen Length of the IP address, in bytes
579  * @param[in] str NULL-terminated string representing an IP address
580  * @return TRUE if the IP address matches the specified string, else FALSE
581  **/
582 
583 bool_t x509CompareIpAddr(const uint8_t *ipAddr, size_t ipAddrLen,
584  const char_t *str)
585 {
586  bool_t res;
587  error_t error;
588  uint8_t buffer[16];
589 
590  //Initialize flag
591  res = FALSE;
592 
593  //Check the length of the IP address
594  if(ipAddrLen == 4)
595  {
596  //Convert the dot-decimal string to a binary IPv4 address
597  error = x509ParseIpv4Addr(str, buffer);
598 
599  //Valid IPv4 address?
600  if(!error)
601  {
602  //Compare addresses
603  if(osMemcmp(ipAddr, buffer, 4) == 0)
604  {
605  res = TRUE;
606  }
607  }
608  }
609  else if(ipAddrLen == 16)
610  {
611  //Convert the string representation to a binary IPv6 address
612  error = x509ParseIpv6Addr(str, buffer);
613 
614  //Valid IPv6 address?
615  if(!error)
616  {
617  //Compare addresses
618  if(osMemcmp(ipAddr, buffer, 16) == 0)
619  {
620  res = TRUE;
621  }
622  }
623  }
624  else
625  {
626  //Invalid IP address
627  }
628 
629  //Return TRUE if the IP address matches the specified string
630  return res;
631 }
632 
633 
634 /**
635  * @brief Convert a dot-decimal string to a binary IPv4 address
636  * @param[in] str NULL-terminated string representing the IPv4 address
637  * @param[out] ipAddr Binary representation of the IPv4 address
638  * @return Error code
639  **/
640 
641 error_t x509ParseIpv4Addr(const char_t *str, uint8_t *ipAddr)
642 {
643  error_t error;
644  int_t i = 0;
645  int_t value = -1;
646 
647  //Parse input string
648  while(1)
649  {
650  //Decimal digit found?
651  if(osIsdigit(*str))
652  {
653  //First digit to be decoded?
654  if(value < 0)
655  value = 0;
656 
657  //Update the value of the current byte
658  value = (value * 10) + (*str - '0');
659 
660  //The resulting value shall be in range 0 to 255
661  if(value > 255)
662  {
663  //The conversion failed
664  error = ERROR_INVALID_SYNTAX;
665  break;
666  }
667  }
668  //Dot separator found?
669  else if(*str == '.' && i < 4)
670  {
671  //Each dot must be preceded by a valid number
672  if(value < 0)
673  {
674  //The conversion failed
675  error = ERROR_INVALID_SYNTAX;
676  break;
677  }
678 
679  //Save the current byte
680  ipAddr[i++] = value;
681  //Prepare to decode the next byte
682  value = -1;
683  }
684  //End of string detected?
685  else if(*str == '\0' && i == 3)
686  {
687  //The NULL character must be preceded by a valid number
688  if(value < 0)
689  {
690  //The conversion failed
691  error = ERROR_INVALID_SYNTAX;
692  }
693  else
694  {
695  //Save the last byte of the IPv4 address
696  ipAddr[i] = value;
697  //The conversion succeeded
698  error = NO_ERROR;
699  }
700 
701  //We are done
702  break;
703  }
704  //Invalid character...
705  else
706  {
707  //The conversion failed
708  error = ERROR_INVALID_SYNTAX;
709  break;
710  }
711 
712  //Point to the next character
713  str++;
714  }
715 
716  //Return status code
717  return error;
718 }
719 
720 
721 /**
722  * @brief Convert a string representation of an IPv6 address to a binary IPv6 address
723  * @param[in] str NULL-terminated string representing the IPv6 address
724  * @param[out] ipAddr Binary representation of the IPv6 address
725  * @return Error code
726  **/
727 
728 error_t x509ParseIpv6Addr(const char_t *str, uint8_t *ipAddr)
729 {
730  error_t error;
731  int_t i = 0;
732  int_t j = -1;
733  int_t k = 0;
734  int32_t value = -1;
735 
736  //Parse input string
737  while(1)
738  {
739  //Hexadecimal digit found?
740  if(isxdigit((uint8_t) *str))
741  {
742  //First digit to be decoded?
743  if(value < 0)
744  {
745  value = 0;
746  }
747 
748  //Update the value of the current 16-bit word
749  if(osIsdigit(*str))
750  {
751  value = (value * 16) + (*str - '0');
752  }
753  else if(osIsupper(*str))
754  {
755  value = (value * 16) + (*str - 'A' + 10);
756  }
757  else
758  {
759  value = (value * 16) + (*str - 'a' + 10);
760  }
761 
762  //Check resulting value
763  if(value > 0xFFFF)
764  {
765  //The conversion failed
766  error = ERROR_INVALID_SYNTAX;
767  break;
768  }
769  }
770  //"::" symbol found?
771  else if(!osStrncmp(str, "::", 2))
772  {
773  //The "::" can only appear once in an IPv6 address
774  if(j >= 0)
775  {
776  //The conversion failed
777  error = ERROR_INVALID_SYNTAX;
778  break;
779  }
780 
781  //The "::" symbol is preceded by a number?
782  if(value >= 0)
783  {
784  //Save the current 16-bit word
785  STORE16BE(value, ipAddr + 2 * i);
786  i++;
787 
788  //Prepare to decode the next 16-bit word
789  value = -1;
790  }
791 
792  //Save the position of the "::" symbol
793  j = i;
794  //Point to the next character
795  str++;
796  }
797  //":" symbol found?
798  else if(*str == ':' && i < 8)
799  {
800  //Each ":" must be preceded by a valid number
801  if(value < 0)
802  {
803  //The conversion failed
804  error = ERROR_INVALID_SYNTAX;
805  break;
806  }
807 
808  //Save the current 16-bit word
809  STORE16BE(value, ipAddr + 2 * i);
810  i++;
811 
812  //Prepare to decode the next 16-bit word
813  value = -1;
814  }
815  //End of string detected?
816  else if(*str == '\0' && i == 7 && j < 0)
817  {
818  //The NULL character must be preceded by a valid number
819  if(value < 0)
820  {
821  //The conversion failed
822  error = ERROR_INVALID_SYNTAX;
823  }
824  else
825  {
826  //Save the last 16-bit word of the IPv6 address
827  STORE16BE(value, ipAddr + 2 * i);
828  //The conversion succeeded
829  error = NO_ERROR;
830  }
831 
832  //We are done
833  break;
834  }
835  else if(*str == '\0' && i < 7 && j >= 0)
836  {
837  //Save the last 16-bit word of the IPv6 address
838  if(value >= 0)
839  {
840  STORE16BE(value, ipAddr + 2 * i);
841  i++;
842  }
843 
844  //Move the part of the address that follows the "::" symbol
845  for(k = 0; k < (i - j); k++)
846  {
847  value = LOAD16BE(ipAddr + 2 * (i - 1 - k));
848  STORE16BE(value, ipAddr + 2 * (7 - k));
849  }
850 
851  //A sequence of zeroes can now be written in place of "::"
852  for(k = 0; k < (8 - i); k++)
853  {
854  STORE16BE(0, ipAddr + 2 * (j + k));
855  }
856 
857  //The conversion succeeded
858  error = NO_ERROR;
859  break;
860  }
861  //Invalid character...
862  else
863  {
864  //The conversion failed
865  error = ERROR_INVALID_SYNTAX;
866  break;
867  }
868 
869  //Point to the next character
870  str++;
871  }
872 
873  //Return status code
874  return error;
875 }
876 
877 #endif
signed int int_t
Definition: compiler_port.h:49
unsigned int uint_t
Definition: compiler_port.h:50
char char_t
Definition: compiler_port.h:48
int bool_t
Definition: compiler_port.h:53
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
#define LOAD16BE(p)
Definition: cpu_endian.h:186
General definitions for cryptographic algorithms.
__weak_func time_t getCurrentUnixTime(void)
Get current time.
Definition: date_time.c:180
int_t compareDateTime(const DateTime *date1, const DateTime *date2)
Compare dates.
Definition: date_time.c:304
void convertUnixTimeToDate(time_t t, DateTime *date)
Convert Unix timestamp to date.
Definition: date_time.c:198
Debugging facilities.
uint8_t n
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
@ ERROR_CERTIFICATE_EXPIRED
Definition: error.h:237
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_BAD_CERTIFICATE
Definition: error.h:234
@ ERROR_INVALID_NAME
Definition: error.h:97
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
uint8_t data[]
Definition: ethernet.h:222
Ipv4Addr ipAddr
Definition: ipcp.h:105
uint8_t m
Definition: ndp.h:304
#define osTolower(c)
Definition: os_port.h:261
#define osMemcmp(p1, p2, length)
Definition: os_port.h:153
#define osStrlen(s)
Definition: os_port.h:165
#define osIsdigit(c)
Definition: os_port.h:279
#define osStrncmp(s1, s2, length)
Definition: os_port.h:177
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
#define osIsupper(c)
Definition: os_port.h:273
const uint8_t res[]
char_t name[]
Date and time representation.
Definition: date_time.h:47
X.509 certificate.
Definition: x509_common.h:1064
X509OctetString signatureValue
Definition: x509_common.h:1067
X509SignAlgoId signatureAlgo
Definition: x509_common.h:1066
X509TbsCertificate tbsCert
Definition: x509_common.h:1065
X.509 certificate extensions.
Definition: x509_common.h:996
General name.
Definition: x509_common.h:852
X509GeneralNameType type
Definition: x509_common.h:853
const char_t * value
Definition: x509_common.h:854
Issuer or subject name.
Definition: x509_common.h:668
X509OctetString raw
Definition: x509_common.h:669
X509String commonName
Definition: x509_common.h:670
const uint8_t * value
Definition: x509_common.h:647
const char_t * value
Definition: x509_common.h:636
size_t length
Definition: x509_common.h:637
X509Version version
Definition: x509_common.h:1048
X509Extensions extensions
Definition: x509_common.h:1055
X509OctetString raw
Definition: x509_common.h:1047
X509Validity validity
Definition: x509_common.h:1052
X509SubjectPublicKeyInfo subjectPublicKeyInfo
Definition: x509_common.h:1054
Validity.
Definition: x509_common.h:708
DateTime notAfter
Definition: x509_common.h:710
DateTime notBefore
Definition: x509_common.h:709
uint8_t length
Definition: tcp.h:368
uint8_t value[]
Definition: tcp.h:369
uint8_t extensions[]
Definition: tls13_misc.h:300
X.509 extension parsing.
error_t x509ParseGeneralSubtree(const uint8_t *data, size_t length, size_t *totalLength, X509GeneralName *generalName)
Parse GeneralSubtree field.
error_t x509ParseName(const uint8_t *data, size_t length, size_t *totalLength, X509Name *name)
Parse Name structure.
error_t x509ParseGeneralName(const uint8_t *data, size_t length, size_t *totalLength, X509GeneralName *generalName)
Parse GeneralName field.
X.509 certificate parsing.
error_t x509CheckNameConstraints(const char_t *subjectName, const X509CertInfo *certInfo)
Check name constraints.
error_t x509ParseIpv6Addr(const char_t *str, uint8_t *ipAddr)
Convert a string representation of an IPv6 address to a binary IPv6 address.
bool_t x509CompareSubtree(const char_t *subjectName, const char_t *subtree, size_t subtreeLen)
Compare a subject name against the specified subtree.
error_t x509ValidateCertificate(const X509CertInfo *certInfo, const X509CertInfo *issuerCertInfo, uint_t pathLen)
X.509 certificate validation.
bool_t x509CompareIpAddr(const uint8_t *ipAddr, size_t ipAddrLen, const char_t *str)
Check whether the IP address matches the specified string.
error_t x509ParseIpv4Addr(const char_t *str, uint8_t *ipAddr)
Convert a dot-decimal string to a binary IPv4 address.
bool_t x509CompareSubjectName(const char_t *subjectName, size_t subjectNameLen, const char_t *fqdn)
Check whether the subject name matches the specified FQDN.
bool_t x509CompareName(const uint8_t *name1, size_t nameLen1, const uint8_t *name2, size_t nameLen2)
Compare distinguished names.
error_t x509CheckSubjectName(const X509CertInfo *certInfo, const char_t *fqdn)
Check whether the certificate matches the specified FQDN.
X.509 certificate validation.
@ X509_KEY_USAGE_KEY_CERT_SIGN
Definition: x509_common.h:476
@ X509_VERSION_3
Definition: x509_common.h:461
@ X509_GENERAL_NAME_TYPE_DNS
Definition: x509_common.h:514
@ X509_GENERAL_NAME_TYPE_IP_ADDRESS
Definition: x509_common.h:519
@ X509_GENERAL_NAME_TYPE_DIRECTORY
Definition: x509_common.h:516
error_t x509VerifySignature(const X509OctetString *tbsData, const X509SignAlgoId *signAlgoId, const X509SubjectPublicKeyInfo *publicKeyInfo, const X509OctetString *signature)
Certificate signature verification.
RSA/DSA/ECDSA/EdDSA signature verification.