Coverage Report

Created: 2024-11-21 07:03

/src/boringssl/crypto/asn1/a_int.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2
 * All rights reserved.
3
 *
4
 * This package is an SSL implementation written
5
 * by Eric Young (eay@cryptsoft.com).
6
 * The implementation was written so as to conform with Netscapes SSL.
7
 *
8
 * This library is free for commercial and non-commercial use as long as
9
 * the following conditions are aheared to.  The following conditions
10
 * apply to all code found in this distribution, be it the RC4, RSA,
11
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12
 * included with this distribution is covered by the same copyright terms
13
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14
 *
15
 * Copyright remains Eric Young's, and as such any Copyright notices in
16
 * the code are not to be removed.
17
 * If this package is used in a product, Eric Young should be given attribution
18
 * as the author of the parts of the library used.
19
 * This can be in the form of a textual message at program startup or
20
 * in documentation (online or textual) provided with the package.
21
 *
22
 * Redistribution and use in source and binary forms, with or without
23
 * modification, are permitted provided that the following conditions
24
 * are met:
25
 * 1. Redistributions of source code must retain the copyright
26
 *    notice, this list of conditions and the following disclaimer.
27
 * 2. Redistributions in binary form must reproduce the above copyright
28
 *    notice, this list of conditions and the following disclaimer in the
29
 *    documentation and/or other materials provided with the distribution.
30
 * 3. All advertising materials mentioning features or use of this software
31
 *    must display the following acknowledgement:
32
 *    "This product includes cryptographic software written by
33
 *     Eric Young (eay@cryptsoft.com)"
34
 *    The word 'cryptographic' can be left out if the rouines from the library
35
 *    being used are not cryptographic related :-).
36
 * 4. If you include any Windows specific code (or a derivative thereof) from
37
 *    the apps directory (application code) you must include an acknowledgement:
38
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39
 *
40
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50
 * SUCH DAMAGE.
51
 *
52
 * The licence and distribution terms for any publically available version or
53
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
54
 * copied and put under another distribution licence
55
 * [including the GNU Public Licence.] */
56
57
#include <openssl/asn1.h>
58
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
70
0
ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x) {
71
0
  return ASN1_STRING_dup(x);
72
0
}
73
74
0
int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) {
75
  // Compare signs.
76
0
  int neg = x->type & V_ASN1_NEG;
77
0
  if (neg != (y->type & V_ASN1_NEG)) {
78
0
    return neg ? -1 : 1;
79
0
  }
80
81
0
  int ret = ASN1_STRING_cmp(x, y);
82
0
  if (neg) {
83
    // This could be |-ret|, but |ASN1_STRING_cmp| is not forbidden from
84
    // returning |INT_MIN|.
85
0
    if (ret < 0) {
86
0
      return 1;
87
0
    } else if (ret > 0) {
88
0
      return -1;
89
0
    } else {
90
0
      return 0;
91
0
    }
92
0
  }
93
94
0
  return ret;
95
0
}
96
97
// negate_twos_complement negates |len| bytes from |buf| in-place, interpreted
98
// as a signed, big-endian two's complement value.
99
0
static void negate_twos_complement(uint8_t *buf, size_t len) {
100
0
  uint8_t borrow = 0;
101
0
  for (size_t i = len - 1; i < len; i--) {
102
0
    uint8_t t = buf[i];
103
0
    buf[i] = 0u - borrow - t;
104
0
    borrow |= t != 0;
105
0
  }
106
0
}
107
108
0
static int is_all_zeros(const uint8_t *in, size_t len) {
109
0
  for (size_t i = 0; i < len; i++) {
110
0
    if (in[i] != 0) {
111
0
      return 0;
112
0
    }
113
0
  }
114
0
  return 1;
115
0
}
116
117
0
int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) {
118
0
  if (in == NULL) {
119
0
    return 0;
120
0
  }
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
0
  CBS cbs;
126
0
  CBS_init(&cbs, in->data, in->length);
127
0
  while (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0) {
128
0
    CBS_skip(&cbs, 1);
129
0
  }
130
131
0
  int is_negative = (in->type & V_ASN1_NEG) != 0;
132
0
  size_t pad;
133
0
  CBS copy = cbs;
134
0
  uint8_t msb;
135
0
  if (!CBS_get_u8(&copy, &msb)) {
136
    // Zero is represented as a single byte.
137
0
    is_negative = 0;
138
0
    pad = 1;
139
0
  } 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
0
    pad = msb > 0x80 ||
145
0
          (msb == 0x80 && !is_all_zeros(CBS_data(&copy), CBS_len(&copy)));
146
0
  } else {
147
    // If the high bit is set, the signed representation needs an extra
148
    // byte to be positive.
149
0
    pad = (msb & 0x80) != 0;
150
0
  }
