summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509v3
diff options
context:
space:
mode:
authordjm <>2008-09-06 12:15:56 +0000
committerdjm <>2008-09-06 12:15:56 +0000
commit12867252827c8efaa8ddd1fa3b3d6e321e2bcdef (patch)
treeb7a1f167ae5aeff4cfd8a18b598b68fe98a066fd /src/lib/libcrypto/x509v3
parentf519f07de9bfb123f2b32aa3965e6f73c8364b80 (diff)
parent5a3c0a05c7f2c5d3c584b7c8d6aec836dd724c80 (diff)
downloadopenbsd-12867252827c8efaa8ddd1fa3b3d6e321e2bcdef.tar.gz
openbsd-12867252827c8efaa8ddd1fa3b3d6e321e2bcdef.tar.bz2
openbsd-12867252827c8efaa8ddd1fa3b3d6e321e2bcdef.zip
This commit was generated by cvs2git to track changes on a CVS vendor
branch.
Diffstat (limited to 'src/lib/libcrypto/x509v3')
-rw-r--r--src/lib/libcrypto/x509v3/pcy_cache.c287
-rw-r--r--src/lib/libcrypto/x509v3/pcy_data.c123
-rw-r--r--src/lib/libcrypto/x509v3/pcy_int.h223
-rw-r--r--src/lib/libcrypto/x509v3/pcy_lib.c167
-rw-r--r--src/lib/libcrypto/x509v3/pcy_map.c186
-rw-r--r--src/lib/libcrypto/x509v3/pcy_node.c158
-rw-r--r--src/lib/libcrypto/x509v3/pcy_tree.c692
-rw-r--r--src/lib/libcrypto/x509v3/v3_ncons.c220
-rw-r--r--src/lib/libcrypto/x509v3/v3_pci.c31
-rw-r--r--src/lib/libcrypto/x509v3/v3_pcons.c136
-rw-r--r--src/lib/libcrypto/x509v3/v3_pmaps.c153
11 files changed, 2355 insertions, 21 deletions
diff --git a/src/lib/libcrypto/x509v3/pcy_cache.c b/src/lib/libcrypto/x509v3/pcy_cache.c
new file mode 100644
index 0000000000..c18beb89f5
--- /dev/null
+++ b/src/lib/libcrypto/x509v3/pcy_cache.c
@@ -0,0 +1,287 @@
1/* pcy_cache.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 2004.
4 */
5/* ====================================================================
6 * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include "cryptlib.h"
60#include <openssl/x509.h>
61#include <openssl/x509v3.h>
62
63#include "pcy_int.h"
64
65static int policy_data_cmp(const X509_POLICY_DATA * const *a,
66 const X509_POLICY_DATA * const *b);
67static int policy_cache_set_int(long *out, ASN1_INTEGER *value);
68
69/* Set cache entry according to CertificatePolicies extension.
70 * Note: this destroys the passed CERTIFICATEPOLICIES structure.
71 */
72
73static int policy_cache_create(X509 *x,
74 CERTIFICATEPOLICIES *policies, int crit)
75 {
76 int i;
77 int ret = 0;
78 X509_POLICY_CACHE *cache = x->policy_cache;
79 X509_POLICY_DATA *data = NULL;
80 POLICYINFO *policy;
81 if (sk_POLICYINFO_num(policies) == 0)
82 goto bad_policy;
83 cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
84 if (!cache->data)
85 goto bad_policy;
86 for (i = 0; i < sk_POLICYINFO_num(policies); i++)
87 {
88 policy = sk_POLICYINFO_value(policies, i);
89 data = policy_data_new(policy, NULL, crit);
90 if (!data)
91 goto bad_policy;
92 /* Duplicate policy OIDs are illegal: reject if matches
93 * found.
94 */
95 if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
96 {
97 if (cache->anyPolicy)
98 {
99 ret = -1;
100 goto bad_policy;
101 }
102 cache->anyPolicy = data;
103 }
104 else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1)
105 {
106 ret = -1;
107 goto bad_policy;
108 }
109 else if (!sk_X509_POLICY_DATA_push(cache->data, data))
110 goto bad_policy;
111 data = NULL;
112 }
113 ret = 1;
114 bad_policy:
115 if (ret == -1)
116 x->ex_flags |= EXFLAG_INVALID_POLICY;
117 if (data)
118 policy_data_free(data);
119 sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
120 if (ret <= 0)
121 {
122 sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
123 cache->data = NULL;
124 }
125 return ret;
126 }
127
128
129static int policy_cache_new(X509 *x)
130 {
131 X509_POLICY_CACHE *cache;
132 ASN1_INTEGER *ext_any = NULL;
133 POLICY_CONSTRAINTS *ext_pcons = NULL;
134 CERTIFICATEPOLICIES *ext_cpols = NULL;
135 POLICY_MAPPINGS *ext_pmaps = NULL;
136 int i;
137 cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE));
138 if (!cache)
139 return 0;
140 cache->anyPolicy = NULL;
141 cache->data = NULL;
142 cache->maps = NULL;
143 cache->any_skip = -1;
144 cache->explicit_skip = -1;
145 cache->map_skip = -1;
146
147 x->policy_cache = cache;
148
149 /* Handle requireExplicitPolicy *first*. Need to process this
150 * even if we don't have any policies.
151 */
152 ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
153
154 if (!ext_pcons)
155 {
156 if (i != -1)
157 goto bad_cache;
158 }
159 else
160 {
161 if (!ext_pcons->requireExplicitPolicy
162 && !ext_pcons->inhibitPolicyMapping)
163 goto bad_cache;
164 if (!policy_cache_set_int(&cache->explicit_skip,
165 ext_pcons->requireExplicitPolicy))
166 goto bad_cache;
167 if (!policy_cache_set_int(&cache->map_skip,
168 ext_pcons->inhibitPolicyMapping))
169 goto bad_cache;
170 }
171
172 /* Process CertificatePolicies */
173
174 ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL);
175 /* If no CertificatePolicies extension or problem decoding then
176 * there is no point continuing because the valid policies will be
177 * NULL.
178 */
179 if (!ext_cpols)
180 {
181 /* If not absent some problem with extension */
182 if (i != -1)
183 goto bad_cache;
184 return 1;
185 }
186
187 i = policy_cache_create(x, ext_cpols, i);
188
189 /* NB: ext_cpols freed by policy_cache_set_policies */
190
191 if (i <= 0)
192 return i;
193
194 ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
195
196 if (!ext_pmaps)
197 {
198 /* If not absent some problem with extension */
199 if (i != -1)
200 goto bad_cache;
201 }
202 else
203 {
204 i = policy_cache_set_mapping(x, ext_pmaps);
205 if (i <= 0)
206 goto bad_cache;
207 }
208
209 ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
210
211 if (!ext_any)
212 {
213 if (i != -1)
214 goto bad_cache;
215 }
216 else if (!policy_cache_set_int(&cache->any_skip, ext_any))
217 goto bad_cache;
218
219 if (0)
220 {
221 bad_cache:
222 x->ex_flags |= EXFLAG_INVALID_POLICY;
223 }
224
225 if(ext_pcons)
226 POLICY_CONSTRAINTS_free(ext_pcons);
227
228 if (ext_any)
229 ASN1_INTEGER_free(ext_any);
230
231 return 1;
232
233
234}
235
236void policy_cache_free(X509_POLICY_CACHE *cache)
237 {
238 if (!cache)
239 return;
240 if (cache->anyPolicy)
241 policy_data_free(cache->anyPolicy);
242 if (cache->data)
243 sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
244 OPENSSL_free(cache);
245 }
246
247const X509_POLICY_CACHE *policy_cache_set(X509 *x)
248 {
249
250 if (x->policy_cache == NULL)
251 {
252 CRYPTO_w_lock(CRYPTO_LOCK_X509);
253 policy_cache_new(x);
254 CRYPTO_w_unlock(CRYPTO_LOCK_X509);
255 }
256
257 return x->policy_cache;
258
259 }
260
261X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
262 const ASN1_OBJECT *id)
263 {
264 int idx;
265 X509_POLICY_DATA tmp;
266 tmp.valid_policy = (ASN1_OBJECT *)id;
267 idx = sk_X509_POLICY_DATA_find(cache->data, &tmp);
268 if (idx == -1)
269 return NULL;
270 return sk_X509_POLICY_DATA_value(cache->data, idx);
271 }
272
273static int policy_data_cmp(const X509_POLICY_DATA * const *a,
274 const X509_POLICY_DATA * const *b)
275 {
276 return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
277 }
278
279static int policy_cache_set_int(long *out, ASN1_INTEGER *value)
280 {
281 if (value == NULL)
282 return 1;
283 if (value->type == V_ASN1_NEG_INTEGER)
284 return 0;
285 *out = ASN1_INTEGER_get(value);
286 return 1;
287 }
diff --git a/src/lib/libcrypto/x509v3/pcy_data.c b/src/lib/libcrypto/x509v3/pcy_data.c
new file mode 100644
index 0000000000..614d2b4935
--- /dev/null
+++ b/src/lib/libcrypto/x509v3/pcy_data.c
@@ -0,0 +1,123 @@
1/* pcy_data.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 2004.
4 */
5/* ====================================================================
6 * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include "cryptlib.h"
60#include <openssl/x509.h>
61#include <openssl/x509v3.h>
62
63#include "pcy_int.h"
64
65/* Policy Node routines */
66
67void policy_data_free(X509_POLICY_DATA *data)
68 {
69 ASN1_OBJECT_free(data->valid_policy);
70 /* Don't free qualifiers if shared */
71 if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
72 sk_POLICYQUALINFO_pop_free(data->qualifier_set,
73 POLICYQUALINFO_free);
74 sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
75 OPENSSL_free(data);
76 }
77
78/* Create a data based on an existing policy. If 'id' is NULL use the
79 * oid in the policy, otherwise use 'id'. This behaviour covers the two
80 * types of data in RFC3280: data with from a CertificatePolcies extension
81 * and additional data with just the qualifiers of anyPolicy and ID from
82 * another source.
83 */
84
85X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, int crit)
86 {
87 X509_POLICY_DATA *ret;
88 if (!policy && !id)
89 return NULL;
90 ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
91 if (!ret)
92 return NULL;
93 ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
94 if (!ret->expected_policy_set)
95 {
96 OPENSSL_free(ret);
97 return NULL;
98 }
99
100 if (crit)
101 ret->flags = POLICY_DATA_FLAG_CRITICAL;
102 else
103 ret->flags = 0;
104
105 if (id)
106 ret->valid_policy = id;
107 else
108 {
109 ret->valid_policy = policy->policyid;
110 policy->policyid = NULL;
111 }
112
113 if (policy)
114 {
115 ret->qualifier_set = policy->qualifiers;
116 policy->qualifiers = NULL;
117 }
118 else
119 ret->qualifier_set = NULL;
120
121 return ret;
122 }
123
diff --git a/src/lib/libcrypto/x509v3/pcy_int.h b/src/lib/libcrypto/x509v3/pcy_int.h
new file mode 100644
index 0000000000..ba62a209da
--- /dev/null
+++ b/src/lib/libcrypto/x509v3/pcy_int.h
@@ -0,0 +1,223 @@
1/* pcy_int.h */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 2004.
4 */
5/* ====================================================================
6 * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59DECLARE_STACK_OF(X509_POLICY_DATA)
60DECLARE_STACK_OF(X509_POLICY_REF)
61DECLARE_STACK_OF(X509_POLICY_NODE)
62
63typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
64typedef struct X509_POLICY_REF_st X509_POLICY_REF;
65
66/* Internal structures */
67
68/* This structure and the field names correspond to the Policy 'node' of
69 * RFC3280. NB this structure contains no pointers to parent or child
70 * data: X509_POLICY_NODE contains that. This means that the main policy data
71 * can be kept static and cached with the certificate.
72 */
73
74struct X509_POLICY_DATA_st
75 {
76 unsigned int flags;
77 /* Policy OID and qualifiers for this data */
78 ASN1_OBJECT *valid_policy;
79 STACK_OF(POLICYQUALINFO) *qualifier_set;
80 STACK_OF(ASN1_OBJECT) *expected_policy_set;
81 };
82
83/* X509_POLICY_DATA flags values */
84
85/* This flag indicates the structure has been mapped using a policy mapping
86 * extension. If policy mapping is not active its references get deleted.
87 */
88
89#define POLICY_DATA_FLAG_MAPPED 0x1
90
91/* This flag indicates the data doesn't correspond to a policy in Certificate
92 * Policies: it has been mapped to any policy.
93 */
94
95#define POLICY_DATA_FLAG_MAPPED_ANY 0x2
96
97/* AND with flags to see if any mapping has occurred */
98
99#define POLICY_DATA_FLAG_MAP_MASK 0x3
100
101/* qualifiers are shared and shouldn't be freed */
102
103#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4
104
105/* Parent node is an extra node and should be freed */
106
107#define POLICY_DATA_FLAG_EXTRA_NODE 0x8
108
109/* Corresponding CertificatePolicies is critical */
110
111#define POLICY_DATA_FLAG_CRITICAL 0x10
112
113/* This structure is an entry from a table of mapped policies which
114 * cross reference the policy it refers to.
115 */
116
117struct X509_POLICY_REF_st
118 {
119 ASN1_OBJECT *subjectDomainPolicy;
120 const X509_POLICY_DATA *data;
121 };
122
123/* This structure is cached with a certificate */
124
125struct X509_POLICY_CACHE_st {
126 /* anyPolicy data or NULL if no anyPolicy */
127 X509_POLICY_DATA *anyPolicy;
128 /* other policy data */
129 STACK_OF(X509_POLICY_DATA) *data;
130 /* If policyMappings extension present a table of mapped policies */
131 STACK_OF(X509_POLICY_REF) *maps;
132 /* If InhibitAnyPolicy present this is its value or -1 if absent. */
133 long any_skip;
134 /* If policyConstraints and requireExplicitPolicy present this is its
135 * value or -1 if absent.
136 */
137 long explicit_skip;
138 /* If policyConstraints and policyMapping present this is its
139 * value or -1 if absent.
140 */
141 long map_skip;
142 };
143
144/*#define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL*/
145
146/* This structure represents the relationship between nodes */
147
148struct X509_POLICY_NODE_st
149 {
150 /* node data this refers to */
151 const X509_POLICY_DATA *data;
152 /* Parent node */
153 X509_POLICY_NODE *parent;
154 /* Number of child nodes */
155 int nchild;
156 };
157
158struct X509_POLICY_LEVEL_st
159 {
160 /* Cert for this level */
161 X509 *cert;
162 /* nodes at this level */
163 STACK_OF(X509_POLICY_NODE) *nodes;
164 /* anyPolicy node */
165 X509_POLICY_NODE *anyPolicy;
166 /* Extra data */
167 /*STACK_OF(X509_POLICY_DATA) *extra_data;*/
168 unsigned int flags;
169 };
170
171struct X509_POLICY_TREE_st
172 {
173 /* This is the tree 'level' data */
174 X509_POLICY_LEVEL *levels;
175 int nlevel;
176 /* Extra policy data when additional nodes (not from the certificate)
177 * are required.
178 */
179 STACK_OF(X509_POLICY_DATA) *extra_data;
180 /* This is the authority constained policy set */
181 STACK_OF(X509_POLICY_NODE) *auth_policies;
182 STACK_OF(X509_POLICY_NODE) *user_policies;
183 unsigned int flags;
184 };
185
186/* Set if anyPolicy present in user policies */
187#define POLICY_FLAG_ANY_POLICY 0x2
188
189/* Useful macros */
190
191#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL)
192#define node_critical(node) node_data_critical(node->data)
193
194/* Internal functions */
195
196X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id,
197 int crit);
198void policy_data_free(X509_POLICY_DATA *data);
199
200X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
201 const ASN1_OBJECT *id);
202int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps);
203
204
205STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void);
206
207void policy_cache_init(void);
208
209void policy_cache_free(X509_POLICY_CACHE *cache);
210
211X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
212 const ASN1_OBJECT *id);
213
214X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
215 const ASN1_OBJECT *id);
216
217X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
218 X509_POLICY_DATA *data,
219 X509_POLICY_NODE *parent,
220 X509_POLICY_TREE *tree);
221void policy_node_free(X509_POLICY_NODE *node);
222
223const X509_POLICY_CACHE *policy_cache_set(X509 *x);
diff --git a/src/lib/libcrypto/x509v3/pcy_lib.c b/src/lib/libcrypto/x509v3/pcy_lib.c
new file mode 100644
index 0000000000..dae4840bc5
--- /dev/null
+++ b/src/lib/libcrypto/x509v3/pcy_lib.c
@@ -0,0 +1,167 @@
1/* pcy_lib.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 2004.
4 */
5/* ====================================================================
6 * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59
60#include "cryptlib.h"
61#include <openssl/x509.h>
62#include <openssl/x509v3.h>
63
64#include "pcy_int.h"
65
66/* accessor functions */
67
68/* X509_POLICY_TREE stuff */
69
70int X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
71 {
72 if (!tree)
73 return 0;
74 return tree->nlevel;
75 }
76
77X509_POLICY_LEVEL *
78 X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i)
79 {
80 if (!tree || (i < 0) || (i >= tree->nlevel))
81 return NULL;
82 return tree->levels + i;
83 }
84
85STACK_OF(X509_POLICY_NODE) *
86 X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree)
87 {
88 if (!tree)
89 return NULL;
90 return tree->auth_policies;
91 }
92
93STACK_OF(X509_POLICY_NODE) *
94 X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree)
95 {
96 if (!tree)
97 return NULL;
98 if (tree->flags & POLICY_FLAG_ANY_POLICY)
99 return tree->auth_policies;
100 else
101 return tree->user_policies;
102 }
103
104/* X509_POLICY_LEVEL stuff */
105
106int X509_policy_level_node_count(X509_POLICY_LEVEL *level)
107 {
108 int n;
109 if (!level)
110 return 0;
111 if (level->anyPolicy)
112 n = 1;
113 else
114 n = 0;
115 if (level->nodes)
116 n += sk_X509_POLICY_NODE_num(level->nodes);
117 return n;
118 }
119
120X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i)
121 {
122 if (!level)
123 return NULL;
124 if (level->anyPolicy)
125 {
126 if (i == 0)
127 return level->anyPolicy;
128 i--;
129 }
130 return sk_X509_POLICY_NODE_value(level->nodes, i);
131 }
132
133/* X509_POLICY_NODE stuff */
134
135const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node)
136 {
137 if (!node)
138 return NULL;
139 return node->data->valid_policy;
140 }
141
142#if 0
143int X509_policy_node_get_critical(const X509_POLICY_NODE *node)
144 {
145 if (node_critical(node))
146 return 1;
147 return 0;
148 }
149#endif
150
151STACK_OF(POLICYQUALINFO) *
152 X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node)
153 {
154 if (!node)
155 return NULL;
156 return node->data->qualifier_set;
157 }
158
159const X509_POLICY_NODE *
160 X509_policy_node_get0_parent(const X509_POLICY_NODE *node)
161 {
162 if (!node)
163 return NULL;
164 return node->parent;
165 }
166
167
diff --git a/src/lib/libcrypto/x509v3/pcy_map.c b/src/lib/libcrypto/x509v3/pcy_map.c
new file mode 100644
index 0000000000..35221e8ba8
--- /dev/null
+++ b/src/lib/libcrypto/x509v3/pcy_map.c
@@ -0,0 +1,186 @@
1/* pcy_map.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 2004.
4 */
5/* ====================================================================
6 * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include "cryptlib.h"
60#include <openssl/x509.h>
61#include <openssl/x509v3.h>
62
63#include "pcy_int.h"
64
65static int ref_cmp(const X509_POLICY_REF * const *a,
66 const X509_POLICY_REF * const *b)
67 {
68 return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy);
69 }
70
71static void policy_map_free(X509_POLICY_REF *map)
72 {
73 if (map->subjectDomainPolicy)
74 ASN1_OBJECT_free(map->subjectDomainPolicy);
75 OPENSSL_free(map);
76 }
77
78static X509_POLICY_REF *policy_map_find(X509_POLICY_CACHE *cache, ASN1_OBJECT *id)
79 {
80 X509_POLICY_REF tmp;
81 int idx;
82 tmp.subjectDomainPolicy = id;
83
84 idx = sk_X509_POLICY_REF_find(cache->maps, &tmp);
85 if (idx == -1)
86 return NULL;
87 return sk_X509_POLICY_REF_value(cache->maps, idx);
88 }
89
90/* Set policy mapping entries in cache.
91 * Note: this modifies the passed POLICY_MAPPINGS structure
92 */
93
94int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
95 {
96 POLICY_MAPPING *map;
97 X509_POLICY_REF *ref = NULL;
98 X509_POLICY_DATA *data;
99 X509_POLICY_CACHE *cache = x->policy_cache;
100 int i;
101 int ret = 0;
102 if (sk_POLICY_MAPPING_num(maps) == 0)
103 {
104 ret = -1;
105 goto bad_mapping;
106 }
107 cache->maps = sk_X509_POLICY_REF_new(ref_cmp);
108 for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++)
109 {
110 map = sk_POLICY_MAPPING_value(maps, i);
111 /* Reject if map to or from anyPolicy */
112 if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy)
113 || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy))
114 {
115 ret = -1;
116 goto bad_mapping;
117 }
118
119 /* If we've already mapped from this OID bad mapping */
120 if (policy_map_find(cache, map->subjectDomainPolicy) != NULL)
121 {
122 ret = -1;
123 goto bad_mapping;
124 }
125
126 /* Attempt to find matching policy data */
127 data = policy_cache_find_data(cache, map->issuerDomainPolicy);
128 /* If we don't have anyPolicy can't map */
129 if (!data && !cache->anyPolicy)
130 continue;
131
132 /* Create a NODE from anyPolicy */
133 if (!data)
134 {
135 data = policy_data_new(NULL, map->issuerDomainPolicy,
136 cache->anyPolicy->flags
137 & POLICY_DATA_FLAG_CRITICAL);
138 if (!data)
139 goto bad_mapping;
140 data->qualifier_set = cache->anyPolicy->qualifier_set;
141 map->issuerDomainPolicy = NULL;
142 data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
143 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
144 if (!sk_X509_POLICY_DATA_push(cache->data, data))
145 {
146 policy_data_free(data);
147 goto bad_mapping;
148 }
149 }
150 else
151 data->flags |= POLICY_DATA_FLAG_MAPPED;
152
153 if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
154 map->subjectDomainPolicy))
155 goto bad_mapping;
156
157 ref = OPENSSL_malloc(sizeof(X509_POLICY_REF));
158 if (!ref)
159 goto bad_mapping;
160
161 ref->subjectDomainPolicy = map->subjectDomainPolicy;
162 map->subjectDomainPolicy = NULL;
163 ref->data = data;
164
165 if (!sk_X509_POLICY_REF_push(cache->maps, ref))
166 goto bad_mapping;
167
168 ref = NULL;
169
170 }
171
172 ret = 1;
173 bad_mapping:
174 if (ret == -1)
175 x->ex_flags |= EXFLAG_INVALID_POLICY;
176 if (ref)
177 policy_map_free(ref);
178 if (ret <= 0)
179 {
180 sk_X509_POLICY_REF_pop_free(cache->maps, policy_map_free);
181 cache->maps = NULL;
182 }
183 sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
184 return ret;
185
186 }
diff --git a/src/lib/libcrypto/x509v3/pcy_node.c b/src/lib/libcrypto/x509v3/pcy_node.c
new file mode 100644
index 0000000000..dcc1554e29
--- /dev/null
+++ b/src/lib/libcrypto/x509v3/pcy_node.c
@@ -0,0 +1,158 @@
1/* pcy_node.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 2004.
4 */
5/* ====================================================================
6 * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <openssl/asn1.h>
60#include <openssl/x509.h>
61#include <openssl/x509v3.h>
62
63#include "pcy_int.h"
64
65static int node_cmp(const X509_POLICY_NODE * const *a,
66 const X509_POLICY_NODE * const *b)
67 {
68 return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
69 }
70
71STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void)
72 {
73 return sk_X509_POLICY_NODE_new(node_cmp);
74 }
75
76X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
77 const ASN1_OBJECT *id)
78 {
79 X509_POLICY_DATA n;
80 X509_POLICY_NODE l;
81 int idx;
82
83 n.valid_policy = (ASN1_OBJECT *)id;
84 l.data = &n;
85
86 idx = sk_X509_POLICY_NODE_find(nodes, &l);
87 if (idx == -1)
88 return NULL;
89
90 return sk_X509_POLICY_NODE_value(nodes, idx);
91
92 }
93
94X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
95 const ASN1_OBJECT *id)
96 {
97 return tree_find_sk(level->nodes, id);
98 }
99
100X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
101 X509_POLICY_DATA *data,
102 X509_POLICY_NODE *parent,
103 X509_POLICY_TREE *tree)
104 {
105 X509_POLICY_NODE *node;
106 node = OPENSSL_malloc(sizeof(X509_POLICY_NODE));
107 if (!node)
108 return NULL;
109 node->data = data;
110 node->parent = parent;
111 node->nchild = 0;
112 if (level)
113 {
114 if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
115 {
116 if (level->anyPolicy)
117 goto node_error;
118 level->anyPolicy = node;
119 }
120 else
121 {
122
123 if (!level->nodes)
124 level->nodes = policy_node_cmp_new();
125 if (!level->nodes)
126 goto node_error;
127 if (!sk_X509_POLICY_NODE_push(level->nodes, node))
128 goto node_error;
129 }
130 }
131
132 if (tree)
133 {
134 if (!tree->extra_data)
135 tree->extra_data = sk_X509_POLICY_DATA_new_null();
136 if (!tree->extra_data)
137 goto node_error;
138 if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
139 goto node_error;
140 }
141
142 if (parent)
143 parent->nchild++;
144
145 return node;
146
147 node_error:
148 policy_node_free(node);
149 return 0;
150
151 }
152
153void policy_node_free(X509_POLICY_NODE *node)
154 {
155 OPENSSL_free(node);
156 }
157
158
diff --git a/src/lib/libcrypto/x509v3/pcy_tree.c b/src/lib/libcrypto/x509v3/pcy_tree.c
new file mode 100644
index 0000000000..4fda1d419a
--- /dev/null
+++ b/src/lib/libcrypto/x509v3/pcy_tree.c
@@ -0,0 +1,692 @@
1/* pcy_tree.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 2004.
4 */
5/* ====================================================================
6 * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include "cryptlib.h"
60#include <openssl/x509.h>
61#include <openssl/x509v3.h>
62
63#include "pcy_int.h"
64
65/* Initialize policy tree. Return values:
66 * 0 Some internal error occured.
67 * -1 Inconsistent or invalid extensions in certificates.
68 * 1 Tree initialized OK.
69 * 2 Policy tree is empty.
70 * 5 Tree OK and requireExplicitPolicy true.
71 * 6 Tree empty and requireExplicitPolicy true.
72 */
73
74static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
75 unsigned int flags)
76 {
77 X509_POLICY_TREE *tree;
78 X509_POLICY_LEVEL *level;
79 const X509_POLICY_CACHE *cache;
80 X509_POLICY_DATA *data = NULL;
81 X509 *x;
82 int ret = 1;
83 int i, n;
84 int explicit_policy;
85 int any_skip;
86 int map_skip;
87 *ptree = NULL;
88 n = sk_X509_num(certs);
89
90 /* Disable policy mapping for now... */
91 flags |= X509_V_FLAG_INHIBIT_MAP;
92
93 if (flags & X509_V_FLAG_EXPLICIT_POLICY)
94 explicit_policy = 0;
95 else
96 explicit_policy = n + 1;
97
98 if (flags & X509_V_FLAG_INHIBIT_ANY)
99 any_skip = 0;
100 else
101 any_skip = n + 1;
102
103 if (flags & X509_V_FLAG_INHIBIT_MAP)
104 map_skip = 0;
105 else
106 map_skip = n + 1;
107
108 /* Can't do anything with just a trust anchor */
109 if (n == 1)
110 return 1;
111 /* First setup policy cache in all certificates apart from the
112 * trust anchor. Note any bad cache results on the way. Also can
113 * calculate explicit_policy value at this point.
114 */
115 for (i = n - 2; i >= 0; i--)
116 {
117 x = sk_X509_value(certs, i);
118 X509_check_purpose(x, -1, -1);
119 cache = policy_cache_set(x);
120 /* If cache NULL something bad happened: return immediately */
121 if (cache == NULL)
122 return 0;
123 /* If inconsistent extensions keep a note of it but continue */
124 if (x->ex_flags & EXFLAG_INVALID_POLICY)
125 ret = -1;
126 /* Otherwise if we have no data (hence no CertificatePolicies)
127 * and haven't already set an inconsistent code note it.
128 */
129 else if ((ret == 1) && !cache->data)
130 ret = 2;
131 if (explicit_policy > 0)
132 {
133 explicit_policy--;
134 if (!(x->ex_flags & EXFLAG_SS)
135 && (cache->explicit_skip != -1)
136 && (cache->explicit_skip < explicit_policy))
137 explicit_policy = cache->explicit_skip;
138 }
139 }
140
141 if (ret != 1)
142 {
143 if (ret == 2 && !explicit_policy)
144 return 6;
145 return ret;
146 }
147
148
149 /* If we get this far initialize the tree */
150
151 tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE));
152
153 if (!tree)
154 return 0;
155
156 tree->flags = 0;
157 tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n);
158 tree->nlevel = 0;
159 tree->extra_data = NULL;
160 tree->auth_policies = NULL;
161 tree->user_policies = NULL;
162
163 if (!tree)
164 {
165 OPENSSL_free(tree);
166 return 0;
167 }
168
169 memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
170
171 tree->nlevel = n;
172
173 level = tree->levels;
174
175 /* Root data: initialize to anyPolicy */
176
177 data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0);
178
179 if (!data || !level_add_node(level, data, NULL, tree))
180 goto bad_tree;
181
182 for (i = n - 2; i >= 0; i--)
183 {
184 level++;
185 x = sk_X509_value(certs, i);
186 cache = policy_cache_set(x);
187
188 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
189 level->cert = x;
190
191 if (!cache->anyPolicy)
192 level->flags |= X509_V_FLAG_INHIBIT_ANY;
193
194 /* Determine inhibit any and inhibit map flags */
195 if (any_skip == 0)
196 {
197 /* Any matching allowed if certificate is self
198 * issued and not the last in the chain.
199 */
200 if (!(x->ex_flags & EXFLAG_SS) || (i == 0))
201 level->flags |= X509_V_FLAG_INHIBIT_ANY;
202 }
203 else
204 {
205 any_skip--;
206 if ((cache->any_skip > 0)
207 && (cache->any_skip < any_skip))
208 any_skip = cache->any_skip;
209 }
210
211 if (map_skip == 0)
212 level->flags |= X509_V_FLAG_INHIBIT_MAP;
213 else
214 {
215 map_skip--;
216 if ((cache->map_skip > 0)
217 && (cache->map_skip < map_skip))
218 map_skip = cache->map_skip;
219 }
220
221
222 }
223
224 *ptree = tree;
225
226 if (explicit_policy)
227 return 1;
228 else
229 return 5;
230
231 bad_tree:
232
233 X509_policy_tree_free(tree);
234
235 return 0;
236
237 }
238
239/* This corresponds to RFC3280 XXXX XXXXX:
240 * link any data from CertificatePolicies onto matching parent
241 * or anyPolicy if no match.
242 */
243
244static int tree_link_nodes(X509_POLICY_LEVEL *curr,
245 const X509_POLICY_CACHE *cache)
246 {
247 int i;
248 X509_POLICY_LEVEL *last;
249 X509_POLICY_DATA *data;
250 X509_POLICY_NODE *parent;
251 last = curr - 1;
252 for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
253 {
254 data = sk_X509_POLICY_DATA_value(cache->data, i);
255 /* If a node is mapped any it doesn't have a corresponding
256 * CertificatePolicies entry.
257 * However such an identical node would be created
258 * if anyPolicy matching is enabled because there would be
259 * no match with the parent valid_policy_set. So we create
260 * link because then it will have the mapping flags
261 * right and we can prune it later.
262 */
263 if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
264 && !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
265 continue;
266 /* Look for matching node in parent */
267 parent = level_find_node(last, data->valid_policy);
268 /* If no match link to anyPolicy */
269 if (!parent)
270 parent = last->anyPolicy;
271 if (parent && !level_add_node(curr, data, parent, NULL))
272 return 0;
273 }
274 return 1;
275 }
276
277/* This corresponds to RFC3280 XXXX XXXXX:
278 * Create new data for any unmatched policies in the parent and link
279 * to anyPolicy.
280 */
281
282static int tree_link_any(X509_POLICY_LEVEL *curr,
283 const X509_POLICY_CACHE *cache,
284 X509_POLICY_TREE *tree)
285 {
286 int i;
287 X509_POLICY_DATA *data;
288 X509_POLICY_NODE *node;
289 X509_POLICY_LEVEL *last;
290
291 last = curr - 1;
292
293 for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
294 {
295 node = sk_X509_POLICY_NODE_value(last->nodes, i);
296
297 /* Skip any node with any children: we only want unmathced
298 * nodes.
299 *
300 * Note: need something better for policy mapping
301 * because each node may have multiple children
302 */
303 if (node->nchild)
304 continue;
305 /* Create a new node with qualifiers from anyPolicy and
306 * id from unmatched node.
307 */
308 data = policy_data_new(NULL, node->data->valid_policy,
309 node_critical(node));
310
311 if (data == NULL)
312 return 0;
313 data->qualifier_set = curr->anyPolicy->data->qualifier_set;
314 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
315 if (!level_add_node(curr, data, node, tree))
316 {
317 policy_data_free(data);
318 return 0;
319 }
320 }
321 /* Finally add link to anyPolicy */
322 if (last->anyPolicy)
323 {
324 if (!level_add_node(curr, cache->anyPolicy,
325 last->anyPolicy, NULL))
326 return 0;
327 }
328 return 1;
329 }
330
331/* Prune the tree: delete any child mapped child data on the current level
332 * then proceed up the tree deleting any data with no children. If we ever
333 * have no data on a level we can halt because the tree will be empty.
334 */
335
336static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
337 {
338 X509_POLICY_NODE *node;
339 int i;
340 for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--)
341 {
342 node = sk_X509_POLICY_NODE_value(curr->nodes, i);
343 /* Delete any mapped data: see RFC3280 XXXX */
344 if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
345 {
346 node->parent->nchild--;
347 OPENSSL_free(node);
348 (void)sk_X509_POLICY_NODE_delete(curr->nodes, i);
349 }
350 }
351
352 for(;;) {
353 --curr;
354 for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--)
355 {
356 node = sk_X509_POLICY_NODE_value(curr->nodes, i);
357 if (node->nchild == 0)
358 {
359 node->parent->nchild--;
360 OPENSSL_free(node);
361 (void)sk_X509_POLICY_NODE_delete(curr->nodes, i);
362 }
363 }
364 if (curr->anyPolicy && !curr->anyPolicy->nchild)
365 {
366 if (curr->anyPolicy->parent)
367 curr->anyPolicy->parent->nchild--;
368 OPENSSL_free(curr->anyPolicy);
369 curr->anyPolicy = NULL;
370 }
371 if (curr == tree->levels)
372 {
373 /* If we zapped anyPolicy at top then tree is empty */
374 if (!curr->anyPolicy)
375 return 2;
376 return 1;
377 }
378 }
379
380 return 1;
381
382 }
383
384static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
385 X509_POLICY_NODE *pcy)
386 {
387 if (!*pnodes)
388 {
389 *pnodes = policy_node_cmp_new();
390 if (!*pnodes)
391 return 0;
392 }
393 else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
394 return 1;
395
396 if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
397 return 0;
398
399 return 1;
400
401 }
402
403/* Calculate the authority set based on policy tree.
404 * The 'pnodes' parameter is used as a store for the set of policy nodes
405 * used to calculate the user set. If the authority set is not anyPolicy
406 * then pnodes will just point to the authority set. If however the authority
407 * set is anyPolicy then the set of valid policies (other than anyPolicy)
408 * is store in pnodes. The return value of '2' is used in this case to indicate
409 * that pnodes should be freed.
410 */
411
412static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
413 STACK_OF(X509_POLICY_NODE) **pnodes)
414 {
415 X509_POLICY_LEVEL *curr;
416 X509_POLICY_NODE *node, *anyptr;
417 STACK_OF(X509_POLICY_NODE) **addnodes;
418 int i, j;
419 curr = tree->levels + tree->nlevel - 1;
420
421 /* If last level contains anyPolicy set is anyPolicy */
422 if (curr->anyPolicy)
423 {
424 if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
425 return 0;
426 addnodes = pnodes;
427 }
428 else
429 /* Add policies to authority set */
430 addnodes = &tree->auth_policies;
431
432 curr = tree->levels;
433 for (i = 1; i < tree->nlevel; i++)
434 {
435 /* If no anyPolicy node on this this level it can't
436 * appear on lower levels so end search.
437 */
438 if (!(anyptr = curr->anyPolicy))
439 break;
440 curr++;
441 for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++)
442 {
443 node = sk_X509_POLICY_NODE_value(curr->nodes, j);
444 if ((node->parent == anyptr)
445 && !tree_add_auth_node(addnodes, node))
446 return 0;
447 }
448 }
449
450 if (addnodes == pnodes)
451 return 2;
452
453 *pnodes = tree->auth_policies;
454
455 return 1;
456 }
457
458static int tree_calculate_user_set(X509_POLICY_TREE *tree,
459 STACK_OF(ASN1_OBJECT) *policy_oids,
460 STACK_OF(X509_POLICY_NODE) *auth_nodes)
461 {
462 int i;
463 X509_POLICY_NODE *node;
464 ASN1_OBJECT *oid;
465
466 X509_POLICY_NODE *anyPolicy;
467 X509_POLICY_DATA *extra;
468
469 /* Check if anyPolicy present in authority constrained policy set:
470 * this will happen if it is a leaf node.
471 */
472
473 if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
474 return 1;
475
476 anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
477
478 for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
479 {
480 oid = sk_ASN1_OBJECT_value(policy_oids, i);
481 if (OBJ_obj2nid(oid) == NID_any_policy)
482 {
483 tree->flags |= POLICY_FLAG_ANY_POLICY;
484 return 1;
485 }
486 }
487
488 for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
489 {
490 oid = sk_ASN1_OBJECT_value(policy_oids, i);
491 node = tree_find_sk(auth_nodes, oid);
492 if (!node)
493 {
494 if (!anyPolicy)
495 continue;
496 /* Create a new node with policy ID from user set
497 * and qualifiers from anyPolicy.
498 */
499 extra = policy_data_new(NULL, oid,
500 node_critical(anyPolicy));
501 if (!extra)
502 return 0;
503 extra->qualifier_set = anyPolicy->data->qualifier_set;
504 extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
505 | POLICY_DATA_FLAG_EXTRA_NODE;
506 node = level_add_node(NULL, extra, anyPolicy->parent,
507 tree);
508 }
509 if (!tree->user_policies)
510 {
511 tree->user_policies = sk_X509_POLICY_NODE_new_null();
512 if (!tree->user_policies)
513 return 1;
514 }
515 if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
516 return 0;
517 }
518 return 1;
519
520 }
521
522static int tree_evaluate(X509_POLICY_TREE *tree)
523 {
524 int ret, i;
525 X509_POLICY_LEVEL *curr = tree->levels + 1;
526 const X509_POLICY_CACHE *cache;
527
528 for(i = 1; i < tree->nlevel; i++, curr++)
529 {
530 cache = policy_cache_set(curr->cert);
531 if (!tree_link_nodes(curr, cache))
532 return 0;
533
534 if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
535 && !tree_link_any(curr, cache, tree))
536 return 0;
537 ret = tree_prune(tree, curr);
538 if (ret != 1)
539 return ret;
540 }
541
542 return 1;
543
544 }
545
546static void exnode_free(X509_POLICY_NODE *node)
547 {
548 if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
549 OPENSSL_free(node);
550 }
551
552
553void X509_policy_tree_free(X509_POLICY_TREE *tree)
554 {
555 X509_POLICY_LEVEL *curr;
556 int i;
557
558 if (!tree)
559 return;
560
561 sk_X509_POLICY_NODE_free(tree->auth_policies);
562 sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
563
564 for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++)
565 {
566 if (curr->cert)
567 X509_free(curr->cert);
568 if (curr->nodes)
569 sk_X509_POLICY_NODE_pop_free(curr->nodes,
570 policy_node_free);
571 if (curr->anyPolicy)
572 policy_node_free(curr->anyPolicy);
573 }
574
575 if (tree->extra_data)
576 sk_X509_POLICY_DATA_pop_free(tree->extra_data,
577 policy_data_free);
578
579 OPENSSL_free(tree->levels);
580 OPENSSL_free(tree);
581
582 }
583
584/* Application policy checking function.
585 * Return codes:
586 * 0 Internal Error.
587 * 1 Successful.
588 * -1 One or more certificates contain invalid or inconsistent extensions
589 * -2 User constrained policy set empty and requireExplicit true.
590 */
591
592int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
593 STACK_OF(X509) *certs,
594 STACK_OF(ASN1_OBJECT) *policy_oids,
595 unsigned int flags)
596 {
597 int ret;
598 X509_POLICY_TREE *tree = NULL;
599 STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
600 *ptree = NULL;
601
602 *pexplicit_policy = 0;
603 ret = tree_init(&tree, certs, flags);
604
605
606 switch (ret)
607 {
608
609 /* Tree empty requireExplicit False: OK */
610 case 2:
611 return 1;
612
613 /* Some internal error */
614 case 0:
615 return 0;
616
617 /* Tree empty requireExplicit True: Error */
618
619 case 6:
620 *pexplicit_policy = 1;
621 return -2;
622
623 /* Tree OK requireExplicit True: OK and continue */
624 case 5:
625 *pexplicit_policy = 1;
626 break;
627
628 /* Tree OK: continue */
629
630 case 1:
631 if (!tree)
632 /*
633 * tree_init() returns success and a null tree
634 * if it's just looking at a trust anchor.
635 * I'm not sure that returning success here is
636 * correct, but I'm sure that reporting this
637 * as an internal error which our caller
638 * interprets as a malloc failure is wrong.
639 */
640 return 1;
641 break;
642 }
643
644 if (!tree) goto error;
645 ret = tree_evaluate(tree);
646
647 if (ret <= 0)
648 goto error;
649
650 /* Return value 2 means tree empty */
651 if (ret == 2)
652 {
653 X509_policy_tree_free(tree);
654 if (*pexplicit_policy)
655 return -2;
656 else
657 return 1;
658 }
659
660 /* Tree is not empty: continue */
661
662 ret = tree_calculate_authority_set(tree, &auth_nodes);
663
664 if (!ret)
665 goto error;
666
667 if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
668 goto error;
669
670 if (ret == 2)
671 sk_X509_POLICY_NODE_free(auth_nodes);
672
673 if (tree)
674 *ptree = tree;
675
676 if (*pexplicit_policy)
677 {
678 nodes = X509_policy_tree_get0_user_policies(tree);
679 if (sk_X509_POLICY_NODE_num(nodes) <= 0)
680 return -2;
681 }
682
683 return 1;
684
685 error:
686
687 X509_policy_tree_free(tree);
688
689 return 0;
690
691 }
692
diff --git a/src/lib/libcrypto/x509v3/v3_ncons.c b/src/lib/libcrypto/x509v3/v3_ncons.c
new file mode 100644
index 0000000000..42e7f5a879
--- /dev/null
+++ b/src/lib/libcrypto/x509v3/v3_ncons.c
@@ -0,0 +1,220 @@
1/* v3_ncons.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59
60#include <stdio.h>
61#include "cryptlib.h"
62#include <openssl/asn1t.h>
63#include <openssl/conf.h>
64#include <openssl/x509v3.h>
65
66static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method,
67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
68static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method,
69 void *a, BIO *bp, int ind);
70static int do_i2r_name_constraints(X509V3_EXT_METHOD *method,
71 STACK_OF(GENERAL_SUBTREE) *trees,
72 BIO *bp, int ind, char *name);
73static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
74
75const X509V3_EXT_METHOD v3_name_constraints = {
76 NID_name_constraints, 0,
77 ASN1_ITEM_ref(NAME_CONSTRAINTS),
78 0,0,0,0,
79 0,0,
80 0, v2i_NAME_CONSTRAINTS,
81 i2r_NAME_CONSTRAINTS,0,
82 NULL
83};
84
85ASN1_SEQUENCE(GENERAL_SUBTREE) = {
86 ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME),
87 ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0),
88 ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1)
89} ASN1_SEQUENCE_END(GENERAL_SUBTREE)
90
91ASN1_SEQUENCE(NAME_CONSTRAINTS) = {
92 ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees,
93 GENERAL_SUBTREE, 0),
94 ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees,
95 GENERAL_SUBTREE, 1),
96} ASN1_SEQUENCE_END(NAME_CONSTRAINTS)
97
98
99IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
100IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
101
102static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method,
103 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
104 {
105 int i;
106 CONF_VALUE tval, *val;
107 STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
108 NAME_CONSTRAINTS *ncons = NULL;
109 GENERAL_SUBTREE *sub = NULL;
110 ncons = NAME_CONSTRAINTS_new();
111 if (!ncons)
112 goto memerr;
113 for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
114 {
115 val = sk_CONF_VALUE_value(nval, i);
116 if (!strncmp(val->name, "permitted", 9) && val->name[9])
117 {
118 ptree = &ncons->permittedSubtrees;
119 tval.name = val->name + 10;
120 }
121 else if (!strncmp(val->name, "excluded", 8) && val->name[8])
122 {
123 ptree = &ncons->excludedSubtrees;
124 tval.name = val->name + 9;
125 }
126 else
127 {
128 X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX);
129 goto err;
130 }
131 tval.value = val->value;
132 sub = GENERAL_SUBTREE_new();
133 if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
134 goto err;
135 if (!*ptree)
136 *ptree = sk_GENERAL_SUBTREE_new_null();
137 if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
138 goto memerr;
139 sub = NULL;
140 }
141
142 return ncons;
143
144 memerr:
145 X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
146 err:
147 if (ncons)
148 NAME_CONSTRAINTS_free(ncons);
149 if (sub)
150 GENERAL_SUBTREE_free(sub);
151
152 return NULL;
153 }
154
155
156
157
158static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method,
159 void *a, BIO *bp, int ind)
160 {
161 NAME_CONSTRAINTS *ncons = a;
162 do_i2r_name_constraints(method, ncons->permittedSubtrees,
163 bp, ind, "Permitted");
164 do_i2r_name_constraints(method, ncons->excludedSubtrees,
165 bp, ind, "Excluded");
166 return 1;
167 }
168
169static int do_i2r_name_constraints(X509V3_EXT_METHOD *method,
170 STACK_OF(GENERAL_SUBTREE) *trees,
171 BIO *bp, int ind, char *name)
172 {
173 GENERAL_SUBTREE *tree;
174 int i;
175 if (sk_GENERAL_SUBTREE_num(trees) > 0)
176 BIO_printf(bp, "%*s%s:\n", ind, "", name);
177 for(i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++)
178 {
179 tree = sk_GENERAL_SUBTREE_value(trees, i);
180 BIO_printf(bp, "%*s", ind + 2, "");
181 if (tree->base->type == GEN_IPADD)
182 print_nc_ipadd(bp, tree->base->d.ip);
183 else
184 GENERAL_NAME_print(bp, tree->base);
185 tree = sk_GENERAL_SUBTREE_value(trees, i);
186 BIO_puts(bp, "\n");
187 }
188 return 1;
189 }
190
191static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
192 {
193 int i, len;
194 unsigned char *p;
195 p = ip->data;
196 len = ip->length;
197 BIO_puts(bp, "IP:");
198 if(len == 8)
199 {
200 BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
201 p[0], p[1], p[2], p[3],
202 p[4], p[5], p[6], p[7]);
203 }
204 else if(len == 32)
205 {
206 for (i = 0; i < 16; i++)
207 {
208 BIO_printf(bp, "%X", p[0] << 8 | p[1]);
209 p += 2;
210 if (i == 7)
211 BIO_puts(bp, "/");
212 else if (i != 15)
213 BIO_puts(bp, ":");
214 }
215 }
216 else
217 BIO_printf(bp, "IP Address:<invalid>");
218 return 1;
219 }
220
diff --git a/src/lib/libcrypto/x509v3/v3_pci.c b/src/lib/libcrypto/x509v3/v3_pci.c
index b32d968619..601211f416 100644
--- a/src/lib/libcrypto/x509v3/v3_pci.c
+++ b/src/lib/libcrypto/x509v3/v3_pci.c
@@ -44,7 +44,7 @@ static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
44static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, 44static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
45 X509V3_CTX *ctx, char *str); 45 X509V3_CTX *ctx, char *str);
46 46
47X509V3_EXT_METHOD v3_pci = 47const X509V3_EXT_METHOD v3_pci =
48 { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), 48 { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
49 0,0,0,0, 49 0,0,0,0,
50 0,0, 50 0,0,
@@ -82,13 +82,13 @@ static int process_pci_value(CONF_VALUE *val,
82 { 82 {
83 if (*language) 83 if (*language)
84 { 84 {
85 X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED); 85 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED);
86 X509V3_conf_err(val); 86 X509V3_conf_err(val);
87 return 0; 87 return 0;
88 } 88 }
89 if (!(*language = OBJ_txt2obj(val->value, 0))) 89 if (!(*language = OBJ_txt2obj(val->value, 0)))
90 { 90 {
91 X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_OBJECT_IDENTIFIER); 91 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INVALID_OBJECT_IDENTIFIER);
92 X509V3_conf_err(val); 92 X509V3_conf_err(val);
93 return 0; 93 return 0;
94 } 94 }
@@ -97,13 +97,13 @@ static int process_pci_value(CONF_VALUE *val,
97 { 97 {
98 if (*pathlen) 98 if (*pathlen)
99 { 99 {
100 X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED); 100 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED);
101 X509V3_conf_err(val); 101 X509V3_conf_err(val);
102 return 0; 102 return 0;
103 } 103 }
104 if (!X509V3_get_value_int(val, pathlen)) 104 if (!X509V3_get_value_int(val, pathlen))
105 { 105 {
106 X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_PATH_LENGTH); 106 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH);
107 X509V3_conf_err(val); 107 X509V3_conf_err(val);
108 return 0; 108 return 0;
109 } 109 }
@@ -117,7 +117,7 @@ static int process_pci_value(CONF_VALUE *val,
117 *policy = ASN1_OCTET_STRING_new(); 117 *policy = ASN1_OCTET_STRING_new();
118 if (!*policy) 118 if (!*policy)
119 { 119 {
120 X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); 120 X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
121 X509V3_conf_err(val); 121 X509V3_conf_err(val);
122 return 0; 122 return 0;
123 } 123 }
@@ -148,7 +148,7 @@ static int process_pci_value(CONF_VALUE *val,
148 BIO *b = BIO_new_file(val->value + 5, "r"); 148 BIO *b = BIO_new_file(val->value + 5, "r");
149 if (!b) 149 if (!b)
150 { 150 {
151 X509V3err(X509V3_F_R2I_PCI,ERR_R_BIO_LIB); 151 X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
152 X509V3_conf_err(val); 152 X509V3_conf_err(val);
153 goto err; 153 goto err;
154 } 154 }
@@ -172,7 +172,7 @@ static int process_pci_value(CONF_VALUE *val,
172 172
173 if (n < 0) 173 if (n < 0)
174 { 174 {
175 X509V3err(X509V3_F_R2I_PCI,ERR_R_BIO_LIB); 175 X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
176 X509V3_conf_err(val); 176 X509V3_conf_err(val);
177 goto err; 177 goto err;
178 } 178 }
@@ -193,13 +193,13 @@ static int process_pci_value(CONF_VALUE *val,
193 } 193 }
194 else 194 else
195 { 195 {
196 X509V3err(X509V3_F_R2I_PCI,X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); 196 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
197 X509V3_conf_err(val); 197 X509V3_conf_err(val);
198 goto err; 198 goto err;
199 } 199 }
200 if (!tmp_data) 200 if (!tmp_data)
201 { 201 {
202 X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); 202 X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
203 X509V3_conf_err(val); 203 X509V3_conf_err(val);
204 goto err; 204 goto err;
205 } 205 }
@@ -286,12 +286,6 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
286 X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); 286 X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE);
287 goto err; 287 goto err;
288 } 288 }
289 pci->proxyPolicy = PROXY_POLICY_new();
290 if (!pci->proxyPolicy)
291 {
292 X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE);
293 goto err;
294 }
295 289
296 pci->proxyPolicy->policyLanguage = language; language = NULL; 290 pci->proxyPolicy->policyLanguage = language; language = NULL;
297 pci->proxyPolicy->policy = policy; policy = NULL; 291 pci->proxyPolicy->policy = policy; policy = NULL;
@@ -301,11 +295,6 @@ err:
301 if (language) { ASN1_OBJECT_free(language); language = NULL; } 295 if (language) { ASN1_OBJECT_free(language); language = NULL; }
302 if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; } 296 if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; }
303 if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; } 297 if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; }
304 if (pci && pci->proxyPolicy)
305 {
306 PROXY_POLICY_free(pci->proxyPolicy);
307 pci->proxyPolicy = NULL;
308 }
309 if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; } 298 if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; }
310end: 299end:
311 sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); 300 sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
diff --git a/src/lib/libcrypto/x509v3/v3_pcons.c b/src/lib/libcrypto/x509v3/v3_pcons.c
new file mode 100644
index 0000000000..13248c2ada
--- /dev/null
+++ b/src/lib/libcrypto/x509v3/v3_pcons.c
@@ -0,0 +1,136 @@
1/* v3_pcons.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59
60#include <stdio.h>
61#include "cryptlib.h"
62#include <openssl/asn1.h>
63#include <openssl/asn1t.h>
64#include <openssl/conf.h>
65#include <openssl/x509v3.h>
66
67static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method,
68 void *bcons, STACK_OF(CONF_VALUE) *extlist);
69static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method,
70 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
71
72const X509V3_EXT_METHOD v3_policy_constraints = {
73NID_policy_constraints, 0,
74ASN1_ITEM_ref(POLICY_CONSTRAINTS),
750,0,0,0,
760,0,
77i2v_POLICY_CONSTRAINTS,
78v2i_POLICY_CONSTRAINTS,
79NULL,NULL,
80NULL
81};
82
83ASN1_SEQUENCE(POLICY_CONSTRAINTS) = {
84 ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0),
85 ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1)
86} ASN1_SEQUENCE_END(POLICY_CONSTRAINTS)
87
88IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
89
90
91static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method,
92 void *a, STACK_OF(CONF_VALUE) *extlist)
93{
94 POLICY_CONSTRAINTS *pcons = a;
95 X509V3_add_value_int("Require Explicit Policy",
96 pcons->requireExplicitPolicy, &extlist);
97 X509V3_add_value_int("Inhibit Policy Mapping",
98 pcons->inhibitPolicyMapping, &extlist);
99 return extlist;
100}
101
102static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method,
103 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values)
104{
105 POLICY_CONSTRAINTS *pcons=NULL;
106 CONF_VALUE *val;
107 int i;
108 if(!(pcons = POLICY_CONSTRAINTS_new())) {
109 X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
110 return NULL;
111 }
112 for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
113 val = sk_CONF_VALUE_value(values, i);
114 if(!strcmp(val->name, "requireExplicitPolicy")) {
115 if(!X509V3_get_value_int(val,
116 &pcons->requireExplicitPolicy)) goto err;
117 } else if(!strcmp(val->name, "inhibitPolicyMapping")) {
118 if(!X509V3_get_value_int(val,
119 &pcons->inhibitPolicyMapping)) goto err;
120 } else {
121 X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME);
122 X509V3_conf_err(val);
123 goto err;
124 }
125 }
126 if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
127 X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_ILLEGAL_EMPTY_EXTENSION);
128 goto err;
129 }
130
131 return pcons;
132 err:
133 POLICY_CONSTRAINTS_free(pcons);
134 return NULL;
135}
136
diff --git a/src/lib/libcrypto/x509v3/v3_pmaps.c b/src/lib/libcrypto/x509v3/v3_pmaps.c
new file mode 100644
index 0000000000..626303264f
--- /dev/null
+++ b/src/lib/libcrypto/x509v3/v3_pmaps.c
@@ -0,0 +1,153 @@
1/* v3_pmaps.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59
60#include <stdio.h>
61#include "cryptlib.h"
62#include <openssl/asn1t.h>
63#include <openssl/conf.h>
64#include <openssl/x509v3.h>
65
66static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method,
67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
68static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method,
69 void *pmps, STACK_OF(CONF_VALUE) *extlist);
70
71const X509V3_EXT_METHOD v3_policy_mappings = {
72 NID_policy_mappings, 0,
73 ASN1_ITEM_ref(POLICY_MAPPINGS),
74 0,0,0,0,
75 0,0,
76 i2v_POLICY_MAPPINGS,
77 v2i_POLICY_MAPPINGS,
78 0,0,
79 NULL
80};
81
82ASN1_SEQUENCE(POLICY_MAPPING) = {
83 ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT),
84 ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT)
85} ASN1_SEQUENCE_END(POLICY_MAPPING)
86
87ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) =
88 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS,
89 POLICY_MAPPING)
90ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS)
91
92IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
93
94
95static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method,
96 void *a, STACK_OF(CONF_VALUE) *ext_list)
97{
98 POLICY_MAPPINGS *pmaps = a;
99 POLICY_MAPPING *pmap;
100 int i;
101 char obj_tmp1[80];
102 char obj_tmp2[80];
103 for(i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
104 pmap = sk_POLICY_MAPPING_value(pmaps, i);
105 i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy);
106 i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy);
107 X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list);
108 }
109 return ext_list;
110}
111
112static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method,
113 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
114{
115 POLICY_MAPPINGS *pmaps;
116 POLICY_MAPPING *pmap;
117 ASN1_OBJECT *obj1, *obj2;
118 CONF_VALUE *val;
119 int i;
120
121 if(!(pmaps = sk_POLICY_MAPPING_new_null())) {
122 X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,ERR_R_MALLOC_FAILURE);
123 return NULL;
124 }
125
126 for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
127 val = sk_CONF_VALUE_value(nval, i);
128 if(!val->value || !val->name) {
129 sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
130 X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,X509V3_R_INVALID_OBJECT_IDENTIFIER);
131 X509V3_conf_err(val);
132 return NULL;
133 }
134 obj1 = OBJ_txt2obj(val->name, 0);
135 obj2 = OBJ_txt2obj(val->value, 0);
136 if(!obj1 || !obj2) {
137 sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
138 X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,X509V3_R_INVALID_OBJECT_IDENTIFIER);
139 X509V3_conf_err(val);
140 return NULL;
141 }
142 pmap = POLICY_MAPPING_new();
143 if (!pmap) {
144 sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
145 X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,ERR_R_MALLOC_FAILURE);
146 return NULL;
147 }
148 pmap->issuerDomainPolicy = obj1;
149 pmap->subjectDomainPolicy = obj2;
150 sk_POLICY_MAPPING_push(pmaps, pmap);
151 }
152 return pmaps;
153}