]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/asn1/tasn_prn.c
Code style: space after 'if'
[thirdparty/openssl.git] / crypto / asn1 / tasn_prn.c
CommitLineData
9d6b1ce6 1/* tasn_prn.c */
ae5c8664
MC
2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4 * 2000.
9d6b1ce6
DSH
5 */
6/* ====================================================================
56defd9a 7 * Copyright (c) 2000,2005 The OpenSSL Project. All rights reserved.
9d6b1ce6
DSH
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
ae5c8664 14 * notice, this list of conditions and the following disclaimer.
9d6b1ce6
DSH
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59
9d6b1ce6 60#include <stddef.h>
c11c64fb 61#include "cryptlib.h"
9d6b1ce6 62#include <openssl/asn1.h>
56defd9a 63#include <openssl/asn1t.h>
9d6b1ce6
DSH
64#include <openssl/objects.h>
65#include <openssl/buffer.h>
66#include <openssl/err.h>
56defd9a
DSH
67#include <openssl/x509v3.h>
68#include "asn1_locl.h"
9d6b1ce6 69
ae5c8664
MC
70/*
71 * Print routines.
9d6b1ce6
DSH
72 */
73
56defd9a 74/* ASN1_PCTX routines */
9d6b1ce6 75
ae5c8664
MC
76ASN1_PCTX default_pctx = {
77 ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
78 0, /* nm_flags */
79 0, /* cert_flags */
80 0, /* oid_flags */
81 0 /* str_flags */
82};
9d6b1ce6 83
56defd9a 84ASN1_PCTX *ASN1_PCTX_new(void)
ae5c8664
MC
85{
86 ASN1_PCTX *ret;
87 ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
88 if (ret == NULL) {
89 ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE);
90 return NULL;
91 }
92 ret->flags = 0;
93 ret->nm_flags = 0;
94 ret->cert_flags = 0;
95 ret->oid_flags = 0;
96 ret->str_flags = 0;
97 return ret;
98}
56defd9a
DSH
99
100void ASN1_PCTX_free(ASN1_PCTX *p)
ae5c8664
MC
101{
102 OPENSSL_free(p);
103}
56defd9a
DSH
104
105unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
ae5c8664
MC
106{
107 return p->flags;
108}
56defd9a
DSH
109
110void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
ae5c8664
MC
111{
112 p->flags = flags;
113}
56defd9a
DSH
114
115unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
ae5c8664
MC
116{
117 return p->nm_flags;
118}
56defd9a
DSH
119
120void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
ae5c8664
MC
121{
122 p->nm_flags = flags;
123}
56defd9a
DSH
124
125unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
ae5c8664
MC
126{
127 return p->cert_flags;
128}
56defd9a
DSH
129
130void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
ae5c8664
MC
131{
132 p->cert_flags = flags;
133}
56defd9a
DSH
134
135unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
ae5c8664
MC
136{
137 return p->oid_flags;
138}
56defd9a
DSH
139
140void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
ae5c8664
MC
141{
142 p->oid_flags = flags;
143}
56defd9a
DSH
144
145unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
ae5c8664
MC
146{
147 return p->str_flags;
148}
56defd9a
DSH
149
150void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
ae5c8664
MC
151{
152 p->str_flags = flags;
153}
56defd9a
DSH
154
155/* Main print routines */
156
157static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
ae5c8664
MC
158 const ASN1_ITEM *it,
159 const char *fname, const char *sname,
160 int nohdr, const ASN1_PCTX *pctx);
9194296d 161
56defd9a 162int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
ae5c8664 163 const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
9194296d 164
56defd9a 165static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
ae5c8664
MC
166 const ASN1_ITEM *it, int indent,
167 const char *fname, const char *sname,
168 const ASN1_PCTX *pctx);
9194296d 169
b173acfc 170static int asn1_print_fsname(BIO *out, int indent,
ae5c8664
MC
171 const char *fname, const char *sname,
172 const ASN1_PCTX *pctx);
56defd9a
DSH
173
174int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
ae5c8664
MC
175 const ASN1_ITEM *it, const ASN1_PCTX *pctx)
176{
177 const char *sname;
178 if (pctx == NULL)
179 pctx = &default_pctx;
180 if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
181 sname = NULL;
182 else
183 sname = it->sname;
184 return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx);
185}
56defd9a
DSH
186
187static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
ae5c8664
MC
188 const ASN1_ITEM *it,
189 const char *fname, const char *sname,
190 int nohdr, const ASN1_PCTX *pctx)
191{
192 const ASN1_TEMPLATE *tt;
193 const ASN1_EXTERN_FUNCS *ef;
194 ASN1_VALUE **tmpfld;
195 const ASN1_AUX *aux = it->funcs;
196 ASN1_aux_cb *asn1_cb;
197 ASN1_PRINT_ARG parg;
198 int i;
199 if (aux && aux->asn1_cb) {
200 parg.out = out;
201 parg.indent = indent;
202 parg.pctx = pctx;
203 asn1_cb = aux->asn1_cb;
204 } else
205 asn1_cb = 0;
206
207 if (*fld == NULL) {
208 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
209 if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
210 return 0;
211 if (BIO_puts(out, "<ABSENT>\n") <= 0)
212 return 0;
213 }
214 return 1;
215 }
216
217 switch (it->itype) {
218 case ASN1_ITYPE_PRIMITIVE:
219 if (it->templates) {
220 if (!asn1_template_print_ctx(out, fld, indent,
221 it->templates, pctx))
222 return 0;
8cd67140 223 break;
ae5c8664
MC
224 }
225 /* fall thru */
226 case ASN1_ITYPE_MSTRING:
227 if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx))
228 return 0;
229 break;
230
231 case ASN1_ITYPE_EXTERN:
232 if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
233 return 0;
234 /* Use new style print routine if possible */
235 ef = it->funcs;
236 if (ef && ef->asn1_ex_print) {
237 i = ef->asn1_ex_print(out, fld, indent, "", pctx);
238 if (!i)
239 return 0;
240 if ((i == 2) && (BIO_puts(out, "\n") <= 0))
241 return 0;
242 return 1;
243 } else if (sname &&
244 BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
245 return 0;
246 break;
247
248 case ASN1_ITYPE_CHOICE:
b173acfc 249#if 0
ae5c8664
MC
250 if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
251 return 0;
b173acfc 252#endif
ae5c8664
MC
253 /* CHOICE type, get selector */
254 i = asn1_get_choice_selector(fld, it);
255 /* This should never happen... */
256 if ((i < 0) || (i >= it->tcount)) {
257 if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0)
258 return 0;
259 return 1;
260 }
261 tt = it->templates + i;
262 tmpfld = asn1_get_field_ptr(fld, tt);
263 if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
264 return 0;
265 break;
266
267 case ASN1_ITYPE_SEQUENCE:
268 case ASN1_ITYPE_NDEF_SEQUENCE:
269 if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
270 return 0;
271 if (fname || sname) {
272 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
273 if (BIO_puts(out, " {\n") <= 0)
274 return 0;
275 } else {
276 if (BIO_puts(out, "\n") <= 0)
277 return 0;
278 }
279 }
280
281 if (asn1_cb) {
282 i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
283 if (i == 0)
284 return 0;
285 if (i == 2)
286 return 1;
287 }
288
289 /* Print each field entry */
290 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
291 const ASN1_TEMPLATE *seqtt;
292 seqtt = asn1_do_adb(fld, tt, 1);
3b38646d 293 if (!seqtt)
15919eca 294 return 0;
ae5c8664
MC
295 tmpfld = asn1_get_field_ptr(fld, seqtt);
296 if (!asn1_template_print_ctx(out, tmpfld,
297 indent + 2, seqtt, pctx))
298 return 0;
299 }
300 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
301 if (BIO_printf(out, "%*s}\n", indent, "") < 0)
302 return 0;
303 }
304
305 if (asn1_cb) {
306 i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
307 if (i == 0)
308 return 0;
309 }
310 break;
311
312 default:
313 BIO_printf(out, "Unprocessed type %d\n", it->itype);
314 return 0;
315 }
316
317 return 1;
318}
9d6b1ce6 319
56defd9a 320int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
ae5c8664
MC
321 const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
322{
323 int i, flags;
324 const char *sname, *fname;
325 flags = tt->flags;
326 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
327 sname = ASN1_ITEM_ptr(tt->item)->sname;
328 else
329 sname = NULL;
330 if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
331 fname = NULL;
332 else
333 fname = tt->field_name;
334 if (flags & ASN1_TFLG_SK_MASK) {
335 char *tname;
336 ASN1_VALUE *skitem;
337 STACK_OF(ASN1_VALUE) *stack;
338
339 /* SET OF, SEQUENCE OF */
340 if (fname) {
341 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
342 if (flags & ASN1_TFLG_SET_OF)
343 tname = "SET";
344 else
345 tname = "SEQUENCE";
346 if (BIO_printf(out, "%*s%s OF %s {\n",
347 indent, "", tname, tt->field_name) <= 0)
348 return 0;
349 } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0)
350 return 0;
351 }
352 stack = (STACK_OF(ASN1_VALUE) *)*fld;
353 for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
354 if ((i > 0) && (BIO_puts(out, "\n") <= 0))
355 return 0;
356
357 skitem = sk_ASN1_VALUE_value(stack, i);
358 if (!asn1_item_print_ctx(out, &skitem, indent + 2,
359 ASN1_ITEM_ptr(tt->item), NULL, NULL, 1,
360 pctx))
361 return 0;
362 }
363 if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
364 return 0;
365 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
366 if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
367 return 0;
368 }
369 return 1;
370 }
371 return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
372 fname, sname, 0, pctx);
373}
56defd9a 374
b173acfc 375static int asn1_print_fsname(BIO *out, int indent,
ae5c8664
MC
376 const char *fname, const char *sname,
377 const ASN1_PCTX *pctx)
378{
379 static char spaces[] = " ";
380 const int nspaces = sizeof(spaces) - 1;
b173acfc
DSH
381
382#if 0
ae5c8664
MC
383 if (!sname && !fname)
384 return 1;
b173acfc
DSH
385#endif
386
ae5c8664
MC
387 while (indent > nspaces) {
388 if (BIO_write(out, spaces, nspaces) != nspaces)
389 return 0;
390 indent -= nspaces;
391 }
392 if (BIO_write(out, spaces, indent) != indent)
393 return 0;
394 if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
395 sname = NULL;
396 if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
397 fname = NULL;
398 if (!sname && !fname)
399 return 1;
400 if (fname) {
401 if (BIO_puts(out, fname) <= 0)
402 return 0;
403 }
404 if (sname) {
405 if (fname) {
406 if (BIO_printf(out, " (%s)", sname) <= 0)
407 return 0;
408 } else {
409 if (BIO_puts(out, sname) <= 0)
410 return 0;
411 }
412 }
413 if (BIO_write(out, ": ", 2) != 2)
414 return 0;
415 return 1;
416}
56defd9a 417
2fee1e06 418static int asn1_print_boolean_ctx(BIO *out, int boolval,
ae5c8664
MC
419 const ASN1_PCTX *pctx)
420{
421 const char *str;
422 switch (boolval) {
423 case -1:
424 str = "BOOL ABSENT";
425 break;
56defd9a 426
ae5c8664
MC
427 case 0:
428 str = "FALSE";
429 break;
56defd9a 430
ae5c8664
MC
431 default:
432 str = "TRUE";
433 break;
56defd9a 434
ae5c8664 435 }
56defd9a 436
ae5c8664
MC
437 if (BIO_puts(out, str) <= 0)
438 return 0;
439 return 1;
56defd9a 440
ae5c8664 441}
56defd9a
DSH
442
443static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
ae5c8664
MC
444 const ASN1_PCTX *pctx)
445{
446 char *s;
447 int ret = 1;
448 s = i2s_ASN1_INTEGER(NULL, str);
449 if (BIO_puts(out, s) <= 0)
450 ret = 0;
451 OPENSSL_free(s);
452 return ret;
453}
56defd9a
DSH
454
455static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
ae5c8664
MC
456 const ASN1_PCTX *pctx)
457{
458 char objbuf[80];
459 const char *ln;
460 ln = OBJ_nid2ln(OBJ_obj2nid(oid));
461 if (!ln)
462 ln = "";
463 OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
464 if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
465 return 0;
466 return 1;
467}
56defd9a
DSH
468
469static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
ae5c8664
MC
470 const ASN1_PCTX *pctx)
471{
472 if (str->type == V_ASN1_BIT_STRING) {
473 if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0)
474 return 0;
475 } else if (BIO_puts(out, "\n") <= 0)
476 return 0;
477 if ((str->length > 0)
478 && BIO_dump_indent(out, (char *)str->data, str->length,
479 indent + 2) <= 0)
480 return 0;
481 return 1;
482}
56defd9a
DSH
483
484static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
ae5c8664
MC
485 const ASN1_ITEM *it, int indent,
486 const char *fname, const char *sname,
487 const ASN1_PCTX *pctx)
488{
489 long utype;
490 ASN1_STRING *str;
491 int ret = 1, needlf = 1;
492 const char *pname;
493 const ASN1_PRIMITIVE_FUNCS *pf;
494 pf = it->funcs;
495 if (!asn1_print_fsname(out, indent, fname, sname, pctx))
496 return 0;
497 if (pf && pf->prim_print)
498 return pf->prim_print(out, fld, it, indent, pctx);
499 str = (ASN1_STRING *)*fld;
500 if (it->itype == ASN1_ITYPE_MSTRING)
501 utype = str->type & ~V_ASN1_NEG;
502 else
503 utype = it->utype;
504 if (utype == V_ASN1_ANY) {
505 ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
506 utype = atype->type;
507 fld = &atype->value.asn1_value;
508 str = (ASN1_STRING *)*fld;
509 if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
510 pname = NULL;
511 else
512 pname = ASN1_tag2str(utype);
513 } else {
514 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
515 pname = ASN1_tag2str(utype);
516 else
517 pname = NULL;
518 }
519
520 if (utype == V_ASN1_NULL) {
521 if (BIO_puts(out, "NULL\n") <= 0)
522 return 0;
523 return 1;
524 }
525
526 if (pname) {
527 if (BIO_puts(out, pname) <= 0)
528 return 0;
529 if (BIO_puts(out, ":") <= 0)
530 return 0;
531 }
532
533 switch (utype) {
534 case V_ASN1_BOOLEAN:
535 {
536 int boolval = *(int *)fld;
537 if (boolval == -1)
538 boolval = it->size;
539 ret = asn1_print_boolean_ctx(out, boolval, pctx);
540 }
541 break;
542
543 case V_ASN1_INTEGER:
544 case V_ASN1_ENUMERATED:
545 ret = asn1_print_integer_ctx(out, str, pctx);
546 break;
547
548 case V_ASN1_UTCTIME:
549 ret = ASN1_UTCTIME_print(out, str);
550 break;
551
552 case V_ASN1_GENERALIZEDTIME:
553 ret = ASN1_GENERALIZEDTIME_print(out, str);
554 break;
555
556 case V_ASN1_OBJECT:
557 ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
558 break;
559
560 case V_ASN1_OCTET_STRING:
561 case V_ASN1_BIT_STRING:
562 ret = asn1_print_obstring_ctx(out, str, indent, pctx);
563 needlf = 0;
564 break;
565
566 case V_ASN1_SEQUENCE:
567 case V_ASN1_SET:
568 case V_ASN1_OTHER:
569 if (BIO_puts(out, "\n") <= 0)
570 return 0;
571 if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0)
572 ret = 0;
573 needlf = 0;
574 break;
575
576 default:
577 ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
578
579 }
580 if (!ret)
581 return 0;
582 if (needlf && BIO_puts(out, "\n") <= 0)
583 return 0;
584 return 1;
585}