2 * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
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
10 /* X509 v3 extension utilities */
13 #include "internal/cryptlib.h"
14 #include <openssl/conf.h>
15 #include <openssl/x509v3.h>
17 /* Extension printing routines */
19 static int unknown_ext_print(BIO
*out
, const unsigned char *ext
, int extlen
,
20 unsigned long flag
, int indent
, int supported
);
22 /* Print out a name+value stack */
24 void X509V3_EXT_val_prn(BIO
*out
, STACK_OF(CONF_VALUE
) *val
, int indent
,
31 if (!ml
|| !sk_CONF_VALUE_num(val
)) {
32 BIO_printf(out
, "%*s", indent
, "");
33 if (!sk_CONF_VALUE_num(val
))
34 BIO_puts(out
, "<EMPTY>\n");
36 for (i
= 0; i
< sk_CONF_VALUE_num(val
); i
++) {
39 BIO_printf(out
, "\n");
40 BIO_printf(out
, "%*s", indent
, "");
43 BIO_printf(out
, ", ");
44 nval
= sk_CONF_VALUE_value(val
, i
);
46 BIO_puts(out
, nval
->value
);
47 else if (!nval
->value
)
48 BIO_puts(out
, nval
->name
);
49 #ifndef CHARSET_EBCDIC
51 BIO_printf(out
, "%s:%s", nval
->name
, nval
->value
);
56 len
= strlen(nval
->value
) + 1;
57 tmp
= OPENSSL_malloc(len
);
59 ascii2ebcdic(tmp
, nval
->value
, len
);
60 BIO_printf(out
, "%s:%s", nval
->name
, tmp
);
68 /* Main routine: print out a general extension */
70 int X509V3_EXT_print(BIO
*out
, X509_EXTENSION
*ext
, unsigned long flag
,
75 ASN1_OCTET_STRING
*extoct
;
76 const unsigned char *p
;
78 const X509V3_EXT_METHOD
*method
;
79 STACK_OF(CONF_VALUE
) *nval
= NULL
;
82 extoct
= X509_EXTENSION_get_data(ext
);
83 p
= ASN1_STRING_get0_data(extoct
);
84 extlen
= ASN1_STRING_length(extoct
);
86 if ((method
= X509V3_EXT_get(ext
)) == NULL
)
87 return unknown_ext_print(out
, p
, extlen
, flag
, indent
, 0);
89 ext_str
= ASN1_item_d2i(NULL
, &p
, extlen
, ASN1_ITEM_ptr(method
->it
));
91 ext_str
= method
->d2i(NULL
, &p
, extlen
);
94 return unknown_ext_print(out
, p
, extlen
, flag
, indent
, 1);
97 if ((value
= method
->i2s(method
, ext_str
)) == NULL
) {
101 #ifndef CHARSET_EBCDIC
102 BIO_printf(out
, "%*s%s", indent
, "", value
);
107 len
= strlen(value
) + 1;
108 tmp
= OPENSSL_malloc(len
);
110 ascii2ebcdic(tmp
, value
, len
);
111 BIO_printf(out
, "%*s%s", indent
, "", tmp
);
116 } else if (method
->i2v
) {
117 if ((nval
= method
->i2v(method
, ext_str
, NULL
)) == NULL
) {
121 X509V3_EXT_val_prn(out
, nval
, indent
,
122 method
->ext_flags
& X509V3_EXT_MULTILINE
);
123 } else if (method
->i2r
) {
124 if (!method
->i2r(method
, ext_str
, out
, indent
))
130 sk_CONF_VALUE_pop_free(nval
, X509V3_conf_free
);
133 ASN1_item_free(ext_str
, ASN1_ITEM_ptr(method
->it
));
135 method
->ext_free(ext_str
);
139 int X509V3_extensions_print(BIO
*bp
, const char *title
,
140 const STACK_OF(X509_EXTENSION
) *exts
,
141 unsigned long flag
, int indent
)
145 if (sk_X509_EXTENSION_num(exts
) <= 0)
149 BIO_printf(bp
, "%*s%s:\n", indent
, "", title
);
153 for (i
= 0; i
< sk_X509_EXTENSION_num(exts
); i
++) {
157 ex
= sk_X509_EXTENSION_value(exts
, i
);
158 obj
= X509_EXTENSION_get_object(ex
);
159 if ((flag
& X509_FLAG_EXTENSIONS_ONLY_KID
) != 0
160 && OBJ_obj2nid(obj
) != NID_subject_key_identifier
161 && OBJ_obj2nid(obj
) != NID_authority_key_identifier
)
163 if (indent
&& BIO_printf(bp
, "%*s", indent
, "") <= 0)
165 i2a_ASN1_OBJECT(bp
, obj
);
166 j
= X509_EXTENSION_get_critical(ex
);
167 if (BIO_printf(bp
, ": %s\n", j
? "critical" : "") <= 0)
169 if (!X509V3_EXT_print(bp
, ex
, flag
, indent
+ 4)) {
170 BIO_printf(bp
, "%*s", indent
+ 4, "");
171 ASN1_STRING_print(bp
, X509_EXTENSION_get_data(ex
));
173 if (BIO_write(bp
, "\n", 1) <= 0)
179 static int unknown_ext_print(BIO
*out
, const unsigned char *ext
, int extlen
,
180 unsigned long flag
, int indent
, int supported
)
182 switch (flag
& X509V3_EXT_UNKNOWN_MASK
) {
184 case X509V3_EXT_DEFAULT
:
187 case X509V3_EXT_ERROR_UNKNOWN
:
189 BIO_printf(out
, "%*s<Parse Error>", indent
, "");
191 BIO_printf(out
, "%*s<Not Supported>", indent
, "");
194 case X509V3_EXT_PARSE_UNKNOWN
:
195 return ASN1_parse_dump(out
, ext
, extlen
, indent
, -1);
196 case X509V3_EXT_DUMP_UNKNOWN
:
197 return BIO_dump_indent(out
, (const char *)ext
, extlen
, indent
);
204 #ifndef OPENSSL_NO_STDIO
205 int X509V3_EXT_print_fp(FILE *fp
, X509_EXTENSION
*ext
, int flag
, int indent
)
210 if ((bio_tmp
= BIO_new_fp(fp
, BIO_NOCLOSE
)) == NULL
)
212 ret
= X509V3_EXT_print(bio_tmp
, ext
, flag
, indent
);