1 /* crypto/x509/x509_vfy.c */ 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59 #include <stdio.h> 60 #include <time.h> 61 #include <errno.h> 62 63 #include "cryptlib.h" 64 #include <openssl/crypto.h> 65 #include <openssl/lhash.h> 66 #include <openssl/buffer.h> 67 #include <openssl/evp.h> 68 #include <openssl/asn1.h> 69 #include <openssl/x509.h> 70 #include <openssl/x509v3.h> 71 #include <openssl/objects.h> 72 73 static int null_callback(int ok,X509_STORE_CTX *e); 74 static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); 75 static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); 76 static int check_chain_purpose(X509_STORE_CTX *ctx); 77 static int check_trust(X509_STORE_CTX *ctx); 78 static int internal_verify(X509_STORE_CTX *ctx); 79 const char *X509_version="X.509" OPENSSL_VERSION_PTEXT; 80 81 static STACK_OF(CRYPTO_EX_DATA_FUNCS) *x509_store_ctx_method=NULL; 82 static int x509_store_ctx_num=0; 83 #if 0 84 static int x509_store_num=1; 85 static STACK *x509_store_method=NULL; 86 #endif 87 88 static int null_callback(int ok, X509_STORE_CTX *e) 89 { 90 return ok; 91 } 92 93 #if 0 94 static int x509_subject_cmp(X509 **a, X509 **b) 95 { 96 return X509_subject_name_cmp(*a,*b); 97 } 98 #endif 99 100 int X509_verify_cert(X509_STORE_CTX *ctx) 101 { 102 X509 *x,*xtmp,*chain_ss=NULL; 103 X509_NAME *xn; 104 int depth,i,ok=0; 105 int num; 106 int (*cb)(); 107 STACK_OF(X509) *sktmp=NULL; 108 109 if (ctx->cert == NULL) 110 { 111 X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); 112 return -1; 113 } 114 115 cb=ctx->verify_cb; 116 if (cb == NULL) cb=null_callback; 117 118 /* first we make sure the chain we are going to build is 119 * present and that the first entry is in place */ 120 if (ctx->chain == NULL) 121 { 122 if ( ((ctx->chain=sk_X509_new_null()) == NULL) || 123 (!sk_X509_push(ctx->chain,ctx->cert))) 124 { 125 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); 126 goto end; 127 } 128 CRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509); 129 ctx->last_untrusted=1; 130 } 131 132 /* We use a temporary STACK so we can chop and hack at it */ 133 if (ctx->untrusted != NULL 134 && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL) 135 { 136 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); 137 goto end; 138 } 139 140 num=sk_X509_num(ctx->chain); 141 x=sk_X509_value(ctx->chain,num-1); 142 depth=ctx->depth; 143 144 145 for (;;) 146 { 147 /* If we have enough, we break */ 148 if (depth < num) break; /* FIXME: If this happens, we should take 149 * note of it and, if appropriate, use the 150 * X509_V_ERR_CERT_CHAIN_TOO_LONG error 151 * code later. 152 */ 153 154 /* If we are self signed, we break */ 155 xn=X509_get_issuer_name(x); 156 if (ctx->check_issued(ctx, x,x)) break; 157 158 /* If we were passed a cert chain, use it first */ 159 if (ctx->untrusted != NULL) 160 { 161 xtmp=find_issuer(ctx, sktmp,x); 162 if (xtmp != NULL) 163 { 164 if (!sk_X509_push(ctx->chain,xtmp)) 165 { 166 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); 167 goto end; 168 } 169 CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509); 170 sk_X509_delete_ptr(sktmp,xtmp); 171 ctx->last_untrusted++; 172 x=xtmp; 173 num++; 174 /* reparse the full chain for 175 * the next one */ 176 continue; 177 } 178 } 179 break; 180 } 181 182 /* at this point, chain should contain a list of untrusted 183 * certificates. We now need to add at least one trusted one, 184 * if possible, otherwise we complain. */ 185 186 /* Examine last certificate in chain and see if it 187 * is self signed. 188 */ 189 190 i=sk_X509_num(ctx->chain); 191 x=sk_X509_value(ctx->chain,i-1); 192 xn = X509_get_subject_name(x); 193 if (ctx->check_issued(ctx, x, x)) 194 { 195 /* we have a self signed certificate */ 196 if (sk_X509_num(ctx->chain) == 1) 197 { 198 /* We have a single self signed certificate: see if 199 * we can find it in the store. We must have an exact 200 * match to avoid possible impersonation. 201 */ 202 ok = ctx->get_issuer(&xtmp, ctx, x); 203 if ((ok <= 0) || X509_cmp(x, xtmp)) 204 { 205 ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; 206 ctx->current_cert=x; 207 ctx->error_depth=i-1; 208 if (ok == 1) X509_free(xtmp); 209 ok=cb(0,ctx); 210 if (!ok) goto end; 211 } 212 else 213 { 214 /* We have a match: replace certificate with store version 215 * so we get any trust settings. 216 */ 217 X509_free(x); 218 x = xtmp; 219 sk_X509_set(ctx->chain, i - 1, x); 220 ctx->last_untrusted=0; 221 } 222 } 223 else 224 { 225 /* extract and save self signed certificate for later use */ 226 chain_ss=sk_X509_pop(ctx->chain); 227 ctx->last_untrusted--; 228 num--; 229 x=sk_X509_value(ctx->chain,num-1); 230 } 231 } 232 233 /* We now lookup certs from the certificate store */ 234 for (;;) 235 { 236 /* If we have enough, we break */ 237 if (depth < num) break; 238 239 /* If we are self signed, we break */ 240 xn=X509_get_issuer_name(x); 241 if (ctx->check_issued(ctx,x,x)) break; 242 243 ok = ctx->get_issuer(&xtmp, ctx, x); 244 245 if (ok < 0) return ok; 246 if (ok == 0) break; 247 248 x = xtmp; 249 if (!sk_X509_push(ctx->chain,x)) 250 { 251 X509_free(xtmp); 252 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); 253 return 0; 254 } 255 num++; 256 } 257 258 /* we now have our chain, lets check it... */ 259 xn=X509_get_issuer_name(x); 260 261 /* Is last certificate looked up self signed? */ 262 if (!ctx->check_issued(ctx,x,x)) 263 { 264 if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) 265 { 266 if (ctx->last_untrusted >= num) 267 ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; 268 else 269 ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; 270 ctx->current_cert=x; 271 } 272 else 273 { 274 275 sk_X509_push(ctx->chain,chain_ss); 276 num++; 277 ctx->last_untrusted=num; 278 ctx->current_cert=chain_ss; 279 ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; 280 chain_ss=NULL; 281 } 282 283 ctx->error_depth=num-1; 284 ok=cb(0,ctx); 285 if (!ok) goto end; 286 } 287 288 /* We have the chain complete: now we need to check its purpose */ 289 if (ctx->purpose > 0) ok = check_chain_purpose(ctx); 290 291 if (!ok) goto end; 292 293 /* The chain extensions are OK: check trust */ 294 295 if (ctx->trust > 0) ok = check_trust(ctx); 296 297 if (!ok) goto end; 298 299 /* We may as well copy down any DSA parameters that are required */ 300 X509_get_pubkey_parameters(NULL,ctx->chain); 301 302 /* At this point, we have a chain and just need to verify it */ 303 if (ctx->verify != NULL) 304 ok=ctx->verify(ctx); 305 else 306 ok=internal_verify(ctx); 307 if (0) 308 { 309 end: 310 X509_get_pubkey_parameters(NULL,ctx->chain); 311 } 312 if (sktmp != NULL) sk_X509_free(sktmp); 313 if (chain_ss != NULL) X509_free(chain_ss); 314 return ok; 315 } 316 317 318 /* Given a STACK_OF(X509) find the issuer of cert (if any) 319 */ 320 321 static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) 322 { 323 int i; 324 X509 *issuer; 325 for (i = 0; i < sk_X509_num(sk); i++) 326 { 327 issuer = sk_X509_value(sk, i); 328 if (ctx->check_issued(ctx, x, issuer)) 329 return issuer; 330 } 331 return NULL; 332 } 333 334 /* Given a possible certificate and issuer check them */ 335 336 static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) 337 { 338 int ret; 339 ret = X509_check_issued(issuer, x); 340 if (ret == X509_V_OK) 341 return 1; 342 /* If we haven't asked for issuer errors don't set ctx */ 343 if (!(ctx->flags & X509_V_FLAG_CB_ISSUER_CHECK)) 344 return 0; 345 346 ctx->error = ret; 347 ctx->current_cert = x; 348 ctx->current_issuer = issuer; 349 if (ctx->verify_cb) 350 return ctx->verify_cb(0, ctx); 351 return 0; 352 } 353 354 /* Alternative lookup method: look from a STACK stored in other_ctx */ 355 356 static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) 357 { 358 *issuer = find_issuer(ctx, ctx->other_ctx, x); 359 if (*issuer) 360 { 361 CRYPTO_add(&(*issuer)->references,1,CRYPTO_LOCK_X509); 362 return 1; 363 } 364 else 365 return 0; 366 } 367 368 369 /* Check a certificate chains extensions for consistency 370 * with the supplied purpose 371 */ 372 373 static int check_chain_purpose(X509_STORE_CTX *ctx) 374 { 375 #ifdef NO_CHAIN_VERIFY 376 return 1; 377 #else 378 int i, ok=0; 379 X509 *x; 380 int (*cb)(); 381 cb=ctx->verify_cb; 382 if (cb == NULL) cb=null_callback; 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 (!X509_check_purpose(x, ctx->purpose, i)) 388 { 389 if (i) 390 ctx->error = X509_V_ERR_INVALID_CA; 391 else 392 ctx->error = X509_V_ERR_INVALID_PURPOSE; 393 ctx->error_depth = i; 394 ctx->current_cert = x; 395 ok=cb(0,ctx); 396 if (!ok) goto end; 397 } 398 /* Check pathlen */ 399 if ((i > 1) && (x->ex_pathlen != -1) 400 && (i > (x->ex_pathlen + 1))) 401 { 402 ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; 403 ctx->error_depth = i; 404 ctx->current_cert = x; 405 ok=cb(0,ctx); 406 if (!ok) goto end; 407 } 408 } 409 ok = 1; 410 end: 411 return ok; 412 #endif 413 } 414 415 static int check_trust(X509_STORE_CTX *ctx) 416 { 417 #ifdef NO_CHAIN_VERIFY 418 return 1; 419 #else 420 int i, ok; 421 X509 *x; 422 int (*cb)(); 423 cb=ctx->verify_cb; 424 if (cb == NULL) cb=null_callback; 425 /* For now just check the last certificate in the chain */ 426 i = sk_X509_num(ctx->chain) - 1; 427 x = sk_X509_value(ctx->chain, i); 428 ok = X509_check_trust(x, ctx->trust, 0); 429 if (ok == X509_TRUST_TRUSTED) 430 return 1; 431 ctx->error_depth = sk_X509_num(ctx->chain) - 1; 432 ctx->current_cert = x; 433 if (ok == X509_TRUST_REJECTED) 434 ctx->error = X509_V_ERR_CERT_REJECTED; 435 else 436 ctx->error = X509_V_ERR_CERT_UNTRUSTED; 437 ok = cb(0, ctx); 438 return ok; 439 #endif 440 } 441 442 static int internal_verify(X509_STORE_CTX *ctx) 443 { 444 int i,ok=0,n; 445 X509 *xs,*xi; 446 EVP_PKEY *pkey=NULL; 447 time_t *ptime; 448 int (*cb)(); 449 450 cb=ctx->verify_cb; 451 if (cb == NULL) cb=null_callback; 452 453 n=sk_X509_num(ctx->chain); 454 ctx->error_depth=n-1; 455 n--; 456 xi=sk_X509_value(ctx->chain,n); 457 if (ctx->flags & X509_V_FLAG_USE_CHECK_TIME) 458 ptime = &ctx->check_time; 459 else 460 ptime = NULL; 461 if (ctx->check_issued(ctx, xi, xi)) 462 xs=xi; 463 else 464 { 465 if (n <= 0) 466 { 467 ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; 468 ctx->current_cert=xi; 469 ok=cb(0,ctx); 470 goto end; 471 } 472 else 473 { 474 n--; 475 ctx->error_depth=n; 476 xs=sk_X509_value(ctx->chain,n); 477 } 478 } 479 480 /* ctx->error=0; not needed */ 481 while (n >= 0) 482 { 483 ctx->error_depth=n; 484 if (!xs->valid) 485 { 486 if ((pkey=X509_get_pubkey(xi)) == NULL) 487 { 488 ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; 489 ctx->current_cert=xi; 490 ok=(*cb)(0,ctx); 491 if (!ok) goto end; 492 } 493 if (X509_verify(xs,pkey) <= 0) 494 { 495 ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE; 496 ctx->current_cert=xs; 497 ok=(*cb)(0,ctx); 498 if (!ok) 499 { 500 EVP_PKEY_free(pkey); 501 goto end; 502 } 503 } 504 EVP_PKEY_free(pkey); 505 pkey=NULL; 506 507 i=X509_cmp_time(X509_get_notBefore(xs), ptime); 508 if (i == 0) 509 { 510 ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; 511 ctx->current_cert=xs; 512 ok=(*cb)(0,ctx); 513 if (!ok) goto end; 514 } 515 if (i > 0) 516 { 517 ctx->error=X509_V_ERR_CERT_NOT_YET_VALID; 518 ctx->current_cert=xs; 519 ok=(*cb)(0,ctx); 520 if (!ok) goto end; 521 } 522 xs->valid=1; 523 } 524 525 i=X509_cmp_time(X509_get_notAfter(xs), ptime); 526 if (i == 0) 527 { 528 ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; 529 ctx->current_cert=xs; 530 ok=(*cb)(0,ctx); 531 if (!ok) goto end; 532 } 533 534 if (i < 0) 535 { 536 ctx->error=X509_V_ERR_CERT_HAS_EXPIRED; 537 ctx->current_cert=xs; 538 ok=(*cb)(0,ctx); 539 if (!ok) goto end; 540 } 541 542 /* CRL CHECK */ 543 544 /* The last error (if any) is still in the error value */ 545 ctx->current_cert=xs; 546 ok=(*cb)(1,ctx); 547 if (!ok) goto end; 548 549 n--; 550 if (n >= 0) 551 { 552 xi=xs; 553 xs=sk_X509_value(ctx->chain,n); 554 } 555 } 556 ok=1; 557 end: 558 return ok; 559 } 560 561 int X509_cmp_current_time(ASN1_TIME *ctm) 562 { 563 return X509_cmp_time(ctm, NULL); 564 } 565 566 int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time) 567 { 568 char *str; 569 ASN1_TIME atm; 570 time_t offset; 571 char buff1[24],buff2[24],*p; 572 int i,j; 573 574 p=buff1; 575 i=ctm->length; 576 str=(char *)ctm->data; 577 if (ctm->type == V_ASN1_UTCTIME) 578 { 579 if ((i < 11) || (i > 17)) return 0; 580 memcpy(p,str,10); 581 p+=10; 582 str+=10; 583 } 584 else 585 { 586 if (i < 13) return 0; 587 memcpy(p,str,12); 588 p+=12; 589 str+=12; 590 } 591 592 if ((*str == 'Z') || (*str == '-') || (*str == '+')) 593 { *(p++)='0'; *(p++)='0'; } 594 else 595 { 596 *(p++)= *(str++); 597 *(p++)= *(str++); 598 /* Skip any fractional seconds... */ 599 if (*str == '.') 600 { 601 str++; 602 while ((*str >= '0') && (*str <= '9')) str++; 603 } 604 605 } 606 *(p++)='Z'; 607 *(p++)='\0'; 608 609 if (*str == 'Z') 610 offset=0; 611 else 612 { 613 if ((*str != '+') && (str[5] != '-')) 614 return 0; 615 offset=((str[1]-'0')*10+(str[2]-'0'))*60; 616 offset+=(str[3]-'0')*10+(str[4]-'0'); 617 if (*str == '-') 618 offset= -offset; 619 } 620 atm.type=ctm->type; 621 atm.length=sizeof(buff2); 622 atm.data=(unsigned char *)buff2; 623 624 X509_time_adj(&atm,-offset*60, cmp_time); 625 626 if (ctm->type == V_ASN1_UTCTIME) 627 { 628 i=(buff1[0]-'0')*10+(buff1[1]-'0'); 629 if (i < 50) i+=100; /* cf. RFC 2459 */ 630 j=(buff2[0]-'0')*10+(buff2[1]-'0'); 631 if (j < 50) j+=100; 632 633 if (i < j) return -1; 634 if (i > j) return 1; 635 } 636 i=strcmp(buff1,buff2); 637 if (i == 0) /* wait a second then return younger :-) */ 638 return -1; 639 else 640 return i; 641 } 642 643 ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) 644 { 645 return X509_time_adj(s, adj, NULL); 646 } 647 648 ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *in_tm) 649 { 650 time_t t; 651 652 if (in_tm) t = *in_tm; 653 else time(&t); 654 655 t+=adj; 656 if (!s) return ASN1_TIME_set(s, t); 657 if (s->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_set(s,t); 658 return ASN1_GENERALIZEDTIME_set(s, t); 659 } 660 661 int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) 662 { 663 EVP_PKEY *ktmp=NULL,*ktmp2; 664 int i,j; 665 666 if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) return 1; 667 668 for (i=0; i<sk_X509_num(chain); i++) 669 { 670 ktmp=X509_get_pubkey(sk_X509_value(chain,i)); 671 if (ktmp == NULL) 672 { 673 X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); 674 return 0; 675 } 676 if (!EVP_PKEY_missing_parameters(ktmp)) 677 break; 678 else 679 { 680 EVP_PKEY_free(ktmp); 681 ktmp=NULL; 682 } 683 } 684 if (ktmp == NULL) 685 { 686 X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); 687 return 0; 688 } 689 690 /* first, populate the other certs */ 691 for (j=i-1; j >= 0; j--) 692 { 693 ktmp2=X509_get_pubkey(sk_X509_value(chain,j)); 694 EVP_PKEY_copy_parameters(ktmp2,ktmp); 695 EVP_PKEY_free(ktmp2); 696 } 697 698 if (pkey != NULL) EVP_PKEY_copy_parameters(pkey,ktmp); 699 EVP_PKEY_free(ktmp); 700 return 1; 701 } 702 703 int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 704 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) 705 { 706 x509_store_ctx_num++; 707 return CRYPTO_get_ex_new_index(x509_store_ctx_num-1, 708 &x509_store_ctx_method, 709 argl,argp,new_func,dup_func,free_func); 710 } 711 712 int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) 713 { 714 return CRYPTO_set_ex_data(&ctx->ex_data,idx,data); 715 } 716 717 void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) 718 { 719 return CRYPTO_get_ex_data(&ctx->ex_data,idx); 720 } 721 722 int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) 723 { 724 return ctx->error; 725 } 726 727 void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) 728 { 729 ctx->error=err; 730 } 731 732 int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) 733 { 734 return ctx->error_depth; 735 } 736 737 X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) 738 { 739 return ctx->current_cert; 740 } 741 742 STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) 743 { 744 return ctx->chain; 745 } 746 747 STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) 748 { 749 int i; 750 X509 *x; 751 STACK_OF(X509) *chain; 752 if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain))) return NULL; 753 for (i = 0; i < sk_X509_num(chain); i++) 754 { 755 x = sk_X509_value(chain, i); 756 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); 757 } 758 return chain; 759 } 760 761 void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) 762 { 763 ctx->cert=x; 764 } 765 766 void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) 767 { 768 ctx->untrusted=sk; 769 } 770 771 int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) 772 { 773 return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); 774 } 775 776 int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) 777 { 778 return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); 779 } 780 781 /* This function is used to set the X509_STORE_CTX purpose and trust 782 * values. This is intended to be used when another structure has its 783 * own trust and purpose values which (if set) will be inherited by 784 * the ctx. If they aren't set then we will usually have a default 785 * purpose in mind which should then be used to set the trust value. 786 * An example of this is SSL use: an SSL structure will have its own 787 * purpose and trust settings which the application can set: if they 788 * aren't set then we use the default of SSL client/server. 789 */ 790 791 int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, 792 int purpose, int trust) 793 { 794 int idx; 795 /* If purpose not set use default */ 796 if (!purpose) purpose = def_purpose; 797 /* If we have a purpose then check it is valid */ 798 if (purpose) 799 { 800 X509_PURPOSE *ptmp; 801 idx = X509_PURPOSE_get_by_id(purpose); 802 if (idx == -1) 803 { 804 X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, 805 X509_R_UNKNOWN_PURPOSE_ID); 806 return 0; 807 } 808 ptmp = X509_PURPOSE_get0(idx); 809 if (ptmp->trust == X509_TRUST_DEFAULT) 810 { 811 idx = X509_PURPOSE_get_by_id(def_purpose); 812 if (idx == -1) 813 { 814 X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, 815 X509_R_UNKNOWN_PURPOSE_ID); 816 return 0; 817 } 818 ptmp = X509_PURPOSE_get0(idx); 819 } 820 /* If trust not set then get from purpose default */ 821 if (!trust) trust = ptmp->trust; 822 } 823 if (trust) 824 { 825 idx = X509_TRUST_get_by_id(trust); 826 if (idx == -1) 827 { 828 X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, 829 X509_R_UNKNOWN_TRUST_ID); 830 return 0; 831 } 832 } 833 834 if (purpose) ctx->purpose = purpose; 835 if (trust) ctx->trust = trust; 836 return 1; 837 } 838 839 X509_STORE_CTX *X509_STORE_CTX_new(void) 840 { 841 X509_STORE_CTX *ctx; 842 ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX)); 843 if (ctx) memset(ctx, 0, sizeof(X509_STORE_CTX)); 844 return ctx; 845 } 846 847 void X509_STORE_CTX_free(X509_STORE_CTX *ctx) 848 { 849 X509_STORE_CTX_cleanup(ctx); 850 OPENSSL_free(ctx); 851 } 852 853 void X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, 854 STACK_OF(X509) *chain) 855 { 856 ctx->ctx=store; 857 ctx->current_method=0; 858 ctx->cert=x509; 859 ctx->untrusted=chain; 860 ctx->last_untrusted=0; 861 ctx->purpose=0; 862 ctx->trust=0; 863 ctx->check_time=0; 864 ctx->flags=0; 865 ctx->other_ctx=NULL; 866 ctx->valid=0; 867 ctx->chain=NULL; 868 ctx->depth=9; 869 ctx->error=0; 870 ctx->error_depth=0; 871 ctx->current_cert=NULL; 872 ctx->current_issuer=NULL; 873 ctx->check_issued = check_issued; 874 ctx->get_issuer = X509_STORE_CTX_get1_issuer; 875 ctx->verify_cb = store->verify_cb; 876 ctx->verify = store->verify; 877 ctx->cleanup = 0; 878 memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); 879 } 880 881 /* Set alternative lookup method: just a STACK of trusted certificates. 882 * This avoids X509_STORE nastiness where it isn't needed. 883 */ 884 885 void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) 886 { 887 ctx->other_ctx = sk; 888 ctx->get_issuer = get_issuer_sk; 889 } 890 891 void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) 892 { 893 if (ctx->cleanup) ctx->cleanup(ctx); 894 if (ctx->chain != NULL) 895 { 896 sk_X509_pop_free(ctx->chain,X509_free); 897 ctx->chain=NULL; 898 } 899 CRYPTO_free_ex_data(x509_store_ctx_method,ctx,&(ctx->ex_data)); 900 memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA)); 901 } 902 903 void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, long flags) 904 { 905 ctx->flags |= flags; 906 } 907 908 void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, long flags, time_t t) 909 { 910 ctx->check_time = t; 911 ctx->flags |= X509_V_FLAG_USE_CHECK_TIME; 912 } 913 914 IMPLEMENT_STACK_OF(X509) 915 IMPLEMENT_ASN1_SET_OF(X509) 916 917 IMPLEMENT_STACK_OF(X509_NAME) 918 919 IMPLEMENT_STACK_OF(X509_ATTRIBUTE) 920 IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE) 921