blob: 8e258fef77dfade68dc2c4ca1b69ce91a3f73532 [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* 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
Adam Langley2b2d66d2015-01-30 17:08:37 -080057#include <string.h>
Adam Langley95c29f32014-06-20 12:00:00 -070058#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>
Brian Smith054e6822015-03-27 21:12:01 -100067#include <openssl/thread.h>
Adam Langley95c29f32014-06-20 12:00:00 -070068#include <openssl/x509.h>
69#include <openssl/x509v3.h>
70
71#include "vpm_int.h"
Brian Smitha039d702015-01-29 15:03:18 -080072#include "../internal.h"
73
David Benjaminaa585132015-06-29 23:36:17 -040074static CRYPTO_EX_DATA_CLASS g_ex_data_class =
Adam Langley57707c72016-01-14 11:25:12 -080075 CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
David Benjamin9f33fc62015-04-15 17:29:53 -040076
Adam Langley95c29f32014-06-20 12:00:00 -070077/* CRL score values */
78
79/* No unhandled critical extensions */
80
Adam Langley57707c72016-01-14 11:25:12 -080081#define CRL_SCORE_NOCRITICAL 0x100
Adam Langley95c29f32014-06-20 12:00:00 -070082
83/* certificate is within CRL scope */
84
Adam Langley57707c72016-01-14 11:25:12 -080085#define CRL_SCORE_SCOPE 0x080
Adam Langley95c29f32014-06-20 12:00:00 -070086
87/* CRL times valid */
88
Adam Langley57707c72016-01-14 11:25:12 -080089#define CRL_SCORE_TIME 0x040
Adam Langley95c29f32014-06-20 12:00:00 -070090
91/* Issuer name matches certificate */
92
Adam Langley57707c72016-01-14 11:25:12 -080093#define CRL_SCORE_ISSUER_NAME 0x020
Adam Langley95c29f32014-06-20 12:00:00 -070094
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
Adam Langley57707c72016-01-14 11:25:12 -0800101#define CRL_SCORE_ISSUER_CERT 0x018
Adam Langley95c29f32014-06-20 12:00:00 -0700102
103/* CRL issuer is on certificate path */
104
Adam Langley57707c72016-01-14 11:25:12 -0800105#define CRL_SCORE_SAME_PATH 0x008
Adam Langley95c29f32014-06-20 12:00:00 -0700106
107/* CRL issuer matches CRL AKID */
108
Adam Langley57707c72016-01-14 11:25:12 -0800109#define CRL_SCORE_AKID 0x004
Adam Langley95c29f32014-06-20 12:00:00 -0700110
111/* Have a delta CRL with valid times */
112
Adam Langley57707c72016-01-14 11:25:12 -0800113#define CRL_SCORE_TIME_DELTA 0x002
Adam Langley95c29f32014-06-20 12:00:00 -0700114
Adam Langley57707c72016-01-14 11:25:12 -0800115static int null_callback(int ok, X509_STORE_CTX *e);
Adam Langley95c29f32014-06-20 12:00:00 -0700116static 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,
Adam Langley57707c72016-01-14 11:25:12 -0800127 unsigned int *preasons, X509_CRL *crl, X509 *x);
Adam Langley95c29f32014-06-20 12:00:00 -0700128static int get_crl_delta(X509_STORE_CTX *ctx,
Adam Langley57707c72016-01-14 11:25:12 -0800129 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 Langley95c29f32014-06-20 12:00:00 -0700135static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
Adam Langley57707c72016-01-14 11:25:12 -0800136 unsigned int *preasons);
Adam Langley95c29f32014-06-20 12:00:00 -0700137static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
138static int check_crl_chain(X509_STORE_CTX *ctx,
Adam Langley57707c72016-01-14 11:25:12 -0800139 STACK_OF(X509) *cert_path,
140 STACK_OF(X509) *crl_path);
Adam Langley95c29f32014-06-20 12:00:00 -0700141
142static int internal_verify(X509_STORE_CTX *ctx);
Adam Langley95c29f32014-06-20 12:00:00 -0700143
Adam Langley95c29f32014-06-20 12:00:00 -0700144static int null_callback(int ok, X509_STORE_CTX *e)
Adam Langley57707c72016-01-14 11:25:12 -0800145{
146 return ok;
147}
Adam Langley95c29f32014-06-20 12:00:00 -0700148
Adam Langley35163dc2014-06-20 12:00:00 -0700149/* Return 1 is a certificate is self signed */
150static int cert_self_signed(X509 *x)
Adam Langley57707c72016-01-14 11:25:12 -0800151{
152 X509_check_purpose(x, -1, 0);
153 if (x->ex_flags & EXFLAG_SS)
154 return 1;
155 else
156 return 0;
157}
Adam Langley95c29f32014-06-20 12:00:00 -0700158
159/* Given a certificate try and find an exact match in the store */
160
161static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
Adam Langley57707c72016-01-14 11:25:12 -0800162{
163 STACK_OF(X509) *certs;
164 X509 *xtmp = NULL;
165 size_t i;
166 /* Lookup all certs with matching subject name */
167 certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
168 if (certs == NULL)
169 return NULL;
170 /* Look for exact match */
171 for (i = 0; i < sk_X509_num(certs); i++) {
172 xtmp = sk_X509_value(certs, i);
173 if (!X509_cmp(xtmp, x))
174 break;
175 }
176 if (i < sk_X509_num(certs))
177 X509_up_ref(xtmp);
178 else
179 xtmp = NULL;
180 sk_X509_pop_free(certs, X509_free);
181 return xtmp;
182}
Adam Langley95c29f32014-06-20 12:00:00 -0700183
184int X509_verify_cert(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -0800185{
Adam Langley3a39b062016-01-14 14:08:58 -0800186 X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
Adam Langley57707c72016-01-14 11:25:12 -0800187 int bad_chain = 0;
188 X509_VERIFY_PARAM *param = ctx->param;
189 int depth, i, ok = 0;
Steven Valdez3f81b602016-02-25 13:43:49 -0500190 int num, j, retry, trust;
Adam Langley57707c72016-01-14 11:25:12 -0800191 int (*cb) (int xok, X509_STORE_CTX *xctx);
192 STACK_OF(X509) *sktmp = NULL;
193 if (ctx->cert == NULL) {
194 OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
David Benjamin8f1e1132016-06-07 12:49:36 -0400195 ctx->error = X509_V_ERR_INVALID_CALL;
Adam Langley57707c72016-01-14 11:25:12 -0800196 return -1;
197 }
198 if (ctx->chain != NULL) {
199 /*
200 * This X509_STORE_CTX has already been used to verify a cert. We
201 * cannot do another one.
202 */
203 OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
David Benjamin8f1e1132016-06-07 12:49:36 -0400204 ctx->error = X509_V_ERR_INVALID_CALL;
Adam Langley57707c72016-01-14 11:25:12 -0800205 return -1;
206 }
Adam Langley95c29f32014-06-20 12:00:00 -0700207
Adam Langley57707c72016-01-14 11:25:12 -0800208 cb = ctx->verify_cb;
Adam Langley95c29f32014-06-20 12:00:00 -0700209
Adam Langley57707c72016-01-14 11:25:12 -0800210 /*
211 * first we make sure the chain we are going to build is present and that
212 * the first entry is in place
213 */
214 ctx->chain = sk_X509_new_null();
215 if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) {
216 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
David Benjamin8f1e1132016-06-07 12:49:36 -0400217 ctx->error = X509_V_ERR_OUT_OF_MEM;
Adam Langley57707c72016-01-14 11:25:12 -0800218 goto end;
219 }
220 X509_up_ref(ctx->cert);
221 ctx->last_untrusted = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700222
Adam Langley28feb922016-12-19 15:39:19 -0800223 /* We use a temporary STACK so we can chop and hack at it.
224 * sktmp = ctx->untrusted ++ ctx->ctx->additional_untrusted */
Adam Langley57707c72016-01-14 11:25:12 -0800225 if (ctx->untrusted != NULL
226 && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
227 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
David Benjamin8f1e1132016-06-07 12:49:36 -0400228 ctx->error = X509_V_ERR_OUT_OF_MEM;
Adam Langley57707c72016-01-14 11:25:12 -0800229 goto end;
230 }
Adam Langley95c29f32014-06-20 12:00:00 -0700231
Adam Langley28feb922016-12-19 15:39:19 -0800232 if (ctx->ctx->additional_untrusted != NULL) {
233 if (sktmp == NULL) {
234 sktmp = sk_X509_new_null();
235 if (sktmp == NULL) {
236 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
237 ctx->error = X509_V_ERR_OUT_OF_MEM;
238 goto end;
239 }
240 }
241
242 for (size_t k = 0; k < sk_X509_num(ctx->ctx->additional_untrusted);
243 k++) {
244 if (!sk_X509_push(sktmp,
245 sk_X509_value(ctx->ctx->additional_untrusted,
246 k))) {
247 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
248 ctx->error = X509_V_ERR_OUT_OF_MEM;
249 goto end;
250 }
251 }
252 }
253
Adam Langley57707c72016-01-14 11:25:12 -0800254 num = sk_X509_num(ctx->chain);
255 x = sk_X509_value(ctx->chain, num - 1);
256 depth = param->depth;
Adam Langley95c29f32014-06-20 12:00:00 -0700257
Adam Langley57707c72016-01-14 11:25:12 -0800258 for (;;) {
259 /* If we have enough, we break */
260 if (depth < num)
261 break; /* FIXME: If this happens, we should take
262 * note of it and, if appropriate, use the
263 * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
264 * later. */
Adam Langley95c29f32014-06-20 12:00:00 -0700265
Adam Langley57707c72016-01-14 11:25:12 -0800266 /* If we are self signed, we break */
267 if (cert_self_signed(x))
268 break;
269 /*
270 * If asked see if we can find issuer in trusted store first
271 */
272 if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) {
273 ok = ctx->get_issuer(&xtmp, ctx, x);
David Benjamin8f1e1132016-06-07 12:49:36 -0400274 if (ok < 0) {
275 ctx->error = X509_V_ERR_STORE_LOOKUP;
Adam Langley57707c72016-01-14 11:25:12 -0800276 goto end;
David Benjamin8f1e1132016-06-07 12:49:36 -0400277 }
Adam Langley57707c72016-01-14 11:25:12 -0800278 /*
279 * If successful for now free up cert so it will be picked up
280 * again later.
281 */
282 if (ok > 0) {
283 X509_free(xtmp);
284 break;
285 }
286 }
Adam Langley95c29f32014-06-20 12:00:00 -0700287
Adam Langley57707c72016-01-14 11:25:12 -0800288 /* If we were passed a cert chain, use it first */
Adam Langley28feb922016-12-19 15:39:19 -0800289 if (sktmp != NULL) {
Adam Langley57707c72016-01-14 11:25:12 -0800290 xtmp = find_issuer(ctx, sktmp, x);
291 if (xtmp != NULL) {
292 if (!sk_X509_push(ctx->chain, xtmp)) {
293 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
David Benjamin8f1e1132016-06-07 12:49:36 -0400294 ctx->error = X509_V_ERR_OUT_OF_MEM;
Steven Valdez3f81b602016-02-25 13:43:49 -0500295 ok = 0;
Adam Langley57707c72016-01-14 11:25:12 -0800296 goto end;
297 }
298 X509_up_ref(xtmp);
299 (void)sk_X509_delete_ptr(sktmp, xtmp);
300 ctx->last_untrusted++;
301 x = xtmp;
302 num++;
303 /*
304 * reparse the full chain for the next one
305 */
306 continue;
307 }
308 }
309 break;
310 }
Adam Langley95c29f32014-06-20 12:00:00 -0700311
Adam Langley3a39b062016-01-14 14:08:58 -0800312 /* Remember how many untrusted certs we have */
313 j = num;
Adam Langley57707c72016-01-14 11:25:12 -0800314 /*
315 * at this point, chain should contain a list of untrusted certificates.
316 * We now need to add at least one trusted one, if possible, otherwise we
317 * complain.
318 */
Adam Langley95c29f32014-06-20 12:00:00 -0700319
Adam Langley3a39b062016-01-14 14:08:58 -0800320 do {
321 /*
322 * Examine last certificate in chain and see if it is self signed.
323 */
324 i = sk_X509_num(ctx->chain);
325 x = sk_X509_value(ctx->chain, i - 1);
326 if (cert_self_signed(x)) {
327 /* we have a self signed certificate */
328 if (sk_X509_num(ctx->chain) == 1) {
329 /*
330 * We have a single self signed certificate: see if we can
331 * find it in the store. We must have an exact match to avoid
332 * possible impersonation.
333 */
334 ok = ctx->get_issuer(&xtmp, ctx, x);
335 if ((ok <= 0) || X509_cmp(x, xtmp)) {
336 ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
337 ctx->current_cert = x;
338 ctx->error_depth = i - 1;
339 if (ok == 1)
340 X509_free(xtmp);
341 bad_chain = 1;
342 ok = cb(0, ctx);
343 if (!ok)
344 goto end;
345 } else {
346 /*
347 * We have a match: replace certificate with store
348 * version so we get any trust settings.
349 */
350 X509_free(x);
351 x = xtmp;
352 (void)sk_X509_set(ctx->chain, i - 1, x);
353 ctx->last_untrusted = 0;
354 }
Adam Langley57707c72016-01-14 11:25:12 -0800355 } else {
356 /*
Adam Langley3a39b062016-01-14 14:08:58 -0800357 * extract and save self signed certificate for later use
Adam Langley57707c72016-01-14 11:25:12 -0800358 */
Adam Langley3a39b062016-01-14 14:08:58 -0800359 chain_ss = sk_X509_pop(ctx->chain);
360 ctx->last_untrusted--;
361 num--;
362 j--;
363 x = sk_X509_value(ctx->chain, num - 1);
Adam Langley57707c72016-01-14 11:25:12 -0800364 }
Adam Langley57707c72016-01-14 11:25:12 -0800365 }
Adam Langley3a39b062016-01-14 14:08:58 -0800366 /* We now lookup certs from the certificate store */
367 for (;;) {
368 /* If we have enough, we break */
369 if (depth < num)
370 break;
371 /* If we are self signed, we break */
372 if (cert_self_signed(x))
373 break;
374 ok = ctx->get_issuer(&xtmp, ctx, x);
Adam Langley95c29f32014-06-20 12:00:00 -0700375
David Benjamin8f1e1132016-06-07 12:49:36 -0400376 if (ok < 0) {
377 ctx->error = X509_V_ERR_STORE_LOOKUP;
Adam Langley3a39b062016-01-14 14:08:58 -0800378 goto end;
David Benjamin8f1e1132016-06-07 12:49:36 -0400379 }
Adam Langley3a39b062016-01-14 14:08:58 -0800380 if (ok == 0)
381 break;
382 x = xtmp;
383 if (!sk_X509_push(ctx->chain, x)) {
384 X509_free(xtmp);
385 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
David Benjamin8f1e1132016-06-07 12:49:36 -0400386 ctx->error = X509_V_ERR_OUT_OF_MEM;
Adam Langley3a39b062016-01-14 14:08:58 -0800387 ok = 0;
388 goto end;
389 }
390 num++;
Adam Langley57707c72016-01-14 11:25:12 -0800391 }
Adam Langley95c29f32014-06-20 12:00:00 -0700392
Adam Langley3a39b062016-01-14 14:08:58 -0800393 /* we now have our chain, lets check it... */
Steven Valdez3f81b602016-02-25 13:43:49 -0500394 trust = check_trust(ctx);
Adam Langley95c29f32014-06-20 12:00:00 -0700395
Adam Langley3a39b062016-01-14 14:08:58 -0800396 /* If explicitly rejected error */
Steven Valdez3f81b602016-02-25 13:43:49 -0500397 if (trust == X509_TRUST_REJECTED) {
398 ok = 0;
Adam Langley3a39b062016-01-14 14:08:58 -0800399 goto end;
Steven Valdez3f81b602016-02-25 13:43:49 -0500400 }
Adam Langley3a39b062016-01-14 14:08:58 -0800401 /*
402 * If it's not explicitly trusted then check if there is an alternative
403 * chain that could be used. We only do this if we haven't already
404 * checked via TRUSTED_FIRST and the user hasn't switched off alternate
405 * chain checking
406 */
407 retry = 0;
Steven Valdez3f81b602016-02-25 13:43:49 -0500408 if (trust != X509_TRUST_TRUSTED
Adam Langley3a39b062016-01-14 14:08:58 -0800409 && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
410 && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
411 while (j-- > 1) {
412 xtmp2 = sk_X509_value(ctx->chain, j - 1);
413 ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
414 if (ok < 0)
415 goto end;
416 /* Check if we found an alternate chain */
417 if (ok > 0) {
418 /*
419 * Free up the found cert we'll add it again later
420 */
421 X509_free(xtmp);
Adam Langley95c29f32014-06-20 12:00:00 -0700422
Adam Langley3a39b062016-01-14 14:08:58 -0800423 /*
424 * Dump all the certs above this point - we've found an
425 * alternate chain
426 */
427 while (num > j) {
428 xtmp = sk_X509_pop(ctx->chain);
429 X509_free(xtmp);
430 num--;
431 }
432 ctx->last_untrusted = sk_X509_num(ctx->chain);
433 retry = 1;
434 break;
435 }
436 }
437 }
438 } while (retry);
439
Adam Langley57707c72016-01-14 11:25:12 -0800440 /*
441 * If not explicitly trusted then indicate error unless it's a single
442 * self signed certificate in which case we've indicated an error already
443 * and set bad_chain == 1
444 */
Steven Valdez3f81b602016-02-25 13:43:49 -0500445 if (trust != X509_TRUST_TRUSTED && !bad_chain) {
Adam Langley57707c72016-01-14 11:25:12 -0800446 if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
447 if (ctx->last_untrusted >= num)
448 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
449 else
450 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
451 ctx->current_cert = x;
452 } else {
Adam Langley95c29f32014-06-20 12:00:00 -0700453
Adam Langley57707c72016-01-14 11:25:12 -0800454 sk_X509_push(ctx->chain, chain_ss);
455 num++;
456 ctx->last_untrusted = num;
457 ctx->current_cert = chain_ss;
458 ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
459 chain_ss = NULL;
460 }
Adam Langley95c29f32014-06-20 12:00:00 -0700461
Adam Langley57707c72016-01-14 11:25:12 -0800462 ctx->error_depth = num - 1;
463 bad_chain = 1;
464 ok = cb(0, ctx);
465 if (!ok)
466 goto end;
467 }
Adam Langley95c29f32014-06-20 12:00:00 -0700468
Adam Langley57707c72016-01-14 11:25:12 -0800469 /* We have the chain complete: now we need to check its purpose */
470 ok = check_chain_extensions(ctx);
Adam Langley95c29f32014-06-20 12:00:00 -0700471
Adam Langley57707c72016-01-14 11:25:12 -0800472 if (!ok)
473 goto end;
Adam Langley95c29f32014-06-20 12:00:00 -0700474
Adam Langley57707c72016-01-14 11:25:12 -0800475 ok = check_id(ctx);
Adam Langley95c29f32014-06-20 12:00:00 -0700476
Adam Langley57707c72016-01-14 11:25:12 -0800477 if (!ok)
478 goto end;
Adam Langley95c29f32014-06-20 12:00:00 -0700479
Adam Langley57707c72016-01-14 11:25:12 -0800480 /*
481 * Check revocation status: we do this after copying parameters because
482 * they may be needed for CRL signature verification.
483 */
Adam Langley95c29f32014-06-20 12:00:00 -0700484
Adam Langley57707c72016-01-14 11:25:12 -0800485 ok = ctx->check_revocation(ctx);
486 if (!ok)
487 goto end;
Adam Langley95c29f32014-06-20 12:00:00 -0700488
Steven Valdez3f81b602016-02-25 13:43:49 -0500489 int err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
490 ctx->param->flags);
491 if (err != X509_V_OK) {
492 ctx->error = err;
Adam Langley57707c72016-01-14 11:25:12 -0800493 ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
494 ok = cb(0, ctx);
495 if (!ok)
496 goto end;
497 }
Adam Langley95c29f32014-06-20 12:00:00 -0700498
Adam Langley57707c72016-01-14 11:25:12 -0800499 /* At this point, we have a chain and need to verify it */
500 if (ctx->verify != NULL)
501 ok = ctx->verify(ctx);
502 else
503 ok = internal_verify(ctx);
504 if (!ok)
505 goto end;
Adam Langley95c29f32014-06-20 12:00:00 -0700506
Martin Kreichgauerb86be362017-08-14 15:55:48 -0700507 /* Check name constraints */
508
509 ok = check_name_constraints(ctx);
510 if (!ok)
511 goto end;
512
Adam Langley57707c72016-01-14 11:25:12 -0800513 /* If we get this far evaluate policies */
514 if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
515 ok = ctx->check_policy(ctx);
David Benjamindd1ca992015-02-16 21:15:53 -0500516
Adam Langley57707c72016-01-14 11:25:12 -0800517 end:
518 if (sktmp != NULL)
519 sk_X509_free(sktmp);
520 if (chain_ss != NULL)
521 X509_free(chain_ss);
David Benjamin8f1e1132016-06-07 12:49:36 -0400522
523 /* Safety net, error returns must set ctx->error */
524 if (ok <= 0 && ctx->error == X509_V_OK)
525 ctx->error = X509_V_ERR_UNSPECIFIED;
Adam Langley57707c72016-01-14 11:25:12 -0800526 return ok;
527}
Adam Langley95c29f32014-06-20 12:00:00 -0700528
Adam Langley57707c72016-01-14 11:25:12 -0800529/*
530 * Given a STACK_OF(X509) find the issuer of cert (if any)
Adam Langley95c29f32014-06-20 12:00:00 -0700531 */
532
533static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
534{
Adam Langley57707c72016-01-14 11:25:12 -0800535 size_t i;
536 X509 *issuer;
537 for (i = 0; i < sk_X509_num(sk); i++) {
538 issuer = sk_X509_value(sk, i);
539 if (ctx->check_issued(ctx, x, issuer))
540 return issuer;
541 }
542 return NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700543}
544
545/* Given a possible certificate and issuer check them */
546
547static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
548{
Adam Langley57707c72016-01-14 11:25:12 -0800549 int ret;
550 ret = X509_check_issued(issuer, x);
551 if (ret == X509_V_OK)
552 return 1;
553 /* If we haven't asked for issuer errors don't set ctx */
554 if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
555 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700556
Adam Langley57707c72016-01-14 11:25:12 -0800557 ctx->error = ret;
558 ctx->current_cert = x;
559 ctx->current_issuer = issuer;
560 return ctx->verify_cb(0, ctx);
Adam Langley95c29f32014-06-20 12:00:00 -0700561}
562
563/* Alternative lookup method: look from a STACK stored in other_ctx */
564
565static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
566{
Adam Langley57707c72016-01-14 11:25:12 -0800567 *issuer = find_issuer(ctx, ctx->other_ctx, x);
568 if (*issuer) {
569 X509_up_ref(*issuer);
570 return 1;
571 } else
572 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700573}
Adam Langley95c29f32014-06-20 12:00:00 -0700574
Adam Langley57707c72016-01-14 11:25:12 -0800575/*
576 * Check a certificate chains extensions for consistency with the supplied
577 * purpose
Adam Langley95c29f32014-06-20 12:00:00 -0700578 */
579
580static int check_chain_extensions(X509_STORE_CTX *ctx)
581{
Adam Langley57707c72016-01-14 11:25:12 -0800582 int i, ok = 0, must_be_ca, plen = 0;
583 X509 *x;
584 int (*cb) (int xok, X509_STORE_CTX *xctx);
585 int proxy_path_length = 0;
586 int purpose;
587 int allow_proxy_certs;
588 cb = ctx->verify_cb;
Adam Langley95c29f32014-06-20 12:00:00 -0700589
Adam Langley57707c72016-01-14 11:25:12 -0800590 /*
591 * must_be_ca can have 1 of 3 values: -1: we accept both CA and non-CA
592 * certificates, to allow direct use of self-signed certificates (which
593 * are marked as CA). 0: we only accept non-CA certificates. This is
594 * currently not used, but the possibility is present for future
595 * extensions. 1: we only accept CA certificates. This is currently used
596 * for all certificates in the chain except the leaf certificate.
597 */
598 must_be_ca = -1;
Adam Langley95c29f32014-06-20 12:00:00 -0700599
Adam Langley57707c72016-01-14 11:25:12 -0800600 /* CRL path validation */
601 if (ctx->parent) {
602 allow_proxy_certs = 0;
603 purpose = X509_PURPOSE_CRL_SIGN;
604 } else {
605 allow_proxy_certs =
606 ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
Adam Langley57707c72016-01-14 11:25:12 -0800607 purpose = ctx->param->purpose;
608 }
Adam Langley95c29f32014-06-20 12:00:00 -0700609
Adam Langley57707c72016-01-14 11:25:12 -0800610 /* Check all untrusted certificates */
611 for (i = 0; i < ctx->last_untrusted; i++) {
612 int ret;
613 x = sk_X509_value(ctx->chain, i);
614 if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
615 && (x->ex_flags & EXFLAG_CRITICAL)) {
616 ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
617 ctx->error_depth = i;
618 ctx->current_cert = x;
619 ok = cb(0, ctx);
620 if (!ok)
621 goto end;
622 }
623 if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
624 ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
625 ctx->error_depth = i;
626 ctx->current_cert = x;
627 ok = cb(0, ctx);
628 if (!ok)
629 goto end;
630 }
631 ret = X509_check_ca(x);
632 switch (must_be_ca) {
633 case -1:
634 if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
635 && (ret != 1) && (ret != 0)) {
636 ret = 0;
637 ctx->error = X509_V_ERR_INVALID_CA;
638 } else
639 ret = 1;
640 break;
641 case 0:
642 if (ret != 0) {
643 ret = 0;
644 ctx->error = X509_V_ERR_INVALID_NON_CA;
645 } else
646 ret = 1;
647 break;
648 default:
649 if ((ret == 0)
650 || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
651 && (ret != 1))) {
652 ret = 0;
653 ctx->error = X509_V_ERR_INVALID_CA;
654 } else
655 ret = 1;
656 break;
657 }
658 if (ret == 0) {
659 ctx->error_depth = i;
660 ctx->current_cert = x;
661 ok = cb(0, ctx);
662 if (!ok)
663 goto end;
664 }
665 if (ctx->param->purpose > 0) {
666 ret = X509_check_purpose(x, purpose, must_be_ca > 0);
667 if ((ret == 0)
668 || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
669 && (ret != 1))) {
670 ctx->error = X509_V_ERR_INVALID_PURPOSE;
671 ctx->error_depth = i;
672 ctx->current_cert = x;
673 ok = cb(0, ctx);
674 if (!ok)
675 goto end;
676 }
677 }
678 /* Check pathlen if not self issued */
679 if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
680 && (x->ex_pathlen != -1)
681 && (plen > (x->ex_pathlen + proxy_path_length + 1))) {
682 ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
683 ctx->error_depth = i;
684 ctx->current_cert = x;
685 ok = cb(0, ctx);
686 if (!ok)
687 goto end;
688 }
689 /* Increment path length if not self issued */
690 if (!(x->ex_flags & EXFLAG_SI))
691 plen++;
692 /*
693 * If this certificate is a proxy certificate, the next certificate
694 * must be another proxy certificate or a EE certificate. If not,
695 * the next certificate must be a CA certificate.
696 */
697 if (x->ex_flags & EXFLAG_PROXY) {
698 if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
699 ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
700 ctx->error_depth = i;
701 ctx->current_cert = x;
702 ok = cb(0, ctx);
703 if (!ok)
704 goto end;
705 }
706 proxy_path_length++;
707 must_be_ca = 0;
708 } else
709 must_be_ca = 1;
710 }
711 ok = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700712 end:
Adam Langley57707c72016-01-14 11:25:12 -0800713 return ok;
Adam Langley95c29f32014-06-20 12:00:00 -0700714}
715
716static int check_name_constraints(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -0800717{
718 X509 *x;
719 int i, j, rv;
720 /* Check name constraints for all certificates */
721 for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) {
722 x = sk_X509_value(ctx->chain, i);
723 /* Ignore self issued certs unless last in chain */
724 if (i && (x->ex_flags & EXFLAG_SI))
725 continue;
726 /*
727 * Check against constraints for all certificates higher in chain
728 * including trust anchor. Trust anchor not strictly speaking needed
729 * but if it includes constraints it is to be assumed it expects them
730 * to be obeyed.
731 */
732 for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) {
733 NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
734 if (nc) {
735 rv = NAME_CONSTRAINTS_check(x, nc);
David Benjamin8f1e1132016-06-07 12:49:36 -0400736 switch (rv) {
737 case X509_V_OK:
738 continue;
739 case X509_V_ERR_OUT_OF_MEM:
740 ctx->error = rv;
741 return 0;
742 default:
Adam Langley57707c72016-01-14 11:25:12 -0800743 ctx->error = rv;
744 ctx->error_depth = i;
745 ctx->current_cert = x;
746 if (!ctx->verify_cb(0, ctx))
747 return 0;
David Benjamin8f1e1132016-06-07 12:49:36 -0400748 break;
Adam Langley57707c72016-01-14 11:25:12 -0800749 }
750 }
751 }
752 }
753 return 1;
754}
Adam Langley95c29f32014-06-20 12:00:00 -0700755
756static int check_id_error(X509_STORE_CTX *ctx, int errcode)
Adam Langley57707c72016-01-14 11:25:12 -0800757{
758 ctx->error = errcode;
759 ctx->current_cert = ctx->cert;
760 ctx->error_depth = 0;
761 return ctx->verify_cb(0, ctx);
762}
Adam Langley95c29f32014-06-20 12:00:00 -0700763
Adam Langley589963f2015-02-11 12:18:56 -0800764static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id)
Adam Langley57707c72016-01-14 11:25:12 -0800765{
766 size_t i;
767 size_t n = sk_OPENSSL_STRING_num(id->hosts);
768 char *name;
Adam Langley589963f2015-02-11 12:18:56 -0800769
Adam Langley3a39b062016-01-14 14:08:58 -0800770 if (id->peername != NULL) {
771 OPENSSL_free(id->peername);
772 id->peername = NULL;
773 }
Adam Langley57707c72016-01-14 11:25:12 -0800774 for (i = 0; i < n; ++i) {
775 name = sk_OPENSSL_STRING_value(id->hosts, i);
776 if (X509_check_host(x, name, strlen(name), id->hostflags,
777 &id->peername) > 0)
778 return 1;
779 }
780 return n == 0;
781}
Adam Langley589963f2015-02-11 12:18:56 -0800782
Adam Langley95c29f32014-06-20 12:00:00 -0700783static int check_id(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -0800784{
785 X509_VERIFY_PARAM *vpm = ctx->param;
786 X509_VERIFY_PARAM_ID *id = vpm->id;
787 X509 *x = ctx->cert;
788 if (id->hosts && check_hosts(x, id) <= 0) {
789 if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
790 return 0;
791 }
792 if (id->email && X509_check_email(x, id->email, id->emaillen, 0) <= 0) {
793 if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
794 return 0;
795 }
796 if (id->ip && X509_check_ip(x, id->ip, id->iplen, 0) <= 0) {
797 if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
798 return 0;
799 }
800 return 1;
801}
Adam Langley95c29f32014-06-20 12:00:00 -0700802
803static int check_trust(X509_STORE_CTX *ctx)
804{
Adam Langley57707c72016-01-14 11:25:12 -0800805 size_t i;
806 int ok;
807 X509 *x = NULL;
808 int (*cb) (int xok, X509_STORE_CTX *xctx);
809 cb = ctx->verify_cb;
810 /* Check all trusted certificates in chain */
811 for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) {
812 x = sk_X509_value(ctx->chain, i);
813 ok = X509_check_trust(x, ctx->param->trust, 0);
814 /* If explicitly trusted return trusted */
815 if (ok == X509_TRUST_TRUSTED)
816 return X509_TRUST_TRUSTED;
817 /*
818 * If explicitly rejected notify callback and reject if not
819 * overridden.
820 */
821 if (ok == X509_TRUST_REJECTED) {
822 ctx->error_depth = i;
823 ctx->current_cert = x;
824 ctx->error = X509_V_ERR_CERT_REJECTED;
825 ok = cb(0, ctx);
826 if (!ok)
827 return X509_TRUST_REJECTED;
828 }
829 }
830 /*
831 * If we accept partial chains and have at least one trusted certificate
832 * return success.
833 */
834 if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
835 X509 *mx;
836 if (ctx->last_untrusted < (int)sk_X509_num(ctx->chain))
837 return X509_TRUST_TRUSTED;
838 x = sk_X509_value(ctx->chain, 0);
839 mx = lookup_cert_match(ctx, x);
840 if (mx) {
841 (void)sk_X509_set(ctx->chain, 0, mx);
842 X509_free(x);
843 ctx->last_untrusted = 0;
844 return X509_TRUST_TRUSTED;
845 }
846 }
Adam Langley95c29f32014-06-20 12:00:00 -0700847
Adam Langley57707c72016-01-14 11:25:12 -0800848 /*
849 * If no trusted certs in chain at all return untrusted and allow
850 * standard (no issuer cert) etc errors to be indicated.
851 */
852 return X509_TRUST_UNTRUSTED;
Adam Langley95c29f32014-06-20 12:00:00 -0700853}
854
855static int check_revocation(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -0800856{
857 int i, last, ok;
858 if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
859 return 1;
860 if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
861 last = sk_X509_num(ctx->chain) - 1;
862 else {
863 /* If checking CRL paths this isn't the EE certificate */
864 if (ctx->parent)
865 return 1;
866 last = 0;
867 }
868 for (i = 0; i <= last; i++) {
869 ctx->error_depth = i;
870 ok = check_cert(ctx);
871 if (!ok)
872 return ok;
873 }
874 return 1;
875}
Adam Langley95c29f32014-06-20 12:00:00 -0700876
877static int check_cert(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -0800878{
879 X509_CRL *crl = NULL, *dcrl = NULL;
880 X509 *x;
Brian Smithdc6c1b82016-01-17 22:21:42 -1000881 int ok = 0, cnum;
Adam Langley57707c72016-01-14 11:25:12 -0800882 unsigned int last_reasons;
883 cnum = ctx->error_depth;
884 x = sk_X509_value(ctx->chain, cnum);
885 ctx->current_cert = x;
886 ctx->current_issuer = NULL;
887 ctx->current_crl_score = 0;
888 ctx->current_reasons = 0;
889 while (ctx->current_reasons != CRLDP_ALL_REASONS) {
890 last_reasons = ctx->current_reasons;
891 /* Try to retrieve relevant CRL */
892 if (ctx->get_crl)
893 ok = ctx->get_crl(ctx, &crl, x);
894 else
895 ok = get_crl_delta(ctx, &crl, &dcrl, x);
896 /*
897 * If error looking up CRL, nothing we can do except notify callback
898 */
899 if (!ok) {
900 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
901 ok = ctx->verify_cb(0, ctx);
902 goto err;
903 }
904 ctx->current_crl = crl;
905 ok = ctx->check_crl(ctx, crl);
906 if (!ok)
907 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -0700908
Adam Langley57707c72016-01-14 11:25:12 -0800909 if (dcrl) {
910 ok = ctx->check_crl(ctx, dcrl);
911 if (!ok)
912 goto err;
913 ok = ctx->cert_crl(ctx, dcrl, x);
914 if (!ok)
915 goto err;
916 } else
917 ok = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700918
Adam Langley57707c72016-01-14 11:25:12 -0800919 /* Don't look in full CRL if delta reason is removefromCRL */
920 if (ok != 2) {
921 ok = ctx->cert_crl(ctx, crl, x);
922 if (!ok)
923 goto err;
924 }
Adam Langley95c29f32014-06-20 12:00:00 -0700925
Adam Langley57707c72016-01-14 11:25:12 -0800926 X509_CRL_free(crl);
927 X509_CRL_free(dcrl);
928 crl = NULL;
929 dcrl = NULL;
930 /*
931 * If reasons not updated we wont get anywhere by another iteration,
932 * so exit loop.
933 */
934 if (last_reasons == ctx->current_reasons) {
935 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
936 ok = ctx->verify_cb(0, ctx);
937 goto err;
938 }
939 }
940 err:
941 X509_CRL_free(crl);
942 X509_CRL_free(dcrl);
Adam Langley95c29f32014-06-20 12:00:00 -0700943
Adam Langley57707c72016-01-14 11:25:12 -0800944 ctx->current_crl = NULL;
945 return ok;
Adam Langley95c29f32014-06-20 12:00:00 -0700946
Adam Langley57707c72016-01-14 11:25:12 -0800947}
Adam Langley95c29f32014-06-20 12:00:00 -0700948
949/* Check CRL times against values in X509_STORE_CTX */
950
951static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
Adam Langley57707c72016-01-14 11:25:12 -0800952{
953 time_t *ptime;
954 int i;
955 if (notify)
956 ctx->current_crl = crl;
957 if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
958 ptime = &ctx->param->check_time;
959 else
960 ptime = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700961
Adam Langley57707c72016-01-14 11:25:12 -0800962 i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
963 if (i == 0) {
964 if (!notify)
965 return 0;
966 ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
967 if (!ctx->verify_cb(0, ctx))
968 return 0;
969 }
Adam Langley95c29f32014-06-20 12:00:00 -0700970
Adam Langley57707c72016-01-14 11:25:12 -0800971 if (i > 0) {
972 if (!notify)
973 return 0;
974 ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
975 if (!ctx->verify_cb(0, ctx))
976 return 0;
977 }
Adam Langley95c29f32014-06-20 12:00:00 -0700978
Adam Langley57707c72016-01-14 11:25:12 -0800979 if (X509_CRL_get_nextUpdate(crl)) {
980 i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
Adam Langley95c29f32014-06-20 12:00:00 -0700981
Adam Langley57707c72016-01-14 11:25:12 -0800982 if (i == 0) {
983 if (!notify)
984 return 0;
985 ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
986 if (!ctx->verify_cb(0, ctx))
987 return 0;
988 }
989 /* Ignore expiry of base CRL is delta is valid */
990 if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) {
991 if (!notify)
992 return 0;
993 ctx->error = X509_V_ERR_CRL_HAS_EXPIRED;
994 if (!ctx->verify_cb(0, ctx))
995 return 0;
996 }
997 }
Adam Langley95c29f32014-06-20 12:00:00 -0700998
Adam Langley57707c72016-01-14 11:25:12 -0800999 if (notify)
1000 ctx->current_crl = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001001
Adam Langley57707c72016-01-14 11:25:12 -08001002 return 1;
1003}
Adam Langley95c29f32014-06-20 12:00:00 -07001004
1005static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
Adam Langley57707c72016-01-14 11:25:12 -08001006 X509 **pissuer, int *pscore, unsigned int *preasons,
1007 STACK_OF(X509_CRL) *crls)
1008{
1009 int crl_score, best_score = *pscore;
1010 size_t i;
1011 unsigned int reasons, best_reasons = 0;
1012 X509 *x = ctx->current_cert;
1013 X509_CRL *crl, *best_crl = NULL;
1014 X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001015
Adam Langley57707c72016-01-14 11:25:12 -08001016 for (i = 0; i < sk_X509_CRL_num(crls); i++) {
1017 crl = sk_X509_CRL_value(crls, i);
1018 reasons = *preasons;
1019 crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
Steven Valdezf9f312a2016-09-26 11:41:04 -04001020 if (crl_score < best_score || crl_score == 0)
David Benjamine76cdde2016-07-26 12:53:42 -04001021 continue;
1022 /* If current CRL is equivalent use it if it is newer */
Steven Valdezf9f312a2016-09-26 11:41:04 -04001023 if (crl_score == best_score && best_crl != NULL) {
David Benjamine76cdde2016-07-26 12:53:42 -04001024 int day, sec;
1025 if (ASN1_TIME_diff(&day, &sec, X509_CRL_get_lastUpdate(best_crl),
1026 X509_CRL_get_lastUpdate(crl)) == 0)
1027 continue;
1028 /*
1029 * ASN1_TIME_diff never returns inconsistent signs for |day|
1030 * and |sec|.
1031 */
1032 if (day <= 0 && sec <= 0)
1033 continue;
Adam Langley57707c72016-01-14 11:25:12 -08001034 }
David Benjamine76cdde2016-07-26 12:53:42 -04001035 best_crl = crl;
1036 best_crl_issuer = crl_issuer;
1037 best_score = crl_score;
1038 best_reasons = reasons;
Adam Langley57707c72016-01-14 11:25:12 -08001039 }
Adam Langley95c29f32014-06-20 12:00:00 -07001040
Adam Langley57707c72016-01-14 11:25:12 -08001041 if (best_crl) {
1042 if (*pcrl)
1043 X509_CRL_free(*pcrl);
1044 *pcrl = best_crl;
1045 *pissuer = best_crl_issuer;
1046 *pscore = best_score;
1047 *preasons = best_reasons;
1048 X509_CRL_up_ref(best_crl);
1049 if (*pdcrl) {
1050 X509_CRL_free(*pdcrl);
1051 *pdcrl = NULL;
1052 }
1053 get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
1054 }
Adam Langley95c29f32014-06-20 12:00:00 -07001055
Adam Langley57707c72016-01-14 11:25:12 -08001056 if (best_score >= CRL_SCORE_VALID)
1057 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -07001058
Adam Langley57707c72016-01-14 11:25:12 -08001059 return 0;
1060}
Adam Langley95c29f32014-06-20 12:00:00 -07001061
Adam Langley57707c72016-01-14 11:25:12 -08001062/*
1063 * Compare two CRL extensions for delta checking purposes. They should be
Adam Langley95c29f32014-06-20 12:00:00 -07001064 * both present or both absent. If both present all fields must be identical.
1065 */
1066
1067static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
Adam Langley57707c72016-01-14 11:25:12 -08001068{
1069 ASN1_OCTET_STRING *exta, *extb;
1070 int i;
1071 i = X509_CRL_get_ext_by_NID(a, nid, -1);
1072 if (i >= 0) {
1073 /* Can't have multiple occurrences */
1074 if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
1075 return 0;
1076 exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
1077 } else
1078 exta = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001079
Adam Langley57707c72016-01-14 11:25:12 -08001080 i = X509_CRL_get_ext_by_NID(b, nid, -1);
Adam Langley95c29f32014-06-20 12:00:00 -07001081
Adam Langley57707c72016-01-14 11:25:12 -08001082 if (i >= 0) {
Adam Langley95c29f32014-06-20 12:00:00 -07001083
Adam Langley57707c72016-01-14 11:25:12 -08001084 if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
1085 return 0;
1086 extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
1087 } else
1088 extb = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001089
Adam Langley57707c72016-01-14 11:25:12 -08001090 if (!exta && !extb)
1091 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -07001092
Adam Langley57707c72016-01-14 11:25:12 -08001093 if (!exta || !extb)
1094 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001095
Adam Langley57707c72016-01-14 11:25:12 -08001096 if (ASN1_OCTET_STRING_cmp(exta, extb))
1097 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001098
Adam Langley57707c72016-01-14 11:25:12 -08001099 return 1;
1100}
Adam Langley95c29f32014-06-20 12:00:00 -07001101
1102/* See if a base and delta are compatible */
1103
1104static int check_delta_base(X509_CRL *delta, X509_CRL *base)
Adam Langley57707c72016-01-14 11:25:12 -08001105{
1106 /* Delta CRL must be a delta */
1107 if (!delta->base_crl_number)
1108 return 0;
1109 /* Base must have a CRL number */
1110 if (!base->crl_number)
1111 return 0;
1112 /* Issuer names must match */
1113 if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta)))
1114 return 0;
1115 /* AKID and IDP must match */
1116 if (!crl_extension_match(delta, base, NID_authority_key_identifier))
1117 return 0;
1118 if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
1119 return 0;
1120 /* Delta CRL base number must not exceed Full CRL number. */
1121 if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
1122 return 0;
1123 /* Delta CRL number must exceed full CRL number */
1124 if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
1125 return 1;
1126 return 0;
1127}
Adam Langley95c29f32014-06-20 12:00:00 -07001128
Adam Langley57707c72016-01-14 11:25:12 -08001129/*
1130 * For a given base CRL find a delta... maybe extend to delta scoring or
1131 * retrieve a chain of deltas...
Adam Langley95c29f32014-06-20 12:00:00 -07001132 */
1133
1134static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
Adam Langley57707c72016-01-14 11:25:12 -08001135 X509_CRL *base, STACK_OF(X509_CRL) *crls)
1136{
1137 X509_CRL *delta;
1138 size_t i;
1139 if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
1140 return;
1141 if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
1142 return;
1143 for (i = 0; i < sk_X509_CRL_num(crls); i++) {
1144 delta = sk_X509_CRL_value(crls, i);
1145 if (check_delta_base(delta, base)) {
1146 if (check_crl_time(ctx, delta, 0))
1147 *pscore |= CRL_SCORE_TIME_DELTA;
1148 X509_CRL_up_ref(delta);
1149 *dcrl = delta;
1150 return;
1151 }
1152 }
1153 *dcrl = NULL;
1154}
Adam Langley95c29f32014-06-20 12:00:00 -07001155
Adam Langley57707c72016-01-14 11:25:12 -08001156/*
1157 * For a given CRL return how suitable it is for the supplied certificate
1158 * 'x'. The return value is a mask of several criteria. If the issuer is not
1159 * the certificate issuer this is returned in *pissuer. The reasons mask is
1160 * also used to determine if the CRL is suitable: if no new reasons the CRL
1161 * is rejected, otherwise reasons is updated.
Adam Langley95c29f32014-06-20 12:00:00 -07001162 */
1163
1164static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
Adam Langley57707c72016-01-14 11:25:12 -08001165 unsigned int *preasons, X509_CRL *crl, X509 *x)
1166{
Adam Langley95c29f32014-06-20 12:00:00 -07001167
Adam Langley57707c72016-01-14 11:25:12 -08001168 int crl_score = 0;
1169 unsigned int tmp_reasons = *preasons, crl_reasons;
Adam Langley95c29f32014-06-20 12:00:00 -07001170
Adam Langley57707c72016-01-14 11:25:12 -08001171 /* First see if we can reject CRL straight away */
Adam Langley95c29f32014-06-20 12:00:00 -07001172
Adam Langley57707c72016-01-14 11:25:12 -08001173 /* Invalid IDP cannot be processed */
1174 if (crl->idp_flags & IDP_INVALID)
1175 return 0;
1176 /* Reason codes or indirect CRLs need extended CRL support */
1177 if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) {
1178 if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
1179 return 0;
1180 } else if (crl->idp_flags & IDP_REASONS) {
1181 /* If no new reasons reject */
1182 if (!(crl->idp_reasons & ~tmp_reasons))
1183 return 0;
1184 }
1185 /* Don't process deltas at this stage */
1186 else if (crl->base_crl_number)
1187 return 0;
1188 /* If issuer name doesn't match certificate need indirect CRL */
1189 if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) {
1190 if (!(crl->idp_flags & IDP_INDIRECT))
1191 return 0;
1192 } else
1193 crl_score |= CRL_SCORE_ISSUER_NAME;
Adam Langley95c29f32014-06-20 12:00:00 -07001194
Adam Langley57707c72016-01-14 11:25:12 -08001195 if (!(crl->flags & EXFLAG_CRITICAL))
1196 crl_score |= CRL_SCORE_NOCRITICAL;
Adam Langley95c29f32014-06-20 12:00:00 -07001197
Adam Langley57707c72016-01-14 11:25:12 -08001198 /* Check expiry */
1199 if (check_crl_time(ctx, crl, 0))
1200 crl_score |= CRL_SCORE_TIME;
Adam Langley95c29f32014-06-20 12:00:00 -07001201
Adam Langley57707c72016-01-14 11:25:12 -08001202 /* Check authority key ID and locate certificate issuer */
1203 crl_akid_check(ctx, crl, pissuer, &crl_score);
Adam Langley95c29f32014-06-20 12:00:00 -07001204
Adam Langley57707c72016-01-14 11:25:12 -08001205 /* If we can't locate certificate issuer at this point forget it */
Adam Langley95c29f32014-06-20 12:00:00 -07001206
Adam Langley57707c72016-01-14 11:25:12 -08001207 if (!(crl_score & CRL_SCORE_AKID))
1208 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001209
Adam Langley57707c72016-01-14 11:25:12 -08001210 /* Check cert for matching CRL distribution points */
Adam Langley95c29f32014-06-20 12:00:00 -07001211
Adam Langley57707c72016-01-14 11:25:12 -08001212 if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) {
1213 /* If no new reasons reject */
1214 if (!(crl_reasons & ~tmp_reasons))
1215 return 0;
1216 tmp_reasons |= crl_reasons;
1217 crl_score |= CRL_SCORE_SCOPE;
1218 }
Adam Langley95c29f32014-06-20 12:00:00 -07001219
Adam Langley57707c72016-01-14 11:25:12 -08001220 *preasons = tmp_reasons;
Adam Langley95c29f32014-06-20 12:00:00 -07001221
Adam Langley57707c72016-01-14 11:25:12 -08001222 return crl_score;
Adam Langley95c29f32014-06-20 12:00:00 -07001223
Adam Langley57707c72016-01-14 11:25:12 -08001224}
Adam Langley95c29f32014-06-20 12:00:00 -07001225
1226static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
Adam Langley57707c72016-01-14 11:25:12 -08001227 X509 **pissuer, int *pcrl_score)
1228{
1229 X509 *crl_issuer = NULL;
1230 X509_NAME *cnm = X509_CRL_get_issuer(crl);
1231 int cidx = ctx->error_depth;
1232 size_t i;
Adam Langley95c29f32014-06-20 12:00:00 -07001233
Adam Langley57707c72016-01-14 11:25:12 -08001234 if ((size_t)cidx != sk_X509_num(ctx->chain) - 1)
1235 cidx++;
Adam Langley95c29f32014-06-20 12:00:00 -07001236
Adam Langley57707c72016-01-14 11:25:12 -08001237 crl_issuer = sk_X509_value(ctx->chain, cidx);
Adam Langley95c29f32014-06-20 12:00:00 -07001238
Adam Langley57707c72016-01-14 11:25:12 -08001239 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1240 if (*pcrl_score & CRL_SCORE_ISSUER_NAME) {
1241 *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT;
1242 *pissuer = crl_issuer;
1243 return;
1244 }
1245 }
Adam Langley95c29f32014-06-20 12:00:00 -07001246
Adam Langley57707c72016-01-14 11:25:12 -08001247 for (cidx++; cidx < (int)sk_X509_num(ctx->chain); cidx++) {
1248 crl_issuer = sk_X509_value(ctx->chain, cidx);
1249 if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1250 continue;
1251 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1252 *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH;
1253 *pissuer = crl_issuer;
1254 return;
1255 }
1256 }
Adam Langley95c29f32014-06-20 12:00:00 -07001257
Adam Langley57707c72016-01-14 11:25:12 -08001258 /* Anything else needs extended CRL support */
Adam Langley95c29f32014-06-20 12:00:00 -07001259
Adam Langley57707c72016-01-14 11:25:12 -08001260 if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
1261 return;
Adam Langley95c29f32014-06-20 12:00:00 -07001262
Adam Langley57707c72016-01-14 11:25:12 -08001263 /*
1264 * Otherwise the CRL issuer is not on the path. Look for it in the set of
1265 * untrusted certificates.
1266 */
1267 for (i = 0; i < sk_X509_num(ctx->untrusted); i++) {
1268 crl_issuer = sk_X509_value(ctx->untrusted, i);
1269 if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1270 continue;
1271 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1272 *pissuer = crl_issuer;
1273 *pcrl_score |= CRL_SCORE_AKID;
1274 return;
1275 }
1276 }
Adam Langley28feb922016-12-19 15:39:19 -08001277
1278 for (i = 0; i < sk_X509_num(ctx->ctx->additional_untrusted); i++) {
1279 crl_issuer = sk_X509_value(ctx->ctx->additional_untrusted, i);
1280 if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1281 continue;
1282 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1283 *pissuer = crl_issuer;
1284 *pcrl_score |= CRL_SCORE_AKID;
1285 return;
1286 }
1287 }
Adam Langley57707c72016-01-14 11:25:12 -08001288}
Adam Langley95c29f32014-06-20 12:00:00 -07001289
Adam Langley57707c72016-01-14 11:25:12 -08001290/*
1291 * Check the path of a CRL issuer certificate. This creates a new
Adam Langley95c29f32014-06-20 12:00:00 -07001292 * X509_STORE_CTX and populates it with most of the parameters from the
Adam Langley57707c72016-01-14 11:25:12 -08001293 * parent. This could be optimised somewhat since a lot of path checking will
1294 * be duplicated by the parent, but this will rarely be used in practice.
Adam Langley95c29f32014-06-20 12:00:00 -07001295 */
1296
1297static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
Adam Langley57707c72016-01-14 11:25:12 -08001298{
1299 X509_STORE_CTX crl_ctx;
1300 int ret;
1301 /* Don't allow recursive CRL path validation */
1302 if (ctx->parent)
1303 return 0;
1304 if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
1305 return -1;
Adam Langley95c29f32014-06-20 12:00:00 -07001306
Adam Langley57707c72016-01-14 11:25:12 -08001307 crl_ctx.crls = ctx->crls;
1308 /* Copy verify params across */
1309 X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
Adam Langley95c29f32014-06-20 12:00:00 -07001310
Adam Langley57707c72016-01-14 11:25:12 -08001311 crl_ctx.parent = ctx;
1312 crl_ctx.verify_cb = ctx->verify_cb;
Adam Langley95c29f32014-06-20 12:00:00 -07001313
Adam Langley57707c72016-01-14 11:25:12 -08001314 /* Verify CRL issuer */
1315 ret = X509_verify_cert(&crl_ctx);
Adam Langley95c29f32014-06-20 12:00:00 -07001316
Adam Langley57707c72016-01-14 11:25:12 -08001317 if (ret <= 0)
1318 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -07001319
Adam Langley57707c72016-01-14 11:25:12 -08001320 /* Check chain is acceptable */
Adam Langley95c29f32014-06-20 12:00:00 -07001321
Adam Langley57707c72016-01-14 11:25:12 -08001322 ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
1323 err:
1324 X509_STORE_CTX_cleanup(&crl_ctx);
1325 return ret;
1326}
Adam Langley95c29f32014-06-20 12:00:00 -07001327
Adam Langley57707c72016-01-14 11:25:12 -08001328/*
1329 * RFC3280 says nothing about the relationship between CRL path and
1330 * certificate path, which could lead to situations where a certificate could
1331 * be revoked or validated by a CA not authorised to do so. RFC5280 is more
1332 * strict and states that the two paths must end in the same trust anchor,
1333 * though some discussions remain... until this is resolved we use the
1334 * RFC5280 version
Adam Langley95c29f32014-06-20 12:00:00 -07001335 */
1336
1337static int check_crl_chain(X509_STORE_CTX *ctx,
Adam Langley57707c72016-01-14 11:25:12 -08001338 STACK_OF(X509) *cert_path,
1339 STACK_OF(X509) *crl_path)
1340{
1341 X509 *cert_ta, *crl_ta;
1342 cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
1343 crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
1344 if (!X509_cmp(cert_ta, crl_ta))
1345 return 1;
1346 return 0;
1347}
Adam Langley95c29f32014-06-20 12:00:00 -07001348
Adam Langley57707c72016-01-14 11:25:12 -08001349/*
1350 * Check for match between two dist point names: three separate cases. 1.
1351 * Both are relative names and compare X509_NAME types. 2. One full, one
1352 * relative. Compare X509_NAME to GENERAL_NAMES. 3. Both are full names and
1353 * compare two GENERAL_NAMES. 4. One is NULL: automatic match.
Adam Langley95c29f32014-06-20 12:00:00 -07001354 */
1355
Adam Langley95c29f32014-06-20 12:00:00 -07001356static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
Adam Langley57707c72016-01-14 11:25:12 -08001357{
1358 X509_NAME *nm = NULL;
1359 GENERAL_NAMES *gens = NULL;
1360 GENERAL_NAME *gena, *genb;
1361 size_t i, j;
1362 if (!a || !b)
1363 return 1;
1364 if (a->type == 1) {
1365 if (!a->dpname)
1366 return 0;
1367 /* Case 1: two X509_NAME */
1368 if (b->type == 1) {
1369 if (!b->dpname)
1370 return 0;
1371 if (!X509_NAME_cmp(a->dpname, b->dpname))
1372 return 1;
1373 else
1374 return 0;
1375 }
1376 /* Case 2: set name and GENERAL_NAMES appropriately */
1377 nm = a->dpname;
1378 gens = b->name.fullname;
1379 } else if (b->type == 1) {
1380 if (!b->dpname)
1381 return 0;
1382 /* Case 2: set name and GENERAL_NAMES appropriately */
1383 gens = a->name.fullname;
1384 nm = b->dpname;
1385 }
Adam Langley95c29f32014-06-20 12:00:00 -07001386
Adam Langley57707c72016-01-14 11:25:12 -08001387 /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
1388 if (nm) {
1389 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
1390 gena = sk_GENERAL_NAME_value(gens, i);
1391 if (gena->type != GEN_DIRNAME)
1392 continue;
1393 if (!X509_NAME_cmp(nm, gena->d.directoryName))
1394 return 1;
1395 }
1396 return 0;
1397 }
Adam Langley95c29f32014-06-20 12:00:00 -07001398
Adam Langley57707c72016-01-14 11:25:12 -08001399 /* Else case 3: two GENERAL_NAMES */
Adam Langley95c29f32014-06-20 12:00:00 -07001400
Adam Langley57707c72016-01-14 11:25:12 -08001401 for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) {
1402 gena = sk_GENERAL_NAME_value(a->name.fullname, i);
1403 for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) {
1404 genb = sk_GENERAL_NAME_value(b->name.fullname, j);
1405 if (!GENERAL_NAME_cmp(gena, genb))
1406 return 1;
1407 }
1408 }
Adam Langley95c29f32014-06-20 12:00:00 -07001409
Adam Langley57707c72016-01-14 11:25:12 -08001410 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001411
Adam Langley57707c72016-01-14 11:25:12 -08001412}
Adam Langley95c29f32014-06-20 12:00:00 -07001413
1414static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
Adam Langley57707c72016-01-14 11:25:12 -08001415{
1416 size_t i;
1417 X509_NAME *nm = X509_CRL_get_issuer(crl);
1418 /* If no CRLissuer return is successful iff don't need a match */
1419 if (!dp->CRLissuer)
1420 return ! !(crl_score & CRL_SCORE_ISSUER_NAME);
1421 for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
1422 GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
1423 if (gen->type != GEN_DIRNAME)
1424 continue;
1425 if (!X509_NAME_cmp(gen->d.directoryName, nm))
1426 return 1;
1427 }
1428 return 0;
1429}
Adam Langley95c29f32014-06-20 12:00:00 -07001430
1431/* Check CRLDP and IDP */
1432
1433static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
Adam Langley57707c72016-01-14 11:25:12 -08001434 unsigned int *preasons)
1435{
1436 size_t i;
1437 if (crl->idp_flags & IDP_ONLYATTR)
1438 return 0;
1439 if (x->ex_flags & EXFLAG_CA) {
1440 if (crl->idp_flags & IDP_ONLYUSER)
1441 return 0;
1442 } else {
1443 if (crl->idp_flags & IDP_ONLYCA)
1444 return 0;
1445 }
1446 *preasons = crl->idp_reasons;
1447 for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
1448 DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
1449 if (crldp_check_crlissuer(dp, crl, crl_score)) {
1450 if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) {
1451 *preasons &= dp->dp_reasons;
1452 return 1;
1453 }
1454 }
1455 }
1456 if ((!crl->idp || !crl->idp->distpoint)
1457 && (crl_score & CRL_SCORE_ISSUER_NAME))
1458 return 1;
1459 return 0;
1460}
Adam Langley95c29f32014-06-20 12:00:00 -07001461
Adam Langley57707c72016-01-14 11:25:12 -08001462/*
1463 * Retrieve CRL corresponding to current certificate. If deltas enabled try
1464 * to find a delta CRL too
Adam Langley95c29f32014-06-20 12:00:00 -07001465 */
Adam Langley57707c72016-01-14 11:25:12 -08001466
Adam Langley95c29f32014-06-20 12:00:00 -07001467static int get_crl_delta(X509_STORE_CTX *ctx,
Adam Langley57707c72016-01-14 11:25:12 -08001468 X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
1469{
1470 int ok;
1471 X509 *issuer = NULL;
1472 int crl_score = 0;
1473 unsigned int reasons;
1474 X509_CRL *crl = NULL, *dcrl = NULL;
1475 STACK_OF(X509_CRL) *skcrl;
1476 X509_NAME *nm = X509_get_issuer_name(x);
1477 reasons = ctx->current_reasons;
1478 ok = get_crl_sk(ctx, &crl, &dcrl,
1479 &issuer, &crl_score, &reasons, ctx->crls);
Adam Langley95c29f32014-06-20 12:00:00 -07001480
Adam Langley57707c72016-01-14 11:25:12 -08001481 if (ok)
1482 goto done;
Adam Langley95c29f32014-06-20 12:00:00 -07001483
Adam Langley57707c72016-01-14 11:25:12 -08001484 /* Lookup CRLs from store */
Adam Langley95c29f32014-06-20 12:00:00 -07001485
Adam Langley57707c72016-01-14 11:25:12 -08001486 skcrl = ctx->lookup_crls(ctx, nm);
Adam Langley95c29f32014-06-20 12:00:00 -07001487
Adam Langley57707c72016-01-14 11:25:12 -08001488 /* If no CRLs found and a near match from get_crl_sk use that */
1489 if (!skcrl && crl)
1490 goto done;
Adam Langley95c29f32014-06-20 12:00:00 -07001491
Adam Langley57707c72016-01-14 11:25:12 -08001492 get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
Adam Langley95c29f32014-06-20 12:00:00 -07001493
Adam Langley57707c72016-01-14 11:25:12 -08001494 sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
Adam Langley95c29f32014-06-20 12:00:00 -07001495
Adam Langley57707c72016-01-14 11:25:12 -08001496 done:
Adam Langley95c29f32014-06-20 12:00:00 -07001497
Adam Langley57707c72016-01-14 11:25:12 -08001498 /* If we got any kind of CRL use it and return success */
1499 if (crl) {
1500 ctx->current_issuer = issuer;
1501 ctx->current_crl_score = crl_score;
1502 ctx->current_reasons = reasons;
1503 *pcrl = crl;
1504 *pdcrl = dcrl;
1505 return 1;
1506 }
Adam Langley95c29f32014-06-20 12:00:00 -07001507
Adam Langley57707c72016-01-14 11:25:12 -08001508 return 0;
1509}
Adam Langley95c29f32014-06-20 12:00:00 -07001510
1511/* Check CRL validity */
1512static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
Adam Langley57707c72016-01-14 11:25:12 -08001513{
1514 X509 *issuer = NULL;
1515 EVP_PKEY *ikey = NULL;
1516 int ok = 0, chnum, cnum;
1517 cnum = ctx->error_depth;
1518 chnum = sk_X509_num(ctx->chain) - 1;
1519 /* if we have an alternative CRL issuer cert use that */
1520 if (ctx->current_issuer)
1521 issuer = ctx->current_issuer;
Adam Langley95c29f32014-06-20 12:00:00 -07001522
Adam Langley57707c72016-01-14 11:25:12 -08001523 /*
1524 * Else find CRL issuer: if not last certificate then issuer is next
1525 * certificate in chain.
1526 */
1527 else if (cnum < chnum)
1528 issuer = sk_X509_value(ctx->chain, cnum + 1);
1529 else {
1530 issuer = sk_X509_value(ctx->chain, chnum);
1531 /* If not self signed, can't check signature */
1532 if (!ctx->check_issued(ctx, issuer, issuer)) {
1533 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
1534 ok = ctx->verify_cb(0, ctx);
1535 if (!ok)
1536 goto err;
1537 }
1538 }
Adam Langley95c29f32014-06-20 12:00:00 -07001539
Adam Langley57707c72016-01-14 11:25:12 -08001540 if (issuer) {
1541 /*
1542 * Skip most tests for deltas because they have already been done
1543 */
1544 if (!crl->base_crl_number) {
1545 /* Check for cRLSign bit if keyUsage present */
1546 if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
1547 !(issuer->ex_kusage & KU_CRL_SIGN)) {
1548 ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
1549 ok = ctx->verify_cb(0, ctx);
1550 if (!ok)
1551 goto err;
1552 }
Adam Langley95c29f32014-06-20 12:00:00 -07001553
Adam Langley57707c72016-01-14 11:25:12 -08001554 if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) {
1555 ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
1556 ok = ctx->verify_cb(0, ctx);
1557 if (!ok)
1558 goto err;
1559 }
Adam Langley95c29f32014-06-20 12:00:00 -07001560
Adam Langley57707c72016-01-14 11:25:12 -08001561 if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) {
1562 if (check_crl_path(ctx, ctx->current_issuer) <= 0) {
1563 ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
1564 ok = ctx->verify_cb(0, ctx);
1565 if (!ok)
1566 goto err;
1567 }
1568 }
Adam Langley95c29f32014-06-20 12:00:00 -07001569
Adam Langley57707c72016-01-14 11:25:12 -08001570 if (crl->idp_flags & IDP_INVALID) {
1571 ctx->error = X509_V_ERR_INVALID_EXTENSION;
1572 ok = ctx->verify_cb(0, ctx);
1573 if (!ok)
1574 goto err;
1575 }
Adam Langley95c29f32014-06-20 12:00:00 -07001576
Adam Langley57707c72016-01-14 11:25:12 -08001577 }
Adam Langley95c29f32014-06-20 12:00:00 -07001578
Adam Langley57707c72016-01-14 11:25:12 -08001579 if (!(ctx->current_crl_score & CRL_SCORE_TIME)) {
1580 ok = check_crl_time(ctx, crl, 1);
1581 if (!ok)
1582 goto err;
1583 }
Adam Langley95c29f32014-06-20 12:00:00 -07001584
Adam Langley57707c72016-01-14 11:25:12 -08001585 /* Attempt to get issuer certificate public key */
1586 ikey = X509_get_pubkey(issuer);
Adam Langley95c29f32014-06-20 12:00:00 -07001587
Adam Langley57707c72016-01-14 11:25:12 -08001588 if (!ikey) {
1589 ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
1590 ok = ctx->verify_cb(0, ctx);
1591 if (!ok)
1592 goto err;
1593 } else {
1594 int rv;
1595 rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags);
1596 if (rv != X509_V_OK) {
1597 ctx->error = rv;
1598 ok = ctx->verify_cb(0, ctx);
1599 if (!ok)
1600 goto err;
1601 }
1602 /* Verify CRL signature */
1603 if (X509_CRL_verify(crl, ikey) <= 0) {
1604 ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
1605 ok = ctx->verify_cb(0, ctx);
1606 if (!ok)
1607 goto err;
1608 }
1609 }
1610 }
Adam Langley95c29f32014-06-20 12:00:00 -07001611
Adam Langley57707c72016-01-14 11:25:12 -08001612 ok = 1;
Adam Langley95c29f32014-06-20 12:00:00 -07001613
Adam Langley57707c72016-01-14 11:25:12 -08001614 err:
1615 EVP_PKEY_free(ikey);
1616 return ok;
1617}
Adam Langley95c29f32014-06-20 12:00:00 -07001618
1619/* Check certificate against CRL */
1620static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
Adam Langley57707c72016-01-14 11:25:12 -08001621{
1622 int ok;
1623 X509_REVOKED *rev;
1624 /*
1625 * The rules changed for this... previously if a CRL contained unhandled
1626 * critical extensions it could still be used to indicate a certificate
1627 * was revoked. This has since been changed since critical extension can
1628 * change the meaning of CRL entries.
1629 */
1630 if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
1631 && (crl->flags & EXFLAG_CRITICAL)) {
1632 ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
1633 ok = ctx->verify_cb(0, ctx);
1634 if (!ok)
1635 return 0;
1636 }
1637 /*
1638 * Look for serial number of certificate in CRL If found make sure reason
1639 * is not removeFromCRL.
1640 */
1641 if (X509_CRL_get0_by_cert(crl, &rev, x)) {
1642 if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
1643 return 2;
1644 ctx->error = X509_V_ERR_CERT_REVOKED;
1645 ok = ctx->verify_cb(0, ctx);
1646 if (!ok)
1647 return 0;
1648 }
Adam Langley95c29f32014-06-20 12:00:00 -07001649
Adam Langley57707c72016-01-14 11:25:12 -08001650 return 1;
1651}
Adam Langley95c29f32014-06-20 12:00:00 -07001652
1653static int check_policy(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08001654{
1655 int ret;
1656 if (ctx->parent)
1657 return 1;
1658 ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
1659 ctx->param->policies, ctx->param->flags);
1660 if (ret == 0) {
1661 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
David Benjamin8f1e1132016-06-07 12:49:36 -04001662 ctx->error = X509_V_ERR_OUT_OF_MEM;
Adam Langley57707c72016-01-14 11:25:12 -08001663 return 0;
1664 }
1665 /* Invalid or inconsistent extensions */
1666 if (ret == -1) {
1667 /*
1668 * Locate certificates with bad extensions and notify callback.
1669 */
1670 X509 *x;
1671 size_t i;
1672 for (i = 1; i < sk_X509_num(ctx->chain); i++) {
1673 x = sk_X509_value(ctx->chain, i);
1674 if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
1675 continue;
1676 ctx->current_cert = x;
1677 ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
1678 if (!ctx->verify_cb(0, ctx))
1679 return 0;
1680 }
1681 return 1;
1682 }
1683 if (ret == -2) {
1684 ctx->current_cert = NULL;
1685 ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
1686 return ctx->verify_cb(0, ctx);
1687 }
Adam Langley95c29f32014-06-20 12:00:00 -07001688
Adam Langley57707c72016-01-14 11:25:12 -08001689 if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
1690 ctx->current_cert = NULL;
David Benjamin8f1e1132016-06-07 12:49:36 -04001691 /*
1692 * Verification errors need to be "sticky", a callback may have allowed
1693 * an SSL handshake to continue despite an error, and we must then
1694 * remain in an error state. Therefore, we MUST NOT clear earlier
1695 * verification errors by setting the error to X509_V_OK.
1696 */
Adam Langley57707c72016-01-14 11:25:12 -08001697 if (!ctx->verify_cb(2, ctx))
1698 return 0;
1699 }
Adam Langley95c29f32014-06-20 12:00:00 -07001700
Adam Langley57707c72016-01-14 11:25:12 -08001701 return 1;
1702}
Adam Langley95c29f32014-06-20 12:00:00 -07001703
1704static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
Adam Langley57707c72016-01-14 11:25:12 -08001705{
1706 time_t *ptime;
1707 int i;
Adam Langley95c29f32014-06-20 12:00:00 -07001708
Adam Langley57707c72016-01-14 11:25:12 -08001709 if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
1710 ptime = &ctx->param->check_time;
1711 else
1712 ptime = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001713
Adam Langley57707c72016-01-14 11:25:12 -08001714 i = X509_cmp_time(X509_get_notBefore(x), ptime);
1715 if (i == 0) {
1716 ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
1717 ctx->current_cert = x;
1718 if (!ctx->verify_cb(0, ctx))
1719 return 0;
1720 }
Adam Langley95c29f32014-06-20 12:00:00 -07001721
Adam Langley57707c72016-01-14 11:25:12 -08001722 if (i > 0) {
1723 ctx->error = X509_V_ERR_CERT_NOT_YET_VALID;
1724 ctx->current_cert = x;
1725 if (!ctx->verify_cb(0, ctx))
1726 return 0;
1727 }
Adam Langley95c29f32014-06-20 12:00:00 -07001728
Adam Langley57707c72016-01-14 11:25:12 -08001729 i = X509_cmp_time(X509_get_notAfter(x), ptime);
1730 if (i == 0) {
1731 ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
1732 ctx->current_cert = x;
1733 if (!ctx->verify_cb(0, ctx))
1734 return 0;
1735 }
Adam Langley95c29f32014-06-20 12:00:00 -07001736
Adam Langley57707c72016-01-14 11:25:12 -08001737 if (i < 0) {
1738 ctx->error = X509_V_ERR_CERT_HAS_EXPIRED;
1739 ctx->current_cert = x;
1740 if (!ctx->verify_cb(0, ctx))
1741 return 0;
1742 }
Adam Langley95c29f32014-06-20 12:00:00 -07001743
Adam Langley57707c72016-01-14 11:25:12 -08001744 return 1;
1745}
Adam Langley95c29f32014-06-20 12:00:00 -07001746
1747static int internal_verify(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08001748{
1749 int ok = 0, n;
1750 X509 *xs, *xi;
1751 EVP_PKEY *pkey = NULL;
1752 int (*cb) (int xok, X509_STORE_CTX *xctx);
Adam Langley95c29f32014-06-20 12:00:00 -07001753
Adam Langley57707c72016-01-14 11:25:12 -08001754 cb = ctx->verify_cb;
Adam Langley95c29f32014-06-20 12:00:00 -07001755
Adam Langley57707c72016-01-14 11:25:12 -08001756 n = sk_X509_num(ctx->chain);
1757 ctx->error_depth = n - 1;
1758 n--;
1759 xi = sk_X509_value(ctx->chain, n);
Adam Langley95c29f32014-06-20 12:00:00 -07001760
Adam Langley57707c72016-01-14 11:25:12 -08001761 if (ctx->check_issued(ctx, xi, xi))
1762 xs = xi;
1763 else {
1764 if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
1765 xs = xi;
1766 goto check_cert;
1767 }
1768 if (n <= 0) {
1769 ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
1770 ctx->current_cert = xi;
1771 ok = cb(0, ctx);
1772 goto end;
1773 } else {
1774 n--;
1775 ctx->error_depth = n;
1776 xs = sk_X509_value(ctx->chain, n);
1777 }
1778 }
Adam Langley95c29f32014-06-20 12:00:00 -07001779
Adam Langley57707c72016-01-14 11:25:12 -08001780/* ctx->error=0; not needed */
1781 while (n >= 0) {
1782 ctx->error_depth = n;
Adam Langley95c29f32014-06-20 12:00:00 -07001783
Adam Langley57707c72016-01-14 11:25:12 -08001784 /*
1785 * Skip signature check for self signed certificates unless
1786 * explicitly asked for. It doesn't add any security and just wastes
1787 * time.
1788 */
David Benjamin00d7a7c2016-07-21 02:21:48 +02001789 if (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)) {
Adam Langley57707c72016-01-14 11:25:12 -08001790 if ((pkey = X509_get_pubkey(xi)) == NULL) {
1791 ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
1792 ctx->current_cert = xi;
1793 ok = (*cb) (0, ctx);
1794 if (!ok)
1795 goto end;
1796 } else if (X509_verify(xs, pkey) <= 0) {
1797 ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
1798 ctx->current_cert = xs;
1799 ok = (*cb) (0, ctx);
1800 if (!ok) {
1801 EVP_PKEY_free(pkey);
1802 goto end;
1803 }
1804 }
1805 EVP_PKEY_free(pkey);
1806 pkey = NULL;
1807 }
Adam Langley95c29f32014-06-20 12:00:00 -07001808
Adam Langley57707c72016-01-14 11:25:12 -08001809 check_cert:
1810 ok = check_cert_time(ctx, xs);
1811 if (!ok)
1812 goto end;
Adam Langley95c29f32014-06-20 12:00:00 -07001813
Adam Langley57707c72016-01-14 11:25:12 -08001814 /* The last error (if any) is still in the error value */
1815 ctx->current_issuer = xi;
1816 ctx->current_cert = xs;
1817 ok = (*cb) (1, ctx);
1818 if (!ok)
1819 goto end;
Adam Langley95c29f32014-06-20 12:00:00 -07001820
Adam Langley57707c72016-01-14 11:25:12 -08001821 n--;
1822 if (n >= 0) {
1823 xi = xs;
1824 xs = sk_X509_value(ctx->chain, n);
1825 }
1826 }
1827 ok = 1;
1828 end:
1829 return ok;
1830}
Adam Langley95c29f32014-06-20 12:00:00 -07001831
1832int X509_cmp_current_time(const ASN1_TIME *ctm)
1833{
Adam Langley57707c72016-01-14 11:25:12 -08001834 return X509_cmp_time(ctm, NULL);
Adam Langley95c29f32014-06-20 12:00:00 -07001835}
1836
1837int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
Adam Langley57707c72016-01-14 11:25:12 -08001838{
1839 char *str;
1840 ASN1_TIME atm;
1841 long offset;
1842 char buff1[24], buff2[24], *p;
1843 int i, j, remaining;
Adam Langley95c29f32014-06-20 12:00:00 -07001844
Adam Langley57707c72016-01-14 11:25:12 -08001845 p = buff1;
1846 remaining = ctm->length;
1847 str = (char *)ctm->data;
1848 /*
1849 * Note that the following (historical) code allows much more slack in
1850 * the time format than RFC5280. In RFC5280, the representation is fixed:
1851 * UTCTime: YYMMDDHHMMSSZ GeneralizedTime: YYYYMMDDHHMMSSZ
1852 */
1853 if (ctm->type == V_ASN1_UTCTIME) {
1854 /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
1855 int min_length = sizeof("YYMMDDHHMMZ") - 1;
1856 int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
1857 if (remaining < min_length || remaining > max_length)
1858 return 0;
David Benjamin17cf2cb2016-12-13 01:07:13 -05001859 OPENSSL_memcpy(p, str, 10);
Adam Langley57707c72016-01-14 11:25:12 -08001860 p += 10;
1861 str += 10;
1862 remaining -= 10;
1863 } else {
1864 /*
1865 * YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm
1866 */
1867 int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
1868 int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
1869 if (remaining < min_length || remaining > max_length)
1870 return 0;
David Benjamin17cf2cb2016-12-13 01:07:13 -05001871 OPENSSL_memcpy(p, str, 12);
Adam Langley57707c72016-01-14 11:25:12 -08001872 p += 12;
1873 str += 12;
1874 remaining -= 12;
1875 }
Adam Langley95c29f32014-06-20 12:00:00 -07001876
Adam Langley57707c72016-01-14 11:25:12 -08001877 if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
1878 *(p++) = '0';
1879 *(p++) = '0';
1880 } else {
1881 /* SS (seconds) */
1882 if (remaining < 2)
1883 return 0;
1884 *(p++) = *(str++);
1885 *(p++) = *(str++);
1886 remaining -= 2;
1887 /*
1888 * Skip any (up to three) fractional seconds... TODO(emilia): in
1889 * RFC5280, fractional seconds are forbidden. Can we just kill them
1890 * altogether?
1891 */
1892 if (remaining && *str == '.') {
1893 str++;
1894 remaining--;
1895 for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
1896 if (*str < '0' || *str > '9')
1897 break;
1898 }
1899 }
Adam Langley95c29f32014-06-20 12:00:00 -07001900
Adam Langley57707c72016-01-14 11:25:12 -08001901 }
1902 *(p++) = 'Z';
1903 *(p++) = '\0';
Adam Langley95c29f32014-06-20 12:00:00 -07001904
Adam Langley57707c72016-01-14 11:25:12 -08001905 /* We now need either a terminating 'Z' or an offset. */
1906 if (!remaining)
1907 return 0;
1908 if (*str == 'Z') {
1909 if (remaining != 1)
1910 return 0;
1911 offset = 0;
1912 } else {
1913 /* (+-)HHMM */
1914 if ((*str != '+') && (*str != '-'))
1915 return 0;
1916 /*
1917 * Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280.
1918 */
1919 if (remaining != 5)
1920 return 0;
1921 if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
1922 str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
1923 return 0;
1924 offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
1925 offset += (str[3] - '0') * 10 + (str[4] - '0');
1926 if (*str == '-')
1927 offset = -offset;
1928 }
1929 atm.type = ctm->type;
1930 atm.flags = 0;
1931 atm.length = sizeof(buff2);
1932 atm.data = (unsigned char *)buff2;
Adam Langley95c29f32014-06-20 12:00:00 -07001933
Adam Langley57707c72016-01-14 11:25:12 -08001934 if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
1935 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001936
Adam Langley57707c72016-01-14 11:25:12 -08001937 if (ctm->type == V_ASN1_UTCTIME) {
1938 i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
1939 if (i < 50)
1940 i += 100; /* cf. RFC 2459 */
1941 j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
1942 if (j < 50)
1943 j += 100;
1944
1945 if (i < j)
1946 return -1;
1947 if (i > j)
1948 return 1;
1949 }
1950 i = strcmp(buff1, buff2);
1951 if (i == 0) /* wait a second then return younger :-) */
1952 return -1;
1953 else
1954 return i;
1955}
Adam Langley95c29f32014-06-20 12:00:00 -07001956
1957ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
1958{
Adam Langley57707c72016-01-14 11:25:12 -08001959 return X509_time_adj(s, adj, NULL);
Adam Langley95c29f32014-06-20 12:00:00 -07001960}
1961
1962ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
Adam Langley57707c72016-01-14 11:25:12 -08001963{
1964 return X509_time_adj_ex(s, 0, offset_sec, in_tm);
1965}
Adam Langley95c29f32014-06-20 12:00:00 -07001966
1967ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
Adam Langley57707c72016-01-14 11:25:12 -08001968 int offset_day, long offset_sec, time_t *in_tm)
1969{
1970 time_t t = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001971
Adam Langley57707c72016-01-14 11:25:12 -08001972 if (in_tm)
1973 t = *in_tm;
1974 else
1975 time(&t);
Adam Langley95c29f32014-06-20 12:00:00 -07001976
Adam Langley57707c72016-01-14 11:25:12 -08001977 if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) {
1978 if (s->type == V_ASN1_UTCTIME)
1979 return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
1980 if (s->type == V_ASN1_GENERALIZEDTIME)
1981 return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
1982 }
1983 return ASN1_TIME_adj(s, t, offset_day, offset_sec);
1984}
Adam Langley95c29f32014-06-20 12:00:00 -07001985
Adam Langley95c29f32014-06-20 12:00:00 -07001986/* Make a delta CRL as the diff between two full CRLs */
1987
1988X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
Adam Langley57707c72016-01-14 11:25:12 -08001989 EVP_PKEY *skey, const EVP_MD *md, unsigned int flags)
1990{
1991 X509_CRL *crl = NULL;
1992 int i;
1993 size_t j;
1994 STACK_OF(X509_REVOKED) *revs = NULL;
1995 /* CRLs can't be delta already */
1996 if (base->base_crl_number || newer->base_crl_number) {
1997 OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA);
1998 return NULL;
1999 }
2000 /* Base and new CRL must have a CRL number */
2001 if (!base->crl_number || !newer->crl_number) {
2002 OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_NUMBER);
2003 return NULL;
2004 }
2005 /* Issuer names must match */
2006 if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) {
2007 OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH);
2008 return NULL;
2009 }
2010 /* AKID and IDP must match */
2011 if (!crl_extension_match(base, newer, NID_authority_key_identifier)) {
2012 OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH);
2013 return NULL;
2014 }
2015 if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) {
2016 OPENSSL_PUT_ERROR(X509, X509_R_IDP_MISMATCH);
2017 return NULL;
2018 }
2019 /* Newer CRL number must exceed full CRL number */
2020 if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) {
2021 OPENSSL_PUT_ERROR(X509, X509_R_NEWER_CRL_NOT_NEWER);
2022 return NULL;
2023 }
2024 /* CRLs must verify */
2025 if (skey && (X509_CRL_verify(base, skey) <= 0 ||
2026 X509_CRL_verify(newer, skey) <= 0)) {
2027 OPENSSL_PUT_ERROR(X509, X509_R_CRL_VERIFY_FAILURE);
2028 return NULL;
2029 }
2030 /* Create new CRL */
2031 crl = X509_CRL_new();
2032 if (!crl || !X509_CRL_set_version(crl, 1))
2033 goto memerr;
2034 /* Set issuer name */
2035 if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer)))
2036 goto memerr;
Adam Langley95c29f32014-06-20 12:00:00 -07002037
Adam Langley57707c72016-01-14 11:25:12 -08002038 if (!X509_CRL_set_lastUpdate(crl, X509_CRL_get_lastUpdate(newer)))
2039 goto memerr;
2040 if (!X509_CRL_set_nextUpdate(crl, X509_CRL_get_nextUpdate(newer)))
2041 goto memerr;
Adam Langley95c29f32014-06-20 12:00:00 -07002042
Adam Langley57707c72016-01-14 11:25:12 -08002043 /* Set base CRL number: must be critical */
Adam Langley95c29f32014-06-20 12:00:00 -07002044
Adam Langley57707c72016-01-14 11:25:12 -08002045 if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0))
2046 goto memerr;
Adam Langley95c29f32014-06-20 12:00:00 -07002047
Adam Langley57707c72016-01-14 11:25:12 -08002048 /*
2049 * Copy extensions across from newest CRL to delta: this will set CRL
2050 * number to correct value too.
2051 */
Adam Langley95c29f32014-06-20 12:00:00 -07002052
Adam Langley57707c72016-01-14 11:25:12 -08002053 for (i = 0; i < X509_CRL_get_ext_count(newer); i++) {
2054 X509_EXTENSION *ext;
2055 ext = X509_CRL_get_ext(newer, i);
2056 if (!X509_CRL_add_ext(crl, ext, -1))
2057 goto memerr;
2058 }
Adam Langley95c29f32014-06-20 12:00:00 -07002059
Adam Langley57707c72016-01-14 11:25:12 -08002060 /* Go through revoked entries, copying as needed */
Adam Langley95c29f32014-06-20 12:00:00 -07002061
Adam Langley57707c72016-01-14 11:25:12 -08002062 revs = X509_CRL_get_REVOKED(newer);
Adam Langley95c29f32014-06-20 12:00:00 -07002063
Adam Langley57707c72016-01-14 11:25:12 -08002064 for (j = 0; j < sk_X509_REVOKED_num(revs); j++) {
2065 X509_REVOKED *rvn, *rvtmp;
2066 rvn = sk_X509_REVOKED_value(revs, j);
2067 /*
2068 * Add only if not also in base. TODO: need something cleverer here
2069 * for some more complex CRLs covering multiple CAs.
2070 */
2071 if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) {
2072 rvtmp = X509_REVOKED_dup(rvn);
2073 if (!rvtmp)
2074 goto memerr;
2075 if (!X509_CRL_add0_revoked(crl, rvtmp)) {
2076 X509_REVOKED_free(rvtmp);
2077 goto memerr;
2078 }
2079 }
2080 }
2081 /* TODO: optionally prune deleted entries */
Adam Langley95c29f32014-06-20 12:00:00 -07002082
Adam Langley57707c72016-01-14 11:25:12 -08002083 if (skey && md && !X509_CRL_sign(crl, skey, md))
2084 goto memerr;
Adam Langley95c29f32014-06-20 12:00:00 -07002085
Adam Langley57707c72016-01-14 11:25:12 -08002086 return crl;
Adam Langley95c29f32014-06-20 12:00:00 -07002087
Adam Langley57707c72016-01-14 11:25:12 -08002088 memerr:
2089 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
2090 if (crl)
2091 X509_CRL_free(crl);
2092 return NULL;
2093}
2094
2095int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
2096 CRYPTO_EX_unused * unused,
David Benjamind94682d2017-05-14 17:10:18 -04002097 CRYPTO_EX_dup *dup_unused,
Adam Langley57707c72016-01-14 11:25:12 -08002098 CRYPTO_EX_free *free_func)
2099{
2100 /*
2101 * This function is (usually) called only once, by
2102 * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c).
2103 */
2104 int index;
2105 if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
David Benjamind94682d2017-05-14 17:10:18 -04002106 free_func)) {
Adam Langley57707c72016-01-14 11:25:12 -08002107 return -1;
2108 }
2109 return index;
2110}
Adam Langley95c29f32014-06-20 12:00:00 -07002111
2112int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
Adam Langley57707c72016-01-14 11:25:12 -08002113{
2114 return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
2115}
Adam Langley95c29f32014-06-20 12:00:00 -07002116
2117void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
Adam Langley57707c72016-01-14 11:25:12 -08002118{
2119 return CRYPTO_get_ex_data(&ctx->ex_data, idx);
2120}
Adam Langley95c29f32014-06-20 12:00:00 -07002121
2122int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08002123{
2124 return ctx->error;
2125}
Adam Langley95c29f32014-06-20 12:00:00 -07002126
2127void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
Adam Langley57707c72016-01-14 11:25:12 -08002128{
2129 ctx->error = err;
2130}
Adam Langley95c29f32014-06-20 12:00:00 -07002131
2132int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08002133{
2134 return ctx->error_depth;
2135}
Adam Langley95c29f32014-06-20 12:00:00 -07002136
2137X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08002138{
2139 return ctx->current_cert;
2140}
Adam Langley95c29f32014-06-20 12:00:00 -07002141
2142STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08002143{
2144 return ctx->chain;
2145}
Adam Langley95c29f32014-06-20 12:00:00 -07002146
2147STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08002148{
2149 if (!ctx->chain)
2150 return NULL;
2151 return X509_chain_up_ref(ctx->chain);
2152}
Adam Langley95c29f32014-06-20 12:00:00 -07002153
2154X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08002155{
2156 return ctx->current_issuer;
2157}
Adam Langley95c29f32014-06-20 12:00:00 -07002158
2159X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08002160{
2161 return ctx->current_crl;
2162}
Adam Langley95c29f32014-06-20 12:00:00 -07002163
2164X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08002165{
2166 return ctx->parent;
2167}
Adam Langley95c29f32014-06-20 12:00:00 -07002168
2169void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
Adam Langley57707c72016-01-14 11:25:12 -08002170{
2171 ctx->cert = x;
2172}
Adam Langley95c29f32014-06-20 12:00:00 -07002173
2174void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
Adam Langley57707c72016-01-14 11:25:12 -08002175{
2176 ctx->untrusted = sk;
2177}
Adam Langley95c29f32014-06-20 12:00:00 -07002178
David Benjamin81f030b2016-08-12 14:48:19 -04002179STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx)
2180{
2181 return ctx->untrusted;
2182}
2183
Adam Langley95c29f32014-06-20 12:00:00 -07002184void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
Adam Langley57707c72016-01-14 11:25:12 -08002185{
2186 ctx->crls = sk;
2187}
Adam Langley95c29f32014-06-20 12:00:00 -07002188
2189int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
Adam Langley57707c72016-01-14 11:25:12 -08002190{
2191 return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
2192}
Adam Langley95c29f32014-06-20 12:00:00 -07002193
2194int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
Adam Langley57707c72016-01-14 11:25:12 -08002195{
2196 return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
2197}
Adam Langley95c29f32014-06-20 12:00:00 -07002198
Adam Langley57707c72016-01-14 11:25:12 -08002199/*
2200 * This function is used to set the X509_STORE_CTX purpose and trust values.
2201 * This is intended to be used when another structure has its own trust and
2202 * purpose values which (if set) will be inherited by the ctx. If they aren't
2203 * set then we will usually have a default purpose in mind which should then
2204 * be used to set the trust value. An example of this is SSL use: an SSL
2205 * structure will have its own purpose and trust settings which the
2206 * application can set: if they aren't set then we use the default of SSL
2207 * client/server.
Adam Langley95c29f32014-06-20 12:00:00 -07002208 */
2209
2210int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
Adam Langley57707c72016-01-14 11:25:12 -08002211 int purpose, int trust)
Adam Langley95c29f32014-06-20 12:00:00 -07002212{
Adam Langley57707c72016-01-14 11:25:12 -08002213 int idx;
2214 /* If purpose not set use default */
2215 if (!purpose)
2216 purpose = def_purpose;
2217 /* If we have a purpose then check it is valid */
2218 if (purpose) {
2219 X509_PURPOSE *ptmp;
2220 idx = X509_PURPOSE_get_by_id(purpose);
2221 if (idx == -1) {
2222 OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
2223 return 0;
2224 }
2225 ptmp = X509_PURPOSE_get0(idx);
2226 if (ptmp->trust == X509_TRUST_DEFAULT) {
2227 idx = X509_PURPOSE_get_by_id(def_purpose);
2228 if (idx == -1) {
2229 OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
2230 return 0;
2231 }
2232 ptmp = X509_PURPOSE_get0(idx);
2233 }
2234 /* If trust not set then get from purpose default */
2235 if (!trust)
2236 trust = ptmp->trust;
2237 }
2238 if (trust) {
2239 idx = X509_TRUST_get_by_id(trust);
2240 if (idx == -1) {
2241 OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID);
2242 return 0;
2243 }
2244 }
Adam Langley95c29f32014-06-20 12:00:00 -07002245
Adam Langley57707c72016-01-14 11:25:12 -08002246 if (purpose && !ctx->param->purpose)
2247 ctx->param->purpose = purpose;
2248 if (trust && !ctx->param->trust)
2249 ctx->param->trust = trust;
2250 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -07002251}
2252
2253X509_STORE_CTX *X509_STORE_CTX_new(void)
2254{
Adam Langley57707c72016-01-14 11:25:12 -08002255 X509_STORE_CTX *ctx;
2256 ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
2257 if (!ctx) {
2258 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
2259 return NULL;
2260 }
David Benjamin4492a612017-08-02 17:16:31 -04002261 X509_STORE_CTX_zero(ctx);
Adam Langley57707c72016-01-14 11:25:12 -08002262 return ctx;
Adam Langley95c29f32014-06-20 12:00:00 -07002263}
2264
David Benjamin4492a612017-08-02 17:16:31 -04002265void X509_STORE_CTX_zero(X509_STORE_CTX *ctx)
2266{
2267 OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
2268}
2269
Adam Langley95c29f32014-06-20 12:00:00 -07002270void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
2271{
Adam Langley3a39b062016-01-14 14:08:58 -08002272 if (ctx == NULL) {
2273 return;
2274 }
Adam Langley57707c72016-01-14 11:25:12 -08002275 X509_STORE_CTX_cleanup(ctx);
2276 OPENSSL_free(ctx);
Adam Langley95c29f32014-06-20 12:00:00 -07002277}
2278
2279int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
Adam Langley57707c72016-01-14 11:25:12 -08002280 STACK_OF(X509) *chain)
2281{
2282 int ret = 1;
Adam Langley69a01602014-11-17 17:26:55 -08002283
David Benjamin4492a612017-08-02 17:16:31 -04002284 X509_STORE_CTX_zero(ctx);
Adam Langley57707c72016-01-14 11:25:12 -08002285 ctx->ctx = store;
2286 ctx->cert = x509;
2287 ctx->untrusted = chain;
Adam Langley69a01602014-11-17 17:26:55 -08002288
Adam Langley57707c72016-01-14 11:25:12 -08002289 CRYPTO_new_ex_data(&ctx->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -07002290
Adam Langley57707c72016-01-14 11:25:12 -08002291 ctx->param = X509_VERIFY_PARAM_new();
2292 if (!ctx->param)
2293 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -07002294
Adam Langley57707c72016-01-14 11:25:12 -08002295 /*
2296 * Inherit callbacks and flags from X509_STORE if not set use defaults.
2297 */
Adam Langley95c29f32014-06-20 12:00:00 -07002298
Adam Langley57707c72016-01-14 11:25:12 -08002299 if (store)
2300 ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
2301 else
2302 ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;
Adam Langley95c29f32014-06-20 12:00:00 -07002303
Adam Langley57707c72016-01-14 11:25:12 -08002304 if (store) {
2305 ctx->verify_cb = store->verify_cb;
2306 ctx->cleanup = store->cleanup;
2307 } else
2308 ctx->cleanup = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07002309
Adam Langley57707c72016-01-14 11:25:12 -08002310 if (ret)
2311 ret = X509_VERIFY_PARAM_inherit(ctx->param,
2312 X509_VERIFY_PARAM_lookup("default"));
Adam Langley95c29f32014-06-20 12:00:00 -07002313
Adam Langley57707c72016-01-14 11:25:12 -08002314 if (ret == 0)
2315 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -07002316
Adam Langley57707c72016-01-14 11:25:12 -08002317 if (store && store->check_issued)
2318 ctx->check_issued = store->check_issued;
2319 else
2320 ctx->check_issued = check_issued;
Adam Langley95c29f32014-06-20 12:00:00 -07002321
Adam Langley57707c72016-01-14 11:25:12 -08002322 if (store && store->get_issuer)
2323 ctx->get_issuer = store->get_issuer;
2324 else
2325 ctx->get_issuer = X509_STORE_CTX_get1_issuer;
Adam Langley95c29f32014-06-20 12:00:00 -07002326
Adam Langley57707c72016-01-14 11:25:12 -08002327 if (store && store->verify_cb)
2328 ctx->verify_cb = store->verify_cb;
2329 else
2330 ctx->verify_cb = null_callback;
Adam Langley95c29f32014-06-20 12:00:00 -07002331
Adam Langley57707c72016-01-14 11:25:12 -08002332 if (store && store->verify)
2333 ctx->verify = store->verify;
2334 else
2335 ctx->verify = internal_verify;
Adam Langley95c29f32014-06-20 12:00:00 -07002336
Adam Langley57707c72016-01-14 11:25:12 -08002337 if (store && store->check_revocation)
2338 ctx->check_revocation = store->check_revocation;
2339 else
2340 ctx->check_revocation = check_revocation;
Adam Langley95c29f32014-06-20 12:00:00 -07002341
Adam Langley57707c72016-01-14 11:25:12 -08002342 if (store && store->get_crl)
2343 ctx->get_crl = store->get_crl;
2344 else
2345 ctx->get_crl = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07002346
Adam Langley57707c72016-01-14 11:25:12 -08002347 if (store && store->check_crl)
2348 ctx->check_crl = store->check_crl;
2349 else
2350 ctx->check_crl = check_crl;
Adam Langley95c29f32014-06-20 12:00:00 -07002351
Adam Langley57707c72016-01-14 11:25:12 -08002352 if (store && store->cert_crl)
2353 ctx->cert_crl = store->cert_crl;
2354 else
2355 ctx->cert_crl = cert_crl;
Adam Langley95c29f32014-06-20 12:00:00 -07002356
Adam Langley57707c72016-01-14 11:25:12 -08002357 if (store && store->lookup_certs)
2358 ctx->lookup_certs = store->lookup_certs;
2359 else
2360 ctx->lookup_certs = X509_STORE_get1_certs;
Adam Langley95c29f32014-06-20 12:00:00 -07002361
Adam Langley57707c72016-01-14 11:25:12 -08002362 if (store && store->lookup_crls)
2363 ctx->lookup_crls = store->lookup_crls;
2364 else
2365 ctx->lookup_crls = X509_STORE_get1_crls;
Adam Langley95c29f32014-06-20 12:00:00 -07002366
Adam Langley57707c72016-01-14 11:25:12 -08002367 ctx->check_policy = check_policy;
Adam Langley95c29f32014-06-20 12:00:00 -07002368
Adam Langley57707c72016-01-14 11:25:12 -08002369 return 1;
Adam Langley69a01602014-11-17 17:26:55 -08002370
Adam Langley57707c72016-01-14 11:25:12 -08002371 err:
2372 CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data);
2373 if (ctx->param != NULL) {
2374 X509_VERIFY_PARAM_free(ctx->param);
2375 }
Adam Langley69a01602014-11-17 17:26:55 -08002376
David Benjamin17cf2cb2016-12-13 01:07:13 -05002377 OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
Adam Langley57707c72016-01-14 11:25:12 -08002378 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
2379 return 0;
2380}
Adam Langley95c29f32014-06-20 12:00:00 -07002381
Adam Langley57707c72016-01-14 11:25:12 -08002382/*
2383 * Set alternative lookup method: just a STACK of trusted certificates. This
2384 * avoids X509_STORE nastiness where it isn't needed.
Adam Langley95c29f32014-06-20 12:00:00 -07002385 */
2386
2387void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
2388{
Adam Langley57707c72016-01-14 11:25:12 -08002389 ctx->other_ctx = sk;
2390 ctx->get_issuer = get_issuer_sk;
Adam Langley95c29f32014-06-20 12:00:00 -07002391}
2392
2393void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08002394{
Adam Langley3a39b062016-01-14 14:08:58 -08002395 /* We need to be idempotent because, unfortunately, |X509_STORE_CTX_free|
2396 * also calls this function. */
2397 if (ctx->cleanup != NULL) {
Adam Langley57707c72016-01-14 11:25:12 -08002398 ctx->cleanup(ctx);
Adam Langley3a39b062016-01-14 14:08:58 -08002399 ctx->cleanup = NULL;
2400 }
Adam Langley57707c72016-01-14 11:25:12 -08002401 if (ctx->param != NULL) {
2402 if (ctx->parent == NULL)
2403 X509_VERIFY_PARAM_free(ctx->param);
2404 ctx->param = NULL;
2405 }
2406 if (ctx->tree != NULL) {
2407 X509_policy_tree_free(ctx->tree);
2408 ctx->tree = NULL;
2409 }
2410 if (ctx->chain != NULL) {
2411 sk_X509_pop_free(ctx->chain, X509_free);
2412 ctx->chain = NULL;
2413 }
2414 CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data));
David Benjamin17cf2cb2016-12-13 01:07:13 -05002415 OPENSSL_memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA));
Adam Langley57707c72016-01-14 11:25:12 -08002416}
Adam Langley95c29f32014-06-20 12:00:00 -07002417
2418void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
Adam Langley57707c72016-01-14 11:25:12 -08002419{
2420 X509_VERIFY_PARAM_set_depth(ctx->param, depth);
2421}
Adam Langley95c29f32014-06-20 12:00:00 -07002422
2423void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
Adam Langley57707c72016-01-14 11:25:12 -08002424{
2425 X509_VERIFY_PARAM_set_flags(ctx->param, flags);
2426}
Adam Langley95c29f32014-06-20 12:00:00 -07002427
Adam Langley57707c72016-01-14 11:25:12 -08002428void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
2429 time_t t)
2430{
2431 X509_VERIFY_PARAM_set_time(ctx->param, t);
2432}
Adam Langley95c29f32014-06-20 12:00:00 -07002433
2434void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
Adam Langley57707c72016-01-14 11:25:12 -08002435 int (*verify_cb) (int, X509_STORE_CTX *))
2436{
2437 ctx->verify_cb = verify_cb;
2438}
Adam Langley95c29f32014-06-20 12:00:00 -07002439
2440X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08002441{
2442 return ctx->tree;
2443}
Adam Langley95c29f32014-06-20 12:00:00 -07002444
2445int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08002446{
2447 return ctx->explicit_policy;
2448}
Adam Langley95c29f32014-06-20 12:00:00 -07002449
2450int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
Adam Langley57707c72016-01-14 11:25:12 -08002451{
2452 const X509_VERIFY_PARAM *param;
2453 param = X509_VERIFY_PARAM_lookup(name);
2454 if (!param)
2455 return 0;
2456 return X509_VERIFY_PARAM_inherit(ctx->param, param);
2457}
Adam Langley95c29f32014-06-20 12:00:00 -07002458
2459X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
Adam Langley57707c72016-01-14 11:25:12 -08002460{
2461 return ctx->param;
2462}
Adam Langley95c29f32014-06-20 12:00:00 -07002463
2464void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
Adam Langley57707c72016-01-14 11:25:12 -08002465{
2466 if (ctx->param)
2467 X509_VERIFY_PARAM_free(ctx->param);
2468 ctx->param = param;
2469}
Adam Langley95c29f32014-06-20 12:00:00 -07002470
2471IMPLEMENT_ASN1_SET_OF(X509)
Adam Langley57707c72016-01-14 11:25:12 -08002472
Adam Langley95c29f32014-06-20 12:00:00 -07002473IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)