151
152
0
  if (CBS_len(&cbs) > INT_MAX - pad) {
153
0
    OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW);
154
0
    return 0;
155
0
  }
156
0
  int len = (int)(pad + CBS_len(&cbs));
157
0
  assert(len > 0);
158
0
  if (outp == NULL) {
159
0
    return len;
160
0
  }
161
162
0
  if (pad) {
163
0
    (*outp)[0] = 0;
164
0
  }
165
0
  OPENSSL_memcpy(*outp + pad, CBS_data(&cbs), CBS_len(&cbs));
166
0
  if (is_negative) {
167
0
    negate_twos_complement(*outp, len);
168
0
    assert((*outp)[0] >= 0x80);
169
0
  } else {
170
0
    assert((*outp)[0] < 0x80);
171
0
  }
172
0
  *outp += len;
173
0
  return len;
174
0
}
175
176
ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp,
177
0
                               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
0
  if (len < 0 || len > INT_MAX / 2) {
182
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
183
0
    return NULL;
184
0
  }
185
186
0
  CBS cbs;
187
0
  CBS_init(&cbs, *inp, (size_t)len);
188
0
  int is_negative;
189
0
  if (!CBS_is_valid_asn1_integer(&cbs, &is_negative)) {
190
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
191
0
    return NULL;
192
0
  }
193
194
0
  ASN1_INTEGER *ret = NULL;
195
0
  if (out == NULL || *out == NULL) {
196
0
    ret = ASN1_INTEGER_new();
197
0
    if (ret == NULL) {
198
0
      return NULL;
199
0
    }
200
0
  } else {
201
0
    ret = *out;
202
0
  }
203
204
  // Convert to |ASN1_INTEGER|'s sign-and-magnitude representation. First,
205
  // determine the size needed for a minimal result.
206
0
  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
0
    if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0xff &&
212
0
        !is_all_zeros(CBS_data(&cbs) + 1, CBS_len(&cbs) - 1)) {
213
0
      CBS_skip(&cbs, 1);
214
0
    }
215
0
  } else {
216
    // Remove the leading zero byte, if any.
217
0
    if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0x00) {
218
0
      CBS_skip(&cbs, 1);
219
0
    }
220
0
  }
221
222
0
  if (!ASN1_STRING_set(ret, CBS_data(&cbs), CBS_len(&cbs))) {
223
0
    goto err;
224
0
  }
225
226
0
  if (is_negative) {
227
0
    ret->type = V_ASN1_NEG_INTEGER;
228
0
    negate_twos_complement(ret->data, ret->length);
229
0
  } else {
230
0
    ret->type = V_ASN1_INTEGER;
231
0
  }
232
233
  // The value should be minimally-encoded.
234
0
  assert(ret->length == 0 || ret->data[0] != 0);
235
  // Zero is not negative.
236
0
  assert(!is_negative || ret->length > 0);
237
238
0
  *inp += len;
239
0
  if (out != NULL) {
240
0
    *out = ret;
241
0
  }
242
0
  return ret;
243
244
0
err:
245
0
  if (ret != NULL && (out == NULL || *out != ret)) {
246
0
    ASN1_INTEGER_free(ret);
247
0
  }
248
0
  return NULL;
