/src/boringssl/crypto/asn1/tasn_dec.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
2 | | * All rights reserved. |
3 | | * |
4 | | * This package is an SSL implementation written |
5 | | * by Eric Young (eay@cryptsoft.com). |
6 | | * The implementation was written so as to conform with Netscapes SSL. |
7 | | * |
8 | | * This library is free for commercial and non-commercial use as long as |
9 | | * the following conditions are aheared to. The following conditions |
10 | | * apply to all code found in this distribution, be it the RC4, RSA, |
11 | | * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
12 | | * included with this distribution is covered by the same copyright terms |
13 | | * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
14 | | * |
15 | | * Copyright remains Eric Young's, and as such any Copyright notices in |
16 | | * the code are not to be removed. |
17 | | * If this package is used in a product, Eric Young should be given attribution |
18 | | * as the author of the parts of the library used. |
19 | | * This can be in the form of a textual message at program startup or |
20 | | * in documentation (online or textual) provided with the package. |
21 | | * |
22 | | * Redistribution and use in source and binary forms, with or without |
23 | | * modification, are permitted provided that the following conditions |
24 | | * are met: |
25 | | * 1. Redistributions of source code must retain the copyright |
26 | | * notice, this list of conditions and the following disclaimer. |
27 | | * 2. Redistributions in binary form must reproduce the above copyright |
28 | | * notice, this list of conditions and the following disclaimer in the |
29 | | * documentation and/or other materials provided with the distribution. |
30 | | * 3. All advertising materials mentioning features or use of this software |
31 | | * must display the following acknowledgement: |
32 | | * "This product includes cryptographic software written by |
33 | | * Eric Young (eay@cryptsoft.com)" |
34 | | * The word 'cryptographic' can be left out if the rouines from the library |
35 | | * being used are not cryptographic related :-). |
36 | | * 4. If you include any Windows specific code (or a derivative thereof) from |
37 | | * the apps directory (application code) you must include an acknowledgement: |
38 | | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
39 | | * |
40 | | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
41 | | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
42 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
43 | | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
44 | | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
45 | | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
46 | | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
47 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
48 | | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
49 | | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
50 | | * SUCH DAMAGE. |
51 | | * |
52 | | * The licence and distribution terms for any publically available version or |
53 | | * derivative of this code cannot be changed. i.e. this code cannot simply be |
54 | | * copied and put under another distribution licence |
55 | | * [including the GNU Public Licence.] */ |
56 | | |
57 | | #include <openssl/asn1.h> |
58 | | #include <openssl/asn1t.h> |
59 | | #include <openssl/bytestring.h> |
60 | | #include <openssl/err.h> |
61 | | #include <openssl/mem.h> |
62 | | #include <openssl/pool.h> |
63 | | |
64 | | #include <assert.h> |
65 | | #include <limits.h> |
66 | | #include <string.h> |
67 | | |
68 | | #include "../bytestring/internal.h" |
69 | | #include "../internal.h" |
70 | | #include "internal.h" |
71 | | |
72 | | // Constructed types with a recursive definition (such as can be found in PKCS7) |
73 | | // could eventually exceed the stack given malicious input with excessive |
74 | | // recursion. Therefore we limit the stack depth. This is the maximum number of |
75 | | // recursive invocations of asn1_item_embed_d2i(). |
76 | 7.67M | #define ASN1_MAX_CONSTRUCTED_NEST 30 |
77 | | |
78 | | static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, |
79 | | char *cst, const unsigned char **in, long len, |
80 | | int exptag, int expclass, char opt); |
81 | | |
82 | | static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, |
83 | | long len, const ASN1_TEMPLATE *tt, char opt, |
84 | | CRYPTO_BUFFER *buf, int depth); |
85 | | static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, |
86 | | long len, const ASN1_TEMPLATE *tt, char opt, |
87 | | CRYPTO_BUFFER *buf, int depth); |
88 | | static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len, |
89 | | int utype, const ASN1_ITEM *it); |
90 | | static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, |
91 | | long len, const ASN1_ITEM *it, int tag, |
92 | | int aclass, char opt); |
93 | | static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, |
94 | | long len, const ASN1_ITEM *it, int tag, int aclass, |
95 | | char opt, CRYPTO_BUFFER *buf, int depth); |
96 | | |
97 | | // Table to convert tags to bit values, used for MSTRING type |
98 | | static const unsigned long tag2bit[31] = { |
99 | | 0, // (reserved) |
100 | | 0, // BOOLEAN |
101 | | 0, // INTEGER |
102 | | B_ASN1_BIT_STRING, |
103 | | B_ASN1_OCTET_STRING, |
104 | | 0, // NULL |
105 | | 0, // OBJECT IDENTIFIER |
106 | | B_ASN1_UNKNOWN, // ObjectDescriptor |
107 | | B_ASN1_UNKNOWN, // EXTERNAL |
108 | | B_ASN1_UNKNOWN, // REAL |
109 | | B_ASN1_UNKNOWN, // ENUMERATED |
110 | | B_ASN1_UNKNOWN, // EMBEDDED PDV |
111 | | B_ASN1_UTF8STRING, |
112 | | B_ASN1_UNKNOWN, // RELATIVE-OID |
113 | | B_ASN1_UNKNOWN, // TIME |
114 | | B_ASN1_UNKNOWN, // (reserved) |
115 | | B_ASN1_SEQUENCE, |
116 | | 0, // SET |
117 | | B_ASN1_NUMERICSTRING, |
118 | | B_ASN1_PRINTABLESTRING, |
119 | | B_ASN1_T61STRING, |
120 | | B_ASN1_VIDEOTEXSTRING, |
121 | | B_ASN1_IA5STRING, |
122 | | B_ASN1_UTCTIME, |
123 | | B_ASN1_GENERALIZEDTIME, |
124 | | B_ASN1_GRAPHICSTRING, |
125 | | B_ASN1_ISO64STRING, |
126 | | B_ASN1_GENERALSTRING, |
127 | | B_ASN1_UNIVERSALSTRING, |
128 | | B_ASN1_UNKNOWN, // CHARACTER STRING |
129 | | B_ASN1_BMPSTRING, |
130 | | }; |
131 | | |
132 | 1.85M | unsigned long ASN1_tag2bit(int tag) { |
133 | 1.85M | if (tag < 0 || tag > 30) { |
134 | 28.2k | return 0; |
135 | 28.2k | } |
136 | 1.82M | return tag2bit[tag]; |
137 | 1.85M | } |
138 | | |
139 | 292k | static int is_supported_universal_type(int tag, int aclass) { |
140 | 292k | if (aclass != V_ASN1_UNIVERSAL) { |
141 | 14.8k | return 0; |
142 | 14.8k | } |
143 | 277k | return tag == V_ASN1_OBJECT || tag == V_ASN1_NULL || tag == V_ASN1_BOOLEAN || |
144 | 277k | tag == V_ASN1_BIT_STRING || tag == V_ASN1_INTEGER || |
145 | 277k | tag == V_ASN1_ENUMERATED || tag == V_ASN1_OCTET_STRING || |
146 | 277k | tag == V_ASN1_NUMERICSTRING || tag == V_ASN1_PRINTABLESTRING || |
147 | 277k | tag == V_ASN1_T61STRING || tag == V_ASN1_VIDEOTEXSTRING || |
148 | 277k | tag == V_ASN1_IA5STRING || tag == V_ASN1_UTCTIME || |
149 | 277k | tag == V_ASN1_GENERALIZEDTIME || tag == V_ASN1_GRAPHICSTRING || |
150 | 277k | tag == V_ASN1_VISIBLESTRING || tag == V_ASN1_GENERALSTRING || |
151 | 277k | tag == V_ASN1_UNIVERSALSTRING || tag == V_ASN1_BMPSTRING || |
152 | 277k | tag == V_ASN1_UTF8STRING || tag == V_ASN1_SET || |
153 | 277k | tag == V_ASN1_SEQUENCE; |
154 | 292k | } |
155 | | |
156 | | // Macro to initialize and invalidate the cache |
157 | | |
158 | | // Decode an ASN1 item, this currently behaves just like a standard 'd2i' |
159 | | // function. 'in' points to a buffer to read the data from, in future we |
160 | | // will have more advanced versions that can input data a piece at a time and |
161 | | // this will simply be a special case. |
162 | | |
163 | | ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, |
164 | 328k | const ASN1_ITEM *it) { |
165 | 328k | ASN1_VALUE *ret = NULL; |
166 | 328k | if (asn1_item_ex_d2i(&ret, in, len, it, /*tag=*/-1, /*aclass=*/0, /*opt=*/0, |
167 | | /*buf=*/NULL, /*depth=*/0) <= 0) { |
168 | | // Clean up, in case the caller left a partial object. |
169 | | // |
170 | | // TODO(davidben): I don't think it can leave one, but the codepaths below |
171 | | // are a bit inconsistent. Revisit this when rewriting this function. |
172 | 9.04k | ASN1_item_ex_free(&ret, it); |
173 | 9.04k | } |
174 | | |
175 | | // If the caller supplied an output pointer, free the old one and replace it |
176 | | // with |ret|. This differs from OpenSSL slightly in that we don't support |
177 | | // object reuse. We run this on both success and failure. On failure, even |
178 | | // with object reuse, OpenSSL destroys the previous object. |
179 | 328k | if (pval != NULL) { |
180 | 0 | ASN1_item_ex_free(pval, it); |
181 | 0 | *pval = ret; |
182 | 0 | } |
183 | 328k | return ret; |
184 | 328k | } |
185 | | |
186 | | // Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and |
187 | | // tag mismatch return -1 to handle OPTIONAL |
188 | | // |
189 | | // TODO(davidben): Historically, all functions in this file had to account for |
190 | | // |*pval| containing an arbitrary existing value. This is no longer the case |
191 | | // because |ASN1_item_d2i| now always starts from NULL. As part of rewriting |
192 | | // this function, take the simplified assumptions into account. Though we must |
193 | | // still account for the internal calls to |ASN1_item_ex_new|. |
194 | | |
195 | | static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, |
196 | | long len, const ASN1_ITEM *it, int tag, int aclass, |
197 | 7.67M | char opt, CRYPTO_BUFFER *buf, int depth) { |
198 | 7.67M | const ASN1_TEMPLATE *tt, *errtt = NULL; |
199 | 7.67M | const unsigned char *p = NULL, *q; |
200 | 7.67M | unsigned char oclass; |
201 | 7.67M | char cst, isopt; |
202 | 7.67M | int i; |
203 | 7.67M | int otag; |
204 | 7.67M | int ret = 0; |
205 | 7.67M | ASN1_VALUE **pchptr; |
206 | 7.67M | if (!pval) { |
207 | 0 | return 0; |
208 | 0 | } |
209 | | |
210 | 7.67M | if (buf != NULL) { |
211 | 3.50M | assert(CRYPTO_BUFFER_data(buf) <= *in && |
212 | 3.50M | *in + len <= CRYPTO_BUFFER_data(buf) + CRYPTO_BUFFER_len(buf)); |
213 | 3.50M | } |
214 | | |
215 | | // Bound |len| to comfortably fit in an int. Lengths in this module often |
216 | | // switch between int and long without overflow checks. |
217 | 7.67M | if (len > INT_MAX / 2) { |
218 | 0 | len = INT_MAX / 2; |
219 | 0 | } |
220 | | |
221 | 7.67M | if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { |
222 | 0 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_TOO_DEEP); |
223 | 0 | goto err; |
224 | 0 | } |
225 | | |
226 | 7.67M | switch (it->itype) { |
227 | 4.35M | case ASN1_ITYPE_PRIMITIVE: |
228 | 4.35M | if (it->templates) { |
229 | | // tagging or OPTIONAL is currently illegal on an item template |
230 | | // because the flags can't get passed down. In practice this |
231 | | // isn't a problem: we include the relevant flags from the item |
232 | | // template in the template itself. |
233 | 985k | if ((tag != -1) || opt) { |
234 | 0 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); |
235 | 0 | goto err; |
236 | 0 | } |
237 | 985k | return asn1_template_ex_d2i(pval, in, len, it->templates, opt, buf, |
238 | 985k | depth); |
239 | 985k | } |
240 | 3.36M | return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt); |
241 | 0 | break; |
242 | | |
243 | 1.03M | case ASN1_ITYPE_MSTRING: |
244 | | // It never makes sense for multi-strings to have implicit tagging, so |
245 | | // if tag != -1, then this looks like an error in the template. |
246 | 1.03M | if (tag != -1) { |
247 | 0 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); |
248 | 0 | goto err; |
249 | 0 | } |
250 | | |
251 | 1.03M | p = *in; |
252 | | // Just read in tag and class |
253 | 1.03M | ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, &p, len, -1, 0, 1); |
254 | 1.03M | if (!ret) { |
255 | 165 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); |
256 | 165 | goto err; |
257 | 165 | } |
258 | | |
259 | | // Must be UNIVERSAL class |
260 | 1.03M | if (oclass != V_ASN1_UNIVERSAL) { |
261 | | // If OPTIONAL, assume this is OK |
262 | 40 | if (opt) { |
263 | 0 | return -1; |
264 | 0 | } |
265 | 40 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL); |
266 | 40 | goto err; |
267 | 40 | } |
268 | | // Check tag matches bit map |
269 | 1.03M | if (!(ASN1_tag2bit(otag) & it->utype)) { |
270 | | // If OPTIONAL, assume this is OK |
271 | 102 | if (opt) { |
272 | 0 | return -1; |
273 | 0 | } |
274 | 102 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG); |
275 | 102 | goto err; |
276 | 102 | } |
277 | 1.03M | return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0); |
278 | | |
279 | 248k | case ASN1_ITYPE_EXTERN: { |
280 | | // We don't support implicit tagging with external types. |
281 | 248k | if (tag != -1) { |
282 | 0 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); |
283 | 0 | goto err; |
284 | 0 | } |
285 | 248k | const ASN1_EXTERN_FUNCS *ef = it->funcs; |
286 | 248k | return ef->asn1_ex_d2i(pval, in, len, it, opt, NULL); |
287 | 248k | } |
288 | | |
289 | 47.2k | case ASN1_ITYPE_CHOICE: { |
290 | | // It never makes sense for CHOICE types to have implicit tagging, so if |
291 | | // tag != -1, then this looks like an error in the template. |
292 | 47.2k | if (tag != -1) { |
293 | 0 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); |
294 | 0 | goto err; |
295 | 0 | } |
296 | | |
297 | 47.2k | const ASN1_AUX *aux = it->funcs; |
298 | 47.2k | ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; |
299 | 47.2k | if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) { |
300 | 0 | goto auxerr; |
301 | 0 | } |
302 | | |
303 | 47.2k | if (*pval) { |
304 | | // Free up and zero CHOICE value if initialised |
305 | 816 | i = asn1_get_choice_selector(pval, it); |
306 | 816 | if ((i >= 0) && (i < it->tcount)) { |
307 | 0 | tt = it->templates + i; |
308 | 0 | pchptr = asn1_get_field_ptr(pval, tt); |
309 | 0 | ASN1_template_free(pchptr, tt); |
310 | 0 | asn1_set_choice_selector(pval, -1, it); |
311 | 0 | } |
312 | 46.3k | } else if (!ASN1_item_ex_new(pval, it)) { |
313 | 0 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); |
314 | 0 | goto err; |
315 | 0 | } |
316 | | // CHOICE type, try each possibility in turn |
317 | 47.2k | p = *in; |
318 | 220k | for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { |
319 | 220k | pchptr = asn1_get_field_ptr(pval, tt); |
320 | | // We mark field as OPTIONAL so its absence can be recognised. |
321 | 220k | ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, buf, depth); |
322 | | // If field not present, try the next one |
323 | 220k | if (ret == -1) { |
324 | 173k | continue; |
325 | 173k | } |
326 | | // If positive return, read OK, break loop |
327 | 47.0k | if (ret > 0) { |
328 | 46.2k | break; |
329 | 46.2k | } |
330 | | // Otherwise must be an ASN1 parsing error |
331 | 844 | errtt = tt; |
332 | 844 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); |
333 | 844 | goto err; |
334 | 47.0k | } |
335 | | |
336 | | // Did we fall off the end without reading anything? |
337 | 46.3k | if (i == it->tcount) { |
338 | | // If OPTIONAL, this is OK |
339 | 117 | if (opt) { |
340 | | // Free and zero it |
341 | 0 | ASN1_item_ex_free(pval, it); |
342 | 0 | return -1; |
343 | 0 | } |
344 | 117 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE); |
345 | 117 | goto err; |
346 | 117 | } |
347 | | |
348 | 46.2k | asn1_set_choice_selector(pval, i, it); |
349 | 46.2k | if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) { |
350 | 0 | goto auxerr; |
351 | 0 | } |
352 | 46.2k | *in = p; |
353 | 46.2k | return 1; |
354 | 46.2k | } |
355 | | |
356 | 1.99M | case ASN1_ITYPE_SEQUENCE: { |
357 | 1.99M | p = *in; |
358 | | |
359 | | // If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL |
360 | 1.99M | if (tag == -1) { |
361 | 1.92M | tag = V_ASN1_SEQUENCE; |
362 | 1.92M | aclass = V_ASN1_UNIVERSAL; |
363 | 1.92M | } |
364 | | // Get SEQUENCE length and update len, p |
365 | 1.99M | ret = asn1_check_tlen(&len, NULL, NULL, &cst, &p, len, tag, aclass, opt); |
366 | 1.99M | if (!ret) { |
367 | 3.27k | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); |
368 | 3.27k | goto err; |
369 | 1.98M | } else if (ret == -1) { |
370 | 63.2k | return -1; |
371 | 63.2k | } |
372 | 1.92M | if (!cst) { |
373 | 113 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); |
374 | 113 | goto err; |
375 | 113 | } |
376 | | |
377 | 1.92M | if (!*pval && !ASN1_item_ex_new(pval, it)) { |
378 | 0 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); |
379 | 0 | goto err; |
380 | 0 | } |
381 | | |
382 | 1.92M | const ASN1_AUX *aux = it->funcs; |
383 | 1.92M | ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL; |
384 | 1.92M | if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) { |
385 | 0 | goto auxerr; |
386 | 0 | } |
387 | | |
388 | | // Free up and zero any ADB found |
389 | 7.20M | for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { |
390 | 5.27M | if (tt->flags & ASN1_TFLG_ADB_MASK) { |
391 | 779 | const ASN1_TEMPLATE *seqtt; |
392 | 779 | ASN1_VALUE **pseqval; |
393 | 779 | seqtt = asn1_do_adb(pval, tt, 0); |
394 | 779 | if (seqtt == NULL) { |
395 | 779 | continue; |
396 | 779 | } |
397 | 0 | pseqval = asn1_get_field_ptr(pval, seqtt); |
398 | 0 | ASN1_template_free(pseqval, seqtt); |
399 | 0 | } |
400 | 5.27M | } |
401 | | |
402 | | // Get each field entry |
403 | 7.02M | for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { |
404 | 5.21M | const ASN1_TEMPLATE *seqtt; |
405 | 5.21M | ASN1_VALUE **pseqval; |
406 | 5.21M | seqtt = asn1_do_adb(pval, tt, 1); |
407 | 5.21M | if (seqtt == NULL) { |
408 | 0 | goto err; |
409 | 0 | } |
410 | 5.21M | pseqval = asn1_get_field_ptr(pval, seqtt); |
411 | | // Have we ran out of data? |
412 | 5.21M | if (!len) { |
413 | 98.0k | break; |
414 | 98.0k | } |
415 | 5.11M | q = p; |
416 | | // This determines the OPTIONAL flag value. The field cannot be |
417 | | // omitted if it is the last of a SEQUENCE and there is still |
418 | | // data to be read. This isn't strictly necessary but it |
419 | | // increases efficiency in some cases. |
420 | 5.11M | if (i == (it->tcount - 1)) { |
421 | 1.81M | isopt = 0; |
422 | 3.29M | } else { |
423 | 3.29M | isopt = (seqtt->flags & ASN1_TFLG_OPTIONAL) != 0; |
424 | 3.29M | } |
425 | | // attempt to read in field, allowing each to be OPTIONAL |
426 | | |
427 | 5.11M | ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, buf, depth); |
428 | 5.11M | if (!ret) { |
429 | 13.4k | errtt = seqtt; |
430 | 13.4k | goto err; |
431 | 5.10M | } else if (ret == -1) { |
432 | | // OPTIONAL component absent. Free and zero the field. |
433 | 554k | ASN1_template_free(pseqval, seqtt); |
434 | 554k | continue; |
435 | 554k | } |
436 | | // Update length |
437 | 4.54M | len -= p - q; |
438 | 4.54M | } |
439 | | |
440 | | // Check all data read |
441 | 1.91M | if (len) { |
442 | 557 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH); |
443 | 557 | goto err; |
444 | 557 | } |
445 | | |
446 | | // If we get here we've got no more data in the SEQUENCE, however we |
447 | | // may not have read all fields so check all remaining are OPTIONAL |
448 | | // and clear any that are. |
449 | 2.01M | for (; i < it->tcount; tt++, i++) { |
450 | 108k | const ASN1_TEMPLATE *seqtt; |
451 | 108k | seqtt = asn1_do_adb(pval, tt, 1); |
452 | 108k | if (seqtt == NULL) { |
453 | 0 | goto err; |
454 | 0 | } |
455 | 108k | if (seqtt->flags & ASN1_TFLG_OPTIONAL) { |
456 | 107k | ASN1_VALUE **pseqval; |
457 | 107k | pseqval = asn1_get_field_ptr(pval, seqtt); |
458 | 107k | ASN1_template_free(pseqval, seqtt); |
459 | 107k | } else { |
460 | 1.64k | errtt = seqtt; |
461 | 1.64k | OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING); |
462 | 1.64k | goto err; |
463 | 1.64k | } |
464 | 108k | } |
465 | | // Save encoding |
466 | 1.91M | if (!asn1_enc_save(pval, *in, p - *in, it, buf)) { |
467 | 0 | goto auxerr; |
468 | 0 | } |
469 | 1.91M | if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) { |
470 | 0 | goto auxerr; |
471 | 0 | } |
472 | 1.91M | *in = p; |
473 | 1.91M | return 1; |
474 | 1.91M | } |
475 | | |
476 | 0 | default: |
477 | 0 | return 0; |
478 | 7.67M | } |
479 | 0 | auxerr: |
480 | 0 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR); |
481 | 20.3k | err: |
482 | 20.3k | ASN1_item_ex_free(pval, it); |
483 | 20.3k | if (errtt) { |
484 | 15.9k | ERR_add_error_data(4, "Field=", errtt->field_name, ", Type=", it->sname); |
485 | 15.9k | } else { |
486 | 4.36k | ERR_add_error_data(2, "Type=", it->sname); |
487 | 4.36k | } |
488 | 20.3k | return 0; |
489 | 0 | } |
490 | | |
491 | | int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, |
492 | | const ASN1_ITEM *it, int tag, int aclass, char opt, |
493 | 377k | CRYPTO_BUFFER *buf) { |
494 | 377k | return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, buf, |
495 | 377k | /*depth=*/0); |
496 | 377k | } |
497 | | |
498 | | // Templates are handled with two separate functions. One handles any |
499 | | // EXPLICIT tag and the other handles the rest. |
500 | | |
501 | | static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, |
502 | | long inlen, const ASN1_TEMPLATE *tt, char opt, |
503 | 6.32M | CRYPTO_BUFFER *buf, int depth) { |
504 | 6.32M | int aclass; |
505 | 6.32M | int ret; |
506 | 6.32M | long len; |
507 | 6.32M | const unsigned char *p, *q; |
508 | 6.32M | if (!val) { |
509 | 0 | return 0; |
510 | 0 | } |
511 | 6.32M | uint32_t flags = tt->flags; |
512 | 6.32M | aclass = flags & ASN1_TFLG_TAG_CLASS; |
513 | | |
514 | 6.32M | p = *in; |
515 | | |
516 | | // Check if EXPLICIT tag expected |
517 | 6.32M | if (flags & ASN1_TFLG_EXPTAG) { |
518 | 267k | char cst; |
519 | | // Need to work out amount of data available to the inner content and |
520 | | // where it starts: so read in EXPLICIT header to get the info. |
521 | 267k | ret = asn1_check_tlen(&len, NULL, NULL, &cst, &p, inlen, tt->tag, aclass, |
522 | 267k | opt); |
523 | 267k | q = p; |
524 | 267k | if (!ret) { |
525 | 408 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); |
526 | 408 | return 0; |
527 | 267k | } else if (ret == -1) { |
528 | 26.2k | return -1; |
529 | 26.2k | } |
530 | 241k | if (!cst) { |
531 | 27 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); |
532 | 27 | return 0; |
533 | 27 | } |
534 | | // We've found the field so it can't be OPTIONAL now |
535 | 240k | ret = asn1_template_noexp_d2i(val, &p, len, tt, /*opt=*/0, buf, depth); |
536 | 240k | if (!ret) { |
537 | 1.08k | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); |
538 | 1.08k | return 0; |
539 | 1.08k | } |
540 | | // We read the field in OK so update length |
541 | 239k | len -= p - q; |
542 | | // Check for trailing data. |
543 | 239k | if (len) { |
544 | 144 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH); |
545 | 144 | goto err; |
546 | 144 | } |
547 | 6.05M | } else { |
548 | 6.05M | return asn1_template_noexp_d2i(val, in, inlen, tt, opt, buf, depth); |
549 | 6.05M | } |
550 | | |
551 | 239k | *in = p; |
552 | 239k | return 1; |
553 | | |
554 | 144 | err: |
555 | 144 | ASN1_template_free(val, tt); |
556 | 144 | return 0; |
557 | 6.32M | } |
558 | | |
559 | | static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, |
560 | | long len, const ASN1_TEMPLATE *tt, char opt, |
561 | 6.29M | CRYPTO_BUFFER *buf, int depth) { |
562 | 6.29M | int aclass; |
563 | 6.29M | int ret; |
564 | 6.29M | const unsigned char *p; |
565 | 6.29M | if (!val) { |
566 | 0 | return 0; |
567 | 0 | } |
568 | 6.29M | uint32_t flags = tt->flags; |
569 | 6.29M | aclass = flags & ASN1_TFLG_TAG_CLASS; |
570 | | |
571 | 6.29M | p = *in; |
572 | | |
573 | 6.29M | if (flags & ASN1_TFLG_SK_MASK) { |
574 | | // SET OF, SEQUENCE OF |
575 | 1.10M | int sktag, skaclass; |
576 | | // First work out expected inner tag value |
577 | 1.10M | if (flags & ASN1_TFLG_IMPTAG) { |
578 | 1.62k | sktag = tt->tag; |
579 | 1.62k | skaclass = aclass; |
580 | 1.10M | } else { |
581 | 1.10M | skaclass = V_ASN1_UNIVERSAL; |
582 | 1.10M | if (flags & ASN1_TFLG_SET_OF) { |
583 | 732k | sktag = V_ASN1_SET; |
584 | 732k | } else { |
585 | 369k | sktag = V_ASN1_SEQUENCE; |
586 | 369k | } |
587 | 1.10M | } |
588 | | // Get the tag |
589 | 1.10M | ret = |
590 | 1.10M | asn1_check_tlen(&len, NULL, NULL, NULL, &p, len, sktag, skaclass, opt); |
591 | 1.10M | if (!ret) { |
592 | 3.01k | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); |
593 | 3.01k | return 0; |
594 | 1.10M | } else if (ret == -1) { |
595 | 297 | return -1; |
596 | 297 | } |
597 | 1.10M | if (!*val) { |
598 | 1.10M | *val = (ASN1_VALUE *)sk_ASN1_VALUE_new_null(); |
599 | 1.10M | } else { |
600 | | // We've got a valid STACK: free up any items present |
601 | 9 | STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val; |
602 | 9 | ASN1_VALUE *vtmp; |
603 | 9 | while (sk_ASN1_VALUE_num(sktmp) > 0) { |
604 | 0 | vtmp = sk_ASN1_VALUE_pop(sktmp); |
605 | 0 | ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); |
606 | 0 | } |
607 | 9 | } |
608 | | |
609 | 1.10M | if (!*val) { |
610 | 0 | goto err; |
611 | 0 | } |
612 | | |
613 | | // Read as many items as we can |
614 | 2.87M | while (len > 0) { |
615 | 1.77M | ASN1_VALUE *skfield; |
616 | 1.77M | const unsigned char *q = p; |
617 | 1.77M | skfield = NULL; |
618 | 1.77M | if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), |
619 | 1.77M | /*tag=*/-1, /*aclass=*/0, /*opt=*/0, buf, depth)) { |
620 | 4.41k | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); |
621 | 4.41k | goto err; |
622 | 4.41k | } |
623 | 1.77M | len -= p - q; |
624 | 1.77M | if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) { |
625 | 0 | ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item)); |
626 | 0 | goto err; |
627 | 0 | } |
628 | 1.77M | } |
629 | 5.19M | } else if (flags & ASN1_TFLG_IMPTAG) { |
630 | | // IMPLICIT tagging |
631 | 436k | ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, |
632 | 436k | aclass, opt, buf, depth); |
633 | 436k | if (!ret) { |
634 | 949 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); |
635 | 949 | goto err; |
636 | 435k | } else if (ret == -1) { |
637 | 387k | return -1; |
638 | 387k | } |
639 | 4.75M | } else { |
640 | | // Nothing special |
641 | 4.75M | ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), /*tag=*/-1, |
642 | 4.75M | /*aclass=*/0, opt, buf, depth); |
643 | 4.75M | if (!ret) { |
644 | 11.6k | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); |
645 | 11.6k | goto err; |
646 | 4.74M | } else if (ret == -1) { |
647 | 313k | return -1; |
648 | 313k | } |
649 | 4.75M | } |
650 | | |
651 | 5.57M | *in = p; |
652 | 5.57M | return 1; |
653 | | |
654 | 16.9k | err: |
655 | 16.9k | ASN1_template_free(val, tt); |
656 | 16.9k | return 0; |
657 | 6.29M | } |
658 | | |
659 | | static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, |
660 | | long inlen, const ASN1_ITEM *it, int tag, |
661 | 4.40M | int aclass, char opt) { |
662 | 4.40M | int ret = 0, utype; |
663 | 4.40M | long plen; |
664 | 4.40M | char cst; |
665 | 4.40M | const unsigned char *p; |
666 | 4.40M | const unsigned char *cont = NULL; |
667 | 4.40M | long len; |
668 | 4.40M | if (!pval) { |
669 | 0 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL); |
670 | 0 | return 0; // Should never happen |
671 | 0 | } |
672 | | |
673 | 4.40M | if (it->itype == ASN1_ITYPE_MSTRING) { |
674 | 1.03M | utype = tag; |
675 | 1.03M | tag = -1; |
676 | 3.36M | } else { |
677 | 3.36M | utype = it->utype; |
678 | 3.36M | } |
679 | | |
680 | 4.40M | if (utype == V_ASN1_ANY) { |
681 | | // If type is ANY need to figure out type from tag |
682 | 292k | unsigned char oclass; |
683 | 292k | if (tag >= 0) { |
684 | 0 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY); |
685 | 0 | return 0; |
686 | 0 | } |
687 | 292k | if (opt) { |
688 | 0 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY); |
689 | 0 | return 0; |
690 | 0 | } |
691 | 292k | p = *in; |
692 | 292k | ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, &p, inlen, -1, 0, 0); |
693 | 292k | if (!ret) { |
694 | 109 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); |
695 | 109 | return 0; |
696 | 109 | } |
697 | 292k | if (!is_supported_universal_type(utype, oclass)) { |
698 | 18.4k | utype = V_ASN1_OTHER; |
699 | 18.4k | } |
700 | 292k | } |
701 | 4.40M | if (tag == -1) { |
702 | 4.03M | tag = utype; |
703 | 4.03M | aclass = V_ASN1_UNIVERSAL; |
704 | 4.03M | } |
705 | 4.40M | p = *in; |
706 | | // Check header |
707 | 4.40M | ret = asn1_check_tlen(&plen, NULL, NULL, &cst, &p, inlen, tag, aclass, opt); |
708 | 4.40M | if (!ret) { |
709 | 3.40k | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); |
710 | 3.40k | return 0; |
711 | 4.39M | } else if (ret == -1) { |
712 | 638k | return -1; |
713 | 638k | } |
714 | 3.76M | ret = 0; |
715 | | // SEQUENCE, SET and "OTHER" are left in encoded form |
716 | 3.76M | if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || |
717 | 3.76M | (utype == V_ASN1_OTHER)) { |
718 | | // SEQUENCE and SET must be constructed |
719 | 53.5k | if (utype != V_ASN1_OTHER && !cst) { |
720 | 43 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED); |
721 | 43 | return 0; |
722 | 43 | } |
723 | | |
724 | 53.4k | cont = *in; |
725 | 53.4k | len = p - cont + plen; |
726 | 53.4k | p += plen; |
727 | 3.70M | } else if (cst) { |
728 | | // This parser historically supported BER constructed strings. We no |
729 | | // longer do and will gradually tighten this parser into a DER |
730 | | // parser. BER types should use |CBS_asn1_ber_to_der|. |
731 | 253 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); |
732 | 253 | return 0; |
733 | 3.70M | } else { |
734 | 3.70M | cont = p; |
735 | 3.70M | len = plen; |
736 | 3.70M | p += plen; |
737 | 3.70M | } |
738 | | |
739 | | // We now have content length and type: translate into a structure |
740 | 3.76M | if (!asn1_ex_c2i(pval, cont, len, utype, it)) { |
741 | 5.05k | goto err; |
742 | 5.05k | } |
743 | | |
744 | 3.75M | *in = p; |
745 | 3.75M | ret = 1; |
746 | 3.76M | err: |
747 | 3.76M | return ret; |
748 | 3.75M | } |
749 | | |
750 | | // Translate ASN1 content octets into a structure |
751 | | |
752 | | static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len, |
753 | 3.76M | int utype, const ASN1_ITEM *it) { |
754 | 3.76M | ASN1_VALUE **opval = NULL; |
755 | 3.76M | ASN1_STRING *stmp; |
756 | 3.76M | ASN1_TYPE *typ = NULL; |
757 | 3.76M | int ret = 0; |
758 | 3.76M | ASN1_INTEGER **tint; |
759 | | |
760 | | // Historically, |it->funcs| for primitive types contained an |
761 | | // |ASN1_PRIMITIVE_FUNCS| table of callbacks. |
762 | 3.76M | assert(it->funcs == NULL); |
763 | | |
764 | | // If ANY type clear type and set pointer to internal value |
765 | 3.76M | if (it->utype == V_ASN1_ANY) { |
766 | 291k | if (!*pval) { |
767 | 290k | typ = ASN1_TYPE_new(); |
768 | 290k | if (typ == NULL) { |
769 | 0 | goto err; |
770 | 0 | } |
771 | 290k | *pval = (ASN1_VALUE *)typ; |
772 | 290k | } else { |
773 | 1.71k | typ = (ASN1_TYPE *)*pval; |
774 | 1.71k | } |
775 | | |
776 | 291k | if (utype != typ->type) { |
777 | 291k | ASN1_TYPE_set(typ, utype, NULL); |
778 | 291k | } |
779 | 291k | opval = pval; |
780 | 291k | pval = &typ->value.asn1_value; |
781 | 291k | } |
782 | 3.76M | switch (utype) { |
783 | 1.58M | case V_ASN1_OBJECT: |
784 | 1.58M | if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) { |
785 | 195 | goto err; |
786 | 195 | } |
787 | 1.58M | break; |
788 | | |
789 | 1.58M | case V_ASN1_NULL: |
790 | 214k | if (len) { |
791 | 68 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH); |
792 | 68 | goto err; |
793 | 68 | } |
794 | 214k | *pval = (ASN1_VALUE *)1; |
795 | 214k | break; |
796 | | |
797 | 75.4k | case V_ASN1_BOOLEAN: |
798 | 75.4k | if (len != 1) { |
799 | 99 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); |
800 | 99 | goto err; |
801 | 75.3k | } else { |
802 | 75.3k | ASN1_BOOLEAN *tbool; |
803 | 75.3k | tbool = (ASN1_BOOLEAN *)pval; |
804 | 75.3k | *tbool = *cont; |
805 | 75.3k | } |
806 | 75.3k | break; |
807 | | |
808 | 137k | case V_ASN1_BIT_STRING: |
809 | 137k | if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) { |
810 | 696 | goto err; |
811 | 696 | } |
812 | 136k | break; |
813 | | |
814 | 259k | case V_ASN1_INTEGER: |
815 | 313k | case V_ASN1_ENUMERATED: |
816 | 313k | tint = (ASN1_INTEGER **)pval; |
817 | 313k | if (!c2i_ASN1_INTEGER(tint, &cont, len)) { |
818 | 165 | goto err; |
819 | 165 | } |
820 | | // Fixup type to match the expected form |
821 | 313k | (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); |
822 | 313k | break; |
823 | | |
824 | 399k | case V_ASN1_OCTET_STRING: |
825 | 400k | case V_ASN1_NUMERICSTRING: |
826 | 646k | case V_ASN1_PRINTABLESTRING: |
827 | 652k | case V_ASN1_T61STRING: |
828 | 653k | case V_ASN1_VIDEOTEXSTRING: |
829 | 685k | case V_ASN1_IA5STRING: |
830 | 930k | case V_ASN1_UTCTIME: |
831 | 932k | case V_ASN1_GENERALIZEDTIME: |
832 | 932k | case V_ASN1_GRAPHICSTRING: |
833 | 932k | case V_ASN1_VISIBLESTRING: |
834 | 933k | case V_ASN1_GENERALSTRING: |
835 | 937k | case V_ASN1_UNIVERSALSTRING: |
836 | 942k | case V_ASN1_BMPSTRING: |
837 | 1.37M | case V_ASN1_UTF8STRING: |
838 | 1.39M | case V_ASN1_OTHER: |
839 | 1.40M | case V_ASN1_SET: |
840 | 1.43M | case V_ASN1_SEQUENCE: |
841 | | // TODO(crbug.com/boringssl/412): This default case should be removed, now |
842 | | // that we've resolved https://crbug.com/boringssl/561. However, it is still |
843 | | // needed to support some edge cases in |ASN1_PRINTABLE|. |ASN1_PRINTABLE| |
844 | | // broadly doesn't tolerate unrecognized universal tags, but except for |
845 | | // eight values that map to |B_ASN1_UNKNOWN| instead of zero. See the |
846 | | // X509Test.NameAttributeValues test. |
847 | 1.43M | default: { |
848 | 1.43M | CBS cbs; |
849 | 1.43M | CBS_init(&cbs, cont, (size_t)len); |
850 | 1.43M | if (utype == V_ASN1_BMPSTRING) { |
851 | 5.66M | while (CBS_len(&cbs) != 0) { |
852 | 5.66M | uint32_t c; |
853 | 5.66M | if (!cbs_get_ucs2_be(&cbs, &c)) { |
854 | 294 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING); |
855 | 294 | goto err; |
856 | 294 | } |
857 | 5.66M | } |
858 | 5.84k | } |
859 | 1.43M | if (utype == V_ASN1_UNIVERSALSTRING) { |
860 | 66.3k | while (CBS_len(&cbs) != 0) { |
861 | 62.8k | uint32_t c; |
862 | 62.8k | if (!cbs_get_utf32_be(&cbs, &c)) { |
863 | 515 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING); |
864 | 515 | goto err; |
865 | 515 | } |
866 | 62.8k | } |
867 | 3.98k | } |
868 | 1.43M | if (utype == V_ASN1_UTF8STRING) { |
869 | 106M | while (CBS_len(&cbs) != 0) { |
870 | 106M | uint32_t c; |
871 | 106M | if (!cbs_get_utf8(&cbs, &c)) { |
872 | 576 | OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING); |
873 | 576 | goto err; |
874 | 576 | } |
875 | 106M | } |
876 | 435k | } |
877 | 1.43M | if (utype == V_ASN1_UTCTIME) { |
878 | 244k | if (!CBS_parse_utc_time(&cbs, NULL, /*allow_timezone_offset=*/1)) { |
879 | 1.14k | OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT); |
880 | 1.14k | goto err; |
881 | 1.14k | } |
882 | 244k | } |
883 | 1.43M | if (utype == V_ASN1_GENERALIZEDTIME) { |
884 | 1.82k | if (!CBS_parse_generalized_time(&cbs, NULL, |
885 | 1.82k | /*allow_timezone_offset=*/0)) { |
886 | 1.29k | OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT); |
887 | 1.29k | goto err; |
888 | 1.29k | } |
889 | 1.82k | } |
890 | | // TODO(https://crbug.com/boringssl/427): Check other string types. |
891 | | |
892 | | // All based on ASN1_STRING and handled the same |
893 | 1.43M | if (!*pval) { |
894 | 71.7k | stmp = ASN1_STRING_type_new(utype); |
895 | 71.7k | if (!stmp) { |
896 | 0 | goto err; |
897 | 0 | } |
898 | 71.7k | *pval = (ASN1_VALUE *)stmp; |
899 | 1.35M | } else { |
900 | 1.35M | stmp = (ASN1_STRING *)*pval; |
901 | 1.35M | stmp->type = utype; |
902 | 1.35M | } |
903 | 1.43M | if (!ASN1_STRING_set(stmp, cont, len)) { |
904 | 0 | ASN1_STRING_free(stmp); |
905 | 0 | *pval = NULL; |
906 | 0 | goto err; |
907 | 0 | } |
908 | 1.43M | break; |
909 | 1.43M | } |
910 | 3.76M | } |
911 | | // If ASN1_ANY and NULL type fix up value |
912 | 3.75M | if (typ && (utype == V_ASN1_NULL)) { |
913 | 214k | typ->value.ptr = NULL; |
914 | 214k | } |
915 | | |
916 | 3.75M | ret = 1; |
917 | 3.76M | err: |
918 | 3.76M | if (!ret) { |
919 | 5.05k | ASN1_TYPE_free(typ); |
920 | 5.05k | if (opval) { |
921 | 1.80k | *opval = NULL; |
922 | 1.80k | } |
923 | 5.05k | } |
924 | 3.76M | return ret; |
925 | 3.75M | } |
926 | | |
927 | | // Check an ASN1 tag and length: a bit like ASN1_get_object but it |
928 | | // checks the expected tag. |
929 | | |
930 | | static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, |
931 | | char *cst, const unsigned char **in, long len, |
932 | 9.09M | int exptag, int expclass, char opt) { |
933 | 9.09M | int i; |
934 | 9.09M | int ptag, pclass; |
935 | 9.09M | long plen; |
936 | 9.09M | const unsigned char *p; |
937 | 9.09M | p = *in; |
938 | | |
939 | 9.09M | i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); |
940 | 9.09M | if (i & 0x80) { |
941 | 6.12k | OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER); |
942 | 6.12k | return 0; |
943 | 6.12k | } |
944 | 9.08M | if (exptag >= 0) { |
945 | 7.74M | if ((exptag != ptag) || (expclass != pclass)) { |
946 | | // If type is OPTIONAL, not an error: indicate missing type. |
947 | 732k | if (opt) { |
948 | 727k | return -1; |
949 | 727k | } |
950 | 4.24k | OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG); |
951 | 4.24k | return 0; |
952 | 732k | } |
953 | 7.74M | } |
954 | | |
955 | 8.35M | if (cst) { |
956 | 5.92M | *cst = i & V_ASN1_CONSTRUCTED; |
957 | 5.92M | } |
958 | | |
959 | 8.35M | if (olen) { |
960 | 7.02M | *olen = plen; |
961 | 7.02M | } |
962 | | |
963 | 8.35M | if (oclass) { |
964 | 1.32M | *oclass = pclass; |
965 | 1.32M | } |
966 | | |
967 | 8.35M | if (otag) { |
968 | 1.32M | *otag = ptag; |
969 | 1.32M | } |
970 | | |
971 | 8.35M | *in = p; |
972 | 8.35M | return 1; |
973 | 9.08M | } |