xref: /freebsd/crypto/openssl/crypto/asn1/f_int.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1  /*
2   * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
3   *
4   * Licensed under the Apache License 2.0 (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 "crypto/ctype.h"
12  #include "internal/cryptlib.h"
13  #include <openssl/buffer.h>
14  #include <openssl/asn1.h>
15  
i2a_ASN1_INTEGER(BIO * bp,const ASN1_INTEGER * a)16  int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
17  {
18      int i, n = 0;
19      static const char *h = "0123456789ABCDEF";
20      char buf[2];
21  
22      if (a == NULL)
23          return 0;
24  
25      if (a->type & V_ASN1_NEG) {
26          if (BIO_write(bp, "-", 1) != 1)
27              goto err;
28          n = 1;
29      }
30  
31      if (a->length == 0) {
32          if (BIO_write(bp, "00", 2) != 2)
33              goto err;
34          n += 2;
35      } else {
36          for (i = 0; i < a->length; i++) {
37              if ((i != 0) && (i % 35 == 0)) {
38                  if (BIO_write(bp, "\\\n", 2) != 2)
39                      goto err;
40                  n += 2;
41              }
42              buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
43              buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
44              if (BIO_write(bp, buf, 2) != 2)
45                  goto err;
46              n += 2;
47          }
48      }
49      return n;
50   err:
51      return -1;
52  }
53  
a2i_ASN1_INTEGER(BIO * bp,ASN1_INTEGER * bs,char * buf,int size)54  int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
55  {
56      int i, j, k, m, n, again, bufsize;
57      unsigned char *s = NULL, *sp;
58      unsigned char *bufp;
59      int num = 0, slen = 0, first = 1;
60  
61      bs->type = V_ASN1_INTEGER;
62  
63      bufsize = BIO_gets(bp, buf, size);
64      for (;;) {
65          if (bufsize < 1)
66              goto err;
67          i = bufsize;
68          if (buf[i - 1] == '\n')
69              buf[--i] = '\0';
70          if (i == 0)
71              goto err;
72          if (buf[i - 1] == '\r')
73              buf[--i] = '\0';
74          if (i == 0)
75              goto err;
76          again = (buf[i - 1] == '\\');
77  
78          for (j = 0; j < i; j++) {
79              if (!ossl_isxdigit(buf[j]))
80              {
81                  i = j;
82                  break;
83              }
84          }
85          buf[i] = '\0';
86          /*
87           * We have now cleared all the crap off the end of the line
88           */
89          if (i < 2)
90              goto err;
91  
92          bufp = (unsigned char *)buf;
93          if (first) {
94              first = 0;
95              if ((bufp[0] == '0') && (bufp[1] == '0')) {
96                  bufp += 2;
97                  i -= 2;
98              }
99          }
100          k = 0;
101          i -= again;
102          if (i % 2 != 0) {
103              ERR_raise(ERR_LIB_ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
104              OPENSSL_free(s);
105              return 0;
106          }
107          i /= 2;
108          if (num + i > slen) {
109              sp = OPENSSL_clear_realloc(s, slen, num + i * 2);
110              if (sp == NULL) {
111                  ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
112                  OPENSSL_free(s);
113                  return 0;
114              }
115              s = sp;
116              slen = num + i * 2;
117          }
118          for (j = 0; j < i; j++, k += 2) {
119              for (n = 0; n < 2; n++) {
120                  m = OPENSSL_hexchar2int(bufp[k + n]);
121                  if (m < 0) {
122                      ERR_raise(ERR_LIB_ASN1, ASN1_R_NON_HEX_CHARACTERS);
123                      goto err;
124                  }
125                  s[num + j] <<= 4;
126                  s[num + j] |= m;
127              }
128          }
129          num += i;
130          if (again)
131              bufsize = BIO_gets(bp, buf, size);
132          else
133              break;
134      }
135      bs->length = num;
136      bs->data = s;
137      return 1;
138   err:
139      ERR_raise(ERR_LIB_ASN1, ASN1_R_SHORT_LINE);
140      OPENSSL_free(s);
141      return 0;
142  }
143  
i2a_ASN1_ENUMERATED(BIO * bp,const ASN1_ENUMERATED * a)144  int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a)
145  {
146      return i2a_ASN1_INTEGER(bp, a);
147  }
148  
a2i_ASN1_ENUMERATED(BIO * bp,ASN1_ENUMERATED * bs,char * buf,int size)149  int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
150  {
151      int rv = a2i_ASN1_INTEGER(bp, bs, buf, size);
152      if (rv == 1)
153          bs->type = V_ASN1_INTEGER | (bs->type & V_ASN1_NEG);
154      return rv;
155  }
156