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_CTX *c);
64 /* type is a 'bitmap' of acceptable string types.
65  */
d2i_ASN1_type_bytes(ASN1_STRING ** a,unsigned char ** pp,long length,int type)66 ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, unsigned char **pp,
67 	     long length, int type)
68 	{
69 	ASN1_STRING *ret=NULL;
70 	unsigned char *p,*s;
71 	long len;
72 	int inf,tag,xclass;
73 	int i=0;
74 
75 	p= *pp;
76 	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
77 	if (inf & 0x80) goto err;
78 
79 	if (tag >= 32)
80 		{
81 		i=ASN1_R_TAG_VALUE_TOO_HIGH;
82 		goto err;
83 		}
84 	if (!(ASN1_tag2bit(tag) & type))
85 		{
86 		i=ASN1_R_WRONG_TYPE;
87 		goto err;
88 		}
89 
90 	/* If a bit-string, exit early */
91 	if (tag == V_ASN1_BIT_STRING)
92 		return(d2i_ASN1_BIT_STRING(a,pp,length));
93 
94 	if ((a == NULL) || ((*a) == NULL))
95 		{
96 		if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
97 		}
98 	else
99 		ret=(*a);
100 
101 	if (len != 0)
102 		{
103 		s=(unsigned char *)OPENSSL_malloc((int)len+1);
104 		if (s == NULL)
105 			{
106 			i=ERR_R_MALLOC_FAILURE;
107 			goto err;
108 			}
109 		memcpy(s,p,(int)len);
110 		s[len]='\0';
111 		p+=len;
112 		}
113 	else
114 		s=NULL;
115 
116 	if (ret->data != NULL) OPENSSL_free(ret->data);
117 	ret->length=(int)len;
118 	ret->data=s;
119 	ret->type=tag;
120 	if (a != NULL) (*a)=ret;
121 	*pp=p;
122 	return(ret);
123 err:
124 	ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES,i);
125 	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
126 		ASN1_STRING_free(ret);
127 	return(NULL);
128 	}
129 
i2d_ASN1_bytes(ASN1_STRING * a,unsigned char ** pp,int tag,int xclass)130 int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
131 	{
132 	int ret,r,constructed;
133 	unsigned char *p;
134 
135 	if (a == NULL)  return(0);
136 
137 	if (tag == V_ASN1_BIT_STRING)
138 		return(i2d_ASN1_BIT_STRING(a,pp));
139 
140 	ret=a->length;
141 	r=ASN1_object_size(0,ret,tag);
142 	if (pp == NULL) return(r);
143 	p= *pp;
144 
145 	if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
146 		constructed=1;
147 	else
148 		constructed=0;
149 	ASN1_put_object(&p,constructed,ret,tag,xclass);
150 	memcpy(p,a->data,a->length);
151 	p+=a->length;
152 	*pp= p;
153 	return(r);
154 	}
155 
d2i_ASN1_bytes(ASN1_STRING ** a,unsigned char ** pp,long length,int Ptag,int Pclass)156 ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, unsigned char **pp, long length,
157 	     int Ptag, int Pclass)
158 	{
159 	ASN1_STRING *ret=NULL;
160 	unsigned char *p,*s;
161 	long len;
162 	int inf,tag,xclass;
163 	int i=0;
164 
165 	if ((a == NULL) || ((*a) == NULL))
166 		{
167 		if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
168 		}
169 	else
170 		ret=(*a);
171 
172 	p= *pp;
173 	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
174 	if (inf & 0x80)
175 		{
176 		i=ASN1_R_BAD_OBJECT_HEADER;
177 		goto err;
178 		}
179 
180 	if (tag != Ptag)
181 		{
182 		i=ASN1_R_WRONG_TAG;
183 		goto err;
184 		}
185 
186 	if (inf & V_ASN1_CONSTRUCTED)
187 		{
188 		ASN1_CTX c;
189 
190 		c.pp=pp;
191 		c.p=p;
192 		c.inf=inf;
193 		c.slen=len;
194 		c.tag=Ptag;
195 		c.xclass=Pclass;
196 		c.max=(length == 0)?0:(p+length);
197 		if (!asn1_collate_primitive(ret,&c))
198 			goto err;
199 		else
200 			{
201 			p=c.p;
202 			}
203 		}
204 	else
205 		{
206 		if (len != 0)
207 			{
208 			if ((ret->length < len) || (ret->data == NULL))
209 				{
210 				if (ret->data != NULL) OPENSSL_free(ret->data);
211 				s=(unsigned char *)OPENSSL_malloc((int)len + 1);
212 				if (s == NULL)
213 					{
214 					i=ERR_R_MALLOC_FAILURE;
215 					goto err;
216 					}
217 				}
218 			else
219 				s=ret->data;
220 			memcpy(s,p,(int)len);
221 			s[len] = '\0';
222 			p+=len;
223 			}
224 		else
225 			{
226 			s=NULL;
227 			if (ret->data != NULL) OPENSSL_free(ret->data);
228 			}
229 
230 		ret->length=(int)len;
231 		ret->data=s;
232 		ret->type=Ptag;
233 		}
234 
235 	if (a != NULL) (*a)=ret;
236 	*pp=p;
237 	return(ret);
238 err:
239 	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
240 		ASN1_STRING_free(ret);
241 	ASN1err(ASN1_F_D2I_ASN1_BYTES,i);
242 	return(NULL);
243 	}
244 
245 
246 /* We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse
247  * them into the one structure that is then returned */
248 /* There have been a few bug fixes for this function from
249  * Paul Keogh <paul.keogh@sse.ie>, many thanks to him */
asn1_collate_primitive(ASN1_STRING * a,ASN1_CTX * c)250 static int asn1_collate_primitive(ASN1_STRING *a, ASN1_CTX *c)
251 	{
252 	ASN1_STRING *os=NULL;
253 	BUF_MEM b;
254 	int num;
255 
256 	b.length=0;
257 	b.max=0;
258 	b.data=NULL;
259 
260 	if (a == NULL)
261 		{
262 		c->error=ERR_R_PASSED_NULL_PARAMETER;
263 		goto err;
264 		}
265 
266 	num=0;
267 	for (;;)
268 		{
269 		if (c->inf & 1)
270 			{
271 			c->eos=ASN1_check_infinite_end(&c->p,
272 				(long)(c->max-c->p));
273 			if (c->eos) break;
274 			}
275 		else
276 			{
277 			if (c->slen <= 0) break;
278 			}
279 
280 		c->q=c->p;
281 		if (d2i_ASN1_bytes(&os,&c->p,c->max-c->p,c->tag,c->xclass)
282 			== NULL)
283 			{
284 			c->error=ERR_R_ASN1_LIB;
285 			goto err;
286 			}
287 
288 		if (!BUF_MEM_grow_clean(&b,num+os->length))
289 			{
290 			c->error=ERR_R_BUF_LIB;
291 			goto err;
292 			}
293 		memcpy(&(b.data[num]),os->data,os->length);
294 		if (!(c->inf & 1))
295 			c->slen-=(c->p-c->q);
296 		num+=os->length;
297 		}
298 
299 	if (!asn1_Finish(c)) goto err;
300 
301 	a->length=num;
302 	if (a->data != NULL) OPENSSL_free(a->data);
303 	a->data=(unsigned char *)b.data;
304 	if (os != NULL) ASN1_STRING_free(os);
305 	return(1);
306 err:
307 	ASN1err(ASN1_F_ASN1_COLLATE_PRIMITIVE,c->error);
308 	if (os != NULL) ASN1_STRING_free(os);
309 	if (b.data != NULL) OPENSSL_free(b.data);
310 	return(0);
311 	}
312 
313