249
0
}
250
251
0
int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t v) {
252
0
  if (v >= 0) {
253
0
    return ASN1_INTEGER_set_uint64(a, (uint64_t)v);
254
0
  }
255
256
0
  if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t)v)) {
257
0
    return 0;
258
0
  }
259
260
0
  a->type = V_ASN1_NEG_INTEGER;
261
0
  return 1;
262
0
}
263
264
0
int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t v) {
265
0
  if (v >= 0) {
266
0
    return ASN1_ENUMERATED_set_uint64(a, (uint64_t)v);
267
0
  }
268
269
0
  if (!ASN1_ENUMERATED_set_uint64(a, 0 - (uint64_t)v)) {
270
0
    return 0;
271
0
  }
272
273
0
  a->type = V_ASN1_NEG_ENUMERATED;
274
0
  return 1;
275
0
}
276
277
0
int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) {
278
0
  static_assert(sizeof(long) <= sizeof(int64_t), "long fits in int64_t");
279
0
  return ASN1_INTEGER_set_int64(a, v);
280
0
}
281
282
0
int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) {
283
0
  static_assert(sizeof(long) <= sizeof(int64_t), "long fits in int64_t");
284
0
  return ASN1_ENUMERATED_set_int64(a, v);
285
0
}
286
287
0
static int asn1_string_set_uint64(ASN1_STRING *out, uint64_t v, int type) {
288
0
  uint8_t buf[sizeof(uint64_t)];
289
0
  CRYPTO_store_u64_be(buf, v);
290
0
  size_t leading_zeros;
291
0
  for (leading_zeros = 0; leading_zeros < sizeof(buf); leading_zeros++) {
292
0
    if (buf[leading_zeros] != 0) {
293
0
      break;
294
0
    }
295
0
  }
296
297
0
  if (!ASN1_STRING_set(out, buf + leading_zeros, sizeof(buf) - leading_zeros)) {
298
0
    return 0;
299
0
  }
300
0
  out->type = type;
301
0
  return 1;
302
0
}
303
304
0
int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v) {
305
0
  return asn1_string_set_uint64(out, v, V_ASN1_INTEGER);
306
0
}
307
308
0
int ASN1_ENUMERATED_set_uint64(ASN1_ENUMERATED *out, uint64_t v) {
309
0
  return asn1_string_set_uint64(out, v, V_ASN1_ENUMERATED);
310
0
}
311
312
static int asn1_string_get_abs_uint64(uint64_t *out, const ASN1_STRING *a,
313
0
                                      int type) {
314
0
  if ((a->type & ~V_ASN1_NEG) != type) {
315
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE);
316
0
    return 0;
317
0
  }
318
0
  uint8_t buf[sizeof(uint64_t)] = {0};
319
0
  if (a->length > (int)sizeof(buf)) {
320
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
321
0
    return 0;
322
0
  }
323
0
  OPENSSL_memcpy(buf + sizeof(buf) - a->length, a->data, a->length);
324
0
  *out = CRYPTO_load_u64_be(buf);
325
0
  return 1;
