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_bitstr.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 <limits.h>
18
#include <string.h>
19
20
#include <openssl/bytestring.h>
21
#include <openssl/err.h>
22
#include <openssl/mem.h>
23
#include <openssl/span.h>
24
25
#include "../internal.h"
26
#include "internal.h"
27
28
29
using namespace bssl;
30
31
int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, const unsigned char *d,
32
0
                        ossl_ssize_t len) {
33
0
  return ASN1_STRING_set(x, d, len);
34
0
}
35
36
int bssl::asn1_bit_string_length(const ASN1_BIT_STRING *str,
37
414k
                                 uint8_t *out_padding_bits) {
38
414k
  int len = str->length;
39
414k
  if (str->flags & ASN1_STRING_FLAG_BITS_LEFT) {
40
    // If the string is already empty, it cannot have padding bits.
41
408k
    *out_padding_bits = len == 0 ? 0 : str->flags & 0x07;
42
408k
    return len;
43
408k
  }
44
45
  // TODO(https://crbug.com/boringssl/447): If we move this logic to
46
  // |ASN1_BIT_STRING_set_bit|, can we remove this representation?
47
6.33k
  while (len > 0 && str->data[len - 1] == 0) {
48
0
    len--;
49
0
  }
50
6.33k
  uint8_t padding_bits = 0;
51
6.33k
  if (len > 0) {
52
6.33k
    uint8_t last = str->data[len - 1];
53
6.33k
    assert(last != 0);
54
38.2k
    for (; padding_bits < 7; padding_bits++) {
55
36.0k
      if (last & (1 << padding_bits)) {
56
4.03k
        break;
57
4.03k
      }
58
36.0k
    }
59
6.33k
  }
60
6.33k
  *out_padding_bits = padding_bits;
61
6.33k
  return len;
62
6.33k
}
63
64
0
int ASN1_BIT_STRING_num_bytes(const ASN1_BIT_STRING *str, size_t *out) {
65
0
  uint8_t padding_bits;
66
0
  int len = asn1_bit_string_length(str, &padding_bits);
67
0
  if (padding_bits != 0) {
68
0
    return 0;
69
0
  }
70
0
  *out = len;
71
0
  return 1;
72
0
}
73
74
414k
int i2c_ASN1_BIT_STRING(const ASN1_BIT_STRING *a, unsigned char **pp) {
75
414k
  if (a == nullptr) {
76
0
    return 0;
77
0
  }
78
79
414k
  uint8_t bits;
80
414k
  int len = asn1_bit_string_length(a, &bits);
81
414k
  if (len > INT_MAX - 1) {
82
0
    OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW);
83
0
    return 0;
84
0
  }
85
414k
  int ret = 1 + len;
86
414k
  if (pp == nullptr) {
87
209k
    return ret;
88
209k
  }
89
90
204k
  uint8_t *p = *pp;
91
204k
  *(p++) = bits;
92
204k
  OPENSSL_memcpy(p, a->data, len);
93
204k
  if (len > 0) {
94
187k
    p[len - 1] &= (0xff << bits);
95
187k
  }
96
204k
  p += len;
97
204k
  *pp = p;
98
204k
  return ret;
99
414k
}
100
101
int bssl::asn1_marshal_bit_string(CBB *out, const ASN1_BIT_STRING *in,
102
200k
                                  CBS_ASN1_TAG tag) {
103
200k
  int len = i2c_ASN1_BIT_STRING(in, nullptr);
104
200k
  if (len <= 0) {
105
0
    return 0;
106
0
  }
107
200k
  tag = tag == 0 ? CBS_ASN1_BITSTRING : tag;
108
200k
  CBB child;
109
200k
  uint8_t *ptr;
110
200k
  return CBB_add_asn1(out, &child, tag) &&                         //
111
200k
         CBB_add_space(&child, &ptr, static_cast<size_t>(len)) &&  //
112
200k
         i2c_ASN1_BIT_STRING(in, &ptr) == len &&                   //
113
200k
         CBB_flush(out);
114
200k
}
115
116
static int asn1_parse_bit_string_contents(Span<const uint8_t> in,
117
335k
                                          ASN1_BIT_STRING *out) {
118
335k
  CBS cbs = in;
119
335k
  uint8_t padding;
120
335k
  if (!CBS_get_u8(&cbs, &padding)) {
121
193
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
122
193
    return 0;
123
193
  }
124
125
335k
  if (padding > 7) {
126
587
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
127
587
    return 0;
128
587
  }
129
130
  // Unused bits in a BIT STRING must be zero.
131
334k
  uint8_t padding_mask = (1 << padding) - 1;
132
334k
  if (padding != 0) {
133
16.4k
    CBS copy = cbs;
134
16.4k
    uint8_t last;
135
16.4k
    if (!CBS_get_last_u8(&copy, &last) || (last & padding_mask) != 0) {
136
302
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_PADDING);
137
302
      return 0;
138
302
    }
139
16.4k
  }
140
141
334k
  if (!ASN1_STRING_set(out, CBS_data(&cbs), CBS_len(&cbs))) {
142
0
    return 0;
143
0
  }
144
145
334k
  out->type = V_ASN1_BIT_STRING;
146
  // |ASN1_STRING_FLAG_BITS_LEFT| and the bottom 3 bits encode |padding|.
147
334k
  out->flags &= ~0x07;
