1 /* $OpenBSD: x509_verify.c,v 1.13 2020/09/26 15:44:06 jsing 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 *
x509_verify_chain_new(void)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
x509_verify_chain_clear(struct x509_verify_chain * chain)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
x509_verify_chain_free(struct x509_verify_chain * chain)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 *
x509_verify_chain_dup(struct x509_verify_chain * 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
x509_verify_chain_append(struct x509_verify_chain * chain,X509 * cert,int * error)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 *
x509_verify_chain_last(struct x509_verify_chain * chain)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 *
x509_verify_chain_leaf(struct x509_verify_chain * chain)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
x509_verify_ctx_reset(struct x509_verify_ctx * ctx)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
x509_verify_ctx_clear(struct x509_verify_ctx * ctx)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
x509_verify_ctx_cert_is_root(struct x509_verify_ctx * ctx,X509 * cert)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
x509_verify_ctx_set_xsc_chain(struct x509_verify_ctx * ctx,struct x509_verify_chain * chain)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
x509_verify_ctx_add_chain(struct x509_verify_ctx * ctx,struct x509_verify_chain * chain)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
x509_verify_potential_parent(struct x509_verify_ctx * ctx,X509 * parent,X509 * child)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
x509_verify_parent_signature(X509 * parent,X509 * child,unsigned char * child_md,int * error)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
x509_verify_consider_candidate(struct x509_verify_ctx * ctx,X509 * cert,unsigned char * cert_md,int is_root_cert,X509 * candidate,struct x509_verify_chain * current_chain)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
x509_verify_cert_error(struct x509_verify_ctx * ctx,X509 * cert,size_t depth,int error,int ok)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
x509_verify_build_chains(struct x509_verify_ctx * ctx,X509 * cert,struct x509_verify_chain * current_chain)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
x509_verify_cert_hostname(struct x509_verify_ctx * ctx,X509 * cert,char * name)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 return x509_vfy_check_id(ctx->xsc);
463 return 1;
464 }
465 if ((candidate = strdup(name)) == NULL) {
466 ctx->error = X509_V_ERR_OUT_OF_MEM;
467 goto err;
468 }
469 if ((len = strlen(candidate)) < 1) {
470 ctx->error = X509_V_ERR_UNSPECIFIED; /* XXX */
471 goto err;
472 }
473
474 /* IP addresses may be written in [ ]. */
475 if (candidate[0] == '[' && candidate[len - 1] == ']') {
476 candidate[len - 1] = '\0';
477 if (X509_check_ip_asc(cert, candidate + 1, 0) <= 0) {
478 ctx->error = X509_V_ERR_IP_ADDRESS_MISMATCH;
479 goto err;
480 }
481 } else {
482 int flags = 0;
483
484 if (ctx->xsc == NULL)
485 flags = X509_CHECK_FLAG_NEVER_CHECK_SUBJECT;
486
487 if (X509_check_host(cert, candidate, len, flags, NULL) <= 0) {
488 ctx->error = X509_V_ERR_HOSTNAME_MISMATCH;
489 goto err;
490 }
491 }
492 free(candidate);
493 return 1;
494 err:
495 free(candidate);
496 return x509_verify_cert_error(ctx, cert, 0, ctx->error, 0);
497 }
498
499 static int
x509_verify_set_check_time(struct x509_verify_ctx * ctx)500 x509_verify_set_check_time(struct x509_verify_ctx *ctx) {
501 if (ctx->xsc != NULL) {
502 if (ctx->xsc->param->flags & X509_V_FLAG_USE_CHECK_TIME) {
503 ctx->check_time = &ctx->xsc->param->check_time;
504 return 1;
505 }
506 if (ctx->xsc->param->flags & X509_V_FLAG_NO_CHECK_TIME)
507 return 0;
508 }
509
510 ctx->check_time = NULL;
511 return 1;
512 }
513
514 int
x509_verify_asn1_time_to_tm(const ASN1_TIME * atime,struct tm * tm,int notafter)515 x509_verify_asn1_time_to_tm(const ASN1_TIME *atime, struct tm *tm, int notafter)
516 {
517 int type;
518
519 memset(tm, 0, sizeof(*tm));
520
521 type = ASN1_time_parse(atime->data, atime->length, tm, atime->type);
522 if (type == -1)
523 return 0;
524
525 /* RFC 5280 section 4.1.2.5 */
526 if (tm->tm_year < 150 && type != V_ASN1_UTCTIME)
527 return 0;
528 if (tm->tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME)
529 return 0;
530
531 if (notafter) {
532 /*
533 * If we are a completely broken operating system with a
534 * 32 bit time_t, and we have been told this is a notafter
535 * date, limit the date to a 32 bit representable value.
536 */
537 if (!ASN1_time_tm_clamp_notafter(tm))
538 return 0;
539 }
540
541 /*
542 * Defensively fail if the time string is not representable as
543 * a time_t. A time_t must be sane if you care about times after
544 * Jan 19 2038.
545 */
546 if (timegm(tm) == -1)
547 return 0;
548
549 return 1;
550 }
551
552 static int
x509_verify_cert_time(int is_notafter,const ASN1_TIME * cert_asn1,time_t * cmp_time,int * error)553 x509_verify_cert_time(int is_notafter, const ASN1_TIME *cert_asn1,
554 time_t *cmp_time, int *error)
555 {
556 struct tm cert_tm, when_tm;
557 time_t when;
558
559 if (cmp_time == NULL)
560 when = time(NULL);
561 else
562 when = *cmp_time;
563
564 if (!x509_verify_asn1_time_to_tm(cert_asn1, &cert_tm,
565 is_notafter)) {
566 *error = is_notafter ?
567 X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD :
568 X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
569 return 0;
570 }
571
572 if (gmtime_r(&when, &when_tm) == NULL) {
573 *error = X509_V_ERR_UNSPECIFIED;
574 return 0;
575 }
576
577 if (is_notafter) {
578 if (ASN1_time_tm_cmp(&cert_tm, &when_tm) == -1) {
579 *error = X509_V_ERR_CERT_HAS_EXPIRED;
580 return 0;
581 }
582 } else {
583 if (ASN1_time_tm_cmp(&cert_tm, &when_tm) == 1) {
584 *error = X509_V_ERR_CERT_NOT_YET_VALID;
585 return 0;
586 }
587 }
588
589 return 1;
590 }
591
592 static int
x509_verify_validate_constraints(X509 * cert,struct x509_verify_chain * current_chain,int * error)593 x509_verify_validate_constraints(X509 *cert,
594 struct x509_verify_chain *current_chain, int *error)
595 {
596 struct x509_constraints_names *excluded = NULL;
597 struct x509_constraints_names *permitted = NULL;
598 int err = X509_V_ERR_UNSPECIFIED;
599
600 if (current_chain == NULL)
601 return 1;
602
603 if (cert->nc != NULL) {
604 if ((permitted = x509_constraints_names_new()) == NULL) {
605 err = X509_V_ERR_OUT_OF_MEM;
606 goto err;
607 }
608 if ((excluded = x509_constraints_names_new()) == NULL) {
609 err = X509_V_ERR_OUT_OF_MEM;
610 goto err;
611 }
612 if (!x509_constraints_extract_constraints(cert,
613 permitted, excluded, &err))
614 goto err;
615 if (!x509_constraints_check(current_chain->names,
616 permitted, excluded, &err))
617 goto err;
618 x509_constraints_names_free(excluded);
619 x509_constraints_names_free(permitted);
620 }
621
622 return 1;
623 err:
624 *error = err;
625 x509_constraints_names_free(excluded);
626 x509_constraints_names_free(permitted);
627 return 0;
628 }
629
630 static int
x509_verify_cert_extensions(struct x509_verify_ctx * ctx,X509 * cert,int need_ca)631 x509_verify_cert_extensions(struct x509_verify_ctx *ctx, X509 *cert, int need_ca)
632 {
633 if (!(cert->ex_flags & EXFLAG_SET)) {
634 CRYPTO_w_lock(CRYPTO_LOCK_X509);
635 x509v3_cache_extensions(cert);
636 CRYPTO_w_unlock(CRYPTO_LOCK_X509);
637 }
638
639 if (ctx->xsc != NULL)
640 return 1; /* legacy is checked after chain is built */
641
642 if (cert->ex_flags & EXFLAG_CRITICAL) {
643 ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
644 return 0;
645 }
646 /* No we don't care about v1, netscape, and other ancient silliness */
647 if (need_ca && (!(cert->ex_flags & EXFLAG_BCONS) &&
648 (cert->ex_flags & EXFLAG_CA))) {
649 ctx->error = X509_V_ERR_INVALID_CA;
650 return 0;
651 }
652 if (ctx->purpose > 0 && X509_check_purpose(cert, ctx->purpose, need_ca)) {
653 ctx->error = X509_V_ERR_INVALID_PURPOSE;
654 return 0;
655 }
656
657 /* XXX support proxy certs later in new api */
658 if (ctx->xsc == NULL && cert->ex_flags & EXFLAG_PROXY) {
659 ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
660 return 0;
661 }
662
663 return 1;
664 }
665
666 /* Validate that cert is a possible candidate to append to current_chain */
667 static int
x509_verify_cert_valid(struct x509_verify_ctx * ctx,X509 * cert,struct x509_verify_chain * current_chain)668 x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert,
669 struct x509_verify_chain *current_chain)
670 {
671 X509 *issuer_candidate;
672 int should_be_ca = current_chain != NULL;
673 size_t depth = 0;
674
675 if (current_chain != NULL)
676 depth = sk_X509_num(current_chain->certs);
677
678 if (!x509_verify_cert_extensions(ctx, cert, should_be_ca))
679 return 0;
680
681 if (should_be_ca) {
682 issuer_candidate = x509_verify_chain_last(current_chain);
683 if (issuer_candidate != NULL &&
684 !X509_check_issued(issuer_candidate, cert))
685 if (!x509_verify_cert_error(ctx, cert, depth,
686 X509_V_ERR_SUBJECT_ISSUER_MISMATCH, 0))
687 return 0;
688 }
689
690 if (x509_verify_set_check_time(ctx)) {
691 if (!x509_verify_cert_time(0, X509_get_notBefore(cert),
692 ctx->check_time, &ctx->error)) {
693 if (!x509_verify_cert_error(ctx, cert, depth,
694 ctx->error, 0))
695 return 0;
696 }
697
698 if (!x509_verify_cert_time(1, X509_get_notAfter(cert),
699 ctx->check_time, &ctx->error)) {
700 if (!x509_verify_cert_error(ctx, cert, depth,
701 ctx->error, 0))
702 return 0;
703 }
704 }
705
706 if (!x509_verify_validate_constraints(cert, current_chain,
707 &ctx->error) && !x509_verify_cert_error(ctx, cert, depth,
708 ctx->error, 0))
709 return 0;
710
711 return 1;
712 }
713
714 struct x509_verify_ctx *
x509_verify_ctx_new_from_xsc(X509_STORE_CTX * xsc,STACK_OF (X509)* roots)715 x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc, STACK_OF(X509) *roots)
716 {
717 struct x509_verify_ctx *ctx;
718 size_t max_depth;
719
720 if (xsc == NULL)
721 return NULL;
722
723 if ((ctx = x509_verify_ctx_new(roots)) == NULL)
724 return NULL;
725
726 ctx->xsc = xsc;
727
728 if (xsc->untrusted &&
729 (ctx->intermediates = X509_chain_up_ref(xsc->untrusted)) == NULL)
730 goto err;
731
732 max_depth = X509_VERIFY_MAX_CHAIN_CERTS;
733 if (xsc->param->depth > 0 && xsc->param->depth < X509_VERIFY_MAX_CHAIN_CERTS)
734 max_depth = xsc->param->depth;
735 if (!x509_verify_ctx_set_max_depth(ctx, max_depth))
736 goto err;
737
738 return ctx;
739 err:
740 x509_verify_ctx_free(ctx);
741 return NULL;
742 }
743
744 /* Public API */
745
746 struct x509_verify_ctx *
x509_verify_ctx_new(STACK_OF (X509)* roots)747 x509_verify_ctx_new(STACK_OF(X509) *roots)
748 {
749 struct x509_verify_ctx *ctx;
750
751 if (roots == NULL)
752 return NULL;
753
754 if ((ctx = calloc(1, sizeof(struct x509_verify_ctx))) == NULL)
755 return NULL;
756
757 if ((ctx->roots = X509_chain_up_ref(roots)) == NULL)
758 goto err;
759
760 ctx->max_depth = X509_VERIFY_MAX_CHAIN_CERTS;
761 ctx->max_chains = X509_VERIFY_MAX_CHAINS;
762 ctx->max_sigs = X509_VERIFY_MAX_SIGCHECKS;
763
764 if ((ctx->chains = calloc(X509_VERIFY_MAX_CHAINS,
765 sizeof(*ctx->chains))) == NULL)
766 goto err;
767
768 return ctx;
769 err:
770 x509_verify_ctx_free(ctx);
771 return NULL;
772 }
773
774 void
x509_verify_ctx_free(struct x509_verify_ctx * ctx)775 x509_verify_ctx_free(struct x509_verify_ctx *ctx)
776 {
777 if (ctx == NULL)
778 return;
779 sk_X509_pop_free(ctx->roots, X509_free);
780 x509_verify_ctx_clear(ctx);
781 free(ctx);
782 }
783
784 int
x509_verify_ctx_set_max_depth(struct x509_verify_ctx * ctx,size_t max)785 x509_verify_ctx_set_max_depth(struct x509_verify_ctx *ctx, size_t max)
786 {
787 if (max < 1 || max > X509_VERIFY_MAX_CHAIN_CERTS)
788 return 0;
789 ctx->max_depth = max;
790 return 1;
791 }
792
793 int
x509_verify_ctx_set_max_chains(struct x509_verify_ctx * ctx,size_t max)794 x509_verify_ctx_set_max_chains(struct x509_verify_ctx *ctx, size_t max)
795 {
796 if (max < 1 || max > X509_VERIFY_MAX_CHAINS)
797 return 0;
798 ctx->max_chains = max;
799 return 1;
800 }
801
802 int
x509_verify_ctx_set_max_signatures(struct x509_verify_ctx * ctx,size_t max)803 x509_verify_ctx_set_max_signatures(struct x509_verify_ctx *ctx, size_t max)
804 {
805 if (max < 1 || max > 100000)
806 return 0;
807 ctx->max_sigs = max;
808 return 1;
809 }
810
811 int
x509_verify_ctx_set_purpose(struct x509_verify_ctx * ctx,int purpose)812 x509_verify_ctx_set_purpose(struct x509_verify_ctx *ctx, int purpose)
813 {
814 if (purpose < X509_PURPOSE_MIN || purpose > X509_PURPOSE_MAX)
815 return 0;
816 ctx->purpose = purpose;
817 return 1;
818 }
819
820 int
x509_verify_ctx_set_intermediates(struct x509_verify_ctx * ctx,STACK_OF (X509)* intermediates)821 x509_verify_ctx_set_intermediates(struct x509_verify_ctx *ctx,
822 STACK_OF(X509) *intermediates)
823 {
824 if ((ctx->intermediates = X509_chain_up_ref(intermediates)) == NULL)
825 return 0;
826 return 1;
827 }
828
829 const char *
x509_verify_ctx_error_string(struct x509_verify_ctx * ctx)830 x509_verify_ctx_error_string(struct x509_verify_ctx *ctx)
831 {
832 return X509_verify_cert_error_string(ctx->error);
833 }
834
835 size_t
x509_verify_ctx_error_depth(struct x509_verify_ctx * ctx)836 x509_verify_ctx_error_depth(struct x509_verify_ctx *ctx)
837 {
838 return ctx->error_depth;
839 }
840
STACK_OF(X509)841 STACK_OF(X509) *
842 x509_verify_ctx_chain(struct x509_verify_ctx *ctx, size_t i)
843 {
844 if (i >= ctx->chains_count)
845 return NULL;
846 return ctx->chains[i]->certs;
847 }
848
849 size_t
x509_verify(struct x509_verify_ctx * ctx,X509 * leaf,char * name)850 x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name)
851 {
852 struct x509_verify_chain *current_chain;
853
854 if (ctx->roots == NULL || ctx->max_depth == 0) {
855 ctx->error = X509_V_ERR_INVALID_CALL;
856 return 0;
857 }
858
859 if (ctx->xsc != NULL) {
860 if (leaf != NULL || name != NULL) {
861 ctx->error = X509_V_ERR_INVALID_CALL;
862 return 0;
863 }
864 leaf = ctx->xsc->cert;
865
866 /*
867 * XXX
868 * The legacy code expects the top level cert to be
869 * there, even if we didn't find a chain. So put it
870 * there, we will clobber it later if we find a valid
871 * chain.
872 */
873 if ((ctx->xsc->chain = sk_X509_new_null()) == NULL) {
874 ctx->error = X509_V_ERR_OUT_OF_MEM;
875 return 0;
876 }
877 if (!X509_up_ref(leaf)) {
878 ctx->error = X509_V_ERR_OUT_OF_MEM;
879 return 0;
880 }
881 if (!sk_X509_push(ctx->xsc->chain, leaf)) {
882 X509_free(leaf);
883 ctx->error = X509_V_ERR_OUT_OF_MEM;
884 return 0;
885 }
886 ctx->xsc->error_depth = 0;
887 ctx->xsc->current_cert = leaf;
888 }
889
890 if (!x509_verify_cert_valid(ctx, leaf, NULL))
891 return 0;
892
893 if (!x509_verify_cert_hostname(ctx, leaf, name))
894 return 0;
895
896 if ((current_chain = x509_verify_chain_new()) == NULL) {
897 ctx->error = X509_V_ERR_OUT_OF_MEM;
898 return 0;
899 }
900 if (!x509_verify_chain_append(current_chain, leaf, &ctx->error)) {
901 x509_verify_chain_free(current_chain);
902 return 0;
903 }
904 if (x509_verify_ctx_cert_is_root(ctx, leaf))
905 x509_verify_ctx_add_chain(ctx, current_chain);
906 else
907 x509_verify_build_chains(ctx, leaf, current_chain);
908
909 x509_verify_chain_free(current_chain);
910
911 /*
912 * Safety net:
913 * We could not find a validated chain, and for some reason do not
914 * have an error set.
915 */
916 if (ctx->chains_count == 0 && ctx->error == 0)
917 ctx->error = X509_V_ERR_UNSPECIFIED;
918
919 /* Clear whatever errors happened if we have any validated chain */
920 if (ctx->chains_count > 0)
921 ctx->error = X509_V_OK;
922
923 if (ctx->xsc != NULL) {
924 ctx->xsc->error = ctx->error;
925 return ctx->xsc->verify_cb(ctx->chains_count, ctx->xsc);
926 }
927 return (ctx->chains_count);
928 }
929