a_int.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 <string.h>
60 #include <limits.h>
61 
62 #include <openssl/err.h>
63 #include <openssl/mem.h>
64 
65 #include "../internal.h"
66 
67 
69 {
70  return ASN1_STRING_dup(x);
71 }
72 
74 {
75  int neg, ret;
76  /* Compare signs */
77  neg = x->type & V_ASN1_NEG;
78  if (neg != (y->type & V_ASN1_NEG)) {
79  if (neg)
80  return -1;
81  else
82  return 1;
83  }
84 
85  ret = ASN1_STRING_cmp(x, y);
86 
87  if (neg)
88  return -ret;
89  else
90  return ret;
91 }
92 
93 /*
94  * This converts an ASN1 INTEGER into its content encoding.
95  * The internal representation is an ASN1_STRING whose data is a big endian
96  * representation of the value, ignoring the sign. The sign is determined by
97  * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
98  *
99  * Positive integers are no problem: they are almost the same as the DER
100  * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
101  *
102  * Negative integers are a bit trickier...
103  * The DER representation of negative integers is in 2s complement form.
104  * The internal form is converted by complementing each octet and finally
105  * adding one to the result. This can be done less messily with a little trick.
106  * If the internal form has trailing zeroes then they will become FF by the
107  * complement and 0 by the add one (due to carry) so just copy as many trailing
108  * zeros to the destination as there are in the source. The carry will add one
109  * to the last none zero octet: so complement this octet and add one and finally
110  * complement any left over until you get to the start of the string.
111  *
112  * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
113  * with 0xff. However if the first byte is 0x80 and one of the following bytes
114  * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
115  * followed by optional zeros isn't padded.
116  */
117 
118 int i2c_ASN1_INTEGER(const ASN1_INTEGER *a, unsigned char **pp)
119 {
120  int pad = 0, ret, i, neg;
121  unsigned char *p, *n, pb = 0;
122 
123  if (a == NULL)
124  return (0);
125  neg = a->type & V_ASN1_NEG;
126  if (a->length == 0)
127  ret = 1;
128  else {
129  ret = a->length;
130  i = a->data[0];
131  if (ret == 1 && i == 0)
132  neg = 0;
133  if (!neg && (i > 127)) {
134  pad = 1;
135  pb = 0;
136  } else if (neg) {
137  if (i > 128) {
138  pad = 1;
139  pb = 0xFF;
140  } else if (i == 128) {
141  /*
142  * Special case: if any other bytes non zero we pad:
143  * otherwise we don't.
144  */
145  for (i = 1; i < a->length; i++)
146  if (a->data[i]) {
147  pad = 1;
148  pb = 0xFF;
149  break;
150  }
151  }
152  }
153  ret += pad;
154  }
155  if (pp == NULL)
156  return (ret);
157  p = *pp;
158 
159  if (pad)
160  *(p++) = pb;
161  if (a->length == 0)
162  *(p++) = 0;
163  else if (!neg)
164  OPENSSL_memcpy(p, a->data, (unsigned int)a->length);
165  else {
166  /* Begin at the end of the encoding */
167  n = a->data + a->length - 1;
168  p += a->length - 1;
169  i = a->length;
170  /* Copy zeros to destination as long as source is zero */
171  while (!*n && i > 1) {
172  *(p--) = 0;
173  n--;
174  i--;
175  }
176  /* Complement and increment next octet */
177  *(p--) = ((*(n--)) ^ 0xff) + 1;
178  i--;
179  /* Complement any octets left */
180  for (; i > 0; i--)
181  *(p--) = *(n--) ^ 0xff;
182  }
183 
184  *pp += ret;
185  return (ret);
186 }
187 
188 /* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
189 
190 ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
191  long len)
192 {
193  ASN1_INTEGER *ret = NULL;
194  const unsigned char *p, *pend;
195  unsigned char *to, *s;
196  int i;
197 
198  /*
199  * This function can handle lengths up to INT_MAX - 1, but the rest of the
200  * legacy ASN.1 code mixes integer types, so avoid exposing it to
201  * ASN1_INTEGERS with larger lengths.
202  */
203  if (len < 0 || len > INT_MAX / 2) {
205  return NULL;
206  }
207 
208  if ((a == NULL) || ((*a) == NULL)) {
209  if ((ret = ASN1_INTEGER_new()) == NULL)
210  return (NULL);
211  ret->type = V_ASN1_INTEGER;
212  } else
213  ret = (*a);
214 
215  p = *pp;
216  pend = p + len;
217 
218  /*
219  * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
220  * a missing NULL parameter.
221  */
222  s = (unsigned char *)OPENSSL_malloc((int)len + 1);
223  if (s == NULL) {
225  goto err;
226  }
227  to = s;
228  if (!len) {
229  /*
230  * Strictly speaking this is an illegal INTEGER but we tolerate it.
231  */
232  ret->type = V_ASN1_INTEGER;
233  } else if (*p & 0x80) { /* a negative number */
234  ret->type = V_ASN1_NEG_INTEGER;
235  if ((*p == 0xff) && (len != 1)) {
236  p++;
237  len--;
238  }
239  i = len;
240  p += i - 1;
241  to += i - 1;
242  while ((!*p) && i) {
243  *(to--) = 0;
244  i--;
245  p--;
246  }
247  /*
248  * Special case: if all zeros then the number will be of the form FF
249  * followed by n zero bytes: this corresponds to 1 followed by n zero
250  * bytes. We've already written n zeros so we just append an extra
251  * one and set the first byte to a 1. This is treated separately
252  * because it is the only case where the number of bytes is larger
253  * than len.
254  */
255  if (!i) {
256  *s = 1;
257  s[len] = 0;
258  len++;
259  } else {
260  *(to--) = (*(p--) ^ 0xff) + 1;
261  i--;
262  for (; i > 0; i--)
263  *(to--) = *(p--) ^ 0xff;
264  }
265  } else {
266  ret->type = V_ASN1_INTEGER;
267  if ((*p == 0) && (len != 1)) {
268  p++;
269  len--;
270  }
271  OPENSSL_memcpy(s, p, (int)len);
272  }
273 
274  if (ret->data != NULL)
275  OPENSSL_free(ret->data);
276  ret->data = s;
277  ret->length = (int)len;
278  if (a != NULL)
279  (*a) = ret;
280  *pp = pend;
281  return (ret);
282  err:
283  OPENSSL_PUT_ERROR(ASN1, i);
284  if ((ret != NULL) && ((a == NULL) || (*a != ret)))
286  return (NULL);
287 }
288 
290 {
291  if (v >= 0) {
292  return ASN1_INTEGER_set_uint64(a, (uint64_t) v);
293  }
294 
295  if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t) v)) {
296  return 0;
297  }
298 
299  a->type = V_ASN1_NEG_INTEGER;
300  return 1;
301 }
302 
304 {
305  uint8_t *const newdata = OPENSSL_malloc(sizeof(uint64_t));
306  if (newdata == NULL) {
308  return 0;
309  }
310 
311  OPENSSL_free(out->data);
312  out->data = newdata;
313  v = CRYPTO_bswap8(v);
314  memcpy(out->data, &v, sizeof(v));
315 
316  out->type = V_ASN1_INTEGER;
317 
318  size_t leading_zeros;
319  for (leading_zeros = 0; leading_zeros < sizeof(uint64_t) - 1;
320  leading_zeros++) {
321  if (out->data[leading_zeros] != 0) {
322  break;
323  }
324  }
325 
326  out->length = sizeof(uint64_t) - leading_zeros;
327  OPENSSL_memmove(out->data, out->data + leading_zeros, out->length);
328 
329  return 1;
330 }
331 
333 {
334  int neg = 0, i;
335 
336  if (a == NULL)
337  return (0L);
338  i = a->type;
339  if (i == V_ASN1_NEG_INTEGER)
340  neg = 1;
341  else if (i != V_ASN1_INTEGER)
342  return -1;
343 
344  OPENSSL_STATIC_ASSERT(sizeof(uint64_t) >= sizeof(long),
345  "long larger than uint64_t");
346 
347  if (a->length > (int)sizeof(uint64_t)) {
348  /* hmm... a bit ugly, return all ones */
349  return -1;
350  }
351 
352  uint64_t r64 = 0;
353  if (a->data != NULL) {
354  for (i = 0; i < a->length; i++) {
355  r64 <<= 8;
356  r64 |= (unsigned char)a->data[i];
357  }
358 
359  if (r64 > LONG_MAX) {
360  return -1;
361  }
362  }
363 
364  long r = (long) r64;
365  if (neg)
366  r = -r;
367 
368  return r;
369 }
370 
372 {
373  ASN1_INTEGER *ret;
374  int len, j;
375 
376  if (ai == NULL)
377  ret = ASN1_INTEGER_new();
378  else
379  ret = ai;
380  if (ret == NULL) {
382  goto err;
383  }
384  if (BN_is_negative(bn) && !BN_is_zero(bn))
385  ret->type = V_ASN1_NEG_INTEGER;
386  else
387  ret->type = V_ASN1_INTEGER;
388  j = BN_num_bits(bn);
389  len = ((j == 0) ? 0 : ((j / 8) + 1));
390  if (ret->length < len + 4) {
391  unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
392  if (!new_data) {
394  goto err;
395  }
396  ret->data = new_data;
397  }
398  ret->length = BN_bn2bin(bn, ret->data);
399  /* Correct zero case */
400  if (!ret->length) {
401  ret->data[0] = 0;
402  ret->length = 1;
403  }
404  return (ret);
405  err:
406  if (ret != ai)
408  return (NULL);
409 }
410 
412 {
413  BIGNUM *ret;
414 
415  if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
417  else if (ai->type == V_ASN1_NEG_INTEGER)
418  BN_set_negative(ret, 1);
419  return (ret);
420 }
i2c_ASN1_INTEGER
int i2c_ASN1_INTEGER(const ASN1_INTEGER *a, unsigned char **pp)
Definition: a_int.c:118
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
ASN1_R_NESTED_ASN1_ERROR
#define ASN1_R_NESTED_ASN1_ERROR
Definition: asn1.h:2001
ASN1_STRING_dup
#define ASN1_STRING_dup
Definition: boringssl_prefix_symbols.h:679
y
const double y
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3611
BN_bin2bn
#define BN_bin2bn
Definition: boringssl_prefix_symbols.h:900
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
CRYPTO_bswap8
static uint64_t CRYPTO_bswap8(uint64_t x)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:759
error_ref_leak.err
err
Definition: error_ref_leak.py:35
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
to
size_t to
Definition: abseil-cpp/absl/container/internal/layout_test.cc:1385
xds_manager.p
p
Definition: xds_manager.py:60
c2i_ASN1_INTEGER
ASN1_INTEGER * c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len)
Definition: a_int.c:190
ASN1_INTEGER_set
int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
Definition: a_int.c:289
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
ASN1_INTEGER_new
OPENSSL_EXPORT ASN1_INTEGER * ASN1_INTEGER_new(void)
V_ASN1_NEG
#define V_ASN1_NEG
Definition: asn1.h:155
asn1_string_st::data
unsigned char * data
Definition: asn1.h:546
OPENSSL_malloc
#define OPENSSL_malloc
Definition: boringssl_prefix_symbols.h:1885
ASN1_R_BN_LIB
#define ASN1_R_BN_LIB
Definition: asn1.h:1948
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
xds_interop_client.int
int
Definition: xds_interop_client.py:113
asn1_string_st::length
int length
Definition: asn1.h:544
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
ASN1_STRING_cmp
#define ASN1_STRING_cmp
Definition: boringssl_prefix_symbols.h:676
pad
int pad
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/statusor_test.cc:47
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
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
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
BN_is_zero
#define BN_is_zero
Definition: boringssl_prefix_symbols.h:940
ASN1_INTEGER_free
OPENSSL_EXPORT void ASN1_INTEGER_free(ASN1_INTEGER *str)
BN_bn2bin
#define BN_bn2bin
Definition: boringssl_prefix_symbols.h:901
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
ASN1_INTEGER_get
long ASN1_INTEGER_get(const ASN1_INTEGER *a)
Definition: a_int.c:332
ASN1_INTEGER_set_uint64
int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v)
Definition: a_int.c:303
BN_num_bits
#define BN_num_bits
Definition: boringssl_prefix_symbols.h:974
pp
const uint8_t ** pp
Definition: ssl_x509.cc:1020
ASN1_INTEGER_dup
ASN1_INTEGER * ASN1_INTEGER_dup(const ASN1_INTEGER *x)
Definition: a_int.c:68
bignum_st
Definition: bn.h:957
BN_to_ASN1_INTEGER
ASN1_INTEGER * BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
Definition: a_int.c:371
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
L
lua_State * L
Definition: upb/upb/bindings/lua/main.c:35
fix_build_deps.r
r
Definition: fix_build_deps.py:491
OPENSSL_memmove
static void * OPENSSL_memmove(void *dst, const void *src, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:827
BN_is_negative
#define BN_is_negative
Definition: boringssl_prefix_symbols.h:933
asn1_string_st::type
int type
Definition: asn1.h:545
ASN1_INTEGER_cmp
int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
Definition: a_int.c:73
mem.h
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
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_INTEGER_to_BN
BIGNUM * ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
Definition: a_int.c:411
V_ASN1_NEG_INTEGER
#define V_ASN1_NEG_INTEGER
Definition: asn1.h:156
BN_set_negative
#define BN_set_negative
Definition: boringssl_prefix_symbols.h:990
asn1_string_st
Definition: asn1.h:543
OPENSSL_STATIC_ASSERT
#define OPENSSL_STATIC_ASSERT(cond, msg)
Definition: type_check.h:75
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
V_ASN1_INTEGER
#define V_ASN1_INTEGER
Definition: asn1.h:126


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