GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/x509v3/v3_purp.c Lines: 137 349 39.3 %
Date: 2016-12-06 Branches: 85 289 29.4 %

Line Branch Exec Source
1
/* $OpenBSD: v3_purp.c,v 1.26 2015/02/10 13:28:17 jsing Exp $ */
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
 */
58
59
#include <stdio.h>
60
#include <string.h>
61
62
#include <openssl/opensslconf.h>
63
64
#include <openssl/err.h>
65
#include <openssl/x509v3.h>
66
#include <openssl/x509_vfy.h>
67
68
static void x509v3_cache_extensions(X509 *x);
69
70
static int check_ssl_ca(const X509 *x);
71
static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
72
    int ca);
73
static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
74
    int ca);
75
static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
76
    int ca);
77
static int purpose_smime(const X509 *x, int ca);
78
static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
79
    int ca);
80
static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x,
81
    int ca);
82
static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x,
83
    int ca);
84
static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
85
    int ca);
86
static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
87
static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca);
88
89
static int xp_cmp(const X509_PURPOSE * const *a, const X509_PURPOSE * const *b);
90
static void xptable_free(X509_PURPOSE *p);
91
92
static X509_PURPOSE xstandard[] = {
93
	{X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, check_purpose_ssl_client, "SSL client", "sslclient", NULL},
94
	{X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ssl_server, "SSL server", "sslserver", NULL},
95
	{X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL},
96
	{X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, "S/MIME signing", "smimesign", NULL},
97
	{X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL},
98
	{X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL},
99
	{X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", NULL},
100
	{X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, "OCSP helper", "ocsphelper", NULL},
101
	{X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", NULL},
102
};
103
104
#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE))
105
106
static STACK_OF(X509_PURPOSE) *xptable = NULL;
107
108
static int
109
xp_cmp(const X509_PURPOSE * const *a, const X509_PURPOSE * const *b)
110
{
111
	return (*a)->purpose - (*b)->purpose;
112
}
113
114
/* As much as I'd like to make X509_check_purpose use a "const" X509*
115
 * I really can't because it does recalculate hashes and do other non-const
116
 * things. */
117
int
118
X509_check_purpose(X509 *x, int id, int ca)
119
17
{
120
	int idx;
121
	const X509_PURPOSE *pt;
122
123
17
	if (!(x->ex_flags & EXFLAG_SET)) {
124
		CRYPTO_w_lock(CRYPTO_LOCK_X509);
125
		x509v3_cache_extensions(x);
126
		CRYPTO_w_unlock(CRYPTO_LOCK_X509);
127
	}
128
17
	if (id == -1)
129
8
		return 1;
130
9
	idx = X509_PURPOSE_get_by_id(id);
131
9
	if (idx == -1)
132
		return -1;
133
9
	pt = X509_PURPOSE_get0(idx);
134
9
	return pt->check_purpose(pt, x, ca);
135
}
136
137
int
138
X509_PURPOSE_set(int *p, int purpose)
139
{
140
	if (X509_PURPOSE_get_by_id(purpose) == -1) {
141
		X509V3err(X509V3_F_X509_PURPOSE_SET, X509V3_R_INVALID_PURPOSE);
142
		return 0;
143
	}
144
	*p = purpose;
145
	return 1;
146
}
147
148
int
149
X509_PURPOSE_get_count(void)
150
{
151
	if (!xptable)
152
		return X509_PURPOSE_COUNT;
153
	return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT;
154
}
155
156
X509_PURPOSE *
157
X509_PURPOSE_get0(int idx)
158
11
{
159
11
	if (idx < 0)
160
		return NULL;
161
11
	if (idx < (int)X509_PURPOSE_COUNT)
162
11
		return xstandard + idx;
163
	return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
164
}
165
166
int
167
X509_PURPOSE_get_by_sname(char *sname)
168
{
169
	int i;
170
	X509_PURPOSE *xptmp;
171
172
	for (i = 0; i < X509_PURPOSE_get_count(); i++) {
173
		xptmp = X509_PURPOSE_get0(i);
174
		if (!strcmp(xptmp->sname, sname))
175
			return i;
176
	}
177
	return -1;
178
}
179
180
int
181
X509_PURPOSE_get_by_id(int purpose)
182
11
{
183
	X509_PURPOSE tmp;
184
	int idx;
185
186
11
	if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
187
11
		return purpose - X509_PURPOSE_MIN;
188
	tmp.purpose = purpose;
189
	if (!xptable)
190
		return -1;
191
	idx = sk_X509_PURPOSE_find(xptable, &tmp);
192
	if (idx == -1)
193
		return -1;
194
	return idx + X509_PURPOSE_COUNT;
195
}
196
197
int
198
X509_PURPOSE_add(int id, int trust, int flags,
199
    int (*ck)(const X509_PURPOSE *, const X509 *, int), char *name,
200
    char *sname, void *arg)
201
{
202
	int idx;
203
	X509_PURPOSE *ptmp;
204
	char *name_dup, *sname_dup;
205
206
	name_dup = sname_dup = NULL;
207
208
	if (name == NULL || sname == NULL) {
209
		X509V3err(X509V3_F_X509_PURPOSE_ADD,
210
		    X509V3_R_INVALID_NULL_ARGUMENT);
211
		return 0;
212
	}
213
214
	/* This is set according to what we change: application can't set it */
215
	flags &= ~X509_PURPOSE_DYNAMIC;
216
	/* This will always be set for application modified trust entries */
217
	flags |= X509_PURPOSE_DYNAMIC_NAME;
218
	/* Get existing entry if any */
219
	idx = X509_PURPOSE_get_by_id(id);
220
	/* Need a new entry */
221
	if (idx == -1) {
222
		if ((ptmp = malloc(sizeof(X509_PURPOSE))) == NULL) {
223
			X509V3err(X509V3_F_X509_PURPOSE_ADD,
224
			    ERR_R_MALLOC_FAILURE);
225
			return 0;
226
		}
227
		ptmp->flags = X509_PURPOSE_DYNAMIC;
228
	} else
229
		ptmp = X509_PURPOSE_get0(idx);
230
231
	if ((name_dup = strdup(name)) == NULL)
232
		goto err;
233
	if ((sname_dup = strdup(sname)) == NULL)
234
		goto err;
235
236
	/* free existing name if dynamic */
237
	if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
238
		free(ptmp->name);
239
		free(ptmp->sname);
240
	}
241
	/* dup supplied name */
242
	ptmp->name = name_dup;
243
	ptmp->sname = sname_dup;
244
	/* Keep the dynamic flag of existing entry */
245
	ptmp->flags &= X509_PURPOSE_DYNAMIC;
246
	/* Set all other flags */
247
	ptmp->flags |= flags;
248
249
	ptmp->purpose = id;
250
	ptmp->trust = trust;
251
	ptmp->check_purpose = ck;
252
	ptmp->usr_data = arg;
253
254
	/* If its a new entry manage the dynamic table */
255
	if (idx == -1) {
256
		if (xptable == NULL &&
257
		    (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL)
258
			goto err;
259
		if (sk_X509_PURPOSE_push(xptable, ptmp) == 0)
260
			goto err;
261
	}
262
	return 1;
263
264
err:
265
	free(name_dup);
266
	free(sname_dup);
267
	if (idx == -1)
268
		free(ptmp);
269
	X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
270
	return 0;
271
}
272
273
static void
274
xptable_free(X509_PURPOSE *p)
275
{
276
	if (!p)
277
		return;
278
	if (p->flags & X509_PURPOSE_DYNAMIC) {
279
		if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
280
			free(p->name);
281
			free(p->sname);
282
		}
283
		free(p);
284
	}
285
}
286
287
void
288
X509_PURPOSE_cleanup(void)
289
{
290
	unsigned int i;
291
292
	sk_X509_PURPOSE_pop_free(xptable, xptable_free);
293
	for(i = 0; i < X509_PURPOSE_COUNT; i++)
294
		xptable_free(xstandard + i);
295
	xptable = NULL;
296
}
297
298
int
299
X509_PURPOSE_get_id(X509_PURPOSE *xp)
300
{
301
	return xp->purpose;
302
}
303
304
char *
305
X509_PURPOSE_get0_name(X509_PURPOSE *xp)
306
{
307
	return xp->name;
308
}
309
310
char *
311
X509_PURPOSE_get0_sname(X509_PURPOSE *xp)
312
{
313
	return xp->sname;
314
}
315
316
int
317
X509_PURPOSE_get_trust(X509_PURPOSE *xp)
318
{
319
	return xp->trust;
320
}
321
322
static int
323
nid_cmp(const int *a, const int *b)
324
52
{
325
52
	return *a - *b;
326
}
327
328
DECLARE_OBJ_BSEARCH_CMP_FN(int, int, nid);
329
67
IMPLEMENT_OBJ_BSEARCH_CMP_FN(int, int, nid);
330
331
int
332
X509_supported_extension(X509_EXTENSION *ex)
333
15
{
334
	/* This table is a list of the NIDs of supported extensions:
335
	 * that is those which are used by the verify process. If
336
	 * an extension is critical and doesn't appear in this list
337
	 * then the verify process will normally reject the certificate.
338
	 * The list must be kept in numerical order because it will be
339
	 * searched using bsearch.
340
	 */
341
342
	static const int supported_nids[] = {
343
		NID_netscape_cert_type, /* 71 */
344
		NID_key_usage,		/* 83 */
345
		NID_subject_alt_name,	/* 85 */
346
		NID_basic_constraints,	/* 87 */
347
		NID_certificate_policies, /* 89 */
348
		NID_ext_key_usage,	/* 126 */
349
		NID_policy_constraints,	/* 401 */
350
		NID_proxyCertInfo,	/* 663 */
351
		NID_name_constraints,	/* 666 */
352
		NID_policy_mappings,	/* 747 */
353
		NID_inhibit_any_policy	/* 748 */
354
	};
355
356
15
	int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
357
358
15
	if (ex_nid == NID_undef)
359
		return 0;
360
361
15
	if (OBJ_bsearch_nid(&ex_nid, supported_nids,
362
	    sizeof(supported_nids) / sizeof(int)))
363
15
		return 1;
364
	return 0;
365
}
366
367
static void
368
setup_dp(X509 *x, DIST_POINT *dp)
369
5
{
370
5
	X509_NAME *iname = NULL;
371
	int i;
372
373
5
	if (dp->reasons) {
374
		if (dp->reasons->length > 0)
375
			dp->dp_reasons = dp->reasons->data[0];
376
		if (dp->reasons->length > 1)
377
			dp->dp_reasons |= (dp->reasons->data[1] << 8);
378
		dp->dp_reasons &= CRLDP_ALL_REASONS;
379
	} else
380
5
		dp->dp_reasons = CRLDP_ALL_REASONS;
381

5
	if (!dp->distpoint || (dp->distpoint->type != 1))
382
		return;
383
	for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
384
		GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
385
		if (gen->type == GEN_DIRNAME) {
386
			iname = gen->d.directoryName;
387
			break;
388
		}
389
	}
390
	if (!iname)
391
		iname = X509_get_issuer_name(x);
392
393
	DIST_POINT_set_dpname(dp->distpoint, iname);
394
395
}
396
397
static void
398
setup_crldp(X509 *x)
399
8
{
400
	int i;
401
402
8
	x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
403
13
	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
404
5
		setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
405
8
}
406
407
static void
408
x509v3_cache_extensions(X509 *x)
409
39
{
410
	BASIC_CONSTRAINTS *bs;
411
	PROXY_CERT_INFO_EXTENSION *pci;
412
	ASN1_BIT_STRING *usage;
413
	ASN1_BIT_STRING *ns;
414
	EXTENDED_KEY_USAGE *extusage;
415
	X509_EXTENSION *ex;
416
417
	int i;
418
39
	if (x->ex_flags & EXFLAG_SET)
419
31
		return;
420
#ifndef OPENSSL_NO_SHA
421
8
	X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
422
#endif
423
	/* Does subject name match issuer ? */
424
8
	if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
425
2
		x->ex_flags |= EXFLAG_SI;
426
	/* V1 should mean no extensions ... */
427
8
	if (!X509_get_version(x))
428
		x->ex_flags |= EXFLAG_V1;
429
	/* Handle basic constraints */
430
8
	if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
431
8
		if (bs->ca)
432
4
			x->ex_flags |= EXFLAG_CA;
433
8
		if (bs->pathlen) {
434

2
			if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) ||
435
			    !bs->ca) {
436
				x->ex_flags |= EXFLAG_INVALID;
437
				x->ex_pathlen = 0;
438
			} else
