1 /*
2 * Copyright 1995-2024 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_STRING(BIO * bp,const ASN1_STRING * a,int type)16 int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type)
17 {
18 int i, n = 0;
19 char buf[2];
20
21 if (a == NULL)
22 return 0;
23
24 if (a->length == 0) {
25 if (BIO_write(bp, "0", 1) != 1)
26 goto err;
27 n = 1;
28 } else {
29 for (i = 0; i < a->length; i++) {
30 if ((i != 0) && (i % 35 == 0)) {
31 if (BIO_write(bp, "\\\n", 2) != 2)
32 goto err;
33 n += 2;
34 }
35 ossl_to_hex(buf, a->data[i]);
36 if (BIO_write(bp, buf, 2) != 2)
37 goto err;
38 n += 2;
39 }
40 }
41 return n;
42 err:
43 return -1;
44 }
45
a2i_ASN1_STRING(BIO * bp,ASN1_STRING * bs,char * buf,int size)46 int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
47 {
48 int i, j, k, m, n, again, bufsize;
49 unsigned char *s = NULL, *sp;
50 unsigned char *bufp;
51 int num = 0, slen = 0, first = 1;
52
53 bufsize = BIO_gets(bp, buf, size);
54 for (;;) {
55 if (bufsize < 1) {
56 if (first)
57 break;
58 else
59 goto err;
60 }
61 first = 0;
62
63 i = bufsize;
64 if (buf[i - 1] == '\n')
65 buf[--i] = '\0';
66 if (i == 0)
67 goto err;
68 if (buf[i - 1] == '\r')
69 buf[--i] = '\0';
70 if (i == 0)
71 goto err;
72 again = (buf[i - 1] == '\\');
73
74 for (j = i - 1; j > 0; j--) {
75 if (!ossl_isxdigit(buf[j])) {
76 i = j;
77 break;
78 }
79 }
80 buf[i] = '\0';
81 /*
82 * We have now cleared all the crap off the end of the line
83 */
84 if (i < 2)
85 goto err;
86
87 bufp = (unsigned char *)buf;
88
89 k = 0;
90 i -= again;
91 if (i % 2 != 0) {
92 ERR_raise(ERR_LIB_ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
93 OPENSSL_free(s);
94 return 0;
95 }
96 i /= 2;
97 if (num + i > slen) {
98 sp = OPENSSL_realloc(s, (unsigned int)num + i * 2);
99 if (sp == NULL) {
100 OPENSSL_free(s);
101 return 0;
102 }
103 s = sp;
104 slen = num + i * 2;
105 }
106 for (j = 0; j < i; j++, k += 2) {
107 for (n = 0; n < 2; n++) {
108 m = OPENSSL_hexchar2int(bufp[k + n]);
109 if (m < 0) {
110 ERR_raise(ERR_LIB_ASN1, ASN1_R_NON_HEX_CHARACTERS);
111 OPENSSL_free(s);
112 return 0;
113 }
114 s[num + j] <<= 4;
115 s[num + j] |= m;
116 }
117 }
118 num += i;
119 if (again)
120 bufsize = BIO_gets(bp, buf, size);
121 else
122 break;
123 }
124 bs->length = num;
125 bs->data = s;
126 return 1;
127
128 err:
129 ERR_raise(ERR_LIB_ASN1, ASN1_R_SHORT_LINE);
130 OPENSSL_free(s);
131 return 0;
132 }
133