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]
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
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;
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)
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);
}
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;
}
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;
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))
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);
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
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);
{
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;
}
* 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)) {
goto end;
ret = 1;
end:
- X509_STORE_CTX_cleanup(&xsc);
+ X509_STORE_CTX_free(xsc);
if (!ret)
ERR_print_errors(bio_err);
if (!sno)
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:",
}
r = 1;
err:
- X509_STORE_CTX_cleanup(&ctx);
+ X509_STORE_CTX_free(ctx);
return r;
}
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 {
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;
+};
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;
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)) {
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;
/* 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
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);
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;
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,
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;
/* 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);
ret = 1;
err:
+ X509_STORE_CTX_free(cert_ctx);
OPENSSL_free(buf);
if (tmpin == indata) {
if (indata)
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;
}
#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);
{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"},
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)
}
}
+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)
{
}
}
+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:
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);
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;
}
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;
* 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;
}
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;
=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
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);
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.
=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
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
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
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.
=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
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.
=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
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
# ifdef BIGNUM
# undef BIGNUM
# endif
+struct dane_st;
typedef struct bio_st BIO;
typedef struct bignum_st BIGNUM;
typedef struct bignum_ctx BN_CTX;
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;
# 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
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
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) \
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);
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);
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);
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);
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
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
* 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;
/* 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,
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 */
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);
}
* 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) {
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;
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();
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);
err:
if (flags & SSL_BUILD_CHAIN_FLAG_CHECK)
X509_STORE_free(chain_store);
+ X509_STORE_CTX_free(xs_ctx);
return rv;
}
{
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
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);
}
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
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:
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:
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
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: