2 * Copyright 1999-2018 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
11 #include "internal/cryptlib.h"
12 #include <openssl/conf.h>
13 #include <openssl/asn1.h>
14 #include <openssl/asn1t.h>
15 #include <openssl/x509v3.h>
20 /* Certificate policies extension support: this one is a bit complex... */
22 static int i2r_certpol(X509V3_EXT_METHOD
*method
, STACK_OF(POLICYINFO
) *pol
,
23 BIO
*out
, int indent
);
24 static STACK_OF(POLICYINFO
) *r2i_certpol(X509V3_EXT_METHOD
*method
,
25 X509V3_CTX
*ctx
, const char *value
);
26 static void print_qualifiers(BIO
*out
, STACK_OF(POLICYQUALINFO
) *quals
,
28 static void print_notice(BIO
*out
, USERNOTICE
*notice
, int indent
);
29 static POLICYINFO
*policy_section(X509V3_CTX
*ctx
,
30 STACK_OF(CONF_VALUE
) *polstrs
, int ia5org
);
31 static POLICYQUALINFO
*notice_section(X509V3_CTX
*ctx
,
32 STACK_OF(CONF_VALUE
) *unot
, int ia5org
);
33 static int nref_nos(STACK_OF(ASN1_INTEGER
) *nnums
, STACK_OF(CONF_VALUE
) *nos
);
34 static int displaytext_str2tag(const char *tagstr
, unsigned int *tag_len
);
35 static int displaytext_get_tag_len(const char *tagstr
);
37 const X509V3_EXT_METHOD v3_cpols
= {
38 NID_certificate_policies
, 0, ASN1_ITEM_ref(CERTIFICATEPOLICIES
),
42 (X509V3_EXT_I2R
)i2r_certpol
,
43 (X509V3_EXT_R2I
)r2i_certpol
,
47 ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES
) =
48 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF
, 0, CERTIFICATEPOLICIES
, POLICYINFO
)
49 ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES
)
51 IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES
)
53 ASN1_SEQUENCE(POLICYINFO
) = {
54 ASN1_SIMPLE(POLICYINFO
, policyid
, ASN1_OBJECT
),
55 ASN1_SEQUENCE_OF_OPT(POLICYINFO
, qualifiers
, POLICYQUALINFO
)
56 } ASN1_SEQUENCE_END(POLICYINFO
)
58 IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO
)
60 ASN1_ADB_TEMPLATE(policydefault
) = ASN1_SIMPLE(POLICYQUALINFO
, d
.other
, ASN1_ANY
);
62 ASN1_ADB(POLICYQUALINFO
) = {
63 ADB_ENTRY(NID_id_qt_cps
, ASN1_SIMPLE(POLICYQUALINFO
, d
.cpsuri
, ASN1_IA5STRING
)),
64 ADB_ENTRY(NID_id_qt_unotice
, ASN1_SIMPLE(POLICYQUALINFO
, d
.usernotice
, USERNOTICE
))
65 } ASN1_ADB_END(POLICYQUALINFO
, 0, pqualid
, 0, &policydefault_tt
, NULL
);
67 ASN1_SEQUENCE(POLICYQUALINFO
) = {
68 ASN1_SIMPLE(POLICYQUALINFO
, pqualid
, ASN1_OBJECT
),
69 ASN1_ADB_OBJECT(POLICYQUALINFO
)
70 } ASN1_SEQUENCE_END(POLICYQUALINFO
)
72 IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO
)
74 ASN1_SEQUENCE(USERNOTICE
) = {
75 ASN1_OPT(USERNOTICE
, noticeref
, NOTICEREF
),
76 ASN1_OPT(USERNOTICE
, exptext
, DISPLAYTEXT
)
77 } ASN1_SEQUENCE_END(USERNOTICE
)
79 IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE
)
81 ASN1_SEQUENCE(NOTICEREF
) = {
82 ASN1_SIMPLE(NOTICEREF
, organization
, DISPLAYTEXT
),
83 ASN1_SEQUENCE_OF(NOTICEREF
, noticenos
, ASN1_INTEGER
)
84 } ASN1_SEQUENCE_END(NOTICEREF
)
86 IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF
)
88 static STACK_OF(POLICYINFO
) *r2i_certpol(X509V3_EXT_METHOD
*method
,
89 X509V3_CTX
*ctx
, const char *value
)
91 STACK_OF(POLICYINFO
) *pols
;
95 STACK_OF(CONF_VALUE
) *vals
= X509V3_parse_list(value
);
97 const int num
= sk_CONF_VALUE_num(vals
);
101 X509V3err(X509V3_F_R2I_CERTPOL
, ERR_R_X509V3_LIB
);
105 pols
= sk_POLICYINFO_new_reserve(NULL
, num
);
107 X509V3err(X509V3_F_R2I_CERTPOL
, ERR_R_MALLOC_FAILURE
);
112 for (i
= 0; i
< num
; i
++) {
113 cnf
= sk_CONF_VALUE_value(vals
, i
);
115 if (cnf
->value
|| !cnf
->name
) {
116 X509V3err(X509V3_F_R2I_CERTPOL
,
117 X509V3_R_INVALID_POLICY_IDENTIFIER
);
118 X509V3_conf_err(cnf
);
122 if (strcmp(pstr
, "ia5org") == 0) {
125 } else if (*pstr
== '@') {
126 STACK_OF(CONF_VALUE
) *polsect
;
127 polsect
= X509V3_get_section(ctx
, pstr
+ 1);
129 X509V3err(X509V3_F_R2I_CERTPOL
, X509V3_R_INVALID_SECTION
);
131 X509V3_conf_err(cnf
);
134 pol
= policy_section(ctx
, polsect
, ia5org
);
135 X509V3_section_free(ctx
, polsect
);
139 if ((pobj
= OBJ_txt2obj(cnf
->name
, 0)) == NULL
) {
140 X509V3err(X509V3_F_R2I_CERTPOL
,
141 X509V3_R_INVALID_OBJECT_IDENTIFIER
);
142 X509V3_conf_err(cnf
);
145 pol
= POLICYINFO_new();
147 ASN1_OBJECT_free(pobj
);
148 X509V3err(X509V3_F_R2I_CERTPOL
, ERR_R_MALLOC_FAILURE
);
151 pol
->policyid
= pobj
;
153 if (!sk_POLICYINFO_push(pols
, pol
)) {
154 POLICYINFO_free(pol
);
155 X509V3err(X509V3_F_R2I_CERTPOL
, ERR_R_MALLOC_FAILURE
);
159 sk_CONF_VALUE_pop_free(vals
, X509V3_conf_free
);
162 sk_CONF_VALUE_pop_free(vals
, X509V3_conf_free
);
163 sk_POLICYINFO_pop_free(pols
, POLICYINFO_free
);
167 static POLICYINFO
*policy_section(X509V3_CTX
*ctx
,
168 STACK_OF(CONF_VALUE
) *polstrs
, int ia5org
)
173 POLICYQUALINFO
*qual
;
175 if ((pol
= POLICYINFO_new()) == NULL
)
177 for (i
= 0; i
< sk_CONF_VALUE_num(polstrs
); i
++) {
178 cnf
= sk_CONF_VALUE_value(polstrs
, i
);
179 if (strcmp(cnf
->name
, "policyIdentifier") == 0) {
181 if ((pobj
= OBJ_txt2obj(cnf
->value
, 0)) == NULL
) {
182 X509V3err(X509V3_F_POLICY_SECTION
,
183 X509V3_R_INVALID_OBJECT_IDENTIFIER
);
184 X509V3_conf_err(cnf
);
187 pol
->policyid
= pobj
;
189 } else if (!name_cmp(cnf
->name
, "CPS")) {
190 if (pol
->qualifiers
== NULL
)
191 pol
->qualifiers
= sk_POLICYQUALINFO_new_null();
192 if ((qual
= POLICYQUALINFO_new()) == NULL
)
194 if (!sk_POLICYQUALINFO_push(pol
->qualifiers
, qual
))
196 if ((qual
->pqualid
= OBJ_nid2obj(NID_id_qt_cps
)) == NULL
) {
197 X509V3err(X509V3_F_POLICY_SECTION
, ERR_R_INTERNAL_ERROR
);
200 if ((qual
->d
.cpsuri
= ASN1_IA5STRING_new()) == NULL
)
202 if (!ASN1_STRING_set(qual
->d
.cpsuri
, cnf
->value
,
205 } else if (!name_cmp(cnf
->name
, "userNotice")) {
206 STACK_OF(CONF_VALUE
) *unot
;
207 if (*cnf
->value
!= '@') {
208 X509V3err(X509V3_F_POLICY_SECTION
,
209 X509V3_R_EXPECTED_A_SECTION_NAME
);
210 X509V3_conf_err(cnf
);
213 unot
= X509V3_get_section(ctx
, cnf
->value
+ 1);
215 X509V3err(X509V3_F_POLICY_SECTION
, X509V3_R_INVALID_SECTION
);
217 X509V3_conf_err(cnf
);
220 qual
= notice_section(ctx
, unot
, ia5org
);
221 X509V3_section_free(ctx
, unot
);
224 if (!pol
->qualifiers
)
225 pol
->qualifiers
= sk_POLICYQUALINFO_new_null();
226 if (!sk_POLICYQUALINFO_push(pol
->qualifiers
, qual
))
229 X509V3err(X509V3_F_POLICY_SECTION
, X509V3_R_INVALID_OPTION
);
231 X509V3_conf_err(cnf
);
235 if (!pol
->policyid
) {
236 X509V3err(X509V3_F_POLICY_SECTION
, X509V3_R_NO_POLICY_IDENTIFIER
);
243 X509V3err(X509V3_F_POLICY_SECTION
, ERR_R_MALLOC_FAILURE
);
246 POLICYINFO_free(pol
);
250 static int displaytext_get_tag_len(const char *tagstr
)
252 char *colon
= strchr(tagstr
, ':');
254 return (colon
== NULL
) ? -1 : colon
- tagstr
;
257 static int displaytext_str2tag(const char *tagstr
, unsigned int *tag_len
)
262 len
= displaytext_get_tag_len(tagstr
);
265 return V_ASN1_VISIBLESTRING
;
267 if (len
== sizeof("UTF8") - 1 && strncmp(tagstr
, "UTF8", len
) == 0)
268 return V_ASN1_UTF8STRING
;
269 if (len
== sizeof("UTF8String") - 1 && strncmp(tagstr
, "UTF8String", len
) == 0)
270 return V_ASN1_UTF8STRING
;
271 if (len
== sizeof("BMP") - 1 && strncmp(tagstr
, "BMP", len
) == 0)
272 return V_ASN1_BMPSTRING
;
273 if (len
== sizeof("BMPSTRING") - 1 && strncmp(tagstr
, "BMPSTRING", len
) == 0)
274 return V_ASN1_BMPSTRING
;
275 if (len
== sizeof("VISIBLE") - 1 && strncmp(tagstr
, "VISIBLE", len
) == 0)
276 return V_ASN1_VISIBLESTRING
;
277 if (len
== sizeof("VISIBLESTRING") - 1 && strncmp(tagstr
, "VISIBLESTRING", len
) == 0)
278 return V_ASN1_VISIBLESTRING
;
280 return V_ASN1_VISIBLESTRING
;
283 static POLICYQUALINFO
*notice_section(X509V3_CTX
*ctx
,
284 STACK_OF(CONF_VALUE
) *unot
, int ia5org
)
286 int i
, ret
, len
, tag
;
287 unsigned int tag_len
;
290 POLICYQUALINFO
*qual
;
293 if ((qual
= POLICYQUALINFO_new()) == NULL
)
295 if ((qual
->pqualid
= OBJ_nid2obj(NID_id_qt_unotice
)) == NULL
) {
296 X509V3err(X509V3_F_NOTICE_SECTION
, ERR_R_INTERNAL_ERROR
);
299 if ((not = USERNOTICE_new()) == NULL
)
301 qual
->d
.usernotice
= not;
302 for (i
= 0; i
< sk_CONF_VALUE_num(unot
); i
++) {
303 cnf
= sk_CONF_VALUE_value(unot
, i
);
305 if (strcmp(cnf
->name
, "explicitText") == 0) {
306 tag
= displaytext_str2tag(value
, &tag_len
);
307 if ((not->exptext
= ASN1_STRING_type_new(tag
)) == NULL
)
310 value
+= tag_len
+ 1;
312 if (!ASN1_STRING_set(not->exptext
, value
, len
))
314 } else if (strcmp(cnf
->name
, "organization") == 0) {
316 if (!not->noticeref
) {
317 if ((nref
= NOTICEREF_new()) == NULL
)
319 not->noticeref
= nref
;
321 nref
= not->noticeref
;
323 nref
->organization
->type
= V_ASN1_IA5STRING
;
325 nref
->organization
->type
= V_ASN1_VISIBLESTRING
;
326 if (!ASN1_STRING_set(nref
->organization
, cnf
->value
,
329 } else if (strcmp(cnf
->name
, "noticeNumbers") == 0) {
331 STACK_OF(CONF_VALUE
) *nos
;
332 if (!not->noticeref
) {
333 if ((nref
= NOTICEREF_new()) == NULL
)
335 not->noticeref
= nref
;
337 nref
= not->noticeref
;
338 nos
= X509V3_parse_list(cnf
->value
);
339 if (!nos
|| !sk_CONF_VALUE_num(nos
)) {
340 X509V3err(X509V3_F_NOTICE_SECTION
, X509V3_R_INVALID_NUMBERS
);
341 X509V3_conf_err(cnf
);
342 sk_CONF_VALUE_pop_free(nos
, X509V3_conf_free
);
345 ret
= nref_nos(nref
->noticenos
, nos
);
346 sk_CONF_VALUE_pop_free(nos
, X509V3_conf_free
);
350 X509V3err(X509V3_F_NOTICE_SECTION
, X509V3_R_INVALID_OPTION
);
351 X509V3_conf_err(cnf
);
356 if (not->noticeref
&&
357 (!not->noticeref
->noticenos
|| !not->noticeref
->organization
)) {
358 X509V3err(X509V3_F_NOTICE_SECTION
,
359 X509V3_R_NEED_ORGANIZATION_AND_NUMBERS
);
366 X509V3err(X509V3_F_NOTICE_SECTION
, ERR_R_MALLOC_FAILURE
);
369 POLICYQUALINFO_free(qual
);
373 static int nref_nos(STACK_OF(ASN1_INTEGER
) *nnums
, STACK_OF(CONF_VALUE
) *nos
)
380 for (i
= 0; i
< sk_CONF_VALUE_num(nos
); i
++) {
381 cnf
= sk_CONF_VALUE_value(nos
, i
);
382 if ((aint
= s2i_ASN1_INTEGER(NULL
, cnf
->name
)) == NULL
) {
383 X509V3err(X509V3_F_NREF_NOS
, X509V3_R_INVALID_NUMBER
);
386 if (!sk_ASN1_INTEGER_push(nnums
, aint
))
392 ASN1_INTEGER_free(aint
);
393 X509V3err(X509V3_F_NREF_NOS
, ERR_R_MALLOC_FAILURE
);
399 static int i2r_certpol(X509V3_EXT_METHOD
*method
, STACK_OF(POLICYINFO
) *pol
,
400 BIO
*out
, int indent
)
404 /* First print out the policy OIDs */
405 for (i
= 0; i
< sk_POLICYINFO_num(pol
); i
++) {
408 pinfo
= sk_POLICYINFO_value(pol
, i
);
409 BIO_printf(out
, "%*sPolicy: ", indent
, "");
410 i2a_ASN1_OBJECT(out
, pinfo
->policyid
);
411 if (pinfo
->qualifiers
) {
413 print_qualifiers(out
, pinfo
->qualifiers
, indent
+ 2);
419 static void print_qualifiers(BIO
*out
, STACK_OF(POLICYQUALINFO
) *quals
,
422 POLICYQUALINFO
*qualinfo
;
424 for (i
= 0; i
< sk_POLICYQUALINFO_num(quals
); i
++) {
427 qualinfo
= sk_POLICYQUALINFO_value(quals
, i
);
428 switch (OBJ_obj2nid(qualinfo
->pqualid
)) {
430 BIO_printf(out
, "%*sCPS: %s", indent
, "",
431 qualinfo
->d
.cpsuri
->data
);
434 case NID_id_qt_unotice
:
435 BIO_printf(out
, "%*sUser Notice:\n", indent
, "");
436 print_notice(out
, qualinfo
->d
.usernotice
, indent
+ 2);
440 BIO_printf(out
, "%*sUnknown Qualifier: ", indent
+ 2, "");
442 i2a_ASN1_OBJECT(out
, qualinfo
->pqualid
);
448 static void print_notice(BIO
*out
, USERNOTICE
*notice
, int indent
)
451 if (notice
->noticeref
) {
453 ref
= notice
->noticeref
;
454 BIO_printf(out
, "%*sOrganization: %s\n", indent
, "",
455 ref
->organization
->data
);
456 BIO_printf(out
, "%*sNumber%s: ", indent
, "",
457 sk_ASN1_INTEGER_num(ref
->noticenos
) > 1 ? "s" : "");
458 for (i
= 0; i
< sk_ASN1_INTEGER_num(ref
->noticenos
); i
++) {
461 num
= sk_ASN1_INTEGER_value(ref
->noticenos
, i
);
465 BIO_puts(out
, "(null)");
467 tmp
= i2s_ASN1_INTEGER(NULL
, num
);
478 BIO_printf(out
, "%*sExplicit Text: %s", indent
, "",
479 notice
->exptext
->data
);
482 void X509_POLICY_NODE_print(BIO
*out
, X509_POLICY_NODE
*node
, int indent
)
484 const X509_POLICY_DATA
*dat
= node
->data
;
486 BIO_printf(out
, "%*sPolicy: ", indent
, "");
488 i2a_ASN1_OBJECT(out
, dat
->valid_policy
);
490 BIO_printf(out
, "%*s%s\n", indent
+ 2, "",
491 node_data_critical(dat
) ? "Critical" : "Non Critical");
492 if (dat
->qualifier_set
) {
493 print_qualifiers(out
, dat
->qualifier_set
, indent
+ 2);
497 BIO_printf(out
, "%*sNo Qualifiers\n", indent
+ 2, "");