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