Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/asn1/tasn_dec.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* | - | ||||||||||||
2 | * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. | - | ||||||||||||
3 | * | - | ||||||||||||
4 | * Licensed under the OpenSSL license (the "License"). You may not use | - | ||||||||||||
5 | * this file except in compliance with the License. You can obtain a copy | - | ||||||||||||
6 | * in the file LICENSE in the source distribution or at | - | ||||||||||||
7 | * https://www.openssl.org/source/license.html | - | ||||||||||||
8 | */ | - | ||||||||||||
9 | - | |||||||||||||
10 | #include <stddef.h> | - | ||||||||||||
11 | #include <string.h> | - | ||||||||||||
12 | #include <openssl/asn1.h> | - | ||||||||||||
13 | #include <openssl/asn1t.h> | - | ||||||||||||
14 | #include <openssl/objects.h> | - | ||||||||||||
15 | #include <openssl/buffer.h> | - | ||||||||||||
16 | #include <openssl/err.h> | - | ||||||||||||
17 | #include "internal/numbers.h" | - | ||||||||||||
18 | #include "asn1_locl.h" | - | ||||||||||||
19 | - | |||||||||||||
20 | - | |||||||||||||
21 | /* | - | ||||||||||||
22 | * Constructed types with a recursive definition (such as can be found in PKCS7) | - | ||||||||||||
23 | * could eventually exceed the stack given malicious input with excessive | - | ||||||||||||
24 | * recursion. Therefore we limit the stack depth. This is the maximum number of | - | ||||||||||||
25 | * recursive invocations of asn1_item_embed_d2i(). | - | ||||||||||||
26 | */ | - | ||||||||||||
27 | #define ASN1_MAX_CONSTRUCTED_NEST 30 | - | ||||||||||||
28 | - | |||||||||||||
29 | static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, | - | ||||||||||||
30 | long len, const ASN1_ITEM *it, | - | ||||||||||||
31 | int tag, int aclass, char opt, ASN1_TLC *ctx, | - | ||||||||||||
32 | int depth); | - | ||||||||||||
33 | - | |||||||||||||
34 | static int asn1_check_eoc(const unsigned char **in, long len); | - | ||||||||||||
35 | static int asn1_find_end(const unsigned char **in, long len, char inf); | - | ||||||||||||
36 | - | |||||||||||||
37 | static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, | - | ||||||||||||
38 | char inf, int tag, int aclass, int depth); | - | ||||||||||||
39 | - | |||||||||||||
40 | static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen); | - | ||||||||||||
41 | - | |||||||||||||
42 | static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, | - | ||||||||||||
43 | char *inf, char *cst, | - | ||||||||||||
44 | const unsigned char **in, long len, | - | ||||||||||||
45 | int exptag, int expclass, char opt, ASN1_TLC *ctx); | - | ||||||||||||
46 | - | |||||||||||||
47 | static int asn1_template_ex_d2i(ASN1_VALUE **pval, | - | ||||||||||||
48 | const unsigned char **in, long len, | - | ||||||||||||
49 | const ASN1_TEMPLATE *tt, char opt, | - | ||||||||||||
50 | ASN1_TLC *ctx, int depth); | - | ||||||||||||
51 | static int asn1_template_noexp_d2i(ASN1_VALUE **val, | - | ||||||||||||
52 | const unsigned char **in, long len, | - | ||||||||||||
53 | const ASN1_TEMPLATE *tt, char opt, | - | ||||||||||||
54 | ASN1_TLC *ctx, int depth); | - | ||||||||||||
55 | static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, | - | ||||||||||||
56 | const unsigned char **in, long len, | - | ||||||||||||
57 | const ASN1_ITEM *it, | - | ||||||||||||
58 | int tag, int aclass, char opt, | - | ||||||||||||
59 | ASN1_TLC *ctx); | - | ||||||||||||
60 | static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, | - | ||||||||||||
61 | int utype, char *free_cont, const ASN1_ITEM *it); | - | ||||||||||||
62 | - | |||||||||||||
63 | /* Table to convert tags to bit values, used for MSTRING type */ | - | ||||||||||||
64 | static const unsigned long tag2bit[32] = { | - | ||||||||||||
65 | /* tags 0 - 3 */ | - | ||||||||||||
66 | 0, 0, 0, B_ASN1_BIT_STRING, | - | ||||||||||||
67 | /* tags 4- 7 */ | - | ||||||||||||
68 | B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN, | - | ||||||||||||
69 | /* tags 8-11 */ | - | ||||||||||||
70 | B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, | - | ||||||||||||
71 | /* tags 12-15 */ | - | ||||||||||||
72 | B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, | - | ||||||||||||
73 | /* tags 16-19 */ | - | ||||||||||||
74 | B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING, | - | ||||||||||||
75 | /* tags 20-22 */ | - | ||||||||||||
76 | B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING, | - | ||||||||||||
77 | /* tags 23-24 */ | - | ||||||||||||
78 | B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, | - | ||||||||||||
79 | /* tags 25-27 */ | - | ||||||||||||
80 | B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING, | - | ||||||||||||
81 | /* tags 28-31 */ | - | ||||||||||||
82 | B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN, | - | ||||||||||||
83 | }; | - | ||||||||||||
84 | - | |||||||||||||
85 | unsigned long ASN1_tag2bit(int tag) | - | ||||||||||||
86 | { | - | ||||||||||||
87 | if ((tag < 0) || (tag > 30))
| 0-426869 | ||||||||||||
88 | return 0; executed 5655 times by 1 test: return 0; Executed by:
| 5655 | ||||||||||||
89 | return tag2bit[tag]; executed 421214 times by 1 test: return tag2bit[tag]; Executed by:
| 421214 | ||||||||||||
90 | } | - | ||||||||||||
91 | - | |||||||||||||
92 | /* Macro to initialize and invalidate the cache */ | - | ||||||||||||
93 | - | |||||||||||||
94 | #define asn1_tlc_clear(c) if (c) (c)->valid = 0 | - | ||||||||||||
95 | /* Version to avoid compiler warning about 'c' always non-NULL */ | - | ||||||||||||
96 | #define asn1_tlc_clear_nc(c) (c)->valid = 0 | - | ||||||||||||
97 | - | |||||||||||||
98 | /* | - | ||||||||||||
99 | * Decode an ASN1 item, this currently behaves just like a standard 'd2i' | - | ||||||||||||
100 | * function. 'in' points to a buffer to read the data from, in future we | - | ||||||||||||
101 | * will have more advanced versions that can input data a piece at a time and | - | ||||||||||||
102 | * this will simply be a special case. | - | ||||||||||||
103 | */ | - | ||||||||||||
104 | - | |||||||||||||
105 | ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, | - | ||||||||||||
106 | const unsigned char **in, long len, | - | ||||||||||||
107 | const ASN1_ITEM *it) | - | ||||||||||||
108 | { | - | ||||||||||||
109 | ASN1_TLC c; | - | ||||||||||||
110 | ASN1_VALUE *ptmpval = NULL; | - | ||||||||||||
111 | if (!pval)
| 9281-1044253 | ||||||||||||
112 | pval = &ptmpval; executed 1044253 times by 2 tests: pval = &ptmpval; Executed by:
| 1044253 | ||||||||||||
113 | asn1_tlc_clear_nc(&c); | - | ||||||||||||
114 | if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
| 440372-613162 | ||||||||||||
115 | return *pval; executed 440372 times by 2 tests: return *pval; Executed by:
| 440372 | ||||||||||||
116 | return NULL; executed 613162 times by 1 test: return ((void *)0) ; Executed by:
| 613162 | ||||||||||||
117 | } | - | ||||||||||||
118 | - | |||||||||||||
119 | int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, | - | ||||||||||||
120 | const ASN1_ITEM *it, | - | ||||||||||||
121 | int tag, int aclass, char opt, ASN1_TLC *ctx) | - | ||||||||||||
122 | { | - | ||||||||||||
123 | int rv; | - | ||||||||||||
124 | rv = asn1_item_embed_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); | - | ||||||||||||
125 | if (rv <= 0)
| 564053-628266 | ||||||||||||
126 | ASN1_item_ex_free(pval, it); executed 628266 times by 1 test: ASN1_item_ex_free(pval, it); Executed by:
| 628266 | ||||||||||||
127 | return rv; executed 1192319 times by 2 tests: return rv; Executed by:
| 1192319 | ||||||||||||
128 | } | - | ||||||||||||
129 | - | |||||||||||||
130 | /* | - | ||||||||||||
131 | * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and | - | ||||||||||||
132 | * tag mismatch return -1 to handle OPTIONAL | - | ||||||||||||
133 | */ | - | ||||||||||||
134 | - | |||||||||||||
135 | static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, | - | ||||||||||||
136 | long len, const ASN1_ITEM *it, | - | ||||||||||||
137 | int tag, int aclass, char opt, ASN1_TLC *ctx, | - | ||||||||||||
138 | int depth) | - | ||||||||||||
139 | { | - | ||||||||||||
140 | const ASN1_TEMPLATE *tt, *errtt = NULL; | - | ||||||||||||
141 | const ASN1_EXTERN_FUNCS *ef; | - | ||||||||||||
142 | const ASN1_AUX *aux = it->funcs; | - | ||||||||||||
143 | ASN1_aux_cb *asn1_cb; | - | ||||||||||||
144 | const unsigned char *p = NULL, *q; | - | ||||||||||||
145 | unsigned char oclass; | - | ||||||||||||
146 | char seq_eoc, seq_nolen, cst, isopt; | - | ||||||||||||
147 | long tmplen; | - | ||||||||||||
148 | int i; | - | ||||||||||||
149 | int otag; | - | ||||||||||||
150 | int ret = 0; | - | ||||||||||||
151 | ASN1_VALUE **pchptr; | - | ||||||||||||
152 | if (!pval)
| 0-5388010 | ||||||||||||
153 | return 0; never executed: return 0; | 0 | ||||||||||||
154 | if (aux && aux->asn1_cb)
| 184708-4625934 | ||||||||||||
155 | asn1_cb = aux->asn1_cb; executed 577368 times by 2 tests: asn1_cb = aux->asn1_cb; Executed by:
| 577368 | ||||||||||||
156 | else | - | ||||||||||||
157 | asn1_cb = 0; executed 4810642 times by 2 tests: asn1_cb = 0; Executed by:
| 4810642 | ||||||||||||
158 | - | |||||||||||||
159 | if (++depth > ASN1_MAX_CONSTRUCTED_NEST) {
| 1-5388009 | ||||||||||||
160 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_NESTED_TOO_DEEP); | - | ||||||||||||
161 | goto err; executed 1 time by 1 test: goto err; Executed by:
| 1 | ||||||||||||
162 | } | - | ||||||||||||
163 | - | |||||||||||||
164 | switch (it->itype) { | - | ||||||||||||
165 | case ASN1_ITYPE_PRIMITIVE: executed 3075763 times by 2 tests: case 0x0: Executed by:
| 3075763 | ||||||||||||
166 | if (it->templates) {
| 333662-2742101 | ||||||||||||
167 | /* | - | ||||||||||||
168 | * tagging or OPTIONAL is currently illegal on an item template | - | ||||||||||||
169 | * because the flags can't get passed down. In practice this | - | ||||||||||||
170 | * isn't a problem: we include the relevant flags from the item | - | ||||||||||||
171 | * template in the template itself. | - | ||||||||||||
172 | */ | - | ||||||||||||
173 | if ((tag != -1) || opt) {
| 0-333662 | ||||||||||||
174 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, | - | ||||||||||||
175 | ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); | - | ||||||||||||
176 | goto err; never executed: goto err; | 0 | ||||||||||||
177 | } | - | ||||||||||||
178 | return asn1_template_ex_d2i(pval, in, len, executed 333662 times by 1 test: return asn1_template_ex_d2i(pval, in, len, it->templates, opt, ctx, depth); Executed by:
| 333662 | ||||||||||||
179 | it->templates, opt, ctx, depth); executed 333662 times by 1 test: return asn1_template_ex_d2i(pval, in, len, it->templates, opt, ctx, depth); Executed by:
| 333662 | ||||||||||||
180 | } | - | ||||||||||||
181 | return asn1_d2i_ex_primitive(pval, in, len, it, executed 2742101 times by 2 tests: return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt, ctx); Executed by:
| 2742101 | ||||||||||||
182 | tag, aclass, opt, ctx); executed 2742101 times by 2 tests: return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt, ctx); Executed by:
| 2742101 | ||||||||||||
183 | - | |||||||||||||
184 | case ASN1_ITYPE_MSTRING: executed 338797 times by 1 test: case 0x5: Executed by:
| 338797 | ||||||||||||
185 | p = *in; | - | ||||||||||||
186 | /* Just read in tag and class */ | - | ||||||||||||
187 | ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, | - | ||||||||||||
188 | &p, len, -1, 0, 1, ctx); | - | ||||||||||||
189 | if (!ret) {
| 1986-336811 | ||||||||||||
190 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
191 | goto err; executed 1986 times by 1 test: goto err; Executed by:
| 1986 | ||||||||||||
192 | } | - | ||||||||||||
193 | - | |||||||||||||
194 | /* Must be UNIVERSAL class */ | - | ||||||||||||
195 | if (oclass != V_ASN1_UNIVERSAL) {
| 30143-306668 | ||||||||||||
196 | /* If OPTIONAL, assume this is OK */ | - | ||||||||||||
197 | if (opt)
| 2717-27426 | ||||||||||||
198 | return -1; executed 27426 times by 1 test: return -1; Executed by:
| 27426 | ||||||||||||
199 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL); | - | ||||||||||||
200 | goto err; executed 2717 times by 1 test: goto err; Executed by:
| 2717 | ||||||||||||
201 | } | - | ||||||||||||
202 | /* Check tag matches bit map */ | - | ||||||||||||
203 | if (!(ASN1_tag2bit(otag) & it->utype)) {
| 29666-277002 | ||||||||||||
204 | /* If OPTIONAL, assume this is OK */ | - | ||||||||||||
205 | if (opt)
| 6116-23550 | ||||||||||||
206 | return -1; executed 6116 times by 1 test: return -1; Executed by:
| 6116 | ||||||||||||
207 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MSTRING_WRONG_TAG); | - | ||||||||||||
208 | goto err; executed 23550 times by 1 test: goto err; Executed by:
| 23550 | ||||||||||||
209 | } | - | ||||||||||||
210 | return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx); executed 277002 times by 1 test: return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx); Executed by:
| 277002 | ||||||||||||
211 | - | |||||||||||||
212 | case ASN1_ITYPE_EXTERN: executed 138785 times by 1 test: case 0x4: Executed by:
| 138785 | ||||||||||||
213 | /* Use new style d2i */ | - | ||||||||||||
214 | ef = it->funcs; | - | ||||||||||||
215 | return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); executed 138785 times by 1 test: return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); Executed by:
| 138785 | ||||||||||||
216 | - | |||||||||||||
217 | case ASN1_ITYPE_CHOICE: executed 207436 times by 1 test: case 0x2: Executed by:
| 207436 | ||||||||||||
218 | if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
| 0-174888 | ||||||||||||
219 | goto auxerr; never executed: goto auxerr; | 0 | ||||||||||||
220 | if (*pval) {
| 22129-185307 | ||||||||||||
221 | /* Free up and zero CHOICE value if initialised */ | - | ||||||||||||
222 | i = asn1_get_choice_selector(pval, it); | - | ||||||||||||
223 | if ((i >= 0) && (i < it->tcount)) {
| 0-22129 | ||||||||||||
224 | tt = it->templates + i; | - | ||||||||||||
225 | pchptr = asn1_get_field_ptr(pval, tt); | - | ||||||||||||
226 | asn1_template_free(pchptr, tt); | - | ||||||||||||
227 | asn1_set_choice_selector(pval, -1, it); | - | ||||||||||||
228 | } never executed: end of block | 0 | ||||||||||||
229 | } else if (!ASN1_item_ex_new(pval, it)) { executed 22129 times by 1 test: end of block Executed by:
| 0-185307 | ||||||||||||
230 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
231 | goto err; never executed: goto err; | 0 | ||||||||||||
232 | } | - | ||||||||||||
233 | /* CHOICE type, try each possibility in turn */ | - | ||||||||||||
234 | p = *in; | - | ||||||||||||
235 | for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
| 31535-643268 | ||||||||||||
236 | pchptr = asn1_get_field_ptr(pval, tt); | - | ||||||||||||
237 | /* | - | ||||||||||||
238 | * We mark field as OPTIONAL so its absence can be recognised. | - | ||||||||||||
239 | */ | - | ||||||||||||
240 | ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth); | - | ||||||||||||
241 | /* If field not present, try the next one */ | - | ||||||||||||
242 | if (ret == -1)
| 175901-467367 | ||||||||||||
243 | continue; executed 467367 times by 1 test: continue; Executed by:
| 467367 | ||||||||||||
244 | /* If positive return, read OK, break loop */ | - | ||||||||||||
245 | if (ret > 0)
| 47727-128174 | ||||||||||||
246 | break; executed 128174 times by 1 test: break; Executed by:
| 128174 | ||||||||||||
247 | /* | - | ||||||||||||
248 | * Must be an ASN1 parsing error. | - | ||||||||||||
249 | * Free up any partial choice value | - | ||||||||||||
250 | */ | - | ||||||||||||
251 | asn1_template_free(pchptr, tt); | - | ||||||||||||
252 | errtt = tt; | - | ||||||||||||
253 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
254 | goto err; executed 47727 times by 1 test: goto err; Executed by:
| 47727 | ||||||||||||
255 | } | - | ||||||||||||
256 | - | |||||||||||||
257 | /* Did we fall off the end without reading anything? */ | - | ||||||||||||
258 | if (i == it->tcount) {
| 31535-128174 | ||||||||||||
259 | /* If OPTIONAL, this is OK */ | - | ||||||||||||
260 | if (opt) {
| 1086-30449 | ||||||||||||
261 | /* Free and zero it */ | - | ||||||||||||
262 | ASN1_item_ex_free(pval, it); | - | ||||||||||||
263 | return -1; executed 1086 times by 1 test: return -1; Executed by:
| 1086 | ||||||||||||
264 | } | - | ||||||||||||
265 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE); | - | ||||||||||||
266 | goto err; executed 30449 times by 1 test: goto err; Executed by:
| 30449 | ||||||||||||
267 | } | - | ||||||||||||
268 | - | |||||||||||||
269 | asn1_set_choice_selector(pval, i, it); | - | ||||||||||||
270 | - | |||||||||||||
271 | if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
| 0-103358 | ||||||||||||
272 | goto auxerr; never executed: goto auxerr; | 0 | ||||||||||||
273 | *in = p; | - | ||||||||||||
274 | return 1; executed 128174 times by 1 test: return 1; Executed by:
| 128174 | ||||||||||||
275 | - | |||||||||||||
276 | case ASN1_ITYPE_NDEF_SEQUENCE: executed 40257 times by 1 test: case 0x6: Executed by:
| 40257 | ||||||||||||
277 | case ASN1_ITYPE_SEQUENCE: executed 1586971 times by 2 tests: case 0x1: Executed by:
| 1586971 | ||||||||||||
278 | p = *in; | - | ||||||||||||
279 | tmplen = len; | - | ||||||||||||
280 | - | |||||||||||||
281 | /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ | - | ||||||||||||
282 | if (tag == -1) {
| 159033-1468195 | ||||||||||||
283 | tag = V_ASN1_SEQUENCE; | - | ||||||||||||
284 | aclass = V_ASN1_UNIVERSAL; | - | ||||||||||||
285 | } executed 1468195 times by 2 tests: end of block Executed by:
| 1468195 | ||||||||||||
286 | /* Get SEQUENCE length and update len, p */ | - | ||||||||||||
287 | ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, | - | ||||||||||||
288 | &p, len, tag, aclass, opt, ctx); | - | ||||||||||||
289 | if (!ret) {
| 119024-1508204 | ||||||||||||
290 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
291 | goto err; executed 119024 times by 1 test: goto err; Executed by:
| 119024 | ||||||||||||
292 | } else if (ret == -1)
| 158106-1350098 | ||||||||||||
293 | return -1; executed 158106 times by 1 test: return -1; Executed by:
| 158106 | ||||||||||||
294 | if (aux && (aux->flags & ASN1_AFLG_BROKEN)) {
| 0-1040613 | ||||||||||||
295 | len = tmplen - (p - *in); | - | ||||||||||||
296 | seq_nolen = 1; | - | ||||||||||||
297 | } never executed: end of block | 0 | ||||||||||||
298 | /* If indefinite we don't do a length check */ | - | ||||||||||||
299 | else | - | ||||||||||||
300 | seq_nolen = seq_eoc; executed 1350098 times by 2 tests: seq_nolen = seq_eoc; Executed by:
| 1350098 | ||||||||||||
301 | if (!cst) {
| 7603-1342495 | ||||||||||||
302 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); | - | ||||||||||||
303 | goto err; executed 7603 times by 1 test: goto err; Executed by:
| 7603 | ||||||||||||
304 | } | - | ||||||||||||
305 | - | |||||||||||||
306 | if (!*pval && !ASN1_item_ex_new(pval, it)) {
| 0-966645 | ||||||||||||
307 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
308 | goto err; never executed: goto err; | 0 | ||||||||||||
309 | } | - | ||||||||||||
310 | - | |||||||||||||
311 | if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
| 0-1077287 | ||||||||||||
312 | goto auxerr; never executed: goto auxerr; | 0 | ||||||||||||
313 | - | |||||||||||||
314 | /* Free up and zero any ADB found */ | - | ||||||||||||
315 | for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
| 1342495-4249393 | ||||||||||||
316 | if (tt->flags & ASN1_TFLG_ADB_MASK) {
| 29687-4219706 | ||||||||||||
317 | const ASN1_TEMPLATE *seqtt; | - | ||||||||||||
318 | ASN1_VALUE **pseqval; | - | ||||||||||||
319 | seqtt = asn1_do_adb(pval, tt, 0); | - | ||||||||||||
320 | if (seqtt == NULL)
| 7441-22246 | ||||||||||||
321 | continue; executed 22246 times by 1 test: continue; Executed by:
| 22246 | ||||||||||||
322 | pseqval = asn1_get_field_ptr(pval, seqtt); | - | ||||||||||||
323 | asn1_template_free(pseqval, seqtt); | - | ||||||||||||
324 | } executed 7441 times by 1 test: end of block Executed by:
| 7441 | ||||||||||||
325 | } executed 4227147 times by 2 tests: end of block Executed by:
| 4227147 | ||||||||||||
326 | - | |||||||||||||
327 | /* Get each field entry */ | - | ||||||||||||
328 | for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
| 745538-3364357 | ||||||||||||
329 | const ASN1_TEMPLATE *seqtt; | - | ||||||||||||
330 | ASN1_VALUE **pseqval; | - | ||||||||||||
331 | seqtt = asn1_do_adb(pval, tt, 1); | - | ||||||||||||
332 | if (seqtt == NULL)
| 0-3364357 | ||||||||||||
333 | goto err; never executed: goto err; | 0 | ||||||||||||
334 | pseqval = asn1_get_field_ptr(pval, seqtt); | - | ||||||||||||
335 | /* Have we ran out of data? */ | - | ||||||||||||
336 | if (!len)
| 78309-3286048 | ||||||||||||
337 | break; executed 78309 times by 1 test: break; Executed by:
| 78309 | ||||||||||||
338 | q = p; | - | ||||||||||||
339 | if (asn1_check_eoc(&p, len)) {
| 139562-3146486 | ||||||||||||
340 | if (!seq_eoc) {
| 1023-138539 | ||||||||||||
341 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_UNEXPECTED_EOC); | - | ||||||||||||
342 | goto err; executed 1023 times by 1 test: goto err; Executed by:
| 1023 | ||||||||||||
343 | } | - | ||||||||||||
344 | len -= p - q; | - | ||||||||||||
345 | seq_eoc = 0; | - | ||||||||||||
346 | q = p; | - | ||||||||||||
347 | break; executed 138539 times by 1 test: break; Executed by:
| 138539 | ||||||||||||
348 | } | - | ||||||||||||
349 | /* | - | ||||||||||||
350 | * This determines the OPTIONAL flag value. The field cannot be | - | ||||||||||||
351 | * omitted if it is the last of a SEQUENCE and there is still | - | ||||||||||||
352 | * data to be read. This isn't strictly necessary but it | - | ||||||||||||
353 | * increases efficiency in some cases. | - | ||||||||||||
354 | */ | - | ||||||||||||
355 | if (i == (it->tcount - 1))
| 827565-2318921 | ||||||||||||
356 | isopt = 0; executed 827565 times by 2 tests: isopt = 0; Executed by:
| 827565 | ||||||||||||
357 | else | - | ||||||||||||
358 | isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); executed 2318921 times by 2 tests: isopt = (char)(seqtt->flags & (0x1)); Executed by:
| 2318921 | ||||||||||||
359 | /* | - | ||||||||||||
360 | * attempt to read in field, allowing each to be OPTIONAL | - | ||||||||||||
361 | */ | - | ||||||||||||
362 | - | |||||||||||||
363 | ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx, | - | ||||||||||||
364 | depth); | - | ||||||||||||
365 | if (!ret) {
| 379086-2767400 | ||||||||||||
366 | errtt = seqtt; | - | ||||||||||||
367 | goto err; executed 379086 times by 1 test: goto err; Executed by:
| 379086 | ||||||||||||
368 | } else if (ret == -1) {
| 516782-2250618 | ||||||||||||
369 | /* | - | ||||||||||||
370 | * OPTIONAL component absent. Free and zero the field. | - | ||||||||||||
371 | */ | - | ||||||||||||
372 | asn1_template_free(pseqval, seqtt); | - | ||||||||||||
373 | continue; executed 516782 times by 1 test: continue; Executed by:
| 516782 | ||||||||||||
374 | } | - | ||||||||||||
375 | /* Update length */ | - | ||||||||||||
376 | len -= p - q; | - | ||||||||||||
377 | } executed 2250618 times by 2 tests: end of block Executed by:
| 2250618 | ||||||||||||
378 | - | |||||||||||||
379 | /* Check for EOC if expecting one */ | - | ||||||||||||
380 | if (seq_eoc && !asn1_check_eoc(&p, len)) {
| 6416-629389 | ||||||||||||
381 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MISSING_EOC); | - | ||||||||||||
382 | goto err; executed 6416 times by 1 test: goto err; Executed by:
| 6416 | ||||||||||||
383 | } | - | ||||||||||||
384 | /* Check all data read */ | - | ||||||||||||
385 | if (!seq_nolen && len) {
| 1118-490850 | ||||||||||||
386 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH); | - | ||||||||||||
387 | goto err; executed 1118 times by 1 test: goto err; Executed by:
| 1118 | ||||||||||||
388 | } | - | ||||||||||||
389 | - | |||||||||||||
390 | /* | - | ||||||||||||
391 | * If we get here we've got no more data in the SEQUENCE, however we | - | ||||||||||||
392 | * may not have read all fields so check all remaining are OPTIONAL | - | ||||||||||||
393 | * and clear any that are. | - | ||||||||||||
394 | */ | - | ||||||||||||
395 | for (; i < it->tcount; tt++, i++) {
| 370403-951963 | ||||||||||||
396 | const ASN1_TEMPLATE *seqtt; | - | ||||||||||||
397 | seqtt = asn1_do_adb(pval, tt, 1); | - | ||||||||||||
398 | if (seqtt == NULL)
| 0-370403 | ||||||||||||
399 | goto err; never executed: goto err; | 0 | ||||||||||||
400 | if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
| 2889-367514 | ||||||||||||
401 | ASN1_VALUE **pseqval; | - | ||||||||||||
402 | pseqval = asn1_get_field_ptr(pval, seqtt); | - | ||||||||||||
403 | asn1_template_free(pseqval, seqtt); | - | ||||||||||||
404 | } else { executed 367514 times by 1 test: end of block Executed by:
| 367514 | ||||||||||||
405 | errtt = seqtt; | - | ||||||||||||
406 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_FIELD_MISSING); | - | ||||||||||||
407 | goto err; executed 2889 times by 1 test: goto err; Executed by:
| 2889 | ||||||||||||
408 | } | - | ||||||||||||
409 | } | - | ||||||||||||
410 | /* Save encoding */ | - | ||||||||||||
411 | if (!asn1_enc_save(pval, *in, p - *in, it))
| 0-951963 | ||||||||||||
412 | goto auxerr; never executed: goto auxerr; | 0 | ||||||||||||
413 | if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
| 8-764894 | ||||||||||||
414 | goto auxerr; executed 8 times by 1 test: goto auxerr; Executed by:
| 8 | ||||||||||||
415 | *in = p; | - | ||||||||||||
416 | return 1; executed 951955 times by 2 tests: return 1; Executed by:
| 951955 | ||||||||||||
417 | - | |||||||||||||
418 | default: never executed: default: | 0 | ||||||||||||
419 | return 0; never executed: return 0; | 0 | ||||||||||||
420 | } | - | ||||||||||||
421 | auxerr: code before this statement never executed: auxerr: | 0 | ||||||||||||
422 | ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_AUX_ERROR); | - | ||||||||||||
423 | err: code before this statement executed 8 times by 1 test: err: Executed by:
| 8 | ||||||||||||
424 | if (errtt)
| 193895-429702 | ||||||||||||
425 | ERR_add_error_data(4, "Field=", errtt->field_name, executed 429702 times by 1 test: ERR_add_error_data(4, "Field=", errtt->field_name, ", Type=", it->sname); Executed by:
| 429702 | ||||||||||||
426 | ", Type=", it->sname); executed 429702 times by 1 test: ERR_add_error_data(4, "Field=", errtt->field_name, ", Type=", it->sname); Executed by:
| 429702 | ||||||||||||
427 | else | - | ||||||||||||
428 | ERR_add_error_data(2, "Type=", it->sname); executed 193895 times by 1 test: ERR_add_error_data(2, "Type=", it->sname); Executed by:
| 193895 | ||||||||||||
429 | return 0; executed 623597 times by 1 test: return 0; Executed by:
| 623597 | ||||||||||||
430 | } | - | ||||||||||||
431 | - | |||||||||||||
432 | /* | - | ||||||||||||
433 | * Templates are handled with two separate functions. One handles any | - | ||||||||||||
434 | * EXPLICIT tag and the other handles the rest. | - | ||||||||||||
435 | */ | - | ||||||||||||
436 | - | |||||||||||||
437 | static int asn1_template_ex_d2i(ASN1_VALUE **val, | - | ||||||||||||
438 | const unsigned char **in, long inlen, | - | ||||||||||||
439 | const ASN1_TEMPLATE *tt, char opt, | - | ||||||||||||
440 | ASN1_TLC *ctx, int depth) | - | ||||||||||||
441 | { | - | ||||||||||||
442 | int flags, aclass; | - | ||||||||||||
443 | int ret; | - | ||||||||||||
444 | long len; | - | ||||||||||||
445 | const unsigned char *p, *q; | - | ||||||||||||
446 | char exp_eoc; | - | ||||||||||||
447 | if (!val)
| 0-4123416 | ||||||||||||
448 | return 0; never executed: return 0; | 0 | ||||||||||||
449 | flags = tt->flags; | - | ||||||||||||
450 | aclass = flags & ASN1_TFLG_TAG_CLASS; | - | ||||||||||||
451 | - | |||||||||||||
452 | p = *in; | - | ||||||||||||
453 | - | |||||||||||||
454 | /* Check if EXPLICIT tag expected */ | - | ||||||||||||
455 | if (flags & ASN1_TFLG_EXPTAG) {
| 270022-3853394 | ||||||||||||
456 | char cst; | - | ||||||||||||
457 | /* | - | ||||||||||||
458 | * Need to work out amount of data available to the inner content and | - | ||||||||||||
459 | * where it starts: so read in EXPLICIT header to get the info. | - | ||||||||||||
460 | */ | - | ||||||||||||
461 | ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, | - | ||||||||||||
462 | &p, inlen, tt->tag, aclass, opt, ctx); | - | ||||||||||||
463 | q = p; | - | ||||||||||||
464 | if (!ret) {
| 13767-256255 | ||||||||||||
465 | ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
466 | return 0; executed 13767 times by 1 test: return 0; Executed by:
| 13767 | ||||||||||||
467 | } else if (ret == -1)
| 109651-146604 | ||||||||||||
468 | return -1; executed 146604 times by 1 test: return -1; Executed by:
| 146604 | ||||||||||||
469 | if (!cst) {
| 947-108704 | ||||||||||||
470 | ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, | - | ||||||||||||
471 | ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); | - | ||||||||||||
472 | return 0; executed 947 times by 1 test: return 0; Executed by:
| 947 | ||||||||||||
473 | } | - | ||||||||||||
474 | /* We've found the field so it can't be OPTIONAL now */ | - | ||||||||||||
475 | ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth); | - | ||||||||||||
476 | if (!ret) {
| 12816-95888 | ||||||||||||
477 | ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
478 | return 0; executed 12816 times by 1 test: return 0; Executed by:
| 12816 | ||||||||||||
479 | } | - | ||||||||||||
480 | /* We read the field in OK so update length */ | - | ||||||||||||
481 | len -= p - q; | - | ||||||||||||
482 | if (exp_eoc) {
| 44513-51375 | ||||||||||||
483 | /* If NDEF we must have an EOC here */ | - | ||||||||||||
484 | if (!asn1_check_eoc(&p, len)) {
| 1537-42976 | ||||||||||||
485 | ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_MISSING_EOC); | - | ||||||||||||
486 | goto err; executed 1537 times by 1 test: goto err; Executed by:
| 1537 | ||||||||||||
487 | } | - | ||||||||||||
488 | } else { executed 42976 times by 1 test: end of block Executed by:
| 42976 | ||||||||||||
489 | /* | - | ||||||||||||
490 | * Otherwise we must hit the EXPLICIT tag end or its an error | - | ||||||||||||
491 | */ | - | ||||||||||||
492 | if (len) {
| 790-50585 | ||||||||||||
493 | ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, | - | ||||||||||||
494 | ASN1_R_EXPLICIT_LENGTH_MISMATCH); | - | ||||||||||||
495 | goto err; executed 790 times by 1 test: goto err; Executed by:
| 790 | ||||||||||||
496 | } | - | ||||||||||||
497 | } executed 50585 times by 1 test: end of block Executed by:
| 50585 | ||||||||||||
498 | } else | - | ||||||||||||
499 | return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth); executed 3853394 times by 2 tests: return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth); Executed by:
| 3853394 | ||||||||||||
500 | - | |||||||||||||
501 | *in = p; | - | ||||||||||||
502 | return 1; executed 93561 times by 1 test: return 1; Executed by:
| 93561 | ||||||||||||
503 | - | |||||||||||||
504 | err: | - | ||||||||||||
505 | return 0; executed 2327 times by 1 test: return 0; Executed by:
| 2327 | ||||||||||||
506 | } | - | ||||||||||||
507 | - | |||||||||||||
508 | static int asn1_template_noexp_d2i(ASN1_VALUE **val, | - | ||||||||||||
509 | const unsigned char **in, long len, | - | ||||||||||||
510 | const ASN1_TEMPLATE *tt, char opt, | - | ||||||||||||
511 | ASN1_TLC *ctx, int depth) | - | ||||||||||||
512 | { | - | ||||||||||||
513 | int flags, aclass; | - | ||||||||||||
514 | int ret; | - | ||||||||||||
515 | ASN1_VALUE *tval; | - | ||||||||||||
516 | const unsigned char *p, *q; | - | ||||||||||||
517 | if (!val)
| 0-3962098 | ||||||||||||
518 | return 0; never executed: return 0; | 0 | ||||||||||||
519 | flags = tt->flags; | - | ||||||||||||
520 | aclass = flags & ASN1_TFLG_TAG_CLASS; | - | ||||||||||||
521 | - | |||||||||||||
522 | p = *in; | - | ||||||||||||
523 | q = p; | - | ||||||||||||
524 | - | |||||||||||||
525 | /* | - | ||||||||||||
526 | * If field is embedded then val needs fixing so it is a pointer to | - | ||||||||||||
527 | * a pointer to a field. | - | ||||||||||||
528 | */ | - | ||||||||||||
529 | if (tt->flags & ASN1_TFLG_EMBED) {
| 669091-3293007 | ||||||||||||
530 | tval = (ASN1_VALUE *)val; | - | ||||||||||||
531 | val = &tval; | - | ||||||||||||
532 | } executed 669091 times by 1 test: end of block Executed by:
| 669091 | ||||||||||||
533 | - | |||||||||||||
534 | if (flags & ASN1_TFLG_SK_MASK) {
| 533882-3428216 | ||||||||||||
535 | /* SET OF, SEQUENCE OF */ | - | ||||||||||||
536 | int sktag, skaclass; | - | ||||||||||||
537 | char sk_eoc; | - | ||||||||||||
538 | /* First work out expected inner tag value */ | - | ||||||||||||
539 | if (flags & ASN1_TFLG_IMPTAG) {
| 77332-456550 | ||||||||||||
540 | sktag = tt->tag; | - | ||||||||||||
541 | skaclass = aclass; | - | ||||||||||||
542 | } else { executed 77332 times by 1 test: end of block Executed by:
| 77332 | ||||||||||||
543 | skaclass = V_ASN1_UNIVERSAL; | - | ||||||||||||
544 | if (flags & ASN1_TFLG_SET_OF)
| 106057-350493 | ||||||||||||
545 | sktag = V_ASN1_SET; executed 106057 times by 1 test: sktag = 17; Executed by:
| 106057 | ||||||||||||
546 | else | - | ||||||||||||
547 | sktag = V_ASN1_SEQUENCE; executed 350493 times by 1 test: sktag = 16; Executed by:
| 350493 | ||||||||||||
548 | } | - | ||||||||||||
549 | /* Get the tag */ | - | ||||||||||||
550 | ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, | - | ||||||||||||
551 | &p, len, sktag, skaclass, opt, ctx); | - | ||||||||||||
552 | if (!ret) {
| 55199-478683 | ||||||||||||
553 | ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
554 | return 0; executed 55199 times by 1 test: return 0; Executed by:
| 55199 | ||||||||||||
555 | } else if (ret == -1)
| 64322-414361 | ||||||||||||
556 | return -1; executed 64322 times by 1 test: return -1; Executed by:
| 64322 | ||||||||||||
557 | if (!*val)
| 12636-401725 | ||||||||||||
558 | *val = (ASN1_VALUE *)sk_ASN1_VALUE_new_null(); executed 401725 times by 1 test: *val = (ASN1_VALUE *)sk_ASN1_VALUE_new_null(); Executed by:
| 401725 | ||||||||||||
559 | else { | - | ||||||||||||
560 | /* | - | ||||||||||||
561 | * We've got a valid STACK: free up any items present | - | ||||||||||||
562 | */ | - | ||||||||||||
563 | STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val; | - | ||||||||||||
564 | ASN1_VALUE *vtmp; | - | ||||||||||||
565 | while (sk_ASN1_VALUE_num(sktmp) > 0) {
| 0-12636 | ||||||||||||
566 | vtmp = sk_ASN1_VALUE_pop(sktmp); | - | ||||||||||||
567 | ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); | - | ||||||||||||
568 | } never executed: end of block | 0 | ||||||||||||
569 | } executed 12636 times by 1 test: end of block Executed by:
| 12636 | ||||||||||||
570 | - | |||||||||||||
571 | if (!*val) {
| 0-414361 | ||||||||||||
572 | ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); | - | ||||||||||||
573 | goto err; never executed: goto err; | 0 | ||||||||||||
574 | } | - | ||||||||||||
575 | - | |||||||||||||
576 | /* Read as many items as we can */ | - | ||||||||||||
577 | while (len > 0) {
| 270318-840095 | ||||||||||||
578 | ASN1_VALUE *skfield; | - | ||||||||||||
579 | q = p; | - | ||||||||||||
580 | /* See if EOC found */ | - | ||||||||||||
581 | if (asn1_check_eoc(&p, len)) {
| 72620-767475 | ||||||||||||
582 | if (!sk_eoc) {
| 833-71787 | ||||||||||||
583 | ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, | - | ||||||||||||
584 | ASN1_R_UNEXPECTED_EOC); | - | ||||||||||||
585 | goto err; executed 833 times by 1 test: goto err; Executed by:
| 833 | ||||||||||||
586 | } | - | ||||||||||||
587 | len -= p - q; | - | ||||||||||||
588 | sk_eoc = 0; | - | ||||||||||||
589 | break; executed 71787 times by 1 test: break; Executed by:
| 71787 | ||||||||||||
590 | } | - | ||||||||||||
591 | skfield = NULL; | - | ||||||||||||
592 | if (!asn1_item_embed_d2i(&skfield, &p, len,
| 71423-696052 | ||||||||||||
593 | ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx,
| 71423-696052 | ||||||||||||
594 | depth)) {
| 71423-696052 | ||||||||||||
595 | ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, | - | ||||||||||||
596 | ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
597 | /* |skfield| may be partially allocated despite failure. */ | - | ||||||||||||
598 | ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item)); | - | ||||||||||||
599 | goto err; executed 71423 times by 1 test: goto err; Executed by:
| 71423 | ||||||||||||
600 | } | - | ||||||||||||
601 | len -= p - q; | - | ||||||||||||
602 | if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
| 0-696052 | ||||||||||||
603 | ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); | - | ||||||||||||
604 | ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item)); | - | ||||||||||||
605 | goto err; never executed: goto err; | 0 | ||||||||||||
606 | } | - | ||||||||||||
607 | } executed 696052 times by 1 test: end of block Executed by:
| 696052 | ||||||||||||
608 | if (sk_eoc) {
| 1116-340989 | ||||||||||||
609 | ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC); | - | ||||||||||||
610 | goto err; executed 1116 times by 1 test: goto err; Executed by:
| 1116 | ||||||||||||
611 | } | - | ||||||||||||
612 | } else if (flags & ASN1_TFLG_IMPTAG) { executed 340989 times by 1 test: end of block Executed by:
| 340989-2838319 | ||||||||||||
613 | /* IMPLICIT tagging */ | - | ||||||||||||
614 | ret = asn1_item_embed_d2i(val, &p, len, | - | ||||||||||||
615 | ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, | - | ||||||||||||
616 | ctx, depth); | - | ||||||||||||
617 | if (!ret) {
| 43659-546238 | ||||||||||||
618 | ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
619 | goto err; executed 43659 times by 1 test: goto err; Executed by:
| 43659 | ||||||||||||
620 | } else if (ret == -1)
| 90984-455254 | ||||||||||||
621 | return -1; executed 455254 times by 1 test: return -1; Executed by:
| 455254 | ||||||||||||
622 | } else { executed 90984 times by 1 test: end of block Executed by:
| 90984 | ||||||||||||
623 | /* Nothing special */ | - | ||||||||||||
624 | ret = asn1_item_embed_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), | - | ||||||||||||
625 | -1, 0, opt, ctx, depth); | - | ||||||||||||
626 | if (!ret) {
| 318226-2520093 | ||||||||||||
627 | ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
628 | goto err; executed 318226 times by 1 test: goto err; Executed by:
| 318226 | ||||||||||||
629 | } else if (ret == -1)
| 317969-2202124 | ||||||||||||
630 | return -1; executed 317969 times by 1 test: return -1; Executed by:
| 317969 | ||||||||||||
631 | } executed 2202124 times by 2 tests: end of block Executed by:
| 2202124 | ||||||||||||
632 | - | |||||||||||||
633 | *in = p; | - | ||||||||||||
634 | return 1; executed 2634097 times by 2 tests: return 1; Executed by:
| 2634097 | ||||||||||||
635 | - | |||||||||||||
636 | err: | - | ||||||||||||
637 | return 0; executed 435257 times by 1 test: return 0; Executed by:
| 435257 | ||||||||||||
638 | } | - | ||||||||||||
639 | - | |||||||||||||
640 | static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, | - | ||||||||||||
641 | const unsigned char **in, long inlen, | - | ||||||||||||
642 | const ASN1_ITEM *it, | - | ||||||||||||
643 | int tag, int aclass, char opt, ASN1_TLC *ctx) | - | ||||||||||||
644 | { | - | ||||||||||||
645 | int ret = 0, utype; | - | ||||||||||||
646 | long plen; | - | ||||||||||||
647 | char cst, inf, free_cont = 0; | - | ||||||||||||
648 | const unsigned char *p; | - | ||||||||||||
649 | BUF_MEM buf = { 0, NULL, 0, 0 }; | - | ||||||||||||
650 | const unsigned char *cont = NULL; | - | ||||||||||||
651 | long len; | - | ||||||||||||
652 | if (!pval) {
| 0-3019103 | ||||||||||||
653 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL); | - | ||||||||||||
654 | return 0; /* Should never happen */ never executed: return 0; | 0 | ||||||||||||
655 | } | - | ||||||||||||
656 | - | |||||||||||||
657 | if (it->itype == ASN1_ITYPE_MSTRING) {
| 277002-2742101 | ||||||||||||
658 | utype = tag; | - | ||||||||||||
659 | tag = -1; | - | ||||||||||||
660 | } else executed 277002 times by 1 test: end of block Executed by:
| 277002 | ||||||||||||
661 | utype = it->utype; executed 2742101 times by 2 tests: utype = it->utype; Executed by:
| 2742101 | ||||||||||||
662 | - | |||||||||||||
663 | if (utype == V_ASN1_ANY) {
| 225601-2793502 | ||||||||||||
664 | /* If type is ANY need to figure out type from tag */ | - | ||||||||||||
665 | unsigned char oclass; | - | ||||||||||||
666 | if (tag >= 0) {
| 0-225601 | ||||||||||||
667 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY); | - | ||||||||||||
668 | return 0; never executed: return 0; | 0 | ||||||||||||
669 | } | - | ||||||||||||
670 | if (opt) {
| 0-225601 | ||||||||||||
671 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, | - | ||||||||||||
672 | ASN1_R_ILLEGAL_OPTIONAL_ANY); | - | ||||||||||||
673 | return 0; never executed: return 0; | 0 | ||||||||||||
674 | } | - | ||||||||||||
675 | p = *in; | - | ||||||||||||
676 | ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, | - | ||||||||||||
677 | &p, inlen, -1, 0, 0, ctx); | - | ||||||||||||
678 | if (!ret) {
| 424-225177 | ||||||||||||
679 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
680 | return 0; executed 424 times by 1 test: return 0; Executed by:
| 424 | ||||||||||||
681 | } | - | ||||||||||||
682 | if (oclass != V_ASN1_UNIVERSAL)
| 30060-195117 | ||||||||||||
683 | utype = V_ASN1_OTHER; executed 30060 times by 1 test: utype = -3; Executed by:
| 30060 | ||||||||||||
684 | } executed 225177 times by 1 test: end of block Executed by:
| 225177 | ||||||||||||
685 | if (tag == -1) {
| 418483-2600196 | ||||||||||||
686 | tag = utype; | - | ||||||||||||
687 | aclass = V_ASN1_UNIVERSAL; | - | ||||||||||||
688 | } executed 2600196 times by 2 tests: end of block Executed by:
| 2600196 | ||||||||||||
689 | p = *in; | - | ||||||||||||
690 | /* Check header */ | - | ||||||||||||
691 | ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, | - | ||||||||||||
692 | &p, inlen, tag, aclass, opt, ctx); | - | ||||||||||||
693 | if (!ret) {
| 303113-2715566 | ||||||||||||
694 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
695 | return 0; executed 303113 times by 1 test: return 0; Executed by:
| 303113 | ||||||||||||
696 | } else if (ret == -1)
| 580489-2135077 | ||||||||||||
697 | return -1; executed 580489 times by 1 test: return -1; Executed by:
| 580489 | ||||||||||||
698 | ret = 0; | - | ||||||||||||
699 | /* SEQUENCE, SET and "OTHER" are left in encoded form */ | - | ||||||||||||
700 | if ((utype == V_ASN1_SEQUENCE)
| 52051-2083026 | ||||||||||||
701 | || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) {
| 3154-2079872 | ||||||||||||
702 | /* | - | ||||||||||||
703 | * Clear context cache for type OTHER because the auto clear when we | - | ||||||||||||
704 | * have a exact match won't work | - | ||||||||||||
705 | */ | - | ||||||||||||
706 | if (utype == V_ASN1_OTHER) {
| 30060-55205 | ||||||||||||
707 | asn1_tlc_clear(ctx); executed 30060 times by 1 test: (ctx)->valid = 0; Executed by:
| 0-30060 | ||||||||||||
708 | } executed 30060 times by 1 test: end of block Executed by:
| 30060 | ||||||||||||
709 | /* SEQUENCE and SET must be constructed */ | - | ||||||||||||
710 | else if (!cst) {
| 1047-54158 | ||||||||||||
711 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, | - | ||||||||||||
712 | ASN1_R_TYPE_NOT_CONSTRUCTED); | - | ||||||||||||
713 | return 0; executed 1047 times by 1 test: return 0; Executed by:
| 1047 | ||||||||||||
714 | } | - | ||||||||||||
715 | - | |||||||||||||
716 | cont = *in; | - | ||||||||||||
717 | /* If indefinite length constructed find the real end */ | - | ||||||||||||
718 | if (inf) {
| 30513-53705 | ||||||||||||
719 | if (!asn1_find_end(&p, plen, inf))
| 13173-17340 | ||||||||||||
720 | goto err; executed 13173 times by 1 test: goto err; Executed by:
| 13173 | ||||||||||||
721 | len = p - cont; | - | ||||||||||||
722 | } else { executed 17340 times by 1 test: end of block Executed by:
| 17340 | ||||||||||||
723 | len = p - cont + plen; | - | ||||||||||||
724 | p += plen; | - | ||||||||||||
725 | } executed 53705 times by 1 test: end of block Executed by:
| 53705 | ||||||||||||
726 | } else if (cst) {
| 63711-1986101 | ||||||||||||
727 | if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
| 434-63277 | ||||||||||||
728 | || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
| 667-61937 | ||||||||||||
729 | || utype == V_ASN1_ENUMERATED) {
| 474-60621 | ||||||||||||
730 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_PRIMITIVE); | - | ||||||||||||
731 | return 0; executed 3090 times by 1 test: return 0; Executed by:
| 3090 | ||||||||||||
732 | } | - | ||||||||||||
733 | - | |||||||||||||
734 | /* Free any returned 'buf' content */ | - | ||||||||||||
735 | free_cont = 1; | - | ||||||||||||
736 | /* | - | ||||||||||||
737 | * Should really check the internal tags are correct but some things | - | ||||||||||||
738 | * may get this wrong. The relevant specs say that constructed string | - | ||||||||||||
739 | * types should be OCTET STRINGs internally irrespective of the type. | - | ||||||||||||
740 | * So instead just check for UNIVERSAL class and ignore the tag. | - | ||||||||||||
741 | */ | - | ||||||||||||
742 | if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) {
| 3652-56969 | ||||||||||||
743 | goto err; executed 3652 times by 1 test: goto err; Executed by:
| 3652 | ||||||||||||
744 | } | - | ||||||||||||
745 | len = buf.length; | - | ||||||||||||
746 | /* Append a final null to string */ | - | ||||||||||||
747 | if (!BUF_MEM_grow_clean(&buf, len + 1)) {
| 0-56969 | ||||||||||||
748 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); | - | ||||||||||||
749 | goto err; never executed: goto err; | 0 | ||||||||||||
750 | } | - | ||||||||||||
751 | buf.data[len] = 0; | - | ||||||||||||
752 | cont = (const unsigned char *)buf.data; | - | ||||||||||||
753 | } else { executed 56969 times by 1 test: end of block Executed by:
| 56969 | ||||||||||||
754 | cont = p; | - | ||||||||||||
755 | len = plen; | - | ||||||||||||
756 | p += plen; | - | ||||||||||||
757 | } executed 1986101 times by 2 tests: end of block Executed by:
| 1986101 | ||||||||||||
758 | - | |||||||||||||
759 | /* We now have content length and type: translate into a structure */ | - | ||||||||||||
760 | /* asn1_ex_c2i may reuse allocated buffer, and so sets free_cont to 0 */ | - | ||||||||||||
761 | if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
| 16527-2097588 | ||||||||||||
762 | goto err; executed 16527 times by 1 test: goto err; Executed by:
| 16527 | ||||||||||||
763 | - | |||||||||||||
764 | *in = p; | - | ||||||||||||
765 | ret = 1; | - | ||||||||||||
766 | err: code before this statement executed 2097588 times by 2 tests: err: Executed by:
| 2097588 | ||||||||||||
767 | if (free_cont)
| 4097-2126843 | ||||||||||||
768 | OPENSSL_free(buf.data); executed 4097 times by 1 test: CRYPTO_free(buf.data, __FILE__, 768); Executed by:
| 4097 | ||||||||||||
769 | return ret; executed 2130940 times by 2 tests: return ret; Executed by:
| 2130940 | ||||||||||||
770 | } | - | ||||||||||||
771 | - | |||||||||||||
772 | /* Translate ASN1 content octets into a structure */ | - | ||||||||||||
773 | - | |||||||||||||
774 | static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, | - | ||||||||||||
775 | int utype, char *free_cont, const ASN1_ITEM *it) | - | ||||||||||||
776 | { | - | ||||||||||||
777 | ASN1_VALUE **opval = NULL; | - | ||||||||||||
778 | ASN1_STRING *stmp; | - | ||||||||||||
779 | ASN1_TYPE *typ = NULL; | - | ||||||||||||
780 | int ret = 0; | - | ||||||||||||
781 | const ASN1_PRIMITIVE_FUNCS *pf; | - | ||||||||||||
782 | ASN1_INTEGER **tint; | - | ||||||||||||
783 | pf = it->funcs; | - | ||||||||||||
784 | - | |||||||||||||
785 | if (pf && pf->prim_c2i)
| 0-1950856 | ||||||||||||
786 | return pf->prim_c2i(pval, cont, len, utype, free_cont, it); executed 163259 times by 2 tests: return pf->prim_c2i(pval, cont, len, utype, free_cont, it); Executed by:
| 163259 | ||||||||||||
787 | /* If ANY type clear type and set pointer to internal value */ | - | ||||||||||||
788 | if (it->utype == V_ASN1_ANY) {
| 217001-1733855 | ||||||||||||
789 | if (!*pval) {
| 3603-213398 | ||||||||||||
790 | typ = ASN1_TYPE_new(); | - | ||||||||||||
791 | if (typ == NULL)
| 0-213398 | ||||||||||||
792 | goto err; never executed: goto err; | 0 | ||||||||||||
793 | *pval = (ASN1_VALUE *)typ; | - | ||||||||||||
794 | } else executed 213398 times by 1 test: end of block Executed by:
| 213398 | ||||||||||||
795 | typ = (ASN1_TYPE *)*pval; executed 3603 times by 1 test: typ = (ASN1_TYPE *)*pval; Executed by:
| 3603 | ||||||||||||
796 | - | |||||||||||||
797 | if (utype != typ->type)
| 0-217001 | ||||||||||||
798 | ASN1_TYPE_set(typ, utype, NULL); executed 217001 times by 1 test: ASN1_TYPE_set(typ, utype, ((void *)0) ); Executed by:
| 217001 | ||||||||||||
799 | opval = pval; | - | ||||||||||||
800 | pval = &typ->value.asn1_value; | - | ||||||||||||
801 | } executed 217001 times by 1 test: end of block Executed by:
| 217001 | ||||||||||||
802 | switch (utype) { | - | ||||||||||||
803 | case V_ASN1_OBJECT: executed 666098 times by 1 test: case 6: Executed by:
| 666098 | ||||||||||||
804 | if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
| 4369-661729 | ||||||||||||
805 | goto err; executed 4369 times by 1 test: goto err; Executed by:
| 4369 | ||||||||||||
806 | break; executed 661729 times by 1 test: break; Executed by:
| 661729 | ||||||||||||
807 | - | |||||||||||||
808 | case V_ASN1_NULL: executed 46684 times by 1 test: case 5: Executed by:
| 46684 | ||||||||||||
809 | if (len) {
| 322-46362 | ||||||||||||
810 | ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_NULL_IS_WRONG_LENGTH); | - | ||||||||||||
811 | goto err; executed 322 times by 1 test: goto err; Executed by:
| 322 | ||||||||||||
812 | } | - | ||||||||||||
813 | *pval = (ASN1_VALUE *)1; | - | ||||||||||||
814 | break; executed 46362 times by 1 test: break; Executed by:
| 46362 | ||||||||||||
815 | - | |||||||||||||
816 | case V_ASN1_BOOLEAN: executed 27684 times by 1 test: case 1: Executed by:
| 27684 | ||||||||||||
817 | if (len != 1) {
| 536-27148 | ||||||||||||
818 | ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); | - | ||||||||||||
819 | goto err; executed 536 times by 1 test: goto err; Executed by:
| 536 | ||||||||||||
820 | } else { | - | ||||||||||||
821 | ASN1_BOOLEAN *tbool; | - | ||||||||||||
822 | tbool = (ASN1_BOOLEAN *)pval; | - | ||||||||||||
823 | *tbool = *cont; | - | ||||||||||||
824 | } executed 27148 times by 1 test: end of block Executed by:
| 27148 | ||||||||||||
825 | break; executed 27148 times by 1 test: break; Executed by:
| 27148 | ||||||||||||
826 | - | |||||||||||||
827 | case V_ASN1_BIT_STRING: executed 147882 times by 1 test: case 3: Executed by:
| 147882 | ||||||||||||
828 | if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
| 1870-146012 | ||||||||||||
829 | goto err; executed 1870 times by 1 test: goto err; Executed by:
| 1870 | ||||||||||||
830 | break; executed 146012 times by 1 test: break; Executed by:
| 146012 | ||||||||||||
831 | - | |||||||||||||
832 | case V_ASN1_INTEGER: executed 255497 times by 1 test: case 2: Executed by:
| 255497 | ||||||||||||
833 | case V_ASN1_ENUMERATED: executed 17429 times by 1 test: case 10: Executed by:
| 17429 | ||||||||||||
834 | tint = (ASN1_INTEGER **)pval; | - | ||||||||||||
835 | if (!c2i_ASN1_INTEGER(tint, &cont, len))
| 7184-265742 | ||||||||||||
836 | goto err; executed 7184 times by 1 test: goto err; Executed by:
| 7184 | ||||||||||||
837 | /* Fixup type to match the expected form */ | - | ||||||||||||
838 | (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); | - | ||||||||||||
839 | break; executed 265742 times by 1 test: break; Executed by:
| 265742 | ||||||||||||
840 | - | |||||||||||||
841 | case V_ASN1_OCTET_STRING: executed 355812 times by 2 tests: case 4: Executed by:
| 355812 | ||||||||||||
842 | case V_ASN1_NUMERICSTRING: executed 5914 times by 1 test: case 18: Executed by:
| 5914 | ||||||||||||
843 | case V_ASN1_PRINTABLESTRING: executed 28425 times by 1 test: case 19: Executed by:
| 28425 | ||||||||||||
844 | case V_ASN1_T61STRING: executed 17382 times by 1 test: case 20: Executed by:
| 17382 | ||||||||||||
845 | case V_ASN1_VIDEOTEXSTRING: executed 423 times by 1 test: case 21: Executed by:
| 423 | ||||||||||||
846 | case V_ASN1_IA5STRING: executed 50244 times by 1 test: case 22: Executed by:
| 50244 | ||||||||||||
847 | case V_ASN1_UTCTIME: executed 79365 times by 1 test: case 23: Executed by:
| 79365 | ||||||||||||
848 | case V_ASN1_GENERALIZEDTIME: executed 55881 times by 1 test: case 24: Executed by:
| 55881 | ||||||||||||
849 | case V_ASN1_GRAPHICSTRING: executed 1086 times by 1 test: case 25: Executed by:
| 1086 | ||||||||||||
850 | case V_ASN1_VISIBLESTRING: executed 1782 times by 1 test: case 26: Executed by:
| 1782 | ||||||||||||
851 | case V_ASN1_GENERALSTRING: executed 1807 times by 1 test: case 27: Executed by:
| 1807 | ||||||||||||
852 | case V_ASN1_UNIVERSALSTRING: executed 14720 times by 1 test: case 28: Executed by:
| 14720 | ||||||||||||
853 | case V_ASN1_BMPSTRING: executed 13083 times by 1 test: case 30: Executed by:
| 13083 | ||||||||||||
854 | case V_ASN1_UTF8STRING: executed 64473 times by 1 test: case 12: Executed by:
| 64473 | ||||||||||||
855 | case V_ASN1_OTHER: executed 26809 times by 1 test: case -3: Executed by:
| 26809 | ||||||||||||
856 | case V_ASN1_SET: executed 2902 times by 1 test: case 17: Executed by:
| 2902 | ||||||||||||
857 | case V_ASN1_SEQUENCE: executed 41334 times by 1 test: case 16: Executed by:
| 41334 | ||||||||||||
858 | default: executed 28140 times by 1 test: default: Executed by:
| 28140 | ||||||||||||
859 | if (utype == V_ASN1_BMPSTRING && (len & 1)) {
| 726-776499 | ||||||||||||
860 | ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BMPSTRING_IS_WRONG_LENGTH); | - | ||||||||||||
861 | goto err; executed 726 times by 1 test: goto err; Executed by:
| 726 | ||||||||||||
862 | } | - | ||||||||||||
863 | if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) {
| 471-774136 | ||||||||||||
864 | ASN1err(ASN1_F_ASN1_EX_C2I, | - | ||||||||||||
865 | ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); | - | ||||||||||||
866 | goto err; executed 471 times by 1 test: goto err; Executed by:
| 471 | ||||||||||||
867 | } | - | ||||||||||||
868 | /* All based on ASN1_STRING and handled the same */ | - | ||||||||||||
869 | if (!*pval) {
| 298851-489534 | ||||||||||||
870 | stmp = ASN1_STRING_type_new(utype); | - | ||||||||||||
871 | if (stmp == NULL) {
| 0-298851 | ||||||||||||
872 | ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); | - | ||||||||||||
873 | goto err; never executed: goto err; | 0 | ||||||||||||
874 | } | - | ||||||||||||
875 | *pval = (ASN1_VALUE *)stmp; | - | ||||||||||||
876 | } else { executed 298851 times by 1 test: end of block Executed by:
| 298851 | ||||||||||||
877 | stmp = (ASN1_STRING *)*pval; | - | ||||||||||||
878 | stmp->type = utype; | - | ||||||||||||
879 | } executed 489534 times by 2 tests: end of block Executed by:
| 489534 | ||||||||||||
880 | /* If we've already allocated a buffer use it */ | - | ||||||||||||
881 | if (*free_cont) {
| 56524-731861 | ||||||||||||
882 | OPENSSL_free(stmp->data); | - | ||||||||||||
883 | stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */ | - | ||||||||||||
884 | stmp->length = len; | - | ||||||||||||
885 | *free_cont = 0; | - | ||||||||||||
886 | } else { executed 56524 times by 1 test: end of block Executed by:
| 56524 | ||||||||||||
887 | if (!ASN1_STRING_set(stmp, cont, len)) {
| 0-731861 | ||||||||||||
888 | ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); | - | ||||||||||||
889 | ASN1_STRING_free(stmp); | - | ||||||||||||
890 | *pval = NULL; | - | ||||||||||||
891 | goto err; never executed: goto err; | 0 | ||||||||||||
892 | } | - | ||||||||||||
893 | } executed 731861 times by 2 tests: end of block Executed by:
| 731861 | ||||||||||||
894 | break; executed 788385 times by 2 tests: break; Executed by:
| 788385 | ||||||||||||
895 | } | - | ||||||||||||
896 | /* If ASN1_ANY and NULL type fix up value */ | - | ||||||||||||
897 | if (typ && (utype == V_ASN1_NULL))
| 45202-1718973 | ||||||||||||
898 | typ->value.ptr = NULL; executed 45202 times by 1 test: typ->value.ptr = ((void *)0) ; Executed by:
| 45202 | ||||||||||||
899 | - | |||||||||||||
900 | ret = 1; | - | ||||||||||||
901 | err: code before this statement executed 1935378 times by 2 tests: err: Executed by:
| 1935378 | ||||||||||||
902 | if (!ret) {
| 15478-1935378 | ||||||||||||
903 | ASN1_TYPE_free(typ); | - | ||||||||||||
904 | if (opval)
| 596-14882 | ||||||||||||
905 | *opval = NULL; executed 596 times by 1 test: *opval = ((void *)0) ; Executed by:
| 596 | ||||||||||||
906 | } executed 15478 times by 1 test: end of block Executed by:
| 15478 | ||||||||||||
907 | return ret; executed 1950856 times by 2 tests: return ret; Executed by:
| 1950856 | ||||||||||||
908 | } | - | ||||||||||||
909 | - | |||||||||||||
910 | /* | - | ||||||||||||
911 | * This function finds the end of an ASN1 structure when passed its maximum | - | ||||||||||||
912 | * length, whether it is indefinite length and a pointer to the content. This | - | ||||||||||||
913 | * is more efficient than calling asn1_collect because it does not recurse on | - | ||||||||||||
914 | * each indefinite length header. | - | ||||||||||||
915 | */ | - | ||||||||||||
916 | - | |||||||||||||
917 | static int asn1_find_end(const unsigned char **in, long len, char inf) | - | ||||||||||||
918 | { | - | ||||||||||||
919 | uint32_t expected_eoc; | - | ||||||||||||
920 | long plen; | - | ||||||||||||
921 | const unsigned char *p = *in, *q; | - | ||||||||||||
922 | /* If not indefinite length constructed just add length */ | - | ||||||||||||
923 | if (inf == 0) {
| 0-30513 | ||||||||||||
924 | *in += len; | - | ||||||||||||
925 | return 1; never executed: return 1; | 0 | ||||||||||||
926 | } | - | ||||||||||||
927 | expected_eoc = 1; | - | ||||||||||||
928 | /* | - | ||||||||||||
929 | * Indefinite length constructed form. Find the end when enough EOCs are | - | ||||||||||||
930 | * found. If more indefinite length constructed headers are encountered | - | ||||||||||||
931 | * increment the expected eoc count otherwise just skip to the end of the | - | ||||||||||||
932 | * data. | - | ||||||||||||
933 | */ | - | ||||||||||||
934 | while (len > 0) {
| 4610-7407911 | ||||||||||||
935 | if (asn1_check_eoc(&p, len)) {
| 1956678-5451233 | ||||||||||||
936 | expected_eoc--; | - | ||||||||||||
937 | if (expected_eoc == 0)
| 17340-1939338 | ||||||||||||
938 | break; executed 17340 times by 1 test: break; Executed by:
| 17340 | ||||||||||||
939 | len -= 2; | - | ||||||||||||
940 | continue; executed 1939338 times by 1 test: continue; Executed by:
| 1939338 | ||||||||||||
941 | } | - | ||||||||||||
942 | q = p; | - | ||||||||||||
943 | /* Just read in a header: only care about the length */ | - | ||||||||||||
944 | if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
| 8563-5442670 | ||||||||||||
945 | -1, 0, 0, NULL)) {
| 8563-5442670 | ||||||||||||
946 | ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
947 | return 0; executed 8563 times by 1 test: return 0; Executed by:
| 8563 | ||||||||||||
948 | } | - | ||||||||||||
949 | if (inf) {
| 1964365-3478305 | ||||||||||||
950 | if (expected_eoc == UINT32_MAX) {
| 0-1964365 | ||||||||||||
951 | ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
952 | return 0; never executed: return 0; | 0 | ||||||||||||
953 | } | - | ||||||||||||
954 | expected_eoc++; | - | ||||||||||||
955 | } else { executed 1964365 times by 1 test: end of block Executed by:
| 1964365 | ||||||||||||
956 | p += plen; | - | ||||||||||||
957 | } executed 3478305 times by 1 test: end of block Executed by:
| 3478305 | ||||||||||||
958 | len -= p - q; | - | ||||||||||||
959 | } executed 5442670 times by 1 test: end of block Executed by:
| 5442670 | ||||||||||||
960 | if (expected_eoc) {
| 4610-17340 | ||||||||||||
961 | ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC); | - | ||||||||||||
962 | return 0; executed 4610 times by 1 test: return 0; Executed by:
| 4610 | ||||||||||||
963 | } | - | ||||||||||||
964 | *in = p; | - | ||||||||||||
965 | return 1; executed 17340 times by 1 test: return 1; Executed by:
| 17340 | ||||||||||||
966 | } | - | ||||||||||||
967 | - | |||||||||||||
968 | /* | - | ||||||||||||
969 | * This function collects the asn1 data from a constructed string type into | - | ||||||||||||
970 | * a buffer. The values of 'in' and 'len' should refer to the contents of the | - | ||||||||||||
971 | * constructed type and 'inf' should be set if it is indefinite length. | - | ||||||||||||
972 | */ | - | ||||||||||||
973 | - | |||||||||||||
974 | #ifndef ASN1_MAX_STRING_NEST | - | ||||||||||||
975 | /* | - | ||||||||||||
976 | * This determines how many levels of recursion are permitted in ASN1 string | - | ||||||||||||
977 | * types. If it is not limited stack overflows can occur. If set to zero no | - | ||||||||||||
978 | * recursion is allowed at all. Although zero should be adequate examples | - | ||||||||||||
979 | * exist that require a value of 1. So 5 should be more than enough. | - | ||||||||||||
980 | */ | - | ||||||||||||
981 | # define ASN1_MAX_STRING_NEST 5 | - | ||||||||||||
982 | #endif | - | ||||||||||||
983 | - | |||||||||||||
984 | static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, | - | ||||||||||||
985 | char inf, int tag, int aclass, int depth) | - | ||||||||||||
986 | { | - | ||||||||||||
987 | const unsigned char *p, *q; | - | ||||||||||||
988 | long plen; | - | ||||||||||||
989 | char cst, ininf; | - | ||||||||||||
990 | p = *in; | - | ||||||||||||
991 | inf &= 1; | - | ||||||||||||
992 | /* | - | ||||||||||||
993 | * If no buffer and not indefinite length constructed just pass over the | - | ||||||||||||
994 | * encoded data | - | ||||||||||||
995 | */ | - | ||||||||||||
996 | if (!buf && !inf) {
| 0-83235 | ||||||||||||
997 | *in += len; | - | ||||||||||||
998 | return 1; never executed: return 1; | 0 | ||||||||||||
999 | } | - | ||||||||||||
1000 | while (len > 0) {
| 57614-94320 | ||||||||||||
1001 | q = p; | - | ||||||||||||
1002 | /* Check for EOC */ | - | ||||||||||||
1003 | if (asn1_check_eoc(&p, len)) {
| 18830-75490 | ||||||||||||
1004 | /* | - | ||||||||||||
1005 | * EOC is illegal outside indefinite length constructed form | - | ||||||||||||
1006 | */ | - | ||||||||||||
1007 | if (!inf) {
| 821-18009 | ||||||||||||
1008 | ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC); | - | ||||||||||||
1009 | return 0; executed 821 times by 1 test: return 0; Executed by:
| 821 | ||||||||||||
1010 | } | - | ||||||||||||
1011 | inf = 0; | - | ||||||||||||
1012 | break; executed 18009 times by 1 test: break; Executed by:
| 18009 | ||||||||||||
1013 | } | - | ||||||||||||
1014 | - | |||||||||||||
1015 | if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
| 1309-74181 | ||||||||||||
1016 | len, tag, aclass, 0, NULL)) {
| 1309-74181 | ||||||||||||
1017 | ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR); | - | ||||||||||||
1018 | return 0; executed 1309 times by 1 test: return 0; Executed by:
| 1309 | ||||||||||||
1019 | } | - | ||||||||||||
1020 | - | |||||||||||||
1021 | /* If indefinite length constructed update max length */ | - | ||||||||||||
1022 | if (cst) {
| 23156-51025 | ||||||||||||
1023 | if (depth >= ASN1_MAX_STRING_NEST) {
| 542-22614 | ||||||||||||
1024 | ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING); | - | ||||||||||||
1025 | return 0; executed 542 times by 1 test: return 0; Executed by:
| 542 | ||||||||||||
1026 | } | - | ||||||||||||
1027 | if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1))
| 4940-17674 | ||||||||||||
1028 | return 0; executed 4940 times by 1 test: return 0; Executed by:
| 4940 | ||||||||||||
1029 | } else if (plen && !collect_data(buf, &p, plen)) executed 17674 times by 1 test: end of block Executed by:
| 0-43604 | ||||||||||||
1030 | return 0; never executed: return 0; | 0 | ||||||||||||
1031 | len -= p - q; | - | ||||||||||||
1032 | } executed 68699 times by 1 test: end of block Executed by:
| 68699 | ||||||||||||
1033 | if (inf) {
| 980-74643 | ||||||||||||
1034 | ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC); | - | ||||||||||||
1035 | return 0; executed 980 times by 1 test: return 0; Executed by:
| 980 | ||||||||||||
1036 | } | - | ||||||||||||
1037 | *in = p; | - | ||||||||||||
1038 | return 1; executed 74643 times by 1 test: return 1; Executed by:
| 74643 | ||||||||||||
1039 | } | - | ||||||||||||
1040 | - | |||||||||||||
1041 | static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen) | - | ||||||||||||
1042 | { | - | ||||||||||||
1043 | int len; | - | ||||||||||||
1044 | if (buf) {
| 0-43604 | ||||||||||||
1045 | len = buf->length; | - | ||||||||||||
1046 | if (!BUF_MEM_grow_clean(buf, len + plen)) {
| 0-43604 | ||||||||||||
1047 | ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE); | - | ||||||||||||
1048 | return 0; never executed: return 0; | 0 | ||||||||||||
1049 | } | - | ||||||||||||
1050 | memcpy(buf->data + len, *p, plen); | - | ||||||||||||
1051 | } executed 43604 times by 1 test: end of block Executed by:
| 43604 | ||||||||||||
1052 | *p += plen; | - | ||||||||||||
1053 | return 1; executed 43604 times by 1 test: return 1; Executed by:
| 43604 | ||||||||||||
1054 | } | - | ||||||||||||
1055 | - | |||||||||||||
1056 | /* Check for ASN1 EOC and swallow it if found */ | - | ||||||||||||
1057 | - | |||||||||||||
1058 | static int asn1_check_eoc(const unsigned char **in, long len) | - | ||||||||||||
1059 | { | - | ||||||||||||
1060 | const unsigned char *p; | - | ||||||||||||
1061 | if (len < 2)
| 7707-11998177 | ||||||||||||
1062 | return 0; executed 7707 times by 1 test: return 0; Executed by:
| 7707 | ||||||||||||
1063 | p = *in; | - | ||||||||||||
1064 | if (!p[0] && !p[1]) {
| 67847-9373083 | ||||||||||||
1065 | *in += 2; | - | ||||||||||||
1066 | return 1; executed 2557247 times by 1 test: return 1; Executed by:
| 2557247 | ||||||||||||
1067 | } | - | ||||||||||||
1068 | return 0; executed 9440930 times by 2 tests: return 0; Executed by:
| 9440930 | ||||||||||||
1069 | } | - | ||||||||||||
1070 | - | |||||||||||||
1071 | /* | - | ||||||||||||
1072 | * Check an ASN1 tag and length: a bit like ASN1_get_object but it sets the | - | ||||||||||||
1073 | * length for indefinite length constructed form, we don't know the exact | - | ||||||||||||
1074 | * length but we can set an upper bound to the amount of data available minus | - | ||||||||||||
1075 | * the header length just read. | - | ||||||||||||
1076 | */ | - | ||||||||||||
1077 | - | |||||||||||||
1078 | static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, | - | ||||||||||||
1079 | char *inf, char *cst, | - | ||||||||||||
1080 | const unsigned char **in, long len, | - | ||||||||||||
1081 | int exptag, int expclass, char opt, ASN1_TLC *ctx) | - | ||||||||||||
1082 | { | - | ||||||||||||
1083 | int i; | - | ||||||||||||
1084 | int ptag, pclass; | - | ||||||||||||
1085 | long plen; | - | ||||||||||||
1086 | const unsigned char *p, *q; | - | ||||||||||||
1087 | p = *in; | - | ||||||||||||
1088 | q = p; | - | ||||||||||||
1089 | - | |||||||||||||
1090 | if (ctx && ctx->valid) {
| 1454793-6014209 | ||||||||||||
1091 | i = ctx->ret; | - | ||||||||||||
1092 | plen = ctx->plen; | - | ||||||||||||
1093 | pclass = ctx->pclass; | - | ||||||||||||
1094 | ptag = ctx->ptag; | - | ||||||||||||
1095 | p += ctx->hdrlen; | - | ||||||||||||
1096 | } else { executed 1454793 times by 1 test: end of block Executed by:
| 1454793 | ||||||||||||
1097 | i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); | - | ||||||||||||
1098 | if (ctx) {
| 4559416-5526723 | ||||||||||||
1099 | ctx->ret = i; | - | ||||||||||||
1100 | ctx->plen = plen; | - | ||||||||||||
1101 | ctx->pclass = pclass; | - | ||||||||||||
1102 | ctx->ptag = ptag; | - | ||||||||||||
1103 | ctx->hdrlen = p - q; | - | ||||||||||||
1104 | ctx->valid = 1; | - | ||||||||||||
1105 | /* | - | ||||||||||||
1106 | * If definite length, and no error, length + header can't exceed | - | ||||||||||||
1107 | * total amount of data available. | - | ||||||||||||
1108 | */ | - | ||||||||||||
1109 | if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) {
| 0-3314160 | ||||||||||||
1110 | ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); | - | ||||||||||||
1111 | asn1_tlc_clear(ctx); never executed: (ctx)->valid = 0;
| 0 | ||||||||||||
1112 | return 0; never executed: return 0; | 0 | ||||||||||||
1113 | } | - | ||||||||||||
1114 | } executed 4559416 times by 2 tests: end of block Executed by:
| 4559416 | ||||||||||||
1115 | } executed 10086139 times by 2 tests: end of block Executed by:
| 10086139 | ||||||||||||
1116 | - | |||||||||||||
1117 | if (i & 0x80) {
| 37472-11503460 | ||||||||||||
1118 | ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER); | - | ||||||||||||
1119 | asn1_tlc_clear(ctx); executed 27600 times by 1 test: (ctx)->valid = 0; Executed by:
| 9872-27600 | ||||||||||||
1120 | return 0; executed 37472 times by 1 test: return 0; Executed by:
| 37472 | ||||||||||||
1121 | } | - | ||||||||||||
1122 | if (exptag >= 0) {
| 5394561-6108899 | ||||||||||||
1123 | if ((exptag != ptag) || (expclass != pclass)) {
| 16550-3995677 | ||||||||||||
1124 | /* | - | ||||||||||||
1125 | * If type is OPTIONAL, not an error: indicate missing type. | - | ||||||||||||
1126 | */ | - | ||||||||||||
1127 | if (opt)
| 465913-949521 | ||||||||||||
1128 | return -1; executed 949521 times by 1 test: return -1; Executed by:
| 949521 | ||||||||||||
1129 | asn1_tlc_clear(ctx); executed 465913 times by 1 test: (ctx)->valid = 0; Executed by:
| 0-465913 | ||||||||||||
1130 | ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG); | - | ||||||||||||
1131 | return 0; executed 465913 times by 1 test: return 0; Executed by:
| 465913 | ||||||||||||
1132 | } | - | ||||||||||||
1133 | /* | - | ||||||||||||
1134 | * We have a tag and class match: assume we are going to do something | - | ||||||||||||
1135 | * with it | - | ||||||||||||
1136 | */ | - | ||||||||||||
1137 | asn1_tlc_clear(ctx); executed 3979127 times by 2 tests: (ctx)->valid = 0; Executed by:
| 0-3979127 | ||||||||||||
1138 | } executed 3979127 times by 2 tests: end of block Executed by:
| 3979127 | ||||||||||||
1139 | - | |||||||||||||
1140 | if (i & 1)
| 3064256-7023770 | ||||||||||||
1141 | plen = len - (p - q); executed 3064256 times by 1 test: plen = len - (p - q); Executed by:
| 3064256 | ||||||||||||
1142 | - | |||||||||||||
1143 | if (inf)
| 561988-9526038 | ||||||||||||
1144 | *inf = i & 1; executed 9526038 times by 2 tests: *inf = i & 1; Executed by:
| 9526038 | ||||||||||||
1145 | - | |||||||||||||
1146 | if (cst)
| 3669007-6419019 | ||||||||||||
1147 | *cst = i & V_ASN1_CONSTRUCTED; executed 3669007 times by 2 tests: *cst = i & 0x20; Executed by:
| 3669007 | ||||||||||||
1148 | - | |||||||||||||
1149 | if (olen)
| 561988-9526038 | ||||||||||||
1150 | *olen = plen; executed 9526038 times by 2 tests: *olen = plen; Executed by:
| 9526038 | ||||||||||||
1151 | - | |||||||||||||
1152 | if (oclass)
| 561988-9526038 | ||||||||||||
1153 | *oclass = pclass; executed 561988 times by 1 test: *oclass = pclass; Executed by:
| 561988 | ||||||||||||
1154 | - | |||||||||||||
1155 | if (otag)
| 561988-9526038 | ||||||||||||
1156 | *otag = ptag; executed 561988 times by 1 test: *otag = ptag; Executed by:
| 561988 | ||||||||||||
1157 | - | |||||||||||||
1158 | *in = p; | - | ||||||||||||
1159 | return 1; executed 10088026 times by 2 tests: return 1; Executed by:
| 10088026 | ||||||||||||
1160 | } | - | ||||||||||||
Source code | Switch to Preprocessed file |