439
2
				x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
440
		} else
441
6
			x->ex_pathlen = -1;
442
8
		BASIC_CONSTRAINTS_free(bs);
443
8
		x->ex_flags |= EXFLAG_BCONS;
444
	}
445
	/* Handle proxy certificates */
446
8
	if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
447
		if (x->ex_flags & EXFLAG_CA ||
448
		    X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0 ||
449
		    X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
450
			x->ex_flags |= EXFLAG_INVALID;
451
		}
452
		if (pci->pcPathLengthConstraint) {
453
			x->ex_pcpathlen =
454
			    ASN1_INTEGER_get(pci->pcPathLengthConstraint);
455
		} else
456
			x->ex_pcpathlen = -1;
457
		PROXY_CERT_INFO_EXTENSION_free(pci);
458
		x->ex_flags |= EXFLAG_PROXY;
459
	}
460
	/* Handle key usage */
461
8
	if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
462
8
		if (usage->length > 0) {
463
8
			x->ex_kusage = usage->data[0];
464
8
			if (usage->length > 1)
465
				x->ex_kusage |= usage->data[1] << 8;
466
		} else
467
			x->ex_kusage = 0;
468
8
		x->ex_flags |= EXFLAG_KUSAGE;
469
8
		ASN1_BIT_STRING_free(usage);
