diff options
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | apps/crl.c | 24 | ||||
-rw-r--r-- | apps/pkcs12.c | 23 | ||||
-rw-r--r-- | apps/s_server.c | 28 | ||||
-rw-r--r-- | apps/verify.c | 2 | ||||
-rw-r--r-- | apps/x509.c | 13 | ||||
-rw-r--r-- | crypto/cms/cms_smime.c | 19 | ||||
-rw-r--r-- | crypto/include/internal/x509_int.h | 82 | ||||
-rw-r--r-- | crypto/ocsp/ocsp_vfy.c | 82 | ||||
-rw-r--r-- | crypto/pkcs7/pk7_smime.c | 19 | ||||
-rw-r--r-- | crypto/ts/ts_rsp_verify.c | 31 | ||||
-rw-r--r-- | crypto/x509/by_file.c | 1 | ||||
-rw-r--r-- | crypto/x509/x509_err.c | 2 | ||||
-rw-r--r-- | crypto/x509/x509_lcl.h | 65 | ||||
-rw-r--r-- | crypto/x509/x509_lu.c | 33 | ||||
-rw-r--r-- | crypto/x509/x509_vfy.c | 44 | ||||
-rw-r--r-- | doc/crypto/X509_STORE_CTX_get_error.pod | 8 | ||||
-rw-r--r-- | doc/crypto/X509_STORE_CTX_new.pod | 69 | ||||
-rw-r--r-- | doc/crypto/X509_STORE_CTX_set_verify_cb.pod | 12 | ||||
-rw-r--r-- | include/openssl/ossl_typ.h | 6 | ||||
-rw-r--r-- | include/openssl/x509.h | 1 | ||||
-rw-r--r-- | include/openssl/x509_vfy.h | 181 | ||||
-rw-r--r-- | ssl/ssl_cert.c | 95 | ||||
-rw-r--r-- | test/ssltest_old.c | 28 | ||||
-rw-r--r-- | util/libcrypto.num | 18 |
26 files changed, 542 insertions, 353 deletions
@@ -4,6 +4,11 @@ Changes between 1.0.2g and 1.1.0 [xx XXX xxxx] + *) The following datatypes were made opaque: X509_OBJECT, X509_STORE_CTX, + X509_STORE, X509_LOOKUP, and X509_LOOKUP_METHOD. The unused type + X509_CERT_FILE_CTX was removed. + [Rich Salz] + *) "shared" builds are now the default. To create only static libraries use the "no-shared" Configure option. [Matt Caswell] @@ -15,8 +15,8 @@ o Support for extended master secret o CCM ciphersuites o Reworked test suite, now based on perl, Test::Harness and Test::More - o Various libcrypto structures made opaque including: BIGNUM, EVP_MD, - EVP_MD_CTX, HMAC_CTX, EVP_CIPHER and EVP_CIPHER_CTX. + o *Most* libcrypto and libssl structures were made opaque including: + <TBA> o libssl internal structures made opaque o SSLv2 support removed o Kerberos ciphersuite support removed diff --git a/apps/crl.c b/apps/crl.c index c6fc9e6675..915c9ac741 100644 --- a/apps/crl.c +++ b/apps/crl.c @@ -112,9 +112,9 @@ int crl_main(int argc, char **argv) X509_CRL *x = NULL; BIO *out = NULL; X509_STORE *store = NULL; - X509_STORE_CTX ctx; + X509_STORE_CTX *ctx = NULL; X509_LOOKUP *lookup = NULL; - X509_OBJECT xobj; + X509_OBJECT *xobj = NULL; EVP_PKEY *pkey; const EVP_MD *digest = EVP_sha1(); unsigned long nmflag = 0; @@ -243,24 +243,26 @@ int crl_main(int argc, char **argv) lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); if (lookup == NULL) goto end; - if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) { + ctx = X509_STORE_CTX_new(); + if (!X509_STORE_CTX_init(ctx, store, NULL, NULL)) { BIO_printf(bio_err, "Error initialising X509 store\n"); goto end; } - i = X509_STORE_get_by_subject(&ctx, X509_LU_X509, - X509_CRL_get_issuer(x), &xobj); - if (i <= 0) { + xobj = X509_STORE_get_X509_by_subject(ctx, X509_LU_X509, + X509_CRL_get_issuer(x)); + if (xobj == NULL) { BIO_printf(bio_err, "Error getting CRL issuer certificate\n"); goto end; } - pkey = X509_get0_pubkey(xobj.data.x509); - X509_OBJECT_free_contents(&xobj); + pkey = X509_get_pubkey(X509_OBJECT_get0_X509(xobj)); + X509_OBJECT_free(xobj); if (!pkey) { BIO_printf(bio_err, "Error getting CRL issuer public key\n"); goto end; } i = X509_CRL_verify(x, pkey); + EVP_PKEY_free(pkey); if (i < 0) goto end; if (i == 0) @@ -388,9 +390,7 @@ int crl_main(int argc, char **argv) ERR_print_errors(bio_err); BIO_free_all(out); X509_CRL_free(x); - if (store) { - X509_STORE_CTX_cleanup(&ctx); - X509_STORE_free(store); - } + X509_STORE_CTX_free(ctx); + X509_STORE_free(store); return (ret); } diff --git a/apps/pkcs12.c b/apps/pkcs12.c index ff3cb8845b..406b10328a 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -758,21 +758,28 @@ int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, static int get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **chain) { - X509_STORE_CTX store_ctx; + X509_STORE_CTX *store_ctx = NULL; STACK_OF(X509) *chn = NULL; int i = 0; - if (!X509_STORE_CTX_init(&store_ctx, store, cert, NULL)) { - *chain = NULL; - return X509_V_ERR_UNSPECIFIED; + store_ctx = X509_STORE_CTX_new(); + if (store_ctx == NULL) { + i = X509_V_ERR_UNSPECIFIED; + goto end; + } + if (!X509_STORE_CTX_init(store_ctx, store, cert, NULL)) { + i = X509_V_ERR_UNSPECIFIED; + goto end; } - if (X509_verify_cert(&store_ctx) > 0) - chn = X509_STORE_CTX_get1_chain(&store_ctx); - else if ((i = X509_STORE_CTX_get_error(&store_ctx)) == 0) + + if (X509_verify_cert(store_ctx) > 0) + chn = X509_STORE_CTX_get1_chain(store_ctx); + else if ((i = X509_STORE_CTX_get_error(store_ctx)) == 0) i = X509_V_ERR_UNSPECIFIED; - X509_STORE_CTX_cleanup(&store_ctx); +end: + X509_STORE_CTX_free(store_ctx); *chain = chn; return i; } diff --git a/apps/s_server.c b/apps/s_server.c index e0aa2ae4f8..6c8541eec9 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -622,8 +622,8 @@ static int cert_status_cb(SSL *s, void *arg) int rspderlen; STACK_OF(OPENSSL_STRING) *aia = NULL; X509 *x = NULL; - X509_STORE_CTX inctx; - X509_OBJECT obj; + X509_STORE_CTX *inctx = NULL; + X509_OBJECT *obj; OCSP_REQUEST *req = NULL; OCSP_RESPONSE *resp = NULL; OCSP_CERTID *id = NULL; @@ -657,22 +657,24 @@ static int cert_status_cb(SSL *s, void *arg) use_ssl = srctx->use_ssl; } - if (!X509_STORE_CTX_init(&inctx, + inctx = X509_STORE_CTX_new(); + if (inctx == NULL) + goto err; + if (!X509_STORE_CTX_init(inctx, SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)), NULL, NULL)) goto err; - if (X509_STORE_get_by_subject(&inctx, X509_LU_X509, - X509_get_issuer_name(x), &obj) <= 0) { + obj = X509_STORE_get_X509_by_subject(inctx, X509_LU_X509, + X509_get_issuer_name(x)); + if (obj == NULL) { BIO_puts(bio_err, "cert_status: Can't retrieve issuer certificate.\n"); - X509_STORE_CTX_cleanup(&inctx); goto done; } req = OCSP_REQUEST_new(); if (req == NULL) goto err; - id = OCSP_cert_to_id(NULL, x, obj.data.x509); - X509_free(obj.data.x509); - X509_STORE_CTX_cleanup(&inctx); + id = OCSP_cert_to_id(NULL, x, X509_OBJECT_get0_X509(obj)); + X509_OBJECT_free(obj); if (!id) goto err; if (!OCSP_request_add0_id(req, id)) @@ -700,6 +702,10 @@ static int cert_status_cb(SSL *s, void *arg) OCSP_RESPONSE_print(bio_err, resp, 2); } ret = SSL_TLSEXT_ERR_OK; + goto done; + + err: + ret = SSL_TLSEXT_ERR_ALERT_FATAL; done: if (ret != SSL_TLSEXT_ERR_OK) ERR_print_errors(bio_err); @@ -712,10 +718,8 @@ static int cert_status_cb(SSL *s, void *arg) OCSP_CERTID_free(id); OCSP_REQUEST_free(req); OCSP_RESPONSE_free(resp); + X509_STORE_CTX_free(inctx); return ret; - err: - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - goto done; } #endif diff --git a/apps/verify.c b/apps/verify.c index 58a48c7f63..fa517830cf 100644 --- a/apps/verify.c +++ b/apps/verify.c @@ -269,7 +269,7 @@ static int check(X509_STORE *ctx, char *file, goto end; } if (tchain) - X509_STORE_CTX_trusted_stack(csc, tchain); + X509_STORE_CTX_set0_trusted_stack(csc, tchain); if (crls) X509_STORE_CTX_set0_crls(csc, crls); i = X509_verify_cert(csc); diff --git a/apps/x509.c b/apps/x509.c index d8be179d43..6e6ee08ad2 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -987,13 +987,14 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, { int ret = 0; ASN1_INTEGER *bs = NULL; - X509_STORE_CTX xsc; + X509_STORE_CTX *xsc = NULL; EVP_PKEY *upkey; upkey = X509_get0_pubkey(xca); EVP_PKEY_copy_parameters(upkey, pkey); - if (!X509_STORE_CTX_init(&xsc, ctx, x, NULL)) { + xsc = X509_STORE_CTX_new(); + if (xsc == NULL || !X509_STORE_CTX_init(xsc, ctx, x, NULL)) { BIO_printf(bio_err, "Error initialising X509 store\n"); goto end; } @@ -1006,9 +1007,9 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, * NOTE: this certificate can/should be self signed, unless it was a * certificate request in which case it is not. */ - X509_STORE_CTX_set_cert(&xsc, x); - X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE); - if (!reqfile && X509_verify_cert(&xsc) <= 0) + X509_STORE_CTX_set_cert(xsc, x); + X509_STORE_CTX_set_flags(xsc, X509_V_FLAG_CHECK_SS_SIGNATURE); + if (!reqfile && X509_verify_cert(xsc) <= 0) goto end; if (!X509_check_private_key(xca, pkey)) { @@ -1047,7 +1048,7 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, goto end; ret = 1; end: - X509_STORE_CTX_cleanup(&xsc); + X509_STORE_CTX_free(xsc); if (!ret) ERR_print_errors(bio_err); if (!sno) diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c index e84b7e7e5f..98054b36b5 100644 --- a/crypto/cms/cms_smime.c +++ b/crypto/cms/cms_smime.c @@ -273,21 +273,26 @@ static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, STACK_OF(X509) *certs, STACK_OF(X509_CRL) *crls) { - X509_STORE_CTX ctx; + X509_STORE_CTX *ctx = X509_STORE_CTX_new(); X509 *signer; int i, j, r = 0; + + if (ctx == NULL) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + goto err; + } CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); - if (!X509_STORE_CTX_init(&ctx, store, signer, certs)) { + if (!X509_STORE_CTX_init(ctx, store, signer, certs)) { CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, CMS_R_STORE_INIT_ERROR); goto err; } - X509_STORE_CTX_set_default(&ctx, "smime_sign"); + X509_STORE_CTX_set_default(ctx, "smime_sign"); if (crls) - X509_STORE_CTX_set0_crls(&ctx, crls); + X509_STORE_CTX_set0_crls(ctx, crls); - i = X509_verify_cert(&ctx); + i = X509_verify_cert(ctx); if (i <= 0) { - j = X509_STORE_CTX_get_error(&ctx); + j = X509_STORE_CTX_get_error(ctx); CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, CMS_R_CERTIFICATE_VERIFY_ERROR); ERR_add_error_data(2, "Verify error:", @@ -296,7 +301,7 @@ static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, } r = 1; err: - X509_STORE_CTX_cleanup(&ctx); + X509_STORE_CTX_free(ctx); return r; } diff --git a/crypto/include/internal/x509_int.h b/crypto/include/internal/x509_int.h index fc032ae07d..ee49f2aa4a 100644 --- a/crypto/include/internal/x509_int.h +++ b/crypto/include/internal/x509_int.h @@ -217,6 +217,77 @@ struct x509_st { CRYPTO_RWLOCK *lock; } /* X509 */ ; +/* + * This is a used when verifying cert chains. Since the gathering of the + * cert chain can take some time (and have to be 'retried', this needs to be + * kept and passed around. + */ +struct x509_store_ctx_st { /* X509_STORE_CTX */ + X509_STORE *ctx; + /* used when looking up certs */ + int current_method; + /* The following are set by the caller */ + /* The cert to check */ + X509 *cert; + /* chain of X509s - untrusted - passed in */ + STACK_OF(X509) *untrusted; + /* set of CRLs passed in */ + STACK_OF(X509_CRL) *crls; + X509_VERIFY_PARAM *param; + /* Other info for use with get_issuer() */ + void *other_ctx; + /* Callbacks for various operations */ + /* called to verify a certificate */ + int (*verify) (X509_STORE_CTX *ctx); + /* error callback */ + int (*verify_cb) (int ok, X509_STORE_CTX *ctx); + /* get issuers cert from ctx */ + int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + /* check issued */ + int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer); + /* Check revocation status of chain */ + int (*check_revocation) (X509_STORE_CTX *ctx); + /* retrieve CRL */ + int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); + /* Check CRL validity */ + int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl); + /* Check certificate against CRL */ + int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); + int (*check_policy) (X509_STORE_CTX *ctx); + STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup) (X509_STORE_CTX *ctx); + /* The following is built up */ + /* if 0, rebuild chain */ + int valid; + /* number of untrusted certs */ + int num_untrusted; + /* chain of X509s - built up and trusted */ + STACK_OF(X509) *chain; + /* Valid policy tree */ + X509_POLICY_TREE *tree; + /* Require explicit policy value */ + int explicit_policy; + /* When something goes wrong, this is why */ + int error_depth; + int error; + X509 *current_cert; + /* cert currently being tested as valid issuer */ + X509 *current_issuer; + /* current CRL */ + X509_CRL *current_crl; + /* score of current CRL */ + int current_crl_score; + /* Reason mask */ + unsigned int current_reasons; + /* For CRL path validation: parent context */ + X509_STORE_CTX *parent; + CRYPTO_EX_DATA ex_data; + SSL_DANE *dane; + /* signed via bare TA public key, rather than CA certificate */ + int bare_ta_signed; +}; + /* PKCS#8 private key info structure */ struct pkcs8_priv_key_info_st { @@ -230,3 +301,14 @@ struct X509_sig_st { X509_ALGOR *algor; ASN1_OCTET_STRING *digest; }; + +struct x509_object_st { + /* one of the above types */ + X509_LOOKUP_TYPE type; + union { + char *ptr; + X509 *x509; + X509_CRL *crl; + EVP_PKEY *pkey; + } data; +}; diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c index 356c79768f..aba623c798 100644 --- a/crypto/ocsp/ocsp_vfy.c +++ b/crypto/ocsp/ocsp_vfy.c @@ -82,13 +82,18 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509 *signer, *x; STACK_OF(X509) *chain = NULL; STACK_OF(X509) *untrusted = NULL; - X509_STORE_CTX ctx; + X509_STORE_CTX *ctx = NULL; int i, ret = ocsp_find_signer(&signer, bs, certs, flags); if (!ret) { OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); - goto end; + goto err; + } + ctx = X509_STORE_CTX_new(); + if (ctx == NULL) { + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; } if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) flags |= OCSP_NOVERIFY; @@ -99,7 +104,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, ret = OCSP_BASICRESP_verify(bs, skey, 0); if (!skey || ret <= 0) { OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); - goto end; + goto err; } } if (!(flags & OCSP_NOVERIFY)) { @@ -111,30 +116,28 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, for (i = 0; i < sk_X509_num(certs); i++) { if (!sk_X509_push(untrusted, sk_X509_value(certs, i))) { OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE); - goto end; + goto err; } } } else { untrusted = bs->certs; } - init_res = X509_STORE_CTX_init(&ctx, st, signer, untrusted); + init_res = X509_STORE_CTX_init(ctx, st, signer, untrusted); if (!init_res) { - ret = -1; OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB); - goto end; + goto err; } - X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); - ret = X509_verify_cert(&ctx); - chain = X509_STORE_CTX_get1_chain(&ctx); - X509_STORE_CTX_cleanup(&ctx); + X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER); + ret = X509_verify_cert(ctx); + chain = X509_STORE_CTX_get1_chain(ctx); if (ret <= 0) { - i = X509_STORE_CTX_get_error(&ctx); + i = X509_STORE_CTX_get_error(ctx); OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_CERTIFICATE_VERIFY_ERROR); ERR_add_error_data(2, "Verify error:", X509_verify_cert_error_string(i)); - goto end; + goto err; } if (flags & OCSP_NOCHECKS) { ret = 1; @@ -148,7 +151,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, /* If fatal error or valid match then finish */ if (ret != 0) - goto end; + goto err; /* * Easy case: explicitly trusted. Get root CA and check for explicit @@ -160,12 +163,16 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, x = sk_X509_value(chain, sk_X509_num(chain) - 1); if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) { OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_ROOT_CA_NOT_TRUSTED); - goto end; + goto err; } ret = 1; + goto end; } + err: + ret = 0; end: + X509_STORE_CTX_free(ctx); sk_X509_pop_free(chain, X509_free); if (bs->certs && certs) sk_X509_free(untrusted); @@ -367,24 +374,30 @@ int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509 *signer; X509_NAME *nm; GENERAL_NAME *gen; - int ret; - X509_STORE_CTX ctx; + int ret = 0; + X509_STORE_CTX *ctx = X509_STORE_CTX_new(); + + if (ctx == NULL) { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!req->optionalSignature) { OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED); - return 0; + goto err; } gen = req->tbsRequest.requestorName; if (!gen || gen->type != GEN_DIRNAME) { OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE); - return 0; + goto err; } nm = gen->d.directoryName; ret = ocsp_req_find_signer(&signer, req, nm, certs, flags); if (ret <= 0) { OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); - return 0; + goto err; } if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) flags |= OCSP_NOVERIFY; @@ -394,35 +407,42 @@ int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, ret = OCSP_REQUEST_verify(req, skey); if (ret <= 0) { OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE); - return 0; + goto err; } } if (!(flags & OCSP_NOVERIFY)) { int init_res; if (flags & OCSP_NOCHAIN) - init_res = X509_STORE_CTX_init(&ctx, store, signer, NULL); + init_res = X509_STORE_CTX_init(ctx, store, signer, NULL); else - init_res = X509_STORE_CTX_init(&ctx, store, signer, + init_res = X509_STORE_CTX_init(ctx, store, signer, req->optionalSignature->certs); if (!init_res) { OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_X509_LIB); - return 0; + goto err; } - X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); - X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST); - ret = X509_verify_cert(&ctx); - X509_STORE_CTX_cleanup(&ctx); + X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER); + X509_STORE_CTX_set_trust(ctx, X509_TRUST_OCSP_REQUEST); + ret = X509_verify_cert(ctx); if (ret <= 0) { - ret = X509_STORE_CTX_get_error(&ctx); + ret = X509_STORE_CTX_get_error(ctx); OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_CERTIFICATE_VERIFY_ERROR); ERR_add_error_data(2, "Verify error:", X509_verify_cert_error_string(ret)); - return 0; + goto err; } } - return 1; + ret = 1; + goto end; + +err: + ret = 0; +end: + X509_STORE_CTX_free(ctx); + return ret; + } static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c index 8027640de3..b146f68137 100644 --- a/crypto/pkcs7/pk7_smime.c +++ b/crypto/pkcs7/pk7_smime.c @@ -257,7 +257,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, X509 *signer; STACK_OF(PKCS7_SIGNER_INFO) *sinfos; PKCS7_SIGNER_INFO *si; - X509_STORE_CTX cert_ctx; + X509_STORE_CTX *cert_ctx = NULL; char *buf = NULL; int i, j = 0, k, ret = 0; BIO *p7bio = NULL; @@ -306,26 +306,28 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, /* Now verify the certificates */ + cert_ctx = X509_STORE_CTX_new(); + if (cert_ctx == NULL) + goto err; if (!(flags & PKCS7_NOVERIFY)) for (k = 0; k < sk_X509_num(signers); k++) { signer = sk_X509_value(signers, k); if (!(flags & PKCS7_NOCHAIN)) { - if (!X509_STORE_CTX_init(&cert_ctx, store, signer, + if (!X509_STORE_CTX_init(cert_ctx, store, signer, p7->d.sign->cert)) { PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); goto err; } - X509_STORE_CTX_set_default(&cert_ctx, "smime_sign"); - } else if (!X509_STORE_CTX_init(&cert_ctx, store, signer, NULL)) { + X509_STORE_CTX_set_default(cert_ctx, "smime_sign"); + } else if (!X509_STORE_CTX_init(cert_ctx, store, signer, NULL)) { PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); goto err; } if (!(flags & PKCS7_NOCRL)) - X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl); - i = X509_verify_cert(&cert_ctx); + X509_STORE_CTX_set0_crls(cert_ctx, p7->d.sign->crl); + i = X509_verify_cert(cert_ctx); if (i <= 0) - j = X509_STORE_CTX_get_error(&cert_ctx); - X509_STORE_CTX_cleanup(&cert_ctx); + j = X509_STORE_CTX_get_error(cert_ctx); if (i <= 0) { PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CERTIFICATE_VERIFY_ERROR); @@ -404,6 +406,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, ret = 1; err: + X509_STORE_CTX_free(cert_ctx); OPENSSL_free(buf); if (tmpin == indata) { if (indata) diff --git a/crypto/ts/ts_rsp_verify.c b/crypto/ts/ts_rsp_verify.c index e6e213ab12..89b86e1dd3 100644 --- a/crypto/ts/ts_rsp_verify.c +++ b/crypto/ts/ts_rsp_verify.c @@ -211,27 +211,36 @@ int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, X509 *signer, STACK_OF(X509) **chain) { - X509_STORE_CTX cert_ctx; + X509_STORE_CTX *cert_ctx = NULL; int i; - int ret = 1; + int ret = 0; *chain = NULL; - if (!X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted)) - return 0; - X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN); - i = X509_verify_cert(&cert_ctx); + cert_ctx = X509_STORE_CTX_new(); + if (cert_ctx == NULL) { + TSerr(TS_F_TS_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!X509_STORE_CTX_init(cert_ctx, store, signer, untrusted)) + goto end; + X509_STORE_CTX_set_purpose(cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN); + i = X509_verify_cert(cert_ctx); if (i <= 0) { - int j = X509_STORE_CTX_get_error(&cert_ctx); + int j = X509_STORE_CTX_get_error(cert_ctx); TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR); ERR_add_error_data(2, "Verify error:", X509_verify_cert_error_string(j)); - ret = 0; - } else { - *chain = X509_STORE_CTX_get1_chain(&cert_ctx); + goto err; } + *chain = X509_STORE_CTX_get1_chain(cert_ctx); + ret = 1; + goto end; - X509_STORE_CTX_cleanup(&cert_ctx); +err: + ret = 0; +end: + X509_STORE_CTX_free(cert_ctx); return ret; } diff --git a/crypto/x509/by_file.c b/crypto/x509/by_file.c index 51d642dd26..eea7a7ee41 100644 --- a/crypto/x509/by_file.c +++ b/crypto/x509/by_file.c @@ -64,6 +64,7 @@ #include <openssl/buffer.h> #include <openssl/x509.h> #include <openssl/pem.h> +#include "x509_lcl.h" static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c index 90a22de41c..d140d5230d 100644 --- a/crypto/x509/x509_err.c +++ b/crypto/x509/x509_err.c @@ -126,6 +126,8 @@ static ERR_STRING_DATA X509_str_functs[] = { {ERR_FUNC(X509_F_X509_STORE_CTX_NEW), "X509_STORE_CTX_new"}, {ERR_FUNC(X509_F_X509_STORE_CTX_PURPOSE_INHERIT), "X509_STORE_CTX_purpose_inherit"}, + {ERR_FUNC(X509_F_X509_STORE_GET_X509_BY_SUBJECT), + "X509_STORE_get_X509_by_subject"}, {ERR_FUNC(X509_F_X509_TO_X509_REQ), "X509_to_X509_REQ"}, {ERR_FUNC(X509_F_X509_TRUST_ADD), "X509_TRUST_add"}, {ERR_FUNC(X509_F_X509_TRUST_SET), "X509_TRUST_set"}, diff --git a/crypto/x509/x509_lcl.h b/crypto/x509/x509_lcl.h index 603c17737f..db98a105aa 100644 --- a/crypto/x509/x509_lcl.h +++ b/crypto/x509/x509_lcl.h @@ -115,6 +115,71 @@ struct x509_crl_method_st { int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk); }; +struct x509_lookup_method_st { + const char *name; + int (*new_item) (X509_LOOKUP *ctx); + void (*free) (X509_LOOKUP *ctx); + int (*init) (X509_LOOKUP *ctx); + int (*shutdown) (X509_LOOKUP *ctx); + int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret); + int (*get_by_subject) (X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); + int (*get_by_issuer_serial) (X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret); + int (*get_by_fingerprint) (X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, + X509_OBJECT *ret); + int (*get_by_alias) (X509_LOOKUP *ctx, int type, char *str, int len, + X509_OBJECT *ret); +}; + +/* This is the functions plus an instance of the local variables. */ +struct x509_lookup_st { + int init; /* have we been started */ + int skip; /* don't use us. */ + X509_LOOKUP_METHOD *method; /* the functions */ + char *method_data; /* method data */ + X509_STORE *store_ctx; /* who owns us */ +}; + +/* + * This is used to hold everything. It is used for all certificate + * validation. Once we have a certificate chain, the 'verify' function is + * then called to actually check the cert chain. + */ +struct x509_store_st { + /* The following is a cache of trusted certs */ + int cache; /* if true, stash any hits */ + STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */ + /* These are external lookup methods */ + STACK_OF(X509_LOOKUP) *get_cert_methods; + X509_VERIFY_PARAM *param; + /* Callbacks for various operations */ + /* called to verify a certificate */ + int (*verify) (X509_STORE_CTX *ctx); + /* error callback */ + int (*verify_cb) (int ok, X509_STORE_CTX *ctx); + /* get issuers cert from ctx */ + int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + /* check issued */ + int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer); + /* Check revocation status of chain */ + int (*check_revocation) (X509_STORE_CTX *ctx); + /* retrieve CRL */ + int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); + /* Check CRL validity */ + int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl); + /* Check certificate against CRL */ + int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); + STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup) (X509_STORE_CTX *ctx); + CRYPTO_EX_DATA ex_data; + int references; + CRYPTO_RWLOCK *lock; +}; + typedef struct lookup_dir_hashes_st BY_DIR_HASH; typedef struct lookup_dir_entry_st BY_DIR_ENTRY; DEFINE_STACK_OF(BY_DIR_HASH) diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index f9802c5a80..b822966203 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -294,6 +294,23 @@ X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) } } +X509_OBJECT *X509_STORE_get_X509_by_subject(X509_STORE_CTX *vs, int type, + X509_NAME *name) +{ + X509_OBJECT *ret; + + ret = OPENSSL_malloc(sizeof (*ret)); + if (ret == NULL) { + X509err(X509_F_X509_STORE_GET_X509_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!X509_STORE_get_by_subject(vs, type, name, ret)) { + OPENSSL_free(ret); + return NULL; + } + return ret; +} + int X509_STORE_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, X509_NAME *name, X509_OBJECT *ret) { @@ -414,9 +431,22 @@ void X509_OBJECT_up_ref_count(X509_OBJECT *a) } } +X509 *X509_OBJECT_get0_X509(X509_OBJECT *a) +{ + return a->data.x509; +} + +void X509_OBJECT_free(X509_OBJECT *a) +{ + if (a == NULL) + return; + X509_OBJECT_free_contents(a); + OPENSSL_free(a); +} + void X509_OBJECT_free_contents(X509_OBJECT *a) { - if (!a) + if (a == NULL) return; switch (a->type) { default: @@ -613,6 +643,7 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) X509_NAME *xn; X509_OBJECT obj, *pobj; int i, ok, idx, ret; + *issuer = NULL; xn = X509_get_issuer_name(x); ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj); diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 2c3efdd4b0..312b112f50 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -1994,7 +1994,7 @@ X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) return ctx->current_cert; } -STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) +STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx) { return ctx->chain; } @@ -2026,11 +2026,6 @@ void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) ctx->cert = x; } -void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) -{ - ctx->untrusted = sk; -} - void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) { ctx->crls = sk; @@ -2278,8 +2273,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, * Set alternative lookup method: just a STACK of trusted certificates. This * avoids X509_STORE nastiness where it isn't needed. */ - -void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) { ctx->other_ctx = sk; ctx->get_issuer = get_issuer_sk; @@ -2329,11 +2323,43 @@ void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, } void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, - int (*verify_cb) (int, X509_STORE_CTX *)) + X509_STORE_CTX_verify_cb verify_cb) { ctx->verify_cb = verify_cb; } +X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx) +{ + return ctx->verify_cb; +} + +X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx) +{ + return ctx->cert; +} + +STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx) +{ + return ctx->untrusted; +} + +void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +{ + sk_X509_pop_free(ctx->chain, X509_free); + ctx->chain = sk; +} + +void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, + X509_STORE_CTX_verify verify) +{ + ctx->verify = verify; +} + +X509_STORE_CTX_verify X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx) +{ + return ctx->verify; +} + X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) { return ctx->tree; diff --git a/doc/crypto/X509_STORE_CTX_get_error.pod b/doc/crypto/X509_STORE_CTX_get_error.pod index 75be45374e..1cc6bb5e8f 100644 --- a/doc/crypto/X509_STORE_CTX_get_error.pod +++ b/doc/crypto/X509_STORE_CTX_get_error.pod @@ -2,7 +2,10 @@ =head1 NAME -X509_STORE_CTX_get_error, X509_STORE_CTX_set_error, X509_STORE_CTX_get_error_depth, X509_STORE_CTX_get_current_cert, X509_STORE_CTX_get1_chain, X509_verify_cert_error_string - get or set certificate verification status information +X509_STORE_CTX_get_error, X509_STORE_CTX_set_error, +X509_STORE_CTX_get_error_depth, X509_STORE_CTX_get_current_cert, +X509_STORE_CTX_get0_cert, +X509_STORE_CTX_get1_chain, X509_verify_cert_error_string - get or set certificate verification status information =head1 SYNOPSIS @@ -13,6 +16,7 @@ X509_STORE_CTX_get_error, X509_STORE_CTX_set_error, X509_STORE_CTX_get_error_dep void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s); int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); + X509 * X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); @@ -35,6 +39,8 @@ non-negative integer representing where in the certificate chain the error occurred. If it is zero it occurred in the end entity certificate, one if it is the certificate which signed the end entity certificate and so on. +X509_STORE_CTX_get0_cert() returns the leaf certificate being verified. + X509_STORE_CTX_get_current_cert() returns the certificate in B<ctx> which caused the error or B<NULL> if no certificate is relevant. diff --git a/doc/crypto/X509_STORE_CTX_new.pod b/doc/crypto/X509_STORE_CTX_new.pod index 1f3ded6d29..69ff7c4538 100644 --- a/doc/crypto/X509_STORE_CTX_new.pod +++ b/doc/crypto/X509_STORE_CTX_new.pod @@ -2,7 +2,18 @@ =head1 NAME -X509_STORE_CTX_new, X509_STORE_CTX_cleanup, X509_STORE_CTX_free, X509_STORE_CTX_init, X509_STORE_CTX_trusted_stack, X509_STORE_CTX_set_cert, X509_STORE_CTX_set_chain, X509_STORE_CTX_set0_crls, X509_STORE_CTX_get0_param, X509_STORE_CTX_set0_param, X509_STORE_CTX_set_default - X509_STORE_CTX initialisation +X509_STORE_CTX_new, X509_STORE_CTX_cleanup, X509_STORE_CTX_free, +X509_STORE_CTX_init, X509_STORE_CTX_set0_trusted_stack, X509_STORE_CTX_set_cert, +X509_STORE_CTX_set0_crls, +X509_STORE_CTX_get0_chain, X509_STORE_CTX_set0_verified_chain, +X509_STORE_CTX_get0_param, X509_STORE_CTX_set0_param, +X509_STORE_CTX_get0_cert, +X509_STORE_CTX_get0_untrusted, +X509_STORE_CTX_get_num_untrusted, +X509_STORE_CTX_set_default, +X509_STORE_CTX_get_verify_cb, +X509_STORE_CTX_set_verify, +X509_STORE_CTX_get_verify - X509_STORE_CTX initialisation =head1 SYNOPSIS @@ -15,18 +26,27 @@ X509_STORE_CTX_new, X509_STORE_CTX_cleanup, X509_STORE_CTX_free, X509_STORE_CTX_ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) *chain); - void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); + void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); - void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx,X509 *x); - void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx,STACK_OF(X509) *sk); - void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk); + void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx,X509 *x); + STACK_OF(X509) *X509_STORE_CTX_get0_chain(X609_STORE_CTX *ctx); + void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *chain); + void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk); X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); + STACK_OF(X509)* X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx); + int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx); + typedef int (*X509_STORE_CTX_verify)(X509_STORE_CTX *); + X509_STORE_CTX_verify X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx); + void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, X509_STORE_CTX_verify verify); + + =head1 DESCRIPTION These functions initialise an B<X509_STORE_CTX> structure for subsequent use @@ -52,15 +72,19 @@ certificates (which will be untrusted but may be used to build the chain) in B<chain>. Any or all of the B<store>, B<x509> and B<chain> parameters can be B<NULL>. -X509_STORE_CTX_trusted_stack() sets the set of trusted certificates of B<ctx> -to B<sk>. This is an alternative way of specifying trusted certificates +X509_STORE_CTX_set0_trusted_stack() sets the set of trusted certificates of +B<ctx> to B<sk>. This is an alternative way of specifying trusted certificates instead of using an B<X509_STORE>. X509_STORE_CTX_set_cert() sets the certificate to be verified in B<ctx> to B<x>. -X509_STORE_CTX_set_chain() sets the additional certificate chain used by B<ctx> -to B<sk>. +X509_STORE_CTX_set0_verified_chain() sets the validated chain used +by B<ctx> to be B<chain>. +Ownership of the chain is transferred to B<ctx> and should not be +free'd by the caller. +X509_STORE_CTX_get0_chain() returns a the internal pointer used by the +B<ctx> that contains the validated chain. X509_STORE_CTX_set0_crls() sets a set of CRLs to use to aid certificate verification to B<sk>. These CRLs will only be used if CRL verification is @@ -68,9 +92,15 @@ enabled in the associated B<X509_VERIFY_PARAM> structure. This might be used where additional "useful" CRLs are supplied as part of a protocol, for example in a PKCS#7 structure. -X509_VERIFY_PARAM *X509_STORE_CTX_get0_param() retrieves an internal pointer +X509_STORE_CTX_get0_param() retrieves an internal pointer to the verification parameters associated with B<ctx>. +X509_STORE_CTX_get0_cert() retrieves an internal pointer to the +certificate being verified by the B<ctx>. + +X509_STORE_CTX_get0_untrusted() retrieves an internal pointer to the +stack of untrusted certifieds associated with B<ctx>. + X509_STORE_CTX_set0_param() sets the internal verification parameter pointer to B<param>. After this call B<param> should not be used. @@ -84,19 +114,7 @@ that were used in building the chain following a call to X509_verify_cert(). =head1 NOTES The certificates and CRLs in a store are used internally and should B<not> -be freed up until after the associated B<X509_STORE_CTX> is freed. Legacy -applications might implicitly use an B<X509_STORE_CTX> like this: - - X509_STORE_CTX ctx; - X509_STORE_CTX_init(&ctx, store, cert, chain); - -this is B<not> recommended in new applications they should instead do: - - X509_STORE_CTX *ctx; - ctx = X509_STORE_CTX_new(); - if (ctx == NULL) - /* Bad error */ - X509_STORE_CTX_init(ctx, store, cert, chain); +be freed up until after the associated B<X509_STORE_CTX> is freed. =head1 BUGS @@ -114,8 +132,9 @@ X509_STORE_CTX_init() returns 1 for success or 0 if an error occurred. X509_STORE_CTX_get0_param() returns a pointer to an B<X509_VERIFY_PARAM> structure or B<NULL> if an error occurred. -X509_STORE_CTX_cleanup(), X509_STORE_CTX_free(), X509_STORE_CTX_trusted_stack(), -X509_STORE_CTX_set_cert(), X509_STORE_CTX_set_chain(), +X509_STORE_CTX_cleanup(), X509_STORE_CTX_free(), +X509_STORE_CTX_set0_trusted_stack(), +X509_STORE_CTX_set_cert(), X509_STORE_CTX_set0_crls() and X509_STORE_CTX_set0_param() do not return values. diff --git a/doc/crypto/X509_STORE_CTX_set_verify_cb.pod b/doc/crypto/X509_STORE_CTX_set_verify_cb.pod index ba35a38474..e89b8060f7 100644 --- a/doc/crypto/X509_STORE_CTX_set_verify_cb.pod +++ b/doc/crypto/X509_STORE_CTX_set_verify_cb.pod @@ -2,14 +2,19 @@ =head1 NAME -X509_STORE_CTX_set_verify_cb - set verification callback +X509_STORE_CTX_get_verify_cb, +X509_STORE_CTX_set_verify_cb - get and set verification callback =head1 SYNOPSIS #include <openssl/x509_vfy.h> + typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *); + + X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx); + void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, - int (*verify_cb)(int ok, X509_STORE_CTX *ctx)); + X509_STORE_CTX_verify_cb verify_cb); =head1 DESCRIPTION @@ -35,6 +40,9 @@ structure and receive additional information about the error, for example by calling X509_STORE_CTX_get_current_cert(). Additional application data can be passed to the callback via the B<ex_data> mechanism. +X509_STORE_CTX_get_verify_cb() returns the value of the current callback +for the specific B<ctx>. + =head1 WARNING In general a verification callback should B<NOT> unconditionally return 1 in diff --git a/include/openssl/ossl_typ.h b/include/openssl/ossl_typ.h index ee6ebcfb67..81da79286b 100644 --- a/include/openssl/ossl_typ.h +++ b/include/openssl/ossl_typ.h @@ -119,6 +119,7 @@ typedef struct asn1_sctx_st ASN1_SCTX; # ifdef BIGNUM # undef BIGNUM # endif +struct dane_st; typedef struct bio_st BIO; typedef struct bignum_st BIGNUM; typedef struct bignum_ctx BN_CTX; @@ -169,6 +170,11 @@ typedef struct X509_pubkey_st X509_PUBKEY; typedef struct x509_store_st X509_STORE; typedef struct x509_store_ctx_st X509_STORE_CTX; +typedef struct x509_object_st X509_OBJECT; +typedef struct x509_lookup_st X509_LOOKUP; +typedef struct x509_lookup_method_st X509_LOOKUP_METHOD; +typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; + typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; typedef struct v3_ext_ctx X509V3_CTX; diff --git a/include/openssl/x509.h b/include/openssl/x509.h index b7123d09c1..a36500c8c2 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -1096,6 +1096,7 @@ void ERR_load_X509_strings(void); # define X509_F_X509_STORE_CTX_INIT 143 # define X509_F_X509_STORE_CTX_NEW 142 # define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134 +# define X509_F_X509_STORE_GET_X509_BY_SUBJECT 149 # define X509_F_X509_TO_X509_REQ 126 # define X509_F_X509_TRUST_ADD 133 # define X509_F_X509_TRUST_SET 141 diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h index 2d0cbc0ddf..544f2ad6ce 100644 --- a/include/openssl/x509_vfy.h +++ b/include/openssl/x509_vfy.h @@ -75,14 +75,6 @@ extern "C" { #endif -typedef struct x509_file_st { - int num_paths; /* number of paths to files or directories */ - int num_alloced; - char **paths; /* the list of paths or directories */ - int *path_type; -} X509_CERT_FILE_CTX; - -/*******************************/ /*- SSL_CTX -> X509_STORE -> X509_LOOKUP @@ -105,168 +97,16 @@ typedef enum { X509_LU_FAIL, X509_LU_X509, X509_LU_CRL } X509_LOOKUP_TYPE; -typedef struct x509_object_st { - /* one of the above types */ - X509_LOOKUP_TYPE type; - union { - char *ptr; - X509 *x509; - X509_CRL *crl; - EVP_PKEY *pkey; - } data; -} X509_OBJECT; - -typedef struct x509_lookup_st X509_LOOKUP; DEFINE_STACK_OF(X509_LOOKUP) DEFINE_STACK_OF(X509_OBJECT) - -/* This is a static that defines the function interface */ -typedef struct x509_lookup_method_st { - const char *name; - int (*new_item) (X509_LOOKUP *ctx); - void (*free) (X509_LOOKUP *ctx); - int (*init) (X509_LOOKUP *ctx); - int (*shutdown) (X509_LOOKUP *ctx); - int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl, - char **ret); - int (*get_by_subject) (X509_LOOKUP *ctx, int type, X509_NAME *name, - X509_OBJECT *ret); - int (*get_by_issuer_serial) (X509_LOOKUP *ctx, int type, X509_NAME *name, - ASN1_INTEGER *serial, X509_OBJECT *ret); - int (*get_by_fingerprint) (X509_LOOKUP *ctx, int type, - unsigned char *bytes, int len, - X509_OBJECT *ret); - int (*get_by_alias) (X509_LOOKUP *ctx, int type, char *str, int len, - X509_OBJECT *ret); -} X509_LOOKUP_METHOD; - -typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; - DEFINE_STACK_OF(X509_VERIFY_PARAM) -/* - * This is used to hold everything. It is used for all certificate - * validation. Once we have a certificate chain, the 'verify' function is - * then called to actually check the cert chain. - */ -struct x509_store_st { - /* The following is a cache of trusted certs */ - int cache; /* if true, stash any hits */ - STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */ - /* These are external lookup methods */ - STACK_OF(X509_LOOKUP) *get_cert_methods; - X509_VERIFY_PARAM *param; - /* Callbacks for various operations */ - /* called to verify a certificate */ - int (*verify) (X509_STORE_CTX *ctx); - /* error callback */ - int (*verify_cb) (int ok, X509_STORE_CTX *ctx); - /* get issuers cert from ctx */ - int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x); - /* check issued */ - int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer); - /* Check revocation status of chain */ - int (*check_revocation) (X509_STORE_CTX *ctx); - /* retrieve CRL */ - int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); - /* Check CRL validity */ - int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl); - /* Check certificate against CRL */ - int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); - STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); - STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); - int (*cleanup) (X509_STORE_CTX *ctx); - CRYPTO_EX_DATA ex_data; - int references; - CRYPTO_RWLOCK *lock; -} /* X509_STORE */ ; - int X509_STORE_set_depth(X509_STORE *store, int depth); # define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func)) # define X509_STORE_set_verify_func(ctx,func) ((ctx)->verify=(func)) -/* This is the functions plus an instance of the local variables. */ -struct x509_lookup_st { - int init; /* have we been started */ - int skip; /* don't use us. */ - X509_LOOKUP_METHOD *method; /* the functions */ - char *method_data; /* method data */ - X509_STORE *store_ctx; /* who owns us */ -} /* X509_LOOKUP */ ; - -/* - * This is a used when verifying cert chains. Since the gathering of the - * cert chain can take some time (and have to be 'retried', this needs to be - * kept and passed around. - */ -struct x509_store_ctx_st { /* X509_STORE_CTX */ - X509_STORE *ctx; - /* used when looking up certs */ - int current_method; - /* The following are set by the caller */ - /* The cert to check */ - X509 *cert; - /* chain of X509s - untrusted - passed in */ - STACK_OF(X509) *untrusted; - /* set of CRLs passed in */ - STACK_OF(X509_CRL) *crls; - X509_VERIFY_PARAM *param; - /* Other info for use with get_issuer() */ - void *other_ctx; - /* Callbacks for various operations */ - /* called to verify a certificate */ - int (*verify) (X509_STORE_CTX *ctx); - /* error callback */ - int (*verify_cb) (int ok, X509_STORE_CTX *ctx); - /* get issuers cert from ctx */ - int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x); - /* check issued */ - int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer); - /* Check revocation status of chain */ - int (*check_revocation) (X509_STORE_CTX *ctx); - /* retrieve CRL */ - int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); - /* Check CRL validity */ - int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl); - /* Check certificate against CRL */ - int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); - int (*check_policy) (X509_STORE_CTX *ctx); - STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); - STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); - int (*cleanup) (X509_STORE_CTX *ctx); - /* The following is built up */ - /* if 0, rebuild chain */ - int valid; - /* number of untrusted certs */ - int num_untrusted; - /* chain of X509s - built up and trusted */ - STACK_OF(X509) *chain; - /* Valid policy tree */ - X509_POLICY_TREE *tree; - /* Require explicit policy value */ - int explicit_policy; - /* When something goes wrong, this is why */ - int error_depth; - int error; - X509 *current_cert; - /* cert currently being tested as valid issuer */ - X509 *current_issuer; - /* current CRL */ - X509_CRL *current_crl; - /* score of current CRL */ - int current_crl_score; - /* Reason mask */ - unsigned int current_reasons; - /* For CRL path validation: parent context */ - X509_STORE_CTX *parent; - CRYPTO_EX_DATA ex_data; - SSL_DANE *dane; - /* signed via bare TA public key, rather than CA certificate */ - int bare_ta_signed; -} /* X509_STORE_CTX */ ; - void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); # define X509_STORE_CTX_set_app_data(ctx,data) \ @@ -431,6 +271,8 @@ X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x); void X509_OBJECT_up_ref_count(X509_OBJECT *a); +void X509_OBJECT_free(X509_OBJECT *a); +X509 *X509_OBJECT_get0_X509(X509_OBJECT *a); void X509_OBJECT_free_contents(X509_OBJECT *a); X509_STORE *X509_STORE_new(void); void X509_STORE_free(X509_STORE *v); @@ -458,10 +300,20 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); void X509_STORE_CTX_free(X509_STORE_CTX *ctx); int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) *chain); -void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); +STACK_OF(X509)* X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx); +typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *); +typedef int (*X509_STORE_CTX_verify)(X509_STORE_CTX *); +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + X509_STORE_CTX_verify_cb verify); +X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, + X509_STORE_CTX_verify verify); +X509_STORE_CTX_verify X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx); X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); @@ -472,6 +324,8 @@ int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, X509_OBJECT *ret); +X509_OBJECT *X509_STORE_get_X509_by_subject(X509_STORE_CTX *vs, int type, + X509_NAME *name); int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); @@ -505,14 +359,15 @@ void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx); int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s); int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get_cert(X509_STORE_CTX *ctx); X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); -STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx); STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x); -void X509_STORE_CTX_set_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk); void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk); int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 24ac352d1d..04a4a36d77 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -475,25 +475,31 @@ void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg) int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) { X509 *x; - int i; + int i = 0; X509_STORE *verify_store; - X509_STORE_CTX ctx; + X509_STORE_CTX *ctx = NULL; X509_VERIFY_PARAM *param; + if ((sk == NULL) || (sk_X509_num(sk) == 0)) + return 0; + if (s->cert->verify_store) verify_store = s->cert->verify_store; else verify_store = s->ctx->cert_store; - if ((sk == NULL) || (sk_X509_num(sk) == 0)) - return (0); + ctx = X509_STORE_CTX_new(); + if (ctx == NULL) { + SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_MALLOC_FAILURE); + return 0; + } x = sk_X509_value(sk, 0); - if (!X509_STORE_CTX_init(&ctx, verify_store, x, sk)) { + if (!X509_STORE_CTX_init(ctx, verify_store, x, sk)) { SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB); - return (0); + goto end; } - param = X509_STORE_CTX_get0_param(&ctx); + param = X509_STORE_CTX_get0_param(ctx); /* * XXX: Separate @AUTHSECLEVEL and @TLSSECLEVEL would be useful at some * point, for now a single @SECLEVEL sets the same policy for TLS crypto @@ -502,12 +508,12 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) X509_VERIFY_PARAM_set_auth_level(param, SSL_get_security_level(s)); /* Set suite B flags if needed */ - X509_STORE_CTX_set_flags(&ctx, tls1_suiteb(s)); - X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s); + X509_STORE_CTX_set_flags(ctx, tls1_suiteb(s)); + X509_STORE_CTX_set_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s); /* Verify via DANE if enabled */ if (DANETLS_ENABLED(&s->dane)) - X509_STORE_CTX_set0_dane(&ctx, &s->dane); + X509_STORE_CTX_set0_dane(ctx, &s->dane); /* * We need to inherit the verify parameters. These can be determined by @@ -515,25 +521,25 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) * vice versa. */ - X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server"); + X509_STORE_CTX_set_default(ctx, s->server ? "ssl_client" : "ssl_server"); /* * Anything non-default in "s->param" should overwrite anything in the ctx. */ X509_VERIFY_PARAM_set1(param, s->param); if (s->verify_callback) - X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); + X509_STORE_CTX_set_verify_cb(ctx, s->verify_callback); if (s->ctx->app_verify_callback != NULL) - i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); + i = s->ctx->app_verify_callback(ctx, s->ctx->app_verify_arg); else - i = X509_verify_cert(&ctx); + i = X509_verify_cert(ctx); - s->verify_result = ctx.error; + s->verify_result = X509_STORE_CTX_get_error(ctx); sk_X509_pop_free(s->verified_chain, X509_free); s->verified_chain = NULL; - if (X509_STORE_CTX_get_chain(&ctx) != NULL) { - s->verified_chain = X509_STORE_CTX_get1_chain(&ctx); + if (X509_STORE_CTX_get0_chain(ctx) != NULL) { + s->verified_chain = X509_STORE_CTX_get1_chain(ctx); if (s->verified_chain == NULL) { SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_MALLOC_FAILURE); i = 0; @@ -543,9 +549,9 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) /* Move peername from the store context params to the SSL handle's */ X509_VERIFY_PARAM_move_peername(s->param, param); - X509_STORE_CTX_cleanup(&ctx); - - return (i); +end: + X509_STORE_CTX_free(ctx); + return i; } static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list, @@ -846,10 +852,10 @@ static int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) { BUF_MEM *buf = s->init_buf; - int i; - + int i, chain_count; X509 *x; STACK_OF(X509) *extra_certs; + STACK_OF(X509) *chain = NULL; X509_STORE *chain_store; /* TLSv1 sends a chain with nothing in it, instead of an alert */ @@ -879,9 +885,14 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) chain_store = s->ctx->cert_store; if (chain_store) { - X509_STORE_CTX xs_ctx; + X509_STORE_CTX* xs_ctx = X509_STORE_CTX_new(); - if (!X509_STORE_CTX_init(&xs_ctx, chain_store, x, NULL)) { + if (xs_ctx == NULL) { + SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_MALLOC_FAILURE); + return (0); + } + if (!X509_STORE_CTX_init(xs_ctx, chain_store, x, NULL)) { + X509_STORE_CTX_free(xs_ctx); SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_X509_LIB); return (0); } @@ -891,30 +902,32 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) * ignore the error return from this call. We're not actually verifying * the cert - we're just building as much of the chain as we can */ - (void) X509_verify_cert(&xs_ctx); + (void) X509_verify_cert(xs_ctx); /* Don't leave errors in the queue */ ERR_clear_error(); - i = ssl_security_cert_chain(s, xs_ctx.chain, NULL, 0); + chain = X509_STORE_CTX_get0_chain(xs_ctx); + i = ssl_security_cert_chain(s, chain, NULL, 0); if (i != 1) { - X509_STORE_CTX_cleanup(&xs_ctx); #if 0 /* Dummy error calls so mkerr generates them */ SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, SSL_R_EE_KEY_TOO_SMALL); SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, SSL_R_CA_KEY_TOO_SMALL); SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, SSL_R_CA_MD_TOO_WEAK); #endif + X509_STORE_CTX_free(xs_ctx); SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, i); return 0; } - for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) { - x = sk_X509_value(xs_ctx.chain, i); + chain_count = sk_X509_num(chain); + for (i = 0; i < chain_count; i++) { + x = sk_X509_value(chain, i); if (!ssl_add_cert_to_buf(buf, l, x)) { - X509_STORE_CTX_cleanup(&xs_ctx); + X509_STORE_CTX_free(xs_ctx); return 0; } } - X509_STORE_CTX_cleanup(&xs_ctx); + X509_STORE_CTX_free(xs_ctx); } else { i = ssl_security_cert_chain(s, extra_certs, x, 0); if (i != 1) { @@ -938,7 +951,7 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) CERT *c = s ? s->cert : ctx->cert; CERT_PKEY *cpk = c->key; X509_STORE *chain_store = NULL; - X509_STORE_CTX xs_ctx; + X509_STORE_CTX *xs_ctx = NULL; STACK_OF(X509) *chain = NULL, *untrusted = NULL; X509 *x; int i, rv = 0; @@ -984,15 +997,20 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) untrusted = cpk->chain; } - if (!X509_STORE_CTX_init(&xs_ctx, chain_store, cpk->x509, untrusted)) { + xs_ctx = X509_STORE_CTX_new(); + if (xs_ctx == NULL) { + SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!X509_STORE_CTX_init(xs_ctx, chain_store, cpk->x509, untrusted)) { SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_X509_LIB); goto err; } /* Set suite B flags if needed */ - X509_STORE_CTX_set_flags(&xs_ctx, + X509_STORE_CTX_set_flags(xs_ctx, c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS); - i = X509_verify_cert(&xs_ctx); + i = X509_verify_cert(xs_ctx); if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) { if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR) ERR_clear_error(); @@ -1000,17 +1018,15 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) rv = 2; } if (i > 0) - chain = X509_STORE_CTX_get1_chain(&xs_ctx); + chain = X509_STORE_CTX_get1_chain(xs_ctx); if (i <= 0) { SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_CERTIFICATE_VERIFY_FAILED); - i = X509_STORE_CTX_get_error(&xs_ctx); + i = X509_STORE_CTX_get_error(xs_ctx); ERR_add_error_data(2, "Verify error:", X509_verify_cert_error_string(i)); - X509_STORE_CTX_cleanup(&xs_ctx); goto err; } - X509_STORE_CTX_cleanup(&xs_ctx); /* Remove EE certificate from chain */ x = sk_X509_shift(chain); X509_free(x); @@ -1045,6 +1061,7 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) err: if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) X509_STORE_free(chain_store); + X509_STORE_CTX_free(xs_ctx); return rv; } diff --git a/test/ssltest_old.c b/test/ssltest_old.c index 0dae90fb20..2fd7da824a 100644 --- a/test/ssltest_old.c +++ b/test/ssltest_old.c @@ -3072,32 +3072,36 @@ static int verify_callback(int ok, X509_STORE_CTX *ctx) { char *s, buf[256]; - s = X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, - sizeof buf); + s = X509_NAME_oneline(X509_get_subject_name(X509_STORE_CTX_get_current_cert(ctx)), + buf, sizeof buf); if (s != NULL) { if (ok) - printf("depth=%d %s\n", ctx->error_depth, buf); + printf("depth=%d %s\n", X509_STORE_CTX_get_error_depth(ctx), buf); else { fprintf(stderr, "depth=%d error=%d %s\n", - ctx->error_depth, ctx->error, buf); + X509_STORE_CTX_get_error_depth(ctx), + X509_STORE_CTX_get_error(ctx), buf); } } if (ok == 0) { - switch (ctx->error) { + int i = X509_STORE_CTX_get_error(ctx); + + switch (i) { default: fprintf(stderr, "Error string: %s\n", - X509_verify_cert_error_string(ctx->error)); + X509_verify_cert_error_string(i)); break; case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: ok = 1; + break; } } if (ok == 1) { - X509 *xs = ctx->current_cert; + X509 *xs = X509_STORE_CTX_get_current_cert(ctx); if (X509_get_extension_flags(xs) & EXFLAG_PROXY) { unsigned int *letters = X509_STORE_CTX_get_ex_data(ctx, get_proxy_auth_ex_data_idx @@ -3434,15 +3438,17 @@ static int app_verify_callback(X509_STORE_CTX *ctx, void *arg) if (cb_arg->app_verify) { char *s = NULL, buf[256]; + X509 *c = X509_STORE_CTX_get0_cert(ctx); printf("In app_verify_callback, allowing cert. "); printf("Arg is: %s\n", cb_arg->string); printf("Finished printing do we have a context? 0x%p a cert? 0x%p\n", - (void *)ctx, (void *)ctx->cert); - if (ctx->cert) - s = X509_NAME_oneline(X509_get_subject_name(ctx->cert), buf, 256); + (void *)ctx, (void *)c); + if (c) + s = X509_NAME_oneline(X509_get_subject_name(c), buf, 256); if (s != NULL) { - printf("cert depth=%d %s\n", ctx->error_depth, buf); + printf("cert depth=%d %s\n", + X509_STORE_CTX_get_error_depth(ctx), buf); } return (1); } diff --git a/util/libcrypto.num b/util/libcrypto.num index 6a9311c8be..a92286c64c 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -1,7 +1,7 @@ d2i_EC_PUBKEY 1 1_1_0 EXIST::FUNCTION:EC b2i_PVK_bio 2 1_1_0 EXIST::FUNCTION:RC4 PEM_read_bio_NETSCAPE_CERT_SEQUENCE 3 1_1_0 EXIST::FUNCTION: -X509_STORE_CTX_get_chain 4 1_1_0 EXIST::FUNCTION: +X509_STORE_CTX_get0_chain 4 1_1_0 EXIST::FUNCTION: COMP_expand_block 5 1_1_0 EXIST::FUNCTION:COMP X509V3_get_string 6 1_1_0 EXIST::FUNCTION: TS_MSG_IMPRINT_free 7 1_1_0 EXIST::FUNCTION:TS @@ -1755,7 +1755,6 @@ X509_REVOKED_new 1703 1_1_0 EXIST::FUNCTION: NCONF_WIN32 1704 1_1_0 EXIST::FUNCTION: RSA_padding_check_PKCS1_OAEP_mgf1 1705 1_1_0 EXIST::FUNCTION:RSA X509_policy_tree_get0_level 1706 1_1_0 EXIST::FUNCTION: -X509_STORE_CTX_set_chain 1707 1_1_0 EXIST::FUNCTION: ASN1_parse_dump 1708 1_1_0 EXIST::FUNCTION: BIO_vfree 1709 1_1_0 EXIST::FUNCTION: CRYPTO_cbc128_decrypt 1710 1_1_0 EXIST::FUNCTION: @@ -1942,7 +1941,7 @@ X509_STORE_set_verify_cb 1882 1_1_0 EXIST::FUNCTION: OCSP_REQUEST_print 1883 1_1_0 EXIST::FUNCTION: CMS_add1_crl 1884 1_1_0 EXIST::FUNCTION:CMS d2i_EDIPARTYNAME 1885 1_1_0 EXIST::FUNCTION: -X509_STORE_CTX_trusted_stack 1886 1_1_0 EXIST::FUNCTION: +X509_STORE_CTX_set0_trusted_stack 1886 1_1_0 EXIST::FUNCTION: BIO_ADDR_service_string 1887 1_1_0 EXIST::FUNCTION: ASN1_BOOLEAN_it 1888 1_1_0 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE: ASN1_BOOLEAN_it 1888 1_1_0 EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION: @@ -4166,7 +4165,6 @@ RSA_meth_get_priv_enc 4032 1_1_0 EXIST::FUNCTION:RSA RSA_set0_crt_params 4037 1_1_0 EXIST::FUNCTION:RSA RSA_get0_crt_params 4038 1_1_0 EXIST::FUNCTION:RSA DH_set0_pqg 4039 1_1_0 EXIST::FUNCTION:DH -DH_set_flags 4040 1_1_0 EXIST::FUNCTION:DH DH_clear_flags 4041 1_1_0 EXIST::FUNCTION:DH DH_get0_key 4042 1_1_0 EXIST::FUNCTION:DH DH_get0_engine 4043 1_1_0 EXIST::FUNCTION:DH @@ -4196,3 +4194,15 @@ DH_meth_set_bn_mod_exp 4066 1_1_0 EXIST::FUNCTION:DH DH_meth_set_generate_key 4067 1_1_0 EXIST::FUNCTION:DH DH_meth_free 4068 1_1_0 EXIST::FUNCTION:DH DH_meth_get_generate_key 4069 1_1_0 EXIST::FUNCTION:DH +DH_set_flags 4070 1_1_0 EXIST::FUNCTION:DH +X509_STORE_get_X509_by_subject 4071 1_1_0 EXIST::FUNCTION: +X509_OBJECT_free 4072 1_1_0 EXIST::FUNCTION: +X509_OBJECT_get0_X509 4073 1_1_0 EXIST::FUNCTION: +X509_STORE_CTX_get0_untrusted 4074 1_1_0 EXIST::FUNCTION: +X509_STORE_CTX_set0_chain 4075 1_1_0 NOEXIST::FUNCTION: +X509_STORE_CTX_get0_cert 4076 1_1_0 EXIST::FUNCTION: +X509_STORE_CTX_set_verify 4077 1_1_0 EXIST::FUNCTION: +X509_STORE_CTX_get_verify 4079 1_1_0 EXIST::FUNCTION: +X509_STORE_CTX_get_verify_cb 4080 1_1_0 EXIST::FUNCTION: +X509_STORE_CTX_get_cert 4081 1_1_0 EXIST::FUNCTION: +X509_STORE_CTX_set0_verified_chain 4082 1_1_0 EXIST::FUNCTION: |