asn1_lib.c
Go to the documentation of this file.
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 <limits.h>
60 #include <string.h>
61 
62 #include <openssl/asn1_mac.h>
63 #include <openssl/err.h>
64 #include <openssl/mem.h>
65 
66 #include "../internal.h"
67 #include "internal.h"
68 
69 
70 /* Cross-module errors from crypto/x509/i2d_pr.c. */
71 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE)
72 
73 /* Cross-module errors from crypto/x509/algorithm.c. */
74 OPENSSL_DECLARE_ERROR_REASON(ASN1, CONTEXT_NOT_INITIALISED)
75 OPENSSL_DECLARE_ERROR_REASON(ASN1, DIGEST_AND_KEY_TYPE_NOT_SUPPORTED)
76 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_MESSAGE_DIGEST_ALGORITHM)
77 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_SIGNATURE_ALGORITHM)
78 OPENSSL_DECLARE_ERROR_REASON(ASN1, WRONG_PUBLIC_KEY_TYPE)
79 /*
80  * Cross-module errors from crypto/x509/asn1_gen.c. TODO(davidben): Remove
81  * these once asn1_gen.c is gone.
82  */
83 OPENSSL_DECLARE_ERROR_REASON(ASN1, DEPTH_EXCEEDED)
84 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT)
85 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN)
86 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_FORMAT)
87 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_HEX)
88 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_IMPLICIT_TAG)
89 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_INTEGER)
90 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NESTED_TAGGING)
91 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NULL_VALUE)
92 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_OBJECT)
93 OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_TIME_VALUE)
94 OPENSSL_DECLARE_ERROR_REASON(ASN1, INTEGER_NOT_ASCII_FORMAT)
95 OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_MODIFIER)
96 OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_NUMBER)
97 OPENSSL_DECLARE_ERROR_REASON(ASN1, LIST_ERROR)
98 OPENSSL_DECLARE_ERROR_REASON(ASN1, MISSING_VALUE)
99 OPENSSL_DECLARE_ERROR_REASON(ASN1, NOT_ASCII_FORMAT)
100 OPENSSL_DECLARE_ERROR_REASON(ASN1, OBJECT_NOT_ASCII_FORMAT)
101 OPENSSL_DECLARE_ERROR_REASON(ASN1, SEQUENCE_OR_SET_NEEDS_CONFIG)
102 OPENSSL_DECLARE_ERROR_REASON(ASN1, TIME_NOT_ASCII_FORMAT)
103 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_FORMAT)
104 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_TAG)
105 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_TYPE)
106 
107 static int asn1_get_length(const unsigned char **pp, long *rl, long max);
108 static void asn1_put_length(unsigned char **pp, int length);
109 
110 int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
111  int *pclass, long omax)
112 {
113  int i, ret;
114  long l;
115  const unsigned char *p = *pp;
116  int tag, xclass;
117  long max = omax;
118 
119  if (!max)
120  goto err;
121  ret = (*p & V_ASN1_CONSTRUCTED);
122  xclass = (*p & V_ASN1_PRIVATE);
123  i = *p & V_ASN1_PRIMITIVE_TAG;
124  if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
125  p++;
126  if (--max == 0)
127  goto err;
128  l = 0;
129  while (*p & 0x80) {
130  l <<= 7L;
131  l |= *(p++) & 0x7f;
132  if (--max == 0)
133  goto err;
134  if (l > (INT_MAX >> 7L))
135  goto err;
136  }
137  l <<= 7L;
138  l |= *(p++) & 0x7f;
139  tag = (int)l;
140  if (--max == 0)
141  goto err;
142  } else {
143  tag = i;
144  p++;
145  if (--max == 0)
146  goto err;
147  }
148 
149  /* To avoid ambiguity with V_ASN1_NEG, impose a limit on universal tags. */
150  if (xclass == V_ASN1_UNIVERSAL && tag > V_ASN1_MAX_UNIVERSAL)
151  goto err;
152 
153  *ptag = tag;
154  *pclass = xclass;
155  if (!asn1_get_length(&p, plength, max))
156  goto err;
157 
158  if (*plength > (omax - (p - *pp))) {
160  return 0x80;
161  }
162  *pp = p;
163  return ret;
164  err:
166  return 0x80;
167 }
168 
169 static int asn1_get_length(const unsigned char **pp, long *rl, long max)
170 {
171  const unsigned char *p = *pp;
172  unsigned long ret = 0;
173  unsigned long i;
174 
175  if (max-- < 1) {
176  return 0;
177  }
178  if (*p == 0x80) {
179  /* We do not support BER indefinite-length encoding. */
180  return 0;
181  }
182  i = *p & 0x7f;
183  if (*(p++) & 0x80) {
184  if (i > sizeof(ret) || max < (long)i)
185  return 0;
186  while (i-- > 0) {
187  ret <<= 8L;
188  ret |= *(p++);
189  }
190  } else {
191  ret = i;
192  }
193  /*
194  * Bound the length to comfortably fit in an int. Lengths in this module
195  * often switch between int and long without overflow checks.
196  */
197  if (ret > INT_MAX / 2)
198  return 0;
199  *pp = p;
200  *rl = (long)ret;
201  return 1;
202 }
203 
204 /*
205  * class 0 is constructed constructed == 2 for indefinite length constructed
206  */
207 void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
208  int xclass)
209 {
210  unsigned char *p = *pp;
211  int i, ttag;
212 
213  i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
214  i |= (xclass & V_ASN1_PRIVATE);
215  if (tag < 31)
216  *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
217  else {
218  *(p++) = i | V_ASN1_PRIMITIVE_TAG;
219  for (i = 0, ttag = tag; ttag > 0; i++)
220  ttag >>= 7;
221  ttag = i;
222  while (i-- > 0) {
223  p[i] = tag & 0x7f;
224  if (i != (ttag - 1))
225  p[i] |= 0x80;
226  tag >>= 7;
227  }
228  p += ttag;
229  }
230  if (constructed == 2)
231  *(p++) = 0x80;
232  else
234  *pp = p;
235 }
236 
237 int ASN1_put_eoc(unsigned char **pp)
238 {
239  /* This function is no longer used in the library, but some external code
240  * uses it. */
241  unsigned char *p = *pp;
242  *p++ = 0;
243  *p++ = 0;
244  *pp = p;
245  return 2;
246 }
247 
248 static void asn1_put_length(unsigned char **pp, int length)
249 {
250  unsigned char *p = *pp;
251  int i, l;
252  if (length <= 127)
253  *(p++) = (unsigned char)length;
254  else {
255  l = length;
256  for (i = 0; l > 0; i++)
257  l >>= 8;
258  *(p++) = i | 0x80;
259  l = i;
260  while (i-- > 0) {
261  p[i] = length & 0xff;
262  length >>= 8;
263  }
264  p += l;
265  }
266  *pp = p;
267 }
268 
269 int ASN1_object_size(int constructed, int length, int tag)
270 {
271  int ret = 1;
272  if (length < 0)
273  return -1;
274  if (tag >= 31) {
275  while (tag > 0) {
276  tag >>= 7;
277  ret++;
278  }
279  }
280  if (constructed == 2) {
281  ret += 3;
282  } else {
283  ret++;
284  if (length > 127) {
285  int tmplen = length;
286  while (tmplen > 0) {
287  tmplen >>= 8;
288  ret++;
289  }
290  }
291  }
292  if (ret >= INT_MAX - length)
293  return -1;
294  return ret + length;
295 }
296 
298 {
299  if (str == NULL)
300  return 0;
301  if (!ASN1_STRING_set(dst, str->data, str->length))
302  return 0;
303  dst->type = str->type;
304  dst->flags = str->flags;
305  return 1;
306 }
307 
309 {
310  ASN1_STRING *ret;
311  if (!str)
312  return NULL;
313  ret = ASN1_STRING_new();
314  if (!ret)
315  return NULL;
316  if (!ASN1_STRING_copy(ret, str)) {
318  return NULL;
319  }
320  return ret;
321 }
322 
323 int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
324 {
325  unsigned char *c;
326  const char *data = _data;
327 
328  if (len < 0) {
329  if (data == NULL)
330  return (0);
331  else
332  len = strlen(data);
333  }
334  if ((str->length <= len) || (str->data == NULL)) {
335  c = str->data;
336  if (c == NULL)
337  str->data = OPENSSL_malloc(len + 1);
338  else
339  str->data = OPENSSL_realloc(c, len + 1);
340 
341  if (str->data == NULL) {
343  str->data = c;
344  return (0);
345  }
346  }
347  str->length = len;
348  if (data != NULL) {
349  OPENSSL_memcpy(str->data, data, len);
350  /* an allowance for strings :-) */
351  str->data[len] = '\0';
352  }
353  return (1);
354 }
355 
357 {
358  OPENSSL_free(str->data);
359  str->data = data;
360  str->length = len;
361 }
362 
364 {
366 }
367 
369 {
370  ASN1_STRING *ret;
371 
373  if (ret == NULL) {
375  return (NULL);
376  }
377  ret->length = 0;
378  ret->type = type;
379  ret->data = NULL;
380  ret->flags = 0;
381  return (ret);
382 }
383 
385 {
386  if (str == NULL)
387  return;
388  OPENSSL_free(str->data);
389  OPENSSL_free(str);
390 }
391 
393 {
394  /* Capture padding bits and implicit truncation in BIT STRINGs. */
395  int a_length = a->length, b_length = b->length;
396  uint8_t a_padding = 0, b_padding = 0;
397  if (a->type == V_ASN1_BIT_STRING) {
398  a_length = asn1_bit_string_length(a, &a_padding);
399  }
400  if (b->type == V_ASN1_BIT_STRING) {
401  b_length = asn1_bit_string_length(b, &b_padding);
402  }
403 
404  if (a_length < b_length) {
405  return -1;
406  }
407  if (a_length > b_length) {
408  return 1;
409  }
410  /* In a BIT STRING, the number of bits is 8 * length - padding. Invert this
411  * comparison so we compare by lengths. */
412  if (a_padding > b_padding) {
413  return -1;
414  }
415  if (a_padding < b_padding) {
416  return 1;
417  }
418 
419  int ret = OPENSSL_memcmp(a->data, b->data, a_length);
420  if (ret != 0) {
421  return ret;
422  }
423 
424  /* Comparing the type first is more natural, but this matches OpenSSL. */
425  if (a->type < b->type) {
426  return -1;
427  }
428  if (a->type > b->type) {
429  return 1;
430  }
431  return 0;
432 }
433 
435 {
436  return str->length;
437 }
438 
440 {
441  return str->type;
442 }
443 
445 {
446  return str->data;
447 }
448 
449 const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *str)
450 {
451  return str->data;
452 }
xds_interop_client.str
str
Definition: xds_interop_client.py:487
ASN1_STRING_set0
void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
Definition: asn1_lib.c:356
ASN1_put_object
void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, int xclass)
Definition: asn1_lib.c:207
dst
static const char dst[]
Definition: test-fs-copyfile.c:37
ASN1_STRING_get0_data
const unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *str)
Definition: asn1_lib.c:449
OPENSSL_memcmp
static int OPENSSL_memcmp(const void *s1, const void *s2, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:811
ASN1_STRING_type_new
ASN1_STRING * ASN1_STRING_type_new(int type)
Definition: asn1_lib.c:368
ASN1_STRING_set
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
Definition: asn1_lib.c:323
OPENSSL_PUT_ERROR
#define OPENSSL_PUT_ERROR(library, reason)
Definition: err.h:423
string.h
OPENSSL_realloc
#define OPENSSL_realloc
Definition: boringssl_prefix_symbols.h:1889
ASN1_STRING_length
int ASN1_STRING_length(const ASN1_STRING *str)
Definition: asn1_lib.c:434
V_ASN1_MAX_UNIVERSAL
#define V_ASN1_MAX_UNIVERSAL
Definition: asn1.h:112
error_ref_leak.err
err
Definition: error_ref_leak.py:35
V_ASN1_OCTET_STRING
#define V_ASN1_OCTET_STRING
Definition: asn1.h:128
ASN1_STRING_new
ASN1_STRING * ASN1_STRING_new(void)
Definition: asn1_lib.c:363
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
xds_manager.p
p
Definition: xds_manager.py:60
ASN1_STRING_type
int ASN1_STRING_type(const ASN1_STRING *str)
Definition: asn1_lib.c:439
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
ASN1_STRING_dup
ASN1_STRING * ASN1_STRING_dup(const ASN1_STRING *str)
Definition: asn1_lib.c:308
ASN1_object_size
int ASN1_object_size(int constructed, int length, int tag)
Definition: asn1_lib.c:269
ASN1_STRING_copy
int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
Definition: asn1_lib.c:297
ASN1_put_eoc
int ASN1_put_eoc(unsigned char **pp)
Definition: asn1_lib.c:237
OPENSSL_malloc
#define OPENSSL_malloc
Definition: boringssl_prefix_symbols.h:1885
ASN1_R_HEADER_TOO_LONG
#define ASN1_R_HEADER_TOO_LONG
Definition: asn1.h:1966
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
V_ASN1_UNIVERSAL
#define V_ASN1_UNIVERSAL
Definition: asn1.h:92
internal.h
xds_interop_client.int
int
Definition: xds_interop_client.py:113
asn1_bit_string_length
#define asn1_bit_string_length
Definition: boringssl_prefix_symbols.h:2827
tag
static void * tag(intptr_t t)
Definition: bad_client.cc:318
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
asn1_mac.h
asn1_put_length
static void asn1_put_length(unsigned char **pp, int length)
Definition: asn1_lib.c:248
OPENSSL_memcpy
static void * OPENSSL_memcpy(void *dst, const void *src, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:819
err.h
V_ASN1_BIT_STRING
#define V_ASN1_BIT_STRING
Definition: asn1.h:127
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
OPENSSL_DECLARE_ERROR_REASON
#define OPENSSL_DECLARE_ERROR_REASON(lib, reason)
Definition: err.h:459
asn1_get_length
static int asn1_get_length(const unsigned char **pp, long *rl, long max)
Definition: asn1_lib.c:169
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
ASN1_STRING_free
void ASN1_STRING_free(ASN1_STRING *str)
Definition: asn1_lib.c:384
V_ASN1_CONSTRUCTED
#define V_ASN1_CONSTRUCTED
Definition: asn1.h:99
V_ASN1_PRIMITIVE_TAG
#define V_ASN1_PRIMITIVE_TAG
Definition: asn1.h:106
pp
const uint8_t ** pp
Definition: ssl_x509.cc:1020
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
L
lua_State * L
Definition: upb/upb/bindings/lua/main.c:35
V_ASN1_PRIVATE
#define V_ASN1_PRIVATE
Definition: asn1.h:95
ASN1_STRING_data
unsigned char * ASN1_STRING_data(ASN1_STRING *str)
Definition: asn1_lib.c:444
ASN1_STRING_cmp
int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
Definition: asn1_lib.c:392
ASN1_get_object
int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, int *pclass, long omax)
Definition: asn1_lib.c:110
mem.h
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
run_grpclb_interop_tests.l
dictionary l
Definition: run_grpclb_interop_tests.py:410
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
ASN1_R_TOO_LONG
#define ASN1_R_TOO_LONG
Definition: asn1.h:2020
OPENSSL_free
#define OPENSSL_free
Definition: boringssl_prefix_symbols.h:1869
asn1_string_st
Definition: asn1.h:543
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
asn1.h
ERR_R_MALLOC_FAILURE
#define ERR_R_MALLOC_FAILURE
Definition: err.h:371
google::protobuf.internal.decoder.long
long
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/decoder.py:89


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:44