470
	}
471
8
	x->ex_xkusage = 0;
472
8
	if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
473
3
		x->ex_flags |= EXFLAG_XKUSAGE;
474
8
		for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
475


5
			switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) {
476
			case NID_server_auth:
477
2
				x->ex_xkusage |= XKU_SSL_SERVER;
478
2
				break;
479
480
			case NID_client_auth:
481
2
				x->ex_xkusage |= XKU_SSL_CLIENT;
482
2
				break;
483
484
			case NID_email_protect:
485
				x->ex_xkusage |= XKU_SMIME;
486
				break;
487
488
			case NID_code_sign:
489
				x->ex_xkusage |= XKU_CODE_SIGN;
490
				break;
491
492
			case NID_ms_sgc:
493
			case NID_ns_sgc:
494
				x->ex_xkusage |= XKU_SGC;
495
				break;
496
497
			case NID_OCSP_sign:
498
1
				x->ex_xkusage |= XKU_OCSP_SIGN;
499
1
				break;
500
501
			case NID_time_stamp:
502
				x->ex_xkusage |= XKU_TIMESTAMP;
503
				break;
504
505
			case NID_dvcs:
506
				x->ex_xkusage |= XKU_DVCS;
507
				break;
508
			}
509
		}
510
3
		sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
511
	}
