]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
2039c421 | 2 | * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. |
9d6b1ce6 | 3 | * |
2039c421 RS |
4 | * Licensed under the OpenSSL license (the "License"). You may not use |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
9d6b1ce6 DSH |
8 | */ |
9 | ||
9d6b1ce6 | 10 | #include <stddef.h> |
b39fc560 | 11 | #include "internal/cryptlib.h" |
9d6b1ce6 | 12 | #include <openssl/asn1.h> |
56defd9a | 13 | #include <openssl/asn1t.h> |
9d6b1ce6 DSH |
14 | #include <openssl/objects.h> |
15 | #include <openssl/buffer.h> | |
16 | #include <openssl/err.h> | |
56defd9a | 17 | #include <openssl/x509v3.h> |
2743e38c | 18 | #include "internal/asn1_int.h" |
c1ee50aa | 19 | #include "asn1_locl.h" |
9d6b1ce6 | 20 | |
0f113f3e MC |
21 | /* |
22 | * Print routines. | |
9d6b1ce6 DSH |
23 | */ |
24 | ||
56defd9a | 25 | /* ASN1_PCTX routines */ |
9d6b1ce6 | 26 | |
df2ee0e2 | 27 | static ASN1_PCTX default_pctx = { |
0f113f3e MC |
28 | ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */ |
29 | 0, /* nm_flags */ | |
30 | 0, /* cert_flags */ | |
31 | 0, /* oid_flags */ | |
32 | 0 /* str_flags */ | |
33 | }; | |
9d6b1ce6 | 34 | |
56defd9a | 35 | ASN1_PCTX *ASN1_PCTX_new(void) |
0f113f3e MC |
36 | { |
37 | ASN1_PCTX *ret; | |
64b25758 RS |
38 | |
39 | ret = OPENSSL_zalloc(sizeof(*ret)); | |
0f113f3e MC |
40 | if (ret == NULL) { |
41 | ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE); | |
42 | return NULL; | |
43 | } | |
0f113f3e MC |
44 | return ret; |
45 | } | |
56defd9a DSH |
46 | |
47 | void ASN1_PCTX_free(ASN1_PCTX *p) | |
0f113f3e | 48 | { |
b548a1f1 | 49 | OPENSSL_free(p); |
0f113f3e | 50 | } |
56defd9a | 51 | |
35da893f | 52 | unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX *p) |
0f113f3e MC |
53 | { |
54 | return p->flags; | |
55 | } | |
56defd9a DSH |
56 | |
57 | void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags) | |
0f113f3e MC |
58 | { |
59 | p->flags = flags; | |
60 | } | |
56defd9a | 61 | |
35da893f | 62 | unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX *p) |
0f113f3e MC |
63 | { |
64 | return p->nm_flags; | |
65 | } | |
56defd9a DSH |
66 | |
67 | void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags) | |
0f113f3e MC |
68 | { |
69 | p->nm_flags = flags; | |
70 | } | |
56defd9a | 71 | |
35da893f | 72 | unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX *p) |
0f113f3e MC |
73 | { |
74 | return p->cert_flags; | |
75 | } | |
56defd9a DSH |
76 | |
77 | void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags) | |
0f113f3e MC |
78 | { |
79 | p->cert_flags = flags; | |
80 | } | |
56defd9a | 81 | |
35da893f | 82 | unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX *p) |
0f113f3e MC |
83 | { |
84 | return p->oid_flags; | |
85 | } | |
56defd9a DSH |
86 | |
87 | void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags) | |
0f113f3e MC |
88 | { |
89 | p->oid_flags = flags; | |
90 | } | |
56defd9a | 91 | |
35da893f | 92 | unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX *p) |
0f113f3e MC |
93 | { |
94 | return p->str_flags; | |
95 | } | |
56defd9a DSH |
96 | |
97 | void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags) | |
0f113f3e MC |
98 | { |
99 | p->str_flags = flags; | |
100 | } | |
56defd9a DSH |
101 | |
102 | /* Main print routines */ | |
103 | ||
104 | static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, | |
0f113f3e MC |
105 | const ASN1_ITEM *it, |
106 | const char *fname, const char *sname, | |
107 | int nohdr, const ASN1_PCTX *pctx); | |
9194296d | 108 | |
35da893f | 109 | static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, |
0f113f3e | 110 | const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx); |
9194296d | 111 | |
56defd9a | 112 | static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, |
0f113f3e MC |
113 | const ASN1_ITEM *it, int indent, |
114 | const char *fname, const char *sname, | |
115 | const ASN1_PCTX *pctx); | |
9194296d | 116 | |
b173acfc | 117 | static int asn1_print_fsname(BIO *out, int indent, |
0f113f3e MC |
118 | const char *fname, const char *sname, |
119 | const ASN1_PCTX *pctx); | |
56defd9a DSH |
120 | |
121 | int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, | |
0f113f3e MC |
122 | const ASN1_ITEM *it, const ASN1_PCTX *pctx) |
123 | { | |
124 | const char *sname; | |
125 | if (pctx == NULL) | |
126 | pctx = &default_pctx; | |
127 | if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) | |
128 | sname = NULL; | |
129 | else | |
130 | sname = it->sname; | |
131 | return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx); | |
132 | } | |
56defd9a DSH |
133 | |
134 | static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, | |
0f113f3e MC |
135 | const ASN1_ITEM *it, |
136 | const char *fname, const char *sname, | |
137 | int nohdr, const ASN1_PCTX *pctx) | |
138 | { | |
139 | const ASN1_TEMPLATE *tt; | |
140 | const ASN1_EXTERN_FUNCS *ef; | |
141 | ASN1_VALUE **tmpfld; | |
142 | const ASN1_AUX *aux = it->funcs; | |
143 | ASN1_aux_cb *asn1_cb; | |
144 | ASN1_PRINT_ARG parg; | |
145 | int i; | |
146 | if (aux && aux->asn1_cb) { | |
147 | parg.out = out; | |
148 | parg.indent = indent; | |
149 | parg.pctx = pctx; | |
150 | asn1_cb = aux->asn1_cb; | |
151 | } else | |
152 | asn1_cb = 0; | |
153 | ||
ad72d9fd DSH |
154 | if (((it->itype != ASN1_ITYPE_PRIMITIVE) |
155 | || (it->utype != V_ASN1_BOOLEAN)) && *fld == NULL) { | |
0f113f3e MC |
156 | if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) { |
157 | if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) | |
158 | return 0; | |
159 | if (BIO_puts(out, "<ABSENT>\n") <= 0) | |
160 | return 0; | |
161 | } | |
162 | return 1; | |
163 | } | |
164 | ||
165 | switch (it->itype) { | |
166 | case ASN1_ITYPE_PRIMITIVE: | |
167 | if (it->templates) { | |
168 | if (!asn1_template_print_ctx(out, fld, indent, | |
169 | it->templates, pctx)) | |
170 | return 0; | |
5dc1247a | 171 | break; |
0f113f3e | 172 | } |
f430ba31 | 173 | /* fall through */ |
0f113f3e MC |
174 | case ASN1_ITYPE_MSTRING: |
175 | if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx)) | |
176 | return 0; | |
177 | break; | |
178 | ||
179 | case ASN1_ITYPE_EXTERN: | |
180 | if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) | |
181 | return 0; | |
182 | /* Use new style print routine if possible */ | |
183 | ef = it->funcs; | |
184 | if (ef && ef->asn1_ex_print) { | |
185 | i = ef->asn1_ex_print(out, fld, indent, "", pctx); | |
186 | if (!i) | |
187 | return 0; | |
188 | if ((i == 2) && (BIO_puts(out, "\n") <= 0)) | |
189 | return 0; | |
190 | return 1; | |
191 | } else if (sname && | |
192 | BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0) | |
193 | return 0; | |
194 | break; | |
195 | ||
196 | case ASN1_ITYPE_CHOICE: | |
0f113f3e MC |
197 | /* CHOICE type, get selector */ |
198 | i = asn1_get_choice_selector(fld, it); | |
199 | /* This should never happen... */ | |
200 | if ((i < 0) || (i >= it->tcount)) { | |
201 | if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0) | |
202 | return 0; | |
203 | return 1; | |
204 | } | |
205 | tt = it->templates + i; | |
206 | tmpfld = asn1_get_field_ptr(fld, tt); | |
207 | if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx)) | |
208 | return 0; | |
209 | break; | |
210 | ||
211 | case ASN1_ITYPE_SEQUENCE: | |
212 | case ASN1_ITYPE_NDEF_SEQUENCE: | |
213 | if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) | |
214 | return 0; | |
215 | if (fname || sname) { | |
216 | if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { | |
217 | if (BIO_puts(out, " {\n") <= 0) | |
218 | return 0; | |
219 | } else { | |
220 | if (BIO_puts(out, "\n") <= 0) | |
221 | return 0; | |
222 | } | |
223 | } | |
224 | ||
225 | if (asn1_cb) { | |
226 | i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg); | |
227 | if (i == 0) | |
228 | return 0; | |
229 | if (i == 2) | |
230 | return 1; | |
231 | } | |
232 | ||
233 | /* Print each field entry */ | |
234 | for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { | |
235 | const ASN1_TEMPLATE *seqtt; | |
236 | seqtt = asn1_do_adb(fld, tt, 1); | |
61986d32 | 237 | if (!seqtt) |
34a7ed0c | 238 | return 0; |
0f113f3e MC |
239 | tmpfld = asn1_get_field_ptr(fld, seqtt); |
240 | if (!asn1_template_print_ctx(out, tmpfld, | |
241 | indent + 2, seqtt, pctx)) | |
242 | return 0; | |
243 | } | |
244 | if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { | |
245 | if (BIO_printf(out, "%*s}\n", indent, "") < 0) | |
246 | return 0; | |
247 | } | |
248 | ||
249 | if (asn1_cb) { | |
250 | i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg); | |
251 | if (i == 0) | |
252 | return 0; | |
253 | } | |
254 | break; | |
255 | ||
256 | default: | |
257 | BIO_printf(out, "Unprocessed type %d\n", it->itype); | |
258 | return 0; | |
259 | } | |
260 | ||
261 | return 1; | |
262 | } | |
9d6b1ce6 | 263 | |
35da893f | 264 | static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, |
0f113f3e MC |
265 | const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx) |
266 | { | |
267 | int i, flags; | |
268 | const char *sname, *fname; | |
9d103dbb | 269 | ASN1_VALUE *tfld; |
0f113f3e MC |
270 | flags = tt->flags; |
271 | if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME) | |
272 | sname = ASN1_ITEM_ptr(tt->item)->sname; | |
273 | else | |
274 | sname = NULL; | |
275 | if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) | |
276 | fname = NULL; | |
277 | else | |
278 | fname = tt->field_name; | |
9d103dbb DSH |
279 | |
280 | /* | |
281 | * If field is embedded then fld needs fixing so it is a pointer to | |
282 | * a pointer to a field. | |
283 | */ | |
284 | if (flags & ASN1_TFLG_EMBED) { | |
285 | tfld = (ASN1_VALUE *)fld; | |
286 | fld = &tfld; | |
287 | } | |
288 | ||
0f113f3e MC |
289 | if (flags & ASN1_TFLG_SK_MASK) { |
290 | char *tname; | |
291 | ASN1_VALUE *skitem; | |
292 | STACK_OF(ASN1_VALUE) *stack; | |
293 | ||
294 | /* SET OF, SEQUENCE OF */ | |
295 | if (fname) { | |
296 | if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) { | |
297 | if (flags & ASN1_TFLG_SET_OF) | |
298 | tname = "SET"; | |
299 | else | |
300 | tname = "SEQUENCE"; | |
301 | if (BIO_printf(out, "%*s%s OF %s {\n", | |
302 | indent, "", tname, tt->field_name) <= 0) | |
303 | return 0; | |
304 | } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0) | |
305 | return 0; | |
306 | } | |
307 | stack = (STACK_OF(ASN1_VALUE) *)*fld; | |
308 | for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) { | |
309 | if ((i > 0) && (BIO_puts(out, "\n") <= 0)) | |
310 | return 0; | |
311 | ||
312 | skitem = sk_ASN1_VALUE_value(stack, i); | |
313 | if (!asn1_item_print_ctx(out, &skitem, indent + 2, | |
314 | ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, | |
315 | pctx)) | |
316 | return 0; | |
317 | } | |
318 | if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0) | |
319 | return 0; | |
320 | if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { | |
321 | if (BIO_printf(out, "%*s}\n", indent, "") <= 0) | |
322 | return 0; | |
323 | } | |
324 | return 1; | |
325 | } | |
326 | return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item), | |
327 | fname, sname, 0, pctx); | |
328 | } | |
56defd9a | 329 | |
b173acfc | 330 | static int asn1_print_fsname(BIO *out, int indent, |
0f113f3e MC |
331 | const char *fname, const char *sname, |
332 | const ASN1_PCTX *pctx) | |
333 | { | |
334 | static const char spaces[] = " "; | |
335 | static const int nspaces = sizeof(spaces) - 1; | |
b173acfc | 336 | |
0f113f3e MC |
337 | while (indent > nspaces) { |
338 | if (BIO_write(out, spaces, nspaces) != nspaces) | |
339 | return 0; | |
340 | indent -= nspaces; | |
341 | } | |
342 | if (BIO_write(out, spaces, indent) != indent) | |
343 | return 0; | |
344 | if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) | |
345 | sname = NULL; | |
346 | if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) | |
347 | fname = NULL; | |
348 | if (!sname && !fname) | |
349 | return 1; | |
350 | if (fname) { | |
351 | if (BIO_puts(out, fname) <= 0) | |
352 | return 0; | |
353 | } | |
354 | if (sname) { | |
355 | if (fname) { | |
356 | if (BIO_printf(out, " (%s)", sname) <= 0) | |
357 | return 0; | |
358 | } else { | |
359 | if (BIO_puts(out, sname) <= 0) | |
360 | return 0; | |
361 | } | |
362 | } | |
363 | if (BIO_write(out, ": ", 2) != 2) | |
364 | return 0; | |
365 | return 1; | |
366 | } | |
56defd9a | 367 | |
a773b52a | 368 | static int asn1_print_boolean(BIO *out, int boolval) |
0f113f3e MC |
369 | { |
370 | const char *str; | |
371 | switch (boolval) { | |
372 | case -1: | |
373 | str = "BOOL ABSENT"; | |
374 | break; | |
56defd9a | 375 | |
0f113f3e MC |
376 | case 0: |
377 | str = "FALSE"; | |
378 | break; | |
56defd9a | 379 | |
0f113f3e MC |
380 | default: |
381 | str = "TRUE"; | |
382 | break; | |
56defd9a | 383 | |
0f113f3e | 384 | } |
56defd9a | 385 | |
0f113f3e MC |
386 | if (BIO_puts(out, str) <= 0) |
387 | return 0; | |
388 | return 1; | |
56defd9a | 389 | |
0f113f3e | 390 | } |
56defd9a | 391 | |
9f5466b9 | 392 | static int asn1_print_integer(BIO *out, const ASN1_INTEGER *str) |
0f113f3e MC |
393 | { |
394 | char *s; | |
395 | int ret = 1; | |
396 | s = i2s_ASN1_INTEGER(NULL, str); | |
5e3553c2 KR |
397 | if (s == NULL) |
398 | return 0; | |
0f113f3e MC |
399 | if (BIO_puts(out, s) <= 0) |
400 | ret = 0; | |
401 | OPENSSL_free(s); | |
402 | return ret; | |
403 | } | |
56defd9a | 404 | |
a773b52a | 405 | static int asn1_print_oid(BIO *out, const ASN1_OBJECT *oid) |
0f113f3e MC |
406 | { |
407 | char objbuf[80]; | |
408 | const char *ln; | |
409 | ln = OBJ_nid2ln(OBJ_obj2nid(oid)); | |
410 | if (!ln) | |
411 | ln = ""; | |
412 | OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1); | |
413 | if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0) | |
414 | return 0; | |
415 | return 1; | |
416 | } | |
56defd9a | 417 | |
9f5466b9 | 418 | static int asn1_print_obstring(BIO *out, const ASN1_STRING *str, int indent) |
0f113f3e MC |
419 | { |
420 | if (str->type == V_ASN1_BIT_STRING) { | |
421 | if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0) | |
422 | return 0; | |
423 | } else if (BIO_puts(out, "\n") <= 0) | |
424 | return 0; | |
425 | if ((str->length > 0) | |
d3d5dc60 | 426 | && BIO_dump_indent(out, (const char *)str->data, str->length, |
0f113f3e MC |
427 | indent + 2) <= 0) |
428 | return 0; | |
429 | return 1; | |
430 | } | |
56defd9a DSH |
431 | |
432 | static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, | |
0f113f3e MC |
433 | const ASN1_ITEM *it, int indent, |
434 | const char *fname, const char *sname, | |
435 | const ASN1_PCTX *pctx) | |
436 | { | |
437 | long utype; | |
438 | ASN1_STRING *str; | |
439 | int ret = 1, needlf = 1; | |
440 | const char *pname; | |
441 | const ASN1_PRIMITIVE_FUNCS *pf; | |
442 | pf = it->funcs; | |
443 | if (!asn1_print_fsname(out, indent, fname, sname, pctx)) | |
444 | return 0; | |
445 | if (pf && pf->prim_print) | |
446 | return pf->prim_print(out, fld, it, indent, pctx); | |
ad72d9fd DSH |
447 | if (it->itype == ASN1_ITYPE_MSTRING) { |
448 | str = (ASN1_STRING *)*fld; | |
0f113f3e | 449 | utype = str->type & ~V_ASN1_NEG; |
ad72d9fd | 450 | } else { |
0f113f3e | 451 | utype = it->utype; |
ad72d9fd DSH |
452 | if (utype == V_ASN1_BOOLEAN) |
453 | str = NULL; | |
454 | else | |
455 | str = (ASN1_STRING *)*fld; | |
456 | } | |
0f113f3e MC |
457 | if (utype == V_ASN1_ANY) { |
458 | ASN1_TYPE *atype = (ASN1_TYPE *)*fld; | |
459 | utype = atype->type; | |
460 | fld = &atype->value.asn1_value; | |
461 | str = (ASN1_STRING *)*fld; | |
462 | if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE) | |
463 | pname = NULL; | |
464 | else | |
465 | pname = ASN1_tag2str(utype); | |
466 | } else { | |
467 | if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE) | |
468 | pname = ASN1_tag2str(utype); | |
469 | else | |
470 | pname = NULL; | |
471 | } | |
472 | ||
473 | if (utype == V_ASN1_NULL) { | |
474 | if (BIO_puts(out, "NULL\n") <= 0) | |
475 | return 0; | |
476 | return 1; | |
477 | } | |
478 | ||
479 | if (pname) { | |
480 | if (BIO_puts(out, pname) <= 0) | |
481 | return 0; | |
482 | if (BIO_puts(out, ":") <= 0) | |
483 | return 0; | |
484 | } | |
485 | ||
486 | switch (utype) { | |
487 | case V_ASN1_BOOLEAN: | |
488 | { | |
489 | int boolval = *(int *)fld; | |
490 | if (boolval == -1) | |
491 | boolval = it->size; | |
a773b52a | 492 | ret = asn1_print_boolean(out, boolval); |
0f113f3e MC |
493 | } |
494 | break; | |
495 | ||
496 | case V_ASN1_INTEGER: | |
497 | case V_ASN1_ENUMERATED: | |
a773b52a | 498 | ret = asn1_print_integer(out, str); |
0f113f3e MC |
499 | break; |
500 | ||
501 | case V_ASN1_UTCTIME: | |
502 | ret = ASN1_UTCTIME_print(out, str); | |
503 | break; | |
504 | ||
505 | case V_ASN1_GENERALIZEDTIME: | |
506 | ret = ASN1_GENERALIZEDTIME_print(out, str); | |
507 | break; | |
508 | ||
509 | case V_ASN1_OBJECT: | |
a773b52a | 510 | ret = asn1_print_oid(out, (const ASN1_OBJECT *)*fld); |
0f113f3e MC |
511 | break; |
512 | ||
513 | case V_ASN1_OCTET_STRING: | |
514 | case V_ASN1_BIT_STRING: | |
a773b52a | 515 | ret = asn1_print_obstring(out, str, indent); |
0f113f3e MC |
516 | needlf = 0; |
517 | break; | |
518 | ||
519 | case V_ASN1_SEQUENCE: | |
520 | case V_ASN1_SET: | |
521 | case V_ASN1_OTHER: | |
522 | if (BIO_puts(out, "\n") <= 0) | |
523 | return 0; | |
524 | if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0) | |
525 | ret = 0; | |
526 | needlf = 0; | |
527 | break; | |
528 | ||
529 | default: | |
530 | ret = ASN1_STRING_print_ex(out, str, pctx->str_flags); | |
531 | ||
532 | } | |
533 | if (!ret) | |
534 | return 0; | |
535 | if (needlf && BIO_puts(out, "\n") <= 0) | |
536 | return 0; | |
537 | return 1; | |
538 | } |