summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509v3/v3_ncons.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/x509v3/v3_ncons.c')
-rw-r--r--src/lib/libcrypto/x509v3/v3_ncons.c258
1 files changed, 118 insertions, 140 deletions
diff --git a/src/lib/libcrypto/x509v3/v3_ncons.c b/src/lib/libcrypto/x509v3/v3_ncons.c
index a01dc64dd2..695176471b 100644
--- a/src/lib/libcrypto/x509v3/v3_ncons.c
+++ b/src/lib/libcrypto/x509v3/v3_ncons.c
@@ -10,7 +10,7 @@
10 * are met: 10 * are met:
11 * 11 *
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 14 *
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in 16 * notice, this list of conditions and the following disclaimer in
@@ -64,12 +64,11 @@
64#include <openssl/x509v3.h> 64#include <openssl/x509v3.h>
65 65
66static void *v2i_NAME_CONSTRAINTS(const 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(const 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(const 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, BIO *bp, int ind, char *name);
72 BIO *bp, int ind, char *name);
73static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); 72static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
74 73
75static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); 74static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
@@ -82,10 +81,10 @@ static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
82const X509V3_EXT_METHOD v3_name_constraints = { 81const X509V3_EXT_METHOD v3_name_constraints = {
83 NID_name_constraints, 0, 82 NID_name_constraints, 0,
84 ASN1_ITEM_ref(NAME_CONSTRAINTS), 83 ASN1_ITEM_ref(NAME_CONSTRAINTS),
85 0,0,0,0, 84 0, 0, 0, 0,
86 0,0, 85 0, 0,
87 0, v2i_NAME_CONSTRAINTS, 86 0, v2i_NAME_CONSTRAINTS,
88 i2r_NAME_CONSTRAINTS,0, 87 i2r_NAME_CONSTRAINTS, 0,
89 NULL 88 NULL
90}; 89};
91 90
@@ -97,44 +96,41 @@ ASN1_SEQUENCE(GENERAL_SUBTREE) = {
97 96
98ASN1_SEQUENCE(NAME_CONSTRAINTS) = { 97ASN1_SEQUENCE(NAME_CONSTRAINTS) = {
99 ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees, 98 ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees,
100 GENERAL_SUBTREE, 0), 99 GENERAL_SUBTREE, 0),
101 ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees, 100 ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees,
102 GENERAL_SUBTREE, 1), 101 GENERAL_SUBTREE, 1),
103} ASN1_SEQUENCE_END(NAME_CONSTRAINTS) 102} ASN1_SEQUENCE_END(NAME_CONSTRAINTS)
104 103
105 104
106IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) 105IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
107IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) 106IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
108 107
109static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, 108static void *
110 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 109v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
111 { 110 STACK_OF(CONF_VALUE) *nval)
111{
112 int i; 112 int i;
113 CONF_VALUE tval, *val; 113 CONF_VALUE tval, *val;
114 STACK_OF(GENERAL_SUBTREE) **ptree = NULL; 114 STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
115 NAME_CONSTRAINTS *ncons = NULL; 115 NAME_CONSTRAINTS *ncons = NULL;
116 GENERAL_SUBTREE *sub = NULL; 116 GENERAL_SUBTREE *sub = NULL;
117
117 ncons = NAME_CONSTRAINTS_new(); 118 ncons = NAME_CONSTRAINTS_new();
118 if (!ncons) 119 if (!ncons)
119 goto memerr; 120 goto memerr;
120 for(i = 0; i < sk_CONF_VALUE_num(nval); i++) 121 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
121 {
122 val = sk_CONF_VALUE_value(nval, i); 122 val = sk_CONF_VALUE_value(nval, i);
123 if (!strncmp(val->name, "permitted", 9) && val->name[9]) 123 if (!strncmp(val->name, "permitted", 9) && val->name[9]) {
124 {
125 ptree = &ncons->permittedSubtrees; 124 ptree = &ncons->permittedSubtrees;
126 tval.name = val->name + 10; 125 tval.name = val->name + 10;
127 } 126 } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) {
128 else if (!strncmp(val->name, "excluded", 8) && val->name[8])
129 {
130 ptree = &ncons->excludedSubtrees; 127 ptree = &ncons->excludedSubtrees;
131 tval.name = val->name + 9; 128 tval.name = val->name + 9;
132 } 129 } else {
133 else 130 X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS,
134 { 131 X509V3_R_INVALID_SYNTAX);
135 X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX);
136 goto err; 132 goto err;
137 } 133 }
138 tval.value = val->value; 134 tval.value = val->value;
139 sub = GENERAL_SUBTREE_new(); 135 sub = GENERAL_SUBTREE_new();
140 if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) 136 if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
@@ -144,45 +140,43 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
144 if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub)) 140 if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
145 goto memerr; 141 goto memerr;
146 sub = NULL; 142 sub = NULL;
147 } 143 }
148 144
149 return ncons; 145 return ncons;
150 146
151 memerr: 147memerr:
152 X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE); 148 X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
153 err: 149err:
154 if (ncons) 150 if (ncons)
155 NAME_CONSTRAINTS_free(ncons); 151 NAME_CONSTRAINTS_free(ncons);
156 if (sub) 152 if (sub)
157 GENERAL_SUBTREE_free(sub); 153 GENERAL_SUBTREE_free(sub);
158 154
159 return NULL; 155 return NULL;
160 } 156}
161
162 157
163 158static int
164 159i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, BIO *bp, int ind)
165static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, 160{
166 BIO *bp, int ind)
167 {
168 NAME_CONSTRAINTS *ncons = a; 161 NAME_CONSTRAINTS *ncons = a;
162
169 do_i2r_name_constraints(method, ncons->permittedSubtrees, 163 do_i2r_name_constraints(method, ncons->permittedSubtrees,
170 bp, ind, "Permitted"); 164 bp, ind, "Permitted");
171 do_i2r_name_constraints(method, ncons->excludedSubtrees, 165 do_i2r_name_constraints(method, ncons->excludedSubtrees,
172 bp, ind, "Excluded"); 166 bp, ind, "Excluded");
173 return 1; 167 return 1;
174 } 168}
175 169
176static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, 170static int
177 STACK_OF(GENERAL_SUBTREE) *trees, 171do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
178 BIO *bp, int ind, char *name) 172 STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, int ind, char *name)
179 { 173{
180 GENERAL_SUBTREE *tree; 174 GENERAL_SUBTREE *tree;
181 int i; 175 int i;
176
182 if (sk_GENERAL_SUBTREE_num(trees) > 0) 177 if (sk_GENERAL_SUBTREE_num(trees) > 0)
183 BIO_printf(bp, "%*s%s:\n", ind, "", name); 178 BIO_printf(bp, "%*s%s:\n", ind, "", name);
184 for(i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) 179 for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) {
185 {
186 tree = sk_GENERAL_SUBTREE_value(trees, i); 180 tree = sk_GENERAL_SUBTREE_value(trees, i);
187 BIO_printf(bp, "%*s", ind + 2, ""); 181 BIO_printf(bp, "%*s", ind + 2, "");
188 if (tree->base->type == GEN_IPADD) 182 if (tree->base->type == GEN_IPADD)
@@ -190,39 +184,35 @@ static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
190 else 184 else
191 GENERAL_NAME_print(bp, tree->base); 185 GENERAL_NAME_print(bp, tree->base);
192 BIO_puts(bp, "\n"); 186 BIO_puts(bp, "\n");
193 }
194 return 1;
195 } 187 }
188 return 1;
189}
196 190
197static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) 191static int
198 { 192print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
193{
199 int i, len; 194 int i, len;
200 unsigned char *p; 195 unsigned char *p;
196
201 p = ip->data; 197 p = ip->data;
202 len = ip->length; 198 len = ip->length;
203 BIO_puts(bp, "IP:"); 199 BIO_puts(bp, "IP:");
204 if(len == 8) 200 if (len == 8) {
205 {
206 BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", 201 BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
207 p[0], p[1], p[2], p[3], 202 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
208 p[4], p[5], p[6], p[7]); 203 } else if (len == 32) {
209 } 204 for (i = 0; i < 16; i++) {
210 else if(len == 32)
211 {
212 for (i = 0; i < 16; i++)
213 {
214 BIO_printf(bp, "%X", p[0] << 8 | p[1]); 205 BIO_printf(bp, "%X", p[0] << 8 | p[1]);
215 p += 2; 206 p += 2;
216 if (i == 7) 207 if (i == 7)
217 BIO_puts(bp, "/"); 208 BIO_puts(bp, "/");
218 else if (i != 15) 209 else if (i != 15)
219 BIO_puts(bp, ":"); 210 BIO_puts(bp, ":");
220 }
221 } 211 }
222 else 212 } else
223 BIO_printf(bp, "IP Address:<invalid>"); 213 BIO_printf(bp, "IP Address:<invalid>");
224 return 1; 214 return 1;
225 } 215}
226 216
227/* Check a certificate conforms to a specified set of constraints. 217/* Check a certificate conforms to a specified set of constraints.
228 * Return values: 218 * Return values:
@@ -233,18 +223,17 @@ static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
233 * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. 223 * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type.
234 * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax. 224 * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax.
235 * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name 225 * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name
236
237 */ 226 */
238 227
239int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) 228int
240 { 229NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
230{
241 int r, i; 231 int r, i;
242 X509_NAME *nm; 232 X509_NAME *nm;
243 233
244 nm = X509_get_subject_name(x); 234 nm = X509_get_subject_name(x);
245 235
246 if (X509_NAME_entry_count(nm) > 0) 236 if (X509_NAME_entry_count(nm) > 0) {
247 {
248 GENERAL_NAME gntmp; 237 GENERAL_NAME gntmp;
249 gntmp.type = GEN_DIRNAME; 238 gntmp.type = GEN_DIRNAME;
250 gntmp.d.directoryName = nm; 239 gntmp.d.directoryName = nm;
@@ -256,15 +245,12 @@ int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
256 245
257 gntmp.type = GEN_EMAIL; 246 gntmp.type = GEN_EMAIL;
258 247
259
260 /* Process any email address attributes in subject name */ 248 /* Process any email address attributes in subject name */
261 249
262 for (i = -1;;) 250 for (i = -1;;) {
263 {
264 X509_NAME_ENTRY *ne; 251 X509_NAME_ENTRY *ne;
265 i = X509_NAME_get_index_by_NID(nm, 252 i = X509_NAME_get_index_by_NID(nm,
266 NID_pkcs9_emailAddress, 253 NID_pkcs9_emailAddress, i);
267 i);
268 if (i == -1) 254 if (i == -1)
269 break; 255 break;
270 ne = X509_NAME_get_entry(nm, i); 256 ne = X509_NAME_get_entry(nm, i);
@@ -276,24 +262,23 @@ int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
276 262
277 if (r != X509_V_OK) 263 if (r != X509_V_OK)
278 return r; 264 return r;
279 }
280
281 } 265 }
282 266
283 for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) 267 }
284 { 268
269 for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) {
285 GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i); 270 GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i);
286 r = nc_match(gen, nc); 271 r = nc_match(gen, nc);
287 if (r != X509_V_OK) 272 if (r != X509_V_OK)
288 return r; 273 return r;
289 } 274 }
290 275
291 return X509_V_OK; 276 return X509_V_OK;
277}
292 278
293 } 279static int
294 280nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
295static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) 281{
296 {
297 GENERAL_SUBTREE *sub; 282 GENERAL_SUBTREE *sub;
298 int i, r, match = 0; 283 int i, r, match = 0;
299 284
@@ -301,8 +286,7 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
301 * at least one subtree must match. 286 * at least one subtree must match.
302 */ 287 */
303 288
304 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) 289 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) {
305 {
306 sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); 290 sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
307 if (gen->type != sub->base->type) 291 if (gen->type != sub->base->type)
308 continue; 292 continue;
@@ -318,15 +302,14 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
318 match = 2; 302 match = 2;
319 else if (r != X509_V_ERR_PERMITTED_VIOLATION) 303 else if (r != X509_V_ERR_PERMITTED_VIOLATION)
320 return r; 304 return r;
321 } 305 }
322 306
323 if (match == 1) 307 if (match == 1)
324 return X509_V_ERR_PERMITTED_VIOLATION; 308 return X509_V_ERR_PERMITTED_VIOLATION;
325 309
326 /* Excluded subtrees: must not match any of these */ 310 /* Excluded subtrees: must not match any of these */
327 311
328 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) 312 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) {
329 {
330 sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); 313 sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
331 if (gen->type != sub->base->type) 314 if (gen->type != sub->base->type)
332 continue; 315 continue;
@@ -339,42 +322,41 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
339 else if (r != X509_V_ERR_PERMITTED_VIOLATION) 322 else if (r != X509_V_ERR_PERMITTED_VIOLATION)
340 return r; 323 return r;
341 324
342 } 325 }
343 326
344 return X509_V_OK; 327 return X509_V_OK;
328}
345 329
346 } 330static int
347 331nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
348static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) 332{
349 { 333 switch (base->type) {
350 switch(base->type) 334 case GEN_DIRNAME:
351 {
352 case GEN_DIRNAME:
353 return nc_dn(gen->d.directoryName, base->d.directoryName); 335 return nc_dn(gen->d.directoryName, base->d.directoryName);
354 336
355 case GEN_DNS: 337 case GEN_DNS:
356 return nc_dns(gen->d.dNSName, base->d.dNSName); 338 return nc_dns(gen->d.dNSName, base->d.dNSName);
357 339
358 case GEN_EMAIL: 340 case GEN_EMAIL:
359 return nc_email(gen->d.rfc822Name, base->d.rfc822Name); 341 return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
360 342
361 case GEN_URI: 343 case GEN_URI:
362 return nc_uri(gen->d.uniformResourceIdentifier, 344 return nc_uri(gen->d.uniformResourceIdentifier,
363 base->d.uniformResourceIdentifier); 345 base->d.uniformResourceIdentifier);
364 346
365 default: 347 default:
366 return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; 348 return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
367 }
368
369 } 349 }
350}
370 351
371/* directoryName name constraint matching. 352/* directoryName name constraint matching.
372 * The canonical encoding of X509_NAME makes this comparison easy. It is 353 * The canonical encoding of X509_NAME makes this comparison easy. It is
373 * matched if the subtree is a subset of the name. 354 * matched if the subtree is a subset of the name.
374 */ 355 */
375 356
376static int nc_dn(X509_NAME *nm, X509_NAME *base) 357static int
377 { 358nc_dn(X509_NAME *nm, X509_NAME *base)
359{
378 /* Ensure canonical encodings are up to date. */ 360 /* Ensure canonical encodings are up to date. */
379 if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) 361 if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
380 return X509_V_ERR_OUT_OF_MEM; 362 return X509_V_ERR_OUT_OF_MEM;
@@ -385,12 +367,14 @@ static int nc_dn(X509_NAME *nm, X509_NAME *base)
385 if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) 367 if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
386 return X509_V_ERR_PERMITTED_VIOLATION; 368 return X509_V_ERR_PERMITTED_VIOLATION;
387 return X509_V_OK; 369 return X509_V_OK;
388 } 370}
389 371
390static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) 372static int
391 { 373nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
374{
392 char *baseptr = (char *)base->data; 375 char *baseptr = (char *)base->data;
393 char *dnsptr = (char *)dns->data; 376 char *dnsptr = (char *)dns->data;
377
394 /* Empty matches everything */ 378 /* Empty matches everything */
395 if (!*baseptr) 379 if (!*baseptr)
396 return X509_V_OK; 380 return X509_V_OK;
@@ -398,71 +382,67 @@ static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
398 * compare RHS and if dns is longer and expect '.' as preceding 382 * compare RHS and if dns is longer and expect '.' as preceding
399 * character. 383 * character.
400 */ 384 */
401 if (dns->length > base->length) 385 if (dns->length > base->length) {
402 {
403 dnsptr += dns->length - base->length; 386 dnsptr += dns->length - base->length;
404 if (dnsptr[-1] != '.') 387 if (dnsptr[-1] != '.')
405 return X509_V_ERR_PERMITTED_VIOLATION; 388 return X509_V_ERR_PERMITTED_VIOLATION;
406 } 389 }
407 390
408 if (strcasecmp(baseptr, dnsptr)) 391 if (strcasecmp(baseptr, dnsptr))
409 return X509_V_ERR_PERMITTED_VIOLATION; 392 return X509_V_ERR_PERMITTED_VIOLATION;
410 393
411 return X509_V_OK; 394 return X509_V_OK;
395}
412 396
413 } 397static int
414 398nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
415static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) 399{
416 {
417 const char *baseptr = (char *)base->data; 400 const char *baseptr = (char *)base->data;
418 const char *emlptr = (char *)eml->data; 401 const char *emlptr = (char *)eml->data;
419
420 const char *baseat = strchr(baseptr, '@'); 402 const char *baseat = strchr(baseptr, '@');
421 const char *emlat = strchr(emlptr, '@'); 403 const char *emlat = strchr(emlptr, '@');
404
422 if (!emlat) 405 if (!emlat)
423 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; 406 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
424 /* Special case: inital '.' is RHS match */ 407 /* Special case: inital '.' is RHS match */
425 if (!baseat && (*baseptr == '.')) 408 if (!baseat && (*baseptr == '.')) {
426 { 409 if (eml->length > base->length) {
427 if (eml->length > base->length)
428 {
429 emlptr += eml->length - base->length; 410 emlptr += eml->length - base->length;
430 if (!strcasecmp(baseptr, emlptr)) 411 if (!strcasecmp(baseptr, emlptr))
431 return X509_V_OK; 412 return X509_V_OK;
432 }
433 return X509_V_ERR_PERMITTED_VIOLATION;
434 } 413 }
414 return X509_V_ERR_PERMITTED_VIOLATION;
415 }
435 416
436 /* If we have anything before '@' match local part */ 417 /* If we have anything before '@' match local part */
437 418
438 if (baseat) 419 if (baseat) {
439 { 420 if (baseat != baseptr) {
440 if (baseat != baseptr)
441 {
442 if ((baseat - baseptr) != (emlat - emlptr)) 421 if ((baseat - baseptr) != (emlat - emlptr))
443 return X509_V_ERR_PERMITTED_VIOLATION; 422 return X509_V_ERR_PERMITTED_VIOLATION;
444 /* Case sensitive match of local part */ 423 /* Case sensitive match of local part */
445 if (strncmp(baseptr, emlptr, emlat - emlptr)) 424 if (strncmp(baseptr, emlptr, emlat - emlptr))
446 return X509_V_ERR_PERMITTED_VIOLATION; 425 return X509_V_ERR_PERMITTED_VIOLATION;
447 } 426 }
448 /* Position base after '@' */ 427 /* Position base after '@' */
449 baseptr = baseat + 1; 428 baseptr = baseat + 1;
450 } 429 }
451 emlptr = emlat + 1; 430 emlptr = emlat + 1;
452 /* Just have hostname left to match: case insensitive */ 431 /* Just have hostname left to match: case insensitive */
453 if (strcasecmp(baseptr, emlptr)) 432 if (strcasecmp(baseptr, emlptr))
454 return X509_V_ERR_PERMITTED_VIOLATION; 433 return X509_V_ERR_PERMITTED_VIOLATION;
455 434
456 return X509_V_OK; 435 return X509_V_OK;
436}
457 437
458 } 438static int
459 439nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
460static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) 440{
461 {
462 const char *baseptr = (char *)base->data; 441 const char *baseptr = (char *)base->data;
463 const char *hostptr = (char *)uri->data; 442 const char *hostptr = (char *)uri->data;
464 const char *p = strchr(hostptr, ':'); 443 const char *p = strchr(hostptr, ':');
465 int hostlen; 444 int hostlen;
445
466 /* Check for foo:// and skip past it */ 446 /* Check for foo:// and skip past it */
467 if (!p || (p[1] != '/') || (p[2] != '/')) 447 if (!p || (p[1] != '/') || (p[2] != '/'))
468 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; 448 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
@@ -486,20 +466,18 @@ static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
486 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; 466 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
487 467
488 /* Special case: inital '.' is RHS match */ 468 /* Special case: inital '.' is RHS match */
489 if (*baseptr == '.') 469 if (*baseptr == '.') {
490 { 470 if (hostlen > base->length) {
491 if (hostlen > base->length)
492 {
493 p = hostptr + hostlen - base->length; 471 p = hostptr + hostlen - base->length;
494 if (!strncasecmp(p, baseptr, base->length)) 472 if (!strncasecmp(p, baseptr, base->length))
495 return X509_V_OK; 473 return X509_V_OK;
496 }
497 return X509_V_ERR_PERMITTED_VIOLATION;
498 } 474 }
475 return X509_V_ERR_PERMITTED_VIOLATION;
476 }
499 477
500 if ((base->length != (int)hostlen) || strncasecmp(hostptr, baseptr, hostlen)) 478 if ((base->length != (int)hostlen) ||
479 strncasecmp(hostptr, baseptr, hostlen))
501 return X509_V_ERR_PERMITTED_VIOLATION; 480 return X509_V_ERR_PERMITTED_VIOLATION;
502 481
503 return X509_V_OK; 482 return X509_V_OK;
504 483}
505 }