xref: /openbsd-src/lib/libcrypto/x509/x509_verify.c (revision d2c5a4743fb945f45b034a3a830a96f7e1bc695d)
1 /* $OpenBSD: x509_verify.c,v 1.16 2020/10/26 12:01:01 tb Exp $ */
2 /*
3  * Copyright (c) 2020 Bob Beck <beck@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /* x509_verify - inspired by golang's crypto/x509/Verify */
19 
20 #include <errno.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <time.h>
24 #include <unistd.h>
25 
26 #include <openssl/safestack.h>
27 #include <openssl/x509.h>
28 #include <openssl/x509v3.h>
29 
30 #include "x509_internal.h"
31 #include "x509_issuer_cache.h"
32 
33 static int x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert,
34     struct x509_verify_chain *current_chain);
35 static void x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
36     struct x509_verify_chain *current_chain);
37 static int x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert,
38     size_t depth, int error, int ok);
39 static void x509_verify_chain_free(struct x509_verify_chain *chain);
40 
41 #define X509_VERIFY_CERT_HASH (EVP_sha512())
42 
43 struct x509_verify_chain *
44 x509_verify_chain_new(void)
45 {
46 	struct x509_verify_chain *chain;
47 
48 	if ((chain = calloc(1, sizeof(*chain))) == NULL)
49 		goto err;
50 	if ((chain->certs = sk_X509_new_null()) == NULL)
51 		goto err;
52 	if ((chain->names = x509_constraints_names_new()) == NULL)
53 		goto err;
54 
55 	return chain;
56  err:
57 	x509_verify_chain_free(chain);
58 	return NULL;
59 }
60 
61 static void
62 x509_verify_chain_clear(struct x509_verify_chain *chain)
63 {
64 	sk_X509_pop_free(chain->certs, X509_free);
65 	chain->certs = NULL;
66 	x509_constraints_names_free(chain->names);
67 	chain->names = NULL;
68 }
69 
70 static void
71 x509_verify_chain_free(struct x509_verify_chain *chain)
72 {
73 	if (chain == NULL)
74 		return;
75 	x509_verify_chain_clear(chain);
76 	free(chain);
77 }
78 
79 static struct x509_verify_chain *
80 x509_verify_chain_dup(struct x509_verify_chain *chain)
81 {
82 	struct x509_verify_chain *new_chain;
83 
84 	if ((new_chain = x509_verify_chain_new()) == NULL)
85 		goto err;
86 	if ((new_chain->certs = X509_chain_up_ref(chain->certs)) == NULL)
87 		goto err;
88 	if ((new_chain->names =
89 	    x509_constraints_names_dup(chain->names)) == NULL)
90 		goto err;
91 	return(new_chain);
92  err:
93 	x509_verify_chain_free(new_chain);
94 	return NULL;
95 }
96 
97 static int
98 x509_verify_chain_append(struct x509_verify_chain *chain, X509 *cert,
99     int *error)
100 {
101 	int verify_err = X509_V_ERR_UNSPECIFIED;
102 
103 	if (!x509_constraints_extract_names(chain->names, cert,
104 	    sk_X509_num(chain->certs) == 0, &verify_err)) {
105 		*error = verify_err;
106 		return 0;
107 	}
108 	X509_up_ref(cert);
109 	if (!sk_X509_push(chain->certs, cert)) {
110 		X509_free(cert);
111 		*error = X509_V_ERR_OUT_OF_MEM;
112 		return 0;
113 	}
114 	return 1;
115 }
116 
117 static X509 *
118 x509_verify_chain_last(struct x509_verify_chain *chain)
119 {
120 	int last;
121 
122 	if (chain->certs == NULL)
123 		return NULL;
124 	if ((last = sk_X509_num(chain->certs) - 1) < 0)
125 		return NULL;
126 	return sk_X509_value(chain->certs, last);
127 }
128 
129 X509 *
130 x509_verify_chain_leaf(struct x509_verify_chain *chain)
131 {
132 	if (chain->certs == NULL)
133 		return NULL;
134 	return sk_X509_value(chain->certs, 0);
135 }
136 
137 static void
138 x509_verify_ctx_reset(struct x509_verify_ctx *ctx)
139 {
140 	size_t i;
141 
142 	for (i = 0; i < ctx->chains_count; i++)
143 		x509_verify_chain_free(ctx->chains[i]);
144 	ctx->error = 0;
145 	ctx->error_depth = 0;
146 	ctx->chains_count = 0;
147 	ctx->sig_checks = 0;
148 	ctx->check_time = NULL;
149 }
150 
151 static void
152 x509_verify_ctx_clear(struct x509_verify_ctx *ctx)
153 {
154 	x509_verify_ctx_reset(ctx);
155 	sk_X509_pop_free(ctx->intermediates, X509_free);
156 	free(ctx->chains);
157 	memset(ctx, 0, sizeof(*ctx));
158 }
159 
160 static int
161 x509_verify_ctx_cert_is_root(struct x509_verify_ctx *ctx, X509 *cert)
162 {
163 	int i;
164 
165 	for (i = 0; i < sk_X509_num(ctx->roots); i++) {
166 		if (X509_cmp(sk_X509_value(ctx->roots, i), cert) == 0)
167 			return 1;
168 	}
169 	return 0;
170 }
171 
172 static int
173 x509_verify_ctx_set_xsc_chain(struct x509_verify_ctx *ctx,
174     struct x509_verify_chain *chain)
175 {
176 	size_t depth;
177 	X509 *last = x509_verify_chain_last(chain);
178 
179 	if (ctx->xsc == NULL)
180 		return 1;
181 
182 	depth = sk_X509_num(chain->certs);
183 	if (depth > 0)
184 		depth--;
185 
186 	ctx->xsc->last_untrusted = depth ? depth - 1 : 0;
187 	sk_X509_pop_free(ctx->xsc->chain, X509_free);
188 	ctx->xsc->chain = X509_chain_up_ref(chain->certs);
189 	if (ctx->xsc->chain == NULL)
190 		return x509_verify_cert_error(ctx, last, depth,
191 		    X509_V_ERR_OUT_OF_MEM, 0);
192 	return 1;
193 }
194 
195 /* Add a validated chain to our list of valid chains */
196 static int
197 x509_verify_ctx_add_chain(struct x509_verify_ctx *ctx,
198     struct x509_verify_chain *chain)
199 {
200 	size_t depth;
201 	X509 *last = x509_verify_chain_last(chain);
202 
203 	depth = sk_X509_num(chain->certs);
204 	if (depth > 0)
205 		depth--;
206 
207 	if (ctx->chains_count >= ctx->max_chains)
208 		return x509_verify_cert_error(ctx, last, depth,
209 		    X509_V_ERR_CERT_CHAIN_TOO_LONG, 0);
210 
211 	/*
212 	 * If we have a legacy xsc, choose a validated chain,
213 	 * and apply the extensions, revocation, and policy checks
214 	 * just like the legacy code did. We do this here instead
215 	 * of as building the chains to more easily support the
216 	 * callback and the bewildering array of VERIFY_PARAM
217 	 * knobs that are there for the fiddling.
218 	 */
219 	if (ctx->xsc != NULL) {
220 		if (!x509_verify_ctx_set_xsc_chain(ctx, chain))
221 			return 0;
222 
223 		/*
224 		 * XXX currently this duplicates some work done
225 		 * in chain build, but we keep it here until
226 		 * we have feature parity
227 		 */
228 		if (!x509_vfy_check_chain_extensions(ctx->xsc))
229 			return 0;
230 
231 		if (!x509_constraints_chain(ctx->xsc->chain,
232 		    &ctx->xsc->error, &ctx->xsc->error_depth)) {
233 			X509 *cert = sk_X509_value(ctx->xsc->chain, depth);
234 			if (!x509_verify_cert_error(ctx, cert,
235 			    ctx->xsc->error_depth, ctx->xsc->error, 0))
236 				return 0;
237 		}
238 
239 		if (!x509_vfy_check_revocation(ctx->xsc))
240 			return 0;
241 
242 		if (!x509_vfy_check_policy(ctx->xsc))
243 			return 0;
244 	}
245 	/*
246 	 * no xsc means we are being called from the non-legacy API,
247 	 * extensions and purpose are dealt with as the chain is built.
248 	 *
249 	 * The non-legacy api returns multiple chains but does not do
250 	 * any revocation checking (it must be done by the caller on
251 	 * any chain they wish to use)
252 	 */
253 
254 	if ((ctx->chains[ctx->chains_count] = x509_verify_chain_dup(chain)) ==
255 	    NULL) {
256 		return x509_verify_cert_error(ctx, last, depth,
257 		    X509_V_ERR_OUT_OF_MEM, 0);
258 	}
259 	ctx->chains_count++;
260 	ctx->error = X509_V_OK;
261 	ctx->error_depth = depth;
262 	return 1;
263 }
264 
265 static int
266 x509_verify_potential_parent(struct x509_verify_ctx *ctx, X509 *parent,
267     X509 *child)
268 {
269 	if (ctx->xsc != NULL)
270 		return (ctx->xsc->check_issued(ctx->xsc, child, parent));
271 
272 	/* XXX key usage */
273 	return X509_check_issued(child, parent) != X509_V_OK;
274 }
275 
276 static int
277 x509_verify_parent_signature(X509 *parent, X509 *child,
278     unsigned char *child_md, int *error)
279 {
280 	unsigned char parent_md[EVP_MAX_MD_SIZE] = { 0 };
281 	EVP_PKEY *pkey;
282 	int cached;
283 	int ret = 0;
284 
285 	/* Use cached value if we have it */
286 	if (child_md != NULL) {
287 		if (!X509_digest(parent, X509_VERIFY_CERT_HASH, parent_md,
288 		    NULL))
289 			return 0;
290 		if ((cached = x509_issuer_cache_find(parent_md, child_md)) >= 0)
291 			return cached;
292 	}
293 
294 	/* Check signature. Did parent sign child? */
295 	if ((pkey = X509_get_pubkey(parent)) == NULL) {
296 		*error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
297 		return 0;
298 	}
299 	if (X509_verify(child, pkey) <= 0)
300 		*error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
301 	else
302 		ret = 1;
303 
304 	/* Add result to cache */
305 	if (child_md != NULL)
306 		x509_issuer_cache_add(parent_md, child_md, ret);
307 
308 	EVP_PKEY_free(pkey);
309 
310 	return ret;
311 }
312 
313 static int
314 x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert,
315     unsigned char *cert_md, int is_root_cert, X509 *candidate,
316     struct x509_verify_chain *current_chain)
317 {
318 	int depth = sk_X509_num(current_chain->certs);
319 	struct x509_verify_chain *new_chain;
320 	int i;
321 
322 	/* Fail if the certificate is already in the chain */
323 	for (i = 0; i < sk_X509_num(current_chain->certs); i++) {
324 		if (X509_cmp(sk_X509_value(current_chain->certs, i),
325 		    candidate) == 0)
326 			return 0;
327 	}
328 
329 	if (ctx->sig_checks++ > X509_VERIFY_MAX_SIGCHECKS) {
330 		/* don't allow callback to override safety check */
331 		(void) x509_verify_cert_error(ctx, candidate, depth,
332 		    X509_V_ERR_CERT_CHAIN_TOO_LONG, 0);
333 		return 0;
334 	}
335 
336 
337 	if (!x509_verify_parent_signature(candidate, cert, cert_md,
338 	    &ctx->error)) {
339 		    if (!x509_verify_cert_error(ctx, candidate, depth,
340 			ctx->error, 0))
341 			    return 0;
342 	}
343 
344 	if (!x509_verify_cert_valid(ctx, candidate, current_chain))
345 		return 0;
346 
347 	/* candidate is good, add it to a copy of the current chain */
348 	if ((new_chain = x509_verify_chain_dup(current_chain)) == NULL) {
349 		x509_verify_cert_error(ctx, candidate, depth,
350 		    X509_V_ERR_OUT_OF_MEM, 0);
351 		return 0;
352 	}
353 	if (!x509_verify_chain_append(new_chain, candidate, &ctx->error)) {
354 		x509_verify_cert_error(ctx, candidate, depth,
355 		    ctx->error, 0);
356 		x509_verify_chain_free(new_chain);
357 		return 0;
358 	}
359 
360 	/*
361 	 * If candidate is a trusted root, we have a validated chain,
362 	 * so we save it.  Otherwise, recurse until we find a root or
363 	 * give up.
364 	 */
365 	if (is_root_cert) {
366 		if (!x509_verify_ctx_set_xsc_chain(ctx, new_chain)) {
367 			x509_verify_chain_free(new_chain);
368 			return 0;
369 		}
370 		if (x509_verify_cert_error(ctx, candidate, depth, X509_V_OK, 1)) {
371 			(void) x509_verify_ctx_add_chain(ctx, new_chain);
372 			goto done;
373 		}
374 	}
375 
376 	x509_verify_build_chains(ctx, candidate, new_chain);
377 
378  done:
379 	x509_verify_chain_free(new_chain);
380 	return 1;
381 }
382 
383 static int
384 x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, size_t depth,
385     int error, int ok)
386 {
387 	ctx->error = error;
388 	ctx->error_depth = depth;
389 	if (ctx->xsc != NULL) {
390 		ctx->xsc->error = error;
391 		ctx->xsc->error_depth = depth;
392 		ctx->xsc->current_cert = cert;
393 		return ctx->xsc->verify_cb(ok, ctx->xsc);
394 	}
395 	return ok;
396 }
397 
398 static void
399 x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
400     struct x509_verify_chain *current_chain)
401 {
402 	unsigned char cert_md[EVP_MAX_MD_SIZE] = { 0 };
403 	X509 *candidate;
404 	int i, depth, count;
405 
406 	depth = sk_X509_num(current_chain->certs);
407 	if (depth > 0)
408 		depth--;
409 
410 	if (depth >= ctx->max_depth &&
411 	    !x509_verify_cert_error(ctx, cert, depth,
412 		X509_V_ERR_CERT_CHAIN_TOO_LONG, 0))
413 		return;
414 
415 	if (!X509_digest(cert, X509_VERIFY_CERT_HASH, cert_md, NULL) &&
416 	    !x509_verify_cert_error(ctx, cert, depth,
417 		X509_V_ERR_UNSPECIFIED, 0))
418 		return;
419 
420 	count = ctx->chains_count;
421 	ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
422 	ctx->error_depth = depth;
423 
424 	for (i = 0; i < sk_X509_num(ctx->roots); i++) {
425 		candidate = sk_X509_value(ctx->roots, i);
426 		if (x509_verify_potential_parent(ctx, candidate, cert)) {
427 			x509_verify_consider_candidate(ctx, cert,
428 			    cert_md, 1, candidate, current_chain);
429 		}
430 	}
431 
432 	if (ctx->intermediates != NULL) {
433 		for (i = 0; i < sk_X509_num(ctx->intermediates); i++) {
434 			candidate = sk_X509_value(ctx->intermediates, i);
435 			if (x509_verify_potential_parent(ctx, candidate, cert)) {
436 				x509_verify_consider_candidate(ctx, cert,
437 				    cert_md, 0, candidate, current_chain);
438 			}
439 		}
440 	}
441 	if (ctx->chains_count > count) {
442 		if (ctx->xsc != NULL) {
443 			ctx->xsc->error = X509_V_OK;
444 			ctx->xsc->error_depth = depth;
445 			ctx->xsc->current_cert = cert;
446 			(void) ctx->xsc->verify_cb(1, ctx->xsc);
447 		}
448 	} else if (ctx->error_depth == depth) {
449 			(void) x509_verify_cert_error(ctx, cert, depth,
450 			    ctx->error, 0);
451 	}
452 }
453 
454 static int
455 x509_verify_cert_hostname(struct x509_verify_ctx *ctx, X509 *cert, char *name)
456 {
457 	char *candidate;
458 	size_t len;
459 
460 	if (name == NULL) {
461 		if (ctx->xsc != NULL) {
462 			int ret;
463 
464 			if ((ret = x509_vfy_check_id(ctx->xsc)) == 0)
465 				ctx->error = ctx->xsc->error;
466 			return ret;
467 		}
468 		return 1;
469 	}
470 	if ((candidate = strdup(name)) == NULL) {
471 		ctx->error = X509_V_ERR_OUT_OF_MEM;
472 		goto err;
473 	}
474 	if ((len = strlen(candidate)) < 1) {
475 		ctx->error = X509_V_ERR_UNSPECIFIED; /* XXX */
476 		goto err;
477 	}
478 
479 	/* IP addresses may be written in [ ]. */
480 	if (candidate[0] == '[' && candidate[len - 1] == ']') {
481 		candidate[len - 1] = '\0';
482 		if (X509_check_ip_asc(cert, candidate + 1, 0) <= 0) {
483 			ctx->error = X509_V_ERR_IP_ADDRESS_MISMATCH;
484 			goto err;
485 		}
486 	} else {
487 		int flags = 0;
488 
489 		if (ctx->xsc == NULL)
490 			flags = X509_CHECK_FLAG_NEVER_CHECK_SUBJECT;
491 
492 		if (X509_check_host(cert, candidate, len, flags, NULL) <= 0) {
493 			ctx->error = X509_V_ERR_HOSTNAME_MISMATCH;
494 			goto err;
495 		}
496 	}
497 	free(candidate);
498 	return 1;
499  err:
500 	free(candidate);
501 	return x509_verify_cert_error(ctx, cert, 0, ctx->error, 0);
502 }
503 
504 static int
505 x509_verify_set_check_time(struct x509_verify_ctx *ctx) {
506 	if (ctx->xsc != NULL)  {
507 		if (ctx->xsc->param->flags & X509_V_FLAG_USE_CHECK_TIME) {
508 			ctx->check_time = &ctx->xsc->param->check_time;
509 			return 1;
510 		}
511 		if (ctx->xsc->param->flags & X509_V_FLAG_NO_CHECK_TIME)
512 			return 0;
513 	}
514 
515 	ctx->check_time = NULL;
516 	return 1;
517 }
518 
519 int
520 x509_verify_asn1_time_to_tm(const ASN1_TIME *atime, struct tm *tm, int notafter)
521 {
522 	int type;
523 
524 	memset(tm, 0, sizeof(*tm));
525 
526 	type = ASN1_time_parse(atime->data, atime->length, tm, atime->type);
527 	if (type == -1)
528 		return 0;
529 
530 	/* RFC 5280 section 4.1.2.5 */
531 	if (tm->tm_year < 150 && type != V_ASN1_UTCTIME)
532 		return 0;
533 	if (tm->tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME)
534 		return 0;
535 
536 	if (notafter) {
537 		/*
538 		 * If we are a completely broken operating system with a
539 		 * 32 bit time_t, and we have been told this is a notafter
540 		 * date, limit the date to a 32 bit representable value.
541 		 */
542 		if (!ASN1_time_tm_clamp_notafter(tm))
543 			return 0;
544 	}
545 
546 	/*
547 	 * Defensively fail if the time string is not representable as
548 	 * a time_t. A time_t must be sane if you care about times after
549 	 * Jan 19 2038.
550 	 */
551 	if (timegm(tm) == -1)
552 		return 0;
553 
554 	return 1;
555 }
556 
557 static int
558 x509_verify_cert_time(int is_notafter, const ASN1_TIME *cert_asn1,
559     time_t *cmp_time, int *error)
560 {
561 	struct tm cert_tm, when_tm;
562 	time_t when;
563 
564 	if (cmp_time == NULL)
565 		when = time(NULL);
566 	else
567 		when = *cmp_time;
568 
569 	if (!x509_verify_asn1_time_to_tm(cert_asn1, &cert_tm,
570 	    is_notafter)) {
571 		*error = is_notafter ?
572 		    X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD :
573 		    X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
574 		return 0;
575 	}
576 
577 	if (gmtime_r(&when, &when_tm) == NULL) {
578 		*error = X509_V_ERR_UNSPECIFIED;
579 		return 0;
580 	}
581 
582 	if (is_notafter) {
583 		if (ASN1_time_tm_cmp(&cert_tm, &when_tm) == -1) {
584 			*error = X509_V_ERR_CERT_HAS_EXPIRED;
585 			return 0;
586 		}
587 	} else  {
588 		if (ASN1_time_tm_cmp(&cert_tm, &when_tm) == 1) {
589 			*error = X509_V_ERR_CERT_NOT_YET_VALID;
590 			return 0;
591 		}
592 	}
593 
594 	return 1;
595 }
596 
597 static int
598 x509_verify_validate_constraints(X509 *cert,
599     struct x509_verify_chain *current_chain, int *error)
600 {
601 	struct x509_constraints_names *excluded = NULL;
602 	struct x509_constraints_names *permitted = NULL;
603 	int err = X509_V_ERR_UNSPECIFIED;
604 
605 	if (current_chain == NULL)
606 		return 1;
607 
608 	if (cert->nc != NULL) {
609 		if ((permitted = x509_constraints_names_new()) == NULL) {
610 			err = X509_V_ERR_OUT_OF_MEM;
611 			goto err;
612 		}
613 		if ((excluded = x509_constraints_names_new()) == NULL) {
614 			err = X509_V_ERR_OUT_OF_MEM;
615 			goto err;
616 		}
617 		if (!x509_constraints_extract_constraints(cert,
618 		    permitted, excluded, &err))
619 			goto err;
620 		if (!x509_constraints_check(current_chain->names,
621 		    permitted, excluded, &err))
622 			goto err;
623 		x509_constraints_names_free(excluded);
624 		x509_constraints_names_free(permitted);
625 	}
626 
627 	return 1;
628  err:
629 	*error = err;
630 	x509_constraints_names_free(excluded);
631 	x509_constraints_names_free(permitted);
632 	return 0;
633 }
634 
635 static int
636 x509_verify_cert_extensions(struct x509_verify_ctx *ctx, X509 *cert, int need_ca)
637 {
638 	if (!(cert->ex_flags & EXFLAG_SET)) {
639 		CRYPTO_w_lock(CRYPTO_LOCK_X509);
640 		x509v3_cache_extensions(cert);
641 		CRYPTO_w_unlock(CRYPTO_LOCK_X509);
642 	}
643 
644 	if (ctx->xsc != NULL)
645 		return 1;	/* legacy is checked after chain is built */
646 
647 	if (cert->ex_flags & EXFLAG_CRITICAL) {
648 		ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
649 		return 0;
650 	}
651 	/* No we don't care about v1, netscape, and other ancient silliness */
652 	if (need_ca && (!(cert->ex_flags & EXFLAG_BCONS) &&
653 	    (cert->ex_flags & EXFLAG_CA))) {
654 		ctx->error = X509_V_ERR_INVALID_CA;
655 		return 0;
656 	}
657 	if (ctx->purpose > 0 && X509_check_purpose(cert, ctx->purpose, need_ca)) {
658 		ctx->error = X509_V_ERR_INVALID_PURPOSE;
659 		return 0;
660 	}
661 
662 	/* XXX support proxy certs later in new api */
663 	if (ctx->xsc == NULL && cert->ex_flags & EXFLAG_PROXY) {
664 		ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
665 		return 0;
666 	}
667 
668 	return 1;
669 }
670 
671 /* Validate that cert is a possible candidate to append to current_chain */
672 static int
673 x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert,
674     struct x509_verify_chain *current_chain)
675 {
676 	X509 *issuer_candidate;
677 	int should_be_ca = current_chain != NULL;
678 	size_t depth = 0;
679 
680 	if (current_chain != NULL)
681 		depth = sk_X509_num(current_chain->certs);
682 
683 	if (!x509_verify_cert_extensions(ctx, cert, should_be_ca))
684 		return 0;
685 
686 	if (should_be_ca) {
687 		issuer_candidate = x509_verify_chain_last(current_chain);
688 		if (issuer_candidate != NULL &&
689 		    !X509_check_issued(issuer_candidate, cert))
690 			if (!x509_verify_cert_error(ctx, cert, depth,
691 			    X509_V_ERR_SUBJECT_ISSUER_MISMATCH, 0))
692 				return 0;
693 	}
694 
695 	if (x509_verify_set_check_time(ctx)) {
696 		if (!x509_verify_cert_time(0, X509_get_notBefore(cert),
697 		    ctx->check_time, &ctx->error)) {
698 			if (!x509_verify_cert_error(ctx, cert, depth,
699 			    ctx->error, 0))
700 				return 0;
701 		}
702 
703 		if (!x509_verify_cert_time(1, X509_get_notAfter(cert),
704 		    ctx->check_time, &ctx->error)) {
705 			if (!x509_verify_cert_error(ctx, cert, depth,
706 			    ctx->error, 0))
707 				return 0;
708 		}
709 	}
710 
711 	if (!x509_verify_validate_constraints(cert, current_chain,
712 	    &ctx->error) && !x509_verify_cert_error(ctx, cert, depth,
713 	    ctx->error, 0))
714 		return 0;
715 
716 	return 1;
717 }
718 
719 struct x509_verify_ctx *
720 x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc, STACK_OF(X509) *roots)
721 {
722 	struct x509_verify_ctx *ctx;
723 	size_t max_depth;
724 
725 	if (xsc == NULL)
726 		return NULL;
727 
728 	if ((ctx = x509_verify_ctx_new(roots)) == NULL)
729 		return NULL;
730 
731 	ctx->xsc = xsc;
732 
733 	if (xsc->untrusted &&
734 	    (ctx->intermediates = X509_chain_up_ref(xsc->untrusted)) == NULL)
735 		goto err;
736 
737 	max_depth = X509_VERIFY_MAX_CHAIN_CERTS;
738 	if (xsc->param->depth > 0 && xsc->param->depth < X509_VERIFY_MAX_CHAIN_CERTS)
739 		max_depth = xsc->param->depth;
740 	if (!x509_verify_ctx_set_max_depth(ctx, max_depth))
741 		goto err;
742 
743 	return ctx;
744  err:
745 	x509_verify_ctx_free(ctx);
746 	return NULL;
747 }
748 
749 /* Public API */
750 
751 struct x509_verify_ctx *
752 x509_verify_ctx_new(STACK_OF(X509) *roots)
753 {
754 	struct x509_verify_ctx *ctx;
755 
756 	if (roots == NULL)
757 		return NULL;
758 
759 	if ((ctx = calloc(1, sizeof(struct x509_verify_ctx))) == NULL)
760 		return NULL;
761 
762 	if ((ctx->roots = X509_chain_up_ref(roots)) == NULL)
763 		goto err;
764 
765 	ctx->max_depth = X509_VERIFY_MAX_CHAIN_CERTS;
766 	ctx->max_chains = X509_VERIFY_MAX_CHAINS;
767 	ctx->max_sigs = X509_VERIFY_MAX_SIGCHECKS;
768 
769 	if ((ctx->chains = calloc(X509_VERIFY_MAX_CHAINS,
770 	    sizeof(*ctx->chains))) == NULL)
771 		goto err;
772 
773 	return ctx;
774  err:
775 	x509_verify_ctx_free(ctx);
776 	return NULL;
777 }
778 
779 void
780 x509_verify_ctx_free(struct x509_verify_ctx *ctx)
781 {
782 	if (ctx == NULL)
783 		return;
784 	sk_X509_pop_free(ctx->roots, X509_free);
785 	x509_verify_ctx_clear(ctx);
786 	free(ctx);
787 }
788 
789 int
790 x509_verify_ctx_set_max_depth(struct x509_verify_ctx *ctx, size_t max)
791 {
792 	if (max < 1 || max > X509_VERIFY_MAX_CHAIN_CERTS)
793 		return 0;
794 	ctx->max_depth = max;
795 	return 1;
796 }
797 
798 int
799 x509_verify_ctx_set_max_chains(struct x509_verify_ctx *ctx, size_t max)
800 {
801 	if (max < 1 || max > X509_VERIFY_MAX_CHAINS)
802 		return 0;
803 	ctx->max_chains = max;
804 	return 1;
805 }
806 
807 int
808 x509_verify_ctx_set_max_signatures(struct x509_verify_ctx *ctx, size_t max)
809 {
810 	if (max < 1 || max > 100000)
811 		return 0;
812 	ctx->max_sigs = max;
813 	return 1;
814 }
815 
816 int
817 x509_verify_ctx_set_purpose(struct x509_verify_ctx *ctx, int purpose)
818 {
819 	if (purpose < X509_PURPOSE_MIN || purpose > X509_PURPOSE_MAX)
820 		return 0;
821 	ctx->purpose = purpose;
822 	return 1;
823 }
824 
825 int
826 x509_verify_ctx_set_intermediates(struct x509_verify_ctx *ctx,
827     STACK_OF(X509) *intermediates)
828 {
829 	if ((ctx->intermediates = X509_chain_up_ref(intermediates)) == NULL)
830 		return 0;
831 	return 1;
832 }
833 
834 const char *
835 x509_verify_ctx_error_string(struct x509_verify_ctx *ctx)
836 {
837 	return X509_verify_cert_error_string(ctx->error);
838 }
839 
840 size_t
841 x509_verify_ctx_error_depth(struct x509_verify_ctx *ctx)
842 {
843 	return ctx->error_depth;
844 }
845 
846 STACK_OF(X509) *
847 x509_verify_ctx_chain(struct x509_verify_ctx *ctx, size_t i)
848 {
849 	if (i >= ctx->chains_count)
850 		return NULL;
851 	return ctx->chains[i]->certs;
852 }
853 
854 size_t
855 x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name)
856 {
857 	struct x509_verify_chain *current_chain;
858 
859 	if (ctx->roots == NULL || ctx->max_depth == 0) {
860 		ctx->error = X509_V_ERR_INVALID_CALL;
861 		goto err;
862 	}
863 
864 	if (ctx->xsc != NULL) {
865 		if (leaf != NULL || name != NULL) {
866 			ctx->error = X509_V_ERR_INVALID_CALL;
867 			goto err;
868 		}
869 		leaf = ctx->xsc->cert;
870 
871 		/*
872 		 * XXX
873 		 * The legacy code expects the top level cert to be
874 		 * there, even if we didn't find a chain. So put it
875 		 * there, we will clobber it later if we find a valid
876 		 * chain.
877 		 */
878 		if ((ctx->xsc->chain = sk_X509_new_null()) == NULL) {
879 			ctx->error = X509_V_ERR_OUT_OF_MEM;
880 			goto err;
881 		}
882 		if (!X509_up_ref(leaf)) {
883 			ctx->error = X509_V_ERR_OUT_OF_MEM;
884 			goto err;
885 		}
886 		if (!sk_X509_push(ctx->xsc->chain, leaf)) {
887 			X509_free(leaf);
888 			ctx->error = X509_V_ERR_OUT_OF_MEM;
889 			goto err;
890 		}
891 		ctx->xsc->error_depth = 0;
892 		ctx->xsc->current_cert = leaf;
893 	}
894 
895 	if (!x509_verify_cert_valid(ctx, leaf, NULL))
896 		goto err;
897 
898 	if (!x509_verify_cert_hostname(ctx, leaf, name))
899 		goto err;
900 
901 	if ((current_chain = x509_verify_chain_new()) == NULL) {
902 		ctx->error = X509_V_ERR_OUT_OF_MEM;
903 		goto err;
904 	}
905 	if (!x509_verify_chain_append(current_chain, leaf, &ctx->error)) {
906 		x509_verify_chain_free(current_chain);
907 		goto err;
908 	}
909 	if (x509_verify_ctx_cert_is_root(ctx, leaf))
910 		x509_verify_ctx_add_chain(ctx, current_chain);
911 	else
912 		x509_verify_build_chains(ctx, leaf, current_chain);
913 
914 	x509_verify_chain_free(current_chain);
915 
916 	/*
917 	 * Safety net:
918 	 * We could not find a validated chain, and for some reason do not
919 	 * have an error set.
920 	 */
921 	if (ctx->chains_count == 0 && ctx->error == 0)
922 		ctx->error = X509_V_ERR_UNSPECIFIED;
923 
924 	/* Clear whatever errors happened if we have any validated chain */
925 	if (ctx->chains_count > 0)
926 		ctx->error = X509_V_OK;
927 
928 	if (ctx->xsc != NULL) {
929 		ctx->xsc->error = ctx->error;
930 		return ctx->xsc->verify_cb(ctx->chains_count, ctx->xsc);
931 	}
932 	return (ctx->chains_count);
933 
934  err:
935 	if (ctx->error == X509_V_OK)
936 		ctx->error = X509_V_ERR_UNSPECIFIED;
937 	if (ctx->xsc != NULL)
938 		ctx->xsc->error = ctx->error;
939 	return 0;
940 }
941