512
513
8
	if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
514
		if (ns->length > 0)
515
			x->ex_nscert = ns->data[0];
516
		else
517
			x->ex_nscert = 0;
518
		x->ex_flags |= EXFLAG_NSCERT;
519
		ASN1_BIT_STRING_free(ns);
520
	}
521
522
8
	x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
523
8
	x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
524
8
	x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
525
8
	x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
526

8
	if (!x->nc && (i != -1))
527
		x->ex_flags |= EXFLAG_INVALID;
528
8
	setup_crldp(x);
529
530
61
	for (i = 0; i < X509_get_ext_count(x); i++) {
531
53
		ex = X509_get_ext(x, i);
532
53
		if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) ==
533
		    NID_freshest_crl)
534
			x->ex_flags |= EXFLAG_FRESHEST;
535
53
		if (!X509_EXTENSION_get_critical(ex))
536
38
			continue;
537
15
		if (!X509_supported_extension(ex)) {
538
			x->ex_flags |= EXFLAG_CRITICAL;
539
			break;
540
		}
541
	}
542
8
	x->ex_flags |= EXFLAG_SET;
543
}
544
545
/* CA checks common to all purposes
546
 * return codes:
547
 * 0 not a CA
548
 * 1 is a CA
549
 * 2 basicConstraints absent so "maybe" a CA
550
 * 3 basicConstraints absent but self signed V1.
551
 * 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
552
 */
553
554
#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
555
#define ku_reject(x, usage) \
556
	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
