blob: 27b58f45b34533bac2649acbd3353c2440eba890 [file] [log] [blame]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.] */
56
57#include <string.h>
58#include <time.h>
59
60#include <openssl/asn1.h>
61#include <openssl/buf.h>
62#include <openssl/err.h>
63#include <openssl/evp.h>
64#include <openssl/lhash.h>
65#include <openssl/mem.h>
66#include <openssl/obj.h>
Adam Langleye9ada862015-05-11 17:20:37 -070067#include <openssl/thread.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080068#include <openssl/x509.h>
69#include <openssl/x509v3.h>
70
71#include "vpm_int.h"
Adam Langleye9ada862015-05-11 17:20:37 -070072#include "../internal.h"
73
Kenny Rootb8494592015-09-25 02:29:14 +000074static CRYPTO_EX_DATA_CLASS g_ex_data_class =
David Benjamin4969cc92016-04-22 15:02:23 -040075 CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
Adam Langleyd9e397b2015-01-22 14:27:53 -080076
77/* CRL score values */
78
79/* No unhandled critical extensions */
80
David Benjamin4969cc92016-04-22 15:02:23 -040081#define CRL_SCORE_NOCRITICAL 0x100
Adam Langleyd9e397b2015-01-22 14:27:53 -080082
83/* certificate is within CRL scope */
84
David Benjamin4969cc92016-04-22 15:02:23 -040085#define CRL_SCORE_SCOPE 0x080
Adam Langleyd9e397b2015-01-22 14:27:53 -080086
87/* CRL times valid */
88
David Benjamin4969cc92016-04-22 15:02:23 -040089#define CRL_SCORE_TIME 0x040
Adam Langleyd9e397b2015-01-22 14:27:53 -080090
91/* Issuer name matches certificate */
92
David Benjamin4969cc92016-04-22 15:02:23 -040093#define CRL_SCORE_ISSUER_NAME 0x020
Adam Langleyd9e397b2015-01-22 14:27:53 -080094
95/* If this score or above CRL is probably valid */
96
97#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE)
98
99/* CRL issuer is certificate issuer */
100
David Benjamin4969cc92016-04-22 15:02:23 -0400101#define CRL_SCORE_ISSUER_CERT 0x018
Adam Langleyd9e397b2015-01-22 14:27:53 -0800102
103/* CRL issuer is on certificate path */
104
David Benjamin4969cc92016-04-22 15:02:23 -0400105#define CRL_SCORE_SAME_PATH 0x008
Adam Langleyd9e397b2015-01-22 14:27:53 -0800106
107/* CRL issuer matches CRL AKID */
108
David Benjamin4969cc92016-04-22 15:02:23 -0400109#define CRL_SCORE_AKID 0x004
Adam Langleyd9e397b2015-01-22 14:27:53 -0800110
111/* Have a delta CRL with valid times */
112
David Benjamin4969cc92016-04-22 15:02:23 -0400113#define CRL_SCORE_TIME_DELTA 0x002
Adam Langleyd9e397b2015-01-22 14:27:53 -0800114
David Benjamin4969cc92016-04-22 15:02:23 -0400115static int null_callback(int ok, X509_STORE_CTX *e);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800116static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
117static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
118static int check_chain_extensions(X509_STORE_CTX *ctx);
119static int check_name_constraints(X509_STORE_CTX *ctx);
120static int check_id(X509_STORE_CTX *ctx);
121static int check_trust(X509_STORE_CTX *ctx);
122static int check_revocation(X509_STORE_CTX *ctx);
123static int check_cert(X509_STORE_CTX *ctx);
124static int check_policy(X509_STORE_CTX *ctx);
125
126static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
David Benjamin4969cc92016-04-22 15:02:23 -0400127 unsigned int *preasons, X509_CRL *crl, X509 *x);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800128static int get_crl_delta(X509_STORE_CTX *ctx,
David Benjamin4969cc92016-04-22 15:02:23 -0400129 X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
130static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl,
131 int *pcrl_score, X509_CRL *base,
132 STACK_OF(X509_CRL) *crls);
133static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
134 int *pcrl_score);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800135static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
David Benjamin4969cc92016-04-22 15:02:23 -0400136 unsigned int *preasons);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800137static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
138static int check_crl_chain(X509_STORE_CTX *ctx,
David Benjamin4969cc92016-04-22 15:02:23 -0400139 STACK_OF(X509) *cert_path,
140 STACK_OF(X509) *crl_path);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800141
142static int internal_verify(X509_STORE_CTX *ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800143
Adam Langleyd9e397b2015-01-22 14:27:53 -0800144static int null_callback(int ok, X509_STORE_CTX *e)
David Benjamin4969cc92016-04-22 15:02:23 -0400145{
146 return ok;
147}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800148
149#if 0
150static int x509_subject_cmp(X509 **a, X509 **b)
David Benjamin4969cc92016-04-22 15:02:23 -0400151{
152 return X509_subject_name_cmp(*a, *b);
153}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800154#endif
155/* Return 1 is a certificate is self signed */
156static int cert_self_signed(X509 *x)
David Benjamin4969cc92016-04-22 15:02:23 -0400157{
158 X509_check_purpose(x, -1, 0);
159 if (x->ex_flags & EXFLAG_SS)
160 return 1;
161 else
162 return 0;
163}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800164
165/* Given a certificate try and find an exact match in the store */
166
167static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
David Benjamin4969cc92016-04-22 15:02:23 -0400168{
169 STACK_OF(X509) *certs;
170 X509 *xtmp = NULL;
171 size_t i;
172 /* Lookup all certs with matching subject name */
173 certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
174 if (certs == NULL)
175 return NULL;
176 /* Look for exact match */
177 for (i = 0; i < sk_X509_num(certs); i++) {
178 xtmp = sk_X509_value(certs, i);
179 if (!X509_cmp(xtmp, x))
180 break;
181 }
182 if (i < sk_X509_num(certs))
183 X509_up_ref(xtmp);
184 else
185 xtmp = NULL;
186 sk_X509_pop_free(certs, X509_free);
187 return xtmp;
188}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800189
190int X509_verify_cert(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -0400191{
192 X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
193 int bad_chain = 0;
194 X509_VERIFY_PARAM *param = ctx->param;
195 int depth, i, ok = 0;
196 int num, j, retry, trust;
197 int (*cb) (int xok, X509_STORE_CTX *xctx);
198 STACK_OF(X509) *sktmp = NULL;
199 if (ctx->cert == NULL) {
200 OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
David Benjamin6e899c72016-06-09 18:02:18 -0400201 ctx->error = X509_V_ERR_INVALID_CALL;
David Benjamin4969cc92016-04-22 15:02:23 -0400202 return -1;
203 }
204 if (ctx->chain != NULL) {
205 /*
206 * This X509_STORE_CTX has already been used to verify a cert. We
207 * cannot do another one.
208 */
209 OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
David Benjamin6e899c72016-06-09 18:02:18 -0400210 ctx->error = X509_V_ERR_INVALID_CALL;
David Benjamin4969cc92016-04-22 15:02:23 -0400211 return -1;
212 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800213
David Benjamin4969cc92016-04-22 15:02:23 -0400214 cb = ctx->verify_cb;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800215
David Benjamin4969cc92016-04-22 15:02:23 -0400216 /*
217 * first we make sure the chain we are going to build is present and that
218 * the first entry is in place
219 */
220 ctx->chain = sk_X509_new_null();
221 if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) {
222 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
David Benjamin6e899c72016-06-09 18:02:18 -0400223 ctx->error = X509_V_ERR_OUT_OF_MEM;
David Benjamin4969cc92016-04-22 15:02:23 -0400224 goto end;
225 }
226 X509_up_ref(ctx->cert);
227 ctx->last_untrusted = 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800228
Robert Sloan69939df2017-01-09 10:53:07 -0800229 /* We use a temporary STACK so we can chop and hack at it.
230 * sktmp = ctx->untrusted ++ ctx->ctx->additional_untrusted */
David Benjamin4969cc92016-04-22 15:02:23 -0400231 if (ctx->untrusted != NULL
232 && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
233 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
David Benjamin6e899c72016-06-09 18:02:18 -0400234 ctx->error = X509_V_ERR_OUT_OF_MEM;
David Benjamin4969cc92016-04-22 15:02:23 -0400235 goto end;
236 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800237
Robert Sloan69939df2017-01-09 10:53:07 -0800238 if (ctx->ctx->additional_untrusted != NULL) {
239 if (sktmp == NULL) {
240 sktmp = sk_X509_new_null();
241 if (sktmp == NULL) {
242 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
243 ctx->error = X509_V_ERR_OUT_OF_MEM;
244 goto end;
245 }
246 }
247
248 for (size_t k = 0; k < sk_X509_num(ctx->ctx->additional_untrusted);
249 k++) {
250 if (!sk_X509_push(sktmp,
251 sk_X509_value(ctx->ctx->additional_untrusted,
252 k))) {
253 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
254 ctx->error = X509_V_ERR_OUT_OF_MEM;
255 goto end;
256 }
257 }
258 }
259
David Benjamin4969cc92016-04-22 15:02:23 -0400260 num = sk_X509_num(ctx->chain);
261 x = sk_X509_value(ctx->chain, num - 1);
262 depth = param->depth;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800263
David Benjamin4969cc92016-04-22 15:02:23 -0400264 for (;;) {
265 /* If we have enough, we break */
266 if (depth < num)
267 break; /* FIXME: If this happens, we should take
268 * note of it and, if appropriate, use the
269 * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
270 * later. */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800271
David Benjamin4969cc92016-04-22 15:02:23 -0400272 /* If we are self signed, we break */
273 if (cert_self_signed(x))
274 break;
275 /*
276 * If asked see if we can find issuer in trusted store first
277 */
278 if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) {
279 ok = ctx->get_issuer(&xtmp, ctx, x);
David Benjamin6e899c72016-06-09 18:02:18 -0400280 if (ok < 0) {
281 ctx->error = X509_V_ERR_STORE_LOOKUP;
David Benjamin4969cc92016-04-22 15:02:23 -0400282 goto end;
David Benjamin6e899c72016-06-09 18:02:18 -0400283 }
David Benjamin4969cc92016-04-22 15:02:23 -0400284 /*
285 * If successful for now free up cert so it will be picked up
286 * again later.
287 */
288 if (ok > 0) {
289 X509_free(xtmp);
290 break;
291 }
292 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800293
David Benjamin4969cc92016-04-22 15:02:23 -0400294 /* If we were passed a cert chain, use it first */
Robert Sloan69939df2017-01-09 10:53:07 -0800295 if (sktmp != NULL) {
David Benjamin4969cc92016-04-22 15:02:23 -0400296 xtmp = find_issuer(ctx, sktmp, x);
297 if (xtmp != NULL) {
298 if (!sk_X509_push(ctx->chain, xtmp)) {
299 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
David Benjamin6e899c72016-06-09 18:02:18 -0400300 ctx->error = X509_V_ERR_OUT_OF_MEM;
David Benjamin4969cc92016-04-22 15:02:23 -0400301 ok = 0;
302 goto end;
303 }
304 X509_up_ref(xtmp);
305 (void)sk_X509_delete_ptr(sktmp, xtmp);
306 ctx->last_untrusted++;
307 x = xtmp;
308 num++;
309 /*
310 * reparse the full chain for the next one
311 */
312 continue;
313 }
314 }
315 break;
316 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800317
David Benjamin4969cc92016-04-22 15:02:23 -0400318 /* Remember how many untrusted certs we have */
319 j = num;
320 /*
321 * at this point, chain should contain a list of untrusted certificates.
322 * We now need to add at least one trusted one, if possible, otherwise we
323 * complain.
324 */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800325
David Benjamin4969cc92016-04-22 15:02:23 -0400326 do {
327 /*
328 * Examine last certificate in chain and see if it is self signed.
329 */
330 i = sk_X509_num(ctx->chain);
331 x = sk_X509_value(ctx->chain, i - 1);
332 if (cert_self_signed(x)) {
333 /* we have a self signed certificate */
334 if (sk_X509_num(ctx->chain) == 1) {
335 /*
336 * We have a single self signed certificate: see if we can
337 * find it in the store. We must have an exact match to avoid
338 * possible impersonation.
339 */
340 ok = ctx->get_issuer(&xtmp, ctx, x);
341 if ((ok <= 0) || X509_cmp(x, xtmp)) {
342 ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
343 ctx->current_cert = x;
344 ctx->error_depth = i - 1;
345 if (ok == 1)
346 X509_free(xtmp);
347 bad_chain = 1;
348 ok = cb(0, ctx);
349 if (!ok)
350 goto end;
351 } else {
352 /*
353 * We have a match: replace certificate with store
354 * version so we get any trust settings.
355 */
356 X509_free(x);
357 x = xtmp;
358 (void)sk_X509_set(ctx->chain, i - 1, x);
359 ctx->last_untrusted = 0;
360 }
361 } else {
362 /*
363 * extract and save self signed certificate for later use
364 */
365 chain_ss = sk_X509_pop(ctx->chain);
366 ctx->last_untrusted--;
367 num--;
368 j--;
369 x = sk_X509_value(ctx->chain, num - 1);
370 }
371 }
372 /* We now lookup certs from the certificate store */
373 for (;;) {
374 /* If we have enough, we break */
375 if (depth < num)
376 break;
377 /* If we are self signed, we break */
378 if (cert_self_signed(x))
379 break;
380 ok = ctx->get_issuer(&xtmp, ctx, x);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800381
David Benjamin6e899c72016-06-09 18:02:18 -0400382 if (ok < 0) {
383 ctx->error = X509_V_ERR_STORE_LOOKUP;
David Benjamin4969cc92016-04-22 15:02:23 -0400384 goto end;
David Benjamin6e899c72016-06-09 18:02:18 -0400385 }
David Benjamin4969cc92016-04-22 15:02:23 -0400386 if (ok == 0)
387 break;
388 x = xtmp;
389 if (!sk_X509_push(ctx->chain, x)) {
390 X509_free(xtmp);
391 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
David Benjamin6e899c72016-06-09 18:02:18 -0400392 ctx->error = X509_V_ERR_OUT_OF_MEM;
David Benjamin4969cc92016-04-22 15:02:23 -0400393 ok = 0;
394 goto end;
395 }
396 num++;
397 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800398
David Benjamin4969cc92016-04-22 15:02:23 -0400399 /* we now have our chain, lets check it... */
400 trust = check_trust(ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800401
David Benjamin4969cc92016-04-22 15:02:23 -0400402 /* If explicitly rejected error */
403 if (trust == X509_TRUST_REJECTED) {
404 ok = 0;
405 goto end;
406 }
407 /*
408 * If it's not explicitly trusted then check if there is an alternative
409 * chain that could be used. We only do this if we haven't already
410 * checked via TRUSTED_FIRST and the user hasn't switched off alternate
411 * chain checking
412 */
413 retry = 0;
414 if (trust != X509_TRUST_TRUSTED
415 && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
416 && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
417 while (j-- > 1) {
418 xtmp2 = sk_X509_value(ctx->chain, j - 1);
419 ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
420 if (ok < 0)
421 goto end;
422 /* Check if we found an alternate chain */
423 if (ok > 0) {
424 /*
425 * Free up the found cert we'll add it again later
426 */
427 X509_free(xtmp);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800428
David Benjamin4969cc92016-04-22 15:02:23 -0400429 /*
430 * Dump all the certs above this point - we've found an
431 * alternate chain
432 */
433 while (num > j) {
434 xtmp = sk_X509_pop(ctx->chain);
435 X509_free(xtmp);
436 num--;
437 }
438 ctx->last_untrusted = sk_X509_num(ctx->chain);
439 retry = 1;
440 break;
441 }
442 }
443 }
444 } while (retry);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800445
David Benjamin4969cc92016-04-22 15:02:23 -0400446 /*
447 * If not explicitly trusted then indicate error unless it's a single
448 * self signed certificate in which case we've indicated an error already
449 * and set bad_chain == 1
450 */
451 if (trust != X509_TRUST_TRUSTED && !bad_chain) {
452 if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
453 if (ctx->last_untrusted >= num)
454 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
455 else
456 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
457 ctx->current_cert = x;
458 } else {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800459
David Benjamin4969cc92016-04-22 15:02:23 -0400460 sk_X509_push(ctx->chain, chain_ss);
461 num++;
462 ctx->last_untrusted = num;
463 ctx->current_cert = chain_ss;
464 ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
465 chain_ss = NULL;
466 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800467
David Benjamin4969cc92016-04-22 15:02:23 -0400468 ctx->error_depth = num - 1;
469 bad_chain = 1;
470 ok = cb(0, ctx);
471 if (!ok)
472 goto end;
473 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800474
David Benjamin4969cc92016-04-22 15:02:23 -0400475 /* We have the chain complete: now we need to check its purpose */
476 ok = check_chain_extensions(ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800477
David Benjamin4969cc92016-04-22 15:02:23 -0400478 if (!ok)
479 goto end;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800480
David Benjamin4969cc92016-04-22 15:02:23 -0400481 /* Check name constraints */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800482
David Benjamin4969cc92016-04-22 15:02:23 -0400483 ok = check_name_constraints(ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800484
David Benjamin4969cc92016-04-22 15:02:23 -0400485 if (!ok)
486 goto end;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800487
David Benjamin4969cc92016-04-22 15:02:23 -0400488 ok = check_id(ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800489
David Benjamin4969cc92016-04-22 15:02:23 -0400490 if (!ok)
491 goto end;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800492
David Benjamin4969cc92016-04-22 15:02:23 -0400493 /*
494 * Check revocation status: we do this after copying parameters because
495 * they may be needed for CRL signature verification.
496 */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800497
David Benjamin4969cc92016-04-22 15:02:23 -0400498 ok = ctx->check_revocation(ctx);
499 if (!ok)
500 goto end;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800501
David Benjamin4969cc92016-04-22 15:02:23 -0400502 int err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
503 ctx->param->flags);
504 if (err != X509_V_OK) {
505 ctx->error = err;
506 ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
507 ok = cb(0, ctx);
508 if (!ok)
509 goto end;
510 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800511
David Benjamin4969cc92016-04-22 15:02:23 -0400512 /* At this point, we have a chain and need to verify it */
513 if (ctx->verify != NULL)
514 ok = ctx->verify(ctx);
515 else
516 ok = internal_verify(ctx);
517 if (!ok)
518 goto end;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800519
David Benjamin4969cc92016-04-22 15:02:23 -0400520 /* If we get this far evaluate policies */
521 if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
522 ok = ctx->check_policy(ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800523
David Benjamin4969cc92016-04-22 15:02:23 -0400524 end:
525 if (sktmp != NULL)
526 sk_X509_free(sktmp);
527 if (chain_ss != NULL)
528 X509_free(chain_ss);
David Benjamin6e899c72016-06-09 18:02:18 -0400529
530 /* Safety net, error returns must set ctx->error */
531 if (ok <= 0 && ctx->error == X509_V_OK)
532 ctx->error = X509_V_ERR_UNSPECIFIED;
David Benjamin4969cc92016-04-22 15:02:23 -0400533 return ok;
534}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800535
David Benjamin4969cc92016-04-22 15:02:23 -0400536/*
537 * Given a STACK_OF(X509) find the issuer of cert (if any)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800538 */
539
540static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
541{
David Benjamin4969cc92016-04-22 15:02:23 -0400542 size_t i;
543 X509 *issuer;
544 for (i = 0; i < sk_X509_num(sk); i++) {
545 issuer = sk_X509_value(sk, i);
546 if (ctx->check_issued(ctx, x, issuer))
547 return issuer;
548 }
549 return NULL;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800550}
551
552/* Given a possible certificate and issuer check them */
553
554static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
555{
David Benjamin4969cc92016-04-22 15:02:23 -0400556 int ret;
557 ret = X509_check_issued(issuer, x);
558 if (ret == X509_V_OK)
559 return 1;
560 /* If we haven't asked for issuer errors don't set ctx */
561 if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
562 return 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800563
David Benjamin4969cc92016-04-22 15:02:23 -0400564 ctx->error = ret;
565 ctx->current_cert = x;
566 ctx->current_issuer = issuer;
567 return ctx->verify_cb(0, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800568}
569
570/* Alternative lookup method: look from a STACK stored in other_ctx */
571
572static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
573{
David Benjamin4969cc92016-04-22 15:02:23 -0400574 *issuer = find_issuer(ctx, ctx->other_ctx, x);
575 if (*issuer) {
576 X509_up_ref(*issuer);
577 return 1;
578 } else
579 return 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800580}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800581
David Benjamin4969cc92016-04-22 15:02:23 -0400582/*
583 * Check a certificate chains extensions for consistency with the supplied
584 * purpose
Adam Langleyd9e397b2015-01-22 14:27:53 -0800585 */
586
587static int check_chain_extensions(X509_STORE_CTX *ctx)
588{
David Benjamin4969cc92016-04-22 15:02:23 -0400589 int i, ok = 0, must_be_ca, plen = 0;
590 X509 *x;
591 int (*cb) (int xok, X509_STORE_CTX *xctx);
592 int proxy_path_length = 0;
593 int purpose;
594 int allow_proxy_certs;
595 cb = ctx->verify_cb;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800596
David Benjamin4969cc92016-04-22 15:02:23 -0400597 /*
598 * must_be_ca can have 1 of 3 values: -1: we accept both CA and non-CA
599 * certificates, to allow direct use of self-signed certificates (which
600 * are marked as CA). 0: we only accept non-CA certificates. This is
601 * currently not used, but the possibility is present for future
602 * extensions. 1: we only accept CA certificates. This is currently used
603 * for all certificates in the chain except the leaf certificate.
604 */
605 must_be_ca = -1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800606
David Benjamin4969cc92016-04-22 15:02:23 -0400607 /* CRL path validation */
608 if (ctx->parent) {
609 allow_proxy_certs = 0;
610 purpose = X509_PURPOSE_CRL_SIGN;
611 } else {
612 allow_proxy_certs =
613 ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
David Benjamin4969cc92016-04-22 15:02:23 -0400614 purpose = ctx->param->purpose;
615 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800616
David Benjamin4969cc92016-04-22 15:02:23 -0400617 /* Check all untrusted certificates */
618 for (i = 0; i < ctx->last_untrusted; i++) {
619 int ret;
620 x = sk_X509_value(ctx->chain, i);
621 if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
622 && (x->ex_flags & EXFLAG_CRITICAL)) {
623 ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
624 ctx->error_depth = i;
625 ctx->current_cert = x;
626 ok = cb(0, ctx);
627 if (!ok)
628 goto end;
629 }
630 if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
631 ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
632 ctx->error_depth = i;
633 ctx->current_cert = x;
634 ok = cb(0, ctx);
635 if (!ok)
636 goto end;
637 }
638 ret = X509_check_ca(x);
639 switch (must_be_ca) {
640 case -1:
641 if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
642 && (ret != 1) && (ret != 0)) {
643 ret = 0;
644 ctx->error = X509_V_ERR_INVALID_CA;
645 } else
646 ret = 1;
647 break;
648 case 0:
649 if (ret != 0) {
650 ret = 0;
651 ctx->error = X509_V_ERR_INVALID_NON_CA;
652 } else
653 ret = 1;
654 break;
655 default:
656 if ((ret == 0)
657 || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
658 && (ret != 1))) {
659 ret = 0;
660 ctx->error = X509_V_ERR_INVALID_CA;
661 } else
662 ret = 1;
663 break;
664 }
665 if (ret == 0) {
666 ctx->error_depth = i;
667 ctx->current_cert = x;
668 ok = cb(0, ctx);
669 if (!ok)
670 goto end;
671 }
672 if (ctx->param->purpose > 0) {
673 ret = X509_check_purpose(x, purpose, must_be_ca > 0);
674 if ((ret == 0)
675 || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
676 && (ret != 1))) {
677 ctx->error = X509_V_ERR_INVALID_PURPOSE;
678 ctx->error_depth = i;
679 ctx->current_cert = x;
680 ok = cb(0, ctx);
681 if (!ok)
682 goto end;
683 }
684 }
685 /* Check pathlen if not self issued */
686 if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
687 && (x->ex_pathlen != -1)
688 && (plen > (x->ex_pathlen + proxy_path_length + 1))) {
689 ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
690 ctx->error_depth = i;
691 ctx->current_cert = x;
692 ok = cb(0, ctx);
693 if (!ok)
694 goto end;
695 }
696 /* Increment path length if not self issued */
697 if (!(x->ex_flags & EXFLAG_SI))
698 plen++;
699 /*
700 * If this certificate is a proxy certificate, the next certificate
701 * must be another proxy certificate or a EE certificate. If not,
702 * the next certificate must be a CA certificate.
703 */
704 if (x->ex_flags & EXFLAG_PROXY) {
705 if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
706 ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
707 ctx->error_depth = i;
708 ctx->current_cert = x;
709 ok = cb(0, ctx);
710 if (!ok)
711 goto end;
712 }
713 proxy_path_length++;
714 must_be_ca = 0;
715 } else
716 must_be_ca = 1;
717 }
718 ok = 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800719 end:
David Benjamin4969cc92016-04-22 15:02:23 -0400720 return ok;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800721}
722
723static int check_name_constraints(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -0400724{
725 X509 *x;
726 int i, j, rv;
727 /* Check name constraints for all certificates */
728 for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) {
729 x = sk_X509_value(ctx->chain, i);
730 /* Ignore self issued certs unless last in chain */
731 if (i && (x->ex_flags & EXFLAG_SI))
732 continue;
733 /*
734 * Check against constraints for all certificates higher in chain
735 * including trust anchor. Trust anchor not strictly speaking needed
736 * but if it includes constraints it is to be assumed it expects them
737 * to be obeyed.
738 */
739 for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) {
740 NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
741 if (nc) {
742 rv = NAME_CONSTRAINTS_check(x, nc);
David Benjamin6e899c72016-06-09 18:02:18 -0400743 switch (rv) {
744 case X509_V_OK:
745 continue;
746 case X509_V_ERR_OUT_OF_MEM:
747 ctx->error = rv;
748 return 0;
749 default:
David Benjamin4969cc92016-04-22 15:02:23 -0400750 ctx->error = rv;
751 ctx->error_depth = i;
752 ctx->current_cert = x;
753 if (!ctx->verify_cb(0, ctx))
754 return 0;
David Benjamin6e899c72016-06-09 18:02:18 -0400755 break;
David Benjamin4969cc92016-04-22 15:02:23 -0400756 }
757 }
758 }
759 }
760 return 1;
761}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800762
763static int check_id_error(X509_STORE_CTX *ctx, int errcode)
David Benjamin4969cc92016-04-22 15:02:23 -0400764{
765 ctx->error = errcode;
766 ctx->current_cert = ctx->cert;
767 ctx->error_depth = 0;
768 return ctx->verify_cb(0, ctx);
769}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800770
Adam Langleye9ada862015-05-11 17:20:37 -0700771static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id)
David Benjamin4969cc92016-04-22 15:02:23 -0400772{
773 size_t i;
774 size_t n = sk_OPENSSL_STRING_num(id->hosts);
775 char *name;
Adam Langleye9ada862015-05-11 17:20:37 -0700776
David Benjamin4969cc92016-04-22 15:02:23 -0400777 if (id->peername != NULL) {
778 OPENSSL_free(id->peername);
779 id->peername = NULL;
780 }
781 for (i = 0; i < n; ++i) {
782 name = sk_OPENSSL_STRING_value(id->hosts, i);
783 if (X509_check_host(x, name, strlen(name), id->hostflags,
784 &id->peername) > 0)
785 return 1;
786 }
787 return n == 0;
788}
Adam Langleye9ada862015-05-11 17:20:37 -0700789
Adam Langleyd9e397b2015-01-22 14:27:53 -0800790static int check_id(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -0400791{
792 X509_VERIFY_PARAM *vpm = ctx->param;
793 X509_VERIFY_PARAM_ID *id = vpm->id;
794 X509 *x = ctx->cert;
795 if (id->hosts && check_hosts(x, id) <= 0) {
796 if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
797 return 0;
798 }
799 if (id->email && X509_check_email(x, id->email, id->emaillen, 0) <= 0) {
800 if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
801 return 0;
802 }
803 if (id->ip && X509_check_ip(x, id->ip, id->iplen, 0) <= 0) {
804 if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
805 return 0;
806 }
807 return 1;
808}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800809
810static int check_trust(X509_STORE_CTX *ctx)
811{
David Benjamin4969cc92016-04-22 15:02:23 -0400812 size_t i;
813 int ok;
814 X509 *x = NULL;
815 int (*cb) (int xok, X509_STORE_CTX *xctx);
816 cb = ctx->verify_cb;
817 /* Check all trusted certificates in chain */
818 for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) {
819 x = sk_X509_value(ctx->chain, i);
820 ok = X509_check_trust(x, ctx->param->trust, 0);
821 /* If explicitly trusted return trusted */
822 if (ok == X509_TRUST_TRUSTED)
823 return X509_TRUST_TRUSTED;
824 /*
825 * If explicitly rejected notify callback and reject if not
826 * overridden.
827 */
828 if (ok == X509_TRUST_REJECTED) {
829 ctx->error_depth = i;
830 ctx->current_cert = x;
831 ctx->error = X509_V_ERR_CERT_REJECTED;
832 ok = cb(0, ctx);
833 if (!ok)
834 return X509_TRUST_REJECTED;
835 }
836 }
837 /*
838 * If we accept partial chains and have at least one trusted certificate
839 * return success.
840 */
841 if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
842 X509 *mx;
843 if (ctx->last_untrusted < (int)sk_X509_num(ctx->chain))
844 return X509_TRUST_TRUSTED;
845 x = sk_X509_value(ctx->chain, 0);
846 mx = lookup_cert_match(ctx, x);
847 if (mx) {
848 (void)sk_X509_set(ctx->chain, 0, mx);
849 X509_free(x);
850 ctx->last_untrusted = 0;
851 return X509_TRUST_TRUSTED;
852 }
853 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800854
David Benjamin4969cc92016-04-22 15:02:23 -0400855 /*
856 * If no trusted certs in chain at all return untrusted and allow
857 * standard (no issuer cert) etc errors to be indicated.
858 */
859 return X509_TRUST_UNTRUSTED;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800860}
861
862static int check_revocation(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -0400863{
864 int i, last, ok;
865 if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
866 return 1;
867 if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
868 last = sk_X509_num(ctx->chain) - 1;
869 else {
870 /* If checking CRL paths this isn't the EE certificate */
871 if (ctx->parent)
872 return 1;
873 last = 0;
874 }
875 for (i = 0; i <= last; i++) {
876 ctx->error_depth = i;
877 ok = check_cert(ctx);
878 if (!ok)
879 return ok;
880 }
881 return 1;
882}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800883
884static int check_cert(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -0400885{
886 X509_CRL *crl = NULL, *dcrl = NULL;
887 X509 *x;
888 int ok = 0, cnum;
889 unsigned int last_reasons;
890 cnum = ctx->error_depth;
891 x = sk_X509_value(ctx->chain, cnum);
892 ctx->current_cert = x;
893 ctx->current_issuer = NULL;
894 ctx->current_crl_score = 0;
895 ctx->current_reasons = 0;
896 while (ctx->current_reasons != CRLDP_ALL_REASONS) {
897 last_reasons = ctx->current_reasons;
898 /* Try to retrieve relevant CRL */
899 if (ctx->get_crl)
900 ok = ctx->get_crl(ctx, &crl, x);
901 else
902 ok = get_crl_delta(ctx, &crl, &dcrl, x);
903 /*
904 * If error looking up CRL, nothing we can do except notify callback
905 */
906 if (!ok) {
907 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
908 ok = ctx->verify_cb(0, ctx);
909 goto err;
910 }
911 ctx->current_crl = crl;
912 ok = ctx->check_crl(ctx, crl);
913 if (!ok)
914 goto err;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800915
David Benjamin4969cc92016-04-22 15:02:23 -0400916 if (dcrl) {
917 ok = ctx->check_crl(ctx, dcrl);
918 if (!ok)
919 goto err;
920 ok = ctx->cert_crl(ctx, dcrl, x);
921 if (!ok)
922 goto err;
923 } else
924 ok = 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800925
David Benjamin4969cc92016-04-22 15:02:23 -0400926 /* Don't look in full CRL if delta reason is removefromCRL */
927 if (ok != 2) {
928 ok = ctx->cert_crl(ctx, crl, x);
929 if (!ok)
930 goto err;
931 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800932
David Benjamin4969cc92016-04-22 15:02:23 -0400933 X509_CRL_free(crl);
934 X509_CRL_free(dcrl);
935 crl = NULL;
936 dcrl = NULL;
937 /*
938 * If reasons not updated we wont get anywhere by another iteration,
939 * so exit loop.
940 */
941 if (last_reasons == ctx->current_reasons) {
942 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
943 ok = ctx->verify_cb(0, ctx);
944 goto err;
945 }
946 }
947 err:
948 X509_CRL_free(crl);
949 X509_CRL_free(dcrl);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800950
David Benjamin4969cc92016-04-22 15:02:23 -0400951 ctx->current_crl = NULL;
952 return ok;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800953
David Benjamin4969cc92016-04-22 15:02:23 -0400954}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800955
956/* Check CRL times against values in X509_STORE_CTX */
957
958static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
David Benjamin4969cc92016-04-22 15:02:23 -0400959{
960 time_t *ptime;
961 int i;
962 if (notify)
963 ctx->current_crl = crl;
964 if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
965 ptime = &ctx->param->check_time;
966 else
967 ptime = NULL;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800968
David Benjamin4969cc92016-04-22 15:02:23 -0400969 i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
970 if (i == 0) {
971 if (!notify)
972 return 0;
973 ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
974 if (!ctx->verify_cb(0, ctx))
975 return 0;
976 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800977
David Benjamin4969cc92016-04-22 15:02:23 -0400978 if (i > 0) {
979 if (!notify)
980 return 0;
981 ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
982 if (!ctx->verify_cb(0, ctx))
983 return 0;
984 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800985
David Benjamin4969cc92016-04-22 15:02:23 -0400986 if (X509_CRL_get_nextUpdate(crl)) {
987 i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800988
David Benjamin4969cc92016-04-22 15:02:23 -0400989 if (i == 0) {
990 if (!notify)
991 return 0;
992 ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
993 if (!ctx->verify_cb(0, ctx))
994 return 0;
995 }
996 /* Ignore expiry of base CRL is delta is valid */
997 if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) {
998 if (!notify)
999 return 0;
1000 ctx->error = X509_V_ERR_CRL_HAS_EXPIRED;
1001 if (!ctx->verify_cb(0, ctx))
1002 return 0;
1003 }
1004 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001005
David Benjamin4969cc92016-04-22 15:02:23 -04001006 if (notify)
1007 ctx->current_crl = NULL;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001008
David Benjamin4969cc92016-04-22 15:02:23 -04001009 return 1;
1010}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001011
1012static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
David Benjamin4969cc92016-04-22 15:02:23 -04001013 X509 **pissuer, int *pscore, unsigned int *preasons,
1014 STACK_OF(X509_CRL) *crls)
1015{
1016 int crl_score, best_score = *pscore;
1017 size_t i;
1018 unsigned int reasons, best_reasons = 0;
1019 X509 *x = ctx->current_cert;
1020 X509_CRL *crl, *best_crl = NULL;
1021 X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001022
David Benjamin4969cc92016-04-22 15:02:23 -04001023 for (i = 0; i < sk_X509_CRL_num(crls); i++) {
1024 crl = sk_X509_CRL_value(crls, i);
1025 reasons = *preasons;
1026 crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
Steven Valdezbb1ceac2016-10-07 10:34:51 -04001027 if (crl_score < best_score || crl_score == 0)
David Benjaminc895d6b2016-08-11 13:26:41 -04001028 continue;
1029 /* If current CRL is equivalent use it if it is newer */
Steven Valdezbb1ceac2016-10-07 10:34:51 -04001030 if (crl_score == best_score && best_crl != NULL) {
David Benjaminc895d6b2016-08-11 13:26:41 -04001031 int day, sec;
1032 if (ASN1_TIME_diff(&day, &sec, X509_CRL_get_lastUpdate(best_crl),
1033 X509_CRL_get_lastUpdate(crl)) == 0)
1034 continue;
1035 /*
1036 * ASN1_TIME_diff never returns inconsistent signs for |day|
1037 * and |sec|.
1038 */
1039 if (day <= 0 && sec <= 0)
1040 continue;
David Benjamin4969cc92016-04-22 15:02:23 -04001041 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001042 best_crl = crl;
1043 best_crl_issuer = crl_issuer;
1044 best_score = crl_score;
1045 best_reasons = reasons;
David Benjamin4969cc92016-04-22 15:02:23 -04001046 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001047
David Benjamin4969cc92016-04-22 15:02:23 -04001048 if (best_crl) {
1049 if (*pcrl)
1050 X509_CRL_free(*pcrl);
1051 *pcrl = best_crl;
1052 *pissuer = best_crl_issuer;
1053 *pscore = best_score;
1054 *preasons = best_reasons;
1055 X509_CRL_up_ref(best_crl);
1056 if (*pdcrl) {
1057 X509_CRL_free(*pdcrl);
1058 *pdcrl = NULL;
1059 }
1060 get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
1061 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001062
David Benjamin4969cc92016-04-22 15:02:23 -04001063 if (best_score >= CRL_SCORE_VALID)
1064 return 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001065
David Benjamin4969cc92016-04-22 15:02:23 -04001066 return 0;
1067}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001068
David Benjamin4969cc92016-04-22 15:02:23 -04001069/*
1070 * Compare two CRL extensions for delta checking purposes. They should be
Adam Langleyd9e397b2015-01-22 14:27:53 -08001071 * both present or both absent. If both present all fields must be identical.
1072 */
1073
1074static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
David Benjamin4969cc92016-04-22 15:02:23 -04001075{
1076 ASN1_OCTET_STRING *exta, *extb;
1077 int i;
1078 i = X509_CRL_get_ext_by_NID(a, nid, -1);
1079 if (i >= 0) {
1080 /* Can't have multiple occurrences */
1081 if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
1082 return 0;
1083 exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
1084 } else
1085 exta = NULL;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001086
David Benjamin4969cc92016-04-22 15:02:23 -04001087 i = X509_CRL_get_ext_by_NID(b, nid, -1);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001088
David Benjamin4969cc92016-04-22 15:02:23 -04001089 if (i >= 0) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001090
David Benjamin4969cc92016-04-22 15:02:23 -04001091 if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
1092 return 0;
1093 extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
1094 } else
1095 extb = NULL;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001096
David Benjamin4969cc92016-04-22 15:02:23 -04001097 if (!exta && !extb)
1098 return 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001099
David Benjamin4969cc92016-04-22 15:02:23 -04001100 if (!exta || !extb)
1101 return 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001102
David Benjamin4969cc92016-04-22 15:02:23 -04001103 if (ASN1_OCTET_STRING_cmp(exta, extb))
1104 return 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001105
David Benjamin4969cc92016-04-22 15:02:23 -04001106 return 1;
1107}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001108
1109/* See if a base and delta are compatible */
1110
1111static int check_delta_base(X509_CRL *delta, X509_CRL *base)
David Benjamin4969cc92016-04-22 15:02:23 -04001112{
1113 /* Delta CRL must be a delta */
1114 if (!delta->base_crl_number)
1115 return 0;
1116 /* Base must have a CRL number */
1117 if (!base->crl_number)
1118 return 0;
1119 /* Issuer names must match */
1120 if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta)))
1121 return 0;
1122 /* AKID and IDP must match */
1123 if (!crl_extension_match(delta, base, NID_authority_key_identifier))
1124 return 0;
1125 if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
1126 return 0;
1127 /* Delta CRL base number must not exceed Full CRL number. */
1128 if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
1129 return 0;
1130 /* Delta CRL number must exceed full CRL number */
1131 if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
1132 return 1;
1133 return 0;
1134}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001135
David Benjamin4969cc92016-04-22 15:02:23 -04001136/*
1137 * For a given base CRL find a delta... maybe extend to delta scoring or
1138 * retrieve a chain of deltas...
Adam Langleyd9e397b2015-01-22 14:27:53 -08001139 */
1140
1141static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
David Benjamin4969cc92016-04-22 15:02:23 -04001142 X509_CRL *base, STACK_OF(X509_CRL) *crls)
1143{
1144 X509_CRL *delta;
1145 size_t i;
1146 if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
1147 return;
1148 if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
1149 return;
1150 for (i = 0; i < sk_X509_CRL_num(crls); i++) {
1151 delta = sk_X509_CRL_value(crls, i);
1152 if (check_delta_base(delta, base)) {
1153 if (check_crl_time(ctx, delta, 0))
1154 *pscore |= CRL_SCORE_TIME_DELTA;
1155 X509_CRL_up_ref(delta);
1156 *dcrl = delta;
1157 return;
1158 }
1159 }
1160 *dcrl = NULL;
1161}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001162
David Benjamin4969cc92016-04-22 15:02:23 -04001163/*
1164 * For a given CRL return how suitable it is for the supplied certificate
1165 * 'x'. The return value is a mask of several criteria. If the issuer is not
1166 * the certificate issuer this is returned in *pissuer. The reasons mask is
1167 * also used to determine if the CRL is suitable: if no new reasons the CRL
1168 * is rejected, otherwise reasons is updated.
Adam Langleyd9e397b2015-01-22 14:27:53 -08001169 */
1170
1171static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
David Benjamin4969cc92016-04-22 15:02:23 -04001172 unsigned int *preasons, X509_CRL *crl, X509 *x)
1173{
Adam Langleyd9e397b2015-01-22 14:27:53 -08001174
David Benjamin4969cc92016-04-22 15:02:23 -04001175 int crl_score = 0;
1176 unsigned int tmp_reasons = *preasons, crl_reasons;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001177
David Benjamin4969cc92016-04-22 15:02:23 -04001178 /* First see if we can reject CRL straight away */
Adam Langleyd9e397b2015-01-22 14:27:53 -08001179
David Benjamin4969cc92016-04-22 15:02:23 -04001180 /* Invalid IDP cannot be processed */
1181 if (crl->idp_flags & IDP_INVALID)
1182 return 0;
1183 /* Reason codes or indirect CRLs need extended CRL support */
1184 if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) {
1185 if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
1186 return 0;
1187 } else if (crl->idp_flags & IDP_REASONS) {
1188 /* If no new reasons reject */
1189 if (!(crl->idp_reasons & ~tmp_reasons))
1190 return 0;
1191 }
1192 /* Don't process deltas at this stage */
1193 else if (crl->base_crl_number)
1194 return 0;
1195 /* If issuer name doesn't match certificate need indirect CRL */
1196 if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) {
1197 if (!(crl->idp_flags & IDP_INDIRECT))
1198 return 0;
1199 } else
1200 crl_score |= CRL_SCORE_ISSUER_NAME;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001201
David Benjamin4969cc92016-04-22 15:02:23 -04001202 if (!(crl->flags & EXFLAG_CRITICAL))
1203 crl_score |= CRL_SCORE_NOCRITICAL;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001204
David Benjamin4969cc92016-04-22 15:02:23 -04001205 /* Check expiry */
1206 if (check_crl_time(ctx, crl, 0))
1207 crl_score |= CRL_SCORE_TIME;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001208
David Benjamin4969cc92016-04-22 15:02:23 -04001209 /* Check authority key ID and locate certificate issuer */
1210 crl_akid_check(ctx, crl, pissuer, &crl_score);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001211
David Benjamin4969cc92016-04-22 15:02:23 -04001212 /* If we can't locate certificate issuer at this point forget it */
Adam Langleyd9e397b2015-01-22 14:27:53 -08001213
David Benjamin4969cc92016-04-22 15:02:23 -04001214 if (!(crl_score & CRL_SCORE_AKID))
1215 return 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001216
David Benjamin4969cc92016-04-22 15:02:23 -04001217 /* Check cert for matching CRL distribution points */
Adam Langleyd9e397b2015-01-22 14:27:53 -08001218
David Benjamin4969cc92016-04-22 15:02:23 -04001219 if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) {
1220 /* If no new reasons reject */
1221 if (!(crl_reasons & ~tmp_reasons))
1222 return 0;
1223 tmp_reasons |= crl_reasons;
1224 crl_score |= CRL_SCORE_SCOPE;
1225 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001226
David Benjamin4969cc92016-04-22 15:02:23 -04001227 *preasons = tmp_reasons;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001228
David Benjamin4969cc92016-04-22 15:02:23 -04001229 return crl_score;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001230
David Benjamin4969cc92016-04-22 15:02:23 -04001231}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001232
1233static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
David Benjamin4969cc92016-04-22 15:02:23 -04001234 X509 **pissuer, int *pcrl_score)
1235{
1236 X509 *crl_issuer = NULL;
1237 X509_NAME *cnm = X509_CRL_get_issuer(crl);
1238 int cidx = ctx->error_depth;
1239 size_t i;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001240
David Benjamin4969cc92016-04-22 15:02:23 -04001241 if ((size_t)cidx != sk_X509_num(ctx->chain) - 1)
1242 cidx++;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001243
David Benjamin4969cc92016-04-22 15:02:23 -04001244 crl_issuer = sk_X509_value(ctx->chain, cidx);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001245
David Benjamin4969cc92016-04-22 15:02:23 -04001246 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1247 if (*pcrl_score & CRL_SCORE_ISSUER_NAME) {
1248 *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT;
1249 *pissuer = crl_issuer;
1250 return;
1251 }
1252 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001253
David Benjamin4969cc92016-04-22 15:02:23 -04001254 for (cidx++; cidx < (int)sk_X509_num(ctx->chain); cidx++) {
1255 crl_issuer = sk_X509_value(ctx->chain, cidx);
1256 if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1257 continue;
1258 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1259 *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH;
1260 *pissuer = crl_issuer;
1261 return;
1262 }
1263 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001264
David Benjamin4969cc92016-04-22 15:02:23 -04001265 /* Anything else needs extended CRL support */
Adam Langleyd9e397b2015-01-22 14:27:53 -08001266
David Benjamin4969cc92016-04-22 15:02:23 -04001267 if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
1268 return;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001269
David Benjamin4969cc92016-04-22 15:02:23 -04001270 /*
1271 * Otherwise the CRL issuer is not on the path. Look for it in the set of
1272 * untrusted certificates.
1273 */
1274 for (i = 0; i < sk_X509_num(ctx->untrusted); i++) {
1275 crl_issuer = sk_X509_value(ctx->untrusted, i);
1276 if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1277 continue;
1278 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1279 *pissuer = crl_issuer;
1280 *pcrl_score |= CRL_SCORE_AKID;
1281 return;
1282 }
1283 }
Robert Sloan69939df2017-01-09 10:53:07 -08001284
1285 for (i = 0; i < sk_X509_num(ctx->ctx->additional_untrusted); i++) {
1286 crl_issuer = sk_X509_value(ctx->ctx->additional_untrusted, i);
1287 if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1288 continue;
1289 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1290 *pissuer = crl_issuer;
1291 *pcrl_score |= CRL_SCORE_AKID;
1292 return;
1293 }
1294 }
David Benjamin4969cc92016-04-22 15:02:23 -04001295}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001296
David Benjamin4969cc92016-04-22 15:02:23 -04001297/*
1298 * Check the path of a CRL issuer certificate. This creates a new
Adam Langleyd9e397b2015-01-22 14:27:53 -08001299 * X509_STORE_CTX and populates it with most of the parameters from the
David Benjamin4969cc92016-04-22 15:02:23 -04001300 * parent. This could be optimised somewhat since a lot of path checking will
1301 * be duplicated by the parent, but this will rarely be used in practice.
Adam Langleyd9e397b2015-01-22 14:27:53 -08001302 */
1303
1304static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
David Benjamin4969cc92016-04-22 15:02:23 -04001305{
1306 X509_STORE_CTX crl_ctx;
1307 int ret;
1308 /* Don't allow recursive CRL path validation */
1309 if (ctx->parent)
1310 return 0;
1311 if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
1312 return -1;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001313
David Benjamin4969cc92016-04-22 15:02:23 -04001314 crl_ctx.crls = ctx->crls;
1315 /* Copy verify params across */
1316 X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001317
David Benjamin4969cc92016-04-22 15:02:23 -04001318 crl_ctx.parent = ctx;
1319 crl_ctx.verify_cb = ctx->verify_cb;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001320
David Benjamin4969cc92016-04-22 15:02:23 -04001321 /* Verify CRL issuer */
1322 ret = X509_verify_cert(&crl_ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001323
David Benjamin4969cc92016-04-22 15:02:23 -04001324 if (ret <= 0)
1325 goto err;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001326
David Benjamin4969cc92016-04-22 15:02:23 -04001327 /* Check chain is acceptable */
Adam Langleyd9e397b2015-01-22 14:27:53 -08001328
David Benjamin4969cc92016-04-22 15:02:23 -04001329 ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
1330 err:
1331 X509_STORE_CTX_cleanup(&crl_ctx);
1332 return ret;
1333}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001334
David Benjamin4969cc92016-04-22 15:02:23 -04001335/*
1336 * RFC3280 says nothing about the relationship between CRL path and
1337 * certificate path, which could lead to situations where a certificate could
1338 * be revoked or validated by a CA not authorised to do so. RFC5280 is more
1339 * strict and states that the two paths must end in the same trust anchor,
1340 * though some discussions remain... until this is resolved we use the
1341 * RFC5280 version
Adam Langleyd9e397b2015-01-22 14:27:53 -08001342 */
1343
1344static int check_crl_chain(X509_STORE_CTX *ctx,
David Benjamin4969cc92016-04-22 15:02:23 -04001345 STACK_OF(X509) *cert_path,
1346 STACK_OF(X509) *crl_path)
1347{
1348 X509 *cert_ta, *crl_ta;
1349 cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
1350 crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
1351 if (!X509_cmp(cert_ta, crl_ta))
1352 return 1;
1353 return 0;
1354}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001355
David Benjamin4969cc92016-04-22 15:02:23 -04001356/*
1357 * Check for match between two dist point names: three separate cases. 1.
1358 * Both are relative names and compare X509_NAME types. 2. One full, one
1359 * relative. Compare X509_NAME to GENERAL_NAMES. 3. Both are full names and
1360 * compare two GENERAL_NAMES. 4. One is NULL: automatic match.
Adam Langleyd9e397b2015-01-22 14:27:53 -08001361 */
1362
Adam Langleyd9e397b2015-01-22 14:27:53 -08001363static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
David Benjamin4969cc92016-04-22 15:02:23 -04001364{
1365 X509_NAME *nm = NULL;
1366 GENERAL_NAMES *gens = NULL;
1367 GENERAL_NAME *gena, *genb;
1368 size_t i, j;
1369 if (!a || !b)
1370 return 1;
1371 if (a->type == 1) {
1372 if (!a->dpname)
1373 return 0;
1374 /* Case 1: two X509_NAME */
1375 if (b->type == 1) {
1376 if (!b->dpname)
1377 return 0;
1378 if (!X509_NAME_cmp(a->dpname, b->dpname))
1379 return 1;
1380 else
1381 return 0;
1382 }
1383 /* Case 2: set name and GENERAL_NAMES appropriately */
1384 nm = a->dpname;
1385 gens = b->name.fullname;
1386 } else if (b->type == 1) {
1387 if (!b->dpname)
1388 return 0;
1389 /* Case 2: set name and GENERAL_NAMES appropriately */
1390 gens = a->name.fullname;
1391 nm = b->dpname;
1392 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001393
David Benjamin4969cc92016-04-22 15:02:23 -04001394 /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
1395 if (nm) {
1396 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
1397 gena = sk_GENERAL_NAME_value(gens, i);
1398 if (gena->type != GEN_DIRNAME)
1399 continue;
1400 if (!X509_NAME_cmp(nm, gena->d.directoryName))
1401 return 1;
1402 }
1403 return 0;
1404 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001405
David Benjamin4969cc92016-04-22 15:02:23 -04001406 /* Else case 3: two GENERAL_NAMES */
Adam Langleyd9e397b2015-01-22 14:27:53 -08001407
David Benjamin4969cc92016-04-22 15:02:23 -04001408 for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) {
1409 gena = sk_GENERAL_NAME_value(a->name.fullname, i);
1410 for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) {
1411 genb = sk_GENERAL_NAME_value(b->name.fullname, j);
1412 if (!GENERAL_NAME_cmp(gena, genb))
1413 return 1;
1414 }
1415 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001416
David Benjamin4969cc92016-04-22 15:02:23 -04001417 return 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001418
David Benjamin4969cc92016-04-22 15:02:23 -04001419}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001420
1421static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
David Benjamin4969cc92016-04-22 15:02:23 -04001422{
1423 size_t i;
1424 X509_NAME *nm = X509_CRL_get_issuer(crl);
1425 /* If no CRLissuer return is successful iff don't need a match */
1426 if (!dp->CRLissuer)
1427 return ! !(crl_score & CRL_SCORE_ISSUER_NAME);
1428 for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
1429 GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
1430 if (gen->type != GEN_DIRNAME)
1431 continue;
1432 if (!X509_NAME_cmp(gen->d.directoryName, nm))
1433 return 1;
1434 }
1435 return 0;
1436}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001437
1438/* Check CRLDP and IDP */
1439
1440static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
David Benjamin4969cc92016-04-22 15:02:23 -04001441 unsigned int *preasons)
1442{
1443 size_t i;
1444 if (crl->idp_flags & IDP_ONLYATTR)
1445 return 0;
1446 if (x->ex_flags & EXFLAG_CA) {
1447 if (crl->idp_flags & IDP_ONLYUSER)
1448 return 0;
1449 } else {
1450 if (crl->idp_flags & IDP_ONLYCA)
1451 return 0;
1452 }
1453 *preasons = crl->idp_reasons;
1454 for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
1455 DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
1456 if (crldp_check_crlissuer(dp, crl, crl_score)) {
1457 if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) {
1458 *preasons &= dp->dp_reasons;
1459 return 1;
1460 }
1461 }
1462 }
1463 if ((!crl->idp || !crl->idp->distpoint)
1464 && (crl_score & CRL_SCORE_ISSUER_NAME))
1465 return 1;
1466 return 0;
1467}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001468
David Benjamin4969cc92016-04-22 15:02:23 -04001469/*
1470 * Retrieve CRL corresponding to current certificate. If deltas enabled try
1471 * to find a delta CRL too
Adam Langleyd9e397b2015-01-22 14:27:53 -08001472 */
David Benjamin4969cc92016-04-22 15:02:23 -04001473
Adam Langleyd9e397b2015-01-22 14:27:53 -08001474static int get_crl_delta(X509_STORE_CTX *ctx,
David Benjamin4969cc92016-04-22 15:02:23 -04001475 X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
1476{
1477 int ok;
1478 X509 *issuer = NULL;
1479 int crl_score = 0;
1480 unsigned int reasons;
1481 X509_CRL *crl = NULL, *dcrl = NULL;
1482 STACK_OF(X509_CRL) *skcrl;
1483 X509_NAME *nm = X509_get_issuer_name(x);
1484 reasons = ctx->current_reasons;
1485 ok = get_crl_sk(ctx, &crl, &dcrl,
1486 &issuer, &crl_score, &reasons, ctx->crls);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001487
David Benjamin4969cc92016-04-22 15:02:23 -04001488 if (ok)
1489 goto done;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001490
David Benjamin4969cc92016-04-22 15:02:23 -04001491 /* Lookup CRLs from store */
Adam Langleyd9e397b2015-01-22 14:27:53 -08001492
David Benjamin4969cc92016-04-22 15:02:23 -04001493 skcrl = ctx->lookup_crls(ctx, nm);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001494
David Benjamin4969cc92016-04-22 15:02:23 -04001495 /* If no CRLs found and a near match from get_crl_sk use that */
1496 if (!skcrl && crl)
1497 goto done;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001498
David Benjamin4969cc92016-04-22 15:02:23 -04001499 get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001500
David Benjamin4969cc92016-04-22 15:02:23 -04001501 sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001502
David Benjamin4969cc92016-04-22 15:02:23 -04001503 done:
Adam Langleyd9e397b2015-01-22 14:27:53 -08001504
David Benjamin4969cc92016-04-22 15:02:23 -04001505 /* If we got any kind of CRL use it and return success */
1506 if (crl) {
1507 ctx->current_issuer = issuer;
1508 ctx->current_crl_score = crl_score;
1509 ctx->current_reasons = reasons;
1510 *pcrl = crl;
1511 *pdcrl = dcrl;
1512 return 1;
1513 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001514
David Benjamin4969cc92016-04-22 15:02:23 -04001515 return 0;
1516}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001517
1518/* Check CRL validity */
1519static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
David Benjamin4969cc92016-04-22 15:02:23 -04001520{
1521 X509 *issuer = NULL;
1522 EVP_PKEY *ikey = NULL;
1523 int ok = 0, chnum, cnum;
1524 cnum = ctx->error_depth;
1525 chnum = sk_X509_num(ctx->chain) - 1;
1526 /* if we have an alternative CRL issuer cert use that */
1527 if (ctx->current_issuer)
1528 issuer = ctx->current_issuer;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001529
David Benjamin4969cc92016-04-22 15:02:23 -04001530 /*
1531 * Else find CRL issuer: if not last certificate then issuer is next
1532 * certificate in chain.
1533 */
1534 else if (cnum < chnum)
1535 issuer = sk_X509_value(ctx->chain, cnum + 1);
1536 else {
1537 issuer = sk_X509_value(ctx->chain, chnum);
1538 /* If not self signed, can't check signature */
1539 if (!ctx->check_issued(ctx, issuer, issuer)) {
1540 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
1541 ok = ctx->verify_cb(0, ctx);
1542 if (!ok)
1543 goto err;
1544 }
1545 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001546
David Benjamin4969cc92016-04-22 15:02:23 -04001547 if (issuer) {
1548 /*
1549 * Skip most tests for deltas because they have already been done
1550 */
1551 if (!crl->base_crl_number) {
1552 /* Check for cRLSign bit if keyUsage present */
1553 if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
1554 !(issuer->ex_kusage & KU_CRL_SIGN)) {
1555 ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
1556 ok = ctx->verify_cb(0, ctx);
1557 if (!ok)
1558 goto err;
1559 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001560
David Benjamin4969cc92016-04-22 15:02:23 -04001561 if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) {
1562 ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
1563 ok = ctx->verify_cb(0, ctx);
1564 if (!ok)
1565 goto err;
1566 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001567
David Benjamin4969cc92016-04-22 15:02:23 -04001568 if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) {
1569 if (check_crl_path(ctx, ctx->current_issuer) <= 0) {
1570 ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
1571 ok = ctx->verify_cb(0, ctx);
1572 if (!ok)
1573 goto err;
1574 }
1575 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001576
David Benjamin4969cc92016-04-22 15:02:23 -04001577 if (crl->idp_flags & IDP_INVALID) {
1578 ctx->error = X509_V_ERR_INVALID_EXTENSION;
1579 ok = ctx->verify_cb(0, ctx);
1580 if (!ok)
1581 goto err;
1582 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001583
David Benjamin4969cc92016-04-22 15:02:23 -04001584 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001585
David Benjamin4969cc92016-04-22 15:02:23 -04001586 if (!(ctx->current_crl_score & CRL_SCORE_TIME)) {
1587 ok = check_crl_time(ctx, crl, 1);
1588 if (!ok)
1589 goto err;
1590 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001591
David Benjamin4969cc92016-04-22 15:02:23 -04001592 /* Attempt to get issuer certificate public key */
1593 ikey = X509_get_pubkey(issuer);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001594
David Benjamin4969cc92016-04-22 15:02:23 -04001595 if (!ikey) {
1596 ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
1597 ok = ctx->verify_cb(0, ctx);
1598 if (!ok)
1599 goto err;
1600 } else {
1601 int rv;
1602 rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags);
1603 if (rv != X509_V_OK) {
1604 ctx->error = rv;
1605 ok = ctx->verify_cb(0, ctx);
1606 if (!ok)
1607 goto err;
1608 }
1609 /* Verify CRL signature */
1610 if (X509_CRL_verify(crl, ikey) <= 0) {
1611 ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
1612 ok = ctx->verify_cb(0, ctx);
1613 if (!ok)
1614 goto err;
1615 }
1616 }
1617 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001618
David Benjamin4969cc92016-04-22 15:02:23 -04001619 ok = 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001620
David Benjamin4969cc92016-04-22 15:02:23 -04001621 err:
1622 EVP_PKEY_free(ikey);
1623 return ok;
1624}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001625
1626/* Check certificate against CRL */
1627static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
David Benjamin4969cc92016-04-22 15:02:23 -04001628{
1629 int ok;
1630 X509_REVOKED *rev;
1631 /*
1632 * The rules changed for this... previously if a CRL contained unhandled
1633 * critical extensions it could still be used to indicate a certificate
1634 * was revoked. This has since been changed since critical extension can
1635 * change the meaning of CRL entries.
1636 */
1637 if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
1638 && (crl->flags & EXFLAG_CRITICAL)) {
1639 ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
1640 ok = ctx->verify_cb(0, ctx);
1641 if (!ok)
1642 return 0;
1643 }
1644 /*
1645 * Look for serial number of certificate in CRL If found make sure reason
1646 * is not removeFromCRL.
1647 */
1648 if (X509_CRL_get0_by_cert(crl, &rev, x)) {
1649 if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
1650 return 2;
1651 ctx->error = X509_V_ERR_CERT_REVOKED;
1652 ok = ctx->verify_cb(0, ctx);
1653 if (!ok)
1654 return 0;
1655 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001656
David Benjamin4969cc92016-04-22 15:02:23 -04001657 return 1;
1658}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001659
1660static int check_policy(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04001661{
1662 int ret;
1663 if (ctx->parent)
1664 return 1;
1665 ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
1666 ctx->param->policies, ctx->param->flags);
1667 if (ret == 0) {
1668 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
David Benjamin6e899c72016-06-09 18:02:18 -04001669 ctx->error = X509_V_ERR_OUT_OF_MEM;
David Benjamin4969cc92016-04-22 15:02:23 -04001670 return 0;
1671 }
1672 /* Invalid or inconsistent extensions */
1673 if (ret == -1) {
1674 /*
1675 * Locate certificates with bad extensions and notify callback.
1676 */
1677 X509 *x;
1678 size_t i;
1679 for (i = 1; i < sk_X509_num(ctx->chain); i++) {
1680 x = sk_X509_value(ctx->chain, i);
1681 if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
1682 continue;
1683 ctx->current_cert = x;
1684 ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
1685 if (!ctx->verify_cb(0, ctx))
1686 return 0;
1687 }
1688 return 1;
1689 }
1690 if (ret == -2) {
1691 ctx->current_cert = NULL;
1692 ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
1693 return ctx->verify_cb(0, ctx);
1694 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001695
David Benjamin4969cc92016-04-22 15:02:23 -04001696 if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
1697 ctx->current_cert = NULL;
David Benjamin6e899c72016-06-09 18:02:18 -04001698 /*
1699 * Verification errors need to be "sticky", a callback may have allowed
1700 * an SSL handshake to continue despite an error, and we must then
1701 * remain in an error state. Therefore, we MUST NOT clear earlier
1702 * verification errors by setting the error to X509_V_OK.
1703 */
David Benjamin4969cc92016-04-22 15:02:23 -04001704 if (!ctx->verify_cb(2, ctx))
1705 return 0;
1706 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001707
David Benjamin4969cc92016-04-22 15:02:23 -04001708 return 1;
1709}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001710
1711static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
David Benjamin4969cc92016-04-22 15:02:23 -04001712{
1713 time_t *ptime;
1714 int i;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001715
David Benjamin4969cc92016-04-22 15:02:23 -04001716 if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
1717 ptime = &ctx->param->check_time;
1718 else
1719 ptime = NULL;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001720
David Benjamin4969cc92016-04-22 15:02:23 -04001721 i = X509_cmp_time(X509_get_notBefore(x), ptime);
1722 if (i == 0) {
1723 ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
1724 ctx->current_cert = x;
1725 if (!ctx->verify_cb(0, ctx))
1726 return 0;
1727 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001728
David Benjamin4969cc92016-04-22 15:02:23 -04001729 if (i > 0) {
1730 ctx->error = X509_V_ERR_CERT_NOT_YET_VALID;
1731 ctx->current_cert = x;
1732 if (!ctx->verify_cb(0, ctx))
1733 return 0;
1734 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001735
David Benjamin4969cc92016-04-22 15:02:23 -04001736 i = X509_cmp_time(X509_get_notAfter(x), ptime);
1737 if (i == 0) {
1738 ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
1739 ctx->current_cert = x;
1740 if (!ctx->verify_cb(0, ctx))
1741 return 0;
1742 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001743
David Benjamin4969cc92016-04-22 15:02:23 -04001744 if (i < 0) {
1745 ctx->error = X509_V_ERR_CERT_HAS_EXPIRED;
1746 ctx->current_cert = x;
1747 if (!ctx->verify_cb(0, ctx))
1748 return 0;
1749 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001750
David Benjamin4969cc92016-04-22 15:02:23 -04001751 return 1;
1752}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001753
1754static int internal_verify(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04001755{
1756 int ok = 0, n;
1757 X509 *xs, *xi;
1758 EVP_PKEY *pkey = NULL;
1759 int (*cb) (int xok, X509_STORE_CTX *xctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001760
David Benjamin4969cc92016-04-22 15:02:23 -04001761 cb = ctx->verify_cb;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001762
David Benjamin4969cc92016-04-22 15:02:23 -04001763 n = sk_X509_num(ctx->chain);
1764 ctx->error_depth = n - 1;
1765 n--;
1766 xi = sk_X509_value(ctx->chain, n);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001767
David Benjamin4969cc92016-04-22 15:02:23 -04001768 if (ctx->check_issued(ctx, xi, xi))
1769 xs = xi;
1770 else {
1771 if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
1772 xs = xi;
1773 goto check_cert;
1774 }
1775 if (n <= 0) {
1776 ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
1777 ctx->current_cert = xi;
1778 ok = cb(0, ctx);
1779 goto end;
1780 } else {
1781 n--;
1782 ctx->error_depth = n;
1783 xs = sk_X509_value(ctx->chain, n);
1784 }
1785 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001786
David Benjamin4969cc92016-04-22 15:02:23 -04001787/* ctx->error=0; not needed */
1788 while (n >= 0) {
1789 ctx->error_depth = n;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001790
David Benjamin4969cc92016-04-22 15:02:23 -04001791 /*
1792 * Skip signature check for self signed certificates unless
1793 * explicitly asked for. It doesn't add any security and just wastes
1794 * time.
1795 */
David Benjaminc895d6b2016-08-11 13:26:41 -04001796 if (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)) {
David Benjamin4969cc92016-04-22 15:02:23 -04001797 if ((pkey = X509_get_pubkey(xi)) == NULL) {
1798 ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
1799 ctx->current_cert = xi;
1800 ok = (*cb) (0, ctx);
1801 if (!ok)
1802 goto end;
1803 } else if (X509_verify(xs, pkey) <= 0) {
1804 ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
1805 ctx->current_cert = xs;
1806 ok = (*cb) (0, ctx);
1807 if (!ok) {
1808 EVP_PKEY_free(pkey);
1809 goto end;
1810 }
1811 }
1812 EVP_PKEY_free(pkey);
1813 pkey = NULL;
1814 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001815
David Benjamin4969cc92016-04-22 15:02:23 -04001816 check_cert:
1817 ok = check_cert_time(ctx, xs);
1818 if (!ok)
1819 goto end;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001820
David Benjamin4969cc92016-04-22 15:02:23 -04001821 /* The last error (if any) is still in the error value */
1822 ctx->current_issuer = xi;
1823 ctx->current_cert = xs;
1824 ok = (*cb) (1, ctx);
1825 if (!ok)
1826 goto end;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001827
David Benjamin4969cc92016-04-22 15:02:23 -04001828 n--;
1829 if (n >= 0) {
1830 xi = xs;
1831 xs = sk_X509_value(ctx->chain, n);
1832 }
1833 }
1834 ok = 1;
1835 end:
1836 return ok;
1837}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001838
1839int X509_cmp_current_time(const ASN1_TIME *ctm)
1840{
David Benjamin4969cc92016-04-22 15:02:23 -04001841 return X509_cmp_time(ctm, NULL);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001842}
1843
1844int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
David Benjamin4969cc92016-04-22 15:02:23 -04001845{
1846 char *str;
1847 ASN1_TIME atm;
1848 long offset;
1849 char buff1[24], buff2[24], *p;
1850 int i, j, remaining;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001851
David Benjamin4969cc92016-04-22 15:02:23 -04001852 p = buff1;
1853 remaining = ctm->length;
1854 str = (char *)ctm->data;
1855 /*
1856 * Note that the following (historical) code allows much more slack in
1857 * the time format than RFC5280. In RFC5280, the representation is fixed:
1858 * UTCTime: YYMMDDHHMMSSZ GeneralizedTime: YYYYMMDDHHMMSSZ
1859 */
1860 if (ctm->type == V_ASN1_UTCTIME) {
1861 /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
1862 int min_length = sizeof("YYMMDDHHMMZ") - 1;
1863 int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
1864 if (remaining < min_length || remaining > max_length)
1865 return 0;
Robert Sloan69939df2017-01-09 10:53:07 -08001866 OPENSSL_memcpy(p, str, 10);
David Benjamin4969cc92016-04-22 15:02:23 -04001867 p += 10;
1868 str += 10;
1869 remaining -= 10;
1870 } else {
1871 /*
1872 * YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm
1873 */
1874 int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
1875 int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
1876 if (remaining < min_length || remaining > max_length)
1877 return 0;
Robert Sloan69939df2017-01-09 10:53:07 -08001878 OPENSSL_memcpy(p, str, 12);
David Benjamin4969cc92016-04-22 15:02:23 -04001879 p += 12;
1880 str += 12;
1881 remaining -= 12;
1882 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001883
David Benjamin4969cc92016-04-22 15:02:23 -04001884 if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
1885 *(p++) = '0';
1886 *(p++) = '0';
1887 } else {
1888 /* SS (seconds) */
1889 if (remaining < 2)
1890 return 0;
1891 *(p++) = *(str++);
1892 *(p++) = *(str++);
1893 remaining -= 2;
1894 /*
1895 * Skip any (up to three) fractional seconds... TODO(emilia): in
1896 * RFC5280, fractional seconds are forbidden. Can we just kill them
1897 * altogether?
1898 */
1899 if (remaining && *str == '.') {
1900 str++;
1901 remaining--;
1902 for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
1903 if (*str < '0' || *str > '9')
1904 break;
1905 }
1906 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001907
David Benjamin4969cc92016-04-22 15:02:23 -04001908 }
1909 *(p++) = 'Z';
1910 *(p++) = '\0';
Adam Langleyd9e397b2015-01-22 14:27:53 -08001911
David Benjamin4969cc92016-04-22 15:02:23 -04001912 /* We now need either a terminating 'Z' or an offset. */
1913 if (!remaining)
1914 return 0;
1915 if (*str == 'Z') {
1916 if (remaining != 1)
1917 return 0;
1918 offset = 0;
1919 } else {
1920 /* (+-)HHMM */
1921 if ((*str != '+') && (*str != '-'))
1922 return 0;
1923 /*
1924 * Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280.
1925 */
1926 if (remaining != 5)
1927 return 0;
1928 if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
1929 str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
1930 return 0;
1931 offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
1932 offset += (str[3] - '0') * 10 + (str[4] - '0');
1933 if (*str == '-')
1934 offset = -offset;
1935 }
1936 atm.type = ctm->type;
1937 atm.flags = 0;
1938 atm.length = sizeof(buff2);
1939 atm.data = (unsigned char *)buff2;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001940
David Benjamin4969cc92016-04-22 15:02:23 -04001941 if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
1942 return 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001943
David Benjamin4969cc92016-04-22 15:02:23 -04001944 if (ctm->type == V_ASN1_UTCTIME) {
1945 i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
1946 if (i < 50)
1947 i += 100; /* cf. RFC 2459 */
1948 j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
1949 if (j < 50)
1950 j += 100;
1951
1952 if (i < j)
1953 return -1;
1954 if (i > j)
1955 return 1;
1956 }
1957 i = strcmp(buff1, buff2);
1958 if (i == 0) /* wait a second then return younger :-) */
1959 return -1;
1960 else
1961 return i;
1962}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001963
1964ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
1965{
David Benjamin4969cc92016-04-22 15:02:23 -04001966 return X509_time_adj(s, adj, NULL);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001967}
1968
1969ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
David Benjamin4969cc92016-04-22 15:02:23 -04001970{
1971 return X509_time_adj_ex(s, 0, offset_sec, in_tm);
1972}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001973
1974ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
David Benjamin4969cc92016-04-22 15:02:23 -04001975 int offset_day, long offset_sec, time_t *in_tm)
1976{
1977 time_t t = 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001978
David Benjamin4969cc92016-04-22 15:02:23 -04001979 if (in_tm)
1980 t = *in_tm;
1981 else
1982 time(&t);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001983
David Benjamin4969cc92016-04-22 15:02:23 -04001984 if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) {
1985 if (s->type == V_ASN1_UTCTIME)
1986 return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
1987 if (s->type == V_ASN1_GENERALIZEDTIME)
1988 return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
1989 }
1990 return ASN1_TIME_adj(s, t, offset_day, offset_sec);
1991}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001992
Adam Langleyd9e397b2015-01-22 14:27:53 -08001993/* Make a delta CRL as the diff between two full CRLs */
1994
1995X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
David Benjamin4969cc92016-04-22 15:02:23 -04001996 EVP_PKEY *skey, const EVP_MD *md, unsigned int flags)
1997{
1998 X509_CRL *crl = NULL;
1999 int i;
2000 size_t j;
2001 STACK_OF(X509_REVOKED) *revs = NULL;
2002 /* CRLs can't be delta already */
2003 if (base->base_crl_number || newer->base_crl_number) {
2004 OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA);
2005 return NULL;
2006 }
2007 /* Base and new CRL must have a CRL number */
2008 if (!base->crl_number || !newer->crl_number) {
2009 OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_NUMBER);
2010 return NULL;
2011 }
2012 /* Issuer names must match */
2013 if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) {
2014 OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH);
2015 return NULL;
2016 }
2017 /* AKID and IDP must match */
2018 if (!crl_extension_match(base, newer, NID_authority_key_identifier)) {
2019 OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH);
2020 return NULL;
2021 }
2022 if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) {
2023 OPENSSL_PUT_ERROR(X509, X509_R_IDP_MISMATCH);
2024 return NULL;
2025 }
2026 /* Newer CRL number must exceed full CRL number */
2027 if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) {
2028 OPENSSL_PUT_ERROR(X509, X509_R_NEWER_CRL_NOT_NEWER);
2029 return NULL;
2030 }
2031 /* CRLs must verify */
2032 if (skey && (X509_CRL_verify(base, skey) <= 0 ||
2033 X509_CRL_verify(newer, skey) <= 0)) {
2034 OPENSSL_PUT_ERROR(X509, X509_R_CRL_VERIFY_FAILURE);
2035 return NULL;
2036 }
2037 /* Create new CRL */
2038 crl = X509_CRL_new();
2039 if (!crl || !X509_CRL_set_version(crl, 1))
2040 goto memerr;
2041 /* Set issuer name */
2042 if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer)))
2043 goto memerr;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002044
David Benjamin4969cc92016-04-22 15:02:23 -04002045 if (!X509_CRL_set_lastUpdate(crl, X509_CRL_get_lastUpdate(newer)))
2046 goto memerr;
2047 if (!X509_CRL_set_nextUpdate(crl, X509_CRL_get_nextUpdate(newer)))
2048 goto memerr;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002049
David Benjamin4969cc92016-04-22 15:02:23 -04002050 /* Set base CRL number: must be critical */
Adam Langleyd9e397b2015-01-22 14:27:53 -08002051
David Benjamin4969cc92016-04-22 15:02:23 -04002052 if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0))
2053 goto memerr;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002054
David Benjamin4969cc92016-04-22 15:02:23 -04002055 /*
2056 * Copy extensions across from newest CRL to delta: this will set CRL
2057 * number to correct value too.
2058 */
Adam Langleyd9e397b2015-01-22 14:27:53 -08002059
David Benjamin4969cc92016-04-22 15:02:23 -04002060 for (i = 0; i < X509_CRL_get_ext_count(newer); i++) {
2061 X509_EXTENSION *ext;
2062 ext = X509_CRL_get_ext(newer, i);
2063 if (!X509_CRL_add_ext(crl, ext, -1))
2064 goto memerr;
2065 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08002066
David Benjamin4969cc92016-04-22 15:02:23 -04002067 /* Go through revoked entries, copying as needed */
Adam Langleyd9e397b2015-01-22 14:27:53 -08002068
David Benjamin4969cc92016-04-22 15:02:23 -04002069 revs = X509_CRL_get_REVOKED(newer);
Adam Langleyd9e397b2015-01-22 14:27:53 -08002070
David Benjamin4969cc92016-04-22 15:02:23 -04002071 for (j = 0; j < sk_X509_REVOKED_num(revs); j++) {
2072 X509_REVOKED *rvn, *rvtmp;
2073 rvn = sk_X509_REVOKED_value(revs, j);
2074 /*
2075 * Add only if not also in base. TODO: need something cleverer here
2076 * for some more complex CRLs covering multiple CAs.
2077 */
2078 if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) {
2079 rvtmp = X509_REVOKED_dup(rvn);
2080 if (!rvtmp)
2081 goto memerr;
2082 if (!X509_CRL_add0_revoked(crl, rvtmp)) {
2083 X509_REVOKED_free(rvtmp);
2084 goto memerr;
2085 }
2086 }
2087 }
2088 /* TODO: optionally prune deleted entries */
Adam Langleyd9e397b2015-01-22 14:27:53 -08002089
David Benjamin4969cc92016-04-22 15:02:23 -04002090 if (skey && md && !X509_CRL_sign(crl, skey, md))
2091 goto memerr;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002092
David Benjamin4969cc92016-04-22 15:02:23 -04002093 return crl;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002094
David Benjamin4969cc92016-04-22 15:02:23 -04002095 memerr:
2096 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
2097 if (crl)
2098 X509_CRL_free(crl);
2099 return NULL;
2100}
2101
2102int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
2103 CRYPTO_EX_unused * unused,
2104 CRYPTO_EX_dup *dup_func,
2105 CRYPTO_EX_free *free_func)
2106{
2107 /*
2108 * This function is (usually) called only once, by
2109 * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c).
2110 */
2111 int index;
2112 if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
2113 dup_func, free_func)) {
2114 return -1;
2115 }
2116 return index;
2117}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002118
2119int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
David Benjamin4969cc92016-04-22 15:02:23 -04002120{
2121 return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
2122}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002123
2124void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
David Benjamin4969cc92016-04-22 15:02:23 -04002125{
2126 return CRYPTO_get_ex_data(&ctx->ex_data, idx);
2127}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002128
2129int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04002130{
2131 return ctx->error;
2132}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002133
2134void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
David Benjamin4969cc92016-04-22 15:02:23 -04002135{
2136 ctx->error = err;
2137}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002138
2139int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04002140{
2141 return ctx->error_depth;
2142}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002143
2144X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04002145{
2146 return ctx->current_cert;
2147}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002148
2149STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04002150{
2151 return ctx->chain;
2152}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002153
2154STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04002155{
2156 if (!ctx->chain)
2157 return NULL;
2158 return X509_chain_up_ref(ctx->chain);
2159}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002160
2161X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04002162{
2163 return ctx->current_issuer;
2164}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002165
2166X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04002167{
2168 return ctx->current_crl;
2169}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002170
2171X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04002172{
2173 return ctx->parent;
2174}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002175
2176void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
David Benjamin4969cc92016-04-22 15:02:23 -04002177{
2178 ctx->cert = x;
2179}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002180
2181void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
David Benjamin4969cc92016-04-22 15:02:23 -04002182{
2183 ctx->untrusted = sk;
2184}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002185
2186void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
David Benjamin4969cc92016-04-22 15:02:23 -04002187{
2188 ctx->crls = sk;
2189}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002190
2191int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
David Benjamin4969cc92016-04-22 15:02:23 -04002192{
2193 return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
2194}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002195
2196int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
David Benjamin4969cc92016-04-22 15:02:23 -04002197{
2198 return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
2199}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002200
David Benjamin4969cc92016-04-22 15:02:23 -04002201/*
2202 * This function is used to set the X509_STORE_CTX purpose and trust values.
2203 * This is intended to be used when another structure has its own trust and
2204 * purpose values which (if set) will be inherited by the ctx. If they aren't
2205 * set then we will usually have a default purpose in mind which should then
2206 * be used to set the trust value. An example of this is SSL use: an SSL
2207 * structure will have its own purpose and trust settings which the
2208 * application can set: if they aren't set then we use the default of SSL
2209 * client/server.
Adam Langleyd9e397b2015-01-22 14:27:53 -08002210 */
2211
2212int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
David Benjamin4969cc92016-04-22 15:02:23 -04002213 int purpose, int trust)
Adam Langleyd9e397b2015-01-22 14:27:53 -08002214{
David Benjamin4969cc92016-04-22 15:02:23 -04002215 int idx;
2216 /* If purpose not set use default */
2217 if (!purpose)
2218 purpose = def_purpose;
2219 /* If we have a purpose then check it is valid */
2220 if (purpose) {
2221 X509_PURPOSE *ptmp;
2222 idx = X509_PURPOSE_get_by_id(purpose);
2223 if (idx == -1) {
2224 OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
2225 return 0;
2226 }
2227 ptmp = X509_PURPOSE_get0(idx);
2228 if (ptmp->trust == X509_TRUST_DEFAULT) {
2229 idx = X509_PURPOSE_get_by_id(def_purpose);
2230 if (idx == -1) {
2231 OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
2232 return 0;
2233 }
2234 ptmp = X509_PURPOSE_get0(idx);
2235 }
2236 /* If trust not set then get from purpose default */
2237 if (!trust)
2238 trust = ptmp->trust;
2239 }
2240 if (trust) {
2241 idx = X509_TRUST_get_by_id(trust);
2242 if (idx == -1) {
2243 OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID);
2244 return 0;
2245 }
2246 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08002247
David Benjamin4969cc92016-04-22 15:02:23 -04002248 if (purpose && !ctx->param->purpose)
2249 ctx->param->purpose = purpose;
2250 if (trust && !ctx->param->trust)
2251 ctx->param->trust = trust;
2252 return 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002253}
2254
2255X509_STORE_CTX *X509_STORE_CTX_new(void)
2256{
David Benjamin4969cc92016-04-22 15:02:23 -04002257 X509_STORE_CTX *ctx;
2258 ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
2259 if (!ctx) {
2260 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
2261 return NULL;
2262 }
Robert Sloan69939df2017-01-09 10:53:07 -08002263 OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
David Benjamin4969cc92016-04-22 15:02:23 -04002264 return ctx;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002265}
2266
2267void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
2268{
David Benjamin4969cc92016-04-22 15:02:23 -04002269 if (ctx == NULL) {
2270 return;
2271 }
2272 X509_STORE_CTX_cleanup(ctx);
2273 OPENSSL_free(ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -08002274}
2275
2276int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
David Benjamin4969cc92016-04-22 15:02:23 -04002277 STACK_OF(X509) *chain)
2278{
2279 int ret = 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002280
Robert Sloan69939df2017-01-09 10:53:07 -08002281 OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
David Benjamin4969cc92016-04-22 15:02:23 -04002282 ctx->ctx = store;
2283 ctx->cert = x509;
2284 ctx->untrusted = chain;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002285
David Benjamin4969cc92016-04-22 15:02:23 -04002286 CRYPTO_new_ex_data(&ctx->ex_data);
Adam Langleyd9e397b2015-01-22 14:27:53 -08002287
David Benjamin4969cc92016-04-22 15:02:23 -04002288 ctx->param = X509_VERIFY_PARAM_new();
2289 if (!ctx->param)
2290 goto err;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002291
David Benjamin4969cc92016-04-22 15:02:23 -04002292 /*
2293 * Inherit callbacks and flags from X509_STORE if not set use defaults.
2294 */
Adam Langleyd9e397b2015-01-22 14:27:53 -08002295
David Benjamin4969cc92016-04-22 15:02:23 -04002296 if (store)
2297 ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
2298 else
2299 ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002300
David Benjamin4969cc92016-04-22 15:02:23 -04002301 if (store) {
2302 ctx->verify_cb = store->verify_cb;
2303 ctx->cleanup = store->cleanup;
2304 } else
2305 ctx->cleanup = 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002306
David Benjamin4969cc92016-04-22 15:02:23 -04002307 if (ret)
2308 ret = X509_VERIFY_PARAM_inherit(ctx->param,
2309 X509_VERIFY_PARAM_lookup("default"));
Adam Langleyd9e397b2015-01-22 14:27:53 -08002310
David Benjamin4969cc92016-04-22 15:02:23 -04002311 if (ret == 0)
2312 goto err;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002313
David Benjamin4969cc92016-04-22 15:02:23 -04002314 if (store && store->check_issued)
2315 ctx->check_issued = store->check_issued;
2316 else
2317 ctx->check_issued = check_issued;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002318
David Benjamin4969cc92016-04-22 15:02:23 -04002319 if (store && store->get_issuer)
2320 ctx->get_issuer = store->get_issuer;
2321 else
2322 ctx->get_issuer = X509_STORE_CTX_get1_issuer;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002323
David Benjamin4969cc92016-04-22 15:02:23 -04002324 if (store && store->verify_cb)
2325 ctx->verify_cb = store->verify_cb;
2326 else
2327 ctx->verify_cb = null_callback;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002328
David Benjamin4969cc92016-04-22 15:02:23 -04002329 if (store && store->verify)
2330 ctx->verify = store->verify;
2331 else
2332 ctx->verify = internal_verify;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002333
David Benjamin4969cc92016-04-22 15:02:23 -04002334 if (store && store->check_revocation)
2335 ctx->check_revocation = store->check_revocation;
2336 else
2337 ctx->check_revocation = check_revocation;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002338
David Benjamin4969cc92016-04-22 15:02:23 -04002339 if (store && store->get_crl)
2340 ctx->get_crl = store->get_crl;
2341 else
2342 ctx->get_crl = NULL;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002343
David Benjamin4969cc92016-04-22 15:02:23 -04002344 if (store && store->check_crl)
2345 ctx->check_crl = store->check_crl;
2346 else
2347 ctx->check_crl = check_crl;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002348
David Benjamin4969cc92016-04-22 15:02:23 -04002349 if (store && store->cert_crl)
2350 ctx->cert_crl = store->cert_crl;
2351 else
2352 ctx->cert_crl = cert_crl;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002353
David Benjamin4969cc92016-04-22 15:02:23 -04002354 if (store && store->lookup_certs)
2355 ctx->lookup_certs = store->lookup_certs;
2356 else
2357 ctx->lookup_certs = X509_STORE_get1_certs;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002358
David Benjamin4969cc92016-04-22 15:02:23 -04002359 if (store && store->lookup_crls)
2360 ctx->lookup_crls = store->lookup_crls;
2361 else
2362 ctx->lookup_crls = X509_STORE_get1_crls;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002363
David Benjamin4969cc92016-04-22 15:02:23 -04002364 ctx->check_policy = check_policy;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002365
David Benjamin4969cc92016-04-22 15:02:23 -04002366 return 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002367
David Benjamin4969cc92016-04-22 15:02:23 -04002368 err:
2369 CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data);
2370 if (ctx->param != NULL) {
2371 X509_VERIFY_PARAM_free(ctx->param);
2372 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08002373
Robert Sloan69939df2017-01-09 10:53:07 -08002374 OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
David Benjamin4969cc92016-04-22 15:02:23 -04002375 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
2376 return 0;
2377}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002378
David Benjamin4969cc92016-04-22 15:02:23 -04002379/*
2380 * Set alternative lookup method: just a STACK of trusted certificates. This
2381 * avoids X509_STORE nastiness where it isn't needed.
Adam Langleyd9e397b2015-01-22 14:27:53 -08002382 */
2383
2384void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
2385{
David Benjamin4969cc92016-04-22 15:02:23 -04002386 ctx->other_ctx = sk;
2387 ctx->get_issuer = get_issuer_sk;
Adam Langleyd9e397b2015-01-22 14:27:53 -08002388}
2389
2390void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04002391{
2392 /* We need to be idempotent because, unfortunately, |X509_STORE_CTX_free|
2393 * also calls this function. */
2394 if (ctx->cleanup != NULL) {
2395 ctx->cleanup(ctx);
2396 ctx->cleanup = NULL;
2397 }
2398 if (ctx->param != NULL) {
2399 if (ctx->parent == NULL)
2400 X509_VERIFY_PARAM_free(ctx->param);
2401 ctx->param = NULL;
2402 }
2403 if (ctx->tree != NULL) {
2404 X509_policy_tree_free(ctx->tree);
2405 ctx->tree = NULL;
2406 }
2407 if (ctx->chain != NULL) {
2408 sk_X509_pop_free(ctx->chain, X509_free);
2409 ctx->chain = NULL;
2410 }
2411 CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data));
Robert Sloan69939df2017-01-09 10:53:07 -08002412 OPENSSL_memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA));
David Benjamin4969cc92016-04-22 15:02:23 -04002413}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002414
2415void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
David Benjamin4969cc92016-04-22 15:02:23 -04002416{
2417 X509_VERIFY_PARAM_set_depth(ctx->param, depth);
2418}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002419
2420void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
David Benjamin4969cc92016-04-22 15:02:23 -04002421{
2422 X509_VERIFY_PARAM_set_flags(ctx->param, flags);
2423}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002424
David Benjamin4969cc92016-04-22 15:02:23 -04002425void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
2426 time_t t)
2427{
2428 X509_VERIFY_PARAM_set_time(ctx->param, t);
2429}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002430
2431void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
David Benjamin4969cc92016-04-22 15:02:23 -04002432 int (*verify_cb) (int, X509_STORE_CTX *))
2433{
2434 ctx->verify_cb = verify_cb;
2435}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002436
2437X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04002438{
2439 return ctx->tree;
2440}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002441
2442int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04002443{
2444 return ctx->explicit_policy;
2445}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002446
2447int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
David Benjamin4969cc92016-04-22 15:02:23 -04002448{
2449 const X509_VERIFY_PARAM *param;
2450 param = X509_VERIFY_PARAM_lookup(name);
2451 if (!param)
2452 return 0;
2453 return X509_VERIFY_PARAM_inherit(ctx->param, param);
2454}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002455
2456X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
David Benjamin4969cc92016-04-22 15:02:23 -04002457{
2458 return ctx->param;
2459}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002460
2461void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
David Benjamin4969cc92016-04-22 15:02:23 -04002462{
2463 if (ctx->param)
2464 X509_VERIFY_PARAM_free(ctx->param);
2465 ctx->param = param;
2466}
Adam Langleyd9e397b2015-01-22 14:27:53 -08002467
2468IMPLEMENT_ASN1_SET_OF(X509)
David Benjamin4969cc92016-04-22 15:02:23 -04002469
Adam Langleyd9e397b2015-01-22 14:27:53 -08002470IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)