File: | src/lib/libcrypto/asn1/a_enum.c |
Warning: | line 336, column 16 The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: a_enum.c,v 1.29 2023/07/05 21:23:36 beck Exp $ */ | |||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | |||
3 | * All rights reserved. | |||
4 | * | |||
5 | * This package is an SSL implementation written | |||
6 | * by Eric Young (eay@cryptsoft.com). | |||
7 | * The implementation was written so as to conform with Netscapes SSL. | |||
8 | * | |||
9 | * This library is free for commercial and non-commercial use as long as | |||
10 | * the following conditions are aheared to. The following conditions | |||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | |||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | |||
13 | * included with this distribution is covered by the same copyright terms | |||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | |||
15 | * | |||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | |||
17 | * the code are not to be removed. | |||
18 | * If this package is used in a product, Eric Young should be given attribution | |||
19 | * as the author of the parts of the library used. | |||
20 | * This can be in the form of a textual message at program startup or | |||
21 | * in documentation (online or textual) provided with the package. | |||
22 | * | |||
23 | * Redistribution and use in source and binary forms, with or without | |||
24 | * modification, are permitted provided that the following conditions | |||
25 | * are met: | |||
26 | * 1. Redistributions of source code must retain the copyright | |||
27 | * notice, this list of conditions and the following disclaimer. | |||
28 | * 2. Redistributions in binary form must reproduce the above copyright | |||
29 | * notice, this list of conditions and the following disclaimer in the | |||
30 | * documentation and/or other materials provided with the distribution. | |||
31 | * 3. All advertising materials mentioning features or use of this software | |||
32 | * must display the following acknowledgement: | |||
33 | * "This product includes cryptographic software written by | |||
34 | * Eric Young (eay@cryptsoft.com)" | |||
35 | * The word 'cryptographic' can be left out if the rouines from the library | |||
36 | * being used are not cryptographic related :-). | |||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | |||
38 | * the apps directory (application code) you must include an acknowledgement: | |||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | |||
40 | * | |||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | |||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
51 | * SUCH DAMAGE. | |||
52 | * | |||
53 | * The licence and distribution terms for any publically available version or | |||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | |||
55 | * copied and put under another distribution licence | |||
56 | * [including the GNU Public Licence.] | |||
57 | */ | |||
58 | ||||
59 | #include <limits.h> | |||
60 | #include <string.h> | |||
61 | ||||
62 | #include <openssl/asn1.h> | |||
63 | #include <openssl/asn1t.h> | |||
64 | #include <openssl/bn.h> | |||
65 | #include <openssl/buffer.h> | |||
66 | #include <openssl/err.h> | |||
67 | ||||
68 | #include "asn1_local.h" | |||
69 | #include "bytestring.h" | |||
70 | ||||
71 | /* | |||
72 | * Code for ENUMERATED type: identical to INTEGER apart from a different tag. | |||
73 | * for comments on encoding see a_int.c | |||
74 | */ | |||
75 | ||||
76 | const ASN1_ITEM ASN1_ENUMERATED_it = { | |||
77 | .itype = ASN1_ITYPE_PRIMITIVE0x0, | |||
78 | .utype = V_ASN1_ENUMERATED10, | |||
79 | .sname = "ASN1_ENUMERATED", | |||
80 | }; | |||
81 | ||||
82 | ASN1_ENUMERATED * | |||
83 | ASN1_ENUMERATED_new(void) | |||
84 | { | |||
85 | return (ASN1_ENUMERATED *)ASN1_item_new(&ASN1_ENUMERATED_it); | |||
86 | } | |||
87 | LCRYPTO_ALIAS(ASN1_ENUMERATED_new)asm(""); | |||
88 | ||||
89 | static void | |||
90 | asn1_aenum_clear(ASN1_ENUMERATED *aenum) | |||
91 | { | |||
92 | freezero(aenum->data, aenum->length); | |||
93 | ||||
94 | memset(aenum, 0, sizeof(*aenum)); | |||
95 | ||||
96 | aenum->type = V_ASN1_ENUMERATED10; | |||
97 | } | |||
98 | ||||
99 | void | |||
100 | ASN1_ENUMERATED_free(ASN1_ENUMERATED *a) | |||
101 | { | |||
102 | ASN1_item_free((ASN1_VALUE *)a, &ASN1_ENUMERATED_it); | |||
103 | } | |||
104 | LCRYPTO_ALIAS(ASN1_ENUMERATED_free)asm(""); | |||
105 | ||||
106 | int | |||
107 | ASN1_ENUMERATED_get_int64(int64_t *out_val, const ASN1_ENUMERATED *aenum) | |||
108 | { | |||
109 | CBS cbs; | |||
110 | ||||
111 | *out_val = 0; | |||
112 | ||||
113 | if (aenum == NULL((void *)0) || aenum->length < 0) | |||
114 | return 0; | |||
115 | ||||
116 | if (aenum->type != V_ASN1_ENUMERATED10 && | |||
117 | aenum->type != V_ASN1_NEG_ENUMERATED(10 | 0x100)) { | |||
118 | ASN1error(ASN1_R_WRONG_INTEGER_TYPE)ERR_put_error(13,(0xfff),(225),"/usr/src/lib/libcrypto/asn1/a_enum.c" ,118); | |||
119 | return 0; | |||
120 | } | |||
121 | ||||
122 | CBS_init(&cbs, aenum->data, aenum->length); | |||
123 | ||||
124 | return asn1_aint_get_int64(&cbs, (aenum->type == V_ASN1_NEG_ENUMERATED(10 | 0x100)), | |||
125 | out_val); | |||
126 | } | |||
127 | LCRYPTO_ALIAS(ASN1_ENUMERATED_get_int64)asm(""); | |||
128 | ||||
129 | int | |||
130 | ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *aenum, int64_t val) | |||
131 | { | |||
132 | uint64_t uval; | |||
133 | ||||
134 | asn1_aenum_clear(aenum); | |||
135 | ||||
136 | uval = (uint64_t)val; | |||
137 | ||||
138 | if (val < 0) { | |||
139 | aenum->type = V_ASN1_NEG_ENUMERATED(10 | 0x100); | |||
140 | uval = -uval; | |||
141 | } | |||
142 | ||||
143 | return asn1_aint_set_uint64(uval, &aenum->data, &aenum->length); | |||
144 | } | |||
145 | LCRYPTO_ALIAS(ASN1_ENUMERATED_set_int64)asm(""); | |||
146 | ||||
147 | long | |||
148 | ASN1_ENUMERATED_get(const ASN1_ENUMERATED *aenum) | |||
149 | { | |||
150 | int64_t val; | |||
151 | ||||
152 | if (aenum == NULL((void *)0)) | |||
153 | return 0; | |||
154 | if (!ASN1_ENUMERATED_get_int64(&val, aenum)) | |||
155 | return -1; | |||
156 | if (val < LONG_MIN(-0x7fffffffffffffffL-1) || val > LONG_MAX0x7fffffffffffffffL) { | |||
157 | /* hmm... a bit ugly, return all ones */ | |||
158 | return -1; | |||
159 | } | |||
160 | ||||
161 | return (long)val; | |||
162 | } | |||
163 | LCRYPTO_ALIAS(ASN1_ENUMERATED_get)asm(""); | |||
164 | ||||
165 | int | |||
166 | ASN1_ENUMERATED_set(ASN1_ENUMERATED *aenum, long val) | |||
167 | { | |||
168 | return ASN1_ENUMERATED_set_int64(aenum, val); | |||
169 | } | |||
170 | LCRYPTO_ALIAS(ASN1_ENUMERATED_set)asm(""); | |||
171 | ||||
172 | ASN1_ENUMERATED * | |||
173 | BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai) | |||
174 | { | |||
175 | ASN1_ENUMERATED *ret; | |||
176 | int len, j; | |||
177 | ||||
178 | if (ai == NULL((void *)0)) | |||
179 | ret = ASN1_ENUMERATED_new(); | |||
180 | else | |||
181 | ret = ai; | |||
182 | if (ret == NULL((void *)0)) { | |||
183 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/a_enum.c" ,183); | |||
184 | goto err; | |||
185 | } | |||
186 | if (BN_is_negative(bn)) | |||
187 | ret->type = V_ASN1_NEG_ENUMERATED(10 | 0x100); | |||
188 | else | |||
189 | ret->type = V_ASN1_ENUMERATED10; | |||
190 | j = BN_num_bits(bn); | |||
191 | len = ((j == 0) ? 0 : ((j / 8) + 1)); | |||
192 | if (ret->length < len + 4) { | |||
193 | unsigned char *new_data = realloc(ret->data, len + 4); | |||
194 | if (!new_data) { | |||
195 | ASN1error(ERR_R_MALLOC_FAILURE)ERR_put_error(13,(0xfff),((1|64)),"/usr/src/lib/libcrypto/asn1/a_enum.c" ,195); | |||
196 | goto err; | |||
197 | } | |||
198 | ret->data = new_data; | |||
199 | } | |||
200 | ret->length = BN_bn2bin(bn, ret->data); | |||
201 | ||||
202 | /* Correct zero case */ | |||
203 | if (!ret->length) { | |||
204 | ret->data[0] = 0; | |||
205 | ret->length = 1; | |||
206 | } | |||
207 | return (ret); | |||
208 | ||||
209 | err: | |||
210 | if (ret != ai) | |||
211 | ASN1_ENUMERATED_free(ret); | |||
212 | return (NULL((void *)0)); | |||
213 | } | |||
214 | LCRYPTO_ALIAS(BN_to_ASN1_ENUMERATED)asm(""); | |||
215 | ||||
216 | BIGNUM * | |||
217 | ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn) | |||
218 | { | |||
219 | BIGNUM *ret; | |||
220 | ||||
221 | if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL((void *)0)) | |||
222 | ASN1error(ASN1_R_BN_LIB)ERR_put_error(13,(0xfff),(105),"/usr/src/lib/libcrypto/asn1/a_enum.c" ,222); | |||
223 | else if (ai->type == V_ASN1_NEG_ENUMERATED(10 | 0x100)) | |||
224 | BN_set_negative(ret, 1); | |||
225 | return (ret); | |||
226 | } | |||
227 | LCRYPTO_ALIAS(ASN1_ENUMERATED_to_BN)asm(""); | |||
228 | ||||
229 | /* Based on a_int.c: equivalent ENUMERATED functions */ | |||
230 | ||||
231 | int | |||
232 | i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a) | |||
233 | { | |||
234 | int i, n = 0; | |||
235 | static const char h[] = "0123456789ABCDEF"; | |||
236 | char buf[2]; | |||
237 | ||||
238 | if (a == NULL((void *)0)) | |||
239 | return (0); | |||
240 | ||||
241 | if (a->length == 0) { | |||
242 | if (BIO_write(bp, "00", 2) != 2) | |||
243 | goto err; | |||
244 | n = 2; | |||
245 | } else { | |||
246 | for (i = 0; i < a->length; i++) { | |||
247 | if ((i != 0) && (i % 35 == 0)) { | |||
248 | if (BIO_write(bp, "\\\n", 2) != 2) | |||
249 | goto err; | |||
250 | n += 2; | |||
251 | } | |||
252 | buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; | |||
253 | buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; | |||
254 | if (BIO_write(bp, buf, 2) != 2) | |||
255 | goto err; | |||
256 | n += 2; | |||
257 | } | |||
258 | } | |||
259 | return (n); | |||
260 | ||||
261 | err: | |||
262 | return (-1); | |||
263 | } | |||
264 | LCRYPTO_ALIAS(i2a_ASN1_ENUMERATED)asm(""); | |||
265 | ||||
266 | int | |||
267 | a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size) | |||
268 | { | |||
269 | int ret = 0; | |||
270 | int i, j,k, m,n, again, bufsize; | |||
271 | unsigned char *s = NULL((void *)0), *sp; | |||
272 | unsigned char *bufp; | |||
273 | int first = 1; | |||
274 | size_t num = 0, slen = 0; | |||
275 | ||||
276 | bs->type = V_ASN1_ENUMERATED10; | |||
277 | ||||
278 | bufsize = BIO_gets(bp, buf, size); | |||
279 | for (;;) { | |||
| ||||
280 | if (bufsize < 1) | |||
281 | goto err_sl; | |||
282 | i = bufsize; | |||
283 | if (buf[i-1] == '\n') | |||
284 | buf[--i] = '\0'; | |||
285 | if (i
| |||
286 | goto err_sl; | |||
287 | if (buf[i-1] == '\r') | |||
288 | buf[--i] = '\0'; | |||
289 | if (i
| |||
290 | goto err_sl; | |||
291 | if (buf[i - 1] == '\\') { | |||
292 | i--; | |||
293 | again = 1; | |||
294 | } else | |||
295 | again = 0; | |||
296 | buf[i] = '\0'; | |||
297 | if (i < 2) | |||
298 | goto err_sl; | |||
299 | ||||
300 | bufp = (unsigned char *)buf; | |||
301 | if (first
| |||
302 | first = 0; | |||
303 | if ((bufp[0] == '0') && (buf[1] == '0')) { | |||
304 | bufp += 2; | |||
305 | i -= 2; | |||
306 | } | |||
307 | } | |||
308 | k = 0; | |||
309 | if (i % 2 != 0) { | |||
310 | ASN1error(ASN1_R_ODD_NUMBER_OF_CHARS)ERR_put_error(13,(0xfff),(145),"/usr/src/lib/libcrypto/asn1/a_enum.c" ,310); | |||
311 | goto err; | |||
312 | } | |||
313 | i /= 2; | |||
314 | if (num + i > slen) { | |||
315 | sp = realloc(s, num + i); | |||
316 | if (sp == NULL((void *)0)) { | |||
317 | ASN1error(ERR_R_MALLOC_FAILURE)ERR_put_error(13,(0xfff),((1|64)),"/usr/src/lib/libcrypto/asn1/a_enum.c" ,317); | |||
318 | goto err; | |||
319 | } | |||
320 | s = sp; | |||
321 | slen = num + i; | |||
322 | } | |||
323 | for (j = 0; j
| |||
324 | for (n = 0; n < 2; n++) { | |||
325 | m = bufp[k + n]; | |||
326 | if ((m >= '0') && (m <= '9')) | |||
327 | m -= '0'; | |||
328 | else if ((m >= 'a') && (m <= 'f')) | |||
329 | m = m - 'a' + 10; | |||
330 | else if ((m >= 'A') && (m <= 'F')) | |||
331 | m = m - 'A' + 10; | |||
332 | else { | |||
333 | ASN1error(ASN1_R_NON_HEX_CHARACTERS)ERR_put_error(13,(0xfff),(141),"/usr/src/lib/libcrypto/asn1/a_enum.c" ,333); | |||
334 | goto err; | |||
335 | } | |||
336 | s[num + j] <<= 4; | |||
| ||||
337 | s[num + j] |= m; | |||
338 | } | |||
339 | } | |||
340 | num += i; | |||
341 | if (again) | |||
342 | bufsize = BIO_gets(bp, buf, size); | |||
343 | else | |||
344 | break; | |||
345 | } | |||
346 | bs->length = num; | |||
347 | bs->data = s; | |||
348 | return (1); | |||
349 | ||||
350 | err_sl: | |||
351 | ASN1error(ASN1_R_SHORT_LINE)ERR_put_error(13,(0xfff),(150),"/usr/src/lib/libcrypto/asn1/a_enum.c" ,351); | |||
352 | err: | |||
353 | free(s); | |||
354 | return (ret); | |||
355 | } | |||
356 | LCRYPTO_ALIAS(a2i_ASN1_ENUMERATED)asm(""); | |||
357 | ||||
358 | int | |||
359 | c2i_ASN1_ENUMERATED_cbs(ASN1_ENUMERATED **out_aenum, CBS *cbs) | |||
360 | { | |||
361 | ASN1_ENUMERATED *aenum = NULL((void *)0); | |||
362 | ||||
363 | if (out_aenum == NULL((void *)0)) | |||
364 | return 0; | |||
365 | ||||
366 | if (*out_aenum != NULL((void *)0)) { | |||
367 | ASN1_INTEGER_free(*out_aenum); | |||
368 | *out_aenum = NULL((void *)0); | |||
369 | } | |||
370 | ||||
371 | if (!c2i_ASN1_INTEGER_cbs((ASN1_INTEGER **)&aenum, cbs)) | |||
372 | return 0; | |||
373 | ||||
374 | aenum->type = V_ASN1_ENUMERATED10 | (aenum->type & V_ASN1_NEG0x100); | |||
375 | *out_aenum = aenum; | |||
376 | ||||
377 | return 1; | |||
378 | } | |||
379 | ||||
380 | int | |||
381 | i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a, unsigned char **out) | |||
382 | { | |||
383 | return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_ENUMERATED_it); | |||
384 | } | |||
385 | LCRYPTO_ALIAS(i2d_ASN1_ENUMERATED)asm(""); | |||
386 | ||||
387 | ASN1_ENUMERATED * | |||
388 | d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a, const unsigned char **in, long len) | |||
389 | { | |||
390 | return (ASN1_ENUMERATED *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, | |||
391 | &ASN1_ENUMERATED_it); | |||
392 | } | |||
393 | LCRYPTO_ALIAS(d2i_ASN1_ENUMERATED)asm(""); |