Coverage Report

Created: 2022-08-24 06:30

/src/libressl/crypto/asn1/a_bitstr.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: a_bitstr.c,v 1.36 2022/05/17 09:17:20 tb Exp $ */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 *
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 *
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#include <limits.h>
60
#include <stdio.h>
61
#include <string.h>
62
63
#include <openssl/asn1.h>
64
#include <openssl/asn1t.h>
65
#include <openssl/conf.h>
66
#include <openssl/err.h>
67
#include <openssl/x509v3.h>
68
69
#include "bytestring.h"
70
71
const ASN1_ITEM ASN1_BIT_STRING_it = {
72
  .itype = ASN1_ITYPE_PRIMITIVE,
73
  .utype = V_ASN1_BIT_STRING,
74
  .sname = "ASN1_BIT_STRING",
75
};
76
77
ASN1_BIT_STRING *
78
ASN1_BIT_STRING_new(void)
79
42.5k
{
80
42.5k
  return (ASN1_BIT_STRING *)ASN1_item_new(&ASN1_BIT_STRING_it);
81
42.5k
}
82
83
void
84
ASN1_BIT_STRING_free(ASN1_BIT_STRING *a)
85
79.0k
{
86
79.0k
  ASN1_item_free((ASN1_VALUE *)a, &ASN1_BIT_STRING_it);
87
79.0k
}
88
89
static void
90
asn1_abs_clear_unused_bits(ASN1_BIT_STRING *abs)
91
42.5k
{
92
42.5k
  abs->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
93
42.5k
}
94
95
int
96
asn1_abs_set_unused_bits(ASN1_BIT_STRING *abs, uint8_t unused_bits)
97
42.5k
{
98
42.5k
  if (unused_bits > 7)
99
6
    return 0;
100
101
42.5k
  asn1_abs_clear_unused_bits(abs);
102
103
42.5k
  abs->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits;
104
105
42.5k
  return 1;
106
42.5k
}
107
108
int
109
ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
110
0
{
111
0
  return ASN1_STRING_set(x, d, len);
112
0
}
113
114
int
115
ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
116
0
{
117
0
  int w, v, iv;
118
0
  unsigned char *c;
119
120
0
  w = n/8;
121
0
  v = 1 << (7 - (n & 0x07));
122
0
  iv = ~v;
123
0
  if (!value)
124
0
    v = 0;
125
126
0
  if (a == NULL)
127
0
    return 0;
128
129
0
  asn1_abs_clear_unused_bits(a);
130
131
0
  if ((a->length < (w + 1)) || (a->data == NULL)) {
132
0
    if (!value)
133
0
      return(1); /* Don't need to set */
134
0
    if ((c = recallocarray(a->data, a->length, w + 1, 1)) == NULL) {
135
0
      ASN1error(ERR_R_MALLOC_FAILURE);
136
0
      return 0;
137
0
    }
138
0
    a->data = c;
139
0
    a->length = w + 1;
140
0
  }
141
0
  a->data[w] = ((a->data[w]) & iv) | v;
142
0
  while ((a->length > 0) && (a->data[a->length - 1] == 0))
143
0
    a->length--;
144
145
0
  return (1);
146
0
}
147
148
int
149
ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n)
150
0
{
151
0
  int w, v;
152
153
0
  w = n / 8;
154
0
  v = 1 << (7 - (n & 0x07));
155
0
  if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
156
0
    return (0);
157
0
  return ((a->data[w] & v) != 0);
158
0
}
159
160
/*
161
 * Checks if the given bit string contains only bits specified by
162
 * the flags vector. Returns 0 if there is at least one bit set in 'a'
163
 * which is not specified in 'flags', 1 otherwise.
164
 * 'len' is the length of 'flags'.
165
 */
166
int
167
ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, const unsigned char *flags,
168
    int flags_len)
169
0
{
170
0
  int i, ok;
171
172
  /* Check if there is one bit set at all. */
173
0
  if (!a || !a->data)
174
0
    return 1;
175
176
  /* Check each byte of the internal representation of the bit string. */
177
0
  ok = 1;
178
0
  for (i = 0; i < a->length && ok; ++i) {
179
0
    unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
180
    /* We are done if there is an unneeded bit set. */
181
0
    ok = (a->data[i] & mask) == 0;
182
0
  }
183
0
  return ok;
184
0
}
185
186
int
187
ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
188
    BIT_STRING_BITNAME *tbl, int indent)
189
0
{
190
0
  BIT_STRING_BITNAME *bnam;
191
0
  char first = 1;
192
193
0
  BIO_printf(out, "%*s", indent, "");
194
0
  for (bnam = tbl; bnam->lname; bnam++) {
195
0
    if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
196
0
      if (!first)
197
0
        BIO_puts(out, ", ");
198
0
      BIO_puts(out, bnam->lname);
199
0
      first = 0;
200
0
    }
201
0
  }
202
0
  BIO_puts(out, "\n");
203
0
  return 1;
204
0
}
205
206
int
207
ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value,
208
    BIT_STRING_BITNAME *tbl)
