Make many X509_xxx types opaque.
authorRich Salz <rsalz@openssl.org>
Fri, 15 Apr 2016 03:59:26 +0000 (23:59 -0400)
committerRich Salz <rsalz@openssl.org>
Fri, 15 Apr 2016 17:21:43 +0000 (13:21 -0400)
Make X509_OBJECT, X509_STORE_CTX, X509_STORE, X509_LOOKUP,
and X509_LOOKUP_METHOD opaque.
Remove unused X509_CERT_FILE_CTX

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
26 files changed:
CHANGES
NEWS
apps/crl.c
apps/pkcs12.c
apps/s_server.c
apps/verify.c
apps/x509.c
crypto/cms/cms_smime.c
crypto/include/internal/x509_int.h
crypto/ocsp/ocsp_vfy.c
crypto/pkcs7/pk7_smime.c
crypto/ts/ts_rsp_verify.c
crypto/x509/by_file.c
crypto/x509/x509_err.c
crypto/x509/x509_lcl.h
crypto/x509/x509_lu.c
crypto/x509/x509_vfy.c
doc/crypto/X509_STORE_CTX_get_error.pod
doc/crypto/X509_STORE_CTX_new.pod
doc/crypto/X509_STORE_CTX_set_verify_cb.pod
include/openssl/ossl_typ.h
include/openssl/x509.h
include/openssl/x509_vfy.h
ssl/ssl_cert.c
test/ssltest_old.c
util/libcrypto.num

diff --git a/CHANGES b/CHANGES
index d6cfc0ec8b3e64bb52a1a48273e97975e8a4b2d4..477d18527d668c8bba87c9fc2d6dbcd9289c40ad 100644 (file)
--- 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 72f757966d98d21f85f5b24ccf3b4aad31e9a957..90336bc6d3aac29cbeac858d4a846dc3721262f0 100644 (file)
--- 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
index c6fc9e667540a9e16d051133e381d4bf512f35ca..915c9ac741c7aeae21be224b58c3f5cd221f08f8 100644 (file)
@@ -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);
 }
index ff3cb8845bf08d5b19e087c2077053fd56ee35c6..406b10328a5ba6add921e1b1ee6a9370f44617d5 100644 (file)
@@ -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;
 }
index e0aa2ae4f86ce9f4a67bbf62813f55eff9c2fb18..6c8541eec9489e9932e32a29af0489124ec8b156 100644 (file)
@@ -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
 
index 58a48c7f6310160258d304e0d83bc30ef75958e3..fa517830cf25eb83735cf213dbdc1fc2640e0be0 100644 (file)
@@ -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);
index d8be179d437db05a7a65d29ed87b8080a93188b4..6e6ee08ad29a1f30ccd14495ec162a401a63d257 100644 (file)
@@ -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)
index e84b7e7e5fb405b42a65ce707ba666b806969adb..98054b36b541ca131f3c416358a2069fa9d969aa 100644 (file)
@@ -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;
 
 }
index fc032ae07d2ef86f51f12e9ccb6f2f9213165183..ee49f2aa4ace3e65dcc694db2728719035fe001d 100644 (file)
@@ -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;
+};
index 356c79768fb2839caa939ab230c6eaf6f5013162..aba623c798de28564280db80cc3e898c5523dfc7 100644 (file)
@@ -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,
index 8027640de35ba83fae88eb4ae4ba9be2939b60c0..b146f6813733ec465b1f60a6ad522d4a46c30f56 100644 (file)
@@ -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)
index e6e213ab12602f622429cc5d1f5f1a211c6ed408..89b86e1dd322f251d6e72466bbcb8c32330b094e 100644 (file)
@@ -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;
 }
 
index 51d642dd263362e9991b153996cd7fcbf208a68c..eea7a7ee41c397663f12bb26fdb7357c6ee074e3 100644 (file)
@@ -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);
index 90a22de41cc2ee9dd001ba7c61a745da3538e4c6..d140d5230d76bffd52393f5afa07e4f5067ecbf0 100644 (file)
@@ -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"},
index 603c17737f1b0f84d585b0b9eaa88b1b6d0f8b22..db98a105aa938344becec1bf2d31626bae40745f 100644 (file)
@@ -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)
index f9802c5a80a9b1f76bd216ffcc015c5c1170c534..b8229662030903300aa1bdae0f3124e41c996596 100644 (file)
@@ -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);
index 2c3efdd4b01a6fd1b896e71a3c9be792c82b4da2..312b112f504f2c5cec5a7e5f3a012455d9b9ee04 100644 (file)
@@ -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;
index 75be45374e2b17f22e0532857ffb15a6b24d6e29..1cc6bb5e8fe84153eed9f04fe6f5af89027b8d09 100644 (file)
@@ -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.
 
index 1f3ded6d29d970ba93c720ccd0ff2845cc65bd21..69ff7c453886e8bc3c21d7316261c5b4b74f7d1b 100644 (file)
@@ -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.
 
index ba35a384740b40355fbe31b33aec8f9a8dba769a..e89b8060f71c9418c5748792f80dcbd00ffbb89e 100644 (file)
@@ -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
index ee6ebcfb677dfc18448b9773bf26616b619e38e3..81da79286b14a072eb16461dac668ed1545f7d3c 100644 (file)
@@ -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;
index b7123d09c1e71508c9bb9fb3eda2dfe6709d5e46..a36500c8c2ecbf502060e919bfe38741ad7a5ad6 100644 (file)
@@ -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
index 2d0cbc0ddf0fb1c767bad4bd0a9b4c3277a458e9..544f2ad6cecbec27c5e9b2a4136284c2de367b30 100644 (file)
 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);
index 24ac352d1da47c4644475b5d55069be32bed1f30..04a4a36d7713b67e0d47ba4ad30525737a6f4fd1 100644 (file)
@@ -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;
 }
index 0dae90fb20013067c1cc0bb2b616d70cdba82ef4..2fd7da824adf3e06d5d25eecdac281e3dc9a6351 100644 (file)
@@ -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);
     }
index 6a9311c8bedb9bd68151c63db60805bec9b97884..a92286c64cf8d395c61f28d7c922ecdb1d10152b 100644 (file)
@@ -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: