Coverage Report

Created: 2025-09-05 06:13

/src/boringssl/crypto/asn1/a_int.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <openssl/asn1.h>
16
17
#include <assert.h>
18
#include <limits.h>
19
#include <string.h>
20
21
#include <openssl/bytestring.h>
22
#include <openssl/err.h>
23
#include <openssl/mem.h>
24
#include <openssl/span.h>
25
26
#include "../internal.h"
27
#include "internal.h"
28
29
30
68
ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x) {
31
68
  return ASN1_STRING_dup(x);
32
68
}
33
34
8
int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) {
35
  // Compare signs.
36
8
  int neg = x->type & V_ASN1_NEG;
37
8
  if (neg != (y->type & V_ASN1_NEG)) {
38
1
    return neg ? -1 : 1;
39
1
  }
40
41
7
  int ret = ASN1_STRING_cmp(x, y);
42
7
  if (neg) {
43
    // This could be |-ret|, but |ASN1_STRING_cmp| is not forbidden from
44
    // returning |INT_MIN|.
45
3
    if (ret < 0) {
46
2
      return 1;
47
2
    } else if (ret > 0) {
48
1
      return -1;
49
1
    } else {
50
0
      return 0;
51
0
    }
52
3
  }
53
54
4
  return ret;
55
7
}
56
57
// negate_twos_complement negates |len| bytes from |buf| in-place, interpreted
58
// as a signed, big-endian two's complement value.
59
132k
static void negate_twos_complement(uint8_t *buf, size_t len) {
60
132k
  uint8_t borrow = 0;
61
5.69M
  for (size_t i = len - 1; i < len; i--) {
62
5.56M
    uint8_t t = buf[i];
63
5.56M
    buf[i] = 0u - borrow - t;
64
5.56M
    borrow |= t != 0;
65
5.56M
  }
66
132k
}
67
68
45.0k
static int is_all_zeros(const uint8_t *in, size_t len) {
69
118k
  for (size_t i = 0; i < len; i++) {
70
111k
    if (in[i] != 0) {
71
38.3k
      return 0;
72
38.3k
    }
73
111k
  }
74
6.78k
  return 1;
75
45.0k
}
76
77
11.8k
int asn1_marshal_integer(CBB *out, const ASN1_INTEGER *in, CBS_ASN1_TAG tag) {
78
11.8k
  int len = i2c_ASN1_INTEGER(in, nullptr);
79
11.8k
  if (len <= 0) {
80
0
    return 0;
81
0
  }
82
11.8k
  tag = tag == 0 ? CBS_ASN1_INTEGER : tag;
83
11.8k
  CBB child;
84
11.8k
  uint8_t *ptr;
85
11.8k
  return CBB_add_asn1(out, &child, tag) &&     //
86
11.8k
         CBB_add_space(&child, &ptr, static_cast<size_t>(len)) &&   //
87
11.8k
         i2c_ASN1_INTEGER(in, &ptr) == len &&  //
88
11.8k
         CBB_flush(out);
89
11.8k
}
90
91
429k
int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) {
92
429k
  if (in == NULL) {
93
0
    return 0;
94
0
  }
95
96
  // |ASN1_INTEGER|s should be represented minimally, but it is possible to
97
  // construct invalid ones. Skip leading zeros so this does not produce an
98
  // invalid encoding or break invariants.
99
429k
  CBS cbs;
100
429k
  CBS_init(&cbs, in->data, in->length);
101
429k
  while (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0) {
102
0
    CBS_skip(&cbs, 1);
103
0
  }
104
105
429k
  int is_negative = (in->type & V_ASN1_NEG) != 0;
106
429k
  size_t pad;
107
429k
  CBS copy = cbs;
108
429k
  uint8_t msb;
109
429k
  if (!CBS_get_u8(&copy, &msb)) {
110
    // Zero is represented as a single byte.
111
19.6k
    is_negative = 0;
112
19.6k
    pad = 1;
113
409k
  } else if (is_negative) {
114
    // 0x80...01 through 0xff...ff have a two's complement of 0x7f...ff
115
    // through 0x00...01 and need an extra byte to be negative.
116
    // 0x01...00 through 0x80...00 have a two's complement of 0xfe...ff
117
    // through 0x80...00 and can be negated as-is.
118
278k
    pad = msb > 0x80 ||
119
278k
          (msb == 0x80 && !is_all_zeros(CBS_data(&copy), CBS_len(&copy)));
120
278k
  } else {
121
    // If the high bit is set, the signed representation needs an extra
122
    // byte to be positive.
123
130k
    pad = (msb & 0x80) != 0;
124
130k
  }
125
126
429k
  if (CBS_len(&cbs) > INT_MAX - pad) {
127
0
    OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW);
128
0
    return 0;
129
0
  }
