1 /* Copyright (C) 1995-1998 Eric Young ([email protected])
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young ([email protected]).
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 ([email protected]).
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 ([email protected])"
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 ([email protected])"
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
59 #include <assert.h>
60 #include <limits.h>
61 #include <string.h>
62
63 #include <openssl/bytestring.h>
64 #include <openssl/err.h>
65 #include <openssl/mem.h>
66
67 #include "../internal.h"
68
69
ASN1_INTEGER_dup(const ASN1_INTEGER * x)70 ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x) {
71 return ASN1_STRING_dup(x);
72 }
73
ASN1_INTEGER_cmp(const ASN1_INTEGER * x,const ASN1_INTEGER * y)74 int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) {
75 // Compare signs.
76 int neg = x->type & V_ASN1_NEG;
77 if (neg != (y->type & V_ASN1_NEG)) {
78 return neg ? -1 : 1;
79 }
80
81 int ret = ASN1_STRING_cmp(x, y);
82 if (neg) {
83 // This could be |-ret|, but |ASN1_STRING_cmp| is not forbidden from
84 // returning |INT_MIN|.
85 if (ret < 0) {
86 return 1;
87 } else if (ret > 0) {
88 return -1;
89 } else {
90 return 0;
91 }
92 }
93
94 return ret;
95 }
96
97 // negate_twos_complement negates |len| bytes from |buf| in-place, interpreted
98 // as a signed, big-endian two's complement value.
negate_twos_complement(uint8_t * buf,size_t len)99 static void negate_twos_complement(uint8_t *buf, size_t len) {
100 uint8_t borrow = 0;
101 for (size_t i = len - 1; i < len; i--) {
102 uint8_t t = buf[i];
103 buf[i] = 0u - borrow - t;
104 borrow |= t != 0;
105 }
106 }
107
is_all_zeros(const uint8_t * in,size_t len)108 static int is_all_zeros(const uint8_t *in, size_t len) {
109 for (size_t i = 0; i < len; i++) {
110 if (in[i] != 0) {
111 return 0;
112 }
113 }
114 return 1;
115 }
116
i2c_ASN1_INTEGER(const ASN1_INTEGER * in,unsigned char ** outp)117 int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) {
118 if (in == NULL) {
119 return 0;
120 }
121
122 // |ASN1_INTEGER|s should be represented minimally, but it is possible to
123 // construct invalid ones. Skip leading zeros so this does not produce an
124 // invalid encoding or break invariants.
125 CBS cbs;
126 CBS_init(&cbs, in->data, in->length);
127 while (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0) {
128 CBS_skip(&cbs, 1);
129 }
130
131 int is_negative = (in->type & V_ASN1_NEG) != 0;
132 size_t pad;
133 CBS copy = cbs;
134 uint8_t msb;
135 if (!CBS_get_u8(©, &msb)) {
136 // Zero is represented as a single byte.
137 is_negative = 0;
138 pad = 1;
139 } else if (is_negative) {
140 // 0x80...01 through 0xff...ff have a two's complement of 0x7f...ff
141 // through 0x00...01 and need an extra byte to be negative.
142 // 0x01...00 through 0x80...00 have a two's complement of 0xfe...ff
143 // through 0x80...00 and can be negated as-is.
144 pad = msb > 0x80 ||
145 (msb == 0x80 && !is_all_zeros(CBS_data(©), CBS_len(©)));
146 } else {
147 // If the high bit is set, the signed representation needs an extra
148 // byte to be positive.
149 pad = (msb & 0x80) != 0;
150 }
151
152 if (CBS_len(&cbs) > INT_MAX - pad) {
153 OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW);
154 return 0;
155 }
156 int len = (int)(pad + CBS_len(&cbs));
157 assert(len > 0);
158 if (outp == NULL) {
159 return len;
160 }
161
162 if (pad) {
163 (*outp)[0] = 0;
164 }
165 OPENSSL_memcpy(*outp + pad, CBS_data(&cbs), CBS_len(&cbs));
166 if (is_negative) {
167 negate_twos_complement(*outp, len);
168 assert((*outp)[0] >= 0x80);
169 } else {
170 assert((*outp)[0] < 0x80);
171 }
172 *outp += len;
173 return len;
174 }
175
c2i_ASN1_INTEGER(ASN1_INTEGER ** out,const unsigned char ** inp,long len)176 ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp,
177 long len) {
178 // This function can handle lengths up to INT_MAX - 1, but the rest of the
179 // legacy ASN.1 code mixes integer types, so avoid exposing it to
180 // ASN1_INTEGERS with larger lengths.
181 if (len < 0 || len > INT_MAX / 2) {
182 OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
183 return NULL;
184 }
185
186 CBS cbs;
187 CBS_init(&cbs, *inp, (size_t)len);
188 int is_negative;
189 if (!CBS_is_valid_asn1_integer(&cbs, &is_negative)) {
190 OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
191 return NULL;
192 }
193
194 ASN1_INTEGER *ret = NULL;
195 if (out == NULL || *out == NULL) {
196 ret = ASN1_INTEGER_new();
197 if (ret == NULL) {
198 return NULL;
199 }
200 } else {
201 ret = *out;
202 }
203
204 // Convert to |ASN1_INTEGER|'s sign-and-magnitude representation. First,
205 // determine the size needed for a minimal result.
206 if (is_negative) {
207 // 0xff00...01 through 0xff7f..ff have a two's complement of 0x00ff...ff
208 // through 0x000100...001 and need one leading zero removed. 0x8000...00
209 // through 0xff00...00 have a two's complement of 0x8000...00 through
210 // 0x0100...00 and will be minimally-encoded as-is.
211 if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0xff &&
212 !is_all_zeros(CBS_data(&cbs) + 1, CBS_len(&cbs) - 1)) {
213 CBS_skip(&cbs, 1);
214 }
215 } else {
216 // Remove the leading zero byte, if any.
217 if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0x00) {
218 CBS_skip(&cbs, 1);
219 }
220 }
221
222 if (!ASN1_STRING_set(ret, CBS_data(&cbs), CBS_len(&cbs))) {
223 goto err;
224 }
225
226 if (is_negative) {
227 ret->type = V_ASN1_NEG_INTEGER;
228 negate_twos_complement(ret->data, ret->length);
229 } else {
230 ret->type = V_ASN1_INTEGER;
231 }
232
233 // The value should be minimally-encoded.
234 assert(ret->length == 0 || ret->data[0] != 0);
235 // Zero is not negative.
236 assert(!is_negative || ret->length > 0);
237
238 *inp += len;
239 if (out != NULL) {
240 *out = ret;
241 }
242 return ret;
243
244 err:
245 if (ret != NULL && (out == NULL || *out != ret)) {
246 ASN1_INTEGER_free(ret);
247 }
248 return NULL;
249 }
250
ASN1_INTEGER_set_int64(ASN1_INTEGER * a,int64_t v)251 int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t v) {
252 if (v >= 0) {
253 return ASN1_INTEGER_set_uint64(a, (uint64_t)v);
254 }
255
256 if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t)v)) {
257 return 0;
258 }
259
260 a->type = V_ASN1_NEG_INTEGER;
261 return 1;
262 }
263
ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED * a,int64_t v)264 int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t v) {
265 if (v >= 0) {
266 return ASN1_ENUMERATED_set_uint64(a, (uint64_t)v);
267 }
268
269 if (!ASN1_ENUMERATED_set_uint64(a, 0 - (uint64_t)v)) {
270 return 0;
271 }
272
273 a->type = V_ASN1_NEG_ENUMERATED;
274 return 1;
275 }
276
ASN1_INTEGER_set(ASN1_INTEGER * a,long v)277 int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) {
278 static_assert(sizeof(long) <= sizeof(int64_t), "long fits in int64_t");
279 return ASN1_INTEGER_set_int64(a, v);
280 }
281
ASN1_ENUMERATED_set(ASN1_ENUMERATED * a,long v)282 int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) {
283 static_assert(sizeof(long) <= sizeof(int64_t), "long fits in int64_t");
284 return ASN1_ENUMERATED_set_int64(a, v);
285 }
286
asn1_string_set_uint64(ASN1_STRING * out,uint64_t v,int type)287 static int asn1_string_set_uint64(ASN1_STRING *out, uint64_t v, int type) {
288 uint8_t buf[sizeof(uint64_t)];
289 CRYPTO_store_u64_be(buf, v);
290 size_t leading_zeros;
291 for (leading_zeros = 0; leading_zeros < sizeof(buf); leading_zeros++) {
292 if (buf[leading_zeros] != 0) {
293 break;
294 }
295 }
296
297 if (!ASN1_STRING_set(out, buf + leading_zeros, sizeof(buf) - leading_zeros)) {
298 return 0;
299 }
300 out->type = type;
301 return 1;
302 }
303
ASN1_INTEGER_set_uint64(ASN1_INTEGER * out,uint64_t v)304 int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v) {
305 return asn1_string_set_uint64(out, v, V_ASN1_INTEGER);
306 }
307
ASN1_ENUMERATED_set_uint64(ASN1_ENUMERATED * out,uint64_t v)308 int ASN1_ENUMERATED_set_uint64(ASN1_ENUMERATED *out, uint64_t v) {
309 return asn1_string_set_uint64(out, v, V_ASN1_ENUMERATED);
310 }
311
asn1_string_get_abs_uint64(uint64_t * out,const ASN1_STRING * a,int type)312 static int asn1_string_get_abs_uint64(uint64_t *out, const ASN1_STRING *a,
313 int type) {
314 if ((a->type & ~V_ASN1_NEG) != type) {
315 OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE);
316 return 0;
317 }
318 uint8_t buf[sizeof(uint64_t)] = {0};
319 if (a->length > (int)sizeof(buf)) {
320 OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
321 return 0;
322 }
323 OPENSSL_memcpy(buf + sizeof(buf) - a->length, a->data, a->length);
324 *out = CRYPTO_load_u64_be(buf);
325 return 1;
326 }
327
asn1_string_get_uint64(uint64_t * out,const ASN1_STRING * a,int type)328 static int asn1_string_get_uint64(uint64_t *out, const ASN1_STRING *a,
329 int type) {
330 if (!asn1_string_get_abs_uint64(out, a, type)) {
331 return 0;
332 }
333 if (a->type & V_ASN1_NEG) {
334 OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
335 return 0;
336 }
337 return 1;
338 }
339
ASN1_INTEGER_get_uint64(uint64_t * out,const ASN1_INTEGER * a)340 int ASN1_INTEGER_get_uint64(uint64_t *out, const ASN1_INTEGER *a) {
341 return asn1_string_get_uint64(out, a, V_ASN1_INTEGER);
342 }
343
ASN1_ENUMERATED_get_uint64(uint64_t * out,const ASN1_ENUMERATED * a)344 int ASN1_ENUMERATED_get_uint64(uint64_t *out, const ASN1_ENUMERATED *a) {
345 return asn1_string_get_uint64(out, a, V_ASN1_ENUMERATED);
346 }
347
asn1_string_get_int64(int64_t * out,const ASN1_STRING * a,int type)348 static int asn1_string_get_int64(int64_t *out, const ASN1_STRING *a, int type) {
349 uint64_t v;
350 if (!asn1_string_get_abs_uint64(&v, a, type)) {
351 return 0;
352 }
353 int64_t i64;
354 int fits_in_i64;
355 // Check |v != 0| to handle manually-constructed negative zeros.
356 if ((a->type & V_ASN1_NEG) && v != 0) {
357 i64 = (int64_t)(0u - v);
358 fits_in_i64 = i64 < 0;
359 } else {
360 i64 = (int64_t)v;
361 fits_in_i64 = i64 >= 0;
362 }
363 if (!fits_in_i64) {
364 OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
365 return 0;
366 }
367 *out = i64;
368 return 1;
369 }
370
ASN1_INTEGER_get_int64(int64_t * out,const ASN1_INTEGER * a)371 int ASN1_INTEGER_get_int64(int64_t *out, const ASN1_INTEGER *a) {
372 return asn1_string_get_int64(out, a, V_ASN1_INTEGER);
373 }
374
ASN1_ENUMERATED_get_int64(int64_t * out,const ASN1_ENUMERATED * a)375 int ASN1_ENUMERATED_get_int64(int64_t *out, const ASN1_ENUMERATED *a) {
376 return asn1_string_get_int64(out, a, V_ASN1_ENUMERATED);
377 }
378
asn1_string_get_long(const ASN1_STRING * a,int type)379 static long asn1_string_get_long(const ASN1_STRING *a, int type) {
380 if (a == NULL) {
381 return 0;
382 }
383
384 int64_t v;
385 if (!asn1_string_get_int64(&v, a, type) || //
386 v < LONG_MIN || v > LONG_MAX) {
387 // This function's return value does not distinguish overflow from -1.
388 ERR_clear_error();
389 return -1;
390 }
391
392 return (long)v;
393 }
394
ASN1_INTEGER_get(const ASN1_INTEGER * a)395 long ASN1_INTEGER_get(const ASN1_INTEGER *a) {
396 return asn1_string_get_long(a, V_ASN1_INTEGER);
397 }
398
ASN1_ENUMERATED_get(const ASN1_ENUMERATED * a)399 long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a) {
400 return asn1_string_get_long(a, V_ASN1_ENUMERATED);
401 }
402
bn_to_asn1_string(const BIGNUM * bn,ASN1_STRING * ai,int type)403 static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai,
404 int type) {
405 ASN1_INTEGER *ret;
406 if (ai == NULL) {
407 ret = ASN1_STRING_type_new(type);
408 } else {
409 ret = ai;
410 }
411 if (ret == NULL) {
412 OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
413 goto err;
414 }
415
416 if (BN_is_negative(bn) && !BN_is_zero(bn)) {
417 ret->type = type | V_ASN1_NEG;
418 } else {
419 ret->type = type;
420 }
421
422 int len = BN_num_bytes(bn);
423 if (!ASN1_STRING_set(ret, NULL, len) ||
424 !BN_bn2bin_padded(ret->data, len, bn)) {
425 goto err;
426 }
427 return ret;
428
429 err:
430 if (ret != ai) {
431 ASN1_STRING_free(ret);
432 }
433 return NULL;
434 }
435
BN_to_ASN1_INTEGER(const BIGNUM * bn,ASN1_INTEGER * ai)436 ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) {
437 return bn_to_asn1_string(bn, ai, V_ASN1_INTEGER);
438 }
439
BN_to_ASN1_ENUMERATED(const BIGNUM * bn,ASN1_ENUMERATED * ai)440 ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai) {
441 return bn_to_asn1_string(bn, ai, V_ASN1_ENUMERATED);
442 }
443
asn1_string_to_bn(const ASN1_STRING * ai,BIGNUM * bn,int type)444 static BIGNUM *asn1_string_to_bn(const ASN1_STRING *ai, BIGNUM *bn, int type) {
445 if ((ai->type & ~V_ASN1_NEG) != type) {
446 OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE);
447 return NULL;
448 }
449
450 BIGNUM *ret;
451 if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) {
452 OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
453 } else if (ai->type & V_ASN1_NEG) {
454 BN_set_negative(ret, 1);
455 }
456 return ret;
457 }
458
ASN1_INTEGER_to_BN(const ASN1_INTEGER * ai,BIGNUM * bn)459 BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) {
460 return asn1_string_to_bn(ai, bn, V_ASN1_INTEGER);
461 }
462
ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED * ai,BIGNUM * bn)463 BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn) {
464 return asn1_string_to_bn(ai, bn, V_ASN1_ENUMERATED);
465 }
466