xref: /minix3/crypto/external/bsd/openssl/dist/crypto/asn1/f_enum.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1ebfedea0SLionel Sambuc /* crypto/asn1/f_enum.c */
2ebfedea0SLionel Sambuc /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3ebfedea0SLionel Sambuc  * All rights reserved.
4ebfedea0SLionel Sambuc  *
5ebfedea0SLionel Sambuc  * This package is an SSL implementation written
6ebfedea0SLionel Sambuc  * by Eric Young (eay@cryptsoft.com).
7ebfedea0SLionel Sambuc  * The implementation was written so as to conform with Netscapes SSL.
8ebfedea0SLionel Sambuc  *
9ebfedea0SLionel Sambuc  * This library is free for commercial and non-commercial use as long as
10ebfedea0SLionel Sambuc  * the following conditions are aheared to.  The following conditions
11ebfedea0SLionel Sambuc  * apply to all code found in this distribution, be it the RC4, RSA,
12ebfedea0SLionel Sambuc  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13ebfedea0SLionel Sambuc  * included with this distribution is covered by the same copyright terms
14ebfedea0SLionel Sambuc  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15ebfedea0SLionel Sambuc  *
16ebfedea0SLionel Sambuc  * Copyright remains Eric Young's, and as such any Copyright notices in
17ebfedea0SLionel Sambuc  * the code are not to be removed.
18ebfedea0SLionel Sambuc  * If this package is used in a product, Eric Young should be given attribution
19ebfedea0SLionel Sambuc  * as the author of the parts of the library used.
20ebfedea0SLionel Sambuc  * This can be in the form of a textual message at program startup or
21ebfedea0SLionel Sambuc  * in documentation (online or textual) provided with the package.
22ebfedea0SLionel Sambuc  *
23ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
24ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
25ebfedea0SLionel Sambuc  * are met:
26ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the copyright
27ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
28ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
29ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
30ebfedea0SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
31ebfedea0SLionel Sambuc  * 3. All advertising materials mentioning features or use of this software
32ebfedea0SLionel Sambuc  *    must display the following acknowledgement:
33ebfedea0SLionel Sambuc  *    "This product includes cryptographic software written by
34ebfedea0SLionel Sambuc  *     Eric Young (eay@cryptsoft.com)"
35ebfedea0SLionel Sambuc  *    The word 'cryptographic' can be left out if the rouines from the library
36ebfedea0SLionel Sambuc  *    being used are not cryptographic related :-).
37ebfedea0SLionel Sambuc  * 4. If you include any Windows specific code (or a derivative thereof) from
38ebfedea0SLionel Sambuc  *    the apps directory (application code) you must include an acknowledgement:
39ebfedea0SLionel Sambuc  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40ebfedea0SLionel Sambuc  *
41ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42ebfedea0SLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43ebfedea0SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44ebfedea0SLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45ebfedea0SLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46ebfedea0SLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47ebfedea0SLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48ebfedea0SLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49ebfedea0SLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50ebfedea0SLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51ebfedea0SLionel Sambuc  * SUCH DAMAGE.
52ebfedea0SLionel Sambuc  *
53ebfedea0SLionel Sambuc  * The licence and distribution terms for any publically available version or
54ebfedea0SLionel Sambuc  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55ebfedea0SLionel Sambuc  * copied and put under another distribution licence
56ebfedea0SLionel Sambuc  * [including the GNU Public Licence.]
57ebfedea0SLionel Sambuc  */
58ebfedea0SLionel Sambuc 
59ebfedea0SLionel Sambuc #include <stdio.h>
60ebfedea0SLionel Sambuc #include "cryptlib.h"
61ebfedea0SLionel Sambuc #include <openssl/buffer.h>
62ebfedea0SLionel Sambuc #include <openssl/asn1.h>
63ebfedea0SLionel Sambuc 
64ebfedea0SLionel Sambuc /* Based on a_int.c: equivalent ENUMERATED functions */
65ebfedea0SLionel Sambuc 
i2a_ASN1_ENUMERATED(BIO * bp,ASN1_ENUMERATED * a)66ebfedea0SLionel Sambuc int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
67ebfedea0SLionel Sambuc {
68ebfedea0SLionel Sambuc     int i, n = 0;
69ebfedea0SLionel Sambuc     static const char *h = "0123456789ABCDEF";
70ebfedea0SLionel Sambuc     char buf[2];
71ebfedea0SLionel Sambuc 
72*0a6a1f1dSLionel Sambuc     if (a == NULL)
73*0a6a1f1dSLionel Sambuc         return (0);
74ebfedea0SLionel Sambuc 
75*0a6a1f1dSLionel Sambuc     if (a->length == 0) {
76*0a6a1f1dSLionel Sambuc         if (BIO_write(bp, "00", 2) != 2)
77*0a6a1f1dSLionel Sambuc             goto err;
78ebfedea0SLionel Sambuc         n = 2;
79*0a6a1f1dSLionel Sambuc     } else {
80*0a6a1f1dSLionel Sambuc         for (i = 0; i < a->length; i++) {
81*0a6a1f1dSLionel Sambuc             if ((i != 0) && (i % 35 == 0)) {
82*0a6a1f1dSLionel Sambuc                 if (BIO_write(bp, "\\\n", 2) != 2)
83*0a6a1f1dSLionel Sambuc                     goto err;
84ebfedea0SLionel Sambuc                 n += 2;
85ebfedea0SLionel Sambuc             }
86ebfedea0SLionel Sambuc             buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
87ebfedea0SLionel Sambuc             buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
88*0a6a1f1dSLionel Sambuc             if (BIO_write(bp, buf, 2) != 2)
89*0a6a1f1dSLionel Sambuc                 goto err;
90ebfedea0SLionel Sambuc             n += 2;
91ebfedea0SLionel Sambuc         }
92ebfedea0SLionel Sambuc     }
93ebfedea0SLionel Sambuc     return (n);
94ebfedea0SLionel Sambuc  err:
95ebfedea0SLionel Sambuc     return (-1);
96ebfedea0SLionel Sambuc }
97ebfedea0SLionel Sambuc 
a2i_ASN1_ENUMERATED(BIO * bp,ASN1_ENUMERATED * bs,char * buf,int size)98ebfedea0SLionel Sambuc int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
99ebfedea0SLionel Sambuc {
100ebfedea0SLionel Sambuc     int ret = 0;
101ebfedea0SLionel Sambuc     int i, j, k, m, n, again, bufsize;
102ebfedea0SLionel Sambuc     unsigned char *s = NULL, *sp;
103ebfedea0SLionel Sambuc     unsigned char *bufp;
104ebfedea0SLionel Sambuc     int num = 0, slen = 0, first = 1;
105ebfedea0SLionel Sambuc 
106ebfedea0SLionel Sambuc     bs->type = V_ASN1_ENUMERATED;
107ebfedea0SLionel Sambuc 
108ebfedea0SLionel Sambuc     bufsize = BIO_gets(bp, buf, size);
109*0a6a1f1dSLionel Sambuc     for (;;) {
110*0a6a1f1dSLionel Sambuc         if (bufsize < 1)
111*0a6a1f1dSLionel Sambuc             goto err_sl;
112ebfedea0SLionel Sambuc         i = bufsize;
113*0a6a1f1dSLionel Sambuc         if (buf[i - 1] == '\n')
114*0a6a1f1dSLionel Sambuc             buf[--i] = '\0';
115*0a6a1f1dSLionel Sambuc         if (i == 0)
116*0a6a1f1dSLionel Sambuc             goto err_sl;
117*0a6a1f1dSLionel Sambuc         if (buf[i - 1] == '\r')
118*0a6a1f1dSLionel Sambuc             buf[--i] = '\0';
119*0a6a1f1dSLionel Sambuc         if (i == 0)
120*0a6a1f1dSLionel Sambuc             goto err_sl;
121ebfedea0SLionel Sambuc         again = (buf[i - 1] == '\\');
122ebfedea0SLionel Sambuc 
123*0a6a1f1dSLionel Sambuc         for (j = 0; j < i; j++) {
124ebfedea0SLionel Sambuc             if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
125ebfedea0SLionel Sambuc                   ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
126*0a6a1f1dSLionel Sambuc                   ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
127ebfedea0SLionel Sambuc                 i = j;
128ebfedea0SLionel Sambuc                 break;
129ebfedea0SLionel Sambuc             }
130ebfedea0SLionel Sambuc         }
131ebfedea0SLionel Sambuc         buf[i] = '\0';
132*0a6a1f1dSLionel Sambuc         /*
133*0a6a1f1dSLionel Sambuc          * We have now cleared all the crap off the end of the line
134*0a6a1f1dSLionel Sambuc          */
135*0a6a1f1dSLionel Sambuc         if (i < 2)
136*0a6a1f1dSLionel Sambuc             goto err_sl;
137ebfedea0SLionel Sambuc 
138ebfedea0SLionel Sambuc         bufp = (unsigned char *)buf;
139*0a6a1f1dSLionel Sambuc         if (first) {
140ebfedea0SLionel Sambuc             first = 0;
141*0a6a1f1dSLionel Sambuc             if ((bufp[0] == '0') && (buf[1] == '0')) {
142ebfedea0SLionel Sambuc                 bufp += 2;
143ebfedea0SLionel Sambuc                 i -= 2;
144ebfedea0SLionel Sambuc             }
145ebfedea0SLionel Sambuc         }
146ebfedea0SLionel Sambuc         k = 0;
147ebfedea0SLionel Sambuc         i -= again;
148*0a6a1f1dSLionel Sambuc         if (i % 2 != 0) {
149ebfedea0SLionel Sambuc             ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_ODD_NUMBER_OF_CHARS);
150ebfedea0SLionel Sambuc             goto err;
151ebfedea0SLionel Sambuc         }
152ebfedea0SLionel Sambuc         i /= 2;
153*0a6a1f1dSLionel Sambuc         if (num + i > slen) {
154ebfedea0SLionel Sambuc             if (s == NULL)
155*0a6a1f1dSLionel Sambuc                 sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
156*0a6a1f1dSLionel Sambuc                                                      i * 2);
157ebfedea0SLionel Sambuc             else
158ebfedea0SLionel Sambuc                 sp = (unsigned char *)OPENSSL_realloc(s,
159*0a6a1f1dSLionel Sambuc                                                       (unsigned int)num +
160*0a6a1f1dSLionel Sambuc                                                       i * 2);
161*0a6a1f1dSLionel Sambuc             if (sp == NULL) {
162ebfedea0SLionel Sambuc                 ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
163*0a6a1f1dSLionel Sambuc                 if (s != NULL)
164*0a6a1f1dSLionel Sambuc                     OPENSSL_free(s);
165ebfedea0SLionel Sambuc                 goto err;
166ebfedea0SLionel Sambuc             }
167ebfedea0SLionel Sambuc             s = sp;
168ebfedea0SLionel Sambuc             slen = num + i * 2;
169ebfedea0SLionel Sambuc         }
170*0a6a1f1dSLionel Sambuc         for (j = 0; j < i; j++, k += 2) {
171*0a6a1f1dSLionel Sambuc             for (n = 0; n < 2; n++) {
172ebfedea0SLionel Sambuc                 m = bufp[k + n];
173ebfedea0SLionel Sambuc                 if ((m >= '0') && (m <= '9'))
174ebfedea0SLionel Sambuc                     m -= '0';
175ebfedea0SLionel Sambuc                 else if ((m >= 'a') && (m <= 'f'))
176ebfedea0SLionel Sambuc                     m = m - 'a' + 10;
177ebfedea0SLionel Sambuc                 else if ((m >= 'A') && (m <= 'F'))
178ebfedea0SLionel Sambuc                     m = m - 'A' + 10;
179*0a6a1f1dSLionel Sambuc                 else {
180*0a6a1f1dSLionel Sambuc                     ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,
181*0a6a1f1dSLionel Sambuc                             ASN1_R_NON_HEX_CHARACTERS);
182ebfedea0SLionel Sambuc                     goto err;
183ebfedea0SLionel Sambuc                 }
184ebfedea0SLionel Sambuc                 s[num + j] <<= 4;
185ebfedea0SLionel Sambuc                 s[num + j] |= m;
186ebfedea0SLionel Sambuc             }
187ebfedea0SLionel Sambuc         }
188ebfedea0SLionel Sambuc         num += i;
189ebfedea0SLionel Sambuc         if (again)
190ebfedea0SLionel Sambuc             bufsize = BIO_gets(bp, buf, size);
191ebfedea0SLionel Sambuc         else
192ebfedea0SLionel Sambuc             break;
193ebfedea0SLionel Sambuc     }
194ebfedea0SLionel Sambuc     bs->length = num;
195ebfedea0SLionel Sambuc     bs->data = s;
196ebfedea0SLionel Sambuc     ret = 1;
197ebfedea0SLionel Sambuc  err:
198*0a6a1f1dSLionel Sambuc     if (0) {
199ebfedea0SLionel Sambuc  err_sl:
200ebfedea0SLionel Sambuc         ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_SHORT_LINE);
201ebfedea0SLionel Sambuc     }
202ebfedea0SLionel Sambuc     return (ret);
203ebfedea0SLionel Sambuc }
204