Line data Source code
1 : /* crypto/asn1/a_bytes.c */
2 : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : * All rights reserved.
4 : *
5 : * This package is an SSL implementation written
6 : * by Eric Young (eay@cryptsoft.com).
7 : * The implementation was written so as to conform with Netscapes SSL.
8 : *
9 : * This library is free for commercial and non-commercial use as long as
10 : * the following conditions are aheared to. The following conditions
11 : * apply to all code found in this distribution, be it the RC4, RSA,
12 : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : * included with this distribution is covered by the same copyright terms
14 : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : *
16 : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : * the code are not to be removed.
18 : * If this package is used in a product, Eric Young should be given attribution
19 : * as the author of the parts of the library used.
20 : * This can be in the form of a textual message at program startup or
21 : * in documentation (online or textual) provided with the package.
22 : *
23 : * Redistribution and use in source and binary forms, with or without
24 : * modification, are permitted provided that the following conditions
25 : * are met:
26 : * 1. Redistributions of source code must retain the copyright
27 : * notice, this list of conditions and the following disclaimer.
28 : * 2. Redistributions in binary form must reproduce the above copyright
29 : * notice, this list of conditions and the following disclaimer in the
30 : * documentation and/or other materials provided with the distribution.
31 : * 3. All advertising materials mentioning features or use of this software
32 : * must display the following acknowledgement:
33 : * "This product includes cryptographic software written by
34 : * Eric Young (eay@cryptsoft.com)"
35 : * The word 'cryptographic' can be left out if the rouines from the library
36 : * being used are not cryptographic related :-).
37 : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : * the apps directory (application code) you must include an acknowledgement:
39 : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : *
41 : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : * SUCH DAMAGE.
52 : *
53 : * The licence and distribution terms for any publically available version or
54 : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : * copied and put under another distribution licence
56 : * [including the GNU Public Licence.]
57 : */
58 :
59 : #include <stdio.h>
60 : #include "cryptlib.h"
61 : #include <openssl/asn1.h>
62 :
63 : static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
64 : /*
65 : * type is a 'bitmap' of acceptable string types.
66 : */
67 0 : ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
68 : long length, int type)
69 : {
70 : ASN1_STRING *ret = NULL;
71 : const unsigned char *p;
72 : unsigned char *s;
73 : long len;
74 : int inf, tag, xclass;
75 : int i = 0;
76 :
77 0 : p = *pp;
78 0 : inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
79 0 : if (inf & 0x80)
80 : goto err;
81 :
82 0 : if (tag >= 32) {
83 : i = ASN1_R_TAG_VALUE_TOO_HIGH;
84 : goto err;
85 : }
86 0 : if (!(ASN1_tag2bit(tag) & type)) {
87 : i = ASN1_R_WRONG_TYPE;
88 : goto err;
89 : }
90 :
91 : /* If a bit-string, exit early */
92 0 : if (tag == V_ASN1_BIT_STRING)
93 0 : return (d2i_ASN1_BIT_STRING(a, pp, length));
94 :
95 0 : if ((a == NULL) || ((*a) == NULL)) {
96 0 : if ((ret = ASN1_STRING_new()) == NULL)
97 : return (NULL);
98 : } else
99 : ret = (*a);
100 :
101 0 : if (len != 0) {
102 0 : s = (unsigned char *)OPENSSL_malloc((int)len + 1);
103 0 : if (s == NULL) {
104 : i = ERR_R_MALLOC_FAILURE;
105 : goto err;
106 : }
107 0 : memcpy(s, p, (int)len);
108 0 : s[len] = '\0';
109 0 : p += len;
110 : } else
111 : s = NULL;
112 :
113 0 : if (ret->data != NULL)
114 0 : OPENSSL_free(ret->data);
115 0 : ret->length = (int)len;
116 0 : ret->data = s;
117 0 : ret->type = tag;
118 0 : if (a != NULL)
119 0 : (*a) = ret;
120 0 : *pp = p;
121 0 : return (ret);
122 : err:
123 0 : ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES, i);
124 0 : if ((ret != NULL) && ((a == NULL) || (*a != ret)))
125 0 : ASN1_STRING_free(ret);
126 : return (NULL);
127 : }
128 :
129 0 : int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
130 : {
131 : int ret, r, constructed;
132 : unsigned char *p;
133 :
134 0 : if (a == NULL)
135 : return (0);
136 :
137 0 : if (tag == V_ASN1_BIT_STRING)
138 0 : return (i2d_ASN1_BIT_STRING(a, pp));
139 :
140 0 : ret = a->length;
141 0 : r = ASN1_object_size(0, ret, tag);
142 0 : if (pp == NULL)
143 : return (r);
144 0 : p = *pp;
145 :
146 0 : if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
147 : constructed = 1;
148 : else
149 : constructed = 0;
150 0 : ASN1_put_object(&p, constructed, ret, tag, xclass);
151 0 : memcpy(p, a->data, a->length);
152 0 : p += a->length;
153 0 : *pp = p;
154 0 : return (r);
155 : }
156 :
157 0 : ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
158 : long length, int Ptag, int Pclass)
159 : {
160 : ASN1_STRING *ret = NULL;
161 : const unsigned char *p;
162 : unsigned char *s;
163 : long len;
164 : int inf, tag, xclass;
165 : int i = 0;
166 :
167 0 : if ((a == NULL) || ((*a) == NULL)) {
168 0 : if ((ret = ASN1_STRING_new()) == NULL)
169 : return (NULL);
170 : } else
171 : ret = (*a);
172 :
173 0 : p = *pp;
174 0 : inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
175 0 : if (inf & 0x80) {
176 : i = ASN1_R_BAD_OBJECT_HEADER;
177 : goto err;
178 : }
179 :
180 0 : if (tag != Ptag) {
181 : i = ASN1_R_WRONG_TAG;
182 : goto err;
183 : }
184 :
185 0 : if (inf & V_ASN1_CONSTRUCTED) {
186 : ASN1_const_CTX c;
187 :
188 0 : c.pp = pp;
189 0 : c.p = p;
190 0 : c.inf = inf;
191 0 : c.slen = len;
192 0 : c.tag = Ptag;
193 0 : c.xclass = Pclass;
194 0 : c.max = (length == 0) ? 0 : (p + length);
195 0 : if (!asn1_collate_primitive(ret, &c))
196 : goto err;
197 : else {
198 0 : p = c.p;
199 : }
200 : } else {
201 0 : if (len != 0) {
202 0 : if ((ret->length < len) || (ret->data == NULL)) {
203 0 : if (ret->data != NULL)
204 0 : OPENSSL_free(ret->data);
205 0 : s = (unsigned char *)OPENSSL_malloc((int)len + 1);
206 0 : if (s == NULL) {
207 : i = ERR_R_MALLOC_FAILURE;
208 : goto err;
209 : }
210 : } else
211 : s = ret->data;
212 0 : memcpy(s, p, (int)len);
213 0 : s[len] = '\0';
214 0 : p += len;
215 : } else {
216 : s = NULL;
217 0 : if (ret->data != NULL)
218 0 : OPENSSL_free(ret->data);
219 : }
220 :
221 0 : ret->length = (int)len;
222 0 : ret->data = s;
223 0 : ret->type = Ptag;
224 : }
225 :
226 0 : if (a != NULL)
227 0 : (*a) = ret;
228 0 : *pp = p;
229 0 : return (ret);
230 : err:
231 0 : if ((ret != NULL) && ((a == NULL) || (*a != ret)))
232 0 : ASN1_STRING_free(ret);
233 0 : ASN1err(ASN1_F_D2I_ASN1_BYTES, i);
234 0 : return (NULL);
235 : }
236 :
237 : /*
238 : * We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse them
239 : * into the one structure that is then returned
240 : */
241 : /*
242 : * There have been a few bug fixes for this function from Paul Keogh
243 : * <paul.keogh@sse.ie>, many thanks to him
244 : */
245 0 : static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
246 : {
247 0 : ASN1_STRING *os = NULL;
248 : BUF_MEM b;
249 : int num;
250 :
251 0 : b.length = 0;
252 0 : b.max = 0;
253 0 : b.data = NULL;
254 :
255 0 : if (a == NULL) {
256 0 : c->error = ERR_R_PASSED_NULL_PARAMETER;
257 0 : goto err;
258 : }
259 :
260 : num = 0;
261 : for (;;) {
262 0 : if (c->inf & 1) {
263 0 : c->eos = ASN1_const_check_infinite_end(&c->p,
264 0 : (long)(c->max - c->p));
265 0 : if (c->eos)
266 : break;
267 : } else {
268 0 : if (c->slen <= 0)
269 : break;
270 : }
271 :
272 0 : c->q = c->p;
273 0 : if (d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass)
274 : == NULL) {
275 0 : c->error = ERR_R_ASN1_LIB;
276 0 : goto err;
277 : }
278 :
279 0 : if (!BUF_MEM_grow_clean(&b, num + os->length)) {
280 0 : c->error = ERR_R_BUF_LIB;
281 0 : goto err;
282 : }
283 0 : memcpy(&(b.data[num]), os->data, os->length);
284 0 : if (!(c->inf & 1))
285 0 : c->slen -= (c->p - c->q);
286 0 : num += os->length;
287 0 : }
288 :
289 0 : if (!asn1_const_Finish(c))
290 : goto err;
291 :
292 0 : a->length = num;
293 0 : if (a->data != NULL)
294 0 : OPENSSL_free(a->data);
295 0 : a->data = (unsigned char *)b.data;
296 0 : if (os != NULL)
297 0 : ASN1_STRING_free(os);
298 : return (1);
299 : err:
300 0 : ASN1err(ASN1_F_ASN1_COLLATE_PRIMITIVE, c->error);
301 0 : if (os != NULL)
302 0 : ASN1_STRING_free(os);
303 0 : if (b.data != NULL)
304 0 : OPENSSL_free(b.data);
305 : return (0);
306 : }
|