1109998Smarkm/* tasn_prn.c */ 2194206Ssimon/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3109998Smarkm * project 2000. 4109998Smarkm */ 5109998Smarkm/* ==================================================================== 6238405Sjkim * Copyright (c) 2000,2005 The OpenSSL Project. All rights reserved. 7109998Smarkm * 8109998Smarkm * Redistribution and use in source and binary forms, with or without 9109998Smarkm * modification, are permitted provided that the following conditions 10109998Smarkm * are met: 11109998Smarkm * 12109998Smarkm * 1. Redistributions of source code must retain the above copyright 13109998Smarkm * notice, this list of conditions and the following disclaimer. 14109998Smarkm * 15109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 16109998Smarkm * notice, this list of conditions and the following disclaimer in 17109998Smarkm * the documentation and/or other materials provided with the 18109998Smarkm * distribution. 19109998Smarkm * 20109998Smarkm * 3. All advertising materials mentioning features or use of this 21109998Smarkm * software must display the following acknowledgment: 22109998Smarkm * "This product includes software developed by the OpenSSL Project 23109998Smarkm * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24109998Smarkm * 25109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26109998Smarkm * endorse or promote products derived from this software without 27109998Smarkm * prior written permission. For written permission, please contact 28109998Smarkm * licensing@OpenSSL.org. 29109998Smarkm * 30109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 31109998Smarkm * nor may "OpenSSL" appear in their names without prior written 32109998Smarkm * permission of the OpenSSL Project. 33109998Smarkm * 34109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 35109998Smarkm * acknowledgment: 36109998Smarkm * "This product includes software developed by the OpenSSL Project 37109998Smarkm * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38109998Smarkm * 39109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 51109998Smarkm * ==================================================================== 52109998Smarkm * 53109998Smarkm * This product includes cryptographic software written by Eric Young 54109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 55109998Smarkm * Hudson (tjh@cryptsoft.com). 56109998Smarkm * 57109998Smarkm */ 58109998Smarkm 59109998Smarkm 60109998Smarkm#include <stddef.h> 61238405Sjkim#include "cryptlib.h" 62109998Smarkm#include <openssl/asn1.h> 63238405Sjkim#include <openssl/asn1t.h> 64109998Smarkm#include <openssl/objects.h> 65109998Smarkm#include <openssl/buffer.h> 66109998Smarkm#include <openssl/err.h> 67238405Sjkim#include <openssl/x509v3.h> 68238405Sjkim#include "asn1_locl.h" 69109998Smarkm 70238405Sjkim/* Print routines. 71109998Smarkm */ 72109998Smarkm 73238405Sjkim/* ASN1_PCTX routines */ 74109998Smarkm 75238405SjkimASN1_PCTX default_pctx = 76238405Sjkim { 77238405Sjkim ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */ 78238405Sjkim 0, /* nm_flags */ 79238405Sjkim 0, /* cert_flags */ 80238405Sjkim 0, /* oid_flags */ 81238405Sjkim 0 /* str_flags */ 82238405Sjkim }; 83238405Sjkim 84109998Smarkm 85238405SjkimASN1_PCTX *ASN1_PCTX_new(void) 86238405Sjkim { 87238405Sjkim ASN1_PCTX *ret; 88238405Sjkim ret = OPENSSL_malloc(sizeof(ASN1_PCTX)); 89238405Sjkim if (ret == NULL) 90238405Sjkim { 91238405Sjkim ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE); 92238405Sjkim return NULL; 93238405Sjkim } 94238405Sjkim ret->flags = 0; 95238405Sjkim ret->nm_flags = 0; 96238405Sjkim ret->cert_flags = 0; 97238405Sjkim ret->oid_flags = 0; 98238405Sjkim ret->str_flags = 0; 99238405Sjkim return ret; 100238405Sjkim } 101238405Sjkim 102238405Sjkimvoid ASN1_PCTX_free(ASN1_PCTX *p) 103238405Sjkim { 104238405Sjkim OPENSSL_free(p); 105238405Sjkim } 106238405Sjkim 107238405Sjkimunsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p) 108238405Sjkim { 109238405Sjkim return p->flags; 110238405Sjkim } 111238405Sjkim 112238405Sjkimvoid ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags) 113238405Sjkim { 114238405Sjkim p->flags = flags; 115238405Sjkim } 116238405Sjkim 117238405Sjkimunsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p) 118238405Sjkim { 119238405Sjkim return p->nm_flags; 120238405Sjkim } 121238405Sjkim 122238405Sjkimvoid ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags) 123238405Sjkim { 124238405Sjkim p->nm_flags = flags; 125238405Sjkim } 126238405Sjkim 127238405Sjkimunsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p) 128238405Sjkim { 129238405Sjkim return p->cert_flags; 130238405Sjkim } 131238405Sjkim 132238405Sjkimvoid ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags) 133238405Sjkim { 134238405Sjkim p->cert_flags = flags; 135238405Sjkim } 136238405Sjkim 137238405Sjkimunsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p) 138238405Sjkim { 139238405Sjkim return p->oid_flags; 140238405Sjkim } 141238405Sjkim 142238405Sjkimvoid ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags) 143238405Sjkim { 144238405Sjkim p->oid_flags = flags; 145238405Sjkim } 146238405Sjkim 147238405Sjkimunsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p) 148238405Sjkim { 149238405Sjkim return p->str_flags; 150238405Sjkim } 151238405Sjkim 152238405Sjkimvoid ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags) 153238405Sjkim { 154238405Sjkim p->str_flags = flags; 155238405Sjkim } 156238405Sjkim 157238405Sjkim/* Main print routines */ 158238405Sjkim 159238405Sjkimstatic int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, 160238405Sjkim const ASN1_ITEM *it, 161238405Sjkim const char *fname, const char *sname, 162238405Sjkim int nohdr, const ASN1_PCTX *pctx); 163238405Sjkim 164238405Sjkimint asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, 165238405Sjkim const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx); 166238405Sjkim 167238405Sjkimstatic int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, 168238405Sjkim const ASN1_ITEM *it, int indent, 169238405Sjkim const char *fname, const char *sname, 170238405Sjkim const ASN1_PCTX *pctx); 171238405Sjkim 172238405Sjkimstatic int asn1_print_fsname(BIO *out, int indent, 173238405Sjkim const char *fname, const char *sname, 174238405Sjkim const ASN1_PCTX *pctx); 175238405Sjkim 176238405Sjkimint ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, 177238405Sjkim const ASN1_ITEM *it, const ASN1_PCTX *pctx) 178238405Sjkim { 179238405Sjkim const char *sname; 180238405Sjkim if (pctx == NULL) 181238405Sjkim pctx = &default_pctx; 182238405Sjkim if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) 183238405Sjkim sname = NULL; 184238405Sjkim else 185238405Sjkim sname = it->sname; 186238405Sjkim return asn1_item_print_ctx(out, &ifld, indent, it, 187238405Sjkim NULL, sname, 0, pctx); 188238405Sjkim } 189238405Sjkim 190238405Sjkimstatic int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, 191238405Sjkim const ASN1_ITEM *it, 192238405Sjkim const char *fname, const char *sname, 193238405Sjkim int nohdr, const ASN1_PCTX *pctx) 194238405Sjkim { 195109998Smarkm const ASN1_TEMPLATE *tt; 196238405Sjkim const ASN1_EXTERN_FUNCS *ef; 197238405Sjkim ASN1_VALUE **tmpfld; 198238405Sjkim const ASN1_AUX *aux = it->funcs; 199238405Sjkim ASN1_aux_cb *asn1_cb; 200238405Sjkim ASN1_PRINT_ARG parg; 201109998Smarkm int i; 202238405Sjkim if (aux && aux->asn1_cb) 203238405Sjkim { 204238405Sjkim parg.out = out; 205238405Sjkim parg.indent = indent; 206238405Sjkim parg.pctx = pctx; 207238405Sjkim asn1_cb = aux->asn1_cb; 208238405Sjkim } 209238405Sjkim else asn1_cb = 0; 210238405Sjkim 211238405Sjkim if(*fld == NULL) 212238405Sjkim { 213238405Sjkim if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) 214238405Sjkim { 215238405Sjkim if (!nohdr && !asn1_print_fsname(out, indent, 216238405Sjkim fname, sname, pctx)) 217238405Sjkim return 0; 218238405Sjkim if (BIO_puts(out, "<ABSENT>\n") <= 0) 219238405Sjkim return 0; 220238405Sjkim } 221109998Smarkm return 1; 222238405Sjkim } 223109998Smarkm 224238405Sjkim switch(it->itype) 225238405Sjkim { 226109998Smarkm case ASN1_ITYPE_PRIMITIVE: 227109998Smarkm if(it->templates) 228238405Sjkim { 229238405Sjkim if (!asn1_template_print_ctx(out, fld, indent, 230238405Sjkim it->templates, pctx)) 231238405Sjkim return 0; 232238405Sjkim } 233238405Sjkim /* fall thru */ 234238405Sjkim case ASN1_ITYPE_MSTRING: 235238405Sjkim if (!asn1_primitive_print(out, fld, it, 236238405Sjkim indent, fname, sname,pctx)) 237238405Sjkim return 0; 238109998Smarkm break; 239109998Smarkm 240109998Smarkm case ASN1_ITYPE_EXTERN: 241238405Sjkim if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) 242238405Sjkim return 0; 243238405Sjkim /* Use new style print routine if possible */ 244238405Sjkim ef = it->funcs; 245238405Sjkim if (ef && ef->asn1_ex_print) 246238405Sjkim { 247238405Sjkim i = ef->asn1_ex_print(out, fld, indent, "", pctx); 248238405Sjkim if (!i) 249238405Sjkim return 0; 250238405Sjkim if ((i == 2) && (BIO_puts(out, "\n") <= 0)) 251238405Sjkim return 0; 252238405Sjkim return 1; 253238405Sjkim } 254238405Sjkim else if (sname && 255238405Sjkim BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0) 256238405Sjkim return 0; 257238405Sjkim break; 258109998Smarkm 259109998Smarkm case ASN1_ITYPE_CHOICE: 260238405Sjkim#if 0 261238405Sjkim if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) 262238405Sjkim return 0; 263238405Sjkim#endif 264109998Smarkm /* CHOICE type, get selector */ 265109998Smarkm i = asn1_get_choice_selector(fld, it); 266109998Smarkm /* This should never happen... */ 267238405Sjkim if((i < 0) || (i >= it->tcount)) 268238405Sjkim { 269238405Sjkim if (BIO_printf(out, 270238405Sjkim "ERROR: selector [%d] invalid\n", i) <= 0) 271238405Sjkim return 0; 272109998Smarkm return 1; 273238405Sjkim } 274109998Smarkm tt = it->templates + i; 275238405Sjkim tmpfld = asn1_get_field_ptr(fld, tt); 276238405Sjkim if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx)) 277238405Sjkim return 0; 278238405Sjkim break; 279109998Smarkm 280109998Smarkm case ASN1_ITYPE_SEQUENCE: 281238405Sjkim case ASN1_ITYPE_NDEF_SEQUENCE: 282238405Sjkim if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) 283238405Sjkim return 0; 284238405Sjkim if (fname || sname) 285238405Sjkim { 286238405Sjkim if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) 287238405Sjkim { 288238405Sjkim if (BIO_puts(out, " {\n") <= 0) 289238405Sjkim return 0; 290238405Sjkim } 291238405Sjkim else 292238405Sjkim { 293238405Sjkim if (BIO_puts(out, "\n") <= 0) 294238405Sjkim return 0; 295238405Sjkim } 296238405Sjkim } 297109998Smarkm 298238405Sjkim if (asn1_cb) 299238405Sjkim { 300238405Sjkim i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg); 301238405Sjkim if (i == 0) 302238405Sjkim return 0; 303238405Sjkim if (i == 2) 304238405Sjkim return 1; 305238405Sjkim } 306238405Sjkim 307238405Sjkim /* Print each field entry */ 308238405Sjkim for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) 309238405Sjkim { 310238405Sjkim const ASN1_TEMPLATE *seqtt; 311238405Sjkim seqtt = asn1_do_adb(fld, tt, 1); 312238405Sjkim tmpfld = asn1_get_field_ptr(fld, seqtt); 313238405Sjkim if (!asn1_template_print_ctx(out, tmpfld, 314238405Sjkim indent + 2, seqtt, pctx)) 315238405Sjkim return 0; 316238405Sjkim } 317238405Sjkim if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) 318238405Sjkim { 319238405Sjkim if (BIO_printf(out, "%*s}\n", indent, "") < 0) 320238405Sjkim return 0; 321238405Sjkim } 322238405Sjkim 323238405Sjkim if (asn1_cb) 324238405Sjkim { 325238405Sjkim i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg); 326238405Sjkim if (i == 0) 327238405Sjkim return 0; 328238405Sjkim } 329238405Sjkim break; 330238405Sjkim 331109998Smarkm default: 332238405Sjkim BIO_printf(out, "Unprocessed type %d\n", it->itype); 333109998Smarkm return 0; 334238405Sjkim } 335238405Sjkim 336238405Sjkim return 1; 337109998Smarkm } 338109998Smarkm 339238405Sjkimint asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, 340238405Sjkim const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx) 341238405Sjkim { 342109998Smarkm int i, flags; 343238405Sjkim const char *sname, *fname; 344109998Smarkm flags = tt->flags; 345238405Sjkim if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME) 346238405Sjkim sname = ASN1_ITEM_ptr(tt->item)->sname; 347238405Sjkim else 348238405Sjkim sname = NULL; 349238405Sjkim if(pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) 350238405Sjkim fname = NULL; 351238405Sjkim else 352238405Sjkim fname = tt->field_name; 353238405Sjkim if(flags & ASN1_TFLG_SK_MASK) 354238405Sjkim { 355109998Smarkm char *tname; 356238405Sjkim ASN1_VALUE *skitem; 357238405Sjkim STACK_OF(ASN1_VALUE) *stack; 358238405Sjkim 359109998Smarkm /* SET OF, SEQUENCE OF */ 360238405Sjkim if (fname) 361238405Sjkim { 362238405Sjkim if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) 363238405Sjkim { 364238405Sjkim if(flags & ASN1_TFLG_SET_OF) 365238405Sjkim tname = "SET"; 366238405Sjkim else 367238405Sjkim tname = "SEQUENCE"; 368238405Sjkim if (BIO_printf(out, "%*s%s OF %s {\n", 369238405Sjkim indent, "", tname, tt->field_name) <= 0) 370238405Sjkim return 0; 371238405Sjkim } 372238405Sjkim else if (BIO_printf(out, "%*s%s:\n", indent, "", 373238405Sjkim fname) <= 0) 374238405Sjkim return 0; 375109998Smarkm } 376238405Sjkim stack = (STACK_OF(ASN1_VALUE) *)*fld; 377238405Sjkim for(i = 0; i < sk_ASN1_VALUE_num(stack); i++) 378238405Sjkim { 379238405Sjkim if ((i > 0) && (BIO_puts(out, "\n") <= 0)) 380238405Sjkim return 0; 381238405Sjkim 382238405Sjkim skitem = sk_ASN1_VALUE_value(stack, i); 383238405Sjkim if (!asn1_item_print_ctx(out, &skitem, indent + 2, 384238405Sjkim ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx)) 385238405Sjkim return 0; 386238405Sjkim } 387238405Sjkim if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0) 388238405Sjkim return 0; 389238405Sjkim if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) 390238405Sjkim { 391238405Sjkim if (BIO_printf(out, "%*s}\n", indent, "") <= 0) 392238405Sjkim return 0; 393238405Sjkim } 394109998Smarkm return 1; 395238405Sjkim } 396238405Sjkim return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item), 397238405Sjkim fname, sname, 0, pctx); 398109998Smarkm } 399109998Smarkm 400238405Sjkimstatic int asn1_print_fsname(BIO *out, int indent, 401238405Sjkim const char *fname, const char *sname, 402238405Sjkim const ASN1_PCTX *pctx) 403238405Sjkim { 404238405Sjkim static char spaces[] = " "; 405238405Sjkim const int nspaces = sizeof(spaces) - 1; 406238405Sjkim 407238405Sjkim#if 0 408238405Sjkim if (!sname && !fname) 409238405Sjkim return 1; 410238405Sjkim#endif 411238405Sjkim 412238405Sjkim while (indent > nspaces) 413238405Sjkim { 414238405Sjkim if (BIO_write(out, spaces, nspaces) != nspaces) 415238405Sjkim return 0; 416238405Sjkim indent -= nspaces; 417109998Smarkm } 418238405Sjkim if (BIO_write(out, spaces, indent) != indent) 419238405Sjkim return 0; 420238405Sjkim if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) 421238405Sjkim sname = NULL; 422238405Sjkim if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) 423238405Sjkim fname = NULL; 424238405Sjkim if (!sname && !fname) 425238405Sjkim return 1; 426238405Sjkim if (fname) 427238405Sjkim { 428238405Sjkim if (BIO_puts(out, fname) <= 0) 429238405Sjkim return 0; 430238405Sjkim } 431238405Sjkim if (sname) 432238405Sjkim { 433238405Sjkim if (fname) 434238405Sjkim { 435238405Sjkim if (BIO_printf(out, " (%s)", sname) <= 0) 436238405Sjkim return 0; 437238405Sjkim } 438238405Sjkim else 439238405Sjkim { 440238405Sjkim if (BIO_puts(out, sname) <= 0) 441238405Sjkim return 0; 442238405Sjkim } 443238405Sjkim } 444238405Sjkim if (BIO_write(out, ": ", 2) != 2) 445238405Sjkim return 0; 446109998Smarkm return 1; 447238405Sjkim } 448238405Sjkim 449238405Sjkimstatic int asn1_print_boolean_ctx(BIO *out, int boolval, 450238405Sjkim const ASN1_PCTX *pctx) 451238405Sjkim { 452238405Sjkim const char *str; 453238405Sjkim switch (boolval) 454238405Sjkim { 455238405Sjkim case -1: 456238405Sjkim str = "BOOL ABSENT"; 457238405Sjkim break; 458238405Sjkim 459238405Sjkim case 0: 460238405Sjkim str = "FALSE"; 461238405Sjkim break; 462238405Sjkim 463238405Sjkim default: 464238405Sjkim str = "TRUE"; 465238405Sjkim break; 466238405Sjkim 467238405Sjkim } 468238405Sjkim 469238405Sjkim if (BIO_puts(out, str) <= 0) 470238405Sjkim return 0; 471238405Sjkim return 1; 472238405Sjkim 473238405Sjkim } 474238405Sjkim 475238405Sjkimstatic int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str, 476238405Sjkim const ASN1_PCTX *pctx) 477238405Sjkim { 478238405Sjkim char *s; 479238405Sjkim int ret = 1; 480238405Sjkim s = i2s_ASN1_INTEGER(NULL, str); 481238405Sjkim if (BIO_puts(out, s) <= 0) 482238405Sjkim ret = 0; 483238405Sjkim OPENSSL_free(s); 484238405Sjkim return ret; 485238405Sjkim } 486238405Sjkim 487238405Sjkimstatic int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid, 488238405Sjkim const ASN1_PCTX *pctx) 489238405Sjkim { 490238405Sjkim char objbuf[80]; 491238405Sjkim const char *ln; 492238405Sjkim ln = OBJ_nid2ln(OBJ_obj2nid(oid)); 493238405Sjkim if(!ln) 494238405Sjkim ln = ""; 495238405Sjkim OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1); 496238405Sjkim if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0) 497238405Sjkim return 0; 498238405Sjkim return 1; 499238405Sjkim } 500238405Sjkim 501238405Sjkimstatic int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent, 502238405Sjkim const ASN1_PCTX *pctx) 503238405Sjkim { 504238405Sjkim if (str->type == V_ASN1_BIT_STRING) 505238405Sjkim { 506238405Sjkim if (BIO_printf(out, " (%ld unused bits)\n", 507238405Sjkim str->flags & 0x7) <= 0) 508238405Sjkim return 0; 509238405Sjkim } 510238405Sjkim else if (BIO_puts(out, "\n") <= 0) 511238405Sjkim return 0; 512238405Sjkim if ((str->length > 0) 513238405Sjkim && BIO_dump_indent(out, (char *)str->data, str->length, 514238405Sjkim indent + 2) <= 0) 515238405Sjkim return 0; 516238405Sjkim return 1; 517238405Sjkim } 518238405Sjkim 519238405Sjkimstatic int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, 520238405Sjkim const ASN1_ITEM *it, int indent, 521238405Sjkim const char *fname, const char *sname, 522238405Sjkim const ASN1_PCTX *pctx) 523238405Sjkim { 524238405Sjkim long utype; 525238405Sjkim ASN1_STRING *str; 526238405Sjkim int ret = 1, needlf = 1; 527238405Sjkim const char *pname; 528238405Sjkim const ASN1_PRIMITIVE_FUNCS *pf; 529238405Sjkim pf = it->funcs; 530238405Sjkim if (!asn1_print_fsname(out, indent, fname, sname, pctx)) 531238405Sjkim return 0; 532238405Sjkim if (pf && pf->prim_print) 533238405Sjkim return pf->prim_print(out, fld, it, indent, pctx); 534238405Sjkim str = (ASN1_STRING *)*fld; 535238405Sjkim if (it->itype == ASN1_ITYPE_MSTRING) 536238405Sjkim utype = str->type & ~V_ASN1_NEG; 537238405Sjkim else 538238405Sjkim utype = it->utype; 539238405Sjkim if (utype == V_ASN1_ANY) 540238405Sjkim { 541238405Sjkim ASN1_TYPE *atype = (ASN1_TYPE *)*fld; 542238405Sjkim utype = atype->type; 543238405Sjkim fld = &atype->value.asn1_value; 544238405Sjkim str = (ASN1_STRING *)*fld; 545238405Sjkim if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE) 546238405Sjkim pname = NULL; 547238405Sjkim else 548238405Sjkim pname = ASN1_tag2str(utype); 549238405Sjkim } 550238405Sjkim else 551238405Sjkim { 552238405Sjkim if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE) 553238405Sjkim pname = ASN1_tag2str(utype); 554238405Sjkim else 555238405Sjkim pname = NULL; 556238405Sjkim } 557238405Sjkim 558238405Sjkim if (utype == V_ASN1_NULL) 559238405Sjkim { 560238405Sjkim if (BIO_puts(out, "NULL\n") <= 0) 561238405Sjkim return 0; 562238405Sjkim return 1; 563238405Sjkim } 564238405Sjkim 565238405Sjkim if (pname) 566238405Sjkim { 567238405Sjkim if (BIO_puts(out, pname) <= 0) 568238405Sjkim return 0; 569238405Sjkim if (BIO_puts(out, ":") <= 0) 570238405Sjkim return 0; 571238405Sjkim } 572238405Sjkim 573238405Sjkim switch (utype) 574238405Sjkim { 575238405Sjkim case V_ASN1_BOOLEAN: 576238405Sjkim { 577238405Sjkim int boolval = *(int *)fld; 578238405Sjkim if (boolval == -1) 579238405Sjkim boolval = it->size; 580238405Sjkim ret = asn1_print_boolean_ctx(out, boolval, pctx); 581238405Sjkim } 582238405Sjkim break; 583238405Sjkim 584238405Sjkim case V_ASN1_INTEGER: 585238405Sjkim case V_ASN1_ENUMERATED: 586238405Sjkim ret = asn1_print_integer_ctx(out, str, pctx); 587238405Sjkim break; 588238405Sjkim 589238405Sjkim case V_ASN1_UTCTIME: 590238405Sjkim ret = ASN1_UTCTIME_print(out, str); 591238405Sjkim break; 592238405Sjkim 593238405Sjkim case V_ASN1_GENERALIZEDTIME: 594238405Sjkim ret = ASN1_GENERALIZEDTIME_print(out, str); 595238405Sjkim break; 596238405Sjkim 597238405Sjkim case V_ASN1_OBJECT: 598238405Sjkim ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx); 599238405Sjkim break; 600238405Sjkim 601238405Sjkim case V_ASN1_OCTET_STRING: 602238405Sjkim case V_ASN1_BIT_STRING: 603238405Sjkim ret = asn1_print_obstring_ctx(out, str, indent, pctx); 604238405Sjkim needlf = 0; 605238405Sjkim break; 606238405Sjkim 607238405Sjkim case V_ASN1_SEQUENCE: 608238405Sjkim case V_ASN1_SET: 609238405Sjkim case V_ASN1_OTHER: 610238405Sjkim if (BIO_puts(out, "\n") <= 0) 611238405Sjkim return 0; 612238405Sjkim if (ASN1_parse_dump(out, str->data, str->length, 613238405Sjkim indent, 0) <= 0) 614238405Sjkim ret = 0; 615238405Sjkim needlf = 0; 616238405Sjkim break; 617238405Sjkim 618238405Sjkim default: 619238405Sjkim ret = ASN1_STRING_print_ex(out, str, pctx->str_flags); 620238405Sjkim 621238405Sjkim } 622238405Sjkim if (!ret) 623238405Sjkim return 0; 624238405Sjkim if (needlf && BIO_puts(out, "\n") <= 0) 625238405Sjkim return 0; 626238405Sjkim return 1; 627238405Sjkim } 628