summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--NEWS4
-rw-r--r--apps/crl.c24
-rw-r--r--apps/pkcs12.c23
-rw-r--r--apps/s_server.c28
-rw-r--r--apps/verify.c2
-rw-r--r--apps/x509.c13
-rw-r--r--crypto/cms/cms_smime.c19
-rw-r--r--crypto/include/internal/x509_int.h82
-rw-r--r--crypto/ocsp/ocsp_vfy.c82
-rw-r--r--crypto/pkcs7/pk7_smime.c19
-rw-r--r--crypto/ts/ts_rsp_verify.c31
-rw-r--r--crypto/x509/by_file.c1
-rw-r--r--crypto/x509/x509_err.c2
-rw-r--r--crypto/x509/x509_lcl.h65
-rw-r--r--crypto/x509/x509_lu.c33
-rw-r--r--crypto/x509/x509_vfy.c44
-rw-r--r--doc/crypto/X509_STORE_CTX_get_error.pod8
-rw-r--r--doc/crypto/X509_STORE_CTX_new.pod69
-rw-r--r--doc/crypto/X509_STORE_CTX_set_verify_cb.pod12
-rw-r--r--include/openssl/ossl_typ.h6
-rw-r--r--include/openssl/x509.h1
-rw-r--r--include/openssl/x509_vfy.h181
-rw-r--r--ssl/ssl_cert.c95
-rw-r--r--test/ssltest_old.c28
-rw-r--r--util/libcrypto.num18
26 files changed, 542 insertions, 353 deletions
diff --git a/CHANGES b/CHANGES
index d6cfc0ec8b..477d18527d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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]
diff --git a/NEWS b/NEWS
index 72f757966d..90336bc6d3 100644
--- a/NEWS
+++ b/NEWS
@@ -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,