209
0
{
210
0
  int bitnum;
211
212
0
  bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
213
0
  if (bitnum < 0)
214
0
    return 0;
215
0
  if (bs) {
216
0
    if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
217
0
      return 0;
218
0
  }
219
0
  return 1;
220
0
}
221
222
int
223
ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl)
224
0
{
225
0
  BIT_STRING_BITNAME *bnam;
226
227
0
  for (bnam = tbl; bnam->lname; bnam++) {
228
0
    if (!strcmp(bnam->sname, name) ||
229
0
        !strcmp(bnam->lname, name))
230
0
      return bnam->bitnum;
231
0
  }
232
0
  return -1;
233
0
}
234
235
int
236
i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
237
65.6k
{
238
65.6k
  int ret, j, bits, len;
239
65.6k
  unsigned char *p, *d;
240
241
65.6k
  if (a == NULL)
242
0
    return (0);
243
244
65.6k
  len = a->length;
245
246
65.6k
  if (len > 0) {
247
65.5k
    if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
248
65.5k
      bits = (int)a->flags & 0x07;
249
65.5k
    } else {
250
0
      for (; len > 0; len--) {
251
0
        if (a->data[len - 1])
252
0
          break;
253
0
      }
254
0
      j = a->data[len - 1];
255
0
      if (j & 0x01)
256
0
        bits = 0;
257
0
      else if (j & 0x02)
258
0
        bits = 1;
259
0
      else if (j & 0x04)
260
0
        bits = 2;
261
0
      else if (j & 0x08)
262
0
        bits = 3;
263
0
      else if (j & 0x10)
264
0
        bits = 4;
265
0
      else if (j & 0x20)
266
0
        bits = 5;
267
0
      else if (j & 0x40)
268
0
        bits = 6;
269
0
      else if (j & 0x80)
270
0
        bits = 7;
271
0
      else
272
0
        bits = 0; /* should not happen */
273
0
    }
274
65.5k
  } else
275
15
    bits = 0;
276
277
65.6k
  ret = 1 + len;
278
65.6k
  if (pp == NULL)
279
49.2k
    return (ret);
280
281
16.3k
  p= *pp;
282
283
16.3k
  *(p++) = (unsigned char)bits;
284
16.3k
  d = a->data;
285
16.3k
  if (len > 0) {
286
16.3k
    memcpy(p, d, len);
287
16.3k
    p += len;
288
16.3k
    p[-1] &= 0xff << bits;
289
16.3k
  }
290
16.3k
  *pp = p;
291
16.3k
  return (ret);
292
65.6k
}
293
294
int
295
c2i_ASN1_BIT_STRING_cbs(ASN1_BIT_STRING **out_abs, CBS *cbs)
296
42.5k
{
297
42.5k
  ASN1_BIT_STRING *abs = NULL;
298
42.5k
  uint8_t *data = NULL;
299
42.5k
  size_t data_len = 0;
300
42.5k
  uint8_t unused_bits;
301
42.5k
  int ret = 0;
302
303
42.5k
  if (out_abs == NULL)
304
0
    goto err;
305
306
42.5k
  if (*out_abs != NULL) {
307
24.3k
    ASN1_BIT_STRING_free(*out_abs);
308
24.3k
    *out_abs = NULL;
309
24.3k
  }
310
311
42.5k
  if (!CBS_get_u8(cbs, &unused_bits)) {
312
1
    ASN1error(ASN1_R_STRING_TOO_SHORT);
313
1
    goto err;
314
1
  }
315
316
42.5k
  if (!CBS_stow(cbs, &data, &data_len))
317
0
    goto err;
318
42.5k
  if (data_len > INT_MAX)
319
0
    goto err;
320
321
42.5k
  if ((abs = ASN1_BIT_STRING_new()) == NULL)
322
0
    goto err;
323
324
42.5k
  abs->data = data;
325
42.5k
  abs->length = (int)data_len;
326
42.5k
  data = NULL;
327
328
  /*
329
   * We do this to preserve the settings. If we modify the settings,
330
   * via the _set_bit function, we will recalculate on output.
331
   */
332
42.5k
  if (!asn1_abs_set_unused_bits(abs, unused_bits)) {
333
6
    ASN1error(ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
334
6
    goto err;
335
6
  }
336
42.5k
  if (abs->length > 0)
337
42.5k
    abs->data[abs->length - 1] &= 0xff << unused_bits;
338
339
42.5k
  *out_abs = abs;
340
42.5k
  abs = NULL;
341
342
42.5k
  ret = 1;
343
344
42.5k
 err:
345
42.5k
  ASN1_BIT_STRING_free(abs);
346
42.5k
  freezero(data, data_len);
347
348
42.5k
  return ret;
349
42.5k
}
350
351
ASN1_BIT_STRING *
352
c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **out_abs, const unsigned char **pp, long len)
353
0
{
354
0
  ASN1_BIT_STRING *abs = NULL;
355
0
  CBS content;
356
357
0
  if (out_abs != NULL) {
358
0
    ASN1_BIT_STRING_free(*out_abs);
359
0
    *out_abs = NULL;
360
0
  }
361
362
0
  if (len < 0) {
363
0
    ASN1error(ASN1_R_LENGTH_ERROR);
364
0
    return NULL;
365
0
  }
366
367
0
  CBS_init(&content, *pp, len);
368
369
0
  if (!c2i_ASN1_BIT_STRING_cbs(&abs, &content))
370
0
    return NULL;
371
372
0
  *pp = CBS_data(&content);
373
374
0
  if (out_abs != NULL)
375
0
    *out_abs = abs;
376
377
0
  return abs;
378
0
}
379
380
int
381
i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **out)
382
0
{
383
0
  return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_BIT_STRING_it);
384
0
}
385
386
ASN1_BIT_STRING *
387
d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **in, long len)
388
0
{
389
0
  return (ASN1_BIT_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
390
0
      &ASN1_BIT_STRING_it);
391
0
}