]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/asn1/asn1_par.c
Import of old SSLeay release: SSLeay 0.8.1b
[thirdparty/openssl.git] / crypto / asn1 / asn1_par.c
1 /* crypto/asn1/asn1_par.c */
2 /* Copyright (C) 1995-1997 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 "buffer.h"
62 #include "objects.h"
63 #include "x509.h"
64
65 #ifndef NOPROTO
66 static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed,
67 int indent);
68 static int asn1_parse2(BIO *bp, unsigned char **pp, long length,
69 int offset, int depth, int indent);
70 #else
71 static int asn1_print_info();
72 static int asn1_parse2();
73 #endif
74
75 static int asn1_print_info(bp, tag, xclass, constructed,indent)
76 BIO *bp;
77 int tag;
78 int xclass;
79 int constructed;
80 int indent;
81 {
82 static char *fmt="%-18s";
83 static char *fmt2="%2d %-15s";
84 char *p,str[128],*p2=NULL;
85
86 if (constructed & V_ASN1_CONSTRUCTED)
87 p="cons: ";
88 else
89 p="prim: ";
90 if (BIO_write(bp,p,6) < 6) goto err;
91 if (indent)
92 {
93 if (indent > 128) indent=128;
94 memset(str,' ',indent);
95 if (BIO_write(bp,str,indent) < indent) goto err;
96 }
97
98 p=str;
99 if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
100 sprintf(str,"priv [ %d ] ",tag);
101 else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
102 sprintf(str,"cont [ %d ]",tag);
103 else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
104 sprintf(str,"appl [ %d ]",tag);
105 else if ((tag == V_ASN1_EOC) /* && (xclass == V_ASN1_UNIVERSAL) */)
106 p="EOC";
107 else if (tag == V_ASN1_BOOLEAN)
108 p="BOOLEAN";
109 else if (tag == V_ASN1_INTEGER)
110 p="INTEGER";
111 else if (tag == V_ASN1_BIT_STRING)
112 p="BIT STRING";
113 else if (tag == V_ASN1_OCTET_STRING)
114 p="OCTET STRING";
115 else if (tag == V_ASN1_NULL)
116 p="NULL";
117 else if (tag == V_ASN1_OBJECT)
118 p="OBJECT";
119 else if (tag == V_ASN1_SEQUENCE)
120 p="SEQUENCE";
121 else if (tag == V_ASN1_SET)
122 p="SET";
123 else if (tag == V_ASN1_PRINTABLESTRING)
124 p="PRINTABLESTRING";
125 else if (tag == V_ASN1_T61STRING)
126 p="T61STRING";
127 else if (tag == V_ASN1_IA5STRING)
128 p="IA5STRING";
129 else if (tag == V_ASN1_UTCTIME)
130 p="UTCTIME";
131
132 /* extras */
133 else if (tag == V_ASN1_NUMERICSTRING)
134 p="NUMERICSTRING";
135 else if (tag == V_ASN1_VIDEOTEXSTRING)
136 p="VIDEOTEXSTRING";
137 else if (tag == V_ASN1_GENERALIZEDTIME)
138 p="GENERALIZEDTIME";
139 else if (tag == V_ASN1_GRAPHICSTRING)
140 p="GRAPHICSTRING";
141 else if (tag == V_ASN1_ISO64STRING)
142 p="ISO64STRING";
143 else if (tag == V_ASN1_GENERALSTRING)
144 p="GENERALSTRING";
145 else if (tag == V_ASN1_UNIVERSALSTRING)
146 p="UNIVERSALSTRING";
147
148 else
149 p2="(unknown)";
150
151 if (p2 != NULL)
152 {
153 if (BIO_printf(bp,fmt2,tag,p2) <= 0) goto err;
154 }
155 else
156 {
157 if (BIO_printf(bp,fmt,p) <= 0) goto err;
158 }
159 return(1);
160 err:
161 return(0);
162 }
163
164 int ASN1_parse(bp, pp, len, indent)
165 BIO *bp;
166 unsigned char *pp;
167 long len;
168 int indent;
169 {
170 return(asn1_parse2(bp,&pp,len,0,0,indent));
171 }
172
173 static int asn1_parse2(bp, pp, length, offset, depth, indent)
174 BIO *bp;
175 unsigned char **pp;
176 long length;
177 int offset;
178 int depth;
179 int indent;
180 {
181 unsigned char *p,*ep,*tot,*op,*opp;
182 long len;
183 int tag,xclass,ret=0;
184 int nl,hl,j,r;
185 ASN1_OBJECT *o=NULL;
186 ASN1_OCTET_STRING *os=NULL;
187
188 p= *pp;
189 tot=p+length;
190 op=p-1;
191 while ((p < tot) && (op < p))
192 {
193 op=p;
194 j=ASN1_get_object(&p,&len,&tag,&xclass,length);
195 #ifdef LINT
196 j=j;
197 #endif
198 if (j & 0x80)
199 {
200 if (BIO_write(bp,"Error in encoding\n",18) <= 0)
201 goto end;
202 ret=0;
203 goto end;
204 }
205 hl=(p-op);
206 length-=hl;
207 /* if j == 0x21 it is a constructed indefinite length object */
208 if (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp))
209 <= 0) goto end;
210
211 if (j != (V_ASN1_CONSTRUCTED | 1))
212 {
213 if (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ",
214 depth,(long)hl,len) <= 0)
215 goto end;
216 }
217 else
218 {
219 if (BIO_printf(bp,"d=%-2d hl=%ld l=inf ",
220 depth,(long)hl) <= 0)
221 goto end;
222 }
223 if (!asn1_print_info(bp,tag,xclass,j,(indent)?depth:0))
224 goto end;
225 if (j & V_ASN1_CONSTRUCTED)
226 {
227 ep=p+len;
228 if (BIO_write(bp,"\n",1) <= 0) goto end;
229 if (len > length)
230 {
231 BIO_printf(bp,
232 "length is greater than %ld\n",length);
233 ret=0;
234 goto end;
235 }
236 if ((j == 0x21) && (len == 0))
237 {
238 for (;;)
239 {
240 r=asn1_parse2(bp,&p,(long)(tot-p),
241 offset+(p - *pp),depth+1,
242 indent);
243 if (r == 0) { ret=0; goto end; }
244 if ((r == 2) || (p >= tot)) break;
245 }
246 }
247 else
248 while (p < ep)
249 {
250 r=asn1_parse2(bp,&p,(long)len,
251 offset+(p - *pp),depth+1,
252 indent);
253 if (r == 0) { ret=0; goto end; }
254 }
255 }
256 else if (xclass != 0)
257 {
258 p+=len;
259 if (BIO_write(bp,"\n",1) <= 0) goto end;
260 }
261 else
262 {
263 nl=0;
264 if ( (tag == V_ASN1_PRINTABLESTRING) ||
265 (tag == V_ASN1_T61STRING) ||
266 (tag == V_ASN1_IA5STRING) ||
267 (tag == V_ASN1_UTCTIME))
268 {
269 if (BIO_write(bp,":",1) <= 0) goto end;
270 if ((len > 0) &&
271 BIO_write(bp,(char *)p,(int)len)
272 != (int)len)
273 goto end;
274 }
275 else if (tag == V_ASN1_OBJECT)
276 {
277 opp=op;
278 if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
279 {
280 if (BIO_write(bp,":",1) <= 0) goto end;
281 i2a_ASN1_OBJECT(bp,o);
282 }
283 else
284 {
285 if (BIO_write(bp,":BAD OBJECT",11) <= 0)
286 goto end;
287 }
288 }
289 else if (tag == V_ASN1_BOOLEAN)
290 {
291 int ii;
292
293 opp=op;
294 ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
295 if (ii < 0)
296 {
297 if (BIO_write(bp,"Bad boolean\n",12))
298 goto end;
299 }
300 BIO_printf(bp,":%d",ii);
301 }
302 else if (tag == V_ASN1_OCTET_STRING)
303 {
304 int i,printable=1;
305
306 opp=op;
307 os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
308 if (os != NULL)
309 {
310 opp=os->data;
311 for (i=0; i<os->length; i++)
312 {
313 if (( (opp[i] < ' ') &&
314 (opp[i] != '\n') &&
315 (opp[i] != '\r') &&
316 (opp[i] != '\t')) ||
317 (opp[i] > '~'))
318 {
319 printable=0;
320 break;
321 }
322 }
323 if (printable && (os->length > 0))
324 {
325 if (BIO_write(bp,":",1) <= 0)
326 goto end;
327 if (BIO_write(bp,(char *)opp,
328 os->length) <= 0)
329 goto end;
330 }
331 ASN1_OCTET_STRING_free(os);
332 os=NULL;
333 }
334 }
335 else if (tag == V_ASN1_INTEGER)
336 {
337 ASN1_INTEGER *bs;
338 int i;
339
340 opp=op;
341 bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
342 if (bs != NULL)
343 {
344 if (BIO_write(bp,":",1) <= 0) goto end;
345 if (bs->type == V_ASN1_NEG_INTEGER)
346 if (BIO_write(bp,"-",1) <= 0)
347 goto end;
348 for (i=0; i<bs->length; i++)
349 {
350 if (BIO_printf(bp,"%02X",
351 bs->data[i]) <= 0)
352 goto end;
353 }
354 if (bs->length == 0)
355 {
356 if (BIO_write(bp,"00",2) <= 0)
357 goto end;
358 }
359 }
360 else
361 {
362 if (BIO_write(bp,"BAD INTEGER",11) <= 0)
363 goto end;
364 }
365 ASN1_INTEGER_free(bs);
366 }
367
368 if (!nl)
369 {
370 if (BIO_write(bp,"\n",1) <= 0) goto end;
371 }
372 p+=len;
373 if ((tag == V_ASN1_EOC) && (xclass == 0))
374 {
375 ret=2; /* End of sequence */
376 goto end;
377 }
378 }
379 length-=len;
380 }
381 ret=1;
382 end:
383 if (o != NULL) ASN1_OBJECT_free(o);
384 if (os != NULL) ASN1_OCTET_STRING_free(os);
385 *pp=p;
386 return(ret);
387 }