]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/x509v3/v3_prn.c
2d5167497202b78e88ef35cefaeb49b6b3668f87
[thirdparty/openssl.git] / crypto / x509v3 / v3_prn.c
1 /* v3_prn.c */
2 /*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4 * 1999.
5 */
6 /* ====================================================================
7 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59 /* X509 v3 extension utilities */
60
61 #include <stdio.h>
62 #include "cryptlib.h"
63 #include <openssl/conf.h>
64 #include <openssl/x509v3.h>
65
66 /* Extension printing routines */
67
68 static int unknown_ext_print(BIO *out, const unsigned char *ext, int extlen,
69 unsigned long flag, int indent, int supported);
70
71 /* Print out a name+value stack */
72
73 void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
74 int ml)
75 {
76 int i;
77 CONF_VALUE *nval;
78 if (!val)
79 return;
80 if (!ml || !sk_CONF_VALUE_num(val)) {
81 BIO_printf(out, "%*s", indent, "");
82 if (!sk_CONF_VALUE_num(val))
83 BIO_puts(out, "<EMPTY>\n");
84 }
85 for (i = 0; i < sk_CONF_VALUE_num(val); i++) {
86 if (ml)
87 BIO_printf(out, "%*s", indent, "");
88 else if (i > 0)
89 BIO_printf(out, ", ");
90 nval = sk_CONF_VALUE_value(val, i);
91 if (!nval->name)
92 BIO_puts(out, nval->value);
93 else if (!nval->value)
94 BIO_puts(out, nval->name);
95 #ifndef CHARSET_EBCDIC
96 else
97 BIO_printf(out, "%s:%s", nval->name, nval->value);
98 #else
99 else {
100 int len;
101 char *tmp;
102 len = strlen(nval->value) + 1;
103 tmp = OPENSSL_malloc(len);
104 if (tmp) {
105 ascii2ebcdic(tmp, nval->value, len);
106 BIO_printf(out, "%s:%s", nval->name, tmp);
107 OPENSSL_free(tmp);
108 }
109 }
110 #endif
111 if (ml)
112 BIO_puts(out, "\n");
113 }
114 }
115
116 /* Main routine: print out a general extension */
117
118 int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
119 int indent)
120 {
121 void *ext_str = NULL;
122 char *value = NULL;
123 ASN1_OCTET_STRING *extoct;
124 const unsigned char *p;
125 int extlen;
126 const X509V3_EXT_METHOD *method;
127 STACK_OF(CONF_VALUE) *nval = NULL;
128 int ok = 1;
129
130 extoct = X509_EXTENSION_get_data(ext);
131 p = ASN1_STRING_data(extoct);
132 extlen = ASN1_STRING_length(extoct);
133
134 if ((method = X509V3_EXT_get(ext)) == NULL)
135 return unknown_ext_print(out, p, extlen, flag, indent, 0);
136 if (method->it)
137 ext_str = ASN1_item_d2i(NULL, &p, extlen, ASN1_ITEM_ptr(method->it));
138 else
139 ext_str = method->d2i(NULL, &p, extlen);
140
141 if (!ext_str)
142 return unknown_ext_print(out, p, extlen, flag, indent, 1);
143
144 if (method->i2s) {
145 if ((value = method->i2s(method, ext_str)) == NULL) {
146 ok = 0;
147 goto err;
148 }
149 #ifndef CHARSET_EBCDIC
150 BIO_printf(out, "%*s%s", indent, "", value);
151 #else
152 {
153 int len;
154 char *tmp;
155 len = strlen(value) + 1;
156 tmp = OPENSSL_malloc(len);
157 if (tmp) {
158 ascii2ebcdic(tmp, value, len);
159 BIO_printf(out, "%*s%s", indent, "", tmp);
160 OPENSSL_free(tmp);
161 }
162 }
163 #endif
164 } else if (method->i2v) {
165 if ((nval = method->i2v(method, ext_str, NULL)) == NULL) {
166 ok = 0;
167 goto err;
168 }
169 X509V3_EXT_val_prn(out, nval, indent,
170 method->ext_flags & X509V3_EXT_MULTILINE);
171 } else if (method->i2r) {
172 if (!method->i2r(method, ext_str, out, indent))
173 ok = 0;
174 } else
175 ok = 0;
176
177 err:
178 sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
179 OPENSSL_free(value);
180 if (method->it)
181 ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it));
182 else
183 method->ext_free(ext_str);
184 return ok;
185 }
186
187 int X509V3_extensions_print(BIO *bp, char *title,
188 STACK_OF(X509_EXTENSION) *exts,
189 unsigned long flag, int indent)
190 {
191 int i, j;
192
193 if (sk_X509_EXTENSION_num(exts) <= 0)
194 return 1;
195
196 if (title) {
197 BIO_printf(bp, "%*s%s:\n", indent, "", title);
198 indent += 4;
199 }
200
201 for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
202 ASN1_OBJECT *obj;
203 X509_EXTENSION *ex;
204 ex = sk_X509_EXTENSION_value(exts, i);
205 if (indent && BIO_printf(bp, "%*s", indent, "") <= 0)
206 return 0;
207 obj = X509_EXTENSION_get_object(ex);
208 i2a_ASN1_OBJECT(bp, obj);
209 j = X509_EXTENSION_get_critical(ex);
210 if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0)
211 return 0;
212 if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) {
213 BIO_printf(bp, "%*s", indent + 4, "");
214 ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex));
215 }
216 if (BIO_write(bp, "\n", 1) <= 0)
217 return 0;
218 }
219 return 1;
220 }
221
222 static int unknown_ext_print(BIO *out, const unsigned char *ext, int extlen,
223 unsigned long flag, int indent, int supported)
224 {
225 switch (flag & X509V3_EXT_UNKNOWN_MASK) {
226
227 case X509V3_EXT_DEFAULT:
228 return 0;
229
230 case X509V3_EXT_ERROR_UNKNOWN:
231 if (supported)
232 BIO_printf(out, "%*s<Parse Error>", indent, "");
233 else
234 BIO_printf(out, "%*s<Not Supported>", indent, "");
235 return 1;
236
237 case X509V3_EXT_PARSE_UNKNOWN:
238 return ASN1_parse_dump(out, ext, extlen, indent, -1);
239 case X509V3_EXT_DUMP_UNKNOWN:
240 return BIO_dump_indent(out, (char *)ext, extlen, indent);
241
242 default:
243 return 1;
244 }
245 }
246
247 #ifndef OPENSSL_NO_STDIO
248 int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent)
249 {
250 BIO *bio_tmp;
251 int ret;
252
253 if ((bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
254 return 0;
255 ret = X509V3_EXT_print(bio_tmp, ext, flag, indent);
256 BIO_free(bio_tmp);
257 return ret;
258 }
259 #endif