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