557
#define xku_reject(x, usage) \
558
	(((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
559
#define ns_reject(x, usage) \
560
	(((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
561
562
static int
563
check_ca(const X509 *x)
564
12
{
565
	/* keyUsage if present should allow cert signing */
566

12
	if (ku_reject(x, KU_KEY_CERT_SIGN))
567
5
		return 0;
568
7
	if (x->ex_flags & EXFLAG_BCONS) {
569
7
		if (x->ex_flags & EXFLAG_CA)
570
7
			return 1;
571
		/* If basicConstraints says not a CA then say so */
572
		else
573
			return 0;
574
	} else {
575
		/* we support V1 roots for...  uh, I don't really know why. */
576
		if ((x->ex_flags & V1_ROOT) == V1_ROOT)
577
			return 3;
578
		/* If key usage present it must have certSign so tolerate it */
579
		else if (x->ex_flags & EXFLAG_KUSAGE)
580
			return 4;
581
		/* Older certificates could have Netscape-specific CA types */
582
		else if (x->ex_flags & EXFLAG_NSCERT &&
583
		    x->ex_nscert & NS_ANY_CA)
584
			return 5;
585
		/* can this still be regarded a CA certificate?  I doubt it */
586
		return 0;
587
	}
588
}
589
590
int
591
X509_check_ca(X509 *x)
592
9
{
593
9
	if (!(x->ex_flags & EXFLAG_SET)) {
594
1
		CRYPTO_w_lock(CRYPTO_LOCK_X509);
595
1
		x509v3_cache_extensions(x);
596
1
		CRYPTO_w_unlock(CRYPTO_LOCK_X509);
597
	}
598
599
9
	return check_ca(x);
600
}
601
602
/* Check SSL CA: common checks for SSL client and server */
603
static int
604
check_ssl_ca(const X509 *x)
605
2
{
606
	int ca_ret;
607
608
2
	ca_ret = check_ca(x);
609
2
	if (!ca_ret)
610
		return 0;
611
	/* check nsCertType if present */
612

2
	if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA)
613
2
		return ca_ret;
614
	else
615
		return 0;
616
}
617
618
static int
619
check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca)
620
{
621
	if (xku_reject(x, XKU_SSL_CLIENT))
622
		return 0;
623
	if (ca)
624
		return check_ssl_ca(x);
625
	/* We need to do digital signatures with it */
626
	if (ku_reject(x, KU_DIGITAL_SIGNATURE))
627
		return 0;
628
	/* nsCertType if present should allow SSL client use */
629
	if (ns_reject(x, NS_SSL_CLIENT))
630
		return 0;
631
	return 1;
632
}
633
634
static int
635
check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
636
4
{
637

4
	if (xku_reject(x, XKU_SSL_SERVER|XKU_SGC))
638
		return 0;
639
4
	if (ca)
640
2
		return check_ssl_ca(x);
641
642

2
	if (ns_reject(x, NS_SSL_SERVER))
643
		return 0;
644
	/* Now as for keyUsage: we'll at least need to sign OR encipher */
645

2
	if (ku_reject(x, KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT))
646
		return 0;
647
648
2
	return 1;
649
}
650
651
static int
652
check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
653
{
654
	int ret;
655
656
	ret = check_purpose_ssl_server(xp, x, ca);
657
	if (!ret || ca)
658
		return ret;
659
	/* We need to encipher or Netscape complains */
660
	if (ku_reject(x, KU_KEY_ENCIPHERMENT))
661
		return 0;
662
	return ret;
663
}
664
665
/* common S/MIME checks */
666
static int
667
purpose_smime(const X509 *x, int ca)
668
2
{
669

2
	if (xku_reject(x, XKU_SMIME))
670
		return 0;
671
2
	if (ca) {
672
		int ca_ret;
673
		ca_ret = check_ca(x);
674
		if (!ca_ret)
675
			return 0;
676
		/* check nsCertType if present */
677
		if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA)
678
			return ca_ret;
679
		else
680
			return 0;
681
	}
682
2
	if (x->ex_flags & EXFLAG_NSCERT) {
683
		if (x->ex_nscert & NS_SMIME)
684
			return 1;
685
		/* Workaround for some buggy certificates */
686
		if (x->ex_nscert & NS_SSL_CLIENT)
687
			return 2;
688
		return 0;
689
	}
690
2
	return 1;
691
}
692
693
static int
694
check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
695
2
{
696
	int ret;
697
698
2
	ret = purpose_smime(x, ca);
699
2
	if (!ret || ca)
700
		return ret;
701

2
	if (ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION))
702
		return 0;
703
2
	return ret;
704
}
705
706
static int
707
check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca)
708
{
709
	int ret;
710
711
	ret = purpose_smime(x, ca);
712
	if (!ret || ca)
713
		return ret;
714
	if (ku_reject(x, KU_KEY_ENCIPHERMENT))
715
		return 0;
716
	return ret;
717
}
718
719
static int
720
check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
721
{
722
	if (ca) {
723
		int ca_ret;
724
		if ((ca_ret = check_ca(x)) != 2)
725
			return ca_ret;
726
		else
727
			return 0;
728
	}
729
	if (ku_reject(x, KU_CRL_SIGN))
730
		return 0;
731
	return 1;
732
}
733
734
/* OCSP helper: this is *not* a full OCSP check. It just checks that
735
 * each CA is valid. Additional checks must be made on the chain.
736
 */
737
static int
738
ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca)
739
3
{
740
	/* Must be a valid CA.  Should we really support the "I don't know"
741
	   value (2)? */
742
3
	if (ca)
743
1
		return check_ca(x);
744
	/* leaf certificate is checked in OCSP_verify() */
745
2
	return 1;
746
}
747
748
static int
749
check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
750
{
751
	int i_ext;
752
753
	/* If ca is true we must return if this is a valid CA certificate. */
754
	if (ca)
755
		return check_ca(x);
756
757
	/*
758
	 * Check the optional key usage field:
759
	 * if Key Usage is present, it must be one of digitalSignature
760
	 * and/or nonRepudiation (other values are not consistent and shall
761
	 * be rejected).
762
	 */
763
	if ((x->ex_flags & EXFLAG_KUSAGE) &&
764
	    ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
765
	    !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
766
		return 0;
767
768
	/* Only time stamp key usage is permitted and it's required. */
769
	if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
770
		return 0;
771
772
	/* Extended Key Usage MUST be critical */
773
	i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, -1);
774
	if (i_ext >= 0) {
775
		X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
776
		if (!X509_EXTENSION_get_critical(ext))
777
			return 0;
778
	}
779
780
	return 1;
781
}
782
783
static int
784
no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
785
{
786
	return 1;
787
}
788
789
/* Various checks to see if one certificate issued the second.
790
 * This can be used to prune a set of possible issuer certificates
791
 * which have been looked up using some simple method such as by
792
 * subject name.
793
 * These are:
794
 * 1. Check issuer_name(subject) == subject_name(issuer)
795
 * 2. If akid(subject) exists check it matches issuer
796
 * 3. If key_usage(issuer) exists check it supports certificate signing
797
 * returns 0 for OK, positive for reason for mismatch, reasons match
798
 * codes for X509_verify_cert()
799
 */
