1109998Smarkm/* tasn_prn.c */
2296465Sdelphij/*
3296465Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4296465Sdelphij * 2000.
5109998Smarkm */
6109998Smarkm/* ====================================================================
7109998Smarkm * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
8109998Smarkm *
9109998Smarkm * Redistribution and use in source and binary forms, with or without
10109998Smarkm * modification, are permitted provided that the following conditions
11109998Smarkm * are met:
12109998Smarkm *
13109998Smarkm * 1. Redistributions of source code must retain the above copyright
14296465Sdelphij *    notice, this list of conditions and the following disclaimer.
15109998Smarkm *
16109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright
17109998Smarkm *    notice, this list of conditions and the following disclaimer in
18109998Smarkm *    the documentation and/or other materials provided with the
19109998Smarkm *    distribution.
20109998Smarkm *
21109998Smarkm * 3. All advertising materials mentioning features or use of this
22109998Smarkm *    software must display the following acknowledgment:
23109998Smarkm *    "This product includes software developed by the OpenSSL Project
24109998Smarkm *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25109998Smarkm *
26109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27109998Smarkm *    endorse or promote products derived from this software without
28109998Smarkm *    prior written permission. For written permission, please contact
29109998Smarkm *    licensing@OpenSSL.org.
30109998Smarkm *
31109998Smarkm * 5. Products derived from this software may not be called "OpenSSL"
32109998Smarkm *    nor may "OpenSSL" appear in their names without prior written
33109998Smarkm *    permission of the OpenSSL Project.
34109998Smarkm *
35109998Smarkm * 6. Redistributions of any form whatsoever must retain the following
36109998Smarkm *    acknowledgment:
37109998Smarkm *    "This product includes software developed by the OpenSSL Project
38109998Smarkm *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39109998Smarkm *
40109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43109998Smarkm * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE.
52109998Smarkm * ====================================================================
53109998Smarkm *
54109998Smarkm * This product includes cryptographic software written by Eric Young
55109998Smarkm * (eay@cryptsoft.com).  This product includes software written by Tim
56109998Smarkm * Hudson (tjh@cryptsoft.com).
57109998Smarkm *
58109998Smarkm */
59109998Smarkm
60109998Smarkm#include <stddef.h>
61109998Smarkm#include <openssl/asn1.h>
62109998Smarkm#include <openssl/objects.h>
63109998Smarkm#include <openssl/buffer.h>
64109998Smarkm#include <openssl/err.h>
65109998Smarkm#include <openssl/nasn.h>
66109998Smarkm
67296465Sdelphij/*
68296465Sdelphij * Print routines. Print out a whole structure from a template.
69109998Smarkm */
70109998Smarkm
71296465Sdelphijstatic int asn1_item_print_nm(BIO *out, void *fld, int indent,
72296465Sdelphij                              const ASN1_ITEM *it, const char *name);
73109998Smarkm
74109998Smarkmint ASN1_item_print(BIO *out, void *fld, int indent, const ASN1_ITEM *it)
75109998Smarkm{
76296465Sdelphij    return asn1_item_print_nm(out, fld, indent, it, it->sname);
77109998Smarkm}
78109998Smarkm
79296465Sdelphijstatic int asn1_item_print_nm(BIO *out, void *fld, int indent,
80296465Sdelphij                              const ASN1_ITEM *it, const char *name)
81109998Smarkm{
82296465Sdelphij    ASN1_STRING *str;
83296465Sdelphij    const ASN1_TEMPLATE *tt;
84296465Sdelphij    void *tmpfld;
85296465Sdelphij    int i;
86296465Sdelphij    if (!fld) {
87296465Sdelphij        BIO_printf(out, "%*s%s ABSENT\n", indent, "", name);
88296465Sdelphij        return 1;
89296465Sdelphij    }
90296465Sdelphij    switch (it->itype) {
91109998Smarkm
92296465Sdelphij    case ASN1_ITYPE_PRIMITIVE:
93296465Sdelphij        if (it->templates)
94296465Sdelphij            return ASN1_template_print(out, fld, indent, it->templates);
95296465Sdelphij        return asn1_primitive_print(out, fld, it->utype, indent, name);
96296465Sdelphij        break;
97109998Smarkm
98296465Sdelphij    case ASN1_ITYPE_MSTRING:
99296465Sdelphij        str = fld;
100296465Sdelphij        return asn1_primitive_print(out, fld, str->type, indent, name);
101109998Smarkm
102296465Sdelphij    case ASN1_ITYPE_EXTERN:
103296465Sdelphij        BIO_printf(out, "%*s%s:EXTERNAL TYPE %s %s\n", indent, "", name,
104296465Sdelphij                   it->sname, fld ? "" : "ABSENT");
105296465Sdelphij        return 1;
106296465Sdelphij    case ASN1_ITYPE_COMPAT:
107296465Sdelphij        BIO_printf(out, "%*s%s:COMPATIBLE TYPE %s %s\n", indent, "", name,
108296465Sdelphij                   it->sname, fld ? "" : "ABSENT");
109296465Sdelphij        return 1;
110109998Smarkm
111296465Sdelphij    case ASN1_ITYPE_CHOICE:
112296465Sdelphij        /* CHOICE type, get selector */
113296465Sdelphij        i = asn1_get_choice_selector(fld, it);
114296465Sdelphij        /* This should never happen... */
115296465Sdelphij        if ((i < 0) || (i >= it->tcount)) {
116296465Sdelphij            BIO_printf(out, "%s selector [%d] out of range\n", it->sname, i);
117296465Sdelphij            return 1;
118296465Sdelphij        }
119296465Sdelphij        tt = it->templates + i;
120296465Sdelphij        tmpfld = asn1_get_field(fld, tt);
121296465Sdelphij        return ASN1_template_print(out, tmpfld, indent, tt);
122109998Smarkm
123296465Sdelphij    case ASN1_ITYPE_SEQUENCE:
124296465Sdelphij        BIO_printf(out, "%*s%s {\n", indent, "", name);
125296465Sdelphij        /* Get each field entry */
126296465Sdelphij        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
127296465Sdelphij            tmpfld = asn1_get_field(fld, tt);
128296465Sdelphij            ASN1_template_print(out, tmpfld, indent + 2, tt);
129296465Sdelphij        }
130296465Sdelphij        BIO_printf(out, "%*s}\n", indent, "");
131296465Sdelphij        return 1;
132109998Smarkm
133296465Sdelphij    default:
134296465Sdelphij        return 0;
135296465Sdelphij    }
136109998Smarkm}
137109998Smarkm
138296465Sdelphijint ASN1_template_print(BIO *out, void *fld, int indent,
139296465Sdelphij                        const ASN1_TEMPLATE *tt)
140109998Smarkm{
141296465Sdelphij    int i, flags;
142109998Smarkm#if 0
143296465Sdelphij    if (!fld)
144296465Sdelphij        return 0;
145109998Smarkm#endif
146296465Sdelphij    flags = tt->flags;
147296465Sdelphij    if (flags & ASN1_TFLG_SK_MASK) {
148296465Sdelphij        char *tname;
149296465Sdelphij        void *skitem;
150296465Sdelphij        /* SET OF, SEQUENCE OF */
151296465Sdelphij        if (flags & ASN1_TFLG_SET_OF)
152296465Sdelphij            tname = "SET";
153296465Sdelphij        else
154296465Sdelphij            tname = "SEQUENCE";
155296465Sdelphij        if (fld) {
156296465Sdelphij            BIO_printf(out, "%*s%s OF %s {\n", indent, "", tname,
157296465Sdelphij                       tt->field_name);
158296465Sdelphij            for (i = 0; i < sk_num(fld); i++) {
159296465Sdelphij                skitem = sk_value(fld, i);
160296465Sdelphij                asn1_item_print_nm(out, skitem, indent + 2, tt->item, "");
161296465Sdelphij            }
162296465Sdelphij            BIO_printf(out, "%*s}\n", indent, "");
163296465Sdelphij        } else
164296465Sdelphij            BIO_printf(out, "%*s%s OF %s ABSENT\n", indent, "", tname,
165296465Sdelphij                       tt->field_name);
166296465Sdelphij        return 1;
167296465Sdelphij    }
168296465Sdelphij    return asn1_item_print_nm(out, fld, indent, tt->item, tt->field_name);
169109998Smarkm}
170109998Smarkm
171296465Sdelphijstatic int asn1_primitive_print(BIO *out, void *fld, long utype, int indent,
172296465Sdelphij                                const char *name)
173109998Smarkm{
174296465Sdelphij    ASN1_STRING *str = fld;
175296465Sdelphij    if (fld) {
176296465Sdelphij        if (utype == V_ASN1_BOOLEAN) {
177296465Sdelphij            int *bool = fld;
178296465Sdelphij            if (*bool == -1)
179296465Sdelphij                printf("BOOL MISSING\n");
180296465Sdelphij            BIO_printf(out, "%*s%s:%s", indent, "", "BOOLEAN",
181296465Sdelphij                       *bool ? "TRUE" : "FALSE");
182296465Sdelphij        } else if ((utype == V_ASN1_INTEGER)
183296465Sdelphij                   || (utype == V_ASN1_ENUMERATED)) {
184296465Sdelphij            char *s, *nm;
185296465Sdelphij            s = i2s_ASN1_INTEGER(NULL, fld);
186296465Sdelphij            if (utype == V_ASN1_INTEGER)
187296465Sdelphij                nm = "INTEGER";
188296465Sdelphij            else
189296465Sdelphij                nm = "ENUMERATED";
190296465Sdelphij            BIO_printf(out, "%*s%s:%s", indent, "", nm, s);
191296465Sdelphij            OPENSSL_free(s);
192296465Sdelphij        } else if (utype == V_ASN1_NULL) {
193296465Sdelphij            BIO_printf(out, "%*s%s", indent, "", "NULL");
194296465Sdelphij        } else if (utype == V_ASN1_UTCTIME) {
195296465Sdelphij            BIO_printf(out, "%*s%s:%s:", indent, "", name, "UTCTIME");
196296465Sdelphij            ASN1_UTCTIME_print(out, str);
197296465Sdelphij        } else if (utype == V_ASN1_GENERALIZEDTIME) {
198296465Sdelphij            BIO_printf(out, "%*s%s:%s:", indent, "", name, "GENERALIZEDTIME");
199296465Sdelphij            ASN1_GENERALIZEDTIME_print(out, str);
200296465Sdelphij        } else if (utype == V_ASN1_OBJECT) {
201296465Sdelphij            char objbuf[80], *ln;
202296465Sdelphij            ln = OBJ_nid2ln(OBJ_obj2nid(fld));
203296465Sdelphij            if (!ln)
204296465Sdelphij                ln = "";
205296465Sdelphij            OBJ_obj2txt(objbuf, sizeof objbuf, fld, 1);
206296465Sdelphij            BIO_printf(out, "%*s%s:%s (%s)", indent, "", "OBJECT", ln,
207296465Sdelphij                       objbuf);
208296465Sdelphij        } else {
209296465Sdelphij            BIO_printf(out, "%*s%s:", indent, "", name);
210296465Sdelphij            ASN1_STRING_print_ex(out, str,
211296465Sdelphij                                 ASN1_STRFLGS_DUMP_UNKNOWN |
212296465Sdelphij                                 ASN1_STRFLGS_SHOW_TYPE);
213296465Sdelphij        }
214296465Sdelphij        BIO_printf(out, "\n");
215296465Sdelphij    } else
216296465Sdelphij        BIO_printf(out, "%*s%s [ABSENT]\n", indent, "", name);
217296465Sdelphij    return 1;
218109998Smarkm}
219