asn1.c
Go to the documentation of this file.
1 /**
2  * @file asn1.c
3  * @brief ASN.1 (Abstract Syntax Notation One)
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 "encoding/asn1.h"
37 #include "encoding/oid.h"
38 #include "debug.h"
39 
40 //Check crypto library configuration
41 #if (ASN1_SUPPORT == ENABLED)
42 
43 
44 /**
45  * @brief Read an ASN.1 tag from the input stream
46  * @param[in] data Input stream where to read the tag
47  * @param[in] length Number of bytes available in the input stream
48  * @param[out] tag Structure describing the ASN.1 tag
49  * @return Error code
50  **/
51 
52 error_t asn1ReadTag(const uint8_t *data, size_t length, Asn1Tag *tag)
53 {
54  uint_t i;
55  uint_t n;
56 
57  //Make sure the identifier octet is present
58  if(length == 0)
59  return ERROR_INVALID_TAG;
60 
61  //Save the class of the ASN.1 tag
62  tag->objClass = data[0] & ASN1_CLASS_MASK;
63  //Primitive or constructed encoding?
65 
66  //Check the tag number
67  if((data[0] & ASN1_TAG_NUMBER_MASK) < 31)
68  {
69  //Tag number is in the range 0 to 30
70  tag->objType = data[0] & ASN1_TAG_NUMBER_MASK;
71  //Point to the tag length field
72  i = 1;
73  }
74  else
75  {
76  //If the tag number is greater than or equal to 31,
77  //the subsequent octets will encode the tag number
78  tag->objType = 0;
79 
80  //Decode the tag number
81  for(i = 1; ; i++)
82  {
83  //The field cannot exceed 5 bytes
84  if(i > (sizeof(tag->objType) + 1))
85  return ERROR_INVALID_TAG;
86  //Insufficient number of bytes to decode the tag number?
87  if(!(length - i))
88  return ERROR_INVALID_TAG;
89 
90  //Update the tag number with bits 7 to 1
91  tag->objType = (tag->objType << 7) | (data[i] & 0x7F);
92 
93  //Bit 8 shall be set unless it is the last octet
94  if(!(data[i] & 0x80))
95  break;
96  }
97  //Point to the tag length field
98  i++;
99  }
100 
101  //Insufficient number of bytes to decode the tag length?
102  if(!(length - i))
103  return ERROR_INVALID_TAG;
104 
105  //Short form is used?
106  if(data[i] < 128)
107  {
108  //Bits 7 to 1 encode the number of bytes in the contents
109  tag->length = data[i];
110  //Point to the contents of the tag
111  i++;
112  }
113  //Long form is used?
114  else if(data[i] > 128 && data[i] < 255)
115  {
116  //Bits 7 to 1 encode the number of octets in the length field
117  n = data[i] & 0x7F;
118 
119  //The field cannot exceed 4 bytes
120  if(n > sizeof(tag->length))
121  return ERROR_INVALID_TAG;
122  //Insufficient number of bytes to decode the tag length?
123  if((length - i) < n)
124  return ERROR_INVALID_TAG;
125 
126  //Clear the tag length
127  tag->length = 0;
128 
129  //Read the subsequent octets
130  for(i++; n > 0; n--)
131  {
132  tag->length = (tag->length << 8) | data[i++];
133  }
134  }
135  //Indefinite form is used?
136  else
137  {
138  //Indefinite form is not supported
139  return ERROR_INVALID_TAG;
140  }
141 
142  //Save the pointer to the tag contents
143  tag->value = data + i;
144  //Check the length of tag
145  if((length - i) < tag->length)
146  return ERROR_INVALID_TAG;
147 
148  //Total length occupied by the ASN.1 tag in the input stream
149  tag->totalLength = i + tag->length;
150  //ASN.1 tag successfully decoded
151  return NO_ERROR;
152 }
153 
154 
155 /**
156  * @brief Read an ASN.1 sequence from the input stream
157  * @param[in] data Input stream where to read the tag
158  * @param[in] length Number of bytes available in the input stream
159  * @param[out] tag Structure describing the ASN.1 tag
160  * @return Error code
161  **/
162 
163 error_t asn1ReadSequence(const uint8_t *data, size_t length, Asn1Tag *tag)
164 {
165  error_t error;
166 
167  //Read ASN.1 tag
168  error = asn1ReadTag(data, length, tag);
169 
170  //Check status code
171  if(!error)
172  {
173  //Enforce encoding, class and type
175  }
176 
177  //Return status code
178  return error;
179 }
180 
181 
182 /**
183  * @brief Read an octet string from the input stream
184  * @param[in] data Input stream where to read the tag
185  * @param[in] length Number of bytes available in the input stream
186  * @param[out] tag Structure describing the ASN.1 tag
187  * @return Error code
188  **/
189 
190 error_t asn1ReadOctetString(const uint8_t *data, size_t length, Asn1Tag *tag)
191 {
192  error_t error;
193 
194  //Read ASN.1 tag
195  error = asn1ReadTag(data, length, tag);
196 
197  //Check status code
198  if(!error)
199  {
200  //Enforce encoding, class and type
203  }
204 
205  //Return status code
206  return error;
207 }
208 
209 
210 /**
211  * @brief Read an object identifier from the input stream
212  * @param[in] data Input stream where to read the tag
213  * @param[in] length Number of bytes available in the input stream
214  * @param[out] tag Structure describing the ASN.1 tag
215  * @return Error code
216  **/
217 
218 error_t asn1ReadOid(const uint8_t *data, size_t length, Asn1Tag *tag)
219 {
220  error_t error;
221 
222  //Read ASN.1 tag
223  error = asn1ReadTag(data, length, tag);
224 
225  //Check status code
226  if(!error)
227  {
228  //Enforce encoding, class and type
231  }
232 
233  //Return status code
234  return error;
235 }
236 
237 
238 /**
239  * @brief Read a boolean from the input stream
240  * @param[in] data Input stream where to read the tag
241  * @param[in] length Number of bytes available in the input stream
242  * @param[out] tag Structure describing the ASN.1 tag
243  * @param[out] value Boolean value
244  * @return Error code
245  **/
246 
247 error_t asn1ReadBoolean(const uint8_t *data, size_t length, Asn1Tag *tag,
248  bool_t *value)
249 {
250  error_t error;
251 
252  //Read ASN.1 tag
253  error = asn1ReadTag(data, length, tag);
254  //Failed to decode ASN.1 tag?
255  if(error)
256  return error;
257 
258  //Enforce encoding, class and type
260  //Invalid tag?
261  if(error)
262  return error;
263 
264  //Make sure the length of the boolean is valid
265  if(tag->length != 1)
266  return ERROR_INVALID_LENGTH;
267 
268  //Read the value of the boolean
269  *value = tag->value[0] ? TRUE : FALSE;
270 
271  //ASN.1 tag successfully decoded
272  return NO_ERROR;
273 }
274 
275 
276 /**
277  * @brief Read a 32-bit integer from the input stream
278  * @param[in] data Input stream where to read the tag
279  * @param[in] length Number of bytes available in the input stream
280  * @param[out] tag Structure describing the ASN.1 tag
281  * @param[out] value Integer value
282  * @return Error code
283  **/
284 
285 error_t asn1ReadInt32(const uint8_t *data, size_t length, Asn1Tag *tag,
286  int32_t *value)
287 {
288  error_t error;
289  size_t i;
290 
291  //Read ASN.1 tag
292  error = asn1ReadTag(data, length, tag);
293  //Failed to decode ASN.1 tag?
294  if(error)
295  return error;
296 
297  //Enforce encoding, class and type
299  //Invalid tag?
300  if(error)
301  return error;
302 
303  //The contents shall consist of one or more octets
304  if(tag->length < 1 || tag->length > 4)
305  return ERROR_INVALID_TAG;
306 
307  //The contents octets shall be a two's complement binary
308  //number equal to the integer value
309  *value = (tag->value[0] & 0x80) ? -1 : 0;
310 
311  //Process contents octets
312  for(i = 0; i < tag->length; i++)
313  {
314  //Rotate left operation
315  *value <<= 8;
316  //Reconstruct integer value
317  *value |= tag->value[i];
318  }
319 
320  //ASN.1 tag successfully decoded
321  return NO_ERROR;
322 }
323 
324 
325 /**
326  * @brief Read a multiple-precision integer from the input stream
327  * @param[in] data Input stream where to read the tag
328  * @param[in] length Number of bytes available in the input stream
329  * @param[out] tag Structure describing the ASN.1 tag
330  * @param[out] value Integer value
331  * @return Error code
332  **/
333 
334 error_t asn1ReadMpi(const uint8_t *data, size_t length, Asn1Tag *tag,
335  Mpi *value)
336 {
337 #if (MPI_SUPPORT == ENABLED)
338  error_t error;
339 
340  //Read ASN.1 tag
341  error = asn1ReadTag(data, length, tag);
342  //Failed to decode ASN.1 tag?
343  if(error)
344  return error;
345 
346  //Enforce encoding, class and type
348  //Invalid tag?
349  if(error)
350  return error;
351 
352  //Negative integer?
353  if(tag->length > 0 && (tag->value[0] & 0x80) != 0)
354  return ERROR_INVALID_SYNTAX;
355 
356  //Convert the octet string to a multiple precision integer
357  error = mpiImport(value, tag->value, tag->length, MPI_FORMAT_BIG_ENDIAN);
358 
359  //Return status code
360  return error;
361 #else
362  //Not implemented
363  return ERROR_NOT_IMPLEMENTED;
364 #endif
365 }
366 
367 
368 /**
369  * @brief Write an ASN.1 tag
370  * @param[in] tag Structure describing the ASN.1 tag
371  * @param[in] reverse Use reverse encoding
372  * @param[out] data Output stream where to write the tag (optional parameter)
373  * @param[out] written Number of bytes written to the output stream (optional parameter)
374  * @return Error code
375  **/
376 
377 error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data,
378  size_t *written)
379 {
380  size_t i;
381  size_t m;
382  size_t n;
383 
384  //Compute the number of octets that are necessary to encode the tag number
385  if(tag->objType < 31)
386  m = 0;
387  else if(tag->objType < 128)
388  m = 1;
389  else if(tag->objType < 16384)
390  m = 2;
391  else if(tag->objType < 2097152)
392  m = 3;
393  else if(tag->objType < 268435456)
394  m = 4;
395  else
396  m = 5;
397 
398  //Compute the number of octets that are necessary to encode the length field
399  if(tag->length < 128)
400  n = 0;
401  else if(tag->length < 256)
402  n = 1;
403  else if(tag->length < 65536)
404  n = 2;
405  else if(tag->length < 16777216)
406  n = 3;
407  else
408  n = 4;
409 
410  //Valid output stream?
411  if(data != NULL)
412  {
413  //Use reverse encoding?
414  if(reverse)
415  {
416  //Any data to copy?
417  if(tag->value != NULL && tag->length > 0)
418  {
419  //Make room for the data
420  data -= tag->length;
421  //Copy data
422  cryptoMemmove(data, tag->value, tag->length);
423  }
424 
425  //Move backward
426  data -= m + n + 2;
427  }
428  else
429  {
430  //Any data to copy?
431  if(tag->value != NULL && tag->length > 0)
432  {
433  //Copy data
434  cryptoMemmove(data + m + n + 2, tag->value, tag->length);
435  }
436  }
437 
438  //Save the class of the ASN.1 tag
439  data[0] = tag->objClass;
440 
441  //Primitive or constructed encoding?
442  if(tag->constructed)
444 
445  //Encode the tag number
446  if(m == 0)
447  {
448  //Tag number is in the range 0 to 30
449  data[0] |= tag->objType;
450  }
451  else
452  {
453  //The tag number is greater than or equal to 31
455 
456  //The subsequent octets will encode the tag number
457  for(i = 0; i < m; i++)
458  {
459  //Bits 7 to 1 encode the tag number
460  data[m - i] = (tag->objType >> (i * 7)) & 0x7F;
461 
462  //Bit 8 of each octet shall be set to one unless it is the
463  //last octet of the identifier octets
464  if(i != 0)
465  data[m - i] |= 0x80;
466  }
467  }
468 
469  //Encode the length field
470  if(n == 0)
471  {
472  //Use short form encoding
473  data[1 + m] = tag->length & 0x7F;
474  }
475  else
476  {
477  //Bits 7 to 1 encode the number of octets in the length field
478  data[1 + m] = 0x80 | (n & 0x7F);
479 
480  //The subsequent octets will encode the length field
481  for(i = 0; i < n; i++)
482  {
483  data[1 + m + n - i] = (tag->length >> (i * 8)) & 0xFF;
484  }
485  }
486  }
487 
488  //Total length occupied by the ASN.1 tag
489  tag->totalLength = tag->length + m + n + 2;
490 
491  //The last parameter is optional
492  if(written != NULL)
493  {
494  //Number of bytes written to the output stream
495  *written = m + n + 2;
496 
497  //Any data copied?
498  if(tag->value != NULL)
499  *written += tag->length;
500  }
501 
502  //Successful processing
503  return NO_ERROR;
504 }
505 
506 
507 /**
508  * @brief Write a 32-bit integer to the output stream
509  * @param[in] value Integer value
510  * @param[in] reverse Use reverse encoding
511  * @param[out] data Output stream where to write the tag (optional parameter)
512  * @param[out] written Number of bytes written to the output stream
513  * @return Error code
514  **/
515 
516 error_t asn1WriteInt32(int32_t value, bool_t reverse, uint8_t *data,
517  size_t *written)
518 {
519  size_t i;
520  size_t n;
521  uint16_t msb;
522 
523  //An integer value is always encoded in the smallest possible number of
524  //octets
525  for(n = 4; n > 1; n--)
526  {
527  //Retrieve the upper 9 bits
528  msb = (value >> (n * 8 - 9)) & 0x01FF;
529 
530  //The upper 9 bits shall not have the same value (all 0 or all 1)
531  if(msb != 0x0000 && msb != 0x01FF)
532  break;
533  }
534 
535  //Valid output stream?
536  if(data != NULL)
537  {
538  //Use reverse encoding?
539  if(reverse)
540  data -= n + 2;
541 
542  //Write tag type
544  //Write tag length
545  data[1] = n & 0xFF;
546 
547  //Write contents octets
548  for(i = 0; i < n; i++)
549  {
550  data[1 + n - i] = (value >> (i * 8)) & 0xFF;
551  }
552  }
553 
554  //Number of bytes written to the output stream
555  if(written != NULL)
556  *written = n + 2;
557 
558  //Successful processing
559  return NO_ERROR;
560 }
561 
562 
563 /**
564  * @brief Write a multiple-precision integer from the output stream
565  * @param[in] value Integer value
566  * @param[in] reverse Use reverse encoding
567  * @param[out] data Output stream where to write the tag (optional parameter)
568  * @param[out] written Number of bytes written to the output stream
569  * @return Error code
570  **/
571 
572 error_t asn1WriteMpi(const Mpi *value, bool_t reverse, uint8_t *data,
573  size_t *written)
574 {
575 #if (MPI_SUPPORT == ENABLED)
576  error_t error;
577  size_t n;
578  Asn1Tag tag;
579 
580  //Retrieve the length of the multiple precision integer
582 
583  //An integer value is always encoded in the smallest possible number of
584  //octets
585  n = (n / 8) + 1;
586 
587  //Valid output stream?
588  if(data != NULL)
589  {
590  //Use reverse encoding?
591  if(reverse)
592  data -= n;
593 
594  //The value of the multiple precision integer is encoded MSB first
596  //Any error to report?
597  if(error)
598  return error;
599  }
600 
601  //The integer is encapsulated within an ASN.1 structure
602  tag.constructed = FALSE;
605  tag.length = n;
606  tag.value = data;
607 
608  //Compute the length of the corresponding ASN.1 structure
609  error = asn1WriteTag(&tag, FALSE, data, NULL);
610  //Any error to report?
611  if(error)
612  return error;
613 
614  //Number of bytes written to the output stream
615  if(written != NULL)
616  *written = tag.totalLength;
617 
618  //Successful processing
619  return NO_ERROR;
620 #else
621  //Not implemented
622  return ERROR_NOT_IMPLEMENTED;
623 #endif
624 }
625 
626 
627 /**
628  * @brief Enforce the type of a specified tag
629  * @param[in] tag Pointer to an ASN.1 tag
630  * @param[in] constructed Expected encoding (TRUE for constructed, FALSE
631  * for primitive)
632  * @param[in] objClass Expected tag class
633  * @param[in] objType Expected tag type
634  * @return Error code
635  **/
636 
637 error_t asn1CheckTag(const Asn1Tag *tag, bool_t constructed, uint_t objClass,
638  uint_t objType)
639 {
640  //Check encoding
641  if(tag->constructed != constructed)
642  return ERROR_WRONG_ENCODING;
643  //Enforce class
644  if(tag->objClass != objClass)
645  return ERROR_INVALID_CLASS;
646  //Enforce type
647  if(tag->objType != objType)
648  return ERROR_INVALID_TYPE;
649 
650  //The tag matches all the criteria
651  return NO_ERROR;
652 }
653 
654 
655 /**
656  * @brief Check ASN.1 tag against a specified OID
657  * @param[in] tag Pointer to an ASN.1 tag
658  * @param[in] oid Expected object identifier (OID)
659  * @param[in] length Length of the OID
660  * @return Error code
661  **/
662 
663 error_t asn1CheckOid(const Asn1Tag *tag, const uint8_t *oid, size_t length)
664 {
665  error_t error;
666 
667  //Enforce encoding, class and type
669  //Any error to report?
670  if(error)
671  return error;
672 
673  //Compare OID against the specified value
674  if(oidComp(tag->value, tag->length, oid, length))
675  return ERROR_WRONG_IDENTIFIER;
676 
677  //The tag matches all the criteria
678  return NO_ERROR;
679 }
680 
681 
682 /**
683  * @brief Display an ASN.1 data object
684  * @param[in] data Pointer to the ASN.1 object to dump
685  * @param[in] length Length of the ASN.1 object
686  * @param[in] level Current level of recursion (this parameter shall be set to 0)
687  * @return Error code
688  **/
689 
690 error_t asn1DumpObject(const uint8_t *data, size_t length, uint_t level)
691 {
692 //Check debugging level
693 #if (TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
694  error_t error;
695  uint_t i;
696  Asn1Tag tag;
697 
698  //ASN.1 universal types
699  static const char_t *label[32] =
700  {
701  "[0]",
702  "BOOLEAN",
703  "INTEGER",
704  "BIT STRING",
705  "OCTET STRING",
706  "NULL",
707  "OBJECT IDENTIFIER",
708  "OBJECT DESCRIPTOR",
709  "EXTERNAL",
710  "REAL",
711  "ENUMERATED",
712  "[11]",
713  "UTF8 STRING",
714  "[13]",
715  "[14]",
716  "[15]",
717  "SEQUENCE",
718  "SET",
719  "NUMERIC STRING",
720  "PRINTABLE STRING",
721  "TELETEX STRING",
722  "VIDEOTEX STRING",
723  "IA5 STRING",
724  "UTC TIME",
725  "GENERALIZED TIME",
726  "GRAPHIC STRING",
727  "VISIBLE STRING",
728  "GENERAL STRING",
729  "UNIVERSAL STRING",
730  "[29]",
731  "BMP STRING",
732  "[31]"
733  };
734 
735  //Prefix used to format the structure
736  static const char_t *prefix[10] =
737  {
738  "",
739  " ",
740  " ",
741  " ",
742  " ",
743  " ",
744  " ",
745  " ",
746  " ",
747  " "
748  };
749 
750  //Parse ASN.1 object
751  while(length > 0)
752  {
753  //Decode current ASN.1 tag
754  error = asn1ReadTag(data, length, &tag);
755  //Decoding failed?
756  if(error)
757  return error;
758 
759  //Point to the next field
760  data += tag.totalLength;
761  length -= tag.totalLength;
762 
763  //Dump tag number, tag class, and contents length fields
764  if(tag.objType < 32 && (tag.objClass & ASN1_CLASS_MASK) == ASN1_CLASS_UNIVERSAL)
765  TRACE_DEBUG("%s%s (%" PRIuSIZE " bytes)\r\n", prefix[level], label[tag.objType], tag.length);
766  else
767  TRACE_DEBUG("%s[%u] (%" PRIuSIZE " bytes)\r\n", prefix[level], tag.objType, tag.length);
768 
769  //Constructed type?
770  if(tag.constructed)
771  {
772  //Check whether the maximum level of recursion is reached
773  if(level < 8)
774  {
775  //Recursive decoding of the ASN.1 tag
776  error = asn1DumpObject(tag.value, tag.length, level + 1);
777  //Decoding failed?
778  if(error)
779  return error;
780  }
781  else
782  {
783  //If the maximum level of recursion is reached, then dump contents
784  TRACE_DEBUG_ARRAY(prefix[level + 1], tag.value, tag.length);
785  }
786  }
787  //Primitive type?
788  else
789  {
790  //Check the type of the current tag
791  switch(tag.objType)
792  {
793  //OID?
795  //Append prefix
796  TRACE_DEBUG(prefix[level + 1]);
797  //Print OID
798  TRACE_DEBUG("%s", oidToString(tag.value, tag.length, NULL, 0));
799  //Add a line feed
800  TRACE_DEBUG("\r\n");
801  break;
802 
803  //String?
815  //Append prefix
816  TRACE_DEBUG("%s", prefix[level + 1]);
817 
818  //Dump the entire string
819  for(i = 0; i < tag.length; i++)
820  {
821  TRACE_DEBUG("%c", tag.value[i]);
822  }
823 
824  //Add a line feed
825  TRACE_DEBUG("\r\n");
826  break;
827 
828  //UTC time?
829  case ASN1_TYPE_UTC_TIME:
830  //Check length
831  if(tag.length != 13)
832  return ERROR_WRONG_ENCODING;
833  //The encoding shall terminate with a "Z"
834  if(tag.value[tag.length - 1] != 'Z')
835  return ERROR_WRONG_ENCODING;
836 
837  //Append prefix
838  TRACE_DEBUG("%s", prefix[level + 1]);
839  //Display date
840  TRACE_DEBUG("%c%c/%c%c/%c%c ", tag.value[0], tag.value[1],
841  tag.value[2], tag.value[3], tag.value[4], tag.value[5]);
842  //Display time
843  TRACE_DEBUG("%c%c:%c%c:%c%c", tag.value[6], tag.value[7],
844  tag.value[8], tag.value[9], tag.value[10], tag.value[11]);
845  //Add a line feed
846  TRACE_DEBUG("\r\n");
847  break;
848 
849  //Generalized time?
851  //Check length
852  if(tag.length != 15)
853  return ERROR_WRONG_ENCODING;
854  //The encoding shall terminate with a "Z"
855  if(tag.value[tag.length - 1] != 'Z')
856  return ERROR_WRONG_ENCODING;
857 
858  //Append prefix
859  TRACE_DEBUG("%s", prefix[level + 1]);
860  //Display date
861  TRACE_DEBUG("%c%c%c%c/%c%c/%c%c ", tag.value[0], tag.value[1], tag.value[2],
862  tag.value[3], tag.value[4], tag.value[5], tag.value[6], tag.value[7]);
863  //Display time
864  TRACE_DEBUG("%c%c:%c%c:%c%c", tag.value[8], tag.value[9],
865  tag.value[10], tag.value[11], tag.value[12], tag.value[13]);
866  //Add a line feed
867  TRACE_DEBUG("\r\n");
868  break;
869 
870  //Any other type?
871  default:
872  //Dump the contents of the tag
873  TRACE_DEBUG_ARRAY(prefix[level + 1], tag.value, tag.length);
874  break;
875  }
876  }
877  }
878 #endif
879 
880  //ASN.1 object successfully decoded
881  return NO_ERROR;
882 }
883 
884 #endif
uint8_t length
Definition: dtls_misc.h:149
@ ASN1_TYPE_UTC_TIME
Definition: asn1.h:83
@ ASN1_TYPE_GENERALIZED_TIME
Definition: asn1.h:84
int bool_t
Definition: compiler_port.h:49
Arbitrary precision integer.
Definition: mpi.h:69
@ ASN1_TYPE_VIDEOTEX_STRING
Definition: asn1.h:81
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
#define ASN1_CLASS_MASK
Definition: asn1.h:47
OID (Object Identifier)
#define TRUE
Definition: os_port.h:50
@ ASN1_TYPE_UTF8_STRING
Definition: asn1.h:75
error_t asn1ReadBoolean(const uint8_t *data, size_t length, Asn1Tag *tag, bool_t *value)
Read a boolean from the input stream.
Definition: asn1.c:247
error_t asn1DumpObject(const uint8_t *data, size_t length, uint_t level)
Display an ASN.1 data object.
Definition: asn1.c:690
@ ASN1_TYPE_IA5_STRING
Definition: asn1.h:82
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 mpiImport(Mpi *r, const uint8_t *data, uint_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:533
Ipv6Addr prefix
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:101
#define ASN1_ENCODING_CONSTRUCTED
Definition: asn1.h:44
error_t asn1ReadOid(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an object identifier from the input stream.
Definition: asn1.c:218
uint8_t level
Definition: tls.h:1702
size_t totalLength
Definition: asn1.h:104
size_t length
Definition: asn1.h:102
#define FALSE
Definition: os_port.h:46
error_t asn1ReadOctetString(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an octet string from the input stream.
Definition: asn1.c:190
error_t mpiExport(const Mpi *a, uint8_t *data, uint_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:618
error_t
Error codes.
Definition: error.h:42
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:48
@ ASN1_TYPE_GRAPHIC_STRING
Definition: asn1.h:85
ASN.1 tag.
Definition: asn1.h:97
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
@ ASN1_TYPE_UNIVERSAL_STRING
Definition: asn1.h:88
#define ASN1_TAG_NUMBER_MASK
Definition: asn1.h:39
@ ASN1_TYPE_VISIBLE_STRING
Definition: asn1.h:86
@ ERROR_INVALID_LENGTH
Definition: error.h:109
General definitions for cryptographic algorithms.
uint8_t oid[1]
Definition: mib_common.h:186
#define cryptoMemmove(dest, src, length)
Definition: crypto.h:648
error_t asn1WriteMpi(const Mpi *value, bool_t reverse, uint8_t *data, size_t *written)
Write a multiple-precision integer from the output stream.
Definition: asn1.c:572
error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag.
Definition: asn1.c:377
@ ERROR_INVALID_TYPE
Definition: error.h:113
uint_t objClass
Definition: asn1.h:100
@ ASN1_TYPE_PRINTABLE_STRING
Definition: asn1.h:79
error_t asn1CheckOid(const Asn1Tag *tag, const uint8_t *oid, size_t length)
Check ASN.1 tag against a specified OID.
Definition: asn1.c:663
@ ASN1_TYPE_TELETEX_STRING
Definition: asn1.h:80
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:195
@ ASN1_TYPE_OCTET_STRING
Definition: asn1.h:68
@ ASN1_TYPE_INTEGER
Definition: asn1.h:66
#define TRACE_DEBUG(...)
Definition: debug.h:106
char char_t
Definition: compiler_port.h:43
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:107
uint8_t m
Definition: ndp.h:302
uint8_t n
char_t * oidToString(const uint8_t *oid, size_t oidLen, char_t *str, size_t maxStrLen)
Convert a binary OID to a string representation.
Definition: oid.c:542
error_t asn1ReadMpi(const uint8_t *data, size_t length, Asn1Tag *tag, Mpi *value)
Read a multiple-precision integer from the input stream.
Definition: asn1.c:334
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:61
bool_t constructed
Definition: asn1.h:99
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:88
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
@ ASN1_TYPE_OBJECT_IDENTIFIER
Definition: asn1.h:70
@ ASN1_TYPE_SEQUENCE
Definition: asn1.h:76
@ ERROR_WRONG_ENCODING
Definition: error.h:120
@ ERROR_INVALID_TAG
Definition: error.h:112
@ ASN1_TYPE_BMP_STRING
Definition: asn1.h:89
@ ERROR_INVALID_CLASS
Definition: error.h:115
uint8_t value[]
Definition: dtls_misc.h:150
#define PRIuSIZE
Definition: compiler_port.h:78
unsigned int uint_t
Definition: compiler_port.h:45
uint8_t data[]
Definition: dtls_misc.h:176
error_t asn1ReadSequence(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 sequence from the input stream.
Definition: asn1.c:163
error_t asn1WriteInt32(int32_t value, bool_t reverse, uint8_t *data, size_t *written)
Write a 32-bit integer to the output stream.
Definition: asn1.c:516
@ ASN1_TYPE_NUMERIC_STRING
Definition: asn1.h:78
@ ASN1_TYPE_BOOLEAN
Definition: asn1.h:65
const uint8_t * value
Definition: asn1.h:103
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
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
uint_t objType
Definition: asn1.h:101
ASN.1 (Abstract Syntax Notation One)
@ ASN1_TYPE_GENERAL_STRING
Definition: asn1.h:87