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-2021 Oryx Embedded SARL. All rights reserved.
10 *
11 * This file is part of CycloneCRYPTO Open.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 *
27 * @author Oryx Embedded SARL (www.oryx-embedded.com)
28 * @version 2.1.2
29 **/
30
31//Switch to the appropriate trace level
32#define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33
34//Dependencies
35#include "core/crypto.h"
36#include "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
52error_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
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
163error_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
190error_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
218error_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
247error_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)
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
285error_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 Write an ASN.1 tag
327 * @param[in] tag Structure describing the ASN.1 tag
328 * @param[in] reverse Use reverse encoding
329 * @param[out] data Output stream where to write the tag (optional parameter)
330 * @param[out] written Number of bytes written to the output stream (optional parameter)
331 * @return Error code
332 **/
333
334error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data,
335 size_t *written)
336{
337 size_t i;
338 size_t m;
339 size_t n;
340
341 //Compute the number of octets that are necessary to encode the tag number
342 if(tag->objType < 31)
343 {
344 m = 0;
345 }
346 else if(tag->objType < 128)
347 {
348 m = 1;
349 }
350 else if(tag->objType < 16384)
351 {
352 m = 2;
353 }
354 else if(tag->objType < 2097152)
355 {
356 m = 3;
357 }
358 else if(tag->objType < 268435456)
359 {
360 m = 4;
361 }
362 else
363 {
364 m = 5;
365 }
366
367 //Compute the number of octets that are necessary to encode the length field
368 if(tag->length < 128)
369 {
370 n = 0;
371 }
372 else if(tag->length < 256)
373 {
374 n = 1;
375 }
376 else if(tag->length < 65536)
377 {
378 n = 2;
379 }
380 else if(tag->length < 16777216)
381 {
382 n = 3;
383 }
384 else
385 {
386 n = 4;
387 }
388
389 //Valid output stream?
390 if(data != NULL)
391 {
392 //Use reverse encoding?
393 if(reverse)
394 {
395 //Any data to copy?
396 if(tag->value != NULL && tag->length > 0)
397 {
398 //Make room for the data
399 data -= tag->length;
400 //Copy data
401 osMemmove(data, tag->value, tag->length);
402 }
403
404 //Move backward
405 data -= m + n + 2;
406 }
407 else
408 {
409 //Any data to copy?
410 if(tag->value != NULL && tag->length > 0)
411 {
412 //Copy data
413 osMemmove(data + m + n + 2, tag->value, tag->length);
414 }
415 }
416
417 //Save the class of the ASN.1 tag
418 data[0] = tag->objClass;
419
420 //Primitive or constructed encoding?
421 if(tag->constructed)
423
424 //Encode the tag number
425 if(m == 0)
426 {
427 //Tag number is in the range 0 to 30
428 data[0] |= tag->objType;
429 }
430 else
431 {
432 //The tag number is greater than or equal to 31
434
435 //The subsequent octets will encode the tag number
436 for(i = 0; i < m; i++)
437 {
438 //Bits 7 to 1 encode the tag number
439 data[m - i] = (tag->objType >> (i * 7)) & 0x7F;
440
441 //Bit 8 of each octet shall be set to one unless it is the
442 //last octet of the identifier octets
443 if(i != 0)
444 data[m - i] |= 0x80;
445 }
446 }
447
448 //Encode the length field
449 if(n == 0)
450 {
451 //Use short form encoding
452 data[1 + m] = tag->length & 0x7F;
453 }
454 else
455 {
456 //Bits 7 to 1 encode the number of octets in the length field
457 data[1 + m] = 0x80 | (n & 0x7F);
458
459 //The subsequent octets will encode the length field
460 for(i = 0; i < n; i++)
461 {
462 data[1 + m + n - i] = (tag->length >> (i * 8)) & 0xFF;
463 }
464 }
465 }
466
467 //Total length occupied by the ASN.1 tag
468 tag->totalLength = tag->length + m + n + 2;
469
470 //The last parameter is optional
471 if(written != NULL)
472 {
473 //Number of bytes written to the output stream
474 *written = m + n + 2;
475
476 //Any data copied?
477 if(tag->value != NULL)
478 *written += tag->length;
479 }
480
481 //Successful processing
482 return NO_ERROR;
483}
484
485
486/**
487 * @brief Write a 32-bit integer to the output stream
488 * @param[in] value Integer value
489 * @param[in] reverse Use reverse encoding
490 * @param[out] data Output stream where to write the tag (optional parameter)
491 * @param[out] written Number of bytes written to the output stream
492 * @return Error code
493 **/
494
495error_t asn1WriteInt32(int32_t value, bool_t reverse, uint8_t *data,
496 size_t *written)
497{
498 size_t i;
499 size_t n;
500 uint16_t msb;
501
502 //An integer value is always encoded in the smallest possible number of
503 //octets
504 for(n = 4; n > 1; n--)
505 {
506 //Retrieve the upper 9 bits
507 msb = (value >> (n * 8 - 9)) & 0x01FF;
508
509 //The upper 9 bits shall not have the same value (all 0 or all 1)
510 if(msb != 0x0000 && msb != 0x01FF)
511 break;
512 }
513
514 //Valid output stream?
515 if(data != NULL)
516 {
517 //Use reverse encoding?
518 if(reverse)
519 data -= n + 2;
520
521 //Write tag type
523 //Write tag length
524 data[1] = n & 0xFF;
525
526 //Write contents octets
527 for(i = 0; i < n; i++)
528 {
529 data[1 + n - i] = (value >> (i * 8)) & 0xFF;
530 }
531 }
532
533 //Number of bytes written to the output stream
534 if(written != NULL)
535 *written = n + 2;
536
537 //Successful processing
538 return NO_ERROR;
539}
540
541
542#if (MPI_SUPPORT == ENABLED)
543
544/**
545 * @brief Read a multiple-precision integer from the input stream
546 * @param[in] data Input stream where to read the tag
547 * @param[in] length Number of bytes available in the input stream
548 * @param[out] tag Structure describing the ASN.1 tag
549 * @param[out] value Integer value
550 * @return Error code
551 **/
552
553error_t asn1ReadMpi(const uint8_t *data, size_t length, Asn1Tag *tag,
554 Mpi *value)
555{
556 error_t error;
557
558 //Read ASN.1 tag
559 error = asn1ReadTag(data, length, tag);
560 //Failed to decode ASN.1 tag?
561 if(error)
562 return error;
563
564 //Enforce encoding, class and type
566 //Invalid tag?
567 if(error)
568 return error;
569
570 //Negative integer?
571 if(tag->length > 0 && (tag->value[0] & 0x80) != 0)
573
574 //Convert the octet string to a multiple precision integer
575 error = mpiImport(value, tag->value, tag->length, MPI_FORMAT_BIG_ENDIAN);
576
577 //Return status code
578 return error;
579}
580
581
582/**
583 * @brief Write a multiple-precision integer from the output stream
584 * @param[in] value Integer value
585 * @param[in] reverse Use reverse encoding
586 * @param[out] data Output stream where to write the tag (optional parameter)
587 * @param[out] written Number of bytes written to the output stream
588 * @return Error code
589 **/
590
591error_t asn1WriteMpi(const Mpi *value, bool_t reverse, uint8_t *data,
592 size_t *written)
593{
594 error_t error;
595 size_t n;
596 Asn1Tag tag;
597
598 //Retrieve the length of the multiple precision integer
600
601 //An integer value is always encoded in the smallest possible number of
602 //octets
603 n = (n / 8) + 1;
604
605 //Valid output stream?
606 if(data != NULL)
607 {
608 //Use reverse encoding?
609 if(reverse)
610 data -= n;
611
612 //The value of the multiple precision integer is encoded MSB first
614 //Any error to report?
615 if(error)
616 return error;
617 }
618
619 //The integer is encapsulated within an ASN.1 structure
620 tag.constructed = FALSE;
623 tag.length = n;
624 tag.value = data;
625
626 //Compute the length of the corresponding ASN.1 structure
627 error = asn1WriteTag(&tag, FALSE, data, NULL);
628 //Any error to report?
629 if(error)
630 return error;
631
632 //Number of bytes written to the output stream
633 if(written != NULL)
634 *written = tag.totalLength;
635
636 //Successful processing
637 return NO_ERROR;
638}
639
640#endif
641
642
643/**
644 * @brief Enforce the type of a specified tag
645 * @param[in] tag Pointer to an ASN.1 tag
646 * @param[in] constructed Expected encoding (TRUE for constructed, FALSE
647 * for primitive)
648 * @param[in] objClass Expected tag class
649 * @param[in] objType Expected tag type
650 * @return Error code
651 **/
652
653error_t asn1CheckTag(const Asn1Tag *tag, bool_t constructed, uint_t objClass,
654 uint_t objType)
655{
656 //Check encoding
657 if(tag->constructed != constructed)
659 //Enforce class
660 if(tag->objClass != objClass)
661 return ERROR_INVALID_CLASS;
662 //Enforce type
663 if(tag->objType != objType)
664 return ERROR_INVALID_TYPE;
665
666 //The tag matches all the criteria
667 return NO_ERROR;
668}
669
670
671/**
672 * @brief Check ASN.1 tag against a specified OID
673 * @param[in] tag Pointer to an ASN.1 tag
674 * @param[in] oid Expected object identifier (OID)
675 * @param[in] length Length of the OID
676 * @return Error code
677 **/
678
679error_t asn1CheckOid(const Asn1Tag *tag, const uint8_t *oid, size_t length)
680{
681 error_t error;
682
683 //Enforce encoding, class and type
685 //Any error to report?
686 if(error)
687 return error;
688
689 //Compare OID against the specified value
690 if(oidComp(tag->value, tag->length, oid, length))
692
693 //The tag matches all the criteria
694 return NO_ERROR;
695}
696
697
698/**
699 * @brief Display an ASN.1 data object
700 * @param[in] data Pointer to the ASN.1 object to dump
701 * @param[in] length Length of the ASN.1 object
702 * @param[in] level Current level of recursion (this parameter shall be set to 0)
703 * @return Error code
704 **/
705
707{
708//Check debugging level
709#if (TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
710 error_t error;
711 uint_t i;
712 Asn1Tag tag;
713
714 //ASN.1 universal types
715 static const char_t *label[32] =
716 {
717 "[0]",
718 "BOOLEAN",
719 "INTEGER",
720 "BIT STRING",
721 "OCTET STRING",
722 "NULL",
723 "OBJECT IDENTIFIER",
724 "OBJECT DESCRIPTOR",
725 "EXTERNAL",
726 "REAL",
727 "ENUMERATED",
728 "[11]",
729 "UTF8 STRING",
730 "[13]",
731 "[14]",
732 "[15]",
733 "SEQUENCE",
734 "SET",
735 "NUMERIC STRING",
736 "PRINTABLE STRING",
737 "TELETEX STRING",
738 "VIDEOTEX STRING",
739 "IA5 STRING",
740 "UTC TIME",
741 "GENERALIZED TIME",
742 "GRAPHIC STRING",
743 "VISIBLE STRING",
744 "GENERAL STRING",
745 "UNIVERSAL STRING",
746 "[29]",
747 "BMP STRING",
748 "[31]"
749 };
750
751 //Prefix used to format the structure
752 static const char_t *prefix[10] =
753 {
754 "",
755 " ",
756 " ",
757 " ",
758 " ",
759 " ",
760 " ",
761 " ",
762 " ",
763 " "
764 };
765
766 //Parse ASN.1 object
767 while(length > 0)
768 {
769 //Decode current ASN.1 tag
770 error = asn1ReadTag(data, length, &tag);
771 //Decoding failed?
772 if(error)
773 return error;
774
775 //Point to the next field
776 data += tag.totalLength;
777 length -= tag.totalLength;
778
779 //Dump tag number, tag class, and contents length fields
780 if(tag.objType < 32 && (tag.objClass & ASN1_CLASS_MASK) == ASN1_CLASS_UNIVERSAL)
781 {
782 TRACE_DEBUG("%s%s (%" PRIuSIZE " bytes)\r\n", prefix[level], label[tag.objType], tag.length);
783 }
784 else
785 {
786 TRACE_DEBUG("%s[%u] (%" PRIuSIZE " bytes)\r\n", prefix[level], tag.objType, tag.length);
787 }
788
789 //Constructed type?
790 if(tag.constructed)
791 {
792 //Check whether the maximum level of recursion is reached
793 if(level < 8)
794 {
795 //Recursive decoding of the ASN.1 tag
796 error = asn1DumpObject(tag.value, tag.length, level + 1);
797 //Decoding failed?
798 if(error)
799 return error;
800 }
801 else
802 {
803 //If the maximum level of recursion is reached, then dump contents
804 TRACE_DEBUG_ARRAY(prefix[level + 1], tag.value, tag.length);
805 }
806 }
807 //Primitive type?
808 else
809 {
810 //Check the type of the current tag
811 switch(tag.objType)
812 {
813 //OID?
815 //Append prefix
817 //Print OID
818 TRACE_DEBUG("%s", oidToString(tag.value, tag.length, NULL, 0));
819 //Add a line feed
820 TRACE_DEBUG("\r\n");
821 break;
822
823 //String?
835 //Append prefix
836 TRACE_DEBUG("%s", prefix[level + 1]);
837
838 //Dump the entire string
839 for(i = 0; i < tag.length; i++)
840 {
841 TRACE_DEBUG("%c", tag.value[i]);
842 }
843
844 //Add a line feed
845 TRACE_DEBUG("\r\n");
846 break;
847
848 //UTC time?
850 //Check length
851 if(tag.length != 13)
853 //The encoding shall terminate with a "Z"
854 if(tag.value[tag.length - 1] != 'Z')
856
857 //Append prefix
858 TRACE_DEBUG("%s", prefix[level + 1]);
859 //Display date
860 TRACE_DEBUG("%c%c/%c%c/%c%c ", tag.value[0], tag.value[1],
861 tag.value[2], tag.value[3], tag.value[4], tag.value[5]);
862 //Display time
863 TRACE_DEBUG("%c%c:%c%c:%c%c", tag.value[6], tag.value[7],
864 tag.value[8], tag.value[9], tag.value[10], tag.value[11]);
865 //Add a line feed
866 TRACE_DEBUG("\r\n");
867 break;
868
869 //Generalized time?
871 //Check length
872 if(tag.length != 15)
874 //The encoding shall terminate with a "Z"
875 if(tag.value[tag.length - 1] != 'Z')
877
878 //Append prefix
879 TRACE_DEBUG("%s", prefix[level + 1]);
880 //Display date
881 TRACE_DEBUG("%c%c%c%c/%c%c/%c%c ", tag.value[0], tag.value[1], tag.value[2],
882 tag.value[3], tag.value[4], tag.value[5], tag.value[6], tag.value[7]);
883 //Display time
884 TRACE_DEBUG("%c%c:%c%c:%c%c", tag.value[8], tag.value[9],
885 tag.value[10], tag.value[11], tag.value[12], tag.value[13]);
886 //Add a line feed
887 TRACE_DEBUG("\r\n");
888 break;
889
890 //Any other type?
891 default:
892 //Dump the contents of the tag
893 TRACE_DEBUG_ARRAY(prefix[level + 1], tag.value, tag.length);
894 break;
895 }
896 }
897 }
898#endif
899
900 //ASN.1 object successfully decoded
901 return NO_ERROR;
902}
903
904#endif
error_t asn1ReadOctetString(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an octet string from the input stream.
Definition: asn1.c:190
error_t 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:495
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 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:591
error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag.
Definition: asn1.c:334
error_t asn1CheckOid(const Asn1Tag *tag, const uint8_t *oid, size_t length)
Check ASN.1 tag against a specified OID.
Definition: asn1.c:679
error_t asn1ReadSequence(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 sequence from the input stream.
Definition: asn1.c:163
error_t asn1CheckTag(const Asn1Tag *tag, bool_t constructed, uint_t objClass, uint_t objType)
Enforce the type of a specified tag.
Definition: asn1.c:653
error_t asn1ReadOid(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an object identifier from the input stream.
Definition: asn1.c:218
error_t 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 asn1ReadMpi(const uint8_t *data, size_t length, Asn1Tag *tag, Mpi *value)
Read a multiple-precision integer from the input stream.
Definition: asn1.c:553
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
error_t asn1DumpObject(const uint8_t *data, size_t length, uint_t level)
Display an ASN.1 data object.
Definition: asn1.c:706
ASN.1 (Abstract Syntax Notation One)
@ ASN1_TYPE_GENERAL_STRING
Definition: asn1.h:91
@ ASN1_TYPE_VISIBLE_STRING
Definition: asn1.h:90
@ ASN1_TYPE_BMP_STRING
Definition: asn1.h:93
@ ASN1_TYPE_GENERALIZED_TIME
Definition: asn1.h:88
@ ASN1_TYPE_VIDEOTEX_STRING
Definition: asn1.h:85
@ ASN1_TYPE_OBJECT_IDENTIFIER
Definition: asn1.h:74
@ ASN1_TYPE_NUMERIC_STRING
Definition: asn1.h:82
@ ASN1_TYPE_BOOLEAN
Definition: asn1.h:69
@ ASN1_TYPE_UNIVERSAL_STRING
Definition: asn1.h:92
@ ASN1_TYPE_UTC_TIME
Definition: asn1.h:87
@ ASN1_TYPE_PRINTABLE_STRING
Definition: asn1.h:83
@ ASN1_TYPE_TELETEX_STRING
Definition: asn1.h:84
@ ASN1_TYPE_OCTET_STRING
Definition: asn1.h:72
@ ASN1_TYPE_IA5_STRING
Definition: asn1.h:86
@ ASN1_TYPE_UTF8_STRING
Definition: asn1.h:79
@ ASN1_TYPE_INTEGER
Definition: asn1.h:70
@ ASN1_TYPE_SEQUENCE
Definition: asn1.h:80
@ ASN1_TYPE_GRAPHIC_STRING
Definition: asn1.h:89
#define ASN1_ENCODING_CONSTRUCTED
Definition: asn1.h:48
#define ASN1_CLASS_MASK
Definition: asn1.h:51
#define ASN1_TAG_NUMBER_MASK
Definition: asn1.h:43
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
unsigned int uint_t
Definition: compiler_port.h:45
#define PRIuSIZE
Definition: compiler_port.h:78
char char_t
Definition: compiler_port.h:43
int bool_t
Definition: compiler_port.h:49
General definitions for cryptographic algorithms.
Debugging facilities.
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
#define TRACE_DEBUG(...)
Definition: debug.h:107
uint8_t n
Ipv6Addr prefix
uint8_t value[]
Definition: dtls_misc.h:150
error_t
Error codes.
Definition: error.h:43
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:88
@ ERROR_INVALID_TYPE
Definition: error.h:114
@ ERROR_INVALID_CLASS
Definition: error.h:116
@ ERROR_WRONG_ENCODING
Definition: error.h:121
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_LENGTH
Definition: error.h:110
@ ERROR_INVALID_TAG
Definition: error.h:113
uint8_t oid[1]
Definition: mib_common.h:186
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:195
error_t mpiImport(Mpi *r, const uint8_t *data, uint_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:577
error_t mpiExport(const Mpi *a, uint8_t *data, uint_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:662
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:61
uint8_t m
Definition: ndp.h:302
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:103
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:562
OID (Object Identifier)
#define osMemmove(dest, src, length)
Definition: os_port.h:140
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
uint8_t data[]
Definition: sftp_common.h:228
uint32_t length
Definition: sftp_common.h:214
ASN.1 tag.
Definition: asn1.h:102
size_t totalLength
Definition: asn1.h:108
const uint8_t * value
Definition: asn1.h:107
uint_t objClass
Definition: asn1.h:104
uint_t objType
Definition: asn1.h:105
bool_t constructed
Definition: asn1.h:103
size_t length
Definition: asn1.h:106
Arbitrary precision integer.
Definition: mpi.h:70
uint8_t level
Definition: tls.h:1747