x509_cert_parse.c
Go to the documentation of this file.
1 /**
2  * @file x509_cert_parse.c
3  * @brief X.509 certificate parsing
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneCrypto Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
31 
32 //Dependencies
33 #include "core/crypto.h"
35 #include "encoding/asn1.h"
36 #include "encoding/oid.h"
37 #include "pkc/rsa.h"
38 #include "pkc/dsa.h"
39 #include "ecc/ecdsa.h"
40 #include "hash/md5.h"
41 #include "hash/sha1.h"
42 #include "hash/sha224.h"
43 #include "hash/sha256.h"
44 #include "hash/sha384.h"
45 #include "hash/sha512.h"
46 #include "debug.h"
47 
48 //Check crypto library configuration
49 #if (X509_SUPPORT == ENABLED)
50 
51 
52 /**
53  * @brief Parse a X.509 certificate
54  * @param[in] data Pointer to the X.509 certificate to parse
55  * @param[in] length Length of the X.509 certificate
56  * @param[out] certInfo Information resulting from the parsing process
57  * @return Error code
58  **/
59 
60 error_t x509ParseCertificate(const uint8_t *data, size_t length,
61  X509CertificateInfo *certInfo)
62 {
63  error_t error;
64  size_t totalLength;
65  Asn1Tag tag;
66 
67  //Debug message
68  TRACE_DEBUG("Parsing X.509 certificate...\r\n");
69 
70  //Clear the certificate information structure
71  cryptoMemset(certInfo, 0, sizeof(X509CertificateInfo));
72 
73  //Where pathLenConstraint does not appear, no limit is imposed
75 
76  //Read the contents of the certificate
77  error = asn1ReadTag(data, length, &tag);
78  //Failed to decode ASN.1 tag?
79  if(error)
80  return ERROR_BAD_CERTIFICATE;
81 
82  //Point to the very first field
83  data = tag.value;
84  length = tag.length;
85 
86  //Parse TBSCertificate structure
87  error = x509ParseTbsCertificate(data, length, &totalLength, certInfo);
88  //Any error to report?
89  if(error)
90  return ERROR_BAD_CERTIFICATE;
91 
92  //Point to the next field
93  data += totalLength;
94  length -= totalLength;
95 
96  //Parse SignatureAlgorithm structure
97  error = x509ParseSignatureAlgo(data, length, &totalLength,
98  &certInfo->signatureAlgo);
99  //Any error to report?
100  if(error)
101  return ERROR_BAD_CERTIFICATE;
102 
103  //Point to the next field
104  data += totalLength;
105  length -= totalLength;
106 
107  //Parse SignatureValue structure
108  error = x509ParseSignatureValue(data, length, &totalLength,
109  &certInfo->signatureValue);
110  //Any error to report?
111  if(error)
112  return ERROR_BAD_CERTIFICATE;
113 
114  //Certificate successfully parsed
115  return NO_ERROR;
116 }
117 
118 
119 /**
120  * @brief Parse TBSCertificate structure
121  * @param[in] data Pointer to the ASN.1 structure to parse
122  * @param[in] length Length of the ASN.1 structure
123  * @param[out] totalLength Number of bytes that have been parsed
124  * @param[out] certInfo Information resulting from the parsing process
125  * @return Error code
126  **/
127 
129  size_t *totalLength, X509CertificateInfo *certInfo)
130 {
131  error_t error;
132  size_t n;
133  Asn1Tag tag;
134 
135  //Debug message
136  TRACE_DEBUG(" Parsing TBSCertificate...\r\n");
137 
138  //Read the contents of the TBSCertificate structure
139  error = asn1ReadTag(data, length, &tag);
140  //Failed to decode ASN.1 tag?
141  if(error)
142  return error;
143 
144  //Save the total length of the field
145  *totalLength = tag.totalLength;
146 
147  //The ASN.1 DER encoded TBSCertificate is used as the input to the
148  //signature function
149  certInfo->tbsCertificate = data;
150  certInfo->tbsCertificateLen = tag.totalLength;
151 
152  //Point to the very first field of the TBSCertificate
153  data = tag.value;
154  length = tag.length;
155 
156  //Parse Version field
157  error = x509ParseVersion(data, length, &n, &certInfo->version);
158  //Any parsing error?
159  if(error)
160  return error;
161 
162  //Point to the next field
163  data += n;
164  length -= n;
165 
166  //Parse SerialNumber field
167  error = x509ParseSerialNumber(data, length, &n, &certInfo->serialNumber);
168  //Any parsing error?
169  if(error)
170  return error;
171 
172  //Point to the next field
173  data += n;
174  length -= n;
175 
176  //Parse Signature field
177  error = x509ParseSignature(data, length, &n, &certInfo->signatureAlgo);
178  //Any parsing error?
179  if(error)
180  return error;
181 
182  //Point to the next field
183  data += n;
184  length -= n;
185 
186  //Parse Issuer field
187  error = x509ParseName(data, length, &n, &certInfo->issuer);
188  //Any parsing error?
189  if(error)
190  return error;
191 
192  //Point to the next field
193  data += n;
194  length -= n;
195 
196  //Parse Validity field
197  error = x509ParseValidity(data, length, &n, &certInfo->validity);
198  //Any parsing error?
199  if(error)
200  return error;
201 
202  //Point to the next field
203  data += n;
204  length -= n;
205 
206  //Parse Subject field
207  error = x509ParseName(data, length, &n, &certInfo->subject);
208  //Any parsing error?
209  if(error)
210  return error;
211 
212  //Point to the next field
213  data += n;
214  length -= n;
215 
216  //Parse SubjectPublicKeyInfo field
218  &certInfo->subjectPublicKeyInfo);
219  //Any parsing error?
220  if(error)
221  return error;
222 
223  //Point to the next field
224  data += n;
225  length -= n;
226 
227  //Parse IssuerUniqueID field
228  error = x509ParseIssuerUniqueId(data, length, &n);
229  //Any parsing error?
230  if(error)
231  return error;
232 
233  //The IssuerUniqueID field is optional
234  if(n > 0)
235  {
236  //This field must only appear if the version is 2 or 3
237  if(certInfo->version < X509_VERSION_2)
238  return ERROR_INVALID_VERSION;
239  }
240 
241  //Point to the next field
242  data += n;
243  length -= n;
244 
245  //Parse SubjectUniqueID field
247  //Any parsing error?
248  if(error)
249  return error;
250 
251  //The SubjectUniqueID field is optional
252  if(n > 0)
253  {
254  //This field must only appear if the version is 2 or 3
255  if(certInfo->version < X509_VERSION_2)
256  return ERROR_INVALID_VERSION;
257  }
258 
259  //Point to the next field
260  data += n;
261  length -= n;
262 
263  //Parse Extensions field
264  error = x509ParseExtensions(data, length, &n, &certInfo->extensions);
265  //Any parsing error?
266  if(error)
267  return error;
268 
269  //The Extensions field is optional
270  if(n > 0)
271  {
272  //This field must only appear if the version is 3
273  if(certInfo->version < X509_VERSION_3)
274  return ERROR_INVALID_VERSION;
275  }
276 
277  //No error to report
278  return NO_ERROR;
279 }
280 
281 
282 /**
283  * @brief Parse Version field
284  * @param[in] data Pointer to the ASN.1 structure to parse
285  * @param[in] length Length of the ASN.1 structure
286  * @param[out] totalLength Number of bytes that have been parsed
287  * @param[out] version Information resulting from the parsing process
288  * @return Error code
289  **/
290 
291 error_t x509ParseVersion(const uint8_t *data, size_t length,
292  size_t *totalLength, X509Version *version)
293 {
294  error_t error;
295  int32_t value;
296  Asn1Tag tag;
297 
298  //Debug message
299  TRACE_DEBUG(" Parsing Version...\r\n");
300 
301  //Explicit tagging shall be used to encode version
302  error = asn1ReadTag(data, length, &tag);
303  //Failed to decode ASN.1 tag?
304  if(error)
305  return error;
306 
307  //Enforce encoding, class and type
308  error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_CONTEXT_SPECIFIC, 0);
309 
310  //The tag does not match the criteria?
311  if(error)
312  {
313  //Assume X.509 version 1 format
315  //Skip the current field
316  *totalLength = 0;
317 
318  //Exit immediately
319  return NO_ERROR;
320  }
321 
322  //Save the total length of the field
323  *totalLength = tag.totalLength;
324 
325  //Read the inner tag
326  error = asn1ReadInt32(tag.value, tag.length, &tag, &value);
327  //Failed to decode ASN.1 tag?
328  if(error)
329  return error;
330 
331  //Check version field
332  if(value > X509_VERSION_3)
333  return ERROR_INVALID_VERSION;
334 
335  //Save certificate version
337 
338  //No error to report
339  return NO_ERROR;
340 }
341 
342 
343 /**
344  * @brief Parse SerialNumber field
345  * @param[in] data Pointer to the ASN.1 structure to parse
346  * @param[in] length Length of the ASN.1 structure
347  * @param[out] totalLength Number of bytes that have been parsed
348  * @param[out] serialNumber Information resulting from the parsing process
349  * @return Error code
350  **/
351 
352 error_t x509ParseSerialNumber(const uint8_t *data, size_t length,
353  size_t *totalLength, X509SerialNumber *serialNumber)
354 {
355  error_t error;
356  Asn1Tag tag;
357 
358  //Debug message
359  TRACE_DEBUG(" Parsing SerialNumber...\r\n");
360 
361  //Read the contents of the SerialNumber structure
362  error = asn1ReadTag(data, length, &tag);
363  //Failed to decode ASN.1 tag?
364  if(error)
365  return error;
366 
367  //Save the total length of the field
368  *totalLength = tag.totalLength;
369 
370  //Enforce encoding, class and type
372  //The tag does not match the criteria?
373  if(error)
374  return error;
375 
376  //Conforming CAs must not use serialNumber values longer than 20 octets
377  //(refer to RFC 5280, section 4.1.2.2)
378  if(tag.length < 1 || tag.length > 20)
379  return ERROR_INVALID_SYNTAX;
380 
381  //Non-conforming CAs may issue certificates with serial numbers that are
382  //negative or zero. Certificate users should be prepared to gracefully
383  //handle such certificates (refer to RFC 5280, section 4.1.2.2)
384  serialNumber->data = tag.value;
385  serialNumber->length = tag.length;
386 
387  //No error to report
388  return NO_ERROR;
389 }
390 
391 
392 /**
393  * @brief Parse Signature field
394  * @param[in] data Pointer to the ASN.1 structure to parse
395  * @param[in] length Length of the ASN.1 structure
396  * @param[out] totalLength Number of bytes that have been parsed
397  * @param[out] signature Information resulting from the parsing process
398  * @return Error code
399  **/
400 
401 error_t x509ParseSignature(const uint8_t *data, size_t length,
402  size_t *totalLength, X509SignatureAlgoId *signature)
403 {
404  error_t error;
405  Asn1Tag tag;
406 
407  //Debug message
408  TRACE_DEBUG(" Parsing Signature...\r\n");
409 
410  //Read the contents of the Signature structure
411  error = asn1ReadSequence(data, length, &tag);
412  //Failed to decode ASN.1 tag?
413  if(error)
414  return error;
415 
416  //Save the total length of the field
417  *totalLength = tag.totalLength;
418 
419  //Point to the first field of the sequence
420  data = tag.value;
421  length = tag.length;
422 
423  //Read signature algorithm identifier
424  error = asn1ReadTag(data, length, &tag);
425  //Failed to decode ASN.1 tag?
426  if(error)
427  return error;
428 
429  //Enforce encoding, class and type
430  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
432  //The tag does not match the criteria?
433  if(error)
434  return error;
435 
436  //Save the signature algorithm identifier
437  signature->oid = tag.value;
438  signature->oidLen = tag.length;
439 
440  //Point to the next field (if any)
441  data += tag.totalLength;
442  length -= tag.totalLength;
443 
444 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
445  //RSASSA-PSS algorithm identifier?
446  if(!asn1CheckOid(&tag, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
447  {
448  //Read RSASSA-PSS parameters
449  error = x509ParseRsaPssParameters(data, length, &signature->rsaPssParams);
450  }
451  else
452 #endif
453  //Unknown algorithm identifier?
454  {
455  //The parameters are optional
456  error = NO_ERROR;
457  }
458 
459  //Return status code
460  return error;
461 }
462 
463 
464 /**
465  * @brief Parse RSASSA-PSS parameters
466  * @param[in] data Pointer to the ASN.1 structure to parse
467  * @param[in] length Length of the ASN.1 structure
468  * @param[out] rsaPssParams Information resulting from the parsing process
469  * @return Error code
470  **/
471 
473  X509RsaPssParameters *rsaPssParams)
474 {
475 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
476  error_t error;
477  Asn1Tag tag;
478 
479 #if(X509_SHA1_SUPPORT == ENABLED && SHA1_SUPPORT == ENABLED)
480  //The default hash algorithm is SHA-1 (refer to RFC 4055, section 3.1)
481  rsaPssParams->hashAlgo = SHA1_OID;
482  rsaPssParams->hashAlgoLen = sizeof(SHA1_OID);
483 #endif
484 
485  //The default length of the salt is 20 (refer to RFC 4055, section 3.1)
486  rsaPssParams->saltLen = 20;
487 
488  //Read the contents of the structure
489  error = asn1ReadSequence(data, length, &tag);
490  //Failed to decode ASN.1 tag?
491  if(error)
492  return error;
493 
494  //Point to the first field of the sequence
495  data = tag.value;
496  length = tag.length;
497 
498  //Parse RSASSA-PSS parameters
499  while(length > 0)
500  {
501  //Read current parameter
502  error = asn1ReadTag(data, length, &tag);
503  //Failed to decode ASN.1 tag?
504  if(error)
505  return error;
506 
507  //The tags in this sequence are explicit
509  {
510  //Parse hashAlgorithm field
511  error = x509ParseRsaPssHashAlgo(tag.value, tag.length, rsaPssParams);
512  //Any error to report?
513  if(error)
514  return error;
515  }
516  else if(!asn1CheckTag(&tag, TRUE, ASN1_CLASS_CONTEXT_SPECIFIC, 2))
517  {
518  //Parse saltLength field
519  error = x509ParseRsaPssSaltLength(tag.value, tag.length, rsaPssParams);
520  //Any error to report?
521  if(error)
522  return error;
523  }
524 
525  //Next parameter
526  data += tag.totalLength;
527  length -= tag.totalLength;
528  }
529 
530  //Successful processing
531  return NO_ERROR;
532 #else
533  //Not implemented
534  return ERROR_NOT_IMPLEMENTED;
535 #endif
536 }
537 
538 
539 /**
540  * @brief Parse RSASSA-PSS hash algorithm
541  * @param[in] data Pointer to the ASN.1 structure to parse
542  * @param[in] length Length of the ASN.1 structure
543  * @param[out] rsaPssParams Information resulting from the parsing process
544  * @return Error code
545  **/
546 
548  X509RsaPssParameters *rsaPssParams)
549 {
550 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
551  error_t error;
552  Asn1Tag tag;
553 
554  //Read the contents of the structure
555  error = asn1ReadSequence(data, length, &tag);
556  //Failed to decode ASN.1 tag?
557  if(error)
558  return error;
559 
560  //Point to the first field of the sequence
561  data = tag.value;
562  length = tag.length;
563 
564  //Read hash algorithm identifier
565  error = asn1ReadTag(data, length, &tag);
566  //Failed to decode ASN.1 tag?
567  if(error)
568  return error;
569 
570  //Enforce encoding, class and type
571  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
573  //The tag does not match the criteria?
574  if(error)
575  return error;
576 
577  //Save the hash algorithm identifier
578  rsaPssParams->hashAlgo = tag.value;
579  rsaPssParams->hashAlgoLen = tag.length;
580 
581  //No error to report
582  return NO_ERROR;
583 #else
584  //Not implemented
585  return ERROR_NOT_IMPLEMENTED;
586 #endif
587 }
588 
589 
590 /**
591  * @brief Parse RSASSA-PSS salt length
592  * @param[in] data Pointer to the ASN.1 structure to parse
593  * @param[in] length Length of the ASN.1 structure
594  * @param[out] rsaPssParams Information resulting from the parsing process
595  * @return Error code
596  **/
597 
599  X509RsaPssParameters *rsaPssParams)
600 {
601 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
602  error_t error;
603  int32_t saltLen;
604  Asn1Tag tag;
605 
606  //Read the saltLength field
607  error = asn1ReadInt32(data, length, &tag, &saltLen);
608  //Failed to decode ASN.1 tag?
609  if(error)
610  return error;
611 
612  //Sanity check
613  if(saltLen < 0)
614  return ERROR_INVALID_SYNTAX;
615 
616  //Save the length of the salt
617  rsaPssParams->saltLen = saltLen;
618 
619  //No error to report
620  return NO_ERROR;
621 #else
622  //Not implemented
623  return ERROR_NOT_IMPLEMENTED;
624 #endif
625 }
626 
627 
628 /**
629  * @brief Parse Name structure
630  * @param[in] data Pointer to the ASN.1 structure to parse
631  * @param[in] length Length of the ASN.1 structure
632  * @param[out] totalLength Number of bytes that have been parsed
633  * @param[out] name Information resulting from the parsing process
634  * @return Error code
635  **/
636 
637 error_t x509ParseName(const uint8_t *data, size_t length,
638  size_t *totalLength, X509Name *name)
639 {
640  error_t error;
641  size_t n;
642  Asn1Tag tag;
643  X509NameAttribute nameAttribute;
644 
645  //Debug message
646  TRACE_DEBUG(" Parsing Name...\r\n");
647 
648  //Read the contents of the Name structure
649  error = asn1ReadSequence(data, length, &tag);
650  //Failed to decode ASN.1 tag?
651  if(error)
652  return error;
653 
654  //Save the total length of the field
655  *totalLength = tag.totalLength;
656 
657  //Raw ASN.1 sequence
658  name->rawData = data;
659  name->rawDataLen = tag.totalLength;
660 
661  //The Name describes a hierarchical name composed of attributes
662  data = tag.value;
663  length = tag.length;
664 
665  //Loop through all the attributes
666  while(length > 0)
667  {
668  //Read current attribute
669  error = x509ParseNameAttribute(data, length, &n, &nameAttribute);
670  //Any error to report?
671  if(error)
672  return error;
673 
674  //Common Name attribute found?
675  if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
677  {
678  name->commonName = nameAttribute.value;
679  name->commonNameLen = nameAttribute.valueLen;
680  }
681  //Surname attribute found?
682  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
684  {
685  name->surname = nameAttribute.value;
686  name->surnameLen = nameAttribute.valueLen;
687  }
688  //Serial Number attribute found?
689  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
691  {
692  name->serialNumber = nameAttribute.value;
693  name->serialNumberLen = nameAttribute.valueLen;
694  }
695  //Country Name attribute found?
696  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
698  {
699  name->countryName = nameAttribute.value;
700  name->countryNameLen = nameAttribute.valueLen;
701  }
702  //Locality Name attribute found?
703  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
705  {
706  name->localityName = nameAttribute.value;
707  name->localityNameLen = nameAttribute.valueLen;
708  }
709  //State Or Province Name attribute found?
710  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
712  {
713  name->stateOrProvinceName = nameAttribute.value;
714  name->stateOrProvinceNameLen = nameAttribute.valueLen;
715  }
716  //Organization Name attribute found?
717  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
719  {
720  name->organizationName = nameAttribute.value;
721  name->organizationNameLen = nameAttribute.valueLen;
722  }
723  //Organizational Unit Name attribute found?
724  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
726  {
727  name->organizationalUnitName = nameAttribute.value;
728  name->organizationalUnitNameLen = nameAttribute.valueLen;
729  }
730  //Title attribute found?
731  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
732  X509_TITLE_OID, sizeof(X509_TITLE_OID)))
733  {
734  name->title = nameAttribute.value;
735  name->titleLen = nameAttribute.valueLen;
736  }
737  //Name attribute found?
738  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
739  X509_NAME_OID, sizeof(X509_NAME_OID)))
740  {
741  name->name = nameAttribute.value;
742  name->nameLen = nameAttribute.valueLen;
743  }
744  //Given Name attribute found?
745  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
747  {
748  name->givenName = nameAttribute.value;
749  name->givenNameLen = nameAttribute.valueLen;
750  }
751  //Initials attribute OID (2.5.4.43)
752  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
754  {
755  name->initials = nameAttribute.value;
756  name->initialsLen = nameAttribute.valueLen;
757  }
758  //Generation Qualifier attribute found?
759  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
761  {
762  name->generationQualifier = nameAttribute.value;
763  name->generationQualifierLen = nameAttribute.valueLen;
764  }
765  //DN Qualifier attribute found?
766  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
768  {
769  name->dnQualifier = nameAttribute.value;
770  name->dnQualifierLen = nameAttribute.valueLen;
771  }
772  //Pseudonym attribute found?
773  else if(!oidComp(nameAttribute.type, nameAttribute.typeLen,
775  {
776  name->pseudonym = nameAttribute.value;
777  name->pseudonymLen = nameAttribute.valueLen;
778  }
779  //Unknown attribute?
780  else
781  {
782  //Discard current attribute
783  }
784 
785  //Next attribute
786  data += n;
787  length -= n;
788  }
789 
790  //Name field successfully parsed
791  return NO_ERROR;
792 }
793 
794 
795 /**
796  * @brief Parse name attribute
797  * @param[in] data Pointer to the ASN.1 structure to parse
798  * @param[in] length Length of the ASN.1 structure
799  * @param[out] totalLength Number of bytes that have been parsed
800  * @param[out] nameAttribute Information resulting from the parsing process
801  * @return Error code
802  **/
803 
804 error_t x509ParseNameAttribute(const uint8_t *data, size_t length,
805  size_t *totalLength, X509NameAttribute *nameAttribute)
806 {
807  error_t error;
808  Asn1Tag tag;
809 
810  //Attributes are encapsulated within a set
811  error = asn1ReadTag(data, length, &tag);
812  //Failed to decode ASN.1 tag?
813  if(error)
814  return error;
815 
816  //Enforce encoding, class and type
818  //The tag does not match the criteria?
819  if(error)
820  return error;
821 
822  //Save the total length of the attribute
823  *totalLength = tag.totalLength;
824 
825  //Read the first field of the set
826  error = asn1ReadSequence(tag.value, tag.length, &tag);
827  //Failed to decode ASN.1 tag?
828  if(error)
829  return error;
830 
831  //Point to the first field of the sequence
832  data = tag.value;
833  length = tag.length;
834 
835  //Read attribute type
836  error = asn1ReadTag(data, length, &tag);
837  //Failed to decode ASN.1 tag?
838  if(error)
839  return error;
840 
841  //Enforce encoding, class and type
842  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
844  //The tag does not match the criteria?
845  if(error)
846  return error;
847 
848  //Save attribute type
849  nameAttribute->type = tag.value;
850  nameAttribute->typeLen = tag.length;
851 
852  //Point to the next field
853  data += tag.totalLength;
854  length -= tag.totalLength;
855 
856  //Read attribute value
857  error = asn1ReadTag(data, length, &tag);
858  //Failed to decode ASN.1 tag?
859  if(error)
860  return error;
861 
862  //Save attribute value
863  nameAttribute->value = (char_t *) tag.value;
864  nameAttribute->valueLen = tag.length;
865 
866  //Successful processing
867  return NO_ERROR;
868 }
869 
870 
871 /**
872  * @brief Parse Validity structure
873  * @param[in] data Pointer to the ASN.1 structure to parse
874  * @param[in] length Length of the ASN.1 structure
875  * @param[out] totalLength Number of bytes that have been parsed
876  * @param[out] validity Information resulting from the parsing process
877  * @return Error code
878  **/
879 
880 error_t x509ParseValidity(const uint8_t *data, size_t length,
881  size_t *totalLength, X509Validity *validity)
882 {
883  error_t error;
884  size_t n;
885  Asn1Tag tag;
886 
887  //Debug message
888  TRACE_DEBUG(" Parsing Validity...\r\n");
889 
890  //Read the contents of the Validity structure
891  error = asn1ReadSequence(data, length, &tag);
892  //Failed to decode ASN.1 tag?
893  if(error)
894  return error;
895 
896  //Save the total length of the field
897  *totalLength = tag.totalLength;
898 
899  //Point to the very first field of the sequence
900  data = tag.value;
901  length = tag.length;
902 
903  //The NotBefore field may be encoded as UTCTime or GeneralizedTime
904  error = x509ParseTime(data, length, &n, &validity->notBefore);
905  //Failed to decode ASN.1 tag?
906  if(error)
907  return error;
908 
909  //Point to the next field
910  data += n;
911  length -= n;
912 
913  //The NotAfter field may be encoded as UTCTime or GeneralizedTime
914  error = x509ParseTime(data, length, &n, &validity->notAfter);
915  //Failed to decode ASN.1 tag?
916  if(error)
917  return error;
918 
919  //Validity field successfully parsed
920  return NO_ERROR;
921 }
922 
923 
924 /**
925  * @brief Parse UTCTime or GeneralizedTime field
926  * @param[in] data Pointer to the ASN.1 structure to parse
927  * @param[in] length Length of the ASN.1 structure
928  * @param[out] totalLength Number of bytes that have been parsed
929  * @param[out] dateTime date resulting from the parsing process
930  * @return Error code
931  **/
932 
933 error_t x509ParseTime(const uint8_t *data, size_t length,
934  size_t *totalLength, DateTime *dateTime)
935 {
936  error_t error;
937  uint_t value;
938  Asn1Tag tag;
939 
940  //Debug message
941  TRACE_DEBUG(" Parsing Time...\r\n");
942 
943  //Read current ASN.1 tag
944  error = asn1ReadTag(data, length, &tag);
945  //Failed to decode ASN.1 tag?
946  if(error)
947  return error;
948 
949  //Save the total length of the field
950  *totalLength = tag.totalLength;
951 
952  //The date may be encoded as UTCTime or GeneralizedTime
954  {
955  //Check the length of the UTCTime field
956  if(tag.length != 13)
957  return ERROR_INVALID_SYNTAX;
958 
959  //The UTCTime uses a 2-digit representation of the year
960  error = x509ReadInt(tag.value, 2, &value);
961  //Any error to report?
962  if(error)
963  return error;
964 
965  //If YY is greater than or equal to 50, the year shall be interpreted
966  //as 19YY. If YY is less than 50, the year shall be interpreted as 20YY
967  if(value >= 50)
968  dateTime->year = 1900 + value;
969  else
970  dateTime->year = 2000 + value;
971 
972  //Point to the next field
973  data = tag.value + 2;
974  }
976  {
977  //Check the length of the GeneralizedTime field
978  if(tag.length != 15)
979  return ERROR_INVALID_SYNTAX;
980 
981  //The GeneralizedTime uses a 4-digit representation of the year
982  error = x509ReadInt(tag.value, 4, &value);
983  //Any error to report?
984  if(error)
985  return error;
986 
987  //Save the resulting value
988  dateTime->year = value;
989 
990  //Point to the next field
991  data = tag.value + 4;
992  }
993  else
994  {
995  //The tag does not contain a valid date
996  return ERROR_FAILURE;
997  }
998 
999  //Month
1000  error = x509ReadInt(data, 2, &value);
1001  //Any error to report?
1002  if(error)
1003  return error;
1004 
1005  //Save the resulting value
1006  dateTime->month = value;
1007 
1008  //Day
1009  error = x509ReadInt(data + 2, 2, &value);
1010  //Any error to report?
1011  if(error)
1012  return error;
1013 
1014  //Save the resulting value
1015  dateTime->day = value;
1016 
1017  //Hours
1018  error = x509ReadInt(data + 4, 2, &value);
1019  //Any error to report?
1020  if(error)
1021  return error;
1022 
1023  //Save the resulting value
1024  dateTime->hours = value;
1025 
1026  //Minutes
1027  error = x509ReadInt(data + 6, 2, &value);
1028  //Any error to report?
1029  if(error)
1030  return error;
1031 
1032  //Save the resulting value
1033  dateTime->minutes = value;
1034 
1035  //Seconds
1036  error = x509ReadInt(data + 8, 2, &value);
1037  //Any error to report?
1038  if(error)
1039  return error;
1040 
1041  //The encoding shall terminate with a "Z"
1042  if(data[10] != 'Z')
1043  return ERROR_INVALID_SYNTAX;
1044 
1045  //Save the resulting value
1046  dateTime->seconds = value;
1047 
1048  //Milliseconds
1049  dateTime->milliseconds = 0;
1050 
1051  //UTCTime or GeneralizedTime field successfully parsed
1052  return NO_ERROR;
1053 }
1054 
1055 
1056 /**
1057  * @brief Parse SubjectPublicKeyInfo structure
1058  * @param[in] data Pointer to the ASN.1 structure to parse
1059  * @param[in] length Length of the ASN.1 structure
1060  * @param[out] totalLength Number of bytes that have been parsed
1061  * @param[out] subjectPublicKeyInfo Information resulting from the parsing process
1062  * @return Error code
1063  **/
1064 
1066  size_t *totalLength, X509SubjectPublicKeyInfo *subjectPublicKeyInfo)
1067 {
1068  error_t error;
1069  size_t n;
1070  size_t oidLen;
1071  const uint8_t *oid;
1072  Asn1Tag tag;
1073 
1074  //Debug message
1075  TRACE_DEBUG(" Parsing SubjectPublicKeyInfo...\r\n");
1076 
1077  //Read SubjectPublicKeyInfo field
1078  error = asn1ReadSequence(data, length, &tag);
1079  //Failed to decode ASN.1 tag?
1080  if(error)
1081  return error;
1082 
1083  //Save the total length of the field
1084  *totalLength = tag.totalLength;
1085 
1086  //Raw ASN.1 sequence
1087  subjectPublicKeyInfo->rawData = data;
1088  subjectPublicKeyInfo->rawDataLen = tag.totalLength;
1089 
1090  //Point to the first field
1091  data = tag.value;
1092  length = tag.length;
1093 
1094  //Read AlgorithmIdentifier field
1095  error = x509ParseAlgorithmIdentifier(data, length, &n, subjectPublicKeyInfo);
1096  //Any error to report?
1097  if(error)
1098  return error;
1099 
1100  //Point to the next field
1101  data += n;
1102  length -= n;
1103 
1104  //The SubjectPublicKey structure is encapsulated within a bit string
1105  error = asn1ReadTag(data, length, &tag);
1106  //Failed to decode ASN.1 tag?
1107  if(error)
1108  return error;
1109 
1110  //Enforce encoding, class and type
1112  //The tag does not match the criteria?
1113  if(error)
1114  return error;
1115 
1116  //The bit string shall contain an initial octet which encodes the number
1117  //of unused bits in the final subsequent octet
1118  if(tag.length < 1 || tag.value[0] != 0x00)
1119  return ERROR_FAILURE;
1120 
1121  //Retrieve signature algorithm identifier
1122  oid = subjectPublicKeyInfo->oid;
1123  oidLen = subjectPublicKeyInfo->oidLen;
1124 
1125 #if (X509_RSA_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
1126  //RSA algorithm identifier?
1127  if(!oidComp(oid, oidLen, RSA_ENCRYPTION_OID, sizeof(RSA_ENCRYPTION_OID)))
1128  {
1129  //Read RSAPublicKey structure
1130  error = x509ParseRsaPublicKey(tag.value + 1, tag.length - 1,
1131  &subjectPublicKeyInfo->rsaPublicKey);
1132  }
1133  else
1134 #endif
1135 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
1136  //RSA-PSS algorithm identifier?
1137  if(!oidComp(oid, oidLen, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
1138  {
1139  //Read RSAPublicKey structure
1140  error = x509ParseRsaPublicKey(tag.value + 1, tag.length - 1,
1141  &subjectPublicKeyInfo->rsaPublicKey);
1142  }
1143  else
1144 #endif
1145 #if (X509_DSA_SUPPORT == ENABLED && DSA_SUPPORT == ENABLED)
1146  //DSA algorithm identifier?
1147  if(!oidComp(oid, oidLen, DSA_OID, sizeof(DSA_OID)))
1148  {
1149  //Read DSAPublicKey structure
1150  error = x509ParseDsaPublicKey(tag.value + 1, tag.length - 1,
1151  &subjectPublicKeyInfo->dsaPublicKey);
1152  }
1153  else
1154 #endif
1155 #if (X509_ECDSA_SUPPORT == ENABLED && ECDSA_SUPPORT == ENABLED)
1156  //EC public key identifier?
1157  if(!oidComp(oid, oidLen, EC_PUBLIC_KEY_OID, sizeof(EC_PUBLIC_KEY_OID)))
1158  {
1159  //Read ECPublicKey structure
1160  error = x509ParseEcPublicKey(tag.value + 1, tag.length - 1,
1161  &subjectPublicKeyInfo->ecPublicKey);
1162  }
1163  else
1164 #endif
1165 #if (X509_ED25519_SUPPORT == ENABLED && ED25519_SUPPORT == ENABLED)
1166  //X25519 or Ed25519 algorithm identifier?
1167  if(!oidComp(oid, oidLen, X25519_OID, sizeof(X25519_OID)) ||
1168  !oidComp(oid, oidLen, ED25519_OID, sizeof(ED25519_OID)))
1169  {
1170  //Read ECPublicKey structure
1171  error = x509ParseEcPublicKey(tag.value + 1, tag.length - 1,
1172  &subjectPublicKeyInfo->ecPublicKey);
1173  }
1174  else
1175 #endif
1176 #if (X509_ED448_SUPPORT == ENABLED && ED448_SUPPORT == ENABLED)
1177  //X448 or Ed448 algorithm identifier?
1178  if(!oidComp(oid, oidLen, X448_OID, sizeof(X448_OID)) ||
1179  !oidComp(oid, oidLen, ED448_OID, sizeof(ED448_OID)))
1180  {
1181  //Read ECPublicKey structure
1182  error = x509ParseEcPublicKey(tag.value + 1, tag.length - 1,
1183  &subjectPublicKeyInfo->ecPublicKey);
1184  }
1185  else
1186 #endif
1187  //The certificate does not contain any valid public key...
1188  {
1189  //Report an error
1190  error = ERROR_BAD_CERTIFICATE;
1191  }
1192 
1193  //Return status code
1194  return error;
1195 }
1196 
1197 
1198 /**
1199  * @brief Parse AlgorithmIdentifier structure
1200  * @param[in] data Pointer to the ASN.1 structure to parse
1201  * @param[in] length Length of the ASN.1 structure
1202  * @param[out] totalLength Number of bytes that have been parsed
1203  * @param[out] subjectPublicKeyInfo Information resulting from the parsing process
1204  * @return Error code
1205  **/
1206 
1208  size_t *totalLength, X509SubjectPublicKeyInfo *subjectPublicKeyInfo)
1209 {
1210  error_t error;
1211  Asn1Tag tag;
1212 
1213  //Debug message
1214  TRACE_DEBUG(" Parsing AlgorithmIdentifier...\r\n");
1215 
1216  //Read AlgorithmIdentifier field
1217  error = asn1ReadSequence(data, length, &tag);
1218  //Failed to decode ASN.1 tag?
1219  if(error)
1220  return error;
1221 
1222  //Save the total length of the field
1223  *totalLength = tag.totalLength;
1224 
1225  //Point to the first field
1226  data = tag.value;
1227  length = tag.length;
1228 
1229  //Read algorithm identifier (OID)
1230  error = asn1ReadTag(data, length, &tag);
1231  //Failed to decode ASN.1 tag?
1232  if(error)
1233  return error;
1234 
1235  //Enforce encoding, class and type
1236  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
1238  //The tag does not match the criteria?
1239  if(error)
1240  return error;
1241 
1242  //Save the algorithm identifier
1243  subjectPublicKeyInfo->oid = tag.value;
1244  subjectPublicKeyInfo->oidLen = tag.length;
1245 
1246  //Point to the next field (if any)
1247  data += tag.totalLength;
1248  length -= tag.totalLength;
1249 
1250 #if (X509_RSA_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
1251  //RSA algorithm identifier?
1253  {
1254  //RSA does not require any additional parameters
1255  error = NO_ERROR;
1256  }
1257  else
1258 #endif
1259 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
1260  //RSA-PSS algorithm identifier?
1261  if(!asn1CheckOid(&tag, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
1262  {
1263  //RSA-PSS does not require any additional parameters
1264  error = NO_ERROR;
1265  }
1266  else
1267 #endif
1268 #if (X509_DSA_SUPPORT == ENABLED && DSA_SUPPORT == ENABLED)
1269  //DSA algorithm identifier?
1270  if(!asn1CheckOid(&tag, DSA_OID, sizeof(DSA_OID)))
1271  {
1272  //Read DsaParameters structure
1274  &subjectPublicKeyInfo->dsaParams);
1275  }
1276  else
1277 #endif
1278 #if (X509_ECDSA_SUPPORT == ENABLED && ECDSA_SUPPORT == ENABLED)
1279  //EC public key identifier?
1280  if(!asn1CheckOid(&tag, EC_PUBLIC_KEY_OID, sizeof(EC_PUBLIC_KEY_OID)))
1281  {
1282  //Read ECParameters structure
1284  &subjectPublicKeyInfo->ecParams);
1285  }
1286  else
1287 #endif
1288 #if (X509_ED25519_SUPPORT == ENABLED && ED25519_SUPPORT == ENABLED)
1289  //X25519 or Ed25519 algorithm identifier?
1290  if(!asn1CheckOid(&tag, X25519_OID, sizeof(X25519_OID)) ||
1291  !asn1CheckOid(&tag, ED25519_OID, sizeof(ED25519_OID)))
1292  {
1293  //For all of the OIDs, the parameters are absent
1294  error = NO_ERROR;
1295  }
1296  else
1297 #endif
1298 #if (X509_ED448_SUPPORT == ENABLED && ED448_SUPPORT == ENABLED)
1299  //X448 or Ed448 algorithm identifier?
1300  if(!asn1CheckOid(&tag, X448_OID, sizeof(X448_OID)) ||
1301  !asn1CheckOid(&tag, ED448_OID, sizeof(ED448_OID)))
1302  {
1303  //For all of the OIDs, the parameters are absent
1304  error = NO_ERROR;
1305  }
1306  else
1307 #endif
1308  //The certificate does not contain any valid public key...
1309  {
1310  //Report an error
1311  error = ERROR_BAD_CERTIFICATE;
1312  }
1313 
1314  //Return status code
1315  return error;
1316 }
1317 
1318 
1319 /**
1320  * @brief Parse RSAPublicKey structure
1321  * @param[in] data Pointer to the ASN.1 structure to parse
1322  * @param[in] length Length of the ASN.1 structure
1323  * @param[out] rsaPublicKey Information resulting from the parsing process
1324  * @return Error code
1325  **/
1326 
1327 error_t x509ParseRsaPublicKey(const uint8_t *data, size_t length,
1328  X509RsaPublicKey *rsaPublicKey)
1329 {
1330 #if (X509_RSA_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
1331  error_t error;
1332  Asn1Tag tag;
1333 
1334  //Debug message
1335  TRACE_DEBUG(" Parsing RSAPublicKey...\r\n");
1336 
1337  //Read RSAPublicKey structure
1338  error = asn1ReadSequence(data, length, &tag);
1339  //Failed to decode ASN.1 tag?
1340  if(error)
1341  return error;
1342 
1343  //Point to the first field
1344  data = tag.value;
1345  length = tag.length;
1346 
1347  //Read Modulus field
1348  error = asn1ReadTag(data, length, &tag);
1349  //Failed to decode ASN.1 tag?
1350  if(error)
1351  return error;
1352 
1353  //Enforce encoding, class and type
1355  //The tag does not match the criteria?
1356  if(error)
1357  return error;
1358 
1359  //Get the modulus
1360  rsaPublicKey->n = tag.value;
1361  rsaPublicKey->nLen = tag.length;
1362 
1363  //Point to the next field
1364  data += tag.totalLength;
1365  length -= tag.totalLength;
1366 
1367  //Read PublicExponent field
1368  error = asn1ReadTag(data, length, &tag);
1369  //Failed to decode ASN.1 tag?
1370  if(error)
1371  return error;
1372 
1373  //Enforce encoding, class and type
1375  //The tag does not match the criteria?
1376  if(error)
1377  return error;
1378 
1379  //Get the public exponent
1380  rsaPublicKey->e = tag.value;
1381  rsaPublicKey->eLen = tag.length;
1382 
1383  //Successful processing
1384  return NO_ERROR;
1385 #else
1386  //Not implemented
1387  return ERROR_NOT_IMPLEMENTED;
1388 #endif
1389 }
1390 
1391 
1392 /**
1393  * @brief Parse DSA domain parameters
1394  * @param[in] data Pointer to the ASN.1 structure to parse
1395  * @param[in] length Length of the ASN.1 structure
1396  * @param[out] dsaParams Information resulting from the parsing process
1397  * @return Error code
1398  **/
1399 
1401  X509DsaParameters *dsaParams)
1402 {
1403 #if (X509_DSA_SUPPORT == ENABLED && DSA_SUPPORT == ENABLED)
1404  error_t error;
1405  Asn1Tag tag;
1406 
1407  //Debug message
1408  TRACE_DEBUG(" Parsing DSAParameters...\r\n");
1409 
1410  //Read DSAParameters structure
1411  error = asn1ReadSequence(data, length, &tag);
1412  //Failed to decode ASN.1 tag?
1413  if(error)
1414  return error;
1415 
1416  //Point to the first field
1417  data = tag.value;
1418  length = tag.length;
1419 
1420  //Read the parameter p
1421  error = asn1ReadTag(data, length, &tag);
1422  //Failed to decode ASN.1 tag?
1423  if(error)
1424  return error;
1425 
1426  //Enforce encoding, class and type
1428  //The tag does not match the criteria?
1429  if(error)
1430  return error;
1431 
1432  //Save the parameter p
1433  dsaParams->p = tag.value;
1434  dsaParams->pLen = tag.length;
1435 
1436  //Point to the next field
1437  data += tag.totalLength;
1438  length -= tag.totalLength;
1439 
1440  //Read the parameter q
1441  error = asn1ReadTag(data, length, &tag);
1442  //Failed to decode ASN.1 tag?
1443  if(error)
1444  return error;
1445 
1446  //Enforce encoding, class and type
1448  //The tag does not match the criteria?
1449  if(error)
1450  return error;
1451 
1452  //Save the parameter q
1453  dsaParams->q = tag.value;
1454  dsaParams->qLen = tag.length;
1455 
1456  //Point to the next field
1457  data += tag.totalLength;
1458  length -= tag.totalLength;
1459 
1460  //Read the parameter g
1461  error = asn1ReadTag(data, length, &tag);
1462  //Failed to decode ASN.1 tag?
1463  if(error)
1464  return error;
1465 
1466  //Enforce encoding, class and type
1468  //The tag does not match the criteria?
1469  if(error)
1470  return error;
1471 
1472  //Save the parameter g
1473  dsaParams->g = tag.value;
1474  dsaParams->gLen = tag.length;
1475 
1476  //Successful processing
1477  return NO_ERROR;
1478 #else
1479  //Not implemented
1480  return ERROR_NOT_IMPLEMENTED;
1481 #endif
1482 }
1483 
1484 
1485 /**
1486  * @brief Parse DSAPublicKey structure
1487  * @param[in] data Pointer to the ASN.1 structure to parse
1488  * @param[in] length Length of the ASN.1 structure
1489  * @param[out] dsaPublicKey Information resulting from the parsing process
1490  * @return Error code
1491  **/
1492 
1493 error_t x509ParseDsaPublicKey(const uint8_t *data, size_t length,
1494  X509DsaPublicKey *dsaPublicKey)
1495 {
1496 #if (X509_DSA_SUPPORT == ENABLED && DSA_SUPPORT == ENABLED)
1497  error_t error;
1498  Asn1Tag tag;
1499 
1500  //Debug message
1501  TRACE_DEBUG(" Parsing DSAPublicKey...\r\n");
1502 
1503  //Read DSAPublicKey structure
1504  error = asn1ReadTag(data, length, &tag);
1505  //Failed to decode ASN.1 tag?
1506  if(error)
1507  return error;
1508 
1509  //Enforce encoding, class and type
1511  //The tag does not match the criteria?
1512  if(error)
1513  return error;
1514 
1515  //Save the DSA public value
1516  dsaPublicKey->y = tag.value;
1517  dsaPublicKey->yLen = tag.length;
1518 
1519  //Successful processing
1520  return NO_ERROR;
1521 #else
1522  //Not implemented
1523  return ERROR_NOT_IMPLEMENTED;
1524 #endif
1525 }
1526 
1527 
1528 /**
1529  * @brief Parse ECParameters structure
1530  * @param[in] data Pointer to the ASN.1 structure to parse
1531  * @param[in] length Length of the ASN.1 structure
1532  * @param[out] ecParams Information resulting from the parsing process
1533  * @return Error code
1534  **/
1535 
1536 error_t x509ParseEcParameters(const uint8_t *data, size_t length,
1537  X509EcParameters *ecParams)
1538 {
1539 #if (X509_ECDSA_SUPPORT == ENABLED && ECDSA_SUPPORT == ENABLED)
1540  error_t error;
1541  Asn1Tag tag;
1542 
1543  //Debug message
1544  TRACE_DEBUG(" Parsing ECParameters...\r\n");
1545 
1546  //Read namedCurve field
1547  error = asn1ReadTag(data, length, &tag);
1548  //Failed to decode ASN.1 tag?
1549  if(error)
1550  return error;
1551 
1552  //Enforce encoding, class and type
1553  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
1555  //The tag does not match the criteria?
1556  if(error)
1557  return error;
1558 
1559  //The namedCurve field identifies all the required values for a particular
1560  //set of elliptic curve domain parameters to be represented by an object
1561  //identifier
1562  ecParams->namedCurve = tag.value;
1563  ecParams->namedCurveLen = tag.length;
1564 
1565  //Successful processing
1566  return NO_ERROR;
1567 #else
1568  //Not implemented
1569  return ERROR_NOT_IMPLEMENTED;
1570 #endif
1571 }
1572 
1573 
1574 /**
1575  * @brief Parse ECPublicKey structure
1576  * @param[in] data Pointer to the ASN.1 structure to parse
1577  * @param[in] length Length of the ASN.1 structure
1578  * @param[out] ecPublicKey Information resulting from the parsing process
1579  * @return Error code
1580  **/
1581 
1582 error_t x509ParseEcPublicKey(const uint8_t *data, size_t length,
1583  X509EcPublicKey *ecPublicKey)
1584 {
1585 #if ((X509_ECDSA_SUPPORT == ENABLED && ECDSA_SUPPORT == ENABLED) || \
1586  (X509_ED25519_SUPPORT == ENABLED && ED25519_SUPPORT == ENABLED) || \
1587  (X509_ED448_SUPPORT == ENABLED && ED448_SUPPORT == ENABLED))
1588  //Debug message
1589  TRACE_DEBUG(" Parsing ECPublicKey...\r\n");
1590 
1591  //Make sure the EC public key is valid
1592  if(length == 0)
1593  return ERROR_BAD_CERTIFICATE;
1594 
1595  //Save the EC public key
1596  ecPublicKey->q = data;
1597  ecPublicKey->qLen = length;
1598 
1599  //Successful processing
1600  return NO_ERROR;
1601 #else
1602  //Not implemented
1603  return ERROR_NOT_IMPLEMENTED;
1604 #endif
1605 }
1606 
1607 
1608 /**
1609  * @brief Parse IssuerUniqueID structure
1610  * @param[in] data Pointer to the ASN.1 structure to parse
1611  * @param[in] length Length of the ASN.1 structure
1612  * @param[out] totalLength Number of bytes that have been parsed
1613  * @return Error code
1614  **/
1615 
1617  size_t *totalLength)
1618 {
1619  error_t error;
1620  Asn1Tag tag;
1621 
1622  //No more data to process?
1623  if(length == 0)
1624  {
1625  //The IssuerUniqueID field is optional
1626  *totalLength = 0;
1627  //Exit immediately
1628  return NO_ERROR;
1629  }
1630 
1631  //Implicit tagging is used to encode the IssuerUniqueID field
1632  error = asn1ReadTag(data, length, &tag);
1633  //Failed to decode ASN.1 tag?
1634  if(error)
1635  return error;
1636 
1637  //Enforce encoding, class and type
1638  error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_CONTEXT_SPECIFIC, 1);
1639  //The tag does not match the criteria?
1640  if(error)
1641  {
1642  //The IssuerUniqueID field is optional
1643  *totalLength = 0;
1644  //Exit immediately
1645  return NO_ERROR;
1646  }
1647 
1648  //Save the total length of the field
1649  *totalLength = tag.totalLength;
1650 
1651  //Debug message
1652  TRACE_DEBUG(" Parsing IssuerUniqueID...\r\n");
1653 
1654  //Conforming applications should be capable of parsing certificates that
1655  //include unique identifiers, but there are no processing requirements
1656  //associated with the unique identifiers
1657  return NO_ERROR;
1658 }
1659 
1660 
1661 /**
1662  * @brief Parse SubjectUniqueID structure
1663  * @param[in] data Pointer to the ASN.1 structure to parse
1664  * @param[in] length Length of the ASN.1 structure
1665  * @param[out] totalLength Number of bytes that have been parsed
1666  * @return Error code
1667  **/
1668 
1670  size_t *totalLength)
1671 {
1672  error_t error;
1673  Asn1Tag tag;
1674 
1675  //No more data to process?
1676  if(length == 0)
1677  {
1678  //The SubjectUniqueID field is optional
1679  *totalLength = 0;
1680  //Exit immediately
1681  return NO_ERROR;
1682  }
1683 
1684  //Implicit tagging is used to encode the SubjectUniqueID field
1685  error = asn1ReadTag(data, length, &tag);
1686  //Failed to decode ASN.1 tag?
1687  if(error)
1688  return error;
1689 
1690  //Enforce encoding, class and type
1691  error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_CONTEXT_SPECIFIC, 2);
1692  //The tag does not match the criteria?
1693  if(error)
1694  {
1695  //The SubjectUniqueID field is optional
1696  *totalLength = 0;
1697  //Exit immediately
1698  return NO_ERROR;
1699  }
1700 
1701  //Save the total length of the field
1702  *totalLength = tag.totalLength;
1703 
1704  //Debug message
1705  TRACE_DEBUG(" Parsing SubjectUniqueID...\r\n");
1706 
1707  //Conforming applications should be capable of parsing certificates that
1708  //include unique identifiers, but there are no processing requirements
1709  //associated with the unique identifiers
1710  return NO_ERROR;
1711 }
1712 
1713 
1714 /**
1715  * @brief Parse Extensions structure
1716  * @param[in] data Pointer to the ASN.1 structure to parse
1717  * @param[in] length Length of the ASN.1 structure
1718  * @param[out] totalLength Number of bytes that have been parsed
1719  * @param[out] extensions Information resulting from the parsing process
1720  * @return Error code
1721  **/
1722 
1723 error_t x509ParseExtensions(const uint8_t *data, size_t length,
1724  size_t *totalLength, X509Extensions *extensions)
1725 {
1726  error_t error;
1727  bool_t critical;
1728  const uint8_t *extensionData;
1729  size_t extensionLength;
1730  Asn1Tag tag;
1731  Asn1Tag oidTag;
1732 
1733  //No more data to process?
1734  if(length == 0)
1735  {
1736  //The Extensions field is optional
1737  *totalLength = 0;
1738  //Exit immediately
1739  return NO_ERROR;
1740  }
1741 
1742  //Explicit tagging is used to encode the Extensions field
1743  error = asn1ReadTag(data, length, &tag);
1744  //Failed to decode ASN.1 tag?
1745  if(error)
1746  return error;
1747 
1748  //Enforce encoding, class and type
1749  error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_CONTEXT_SPECIFIC, 3);
1750  //The tag does not match the criteria?
1751  if(error)
1752  {
1753  //The Extensions field is optional
1754  *totalLength = 0;
1755  //Exit immediately
1756  return NO_ERROR;
1757  }
1758 
1759  //Save the total length of the field
1760  *totalLength = tag.totalLength;
1761 
1762  //Debug message
1763  TRACE_DEBUG(" Parsing Extensions...\r\n");
1764 
1765  //Read inner tag
1766  error = asn1ReadSequence(tag.value, tag.length, &tag);
1767  //Failed to decode ASN.1 tag?
1768  if(error)
1769  return error;
1770 
1771  //This field is a sequence of one or more certificate extensions
1772  data = tag.value;
1773  length = tag.length;
1774 
1775  //Loop through the extensions
1776  while(length > 0)
1777  {
1778  //Read current extension
1779  error = asn1ReadSequence(data, length, &tag);
1780  //Failed to decode ASN.1 tag?
1781  if(error)
1782  return error;
1783 
1784  //Point to the next extension
1785  data += tag.totalLength;
1786  length -= tag.totalLength;
1787 
1788  //Contents of the current extension
1789  extensionData = tag.value;
1790  extensionLength = tag.length;
1791 
1792  //Read the object identifier
1793  error = asn1ReadTag(extensionData, extensionLength, &oidTag);
1794  //Failed to decode ASN.1 tag?
1795  if(error)
1796  return error;
1797 
1798  //Enforce encoding, class and type
1799  error = asn1CheckTag(&oidTag, FALSE, ASN1_CLASS_UNIVERSAL,
1801  //The tag does not match the criteria?
1802  if(error)
1803  return error;
1804 
1805  //Next item
1806  extensionData += oidTag.totalLength;
1807  extensionLength -= oidTag.totalLength;
1808 
1809  //Read the Critical flag (if present)
1810  error = asn1ReadTag(extensionData, extensionLength, &tag);
1811  //Failed to decode ASN.1 tag?
1812  if(error)
1813  return error;
1814 
1815  //Enforce encoding, class and type
1817 
1818  //Check whether the Critical field is present
1819  if(!error)
1820  {
1821  //Make sure the length of the boolean is valid
1822  if(tag.length != 1)
1823  return ERROR_INVALID_LENGTH;
1824 
1825  //Each extension in a certificate is designated as either critical
1826  //or non-critical
1827  critical = tag.value[0] ? TRUE : FALSE;
1828 
1829  //Next item
1830  extensionData += tag.totalLength;
1831  extensionLength -= tag.totalLength;
1832  }
1833  else
1834  {
1835  //The extension is considered as non-critical
1836  critical = FALSE;
1837  }
1838 
1839  //The extension itself is encapsulated in an octet string
1840  error = asn1ReadTag(extensionData, extensionLength, &tag);
1841  //Failed to decode ASN.1 tag?
1842  if(error)
1843  return error;
1844 
1845  //Enforce encoding, class and type
1846  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
1848  //The tag does not match the criteria?
1849  if(error)
1850  return error;
1851 
1852  //BasicConstraints extension found?
1853  if(!oidComp(oidTag.value, oidTag.length,
1855  {
1856  //Parse BasicConstraints extension
1857  error = x509ParseBasicConstraints(tag.value, tag.length,
1858  &extensions->basicConstraints);
1859  }
1860  //NameConstraints extension found?
1861  else if(!oidComp(oidTag.value, oidTag.length,
1863  {
1864  //Parse NameConstraints extension
1865  error = x509ParseNameConstraints(tag.value, tag.length,
1866  &extensions->nameConstraints);
1867  }
1868 #if 0
1869  //PolicyConstraints extension found?
1870  else if(!oidComp(oidTag.value, oidTag.length,
1872  {
1873  //Parse PolicyConstraints extension
1874  error = x509ParsePolicyConstraints(tag.value, tag.length);
1875  }
1876  //PolicyMappings extension found?
1877  else if(!oidComp(oidTag.value, oidTag.length,
1879  {
1880  //Parse PolicyMappings extension
1881  error = x509ParsePolicyMappings(tag.value, tag.length);
1882  }
1883  //InhibitAnyPolicy extension found?
1884  else if(!oidComp(oidTag.value, oidTag.length,
1886  {
1887  //Parse InhibitAnyPolicy extension
1888  error = x509ParseInhibitAnyPolicy(tag.value, tag.length);
1889  }
1890 #endif
1891  //KeyUsage extension found?
1892  else if(!oidComp(oidTag.value, oidTag.length,
1894  {
1895  //Parse KeyUsage extension
1896  error = x509ParseKeyUsage(tag.value, tag.length,
1897  &extensions->keyUsage);
1898  }
1899  //ExtendedKeyUsage extension found?
1900  else if(!oidComp(oidTag.value, oidTag.length,
1902  {
1903  //Parse ExtendedKeyUsage extension
1904  error = x509ParseExtendedKeyUsage(tag.value, tag.length,
1905  &extensions->extKeyUsage);
1906  }
1907  //SubjectAltName extension found?
1908  else if(!oidComp(oidTag.value, oidTag.length,
1910  {
1911  //Parse SubjectAltName extension
1912  error = x509ParseSubjectAltName(tag.value, tag.length,
1913  &extensions->subjectAltName);
1914  }
1915  //SubjectKeyIdentifier extension found?
1916  else if(!oidComp(oidTag.value, oidTag.length,
1918  {
1919  //Parse SubjectKeyIdentifier extension
1920  error = x509ParseSubjectKeyId(tag.value, tag.length,
1921  &extensions->subjectKeyId);
1922  }
1923  //AuthorityKeyIdentifier extension found?
1924  else if(!oidComp(oidTag.value, oidTag.length,
1926  {
1927  //Parse AuthorityKeyIdentifier extension
1928  error = x509ParseAuthorityKeyId(tag.value, tag.length,
1929  &extensions->authorityKeyId);
1930  }
1931  //NetscapeCertType extension found?
1932  else if(!oidComp(oidTag.value, oidTag.length,
1934  {
1935  //Parse NetscapeCertType extension
1936  error = x509ParseNsCertType(tag.value, tag.length,
1937  &extensions->nsCertType);
1938  }
1939  //Unknown extension?
1940  else
1941  {
1942  //Check if the current extension is marked as critical
1943  if(critical)
1944  {
1945  //An application must reject the certificate if it encounters a
1946  //critical extension it does not recognize or a critical extension
1947  //that contains information that it cannot process
1949  }
1950  }
1951 
1952  //Any error to report?
1953  if(error)
1954  return error;
1955  }
1956 
1957  //Check whether the keyCertSign bit is asserted
1959  {
1960  //If the keyCertSign bit is asserted, then the cA bit in the basic
1961  //constraints extension must also be asserted (refer to RFC 5280,
1962  //section 4.2.1.3)
1963  if(!extensions->basicConstraints.cA)
1964  return ERROR_INVALID_SYNTAX;
1965  }
1966 
1967  //Successful processing
1968  return NO_ERROR;
1969 }
1970 
1971 
1972 /**
1973  * @brief Parse BasicConstraints extension
1974  * @param[in] data Pointer to the ASN.1 structure to parse
1975  * @param[in] length Length of the ASN.1 structure
1976  * @param[out] basicConstraints Information resulting from the parsing process
1977  * @return Error code
1978  **/
1979 
1981  X509BasicConstraints *basicConstraints)
1982 {
1983  error_t error;
1984  int32_t value;
1985  Asn1Tag tag;
1986 
1987  //Debug message
1988  TRACE_DEBUG(" Parsing BasicConstraints...\r\n");
1989 
1990  //The BasicConstraints structure shall contain a valid sequence
1991  error = asn1ReadSequence(data, length, &tag);
1992  //Failed to decode ASN.1 tag?
1993  if(error)
1994  return error;
1995 
1996  //Point to the first item of the sequence
1997  data = tag.value;
1998  length = tag.length;
1999 
2000  //The cA field is optional
2001  if(length > 0)
2002  {
2003  //The cA boolean indicates whether the certified public key may be used
2004  //to verify certificate signatures
2005  error = asn1ReadTag(data, length, &tag);
2006  //Failed to decode ASN.1 tag?
2007  if(error)
2008  return error;
2009 
2010  //Enforce encoding, class and type
2012 
2013  //Check status code
2014  if(!error)
2015  {
2016  //Make sure the length of the boolean is valid
2017  if(tag.length != 1)
2018  return ERROR_INVALID_LENGTH;
2019 
2020  //Get boolean value
2021  basicConstraints->cA = tag.value[0] ? TRUE : FALSE;
2022 
2023  //Point to the next item
2024  data += tag.totalLength;
2025  length -= tag.totalLength;
2026  }
2027  }
2028 
2029  //The pathLenConstraint field is optional
2030  if(length > 0)
2031  {
2032  //Read the pathLenConstraint field
2033  error = asn1ReadInt32(data, length, &tag, &value);
2034  //Failed to decode ASN.1 tag?
2035  if(error)
2036  return error;
2037 
2038  //The pathLenConstraint field is meaningful only if the cA boolean is
2039  //asserted (refer to RFC 5280, section 4.2.1.9)
2040  if(!basicConstraints->cA)
2041  return ERROR_INVALID_SYNTAX;
2042 
2043  //Where it appears, the pathLenConstraint field must be greater than or
2044  //equal to zero (refer to RFC 5280, section 4.2.1.9)
2045  if(value < 0)
2046  return ERROR_INVALID_SYNTAX;
2047 
2048  //The pathLenConstraint field gives the maximum number of non-self-issued
2049  //intermediate certificates that may follow this certificate in a valid
2050  //certification path
2051  basicConstraints->pathLenConstraint = value;
2052  }
2053 
2054  //Successful processing
2055  return NO_ERROR;
2056 }
2057 
2058 
2059 /**
2060  * @brief Parse NameConstraints extension
2061  * @param[in] data Pointer to the ASN.1 structure to parse
2062  * @param[in] length Length of the ASN.1 structure
2063  * @param[out] nameConstraints Information resulting from the parsing process
2064  * @return Error code
2065  **/
2066 
2068  X509NameConstraints *nameConstraints)
2069 {
2070  error_t error;
2071  Asn1Tag tag;
2072 
2073  //Debug message
2074  TRACE_DEBUG(" Parsing NameConstraints...\r\n");
2075 
2076  //The NameConstraints structure shall contain a valid sequence
2077  error = asn1ReadSequence(data, length, &tag);
2078  //Failed to decode ASN.1 tag?
2079  if(error)
2080  return error;
2081 
2082  //Conforming CAs must not issue certificates where name constraints is an
2083  //empty sequence (refer to RFC 5280, section 4.2.1.10)
2084  if(tag.length == 0)
2085  return ERROR_INVALID_SYNTAX;
2086 
2087  //Point to the first item of the sequence
2088  data = tag.value;
2089  length = tag.length;
2090 
2091  //The name constraints extension indicates a name space within which all
2092  //subject names in subsequent certificates in a certification path must
2093  //be located
2094  while(length > 0)
2095  {
2096  //Parse GeneralSubtrees field
2097  error = asn1ReadTag(data, length, &tag);
2098  //Failed to decode ASN.1 tag?
2099  if(error)
2100  return error;
2101 
2102  //Explicit tagging shall be used to encode the GeneralSubtrees field
2104  return ERROR_INVALID_CLASS;
2105 
2106  //The sequence cannot be empty (refer to RFC 5280, section 4.2.1.10)
2107  if(tag.length == 0)
2108  return ERROR_INVALID_SYNTAX;
2109 
2110  //Restrictions are defined in terms of permitted or excluded name subtrees
2111  if(tag.objType == 0)
2112  {
2113  //Parse the permittedSubtrees field
2114  error = x509ParseGeneralSubtrees(tag.value, tag.length);
2115  //Any error to report?
2116  if(error)
2117  return error;
2118 
2119  //Raw contents of the ASN.1 sequence
2120  nameConstraints->permittedSubtrees = tag.value;
2121  nameConstraints->permittedSubtreesLen = tag.length;
2122  }
2123  else if(tag.objType == 1)
2124  {
2125  //Parse the excludedSubtrees field
2126  error = x509ParseGeneralSubtrees(tag.value, tag.length);
2127  //Any error to report?
2128  if(error)
2129  return error;
2130 
2131  //Raw contents of the ASN.1 sequence
2132  nameConstraints->excludedSubtrees = tag.value;
2133  nameConstraints->excludedSubtreesLen = tag.length;
2134  }
2135  else
2136  {
2137  //Report an error
2138  return ERROR_INVALID_TYPE;
2139  }
2140 
2141  //Next item
2142  data += tag.totalLength;
2143  length -= tag.totalLength;
2144  }
2145 
2146  //Successful processing
2147  return NO_ERROR;
2148 }
2149 
2150 
2151 /**
2152  * @brief Parse PolicyConstraints extension
2153  * @param[in] data Pointer to the ASN.1 structure to parse
2154  * @param[in] length Length of the ASN.1 structure
2155  * @return Error code
2156  **/
2157 
2159 {
2160  error_t error;
2161  Asn1Tag tag;
2162 
2163  //Debug message
2164  TRACE_DEBUG(" Parsing PolicyConstraints...\r\n");
2165 
2166  //The PolicyConstraints structure shall contain a valid sequence
2167  error = asn1ReadSequence(data, length, &tag);
2168  //Failed to decode ASN.1 tag?
2169  if(error)
2170  return error;
2171 
2172  //Conforming CAs must not issue certificates where policy constraints is an
2173  //empty sequence (refer to RFC 5280, section 4.2.1.11)
2174  if(tag.length == 0)
2175  return ERROR_INVALID_SYNTAX;
2176 
2177  //Successful processing
2178  return NO_ERROR;
2179 }
2180 
2181 
2182 /**
2183  * @brief Parse PolicyMappings extension
2184  * @param[in] data Pointer to the ASN.1 structure to parse
2185  * @param[in] length Length of the ASN.1 structure
2186  * @return Error code
2187  **/
2188 
2190 {
2191  error_t error;
2192  Asn1Tag tag;
2193 
2194  //Debug message
2195  TRACE_DEBUG(" Parsing PolicyMappings...\r\n");
2196 
2197  //The PolicyMappings structure shall contain a valid sequence
2198  error = asn1ReadSequence(data, length, &tag);
2199  //Failed to decode ASN.1 tag?
2200  if(error)
2201  return error;
2202 
2203  //The sequence cannot be empty (refer to RFC 5280, section 4.2.1.5)
2204  if(tag.length == 0)
2205  return ERROR_INVALID_SYNTAX;
2206 
2207  //Successful processing
2208  return NO_ERROR;
2209 }
2210 
2211 
2212 /**
2213  * @brief Parse InhibitAnyPolicy extension
2214  * @param[in] data Pointer to the ASN.1 structure to parse
2215  * @param[in] length Length of the ASN.1 structure
2216  * @return Error code
2217  **/
2218 
2220 {
2221  //Debug message
2222  TRACE_DEBUG(" Parsing InhibitAnyPolicy...\r\n");
2223 
2224  //Successful processing
2225  return NO_ERROR;
2226 }
2227 
2228 
2229 /**
2230  * @brief Parse KeyUsage extension
2231  * @param[in] data Pointer to the ASN.1 structure to parse
2232  * @param[in] length Length of the ASN.1 structure
2233  * @param[out] keyUsage Information resulting from the parsing process
2234  * @return Error code
2235  **/
2236 
2237 error_t x509ParseKeyUsage(const uint8_t *data, size_t length,
2238  uint16_t *keyUsage)
2239 {
2240  error_t error;
2241  Asn1Tag tag;
2242 
2243  //Debug message
2244  TRACE_DEBUG(" Parsing KeyUsage...\r\n");
2245 
2246  //A certificate must not include more than one instance of a particular
2247  //extension (refer to RFC 5280, section 4.2)
2248  if(*keyUsage != 0)
2249  return ERROR_INVALID_SYNTAX;
2250 
2251  //The key usage extension defines the purpose of the key contained in the
2252  //certificate
2253  error = asn1ReadTag(data, length, &tag);
2254  //Failed to decode ASN.1 tag?
2255  if(error)
2256  return error;
2257 
2258  //Enforce encoding, class and type
2260  //The tag does not match the criteria?
2261  if(error)
2262  return error;
2263 
2264  //The bit string shall contain an initial octet which encodes the number
2265  //of unused bits in the final subsequent octet
2266  if(tag.length < 1)
2267  return ERROR_INVALID_SYNTAX;
2268 
2269  //Sanity check
2270  if(tag.value[0] >= 8)
2271  return ERROR_INVALID_SYNTAX;
2272 
2273  //Clear bit string
2274  *keyUsage = 0;
2275 
2276  //Read bits b0 to b7
2277  if(tag.length >= 2)
2278  *keyUsage |= reverseInt8(tag.value[1]);
2279 
2280  //Read bits b8 to b15
2281  if(tag.length >= 3)
2282  *keyUsage |= reverseInt8(tag.value[2]) << 8;
2283 
2284  //When the key usage extension appears in a certificate, at least one of
2285  //the bits must be set to 1 (refer to RFC 5280, section 4.2.1.3)
2286  if(*keyUsage == 0)
2287  return ERROR_INVALID_SYNTAX;
2288 
2289  //Successful processing
2290  return NO_ERROR;
2291 }
2292 
2293 
2294 /**
2295  * @brief Parse ExtendedKeyUsage extension
2296  * @param[in] data Pointer to the ASN.1 structure to parse
2297  * @param[in] length Length of the ASN.1 structure
2298  * @param[out] extKeyUsage Information resulting from the parsing process
2299  * @return Error code
2300  **/
2301 
2303  uint8_t *extKeyUsage)
2304 {
2305  error_t error;
2306  Asn1Tag tag;
2307 
2308  //Debug message
2309  TRACE_DEBUG(" Parsing ExtendedKeyUsage...\r\n");
2310 
2311  //A certificate must not include more than one instance of a particular
2312  //extension (refer to RFC 5280, section 4.2)
2313  if(*extKeyUsage != 0)
2314  return ERROR_INVALID_SYNTAX;
2315 
2316  //The ExtendedKeyUsage structure shall contain a valid sequence
2317  error = asn1ReadSequence(data, length, &tag);
2318  //Failed to decode ASN.1 tag?
2319  if(error)
2320  return error;
2321 
2322  //The sequence cannot be empty (refer to RFC 5280, section 4.2.1.12)
2323  if(tag.length == 0)
2324  return ERROR_INVALID_SYNTAX;
2325 
2326  //Point to the first item of the sequence
2327  data = tag.value;
2328  length = tag.length;
2329 
2330  //This extension indicates one or more purposes for which the certified
2331  //public key may be used
2332  while(length > 0)
2333  {
2334  //Read KeyPurposeId field
2335  error = asn1ReadTag(data, length, &tag);
2336  //Failed to decode ASN.1 tag?
2337  if(error)
2338  return error;
2339 
2340  //Enforce encoding, class and type
2341  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
2343  //The tag does not match the criteria?
2344  if(error)
2345  return error;
2346 
2347  //anyExtendedKeyUsage?
2348  if(!oidComp(tag.value, tag.length,
2350  {
2351  //If a CA includes extended key usages to satisfy such applications,
2352  //but does not wish to restrict usages of the key, the CA can include
2353  //the special KeyPurposeId anyExtendedKeyUsage
2354  *extKeyUsage |= X509_EXT_KEY_USAGE_ANY;
2355  }
2356  //id-kp-serverAuth?
2357  else if(!oidComp(tag.value, tag.length,
2359  {
2360  //TLS WWW server authentication
2361  *extKeyUsage |= X509_EXT_KEY_USAGE_SERVER_AUTH;
2362  }
2363  //id-kp-clientAuth?
2364  else if(!oidComp(tag.value, tag.length,
2366  {
2367  //TLS WWW client authentication
2368  *extKeyUsage |= X509_EXT_KEY_USAGE_CLIENT_AUTH;
2369  }
2370  //id-kp-codeSigning?
2371  else if(!oidComp(tag.value, tag.length,
2373  {
2374  //Signing of downloadable executable code
2375  *extKeyUsage |= X509_EXT_KEY_USAGE_CODE_SIGNING;
2376  }
2377  //id-kp-emailProtection?
2378  else if(!oidComp(tag.value, tag.length,
2380  {
2381  //Email protection
2382  *extKeyUsage |= X509_EXT_KEY_USAGE_EMAIL_PROTECTION;
2383  }
2384  //id-kp-timeStamping?
2385  else if(!oidComp(tag.value, tag.length,
2387  {
2388  //Binding the hash of an object to a time
2389  *extKeyUsage |= X509_EXT_KEY_USAGE_TIME_STAMPING;
2390  }
2391  //id-kp-OCSPSigning?
2392  else if(!oidComp(tag.value, tag.length,
2394  {
2395  //Signing OCSP responses
2396  *extKeyUsage |= X509_EXT_KEY_USAGE_OCSP_SIGNING;
2397  }
2398  //Unknown key purpose?
2399  else
2400  {
2401  //Discard KeyPurposeId field
2402  }
2403 
2404  //Next item
2405  data += tag.totalLength;
2406  length -= tag.totalLength;
2407  }
2408 
2409  //Successful processing
2410  return NO_ERROR;
2411 }
2412 
2413 
2414 /**
2415  * @brief Parse SubjectAltName extension
2416  * @param[in] data Pointer to the ASN.1 structure to parse
2417  * @param[in] length Length of the ASN.1 structure
2418  * @param[out] subjectAltName Information resulting from the parsing process
2419  * @return Error code
2420  **/
2421 
2423  X509SubjectAltName *subjectAltName)
2424 {
2425  error_t error;
2426  uint_t i;
2427  size_t n;
2428  Asn1Tag tag;
2429  X509GeneralName generalName;
2430 
2431  //Debug message
2432  TRACE_DEBUG(" Parsing SubjectAltName...\r\n");
2433 
2434  //The SubjectAltName structure shall contain a valid sequence
2435  error = asn1ReadSequence(data, length, &tag);
2436  //Failed to decode ASN.1 tag?
2437  if(error)
2438  return error;
2439 
2440  //Raw contents of the ASN.1 sequence
2441  subjectAltName->rawData = tag.value;
2442  subjectAltName->rawDataLen = tag.length;
2443 
2444  //Point to the first item of the sequence
2445  data = tag.value;
2446  length = tag.length;
2447 
2448  //The subject alternative name extension allows identities to be bound to the
2449  //subject of the certificate. These identities may be included in addition
2450  //to or in place of the identity in the subject field of the certificate
2451  for(i = 0; length > 0; i++)
2452  {
2453  //Parse GeneralName field
2454  error = x509ParseGeneralName(data, length, &n, &generalName);
2455  //Any error to report?
2456  if(error)
2457  return error;
2458 
2459  //Sanity check
2461  {
2462  //Save subject alternative name
2463  subjectAltName->generalNames[i] = generalName;
2464  }
2465 
2466  //Next item
2467  data += n;
2468  length -= n;
2469  }
2470 
2471  //If the SubjectAltName extension is present, the sequence must contain at
2472  //least one entry (refer to RFC 5280, section 4.2.1.6)
2473  if(i == 0)
2474  return ERROR_INVALID_SYNTAX;
2475 
2476  //Save the number of subject alternative names
2477  subjectAltName->numGeneralNames = MIN(i, X509_MAX_SUBJECT_ALT_NAMES);
2478 
2479  //Successful processing
2480  return NO_ERROR;
2481 }
2482 
2483 
2484 /**
2485  * @brief Parse GeneralSubtrees field
2486  * @param[in] data Pointer to the ASN.1 structure to parse
2487  * @param[in] length Length of the ASN.1 structure
2488  * @return Error code
2489  **/
2490 
2492 {
2493  error_t error;
2494  size_t n;
2495  X509GeneralName generalName;
2496 
2497  //Loop through the list of GeneralSubtree fields
2498  while(length > 0)
2499  {
2500  //Parse current GeneralSubtree field
2501  error = x509ParseGeneralSubtree(data, length, &n, &generalName);
2502  //Any error to report?
2503  if(error)
2504  return error;
2505 
2506  //Next item
2507  data += n;
2508  length -= n;
2509  }
2510 
2511  //Successful processing
2512  return NO_ERROR;
2513 }
2514 
2515 
2516 /**
2517  * @brief Parse GeneralSubtree field
2518  * @param[in] data Pointer to the ASN.1 structure to parse
2519  * @param[in] length Length of the ASN.1 structure
2520  * @param[out] totalLength Number of bytes that have been parsed
2521  * @param[out] generalName Information resulting from the parsing process
2522  * @return Error code
2523  **/
2524 
2526  size_t *totalLength, X509GeneralName *generalName)
2527 {
2528  error_t error;
2529  size_t n;
2530  Asn1Tag tag;
2531 
2532  //The GeneralSubtrees structure shall contain a valid sequence
2533  error = asn1ReadSequence(data, length, &tag);
2534  //Failed to decode ASN.1 tag?
2535  if(error)
2536  return error;
2537 
2538  //Save the total length of the field
2539  *totalLength = tag.totalLength;
2540 
2541  //Parse GeneralName field
2542  error = x509ParseGeneralName(tag.value, tag.length, &n, generalName);
2543 
2544  //Discard minimum and maximum fields
2545  return error;
2546 }
2547 
2548 
2549 /**
2550  * @brief Parse GeneralName field
2551  * @param[in] data Pointer to the ASN.1 structure to parse
2552  * @param[in] length Length of the ASN.1 structure
2553  * @param[out] totalLength Number of bytes that have been parsed
2554  * @param[out] generalName Information resulting from the parsing process
2555  * @return Error code
2556  **/
2557 
2558 error_t x509ParseGeneralName(const uint8_t *data, size_t length,
2559  size_t *totalLength, X509GeneralName *generalName)
2560 {
2561  error_t error;
2562  Asn1Tag tag;
2563 
2564  //Debug message
2565  TRACE_DEBUG(" Parsing GeneralName...\r\n");
2566 
2567  //Read current item
2568  error = asn1ReadTag(data, length, &tag);
2569  //Failed to decode ASN.1 tag?
2570  if(error)
2571  return error;
2572 
2573  //Explicit tagging shall be used to encode the subject alternative name
2575  return ERROR_INVALID_CLASS;
2576 
2577  //Conforming CAs must not issue certificates with subjectAltNames containing
2578  //empty GeneralName fields (refer to RFC 5280, section 4.2.1.6)
2579  if(tag.length == 0)
2580  return ERROR_INVALID_SYNTAX;
2581 
2582  //Save subject alternative name
2583  generalName->type = (X509GeneralNameType) tag.objType;
2584  generalName->value = (char_t *) tag.value;
2585  generalName->length = tag.length;
2586 
2587  //Save the total length of the field
2588  *totalLength = tag.totalLength;
2589 
2590  //Successful processing
2591  return NO_ERROR;
2592 }
2593 
2594 
2595 /**
2596  * @brief Parse SubjectKeyIdentifier extension
2597  * @param[in] data Pointer to the ASN.1 structure to parse
2598  * @param[in] length Length of the ASN.1 structure
2599  * @param[out] subjectKeyId Information resulting from the parsing process
2600  * @return Error code
2601  **/
2602 
2603 error_t x509ParseSubjectKeyId(const uint8_t *data, size_t length,
2604  X509SubjectKeyId *subjectKeyId)
2605 {
2606  error_t error;
2607  Asn1Tag tag;
2608 
2609  //Debug message
2610  TRACE_DEBUG(" Parsing SubjectKeyIdentifier...\r\n");
2611 
2612  //The subject key identifier extension provides a means of identifying
2613  //certificates that contain a particular public key
2614  error = asn1ReadTag(data, length, &tag);
2615  //Failed to decode ASN.1 tag?
2616  if(error)
2617  return error;
2618 
2619  //Enforce encoding, class and type
2621  //The tag does not match the criteria?
2622  if(error)
2623  return error;
2624 
2625  //Save the subject key identifier
2626  subjectKeyId->value = tag.value;
2627  subjectKeyId->length = tag.length;
2628 
2629  //Successful processing
2630  return NO_ERROR;
2631 }
2632 
2633 
2634 /**
2635  * @brief Parse AuthorityKeyIdentifier extension
2636  * @param[in] data Pointer to the ASN.1 structure to parse
2637  * @param[in] length Length of the ASN.1 structure
2638  * @param[out] authorityKeyId Information resulting from the parsing process
2639  * @return Error code
2640  **/
2641 
2643  X509AuthorityKeyId *authorityKeyId)
2644 {
2645  error_t error;
2646  Asn1Tag tag;
2647 
2648  //Debug message
2649  TRACE_DEBUG(" Parsing AuthorityKeyIdentifier...\r\n");
2650 
2651  //The AuthorityKeyIdentifier structure shall contain a valid sequence
2652  error = asn1ReadSequence(data, length, &tag);
2653  //Failed to decode ASN.1 tag?
2654  if(error)
2655  return error;
2656 
2657  //Point to the first item of the sequence
2658  data = tag.value;
2659  length = tag.length;
2660 
2661  //Parse the content of the sequence
2662  while(length > 0)
2663  {
2664  //Read current item
2665  error = asn1ReadTag(data, length, &tag);
2666  //Failed to decode ASN.1 tag?
2667  if(error)
2668  return error;
2669 
2670  //Explicit tagging shall be used to encode the authority key identifier
2672  return ERROR_INVALID_CLASS;
2673 
2674  //keyIdentifier object found?
2675  if(tag.objType == 0)
2676  {
2677  //Save the authority key identifier
2678  authorityKeyId->value = tag.value;
2679  authorityKeyId->length = tag.length;
2680  }
2681 
2682  //Next item
2683  data += tag.totalLength;
2684  length -= tag.totalLength;
2685  }
2686 
2687  //Successful processing
2688  return NO_ERROR;
2689 }
2690 
2691 
2692 /**
2693  * @brief Parse NetscapeCertType extension
2694  * @param[in] data Pointer to the ASN.1 structure to parse
2695  * @param[in] length Length of the ASN.1 structure
2696  * @param[out] nsCertType Information resulting from the parsing process
2697  * @return Error code
2698  **/
2699 
2700 error_t x509ParseNsCertType(const uint8_t *data, size_t length,
2701  uint8_t *nsCertType)
2702 {
2703  error_t error;
2704  Asn1Tag tag;
2705 
2706  //Debug message
2707  TRACE_DEBUG(" Parsing NetscapeCertType...\r\n");
2708 
2709  //The NetscapeCertType extension limit the use of a certificate
2710  error = asn1ReadTag(data, length, &tag);
2711  //Failed to decode ASN.1 tag?
2712  if(error)
2713  return error;
2714 
2715  //Enforce encoding, class and type
2717  //The tag does not match the criteria?
2718  if(error)
2719  return error;
2720 
2721  //The bit string shall contain an initial octet which encodes the number
2722  //of unused bits in the final subsequent octet
2723  if(tag.length < 1)
2724  return ERROR_INVALID_SYNTAX;
2725 
2726  //Sanity check
2727  if(tag.value[0] >= 8)
2728  return ERROR_INVALID_SYNTAX;
2729 
2730  //Clear bit string
2731  *nsCertType = 0;
2732 
2733  //Read bits b0 to b7
2734  if(tag.length >= 2)
2735  *nsCertType |= reverseInt8(tag.value[1]);
2736 
2737  //Successful processing
2738  return NO_ERROR;
2739 }
2740 
2741 
2742 /**
2743  * @brief Parse SignatureAlgorithm structure
2744  * @param[in] data Pointer to the ASN.1 structure to parse
2745  * @param[in] length Length of the ASN.1 structure
2746  * @param[out] totalLength Number of bytes that have been parsed
2747  * @param[out] signatureAlgo Information resulting from the parsing process
2748  * @return Error code
2749  **/
2750 
2752  size_t *totalLength, X509SignatureAlgoId *signatureAlgo)
2753 {
2754  error_t error;
2755  Asn1Tag tag;
2756 
2757  //Debug message
2758  TRACE_DEBUG(" Parsing SignatureAlgorithm...\r\n");
2759 
2760  //Read the contents of the SignatureAlgorithm field
2761  error = asn1ReadSequence(data, length, &tag);
2762  //Failed to decode ASN.1 tag?
2763  if(error)
2764  return error;
2765 
2766  //Save the total length of the field
2767  *totalLength = tag.totalLength;
2768 
2769  //Read the inner tag
2770  error = asn1ReadTag(tag.value, tag.length, &tag);
2771  //Failed to decode ASN.1 tag?
2772  if(error)
2773  return error;
2774 
2775  //This field must contain the same algorithm identifier as the signature
2776  //field in the TBSCertificate sequence
2777  error = asn1CheckOid(&tag, signatureAlgo->oid, signatureAlgo->oidLen);
2778  //The tag does not match the criteria?
2779  if(error)
2780  return error;
2781 
2782  //Successful processing
2783  return NO_ERROR;
2784 }
2785 
2786 
2787 /**
2788  * @brief Parse SignatureValue field
2789  * @param[in] data Pointer to the ASN.1 structure to parse
2790  * @param[in] length Length of the ASN.1 structure
2791  * @param[out] totalLength Number of bytes that have been parsed
2792  * @param[out] signatureValue Information resulting from the parsing process
2793  * @return Error code
2794  **/
2795 
2797  size_t *totalLength, X509SignatureValue *signatureValue)
2798 {
2799  error_t error;
2800  Asn1Tag tag;
2801 
2802  //Debug message
2803  TRACE_DEBUG(" Parsing SignatureValue...\r\n");
2804 
2805  //Read the contents of the SignatureValue structure
2806  error = asn1ReadTag(data, length, &tag);
2807  //Failed to decode ASN.1 tag?
2808  if(error)
2809  return error;
2810 
2811  //Save the total length of the field
2812  *totalLength = tag.totalLength;
2813 
2814  //Enforce encoding, class and type
2816  //The tag does not match the criteria?
2817  if(error)
2818  return error;
2819 
2820  //The bit string shall contain an initial octet which encodes
2821  //the number of unused bits in the final subsequent octet
2822  if(tag.length < 1 || tag.value[0] != 0x00)
2823  return ERROR_FAILURE;
2824 
2825  //Get the signature value
2826  signatureValue->data = tag.value + 1;
2827  signatureValue->length = tag.length - 1;
2828 
2829  //Successful processing
2830  return NO_ERROR;
2831 }
2832 
2833 #endif
error_t x509ParseKeyUsage(const uint8_t *data, size_t length, uint16_t *keyUsage)
Parse KeyUsage extension.
const uint8_t X25519_OID[3]
Definition: ec_curves.c:90
uint_t objType
Definition: asn1.h:98
error_t x509ParseSignature(const uint8_t *data, size_t length, size_t *totalLength, X509SignatureAlgoId *signature)
Parse Signature field.
uint16_t version
Definition: dtls_misc.h:163
error_t x509ParsePolicyMappings(const uint8_t *data, size_t length)
Parse PolicyMappings extension.
uint8_t reverseInt8(uint8_t value)
Reverse bit order in a byte.
Definition: cpu_endian.c:88
const uint8_t X509_COMMON_NAME_OID[3]
Definition: x509_common.c:64
const uint8_t X509_NAME_OID[3]
Definition: x509_common.c:82
const uint8_t X509_SURNAME_OID[3]
Definition: x509_common.c:66
char char_t
Definition: compiler_port.h:41
const uint8_t * rawData
Definition: x509_common.h:601
error_t asn1ReadInt32(const uint8_t *data, size_t length, Asn1Tag *tag, int32_t *value)
Read an integer from the input stream.
Definition: asn1.c:186
Basic constraints.
Definition: x509_common.h:623
uint16_t year
Definition: date_time.h:46
DateTime notAfter
Definition: x509_common.h:530
const uint8_t X509_DN_QUALIFIER_OID[3]
Definition: x509_common.c:90
const uint8_t X509_PSEUDONYM_OID[3]
Definition: x509_common.c:92
X509GeneralNameType type
Definition: x509_common.h:649
X509DsaParameters dsaParams
Definition: x509_common.h:609
SHA-224 (Secure Hash Algorithm 224)
const uint8_t X509_LOCALITY_NAME_OID[3]
Definition: x509_common.c:72
error_t x509ParseNsCertType(const uint8_t *data, size_t length, uint8_t *nsCertType)
Parse NetscapeCertType extension.
const uint8_t X509_NAME_CONSTRAINTS_OID[3]
Definition: x509_common.c:107
const uint8_t X509_TITLE_OID[3]
Definition: x509_common.c:80
Debugging facilities.
Serial number.
Definition: x509_common.h:462
const uint8_t X509_INHIBIT_ANY_POLICY_OID[3]
Definition: x509_common.c:123
EC parameters.
Definition: x509_common.h:577
size_t permittedSubtreesLen
Definition: x509_common.h:637
const uint8_t * q
Definition: x509_common.h:555
const uint8_t * data
Definition: x509_common.h:739
General name.
Definition: x509_common.h:647
Generic error code.
Definition: error.h:43
size_t totalLength
Definition: asn1.h:101
error_t x509ParseDsaPublicKey(const uint8_t *data, size_t length, X509DsaPublicKey *dsaPublicKey)
Parse DSAPublicKey structure.
ECDSA (Elliptic Curve Digital Signature Algorithm)
const uint8_t X509_EXTENDED_KEY_USAGE_OID[3]
Definition: x509_common.c:119
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:86
General definitions for cryptographic algorithms.
Issuer or subject name.
Definition: x509_common.h:473
error_t x509ParseRsaPublicKey(const uint8_t *data, size_t length, X509RsaPublicKey *rsaPublicKey)
Parse RSAPublicKey structure.
const uint8_t X509_ORGANIZATION_NAME_OID[3]
Definition: x509_common.c:76
const uint8_t X509_KP_SERVER_AUTH_OID[8]
Definition: x509_common.c:131
error_t x509ParseSubjectUniqueId(const uint8_t *data, size_t length, size_t *totalLength)
Parse SubjectUniqueID structure.
const uint8_t X509_STATE_OR_PROVINCE_NAME_OID[]
Definition: x509_common.c:74
error_t x509ParseName(const uint8_t *data, size_t length, size_t *totalLength, X509Name *name)
Parse Name structure.
Subject key identifier.
Definition: x509_common.h:672
const uint8_t * data
Definition: x509_common.h:464
error_t asn1CheckOid(const Asn1Tag *tag, const uint8_t *oid, size_t length)
Check ASN.1 tag against a specified OID.
Definition: asn1.c:451
const uint8_t X509_SERIAL_NUMBER_OID[3]
Definition: x509_common.c:68
uint8_t minutes
Definition: date_time.h:51
X509RsaPublicKey rsaPublicKey
Definition: x509_common.h:606
error_t x509ParseSignatureAlgo(const uint8_t *data, size_t length, size_t *totalLength, X509SignatureAlgoId *signatureAlgo)
Parse SignatureAlgorithm structure.
#define ASN1_CLASS_CONTEXT_SPECIFIC
Definition: asn1.h:47
Signature value.
Definition: x509_common.h:737
X509EcParameters ecParams
Definition: x509_common.h:613
error_t x509ParseDsaParameters(const uint8_t *data, size_t length, X509DsaParameters *dsaParams)
Parse DSA domain parameters.
RSA public key.
Definition: x509_common.h:538
X509BasicConstraints basicConstraints
Definition: x509_common.h:696
X509EcPublicKey ecPublicKey
Definition: x509_common.h:614
X509SerialNumber serialNumber
Definition: x509_common.h:753
error_t x509ParseRsaPssHashAlgo(const uint8_t *data, size_t length, X509RsaPssParameters *rsaPssParams)
Parse RSASSA-PSS hash algorithm.
const uint8_t * p
Definition: x509_common.h:553
error_t x509ParseNameAttribute(const uint8_t *data, size_t length, size_t *totalLength, X509NameAttribute *nameAttribute)
Parse name attribute.
error_t x509ParseEcParameters(const uint8_t *data, size_t length, X509EcParameters *ecParams)
Parse ECParameters structure.
const uint8_t X509_KP_CODE_SIGNING_OID[8]
Definition: x509_common.c:135
const uint8_t * oid
Definition: x509_common.h:603
const uint8_t * namedCurve
Definition: x509_common.h:579
SHA-384 (Secure Hash Algorithm 384)
const uint8_t * oid
Definition: x509_common.h:725
error_t x509ParseIssuerUniqueId(const uint8_t *data, size_t length, size_t *totalLength)
Parse IssuerUniqueID structure.
size_t excludedSubtreesLen
Definition: x509_common.h:639
const uint8_t X509_KP_EMAIL_PROTECTION_OID[8]
Definition: x509_common.c:137
Name constraints.
Definition: x509_common.h:634
RSASSA-PSS parameters.
Definition: x509_common.h:711
OID (Object Identifier)
error_t x509ParseExtensions(const uint8_t *data, size_t length, size_t *totalLength, X509Extensions *extensions)
Parse Extensions structure.
error_t x509ParseAuthorityKeyId(const uint8_t *data, size_t length, X509AuthorityKeyId *authorityKeyId)
Parse AuthorityKeyIdentifier extension.
error_t x509ParseVersion(const uint8_t *data, size_t length, size_t *totalLength, X509Version *version)
Parse Version field.
error_t x509ParseRsaPssSaltLength(const uint8_t *data, size_t length, X509RsaPssParameters *rsaPssParams)
Parse RSASSA-PSS salt length.
ASN.1 tag.
Definition: asn1.h:94
#define TRUE
Definition: os_port.h:48
X509Version
X.509 versions.
Definition: x509_common.h:350
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:426
const uint8_t * value
Definition: x509_common.h:685
Name attribute.
Definition: x509_common.h:514
error_t x509ParseSerialNumber(const uint8_t *data, size_t length, size_t *totalLength, X509SerialNumber *serialNumber)
Parse SerialNumber field.
uint8_t day
Definition: date_time.h:48
X509DsaPublicKey dsaPublicKey
Definition: x509_common.h:610
Extensions.
Definition: x509_common.h:694
error_t x509ParseTime(const uint8_t *data, size_t length, size_t *totalLength, DateTime *dateTime)
Parse UTCTime or GeneralizedTime field.
ASN.1 (Abstract Syntax Notation One)
error_t asn1ReadSequence(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 sequence from the input stream.
Definition: asn1.c:158
const uint8_t * e
Definition: x509_common.h:542
const uint8_t X509_ANY_EXT_KEY_USAGE_OID[4]
Definition: x509_common.c:129
const uint8_t X509_KP_OCSP_SIGNING_OID[8]
Definition: x509_common.c:141
error_t x509ParseExtendedKeyUsage(const uint8_t *data, size_t length, uint8_t *extKeyUsage)
Parse ExtendedKeyUsage extension.
Authority key identifier.
Definition: x509_common.h:683
const char_t * value
Definition: x509_common.h:650
error_t x509ParseAlgorithmIdentifier(const uint8_t *data, size_t length, size_t *totalLength, X509SubjectPublicKeyInfo *subjectPublicKeyInfo)
Parse AlgorithmIdentifier structure.
error_t x509ParseGeneralSubtrees(const uint8_t *data, size_t length)
Parse GeneralSubtrees field.
char_t name[]
uint8_t month
Definition: date_time.h:47
const uint8_t * rawData
Definition: x509_common.h:661
size_t namedCurveLen
Definition: x509_common.h:580
error_t asn1ReadTag(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 tag from the input stream.
Definition: asn1.c:50
X509Extensions extensions
Definition: x509_common.h:758
X509SignatureValue signatureValue
Definition: x509_common.h:760
size_t length
Definition: asn1.h:99
X509Version version
Definition: x509_common.h:752
const uint8_t * permittedSubtrees
Definition: x509_common.h:636
const uint8_t ED448_OID[3]
Definition: ec_curves.c:96
error_t x509ParseValidity(const uint8_t *data, size_t length, size_t *totalLength, X509Validity *validity)
Parse Validity structure.
error_t x509ParseCertificate(const uint8_t *data, size_t length, X509CertificateInfo *certInfo)
Parse a X.509 certificate.
const uint8_t X509_KEY_USAGE_OID[3]
Definition: x509_common.c:99
uint8_t seconds
Definition: date_time.h:52
Subject alternative name.
Definition: x509_common.h:659
const uint8_t * q
Definition: x509_common.h:590
#define MIN(a, b)
Definition: os_port.h:60
uint8_t signature
Definition: tls.h:1364
DSA (Digital Signature Algorithm)
error_t x509ParseNameConstraints(const uint8_t *data, size_t length, X509NameConstraints *nameConstraints)
Parse NameConstraints extension.
Date and time representation.
Definition: date_time.h:44
DateTime notBefore
Definition: x509_common.h:529
const uint8_t X448_OID[3]
Definition: ec_curves.c:92
error_t x509ReadInt(const uint8_t *data, size_t length, uint_t *value)
Convert string to integer.
Definition: x509_common.c:152
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:99
error_t x509ParseSubjectAltName(const uint8_t *data, size_t length, X509SubjectAltName *subjectAltName)
Parse SubjectAltName extension.
const uint8_t * n
Definition: x509_common.h:540
const uint8_t X509_GENERATION_QUALIFIER_OID[3]
Definition: x509_common.c:88
const uint8_t ED25519_OID[3]
Definition: ec_curves.c:94
X509Validity validity
Definition: x509_common.h:755
error_t x509ParseRsaPssParameters(const uint8_t *data, size_t length, X509RsaPssParameters *rsaPssParams)
Parse RSASSA-PSS parameters.
Success.
Definition: error.h:42
const uint8_t * tbsCertificate
Definition: x509_common.h:750
const uint8_t RSA_ENCRYPTION_OID[9]
Definition: rsa.c:55
Subject public key info.
Definition: x509_common.h:599
const uint8_t X509_INITIALS_OID[3]
Definition: x509_common.c:86
error_t
Error codes.
Definition: error.h:40
DSA domain parameters.
Definition: x509_common.h:551
X509GeneralNameType
General name types.
Definition: x509_common.h:396
uint8_t extensions[]
Definition: tls13_misc.h:322
uint8_t hours
Definition: date_time.h:50
const uint8_t * excludedSubtrees
Definition: x509_common.h:638
RSA public-key cryptography standard.
error_t x509ParseSubjectPublicKeyInfo(const uint8_t *data, size_t length, size_t *totalLength, X509SubjectPublicKeyInfo *subjectPublicKeyInfo)
Parse SubjectPublicKeyInfo structure.
error_t x509ParseEcPublicKey(const uint8_t *data, size_t length, X509EcPublicKey *ecPublicKey)
Parse ECPublicKey structure.
unsigned int uint_t
Definition: compiler_port.h:43
DSA public key.
Definition: x509_common.h:566
uint8_t data[]
Definition: dtls_misc.h:167
const uint8_t X509_POLICY_CONSTRAINTS_OID[3]
Definition: x509_common.c:117
SHA-1 (Secure Hash Algorithm 1)
X509SignatureAlgoId signatureAlgo
Definition: x509_common.h:759
const uint8_t * hashAlgo
Definition: x509_common.h:713
X509GeneralName generalNames[X509_MAX_SUBJECT_ALT_NAMES]
Definition: x509_common.h:664
X.509 certificate.
Definition: x509_common.h:748
uint8_t value[]
Definition: dtls_misc.h:141
error_t x509ParseInhibitAnyPolicy(const uint8_t *data, size_t length)
Parse InhibitAnyPolicy extension.
const uint8_t X509_POLICY_MAPPINGS_OID[3]
Definition: x509_common.c:113
error_t x509ParseTbsCertificate(const uint8_t *data, size_t length, size_t *totalLength, X509CertificateInfo *certInfo)
Parse TBSCertificate structure.
uint_t objClass
Definition: asn1.h:97
X509SubjectPublicKeyInfo subjectPublicKeyInfo
Definition: x509_common.h:757
const uint8_t X509_KP_CLIENT_AUTH_OID[8]
Definition: x509_common.c:133
const uint8_t X509_COUNTRY_NAME_OID[3]
Definition: x509_common.c:70
const uint8_t * type
Definition: x509_common.h:516
SHA-512 (Secure Hash Algorithm 512)
error_t x509ParsePolicyConstraints(const uint8_t *data, size_t length)
Parse PolicyConstraints extension.
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:45
#define X509_MAX_SUBJECT_ALT_NAMES
Definition: x509_common.h:335
const uint8_t X509_SUBJECT_ALT_NAME_OID[3]
Definition: x509_common.c:101
error_t x509ParseBasicConstraints(const uint8_t *data, size_t length, X509BasicConstraints *basicConstraints)
Parse BasicConstraints extension.
error_t x509ParseGeneralName(const uint8_t *data, size_t length, size_t *totalLength, X509GeneralName *generalName)
Parse GeneralName field.
X.509 certificate parsing.
uint16_t milliseconds
Definition: date_time.h:53
const char_t * value
Definition: x509_common.h:518
#define cryptoMemset(p, value, length)
Definition: crypto.h:584
Signature algorithm identifier.
Definition: x509_common.h:723
const uint8_t * value
Definition: x509_common.h:674
error_t x509ParseSignatureValue(const uint8_t *data, size_t length, size_t *totalLength, X509SignatureValue *signatureValue)
Parse SignatureValue field.
#define SHA1_OID
Definition: sha1.h:40
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
uint8_t oid[1]
Definition: mib_common.h:184
const uint8_t * y
Definition: x509_common.h:568
MD5 (Message-Digest Algorithm)
error_t x509ParseGeneralSubtree(const uint8_t *data, size_t length, size_t *totalLength, X509GeneralName *generalName)
Parse GeneralSubtree field.
SHA-256 (Secure Hash Algorithm 256)
const uint8_t X509_ORGANIZATIONAL_UNIT_NAME_OID[3]
Definition: x509_common.c:78
const uint8_t DSA_OID[7]
Definition: dsa.c:49
#define FALSE
Definition: os_port.h:44
EC public key.
Definition: x509_common.h:588
const uint8_t X509_AUTHORITY_KEY_ID_OID[3]
Definition: x509_common.c:115
int bool_t
Definition: compiler_port.h:47
const uint8_t X509_BASIC_CONSTRAINTS_OID[3]
Definition: x509_common.c:105
const uint8_t X509_GIVEN_NAME_OID[3]
Definition: x509_common.c:84
const uint8_t * g
Definition: x509_common.h:557
const uint8_t X509_KP_TIME_STAMPING_OID[8]
Definition: x509_common.c:139
const uint8_t X509_SUBJECT_KEY_ID_OID[3]
Definition: x509_common.c:97
const uint8_t * value
Definition: asn1.h:100
Validity.
Definition: x509_common.h:527
error_t x509ParseSubjectKeyId(const uint8_t *data, size_t length, X509SubjectKeyId *subjectKeyId)
Parse SubjectKeyIdentifier extension.
#define TRACE_DEBUG(...)
Definition: debug.h:98
const uint8_t X509_NS_CERT_TYPE_OID[9]
Definition: x509_common.c:126
const uint8_t EC_PUBLIC_KEY_OID[7]
Definition: ec.c:45