• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include "internal/numbers.h"
13 #include <limits.h>
14 #include <openssl/asn1.h>
15 #include <openssl/bn.h>
16 #include "asn1_local.h"
17 
ASN1_INTEGER_dup(const ASN1_INTEGER * x)18 ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
19 {
20     return ASN1_STRING_dup(x);
21 }
22 
ASN1_INTEGER_cmp(const ASN1_INTEGER * x,const ASN1_INTEGER * y)23 int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
24 {
25     int neg, ret;
26     /* Compare signs */
27     neg = x->type & V_ASN1_NEG;
28     if (neg != (y->type & V_ASN1_NEG)) {
29         if (neg)
30             return -1;
31         else
32             return 1;
33     }
34 
35     ret = ASN1_STRING_cmp(x, y);
36 
37     if (neg)
38         return -ret;
39     else
40         return ret;
41 }
42 
43 /*-
44  * This converts a big endian buffer and sign into its content encoding.
45  * This is used for INTEGER and ENUMERATED types.
46  * The internal representation is an ASN1_STRING whose data is a big endian
47  * representation of the value, ignoring the sign. The sign is determined by
48  * the type: if type & V_ASN1_NEG is true it is negative, otherwise positive.
49  *
50  * Positive integers are no problem: they are almost the same as the DER
51  * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
52  *
53  * Negative integers are a bit trickier...
54  * The DER representation of negative integers is in 2s complement form.
55  * The internal form is converted by complementing each octet and finally
56  * adding one to the result. This can be done less messily with a little trick.
57  * If the internal form has trailing zeroes then they will become FF by the
58  * complement and 0 by the add one (due to carry) so just copy as many trailing
59  * zeros to the destination as there are in the source. The carry will add one
60  * to the last none zero octet: so complement this octet and add one and finally
61  * complement any left over until you get to the start of the string.
62  *
63  * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
64  * with 0xff. However if the first byte is 0x80 and one of the following bytes
65  * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
66  * followed by optional zeros isn't padded.
67  */
68 
69 /*
70  * If |pad| is zero, the operation is effectively reduced to memcpy,
71  * and if |pad| is 0xff, then it performs two's complement, ~dst + 1.
72  * Note that in latter case sequence of zeros yields itself, and so
73  * does 0x80 followed by any number of zeros. These properties are
74  * used elsewhere below...
75  */
twos_complement(unsigned char * dst,const unsigned char * src,size_t len,unsigned char pad)76 static void twos_complement(unsigned char *dst, const unsigned char *src,
77                             size_t len, unsigned char pad)
78 {
79     unsigned int carry = pad & 1;
80 
81     /* Begin at the end of the encoding */
82     dst += len;
83     src += len;
84     /* two's complement value: ~value + 1 */
85     while (len-- != 0) {
86         *(--dst) = (unsigned char)(carry += *(--src) ^ pad);
87         carry >>= 8;
88     }
89 }
90 
i2c_ibuf(const unsigned char * b,size_t blen,int neg,unsigned char ** pp)91 static size_t i2c_ibuf(const unsigned char *b, size_t blen, int neg,
92                        unsigned char **pp)
93 {
94     unsigned int pad = 0;
95     size_t ret, i;
96     unsigned char *p, pb = 0;
97 
98     if (b != NULL && blen) {
99         ret = blen;
100         i = b[0];
101         if (!neg && (i > 127)) {
102             pad = 1;
103             pb = 0;
104         } else if (neg) {
105             pb = 0xFF;
106             if (i > 128) {
107                 pad = 1;
108             } else if (i == 128) {
109                 /*
110                  * Special case [of minimal negative for given length]:
111                  * if any other bytes non zero we pad, otherwise we don't.
112                  */
113                 for (pad = 0, i = 1; i < blen; i++)
114                     pad |= b[i];
115                 pb = pad != 0 ? 0xffU : 0;
116                 pad = pb & 1;
117             }
118         }
119         ret += pad;
120     } else {
121         ret = 1;
122         blen = 0;   /* reduce '(b == NULL || blen == 0)' to '(blen == 0)' */
123     }
124 
125     if (pp == NULL || (p = *pp) == NULL)
126         return ret;
127 
128     /*
129      * This magically handles all corner cases, such as '(b == NULL ||
130      * blen == 0)', non-negative value, "negative" zero, 0x80 followed
131      * by any number of zeros...
132      */
133     *p = pb;
134     p += pad;       /* yes, p[0] can be written twice, but it's little
135                      * price to pay for eliminated branches */
136     twos_complement(p, b, blen, pb);
137 
138     *pp += ret;
139     return ret;
140 }
141 
142 /*
143  * convert content octets into a big endian buffer. Returns the length
144  * of buffer or 0 on error: for malformed INTEGER. If output buffer is
145  * NULL just return length.
146  */
147 
c2i_ibuf(unsigned char * b,int * pneg,const unsigned char * p,size_t plen)148 static size_t c2i_ibuf(unsigned char *b, int *pneg,
149                        const unsigned char *p, size_t plen)
150 {
151     int neg, pad;
152     /* Zero content length is illegal */
153     if (plen == 0) {
154         ASN1err(ASN1_F_C2I_IBUF, ASN1_R_ILLEGAL_ZERO_CONTENT);
155         return 0;
156     }
157     neg = p[0] & 0x80;
158     if (pneg)
159         *pneg = neg;
160     /* Handle common case where length is 1 octet separately */
161     if (plen == 1) {
162         if (b != NULL) {
163             if (neg)
164                 b[0] = (p[0] ^ 0xFF) + 1;
165             else
166                 b[0] = p[0];
167         }
168         return 1;
169     }
170 
171     pad = 0;
172     if (p[0] == 0) {
173         pad = 1;
174     } else if (p[0] == 0xFF) {
175         size_t i;
176 
177         /*
178          * Special case [of "one less minimal negative" for given length]:
179          * if any other bytes non zero it was padded, otherwise not.
180          */
181         for (pad = 0, i = 1; i < plen; i++)
182             pad |= p[i];
183         pad = pad != 0 ? 1 : 0;
184     }
185     /* reject illegal padding: first two octets MSB can't match */
186     if (pad && (neg == (p[1] & 0x80))) {
187         ASN1err(ASN1_F_C2I_IBUF, ASN1_R_ILLEGAL_PADDING);
188         return 0;
189     }
190 
191     /* skip over pad */
192     p += pad;
193     plen -= pad;
194 
195     if (b != NULL)
196         twos_complement(b, p, plen, neg ? 0xffU : 0);
197 
198     return plen;
199 }
200 
i2c_ASN1_INTEGER(ASN1_INTEGER * a,unsigned char ** pp)201 int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
202 {
203     return i2c_ibuf(a->data, a->length, a->type & V_ASN1_NEG, pp);
204 }
205 
206 /* Convert big endian buffer into uint64_t, return 0 on error */
asn1_get_uint64(uint64_t * pr,const unsigned char * b,size_t blen)207 static int asn1_get_uint64(uint64_t *pr, const unsigned char *b, size_t blen)
208 {
209     size_t i;
210     uint64_t r;
211 
212     if (blen > sizeof(*pr)) {
213         ASN1err(ASN1_F_ASN1_GET_UINT64, ASN1_R_TOO_LARGE);
214         return 0;
215     }
216     if (b == NULL)
217         return 0;
218     for (r = 0, i = 0; i < blen; i++) {
219         r <<= 8;
220         r |= b[i];
221     }
222     *pr = r;
223     return 1;
224 }
225 
226 /*
227  * Write uint64_t to big endian buffer and return offset to first
228  * written octet. In other words it returns offset in range from 0
229  * to 7, with 0 denoting 8 written octets and 7 - one.
230  */
asn1_put_uint64(unsigned char b[sizeof (uint64_t)],uint64_t r)231 static size_t asn1_put_uint64(unsigned char b[sizeof(uint64_t)], uint64_t r)
232 {
233     size_t off = sizeof(uint64_t);
234 
235     do {
236         b[--off] = (unsigned char)r;
237     } while (r >>= 8);
238 
239     return off;
240 }
241 
242 /*
243  * Absolute value of INT64_MIN: we can't just use -INT64_MIN as gcc produces
244  * overflow warnings.
245  */
246 #define ABS_INT64_MIN ((uint64_t)INT64_MAX + (-(INT64_MIN + INT64_MAX)))
247 
248 /* signed version of asn1_get_uint64 */
asn1_get_int64(int64_t * pr,const unsigned char * b,size_t blen,int neg)249 static int asn1_get_int64(int64_t *pr, const unsigned char *b, size_t blen,
250                           int neg)
251 {
252     uint64_t r;
253     if (asn1_get_uint64(&r, b, blen) == 0)
254         return 0;
255     if (neg) {
256         if (r <= INT64_MAX) {
257             /* Most significant bit is guaranteed to be clear, negation
258              * is guaranteed to be meaningful in platform-neutral sense. */
259             *pr = -(int64_t)r;
260         } else if (r == ABS_INT64_MIN) {
261             /* This never happens if INT64_MAX == ABS_INT64_MIN, e.g.
262              * on ones'-complement system. */
263             *pr = (int64_t)(0 - r);
264         } else {
265             ASN1err(ASN1_F_ASN1_GET_INT64, ASN1_R_TOO_SMALL);
266             return 0;
267         }
268     } else {
269         if (r <= INT64_MAX) {
270             *pr = (int64_t)r;
271         } else {
272             ASN1err(ASN1_F_ASN1_GET_INT64, ASN1_R_TOO_LARGE);
273             return 0;
274         }
275     }
276     return 1;
277 }
278 
279 /* Convert ASN1 INTEGER content octets to ASN1_INTEGER structure */
c2i_ASN1_INTEGER(ASN1_INTEGER ** a,const unsigned char ** pp,long len)280 ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
281                                long len)
282 {
283     ASN1_INTEGER *ret = NULL;
284     size_t r;
285     int neg;
286 
287     r = c2i_ibuf(NULL, NULL, *pp, len);
288 
289     if (r == 0)
290         return NULL;
291 
292     if ((a == NULL) || ((*a) == NULL)) {
293         ret = ASN1_INTEGER_new();
294         if (ret == NULL)
295             return NULL;
296         ret->type = V_ASN1_INTEGER;
297     } else
298         ret = *a;
299 
300     if (ASN1_STRING_set(ret, NULL, r) == 0)
301         goto err;
302 
303     c2i_ibuf(ret->data, &neg, *pp, len);
304 
305     if (neg)
306         ret->type |= V_ASN1_NEG;
307 
308     *pp += len;
309     if (a != NULL)
310         (*a) = ret;
311     return ret;
312  err:
313     ASN1err(ASN1_F_C2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
314     if ((a == NULL) || (*a != ret))
315         ASN1_INTEGER_free(ret);
316     return NULL;
317 }
318 
asn1_string_get_int64(int64_t * pr,const ASN1_STRING * a,int itype)319 static int asn1_string_get_int64(int64_t *pr, const ASN1_STRING *a, int itype)
320 {
321     if (a == NULL) {
322         ASN1err(ASN1_F_ASN1_STRING_GET_INT64, ERR_R_PASSED_NULL_PARAMETER);
323         return 0;
324     }
325     if ((a->type & ~V_ASN1_NEG) != itype) {
326         ASN1err(ASN1_F_ASN1_STRING_GET_INT64, ASN1_R_WRONG_INTEGER_TYPE);
327         return 0;
328     }
329     return asn1_get_int64(pr, a->data, a->length, a->type & V_ASN1_NEG);
330 }
331 
asn1_string_set_int64(ASN1_STRING * a,int64_t r,int itype)332 static int asn1_string_set_int64(ASN1_STRING *a, int64_t r, int itype)
333 {
334     unsigned char tbuf[sizeof(r)];
335     size_t off;
336 
337     a->type = itype;
338     if (r < 0) {
339         /* Most obvious '-r' triggers undefined behaviour for most
340          * common INT64_MIN. Even though below '0 - (uint64_t)r' can
341          * appear two's-complement centric, it does produce correct/
342          * expected result even on one's-complement. This is because
343          * cast to unsigned has to change bit pattern... */
344         off = asn1_put_uint64(tbuf, 0 - (uint64_t)r);
345         a->type |= V_ASN1_NEG;
346     } else {
347         off = asn1_put_uint64(tbuf, r);
348         a->type &= ~V_ASN1_NEG;
349     }
350     return ASN1_STRING_set(a, tbuf + off, sizeof(tbuf) - off);
351 }
352 
asn1_string_get_uint64(uint64_t * pr,const ASN1_STRING * a,int itype)353 static int asn1_string_get_uint64(uint64_t *pr, const ASN1_STRING *a,
354                                   int itype)
355 {
356     if (a == NULL) {
357         ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ERR_R_PASSED_NULL_PARAMETER);
358         return 0;
359     }
360     if ((a->type & ~V_ASN1_NEG) != itype) {
361         ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ASN1_R_WRONG_INTEGER_TYPE);
362         return 0;
363     }
364     if (a->type & V_ASN1_NEG) {
365         ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
366         return 0;
367     }
368     return asn1_get_uint64(pr, a->data, a->length);
369 }
370 
asn1_string_set_uint64(ASN1_STRING * a,uint64_t r,int itype)371 static int asn1_string_set_uint64(ASN1_STRING *a, uint64_t r, int itype)
372 {
373     unsigned char tbuf[sizeof(r)];
374     size_t off;
375 
376     a->type = itype;
377     off = asn1_put_uint64(tbuf, r);
378     return ASN1_STRING_set(a, tbuf + off, sizeof(tbuf) - off);
379 }
380 
381 /*
382  * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1
383  * integers: some broken software can encode a positive INTEGER with its MSB
384  * set as negative (it doesn't add a padding zero).
385  */
386 
d2i_ASN1_UINTEGER(ASN1_INTEGER ** a,const unsigned char ** pp,long length)387 ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
388                                 long length)
389 {
390     ASN1_INTEGER *ret = NULL;
391     const unsigned char *p;
392     unsigned char *s;
393     long len;
394     int inf, tag, xclass;
395     int i;
396 
397     if ((a == NULL) || ((*a) == NULL)) {
398         if ((ret = ASN1_INTEGER_new()) == NULL)
399             return NULL;
400         ret->type = V_ASN1_INTEGER;
401     } else
402         ret = (*a);
403 
404     p = *pp;
405     inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
406     if (inf & 0x80) {
407         i = ASN1_R_BAD_OBJECT_HEADER;
408         goto err;
409     }
410 
411     if (tag != V_ASN1_INTEGER) {
412         i = ASN1_R_EXPECTING_AN_INTEGER;
413         goto err;
414     }
415 
416     /*
417      * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
418      * a missing NULL parameter.
419      */
420     s = OPENSSL_malloc((int)len + 1);
421     if (s == NULL) {
422         i = ERR_R_MALLOC_FAILURE;
423         goto err;
424     }
425     ret->type = V_ASN1_INTEGER;
426     if (len) {
427         if ((*p == 0) && (len != 1)) {
428             p++;
429             len--;
430         }
431         memcpy(s, p, (int)len);
432         p += len;
433     }
434 
435     OPENSSL_free(ret->data);
436     ret->data = s;
437     ret->length = (int)len;
438     if (a != NULL)
439         (*a) = ret;
440     *pp = p;
441     return ret;
442  err:
443     ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i);
444     if ((a == NULL) || (*a != ret))
445         ASN1_INTEGER_free(ret);
446     return NULL;
447 }
448 
bn_to_asn1_string(const BIGNUM * bn,ASN1_STRING * ai,int atype)449 static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai,
450                                       int atype)
451 {
452     ASN1_INTEGER *ret;
453     int len;
454 
455     if (ai == NULL) {
456         ret = ASN1_STRING_type_new(atype);
457     } else {
458         ret = ai;
459         ret->type = atype;
460     }
461 
462     if (ret == NULL) {
463         ASN1err(ASN1_F_BN_TO_ASN1_STRING, ERR_R_NESTED_ASN1_ERROR);
464         goto err;
465     }
466 
467     if (BN_is_negative(bn) && !BN_is_zero(bn))
468         ret->type |= V_ASN1_NEG_INTEGER;
469 
470     len = BN_num_bytes(bn);
471 
472     if (len == 0)
473         len = 1;
474 
475     if (ASN1_STRING_set(ret, NULL, len) == 0) {
476         ASN1err(ASN1_F_BN_TO_ASN1_STRING, ERR_R_MALLOC_FAILURE);
477         goto err;
478     }
479 
480     /* Correct zero case */
481     if (BN_is_zero(bn))
482         ret->data[0] = 0;
483     else
484         len = BN_bn2bin(bn, ret->data);
485     ret->length = len;
486     return ret;
487  err:
488     if (ret != ai)
489         ASN1_INTEGER_free(ret);
490     return NULL;
491 }
492 
asn1_string_to_bn(const ASN1_INTEGER * ai,BIGNUM * bn,int itype)493 static BIGNUM *asn1_string_to_bn(const ASN1_INTEGER *ai, BIGNUM *bn,
494                                  int itype)
495 {
496     BIGNUM *ret;
497 
498     if ((ai->type & ~V_ASN1_NEG) != itype) {
499         ASN1err(ASN1_F_ASN1_STRING_TO_BN, ASN1_R_WRONG_INTEGER_TYPE);
500         return NULL;
501     }
502 
503     ret = BN_bin2bn(ai->data, ai->length, bn);
504     if (ret == NULL) {
505         ASN1err(ASN1_F_ASN1_STRING_TO_BN, ASN1_R_BN_LIB);
506         return NULL;
507     }
508     if (ai->type & V_ASN1_NEG)
509         BN_set_negative(ret, 1);
510     return ret;
511 }
512 
ASN1_INTEGER_get_int64(int64_t * pr,const ASN1_INTEGER * a)513 int ASN1_INTEGER_get_int64(int64_t *pr, const ASN1_INTEGER *a)
514 {
515     return asn1_string_get_int64(pr, a, V_ASN1_INTEGER);
516 }
517 
ASN1_INTEGER_set_int64(ASN1_INTEGER * a,int64_t r)518 int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t r)
519 {
520     return asn1_string_set_int64(a, r, V_ASN1_INTEGER);
521 }
522 
ASN1_INTEGER_get_uint64(uint64_t * pr,const ASN1_INTEGER * a)523 int ASN1_INTEGER_get_uint64(uint64_t *pr, const ASN1_INTEGER *a)
524 {
525     return asn1_string_get_uint64(pr, a, V_ASN1_INTEGER);
526 }
527 
ASN1_INTEGER_set_uint64(ASN1_INTEGER * a,uint64_t r)528 int ASN1_INTEGER_set_uint64(ASN1_INTEGER *a, uint64_t r)
529 {
530     return asn1_string_set_uint64(a, r, V_ASN1_INTEGER);
531 }
532 
ASN1_INTEGER_set(ASN1_INTEGER * a,long v)533 int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
534 {
535     return ASN1_INTEGER_set_int64(a, v);
536 }
537 
ASN1_INTEGER_get(const ASN1_INTEGER * a)538 long ASN1_INTEGER_get(const ASN1_INTEGER *a)
539 {
540     int i;
541     int64_t r;
542     if (a == NULL)
543         return 0;
544     i = ASN1_INTEGER_get_int64(&r, a);
545     if (i == 0)
546         return -1;
547     if (r > LONG_MAX || r < LONG_MIN)
548         return -1;
549     return (long)r;
550 }
551 
BN_to_ASN1_INTEGER(const BIGNUM * bn,ASN1_INTEGER * ai)552 ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
553 {
554     return bn_to_asn1_string(bn, ai, V_ASN1_INTEGER);
555 }
556 
ASN1_INTEGER_to_BN(const ASN1_INTEGER * ai,BIGNUM * bn)557 BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
558 {
559     return asn1_string_to_bn(ai, bn, V_ASN1_INTEGER);
560 }
561 
ASN1_ENUMERATED_get_int64(int64_t * pr,const ASN1_ENUMERATED * a)562 int ASN1_ENUMERATED_get_int64(int64_t *pr, const ASN1_ENUMERATED *a)
563 {
564     return asn1_string_get_int64(pr, a, V_ASN1_ENUMERATED);
565 }
566 
ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED * a,int64_t r)567 int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t r)
568 {
569     return asn1_string_set_int64(a, r, V_ASN1_ENUMERATED);
570 }
571 
ASN1_ENUMERATED_set(ASN1_ENUMERATED * a,long v)572 int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
573 {
574     return ASN1_ENUMERATED_set_int64(a, v);
575 }
576 
ASN1_ENUMERATED_get(const ASN1_ENUMERATED * a)577 long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a)
578 {
579     int i;
580     int64_t r;
581     if (a == NULL)
582         return 0;
583     if ((a->type & ~V_ASN1_NEG) != V_ASN1_ENUMERATED)
584         return -1;
585     if (a->length > (int)sizeof(long))
586         return 0xffffffffL;
587     i = ASN1_ENUMERATED_get_int64(&r, a);
588     if (i == 0)
589         return -1;
590     if (r > LONG_MAX || r < LONG_MIN)
591         return -1;
592     return (long)r;
593 }
594 
BN_to_ASN1_ENUMERATED(const BIGNUM * bn,ASN1_ENUMERATED * ai)595 ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai)
596 {
597     return bn_to_asn1_string(bn, ai, V_ASN1_ENUMERATED);
598 }
599 
ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED * ai,BIGNUM * bn)600 BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn)
601 {
602     return asn1_string_to_bn(ai, bn, V_ASN1_ENUMERATED);
603 }
604 
605 /* Internal functions used by x_int64.c */
c2i_uint64_int(uint64_t * ret,int * neg,const unsigned char ** pp,long len)606 int c2i_uint64_int(uint64_t *ret, int *neg, const unsigned char **pp, long len)
607 {
608     unsigned char buf[sizeof(uint64_t)];
609     size_t buflen;
610 
611     buflen = c2i_ibuf(NULL, NULL, *pp, len);
612     if (buflen == 0)
613         return 0;
614     if (buflen > sizeof(uint64_t)) {
615         ASN1err(ASN1_F_C2I_UINT64_INT, ASN1_R_TOO_LARGE);
616         return 0;
617     }
618     (void)c2i_ibuf(buf, neg, *pp, len);
619     return asn1_get_uint64(ret, buf, buflen);
620 }
621 
i2c_uint64_int(unsigned char * p,uint64_t r,int neg)622 int i2c_uint64_int(unsigned char *p, uint64_t r, int neg)
623 {
624     unsigned char buf[sizeof(uint64_t)];
625     size_t off;
626 
627     off = asn1_put_uint64(buf, r);
628     return i2c_ibuf(buf + off, sizeof(buf) - off, neg, &p);
629 }
630 
631