summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509/x509_verify.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/x509/x509_verify.c1288
1 files changed, 0 insertions, 1288 deletions
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c
deleted file mode 100644
index f25e2b3f15..0000000000
--- a/src/lib/libcrypto/x509/x509_verify.c
+++ /dev/null
@@ -1,1288 +0,0 @@
1/* $OpenBSD: x509_verify.c,v 1.73 2025/02/08 10:12:00 tb Exp $ */
2/*
3 * Copyright (c) 2020-2021 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 "asn1_local.h"
31#include "x509_internal.h"
32#include "x509_issuer_cache.h"
33
34static int x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert,
35 struct x509_verify_chain *current_chain);
36static int x509_verify_cert_hostname(struct x509_verify_ctx *ctx, X509 *cert,
37 char *name);
38static void x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
39 struct x509_verify_chain *current_chain, int full_chain, char *name);
40static int x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert,
41 size_t depth, int error, int ok);
42static void x509_verify_chain_free(struct x509_verify_chain *chain);
43
44/*
45 * Parse an asn1 to a representable time_t as per RFC 5280 rules.
46 * Returns -1 if that can't be done for any reason.
47 */
48int
49x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notAfter,
50 time_t *out)
51{
52 struct tm tm = { 0 };
53 int type;
54
55 if (atime == NULL)
56 return 0;
57
58 type = ASN1_time_parse(atime->data, atime->length, &tm, atime->type);
59 if (type == -1)
60 return 0;
61
62 /* RFC 5280 section 4.1.2.5 */
63 if (tm.tm_year < 150 && type != V_ASN1_UTCTIME)
64 return 0;
65 if (tm.tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME)
66 return 0;
67
68 if (notAfter) {
69 /*
70 * If we are a completely broken operating system with a
71 * 32 bit time_t, and we have been told this is a notAfter
72 * date, limit the date to a 32 bit representable value.
73 */
74 if (!ASN1_time_tm_clamp_notafter(&tm))
75 return 0;
76 }
77
78 /*
79 * Defensively fail if the time string is not representable as
80 * a time_t. A time_t must be sane if you care about times after
81 * Jan 19 2038.
82 */
83 return asn1_time_tm_to_time_t(&tm, out);
84}
85
86struct x509_verify_chain *
87x509_verify_chain_new(void)
88{
89 struct x509_verify_chain *chain;
90
91 if ((chain = calloc(1, sizeof(*chain))) == NULL)
92 goto err;
93 if ((chain->certs = sk_X509_new_null()) == NULL)
94 goto err;
95 if ((chain->cert_errors = calloc(X509_VERIFY_MAX_CHAIN_CERTS,
96 sizeof(int))) == NULL)
97 goto err;
98 if ((chain->names =
99 x509_constraints_names_new(X509_VERIFY_MAX_CHAIN_NAMES)) == NULL)
100 goto err;
101
102 return chain;
103 err:
104 x509_verify_chain_free(chain);
105 return NULL;
106}
107
108static void
109x509_verify_chain_clear(struct x509_verify_chain *chain)
110{
111 sk_X509_pop_free(chain->certs, X509_free);
112 chain->certs = NULL;
113 free(chain->cert_errors);
114 chain->cert_errors = NULL;
115 x509_constraints_names_free(chain->names);
116 chain->names = NULL;
117}
118
119static void
120x509_verify_chain_free(struct x509_verify_chain *chain)
121{
122 if (chain == NULL)
123 return;
124 x509_verify_chain_clear(chain);
125 free(chain);
126}
127
128static struct x509_verify_chain *
129x509_verify_chain_dup(struct x509_verify_chain *chain)
130{
131 struct x509_verify_chain *new_chain;
132
133 if ((new_chain = calloc(1, sizeof(*chain))) == NULL)
134 goto err;
135 if ((new_chain->certs = X509_chain_up_ref(chain->certs)) == NULL)
136 goto err;
137 if ((new_chain->cert_errors = calloc(X509_VERIFY_MAX_CHAIN_CERTS,
138 sizeof(int))) == NULL)
139 goto err;
140 memcpy(new_chain->cert_errors, chain->cert_errors,
141 X509_VERIFY_MAX_CHAIN_CERTS * sizeof(int));
142 if ((new_chain->names =
143 x509_constraints_names_dup(chain->names)) == NULL)
144 goto err;
145 return(new_chain);
146 err:
147 x509_verify_chain_free(new_chain);
148 return NULL;
149}
150
151static int
152x509_verify_chain_append(struct x509_verify_chain *chain, X509 *cert,
153 int *error)
154{
155 int verify_err = X509_V_ERR_UNSPECIFIED;
156 size_t idx;
157
158 if (!x509_constraints_extract_names(chain->names, cert,
159 sk_X509_num(chain->certs) == 0, &verify_err)) {
160 *error = verify_err;
161 return 0;
162 }
163
164 X509_up_ref(cert);
165 if (!sk_X509_push(chain->certs, cert)) {
166 X509_free(cert);
167 *error = X509_V_ERR_OUT_OF_MEM;
168 return 0;
169 }
170
171 idx = sk_X509_num(chain->certs) - 1;
172 chain->cert_errors[idx] = *error;
173
174 /*
175 * We've just added the issuer for the previous certificate,
176 * clear its error if appropriate.
177 */
178 if (idx > 1 && chain->cert_errors[idx - 1] ==
179 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
180 chain->cert_errors[idx - 1] = X509_V_OK;
181
182 return 1;
183}
184
185static X509 *
186x509_verify_chain_last(struct x509_verify_chain *chain)
187{
188 int last;
189
190 if (chain->certs == NULL)
191 return NULL;
192 if ((last = sk_X509_num(chain->certs) - 1) < 0)
193 return NULL;
194 return sk_X509_value(chain->certs, last);
195}
196
197X509 *
198x509_verify_chain_leaf(struct x509_verify_chain *chain)
199{
200 if (chain->certs == NULL)
201 return NULL;
202 return sk_X509_value(chain->certs, 0);
203}
204
205static void
206x509_verify_ctx_reset(struct x509_verify_ctx *ctx)
207{
208 size_t i;
209
210 for (i = 0; i < ctx->chains_count; i++)
211 x509_verify_chain_free(ctx->chains[i]);
212 sk_X509_pop_free(ctx->saved_error_chain, X509_free);
213 ctx->saved_error = 0;
214 ctx->saved_error_depth = 0;
215 ctx->error = 0;
216 ctx->error_depth = 0;
217 ctx->chains_count = 0;
218 ctx->sig_checks = 0;
219 ctx->check_time = NULL;
220}
221
222static void
223x509_verify_ctx_clear(struct x509_verify_ctx *ctx)
224{
225 x509_verify_ctx_reset(ctx);
226 sk_X509_pop_free(ctx->intermediates, X509_free);
227 free(ctx->chains);
228
229}
230
231static int
232x509_verify_cert_cache_extensions(X509 *cert)
233{
234 return x509v3_cache_extensions(cert);
235}
236
237static int
238x509_verify_cert_self_signed(X509 *cert)
239{
240 return (cert->ex_flags & EXFLAG_SS) ? 1 : 0;
241}
242
243/* XXX beck - clean up this mess of is_root */
244static int
245x509_verify_check_chain_end(X509 *cert, int full_chain)
246{
247 if (full_chain)
248 return x509_verify_cert_self_signed(cert);
249 return 1;
250}
251
252static int
253x509_verify_ctx_cert_is_root(struct x509_verify_ctx *ctx, X509 *cert,
254 int full_chain)
255{
256 X509 *match = NULL;
257 int i;
258
259 if (!x509_verify_cert_cache_extensions(cert))
260 return 0;
261
262 /* Check by lookup if we have a legacy xsc */
263 if (ctx->xsc != NULL) {
264 /*
265 * "alternative" lookup method, using the "trusted" stack in the
266 * xsc as the source for roots.
267 */
268 if (ctx->xsc->trusted != NULL) {
269 for (i = 0; i < sk_X509_num(ctx->xsc->trusted); i++) {
270 if (X509_cmp(sk_X509_value(ctx->xsc->trusted,
271 i), cert) == 0)
272 return x509_verify_check_chain_end(cert,
273 full_chain);
274 }
275 }
276 if ((match = x509_vfy_lookup_cert_match(ctx->xsc,
277 cert)) != NULL) {
278 X509_free(match);
279 return x509_verify_check_chain_end(cert, full_chain);
280 }
281 } else {
282 /* Check the provided roots */
283 for (i = 0; i < sk_X509_num(ctx->roots); i++) {
284 if (X509_cmp(sk_X509_value(ctx->roots, i), cert) == 0)
285 return x509_verify_check_chain_end(cert,
286 full_chain);
287 }
288 }
289
290 return 0;
291}
292
293static int
294x509_verify_ctx_set_xsc_chain(struct x509_verify_ctx *ctx,
295 struct x509_verify_chain *chain, int set_error, int is_trusted)
296{
297 size_t num_untrusted;
298 int i;
299
300 if (ctx->xsc == NULL)
301 return 1;
302
303 /*
304 * XXX num_untrusted is the number of untrusted certs at the
305 * bottom of the chain. This works now since we stop at the first
306 * trusted cert. This will need fixing once we allow more than one
307 * trusted certificate.
308 */
309 num_untrusted = sk_X509_num(chain->certs);
310 if (is_trusted && num_untrusted > 0)
311 num_untrusted--;
312 ctx->xsc->num_untrusted = num_untrusted;
313
314 sk_X509_pop_free(ctx->xsc->chain, X509_free);
315 ctx->xsc->chain = X509_chain_up_ref(chain->certs);
316 if (ctx->xsc->chain == NULL)
317 return x509_verify_cert_error(ctx, NULL, 0,
318 X509_V_ERR_OUT_OF_MEM, 0);
319
320 if (set_error) {
321 ctx->xsc->error = X509_V_OK;
322 ctx->xsc->error_depth = 0;
323 for (i = 0; i < sk_X509_num(chain->certs); i++) {
324 if (chain->cert_errors[i] != X509_V_OK) {
325 ctx->xsc->error = chain->cert_errors[i];
326 ctx->xsc->error_depth = i;
327 break;
328 }
329 }
330 }
331
332 return 1;
333}
334
335
336/*
337 * Save the error state and unvalidated chain off of the xsc for
338 * later.
339 */
340static int
341x509_verify_ctx_save_xsc_error(struct x509_verify_ctx *ctx)
342{
343 if (ctx->xsc != NULL && ctx->xsc->chain != NULL) {
344 sk_X509_pop_free(ctx->saved_error_chain, X509_free);
345 ctx->saved_error_chain = X509_chain_up_ref(ctx->xsc->chain);
346 if (ctx->saved_error_chain == NULL)
347 return x509_verify_cert_error(ctx, NULL, 0,
348 X509_V_ERR_OUT_OF_MEM, 0);
349 ctx->saved_error = ctx->xsc->error;
350 ctx->saved_error_depth = ctx->xsc->error_depth;
351 }
352 return 1;
353}
354
355/*
356 * Restore the saved error state and unvalidated chain to the xsc
357 * if we do not have a validated chain.
358 */
359static int
360x509_verify_ctx_restore_xsc_error(struct x509_verify_ctx *ctx)
361{
362 if (ctx->xsc != NULL && ctx->chains_count == 0 &&
363 ctx->saved_error_chain != NULL) {
364 sk_X509_pop_free(ctx->xsc->chain, X509_free);
365 ctx->xsc->chain = X509_chain_up_ref(ctx->saved_error_chain);
366 if (ctx->xsc->chain == NULL)
367 return x509_verify_cert_error(ctx, NULL, 0,
368 X509_V_ERR_OUT_OF_MEM, 0);
369 ctx->xsc->error = ctx->saved_error;
370 ctx->xsc->error_depth = ctx->saved_error_depth;
371 }
372 return 1;
373}
374
375/* Perform legacy style validation of a chain */
376static int
377x509_verify_ctx_validate_legacy_chain(struct x509_verify_ctx *ctx,
378 struct x509_verify_chain *chain, size_t depth)
379{
380 int ret = 0, trust;
381
382 if (ctx->xsc == NULL)
383 return 1;
384
385 /*
386 * If we have a legacy xsc, choose a validated chain, and
387 * apply the extensions, revocation, and policy checks just
388 * like the legacy code did. We do this here instead of as
389 * building the chains to more easily support the callback and
390 * the bewildering array of VERIFY_PARAM knobs that are there
391 * for the fiddling.
392 */
393
394 /* These may be set in one of the following calls. */
395 ctx->xsc->error = X509_V_OK;
396 ctx->xsc->error_depth = 0;
397
398 if (!x509_verify_ctx_set_xsc_chain(ctx, chain, 0, 1))
399 goto err;
400
401 /*
402 * Call the legacy code to walk the chain and check trust
403 * in the legacy way to handle partial chains and get the
404 * callback fired correctly.
405 */
406 trust = x509_vfy_check_trust(ctx->xsc);
407 if (trust == X509_TRUST_REJECTED)
408 goto err; /* callback was called in x509_vfy_check_trust */
409 if (trust != X509_TRUST_TRUSTED) {
410 /* NOTREACHED */
411 goto err; /* should not happen if we get in here - abort? */
412 }
413
414 /*
415 * XXX currently this duplicates some work done in chain
416 * build, but we keep it here until we have feature parity
417 */
418 if (!x509_vfy_check_chain_extensions(ctx->xsc))
419 goto err;
420
421#ifndef OPENSSL_NO_RFC3779
422 if (!X509v3_asid_validate_path(ctx->xsc))
423 goto err;
424
425 if (!X509v3_addr_validate_path(ctx->xsc))
426 goto err;
427#endif
428
429 if (!x509_vfy_check_security_level(ctx->xsc))
430 goto err;
431
432 if (!x509_constraints_chain(ctx->xsc->chain,
433 &ctx->xsc->error, &ctx->xsc->error_depth)) {
434 X509 *cert = sk_X509_value(ctx->xsc->chain, depth);
435 if (!x509_verify_cert_error(ctx, cert,
436 ctx->xsc->error_depth, ctx->xsc->error, 0))
437 goto err;
438 }
439
440 if (!x509_vfy_check_revocation(ctx->xsc))
441 goto err;
442
443 if (!x509_vfy_check_policy(ctx->xsc))
444 goto err;
445
446 ret = 1;
447
448 err:
449 /*
450 * The above checks may have set ctx->xsc->error and
451 * ctx->xsc->error_depth - save these for later on.
452 */
453 if (ctx->xsc->error != X509_V_OK) {
454 if (ctx->xsc->error_depth < 0 ||
455 ctx->xsc->error_depth >= X509_VERIFY_MAX_CHAIN_CERTS)
456 return 0;
457 chain->cert_errors[ctx->xsc->error_depth] =
458 ctx->xsc->error;
459 ctx->error_depth = ctx->xsc->error_depth;
460 }
461
462 return ret;
463}
464
465/* Add a validated chain to our list of valid chains */
466static int
467x509_verify_ctx_add_chain(struct x509_verify_ctx *ctx,
468 struct x509_verify_chain *chain, char *name)
469{
470 size_t depth;
471 X509 *last = x509_verify_chain_last(chain);
472 X509 *leaf = x509_verify_chain_leaf(chain);
473
474 depth = sk_X509_num(chain->certs);
475 if (depth > 0)
476 depth--;
477
478 if (ctx->chains_count >= ctx->max_chains)
479 return x509_verify_cert_error(ctx, last, depth,
480 X509_V_ERR_CERT_CHAIN_TOO_LONG, 0);
481
482 /* Clear a get issuer failure for a root certificate. */
483 if (chain->cert_errors[depth] ==
484 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
485 chain->cert_errors[depth] = X509_V_OK;
486
487 if (!x509_verify_ctx_validate_legacy_chain(ctx, chain, depth))
488 return 0;
489
490 /* Verify the leaf certificate and store any resulting error. */
491 if (!x509_verify_cert_valid(ctx, leaf, NULL))
492 return 0;
493 if (!x509_verify_cert_hostname(ctx, leaf, name))
494 return 0;
495 if (ctx->error_depth == 0 &&
496 ctx->error != X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
497 chain->cert_errors[0] = ctx->error;
498
499 /*
500 * In the non-legacy code, extensions and purpose are dealt
501 * with as the chain is built.
502 *
503 * The non-legacy api returns multiple chains but does not do
504 * any revocation checking (it must be done by the caller on
505 * any chain they wish to use)
506 */
507
508 if ((ctx->chains[ctx->chains_count] = x509_verify_chain_dup(chain)) ==
509 NULL) {
510 return x509_verify_cert_error(ctx, last, depth,
511 X509_V_ERR_OUT_OF_MEM, 0);
512 }
513 ctx->chains_count++;
514
515 ctx->error = X509_V_OK;
516 ctx->error_depth = depth;
517
518 return 1;
519}
520
521static int
522x509_verify_potential_parent(struct x509_verify_ctx *ctx, X509 *parent,
523 X509 *child)
524{
525 if (!x509_verify_cert_cache_extensions(parent))
526 return 0;
527 if (ctx->xsc != NULL)
528 return (ctx->xsc->check_issued(ctx->xsc, child, parent));
529
530 /* XXX key usage */
531 return X509_check_issued(parent, child) == X509_V_OK;
532}
533
534/* Matches x509_crl_verify_parent_signature() */
535static int
536x509_verify_parent_signature(X509 *parent, X509 *child, int *error)
537{
538 EVP_PKEY *pkey;
539 int cached;
540 int ret = 0;
541
542 /* Use cached value if we have it */
543 if ((cached = x509_issuer_cache_find(parent->hash, child->hash)) >= 0) {
544 if (cached == 0)
545 *error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
546 return cached;
547 }
548
549 /* Check signature. Did parent sign child? */
550 if ((pkey = X509_get0_pubkey(parent)) == NULL) {
551 *error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
552 return 0;
553 }
554 if (X509_verify(child, pkey) <= 0)
555 *error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
556 else
557 ret = 1;
558
559 /* Add result to cache */
560 x509_issuer_cache_add(parent->hash, child->hash, ret);
561
562 return ret;
563}
564
565static int
566x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert,
567 int is_root_cert, X509 *candidate, struct x509_verify_chain *current_chain,
568 int full_chain, char *name)
569{
570 int depth = sk_X509_num(current_chain->certs);
571 struct x509_verify_chain *new_chain;
572 int i;
573
574 /* Fail if the certificate is already in the chain */
575 for (i = 0; i < sk_X509_num(current_chain->certs); i++) {
576 if (X509_cmp(sk_X509_value(current_chain->certs, i),
577 candidate) == 0)
578 return 0;
579 }
580
581 if (ctx->sig_checks++ > X509_VERIFY_MAX_SIGCHECKS) {
582 /* don't allow callback to override safety check */
583 (void) x509_verify_cert_error(ctx, candidate, depth,
584 X509_V_ERR_CERT_CHAIN_TOO_LONG, 0);
585 return 0;
586 }
587
588 if (!x509_verify_parent_signature(candidate, cert, &ctx->error)) {
589 if (!x509_verify_cert_error(ctx, candidate, depth,
590 ctx->error, 0))
591 return 0;
592 }
593
594 if (!x509_verify_cert_valid(ctx, candidate, current_chain))
595 return 0;
596
597 /* candidate is good, add it to a copy of the current chain */
598 if ((new_chain = x509_verify_chain_dup(current_chain)) == NULL) {
599 x509_verify_cert_error(ctx, candidate, depth,
600 X509_V_ERR_OUT_OF_MEM, 0);
601 return 0;
602 }
603 if (!x509_verify_chain_append(new_chain, candidate, &ctx->error)) {
604 x509_verify_cert_error(ctx, candidate, depth, ctx->error, 0);
605 x509_verify_chain_free(new_chain);
606 return 0;
607 }
608
609 /*
610 * If candidate is a trusted root, we have a validated chain,
611 * so we save it. Otherwise, recurse until we find a root or
612 * give up.
613 */
614 if (is_root_cert) {
615 if (!x509_verify_ctx_set_xsc_chain(ctx, new_chain, 0, 1)) {
616 x509_verify_chain_free(new_chain);
617 return 0;
618 }
619 if (!x509_verify_ctx_add_chain(ctx, new_chain, name)) {
620 x509_verify_chain_free(new_chain);
621 return 0;
622 }
623 goto done;
624 }
625
626 x509_verify_build_chains(ctx, candidate, new_chain, full_chain, name);
627
628 done:
629 x509_verify_chain_free(new_chain);
630 return 1;
631}
632
633static int
634x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, size_t depth,
635 int error, int ok)
636{
637 ctx->error = error;
638 ctx->error_depth = depth;
639 if (ctx->xsc != NULL) {
640 ctx->xsc->error = error;
641 ctx->xsc->error_depth = depth;
642 ctx->xsc->current_cert = cert;
643 return ctx->xsc->verify_cb(ok, ctx->xsc);
644 }
645 return ok;
646}
647
648static void
649x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
650 struct x509_verify_chain *current_chain, int full_chain, char *name)
651{
652 X509 *candidate;
653 int i, depth, count, ret, is_root;
654
655 /*
656 * If we are finding chains with an xsc, just stop after we have
657 * one chain, there's no point in finding more, it just exercises
658 * the potentially buggy callback processing in the calling software.
659 */
660 if (ctx->xsc != NULL && ctx->chains_count > 0)
661 return;
662
663 depth = sk_X509_num(current_chain->certs);
664 if (depth > 0)
665 depth--;
666
667 if (depth >= ctx->max_depth &&
668 !x509_verify_cert_error(ctx, cert, depth,
669 X509_V_ERR_CERT_CHAIN_TOO_LONG, 0))
670 return;
671
672 count = ctx->chains_count;
673
674 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
675 ctx->error_depth = depth;
676
677 if (ctx->saved_error != 0)
678 ctx->error = ctx->saved_error;
679 if (ctx->saved_error_depth != 0)
680 ctx->error_depth = ctx->saved_error_depth;
681
682 if (ctx->xsc != NULL) {
683 /*
684 * Long ago experiments at Muppet labs resulted in a
685 * situation where software not only sees these errors
686 * but forced developers to expect them in certain cases.
687 * so we must mimic this awfulness for the legacy case.
688 */
689 if (cert->ex_flags & EXFLAG_SS)
690 ctx->error = (depth == 0) ?
691 X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
692 X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
693 }
694
695 /* Check for legacy mode roots */
696 if (ctx->xsc != NULL) {
697 if ((ret = ctx->xsc->get_issuer(&candidate, ctx->xsc, cert)) < 0) {
698 x509_verify_cert_error(ctx, cert, depth,
699 X509_V_ERR_STORE_LOOKUP, 0);
700 return;
701 }
702 if (ret > 0) {
703 if (x509_verify_potential_parent(ctx, candidate, cert)) {
704 is_root = x509_verify_check_chain_end(candidate,
705 full_chain);
706 x509_verify_consider_candidate(ctx, cert,
707 is_root, candidate, current_chain,
708 full_chain, name);
709 }
710 X509_free(candidate);
711 }
712 } else {
713 /* Check to see if we have a trusted root issuer. */
714 for (i = 0; i < sk_X509_num(ctx->roots); i++) {
715 candidate = sk_X509_value(ctx->roots, i);
716 if (x509_verify_potential_parent(ctx, candidate, cert)) {
717 is_root = x509_verify_check_chain_end(candidate,
718 full_chain);
719 x509_verify_consider_candidate(ctx, cert,
720 is_root, candidate, current_chain,
721 full_chain, name);
722 }
723 }
724 }
725
726 /* Check intermediates after checking roots */
727 if (ctx->intermediates != NULL) {
728 for (i = 0; i < sk_X509_num(ctx->intermediates); i++) {
729 candidate = sk_X509_value(ctx->intermediates, i);
730 if (x509_verify_potential_parent(ctx, candidate, cert)) {
731 x509_verify_consider_candidate(ctx, cert,
732 0, candidate, current_chain,
733 full_chain, name);
734 }
735 }
736 }
737
738 if (ctx->chains_count > count) {
739 if (ctx->xsc != NULL) {
740 ctx->xsc->error = X509_V_OK;
741 ctx->xsc->error_depth = depth;
742 ctx->xsc->current_cert = cert;
743 }
744 } else if (ctx->error_depth == depth) {
745 if (!x509_verify_ctx_set_xsc_chain(ctx, current_chain, 0, 0))
746 return;
747 }
748}
749
750static int
751x509_verify_cert_hostname(struct x509_verify_ctx *ctx, X509 *cert, char *name)
752{
753 char *candidate;
754 size_t len;
755
756 if (name == NULL) {
757 if (ctx->xsc != NULL) {
758 int ret;
759
760 if ((ret = x509_vfy_check_id(ctx->xsc)) == 0)
761 ctx->error = ctx->xsc->error;
762 return ret;
763 }
764 return 1;
765 }
766 if ((candidate = strdup(name)) == NULL) {
767 ctx->error = X509_V_ERR_OUT_OF_MEM;
768 goto err;
769 }
770 if ((len = strlen(candidate)) < 1) {
771 ctx->error = X509_V_ERR_UNSPECIFIED; /* XXX */
772 goto err;
773 }
774
775 /* IP addresses may be written in [ ]. */
776 if (candidate[0] == '[' && candidate[len - 1] == ']') {
777 candidate[len - 1] = '\0';
778 if (X509_check_ip_asc(cert, candidate + 1, 0) <= 0) {
779 ctx->error = X509_V_ERR_IP_ADDRESS_MISMATCH;
780 goto err;
781 }
782 } else {
783 int flags = 0;
784
785 if (ctx->xsc == NULL)
786 flags = X509_CHECK_FLAG_NEVER_CHECK_SUBJECT;
787
788 if (X509_check_host(cert, candidate, len, flags, NULL) <= 0) {
789 ctx->error = X509_V_ERR_HOSTNAME_MISMATCH;
790 goto err;
791 }
792 }
793 free(candidate);
794 return 1;
795 err:
796 free(candidate);
797 return x509_verify_cert_error(ctx, cert, 0, ctx->error, 0);
798}
799
800static int
801x509_verify_set_check_time(struct x509_verify_ctx *ctx)
802{
803 if (ctx->xsc != NULL) {
804 if (ctx->xsc->param->flags & X509_V_FLAG_USE_CHECK_TIME) {
805 ctx->check_time = &ctx->xsc->param->check_time;
806 return 1;
807 }
808 if (ctx->xsc->param->flags & X509_V_FLAG_NO_CHECK_TIME)
809 return 0;
810 }
811
812 ctx->check_time = NULL;
813 return 1;
814}
815
816static int
817x509_verify_cert_times(X509 *cert, time_t *cmp_time, int *error)
818{
819 time_t when, not_before, not_after;
820
821 if (cmp_time == NULL)
822 when = time(NULL);
823 else
824 when = *cmp_time;
825
826 if (!x509_verify_asn1_time_to_time_t(X509_get_notBefore(cert), 0,
827 &not_before)) {
828 *error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
829 return 0;
830 }
831 if (when < not_before) {
832 *error = X509_V_ERR_CERT_NOT_YET_VALID;
833 return 0;
834 }
835 if (!x509_verify_asn1_time_to_time_t(X509_get_notAfter(cert), 1,
836 &not_after)) {
837 *error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
838 return 0;
839 }
840 if (when > not_after) {
841 *error = X509_V_ERR_CERT_HAS_EXPIRED;
842 return 0;
843 }
844
845 return 1;
846}
847
848static int
849x509_verify_validate_constraints(X509 *cert,
850 struct x509_verify_chain *current_chain, int *error)
851{
852 struct x509_constraints_names *excluded = NULL;
853 struct x509_constraints_names *permitted = NULL;
854 int err = X509_V_ERR_UNSPECIFIED;
855
856 if (current_chain == NULL)
857 return 1;
858
859 if (cert->nc != NULL) {
860 if ((permitted = x509_constraints_names_new(
861 X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) {
862 err = X509_V_ERR_OUT_OF_MEM;
863 goto err;
864 }
865 if ((excluded = x509_constraints_names_new(
866 X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) {
867 err = X509_V_ERR_OUT_OF_MEM;
868 goto err;
869 }
870 if (!x509_constraints_extract_constraints(cert,
871 permitted, excluded, &err))
872 goto err;
873 if (!x509_constraints_check(current_chain->names,
874 permitted, excluded, &err))
875 goto err;
876 x509_constraints_names_free(excluded);
877 x509_constraints_names_free(permitted);
878 }
879
880 return 1;
881 err:
882 *error = err;
883 x509_constraints_names_free(excluded);
884 x509_constraints_names_free(permitted);
885 return 0;
886}
887
888static int
889x509_verify_cert_extensions(struct x509_verify_ctx *ctx, X509 *cert, int need_ca)
890{
891 if (!x509_verify_cert_cache_extensions(cert)) {
892 ctx->error = X509_V_ERR_UNSPECIFIED;
893 return 0;
894 }
895
896 if (ctx->xsc != NULL)
897 return 1; /* legacy is checked after chain is built */
898
899 if (cert->ex_flags & EXFLAG_CRITICAL) {
900 ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
901 return 0;
902 }
903 /* No we don't care about v1, netscape, and other ancient silliness */
904 if (need_ca && (!(cert->ex_flags & EXFLAG_BCONS) &&
905 (cert->ex_flags & EXFLAG_CA))) {
906 ctx->error = X509_V_ERR_INVALID_CA;
907 return 0;
908 }
909 if (ctx->purpose > 0 && X509_check_purpose(cert, ctx->purpose, need_ca)) {
910 ctx->error = X509_V_ERR_INVALID_PURPOSE;
911 return 0;
912 }
913
914 return 1;
915}
916
917/* Validate that cert is a possible candidate to append to current_chain */
918static int
919x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert,
920 struct x509_verify_chain *current_chain)
921{
922 X509 *issuer_candidate;
923 int should_be_ca = current_chain != NULL;
924 size_t depth = 0;
925
926 if (current_chain != NULL)
927 depth = sk_X509_num(current_chain->certs);
928
929 if (!x509_verify_cert_extensions(ctx, cert, should_be_ca))
930 return 0;
931
932 if (should_be_ca) {
933 issuer_candidate = x509_verify_chain_last(current_chain);
934 if (issuer_candidate != NULL &&
935 !X509_check_issued(issuer_candidate, cert))
936 if (!x509_verify_cert_error(ctx, cert, depth,
937 X509_V_ERR_SUBJECT_ISSUER_MISMATCH, 0))
938 return 0;
939 }
940
941 if (x509_verify_set_check_time(ctx)) {
942 if (!x509_verify_cert_times(cert, ctx->check_time,
943 &ctx->error)) {
944 if (!x509_verify_cert_error(ctx, cert, depth,
945 ctx->error, 0))
946 return 0;
947 }
948 }
949
950 if (!x509_verify_validate_constraints(cert, current_chain,
951 &ctx->error) && !x509_verify_cert_error(ctx, cert, depth,
952 ctx->error, 0))
953 return 0;
954
955 return 1;
956}
957
958struct x509_verify_ctx *
959x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc)
960{
961 struct x509_verify_ctx *ctx;
962 size_t max_depth;
963
964 if (xsc == NULL)
965 return NULL;
966
967 if ((ctx = x509_verify_ctx_new(NULL)) == NULL)
968 return NULL;
969
970 ctx->xsc = xsc;
971
972 if (xsc->untrusted &&
973 (ctx->intermediates = X509_chain_up_ref(xsc->untrusted)) == NULL)
974 goto err;
975
976 max_depth = X509_VERIFY_MAX_CHAIN_CERTS;
977 if (xsc->param->depth > 0 && xsc->param->depth < X509_VERIFY_MAX_CHAIN_CERTS)
978 max_depth = xsc->param->depth;
979 if (!x509_verify_ctx_set_max_depth(ctx, max_depth))
980 goto err;
981
982 return ctx;
983 err:
984 x509_verify_ctx_free(ctx);
985 return NULL;
986}
987
988/* Public API */
989
990struct x509_verify_ctx *
991x509_verify_ctx_new(STACK_OF(X509) *roots)
992{
993 struct x509_verify_ctx *ctx;
994
995 if ((ctx = calloc(1, sizeof(struct x509_verify_ctx))) == NULL)
996 return NULL;
997
998 if (roots != NULL) {
999 if ((ctx->roots = X509_chain_up_ref(roots)) == NULL)
1000 goto err;
1001 } else {
1002 if ((ctx->roots = sk_X509_new_null()) == NULL)
1003 goto err;
1004 }
1005
1006 ctx->max_depth = X509_VERIFY_MAX_CHAIN_CERTS;
1007 ctx->max_chains = X509_VERIFY_MAX_CHAINS;
1008 ctx->max_sigs = X509_VERIFY_MAX_SIGCHECKS;
1009
1010 if ((ctx->chains = calloc(X509_VERIFY_MAX_CHAINS,
1011 sizeof(*ctx->chains))) == NULL)
1012 goto err;
1013
1014 return ctx;
1015 err:
1016 x509_verify_ctx_free(ctx);
1017 return NULL;
1018}
1019
1020void
1021x509_verify_ctx_free(struct x509_verify_ctx *ctx)
1022{
1023 if (ctx == NULL)
1024 return;
1025 sk_X509_pop_free(ctx->roots, X509_free);
1026 x509_verify_ctx_clear(ctx);
1027 free(ctx);
1028}
1029
1030int
1031x509_verify_ctx_set_max_depth(struct x509_verify_ctx *ctx, size_t max)
1032{
1033 if (max < 1 || max > X509_VERIFY_MAX_CHAIN_CERTS)
1034 return 0;
1035 ctx->max_depth = max;
1036 return 1;
1037}
1038
1039int
1040x509_verify_ctx_set_max_chains(struct x509_verify_ctx *ctx, size_t max)
1041{
1042 if (max < 1 || max > X509_VERIFY_MAX_CHAINS)
1043 return 0;
1044 ctx->max_chains = max;
1045 return 1;
1046}
1047
1048int
1049x509_verify_ctx_set_max_signatures(struct x509_verify_ctx *ctx, size_t max)
1050{
1051 if (max < 1 || max > 100000)
1052 return 0;
1053 ctx->max_sigs = max;
1054 return 1;
1055}
1056
1057int
1058x509_verify_ctx_set_purpose(struct x509_verify_ctx *ctx, int purpose)
1059{
1060 if (purpose < X509_PURPOSE_MIN || purpose > X509_PURPOSE_MAX)
1061 return 0;
1062 ctx->purpose = purpose;
1063 return 1;
1064}
1065
1066int
1067x509_verify_ctx_set_intermediates(struct x509_verify_ctx *ctx,
1068 STACK_OF(X509) *intermediates)
1069{
1070 if ((ctx->intermediates = X509_chain_up_ref(intermediates)) == NULL)
1071 return 0;
1072 return 1;
1073}
1074
1075const char *
1076x509_verify_ctx_error_string(struct x509_verify_ctx *ctx)
1077{
1078 return X509_verify_cert_error_string(ctx->error);
1079}
1080
1081size_t
1082x509_verify_ctx_error_depth(struct x509_verify_ctx *ctx)
1083{
1084 return ctx->error_depth;
1085}
1086
1087STACK_OF(X509) *
1088x509_verify_ctx_chain(struct x509_verify_ctx *ctx, size_t i)
1089{
1090 if (i >= ctx->chains_count)
1091 return NULL;
1092 return ctx->chains[i]->certs;
1093}
1094
1095size_t
1096x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name)
1097{
1098 struct x509_verify_chain *current_chain;
1099 int retry_chain_build, full_chain = 0;
1100
1101 if (ctx->roots == NULL || ctx->max_depth == 0) {
1102 ctx->error = X509_V_ERR_INVALID_CALL;
1103 goto err;
1104 }
1105
1106 if (ctx->xsc != NULL) {
1107 if (leaf != NULL || name != NULL) {
1108 ctx->error = X509_V_ERR_INVALID_CALL;
1109 goto err;
1110 }
1111 leaf = ctx->xsc->cert;
1112
1113 /* XXX */
1114 full_chain = 1;
1115 if (ctx->xsc->param->flags & X509_V_FLAG_PARTIAL_CHAIN)
1116 full_chain = 0;
1117 /*
1118 * XXX
1119 * The legacy code expects the top level cert to be
1120 * there, even if we didn't find a chain. So put it
1121 * there, we will clobber it later if we find a valid
1122 * chain.
1123 */
1124 if ((ctx->xsc->chain = sk_X509_new_null()) == NULL) {
1125 ctx->error = X509_V_ERR_OUT_OF_MEM;
1126 goto err;
1127 }
1128 if (!X509_up_ref(leaf)) {
1129 ctx->error = X509_V_ERR_OUT_OF_MEM;
1130 goto err;
1131 }
1132 if (!sk_X509_push(ctx->xsc->chain, leaf)) {
1133 X509_free(leaf);
1134 ctx->error = X509_V_ERR_OUT_OF_MEM;
1135 goto err;
1136 }
1137 ctx->xsc->error_depth = 0;
1138 ctx->xsc->current_cert = leaf;
1139 }
1140
1141 if ((current_chain = x509_verify_chain_new()) == NULL) {
1142 ctx->error = X509_V_ERR_OUT_OF_MEM;
1143 goto err;
1144 }
1145
1146 /*
1147 * Add the leaf to the chain and try to build chains from it.
1148 * Note that unlike Go's verifier, we have not yet checked
1149 * anything about the leaf, This is intentional, so that we
1150 * report failures in chain building before we report problems
1151 * with the leaf.
1152 */
1153 if (!x509_verify_chain_append(current_chain, leaf, &ctx->error)) {
1154 x509_verify_chain_free(current_chain);
1155 goto err;
1156 }
1157 do {
1158 retry_chain_build = 0;
1159 if (x509_verify_ctx_cert_is_root(ctx, leaf, full_chain)) {
1160 if (!x509_verify_ctx_add_chain(ctx, current_chain,
1161 name)) {
1162 x509_verify_chain_free(current_chain);
1163 goto err;
1164 }
1165 } else {
1166 x509_verify_build_chains(ctx, leaf, current_chain,
1167 full_chain, name);
1168 if (full_chain && ctx->chains_count == 0) {
1169 /*
1170 * Save the error state from the xsc
1171 * at this point to put back on the
1172 * xsc in case we do not find a chain
1173 * that is trusted but not a full
1174 * chain to a self signed root. This
1175 * is because the unvalidated chain is
1176 * used by the autochain batshittery
1177 * on failure and will be needed for
1178 * that.
1179 */
1180 ctx->xsc->error_depth = ctx->error_depth;
1181 if (!x509_verify_ctx_save_xsc_error(ctx)) {
1182 x509_verify_chain_free(current_chain);
1183 goto err;
1184 }
1185 full_chain = 0;
1186 retry_chain_build = 1;
1187 }
1188 }
1189 } while (retry_chain_build);
1190
1191 x509_verify_chain_free(current_chain);
1192
1193 /*
1194 * Do the new verifier style return, where we don't have an xsc
1195 * that allows a crazy callback to turn invalid things into valid.
1196 */
1197 if (ctx->xsc == NULL) {
1198 /*
1199 * Safety net:
1200 * We could not find a validated chain, and for some reason do not
1201 * have an error set.
1202 */
1203 if (ctx->chains_count == 0 && ctx->error == X509_V_OK)
1204 ctx->error = X509_V_ERR_UNSPECIFIED;
1205
1206 /*
1207 * If we are not using an xsc, and have no possibility for the
1208 * crazy OpenSSL callback API changing the results of
1209 * validation steps (because the callback can make validation
1210 * proceed in the presence of invalid certs), any chains we
1211 * have here are correctly built and verified.
1212 */
1213 if (ctx->chains_count > 0)
1214 ctx->error = X509_V_OK;
1215
1216 return ctx->chains_count;
1217 }
1218
1219 /*
1220 * Otherwise we are doing compatibility with an xsc, which means that we
1221 * will have one chain, which might actually be a bogus chain because
1222 * the callback told us to ignore errors and proceed to build an invalid
1223 * chain. Possible return values from this include returning 1 with an
1224 * invalid chain and a value of xsc->error != X509_V_OK (It's tradition
1225 * that makes it ok).
1226 */
1227
1228 if (ctx->chains_count > 0) {
1229 /*
1230 * The chain we have using an xsc might not be a verified chain
1231 * if the callback perverted things while we built it to ignore
1232 * failures and proceed with chain building. We put this chain
1233 * and the error associated with it on the xsc.
1234 */
1235 if (!x509_verify_ctx_set_xsc_chain(ctx, ctx->chains[0], 1, 1))
1236 goto err;
1237
1238 /*
1239 * Call the callback for completion up our built
1240 * chain. The callback could still tell us to
1241 * fail. Since this chain might exist as the result of
1242 * callback doing perversions, we could still return
1243 * "success" with something other than X509_V_OK set
1244 * as the error.
1245 */
1246 if (!x509_vfy_callback_indicate_completion(ctx->xsc))
1247 goto err;
1248 } else {
1249 /*
1250 * We did not find a chain. Bring back the failure
1251 * case we wanted to the xsc if we saved one. If we
1252 * did not we should have just the leaf on the xsc.
1253 */
1254 if (!x509_verify_ctx_restore_xsc_error(ctx))
1255 goto err;
1256
1257 /*
1258 * Safety net, ensure we have an error set in the
1259 * failing case.
1260 */
1261 if (ctx->xsc->error == X509_V_OK) {
1262 if (ctx->error == X509_V_OK)
1263 ctx->error = X509_V_ERR_UNSPECIFIED;
1264 ctx->xsc->error = ctx->error;
1265 }
1266
1267 /*
1268 * Let the callback override the return value
1269 * at depth 0 if it chooses to
1270 */
1271 return ctx->xsc->verify_cb(0, ctx->xsc);
1272 }
1273
1274 /* We only ever find one chain in compat mode with an xsc. */
1275 return 1;
1276
1277 err:
1278 if (ctx->error == X509_V_OK)
1279 ctx->error = X509_V_ERR_UNSPECIFIED;
1280
1281 if (ctx->xsc != NULL) {
1282 if (ctx->xsc->error == X509_V_OK)
1283 ctx->xsc->error = X509_V_ERR_UNSPECIFIED;
1284 ctx->error = ctx->xsc->error;
1285 }
1286
1287 return 0;
1288}