tasn_prn.c revision 296465
1/* tasn_prn.c */ 2/* 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4 * 2000. 5 */ 6/* ==================================================================== 7 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 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 14 * notice, this list of conditions and the following disclaimer. 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 60#include <stddef.h> 61#include <openssl/asn1.h> 62#include <openssl/objects.h> 63#include <openssl/buffer.h> 64#include <openssl/err.h> 65#include <openssl/nasn.h> 66 67/* 68 * Print routines. Print out a whole structure from a template. 69 */ 70 71static int asn1_item_print_nm(BIO *out, void *fld, int indent, 72 const ASN1_ITEM *it, const char *name); 73 74int ASN1_item_print(BIO *out, void *fld, int indent, const ASN1_ITEM *it) 75{ 76 return asn1_item_print_nm(out, fld, indent, it, it->sname); 77} 78 79static int asn1_item_print_nm(BIO *out, void *fld, int indent, 80 const ASN1_ITEM *it, const char *name) 81{ 82 ASN1_STRING *str; 83 const ASN1_TEMPLATE *tt; 84 void *tmpfld; 85 int i; 86 if (!fld) { 87 BIO_printf(out, "%*s%s ABSENT\n", indent, "", name); 88 return 1; 89 } 90 switch (it->itype) { 91 92 case ASN1_ITYPE_PRIMITIVE: 93 if (it->templates) 94 return ASN1_template_print(out, fld, indent, it->templates); 95 return asn1_primitive_print(out, fld, it->utype, indent, name); 96 break; 97 98 case ASN1_ITYPE_MSTRING: 99 str = fld; 100 return asn1_primitive_print(out, fld, str->type, indent, name); 101 102 case ASN1_ITYPE_EXTERN: 103 BIO_printf(out, "%*s%s:EXTERNAL TYPE %s %s\n", indent, "", name, 104 it->sname, fld ? "" : "ABSENT"); 105 return 1; 106 case ASN1_ITYPE_COMPAT: 107 BIO_printf(out, "%*s%s:COMPATIBLE TYPE %s %s\n", indent, "", name, 108 it->sname, fld ? "" : "ABSENT"); 109 return 1; 110 111 case ASN1_ITYPE_CHOICE: 112 /* CHOICE type, get selector */ 113 i = asn1_get_choice_selector(fld, it); 114 /* This should never happen... */ 115 if ((i < 0) || (i >= it->tcount)) { 116 BIO_printf(out, "%s selector [%d] out of range\n", it->sname, i); 117 return 1; 118 } 119 tt = it->templates + i; 120 tmpfld = asn1_get_field(fld, tt); 121 return ASN1_template_print(out, tmpfld, indent, tt); 122 123 case ASN1_ITYPE_SEQUENCE: 124 BIO_printf(out, "%*s%s {\n", indent, "", name); 125 /* Get each field entry */ 126 for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { 127 tmpfld = asn1_get_field(fld, tt); 128 ASN1_template_print(out, tmpfld, indent + 2, tt); 129 } 130 BIO_printf(out, "%*s}\n", indent, ""); 131 return 1; 132 133 default: 134 return 0; 135 } 136} 137 138int ASN1_template_print(BIO *out, void *fld, int indent, 139 const ASN1_TEMPLATE *tt) 140{ 141 int i, flags; 142#if 0 143 if (!fld) 144 return 0; 145#endif 146 flags = tt->flags; 147 if (flags & ASN1_TFLG_SK_MASK) { 148 char *tname; 149 void *skitem; 150 /* SET OF, SEQUENCE OF */ 151 if (flags & ASN1_TFLG_SET_OF) 152 tname = "SET"; 153 else 154 tname = "SEQUENCE"; 155 if (fld) { 156 BIO_printf(out, "%*s%s OF %s {\n", indent, "", tname, 157 tt->field_name); 158 for (i = 0; i < sk_num(fld); i++) { 159 skitem = sk_value(fld, i); 160 asn1_item_print_nm(out, skitem, indent + 2, tt->item, ""); 161 } 162 BIO_printf(out, "%*s}\n", indent, ""); 163 } else 164 BIO_printf(out, "%*s%s OF %s ABSENT\n", indent, "", tname, 165 tt->field_name); 166 return 1; 167 } 168 return asn1_item_print_nm(out, fld, indent, tt->item, tt->field_name); 169} 170 171static int asn1_primitive_print(BIO *out, void *fld, long utype, int indent, 172 const char *name) 173{ 174 ASN1_STRING *str = fld; 175 if (fld) { 176 if (utype == V_ASN1_BOOLEAN) { 177 int *bool = fld; 178 if (*bool == -1) 179 printf("BOOL MISSING\n"); 180 BIO_printf(out, "%*s%s:%s", indent, "", "BOOLEAN", 181 *bool ? "TRUE" : "FALSE"); 182 } else if ((utype == V_ASN1_INTEGER) 183 || (utype == V_ASN1_ENUMERATED)) { 184 char *s, *nm; 185 s = i2s_ASN1_INTEGER(NULL, fld); 186 if (utype == V_ASN1_INTEGER) 187 nm = "INTEGER"; 188 else 189 nm = "ENUMERATED"; 190 BIO_printf(out, "%*s%s:%s", indent, "", nm, s); 191 OPENSSL_free(s); 192 } else if (utype == V_ASN1_NULL) { 193 BIO_printf(out, "%*s%s", indent, "", "NULL"); 194 } else if (utype == V_ASN1_UTCTIME) { 195 BIO_printf(out, "%*s%s:%s:", indent, "", name, "UTCTIME"); 196 ASN1_UTCTIME_print(out, str); 197 } else if (utype == V_ASN1_GENERALIZEDTIME) { 198 BIO_printf(out, "%*s%s:%s:", indent, "", name, "GENERALIZEDTIME"); 199 ASN1_GENERALIZEDTIME_print(out, str); 200 } else if (utype == V_ASN1_OBJECT) { 201 char objbuf[80], *ln; 202 ln = OBJ_nid2ln(OBJ_obj2nid(fld)); 203 if (!ln) 204 ln = ""; 205 OBJ_obj2txt(objbuf, sizeof objbuf, fld, 1); 206 BIO_printf(out, "%*s%s:%s (%s)", indent, "", "OBJECT", ln, 207 objbuf); 208 } else { 209 BIO_printf(out, "%*s%s:", indent, "", name); 210 ASN1_STRING_print_ex(out, str, 211 ASN1_STRFLGS_DUMP_UNKNOWN | 212 ASN1_STRFLGS_SHOW_TYPE); 213 } 214 BIO_printf(out, "\n"); 215 } else 216 BIO_printf(out, "%*s%s [ABSENT]\n", indent, "", name); 217 return 1; 218} 219