x509_crl_parse.c
Go to the documentation of this file.
1 /**
2  * @file x509_crl_parse.c
3  * @brief CRL (Certificate Revocation List)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCrypto Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/crypto.h"
36 #include "pkix/x509_cert_parse.h"
37 #include "pkix/x509_crl_parse.h"
38 #include "encoding/asn1.h"
39 #include "encoding/oid.h"
40 #include "debug.h"
41 
42 //Check crypto library configuration
43 #if (X509_SUPPORT == ENABLED)
44 
45 
46 /**
47  * @brief Parse a CRL (Certificate Revocation List)
48  * @param[in] data Pointer to the CRL to parse
49  * @param[in] length Length of the CRL
50  * @param[out] crlInfo Information resulting from the parsing process
51  * @return Error code
52  **/
53 
54 error_t x509ParseCrl(const uint8_t *data, size_t length,
55  X509CrlInfo *crlInfo)
56 {
57  error_t error;
58  size_t totalLength;
59  Asn1Tag tag;
60 
61  //Debug message
62  TRACE_DEBUG("Parsing X.509 CRL...\r\n");
63 
64  //Check parameters
65  if(data == NULL || crlInfo == NULL)
67 
68  //Clear the CRL information structure
69  cryptoMemset(crlInfo, 0, sizeof(X509CrlInfo));
70 
71  //The CRL is encapsulated within a sequence
72  error = asn1ReadTag(data, length, &tag);
73  //Failed to decode ASN.1 tag?
74  if(error)
75  return error;
76 
77  //Point to the very first field
78  data = tag.value;
79  length = tag.length;
80 
81  //Parse TBSCertList structure
82  error = x509ParseTbsCertList(data, length, &totalLength,
83  &crlInfo->tbsCertList);
84  //Any error to report?
85  if(error)
86  return error;
87 
88  //Point to the next field
89  data += totalLength;
90  length -= totalLength;
91 
92  //Parse SignatureAlgorithm structure
93  error = x509ParseSignatureAlgo(data, length, &totalLength,
94  &crlInfo->signatureAlgo);
95  //Any error to report?
96  if(error)
97  return error;
98 
99  //This field must contain the same algorithm identifier as the signature
100  //field in the TBSCertList sequence (refer to RFC 5280, section 5.1.1.2)
101  if(oidComp(crlInfo->signatureAlgo.oid, crlInfo->signatureAlgo.oidLen,
103  {
104  //Report an error
105  return ERROR_WRONG_IDENTIFIER;
106  }
107 
108  //Point to the next field
109  data += totalLength;
110  length -= totalLength;
111 
112  //Parse SignatureValue structure
113  error = x509ParseSignatureValue(data, length, &totalLength,
114  &crlInfo->signatureValue);
115  //Any error to report?
116  if(error)
117  return error;
118 
119  //CRL successfully parsed
120  return NO_ERROR;
121 }
122 
123 
124 /**
125  * @brief Parse TBSCertList structure
126  * @param[in] data Pointer to the ASN.1 structure to parse
127  * @param[in] length Length of the ASN.1 structure
128  * @param[out] totalLength Number of bytes that have been parsed
129  * @param[out] tbsCertList Information resulting from the parsing process
130  * @return Error code
131  **/
132 
133 error_t x509ParseTbsCertList(const uint8_t *data, size_t length,
134  size_t *totalLength, X509TbsCertList *tbsCertList)
135 {
136  error_t error;
137  size_t n;
138  Asn1Tag tag;
139 
140  //Debug message
141  TRACE_DEBUG(" Parsing TBSCertList...\r\n");
142 
143  //Read the contents of the TBSCertList structure
144  error = asn1ReadTag(data, length, &tag);
145  //Failed to decode ASN.1 tag?
146  if(error)
147  return error;
148 
149  //Save the total length of the field
150  *totalLength = tag.totalLength;
151 
152  //The ASN.1 DER-encoded TBSCertList is used as the input to the
153  //signature function
154  tbsCertList->rawData = data;
155  tbsCertList->rawDataLen = tag.totalLength;
156 
157  //Point to the very first field of the TBSCertList
158  data = tag.value;
159  length = tag.length;
160 
161  //Parse Version field
162  error = x509ParseCrlVersion(data, length, &n, &tbsCertList->version);
163  //Any parsing error?
164  if(error)
165  return error;
166 
167  //Point to the next field
168  data += n;
169  length -= n;
170 
171  //Parse Signature field
172  error = x509ParseSignatureAlgo(data, length, &n,
173  &tbsCertList->signatureAlgo);
174  //Any parsing error?
175  if(error)
176  return error;
177 
178  //Point to the next field
179  data += n;
180  length -= n;
181 
182  //Parse Issuer field
183  error = x509ParseName(data, length, &n, &tbsCertList->issuer);
184  //Any parsing error?
185  if(error)
186  return error;
187 
188  //Point to the next field
189  data += n;
190  length -= n;
191 
192  //Parse ThisUpdate field
193  error = x509ParseTime(data, length, &n, &tbsCertList->thisUpdate);
194  //Any parsing error?
195  if(error)
196  return error;
197 
198  //Point to the next field
199  data += n;
200  length -= n;
201 
202  //Parse NextUpdate field
203  error = x509ParseTime(data, length, &n, &tbsCertList->nextUpdate);
204  //Any parsing error?
205  if(error)
206  return error;
207 
208  //Point to the next field
209  data += n;
210  length -= n;
211 
212  //Parse RevokedCertificates field
213  error = x509ParseRevokedCertificates(data, length, &n, tbsCertList);
214  //Any parsing error?
215  if(error)
216  return error;
217 
218  //Point to the next field
219  data += n;
220  length -= n;
221 
222  //Parse CrlExtensions field
223  error = x509ParseCrlExtensions(data, length, &n, &tbsCertList->crlExtensions);
224  //Any parsing error?
225  if(error)
226  return error;
227 
228  //The CrlExtensions field is optional
229  if(n > 0)
230  {
231  //This field must only appear if the version is 2
232  if(tbsCertList->version < X509_VERSION_2)
233  return ERROR_INVALID_VERSION;
234  }
235 
236  //No error to report
237  return NO_ERROR;
238 }
239 
240 
241 /**
242  * @brief Parse Version field
243  * @param[in] data Pointer to the ASN.1 structure to parse
244  * @param[in] length Length of the ASN.1 structure
245  * @param[out] totalLength Number of bytes that have been parsed
246  * @param[out] version Information resulting from the parsing process
247  * @return Error code
248  **/
249 
250 error_t x509ParseCrlVersion(const uint8_t *data, size_t length,
251  size_t *totalLength, X509Version *version)
252 {
253  error_t error;
254  int32_t value;
255  Asn1Tag tag;
256 
257  //Debug message
258  TRACE_DEBUG(" Parsing Version...\r\n");
259 
260  //The Version field is optional
261  error = asn1ReadTag(data, length, &tag);
262  //Failed to decode ASN.1 tag?
263  if(error)
264  return error;
265 
266  //Check encoding, class and type
268 
269  //The tag does not match the criteria?
270  if(error)
271  {
272  //Assume X.509 version 1 format
274  //Skip the current field
275  *totalLength = 0;
276 
277  //Exit immediately
278  return NO_ERROR;
279  }
280 
281  //Parse Version field
282  error = asn1ReadInt32(data, length, &tag, &value);
283  //Failed to decode ASN.1 tag?
284  if(error)
285  return error;
286 
287  //Save the version
289  //Save the total length of the field
290  *totalLength = tag.totalLength;
291 
292  //Successful processing
293  return NO_ERROR;
294 }
295 
296 
297 /**
298  * @brief Parse RevokedCertificates field
299  * @param[in] data Pointer to the ASN.1 structure to parse
300  * @param[in] length Length of the ASN.1 structure
301  * @param[out] totalLength Number of bytes that have been parsed
302  * @param[out] tbsCertList Information resulting from the parsing process
303  * @return Error code
304  **/
305 
307  size_t *totalLength, X509TbsCertList *tbsCertList)
308 {
309  error_t error;
310  size_t n;
311  Asn1Tag tag;
312  X509RevokedCertificate revokedCertificate;
313 
314  //Debug message
315  TRACE_DEBUG(" Parsing RevokedCertificates...\r\n");
316 
317  //The RevokedCertificates is optional
318  error = asn1ReadTag(data, length, &tag);
319  //Failed to decode ASN.1 tag?
320  if(error)
321  return error;
322 
323  //Check encoding, class and type
325 
326  //The tag does not match the criteria?
327  if(error)
328  {
329  //Skip the current field
330  *totalLength = 0;
331  //Exit immediately
332  return NO_ERROR;
333  }
334 
335  //Save the total length of the field
336  *totalLength = tag.totalLength;
337 
338  //Raw contents of the ASN.1 sequence
339  tbsCertList->revokedCerts = tag.value;
340  tbsCertList->revokedCertsLen = tag.length;
341 
342  //Point to the first item of the sequence
343  data = tag.value;
344  length = tag.length;
345 
346  //Loop through the list of revoked certificates
347  while(length > 0)
348  {
349  //Parse current item
350  error = x509ParseRevokedCertificate(data, length, &n, &revokedCertificate);
351  //Any error to report?
352  if(error)
353  return error;
354 
355  //Next item
356  data += n;
357  length -= n;
358  }
359 
360  //Successful processing
361  return NO_ERROR;
362 }
363 
364 
365 /**
366  * @brief Parse RevokedCertificate field
367  * @param[in] data Pointer to the ASN.1 structure to parse
368  * @param[in] length Length of the ASN.1 structure
369  * @param[out] totalLength Number of bytes that have been parsed
370  * @param[out] revokedCertificate Information resulting from the parsing process
371  * @return Error code
372  **/
373 
375  size_t *totalLength, X509RevokedCertificate *revokedCertificate)
376 {
377  error_t error;
378  size_t n;
379  Asn1Tag tag;
380 
381  //Debug message
382  TRACE_DEBUG(" Parsing RevokedCertificate...\r\n");
383 
384  //Clear the RevokedCertificate structure
385  cryptoMemset(revokedCertificate, 0, sizeof(X509RevokedCertificate));
386 
387  //The RevokedCertificate structure shall contain a valid sequence
388  error = asn1ReadSequence(data, length, &tag);
389  //Failed to decode ASN.1 tag?
390  if(error)
391  return error;
392 
393  //Save the total length of the field
394  *totalLength = tag.totalLength;
395 
396  //Point to the first item of the sequence
397  data = tag.value;
398  length = tag.length;
399 
400  //Parse UserCertificate field
401  error = x509ParseSerialNumber(data, length, &n,
402  &revokedCertificate->userCert);
403  //Any error to report?
404  if(error)
405  return error;
406 
407  //Point to the next field
408  data += n;
409  length -= n;
410 
411  //Parse RevocationDate field
412  error = x509ParseTime(data, length, &n,
413  &revokedCertificate->revocationDate);
414  //Any error to report?
415  if(error)
416  return error;
417 
418  //Point to the next field
419  data += n;
420  length -= n;
421 
422  //Parse CrlEntryExtensions field
424  &revokedCertificate->crlEntryExtensions);
425  //Any parsing error?
426  if(error)
427  return error;
428 
429  //Successful processing
430  return NO_ERROR;
431 }
432 
433 
434 /**
435  * @brief Parse CRL extensions
436  * @param[in] data Pointer to the ASN.1 structure to parse
437  * @param[in] length Length of the ASN.1 structure
438  * @param[out] totalLength Number of bytes that have been parsed
439  * @param[out] crlExtensions Information resulting from the parsing process
440  * @return Error code
441  **/
442 
443 error_t x509ParseCrlExtensions(const uint8_t *data, size_t length,
444  size_t *totalLength, X509CrlExtensions *crlExtensions)
445 {
446  error_t error;
447  size_t n;
448  Asn1Tag tag;
449  X509Extension extension;
450 
451  //No more data to process?
452  if(length == 0)
453  {
454  //The CrlExtensions field is optional
455  *totalLength = 0;
456  //Exit immediately
457  return NO_ERROR;
458  }
459 
460  //Explicit tagging is used to encode the CrlExtensions field
461  error = asn1ReadTag(data, length, &tag);
462  //Failed to decode ASN.1 tag?
463  if(error)
464  return error;
465 
466  //Enforce encoding, class and type
467  error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_CONTEXT_SPECIFIC, 0);
468  //Invalid tag?
469  if(error)
470  {
471  //The CrlExtensions field is optional
472  *totalLength = 0;
473  //Exit immediately
474  return NO_ERROR;
475  }
476 
477  //Save the total length of the field
478  *totalLength = tag.totalLength;
479 
480  //Debug message
481  TRACE_DEBUG(" Parsing CrlExtensions...\r\n");
482 
483  //This field is a sequence of one or more CRL extensions
484  error = asn1ReadSequence(tag.value, tag.length, &tag);
485  //Failed to decode ASN.1 tag?
486  if(error)
487  return error;
488 
489  //Raw contents of the ASN.1 sequence
490  crlExtensions->rawData = tag.value;
491  crlExtensions->rawDataLen = tag.length;
492 
493  //Point to the first item of the sequence
494  data = tag.value;
495  length = tag.length;
496 
497  //Loop through the extensions
498  while(length > 0)
499  {
500  //Each extension includes an OID and a value
501  error = x509ParseExtension(data, length, &n, &extension);
502  //Any error to report?
503  if(error)
504  return error;
505 
506  //CRLNumber extension found?
507  if(!oidComp(extension.oid, extension.oidLen,
509  {
510  //Parse CRLNumber extension
511  error = x509ParseCrlNumber(extension.critical, extension.value,
512  extension.valueLen, &crlExtensions->crlNumber);
513  }
514  //DeltaCRLIndicator extension found?
515  else if(!oidComp(extension.oid, extension.oidLen,
517  {
518  //Parse DeltaCRLIndicator extension
519  error = x509ParseDeltaCrlIndicator(extension.critical, extension.value,
520  extension.valueLen, &crlExtensions->deltaCrlIndicator);
521  }
522  //IssuingDistributionPoint extension found?
523  else if(!oidComp(extension.oid, extension.oidLen,
525  {
526  //Parse IssuingDistributionPoint extension
527  error = x509ParseIssuingDistrPoint(extension.critical, extension.value,
528  extension.valueLen, &crlExtensions->issuingDistrPoint);
529  }
530  //AuthorityKeyIdentifier extension found?
531  else if(!oidComp(extension.oid, extension.oidLen,
533  {
534  //Parse AuthorityKeyIdentifier extension
535  error = x509ParseAuthorityKeyId(extension.critical, extension.value,
536  extension.valueLen, &crlExtensions->authKeyId);
537  }
538  //Unknown extension?
539  else
540  {
541  //Check if the extension is marked as critical
542  if(extension.critical)
543  {
544  //If a CRL contains a critical extension that the application cannot
545  //process, then the application must not use that CRL to determine
546  //the status of certificates (refer to RFC 5280, section 5.2)
548  }
549  }
550 
551  //Any parsing error?
552  if(error)
553  return error;
554 
555  //Next extension
556  data += n;
557  length -= n;
558  }
559 
560  //Successful processing
561  return NO_ERROR;
562 }
563 
564 
565 /**
566  * @brief Parse CRLNumber extension
567  * @param[in] critical Critical extension flag
568  * @param[in] data Pointer to the ASN.1 structure to parse
569  * @param[in] length Length of the ASN.1 structure
570  * @param[out] crlNumber Information resulting from the parsing process
571  * @return Error code
572  **/
573 
574 error_t x509ParseCrlNumber(bool_t critical, const uint8_t *data,
575  size_t length, X509CrlNumber *crlNumber)
576 {
577  error_t error;
578  Asn1Tag tag;
579 
580  //Debug message
581  TRACE_DEBUG(" Parsing CRLNumber...\r\n");
582 
583  //An CRL extension can be marked as critical
584  crlNumber->critical = critical;
585 
586  //Read CRLNumber structure
587  error = asn1ReadTag(data, length, &tag);
588  //Failed to decode ASN.1 tag?
589  if(error)
590  return error;
591 
592  //Enforce encoding, class and type
594  //Invalid tag?
595  if(error)
596  return error;
597 
598  //Save the CRL number
599  crlNumber->value = tag.value;
600  crlNumber->length = tag.length;
601 
602  //Successful processing
603  return NO_ERROR;
604 }
605 
606 
607 /**
608  * @brief Parse DeltaCRLIndicator extension
609  * @param[in] critical Critical extension flag
610  * @param[in] data Pointer to the ASN.1 structure to parse
611  * @param[in] length Length of the ASN.1 structure
612  * @param[out] deltaCrlIndicator Information resulting from the parsing process
613  * @return Error code
614  **/
615 
617  size_t length, X509DeltaCrlIndicator *deltaCrlIndicator)
618 {
619  error_t error;
620  Asn1Tag tag;
621 
622  //Debug message
623  TRACE_DEBUG(" Parsing DeltaCRLIndicator...\r\n");
624 
625  //An CRL extension can be marked as critical
626  deltaCrlIndicator->critical = critical;
627 
628  //Read BaseCRLNumber structure
629  error = asn1ReadTag(data, length, &tag);
630  //Failed to decode ASN.1 tag?
631  if(error)
632  return error;
633 
634  //Enforce encoding, class and type
636  //Invalid tag?
637  if(error)
638  return error;
639 
640  //Save the CRL number
641  deltaCrlIndicator->baseCrlNumber = tag.value;
642  deltaCrlIndicator->baseCrlNumberLen = tag.length;
643 
644  //Successful processing
645  return NO_ERROR;
646 }
647 
648 
649 /**
650  * @brief Parse IssuingDistributionPoint extension
651  * @param[in] critical Critical extension flag
652  * @param[in] data Pointer to the ASN.1 structure to parse
653  * @param[in] length Length of the ASN.1 structure
654  * @param[out] issuingDistrPoint Information resulting from the parsing process
655  * @return Error code
656  **/
657 
659  size_t length, X509IssuingDistrPoint *issuingDistrPoint)
660 {
661  error_t error;
662  Asn1Tag tag;
663 
664  //Debug message
665  TRACE_DEBUG(" Parsing IssuingDistributionPoint...\r\n");
666 
667  //An CRL extension can be marked as critical
668  issuingDistrPoint->critical = critical;
669 
670  //The IssuingDistributionPoint extension is encapsulated within a sequence
671  error = asn1ReadSequence(data, length, &tag);
672  //Failed to decode ASN.1 tag?
673  if(error)
674  return error;
675 
676  //Point to the first subfield of the sequence
677  data = tag.value;
678  length = tag.length;
679 
680  //The issuing distribution point is a critical CRL extension that identifies
681  //the CRL distribution point and scope for a particular CRL, and it indicates
682  //whether the CRL covers revocation for end entity certificates only, CA
683  //certificates only, attribute certificates only, or a limited set of reason
684  //codes
685  while(length > 0)
686  {
687  //Read current subfield
688  error = asn1ReadTag(data, length, &tag);
689  //Failed to decode ASN.1 tag?
690  if(error)
691  return error;
692 
693  //Explicit tagging shall be used to encode each subfield
695  return ERROR_INVALID_CLASS;
696 
697  //Check subfield type
698  if(tag.objType == 0)
699  {
700  //Parse distributionPoint subfield
701  }
702  else if(tag.objType == 1)
703  {
704  //Make sure the length of the boolean is valid
705  if(tag.length != 1)
706  return ERROR_INVALID_SYNTAX;
707 
708  //Save the value of the onlyContainsUserCerts subfield
709  issuingDistrPoint->onlyContainsUserCerts = tag.value[0] ? TRUE : FALSE;
710  }
711  else if(tag.objType == 2)
712  {
713  //Make sure the length of the boolean is valid
714  if(tag.length != 1)
715  return ERROR_INVALID_SYNTAX;
716 
717  //Save the value of the onlyContainsCACerts subfield
718  issuingDistrPoint->onlyContainsCaCerts = tag.value[0] ? TRUE : FALSE;
719  }
720  else if(tag.objType == 3)
721  {
722  //Parse onlySomeReasons subfield
723  }
724  else if(tag.objType == 4)
725  {
726  //Make sure the length of the boolean is valid
727  if(tag.length != 1)
728  return ERROR_INVALID_SYNTAX;
729 
730  //Save the value of the indirectCRL subfield
731  issuingDistrPoint->indirectCrl = tag.value[0] ? TRUE : FALSE;
732  }
733  else if(tag.objType == 5)
734  {
735  //Make sure the length of the boolean is valid
736  if(tag.length != 1)
737  return ERROR_INVALID_SYNTAX;
738 
739  //Save the value of the onlyContainsAttributeCerts subfield
740  issuingDistrPoint->onlyContainsAttributeCerts = tag.value[0] ? TRUE : FALSE;
741  }
742  else
743  {
744  //Discard unknown subfields
745  }
746 
747  //Next subfield
748  data += tag.totalLength;
749  length -= tag.totalLength;
750  }
751 
752  //Successful processing
753  return NO_ERROR;
754 }
755 
756 
757 /**
758  * @brief Parse CRL entry extensions
759  * @param[in] data Pointer to the ASN.1 structure to parse
760  * @param[in] length Length of the ASN.1 structure
761  * @param[out] totalLength Number of bytes that have been parsed
762  * @param[out] crlEntryExtensions Information resulting from the parsing process
763  * @return Error code
764  **/
765 
767  size_t *totalLength, X509CrlEntryExtensions *crlEntryExtensions)
768 {
769  error_t error;
770  size_t n;
771  Asn1Tag tag;
772  X509Extension extension;
773 
774  //No more data to process?
775  if(length == 0)
776  {
777  //The CrlEntryExtensions field is optional
778  *totalLength = 0;
779  //Exit immediately
780  return NO_ERROR;
781  }
782 
783  //Debug message
784  TRACE_DEBUG(" Parsing CrlEntryExtensions...\r\n");
785 
786  //This field is a sequence of one or more CRL entry extensions
787  error = asn1ReadSequence(data, length, &tag);
788  //Failed to decode ASN.1 tag?
789  if(error)
790  return error;
791 
792  //Save the total length of the CrlEntryExtensions field
793  *totalLength = tag.totalLength;
794 
795  //Raw contents of the ASN.1 sequence
796  crlEntryExtensions->rawData = tag.value;
797  crlEntryExtensions->rawDataLen = tag.length;
798 
799  //Point to the first item of the sequence
800  data = tag.value;
801  length = tag.length;
802 
803  //Loop through the extensions
804  while(length > 0)
805  {
806  //Each extension includes an OID and a value
807  error = x509ParseExtension(data, length, &n, &extension);
808  //Any error to report?
809  if(error)
810  return error;
811 
812  //ReasonCode extension found?
813  if(!oidComp(extension.oid, extension.oidLen,
815  {
816  //Parse ReasonCode extension
817  error = x509ParseReasonCode(extension.critical, extension.value,
818  extension.valueLen, &crlEntryExtensions->reasonCode);
819  }
820  //InvalidityDate extension found?
821  else if(!oidComp(extension.oid, extension.oidLen,
823  {
824  //Parse InvalidityDate extension
825  error = x509ParseInvalidityDate(extension.critical, extension.value,
826  extension.valueLen, &crlEntryExtensions->invalidityDate);
827  }
828  //CertificateIssuer extension found?
829  else if(!oidComp(extension.oid, extension.oidLen,
831  {
832  //Parse CertificateIssuer extension
833  error = x509ParseCertificateIssuer(extension.critical, extension.value,
834  extension.valueLen, &crlEntryExtensions->certIssuer);
835  }
836  //Unknown extension?
837  else
838  {
839  //Check if the extension is marked as critical
840  if(extension.critical)
841  {
842  //If a CRL contains a critical CRL entry extension that the
843  //application cannot process, then the application must not use
844  //that CRL to determine the status of any certificates
846  }
847  }
848 
849  //Any parsing error?
850  if(error)
851  return error;
852 
853  //Next extension
854  data += n;
855  length -= n;
856  }
857 
858  //Successful processing
859  return NO_ERROR;
860 }
861 
862 
863 /**
864  * @brief Parse ReasonCode entry extension
865  * @param[in] critical Critical extension flag
866  * @param[in] data Pointer to the ASN.1 structure to parse
867  * @param[in] length Length of the ASN.1 structure
868  * @param[out] reasonCode Information resulting from the parsing process
869  * @return Error code
870  **/
871 
872 error_t x509ParseReasonCode(bool_t critical, const uint8_t *data,
873  size_t length, X509CrlReason *reasonCode)
874 {
875  error_t error;
876  Asn1Tag tag;
877 
878  //Debug message
879  TRACE_DEBUG(" Parsing ReasonCode...\r\n");
880 
881  //An CRL entry extension can be marked as critical
882  reasonCode->critical = critical;
883 
884  //Read ReasonCode field
885  error = asn1ReadTag(data, length, &tag);
886  //Failed to decode ASN.1 tag?
887  if(error)
888  return error;
889 
890  //Enforce encoding, class and type
892  //Invalid tag?
893  if(error)
894  return error;
895 
896  //Check the length of the field
897  if(tag.length != 1)
898  return ERROR_INVALID_SYNTAX;
899 
900  //The ReasonCode is a non-critical CRL entry extension that identifies
901  //the reason for the certificate revocation
902  reasonCode->value = tag.value[0];
903 
904  //Successful processing
905  return NO_ERROR;
906 }
907 
908 
909 /**
910  * @brief Parse InvalidityDate entry extension
911  * @param[in] critical Critical extension flag
912  * @param[in] data Pointer to the ASN.1 structure to parse
913  * @param[in] length Length of the ASN.1 structure
914  * @param[out] invalidityDate Information resulting from the parsing process
915  * @return Error code
916  **/
917 
918 error_t x509ParseInvalidityDate(bool_t critical, const uint8_t *data,
919  size_t length, X509InvalidityDate *invalidityDate)
920 {
921  error_t error;
922  size_t n;
923 
924  //Debug message
925  TRACE_DEBUG(" Parsing InvalidityDate...\r\n");
926 
927  //An CRL entry extension can be marked as critical
928  invalidityDate->critical = critical;
929 
930  //Read InvalidityDate field
931  error = x509ParseTime(data, length, &n, &invalidityDate->value);
932 
933  //Return status code
934  return error;
935 }
936 
937 
938 /**
939  * @brief Parse CertificateIssuer entry extension
940  * @param[in] critical Critical extension flag
941  * @param[in] data Pointer to the ASN.1 structure to parse
942  * @param[in] length Length of the ASN.1 structure
943  * @param[out] certificateIssuer Information resulting from the parsing process
944  * @return Error code
945  **/
946 
948  size_t length, X509CertificateIssuer *certificateIssuer)
949 {
950  error_t error;
951  uint_t i;
952  size_t n;
953  Asn1Tag tag;
954  X509GeneralName generalName;
955 
956  //Debug message
957  TRACE_DEBUG(" Parsing CertificateIssuer...\r\n");
958 
959  //An CRL entry extension can be marked as critical
960  certificateIssuer->critical = critical;
961 
962  //The CertificateIssuer structure shall contain a valid sequence
963  error = asn1ReadSequence(data, length, &tag);
964  //Failed to decode ASN.1 tag?
965  if(error)
966  return error;
967 
968  //Raw contents of the ASN.1 sequence
969  certificateIssuer->rawData = tag.value;
970  certificateIssuer->rawDataLen = tag.length;
971 
972  //Point to the first item of the sequence
973  data = tag.value;
974  length = tag.length;
975 
976  //This CRL entry extension identifies the certificate issuer associated
977  //with an entry in an indirect CRL, that is, a CRL that has the indirectCRL
978  //indicator set in its issuing distribution point extension
979  for(i = 0; length > 0; i++)
980  {
981  //Parse GeneralName field
982  error = x509ParseGeneralName(data, length, &n, &generalName);
983  //Any error to report?
984  if(error)
985  return error;
986 
987  //Sanity check
989  {
990  //Save issuer alternative name
991  certificateIssuer->generalNames[i] = generalName;
992  }
993 
994  //Next item
995  data += n;
996  length -= n;
997  }
998 
999  //When present, the certificate issuer CRL entry extension includes one or
1000  //more names (refer to RFC 5280, section 5.3.3)
1001  if(i == 0)
1002  return ERROR_INVALID_SYNTAX;
1003 
1004  //Save the number of issuer alternative names
1005  certificateIssuer->numGeneralNames = MIN(i, X509_MAX_CERT_ISSUER_NAMES);
1006 
1007  //Successful processing
1008  return NO_ERROR;
1009 }
1010 
1011 #endif
error_t x509ParseCrlNumber(bool_t critical, const uint8_t *data, size_t length, X509CrlNumber *crlNumber)
Parse CRLNumber extension.
error_t x509ParseTime(const uint8_t *data, size_t length, size_t *totalLength, DateTime *dateTime)
Parse UTCTime or GeneralizedTime field.
X.509 certificate parsing.
uint8_t length
Definition: dtls_misc.h:149
CRL extensions.
Definition: x509_common.h:968
const uint8_t * rawData
Definition: x509_common.h:957
const uint8_t * oid
Definition: x509_common.h:878
int bool_t
Definition: compiler_port.h:49
error_t x509ParseCrlEntryExtensions(const uint8_t *data, size_t length, size_t *totalLength, X509CrlEntryExtensions *crlEntryExtensions)
Parse CRL entry extensions.
error_t x509ParseTbsCertList(const uint8_t *data, size_t length, size_t *totalLength, X509TbsCertList *tbsCertList)
Parse TBSCertList structure.
error_t x509ParseAuthorityKeyId(bool_t critical, const uint8_t *data, size_t length, X509AuthorityKeyId *authKeyId)
Parse AuthorityKeyIdentifier extension.
OID (Object Identifier)
#define TRUE
Definition: os_port.h:50
bool_t critical
Definition: x509_common.h:831
size_t valueLen
Definition: x509_common.h:833
uint16_t version
Definition: dtls_misc.h:172
const uint8_t * value
Definition: x509_common.h:832
const uint8_t X509_INVALIDITY_DATE_OID[3]
Definition: x509_common.c:114
bool_t critical
Definition: x509_common.h:934
CRL (Certificate Revocation List)
X509GeneralName generalNames[X509_MAX_CERT_ISSUER_NAMES]
Definition: x509_common.h:960
CRL (Certificate Revocation List)
Definition: x509_common.h:1082
const uint8_t X509_ISSUING_DISTR_POINT_OID[3]
Definition: x509_common.c:118
error_t x509ParseSerialNumber(const uint8_t *data, size_t length, size_t *totalLength, X509SerialNumber *serialNumber)
Parse SerialNumber field.
error_t asn1ReadTag(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 tag from the input stream.
Definition: asn1.c:52
error_t x509ParseReasonCode(bool_t critical, const uint8_t *data, size_t length, X509CrlReason *reasonCode)
Parse ReasonCode entry extension.
Invalidity date.
Definition: x509_common.h:943
const uint8_t * rawData
Definition: x509_common.h:1065
error_t x509ParseExtension(const uint8_t *data, size_t length, size_t *totalLength, X509Extension *extension)
Parse X.509 certificate extension.
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:101
X509DeltaCrlIndicator deltaCrlIndicator
Definition: x509_common.h:1053
const uint8_t X509_DELTA_CRL_INDICATOR_OID[3]
Definition: x509_common.c:116
error_t x509ParseCrl(const uint8_t *data, size_t length, X509CrlInfo *crlInfo)
Parse a CRL (Certificate Revocation List)
size_t totalLength
Definition: asn1.h:104
size_t length
Definition: asn1.h:102
error_t x509ParseCrlExtensions(const uint8_t *data, size_t length, size_t *totalLength, X509CrlExtensions *crlExtensions)
Parse CRL extensions.
#define FALSE
Definition: os_port.h:46
Certificate issuer.
Definition: x509_common.h:954
General name.
Definition: x509_common.h:766
Invalid parameter.
Definition: error.h:47
error_t x509ParseInvalidityDate(bool_t critical, const uint8_t *data, size_t length, X509InvalidityDate *invalidityDate)
Parse InvalidityDate entry extension.
const uint8_t * value
Definition: x509_common.h:997
X509CrlNumber crlNumber
Definition: x509_common.h:1052
error_t
Error codes.
Definition: error.h:42
const uint8_t * rawData
Definition: x509_common.h:970
error_t x509ParseName(const uint8_t *data, size_t length, size_t *totalLength, X509Name *name)
Parse Name structure.
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:48
X509Version
X.509 versions.
Definition: x509_common.h:390
X509InvalidityDate invalidityDate
Definition: x509_common.h:973
ASN.1 tag.
Definition: asn1.h:97
X509CrlEntryExtensions crlEntryExtensions
Definition: x509_common.h:986
TBSCertList structure.
Definition: x509_common.h:1063
const uint8_t X509_REASON_CODE_OID[3]
Definition: x509_common.c:112
uint8_t value
Definition: x509_common.h:935
error_t asn1ReadInt32(const uint8_t *data, size_t length, Asn1Tag *tag, int32_t *value)
Read a 32-bit integer from the input stream.
Definition: asn1.c:285
X.509 certificate extension.
Definition: x509_common.h:827
const uint8_t X509_AUTHORITY_KEY_ID_OID[3]
Definition: x509_common.c:130
General definitions for cryptographic algorithms.
size_t rawDataLen
Definition: x509_common.h:971
size_t revokedCertsLen
Definition: x509_common.h:1073
error_t x509ParseRevokedCertificate(const uint8_t *data, size_t length, size_t *totalLength, X509RevokedCertificate *revokedCertificate)
Parse RevokedCertificate field.
uint_t objClass
Definition: asn1.h:100
const uint8_t * rawData
Definition: x509_common.h:1050
error_t x509ParseRevokedCertificates(const uint8_t *data, size_t length, size_t *totalLength, X509TbsCertList *tbsCertList)
Parse RevokedCertificates field.
const uint8_t X509_CRL_NUMBER_OID[3]
Definition: x509_common.c:110
Revoked certificate.
Definition: x509_common.h:982
const uint8_t X509_CERTIFICATE_ISSUER_OID[3]
Definition: x509_common.c:120
X509TbsCertList tbsCertList
Definition: x509_common.h:1084
#define MIN(a, b)
Definition: os_port.h:62
X509CrlExtensions crlExtensions
Definition: x509_common.h:1074
X509SignatureAlgoId signatureAlgo
Definition: x509_common.h:1068
#define X509_MAX_CERT_ISSUER_NAMES
Definition: x509_common.h:352
bool_t onlyContainsAttributeCerts
Definition: x509_common.h:1040
error_t x509ParseIssuingDistrPoint(bool_t critical, const uint8_t *data, size_t length, X509IssuingDistrPoint *issuingDistrPoint)
Parse IssuingDistributionPoint extension.
#define cryptoMemset(p, value, length)
Definition: crypto.h:636
#define TRACE_DEBUG(...)
Definition: debug.h:106
error_t x509ParseSignatureValue(const uint8_t *data, size_t length, size_t *totalLength, X509SignatureValue *signatureValue)
Parse SignatureValue field.
X509IssuingDistrPoint issuingDistrPoint
Definition: x509_common.h:1054
uint8_t n
X509CertificateIssuer certIssuer
Definition: x509_common.h:974
const uint8_t * oid
Definition: x509_common.h:829
X509SignatureValue signatureValue
Definition: x509_common.h:1086
CRL extensions.
Definition: x509_common.h:1048
#define ASN1_CLASS_CONTEXT_SPECIFIC
Definition: asn1.h:50
X509CrlReason reasonCode
Definition: x509_common.h:972
const uint8_t * revokedCerts
Definition: x509_common.h:1072
CRL reason.
Definition: x509_common.h:932
bool_t critical
Definition: x509_common.h:996
Delta CRL indicator.
Definition: x509_common.h:1006
DateTime thisUpdate
Definition: x509_common.h:1070
X509SignatureAlgoId signatureAlgo
Definition: x509_common.h:1085
error_t x509ParseCrlVersion(const uint8_t *data, size_t length, size_t *totalLength, X509Version *version)
Parse Version field.
CRL number.
Definition: x509_common.h:994
X509SerialNumber userCert
Definition: x509_common.h:984
uint8_t value[]
Definition: dtls_misc.h:150
unsigned int uint_t
Definition: compiler_port.h:45
Issuing distribution point.
Definition: x509_common.h:1032
DateTime nextUpdate
Definition: x509_common.h:1071
uint8_t data[]
Definition: dtls_misc.h:176
error_t x509ParseDeltaCrlIndicator(bool_t critical, const uint8_t *data, size_t length, X509DeltaCrlIndicator *deltaCrlIndicator)
Parse DeltaCRLIndicator extension.
error_t x509ParseGeneralName(const uint8_t *data, size_t length, size_t *totalLength, X509GeneralName *generalName)
Parse GeneralName field.
error_t asn1ReadSequence(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 sequence from the input stream.
Definition: asn1.c:163
X509Version version
Definition: x509_common.h:1067
X509AuthorityKeyId authKeyId
Definition: x509_common.h:1055
error_t x509ParseSignatureAlgo(const uint8_t *data, size_t length, size_t *totalLength, X509SignatureAlgoId *signatureAlgo)
Parse SignatureAlgorithm structure.
const uint8_t * value
Definition: asn1.h:103
const uint8_t * baseCrlNumber
Definition: x509_common.h:1009
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:637
Success.
Definition: error.h:44
error_t x509ParseCertificateIssuer(bool_t critical, const uint8_t *data, size_t length, X509CertificateIssuer *certificateIssuer)
Parse CertificateIssuer entry extension.
Debugging facilities.
uint_t objType
Definition: asn1.h:101
ASN.1 (Abstract Syntax Notation One)