summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509/x509_vfy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/x509/x509_vfy.c')
-rw-r--r--src/lib/libcrypto/x509/x509_vfy.c1067
1 files changed, 775 insertions, 292 deletions
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c
index c1be91edba..db12f7bd35 100644
--- a/src/lib/libcrypto/x509/x509_vfy.c
+++ b/src/lib/libcrypto/x509/x509_vfy.c
@@ -59,76 +59,63 @@
59#include <stdio.h> 59#include <stdio.h>
60#include <time.h> 60#include <time.h>
61#include <errno.h> 61#include <errno.h>
62#include <sys/types.h>
63#include <sys/stat.h>
64 62
65#include "crypto.h"
66#include "cryptlib.h" 63#include "cryptlib.h"
67#include "lhash.h" 64#include <openssl/crypto.h>
68#include "buffer.h" 65#include <openssl/lhash.h>
69#include "evp.h" 66#include <openssl/buffer.h>
70#include "asn1.h" 67#include <openssl/evp.h>
71#include "x509.h" 68#include <openssl/asn1.h>
72#include "objects.h" 69#include <openssl/x509.h>
73#include "pem.h" 70#include <openssl/x509v3.h>
74 71#include <openssl/objects.h>
75#ifndef NOPROTO 72
76static int null_callback(int ok,X509_STORE_CTX *e); 73static int null_callback(int ok,X509_STORE_CTX *e);
74static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
75static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
76static int check_chain_purpose(X509_STORE_CTX *ctx);
77static int check_trust(X509_STORE_CTX *ctx);
78static int check_revocation(X509_STORE_CTX *ctx);
79static int check_cert(X509_STORE_CTX *ctx);
77static int internal_verify(X509_STORE_CTX *ctx); 80static int internal_verify(X509_STORE_CTX *ctx);
78#else 81const char *X509_version="X.509" OPENSSL_VERSION_PTEXT;
79static int null_callback();
80static int internal_verify();
81#endif
82 82
83char *X509_version="X509 part of SSLeay 0.9.0b 29-Jun-1998";
84static STACK *x509_store_ctx_method=NULL;
85static int x509_store_ctx_num=0;
86#if 0
87static int x509_store_num=1;
88static STACK *x509_store_method=NULL;
89#endif
90 83
91static int null_callback(ok,e) 84static int null_callback(int ok, X509_STORE_CTX *e)
92int ok;
93X509_STORE_CTX *e;
94 { 85 {
95 return(ok); 86 return ok;
96 } 87 }
97 88
98#if 0 89#if 0
99static int x509_subject_cmp(a,b) 90static int x509_subject_cmp(X509 **a, X509 **b)
100X509 **a,**b;
101 { 91 {
102 return(X509_subject_name_cmp(*a,*b)); 92 return X509_subject_name_cmp(*a,*b);
103 } 93 }
104#endif 94#endif
105 95
106int X509_verify_cert(ctx) 96int X509_verify_cert(X509_STORE_CTX *ctx)
107X509_STORE_CTX *ctx;
108 { 97 {
109 X509 *x,*xtmp,*chain_ss=NULL; 98 X509 *x,*xtmp,*chain_ss=NULL;
110 X509_NAME *xn; 99 X509_NAME *xn;
111 X509_OBJECT obj;
112 int depth,i,ok=0; 100 int depth,i,ok=0;
113 int num; 101 int num;
114 int (*cb)(); 102 int (*cb)();
115 STACK *sktmp=NULL; 103 STACK_OF(X509) *sktmp=NULL;
116 104
117 if (ctx->cert == NULL) 105 if (ctx->cert == NULL)
118 { 106 {
119 X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); 107 X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
120 return(-1); 108 return -1;
121 } 109 }
122 110
123 cb=ctx->ctx->verify_cb; 111 cb=ctx->verify_cb;
124 if (cb == NULL) cb=null_callback;
125 112
126 /* first we make sure the chain we are going to build is 113 /* first we make sure the chain we are going to build is
127 * present and that the first entry is in place */ 114 * present and that the first entry is in place */
128 if (ctx->chain == NULL) 115 if (ctx->chain == NULL)
129 { 116 {
130 if ( ((ctx->chain=sk_new_null()) == NULL) || 117 if ( ((ctx->chain=sk_X509_new_null()) == NULL) ||
131 (!sk_push(ctx->chain,(char *)ctx->cert))) 118 (!sk_X509_push(ctx->chain,ctx->cert)))
132 { 119 {
133 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); 120 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
134 goto end; 121 goto end;
@@ -137,41 +124,45 @@ X509_STORE_CTX *ctx;
137 ctx->last_untrusted=1; 124 ctx->last_untrusted=1;
138 } 125 }
139 126
140 /* We use a temporary so we can chop and hack at it */ 127 /* We use a temporary STACK so we can chop and hack at it */
141 if ((ctx->untrusted != NULL) && (sktmp=sk_dup(ctx->untrusted)) == NULL) 128 if (ctx->untrusted != NULL
129 && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL)
142 { 130 {
143 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); 131 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
144 goto end; 132 goto end;
145 } 133 }
146 134
147 num=sk_num(ctx->chain); 135 num=sk_X509_num(ctx->chain);
148 x=(X509 *)sk_value(ctx->chain,num-1); 136 x=sk_X509_value(ctx->chain,num-1);
149 depth=ctx->depth; 137 depth=ctx->depth;
150 138
151 139
152 for (;;) 140 for (;;)
153 { 141 {
154 /* If we have enough, we break */ 142 /* If we have enough, we break */
155 if (depth <= num) break; 143 if (depth < num) break; /* FIXME: If this happens, we should take
144 * note of it and, if appropriate, use the
145 * X509_V_ERR_CERT_CHAIN_TOO_LONG error
146 * code later.
147 */
156 148
157 /* If we are self signed, we break */ 149 /* If we are self signed, we break */
158 xn=X509_get_issuer_name(x); 150 xn=X509_get_issuer_name(x);
159 if (X509_NAME_cmp(X509_get_subject_name(x),xn) == 0) 151 if (ctx->check_issued(ctx, x,x)) break;
160 break;
161 152
162 /* If we were passed a cert chain, use it first */ 153 /* If we were passed a cert chain, use it first */
163 if (ctx->untrusted != NULL) 154 if (ctx->untrusted != NULL)
164 { 155 {
165 xtmp=X509_find_by_subject(sktmp,xn); 156 xtmp=find_issuer(ctx, sktmp,x);
166 if (xtmp != NULL) 157 if (xtmp != NULL)
167 { 158 {
168 if (!sk_push(ctx->chain,(char *)xtmp)) 159 if (!sk_X509_push(ctx->chain,xtmp))
169 { 160 {
170 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); 161 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
171 goto end; 162 goto end;
172 } 163 }
173 CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509); 164 CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
174 sk_delete_ptr(sktmp,(char *)xtmp); 165 sk_X509_delete_ptr(sktmp,xtmp);
175 ctx->last_untrusted++; 166 ctx->last_untrusted++;
176 x=xtmp; 167 x=xtmp;
177 num++; 168 num++;
@@ -187,27 +178,50 @@ X509_STORE_CTX *ctx;
187 * certificates. We now need to add at least one trusted one, 178 * certificates. We now need to add at least one trusted one,
188 * if possible, otherwise we complain. */ 179 * if possible, otherwise we complain. */
189 180
190 i=sk_num(ctx->chain); 181 /* Examine last certificate in chain and see if it
191 x=(X509 *)sk_value(ctx->chain,i-1); 182 * is self signed.
192 if (X509_NAME_cmp(X509_get_subject_name(x),X509_get_issuer_name(x)) 183 */
193 == 0) 184
185 i=sk_X509_num(ctx->chain);
186 x=sk_X509_value(ctx->chain,i-1);
187 xn = X509_get_subject_name(x);
188 if (ctx->check_issued(ctx, x, x))
194 { 189 {
195 /* we have a self signed certificate */ 190 /* we have a self signed certificate */
196 if (sk_num(ctx->chain) == 1) 191 if (sk_X509_num(ctx->chain) == 1)
197 { 192 {
198 ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; 193 /* We have a single self signed certificate: see if
199 ctx->current_cert=x; 194 * we can find it in the store. We must have an exact
200 ctx->error_depth=i-1; 195 * match to avoid possible impersonation.
201 ok=cb(0,ctx); 196 */
202 if (!ok) goto end; 197 ok = ctx->get_issuer(&xtmp, ctx, x);
198 if ((ok <= 0) || X509_cmp(x, xtmp))
199 {
200 ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
201 ctx->current_cert=x;
202 ctx->error_depth=i-1;
203 if (ok == 1) X509_free(xtmp);
204 ok=cb(0,ctx);
205 if (!ok) goto end;
206 }
207 else
208 {
209 /* We have a match: replace certificate with store version
210 * so we get any trust settings.
211 */
212 X509_free(x);
213 x = xtmp;
214 sk_X509_set(ctx->chain, i - 1, x);
215 ctx->last_untrusted=0;
216 }
203 } 217 }
204 else 218 else
205 { 219 {
206 /* worry more about this one elsewhere */ 220 /* extract and save self signed certificate for later use */
207 chain_ss=(X509 *)sk_pop(ctx->chain); 221 chain_ss=sk_X509_pop(ctx->chain);
208 ctx->last_untrusted--; 222 ctx->last_untrusted--;
209 num--; 223 num--;
210 x=(X509 *)sk_value(ctx->chain,num-1); 224 x=sk_X509_value(ctx->chain,num-1);
211 } 225 }
212 } 226 }
213 227
@@ -215,45 +229,34 @@ X509_STORE_CTX *ctx;
215 for (;;) 229 for (;;)
216 { 230 {
217 /* If we have enough, we break */ 231 /* If we have enough, we break */
218 if (depth <= num) break; 232 if (depth < num) break;
219 233
220 /* If we are self signed, we break */ 234 /* If we are self signed, we break */
221 xn=X509_get_issuer_name(x); 235 xn=X509_get_issuer_name(x);
222 if (X509_NAME_cmp(X509_get_subject_name(x),xn) == 0) 236 if (ctx->check_issued(ctx,x,x)) break;
223 break;
224 237
225 ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj); 238 ok = ctx->get_issuer(&xtmp, ctx, x);
226 if (ok != X509_LU_X509) 239
227 { 240 if (ok < 0) return ok;
228 if (ok == X509_LU_RETRY) 241 if (ok == 0) break;
229 { 242
230 X509_OBJECT_free_contents(&obj); 243 x = xtmp;
231 X509err(X509_F_X509_VERIFY_CERT,X509_R_SHOULD_RETRY); 244 if (!sk_X509_push(ctx->chain,x))
232 return(ok);
233 }
234 else if (ok != X509_LU_FAIL)
235 {
236 X509_OBJECT_free_contents(&obj);
237 /* not good :-(, break anyway */
238 return(ok);
239 }
240 break;
241 }
242 x=obj.data.x509;
243 if (!sk_push(ctx->chain,(char *)obj.data.x509))
244 { 245 {
245 X509_OBJECT_free_contents(&obj); 246 X509_free(xtmp);
246 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); 247 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
247 return(0); 248 return 0;
248 } 249 }
249 num++; 250 num++;
250 } 251 }
251 252
252 /* we now have our chain, lets check it... */ 253 /* we now have our chain, lets check it... */
253 xn=X509_get_issuer_name(x); 254 xn=X509_get_issuer_name(x);
254 if (X509_NAME_cmp(X509_get_subject_name(x),xn) != 0) 255
256 /* Is last certificate looked up self signed? */
257 if (!ctx->check_issued(ctx,x,x))
255 { 258 {
256 if ((chain_ss == NULL) || (X509_NAME_cmp(X509_get_subject_name(chain_ss),xn) != 0)) 259 if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss))
257 { 260 {
258 if (ctx->last_untrusted >= num) 261 if (ctx->last_untrusted >= num)
259 ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; 262 ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
@@ -264,7 +267,7 @@ X509_STORE_CTX *ctx;
264 else 267 else
265 { 268 {
266 269
267 sk_push(ctx->chain,(char *)chain_ss); 270 sk_X509_push(ctx->chain,chain_ss);
268 num++; 271 num++;
269 ctx->last_untrusted=num; 272 ctx->last_untrusted=num;
270 ctx->current_cert=chain_ss; 273 ctx->current_cert=chain_ss;
@@ -277,37 +280,369 @@ X509_STORE_CTX *ctx;
277 if (!ok) goto end; 280 if (!ok) goto end;
278 } 281 }
279 282
283 /* We have the chain complete: now we need to check its purpose */
284 if (ctx->purpose > 0) ok = check_chain_purpose(ctx);
285
286 if (!ok) goto end;
287
288 /* The chain extensions are OK: check trust */
289
290 if (ctx->trust > 0) ok = check_trust(ctx);
291
292 if (!ok) goto end;
293
280 /* We may as well copy down any DSA parameters that are required */ 294 /* We may as well copy down any DSA parameters that are required */
281 X509_get_pubkey_parameters(NULL,ctx->chain); 295 X509_get_pubkey_parameters(NULL,ctx->chain);
282 296
297 /* Check revocation status: we do this after copying parameters
298 * because they may be needed for CRL signature verification.
299 */
300
301 ok = ctx->check_revocation(ctx);
302 if(!ok) goto end;
303
283 /* At this point, we have a chain and just need to verify it */ 304 /* At this point, we have a chain and just need to verify it */
284 if (ctx->ctx->verify != NULL) 305 if (ctx->verify != NULL)
285 ok=ctx->ctx->verify(ctx); 306 ok=ctx->verify(ctx);
286 else 307 else
287 ok=internal_verify(ctx); 308 ok=internal_verify(ctx);
309 if (0)
310 {
288end: 311end:
289 if (sktmp != NULL) sk_free(sktmp); 312 X509_get_pubkey_parameters(NULL,ctx->chain);
313 }
314 if (sktmp != NULL) sk_X509_free(sktmp);
290 if (chain_ss != NULL) X509_free(chain_ss); 315 if (chain_ss != NULL) X509_free(chain_ss);
291 return(ok); 316 return ok;
317 }
318
319
320/* Given a STACK_OF(X509) find the issuer of cert (if any)
321 */
322
323static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
324{
325 int i;
326 X509 *issuer;
327 for (i = 0; i < sk_X509_num(sk); i++)
328 {
329 issuer = sk_X509_value(sk, i);
330 if (ctx->check_issued(ctx, x, issuer))
331 return issuer;
332 }
333 return NULL;
334}
335
336/* Given a possible certificate and issuer check them */
337
338static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
339{
340 int ret;
341 ret = X509_check_issued(issuer, x);
342 if (ret == X509_V_OK)
343 return 1;
344 /* If we haven't asked for issuer errors don't set ctx */
345 if (!(ctx->flags & X509_V_FLAG_CB_ISSUER_CHECK))
346 return 0;
347
348 ctx->error = ret;
349 ctx->current_cert = x;
350 ctx->current_issuer = issuer;
351 return ctx->verify_cb(0, ctx);
352 return 0;
353}
354
355/* Alternative lookup method: look from a STACK stored in other_ctx */
356
357static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
358{
359 *issuer = find_issuer(ctx, ctx->other_ctx, x);
360 if (*issuer)
361 {
362 CRYPTO_add(&(*issuer)->references,1,CRYPTO_LOCK_X509);
363 return 1;
364 }
365 else
366 return 0;
367}
368
369
370/* Check a certificate chains extensions for consistency
371 * with the supplied purpose
372 */
373
374static int check_chain_purpose(X509_STORE_CTX *ctx)
375{
376#ifdef OPENSSL_NO_CHAIN_VERIFY
377 return 1;
378#else
379 int i, ok=0;
380 X509 *x;
381 int (*cb)();
382 cb=ctx->verify_cb;
383 /* Check all untrusted certificates */
384 for (i = 0; i < ctx->last_untrusted; i++)
385 {
386 x = sk_X509_value(ctx->chain, i);
387 if (!(ctx->flags & X509_V_FLAG_IGNORE_CRITICAL)
388 && (x->ex_flags & EXFLAG_CRITICAL))
389 {
390 ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
391 ctx->error_depth = i;
392 ctx->current_cert = x;
393 ok=cb(0,ctx);
394 if (!ok) goto end;
395 }
396 if (!X509_check_purpose(x, ctx->purpose, i))
397 {
398 if (i)
399 ctx->error = X509_V_ERR_INVALID_CA;
400 else
401 ctx->error = X509_V_ERR_INVALID_PURPOSE;
402 ctx->error_depth = i;
403 ctx->current_cert = x;
404 ok=cb(0,ctx);
405 if (!ok) goto end;
406 }
407 /* Check pathlen */
408 if ((i > 1) && (x->ex_pathlen != -1)
409 && (i > (x->ex_pathlen + 1)))
410 {
411 ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
412 ctx->error_depth = i;
413 ctx->current_cert = x;
414 ok=cb(0,ctx);
415 if (!ok) goto end;
416 }
417 }
418 ok = 1;
419 end:
420 return ok;
421#endif
422}
423
424static int check_trust(X509_STORE_CTX *ctx)
425{
426#ifdef OPENSSL_NO_CHAIN_VERIFY
427 return 1;
428#else
429 int i, ok;
430 X509 *x;
431 int (*cb)();
432 cb=ctx->verify_cb;
433/* For now just check the last certificate in the chain */
434 i = sk_X509_num(ctx->chain) - 1;
435 x = sk_X509_value(ctx->chain, i);
436 ok = X509_check_trust(x, ctx->trust, 0);
437 if (ok == X509_TRUST_TRUSTED)
438 return 1;
439 ctx->error_depth = i;
440 ctx->current_cert = x;
441 if (ok == X509_TRUST_REJECTED)
442 ctx->error = X509_V_ERR_CERT_REJECTED;
443 else
444 ctx->error = X509_V_ERR_CERT_UNTRUSTED;
445 ok = cb(0, ctx);
446 return ok;
447#endif
448}
449
450static int check_revocation(X509_STORE_CTX *ctx)
451 {
452 int i, last, ok;
453 if (!(ctx->flags & X509_V_FLAG_CRL_CHECK))
454 return 1;
455 if (ctx->flags & X509_V_FLAG_CRL_CHECK_ALL)
456 last = 0;
457 else
458 last = sk_X509_num(ctx->chain) - 1;
459 for(i = 0; i <= last; i++)
460 {
461 ctx->error_depth = i;
462 ok = check_cert(ctx);
463 if (!ok) return ok;
464 }
465 return 1;
466 }
467
468static int check_cert(X509_STORE_CTX *ctx)
469 {
470 X509_CRL *crl = NULL;
471 X509 *x;
472 int ok, cnum;
473 cnum = ctx->error_depth;
474 x = sk_X509_value(ctx->chain, cnum);
475 ctx->current_cert = x;
476 /* Try to retrieve relevant CRL */
477 ok = ctx->get_crl(ctx, &crl, x);
478 /* If error looking up CRL, nothing we can do except
479 * notify callback
480 */
481 if(!ok)
482 {
483 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
484 ok = ctx->verify_cb(0, ctx);
485 goto err;
486 }
487 ctx->current_crl = crl;
488 ok = ctx->check_crl(ctx, crl);
489 if (!ok) goto err;
490 ok = ctx->cert_crl(ctx, crl, x);
491 err:
492 ctx->current_crl = NULL;
493 X509_CRL_free(crl);
494 return ok;
495
496 }
497
498/* Retrieve CRL corresponding to certificate: currently just a
499 * subject lookup: maybe use AKID later...
500 * Also might look up any included CRLs too (e.g PKCS#7 signedData).
501 */
502static int get_crl(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x)
503 {
504 int ok;
505 X509_OBJECT xobj;
506 ok = X509_STORE_get_by_subject(ctx, X509_LU_CRL, X509_get_issuer_name(x), &xobj);
507 if (!ok) return 0;
508 *crl = xobj.data.crl;
509 return 1;
510 }
511
512/* Check CRL validity */
513static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
514 {
515 X509 *issuer = NULL;
516 EVP_PKEY *ikey = NULL;
517 int ok = 0, chnum, cnum, i;
518 time_t *ptime;
519 cnum = ctx->error_depth;
520 chnum = sk_X509_num(ctx->chain) - 1;
521 /* Find CRL issuer: if not last certificate then issuer
522 * is next certificate in chain.
523 */
524 if(cnum < chnum)
525 issuer = sk_X509_value(ctx->chain, cnum + 1);
526 else
527 {
528 issuer = sk_X509_value(ctx->chain, chnum);
529 /* If not self signed, can't check signature */
530 if(!ctx->check_issued(ctx, issuer, issuer))
531 {
532 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
533 ok = ctx->verify_cb(0, ctx);
534 if(!ok) goto err;
535 }
536 }
537
538 if(issuer)
539 {
540
541 /* Attempt to get issuer certificate public key */
542 ikey = X509_get_pubkey(issuer);
543
544 if(!ikey)
545 {
546 ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
547 ok = ctx->verify_cb(0, ctx);
548 if (!ok) goto err;
549 }
550 else
551 {
552 /* Verify CRL signature */
553 if(X509_CRL_verify(crl, ikey) <= 0)
554 {
555 ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE;
556 ok = ctx->verify_cb(0, ctx);
557 if (!ok) goto err;
558 }
559 }
560 }
561
562 /* OK, CRL signature valid check times */
563 if (ctx->flags & X509_V_FLAG_USE_CHECK_TIME)
564 ptime = &ctx->check_time;
565 else
566 ptime = NULL;
567
568 i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
569 if (i == 0)
570 {
571 ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
572 ok = ctx->verify_cb(0, ctx);
573 if (!ok) goto err;
574 }
575
576 if (i > 0)
577 {
578 ctx->error=X509_V_ERR_CRL_NOT_YET_VALID;
579 ok = ctx->verify_cb(0, ctx);
580 if (!ok) goto err;
581 }
582
583 if(X509_CRL_get_nextUpdate(crl))
584 {
585 i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
586
587 if (i == 0)
588 {
589 ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
590 ok = ctx->verify_cb(0, ctx);
591 if (!ok) goto err;
592 }
593
594 if (i < 0)
595 {
596 ctx->error=X509_V_ERR_CRL_HAS_EXPIRED;
597 ok = ctx->verify_cb(0, ctx);
598 if (!ok) goto err;
599 }
600 }
601
602 ok = 1;
603
604 err:
605 EVP_PKEY_free(ikey);
606 return ok;
607 }
608
609/* Check certificate against CRL */
610static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
611 {
612 int idx, ok;
613 X509_REVOKED rtmp;
614 /* Look for serial number of certificate in CRL */
615 rtmp.serialNumber = X509_get_serialNumber(x);
616 idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
617 /* Not found: OK */
618 if(idx == -1) return 1;
619 /* Otherwise revoked: want something cleverer than
620 * this to handle entry extensions in V2 CRLs.
621 */
622 ctx->error = X509_V_ERR_CERT_REVOKED;
623 ok = ctx->verify_cb(0, ctx);
624 return ok;
292 } 625 }
293 626
294static int internal_verify(ctx) 627static int internal_verify(X509_STORE_CTX *ctx)
295X509_STORE_CTX *ctx;
296 { 628 {
297 int i,ok=0,n; 629 int i,ok=0,n;
298 X509 *xs,*xi; 630 X509 *xs,*xi;
299 EVP_PKEY *pkey=NULL; 631 EVP_PKEY *pkey=NULL;
632 time_t *ptime;
300 int (*cb)(); 633 int (*cb)();
301 634
302 cb=ctx->ctx->verify_cb; 635 cb=ctx->verify_cb;
303 if (cb == NULL) cb=null_callback;
304 636
305 n=sk_num(ctx->chain); 637 n=sk_X509_num(ctx->chain);
306 ctx->error_depth=n-1; 638 ctx->error_depth=n-1;
307 n--; 639 n--;
308 xi=(X509 *)sk_value(ctx->chain,n); 640 xi=sk_X509_value(ctx->chain,n);
309 if (X509_NAME_cmp(X509_get_subject_name(xi), 641 if (ctx->flags & X509_V_FLAG_USE_CHECK_TIME)
310 X509_get_issuer_name(xi)) == 0) 642 ptime = &ctx->check_time;
643 else
644 ptime = NULL;
645 if (ctx->check_issued(ctx, xi, xi))
311 xs=xi; 646 xs=xi;
312 else 647 else
313 { 648 {
@@ -322,7 +657,7 @@ X509_STORE_CTX *ctx;
322 { 657 {
323 n--; 658 n--;
324 ctx->error_depth=n; 659 ctx->error_depth=n;
325 xs=(X509 *)sk_value(ctx->chain,n); 660 xs=sk_X509_value(ctx->chain,n);
326 } 661 }
327 } 662 }
328 663
@@ -340,15 +675,27 @@ X509_STORE_CTX *ctx;
340 if (!ok) goto end; 675 if (!ok) goto end;
341 } 676 }
342 if (X509_verify(xs,pkey) <= 0) 677 if (X509_verify(xs,pkey) <= 0)
678 /* XXX For the final trusted self-signed cert,
679 * this is a waste of time. That check should
680 * optional so that e.g. 'openssl x509' can be
681 * used to detect invalid self-signatures, but
682 * we don't verify again and again in SSL
683 * handshakes and the like once the cert has
684 * been declared trusted. */
343 { 685 {
344 ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE; 686 ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE;
345 ctx->current_cert=xs; 687 ctx->current_cert=xs;
346 ok=(*cb)(0,ctx); 688 ok=(*cb)(0,ctx);
347 if (!ok) goto end; 689 if (!ok)
690 {
691 EVP_PKEY_free(pkey);
692 goto end;
693 }
348 } 694 }
695 EVP_PKEY_free(pkey);
349 pkey=NULL; 696 pkey=NULL;
350 697
351 i=X509_cmp_current_time(X509_get_notBefore(xs)); 698 i=X509_cmp_time(X509_get_notBefore(xs), ptime);
352 if (i == 0) 699 if (i == 0)
353 { 700 {
354 ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; 701 ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
@@ -366,7 +713,7 @@ X509_STORE_CTX *ctx;
366 xs->valid=1; 713 xs->valid=1;
367 } 714 }
368 715
369 i=X509_cmp_current_time(X509_get_notAfter(xs)); 716 i=X509_cmp_time(X509_get_notAfter(xs), ptime);
370 if (i == 0) 717 if (i == 0)
371 { 718 {
372 ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; 719 ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
@@ -383,8 +730,6 @@ X509_STORE_CTX *ctx;
383 if (!ok) goto end; 730 if (!ok) goto end;
384 } 731 }
385 732
386 /* CRL CHECK */
387
388 /* The last error (if any) is still in the error value */ 733 /* The last error (if any) is still in the error value */
389 ctx->current_cert=xs; 734 ctx->current_cert=xs;
390 ok=(*cb)(1,ctx); 735 ok=(*cb)(1,ctx);
@@ -394,19 +739,23 @@ X509_STORE_CTX *ctx;
394 if (n >= 0) 739 if (n >= 0)
395 { 740 {
396 xi=xs; 741 xi=xs;
397 xs=(X509 *)sk_value(ctx->chain,n); 742 xs=sk_X509_value(ctx->chain,n);
398 } 743 }
399 } 744 }
400 ok=1; 745 ok=1;
401end: 746end:
402 return(ok); 747 return ok;
403 } 748 }
404 749
405int X509_cmp_current_time(ctm) 750int X509_cmp_current_time(ASN1_TIME *ctm)
406ASN1_UTCTIME *ctm; 751{
752 return X509_cmp_time(ctm, NULL);
753}
754
755int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time)
407 { 756 {
408 char *str; 757 char *str;
409 ASN1_UTCTIME atm; 758 ASN1_TIME atm;
410 time_t offset; 759 time_t offset;
411 char buff1[24],buff2[24],*p; 760 char buff1[24],buff2[24],*p;
412 int i,j; 761 int i,j;
@@ -414,14 +763,35 @@ ASN1_UTCTIME *ctm;
414 p=buff1; 763 p=buff1;
415 i=ctm->length; 764 i=ctm->length;
416 str=(char *)ctm->data; 765 str=(char *)ctm->data;
417 if ((i < 11) || (i > 17)) return(0); 766 if (ctm->type == V_ASN1_UTCTIME)
418 memcpy(p,str,10); 767 {
419 p+=10; 768 if ((i < 11) || (i > 17)) return 0;
420 str+=10; 769 memcpy(p,str,10);
770 p+=10;
771 str+=10;
772 }
773 else
774 {
775 if (i < 13) return 0;
776 memcpy(p,str,12);
777 p+=12;
778 str+=12;
779 }
421 780
422 if ((*str == 'Z') || (*str == '-') || (*str == '+')) 781 if ((*str == 'Z') || (*str == '-') || (*str == '+'))
423 { *(p++)='0'; *(p++)='0'; } 782 { *(p++)='0'; *(p++)='0'; }
424 else { *(p++)= *(str++); *(p++)= *(str++); } 783 else
784 {
785 *(p++)= *(str++);
786 *(p++)= *(str++);
787 /* Skip any fractional seconds... */
788 if (*str == '.')
789 {
790 str++;
791 while ((*str >= '0') && (*str <= '9')) str++;
792 }
793
794 }
425 *(p++)='Z'; 795 *(p++)='Z';
426 *(p++)='\0'; 796 *(p++)='\0';
427 797
@@ -430,275 +800,388 @@ ASN1_UTCTIME *ctm;
430 else 800 else
431 { 801 {
432 if ((*str != '+') && (str[5] != '-')) 802 if ((*str != '+') && (str[5] != '-'))
433 return(0); 803 return 0;
434 offset=((str[1]-'0')*10+(str[2]-'0'))*60; 804 offset=((str[1]-'0')*10+(str[2]-'0'))*60;
435 offset+=(str[3]-'0')*10+(str[4]-'0'); 805 offset+=(str[3]-'0')*10+(str[4]-'0');
436 if (*str == '-') 806 if (*str == '-')
437 offset=-offset; 807 offset= -offset;
438 } 808 }
439 atm.type=V_ASN1_UTCTIME; 809 atm.type=ctm->type;
440 atm.length=sizeof(buff2); 810 atm.length=sizeof(buff2);
441 atm.data=(unsigned char *)buff2; 811 atm.data=(unsigned char *)buff2;
442 812
443 X509_gmtime_adj(&atm,-offset); 813 X509_time_adj(&atm,-offset*60, cmp_time);
444 814
445 i=(buff1[0]-'0')*10+(buff1[1]-'0'); 815 if (ctm->type == V_ASN1_UTCTIME)
446 if (i < 70) i+=100; 816 {
447 j=(buff2[0]-'0')*10+(buff2[1]-'0'); 817 i=(buff1[0]-'0')*10+(buff1[1]-'0');
448 if (j < 70) j+=100; 818 if (i < 50) i+=100; /* cf. RFC 2459 */
819 j=(buff2[0]-'0')*10+(buff2[1]-'0');
820 if (j < 50) j+=100;
449 821
450 if (i < j) return (-1); 822 if (i < j) return -1;
451 if (i > j) return (1); 823 if (i > j) return 1;
824 }
452 i=strcmp(buff1,buff2); 825 i=strcmp(buff1,buff2);
453 if (i == 0) /* wait a second then return younger :-) */ 826 if (i == 0) /* wait a second then return younger :-) */
454 return(-1); 827 return -1;
455 else 828 else
456 return(i); 829 return i;
457 } 830 }
458 831
459ASN1_UTCTIME *X509_gmtime_adj(s, adj) 832ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
460ASN1_UTCTIME *s; 833{
461long adj; 834 return X509_time_adj(s, adj, NULL);
835}
836
837ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *in_tm)
462 { 838 {
463 time_t t; 839 time_t t;
840 int type = -1;
841
842 if (in_tm) t = *in_tm;
843 else time(&t);
464 844
465 time(&t);
466 t+=adj; 845 t+=adj;
467 return(ASN1_UTCTIME_set(s,t)); 846 if (s) type = s->type;
847 if (type == V_ASN1_UTCTIME) return ASN1_UTCTIME_set(s,t);
848 if (type == V_ASN1_GENERALIZEDTIME) return ASN1_GENERALIZEDTIME_set(s, t);
849 return ASN1_TIME_set(s, t);
468 } 850 }
469 851
470int X509_get_pubkey_parameters(pkey,chain) 852int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
471EVP_PKEY *pkey;
472STACK *chain;
473 { 853 {
474 EVP_PKEY *ktmp=NULL,*ktmp2; 854 EVP_PKEY *ktmp=NULL,*ktmp2;
475 int i,j; 855 int i,j;
476 856
477 if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) return(1); 857 if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) return 1;
478 858
479 for (i=0; i<sk_num(chain); i++) 859 for (i=0; i<sk_X509_num(chain); i++)
480 { 860 {
481 ktmp=X509_get_pubkey((X509 *)sk_value(chain,i)); 861 ktmp=X509_get_pubkey(sk_X509_value(chain,i));
482 if (ktmp == NULL) 862 if (ktmp == NULL)
483 { 863 {
484 X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); 864 X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
485 return(0); 865 return 0;
486 } 866 }
487 if (!EVP_PKEY_missing_parameters(ktmp)) 867 if (!EVP_PKEY_missing_parameters(ktmp))
488 break; 868 break;
489 else 869 else
490 { 870 {
871 EVP_PKEY_free(ktmp);
491 ktmp=NULL; 872 ktmp=NULL;
492 } 873 }
493 } 874 }
494 if (ktmp == NULL) 875 if (ktmp == NULL)
495 { 876 {
496 X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); 877 X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN);
497 return(0); 878 return 0;
498 } 879 }
499 880
500 /* first, populate the other certs */ 881 /* first, populate the other certs */
501 for (j=i-1; j >= 0; j--) 882 for (j=i-1; j >= 0; j--)
502 { 883 {
503 ktmp2=X509_get_pubkey((X509 *)sk_value(chain,j)); 884 ktmp2=X509_get_pubkey(sk_X509_value(chain,j));
504 EVP_PKEY_copy_parameters(ktmp2,ktmp); 885 EVP_PKEY_copy_parameters(ktmp2,ktmp);
886 EVP_PKEY_free(ktmp2);
505 } 887 }
506 888
507 if (pkey != NULL) 889 if (pkey != NULL) EVP_PKEY_copy_parameters(pkey,ktmp);
508 EVP_PKEY_copy_parameters(pkey,ktmp); 890 EVP_PKEY_free(ktmp);
509 return(1); 891 return 1;
510 } 892 }
511 893
512EVP_PKEY *X509_get_pubkey(x) 894int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
513X509 *x; 895 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
514 { 896 {
515 if ((x == NULL) || (x->cert_info == NULL)) 897 /* This function is (usually) called only once, by
516 return(NULL); 898 * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */
517 return(X509_PUBKEY_get(x->cert_info->key)); 899 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp,
900 new_func, dup_func, free_func);
518 } 901 }
519 902
520int X509_check_private_key(x,k) 903int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
521X509 *x;
522EVP_PKEY *k;
523 { 904 {
524 EVP_PKEY *xk=NULL; 905 return CRYPTO_set_ex_data(&ctx->ex_data,idx,data);
525 int ok=0;
526
527 xk=X509_get_pubkey(x);
528 if (xk->type != k->type) goto err;
529 switch (k->type)
530 {
531#ifndef NO_RSA
532 case EVP_PKEY_RSA:
533 if (BN_cmp(xk->pkey.rsa->n,k->pkey.rsa->n) != 0) goto err;
534 if (BN_cmp(xk->pkey.rsa->e,k->pkey.rsa->e) != 0) goto err;
535 break;
536#endif
537#ifndef NO_DSA
538 case EVP_PKEY_DSA:
539 if (BN_cmp(xk->pkey.dsa->pub_key,k->pkey.dsa->pub_key) != 0)
540 goto err;
541 break;
542#endif
543#ifndef NO_DH
544 case EVP_PKEY_DH:
545 /* No idea */
546 goto err;
547#endif
548 default:
549 goto err;
550 }
551
552 ok=1;
553err:
554 return(ok);
555 } 906 }
556 907
557int X509_STORE_add_cert(ctx,x) 908void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
558X509_STORE *ctx;
559X509 *x;
560 { 909 {
561 X509_OBJECT *obj,*r; 910 return CRYPTO_get_ex_data(&ctx->ex_data,idx);
562 int ret=1; 911 }
563
564 if (x == NULL) return(0);
565 obj=(X509_OBJECT *)Malloc(sizeof(X509_OBJECT));
566 if (obj == NULL)
567 {
568 X509err(X509_F_X509_STORE_ADD_CERT,ERR_R_MALLOC_FAILURE);
569 return(0);
570 }
571 obj->type=X509_LU_X509;
572 obj->data.x509=x;
573
574 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
575 912
576 X509_OBJECT_up_ref_count(obj); 913int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
914 {
915 return ctx->error;
916 }
577 917
578 r=(X509_OBJECT *)lh_insert(ctx->certs,(char *)obj); 918void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
579 if (r != NULL) 919 {
580 { /* oops, put it back */ 920 ctx->error=err;
581 lh_delete(ctx->certs,(char *)obj); 921 }
582 X509_OBJECT_free_contents(obj);
583 Free(obj);
584 lh_insert(ctx->certs,(char *)r);
585 X509err(X509_F_X509_STORE_ADD_CERT,X509_R_CERT_ALREADY_IN_HASH_TABLE);
586 ret=0;
587 }
588 922
589 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 923int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
924 {
925 return ctx->error_depth;
926 }
590 927
591 return(ret); 928X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
929 {
930 return ctx->current_cert;
592 } 931 }
593 932
594int X509_STORE_add_crl(ctx,x) 933STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
595X509_STORE *ctx;
596X509_CRL *x;
597 { 934 {
598 X509_OBJECT *obj,*r; 935 return ctx->chain;
599 int ret=1; 936 }
600 937
601 if (x == NULL) return(0); 938STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
602 obj=(X509_OBJECT *)Malloc(sizeof(X509_OBJECT)); 939 {
603 if (obj == NULL) 940 int i;
941 X509 *x;
942 STACK_OF(X509) *chain;
943 if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain))) return NULL;
944 for (i = 0; i < sk_X509_num(chain); i++)
604 { 945 {
605 X509err(X509_F_X509_STORE_ADD_CRL,ERR_R_MALLOC_FAILURE); 946 x = sk_X509_value(chain, i);
606 return(0); 947 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
607 } 948 }
608 obj->type=X509_LU_CRL; 949 return chain;
609 obj->data.crl=x;
610
611 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
612
613 X509_OBJECT_up_ref_count(obj);
614
615 r=(X509_OBJECT *)lh_insert(ctx->certs,(char *)obj);
616 if (r != NULL)
617 { /* oops, put it back */
618 lh_delete(ctx->certs,(char *)obj);
619 X509_OBJECT_free_contents(obj);
620 Free(obj);
621 lh_insert(ctx->certs,(char *)r);
622 X509err(X509_F_X509_STORE_ADD_CRL,X509_R_CERT_ALREADY_IN_HASH_TABLE);
623 ret=0;
624 }
625
626 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
627
628 return(ret);
629 } 950 }
630 951
631int X509_STORE_CTX_get_ex_new_index(argl,argp,new_func,dup_func,free_func) 952void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
632long argl;
633char *argp;
634int (*new_func)();
635int (*dup_func)();
636void (*free_func)();
637 {
638 x509_store_ctx_num++;
639 return(CRYPTO_get_ex_new_index(x509_store_ctx_num-1,
640 &x509_store_ctx_method,
641 argl,argp,new_func,dup_func,free_func));
642 }
643
644int X509_STORE_CTX_set_ex_data(ctx,idx,data)
645X509_STORE_CTX *ctx;
646int idx;
647char *data;
648 { 953 {
649 return(CRYPTO_set_ex_data(&ctx->ex_data,idx,data)); 954 ctx->cert=x;
650 } 955 }
651 956
652char *X509_STORE_CTX_get_ex_data(ctx,idx) 957void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
653X509_STORE_CTX *ctx;
654int idx;
655 { 958 {
656 return(CRYPTO_get_ex_data(&ctx->ex_data,idx)); 959 ctx->untrusted=sk;
657 } 960 }
658 961
659int X509_STORE_CTX_get_error(ctx) 962int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
660X509_STORE_CTX *ctx;
661 { 963 {
662 return(ctx->error); 964 return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
663 } 965 }
664 966
665void X509_STORE_CTX_set_error(ctx,err) 967int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
666X509_STORE_CTX *ctx;
667int err;
668 { 968 {
669 ctx->error=err; 969 return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
670 } 970 }
671 971
672int X509_STORE_CTX_get_error_depth(ctx) 972/* This function is used to set the X509_STORE_CTX purpose and trust
673X509_STORE_CTX *ctx; 973 * values. This is intended to be used when another structure has its
974 * own trust and purpose values which (if set) will be inherited by
975 * the ctx. If they aren't set then we will usually have a default
976 * purpose in mind which should then be used to set the trust value.
977 * An example of this is SSL use: an SSL structure will have its own
978 * purpose and trust settings which the application can set: if they
979 * aren't set then we use the default of SSL client/server.
980 */
981
982int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
983 int purpose, int trust)
984{
985 int idx;
986 /* If purpose not set use default */
987 if (!purpose) purpose = def_purpose;
988 /* If we have a purpose then check it is valid */
989 if (purpose)
990 {
991 X509_PURPOSE *ptmp;
992 idx = X509_PURPOSE_get_by_id(purpose);
993 if (idx == -1)
994 {
995 X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
996 X509_R_UNKNOWN_PURPOSE_ID);
997 return 0;
998 }
999 ptmp = X509_PURPOSE_get0(idx);
1000 if (ptmp->trust == X509_TRUST_DEFAULT)
1001 {
1002 idx = X509_PURPOSE_get_by_id(def_purpose);
1003 if (idx == -1)
1004 {
1005 X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1006 X509_R_UNKNOWN_PURPOSE_ID);
1007 return 0;
1008 }
1009 ptmp = X509_PURPOSE_get0(idx);
1010 }
1011 /* If trust not set then get from purpose default */
1012 if (!trust) trust = ptmp->trust;
1013 }
1014 if (trust)
1015 {
1016 idx = X509_TRUST_get_by_id(trust);
1017 if (idx == -1)
1018 {
1019 X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1020 X509_R_UNKNOWN_TRUST_ID);
1021 return 0;
1022 }
1023 }
1024
1025 if (purpose && !ctx->purpose) ctx->purpose = purpose;
1026 if (trust && !ctx->trust) ctx->trust = trust;
1027 return 1;
1028}
1029
1030X509_STORE_CTX *X509_STORE_CTX_new(void)
1031{
1032 X509_STORE_CTX *ctx;
1033 ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
1034 if (!ctx)
1035 {
1036 X509err(X509_F_X509_STORE_CTX_NEW,ERR_R_MALLOC_FAILURE);
1037 return NULL;
1038 }
1039 memset(ctx, 0, sizeof(X509_STORE_CTX));
1040 return ctx;
1041}
1042
1043void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
1044{
1045 X509_STORE_CTX_cleanup(ctx);
1046 OPENSSL_free(ctx);
1047}
1048
1049int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
1050 STACK_OF(X509) *chain)
674 { 1051 {
675 return(ctx->error_depth); 1052 ctx->ctx=store;
1053 ctx->current_method=0;
1054 ctx->cert=x509;
1055 ctx->untrusted=chain;
1056 ctx->last_untrusted=0;
1057 ctx->check_time=0;
1058 ctx->other_ctx=NULL;
1059 ctx->valid=0;
1060 ctx->chain=NULL;
1061 ctx->depth=9;
1062 ctx->error=0;
1063 ctx->error_depth=0;
1064 ctx->current_cert=NULL;
1065 ctx->current_issuer=NULL;
1066
1067 /* Inherit callbacks and flags from X509_STORE if not set
1068 * use defaults.
1069 */
1070
1071
1072 if (store)
1073 {
1074 ctx->purpose=store->purpose;
1075 ctx->trust=store->trust;
1076 ctx->flags = store->flags;
1077 ctx->cleanup = store->cleanup;
1078 }
1079 else
1080 {
1081 ctx->purpose = 0;
1082 ctx->trust = 0;
1083 ctx->flags = 0;
1084 ctx->cleanup = 0;
1085 }
1086
1087 if (store && store->check_issued)
1088 ctx->check_issued = store->check_issued;
1089 else
1090 ctx->check_issued = check_issued;
1091
1092 if (store && store->get_issuer)
1093 ctx->get_issuer = store->get_issuer;
1094 else
1095 ctx->get_issuer = X509_STORE_CTX_get1_issuer;
1096
1097 if (store && store->verify_cb)
1098 ctx->verify_cb = store->verify_cb;
1099 else
1100 ctx->verify_cb = null_callback;
1101
1102 if (store && store->verify)
1103 ctx->verify = store->verify;
1104 else
1105 ctx->verify = internal_verify;
1106
1107 if (store && store->check_revocation)
1108 ctx->check_revocation = store->check_revocation;
1109 else
1110 ctx->check_revocation = check_revocation;
1111
1112 if (store && store->get_crl)
1113 ctx->get_crl = store->get_crl;
1114 else
1115 ctx->get_crl = get_crl;
1116
1117 if (store && store->check_crl)
1118 ctx->check_crl = store->check_crl;
1119 else
1120 ctx->check_crl = check_crl;
1121
1122 if (store && store->cert_crl)
1123 ctx->cert_crl = store->cert_crl;
1124 else
1125 ctx->cert_crl = cert_crl;
1126
1127
1128 /* This memset() can't make any sense anyway, so it's removed. As
1129 * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a
1130 * corresponding "new" here and remove this bogus initialisation. */
1131 /* memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); */
1132 if(!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
1133 &(ctx->ex_data)))
1134 {
1135 OPENSSL_free(ctx);
1136 X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE);
1137 return 0;
1138 }
1139 return 1;
676 } 1140 }
677 1141
678X509 *X509_STORE_CTX_get_current_cert(ctx) 1142/* Set alternative lookup method: just a STACK of trusted certificates.
679X509_STORE_CTX *ctx; 1143 * This avoids X509_STORE nastiness where it isn't needed.
1144 */
1145
1146void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
1147{
1148 ctx->other_ctx = sk;
1149 ctx->get_issuer = get_issuer_sk;
1150}
1151
1152void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
680 { 1153 {
681 return(ctx->current_cert); 1154 if (ctx->cleanup) ctx->cleanup(ctx);
1155 if (ctx->chain != NULL)
1156 {
1157 sk_X509_pop_free(ctx->chain,X509_free);
1158 ctx->chain=NULL;
1159 }
1160 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data));
1161 memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA));
682 } 1162 }
683 1163
684STACK *X509_STORE_CTX_get_chain(ctx) 1164void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, long flags)
685X509_STORE_CTX *ctx;
686 { 1165 {
687 return(ctx->chain); 1166 ctx->flags |= flags;
688 } 1167 }
689 1168
690void X509_STORE_CTX_set_cert(ctx,x) 1169void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, long flags, time_t t)
691X509_STORE_CTX *ctx;
692X509 *x;
693 { 1170 {
694 ctx->cert=x; 1171 ctx->check_time = t;
1172 ctx->flags |= X509_V_FLAG_USE_CHECK_TIME;
695 } 1173 }
696 1174
697void X509_STORE_CTX_set_chain(ctx,sk) 1175void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
698X509_STORE_CTX *ctx; 1176 int (*verify_cb)(int, X509_STORE_CTX *))
699STACK *sk;
700 { 1177 {
701 ctx->untrusted=sk; 1178 ctx->verify_cb=verify_cb;
702 } 1179 }
703 1180
1181IMPLEMENT_STACK_OF(X509)
1182IMPLEMENT_ASN1_SET_OF(X509)
1183
1184IMPLEMENT_STACK_OF(X509_NAME)
704 1185
1186IMPLEMENT_STACK_OF(X509_ATTRIBUTE)
1187IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)