130
429k
  int len = (int)(pad + CBS_len(&cbs));
131
429k
  assert(len > 0);
132
429k
  if (outp == NULL) {
133
331k
    return len;
134
331k
  }
135
136
97.8k
  if (pad) {
137
36.7k
    (*outp)[0] = 0;
138
36.7k
  }
139
97.8k
  OPENSSL_memcpy(*outp + pad, CBS_data(&cbs), CBS_len(&cbs));
140
97.8k
  if (is_negative) {
141
62.2k
    negate_twos_complement(*outp, len);
142
62.2k
    assert((*outp)[0] >= 0x80);
143
62.2k
  } else {
144
35.5k
    assert((*outp)[0] < 0x80);
145
35.5k
  }
146
97.8k
  *outp += len;
147
97.8k
  return len;
148
97.8k
}
149
150
static int asn1_parse_integer_contents(bssl::Span<const uint8_t> in,
151
276k
                                       ASN1_INTEGER *out) {
152
276k
  CBS cbs = in;
153
276k
  int is_negative;
154
276k
  if (!CBS_is_valid_asn1_integer(&cbs, &is_negative)) {
155
203
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
156
203
    return 0;
157
203
  }
158
159
  // Convert to |ASN1_INTEGER|'s sign-and-magnitude representation. First,
160
  // determine the size needed for a minimal result.
161
276k
  if (is_negative) {
162
    // 0xff00...01 through 0xff7f..ff have a two's complement of 0x00ff...ff
163
    // through 0x000100...001 and need one leading zero removed. 0x8000...00
164
    // through 0xff00...00 have a two's complement of 0x8000...00 through
165
    // 0x0100...00 and will be minimally-encoded as-is.
166
70.2k
    if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0xff &&
167
70.2k
        !is_all_zeros(CBS_data(&cbs) + 1, CBS_len(&cbs) - 1)) {
168
34.9k
      CBS_skip(&cbs, 1);
169
34.9k
    }
170
206k
  } else {
171
    // Remove the leading zero byte, if any.
172
206k
    if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0x00) {
173
133k
      CBS_skip(&cbs, 1);
174
133k
    }
175
206k
  }
176
177
276k
  if (!ASN1_STRING_set(out, CBS_data(&cbs), CBS_len(&cbs))) {
178
0
    return 0;
179
0
  }
180
181
276k
  if (is_negative) {
182
70.2k
    out->type = V_ASN1_NEG_INTEGER;
183
70.2k
    negate_twos_complement(out->data, out->length);
184
206k
  } else {
185
206k
    out->type = V_ASN1_INTEGER;
186
206k
  }
187
188
  // The value should be minimally-encoded.
189
276k
  assert(out->length == 0 || out->data[0] != 0);
190
  // Zero is not negative.
191
276k
  assert(!is_negative || out->length > 0);
192
276k
  return 1;
193
276k
}
194
195
277k
int asn1_parse_integer(CBS *cbs, ASN1_INTEGER *out, CBS_ASN1_TAG tag) {
196
277k
  tag = tag == 0 ? CBS_ASN1_INTEGER : tag;
197
277k
  CBS child;
198
277k
  if (!CBS_get_asn1(cbs, &child, tag)) {
199
1.24k
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
200
1.24k
    return 0;
201
1.24k
  }
202
276k
  return asn1_parse_integer_contents(child, out);
203
277k
}
204
205
81.6k
int asn1_parse_enumerated(CBS *cbs, ASN1_ENUMERATED *out, CBS_ASN1_TAG tag) {
206
81.6k
  tag = tag == 0 ? CBS_ASN1_ENUMERATED : tag;
207
81.6k
  if (!asn1_parse_integer(cbs, out, tag)) {
208
559
    return 0;
209
559
  }
210
  // Fix the type value.
211
81.1k
  out->type =
212
81.1k
      (out->type & V_ASN1_NEG) ? V_ASN1_NEG_ENUMERATED : V_ASN1_ENUMERATED;
213
81.1k
  return 1;
214
81.6k
}
215
216
ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp,
217
0
                               long len) {
218
0
  if (len < 0) {
219
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
220
0
    return nullptr;
221
0
  }
222
223
0
  ASN1_INTEGER *ret = nullptr;
224
0
  if (out == nullptr || *out == nullptr) {
225
0
    ret = ASN1_INTEGER_new();
226
0
    if (ret == nullptr) {
227
0
      return nullptr;
228
0
    }
229
0
  } else {
230
0
    ret = *out;
231
0
  }
232
233
0
  if (!asn1_parse_integer_contents(bssl::Span(*inp, len), ret)) {
234
0
    if (ret != nullptr && (out == nullptr || *out != ret)) {
235
0
      ASN1_INTEGER_free(ret);
236
0
    }
237
0
    return nullptr;
238
0
  }
239
240
0
  *inp += len;
241
0
  if (out != nullptr) {
242
0
    *out = ret;
243
0
  }
244
0
  return ret;
245
246
0
}
247
248
0
int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t v) {
249
0
  if (v >= 0) {
250
0
    return ASN1_INTEGER_set_uint64(a, (uint64_t)v);
251
0
  }
252
253
0
  if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t)v)) {
254
0
    return 0;
255
0
  }
