Coverage Report

Created: 2026-02-16 07:12

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