160662d10Schristos /*
2*1dcdf01fSchristos  * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
360662d10Schristos  *
4*1dcdf01fSchristos  * Licensed under the OpenSSL license (the "License").  You may not use
5*1dcdf01fSchristos  * this file except in compliance with the License.  You can obtain a copy
6*1dcdf01fSchristos  * in the file LICENSE in the source distribution or at
7*1dcdf01fSchristos  * https://www.openssl.org/source/license.html
860662d10Schristos  */
960662d10Schristos 
1060662d10Schristos #include <stddef.h>
11*1dcdf01fSchristos #include "internal/cryptlib.h"
1260662d10Schristos #include <openssl/asn1.h>
1360662d10Schristos #include <openssl/asn1t.h>
1460662d10Schristos #include <openssl/objects.h>
1560662d10Schristos #include <openssl/buffer.h>
1660662d10Schristos #include <openssl/err.h>
1760662d10Schristos #include <openssl/x509v3.h>
18*1dcdf01fSchristos #include "crypto/asn1.h"
19*1dcdf01fSchristos #include "asn1_local.h"
2060662d10Schristos 
2160662d10Schristos /*
2260662d10Schristos  * Print routines.
2360662d10Schristos  */
2460662d10Schristos 
2560662d10Schristos /* ASN1_PCTX routines */
2660662d10Schristos 
27*1dcdf01fSchristos static ASN1_PCTX default_pctx = {
2860662d10Schristos     ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
2960662d10Schristos     0,                          /* nm_flags */
3060662d10Schristos     0,                          /* cert_flags */
3160662d10Schristos     0,                          /* oid_flags */
3260662d10Schristos     0                           /* str_flags */
3360662d10Schristos };
3460662d10Schristos 
ASN1_PCTX_new(void)3560662d10Schristos ASN1_PCTX *ASN1_PCTX_new(void)
3660662d10Schristos {
3760662d10Schristos     ASN1_PCTX *ret;
38*1dcdf01fSchristos 
39*1dcdf01fSchristos     ret = OPENSSL_zalloc(sizeof(*ret));
4060662d10Schristos     if (ret == NULL) {
4160662d10Schristos         ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE);
4260662d10Schristos         return NULL;
4360662d10Schristos     }
4460662d10Schristos     return ret;
4560662d10Schristos }
4660662d10Schristos 
ASN1_PCTX_free(ASN1_PCTX * p)4760662d10Schristos void ASN1_PCTX_free(ASN1_PCTX *p)
4860662d10Schristos {
4960662d10Schristos     OPENSSL_free(p);
5060662d10Schristos }
5160662d10Schristos 
ASN1_PCTX_get_flags(const ASN1_PCTX * p)52*1dcdf01fSchristos unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX *p)
5360662d10Schristos {
5460662d10Schristos     return p->flags;
5560662d10Schristos }
5660662d10Schristos 
ASN1_PCTX_set_flags(ASN1_PCTX * p,unsigned long flags)5760662d10Schristos void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
5860662d10Schristos {
5960662d10Schristos     p->flags = flags;
6060662d10Schristos }
6160662d10Schristos 
ASN1_PCTX_get_nm_flags(const ASN1_PCTX * p)62*1dcdf01fSchristos unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX *p)
6360662d10Schristos {
6460662d10Schristos     return p->nm_flags;
6560662d10Schristos }
6660662d10Schristos 
ASN1_PCTX_set_nm_flags(ASN1_PCTX * p,unsigned long flags)6760662d10Schristos void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
6860662d10Schristos {
6960662d10Schristos     p->nm_flags = flags;
7060662d10Schristos }
7160662d10Schristos 
ASN1_PCTX_get_cert_flags(const ASN1_PCTX * p)72*1dcdf01fSchristos unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX *p)
7360662d10Schristos {
7460662d10Schristos     return p->cert_flags;
7560662d10Schristos }
7660662d10Schristos 
ASN1_PCTX_set_cert_flags(ASN1_PCTX * p,unsigned long flags)7760662d10Schristos void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
7860662d10Schristos {
7960662d10Schristos     p->cert_flags = flags;
8060662d10Schristos }
8160662d10Schristos 
ASN1_PCTX_get_oid_flags(const ASN1_PCTX * p)82*1dcdf01fSchristos unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX *p)
8360662d10Schristos {
8460662d10Schristos     return p->oid_flags;
8560662d10Schristos }
8660662d10Schristos 
ASN1_PCTX_set_oid_flags(ASN1_PCTX * p,unsigned long flags)8760662d10Schristos void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
8860662d10Schristos {
8960662d10Schristos     p->oid_flags = flags;
9060662d10Schristos }
9160662d10Schristos 
ASN1_PCTX_get_str_flags(const ASN1_PCTX * p)92*1dcdf01fSchristos unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX *p)
9360662d10Schristos {
9460662d10Schristos     return p->str_flags;
9560662d10Schristos }
9660662d10Schristos 
ASN1_PCTX_set_str_flags(ASN1_PCTX * p,unsigned long flags)9760662d10Schristos void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
9860662d10Schristos {
9960662d10Schristos     p->str_flags = flags;
10060662d10Schristos }
10160662d10Schristos 
10260662d10Schristos /* Main print routines */
10360662d10Schristos 
10460662d10Schristos static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
10560662d10Schristos                                const ASN1_ITEM *it,
10660662d10Schristos                                const char *fname, const char *sname,
10760662d10Schristos                                int nohdr, const ASN1_PCTX *pctx);
10860662d10Schristos 
109*1dcdf01fSchristos static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
11060662d10Schristos                             const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
11160662d10Schristos 
11260662d10Schristos static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
11360662d10Schristos                                 const ASN1_ITEM *it, int indent,
11460662d10Schristos                                 const char *fname, const char *sname,
11560662d10Schristos                                 const ASN1_PCTX *pctx);
11660662d10Schristos 
11760662d10Schristos static int asn1_print_fsname(BIO *out, int indent,
11860662d10Schristos                              const char *fname, const char *sname,
11960662d10Schristos                              const ASN1_PCTX *pctx);
12060662d10Schristos 
ASN1_item_print(BIO * out,ASN1_VALUE * ifld,int indent,const ASN1_ITEM * it,const ASN1_PCTX * pctx)12160662d10Schristos int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
12260662d10Schristos                     const ASN1_ITEM *it, const ASN1_PCTX *pctx)
12360662d10Schristos {
12460662d10Schristos     const char *sname;
12560662d10Schristos     if (pctx == NULL)
12660662d10Schristos         pctx = &default_pctx;
12760662d10Schristos     if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
12860662d10Schristos         sname = NULL;
12960662d10Schristos     else
13060662d10Schristos         sname = it->sname;
13160662d10Schristos     return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx);
13260662d10Schristos }
13360662d10Schristos 
asn1_item_print_ctx(BIO * out,ASN1_VALUE ** fld,int indent,const ASN1_ITEM * it,const char * fname,const char * sname,int nohdr,const ASN1_PCTX * pctx)13460662d10Schristos static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
13560662d10Schristos                                const ASN1_ITEM *it,
13660662d10Schristos                                const char *fname, const char *sname,
13760662d10Schristos                                int nohdr, const ASN1_PCTX *pctx)
13860662d10Schristos {
13960662d10Schristos     const ASN1_TEMPLATE *tt;
14060662d10Schristos     const ASN1_EXTERN_FUNCS *ef;
14160662d10Schristos     ASN1_VALUE **tmpfld;
14260662d10Schristos     const ASN1_AUX *aux = it->funcs;
14360662d10Schristos     ASN1_aux_cb *asn1_cb;
14460662d10Schristos     ASN1_PRINT_ARG parg;
14560662d10Schristos     int i;
14660662d10Schristos     if (aux && aux->asn1_cb) {
14760662d10Schristos         parg.out = out;
14860662d10Schristos         parg.indent = indent;
14960662d10Schristos         parg.pctx = pctx;
15060662d10Schristos         asn1_cb = aux->asn1_cb;
15160662d10Schristos     } else
15260662d10Schristos         asn1_cb = 0;
15360662d10Schristos 
15460662d10Schristos    if (((it->itype != ASN1_ITYPE_PRIMITIVE)
15560662d10Schristos        || (it->utype != V_ASN1_BOOLEAN)) && *fld == NULL) {
15660662d10Schristos         if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
15760662d10Schristos             if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
15860662d10Schristos                 return 0;
15960662d10Schristos             if (BIO_puts(out, "<ABSENT>\n") <= 0)
16060662d10Schristos                 return 0;
16160662d10Schristos         }
16260662d10Schristos         return 1;
16360662d10Schristos     }
16460662d10Schristos 
16560662d10Schristos     switch (it->itype) {
16660662d10Schristos     case ASN1_ITYPE_PRIMITIVE:
16760662d10Schristos         if (it->templates) {
16860662d10Schristos             if (!asn1_template_print_ctx(out, fld, indent,
16960662d10Schristos                                          it->templates, pctx))
17060662d10Schristos                 return 0;
17160662d10Schristos             break;
17260662d10Schristos         }
173*1dcdf01fSchristos         /* fall through */
17460662d10Schristos     case ASN1_ITYPE_MSTRING:
17560662d10Schristos         if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx))
17660662d10Schristos             return 0;
17760662d10Schristos         break;
17860662d10Schristos 
17960662d10Schristos     case ASN1_ITYPE_EXTERN:
18060662d10Schristos         if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
18160662d10Schristos             return 0;
18260662d10Schristos         /* Use new style print routine if possible */
18360662d10Schristos         ef = it->funcs;
18460662d10Schristos         if (ef && ef->asn1_ex_print) {
18560662d10Schristos             i = ef->asn1_ex_print(out, fld, indent, "", pctx);
18660662d10Schristos             if (!i)
18760662d10Schristos                 return 0;
18860662d10Schristos             if ((i == 2) && (BIO_puts(out, "\n") <= 0))
18960662d10Schristos                 return 0;
19060662d10Schristos             return 1;
19160662d10Schristos         } else if (sname &&
19260662d10Schristos                    BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
19360662d10Schristos             return 0;
19460662d10Schristos         break;
19560662d10Schristos 
19660662d10Schristos     case ASN1_ITYPE_CHOICE:
19760662d10Schristos         /* CHOICE type, get selector */
19860662d10Schristos         i = asn1_get_choice_selector(fld, it);
19960662d10Schristos         /* This should never happen... */
20060662d10Schristos         if ((i < 0) || (i >= it->tcount)) {
20160662d10Schristos             if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0)
20260662d10Schristos                 return 0;
20360662d10Schristos             return 1;
20460662d10Schristos         }
20560662d10Schristos         tt = it->templates + i;
20660662d10Schristos         tmpfld = asn1_get_field_ptr(fld, tt);
20760662d10Schristos         if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
20860662d10Schristos             return 0;
20960662d10Schristos         break;
21060662d10Schristos 
21160662d10Schristos     case ASN1_ITYPE_SEQUENCE:
21260662d10Schristos     case ASN1_ITYPE_NDEF_SEQUENCE:
21360662d10Schristos         if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
21460662d10Schristos             return 0;
21560662d10Schristos         if (fname || sname) {
21660662d10Schristos             if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
21760662d10Schristos                 if (BIO_puts(out, " {\n") <= 0)
21860662d10Schristos                     return 0;
21960662d10Schristos             } else {
22060662d10Schristos                 if (BIO_puts(out, "\n") <= 0)
22160662d10Schristos                     return 0;
22260662d10Schristos             }
22360662d10Schristos         }
22460662d10Schristos 
22560662d10Schristos         if (asn1_cb) {
22660662d10Schristos             i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
22760662d10Schristos             if (i == 0)
22860662d10Schristos                 return 0;
22960662d10Schristos             if (i == 2)
23060662d10Schristos                 return 1;
23160662d10Schristos         }
23260662d10Schristos 
23360662d10Schristos         /* Print each field entry */
23460662d10Schristos         for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
23560662d10Schristos             const ASN1_TEMPLATE *seqtt;
23660662d10Schristos             seqtt = asn1_do_adb(fld, tt, 1);
23760662d10Schristos             if (!seqtt)
23860662d10Schristos                 return 0;
23960662d10Schristos             tmpfld = asn1_get_field_ptr(fld, seqtt);
24060662d10Schristos             if (!asn1_template_print_ctx(out, tmpfld,
24160662d10Schristos                                          indent + 2, seqtt, pctx))
24260662d10Schristos                 return 0;
24360662d10Schristos         }
24460662d10Schristos         if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
24560662d10Schristos             if (BIO_printf(out, "%*s}\n", indent, "") < 0)
24660662d10Schristos                 return 0;
24760662d10Schristos         }
24860662d10Schristos 
24960662d10Schristos         if (asn1_cb) {
25060662d10Schristos             i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
25160662d10Schristos             if (i == 0)
25260662d10Schristos                 return 0;
25360662d10Schristos         }
25460662d10Schristos         break;
25560662d10Schristos 
25660662d10Schristos     default:
25760662d10Schristos         BIO_printf(out, "Unprocessed type %d\n", it->itype);
25860662d10Schristos         return 0;
25960662d10Schristos     }
26060662d10Schristos 
26160662d10Schristos     return 1;
26260662d10Schristos }
26360662d10Schristos 
asn1_template_print_ctx(BIO * out,ASN1_VALUE ** fld,int indent,const ASN1_TEMPLATE * tt,const ASN1_PCTX * pctx)264*1dcdf01fSchristos static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
26560662d10Schristos                             const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
26660662d10Schristos {
26760662d10Schristos     int i, flags;
26860662d10Schristos     const char *sname, *fname;
269*1dcdf01fSchristos     ASN1_VALUE *tfld;
27060662d10Schristos     flags = tt->flags;
27160662d10Schristos     if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
27260662d10Schristos         sname = ASN1_ITEM_ptr(tt->item)->sname;
27360662d10Schristos     else
27460662d10Schristos         sname = NULL;
27560662d10Schristos     if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
27660662d10Schristos         fname = NULL;
27760662d10Schristos     else
27860662d10Schristos         fname = tt->field_name;
279*1dcdf01fSchristos 
280*1dcdf01fSchristos     /*
281*1dcdf01fSchristos      * If field is embedded then fld needs fixing so it is a pointer to
282*1dcdf01fSchristos      * a pointer to a field.
283*1dcdf01fSchristos      */
284*1dcdf01fSchristos     if (flags & ASN1_TFLG_EMBED) {
285*1dcdf01fSchristos         tfld = (ASN1_VALUE *)fld;
286*1dcdf01fSchristos         fld = &tfld;
287*1dcdf01fSchristos     }
288*1dcdf01fSchristos 
28960662d10Schristos     if (flags & ASN1_TFLG_SK_MASK) {
29060662d10Schristos         char *tname;
29160662d10Schristos         ASN1_VALUE *skitem;
29260662d10Schristos         STACK_OF(ASN1_VALUE) *stack;
29360662d10Schristos 
29460662d10Schristos         /* SET OF, SEQUENCE OF */
29560662d10Schristos         if (fname) {
29660662d10Schristos             if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
29760662d10Schristos                 if (flags & ASN1_TFLG_SET_OF)
29860662d10Schristos                     tname = "SET";
29960662d10Schristos                 else
30060662d10Schristos                     tname = "SEQUENCE";
30160662d10Schristos                 if (BIO_printf(out, "%*s%s OF %s {\n",
30260662d10Schristos                                indent, "", tname, tt->field_name) <= 0)
30360662d10Schristos                     return 0;
30460662d10Schristos             } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0)
30560662d10Schristos                 return 0;
30660662d10Schristos         }
30760662d10Schristos         stack = (STACK_OF(ASN1_VALUE) *)*fld;
30860662d10Schristos         for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
30960662d10Schristos             if ((i > 0) && (BIO_puts(out, "\n") <= 0))
31060662d10Schristos                 return 0;
31160662d10Schristos 
31260662d10Schristos             skitem = sk_ASN1_VALUE_value(stack, i);
31360662d10Schristos             if (!asn1_item_print_ctx(out, &skitem, indent + 2,
31460662d10Schristos                                      ASN1_ITEM_ptr(tt->item), NULL, NULL, 1,
31560662d10Schristos                                      pctx))
31660662d10Schristos                 return 0;
31760662d10Schristos         }
318*1dcdf01fSchristos         if (i == 0 && BIO_printf(out, "%*s<%s>\n", indent + 2, "",
319*1dcdf01fSchristos                                  stack == NULL ? "ABSENT" : "EMPTY") <= 0)
32060662d10Schristos             return 0;
32160662d10Schristos         if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
32260662d10Schristos             if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
32360662d10Schristos                 return 0;
32460662d10Schristos         }
32560662d10Schristos         return 1;
32660662d10Schristos     }
32760662d10Schristos     return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
32860662d10Schristos                                fname, sname, 0, pctx);
32960662d10Schristos }
33060662d10Schristos 
asn1_print_fsname(BIO * out,int indent,const char * fname,const char * sname,const ASN1_PCTX * pctx)33160662d10Schristos static int asn1_print_fsname(BIO *out, int indent,
33260662d10Schristos                              const char *fname, const char *sname,
33360662d10Schristos                              const ASN1_PCTX *pctx)
33460662d10Schristos {
335*1dcdf01fSchristos     static const char spaces[] = "                    ";
336*1dcdf01fSchristos     static const int nspaces = sizeof(spaces) - 1;
33760662d10Schristos 
33860662d10Schristos     while (indent > nspaces) {
33960662d10Schristos         if (BIO_write(out, spaces, nspaces) != nspaces)
34060662d10Schristos             return 0;
34160662d10Schristos         indent -= nspaces;
34260662d10Schristos     }
34360662d10Schristos     if (BIO_write(out, spaces, indent) != indent)
34460662d10Schristos         return 0;
34560662d10Schristos     if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
34660662d10Schristos         sname = NULL;
34760662d10Schristos     if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
34860662d10Schristos         fname = NULL;
34960662d10Schristos     if (!sname && !fname)
35060662d10Schristos         return 1;
35160662d10Schristos     if (fname) {
35260662d10Schristos         if (BIO_puts(out, fname) <= 0)
35360662d10Schristos             return 0;
35460662d10Schristos     }
35560662d10Schristos     if (sname) {
35660662d10Schristos         if (fname) {
35760662d10Schristos             if (BIO_printf(out, " (%s)", sname) <= 0)
35860662d10Schristos                 return 0;
35960662d10Schristos         } else {
36060662d10Schristos             if (BIO_puts(out, sname) <= 0)
36160662d10Schristos                 return 0;
36260662d10Schristos         }
36360662d10Schristos     }
36460662d10Schristos     if (BIO_write(out, ": ", 2) != 2)
36560662d10Schristos         return 0;
36660662d10Schristos     return 1;
36760662d10Schristos }
36860662d10Schristos 
asn1_print_boolean(BIO * out,int boolval)369*1dcdf01fSchristos static int asn1_print_boolean(BIO *out, int boolval)
37060662d10Schristos {
37160662d10Schristos     const char *str;
37260662d10Schristos     switch (boolval) {
37360662d10Schristos     case -1:
37460662d10Schristos         str = "BOOL ABSENT";
37560662d10Schristos         break;
37660662d10Schristos 
37760662d10Schristos     case 0:
37860662d10Schristos         str = "FALSE";
37960662d10Schristos         break;
38060662d10Schristos 
38160662d10Schristos     default:
38260662d10Schristos         str = "TRUE";
38360662d10Schristos         break;
38460662d10Schristos 
38560662d10Schristos     }
38660662d10Schristos 
38760662d10Schristos     if (BIO_puts(out, str) <= 0)
38860662d10Schristos         return 0;
38960662d10Schristos     return 1;
39060662d10Schristos 
39160662d10Schristos }
39260662d10Schristos 
asn1_print_integer(BIO * out,const ASN1_INTEGER * str)393*1dcdf01fSchristos static int asn1_print_integer(BIO *out, const ASN1_INTEGER *str)
39460662d10Schristos {
39560662d10Schristos     char *s;
39660662d10Schristos     int ret = 1;
39760662d10Schristos     s = i2s_ASN1_INTEGER(NULL, str);
39860662d10Schristos     if (s == NULL)
39960662d10Schristos         return 0;
40060662d10Schristos     if (BIO_puts(out, s) <= 0)
40160662d10Schristos         ret = 0;
40260662d10Schristos     OPENSSL_free(s);
40360662d10Schristos     return ret;
40460662d10Schristos }
40560662d10Schristos 
asn1_print_oid(BIO * out,const ASN1_OBJECT * oid)406*1dcdf01fSchristos static int asn1_print_oid(BIO *out, const ASN1_OBJECT *oid)
40760662d10Schristos {
40860662d10Schristos     char objbuf[80];
40960662d10Schristos     const char *ln;
41060662d10Schristos     ln = OBJ_nid2ln(OBJ_obj2nid(oid));
41160662d10Schristos     if (!ln)
41260662d10Schristos         ln = "";
413*1dcdf01fSchristos     OBJ_obj2txt(objbuf, sizeof(objbuf), oid, 1);
41460662d10Schristos     if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
41560662d10Schristos         return 0;
41660662d10Schristos     return 1;
41760662d10Schristos }
41860662d10Schristos 
asn1_print_obstring(BIO * out,const ASN1_STRING * str,int indent)419*1dcdf01fSchristos static int asn1_print_obstring(BIO *out, const ASN1_STRING *str, int indent)
42060662d10Schristos {
42160662d10Schristos     if (str->type == V_ASN1_BIT_STRING) {
42260662d10Schristos         if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0)
42360662d10Schristos             return 0;
42460662d10Schristos     } else if (BIO_puts(out, "\n") <= 0)
42560662d10Schristos         return 0;
42660662d10Schristos     if ((str->length > 0)
427*1dcdf01fSchristos         && BIO_dump_indent(out, (const char *)str->data, str->length,
42860662d10Schristos                            indent + 2) <= 0)
42960662d10Schristos         return 0;
43060662d10Schristos     return 1;
43160662d10Schristos }
43260662d10Schristos 
asn1_primitive_print(BIO * out,ASN1_VALUE ** fld,const ASN1_ITEM * it,int indent,const char * fname,const char * sname,const ASN1_PCTX * pctx)43360662d10Schristos static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
43460662d10Schristos                                 const ASN1_ITEM *it, int indent,
43560662d10Schristos                                 const char *fname, const char *sname,
43660662d10Schristos                                 const ASN1_PCTX *pctx)
43760662d10Schristos {
43860662d10Schristos     long utype;
43960662d10Schristos     ASN1_STRING *str;
44060662d10Schristos     int ret = 1, needlf = 1;
44160662d10Schristos     const char *pname;
44260662d10Schristos     const ASN1_PRIMITIVE_FUNCS *pf;
44360662d10Schristos     pf = it->funcs;
44460662d10Schristos     if (!asn1_print_fsname(out, indent, fname, sname, pctx))
44560662d10Schristos         return 0;
44660662d10Schristos     if (pf && pf->prim_print)
44760662d10Schristos         return pf->prim_print(out, fld, it, indent, pctx);
44860662d10Schristos     if (it->itype == ASN1_ITYPE_MSTRING) {
44960662d10Schristos         str = (ASN1_STRING *)*fld;
45060662d10Schristos         utype = str->type & ~V_ASN1_NEG;
45160662d10Schristos     } else {
45260662d10Schristos         utype = it->utype;
45360662d10Schristos         if (utype == V_ASN1_BOOLEAN)
45460662d10Schristos             str = NULL;
45560662d10Schristos         else
45660662d10Schristos             str = (ASN1_STRING *)*fld;
45760662d10Schristos     }
45860662d10Schristos     if (utype == V_ASN1_ANY) {
45960662d10Schristos         ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
46060662d10Schristos         utype = atype->type;
46160662d10Schristos         fld = &atype->value.asn1_value;
46260662d10Schristos         str = (ASN1_STRING *)*fld;
46360662d10Schristos         if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
46460662d10Schristos             pname = NULL;
46560662d10Schristos         else
46660662d10Schristos             pname = ASN1_tag2str(utype);
46760662d10Schristos     } else {
46860662d10Schristos         if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
46960662d10Schristos             pname = ASN1_tag2str(utype);
47060662d10Schristos         else
47160662d10Schristos             pname = NULL;
47260662d10Schristos     }
47360662d10Schristos 
47460662d10Schristos     if (utype == V_ASN1_NULL) {
47560662d10Schristos         if (BIO_puts(out, "NULL\n") <= 0)
47660662d10Schristos             return 0;
47760662d10Schristos         return 1;
47860662d10Schristos     }
47960662d10Schristos 
48060662d10Schristos     if (pname) {
48160662d10Schristos         if (BIO_puts(out, pname) <= 0)
48260662d10Schristos             return 0;
48360662d10Schristos         if (BIO_puts(out, ":") <= 0)
48460662d10Schristos             return 0;
48560662d10Schristos     }
48660662d10Schristos 
48760662d10Schristos     switch (utype) {
48860662d10Schristos     case V_ASN1_BOOLEAN:
48960662d10Schristos         {
49060662d10Schristos             int boolval = *(int *)fld;
49160662d10Schristos             if (boolval == -1)
49260662d10Schristos                 boolval = it->size;
493*1dcdf01fSchristos             ret = asn1_print_boolean(out, boolval);
49460662d10Schristos         }
49560662d10Schristos         break;
49660662d10Schristos 
49760662d10Schristos     case V_ASN1_INTEGER:
49860662d10Schristos     case V_ASN1_ENUMERATED:
499*1dcdf01fSchristos         ret = asn1_print_integer(out, str);
50060662d10Schristos         break;
50160662d10Schristos 
50260662d10Schristos     case V_ASN1_UTCTIME:
50360662d10Schristos         ret = ASN1_UTCTIME_print(out, str);
50460662d10Schristos         break;
50560662d10Schristos 
50660662d10Schristos     case V_ASN1_GENERALIZEDTIME:
50760662d10Schristos         ret = ASN1_GENERALIZEDTIME_print(out, str);
50860662d10Schristos         break;
50960662d10Schristos 
51060662d10Schristos     case V_ASN1_OBJECT:
511*1dcdf01fSchristos         ret = asn1_print_oid(out, (const ASN1_OBJECT *)*fld);
51260662d10Schristos         break;
51360662d10Schristos 
51460662d10Schristos     case V_ASN1_OCTET_STRING:
51560662d10Schristos     case V_ASN1_BIT_STRING:
516*1dcdf01fSchristos         ret = asn1_print_obstring(out, str, indent);
51760662d10Schristos         needlf = 0;
51860662d10Schristos         break;
51960662d10Schristos 
52060662d10Schristos     case V_ASN1_SEQUENCE:
52160662d10Schristos     case V_ASN1_SET:
52260662d10Schristos     case V_ASN1_OTHER:
52360662d10Schristos         if (BIO_puts(out, "\n") <= 0)
52460662d10Schristos             return 0;
52560662d10Schristos         if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0)
52660662d10Schristos             ret = 0;
52760662d10Schristos         needlf = 0;
52860662d10Schristos         break;
52960662d10Schristos 
53060662d10Schristos     default:
53160662d10Schristos         ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
53260662d10Schristos 
53360662d10Schristos     }
53460662d10Schristos     if (!ret)
53560662d10Schristos         return 0;
53660662d10Schristos     if (needlf && BIO_puts(out, "\n") <= 0)
53760662d10Schristos         return 0;
53860662d10Schristos     return 1;
53960662d10Schristos }
540