256
257
0
  a->type = V_ASN1_NEG_INTEGER;
258
0
  return 1;
259
0
}
260
261
0
int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t v) {
262
0
  if (v >= 0) {
263
0
    return ASN1_ENUMERATED_set_uint64(a, (uint64_t)v);
264
0
  }
265
266
0
  if (!ASN1_ENUMERATED_set_uint64(a, 0 - (uint64_t)v)) {
267
0
    return 0;
268
0
  }
269
270
0
  a->type = V_ASN1_NEG_ENUMERATED;
271
0
  return 1;
272
0
}
273
274
0
int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) {
275
0
  static_assert(sizeof(long) <= sizeof(int64_t), "long fits in int64_t");
276
0
  return ASN1_INTEGER_set_int64(a, v);
277
0
}
278
279
0
int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) {
280
0
  static_assert(sizeof(long) <= sizeof(int64_t), "long fits in int64_t");
281
0
  return ASN1_ENUMERATED_set_int64(a, v);
282
0
}
283
284
0
static int asn1_string_set_uint64(ASN1_STRING *out, uint64_t v, int type) {
285
0
  uint8_t buf[sizeof(uint64_t)];
286
0
  CRYPTO_store_u64_be(buf, v);
287
0
  size_t leading_zeros;
288
0
  for (leading_zeros = 0; leading_zeros < sizeof(buf); leading_zeros++) {
289
0
    if (buf[leading_zeros] != 0) {
290
0
      break;
291
0
    }
292
0
  }
293
294
0
  if (!ASN1_STRING_set(out, buf + leading_zeros, sizeof(buf) - leading_zeros)) {
295
0
    return 0;
296
0
  }
297
0
  out->type = type;
298
0
  return 1;
299
0
}
300
301
0
int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v) {
302
0
  return asn1_string_set_uint64(out, v, V_ASN1_INTEGER);
303
0
}
304
305
0
int ASN1_ENUMERATED_set_uint64(ASN1_ENUMERATED *out, uint64_t v) {
306
0
  return asn1_string_set_uint64(out, v, V_ASN1_ENUMERATED);
307
0
}
308
309
static int asn1_string_get_abs_uint64(uint64_t *out, const ASN1_STRING *a,
310
3.00k
                                      int type) {
311
3.00k
  if ((a->type & ~V_ASN1_NEG) != type) {
312
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE);
313
0
    return 0;
314
0
  }
315
3.00k
  uint8_t buf[sizeof(uint64_t)] = {0};
316
3.00k
  if (a->length > (int)sizeof(buf)) {
317
1.66k
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
318
1.66k
    return 0;
319
1.66k
  }
320
1.34k
  OPENSSL_memcpy(buf + sizeof(buf) - a->length, a->data, a->length);
321
1.34k
  *out = CRYPTO_load_u64_be(buf);
322
1.34k
  return 1;
