Loading crypto/asn1/asn1_locl.h 0 → 100644 +70 −0 Original line number Diff line number Diff line /* asn1t.h */ /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL * project 2005. */ /* ==================================================================== * Copyright (c) 2005 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */ /* Internal ASN1 structures and functions: not for application use */ /* ASN1 print context structure */ struct asn1_pctx_st { unsigned long flags; unsigned long nm_flags; unsigned long cert_flags; unsigned long oid_flags; unsigned long str_flags; } /* ASN1_PCTX */; crypto/asn1/tasn_prn.c +410 −98 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== * Copyright (c) 2000 The OpenSSL Project. All rights reserved. * Copyright (c) 2000,2005 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions Loading Loading @@ -59,140 +59,452 @@ #include <stddef.h> #include <openssl/asn1.h> #include <openssl/asn1t.h> #include <openssl/objects.h> #include <openssl/buffer.h> #include <openssl/err.h> #include <openssl/nasn.h> #include <openssl/x509v3.h> #include "asn1_locl.h" /* Print routines. Print out a whole structure from a template. #define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x1 #define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x2 #define ASN1_PCTX_FLAGS_SHOW_TYPE 0x4 #define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x8 #define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x10 /* Print routines. */ static int asn1_item_print_nm(BIO *out, void *fld, int indent, const ASN1_ITEM *it, const char *name); /* ASN1_PCTX routines */ ASN1_PCTX default_pctx = { ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */ 0, /* nm_flags */ 0, /* cert_flags */ 0, /* oid_flags */ 0 /* str_flags */ }; ASN1_PCTX *ASN1_PCTX_new(void) { ASN1_PCTX *ret; ret = OPENSSL_malloc(sizeof(ASN1_PCTX)); if (ret == NULL) { ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE); return NULL; } ret->flags = 0; ret->nm_flags = 0; ret->cert_flags = 0; ret->oid_flags = 0; ret->str_flags = 0; return ret; } int ASN1_item_print(BIO *out, void *fld, int indent, const ASN1_ITEM *it) void ASN1_PCTX_free(ASN1_PCTX *p) { return asn1_item_print_nm(out, fld, indent, it, it->sname); OPENSSL_free(p); } static int asn1_item_print_nm(BIO *out, void *fld, int indent, const ASN1_ITEM *it, const char *name) unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p) { return p->flags; } void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags) { p->flags = flags; } unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p) { return p->nm_flags; } void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags) { p->nm_flags = flags; } unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p) { return p->cert_flags; } void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags) { p->cert_flags = flags; } unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p) { return p->oid_flags; } void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags) { p->oid_flags = flags; } unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p) { return p->str_flags; } void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags) { p->str_flags = flags; } /* Main print routines */ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, const ASN1_ITEM *it, const ASN1_PCTX *pctx); int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx); static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx); int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, const ASN1_ITEM *it, const ASN1_PCTX *pctx) { if (pctx == NULL) pctx = &default_pctx; return asn1_item_print_ctx(out, &ifld, indent, it, pctx); } static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, const ASN1_ITEM *it, const ASN1_PCTX *pctx) { ASN1_STRING *str; const ASN1_TEMPLATE *tt; void *tmpfld; const ASN1_EXTERN_FUNCS *ef; ASN1_VALUE **tmpfld; int i; if(!fld) { BIO_printf(out, "%*s%s ABSENT\n", indent, "", name); if (BIO_printf(out, "%s:", it->sname) <= 0) return 0; if(*fld == NULL) { if (!(pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT)) { if (BIO_puts(out, "\n") <= 0) return 0; } else { if (BIO_puts(out, "<ABSENT>\n") <= 0) return 0; } return 1; } switch(it->itype) { switch(it->itype) { case ASN1_ITYPE_PRIMITIVE: if(it->templates) return ASN1_template_print(out, fld, indent, it->templates); return asn1_primitive_print(out, fld, it->utype, indent, name); break; { if (!asn1_template_print_ctx(out, fld, indent, it->templates, pctx)) return 0; } /* fall thru */ case ASN1_ITYPE_MSTRING: str = fld; return asn1_primitive_print(out, fld, str->type, indent, name); if (!asn1_primitive_print(out, fld, it, indent, pctx)) return 0; break; case ASN1_ITYPE_EXTERN: BIO_printf(out, "%*s%s:EXTERNAL TYPE %s %s\n", indent, "", name, it->sname, fld ? "" : "ABSENT"); return 1; case ASN1_ITYPE_COMPAT: BIO_printf(out, "%*s%s:COMPATIBLE TYPE %s %s\n", indent, "", name, it->sname, fld ? "" : "ABSENT"); return 1; /* Use new style print routine if possible */ ef = it->funcs; if (ef && ef->asn1_ex_print) { if (!ef->asn1_ex_print(out, fld, indent, "", pctx)) return 0; } else if (BIO_printf(out, ":EXTERNAL TYPE %s\n", it->sname) <= 0) return 0; break; case ASN1_ITYPE_CHOICE: /* CHOICE type, get selector */ i = asn1_get_choice_selector(fld, it); /* This should never happen... */ if((i < 0) || (i >= it->tcount)) { BIO_printf(out, "%s selector [%d] out of range\n", it->sname, i); if((i < 0) || (i >= it->tcount)) { if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0) return 0; return 1; } tt = it->templates + i; tmpfld = asn1_get_field(fld, tt); return ASN1_template_print(out, tmpfld, indent, tt); tmpfld = asn1_get_field_ptr(fld, tt); if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx)) return 0; break; case ASN1_ITYPE_SEQUENCE: BIO_printf(out, "%*s%s {\n", indent, "", name); /* Get each field entry */ for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) { tmpfld = asn1_get_field(fld, tt); ASN1_template_print(out, tmpfld, indent + 2, tt); case ASN1_ITYPE_NDEF_SEQUENCE: if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { if (BIO_puts(out, " {\n") <= 0) return 0; } else { if (BIO_puts(out, "\n") <= 0) return 0; } BIO_printf(out, "%*s}\n", indent, ""); return 1; /* Print each field entry */ for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) { const ASN1_TEMPLATE *seqtt; seqtt = asn1_do_adb(fld, tt, 1); tmpfld = asn1_get_field_ptr(fld, seqtt); if (!asn1_template_print_ctx(out, tmpfld, indent + 2, seqtt, pctx)) return 0; } if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { if (BIO_printf(out, "%*s}\n", indent, "") < 0) return 0; } break; default: BIO_printf(out, "Unprocessed type %d\n", it->itype); return 0; } if (BIO_puts(out, "\n") <= 0) return 0; return 1; } int ASN1_template_print(BIO *out, void *fld, int indent, const ASN1_TEMPLATE *tt) int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx) { int i, flags; #if 0 if(!fld) return 0; #endif flags = tt->flags; if(flags & ASN1_TFLG_SK_MASK) { if(flags & ASN1_TFLG_SK_MASK) { char *tname; void *skitem; ASN1_VALUE *skitem; /* SET OF, SEQUENCE OF */ if(flags & ASN1_TFLG_SET_OF) tname = "SET"; else tname = "SEQUENCE"; if(fld) { BIO_printf(out, "%*s%s OF %s {\n", indent, "", tname, tt->field_name); for(i = 0; i < sk_num(fld); i++) { skitem = sk_value(fld, i); asn1_item_print_nm(out, skitem, indent + 2, tt->item, ""); } BIO_printf(out, "%*s}\n", indent, ""); } else BIO_printf(out, "%*s%s OF %s ABSENT\n", indent, "", tname, tt->field_name); if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { if(flags & ASN1_TFLG_SET_OF) tname = "SET"; else tname = "SEQUENCE"; if (BIO_printf(out, "%*s%s OF %s {\n", indent, "", tname, tt->field_name) <= 0) return 0; } else if (BIO_printf(out, "%*s%s:\n", indent, "", tt->field_name) <= 0) return 0; for(i = 0; i < sk_num((STACK *)*fld); i++) { if (BIO_printf(out, "%*s", indent + 2, "") <= 0) return 0; skitem = (ASN1_VALUE *)sk_value((STACK *)*fld, i); if (!asn1_item_print_ctx(out, &skitem, indent + 2, tt->item, pctx)) return 0; } if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { if (BIO_printf(out, "%*s}\n", indent, "") <= 0) return 0; } return 1; } else if (BIO_printf(out, "%*s%s:", indent, "", tt->field_name) <= 0) return 0; return asn1_item_print_ctx(out, fld, indent, tt->item, pctx); } int asn1_print_fsname(BIO *out, int indent, const char *fname, const char *sname, const ASN1_PCTX *pctx) { static char spaces[] = " "; const int nspaces = sizeof(spaces) - 1; while (indent > nspaces) { if (BIO_write(out, spaces, nspaces) != nspaces) return 0; indent -= nspaces; } if (BIO_write(out, spaces, indent) != indent) return 0; if (!(pctx->flags & (ASN1_PCTX_FLAGS_NO_FIELD_NAME|ASN1_PCTX_FLAGS_NO_STRUCT_NAME))) return 1; if (fname && !(pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)) { if (BIO_puts(out, fname) <= 0) return 0; } if (sname && !(pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)) { if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) { if (BIO_puts(out, sname) <= 0) return 0; } else if (BIO_printf(out, " (%s)", sname) <= 0) return 0; } if (BIO_write(out, ":", 1) != 1) return 0; return 1; } return asn1_item_print_nm(out, fld, indent, tt->item, tt->field_name); int asn1_print_boolean_ctx(BIO *out, const int bool, const ASN1_PCTX *pctx) { const char *str; switch (bool) { case -1: str = "BOOL ABSENT"; break; case 0: str = "FALSE"; break; default: str = "TRUE"; break; } static int asn1_primitive_print(BIO *out, void *fld, long utype, int indent, const char *name) if (BIO_puts(out, str) <= 0) return 0; return 1; } static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str, const ASN1_PCTX *pctx) { ASN1_STRING *str = fld; if(fld) { if(utype == V_ASN1_BOOLEAN) { int *bool = fld; if(*bool == -1) printf("BOOL MISSING\n"); BIO_printf(out, "%*s%s:%s", indent, "", "BOOLEAN", *bool ? "TRUE" : "FALSE"); } else if((utype == V_ASN1_INTEGER) || (utype == V_ASN1_ENUMERATED)) { char *s, *nm; s = i2s_ASN1_INTEGER(NULL, fld); if(utype == V_ASN1_INTEGER) nm = "INTEGER"; else nm = "ENUMERATED"; BIO_printf(out, "%*s%s:%s", indent, "", nm, s); char *s; int ret = 1; s = i2s_ASN1_INTEGER(NULL, str); if (BIO_printf(out, "%s", s) <= 0) ret = 0; OPENSSL_free(s); } else if(utype == V_ASN1_NULL) { BIO_printf(out, "%*s%s", indent, "", "NULL"); } else if(utype == V_ASN1_UTCTIME) { BIO_printf(out, "%*s%s:%s:", indent, "", name, "UTCTIME"); ASN1_UTCTIME_print(out, str); } else if(utype == V_ASN1_GENERALIZEDTIME) { BIO_printf(out, "%*s%s:%s:", indent, "", name, "GENERALIZEDTIME"); ASN1_GENERALIZEDTIME_print(out, str); } else if(utype == V_ASN1_OBJECT) { char objbuf[80], *ln; ln = OBJ_nid2ln(OBJ_obj2nid(fld)); if(!ln) ln = ""; OBJ_obj2txt(objbuf, sizeof objbuf, fld, 1); BIO_printf(out, "%*s%s:%s (%s)", indent, "", "OBJECT", ln, objbuf); } else { BIO_printf(out, "%*s%s:", indent, "", name); ASN1_STRING_print_ex(out, str, ASN1_STRFLGS_DUMP_UNKNOWN|ASN1_STRFLGS_SHOW_TYPE); } BIO_printf(out, "\n"); } else BIO_printf(out, "%*s%s [ABSENT]\n", indent, "", name); return ret; } static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid, const ASN1_PCTX *pctx) { char objbuf[80]; const char *ln; ln = OBJ_nid2ln(OBJ_obj2nid(oid)); if(!ln) ln = ""; OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1); if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0) return 0; return 1; } static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent, const ASN1_PCTX *pctx) { if (str->type == V_ASN1_BIT_STRING) { if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0) return 0; } else if (BIO_puts(out, "\n") <= 0) return 0; if (BIO_dump_indent(out, (char *)str->data, str->length, indent + 2) <= 0) return 0; return 1; } static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx) { long utype; ASN1_STRING *str; int ret = 1; str = (ASN1_STRING *)*fld; if (it->itype == ASN1_ITYPE_MSTRING) utype = str->type & ~V_ASN1_NEG; else utype = it->utype; if (utype == V_ASN1_ANY) { ASN1_TYPE *atype = (ASN1_TYPE *)*fld; utype = atype->type; fld = (ASN1_VALUE **)&atype->value.ptr; str = (ASN1_STRING *)*fld; } if (BIO_puts(out, ASN1_tag2str(utype)) <= 0) return 0; if (utype != V_ASN1_NULL && BIO_puts(out, ":") <= 0) return 0; switch (utype) { case V_ASN1_BOOLEAN: { int bool = *(int *)fld; if (bool == -1) bool = it->size; ret = asn1_print_boolean_ctx(out, bool, pctx); } break; case V_ASN1_INTEGER: case V_ASN1_ENUMERATED: ret = asn1_print_integer_ctx(out, str, pctx); break; case V_ASN1_NULL: break; case V_ASN1_UTCTIME: ret = ASN1_UTCTIME_print(out, str); break; case V_ASN1_GENERALIZEDTIME: ret = ASN1_GENERALIZEDTIME_print(out, str); break; case V_ASN1_OBJECT: ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx); break; case V_ASN1_OCTET_STRING: case V_ASN1_BIT_STRING: ret = asn1_print_obstring_ctx(out, str, indent, pctx); break; case V_ASN1_SEQUENCE: case V_ASN1_SET: if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0) ret = 0; break; default: ret = ASN1_STRING_print_ex(out, str, pctx->str_flags); } if (!ret) return 0; return 1; } Loading
crypto/asn1/asn1_locl.h 0 → 100644 +70 −0 Original line number Diff line number Diff line /* asn1t.h */ /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL * project 2005. */ /* ==================================================================== * Copyright (c) 2005 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */ /* Internal ASN1 structures and functions: not for application use */ /* ASN1 print context structure */ struct asn1_pctx_st { unsigned long flags; unsigned long nm_flags; unsigned long cert_flags; unsigned long oid_flags; unsigned long str_flags; } /* ASN1_PCTX */;
crypto/asn1/tasn_prn.c +410 −98 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== * Copyright (c) 2000 The OpenSSL Project. All rights reserved. * Copyright (c) 2000,2005 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions Loading Loading @@ -59,140 +59,452 @@ #include <stddef.h> #include <openssl/asn1.h> #include <openssl/asn1t.h> #include <openssl/objects.h> #include <openssl/buffer.h> #include <openssl/err.h> #include <openssl/nasn.h> #include <openssl/x509v3.h> #include "asn1_locl.h" /* Print routines. Print out a whole structure from a template. #define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x1 #define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x2 #define ASN1_PCTX_FLAGS_SHOW_TYPE 0x4 #define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x8 #define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x10 /* Print routines. */ static int asn1_item_print_nm(BIO *out, void *fld, int indent, const ASN1_ITEM *it, const char *name); /* ASN1_PCTX routines */ ASN1_PCTX default_pctx = { ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */ 0, /* nm_flags */ 0, /* cert_flags */ 0, /* oid_flags */ 0 /* str_flags */ }; ASN1_PCTX *ASN1_PCTX_new(void) { ASN1_PCTX *ret; ret = OPENSSL_malloc(sizeof(ASN1_PCTX)); if (ret == NULL) { ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE); return NULL; } ret->flags = 0; ret->nm_flags = 0; ret->cert_flags = 0; ret->oid_flags = 0; ret->str_flags = 0; return ret; } int ASN1_item_print(BIO *out, void *fld, int indent, const ASN1_ITEM *it) void ASN1_PCTX_free(ASN1_PCTX *p) { return asn1_item_print_nm(out, fld, indent, it, it->sname); OPENSSL_free(p); } static int asn1_item_print_nm(BIO *out, void *fld, int indent, const ASN1_ITEM *it, const char *name) unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p) { return p->flags; } void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags) { p->flags = flags; } unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p) { return p->nm_flags; } void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags) { p->nm_flags = flags; } unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p) { return p->cert_flags; } void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags) { p->cert_flags = flags; } unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p) { return p->oid_flags; } void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags) { p->oid_flags = flags; } unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p) { return p->str_flags; } void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags) { p->str_flags = flags; } /* Main print routines */ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, const ASN1_ITEM *it, const ASN1_PCTX *pctx); int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx); static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx); int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, const ASN1_ITEM *it, const ASN1_PCTX *pctx) { if (pctx == NULL) pctx = &default_pctx; return asn1_item_print_ctx(out, &ifld, indent, it, pctx); } static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, const ASN1_ITEM *it, const ASN1_PCTX *pctx) { ASN1_STRING *str; const ASN1_TEMPLATE *tt; void *tmpfld; const ASN1_EXTERN_FUNCS *ef; ASN1_VALUE **tmpfld; int i; if(!fld) { BIO_printf(out, "%*s%s ABSENT\n", indent, "", name); if (BIO_printf(out, "%s:", it->sname) <= 0) return 0; if(*fld == NULL) { if (!(pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT)) { if (BIO_puts(out, "\n") <= 0) return 0; } else { if (BIO_puts(out, "<ABSENT>\n") <= 0) return 0; } return 1; } switch(it->itype) { switch(it->itype) { case ASN1_ITYPE_PRIMITIVE: if(it->templates) return ASN1_template_print(out, fld, indent, it->templates); return asn1_primitive_print(out, fld, it->utype, indent, name); break; { if (!asn1_template_print_ctx(out, fld, indent, it->templates, pctx)) return 0; } /* fall thru */ case ASN1_ITYPE_MSTRING: str = fld; return asn1_primitive_print(out, fld, str->type, indent, name); if (!asn1_primitive_print(out, fld, it, indent, pctx)) return 0; break; case ASN1_ITYPE_EXTERN: BIO_printf(out, "%*s%s:EXTERNAL TYPE %s %s\n", indent, "", name, it->sname, fld ? "" : "ABSENT"); return 1; case ASN1_ITYPE_COMPAT: BIO_printf(out, "%*s%s:COMPATIBLE TYPE %s %s\n", indent, "", name, it->sname, fld ? "" : "ABSENT"); return 1; /* Use new style print routine if possible */ ef = it->funcs; if (ef && ef->asn1_ex_print) { if (!ef->asn1_ex_print(out, fld, indent, "", pctx)) return 0; } else if (BIO_printf(out, ":EXTERNAL TYPE %s\n", it->sname) <= 0) return 0; break; case ASN1_ITYPE_CHOICE: /* CHOICE type, get selector */ i = asn1_get_choice_selector(fld, it); /* This should never happen... */ if((i < 0) || (i >= it->tcount)) { BIO_printf(out, "%s selector [%d] out of range\n", it->sname, i); if((i < 0) || (i >= it->tcount)) { if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0) return 0; return 1; } tt = it->templates + i; tmpfld = asn1_get_field(fld, tt); return ASN1_template_print(out, tmpfld, indent, tt); tmpfld = asn1_get_field_ptr(fld, tt); if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx)) return 0; break; case ASN1_ITYPE_SEQUENCE: BIO_printf(out, "%*s%s {\n", indent, "", name); /* Get each field entry */ for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) { tmpfld = asn1_get_field(fld, tt); ASN1_template_print(out, tmpfld, indent + 2, tt); case ASN1_ITYPE_NDEF_SEQUENCE: if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { if (BIO_puts(out, " {\n") <= 0) return 0; } else { if (BIO_puts(out, "\n") <= 0) return 0; } BIO_printf(out, "%*s}\n", indent, ""); return 1; /* Print each field entry */ for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) { const ASN1_TEMPLATE *seqtt; seqtt = asn1_do_adb(fld, tt, 1); tmpfld = asn1_get_field_ptr(fld, seqtt); if (!asn1_template_print_ctx(out, tmpfld, indent + 2, seqtt, pctx)) return 0; } if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { if (BIO_printf(out, "%*s}\n", indent, "") < 0) return 0; } break; default: BIO_printf(out, "Unprocessed type %d\n", it->itype); return 0; } if (BIO_puts(out, "\n") <= 0) return 0; return 1; } int ASN1_template_print(BIO *out, void *fld, int indent, const ASN1_TEMPLATE *tt) int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx) { int i, flags; #if 0 if(!fld) return 0; #endif flags = tt->flags; if(flags & ASN1_TFLG_SK_MASK) { if(flags & ASN1_TFLG_SK_MASK) { char *tname; void *skitem; ASN1_VALUE *skitem; /* SET OF, SEQUENCE OF */ if(flags & ASN1_TFLG_SET_OF) tname = "SET"; else tname = "SEQUENCE"; if(fld) { BIO_printf(out, "%*s%s OF %s {\n", indent, "", tname, tt->field_name); for(i = 0; i < sk_num(fld); i++) { skitem = sk_value(fld, i); asn1_item_print_nm(out, skitem, indent + 2, tt->item, ""); } BIO_printf(out, "%*s}\n", indent, ""); } else BIO_printf(out, "%*s%s OF %s ABSENT\n", indent, "", tname, tt->field_name); if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { if(flags & ASN1_TFLG_SET_OF) tname = "SET"; else tname = "SEQUENCE"; if (BIO_printf(out, "%*s%s OF %s {\n", indent, "", tname, tt->field_name) <= 0) return 0; } else if (BIO_printf(out, "%*s%s:\n", indent, "", tt->field_name) <= 0) return 0; for(i = 0; i < sk_num((STACK *)*fld); i++) { if (BIO_printf(out, "%*s", indent + 2, "") <= 0) return 0; skitem = (ASN1_VALUE *)sk_value((STACK *)*fld, i); if (!asn1_item_print_ctx(out, &skitem, indent + 2, tt->item, pctx)) return 0; } if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { if (BIO_printf(out, "%*s}\n", indent, "") <= 0) return 0; } return 1; } else if (BIO_printf(out, "%*s%s:", indent, "", tt->field_name) <= 0) return 0; return asn1_item_print_ctx(out, fld, indent, tt->item, pctx); } int asn1_print_fsname(BIO *out, int indent, const char *fname, const char *sname, const ASN1_PCTX *pctx) { static char spaces[] = " "; const int nspaces = sizeof(spaces) - 1; while (indent > nspaces) { if (BIO_write(out, spaces, nspaces) != nspaces) return 0; indent -= nspaces; } if (BIO_write(out, spaces, indent) != indent) return 0; if (!(pctx->flags & (ASN1_PCTX_FLAGS_NO_FIELD_NAME|ASN1_PCTX_FLAGS_NO_STRUCT_NAME))) return 1; if (fname && !(pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)) { if (BIO_puts(out, fname) <= 0) return 0; } if (sname && !(pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)) { if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) { if (BIO_puts(out, sname) <= 0) return 0; } else if (BIO_printf(out, " (%s)", sname) <= 0) return 0; } if (BIO_write(out, ":", 1) != 1) return 0; return 1; } return asn1_item_print_nm(out, fld, indent, tt->item, tt->field_name); int asn1_print_boolean_ctx(BIO *out, const int bool, const ASN1_PCTX *pctx) { const char *str; switch (bool) { case -1: str = "BOOL ABSENT"; break; case 0: str = "FALSE"; break; default: str = "TRUE"; break; } static int asn1_primitive_print(BIO *out, void *fld, long utype, int indent, const char *name) if (BIO_puts(out, str) <= 0) return 0; return 1; } static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str, const ASN1_PCTX *pctx) { ASN1_STRING *str = fld; if(fld) { if(utype == V_ASN1_BOOLEAN) { int *bool = fld; if(*bool == -1) printf("BOOL MISSING\n"); BIO_printf(out, "%*s%s:%s", indent, "", "BOOLEAN", *bool ? "TRUE" : "FALSE"); } else if((utype == V_ASN1_INTEGER) || (utype == V_ASN1_ENUMERATED)) { char *s, *nm; s = i2s_ASN1_INTEGER(NULL, fld); if(utype == V_ASN1_INTEGER) nm = "INTEGER"; else nm = "ENUMERATED"; BIO_printf(out, "%*s%s:%s", indent, "", nm, s); char *s; int ret = 1; s = i2s_ASN1_INTEGER(NULL, str); if (BIO_printf(out, "%s", s) <= 0) ret = 0; OPENSSL_free(s); } else if(utype == V_ASN1_NULL) { BIO_printf(out, "%*s%s", indent, "", "NULL"); } else if(utype == V_ASN1_UTCTIME) { BIO_printf(out, "%*s%s:%s:", indent, "", name, "UTCTIME"); ASN1_UTCTIME_print(out, str); } else if(utype == V_ASN1_GENERALIZEDTIME) { BIO_printf(out, "%*s%s:%s:", indent, "", name, "GENERALIZEDTIME"); ASN1_GENERALIZEDTIME_print(out, str); } else if(utype == V_ASN1_OBJECT) { char objbuf[80], *ln; ln = OBJ_nid2ln(OBJ_obj2nid(fld)); if(!ln) ln = ""; OBJ_obj2txt(objbuf, sizeof objbuf, fld, 1); BIO_printf(out, "%*s%s:%s (%s)", indent, "", "OBJECT", ln, objbuf); } else { BIO_printf(out, "%*s%s:", indent, "", name); ASN1_STRING_print_ex(out, str, ASN1_STRFLGS_DUMP_UNKNOWN|ASN1_STRFLGS_SHOW_TYPE); } BIO_printf(out, "\n"); } else BIO_printf(out, "%*s%s [ABSENT]\n", indent, "", name); return ret; } static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid, const ASN1_PCTX *pctx) { char objbuf[80]; const char *ln; ln = OBJ_nid2ln(OBJ_obj2nid(oid)); if(!ln) ln = ""; OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1); if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0) return 0; return 1; } static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent, const ASN1_PCTX *pctx) { if (str->type == V_ASN1_BIT_STRING) { if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0) return 0; } else if (BIO_puts(out, "\n") <= 0) return 0; if (BIO_dump_indent(out, (char *)str->data, str->length, indent + 2) <= 0) return 0; return 1; } static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx) { long utype; ASN1_STRING *str; int ret = 1; str = (ASN1_STRING *)*fld; if (it->itype == ASN1_ITYPE_MSTRING) utype = str->type & ~V_ASN1_NEG; else utype = it->utype; if (utype == V_ASN1_ANY) { ASN1_TYPE *atype = (ASN1_TYPE *)*fld; utype = atype->type; fld = (ASN1_VALUE **)&atype->value.ptr; str = (ASN1_STRING *)*fld; } if (BIO_puts(out, ASN1_tag2str(utype)) <= 0) return 0; if (utype != V_ASN1_NULL && BIO_puts(out, ":") <= 0) return 0; switch (utype) { case V_ASN1_BOOLEAN: { int bool = *(int *)fld; if (bool == -1) bool = it->size; ret = asn1_print_boolean_ctx(out, bool, pctx); } break; case V_ASN1_INTEGER: case V_ASN1_ENUMERATED: ret = asn1_print_integer_ctx(out, str, pctx); break; case V_ASN1_NULL: break; case V_ASN1_UTCTIME: ret = ASN1_UTCTIME_print(out, str); break; case V_ASN1_GENERALIZEDTIME: ret = ASN1_GENERALIZEDTIME_print(out, str); break; case V_ASN1_OBJECT: ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx); break; case V_ASN1_OCTET_STRING: case V_ASN1_BIT_STRING: ret = asn1_print_obstring_ctx(out, str, indent, pctx); break; case V_ASN1_SEQUENCE: case V_ASN1_SET: if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0) ret = 0; break; default: ret = ASN1_STRING_print_ex(out, str, pctx->str_flags); } if (!ret) return 0; return 1; }