• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* v3_purp.c */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 2001.
4  */
5 /* ====================================================================
6  * Copyright (c) 1999-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 #include <stdio.h>
58 
59 #include <string.h>
60 
61 #include <openssl/buf.h>
62 #include <openssl/err.h>
63 #include <openssl/digest.h>
64 #include <openssl/mem.h>
65 #include <openssl/obj.h>
66 #include <openssl/thread.h>
67 #include <openssl/x509_vfy.h>
68 #include <openssl/x509v3.h>
69 
70 #include "../internal.h"
71 
72 
73 #define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
74 #define ku_reject(x, usage) \
75 	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
76 #define xku_reject(x, usage) \
77 	(((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
78 #define ns_reject(x, usage) \
79 	(((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
80 
81 static void x509v3_cache_extensions(X509 *x);
82 
83 static int check_ssl_ca(const X509 *x);
84 static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca);
85 static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca);
86 static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca);
87 static int purpose_smime(const X509 *x, int ca);
88 static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
89 static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca);
90 static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
91 static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
92 static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
93 static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca);
94 
95 static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **b);
96 static void xptable_free(X509_PURPOSE *p);
97 
98 static X509_PURPOSE xstandard[] = {
99 	{X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, check_purpose_ssl_client, (char *) "SSL client", (char *) "sslclient", NULL},
100 	{X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ssl_server, (char *) "SSL server", (char *) "sslserver", NULL},
101 	{X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, (char *) "Netscape SSL server", (char *) "nssslserver", NULL},
102 	{X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, (char *) "S/MIME signing", (char *) "smimesign", NULL},
103 	{X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, (char *) "S/MIME encryption", (char *) "smimeencrypt", NULL},
104 	{X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, (char *) "CRL signing", (char *) "crlsign", NULL},
105 	{X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, (char *) "Any Purpose", (char *) "any", NULL},
106 	{X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, (char *) "OCSP helper", (char *) "ocsphelper", NULL},
107 	{X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, (char *) "Time Stamp signing", (char *) "timestampsign", NULL},
108 };
109 
110 #define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE))
111 
112 static STACK_OF(X509_PURPOSE) *xptable = NULL;
113 
xp_cmp(const X509_PURPOSE ** a,const X509_PURPOSE ** b)114 static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **b)
115 {
116 	return (*a)->purpose - (*b)->purpose;
117 }
118 
119 /* As much as I'd like to make X509_check_purpose use a "const" X509*
120  * I really can't because it does recalculate hashes and do other non-const
121  * things. */
X509_check_purpose(X509 * x,int id,int ca)122 int X509_check_purpose(X509 *x, int id, int ca)
123 {
124 	int idx;
125 	const X509_PURPOSE *pt;
126 	if(!(x->ex_flags & EXFLAG_SET)) {
127 		x509v3_cache_extensions(x);
128 	}
129 	if(id == -1) return 1;
130 	idx = X509_PURPOSE_get_by_id(id);
131 	if(idx == -1) return -1;
132 	pt = X509_PURPOSE_get0(idx);
133 	return pt->check_purpose(pt, x, ca);
134 }
135 
X509_PURPOSE_set(int * p,int purpose)136 int X509_PURPOSE_set(int *p, int purpose)
137 {
138 	if(X509_PURPOSE_get_by_id(purpose) == -1) {
139 		OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PURPOSE);
140 		return 0;
141 	}
142 	*p = purpose;
143 	return 1;
144 }
145 
X509_PURPOSE_get_count(void)146 int X509_PURPOSE_get_count(void)
147 {
148 	if(!xptable) return X509_PURPOSE_COUNT;
149 	return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT;
150 }
151 
X509_PURPOSE_get0(int idx)152 X509_PURPOSE * X509_PURPOSE_get0(int idx)
153 {
154 	if(idx < 0) return NULL;
155 	if(idx < (int)X509_PURPOSE_COUNT) return xstandard + idx;
156 	return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
157 }
158 
X509_PURPOSE_get_by_sname(char * sname)159 int X509_PURPOSE_get_by_sname(char *sname)
160 {
161 	int i;
162 	X509_PURPOSE *xptmp;
163 	for(i = 0; i < X509_PURPOSE_get_count(); i++) {
164 		xptmp = X509_PURPOSE_get0(i);
165 		if(!strcmp(xptmp->sname, sname)) return i;
166 	}
167 	return -1;
168 }
169 
X509_PURPOSE_get_by_id(int purpose)170 int X509_PURPOSE_get_by_id(int purpose)
171 {
172 	X509_PURPOSE tmp;
173 	size_t idx;
174 
175 	if((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
176 		return purpose - X509_PURPOSE_MIN;
177 	tmp.purpose = purpose;
178 	if(!xptable) return -1;
179 
180 	if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp))
181 		return -1;
182 	return idx + X509_PURPOSE_COUNT;
183 }
184 
X509_PURPOSE_add(int id,int trust,int flags,int (* ck)(const X509_PURPOSE *,const X509 *,int),char * name,char * sname,void * arg)185 int X509_PURPOSE_add(int id, int trust, int flags,
186 			int (*ck)(const X509_PURPOSE *, const X509 *, int),
187 					char *name, char *sname, void *arg)
188 {
189 	int idx;
190 	X509_PURPOSE *ptmp;
191 	char *name_dup, *sname_dup;
192 
193 	/* This is set according to what we change: application can't set it */
194 	flags &= ~X509_PURPOSE_DYNAMIC;
195 	/* This will always be set for application modified trust entries */
196 	flags |= X509_PURPOSE_DYNAMIC_NAME;
197 	/* Get existing entry if any */
198 	idx = X509_PURPOSE_get_by_id(id);
199 	/* Need a new entry */
200 	if(idx == -1) {
201 		if(!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) {
202 			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
203 			return 0;
204 		}
205 		ptmp->flags = X509_PURPOSE_DYNAMIC;
206 	} else ptmp = X509_PURPOSE_get0(idx);
207 
208 	/* Duplicate the supplied names. */
209 	name_dup = BUF_strdup(name);
210 	sname_dup = BUF_strdup(sname);
211 	if (name_dup == NULL || sname_dup == NULL) {
212 		OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
213 		if (name_dup != NULL)
214 			OPENSSL_free(name_dup);
215 		if (sname_dup != NULL)
216 			OPENSSL_free(sname_dup);
217 		if (idx == -1)
218 			OPENSSL_free(ptmp);
219 		return 0;
220 	}
221 
222 	/* OPENSSL_free existing name if dynamic */
223 	if(ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
224 		OPENSSL_free(ptmp->name);
225 		OPENSSL_free(ptmp->sname);
226 	}
227 	/* dup supplied name */
228 	ptmp->name = name_dup;
229 	ptmp->sname = sname_dup;
230 	/* Keep the dynamic flag of existing entry */
231 	ptmp->flags &= X509_PURPOSE_DYNAMIC;
232 	/* Set all other flags */
233 	ptmp->flags |= flags;
234 
235 	ptmp->purpose = id;
236 	ptmp->trust = trust;
237 	ptmp->check_purpose = ck;
238 	ptmp->usr_data = arg;
239 
240 	/* If its a new entry manage the dynamic table */
241 	if(idx == -1) {
242 		if(!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) {
243 			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
244 			xptable_free(ptmp);
245 			return 0;
246 		}
247 		if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
248 			OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
249 			xptable_free(ptmp);
250 			return 0;
251 		}
252 	}
253 	return 1;
254 }
255 
xptable_free(X509_PURPOSE * p)256 static void xptable_free(X509_PURPOSE *p)
257 	{
258 	if(!p) return;
259 	if (p->flags & X509_PURPOSE_DYNAMIC)
260 		{
261 		if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
262 			OPENSSL_free(p->name);
263 			OPENSSL_free(p->sname);
264 		}
265 		OPENSSL_free(p);
266 		}
267 	}
268 
X509_PURPOSE_cleanup(void)269 void X509_PURPOSE_cleanup(void)
270 {
271 	unsigned int i;
272 	sk_X509_PURPOSE_pop_free(xptable, xptable_free);
273 	for(i = 0; i < X509_PURPOSE_COUNT; i++) xptable_free(xstandard + i);
274 	xptable = NULL;
275 }
276 
X509_PURPOSE_get_id(X509_PURPOSE * xp)277 int X509_PURPOSE_get_id(X509_PURPOSE *xp)
278 {
279 	return xp->purpose;
280 }
281 
X509_PURPOSE_get0_name(X509_PURPOSE * xp)282 char *X509_PURPOSE_get0_name(X509_PURPOSE *xp)
283 {
284 	return xp->name;
285 }
286 
X509_PURPOSE_get0_sname(X509_PURPOSE * xp)287 char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp)
288 {
289 	return xp->sname;
290 }
291 
X509_PURPOSE_get_trust(X509_PURPOSE * xp)292 int X509_PURPOSE_get_trust(X509_PURPOSE *xp)
293 {
294 	return xp->trust;
295 }
296 
nid_cmp(const void * void_a,const void * void_b)297 static int nid_cmp(const void *void_a, const void *void_b)
298 	{
299 	const int *a = void_a, *b = void_b;
300 
301 	return *a - *b;
302 	}
303 
X509_supported_extension(X509_EXTENSION * ex)304 int X509_supported_extension(X509_EXTENSION *ex)
305 	{
306 	/* This table is a list of the NIDs of supported extensions:
307 	 * that is those which are used by the verify process. If
308 	 * an extension is critical and doesn't appear in this list
309 	 * then the verify process will normally reject the certificate.
310 	 * The list must be kept in numerical order because it will be
311 	 * searched using bsearch.
312 	 */
313 
314 	static const int supported_nids[] = {
315 		NID_netscape_cert_type, /* 71 */
316         	NID_key_usage,		/* 83 */
317 		NID_subject_alt_name,	/* 85 */
318 		NID_basic_constraints,	/* 87 */
319 		NID_certificate_policies, /* 89 */
320         	NID_ext_key_usage,	/* 126 */
321 		NID_policy_constraints,	/* 401 */
322 		NID_proxyCertInfo,	/* 663 */
323 		NID_name_constraints,	/* 666 */
324 		NID_policy_mappings,	/* 747 */
325 		NID_inhibit_any_policy	/* 748 */
326 	};
327 
328 	int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
329 
330 	if (ex_nid == NID_undef)
331 		return 0;
332 
333 	if (bsearch(&ex_nid, supported_nids, sizeof(supported_nids)/sizeof(int), sizeof(int), nid_cmp) != NULL)
334 		return 1;
335 	return 0;
336 	}
337 
setup_dp(X509 * x,DIST_POINT * dp)338 static void setup_dp(X509 *x, DIST_POINT *dp)
339 	{
340 	X509_NAME *iname = NULL;
341 	size_t i;
342 	if (dp->reasons)
343 		{
344 		if (dp->reasons->length > 0)
345 			dp->dp_reasons = dp->reasons->data[0];
346 		if (dp->reasons->length > 1)
347 			dp->dp_reasons |= (dp->reasons->data[1] << 8);
348 		dp->dp_reasons &= CRLDP_ALL_REASONS;
349 		}
350 	else
351 		dp->dp_reasons = CRLDP_ALL_REASONS;
352 	if (!dp->distpoint || (dp->distpoint->type != 1))
353 		return;
354 	for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
355 		{
356 		GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
357 		if (gen->type == GEN_DIRNAME)
358 			{
359 			iname = gen->d.directoryName;
360 			break;
361 			}
362 		}
363 	if (!iname)
364 		iname = X509_get_issuer_name(x);
365 
366 	DIST_POINT_set_dpname(dp->distpoint, iname);
367 
368 	}
369 
setup_crldp(X509 * x)370 static void setup_crldp(X509 *x)
371 	{
372 	size_t i;
373 	x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
374 	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
375 		setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
376 	}
377 
378 /* g_x509_cache_extensions_lock is used to protect against concurrent calls to
379  * |x509v3_cache_extensions|. Ideally this would be done with a |CRYPTO_once_t|
380  * in the |X509| structure, but |CRYPTO_once_t| isn't public.
381  *
382  * Note: it's not entirely clear whether this lock is needed. Not all paths to
383  * this function took a lock in OpenSSL. */
384 static struct CRYPTO_STATIC_MUTEX g_x509_cache_extensions_lock =
385     CRYPTO_STATIC_MUTEX_INIT;
386 
x509v3_cache_extensions(X509 * x)387 static void x509v3_cache_extensions(X509 *x)
388 {
389 	BASIC_CONSTRAINTS *bs;
390 	PROXY_CERT_INFO_EXTENSION *pci;
391 	ASN1_BIT_STRING *usage;
392 	ASN1_BIT_STRING *ns;
393 	EXTENDED_KEY_USAGE *extusage;
394 	X509_EXTENSION *ex;
395 	size_t i;
396 	int j;
397 
398 	CRYPTO_STATIC_MUTEX_lock_write(&g_x509_cache_extensions_lock);
399 
400 	if(x->ex_flags & EXFLAG_SET)
401 		{
402 		CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
403 		return;
404 		}
405 
406 	X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
407 	/* V1 should mean no extensions ... */
408 	if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1;
409 	/* Handle basic constraints */
410 	if((bs=X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
411 		if(bs->ca) x->ex_flags |= EXFLAG_CA;
412 		if(bs->pathlen) {
413 			if((bs->pathlen->type == V_ASN1_NEG_INTEGER)
414 						|| !bs->ca) {
415 				x->ex_flags |= EXFLAG_INVALID;
416 				x->ex_pathlen = 0;
417 			} else x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
418 		} else x->ex_pathlen = -1;
419 		BASIC_CONSTRAINTS_free(bs);
420 		x->ex_flags |= EXFLAG_BCONS;
421 	}
422 	/* Handle proxy certificates */
423 	if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
424 		if (x->ex_flags & EXFLAG_CA
425 		    || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
426 		    || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
427 			x->ex_flags |= EXFLAG_INVALID;
428 		}
429 		if (pci->pcPathLengthConstraint) {
430 			x->ex_pcpathlen =
431 				ASN1_INTEGER_get(pci->pcPathLengthConstraint);
432 		} else x->ex_pcpathlen = -1;
433 		PROXY_CERT_INFO_EXTENSION_free(pci);
434 		x->ex_flags |= EXFLAG_PROXY;
435 	}
436 	/* Handle key usage */
437 	if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
438 		if(usage->length > 0) {
439 			x->ex_kusage = usage->data[0];
440 			if(usage->length > 1)
441 				x->ex_kusage |= usage->data[1] << 8;
442 		} else x->ex_kusage = 0;
443 		x->ex_flags |= EXFLAG_KUSAGE;
444 		ASN1_BIT_STRING_free(usage);
445 	}
446 	x->ex_xkusage = 0;
447 	if((extusage=X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
448 		x->ex_flags |= EXFLAG_XKUSAGE;
449 		for(i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
450 			switch(OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage,i))) {
451 				case NID_server_auth:
452 				x->ex_xkusage |= XKU_SSL_SERVER;
453 				break;
454 
455 				case NID_client_auth:
456 				x->ex_xkusage |= XKU_SSL_CLIENT;
457 				break;
458 
459 				case NID_email_protect:
460 				x->ex_xkusage |= XKU_SMIME;
461 				break;
462 
463 				case NID_code_sign:
464 				x->ex_xkusage |= XKU_CODE_SIGN;
465 				break;
466 
467 				case NID_ms_sgc:
468 				case NID_ns_sgc:
469 				x->ex_xkusage |= XKU_SGC;
470 				break;
471 
472 				case NID_OCSP_sign:
473 				x->ex_xkusage |= XKU_OCSP_SIGN;
474 				break;
475 
476 				case NID_time_stamp:
477 				x->ex_xkusage |= XKU_TIMESTAMP;
478 				break;
479 
480 				case NID_dvcs:
481 				x->ex_xkusage |= XKU_DVCS;
482 				break;
483 
484 				case NID_anyExtendedKeyUsage:
485 				x->ex_xkusage |= XKU_ANYEKU;
486 				break;
487 			}
488 		}
489 		sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
490 	}
491 
492 	if((ns=X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
493 		if(ns->length > 0) x->ex_nscert = ns->data[0];
494 		else x->ex_nscert = 0;
495 		x->ex_flags |= EXFLAG_NSCERT;
496 		ASN1_BIT_STRING_free(ns);
497 	}
498 	x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
499 	x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
500 	/* Does subject name match issuer ? */
501 	if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
502 			{
503 			x->ex_flags |= EXFLAG_SI;
504 			/* If SKID matches AKID also indicate self signed */
505 			if (X509_check_akid(x, x->akid) == X509_V_OK &&
506 				!ku_reject(x, KU_KEY_CERT_SIGN))
507 				x->ex_flags |= EXFLAG_SS;
508 			}
509 	x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
510 	x->nc = X509_get_ext_d2i(x, NID_name_constraints, &j, NULL);
511 	if (!x->nc && (j != -1))
512 		x->ex_flags |= EXFLAG_INVALID;
513 	setup_crldp(x);
514 
515 	for (j = 0; j < X509_get_ext_count(x); j++)
516 		{
517 		ex = X509_get_ext(x, j);
518 		if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
519 					== NID_freshest_crl)
520 			x->ex_flags |= EXFLAG_FRESHEST;
521 		if (!X509_EXTENSION_get_critical(ex))
522 			continue;
523 		if (!X509_supported_extension(ex))
524 			{
525 			x->ex_flags |= EXFLAG_CRITICAL;
526 			break;
527 			}
528 		}
529 	x->ex_flags |= EXFLAG_SET;
530 
531 	CRYPTO_STATIC_MUTEX_unlock(&g_x509_cache_extensions_lock);
532 }
533 
534 /* CA checks common to all purposes
535  * return codes:
536  * 0 not a CA
537  * 1 is a CA
538  * 2 basicConstraints absent so "maybe" a CA
539  * 3 basicConstraints absent but self signed V1.
540  * 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
541  */
542 
check_ca(const X509 * x)543 static int check_ca(const X509 *x)
544 {
545 	/* keyUsage if present should allow cert signing */
546 	if(ku_reject(x, KU_KEY_CERT_SIGN)) return 0;
547 	if(x->ex_flags & EXFLAG_BCONS) {
548 		if(x->ex_flags & EXFLAG_CA) return 1;
549 		/* If basicConstraints says not a CA then say so */
550 		else return 0;
551 	} else {
552 		/* we support V1 roots for...  uh, I don't really know why. */
553 		if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3;
554 		/* If key usage present it must have certSign so tolerate it */
555 		else if (x->ex_flags & EXFLAG_KUSAGE) return 4;
556 		/* Older certificates could have Netscape-specific CA types */
557 		else if (x->ex_flags & EXFLAG_NSCERT
558 			 && x->ex_nscert & NS_ANY_CA) return 5;
559 		/* can this still be regarded a CA certificate?  I doubt it */
560 		return 0;
561 	}
562 }
563 
X509_check_ca(X509 * x)564 int X509_check_ca(X509 *x)
565 {
566 	if(!(x->ex_flags & EXFLAG_SET)) {
567 		x509v3_cache_extensions(x);
568 	}
569 
570 	return check_ca(x);
571 }
572 
573 /* Check SSL CA: common checks for SSL client and server */
check_ssl_ca(const X509 * x)574 static int check_ssl_ca(const X509 *x)
575 {
576 	int ca_ret;
577 	ca_ret = check_ca(x);
578 	if(!ca_ret) return 0;
579 	/* check nsCertType if present */
580 	if(ca_ret != 5 || x->ex_nscert & NS_SSL_CA) return ca_ret;
581 	else return 0;
582 }
583 
584 
check_purpose_ssl_client(const X509_PURPOSE * xp,const X509 * x,int ca)585 static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca)
586 {
587 	if(xku_reject(x,XKU_SSL_CLIENT)) return 0;
588 	if(ca) return check_ssl_ca(x);
589 	/* We need to do digital signatures or key agreement */
590 	if(ku_reject(x,KU_DIGITAL_SIGNATURE|KU_KEY_AGREEMENT)) return 0;
591 	/* nsCertType if present should allow SSL client use */
592 	if(ns_reject(x, NS_SSL_CLIENT)) return 0;
593 	return 1;
594 }
595 /* Key usage needed for TLS/SSL server: digital signature, encipherment or
596  * key agreement. The ssl code can check this more thoroughly for individual
597  * key types.
598  */
599 #define KU_TLS \
600 	KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT
601 
check_purpose_ssl_server(const X509_PURPOSE * xp,const X509 * x,int ca)602 static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
603 {
604 	if(xku_reject(x,XKU_SSL_SERVER|XKU_SGC)) return 0;
605 	if(ca) return check_ssl_ca(x);
606 
607 	if(ns_reject(x, NS_SSL_SERVER)) return 0;
608 	if(ku_reject(x, KU_TLS)) return 0;
609 
610 	return 1;
611 
612 }
613 
check_purpose_ns_ssl_server(const X509_PURPOSE * xp,const X509 * x,int ca)614 static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
615 {
616 	int ret;
617 	ret = check_purpose_ssl_server(xp, x, ca);
618 	if(!ret || ca) return ret;
619 	/* We need to encipher or Netscape complains */
620 	if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
621 	return ret;
622 }
623 
624 /* common S/MIME checks */
purpose_smime(const X509 * x,int ca)625 static int purpose_smime(const X509 *x, int ca)
626 {
627 	if(xku_reject(x,XKU_SMIME)) return 0;
628 	if(ca) {
629 		int ca_ret;
630 		ca_ret = check_ca(x);
631 		if(!ca_ret) return 0;
632 		/* check nsCertType if present */
633 		if(ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) return ca_ret;
634 		else return 0;
635 	}
636 	if(x->ex_flags & EXFLAG_NSCERT) {
637 		if(x->ex_nscert & NS_SMIME) return 1;
638 		/* Workaround for some buggy certificates */
639 		if(x->ex_nscert & NS_SSL_CLIENT) return 2;
640 		return 0;
641 	}
642 	return 1;
643 }
644 
check_purpose_smime_sign(const X509_PURPOSE * xp,const X509 * x,int ca)645 static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
646 {
647 	int ret;
648 	ret = purpose_smime(x, ca);
649 	if(!ret || ca) return ret;
650 	if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION)) return 0;
651 	return ret;
652 }
653 
check_purpose_smime_encrypt(const X509_PURPOSE * xp,const X509 * x,int ca)654 static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca)
655 {
656 	int ret;
657 	ret = purpose_smime(x, ca);
658 	if(!ret || ca) return ret;
659 	if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
660 	return ret;
661 }
662 
check_purpose_crl_sign(const X509_PURPOSE * xp,const X509 * x,int ca)663 static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
664 {
665 	if(ca) {
666 		int ca_ret;
667 		if((ca_ret = check_ca(x)) != 2) return ca_ret;
668 		else return 0;
669 	}
670 	if(ku_reject(x, KU_CRL_SIGN)) return 0;
671 	return 1;
672 }
673 
674 /* OCSP helper: this is *not* a full OCSP check. It just checks that
675  * each CA is valid. Additional checks must be made on the chain.
676  */
677 
ocsp_helper(const X509_PURPOSE * xp,const X509 * x,int ca)678 static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca)
679 {
680 	/* Must be a valid CA.  Should we really support the "I don't know"
681 	   value (2)? */
682 	if(ca) return check_ca(x);
683 	/* leaf certificate is checked in OCSP_verify() */
684 	return 1;
685 }
686 
check_purpose_timestamp_sign(const X509_PURPOSE * xp,const X509 * x,int ca)687 static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
688 					int ca)
689 {
690 	int i_ext;
691 
692 	/* If ca is true we must return if this is a valid CA certificate. */
693 	if (ca) return check_ca(x);
694 
695 	/*
696 	 * Check the optional key usage field:
697 	 * if Key Usage is present, it must be one of digitalSignature
698 	 * and/or nonRepudiation (other values are not consistent and shall
699 	 * be rejected).
700 	 */
701 	if ((x->ex_flags & EXFLAG_KUSAGE)
702 	    && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
703 		!(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
704 		return 0;
705 
706 	/* Only time stamp key usage is permitted and it's required. */
707 	if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
708 		return 0;
709 
710 	/* Extended Key Usage MUST be critical */
711 	i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, -1);
712 	if (i_ext >= 0)
713 		{
714 		X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
715 		if (!X509_EXTENSION_get_critical(ext))
716 			return 0;
717 		}
718 
719 	return 1;
720 }
721 
no_check(const X509_PURPOSE * xp,const X509 * x,int ca)722 static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
723 {
724 	return 1;
725 }
726 
727 /* Various checks to see if one certificate issued the second.
728  * This can be used to prune a set of possible issuer certificates
729  * which have been looked up using some simple method such as by
730  * subject name.
731  * These are:
732  * 1. Check issuer_name(subject) == subject_name(issuer)
733  * 2. If akid(subject) exists check it matches issuer
734  * 3. If key_usage(issuer) exists check it supports certificate signing
735  * returns 0 for OK, positive for reason for mismatch, reasons match
736  * codes for X509_verify_cert()
737  */
738 
X509_check_issued(X509 * issuer,X509 * subject)739 int X509_check_issued(X509 *issuer, X509 *subject)
740 {
741 	if(X509_NAME_cmp(X509_get_subject_name(issuer),
742 			X509_get_issuer_name(subject)))
743 				return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
744 	x509v3_cache_extensions(issuer);
745 	x509v3_cache_extensions(subject);
746 
747 	if(subject->akid)
748 		{
749 		int ret = X509_check_akid(issuer, subject->akid);
750 		if (ret != X509_V_OK)
751 			return ret;
752 		}
753 
754 	if(subject->ex_flags & EXFLAG_PROXY)
755 		{
756 		if(ku_reject(issuer, KU_DIGITAL_SIGNATURE))
757 			return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
758 		}
759 	else if(ku_reject(issuer, KU_KEY_CERT_SIGN))
760 		return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
761 	return X509_V_OK;
762 }
763 
X509_check_akid(X509 * issuer,AUTHORITY_KEYID * akid)764 int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
765 	{
766 
767 	if(!akid)
768 		return X509_V_OK;
769 
770 	/* Check key ids (if present) */
771 	if(akid->keyid && issuer->skid &&
772 		 ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid) )
773 				return X509_V_ERR_AKID_SKID_MISMATCH;
774 	/* Check serial number */
775 	if(akid->serial &&
776 		ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
777 				return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
778 	/* Check issuer name */
779 	if(akid->issuer)
780 		{
781 		/* Ugh, for some peculiar reason AKID includes
782 		 * SEQUENCE OF GeneralName. So look for a DirName.
783 		 * There may be more than one but we only take any
784 		 * notice of the first.
785 		 */
786 		GENERAL_NAMES *gens;
787 		GENERAL_NAME *gen;
788 		X509_NAME *nm = NULL;
789 		size_t i;
790 		gens = akid->issuer;
791 		for(i = 0; i < sk_GENERAL_NAME_num(gens); i++)
792 			{
793 			gen = sk_GENERAL_NAME_value(gens, i);
794 			if(gen->type == GEN_DIRNAME)
795 				{
796 				nm = gen->d.dirn;
797 				break;
798 				}
799 			}
800 		if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
801 			return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
802 		}
803 	return X509_V_OK;
804 	}
805 
806