2 * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 #include "internal/cryptlib.h"
12 #include <openssl/asn1.h>
13 #include <openssl/asn1t.h>
14 #include <openssl/objects.h>
15 #include <openssl/buffer.h>
16 #include <openssl/err.h>
17 #include <openssl/x509v3.h>
18 #include "crypto/asn1.h"
19 #include "asn1_local.h"
25 /* ASN1_PCTX routines */
27 static ASN1_PCTX default_pctx
= {
28 ASN1_PCTX_FLAGS_SHOW_ABSENT
, /* flags */
35 ASN1_PCTX
*ASN1_PCTX_new(void)
39 ret
= OPENSSL_zalloc(sizeof(*ret
));
41 ASN1err(ASN1_F_ASN1_PCTX_NEW
, ERR_R_MALLOC_FAILURE
);
47 void ASN1_PCTX_free(ASN1_PCTX
*p
)
52 unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX
*p
)
57 void ASN1_PCTX_set_flags(ASN1_PCTX
*p
, unsigned long flags
)
62 unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX
*p
)
67 void ASN1_PCTX_set_nm_flags(ASN1_PCTX
*p
, unsigned long flags
)
72 unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX
*p
)
77 void ASN1_PCTX_set_cert_flags(ASN1_PCTX
*p
, unsigned long flags
)
79 p
->cert_flags
= flags
;
82 unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX
*p
)
87 void ASN1_PCTX_set_oid_flags(ASN1_PCTX
*p
, unsigned long flags
)
92 unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX
*p
)
97 void ASN1_PCTX_set_str_flags(ASN1_PCTX
*p
, unsigned long flags
)
102 /* Main print routines */
104 static int asn1_item_print_ctx(BIO
*out
, const ASN1_VALUE
**fld
, int indent
,
106 const char *fname
, const char *sname
,
107 int nohdr
, const ASN1_PCTX
*pctx
);
109 static int asn1_template_print_ctx(BIO
*out
, const ASN1_VALUE
**fld
, int indent
,
110 const ASN1_TEMPLATE
*tt
, const ASN1_PCTX
*pctx
);
112 static int asn1_primitive_print(BIO
*out
, const ASN1_VALUE
**fld
,
113 const ASN1_ITEM
*it
, int indent
,
114 const char *fname
, const char *sname
,
115 const ASN1_PCTX
*pctx
);
117 static int asn1_print_fsname(BIO
*out
, int indent
,
118 const char *fname
, const char *sname
,
119 const ASN1_PCTX
*pctx
);
121 int ASN1_item_print(BIO
*out
, const ASN1_VALUE
*ifld
, int indent
,
122 const ASN1_ITEM
*it
, const ASN1_PCTX
*pctx
)
126 pctx
= &default_pctx
;
127 if (pctx
->flags
& ASN1_PCTX_FLAGS_NO_STRUCT_NAME
)
131 return asn1_item_print_ctx(out
, &ifld
, indent
, it
, NULL
, sname
, 0, pctx
);
134 static int asn1_item_print_ctx(BIO
*out
, const ASN1_VALUE
**fld
, int indent
,
136 const char *fname
, const char *sname
,
137 int nohdr
, const ASN1_PCTX
*pctx
)
139 const ASN1_TEMPLATE
*tt
;
140 const ASN1_EXTERN_FUNCS
*ef
;
141 const ASN1_VALUE
**tmpfld
;
142 const ASN1_AUX
*aux
= it
->funcs
;
143 ASN1_aux_const_cb
*asn1_cb
= NULL
;
148 parg
.indent
= indent
;
150 asn1_cb
= ((aux
->flags
& ASN1_AFLG_CONST_CB
) != 0) ? aux
->asn1_const_cb
151 : (ASN1_aux_const_cb
*)aux
->asn1_cb
; /* backward compatibility */
154 if (((it
->itype
!= ASN1_ITYPE_PRIMITIVE
)
155 || (it
->utype
!= V_ASN1_BOOLEAN
)) && *fld
== NULL
) {
156 if (pctx
->flags
& ASN1_PCTX_FLAGS_SHOW_ABSENT
) {
157 if (!nohdr
&& !asn1_print_fsname(out
, indent
, fname
, sname
, pctx
))
159 if (BIO_puts(out
, "<ABSENT>\n") <= 0)
166 case ASN1_ITYPE_PRIMITIVE
:
168 if (!asn1_template_print_ctx(out
, fld
, indent
,
169 it
->templates
, pctx
))
174 case ASN1_ITYPE_MSTRING
:
175 if (!asn1_primitive_print(out
, fld
, it
, indent
, fname
, sname
, pctx
))
179 case ASN1_ITYPE_EXTERN
:
180 if (!nohdr
&& !asn1_print_fsname(out
, indent
, fname
, sname
, pctx
))
182 /* Use new style print routine if possible */
184 if (ef
&& ef
->asn1_ex_print
) {
185 i
= ef
->asn1_ex_print(out
, fld
, indent
, "", pctx
);
188 if ((i
== 2) && (BIO_puts(out
, "\n") <= 0))
192 BIO_printf(out
, ":EXTERNAL TYPE %s\n", sname
) <= 0)
196 case ASN1_ITYPE_CHOICE
:
197 /* CHOICE type, get selector */
198 i
= asn1_get_choice_selector_const(fld
, it
);
199 /* This should never happen... */
200 if ((i
< 0) || (i
>= it
->tcount
)) {
201 if (BIO_printf(out
, "ERROR: selector [%d] invalid\n", i
) <= 0)
205 tt
= it
->templates
+ i
;
206 tmpfld
= asn1_get_const_field_ptr(fld
, tt
);
207 if (!asn1_template_print_ctx(out
, tmpfld
, indent
, tt
, pctx
))
211 case ASN1_ITYPE_SEQUENCE
:
212 case ASN1_ITYPE_NDEF_SEQUENCE
:
213 if (!nohdr
&& !asn1_print_fsname(out
, indent
, fname
, sname
, pctx
))
215 if (fname
|| sname
) {
216 if (pctx
->flags
& ASN1_PCTX_FLAGS_SHOW_SEQUENCE
) {
217 if (BIO_puts(out
, " {\n") <= 0)
220 if (BIO_puts(out
, "\n") <= 0)
226 i
= asn1_cb(ASN1_OP_PRINT_PRE
, fld
, it
, &parg
);
233 /* Print each field entry */
234 for (i
= 0, tt
= it
->templates
; i
< it
->tcount
; i
++, tt
++) {
235 const ASN1_TEMPLATE
*seqtt
;
236 seqtt
= asn1_do_adb(*fld
, tt
, 1);
239 tmpfld
= asn1_get_const_field_ptr(fld
, seqtt
);
240 if (!asn1_template_print_ctx(out
, tmpfld
,
241 indent
+ 2, seqtt
, pctx
))
244 if (pctx
->flags
& ASN1_PCTX_FLAGS_SHOW_SEQUENCE
) {
245 if (BIO_printf(out
, "%*s}\n", indent
, "") < 0)
250 i
= asn1_cb(ASN1_OP_PRINT_POST
, fld
, it
, &parg
);
257 BIO_printf(out
, "Unprocessed type %d\n", it
->itype
);
264 static int asn1_template_print_ctx(BIO
*out
, const ASN1_VALUE
**fld
, int indent
,
265 const ASN1_TEMPLATE
*tt
, const ASN1_PCTX
*pctx
)
268 const char *sname
, *fname
;
269 const ASN1_VALUE
*tfld
;
271 if (pctx
->flags
& ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME
)
272 sname
= ASN1_ITEM_ptr(tt
->item
)->sname
;
275 if (pctx
->flags
& ASN1_PCTX_FLAGS_NO_FIELD_NAME
)
278 fname
= tt
->field_name
;
281 * If field is embedded then fld needs fixing so it is a pointer to
282 * a pointer to a field.
284 if (flags
& ASN1_TFLG_EMBED
) {
285 tfld
= (const ASN1_VALUE
*)fld
;
289 if (flags
& ASN1_TFLG_SK_MASK
) {
291 const ASN1_VALUE
*skitem
;
292 STACK_OF(const_ASN1_VALUE
) *stack
;
294 /* SET OF, SEQUENCE OF */
296 if (pctx
->flags
& ASN1_PCTX_FLAGS_SHOW_SSOF
) {
297 if (flags
& ASN1_TFLG_SET_OF
)
301 if (BIO_printf(out
, "%*s%s OF %s {\n",
302 indent
, "", tname
, tt
->field_name
) <= 0)
304 } else if (BIO_printf(out
, "%*s%s:\n", indent
, "", fname
) <= 0)
307 stack
= (STACK_OF(const_ASN1_VALUE
) *)*fld
;
308 for (i
= 0; i
< sk_const_ASN1_VALUE_num(stack
); i
++) {
309 if ((i
> 0) && (BIO_puts(out
, "\n") <= 0))
312 skitem
= sk_const_ASN1_VALUE_value(stack
, i
);
313 if (!asn1_item_print_ctx(out
, &skitem
, indent
+ 2,
314 ASN1_ITEM_ptr(tt
->item
), NULL
, NULL
, 1,
318 if (i
== 0 && BIO_printf(out
, "%*s<%s>\n", indent
+ 2, "",
319 stack
== NULL
? "ABSENT" : "EMPTY") <= 0)
321 if (pctx
->flags
& ASN1_PCTX_FLAGS_SHOW_SEQUENCE
) {
322 if (BIO_printf(out
, "%*s}\n", indent
, "") <= 0)
327 return asn1_item_print_ctx(out
, fld
, indent
, ASN1_ITEM_ptr(tt
->item
),
328 fname
, sname
, 0, pctx
);
331 static int asn1_print_fsname(BIO
*out
, int indent
,
332 const char *fname
, const char *sname
,
333 const ASN1_PCTX
*pctx
)
335 static const char spaces
[] = " ";
336 static const int nspaces
= sizeof(spaces
) - 1;
338 while (indent
> nspaces
) {
339 if (BIO_write(out
, spaces
, nspaces
) != nspaces
)
343 if (BIO_write(out
, spaces
, indent
) != indent
)
345 if (pctx
->flags
& ASN1_PCTX_FLAGS_NO_STRUCT_NAME
)
347 if (pctx
->flags
& ASN1_PCTX_FLAGS_NO_FIELD_NAME
)
349 if (!sname
&& !fname
)
352 if (BIO_puts(out
, fname
) <= 0)
357 if (BIO_printf(out
, " (%s)", sname
) <= 0)
360 if (BIO_puts(out
, sname
) <= 0)
364 if (BIO_write(out
, ": ", 2) != 2)
369 static int asn1_print_boolean(BIO
*out
, int boolval
)
387 if (BIO_puts(out
, str
) <= 0)
393 static int asn1_print_integer(BIO
*out
, const ASN1_INTEGER
*str
)
397 s
= i2s_ASN1_INTEGER(NULL
, str
);
400 if (BIO_puts(out
, s
) <= 0)
406 static int asn1_print_oid(BIO
*out
, const ASN1_OBJECT
*oid
)
410 ln
= OBJ_nid2ln(OBJ_obj2nid(oid
));
413 OBJ_obj2txt(objbuf
, sizeof(objbuf
), oid
, 1);
414 if (BIO_printf(out
, "%s (%s)", ln
, objbuf
) <= 0)
419 static int asn1_print_obstring(BIO
*out
, const ASN1_STRING
*str
, int indent
)
421 if (str
->type
== V_ASN1_BIT_STRING
) {
422 if (BIO_printf(out
, " (%ld unused bits)\n", str
->flags
& 0x7) <= 0)
424 } else if (BIO_puts(out
, "\n") <= 0)
426 if ((str
->length
> 0)
427 && BIO_dump_indent(out
, (const char *)str
->data
, str
->length
,
433 static int asn1_primitive_print(BIO
*out
, const ASN1_VALUE
**fld
,
434 const ASN1_ITEM
*it
, int indent
,
435 const char *fname
, const char *sname
,
436 const ASN1_PCTX
*pctx
)
440 int ret
= 1, needlf
= 1;
442 const ASN1_PRIMITIVE_FUNCS
*pf
;
444 if (!asn1_print_fsname(out
, indent
, fname
, sname
, pctx
))
446 if (pf
&& pf
->prim_print
)
447 return pf
->prim_print(out
, fld
, it
, indent
, pctx
);
448 if (it
->itype
== ASN1_ITYPE_MSTRING
) {
449 str
= (ASN1_STRING
*)*fld
;
450 utype
= str
->type
& ~V_ASN1_NEG
;
453 if (utype
== V_ASN1_BOOLEAN
)
456 str
= (ASN1_STRING
*)*fld
;
458 if (utype
== V_ASN1_ANY
) {
459 const ASN1_TYPE
*atype
= (const ASN1_TYPE
*)*fld
;
461 fld
= (const ASN1_VALUE
**)&atype
->value
.asn1_value
; /* actually is const */
462 str
= (ASN1_STRING
*)*fld
;
463 if (pctx
->flags
& ASN1_PCTX_FLAGS_NO_ANY_TYPE
)
466 pname
= ASN1_tag2str(utype
);
468 if (pctx
->flags
& ASN1_PCTX_FLAGS_SHOW_TYPE
)
469 pname
= ASN1_tag2str(utype
);
474 if (utype
== V_ASN1_NULL
) {
475 if (BIO_puts(out
, "NULL\n") <= 0)
481 if (BIO_puts(out
, pname
) <= 0)
483 if (BIO_puts(out
, ":") <= 0)
490 int boolval
= *(int *)fld
;
493 ret
= asn1_print_boolean(out
, boolval
);
498 case V_ASN1_ENUMERATED
:
499 ret
= asn1_print_integer(out
, str
);
503 ret
= ASN1_UTCTIME_print(out
, str
);
506 case V_ASN1_GENERALIZEDTIME
:
507 ret
= ASN1_GENERALIZEDTIME_print(out
, str
);
511 ret
= asn1_print_oid(out
, (const ASN1_OBJECT
*)*fld
);
514 case V_ASN1_OCTET_STRING
:
515 case V_ASN1_BIT_STRING
:
516 ret
= asn1_print_obstring(out
, str
, indent
);
520 case V_ASN1_SEQUENCE
:
523 if (BIO_puts(out
, "\n") <= 0)
525 if (ASN1_parse_dump(out
, str
->data
, str
->length
, indent
, 0) <= 0)
531 ret
= ASN1_STRING_print_ex(out
, str
, pctx
->str_flags
);
536 if (needlf
&& BIO_puts(out
, "\n") <= 0)