323
3.00k
}
324
325
static int asn1_string_get_uint64(uint64_t *out, const ASN1_STRING *a,
326
2.20k
                                  int type) {
327
2.20k
  if (!asn1_string_get_abs_uint64(out, a, type)) {
328
1.41k
    return 0;
329
1.41k
  }
330
792
  if (a->type & V_ASN1_NEG) {
331
222
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
332
222
    return 0;
333
222
  }
334
570
  return 1;
335
792
}
336
337
2.20k
int ASN1_INTEGER_get_uint64(uint64_t *out, const ASN1_INTEGER *a) {
338
2.20k
  return asn1_string_get_uint64(out, a, V_ASN1_INTEGER);
339
2.20k
}
340
341
0
int ASN1_ENUMERATED_get_uint64(uint64_t *out, const ASN1_ENUMERATED *a) {
342
0
  return asn1_string_get_uint64(out, a, V_ASN1_ENUMERATED);
343
0
}
344
345
801
static int asn1_string_get_int64(int64_t *out, const ASN1_STRING *a, int type) {
346
801
  uint64_t v;
347
801
  if (!asn1_string_get_abs_uint64(&v, a, type)) {
348
249
    return 0;
349
249
  }
350
552
  int64_t i64;
351
552
  int fits_in_i64;
352
  // Check |v != 0| to handle manually-constructed negative zeros.
353
552
  if ((a->type & V_ASN1_NEG) && v != 0) {
354
264
    i64 = (int64_t)(0u - v);
355
264
    fits_in_i64 = i64 < 0;
356
288
  } else {
357
288
    i64 = (int64_t)v;
358
288
    fits_in_i64 = i64 >= 0;
359
288
  }
360
552
  if (!fits_in_i64) {
361
168
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
362
168
    return 0;
363
168
  }
364
384
  *out = i64;
365
384
  return 1;
366
552
}
367
368
0
int ASN1_INTEGER_get_int64(int64_t *out, const ASN1_INTEGER *a) {
369
0
  return asn1_string_get_int64(out, a, V_ASN1_INTEGER);
370
0
}
371
372
0
int ASN1_ENUMERATED_get_int64(int64_t *out, const ASN1_ENUMERATED *a) {
373
0
  return asn1_string_get_int64(out, a, V_ASN1_ENUMERATED);
374
0
}
375
376
801
static long asn1_string_get_long(const ASN1_STRING *a, int type) {
377
801
  if (a == NULL) {
378
0
    return 0;
379
0
  }
380
381
801
  int64_t v;
382
801
  if (!asn1_string_get_int64(&v, a, type) ||  //
383
801
      v < LONG_MIN || v > LONG_MAX) {
384
    // This function's return value does not distinguish overflow from -1.
385
417
    ERR_clear_error();
386
417
    return -1;
387
417
  }
388
389
384
  return (long)v;
390
801
}
391
392
13
long ASN1_INTEGER_get(const ASN1_INTEGER *a) {
393
13
  return asn1_string_get_long(a, V_ASN1_INTEGER);
394
13
}
395
396
788
long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a) {
397
788
  return asn1_string_get_long(a, V_ASN1_ENUMERATED);
398
788
}
399
400
static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai,
401
18.5k
                                      int type) {
402
18.5k
  ASN1_INTEGER *ret;
403
18.5k
  if (ai == NULL) {
404
18.5k
    ret = ASN1_STRING_type_new(type);
405
18.5k
  } else {
406
0
    ret = ai;
407
0
  }
408
18.5k
  int len;
409
18.5k
  if (ret == NULL) {
410
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
411
0
    goto err;
412
0
  }
413
414
18.5k
  if (BN_is_negative(bn) && !BN_is_zero(bn)) {
415
531
    ret->type = type | V_ASN1_NEG;
416
18.0k
  } else {
417
18.0k
    ret->type = type;
418
18.0k
  }
419
420
18.5k
  len = BN_num_bytes(bn);
421
18.5k
  if (!ASN1_STRING_set(ret, NULL, len) ||
422
18.5k
      !BN_bn2bin_padded(ret->data, len, bn)) {
423
0
    goto err;
424
0
  }
425
18.5k
  return ret;
426
427
0
err:
428
0
  if (ret != ai) {
429
0
    ASN1_STRING_free(ret);
430
0
  }
431
0
  return NULL;
432
18.5k
}
433
434
18.5k
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) {
435
18.5k
  return bn_to_asn1_string(bn, ai, V_ASN1_INTEGER);
436
18.5k
}
437
438
0
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai) {
439
0
  return bn_to_asn1_string(bn, ai, V_ASN1_ENUMERATED);
440
0
}
441
442
1.19k
static BIGNUM *asn1_string_to_bn(const ASN1_STRING *ai, BIGNUM *bn, int type) {
443
1.19k
  if ((ai->type & ~V_ASN1_NEG) != type) {
444
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE);
445
0
    return NULL;
446
0
  }
447
448
1.19k
  BIGNUM *ret;
449
1.19k
  if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) {
450
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
451
1.19k
  } else if (ai->type & V_ASN1_NEG) {
452
591
    BN_set_negative(ret, 1);
453
591
  }
454
1.19k
  return ret;
455
1.19k
}
456
457
457
BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) {
458
457
  return asn1_string_to_bn(ai, bn, V_ASN1_INTEGER);
459
457
}
460
461
733
BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn) {
462
733
  return asn1_string_to_bn(ai, bn, V_ASN1_ENUMERATED);
463
733
}