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-2025 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.5.2
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 status 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 Check whether the subject name matches the specified FQDN
423  * @param[in] subjectName Subject name
424  * @param[in] subjectNameLen Length of the subject name
425  * @param[in] fqdn NULL-terminated string that contains the fully-qualified domain name
426  * @return TRUE if the subject name matches the specified FQDN, else FALSE
427  **/
428 
429 bool_t x509CompareSubjectName(const char_t *subjectName, size_t subjectNameLen,
430  const char_t *fqdn)
431 {
432  size_t i;
433  size_t j;
434  size_t fqdnLen;
435 
436  //Retrieve the length of the FQDN
437  fqdnLen = osStrlen(fqdn);
438 
439  //Initialize variables
440  i = 0;
441  j = 0;
442 
443  //Parse the subject name
444  while(i < subjectNameLen && j < fqdnLen)
445  {
446  //Wildcard name found?
447  if(subjectName[i] == '*')
448  {
449  //The implementation should not attempt to match a presented
450  //identifier in which the wildcard character comprises a label other
451  //than the left-most label (refer to RFC 6125, section 6.4.3)
452  if(i != 0)
453  {
454  break;
455  }
456 
457  //The implementation should not compare against anything but the
458  //left-most label of the reference identifier
459  if(fqdn[j] == '.')
460  {
461  i++;
462  }
463  else
464  {
465  j++;
466  }
467  }
468  else
469  {
470  //Perform case insensitive character comparison
471  if(osTolower(subjectName[i]) != fqdn[j])
472  {
473  break;
474  }
475 
476  //Compare next characters
477  i++;
478  j++;
479  }
480  }
481 
482  //Check whether the subject name matches the specified FQDN
483  if(i == subjectNameLen && j == fqdnLen)
484  {
485  return TRUE;
486  }
487  else
488  {
489  return FALSE;
490  }
491 }
492 
493 
494 /**
495  * @brief Compare a subject name against the specified subtree
496  * @param[in] subjectName NULL-terminated string that contains the subject name
497  * @param[in] subtree Pointer to the subtree
498  * @param[in] subtreeLen Length of the subtree
499  * @return Comparison result
500  **/
501 
502 bool_t x509CompareSubtree(const char_t *subjectName, const char_t *subtree,
503  size_t subtreeLen)
504 {
505  int_t i;
506  int_t j;
507 
508  //Point to the last character of the subtree
509  i = subtreeLen - 1;
510  //Point to the last character of the subject name
511  j = osStrlen(subjectName) - 1;
512 
513  //Parse the subtree
514  while(i >= 0 && j >= 0)
515  {
516  //Perform case insensitive character comparison
517  if(osTolower(subtree[i]) != subjectName[j])
518  {
519  break;
520  }
521 
522  //The constraint may specify a host or a domain
523  if(subtree[i] == '.' && i == 0)
524  {
525  //When the constraint begins with a period, it may be expanded with
526  //one or more labels (refer to RFC 5280, section 4.2.1.10)
527  i = -1;
528  j = -1;
529  }
530  else
531  {
532  //Compare previous characters
533  i--;
534  j--;
535  }
536  }
537 
538  //Check whether the subject name matches the specified subtree
539  if(i < 0 && j < 0)
540  {
541  return TRUE;
542  }
543  else
544  {
545  return FALSE;
546  }
547 }
548 
549 
550 /**
551  * @brief Check whether the IP address matches the specified string
552  * @param[in] ipAddr Binary representation of the IP address
553  * @param[in] ipAddrLen Length of the IP address, in bytes
554  * @param[in] str NULL-terminated string representing an IP address
555  * @return TRUE if the IP address matches the specified string, else FALSE
556  **/
557 
558 bool_t x509CompareIpAddr(const uint8_t *ipAddr, size_t ipAddrLen,
559  const char_t *str)
560 {
561  bool_t res;
562  error_t error;
563  uint8_t buffer[16];
564 
565  //Initialize flag
566  res = FALSE;
567 
568  //Check the length of the IP address
569  if(ipAddrLen == 4)
570  {
571  //Convert the dot-decimal string to a binary IPv4 address
572  error = x509ParseIpv4Addr(str, buffer);
573 
574  //Valid IPv4 address?
575  if(!error)
576  {
577  //Compare addresses
578  if(osMemcmp(ipAddr, buffer, 4) == 0)
579  {
580  res = TRUE;
581  }
582  }
583  }
584  else if(ipAddrLen == 16)
585  {
586  //Convert the string representation to a binary IPv6 address
587  error = x509ParseIpv6Addr(str, buffer);
588 
589  //Valid IPv6 address?
590  if(!error)
591  {
592  //Compare addresses
593  if(osMemcmp(ipAddr, buffer, 16) == 0)
594  {
595  res = TRUE;
596  }
597  }
598  }
599  else
600  {
601  //Invalid IP address
602  }
603 
604  //Return TRUE if the IP address matches the specified string
605  return res;
606 }
607 
608 
609 /**
610  * @brief Convert a dot-decimal string to a binary IPv4 address
611  * @param[in] str NULL-terminated string representing the IPv4 address
612  * @param[out] ipAddr Binary representation of the IPv4 address
613  * @return Error code
614  **/
615 
616 error_t x509ParseIpv4Addr(const char_t *str, uint8_t *ipAddr)
617 {
618  error_t error;
619  int_t i = 0;
620  int_t value = -1;
621 
622  //Parse input string
623  while(1)
624  {
625  //Decimal digit found?
626  if(osIsdigit(*str))
627  {
628  //First digit to be decoded?
629  if(value < 0)
630  value = 0;
631 
632  //Update the value of the current byte
633  value = (value * 10) + (*str - '0');
634 
635  //The resulting value shall be in range 0 to 255
636  if(value > 255)
637  {
638  //The conversion failed
639  error = ERROR_INVALID_SYNTAX;
640  break;
641  }
642  }
643  //Dot separator found?
644  else if(*str == '.' && i < 4)
645  {
646  //Each dot must be preceded by a valid number
647  if(value < 0)
648  {
649  //The conversion failed
650  error = ERROR_INVALID_SYNTAX;
651  break;
652  }
653 
654  //Save the current byte
655  ipAddr[i++] = value;
656  //Prepare to decode the next byte
657  value = -1;
658  }
659  //End of string detected?
660  else if(*str == '\0' && i == 3)
661  {
662  //The NULL character must be preceded by a valid number
663  if(value < 0)
664  {
665  //The conversion failed
666  error = ERROR_INVALID_SYNTAX;
667  }
668  else
669  {
670  //Save the last byte of the IPv4 address
671  ipAddr[i] = value;
672  //The conversion succeeded
673  error = NO_ERROR;
674  }
675 
676  //We are done
677  break;
678  }
679  //Invalid character...
680  else
681  {
682  //The conversion failed
683  error = ERROR_INVALID_SYNTAX;
684  break;
685  }
686 
687  //Point to the next character
688  str++;
689  }
690 
691  //Return status code
692  return error;
693 }
694 
695 
696 /**
697  * @brief Convert a string representation of an IPv6 address to a binary IPv6 address
698  * @param[in] str NULL-terminated string representing the IPv6 address
699  * @param[out] ipAddr Binary representation of the IPv6 address
700  * @return Error code
701  **/
702 
703 error_t x509ParseIpv6Addr(const char_t *str, uint8_t *ipAddr)
704 {
705  error_t error;
706  int_t i = 0;
707  int_t j = -1;
708  int_t k = 0;
709  int32_t value = -1;
710 
711  //Parse input string
712  while(1)
713  {
714  //Hexadecimal digit found?
715  if(isxdigit((uint8_t) *str))
716  {
717  //First digit to be decoded?
718  if(value < 0)
719  {
720  value = 0;
721  }
722 
723  //Update the value of the current 16-bit word
724  if(osIsdigit(*str))
725  {
726  value = (value * 16) + (*str - '0');
727  }
728  else if(osIsupper(*str))
729  {
730  value = (value * 16) + (*str - 'A' + 10);
731  }
732  else
733  {
734  value = (value * 16) + (*str - 'a' + 10);
735  }
736 
737  //Check resulting value
738  if(value > 0xFFFF)
739  {
740  //The conversion failed
741  error = ERROR_INVALID_SYNTAX;
742  break;
743  }
744  }
745  //"::" symbol found?
746  else if(osStrncmp(str, "::", 2) == 0)
747  {
748  //The "::" can only appear once in an IPv6 address
749  if(j >= 0)
750  {
751  //The conversion failed
752  error = ERROR_INVALID_SYNTAX;
753  break;
754  }
755 
756  //The "::" symbol is preceded by a number?
757  if(value >= 0)
758  {
759  //Save the current 16-bit word
760  STORE16BE(value, ipAddr + 2 * i);
761  i++;
762 
763  //Prepare to decode the next 16-bit word
764  value = -1;
765  }
766 
767  //Save the position of the "::" symbol
768  j = i;
769  //Point to the next character
770  str++;
771  }
772  //":" symbol found?
773  else if(*str == ':' && i < 8)
774  {
775  //Each ":" must be preceded by a valid number
776  if(value < 0)
777  {
778  //The conversion failed
779  error = ERROR_INVALID_SYNTAX;
780  break;
781  }
782 
783  //Save the current 16-bit word
784  STORE16BE(value, ipAddr + 2 * i);
785  i++;
786 
787  //Prepare to decode the next 16-bit word
788  value = -1;
789  }
790  //End of string detected?
791  else if(*str == '\0' && i == 7 && j < 0)
792  {
793  //The NULL character must be preceded by a valid number
794  if(value < 0)
795  {
796  //The conversion failed
797  error = ERROR_INVALID_SYNTAX;
798  }
799  else
800  {
801  //Save the last 16-bit word of the IPv6 address
802  STORE16BE(value, ipAddr + 2 * i);
803  //The conversion succeeded
804  error = NO_ERROR;
805  }
806 
807  //We are done
808  break;
809  }
810  else if(*str == '\0' && i < 7 && j >= 0)
811  {
812  //Save the last 16-bit word of the IPv6 address
813  if(value >= 0)
814  {
815  STORE16BE(value, ipAddr + 2 * i);
816  i++;
817  }
818 
819  //Move the part of the address that follows the "::" symbol
820  for(k = 0; k < (i - j); k++)
821  {
822  value = LOAD16BE(ipAddr + 2 * (i - 1 - k));
823  STORE16BE(value, ipAddr + 2 * (7 - k));
824  }
825 
826  //A sequence of zeroes can now be written in place of "::"
827  for(k = 0; k < (8 - i); k++)
828  {
829  STORE16BE(0, ipAddr + 2 * (j + k));
830  }
831 
832  //The conversion succeeded
833  error = NO_ERROR;
834  break;
835  }
836  //Invalid character...
837  else
838  {
839  //The conversion failed
840  error = ERROR_INVALID_SYNTAX;
841  break;
842  }
843 
844  //Point to the next character
845  str++;
846  }
847 
848  //Return status code
849  return error;
850 }
851 
852 #endif
X509Validity validity
Definition: x509_common.h:1107
X.509 certificate parsing.
uint8_t extensions[]
Definition: ntp_common.h:207
X509GeneralNameType type
Definition: x509_common.h:908
int bool_t
Definition: compiler_port.h:61
X509SignAlgoId signatureAlgo
Definition: x509_common.h:1122
error_t x509ValidateCertificate(const X509CertInfo *certInfo, const X509CertInfo *issuerCertInfo, uint_t pathLen)
X.509 certificate validation.
error_t x509ParseGeneralSubtree(const uint8_t *data, size_t length, size_t *totalLength, X509GeneralName *generalName)
Parse GeneralSubtree field.
X509TbsCertificate tbsCert
Definition: x509_common.h:1121
signed int int_t
Definition: compiler_port.h:56
bool_t x509CompareIpAddr(const uint8_t *ipAddr, size_t ipAddrLen, const char_t *str)
Check whether the IP address matches the specified string.
X509Extensions extensions
Definition: x509_common.h:1110
Validity.
Definition: x509_common.h:763
X509OctetString raw
Definition: x509_common.h:1102
#define TRUE
Definition: os_port.h:50
uint8_t data[]
Definition: ethernet.h:224
#define osMemcmp(p1, p2, length)
Definition: os_port.h:156
void convertUnixTimeToDate(time_t t, DateTime *date)
Convert Unix timestamp to date.
Definition: date_time.c:204
char_t name[]
error_t x509ParseIpv6Addr(const char_t *str, uint8_t *ipAddr)
Convert a string representation of an IPv6 address to a binary IPv6 address.
#define osStrlen(s)
Definition: os_port.h:168
X.509 extension parsing.
const uint8_t res[]
size_t length
Definition: x509_common.h:692
X509String commonName
Definition: x509_common.h:725
error_t x509VerifySignature(const X509OctetString *tbsData, const X509SignAlgoId *signAlgoId, const X509SubjectPublicKeyInfo *publicKeyInfo, const X509OctetString *signature)
Signature verification.
@ X509_GENERAL_NAME_TYPE_DIRECTORY
Definition: x509_common.h:571
@ ERROR_INVALID_NAME
Definition: error.h:97
DateTime notAfter
Definition: x509_common.h:765
#define FALSE
Definition: os_port.h:46
General name.
Definition: x509_common.h:907
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
@ X509_GENERAL_NAME_TYPE_DNS
Definition: x509_common.h:569
X.509 certificate.
Definition: x509_common.h:1119
error_t
Error codes.
Definition: error.h:43
error_t x509ParseName(const uint8_t *data, size_t length, size_t *totalLength, X509Name *name)
Parse Name structure.
X509Version version
Definition: x509_common.h:1103
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
@ X509_VERSION_3
Definition: x509_common.h:516
General definitions for cryptographic algorithms.
@ ERROR_BAD_CERTIFICATE
Definition: error.h:236
X509OctetString signatureValue
Definition: x509_common.h:1123
Date and time representation.
Definition: date_time.h:47
error_t x509ParseIpv4Addr(const char_t *str, uint8_t *ipAddr)
Convert a dot-decimal string to a binary IPv4 address.
#define osIsdigit(c)
Definition: os_port.h:288
uint8_t length
Definition: tcp.h:375
error_t x509CheckNameConstraints(const char_t *subjectName, const X509CertInfo *certInfo)
Check name constraints.
const char_t * value
Definition: x509_common.h:909
char char_t
Definition: compiler_port.h:55
DateTime notBefore
Definition: x509_common.h:764
const char_t * value
Definition: x509_common.h:691
RSA/DSA/ECDSA/EdDSA signature verification.
uint8_t m
Definition: ndp.h:304
uint8_t n
Issuer or subject name.
Definition: x509_common.h:723
@ ERROR_CERTIFICATE_EXPIRED
Definition: error.h:239
uint8_t value[]
Definition: tcp.h:376
X.509 certificate validation.
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
#define osTolower(c)
Definition: os_port.h:270
X.509 certificate extensions.
Definition: x509_common.h:1051
#define osStrncmp(s1, s2, length)
Definition: os_port.h:180
Ipv4Addr ipAddr
Definition: ipcp.h:105
error_t x509CheckSubjectName(const X509CertInfo *certInfo, const char_t *fqdn)
Check whether the certificate matches the specified FQDN.
const uint8_t * value
Definition: x509_common.h:702
bool_t x509CompareName(const uint8_t *name1, size_t nameLen1, const uint8_t *name2, size_t nameLen2)
Compare distinguished names.
Definition: x509_common.c:184
bool_t x509CompareSubjectName(const char_t *subjectName, size_t subjectNameLen, const char_t *fqdn)
Check whether the subject name matches the specified FQDN.
unsigned int uint_t
Definition: compiler_port.h:57
#define LOAD16BE(p)
Definition: cpu_endian.h:186
@ X509_GENERAL_NAME_TYPE_IP_ADDRESS
Definition: x509_common.h:574
error_t x509ParseGeneralName(const uint8_t *data, size_t length, size_t *totalLength, X509GeneralName *generalName)
Parse GeneralName field.
X509SubjectPublicKeyInfo subjectPublicKeyInfo
Definition: x509_common.h:1109
#define osIsupper(c)
Definition: os_port.h:282
__weak_func time_t getCurrentUnixTime(void)
Get current time.
Definition: date_time.c:186
X509OctetString raw
Definition: x509_common.h:724
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
@ X509_KEY_USAGE_KEY_CERT_SIGN
Definition: x509_common.h:531
bool_t x509CompareSubtree(const char_t *subjectName, const char_t *subtree, size_t subtreeLen)
Compare a subject name against the specified subtree.
int_t compareDateTime(const DateTime *date1, const DateTime *date2)
Compare dates.
Definition: date_time.c:310