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