x509_cert_ext_parse.c
Go to the documentation of this file.
1 /**
2  * @file x509_cert_ext_parse.c
3  * @brief X.509 extension parsing
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"
38 #include "encoding/asn1.h"
39 #include "encoding/oid.h"
40 #include "debug.h"
41 
42 //Check crypto library configuration
43 #if (X509_SUPPORT == ENABLED)
44 
45 
46 /**
47  * @brief Parse X.509 certificate extensions
48  * @param[in] data Pointer to the ASN.1 structure to parse
49  * @param[in] length Length of the ASN.1 structure
50  * @param[out] totalLength Number of bytes that have been parsed
51  * @param[out] extensions Information resulting from the parsing process
52  * @param[in] ignoreUnknown Ignore unknown extensions
53  * @return Error code
54  **/
55 
56 error_t x509ParseCertExtensions(const uint8_t *data, size_t length,
57  size_t *totalLength, X509Extensions *extensions, bool_t ignoreUnknown)
58 {
59  error_t error;
60  size_t n;
61  Asn1Tag tag;
62  X509Extension extension;
63 
64  //No more data to process?
65  if(length == 0)
66  {
67  //The Extensions field is optional
68  *totalLength = 0;
69  //Exit immediately
70  return NO_ERROR;
71  }
72 
73  //Explicit tagging is used to encode the Extensions field
74  error = asn1ReadTag(data, length, &tag);
75  //Failed to decode ASN.1 tag?
76  if(error)
77  return error;
78 
79  //Enforce encoding, class and type
81  //Invalid tag?
82  if(error)
83  {
84  //The Extensions field is optional
85  *totalLength = 0;
86  //Exit immediately
87  return NO_ERROR;
88  }
89 
90  //Save the total length of the field
91  *totalLength = tag.totalLength;
92 
93  //Debug message
94  TRACE_DEBUG(" Parsing Extensions...\r\n");
95 
96  //This field is a sequence of one or more certificate extensions
97  error = asn1ReadSequence(tag.value, tag.length, &tag);
98  //Failed to decode ASN.1 tag?
99  if(error)
100  return error;
101 
102  //Raw contents of the ASN.1 sequence
103  extensions->raw.value = tag.value;
104  extensions->raw.length = tag.length;
105 
106  //Point to the first item of the sequence
107  data = tag.value;
108  length = tag.length;
109 
110  //Loop through the extensions
111  while(length > 0)
112  {
113  //Each extension includes an OID and a value
114  error = x509ParseExtension(data, length, &n, &extension);
115  //Any error to report?
116  if(error)
117  return error;
118 
119  //Jump to the next extension
120  data += n;
121  length -= n;
122 
123  //Test if the current extension is a duplicate
124  error = x509CheckDuplicateExtension(extension.oid.value,
125  extension.oid.length, data, length);
126  //Duplicate extension found?
127  if(error)
128  return error;
129 
130  //Check extension identifier
131  if(!oidComp(extension.oid.value, extension.oid.length,
133  {
134  //Parse BasicConstraints extension
135  error = x509ParseBasicConstraints(extension.critical, extension.data.value,
136  extension.data.length, &extensions->basicConstraints);
137  }
138  else if(!oidComp(extension.oid.value, extension.oid.length,
140  {
141  //Parse NameConstraints extension
142  error = x509ParseNameConstraints(extension.critical, extension.data.value,
143  extension.data.length, &extensions->nameConstraints);
144  }
145  else if(!oidComp(extension.oid.value, extension.oid.length,
147  {
148  //Parse KeyUsage extension
149  error = x509ParseKeyUsage(extension.critical, extension.data.value,
150  extension.data.length, &extensions->keyUsage);
151  }
152  else if(!oidComp(extension.oid.value, extension.oid.length,
154  {
155  //Parse ExtendedKeyUsage extension
156  error = x509ParseExtendedKeyUsage(extension.critical, extension.data.value,
157  extension.data.length, &extensions->extKeyUsage);
158  }
159  else if(!oidComp(extension.oid.value, extension.oid.length,
161  {
162  //Parse SubjectAltName extension
163  error = x509ParseSubjectAltName(extension.critical, extension.data.value,
164  extension.data.length, &extensions->subjectAltName);
165  }
166  else if(!oidComp(extension.oid.value, extension.oid.length,
168  {
169  //Parse SubjectKeyIdentifier extension
170  error = x509ParseSubjectKeyId(extension.critical, extension.data.value,
171  extension.data.length, &extensions->subjectKeyId);
172  }
173  else if(!oidComp(extension.oid.value, extension.oid.length,
175  {
176  //Parse AuthorityKeyIdentifier extension
177  error = x509ParseAuthKeyId(extension.critical, extension.data.value,
178  extension.data.length, &extensions->authKeyId);
179  }
180  else if(!oidComp(extension.oid.value, extension.oid.length,
182  {
183  //Parse CRLDistributionPoints extension
184  error = x509ParseCrlDistrPoints(extension.critical, extension.data.value,
185  extension.data.length, &extensions->crlDistrPoints);
186  }
187  else if(!oidComp(extension.oid.value, extension.oid.length,
189  {
190  //Parse AuthorityInformationAccess extension
191  error = x509ParseAuthInfoAccess(extension.critical, extension.data.value,
192  extension.data.length, &extensions->authInfoAccess);
193  }
194  else if(!oidComp(extension.oid.value, extension.oid.length,
196  {
197  //Parse PkixOcspNoCheck extension
198  error = x509ParsePkixOcspNoCheck(extension.critical, extension.data.value,
199  extension.data.length, &extensions->pkixOcspNoCheck);
200  }
201  else if(!oidComp(extension.oid.value, extension.oid.length,
203  {
204  //Parse NetscapeCertType extension
205  error = x509ParseNsCertType(extension.critical, extension.data.value,
206  extension.data.length, &extensions->nsCertType);
207  }
208  else
209  {
210  //Parse unknown extension
211  error = x509ParseUnknownCertExtension(extension.oid.value,
212  extension.oid.length, extension.critical, extension.data.value,
213  extension.data.length, extensions);
214 
215  //Check status code
216  if(error == ERROR_UNSUPPORTED_EXTENSION)
217  {
218  //An application must reject the certificate if it encounters a
219  //critical extension it does not recognize or a critical extension
220  //that contains information that it cannot process
221  if(!extension.critical || ignoreUnknown)
222  {
223  error = NO_ERROR;
224  }
225  }
226  }
227 
228  //Any parsing error?
229  if(error)
230  return error;
231  }
232 
233  //Check whether the keyCertSign bit is asserted
234  if((extensions->keyUsage.bitmap & X509_KEY_USAGE_KEY_CERT_SIGN) != 0)
235  {
236  //If the keyCertSign bit is asserted, then the cA bit in the basic
237  //constraints extension must also be asserted (refer to RFC 5280,
238  //section 4.2.1.3)
239  if(!extensions->basicConstraints.cA)
240  return ERROR_INVALID_SYNTAX;
241  }
242 
243  //Check whether the NameConstraints extension is present
244  if(extensions->nameConstraints.permittedSubtrees.length > 0 ||
245  extensions->nameConstraints.excludedSubtrees.length > 0)
246  {
247  //The NameConstraints extension, must be used only in a CA certificate
248  //(refer to RFC 5280, section 4.2.1.10)
249  if(!extensions->basicConstraints.cA)
250  return ERROR_INVALID_SYNTAX;
251  }
252 
253  //Successful processing
254  return NO_ERROR;
255 }
256 
257 
258 /**
259  * @brief Parse X.509 certificate extension
260  * @param[in] data Pointer to the ASN.1 structure to parse
261  * @param[in] length Length of the ASN.1 structure
262  * @param[out] totalLength Number of bytes that have been parsed
263  * @param[out] extension Information resulting from the parsing process
264  * @return Error code
265  **/
266 
267 error_t x509ParseExtension(const uint8_t *data, size_t length,
268  size_t *totalLength, X509Extension *extension)
269 {
270  error_t error;
271  Asn1Tag tag;
272 
273  //The X.509 extension is encapsulated within a sequence
274  error = asn1ReadSequence(data, length, &tag);
275  //Failed to decode ASN.1 tag?
276  if(error)
277  return error;
278 
279  //Save the total length of the X.509 extension
280  *totalLength = tag.totalLength;
281 
282  //Each extension includes an OID and a value
283  data = tag.value;
284  length = tag.length;
285 
286  //Read extension OID
287  error = asn1ReadOid(data, length, &tag);
288  //Failed to decode ASN.1 tag?
289  if(error)
290  return error;
291 
292  //Save the object identifier
293  extension->oid.value = tag.value;
294  extension->oid.length = tag.length;
295 
296  //Next item
297  data += tag.totalLength;
298  length -= tag.totalLength;
299 
300  //Read the Critical flag (if present)
301  error = asn1ReadTag(data, length, &tag);
302  //Failed to decode ASN.1 tag?
303  if(error)
304  return error;
305 
306  //Enforce encoding, class and type
308 
309  //Check whether the Critical field is present
310  if(!error)
311  {
312  //Make sure the length of the boolean is valid
313  if(tag.length != 1)
314  return ERROR_INVALID_LENGTH;
315 
316  //Each extension in a certificate is designated as either critical
317  //or non-critical
318  extension->critical = tag.value[0] ? TRUE : FALSE;
319 
320  //Next item
321  data += tag.totalLength;
322  length -= tag.totalLength;
323  }
324  else
325  {
326  //The extension is considered as non-critical
327  extension->critical = FALSE;
328  }
329 
330  //The extension value is encapsulated within an octet string
331  error = asn1ReadOctetString(data, length, &tag);
332  //Failed to decode ASN.1 tag?
333  if(error)
334  return error;
335 
336  //Save the value of the extension
337  extension->data.value = tag.value;
338  extension->data.length = tag.length;
339 
340  //Successful processing
341  return NO_ERROR;
342 }
343 
344 
345 /**
346  * @brief Parse BasicConstraints extension
347  * @param[in] critical Critical extension flag
348  * @param[in] data Pointer to the ASN.1 structure to parse
349  * @param[in] length Length of the ASN.1 structure
350  * @param[out] basicConstraints Information resulting from the parsing process
351  * @return Error code
352  **/
353 
355  size_t length, X509BasicConstraints *basicConstraints)
356 {
357  error_t error;
358  int32_t value;
359  Asn1Tag tag;
360 
361  //Debug message
362  TRACE_DEBUG(" Parsing BasicConstraints...\r\n");
363 
364  //An extension can be marked as critical
365  basicConstraints->critical = critical;
366 
367  //The BasicConstraints structure shall contain a valid sequence
368  error = asn1ReadSequence(data, length, &tag);
369  //Failed to decode ASN.1 tag?
370  if(error)
371  return error;
372 
373  //Point to the first item of the sequence
374  data = tag.value;
375  length = tag.length;
376 
377  //The cA field is optional
378  if(length > 0)
379  {
380  //The cA boolean indicates whether the certified public key may be used
381  //to verify certificate signatures
382  error = asn1ReadTag(data, length, &tag);
383  //Failed to decode ASN.1 tag?
384  if(error)
385  return error;
386 
387  //Enforce encoding, class and type
389 
390  //Check status code
391  if(!error)
392  {
393  //Make sure the length of the boolean is valid
394  if(tag.length != 1)
395  return ERROR_INVALID_LENGTH;
396 
397  //Get boolean value
398  basicConstraints->cA = tag.value[0] ? TRUE : FALSE;
399 
400  //Point to the next item
401  data += tag.totalLength;
402  length -= tag.totalLength;
403  }
404  }
405 
406  //The pathLenConstraint field is optional
407  if(length > 0)
408  {
409  //Read the pathLenConstraint field
410  error = asn1ReadInt32(data, length, &tag, &value);
411  //Failed to decode ASN.1 tag?
412  if(error)
413  return error;
414 
415  //The pathLenConstraint field is meaningful only if the cA boolean is
416  //asserted (refer to RFC 5280, section 4.2.1.9)
417  if(!basicConstraints->cA)
418  return ERROR_INVALID_SYNTAX;
419 
420  //Where it appears, the pathLenConstraint field must be greater than or
421  //equal to zero (refer to RFC 5280, section 4.2.1.9)
422  if(value < 0)
423  return ERROR_INVALID_SYNTAX;
424 
425  //The pathLenConstraint field gives the maximum number of non-self-issued
426  //intermediate certificates that may follow this certificate in a valid
427  //certification path
428  basicConstraints->pathLenConstraint = value;
429  }
430 
431  //Successful processing
432  return NO_ERROR;
433 }
434 
435 
436 /**
437  * @brief Parse NameConstraints extension
438  * @param[in] critical Critical extension flag
439  * @param[in] data Pointer to the ASN.1 structure to parse
440  * @param[in] length Length of the ASN.1 structure
441  * @param[out] nameConstraints Information resulting from the parsing process
442  * @return Error code
443  **/
444 
446  size_t length, X509NameConstraints *nameConstraints)
447 {
448  error_t error;
449  Asn1Tag tag;
450 
451  //Debug message
452  TRACE_DEBUG(" Parsing NameConstraints...\r\n");
453 
454  //An extension can be marked as critical
455  nameConstraints->critical = critical;
456 
457  //Conforming CAs must mark the NameConstraints extension as critical (refer
458  //to RFC 5280, section 4.2.1.10)
459  if(!nameConstraints->critical)
460  return ERROR_INVALID_SYNTAX;
461 
462  //The NameConstraints structure shall contain a valid sequence
463  error = asn1ReadSequence(data, length, &tag);
464  //Failed to decode ASN.1 tag?
465  if(error)
466  return error;
467 
468  //Conforming CAs must not issue certificates where name constraints is an
469  //empty sequence (refer to RFC 5280, section 4.2.1.10)
470  if(tag.length == 0)
471  return ERROR_INVALID_SYNTAX;
472 
473  //Point to the first item of the sequence
474  data = tag.value;
475  length = tag.length;
476 
477  //The name constraints extension indicates a name space within which all
478  //subject names in subsequent certificates in a certification path must
479  //be located
480  while(length > 0)
481  {
482  //Parse GeneralSubtrees field
483  error = asn1ReadTag(data, length, &tag);
484  //Failed to decode ASN.1 tag?
485  if(error)
486  return error;
487 
488  //Implicit tagging shall be used to encode the GeneralSubtrees field
490  return ERROR_INVALID_CLASS;
491 
492  //The sequence cannot be empty (refer to RFC 5280, section 4.2.1.10)
493  if(tag.length == 0)
494  return ERROR_INVALID_SYNTAX;
495 
496  //Restrictions are defined in terms of permitted or excluded name subtrees
497  if(tag.objType == 0)
498  {
499  //Parse the permittedSubtrees field
500  error = x509ParseGeneralSubtrees(tag.value, tag.length);
501  //Any error to report?
502  if(error)
503  return error;
504 
505  //Raw contents of the ASN.1 sequence
506  nameConstraints->permittedSubtrees.value = tag.value;
507  nameConstraints->permittedSubtrees.length = tag.length;
508  }
509  else if(tag.objType == 1)
510  {
511  //Parse the excludedSubtrees field
512  error = x509ParseGeneralSubtrees(tag.value, tag.length);
513  //Any error to report?
514  if(error)
515  return error;
516 
517  //Raw contents of the ASN.1 sequence
518  nameConstraints->excludedSubtrees.value = tag.value;
519  nameConstraints->excludedSubtrees.length = tag.length;
520  }
521  else
522  {
523  //Report an error
524  return ERROR_INVALID_TYPE;
525  }
526 
527  //Next item
528  data += tag.totalLength;
529  length -= tag.totalLength;
530  }
531 
532  //Successful processing
533  return NO_ERROR;
534 }
535 
536 
537 /**
538  * @brief Parse PolicyConstraints extension
539  * @param[in] critical Critical extension flag
540  * @param[in] data Pointer to the ASN.1 structure to parse
541  * @param[in] length Length of the ASN.1 structure
542  * @return Error code
543  **/
544 
546  size_t length)
547 {
548  error_t error;
549  Asn1Tag tag;
550 
551  //Debug message
552  TRACE_DEBUG(" Parsing PolicyConstraints...\r\n");
553 
554  //The PolicyConstraints structure shall contain a valid sequence
555  error = asn1ReadSequence(data, length, &tag);
556  //Failed to decode ASN.1 tag?
557  if(error)
558  return error;
559 
560  //Conforming CAs must not issue certificates where policy constraints is an
561  //empty sequence (refer to RFC 5280, section 4.2.1.11)
562  if(tag.length == 0)
563  return ERROR_INVALID_SYNTAX;
564 
565  //Successful processing
566  return NO_ERROR;
567 }
568 
569 
570 /**
571  * @brief Parse PolicyMappings extension
572  * @param[in] critical Critical extension flag
573  * @param[in] data Pointer to the ASN.1 structure to parse
574  * @param[in] length Length of the ASN.1 structure
575  * @return Error code
576  **/
577 
579  size_t length)
580 {
581  error_t error;
582  Asn1Tag tag;
583 
584  //Debug message
585  TRACE_DEBUG(" Parsing PolicyMappings...\r\n");
586 
587  //The PolicyMappings structure shall contain a valid sequence
588  error = asn1ReadSequence(data, length, &tag);
589  //Failed to decode ASN.1 tag?
590  if(error)
591  return error;
592 
593  //The sequence cannot be empty (refer to RFC 5280, section 4.2.1.5)
594  if(tag.length == 0)
595  return ERROR_INVALID_SYNTAX;
596 
597  //Successful processing
598  return NO_ERROR;
599 }
600 
601 
602 /**
603  * @brief Parse InhibitAnyPolicy extension
604  * @param[in] critical Critical extension flag
605  * @param[in] data Pointer to the ASN.1 structure to parse
606  * @param[in] length Length of the ASN.1 structure
607  * @return Error code
608  **/
609 
611  size_t length)
612 {
613  //Debug message
614  TRACE_DEBUG(" Parsing InhibitAnyPolicy...\r\n");
615 
616  //Successful processing
617  return NO_ERROR;
618 }
619 
620 
621 /**
622  * @brief Parse KeyUsage extension
623  * @param[in] critical Critical extension flag
624  * @param[in] data Pointer to the ASN.1 structure to parse
625  * @param[in] length Length of the ASN.1 structure
626  * @param[out] keyUsage Information resulting from the parsing process
627  * @return Error code
628  **/
629 
631  size_t length, X509KeyUsage *keyUsage)
632 {
633  error_t error;
634  Asn1Tag tag;
635 
636  //Debug message
637  TRACE_DEBUG(" Parsing KeyUsage...\r\n");
638 
639  //An extension can be marked as critical
640  keyUsage->critical = critical;
641 
642  //The key usage extension defines the purpose of the key contained in the
643  //certificate
644  error = asn1ReadTag(data, length, &tag);
645  //Failed to decode ASN.1 tag?
646  if(error)
647  return error;
648 
649  //Enforce encoding, class and type
650  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
652  //Invalid tag?
653  if(error)
654  return error;
655 
656  //The bit string shall contain an initial octet which encodes the number
657  //of unused bits in the final subsequent octet
658  if(tag.length < 1)
659  return ERROR_INVALID_SYNTAX;
660 
661  //Sanity check
662  if(tag.value[0] >= 8)
663  return ERROR_INVALID_SYNTAX;
664 
665  //Clear bit string
666  keyUsage->bitmap = 0;
667 
668  //Read bits b0 to b7
669  if(tag.length >= 2)
670  {
671  keyUsage->bitmap |= reverseInt8(tag.value[1]);
672  }
673 
674  //Read bits b8 to b15
675  if(tag.length >= 3)
676  {
677  keyUsage->bitmap |= reverseInt8(tag.value[2]) << 8;
678  }
679 
680  //When the key usage extension appears in a certificate, at least one of
681  //the bits must be set to 1 (refer to RFC 5280, section 4.2.1.3)
682  if(keyUsage->bitmap == 0)
683  return ERROR_INVALID_SYNTAX;
684 
685  //Successful processing
686  return NO_ERROR;
687 }
688 
689 
690 /**
691  * @brief Parse ExtendedKeyUsage extension
692  * @param[in] critical Critical extension flag
693  * @param[in] data Pointer to the ASN.1 structure to parse
694  * @param[in] length Length of the ASN.1 structure
695  * @param[out] extKeyUsage Information resulting from the parsing process
696  * @return Error code
697  **/
698 
700  size_t length, X509ExtendedKeyUsage *extKeyUsage)
701 {
702  error_t error;
703  Asn1Tag tag;
704 
705  //Debug message
706  TRACE_DEBUG(" Parsing ExtendedKeyUsage...\r\n");
707 
708  //An extension can be marked as critical
709  extKeyUsage->critical = critical;
710 
711  //The ExtendedKeyUsage structure shall contain a valid sequence
712  error = asn1ReadSequence(data, length, &tag);
713  //Failed to decode ASN.1 tag?
714  if(error)
715  return error;
716 
717  //The sequence cannot be empty (refer to RFC 5280, section 4.2.1.12)
718  if(tag.length == 0)
719  return ERROR_INVALID_SYNTAX;
720 
721  //Point to the first item of the sequence
722  data = tag.value;
723  length = tag.length;
724 
725  //This extension indicates one or more purposes for which the certified
726  //public key may be used
727  while(length > 0)
728  {
729  //Read KeyPurposeId field
730  error = asn1ReadOid(data, length, &tag);
731  //Failed to decode ASN.1 tag?
732  if(error)
733  return error;
734 
735  //anyExtendedKeyUsage?
736  if(!oidComp(tag.value, tag.length,
738  {
739  //If a CA includes extended key usages to satisfy such applications,
740  //but does not wish to restrict usages of the key, the CA can include
741  //the special KeyPurposeId anyExtendedKeyUsage
742  extKeyUsage->bitmap |= X509_EXT_KEY_USAGE_ANY;
743  }
744  //id-kp-serverAuth?
745  else if(!oidComp(tag.value, tag.length,
747  {
748  //TLS WWW server authentication
749  extKeyUsage->bitmap |= X509_EXT_KEY_USAGE_SERVER_AUTH;
750  }
751  //id-kp-clientAuth?
752  else if(!oidComp(tag.value, tag.length,
754  {
755  //TLS WWW client authentication
756  extKeyUsage->bitmap |= X509_EXT_KEY_USAGE_CLIENT_AUTH;
757  }
758  //id-kp-codeSigning?
759  else if(!oidComp(tag.value, tag.length,
761  {
762  //Signing of downloadable executable code
763  extKeyUsage->bitmap |= X509_EXT_KEY_USAGE_CODE_SIGNING;
764  }
765  //id-kp-emailProtection?
766  else if(!oidComp(tag.value, tag.length,
768  {
769  //Email protection
771  }
772  //id-kp-ipsecEndSystem ?
773  else if(!oidComp(tag.value, tag.length,
775  {
776  //IPsec end system
778  }
779  //id-kp-ipsecTunnel ?
780  else if(!oidComp(tag.value, tag.length,
782  {
783  //IPsec tunnel
784  extKeyUsage->bitmap |= X509_EXT_KEY_USAGE_IPSEC_TUNNEL;
785  }
786  //id-kp-ipsecUser ?
787  else if(!oidComp(tag.value, tag.length,
789  {
790  //IPsec user
791  extKeyUsage->bitmap |= X509_EXT_KEY_USAGE_IPSEC_USER;
792  }
793  //id-kp-timeStamping?
794  else if(!oidComp(tag.value, tag.length,
796  {
797  //Binding the hash of an object to a time
799  }
800  //id-kp-OCSPSigning?
801  else if(!oidComp(tag.value, tag.length,
803  {
804  //Signing OCSP responses
805  extKeyUsage->bitmap |= X509_EXT_KEY_USAGE_OCSP_SIGNING;
806  }
807  //id-kp-ipsecIKE ?
808  else if(!oidComp(tag.value, tag.length,
810  {
811  //The certificate is intended to be used with IKE
812  extKeyUsage->bitmap |= X509_EXT_KEY_USAGE_IPSEC_IKE;
813  }
814  //id-kp-secureShellClient?
815  else if(!oidComp(tag.value, tag.length,
817  {
818  //The key can be used for a Secure Shell client
819  extKeyUsage->bitmap |= X509_EXT_KEY_USAGE_SSH_CLIENT;
820  }
821  //id-kp-secureShellServer?
822  else if(!oidComp(tag.value, tag.length,
824  {
825  //The key can be used for a Secure Shell server
826  extKeyUsage->bitmap |= X509_EXT_KEY_USAGE_SSH_SERVER;
827  }
828  //id-kp-documentSigning?
829  else if(!oidComp(tag.value, tag.length,
831  {
832  //The public key encoded in the certificate has been certified to be
833  //used for cryptographic operations on contents that are consumed by
834  //people (refer to RFC 9336, section 3.1)
835  extKeyUsage->bitmap |= X509_EXT_KEY_USAGE_DOC_SIGNING;
836  }
837  //Unknown key purpose?
838  else
839  {
840  //Discard KeyPurposeId field
841  }
842 
843  //Next item
844  data += tag.totalLength;
845  length -= tag.totalLength;
846  }
847 
848  //Successful processing
849  return NO_ERROR;
850 }
851 
852 
853 /**
854  * @brief Parse SubjectAltName extension
855  * @param[in] critical Critical extension flag
856  * @param[in] data Pointer to the ASN.1 structure to parse
857  * @param[in] length Length of the ASN.1 structure
858  * @param[out] subjectAltName Information resulting from the parsing process
859  * @return Error code
860  **/
861 
863  size_t length, X509SubjectAltName *subjectAltName)
864 {
865  error_t error;
866  Asn1Tag tag;
867 
868  //Debug message
869  TRACE_DEBUG(" Parsing SubjectAltName...\r\n");
870 
871  //An extension can be marked as critical
872  subjectAltName->critical = critical;
873 
874  //The SubjectAltName structure shall contain a valid sequence
875  error = asn1ReadSequence(data, length, &tag);
876  //Failed to decode ASN.1 tag?
877  if(error)
878  return error;
879 
880  //Raw contents of the ASN.1 sequence
881  subjectAltName->raw.value = tag.value;
882  subjectAltName->raw.length = tag.length;
883 
884  //The subject alternative name extension allows identities to be bound to the
885  //subject of the certificate. These identities may be included in addition
886  //to or in place of the identity in the subject field of the certificate
887  return x509ParseGeneralNames(tag.value, tag.length,
888  subjectAltName->generalNames, X509_MAX_SUBJECT_ALT_NAMES,
889  &subjectAltName->numGeneralNames);
890 }
891 
892 
893 /**
894  * @brief Parse SubjectKeyIdentifier extension
895  * @param[in] critical Critical extension flag
896  * @param[in] data Pointer to the ASN.1 structure to parse
897  * @param[in] length Length of the ASN.1 structure
898  * @param[out] subjectKeyId Information resulting from the parsing process
899  * @return Error code
900  **/
901 
903  size_t length, X509SubjectKeyId *subjectKeyId)
904 {
905  error_t error;
906  Asn1Tag tag;
907 
908  //Debug message
909  TRACE_DEBUG(" Parsing SubjectKeyIdentifier...\r\n");
910 
911  //An extension can be marked as critical
912  subjectKeyId->critical = critical;
913 
914  //The subject key identifier extension provides a means of identifying
915  //certificates that contain a particular public key
916  error = asn1ReadOctetString(data, length, &tag);
917  //Failed to decode ASN.1 tag?
918  if(error)
919  return error;
920 
921  //Save the subject key identifier
922  subjectKeyId->value = tag.value;
923  subjectKeyId->length = tag.length;
924 
925  //Successful processing
926  return NO_ERROR;
927 }
928 
929 
930 /**
931  * @brief Parse AuthorityKeyIdentifier extension
932  * @param[in] critical Critical extension flag
933  * @param[in] data Pointer to the ASN.1 structure to parse
934  * @param[in] length Length of the ASN.1 structure
935  * @param[out] authKeyId Information resulting from the parsing process
936  * @return Error code
937  **/
938 
940  size_t length, X509AuthKeyId *authKeyId)
941 {
942  error_t error;
943  Asn1Tag tag;
944 
945  //Debug message
946  TRACE_DEBUG(" Parsing AuthorityKeyIdentifier...\r\n");
947 
948  //An extension can be marked as critical
949  authKeyId->critical = critical;
950 
951  //The AuthorityKeyIdentifier structure shall contain a valid sequence
952  error = asn1ReadSequence(data, length, &tag);
953  //Failed to decode ASN.1 tag?
954  if(error)
955  return error;
956 
957  //Point to the first item of the sequence
958  data = tag.value;
959  length = tag.length;
960 
961  //Parse the content of the sequence
962  while(length > 0)
963  {
964  //Read current item
965  error = asn1ReadTag(data, length, &tag);
966  //Failed to decode ASN.1 tag?
967  if(error)
968  return error;
969 
970  //Implicit tagging shall be used to encode the item
972  return ERROR_INVALID_CLASS;
973 
974  //keyIdentifier object found?
975  if(tag.objType == 0)
976  {
977  //Save the authority key identifier
978  authKeyId->keyId.value = tag.value;
979  authKeyId->keyId.length = tag.length;
980  }
981 
982  //Next item
983  data += tag.totalLength;
984  length -= tag.totalLength;
985  }
986 
987  //Successful processing
988  return NO_ERROR;
989 }
990 
991 
992 /**
993  * @brief Parse CRLDistributionPoints extension
994  * @param[in] critical Critical extension flag
995  * @param[in] data Pointer to the ASN.1 structure to parse
996  * @param[in] length Length of the ASN.1 structure
997  * @param[out] crlDistrPoints Information resulting from the parsing process
998  * @return Error code
999  **/
1000 
1002  size_t length, X509CrlDistrPoints *crlDistrPoints)
1003 {
1004  error_t error;
1005  uint_t i;
1006  size_t n;
1007  Asn1Tag tag;
1008  X509DistrPoint distrPoint;
1009 
1010  //Debug message
1011  TRACE_DEBUG(" Parsing CRLDistributionPoints...\r\n");
1012 
1013  //An extension can be marked as critical
1014  crlDistrPoints->critical = critical;
1015 
1016  //The CRLDistributionPoints structure shall contain a valid sequence
1017  error = asn1ReadSequence(data, length, &tag);
1018  //Failed to decode ASN.1 tag?
1019  if(error)
1020  return error;
1021 
1022  //Raw contents of the ASN.1 sequence
1023  crlDistrPoints->raw.value = tag.value;
1024  crlDistrPoints->raw.length = tag.length;
1025 
1026  //Point to the first item of the sequence
1027  data = tag.value;
1028  length = tag.length;
1029 
1030  //Parse the content of the sequence
1031  for(i = 0; length > 0; i++)
1032  {
1033  //Parse DistributionPoint field
1034  error = x509ParseDistrPoint(data, length, &n, &distrPoint);
1035  //Any error to report?
1036  if(error)
1037  return error;
1038 
1039  //Save distribution point
1040  if(i < X509_MAX_DISTR_POINTS)
1041  {
1042  crlDistrPoints->distrPoints[i] = distrPoint;
1043  }
1044 
1045  //Next item
1046  data += n;
1047  length -= n;
1048  }
1049 
1050  //If the CRLDistributionPoints extension is present, the sequence must
1051  //contain at least one entry (refer to RFC 5280, section 4.2.1.13)
1052  if(i == 0)
1053  return ERROR_INVALID_SYNTAX;
1054 
1055  //Save the number of distribution points
1056  crlDistrPoints->numDistrPoints = MIN(i, X509_MAX_DISTR_POINTS);
1057 
1058  //Successful processing
1059  return NO_ERROR;
1060 }
1061 
1062 
1063 /**
1064  * @brief Parse DistributionPoint field
1065  * @param[in] data Pointer to the ASN.1 structure to parse
1066  * @param[in] length Length of the ASN.1 structure
1067  * @param[out] totalLength Number of bytes that have been parsed
1068  * @param[out] distrPoint Information resulting from the parsing process
1069  * @return Error code
1070  **/
1071 
1072 error_t x509ParseDistrPoint(const uint8_t *data, size_t length,
1073  size_t *totalLength, X509DistrPoint *distrPoint)
1074 {
1075  error_t error;
1076  Asn1Tag tag;
1077 
1078  //Clear the structure
1079  osMemset(distrPoint, 0, sizeof(X509DistrPoint));
1080 
1081  //The DistributionPoint structure shall contain a valid sequence
1082  error = asn1ReadSequence(data, length, &tag);
1083  //Failed to decode ASN.1 tag?
1084  if(error)
1085  return error;
1086 
1087  //Save the total length of the field
1088  *totalLength = tag.totalLength;
1089 
1090  //Point to the first item of the sequence
1091  data = tag.value;
1092  length = tag.length;
1093 
1094  //Parse the content of the sequence
1095  while(length > 0)
1096  {
1097  //Read current item
1098  error = asn1ReadTag(data, length, &tag);
1099  //Failed to decode ASN.1 tag?
1100  if(error)
1101  return error;
1102 
1103  //Implicit tagging shall be used to encode the item
1105  return ERROR_INVALID_CLASS;
1106 
1107  //A DistributionPoint consists of three fields, each of which is optional
1108  if(tag.objType == 0)
1109  {
1110  //Parse DistributionPointName field
1111  error = x509ParseDistrPointName(tag.value, tag.length,
1112  &distrPoint->distrPointName);
1113  }
1114  else if(tag.objType == 1)
1115  {
1116  //Parse ReasonFlags field
1117  error = x509ParseReasonFlags(tag.value, tag.length,
1118  &distrPoint->reasonFlags);
1119  }
1120  else if(tag.objType == 2)
1121  {
1122  //Parse CRLIssuer field
1123  error = x509ParseGeneralNames(tag.value, tag.length,
1124  distrPoint->crlIssuers, X509_MAX_CRL_ISSUERS,
1125  &distrPoint->numCrlIssuers);
1126  }
1127  else
1128  {
1129  //Report an error
1130  error = ERROR_INVALID_TYPE;
1131  }
1132 
1133  //Any error to report?
1134  if(error)
1135  return error;
1136 
1137  //Next item
1138  data += tag.totalLength;
1139  length -= tag.totalLength;
1140  }
1141 
1142  //Successful processing
1143  return NO_ERROR;
1144 }
1145 
1146 
1147 /**
1148  * @brief Parse DistributionPointName field
1149  * @param[in] data Pointer to the ASN.1 structure to parse
1150  * @param[in] length Length of the ASN.1 structure
1151  * @param[out] distrPointName Information resulting from the parsing process
1152  * @return Error code
1153  **/
1154 
1156  X509DistrPointName *distrPointName)
1157 {
1158  error_t error;
1159  Asn1Tag tag;
1160 
1161  //Parse ASN.1 tag
1162  error = asn1ReadTag(data, length, &tag);
1163  //Failed to decode ASN.1 tag?
1164  if(error)
1165  return error;
1166 
1167  //Implicit tagging shall be used to encode the item
1169  return ERROR_INVALID_CLASS;
1170 
1171  //When the distributionPoint field is present, it contains either a
1172  //sequence of general names or a single value, nameRelativeToCRLIssuer
1173  if(tag.objType == 0)
1174  {
1175  //Parse fullName field
1176  error = x509ParseGeneralNames(tag.value, tag.length,
1177  distrPointName->fullNames, X509_MAX_FULL_NAMES,
1178  &distrPointName->numFullNames);
1179  }
1180  else if(tag.objType == 1)
1181  {
1182  //Parse nameRelativeToCRLIssuer field
1183  error = x509ParseRelativeName(tag.value, tag.length,
1184  &distrPointName->relativeName);
1185  }
1186  else
1187  {
1188  //Report an error
1189  error = ERROR_INVALID_TYPE;
1190  }
1191 
1192  //Return status code
1193  return error;
1194 }
1195 
1196 
1197 /**
1198  * @brief Parse nameRelativeToCRLIssuer field
1199  * @param[in] data Pointer to the ASN.1 structure to parse
1200  * @param[in] length Length of the ASN.1 structure
1201  * @param[out] relativeName Information resulting from the parsing process
1202  * @return Error code
1203  **/
1204 
1205 error_t x509ParseRelativeName(const uint8_t *data, size_t length,
1206  X509NameAttribute *relativeName)
1207 {
1208  error_t error;
1209  Asn1Tag tag;
1210 
1211  //Read the first field of the set
1212  error = asn1ReadSequence(data, length, &tag);
1213  //Failed to decode ASN.1 tag?
1214  if(error)
1215  return error;
1216 
1217  //Point to the first field of the sequence
1218  data = tag.value;
1219  length = tag.length;
1220 
1221  //Read AttributeType field
1222  error = asn1ReadOid(data, length, &tag);
1223  //Failed to decode ASN.1 tag?
1224  if(error)
1225  return error;
1226 
1227  //Save attribute type
1228  relativeName->oid.value = tag.value;
1229  relativeName->oid.length = tag.length;
1230 
1231  //Point to the next field
1232  data += tag.totalLength;
1233  length -= tag.totalLength;
1234 
1235  //Read AttributeValue field
1236  error = asn1ReadTag(data, length, &tag);
1237  //Failed to decode ASN.1 tag?
1238  if(error)
1239  return error;
1240 
1241  //Save ASN.1 string type
1242  relativeName->type = tag.objType;
1243 
1244  //Save attribute value
1245  relativeName->data.value = (char_t *) tag.value;
1246  relativeName->data.length = tag.length;
1247 
1248  //Successful processing
1249  return NO_ERROR;
1250 }
1251 
1252 
1253 /**
1254  * @brief Parse ReasonFlags field
1255  * @param[in] data Pointer to the ASN.1 structure to parse
1256  * @param[in] length Length of the ASN.1 structure
1257  * @param[out] reasonFlags Information resulting from the parsing process
1258  * @return Error code
1259  **/
1260 
1261 error_t x509ParseReasonFlags(const uint8_t *data, size_t length,
1262  uint16_t *reasonFlags)
1263 {
1264  //The bit string shall contain an initial octet which encodes the number
1265  //of unused bits in the final subsequent octet
1266  if(length < 1)
1267  return ERROR_INVALID_SYNTAX;
1268 
1269  //Sanity check
1270  if(data[0] >= 8)
1271  return ERROR_INVALID_SYNTAX;
1272 
1273  //Clear bit string
1274  *reasonFlags = 0;
1275 
1276  //Read bits b0 to b7
1277  if(length >= 2)
1278  {
1279  *reasonFlags |= reverseInt8(data[1]);
1280  }
1281 
1282  //Read bits b8 to b15
1283  if(length >= 3)
1284  {
1285  *reasonFlags |= reverseInt8(data[2]) << 8;
1286  }
1287 
1288  //Successful processing
1289  return NO_ERROR;
1290 }
1291 
1292 
1293 /**
1294  * @brief Parse AuthorityInformationAccess extension
1295  * @param[in] critical Critical extension flag
1296  * @param[in] data Pointer to the ASN.1 structure to parse
1297  * @param[in] length Length of the ASN.1 structure
1298  * @param[out] authInfoAccess Information resulting from the parsing process
1299  * @return Error code
1300  **/
1301 
1303  size_t length, X509AuthInfoAccess *authInfoAccess)
1304 {
1305  error_t error;
1306  uint_t i;
1307  size_t n;
1308  Asn1Tag tag;
1309  X509AccessDescription accessDescription;
1310 
1311  //Debug message
1312  TRACE_DEBUG(" Parsing AuthorityInformationAccess...\r\n");
1313 
1314  //An extension can be marked as critical
1315  authInfoAccess->critical = critical;
1316 
1317  //The AuthorityInformationAccess structure shall contain a valid sequence
1318  error = asn1ReadSequence(data, length, &tag);
1319  //Failed to decode ASN.1 tag?
1320  if(error)
1321  return error;
1322 
1323  //Raw contents of the ASN.1 sequence
1324  authInfoAccess->raw.value = tag.value;
1325  authInfoAccess->raw.length = tag.length;
1326 
1327  //Point to the first item of the sequence
1328  data = tag.value;
1329  length = tag.length;
1330 
1331  //Parse the content of the sequence
1332  for(i = 0; length > 0; i++)
1333  {
1334  //Parse AccessDescription field
1335  error = x509ParseAccessDescription(data, length, &n, &accessDescription);
1336  //Any error to report?
1337  if(error)
1338  return error;
1339 
1340  //Save access description
1342  {
1343  authInfoAccess->accessDescriptions[i] = accessDescription;
1344  }
1345 
1346  //Next item
1347  data += n;
1348  length -= n;
1349  }
1350 
1351  //If the AuthorityInformationAccess extension is present, the sequence must
1352  //contain at least one entry (refer to RFC 5280, section 4.2.2.1)
1353  if(i == 0)
1354  return ERROR_INVALID_SYNTAX;
1355 
1356  //Save the number of access descriptions
1358 
1359  //Successful processing
1360  return NO_ERROR;
1361 }
1362 
1363 
1364 /**
1365  * @brief Parse AccessDescription field
1366  * @param[in] data Pointer to the ASN.1 structure to parse
1367  * @param[in] length Length of the ASN.1 structure
1368  * @param[out] totalLength Number of bytes that have been parsed
1369  * @param[out] accessDescription Information resulting from the parsing process
1370  * @return Error code
1371  **/
1372 
1374  size_t *totalLength, X509AccessDescription *accessDescription)
1375 {
1376  error_t error;
1377  size_t n;
1378  Asn1Tag tag;
1379 
1380  //Clear the structure
1381  osMemset(accessDescription, 0, sizeof(X509AccessDescription));
1382 
1383  //The AccessDescription structure shall contain a valid sequence
1384  error = asn1ReadSequence(data, length, &tag);
1385  //Failed to decode ASN.1 tag?
1386  if(error)
1387  return error;
1388 
1389  //Save the total length of the field
1390  *totalLength = tag.totalLength;
1391 
1392  //Point to the first item of the sequence
1393  data = tag.value;
1394  length = tag.length;
1395 
1396  //Read accessMethod field
1397  error = asn1ReadOid(data, length, &tag);
1398  //Failed to decode ASN.1 tag?
1399  if(error)
1400  return error;
1401 
1402  //The type and format of the information are specified by the accessMethod
1403  //field (refer to RFC 5280, section 4.2.2.1)
1404  accessDescription->accessMethod.value = tag.value;
1405  accessDescription->accessMethod.length = tag.length;
1406 
1407  //Point to the next field
1408  data += tag.totalLength;
1409  length -= tag.totalLength;
1410 
1411  //The accessLocation field specifies the location of the information
1412  error = x509ParseGeneralName(data, length, &n,
1413  &accessDescription->accessLocation);
1414  //Failed to decode ASN.1 tag?
1415  if(error)
1416  return error;
1417 
1418  //Point to the next field
1419  data += n;
1420  length -= n;
1421 
1422  //Successful processing
1423  return NO_ERROR;
1424 }
1425 
1426 
1427 /**
1428  * @brief Parse PkixOcspNoCheck extension
1429  * @param[in] critical Critical extension flag
1430  * @param[in] data Pointer to the ASN.1 structure to parse
1431  * @param[in] length Length of the ASN.1 structure
1432  * @param[out] pkixOcspNoCheck Information resulting from the parsing process
1433  * @return Error code
1434  **/
1435 
1437  size_t length, X509PkixOcspNoCheck *pkixOcspNoCheck)
1438 {
1439  error_t error;
1440  Asn1Tag tag;
1441 
1442  //Debug message
1443  TRACE_DEBUG(" Parsing PkixOcspNoCheck...\r\n");
1444 
1445  //The extension should be a non-critical extension
1446  pkixOcspNoCheck->critical = critical;
1447 
1448  //The value of the extension shall be NULL (refer to RFC 6960,
1449  //section 4.2.2.2.1)
1450  error = asn1ReadTag(data, length, &tag);
1451  //Failed to decode ASN.1 tag?
1452  if(error)
1453  return error;
1454 
1455  //Enforce encoding, class and type
1457  //Invalid tag?
1458  if(error)
1459  return error;
1460 
1461  //The certificate contains a valid id-pkix-ocsp-nocheck extension
1462  pkixOcspNoCheck->present = TRUE;
1463 
1464  //Successful processing
1465  return NO_ERROR;
1466 }
1467 
1468 
1469 /**
1470  * @brief Parse NetscapeCertType extension
1471  * @param[in] critical Critical extension flag
1472  * @param[in] data Pointer to the ASN.1 structure to parse
1473  * @param[in] length Length of the ASN.1 structure
1474  * @param[out] nsCertType Information resulting from the parsing process
1475  * @return Error code
1476  **/
1477 
1479  size_t length, X509NsCertType *nsCertType)
1480 {
1481  error_t error;
1482  Asn1Tag tag;
1483 
1484  //Debug message
1485  TRACE_DEBUG(" Parsing NetscapeCertType...\r\n");
1486 
1487  //An extension can be marked as critical
1488  nsCertType->critical = critical;
1489 
1490  //The NetscapeCertType extension limit the use of a certificate
1491  error = asn1ReadTag(data, length, &tag);
1492  //Failed to decode ASN.1 tag?
1493  if(error)
1494  return error;
1495 
1496  //Enforce encoding, class and type
1497  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
1499  //Invalid tag?
1500  if(error)
1501  return error;
1502 
1503  //The bit string shall contain an initial octet which encodes the number
1504  //of unused bits in the final subsequent octet
1505  if(tag.length < 1)
1506  return ERROR_INVALID_SYNTAX;
1507 
1508  //Sanity check
1509  if(tag.value[0] >= 8)
1510  return ERROR_INVALID_SYNTAX;
1511 
1512  //Clear bit string
1513  nsCertType->bitmap = 0;
1514 
1515  //Read bits b0 to b7
1516  if(tag.length >= 2)
1517  {
1518  nsCertType->bitmap |= reverseInt8(tag.value[1]);
1519  }
1520 
1521  //Successful processing
1522  return NO_ERROR;
1523 }
1524 
1525 
1526 /**
1527  * @brief Parse unknown X.509 certificate extension
1528  * @param[in] oid Extension identifier
1529  * @param[in] oidLen Length of the extension identifier
1530  * @param[in] critical Critical extension flag
1531  * @param[in] data Extension value
1532  * @param[in] dataLen Length of the extension value
1533  * @param[out] extensions Information resulting from the parsing process
1534  * @return Error code
1535  **/
1536 
1537 __weak_func error_t x509ParseUnknownCertExtension(const uint8_t *oid,
1538  size_t oidLen, bool_t critical, const uint8_t *data, size_t dataLen,
1540 {
1541  //The extension is not supported
1543 }
1544 
1545 
1546 /**
1547  * @brief Check whether the specified extension is a duplicate
1548  * @param[in] oid Extension identifier
1549  * @param[in] oidLen Length of the extension identifier
1550  * @param[in] data Pointer to the extension list
1551  * @param[in] length Length of the extension list
1552  * @return Error code
1553  **/
1554 
1556  const uint8_t *data, size_t length)
1557 {
1558  error_t error;
1559  size_t n;
1560  X509Extension extension;
1561 
1562  //Loop through the extensions
1563  while(length > 0)
1564  {
1565  //Each extension includes an OID and a value
1566  error = x509ParseExtension(data, length, &n, &extension);
1567  //Any error to report?
1568  if(error)
1569  return error;
1570 
1571  //A certificate must not include more than one instance of a particular
1572  //extension (refer to RFC 5280, section 4.2)
1573  if(!oidComp(extension.oid.value, extension.oid.length, oid, oidLen))
1574  {
1575  return ERROR_INVALID_SYNTAX;
1576  }
1577 
1578  //Jump to the next extension
1579  data += n;
1580  length -= n;
1581  }
1582 
1583  //Successful verification
1584  return NO_ERROR;
1585 }
1586 
1587 #endif
error_t asn1ReadOctetString(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an octet string from the input stream.
Definition: asn1.c:190
error_t asn1ReadTag(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 tag from the input stream.
Definition: asn1.c:52
error_t asn1ReadSequence(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 sequence from the input stream.
Definition: asn1.c:163
error_t asn1CheckTag(const Asn1Tag *tag, bool_t constructed, uint_t objClass, uint_t objType)
Enforce the type of a specified tag.
Definition: asn1.c:653
error_t asn1ReadOid(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an object identifier from the input stream.
Definition: asn1.c:218
error_t asn1ReadInt32(const uint8_t *data, size_t length, Asn1Tag *tag, int32_t *value)
Read a 32-bit integer from the input stream.
Definition: asn1.c:285
ASN.1 (Abstract Syntax Notation One)
@ ASN1_TYPE_BOOLEAN
Definition: asn1.h:69
@ ASN1_TYPE_BIT_STRING
Definition: asn1.h:71
@ ASN1_TYPE_NULL
Definition: asn1.h:73
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
#define ASN1_CLASS_CONTEXT_SPECIFIC
Definition: asn1.h:54
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
uint8_t reverseInt8(uint8_t value)
Reverse bit order in a byte.
Definition: cpu_endian.c:90
General definitions for cryptographic algorithms.
Debugging facilities.
#define TRACE_DEBUG(...)
Definition: debug.h:107
uint8_t n
error_t
Error codes.
Definition: error.h:43
@ ERROR_UNSUPPORTED_EXTENSION
Definition: error.h:244
@ ERROR_INVALID_TYPE
Definition: error.h:115
@ ERROR_INVALID_CLASS
Definition: error.h:117
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_LENGTH
Definition: error.h:111
uint8_t data[]
Definition: ethernet.h:222
uint8_t critical
Definition: ike.h:1281
uint16_t totalLength
Definition: ipv4.h:292
uint8_t oid[]
Definition: lldp_tlv.h:300
uint8_t oidLen
Definition: lldp_tlv.h:299
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:103
OID (Object Identifier)
#define osMemset(p, value, length)
Definition: os_port.h:135
#define MIN(a, b)
Definition: os_port.h:63
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
uint32_t dataLen
Definition: sftp_common.h:229
ASN.1 tag.
Definition: asn1.h:102
size_t totalLength
Definition: asn1.h:108
const uint8_t * value
Definition: asn1.h:107
uint_t objClass
Definition: asn1.h:104
uint_t objType
Definition: asn1.h:105
size_t length
Definition: asn1.h:106
Access Description extension.
Definition: x509_common.h:938
X509GeneralName accessLocation
Definition: x509_common.h:940
X509OctetString accessMethod
Definition: x509_common.h:939
Authority Information Access extension.
Definition: x509_common.h:949
uint_t numAccessDescriptions
Definition: x509_common.h:952
X509AccessDescription accessDescriptions[X509_MAX_ACCESS_DESCRIPTIONS]
Definition: x509_common.h:953
X509OctetString raw
Definition: x509_common.h:951
Authority Key Identifier extension.
Definition: x509_common.h:889
bool_t critical
Definition: x509_common.h:890
X509OctetString keyId
Definition: x509_common.h:891
Basic Constraints extension.
Definition: x509_common.h:806
CRL Distribution Points extension.
Definition: x509_common.h:925
X509DistrPoint distrPoints[X509_MAX_DISTR_POINTS]
Definition: x509_common.h:929
X509OctetString raw
Definition: x509_common.h:927
Distribution Point structure.
Definition: x509_common.h:912
X509DistrPointName distrPointName
Definition: x509_common.h:913
uint_t numCrlIssuers
Definition: x509_common.h:915
uint16_t reasonFlags
Definition: x509_common.h:914
X509GeneralName crlIssuers[X509_MAX_CRL_ISSUERS]
Definition: x509_common.h:916
Distribution Point Name structure.
Definition: x509_common.h:900
X509GeneralName fullNames[X509_MAX_FULL_NAMES]
Definition: x509_common.h:902
X509NameAttribute relativeName
Definition: x509_common.h:903
Extended Key Usage extension.
Definition: x509_common.h:841
X.509 certificate extension.
Definition: x509_common.h:984
X509OctetString data
Definition: x509_common.h:987
bool_t critical
Definition: x509_common.h:986
X509OctetString oid
Definition: x509_common.h:985
X.509 certificate extensions.
Definition: x509_common.h:996
Key Usage extension.
Definition: x509_common.h:830
uint16_t bitmap
Definition: x509_common.h:832
bool_t critical
Definition: x509_common.h:831
Name attribute.
Definition: x509_common.h:696
X509String data
Definition: x509_common.h:699
X509OctetString oid
Definition: x509_common.h:697
Name Constraints extension.
Definition: x509_common.h:818
X509OctetString excludedSubtrees
Definition: x509_common.h:821
X509OctetString permittedSubtrees
Definition: x509_common.h:820
Netscape certificate type.
Definition: x509_common.h:973
uint8_t bitmap
Definition: x509_common.h:975
const uint8_t * value
Definition: x509_common.h:647
PKIX OCSP No Check extension.
Definition: x509_common.h:962
const char_t * value
Definition: x509_common.h:636
size_t length
Definition: x509_common.h:637
Subject Alternative Name extension.
Definition: x509_common.h:864
X509OctetString raw
Definition: x509_common.h:866
X509GeneralName generalNames[X509_MAX_SUBJECT_ALT_NAMES]
Definition: x509_common.h:868
Subject Key Identifier extension.
Definition: x509_common.h:877
const uint8_t * value
Definition: x509_common.h:879
uint8_t length
Definition: tcp.h:368
uint8_t value[]
Definition: tcp.h:369
uint8_t extensions[]
Definition: tls13_misc.h:300
error_t x509ParsePkixOcspNoCheck(bool_t critical, const uint8_t *data, size_t length, X509PkixOcspNoCheck *pkixOcspNoCheck)
Parse PkixOcspNoCheck extension.
error_t x509ParseCrlDistrPoints(bool_t critical, const uint8_t *data, size_t length, X509CrlDistrPoints *crlDistrPoints)
Parse CRLDistributionPoints extension.
error_t x509ParseSubjectAltName(bool_t critical, const uint8_t *data, size_t length, X509SubjectAltName *subjectAltName)
Parse SubjectAltName extension.
error_t x509ParseAuthKeyId(bool_t critical, const uint8_t *data, size_t length, X509AuthKeyId *authKeyId)
Parse AuthorityKeyIdentifier extension.
error_t x509ParseKeyUsage(bool_t critical, const uint8_t *data, size_t length, X509KeyUsage *keyUsage)
Parse KeyUsage extension.
error_t x509ParseDistrPoint(const uint8_t *data, size_t length, size_t *totalLength, X509DistrPoint *distrPoint)
Parse DistributionPoint field.
error_t x509ParsePolicyConstraints(bool_t critical, const uint8_t *data, size_t length)
Parse PolicyConstraints extension.
error_t x509ParseDistrPointName(const uint8_t *data, size_t length, X509DistrPointName *distrPointName)
Parse DistributionPointName field.
error_t x509ParseReasonFlags(const uint8_t *data, size_t length, uint16_t *reasonFlags)
Parse ReasonFlags field.
error_t x509ParseAuthInfoAccess(bool_t critical, const uint8_t *data, size_t length, X509AuthInfoAccess *authInfoAccess)
Parse AuthorityInformationAccess extension.
error_t x509ParseNameConstraints(bool_t critical, const uint8_t *data, size_t length, X509NameConstraints *nameConstraints)
Parse NameConstraints extension.
error_t x509ParsePolicyMappings(bool_t critical, const uint8_t *data, size_t length)
Parse PolicyMappings extension.
error_t x509ParseExtendedKeyUsage(bool_t critical, const uint8_t *data, size_t length, X509ExtendedKeyUsage *extKeyUsage)
Parse ExtendedKeyUsage extension.
__weak_func error_t x509ParseUnknownCertExtension(const uint8_t *oid, size_t oidLen, bool_t critical, const uint8_t *data, size_t dataLen, X509Extensions *extensions)
Parse unknown X.509 certificate extension.
error_t x509ParseNsCertType(bool_t critical, const uint8_t *data, size_t length, X509NsCertType *nsCertType)
Parse NetscapeCertType extension.
error_t x509ParseCertExtensions(const uint8_t *data, size_t length, size_t *totalLength, X509Extensions *extensions, bool_t ignoreUnknown)
Parse X.509 certificate extensions.
error_t x509ParseExtension(const uint8_t *data, size_t length, size_t *totalLength, X509Extension *extension)
Parse X.509 certificate extension.
error_t x509ParseSubjectKeyId(bool_t critical, const uint8_t *data, size_t length, X509SubjectKeyId *subjectKeyId)
Parse SubjectKeyIdentifier extension.
error_t x509ParseBasicConstraints(bool_t critical, const uint8_t *data, size_t length, X509BasicConstraints *basicConstraints)
Parse BasicConstraints extension.
error_t x509ParseInhibitAnyPolicy(bool_t critical, const uint8_t *data, size_t length)
Parse InhibitAnyPolicy extension.
error_t x509ParseRelativeName(const uint8_t *data, size_t length, X509NameAttribute *relativeName)
Parse nameRelativeToCRLIssuer field.
error_t x509CheckDuplicateExtension(const uint8_t *oid, size_t oidLen, const uint8_t *data, size_t length)
Check whether the specified extension is a duplicate.
error_t x509ParseAccessDescription(const uint8_t *data, size_t length, size_t *totalLength, X509AccessDescription *accessDescription)
Parse AccessDescription field.
X.509 extension parsing.
error_t x509ParseGeneralSubtrees(const uint8_t *data, size_t length)
Parse GeneralSubtrees field.
error_t x509ParseGeneralNames(const uint8_t *data, size_t length, X509GeneralName *generalNames, uint_t maxGeneralNames, uint_t *numGeneralNames)
Parse GeneralNames field.
error_t x509ParseGeneralName(const uint8_t *data, size_t length, size_t *totalLength, X509GeneralName *generalName)
Parse GeneralName field.
X.509 certificate parsing.
const uint8_t X509_SUBJECT_KEY_ID_OID[3]
Definition: x509_common.c:81
const uint8_t X509_NAME_CONSTRAINTS_OID[3]
Definition: x509_common.c:103
const uint8_t X509_PKIX_OCSP_NO_CHECK_OID[9]
Definition: x509_common.c:123
const uint8_t X509_KP_CODE_SIGNING_OID[8]
Definition: x509_common.c:134
const uint8_t X509_NS_CERT_TYPE_OID[9]
Definition: x509_common.c:125
const uint8_t X509_BASIC_CONSTRAINTS_OID[3]
Definition: x509_common.c:89
const uint8_t X509_SUBJECT_ALT_NAME_OID[3]
Definition: x509_common.c:85
const uint8_t X509_KP_EMAIL_PROTECTION_OID[8]
Definition: x509_common.c:136
const uint8_t X509_ANY_EXT_KEY_USAGE_OID[4]
Definition: x509_common.c:128
const uint8_t X509_KP_IPSEC_TUNNEL_OID[8]
Definition: x509_common.c:140
const uint8_t X509_KP_SSH_CLIENT_OID[8]
Definition: x509_common.c:150
const uint8_t X509_KP_CLIENT_AUTH_OID[8]
Definition: x509_common.c:132
const uint8_t X509_KP_SSH_SERVER_OID[8]
Definition: x509_common.c:152
const uint8_t X509_KP_IPSEC_IKE_OID[8]
Definition: x509_common.c:148
const uint8_t X509_EXTENDED_KEY_USAGE_OID[3]
Definition: x509_common.c:115
const uint8_t X509_KP_IPSEC_END_SYSTEM_OID[8]
Definition: x509_common.c:138
const uint8_t X509_KEY_USAGE_OID[3]
Definition: x509_common.c:83
const uint8_t X509_KP_IPSEC_USER_OID[8]
Definition: x509_common.c:142
const uint8_t X509_KP_DOC_SIGNING_OID[8]
Definition: x509_common.c:154
const uint8_t X509_KP_OCSP_SIGNING_OID[8]
Definition: x509_common.c:146
const uint8_t X509_CRL_DISTR_POINTS_OID[3]
Definition: x509_common.c:105
const uint8_t X509_AUTH_INFO_ACCESS_OID[8]
Definition: x509_common.c:121
const uint8_t X509_AUTHORITY_KEY_ID_OID[3]
Definition: x509_common.c:111
const uint8_t X509_KP_SERVER_AUTH_OID[8]
Definition: x509_common.c:130
const uint8_t X509_KP_TIME_STAMPING_OID[8]
Definition: x509_common.c:144
@ X509_EXT_KEY_USAGE_DOC_SIGNING
Definition: x509_common.h:501
@ X509_EXT_KEY_USAGE_IPSEC_IKE
Definition: x509_common.h:498
@ X509_EXT_KEY_USAGE_TIME_STAMPING
Definition: x509_common.h:496
@ X509_EXT_KEY_USAGE_IPSEC_END_SYSTEM
Definition: x509_common.h:493
@ X509_EXT_KEY_USAGE_SERVER_AUTH
Definition: x509_common.h:489
@ X509_EXT_KEY_USAGE_CODE_SIGNING
Definition: x509_common.h:491
@ X509_EXT_KEY_USAGE_IPSEC_USER
Definition: x509_common.h:495
@ X509_EXT_KEY_USAGE_ANY
Definition: x509_common.h:502
@ X509_EXT_KEY_USAGE_OCSP_SIGNING
Definition: x509_common.h:497
@ X509_EXT_KEY_USAGE_IPSEC_TUNNEL
Definition: x509_common.h:494
@ X509_EXT_KEY_USAGE_SSH_CLIENT
Definition: x509_common.h:499
@ X509_EXT_KEY_USAGE_EMAIL_PROTECTION
Definition: x509_common.h:492
@ X509_EXT_KEY_USAGE_CLIENT_AUTH
Definition: x509_common.h:490
@ X509_EXT_KEY_USAGE_SSH_SERVER
Definition: x509_common.h:500
#define X509_MAX_CRL_ISSUERS
Definition: x509_common.h:388
@ X509_KEY_USAGE_KEY_CERT_SIGN
Definition: x509_common.h:476
#define X509_MAX_ACCESS_DESCRIPTIONS
Definition: x509_common.h:409
#define X509_MAX_FULL_NAMES
Definition: x509_common.h:402
#define X509_MAX_SUBJECT_ALT_NAMES
Definition: x509_common.h:374
#define X509_MAX_DISTR_POINTS
Definition: x509_common.h:395