148
334k
  out->flags |= ASN1_STRING_FLAG_BITS_LEFT | padding;
149
334k
  return 1;
150
334k
}
151
152
ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
153
0
                                     const unsigned char **pp, long len) {
154
0
  if (len < 0) {
155
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
156
0
    return nullptr;
157
0
  }
158
159
0
  ASN1_BIT_STRING *ret = nullptr;
160
0
  if (a == nullptr || *a == nullptr) {
161
0
    if ((ret = ASN1_BIT_STRING_new()) == nullptr) {
162
0
      return nullptr;
163
0
    }
164
0
  } else {
165
0
    ret = *a;
166
0
  }
167
168
0
  if (!asn1_parse_bit_string_contents(Span(*pp, len), ret)) {
169
0
    if (ret != nullptr && (a == nullptr || *a != ret)) {
170
0
      ASN1_BIT_STRING_free(ret);
171
0
    }
172
0
    return nullptr;
173
0
  }
174
175
0
  if (a != nullptr) {
176
0
    *a = ret;
177
0
  }
178
0
  *pp += len;
179
0
  return ret;
180
0
}
181
182
int bssl::asn1_parse_bit_string(CBS *cbs, ASN1_BIT_STRING *out,
183
178k
                                CBS_ASN1_TAG tag) {
184
178k
  tag = tag == 0 ? CBS_ASN1_BITSTRING : tag;
185
178k
  CBS child;
186
178k
  if (!CBS_get_asn1(cbs, &child, tag)) {
187
1.30k
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
188
1.30k
    return 0;
189
1.30k
  }
190
177k
  return asn1_parse_bit_string_contents(child, out);
191
178k
}
192
193
int bssl::asn1_parse_bit_string_with_bad_length(CBS *cbs,
194
159k
                                                ASN1_BIT_STRING *out) {
195
159k
  CBS child;
196
159k
  CBS_ASN1_TAG tag;
197
159k
  size_t header_len;
198
159k
  int indefinite;
199
159k
  if (!CBS_get_any_ber_asn1_element(cbs, &child, &tag, &header_len,
200
159k
                                    /*out_ber_found=*/nullptr,
201
159k
                                    &indefinite) ||
202
158k
      tag != CBS_ASN1_BITSTRING || indefinite ||  //
203
158k
      !CBS_skip(&child, header_len)) {
204
1.07k
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
205
1.07k
    return 0;
206
1.07k
  }
207
158k
  return asn1_parse_bit_string_contents(child, out);
208
159k
}
209
210
// These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
211
4.35k
int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) {
212
4.35k
  int w, v, iv;
213
4.35k
  unsigned char *c;
214
215
4.35k
  w = n / 8;
216
4.35k
  v = 1 << (7 - (n & 0x07));
217
4.35k
  iv = ~v;
218
4.35k
  if (!value) {
219
0
    v = 0;
220
0
  }
221
222
4.35k
  if (a == nullptr) {
223
0
    return 0;
224
0
  }
225
226
4.35k
  a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);  // clear, set on write
227
228
4.35k
  if ((a->length < (w + 1)) || (a->data == nullptr)) {
229
2.90k
    if (!value) {
230
0
      return 1;  // Don't need to set
231
0
    }
232
2.90k
    if (a->data == nullptr) {
233
2.61k
      c = (unsigned char *)OPENSSL_malloc(w + 1);
234
2.61k
    } else {
235
289
      c = (unsigned char *)OPENSSL_realloc(a->data, w + 1);
236
289
    }
237
2.90k
    if (c == nullptr) {
238
0
      return 0;
239
0
    }
240
2.90k
    if (w + 1 - a->length > 0) {
241
2.90k
      OPENSSL_memset(c + a->length, 0, w + 1 - a->length);
242
2.90k
    }
243
2.90k
    a->data = c;
244
2.90k
    a->length = w + 1;
245
2.90k
  }
246
4.35k
  a->data[w] = ((a->data[w]) & iv) | v;
247
4.35k
  while ((a->length > 0) && (a->data[a->length - 1] == 0)) {
248
0
    a->length--;
249
0
  }
250
4.35k
  return 1;
251
4.35k
}
252
253
6.80k
int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n) {
254
6.80k
  int w, v;
255
256
6.80k
  w = n / 8;
257
6.80k
  v = 1 << (7 - (n & 0x07));
258
6.80k
  if ((a == nullptr) || (a->length < (w + 1)) || (a->data == nullptr)) {
259
831
    return 0;
260
831
  }
261
5.97k
  return ((a->data[w] & v) != 0);
262
6.80k
}
263
264
// Checks if the given bit string contains only bits specified by
265
// the flags vector. Returns 0 if there is at least one bit set in 'a'
266
// which is not specified in 'flags', 1 otherwise.
267
// 'len' is the length of 'flags'.
268
int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, const unsigned char *flags,
269
0
                          int flags_len) {
270
0
  int i, ok;
271
  // Check if there is one bit set at all.
272
0
  if (!a || !a->data) {
273
0
    return 1;
274
0
  }
275
276
  // Check each byte of the internal representation of the bit string.
277
0
  ok = 1;
278
0
  for (i = 0; i < a->length && ok; ++i) {
279
0
    unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
280
    // We are done if there is an unneeded bit set.
281
0
    ok = (a->data[i] & mask) == 0;
282
0
  }
283
0
  return ok;
284
0
}