1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 #include <stdarg.h>
5
6
7 /**
8 @file der_decode_sequence_multi.c
9 ASN.1 DER, decode a SEQUENCE, Tom St Denis
10 */
11
12 #ifdef LTC_DER
13
14 /**
15 Decode a SEQUENCE type using a VA list
16 @param in Input buffer
17 @param inlen Length of input in octets
18 @param a1 Initialized argument list #1
19 @param a2 Initialized argument list #2 (copy of #1)
20 @param flags c.f. enum ltc_der_seq
21 @return CRYPT_OK on success
22 */
s_der_decode_sequence_va(const unsigned char * in,unsigned long inlen,va_list a1,va_list a2,unsigned int flags)23 static int s_der_decode_sequence_va(const unsigned char *in, unsigned long inlen, va_list a1, va_list a2, unsigned int flags)
24 {
25 int err;
26 ltc_asn1_type type;
27 unsigned long size, x;
28 void *data;
29 ltc_asn1_list *list;
30
31 LTC_ARGCHK(in != NULL);
32
33 /* get size of output that will be required */
34 x = 0;
35 for (;;) {
36 type = (ltc_asn1_type)va_arg(a1, int);
37
38 if (type == LTC_ASN1_EOL) {
39 break;
40 }
41
42 size = va_arg(a1, unsigned long);
43 data = va_arg(a1, void*);
44 LTC_UNUSED_PARAM(size);
45 LTC_UNUSED_PARAM(data);
46
47 switch (type) {
48 case LTC_ASN1_BOOLEAN:
49 case LTC_ASN1_INTEGER:
50 case LTC_ASN1_SHORT_INTEGER:
51 case LTC_ASN1_BIT_STRING:
52 case LTC_ASN1_OCTET_STRING:
53 case LTC_ASN1_NULL:
54 case LTC_ASN1_OBJECT_IDENTIFIER:
55 case LTC_ASN1_IA5_STRING:
56 case LTC_ASN1_PRINTABLE_STRING:
57 case LTC_ASN1_UTF8_STRING:
58 case LTC_ASN1_UTCTIME:
59 case LTC_ASN1_SET:
60 case LTC_ASN1_SETOF:
61 case LTC_ASN1_SEQUENCE:
62 case LTC_ASN1_CHOICE:
63 case LTC_ASN1_RAW_BIT_STRING:
64 case LTC_ASN1_TELETEX_STRING:
65 case LTC_ASN1_GENERALIZEDTIME:
66 ++x;
67 break;
68
69 case LTC_ASN1_EOL:
70 case LTC_ASN1_CUSTOM_TYPE:
71 default:
72 return CRYPT_INVALID_ARG;
73 }
74 }
75
76 /* allocate structure for x elements */
77 if (x == 0) {
78 return CRYPT_NOP;
79 }
80
81 list = XCALLOC(sizeof(*list), x);
82 if (list == NULL) {
83 return CRYPT_MEM;
84 }
85
86 /* fill in the structure */
87 x = 0;
88 for (;;) {
89 type = (ltc_asn1_type)va_arg(a2, int);
90 size = va_arg(a2, unsigned long);
91 data = va_arg(a2, void*);
92
93 if (type == LTC_ASN1_EOL) {
94 break;
95 }
96
97 switch (type) {
98 case LTC_ASN1_BOOLEAN:
99 case LTC_ASN1_INTEGER:
100 case LTC_ASN1_SHORT_INTEGER:
101 case LTC_ASN1_BIT_STRING:
102 case LTC_ASN1_OCTET_STRING:
103 case LTC_ASN1_NULL:
104 case LTC_ASN1_OBJECT_IDENTIFIER:
105 case LTC_ASN1_IA5_STRING:
106 case LTC_ASN1_PRINTABLE_STRING:
107 case LTC_ASN1_UTF8_STRING:
108 case LTC_ASN1_UTCTIME:
109 case LTC_ASN1_SEQUENCE:
110 case LTC_ASN1_SET:
111 case LTC_ASN1_SETOF:
112 case LTC_ASN1_CHOICE:
113 case LTC_ASN1_RAW_BIT_STRING:
114 case LTC_ASN1_TELETEX_STRING:
115 case LTC_ASN1_GENERALIZEDTIME:
116 LTC_SET_ASN1(list, x++, type, data, size);
117 break;
118 /* coverity[dead_error_line] */
119 case LTC_ASN1_EOL:
120 case LTC_ASN1_CUSTOM_TYPE:
121 default:
122 break;
123 }
124 }
125
126 err = der_decode_sequence_ex(in, inlen, list, x, flags);
127 XFREE(list);
128 return err;
129 }
130
131 /**
132 Decode a SEQUENCE type using a VA list
133 @param in Input buffer
134 @param inlen Length of input in octets
135 @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
136 @return CRYPT_OK on success
137 */
der_decode_sequence_multi(const unsigned char * in,unsigned long inlen,...)138 int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
139 {
140 va_list a1, a2;
141 int err;
142
143 LTC_ARGCHK(in != NULL);
144
145 va_start(a1, inlen);
146 va_start(a2, inlen);
147
148 err = s_der_decode_sequence_va(in, inlen, a1, a2, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_RELAXED);
149
150 va_end(a2);
151 va_end(a1);
152
153 return err;
154 }
155
156 /**
157 Decode a SEQUENCE type using a VA list
158 @param in Input buffer
159 @param inlen Length of input in octets
160 @param flags c.f. enum ltc_der_seq
161 @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
162 @return CRYPT_OK on success
163 */
der_decode_sequence_multi_ex(const unsigned char * in,unsigned long inlen,unsigned int flags,...)164 int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...)
165 {
166 va_list a1, a2;
167 int err;
168
169 LTC_ARGCHK(in != NULL);
170
171 va_start(a1, flags);
172 va_start(a2, flags);
173
174 err = s_der_decode_sequence_va(in, inlen, a1, a2, flags);
175
176 va_end(a2);
177 va_end(a1);
178
179 return err;
180 }
181
182 #endif
183
184