summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509v3
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/x509v3')
-rw-r--r--src/lib/libcrypto/x509v3/pcy_cache.c1
-rw-r--r--src/lib/libcrypto/x509v3/pcy_int.h25
-rw-r--r--src/lib/libcrypto/x509v3/pcy_map.c56
-rw-r--r--src/lib/libcrypto/x509v3/pcy_node.c43
-rw-r--r--src/lib/libcrypto/x509v3/v3_ncons.c312
-rw-r--r--src/lib/libcrypto/x509v3/v3_pci.c32
-rw-r--r--src/lib/libcrypto/x509v3/v3_pcons.c20
-rw-r--r--src/lib/libcrypto/x509v3/v3_pmaps.c18
8 files changed, 399 insertions, 108 deletions
diff --git a/src/lib/libcrypto/x509v3/pcy_cache.c b/src/lib/libcrypto/x509v3/pcy_cache.c
index 1030931b71..172b7e7ee4 100644
--- a/src/lib/libcrypto/x509v3/pcy_cache.c
+++ b/src/lib/libcrypto/x509v3/pcy_cache.c
@@ -139,7 +139,6 @@ static int policy_cache_new(X509 *x)
139 return 0; 139 return 0;
140 cache->anyPolicy = NULL; 140 cache->anyPolicy = NULL;
141 cache->data = NULL; 141 cache->data = NULL;
142 cache->maps = NULL;
143 cache->any_skip = -1; 142 cache->any_skip = -1;
144 cache->explicit_skip = -1; 143 cache->explicit_skip = -1;
145 cache->map_skip = -1; 144 cache->map_skip = -1;
diff --git a/src/lib/libcrypto/x509v3/pcy_int.h b/src/lib/libcrypto/x509v3/pcy_int.h
index 3780de4fcd..ccff92846e 100644
--- a/src/lib/libcrypto/x509v3/pcy_int.h
+++ b/src/lib/libcrypto/x509v3/pcy_int.h
@@ -56,12 +56,10 @@
56 * 56 *
57 */ 57 */
58 58
59DECLARE_STACK_OF(X509_POLICY_DATA)
60DECLARE_STACK_OF(X509_POLICY_REF)
61DECLARE_STACK_OF(X509_POLICY_NODE)
62 59
63typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; 60typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
64typedef struct X509_POLICY_REF_st X509_POLICY_REF; 61
62DECLARE_STACK_OF(X509_POLICY_DATA)
65 63
66/* Internal structures */ 64/* Internal structures */
67 65
@@ -110,16 +108,6 @@ struct X509_POLICY_DATA_st
110 108
111#define POLICY_DATA_FLAG_CRITICAL 0x10 109#define POLICY_DATA_FLAG_CRITICAL 0x10
112 110
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 */ 111/* This structure is cached with a certificate */
124 112
125struct X509_POLICY_CACHE_st { 113struct X509_POLICY_CACHE_st {
@@ -127,8 +115,6 @@ struct X509_POLICY_CACHE_st {
127 X509_POLICY_DATA *anyPolicy; 115 X509_POLICY_DATA *anyPolicy;
128 /* other policy data */ 116 /* other policy data */
129 STACK_OF(X509_POLICY_DATA) *data; 117 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. */ 118 /* If InhibitAnyPolicy present this is its value or -1 if absent. */
133 long any_skip; 119 long any_skip;
134 /* If policyConstraints and requireExplicitPolicy present this is its 120 /* If policyConstraints and requireExplicitPolicy present this is its
@@ -193,7 +179,7 @@ struct X509_POLICY_TREE_st
193 179
194/* Internal functions */ 180/* Internal functions */
195 181
196X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, 182X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
197 int crit); 183 int crit);
198void policy_data_free(X509_POLICY_DATA *data); 184void policy_data_free(X509_POLICY_DATA *data);
199 185
@@ -209,15 +195,18 @@ void policy_cache_init(void);
209void policy_cache_free(X509_POLICY_CACHE *cache); 195void policy_cache_free(X509_POLICY_CACHE *cache);
210 196
211X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, 197X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
198 const X509_POLICY_NODE *parent,
212 const ASN1_OBJECT *id); 199 const ASN1_OBJECT *id);
213 200
214X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, 201X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
215 const ASN1_OBJECT *id); 202 const ASN1_OBJECT *id);
216 203
217X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, 204X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
218 X509_POLICY_DATA *data, 205 const X509_POLICY_DATA *data,
219 X509_POLICY_NODE *parent, 206 X509_POLICY_NODE *parent,
220 X509_POLICY_TREE *tree); 207 X509_POLICY_TREE *tree);
221void policy_node_free(X509_POLICY_NODE *node); 208void policy_node_free(X509_POLICY_NODE *node);
209int policy_node_match(const X509_POLICY_LEVEL *lvl,
210 const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
222 211
223const X509_POLICY_CACHE *policy_cache_set(X509 *x); 212const X509_POLICY_CACHE *policy_cache_set(X509 *x);
diff --git a/src/lib/libcrypto/x509v3/pcy_map.c b/src/lib/libcrypto/x509v3/pcy_map.c
index f28796e6d4..21163b529d 100644
--- a/src/lib/libcrypto/x509v3/pcy_map.c
+++ b/src/lib/libcrypto/x509v3/pcy_map.c
@@ -62,31 +62,6 @@
62 62
63#include "pcy_int.h" 63#include "pcy_int.h"
64 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. 65/* Set policy mapping entries in cache.
91 * Note: this modifies the passed POLICY_MAPPINGS structure 66 * Note: this modifies the passed POLICY_MAPPINGS structure
92 */ 67 */
@@ -94,7 +69,6 @@ static X509_POLICY_REF *policy_map_find(X509_POLICY_CACHE *cache, ASN1_OBJECT *i
94int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) 69int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
95 { 70 {
96 POLICY_MAPPING *map; 71 POLICY_MAPPING *map;
97 X509_POLICY_REF *ref = NULL;
98 X509_POLICY_DATA *data; 72 X509_POLICY_DATA *data;
99 X509_POLICY_CACHE *cache = x->policy_cache; 73 X509_POLICY_CACHE *cache = x->policy_cache;
100 int i; 74 int i;
@@ -104,7 +78,6 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
104 ret = -1; 78 ret = -1;
105 goto bad_mapping; 79 goto bad_mapping;
106 } 80 }
107 cache->maps = sk_X509_POLICY_REF_new(ref_cmp);
108 for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) 81 for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++)
109 { 82 {
110 map = sk_POLICY_MAPPING_value(maps, i); 83 map = sk_POLICY_MAPPING_value(maps, i);
@@ -116,13 +89,6 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
116 goto bad_mapping; 89 goto bad_mapping;
117 } 90 }
118 91
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 */ 92 /* Attempt to find matching policy data */
127 data = policy_cache_find_data(cache, map->issuerDomainPolicy); 93 data = policy_cache_find_data(cache, map->issuerDomainPolicy);
128 /* If we don't have anyPolicy can't map */ 94 /* If we don't have anyPolicy can't map */
@@ -138,7 +104,7 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
138 if (!data) 104 if (!data)
139 goto bad_mapping; 105 goto bad_mapping;
140 data->qualifier_set = cache->anyPolicy->qualifier_set; 106 data->qualifier_set = cache->anyPolicy->qualifier_set;
141 map->issuerDomainPolicy = NULL; 107 /*map->issuerDomainPolicy = NULL;*/
142 data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; 108 data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
143 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; 109 data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
144 if (!sk_X509_POLICY_DATA_push(cache->data, data)) 110 if (!sk_X509_POLICY_DATA_push(cache->data, data))
@@ -149,23 +115,10 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
149 } 115 }
150 else 116 else
151 data->flags |= POLICY_DATA_FLAG_MAPPED; 117 data->flags |= POLICY_DATA_FLAG_MAPPED;
152
153 if (!sk_ASN1_OBJECT_push(data->expected_policy_set, 118 if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
154 map->subjectDomainPolicy)) 119 map->subjectDomainPolicy))
155 goto bad_mapping; 120 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; 121 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 122
170 } 123 }
171 124
@@ -173,13 +126,6 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
173 bad_mapping: 126 bad_mapping:
174 if (ret == -1) 127 if (ret == -1)
175 x->ex_flags |= EXFLAG_INVALID_POLICY; 128 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); 129 sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
184 return ret; 130 return ret;
185 131
diff --git a/src/lib/libcrypto/x509v3/pcy_node.c b/src/lib/libcrypto/x509v3/pcy_node.c
index 6587cb05ab..bd1e7f1ae8 100644
--- a/src/lib/libcrypto/x509v3/pcy_node.c
+++ b/src/lib/libcrypto/x509v3/pcy_node.c
@@ -92,13 +92,25 @@ X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
92 } 92 }
93 93
94X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, 94X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
95 const X509_POLICY_NODE *parent,
95 const ASN1_OBJECT *id) 96 const ASN1_OBJECT *id)
96 { 97 {
97 return tree_find_sk(level->nodes, id); 98 X509_POLICY_NODE *node;
99 int i;
100 for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++)
101 {
102 node = sk_X509_POLICY_NODE_value(level->nodes, i);
103 if (node->parent == parent)
104 {
105 if (!OBJ_cmp(node->data->valid_policy, id))
106 return node;
107 }
108 }
109 return NULL;
98 } 110 }
99 111
100X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, 112X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
101 X509_POLICY_DATA *data, 113 const X509_POLICY_DATA *data,
102 X509_POLICY_NODE *parent, 114 X509_POLICY_NODE *parent,
103 X509_POLICY_TREE *tree) 115 X509_POLICY_TREE *tree)
104 { 116 {
@@ -155,4 +167,31 @@ void policy_node_free(X509_POLICY_NODE *node)
155 OPENSSL_free(node); 167 OPENSSL_free(node);
156 } 168 }
157 169
170/* See if a policy node matches a policy OID. If mapping enabled look through
171 * expected policy set otherwise just valid policy.
172 */
173
174int policy_node_match(const X509_POLICY_LEVEL *lvl,
175 const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
176 {
177 int i;
178 ASN1_OBJECT *policy_oid;
179 const X509_POLICY_DATA *x = node->data;
180
181 if ( (lvl->flags & X509_V_FLAG_INHIBIT_MAP)
182 || !(x->flags & POLICY_DATA_FLAG_MAP_MASK))
183 {
184 if (!OBJ_cmp(x->valid_policy, oid))
185 return 1;
186 return 0;
187 }
188
189 for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++)
190 {
191 policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
192 if (!OBJ_cmp(policy_oid, oid))
193 return 1;
194 }
195 return 0;
158 196
197 }
diff --git a/src/lib/libcrypto/x509v3/v3_ncons.c b/src/lib/libcrypto/x509v3/v3_ncons.c
index 4e706be3e1..689df46acd 100644
--- a/src/lib/libcrypto/x509v3/v3_ncons.c
+++ b/src/lib/libcrypto/x509v3/v3_ncons.c
@@ -63,15 +63,22 @@
63#include <openssl/conf.h> 63#include <openssl/conf.h>
64#include <openssl/x509v3.h> 64#include <openssl/x509v3.h>
65 65
66static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, 66static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); 67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
68static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, 68static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
69 void *a, BIO *bp, int ind); 69 void *a, BIO *bp, int ind);
70static int do_i2r_name_constraints(X509V3_EXT_METHOD *method, 70static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
71 STACK_OF(GENERAL_SUBTREE) *trees, 71 STACK_OF(GENERAL_SUBTREE) *trees,
72 BIO *bp, int ind, char *name); 72 BIO *bp, int ind, char *name);
73static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); 73static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
74 74
75static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
76static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen);
77static int nc_dn(X509_NAME *sub, X509_NAME *nm);
78static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns);
79static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
80static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
81
75const X509V3_EXT_METHOD v3_name_constraints = { 82const X509V3_EXT_METHOD v3_name_constraints = {
76 NID_name_constraints, 0, 83 NID_name_constraints, 0,
77 ASN1_ITEM_ref(NAME_CONSTRAINTS), 84 ASN1_ITEM_ref(NAME_CONSTRAINTS),
@@ -99,8 +106,8 @@ ASN1_SEQUENCE(NAME_CONSTRAINTS) = {
99IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) 106IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
100IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) 107IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
101 108
102static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, 109static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
103 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 110 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
104 { 111 {
105 int i; 112 int i;
106 CONF_VALUE tval, *val; 113 CONF_VALUE tval, *val;
@@ -155,8 +162,8 @@ static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method,
155 162
156 163
157 164
158static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, 165static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
159 void *a, BIO *bp, int ind) 166 BIO *bp, int ind)
160 { 167 {
161 NAME_CONSTRAINTS *ncons = a; 168 NAME_CONSTRAINTS *ncons = a;
162 do_i2r_name_constraints(method, ncons->permittedSubtrees, 169 do_i2r_name_constraints(method, ncons->permittedSubtrees,
@@ -166,9 +173,9 @@ static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method,
166 return 1; 173 return 1;
167 } 174 }
168 175
169static int do_i2r_name_constraints(X509V3_EXT_METHOD *method, 176static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
170 STACK_OF(GENERAL_SUBTREE) *trees, 177 STACK_OF(GENERAL_SUBTREE) *trees,
171 BIO *bp, int ind, char *name) 178 BIO *bp, int ind, char *name)
172 { 179 {
173 GENERAL_SUBTREE *tree; 180 GENERAL_SUBTREE *tree;
174 int i; 181 int i;
@@ -218,3 +225,282 @@ static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
218 return 1; 225 return 1;
219 } 226 }
220 227
228/* Check a certificate conforms to a specified set of constraints.
229 * Return values:
230 * X509_V_OK: All constraints obeyed.
231 * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation.
232 * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation.
233 * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type.
234 * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type.
235 * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax.
236 * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name
237
238 */
239
240int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
241 {
242 int r, i;
243 X509_NAME *nm;
244
245 nm = X509_get_subject_name(x);
246
247 if (X509_NAME_entry_count(nm) > 0)
248 {
249 GENERAL_NAME gntmp;
250 gntmp.type = GEN_DIRNAME;
251 gntmp.d.directoryName = nm;
252
253 r = nc_match(&gntmp, nc);
254
255 if (r != X509_V_OK)
256 return r;
257
258 gntmp.type = GEN_EMAIL;
259
260
261 /* Process any email address attributes in subject name */
262
263 for (i = -1;;)
264 {
265 X509_NAME_ENTRY *ne;
266 i = X509_NAME_get_index_by_NID(nm,
267 NID_pkcs9_emailAddress,
268 i);
269 if (i == -1)
270 break;
271 ne = X509_NAME_get_entry(nm, i);
272 gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
273 if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
274 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
275
276 r = nc_match(&gntmp, nc);
277
278 if (r != X509_V_OK)
279 return r;
280 }
281
282 }
283
284 for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++)
285 {
286 GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i);
287 r = nc_match(gen, nc);
288 if (r != X509_V_OK)
289 return r;
290 }
291
292 return X509_V_OK;
293
294 }
295
296static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
297 {
298 GENERAL_SUBTREE *sub;
299 int i, r, match = 0;
300
301 /* Permitted subtrees: if any subtrees exist of matching the type
302 * at least one subtree must match.
303 */
304
305 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++)
306 {
307 sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
308 if (gen->type != sub->base->type)
309 continue;
310 if (sub->minimum || sub->maximum)
311 return X509_V_ERR_SUBTREE_MINMAX;
312 /* If we already have a match don't bother trying any more */
313 if (match == 2)
314 continue;
315 if (match == 0)
316 match = 1;
317 r = nc_match_single(gen, sub->base);
318 if (r == X509_V_OK)
319 match = 2;
320 else if (r != X509_V_ERR_PERMITTED_VIOLATION)
321 return r;
322 }
323
324 if (match == 1)
325 return X509_V_ERR_PERMITTED_VIOLATION;
326
327 /* Excluded subtrees: must not match any of these */
328
329 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++)
330 {
331 sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
332 if (gen->type != sub->base->type)
333 continue;
334 if (sub->minimum || sub->maximum)
335 return X509_V_ERR_SUBTREE_MINMAX;
336
337 r = nc_match_single(gen, sub->base);
338 if (r == X509_V_OK)
339 return X509_V_ERR_EXCLUDED_VIOLATION;
340 else if (r != X509_V_ERR_PERMITTED_VIOLATION)
341 return r;
342
343 }
344
345 return X509_V_OK;
346
347 }
348
349static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
350 {
351 switch(base->type)
352 {
353 case GEN_DIRNAME:
354 return nc_dn(gen->d.directoryName, base->d.directoryName);
355
356 case GEN_DNS:
357 return nc_dns(gen->d.dNSName, base->d.dNSName);
358
359 case GEN_EMAIL:
360 return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
361
362 case GEN_URI:
363 return nc_uri(gen->d.uniformResourceIdentifier,
364 base->d.uniformResourceIdentifier);
365
366 default:
367 return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
368 }
369
370 }
371
372/* directoryName name constraint matching.
373 * The canonical encoding of X509_NAME makes this comparison easy. It is
374 * matched if the subtree is a subset of the name.
375 */
376
377static int nc_dn(X509_NAME *nm, X509_NAME *base)
378 {
379 /* Ensure canonical encodings are up to date. */
380 if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
381 return X509_V_ERR_OUT_OF_MEM;
382 if (base->modified && i2d_X509_NAME(base, NULL) < 0)
383 return X509_V_ERR_OUT_OF_MEM;
384 if (base->canon_enclen > nm->canon_enclen)
385 return X509_V_ERR_PERMITTED_VIOLATION;
386 if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
387 return X509_V_ERR_PERMITTED_VIOLATION;
388 return X509_V_OK;
389 }
390
391static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
392 {
393 char *baseptr = (char *)base->data;
394 char *dnsptr = (char *)dns->data;
395 /* Empty matches everything */
396 if (!*baseptr)
397 return X509_V_OK;
398 /* Otherwise can add zero or more components on the left so
399 * compare RHS and if dns is longer and expect '.' as preceding
400 * character.
401 */
402 if (dns->length > base->length)
403 {
404 dnsptr += dns->length - base->length;
405 if (dnsptr[-1] != '.')
406 return X509_V_ERR_PERMITTED_VIOLATION;
407 }
408
409 if (strcasecmp(baseptr, dnsptr))
410 return X509_V_ERR_PERMITTED_VIOLATION;
411
412 return X509_V_OK;
413
414 }
415
416static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
417 {
418 const char *baseptr = (char *)base->data;
419 const char *emlptr = (char *)eml->data;
420
421 const char *baseat = strchr(baseptr, '@');
422 const char *emlat = strchr(emlptr, '@');
423 if (!emlat)
424 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
425 /* Special case: inital '.' is RHS match */
426 if (!baseat && (*baseptr == '.'))
427 {
428 if (eml->length > base->length)
429 {
430 emlptr += eml->length - base->length;
431 if (!strcasecmp(baseptr, emlptr))
432 return X509_V_OK;
433 }
434 return X509_V_ERR_PERMITTED_VIOLATION;
435 }
436
437 /* If we have anything before '@' match local part */
438
439 if (baseat)
440 {
441 if (baseat != baseptr)
442 {
443 if ((baseat - baseptr) != (emlat - emlptr))
444 return X509_V_ERR_PERMITTED_VIOLATION;
445 /* Case sensitive match of local part */
446 if (strncmp(baseptr, emlptr, emlat - emlptr))
447 return X509_V_ERR_PERMITTED_VIOLATION;
448 }
449 /* Position base after '@' */
450 baseptr = baseat + 1;
451 }
452 emlptr = emlat + 1;
453 /* Just have hostname left to match: case insensitive */
454 if (strcasecmp(baseptr, emlptr))
455 return X509_V_ERR_PERMITTED_VIOLATION;
456
457 return X509_V_OK;
458
459 }
460
461static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
462 {
463 const char *baseptr = (char *)base->data;
464 const char *hostptr = (char *)uri->data;
465 const char *p = strchr(hostptr, ':');
466 int hostlen;
467 /* Check for foo:// and skip past it */
468 if (!p || (p[1] != '/') || (p[2] != '/'))
469 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
470 hostptr = p + 3;
471
472 /* Determine length of hostname part of URI */
473
474 /* Look for a port indicator as end of hostname first */
475
476 p = strchr(hostptr, ':');
477 /* Otherwise look for trailing slash */
478 if (!p)
479 p = strchr(hostptr, '/');
480
481 if (!p)
482 hostlen = strlen(hostptr);
483 else
484 hostlen = p - hostptr;
485
486 if (hostlen == 0)
487 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
488
489 /* Special case: inital '.' is RHS match */
490 if (*baseptr == '.')
491 {
492 if (hostlen > base->length)
493 {
494 p = hostptr + hostlen - base->length;
495 if (!strncasecmp(p, baseptr, base->length))
496 return X509_V_OK;
497 }
498 return X509_V_ERR_PERMITTED_VIOLATION;
499 }
500
501 if ((base->length != (int)hostlen) || strncasecmp(hostptr, baseptr, hostlen))
502 return X509_V_ERR_PERMITTED_VIOLATION;
503
504 return X509_V_OK;
505
506 }
diff --git a/src/lib/libcrypto/x509v3/v3_pci.c b/src/lib/libcrypto/x509v3/v3_pci.c
index 601211f416..0dcfa004fe 100644
--- a/src/lib/libcrypto/x509v3/v3_pci.c
+++ b/src/lib/libcrypto/x509v3/v3_pci.c
@@ -82,7 +82,7 @@ static int process_pci_value(CONF_VALUE *val,
82 { 82 {
83 if (*language) 83 if (*language)
84 { 84 {
85 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED); 85 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
86 X509V3_conf_err(val); 86 X509V3_conf_err(val);
87 return 0; 87 return 0;
88 } 88 }
@@ -97,7 +97,7 @@ static int process_pci_value(CONF_VALUE *val,
97 { 97 {
98 if (*pathlen) 98 if (*pathlen)
99 { 99 {
100 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED); 100 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
101 X509V3_conf_err(val); 101 X509V3_conf_err(val);
102 return 0; 102 return 0;
103 } 103 }
@@ -128,7 +128,12 @@ static int process_pci_value(CONF_VALUE *val,
128 unsigned char *tmp_data2 = 128 unsigned char *tmp_data2 =
129 string_to_hex(val->value + 4, &val_len); 129 string_to_hex(val->value + 4, &val_len);
130 130
131 if (!tmp_data2) goto err; 131 if (!tmp_data2)
132 {
133 X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_ILLEGAL_HEX_DIGIT);
134 X509V3_conf_err(val);
135 goto err;
136 }
132 137
133 tmp_data = OPENSSL_realloc((*policy)->data, 138 tmp_data = OPENSSL_realloc((*policy)->data,
134 (*policy)->length + val_len + 1); 139 (*policy)->length + val_len + 1);
@@ -140,6 +145,17 @@ static int process_pci_value(CONF_VALUE *val,
140 (*policy)->length += val_len; 145 (*policy)->length += val_len;
141 (*policy)->data[(*policy)->length] = '\0'; 146 (*policy)->data[(*policy)->length] = '\0';
142 } 147 }
148 else
149 {
150 OPENSSL_free(tmp_data2);
151 /* realloc failure implies the original data space is b0rked too! */
152 (*policy)->data = NULL;
153 (*policy)->length = 0;
154 X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
155 X509V3_conf_err(val);
156 goto err;
157 }
158 OPENSSL_free(tmp_data2);
143 } 159 }
144 else if (strncmp(val->value, "file:", 5) == 0) 160 else if (strncmp(val->value, "file:", 5) == 0)
145 { 161 {
@@ -169,6 +185,7 @@ static int process_pci_value(CONF_VALUE *val,
169 (*policy)->length += n; 185 (*policy)->length += n;
170 (*policy)->data[(*policy)->length] = '\0'; 186 (*policy)->data[(*policy)->length] = '\0';
171 } 187 }
188 BIO_free_all(b);
172 189
173 if (n < 0) 190 if (n < 0)
174 { 191 {
@@ -190,6 +207,15 @@ static int process_pci_value(CONF_VALUE *val,
190 (*policy)->length += val_len; 207 (*policy)->length += val_len;
191 (*policy)->data[(*policy)->length] = '\0'; 208 (*policy)->data[(*policy)->length] = '\0';
192 } 209 }
210 else
211 {
212 /* realloc failure implies the original data space is b0rked too! */
213 (*policy)->data = NULL;
214 (*policy)->length = 0;
215 X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
216 X509V3_conf_err(val);
217 goto err;
218 }
193 } 219 }
194 else 220 else
195 { 221 {
diff --git a/src/lib/libcrypto/x509v3/v3_pcons.c b/src/lib/libcrypto/x509v3/v3_pcons.c
index 86c0ff70e6..30ca652351 100644
--- a/src/lib/libcrypto/x509v3/v3_pcons.c
+++ b/src/lib/libcrypto/x509v3/v3_pcons.c
@@ -64,10 +64,12 @@
64#include <openssl/conf.h> 64#include <openssl/conf.h>
65#include <openssl/x509v3.h> 65#include <openssl/x509v3.h>
66 66
67static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, 67static STACK_OF(CONF_VALUE) *
68 void *bcons, STACK_OF(CONF_VALUE) *extlist); 68i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons,
69static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, 69 STACK_OF(CONF_VALUE) *extlist);
70 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); 70static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
71 X509V3_CTX *ctx,
72 STACK_OF(CONF_VALUE) *values);
71 73
72const X509V3_EXT_METHOD v3_policy_constraints = { 74const X509V3_EXT_METHOD v3_policy_constraints = {
73NID_policy_constraints, 0, 75NID_policy_constraints, 0,
@@ -88,8 +90,9 @@ ASN1_SEQUENCE(POLICY_CONSTRAINTS) = {
88IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) 90IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
89 91
90 92
91static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, 93static STACK_OF(CONF_VALUE) *
92 void *a, STACK_OF(CONF_VALUE) *extlist) 94i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
95 STACK_OF(CONF_VALUE) *extlist)
93{ 96{
94 POLICY_CONSTRAINTS *pcons = a; 97 POLICY_CONSTRAINTS *pcons = a;
95 X509V3_add_value_int("Require Explicit Policy", 98 X509V3_add_value_int("Require Explicit Policy",
@@ -99,8 +102,9 @@ static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method,
99 return extlist; 102 return extlist;
100} 103}
101 104
102static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, 105static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
103 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values) 106 X509V3_CTX *ctx,
107 STACK_OF(CONF_VALUE) *values)
104{ 108{
105 POLICY_CONSTRAINTS *pcons=NULL; 109 POLICY_CONSTRAINTS *pcons=NULL;
106 CONF_VALUE *val; 110 CONF_VALUE *val;
diff --git a/src/lib/libcrypto/x509v3/v3_pmaps.c b/src/lib/libcrypto/x509v3/v3_pmaps.c
index da03bbc35d..865bcd3980 100644
--- a/src/lib/libcrypto/x509v3/v3_pmaps.c
+++ b/src/lib/libcrypto/x509v3/v3_pmaps.c
@@ -63,10 +63,11 @@
63#include <openssl/conf.h> 63#include <openssl/conf.h>
64#include <openssl/x509v3.h> 64#include <openssl/x509v3.h>
65 65
66static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, 66static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); 67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
68static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, 68static STACK_OF(CONF_VALUE) *
69 void *pmps, STACK_OF(CONF_VALUE) *extlist); 69i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *pmps,
70 STACK_OF(CONF_VALUE) *extlist);
70 71
71const X509V3_EXT_METHOD v3_policy_mappings = { 72const X509V3_EXT_METHOD v3_policy_mappings = {
72 NID_policy_mappings, 0, 73 NID_policy_mappings, 0,
@@ -92,8 +93,9 @@ ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS)
92IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) 93IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
93 94
94 95
95static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, 96static STACK_OF(CONF_VALUE) *
96 void *a, STACK_OF(CONF_VALUE) *ext_list) 97i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a,
98 STACK_OF(CONF_VALUE) *ext_list)
97{ 99{
98 POLICY_MAPPINGS *pmaps = a; 100 POLICY_MAPPINGS *pmaps = a;
99 POLICY_MAPPING *pmap; 101 POLICY_MAPPING *pmap;
@@ -109,8 +111,8 @@ static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method,
109 return ext_list; 111 return ext_list;
110} 112}
111 113
112static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, 114static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
113 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 115 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
114{ 116{
115 POLICY_MAPPINGS *pmaps; 117 POLICY_MAPPINGS *pmaps;
116 POLICY_MAPPING *pmap; 118 POLICY_MAPPING *pmap;