| OLD | NEW |
| (Empty) |
| 1 /* tasn_prn.c */ | |
| 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | |
| 3 * project 2000. | |
| 4 */ | |
| 5 /* ==================================================================== | |
| 6 * Copyright (c) 2000,2005 The OpenSSL Project. All rights reserved. | |
| 7 * | |
| 8 * Redistribution and use in source and binary forms, with or without | |
| 9 * modification, are permitted provided that the following conditions | |
| 10 * are met: | |
| 11 * | |
| 12 * 1. Redistributions of source code must retain the above copyright | |
| 13 * notice, this list of conditions and the following disclaimer. | |
| 14 * | |
| 15 * 2. Redistributions in binary form must reproduce the above copyright | |
| 16 * notice, this list of conditions and the following disclaimer in | |
| 17 * the documentation and/or other materials provided with the | |
| 18 * distribution. | |
| 19 * | |
| 20 * 3. All advertising materials mentioning features or use of this | |
| 21 * software must display the following acknowledgment: | |
| 22 * "This product includes software developed by the OpenSSL Project | |
| 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | |
| 24 * | |
| 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
| 26 * endorse or promote products derived from this software without | |
| 27 * prior written permission. For written permission, please contact | |
| 28 * licensing@OpenSSL.org. | |
| 29 * | |
| 30 * 5. Products derived from this software may not be called "OpenSSL" | |
| 31 * nor may "OpenSSL" appear in their names without prior written | |
| 32 * permission of the OpenSSL Project. | |
| 33 * | |
| 34 * 6. Redistributions of any form whatsoever must retain the following | |
| 35 * acknowledgment: | |
| 36 * "This product includes software developed by the OpenSSL Project | |
| 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | |
| 38 * | |
| 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
| 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
| 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
| 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
| 50 * OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 51 * ==================================================================== | |
| 52 * | |
| 53 * This product includes cryptographic software written by Eric Young | |
| 54 * (eay@cryptsoft.com). This product includes software written by Tim | |
| 55 * Hudson (tjh@cryptsoft.com). | |
| 56 * | |
| 57 */ | |
| 58 | |
| 59 | |
| 60 #include <stddef.h> | |
| 61 #include "cryptlib.h" | |
| 62 #include <openssl/asn1.h> | |
| 63 #include <openssl/asn1t.h> | |
| 64 #include <openssl/objects.h> | |
| 65 #include <openssl/buffer.h> | |
| 66 #include <openssl/err.h> | |
| 67 #include <openssl/x509v3.h> | |
| 68 #include "asn1_locl.h" | |
| 69 | |
| 70 /* Print routines. | |
| 71 */ | |
| 72 | |
| 73 /* ASN1_PCTX routines */ | |
| 74 | |
| 75 ASN1_PCTX default_pctx = | |
| 76 { | |
| 77 ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */ | |
| 78 0, /* nm_flags */ | |
| 79 0, /* cert_flags */ | |
| 80 0, /* oid_flags */ | |
| 81 0 /* str_flags */ | |
| 82 }; | |
| 83 | |
| 84 | |
| 85 ASN1_PCTX *ASN1_PCTX_new(void) | |
| 86 { | |
| 87 ASN1_PCTX *ret; | |
| 88 ret = OPENSSL_malloc(sizeof(ASN1_PCTX)); | |
| 89 if (ret == NULL) | |
| 90 { | |
| 91 ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE); | |
| 92 return NULL; | |
| 93 } | |
| 94 ret->flags = 0; | |
| 95 ret->nm_flags = 0; | |
| 96 ret->cert_flags = 0; | |
| 97 ret->oid_flags = 0; | |
| 98 ret->str_flags = 0; | |
| 99 return ret; | |
| 100 } | |
| 101 | |
| 102 void ASN1_PCTX_free(ASN1_PCTX *p) | |
| 103 { | |
| 104 OPENSSL_free(p); | |
| 105 } | |
| 106 | |
| 107 unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p) | |
| 108 { | |
| 109 return p->flags; | |
| 110 } | |
| 111 | |
| 112 void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags) | |
| 113 { | |
| 114 p->flags = flags; | |
| 115 } | |
| 116 | |
| 117 unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p) | |
| 118 { | |
| 119 return p->nm_flags; | |
| 120 } | |
| 121 | |
| 122 void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags) | |
| 123 { | |
| 124 p->nm_flags = flags; | |
| 125 } | |
| 126 | |
| 127 unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p) | |
| 128 { | |
| 129 return p->cert_flags; | |
| 130 } | |
| 131 | |
| 132 void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags) | |
| 133 { | |
| 134 p->cert_flags = flags; | |
| 135 } | |
| 136 | |
| 137 unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p) | |
| 138 { | |
| 139 return p->oid_flags; | |
| 140 } | |
| 141 | |
| 142 void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags) | |
| 143 { | |
| 144 p->oid_flags = flags; | |
| 145 } | |
| 146 | |
| 147 unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p) | |
| 148 { | |
| 149 return p->str_flags; | |
| 150 } | |
| 151 | |
| 152 void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags) | |
| 153 { | |
| 154 p->str_flags = flags; | |
| 155 } | |
| 156 | |
| 157 /* Main print routines */ | |
| 158 | |
| 159 static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, | |
| 160 const ASN1_ITEM *it, | |
| 161 const char *fname, const char *sname, | |
| 162 int nohdr, const ASN1_PCTX *pctx); | |
| 163 | |
| 164 int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, | |
| 165 const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx); | |
| 166 | |
| 167 static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, | |
| 168 const ASN1_ITEM *it, int indent, | |
| 169 const char *fname, const char *sname, | |
| 170 const ASN1_PCTX *pctx); | |
| 171 | |
| 172 static int asn1_print_fsname(BIO *out, int indent, | |
| 173 const char *fname, const char *sname, | |
| 174 const ASN1_PCTX *pctx); | |
| 175 | |
| 176 int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, | |
| 177 const ASN1_ITEM *it, const ASN1_PCTX *pctx) | |
| 178 { | |
| 179 const char *sname; | |
| 180 if (pctx == NULL) | |
| 181 pctx = &default_pctx; | |
| 182 if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) | |
| 183 sname = NULL; | |
| 184 else | |
| 185 sname = it->sname; | |
| 186 return asn1_item_print_ctx(out, &ifld, indent, it, | |
| 187 NULL, sname, 0, pctx); | |
| 188 } | |
| 189 | |
| 190 static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, | |
| 191 const ASN1_ITEM *it, | |
| 192 const char *fname, const char *sname, | |
| 193 int nohdr, const ASN1_PCTX *pctx) | |
| 194 { | |
| 195 const ASN1_TEMPLATE *tt; | |
| 196 const ASN1_EXTERN_FUNCS *ef; | |
| 197 ASN1_VALUE **tmpfld; | |
| 198 const ASN1_AUX *aux = it->funcs; | |
| 199 ASN1_aux_cb *asn1_cb; | |
| 200 ASN1_PRINT_ARG parg; | |
| 201 int i; | |
| 202 if (aux && aux->asn1_cb) | |
| 203 { | |
| 204 parg.out = out; | |
| 205 parg.indent = indent; | |
| 206 parg.pctx = pctx; | |
| 207 asn1_cb = aux->asn1_cb; | |
| 208 } | |
| 209 else asn1_cb = 0; | |
| 210 | |
| 211 if(*fld == NULL) | |
| 212 { | |
| 213 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) | |
| 214 { | |
| 215 if (!nohdr && !asn1_print_fsname(out, indent, | |
| 216 fname, sname, pctx)) | |
| 217 return 0; | |
| 218 if (BIO_puts(out, "<ABSENT>\n") <= 0) | |
| 219 return 0; | |
| 220 } | |
| 221 return 1; | |
| 222 } | |
| 223 | |
| 224 switch(it->itype) | |
| 225 { | |
| 226 case ASN1_ITYPE_PRIMITIVE: | |
| 227 if(it->templates) | |
| 228 { | |
| 229 if (!asn1_template_print_ctx(out, fld, indent, | |
| 230 it->templates, pctx)) | |
| 231 return 0; | |
| 232 } | |
| 233 /* fall thru */ | |
| 234 case ASN1_ITYPE_MSTRING: | |
| 235 if (!asn1_primitive_print(out, fld, it, | |
| 236 indent, fname, sname,pctx)) | |
| 237 return 0; | |
| 238 break; | |
| 239 | |
| 240 case ASN1_ITYPE_EXTERN: | |
| 241 if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx
)) | |
| 242 return 0; | |
| 243 /* Use new style print routine if possible */ | |
| 244 ef = it->funcs; | |
| 245 if (ef && ef->asn1_ex_print) | |
| 246 { | |
| 247 i = ef->asn1_ex_print(out, fld, indent, "", pctx); | |
| 248 if (!i) | |
| 249 return 0; | |
| 250 if ((i == 2) && (BIO_puts(out, "\n") <= 0)) | |
| 251 return 0; | |
| 252 return 1; | |
| 253 } | |
| 254 else if (sname && | |
| 255 BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0) | |
| 256 return 0; | |
| 257 break; | |
| 258 | |
| 259 case ASN1_ITYPE_CHOICE: | |
| 260 #if 0 | |
| 261 if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx
)) | |
| 262 return 0; | |
| 263 #endif | |
| 264 /* CHOICE type, get selector */ | |
| 265 i = asn1_get_choice_selector(fld, it); | |
| 266 /* This should never happen... */ | |
| 267 if((i < 0) || (i >= it->tcount)) | |
| 268 { | |
| 269 if (BIO_printf(out, | |
| 270 "ERROR: selector [%d] invalid\n", i) <= 0) | |
| 271 return 0; | |
| 272 return 1; | |
| 273 } | |
| 274 tt = it->templates + i; | |
| 275 tmpfld = asn1_get_field_ptr(fld, tt); | |
| 276 if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx)) | |
| 277 return 0; | |
| 278 break; | |
| 279 | |
| 280 case ASN1_ITYPE_SEQUENCE: | |
| 281 case ASN1_ITYPE_NDEF_SEQUENCE: | |
| 282 if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx
)) | |
| 283 return 0; | |
| 284 if (fname || sname) | |
| 285 { | |
| 286 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) | |
| 287 { | |
| 288 if (BIO_puts(out, " {\n") <= 0) | |
| 289 return 0; | |
| 290 } | |
| 291 else | |
| 292 { | |
| 293 if (BIO_puts(out, "\n") <= 0) | |
| 294 return 0; | |
| 295 } | |
| 296 } | |
| 297 | |
| 298 if (asn1_cb) | |
| 299 { | |
| 300 i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg); | |
| 301 if (i == 0) | |
| 302 return 0; | |
| 303 if (i == 2) | |
| 304 return 1; | |
| 305 } | |
| 306 | |
| 307 /* Print each field entry */ | |
| 308 for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) | |
| 309 { | |
| 310 const ASN1_TEMPLATE *seqtt; | |
| 311 seqtt = asn1_do_adb(fld, tt, 1); | |
| 312 tmpfld = asn1_get_field_ptr(fld, seqtt); | |
| 313 if (!asn1_template_print_ctx(out, tmpfld, | |
| 314 indent + 2, seqtt, pctx)) | |
| 315 return 0; | |
| 316 } | |
| 317 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) | |
| 318 { | |
| 319 if (BIO_printf(out, "%*s}\n", indent, "") < 0) | |
| 320 return 0; | |
| 321 } | |
| 322 | |
| 323 if (asn1_cb) | |
| 324 { | |
| 325 i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg); | |
| 326 if (i == 0) | |
| 327 return 0; | |
| 328 } | |
| 329 break; | |
| 330 | |
| 331 default: | |
| 332 BIO_printf(out, "Unprocessed type %d\n", it->itype); | |
| 333 return 0; | |
| 334 } | |
| 335 | |
| 336 return 1; | |
| 337 } | |
| 338 | |
| 339 int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, | |
| 340 const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx) | |
| 341 { | |
| 342 int i, flags; | |
| 343 const char *sname, *fname; | |
| 344 flags = tt->flags; | |
| 345 if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME) | |
| 346 sname = ASN1_ITEM_ptr(tt->item)->sname; | |
| 347 else | |
| 348 sname = NULL; | |
| 349 if(pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) | |
| 350 fname = NULL; | |
| 351 else | |
| 352 fname = tt->field_name; | |
| 353 if(flags & ASN1_TFLG_SK_MASK) | |
| 354 { | |
| 355 char *tname; | |
| 356 ASN1_VALUE *skitem; | |
| 357 STACK_OF(ASN1_VALUE) *stack; | |
| 358 | |
| 359 /* SET OF, SEQUENCE OF */ | |
| 360 if (fname) | |
| 361 { | |
| 362 if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) | |
| 363 { | |
| 364 if(flags & ASN1_TFLG_SET_OF) | |
| 365 tname = "SET"; | |
| 366 else | |
| 367 tname = "SEQUENCE"; | |
| 368 if (BIO_printf(out, "%*s%s OF %s {\n", | |
| 369 indent, "", tname, tt->field_name) <= 0) | |
| 370 return 0; | |
| 371 } | |
| 372 else if (BIO_printf(out, "%*s%s:\n", indent, "", | |
| 373 fname) <= 0) | |
| 374 return 0; | |
| 375 } | |
| 376 stack = (STACK_OF(ASN1_VALUE) *)*fld; | |
| 377 for(i = 0; i < sk_ASN1_VALUE_num(stack); i++) | |
| 378 { | |
| 379 if ((i > 0) && (BIO_puts(out, "\n") <= 0)) | |
| 380 return 0; | |
| 381 | |
| 382 skitem = sk_ASN1_VALUE_value(stack, i); | |
| 383 if (!asn1_item_print_ctx(out, &skitem, indent + 2, | |
| 384 ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx)) | |
| 385 return 0; | |
| 386 } | |
| 387 if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0) | |
| 388 return 0; | |
| 389 if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) | |
| 390 { | |
| 391 if (BIO_printf(out, "%*s}\n", indent, "") <= 0) | |
| 392 return 0; | |
| 393 } | |
| 394 return 1; | |
| 395 } | |
| 396 return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item), | |
| 397 fname, sname, 0, pctx); | |
| 398 } | |
| 399 | |
| 400 static int asn1_print_fsname(BIO *out, int indent, | |
| 401 const char *fname, const char *sname, | |
| 402 const ASN1_PCTX *pctx) | |
| 403 { | |
| 404 static char spaces[] = " "; | |
| 405 const int nspaces = sizeof(spaces) - 1; | |
| 406 | |
| 407 #if 0 | |
| 408 if (!sname && !fname) | |
| 409 return 1; | |
| 410 #endif | |
| 411 | |
| 412 while (indent > nspaces) | |
| 413 { | |
| 414 if (BIO_write(out, spaces, nspaces) != nspaces) | |
| 415 return 0; | |
| 416 indent -= nspaces; | |
| 417 } | |
| 418 if (BIO_write(out, spaces, indent) != indent) | |
| 419 return 0; | |
| 420 if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) | |
| 421 sname = NULL; | |
| 422 if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) | |
| 423 fname = NULL; | |
| 424 if (!sname && !fname) | |
| 425 return 1; | |
| 426 if (fname) | |
| 427 { | |
| 428 if (BIO_puts(out, fname) <= 0) | |
| 429 return 0; | |
| 430 } | |
| 431 if (sname) | |
| 432 { | |
| 433 if (fname) | |
| 434 { | |
| 435 if (BIO_printf(out, " (%s)", sname) <= 0) | |
| 436 return 0; | |
| 437 } | |
| 438 else | |
| 439 { | |
| 440 if (BIO_puts(out, sname) <= 0) | |
| 441 return 0; | |
| 442 } | |
| 443 } | |
| 444 if (BIO_write(out, ": ", 2) != 2) | |
| 445 return 0; | |
| 446 return 1; | |
| 447 } | |
| 448 | |
| 449 static int asn1_print_boolean_ctx(BIO *out, int boolval, | |
| 450 const ASN1_PCTX *pctx) | |
| 451 { | |
| 452 const char *str; | |
| 453 switch (boolval) | |
| 454 { | |
| 455 case -1: | |
| 456 str = "BOOL ABSENT"; | |
| 457 break; | |
| 458 | |
| 459 case 0: | |
| 460 str = "FALSE"; | |
| 461 break; | |
| 462 | |
| 463 default: | |
| 464 str = "TRUE"; | |
| 465 break; | |
| 466 | |
| 467 } | |
| 468 | |
| 469 if (BIO_puts(out, str) <= 0) | |
| 470 return 0; | |
| 471 return 1; | |
| 472 | |
| 473 } | |
| 474 | |
| 475 static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str, | |
| 476 const ASN1_PCTX *pctx) | |
| 477 { | |
| 478 char *s; | |
| 479 int ret = 1; | |
| 480 s = i2s_ASN1_INTEGER(NULL, str); | |
| 481 if (BIO_puts(out, s) <= 0) | |
| 482 ret = 0; | |
| 483 OPENSSL_free(s); | |
| 484 return ret; | |
| 485 } | |
| 486 | |
| 487 static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid, | |
| 488 const ASN1_PCTX *pctx) | |
| 489 { | |
| 490 char objbuf[80]; | |
| 491 const char *ln; | |
| 492 ln = OBJ_nid2ln(OBJ_obj2nid(oid)); | |
| 493 if(!ln) | |
| 494 ln = ""; | |
| 495 OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1); | |
| 496 if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0) | |
| 497 return 0; | |
| 498 return 1; | |
| 499 } | |
| 500 | |
| 501 static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent, | |
| 502 const ASN1_PCTX *pctx) | |
| 503 { | |
| 504 if (str->type == V_ASN1_BIT_STRING) | |
| 505 { | |
| 506 if (BIO_printf(out, " (%ld unused bits)\n", | |
| 507 str->flags & 0x7) <= 0) | |
| 508 return 0; | |
| 509 } | |
| 510 else if (BIO_puts(out, "\n") <= 0) | |
| 511 return 0; | |
| 512 if ((str->length > 0) | |
| 513 && BIO_dump_indent(out, (char *)str->data, str->length, | |
| 514 indent + 2) <= 0) | |
| 515 return 0; | |
| 516 return 1; | |
| 517 } | |
| 518 | |
| 519 static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, | |
| 520 const ASN1_ITEM *it, int indent, | |
| 521 const char *fname, const char *sname, | |
| 522 const ASN1_PCTX *pctx) | |
| 523 { | |
| 524 long utype; | |
| 525 ASN1_STRING *str; | |
| 526 int ret = 1, needlf = 1; | |
| 527 const char *pname; | |
| 528 const ASN1_PRIMITIVE_FUNCS *pf; | |
| 529 pf = it->funcs; | |
| 530 if (!asn1_print_fsname(out, indent, fname, sname, pctx)) | |
| 531 return 0; | |
| 532 if (pf && pf->prim_print) | |
| 533 return pf->prim_print(out, fld, it, indent, pctx); | |
| 534 str = (ASN1_STRING *)*fld; | |
| 535 if (it->itype == ASN1_ITYPE_MSTRING) | |
| 536 utype = str->type & ~V_ASN1_NEG; | |
| 537 else | |
| 538 utype = it->utype; | |
| 539 if (utype == V_ASN1_ANY) | |
| 540 { | |
| 541 ASN1_TYPE *atype = (ASN1_TYPE *)*fld; | |
| 542 utype = atype->type; | |
| 543 fld = &atype->value.asn1_value; | |
| 544 str = (ASN1_STRING *)*fld; | |
| 545 if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE) | |
| 546 pname = NULL; | |
| 547 else | |
| 548 pname = ASN1_tag2str(utype); | |
| 549 } | |
| 550 else | |
| 551 { | |
| 552 if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE) | |
| 553 pname = ASN1_tag2str(utype); | |
| 554 else | |
| 555 pname = NULL; | |
| 556 } | |
| 557 | |
| 558 if (utype == V_ASN1_NULL) | |
| 559 { | |
| 560 if (BIO_puts(out, "NULL\n") <= 0) | |
| 561 return 0; | |
| 562 return 1; | |
| 563 } | |
| 564 | |
| 565 if (pname) | |
| 566 { | |
| 567 if (BIO_puts(out, pname) <= 0) | |
| 568 return 0; | |
| 569 if (BIO_puts(out, ":") <= 0) | |
| 570 return 0; | |
| 571 } | |
| 572 | |
| 573 switch (utype) | |
| 574 { | |
| 575 case V_ASN1_BOOLEAN: | |
| 576 { | |
| 577 int boolval = *(int *)fld; | |
| 578 if (boolval == -1) | |
| 579 boolval = it->size; | |
| 580 ret = asn1_print_boolean_ctx(out, boolval, pctx); | |
| 581 } | |
| 582 break; | |
| 583 | |
| 584 case V_ASN1_INTEGER: | |
| 585 case V_ASN1_ENUMERATED: | |
| 586 ret = asn1_print_integer_ctx(out, str, pctx); | |
| 587 break; | |
| 588 | |
| 589 case V_ASN1_UTCTIME: | |
| 590 ret = ASN1_UTCTIME_print(out, str); | |
| 591 break; | |
| 592 | |
| 593 case V_ASN1_GENERALIZEDTIME: | |
| 594 ret = ASN1_GENERALIZEDTIME_print(out, str); | |
| 595 break; | |
| 596 | |
| 597 case V_ASN1_OBJECT: | |
| 598 ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx); | |
| 599 break; | |
| 600 | |
| 601 case V_ASN1_OCTET_STRING: | |
| 602 case V_ASN1_BIT_STRING: | |
| 603 ret = asn1_print_obstring_ctx(out, str, indent, pctx); | |
| 604 needlf = 0; | |
| 605 break; | |
| 606 | |
| 607 case V_ASN1_SEQUENCE: | |
| 608 case V_ASN1_SET: | |
| 609 case V_ASN1_OTHER: | |
| 610 if (BIO_puts(out, "\n") <= 0) | |
| 611 return 0; | |
| 612 if (ASN1_parse_dump(out, str->data, str->length, | |
| 613 indent, 0) <= 0) | |
| 614 ret = 0; | |
| 615 needlf = 0; | |
| 616 break; | |
| 617 | |
| 618 default: | |
| 619 ret = ASN1_STRING_print_ex(out, str, pctx->str_flags); | |
| 620 | |
| 621 } | |
| 622 if (!ret) | |
| 623 return 0; | |
| 624 if (needlf && BIO_puts(out, "\n") <= 0) | |
| 625 return 0; | |
| 626 return 1; | |
| 627 } | |
| OLD | NEW |