800
801
int
802
X509_check_issued(X509 *issuer, X509 *subject)
803
55
{
804
55
	if (X509_NAME_cmp(X509_get_subject_name(issuer),
805
	    X509_get_issuer_name(subject)))
806
36
		return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
807
19
	x509v3_cache_extensions(issuer);
808
19
	x509v3_cache_extensions(subject);
809
810
19
	if (subject->akid) {
811
13
		int ret = X509_check_akid(issuer, subject->akid);
812
13
		if (ret != X509_V_OK)
813
			return ret;
814
	}
815
816
19
	if (subject->ex_flags & EXFLAG_PROXY) {
817
		if (ku_reject(issuer, KU_DIGITAL_SIGNATURE))
818
			return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
819

19
	} else if (ku_reject(issuer, KU_KEY_CERT_SIGN))
820
		return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
821
19
	return X509_V_OK;
822
}
823
824
int
825
X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
826
13
{
827
13
	if (!akid)
828
		return X509_V_OK;
829
830
	/* Check key ids (if present) */
831

13
	if (akid->keyid && issuer->skid &&
832
	    ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid) )
833
		return X509_V_ERR_AKID_SKID_MISMATCH;
834
	/* Check serial number */
835

13
	if (akid->serial &&
836
	    ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
837
		return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
838
	/* Check issuer name */
839
13
	if (akid->issuer) {
840
		/* Ugh, for some peculiar reason AKID includes
841
		 * SEQUENCE OF GeneralName. So look for a DirName.
842
		 * There may be more than one but we only take any
843
		 * notice of the first.
844
		 */
845
		GENERAL_NAMES *gens;
846
		GENERAL_NAME *gen;
847
		X509_NAME *nm = NULL;
848
		int i;
849
		gens = akid->issuer;
850
		for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
851
			gen = sk_GENERAL_NAME_value(gens, i);
852
			if (gen->type == GEN_DIRNAME) {
853
				nm = gen->d.dirn;
854
				break;
855
			}
856
		}
857
		if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
858
			return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
859
	}
860
13
	return X509_V_OK;
861
}