326
0
}
327
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
340
1
int ASN1_INTEGER_get_uint64(uint64_t *out, const ASN1_INTEGER *a) {
341
1
  return asn1_string_get_uint64(out, a, V_ASN1_INTEGER);
342
1
}
343
344
0
int ASN1_ENUMERATED_get_uint64(uint64_t *out, const ASN1_ENUMERATED *a) {
345
0
  return asn1_string_get_uint64(out, a, V_ASN1_ENUMERATED);
346
0
}
347
348
0
static int asn1_string_get_int64(int64_t *out, const ASN1_STRING *a, int type) {
349
0
  uint64_t v;
350
0
  if (!asn1_string_get_abs_uint64(&v, a, type)) {
351
0
    return 0;
352
0
  }
353
0
  int64_t i64;
354
0
  int fits_in_i64;
355
  // Check |v != 0| to handle manually-constructed negative zeros.
356
0
  if ((a->type & V_ASN1_NEG) && v != 0) {
357
0
    i64 = (int64_t)(0u - v);
358
0
    fits_in_i64 = i64 < 0;
359
0
  } else {
360
0
    i64 = (int64_t)v;
361
0
    fits_in_i64 = i64 >= 0;
362
0
  }
363
0
  if (!fits_in_i64) {
364
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
365
0
    return 0;
366
0
  }
367
0
  *out = i64;
368
0
  return 1;
369
0
}
370
371
0
int ASN1_INTEGER_get_int64(int64_t *out, const ASN1_INTEGER *a) {
372
0
  return asn1_string_get_int64(out, a, V_ASN1_INTEGER);
373
0
}
374
375
0
int ASN1_ENUMERATED_get_int64(int64_t *out, const ASN1_ENUMERATED *a) {
376
0
  return asn1_string_get_int64(out, a, V_ASN1_ENUMERATED);
377
0
}
378
379
0
static long asn1_string_get_long(const ASN1_STRING *a, int type) {
380
0
  if (a == NULL) {
381
0
    return 0;
382
0
  }
383
384
0
  int64_t v;
385
0
  if (!asn1_string_get_int64(&v, a, type) ||  //
386
0
      v < LONG_MIN || v > LONG_MAX) {
387
    // This function's return value does not distinguish overflow from -1.
388
0
    ERR_clear_error();
389
0
    return -1;
390
0
  }
391
392
0
  return (long)v;
393
0
}
394
395
0
long ASN1_INTEGER_get(const ASN1_INTEGER *a) {
396
0
  return asn1_string_get_long(a, V_ASN1_INTEGER);
397
0
}
398
399
0
long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a) {
400
0
  return asn1_string_get_long(a, V_ASN1_ENUMERATED);
401
0
}
402
403
static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai,
404
5.49k
                                      int type) {
405
5.49k
  ASN1_INTEGER *ret;
406
5.49k
  if (ai == NULL) {
407
5.49k
    ret = ASN1_STRING_type_new(type);
408
5.49k
  } else {
409
0
    ret = ai;
410
0
  }
411
5.49k
  if (ret == NULL) {
412
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
413
0
    goto err;
414
0
  }
415
416
5.49k
  if (BN_is_negative(bn) && !BN_is_zero(bn)) {
417
23
    ret->type = type | V_ASN1_NEG;
418
5.47k
  } else {
419
5.47k
    ret->type = type;
420
5.47k
  }
421
422
5.49k
  int len = BN_num_bytes(bn);
423
5.49k
  if (!ASN1_STRING_set(ret, NULL, len) ||
424
5.49k
      !BN_bn2bin_padded(ret->data, len, bn)) {
425
0
    goto err;
426
0
  }
427
5.49k
  return ret;
428
429
0
err:
430
0
  if (ret != ai) {
431
0
    ASN1_STRING_free(ret);
432
0
  }
433
0
  return NULL;
434
5.49k
}
435
436
7.65k
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) {
437
7.65k
  return bn_to_asn1_string(bn, ai, V_ASN1_INTEGER);
438
7.65k
}
439
440
7.18k
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai) {
441
7.18k
  return bn_to_asn1_string(bn, ai, V_ASN1_ENUMERATED);
442
7.18k
}
443
444
5.49k
static BIGNUM *asn1_string_to_bn(const ASN1_STRING *ai, BIGNUM *bn, int type) {
445
5.49k
  if ((ai->type & ~V_ASN1_NEG) != type) {
446
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE);
447
0
    return NULL;
448
0
  }
449
450
5.49k
  BIGNUM *ret;
451
5.49k
  if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) {
452
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
453
5.49k
  } else if (ai->type & V_ASN1_NEG) {
454
23
    BN_set_negative(ret, 1);
455
23
  }
456
5.49k
  return ret;
457
5.49k
}
458
459
7.65k
BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) {
460
7.65k
  return asn1_string_to_bn(ai, bn, V_ASN1_INTEGER);
461
7.65k
}
462
463
7.18k
BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn) {
464
7.18k
  return asn1_string_to_bn(ai, bn, V_ASN1_ENUMERATED);
465
7.18k
}