Add support for certificate stores in CERT structure. This makes it
possible to have different stores per SSL structure or one store in the parent SSL_CTX. Include distint stores for certificate chain verification and chain building. New ctrl SSL_CTRL_BUILD_CERT_CHAIN to build and store a certificate chain in CERT structure: returing an error if the chain cannot be built: this will allow applications to test if a chain is correctly configured. Note: if the CERT based stores are not set then the parent SSL_CTX store is used to retain compatibility with existing behaviour.
This commit is contained in:
parent
5818a07a4f
commit
74ecfab401
13
CHANGES
13
CHANGES
@ -4,6 +4,19 @@
|
||||
|
||||
Changes between 1.0.1 and 1.1.0 [xx XXX xxxx]
|
||||
|
||||
*) Add support for certificate stores in CERT structure. This makes it
|
||||
possible to have different stores per SSL structure or one store in
|
||||
the parent SSL_CTX. Include distint stores for certificate chain
|
||||
verification and chain building. New ctrl SSL_CTRL_BUILD_CERT_CHAIN
|
||||
to build and store a certificate chain in CERT structure: returing
|
||||
an error if the chain cannot be built: this will allow applications
|
||||
to test if a chain is correctly configured.
|
||||
|
||||
Note: if the CERT based stores are not set then the parent SSL_CTX
|
||||
store is used to retain compatibility with existing behaviour.
|
||||
|
||||
[Steve Henson]
|
||||
|
||||
*) New function ssl_set_client_disabled to set a ciphersuite disabled
|
||||
mask based on the current session, check mask when sending client
|
||||
hello and checking the requested ciphersuite.
|
||||
|
@ -155,7 +155,7 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
|
||||
#ifdef HEADER_SSL_H
|
||||
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
|
||||
int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
|
||||
STACK_OF(X509) *chain);
|
||||
STACK_OF(X509) *chain, int build_chain);
|
||||
# ifndef OPENSSL_NO_TLSEXT
|
||||
int set_cert_key_and_authz(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
|
||||
unsigned char *authz, size_t authz_length);
|
||||
|
32
apps/s_cb.c
32
apps/s_cb.c
@ -251,7 +251,7 @@ int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
|
||||
}
|
||||
|
||||
int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
|
||||
STACK_OF(X509) *chain)
|
||||
STACK_OF(X509) *chain, int build_chain)
|
||||
{
|
||||
if (cert == NULL)
|
||||
return 1;
|
||||
@ -282,6 +282,13 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
|
||||
ERR_print_errors(bio_err);
|
||||
return 0;
|
||||
}
|
||||
if (!chain && build_chain && !SSL_CTX_build_cert_chain(ctx, 0))
|
||||
{
|
||||
BIO_printf(bio_err,"error building certificate chain\n");
|
||||
ERR_print_errors(bio_err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1123,6 +1130,7 @@ struct ssl_excert_st
|
||||
X509 *cert;
|
||||
EVP_PKEY *key;
|
||||
STACK_OF(X509) *chain;
|
||||
int build_chain;
|
||||
struct ssl_excert_st *next, *prev;
|
||||
};
|
||||
|
||||
@ -1150,7 +1158,16 @@ static int set_cert_cb(SSL *ssl, void *arg)
|
||||
{
|
||||
SSL_use_certificate(ssl, exc->cert);
|
||||
SSL_use_PrivateKey(ssl, exc->key);
|
||||
if (exc->chain)
|
||||
/* NB: we wouldn't normally do this as it is
|
||||
* not efficient building chains on each connection
|
||||
* better to cache the chain in advance.
|
||||
*/
|
||||
if (exc->build_chain)
|
||||
{
|
||||
if (!SSL_build_cert_chain(ssl, 0))
|
||||
return 0;
|
||||
}
|
||||
else if (exc->chain)
|
||||
SSL_set1_chain(ssl, exc->chain);
|
||||
}
|
||||
exc = exc->prev;
|
||||
@ -1176,6 +1193,7 @@ static int ssl_excert_prepend(SSL_EXCERT **pexc)
|
||||
exc->key = NULL;
|
||||
exc->chain = NULL;
|
||||
exc->prev = NULL;
|
||||
exc->build_chain = 0;
|
||||
|
||||
exc->next = *pexc;
|
||||
*pexc = exc;
|
||||
@ -1260,6 +1278,7 @@ int args_excert(char ***pargs, int *pargc,
|
||||
{
|
||||
char *arg = **pargs, *argn = (*pargs)[1];
|
||||
SSL_EXCERT *exc = *pexc;
|
||||
int narg = 2;
|
||||
if (!exc)
|
||||
{
|
||||
if (ssl_excert_prepend(&exc))
|
||||
@ -1316,6 +1335,11 @@ int args_excert(char ***pargs, int *pargc,
|
||||
}
|
||||
exc->chainfile = argn;
|
||||
}
|
||||
else if (strcmp(arg,"-xchain_build") == 0)
|
||||
{
|
||||
narg = 1;
|
||||
exc->build_chain = 1;
|
||||
}
|
||||
else if (strcmp(arg,"-xcertform") == 0)
|
||||
{
|
||||
if (!argn)
|
||||
@ -1337,10 +1361,10 @@ int args_excert(char ***pargs, int *pargc,
|
||||
else
|
||||
return 0;
|
||||
|
||||
(*pargs) += 2;
|
||||
(*pargs) += narg;
|
||||
|
||||
if (pargc)
|
||||
*pargc -= 2;
|
||||
*pargc -= narg;
|
||||
|
||||
*pexc = exc;
|
||||
|
||||
|
@ -559,6 +559,7 @@ int MAIN(int argc, char **argv)
|
||||
{
|
||||
unsigned int off=0, clr=0;
|
||||
unsigned int cert_flags=0;
|
||||
int build_chain = 0;
|
||||
SSL *con=NULL;
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
KSSL_CTX *kctx;
|
||||
@ -877,6 +878,8 @@ int MAIN(int argc, char **argv)
|
||||
if (--argc < 1) goto bad;
|
||||
CApath= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-build_chain") == 0)
|
||||
build_chain = 1;
|
||||
else if (strcmp(*argv,"-CAfile") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
@ -1212,8 +1215,6 @@ bad:
|
||||
#endif
|
||||
|
||||
SSL_CTX_set_verify(ctx,verify,verify_callback);
|
||||
if (!set_cert_key_stuff(ctx,cert,key, NULL))
|
||||
goto end;
|
||||
|
||||
if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
|
||||
(!SSL_CTX_set_default_verify_paths(ctx)))
|
||||
@ -1223,6 +1224,9 @@ bad:
|
||||
/* goto end; */
|
||||
}
|
||||
|
||||
if (!set_cert_key_stuff(ctx,cert,key, NULL, build_chain))
|
||||
goto end;
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (curves != NULL)
|
||||
if(!SSL_CTX_set1_curves_list(ctx,curves)) {
|
||||
|
@ -215,6 +215,9 @@ static int generate_session_id(const SSL *ssl, unsigned char *id,
|
||||
unsigned int *id_len);
|
||||
static void init_session_cache_ctx(SSL_CTX *sctx);
|
||||
static void free_sessions(void);
|
||||
static int ssl_load_stores(SSL_CTX *sctx,
|
||||
const char *vfyCApath, const char *vfyCAfile,
|
||||
const char *chCApath, const char *chCAfile);
|
||||
#ifndef OPENSSL_NO_DH
|
||||
static DH *load_dh_param(const char *dhfile);
|
||||
static DH *get_dh512(void);
|
||||
@ -952,6 +955,8 @@ int MAIN(int argc, char *argv[])
|
||||
int badarg = 0;
|
||||
short port=PORT;
|
||||
char *CApath=NULL,*CAfile=NULL;
|
||||
char *chCApath=NULL,*chCAfile=NULL;
|
||||
char *vfyCApath=NULL,*vfyCAfile=NULL;
|
||||
unsigned char *context = NULL;
|
||||
char *dhfile = NULL;
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
@ -961,6 +966,7 @@ int MAIN(int argc, char *argv[])
|
||||
int ret=1;
|
||||
int off=0;
|
||||
unsigned int cert_flags = 0;
|
||||
int build_chain = 0;
|
||||
int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
|
||||
int state=0;
|
||||
const SSL_METHOD *meth=NULL;
|
||||
@ -1135,6 +1141,16 @@ int MAIN(int argc, char *argv[])
|
||||
if (--argc < 1) goto bad;
|
||||
CApath= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-chainCApath") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
chCApath= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-verifyCApath") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
vfyCApath= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-no_cache") == 0)
|
||||
no_cache = 1;
|
||||
else if (strcmp(*argv,"-ext_cache") == 0)
|
||||
@ -1162,11 +1178,23 @@ int MAIN(int argc, char *argv[])
|
||||
if (--argc < 1) goto bad;
|
||||
cipher= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-build_chain") == 0)
|
||||
build_chain = 1;
|
||||
else if (strcmp(*argv,"-CAfile") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
CAfile= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-chainCAfile") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
chCAfile= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-verifyCAfile") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
vfyCAfile= *(++argv);
|
||||
}
|
||||
#ifdef FIONBIO
|
||||
else if (strcmp(*argv,"-nbio") == 0)
|
||||
{ s_nbio=1; }
|
||||
@ -1672,6 +1700,13 @@ bad:
|
||||
if (vpm)
|
||||
SSL_CTX_set1_param(ctx, vpm);
|
||||
|
||||
if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile))
|
||||
{
|
||||
BIO_printf(bio_err, "Error loading store locations\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s_cert2)
|
||||
{
|
||||
@ -1834,19 +1869,19 @@ bad:
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain))
|
||||
if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain))
|
||||
goto end;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s_authz_file != NULL && !SSL_CTX_use_authz_file(ctx, s_authz_file))
|
||||
goto end;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL))
|
||||
if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL, build_chain))
|
||||
goto end;
|
||||
#endif
|
||||
if (s_dcert != NULL)
|
||||
{
|
||||
if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, s_dchain))
|
||||
if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, s_dchain, build_chain))
|
||||
goto end;
|
||||
}
|
||||
|
||||
@ -3305,7 +3340,36 @@ static void free_sessions(void)
|
||||
}
|
||||
first = NULL;
|
||||
}
|
||||
|
||||
|
||||
static int ssl_load_stores(SSL_CTX *sctx,
|
||||
const char *vfyCApath, const char *vfyCAfile,
|
||||
const char *chCApath, const char *chCAfile)
|
||||
{
|
||||
X509_STORE *vfy = NULL, *ch = NULL;
|
||||
int rv = 0;
|
||||
if (vfyCApath || vfyCAfile)
|
||||
{
|
||||
vfy = X509_STORE_new();
|
||||
if (!X509_STORE_load_locations(vfy, vfyCAfile, vfyCApath))
|
||||
goto err;
|
||||
SSL_CTX_set1_verify_cert_store(ctx, vfy);
|
||||
}
|
||||
if (chCApath || chCAfile)
|
||||
{
|
||||
ch = X509_STORE_new();
|
||||
if (!X509_STORE_load_locations(ch, chCAfile, chCApath))
|
||||
goto err;
|
||||
/*X509_STORE_set_verify_cb(ch, verify_callback);*/
|
||||
SSL_CTX_set1_chain_cert_store(ctx, ch);
|
||||
}
|
||||
rv = 1;
|
||||
err:
|
||||
if (vfy)
|
||||
X509_STORE_free(vfy);
|
||||
if (ch)
|
||||
X509_STORE_free(ch);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
18
ssl/s3_lib.c
18
ssl/s3_lib.c
@ -3449,6 +3449,15 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
return 0;
|
||||
return ssl3_set_req_cert_type(s->cert, parg, larg);
|
||||
|
||||
case SSL_CTRL_BUILD_CERT_CHAIN:
|
||||
return ssl_build_cert_chain(s->cert, s->ctx->cert_store, larg);
|
||||
|
||||
case SSL_CTRL_SET_VERIFY_CERT_STORE:
|
||||
return ssl_cert_set_cert_store(s->cert, parg, 0, larg);
|
||||
|
||||
case SSL_CTRL_SET_CHAIN_CERT_STORE:
|
||||
return ssl_cert_set_cert_store(s->cert, parg, 1, larg);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -3746,6 +3755,15 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
|
||||
case SSL_CTRL_SET_CLIENT_CERT_TYPES:
|
||||
return ssl3_set_req_cert_type(ctx->cert, parg, larg);
|
||||
|
||||
case SSL_CTRL_BUILD_CERT_CHAIN:
|
||||
return ssl_build_cert_chain(ctx->cert, ctx->cert_store, larg);
|
||||
|
||||
case SSL_CTRL_SET_VERIFY_CERT_STORE:
|
||||
return ssl_cert_set_cert_store(ctx->cert, parg, 0, larg);
|
||||
|
||||
case SSL_CTRL_SET_CHAIN_CERT_STORE:
|
||||
return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg);
|
||||
|
||||
case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG:
|
||||
ctx->tlsext_authz_server_audit_proof_cb_arg = parg;
|
||||
break;
|
||||
|
32
ssl/ssl.h
32
ssl/ssl.h
@ -656,6 +656,12 @@ struct ssl_session_st
|
||||
*/
|
||||
#define SSL_CERT_FLAG_TLS_STRICT 0x00000001L
|
||||
|
||||
/* Flags for building certificate chains */
|
||||
/* Treat any existing certificates as untrusted CAs */
|
||||
#define SSL_BUILD_CHAIN_FLAG_UNTRUSTED 0x1
|
||||
/* Con't include root CA in chain */
|
||||
#define SSL_BUILD_CHAIN_FLAG_NO_ROOT 0x2
|
||||
|
||||
/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
|
||||
* they cannot be used to clear bits. */
|
||||
|
||||
@ -1666,6 +1672,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
#define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102
|
||||
#define SSL_CTRL_GET_CLIENT_CERT_TYPES 103
|
||||
#define SSL_CTRL_SET_CLIENT_CERT_TYPES 104
|
||||
#define SSL_CTRL_BUILD_CERT_CHAIN 105
|
||||
#define SSL_CTRL_SET_VERIFY_CERT_STORE 106
|
||||
#define SSL_CTRL_SET_CHAIN_CERT_STORE 107
|
||||
|
||||
#define DTLSv1_get_timeout(ssl, arg) \
|
||||
SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
|
||||
@ -1716,6 +1725,17 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509)
|
||||
#define SSL_CTX_add1_chain_cert(ctx,x509) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509)
|
||||
#define SSL_CTX_build_cert_chain(ctx, flags) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
|
||||
|
||||
#define SSL_CTX_set0_verify_cert_store(ctx,st) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st)
|
||||
#define SSL_CTX_set1_verify_cert_store(ctx,st) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st)
|
||||
#define SSL_CTX_set0_chain_cert_store(ctx,st) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st)
|
||||
#define SSL_CTX_set1_chain_cert_store(ctx,st) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st)
|
||||
|
||||
#define SSL_set0_chain(ctx,sk) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk)
|
||||
@ -1725,6 +1745,17 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509)
|
||||
#define SSL_add1_chain_cert(ctx,x509) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509)
|
||||
#define SSL_build_cert_chain(s, flags) \
|
||||
SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
|
||||
#define SSL_set0_verify_cert_store(s,st) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st)
|
||||
#define SSL_set1_verify_cert_store(s,st) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st)
|
||||
#define SSL_set0_chain_cert_store(s,st) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st)
|
||||
#define SSL_set1_chain_cert_store(s,st) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st)
|
||||
|
||||
#define SSL_get1_curves(ctx, s) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_GET_CURVES,0,(char *)s)
|
||||
#define SSL_CTX_set1_curves(ctx, clist, clistlen) \
|
||||
@ -2328,6 +2359,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278
|
||||
#define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 308
|
||||
#define SSL_F_SSL_BAD_METHOD 160
|
||||
#define SSL_F_SSL_BUILD_CERT_CHAIN 332
|
||||
#define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161
|
||||
#define SSL_F_SSL_CERT_DUP 221
|
||||
#define SSL_F_SSL_CERT_INST 222
|
||||
|
@ -403,6 +403,18 @@ CERT *ssl_cert_dup(CERT *cert)
|
||||
ret->cert_cb = cert->cert_cb;
|
||||
ret->cert_cb_arg = cert->cert_cb_arg;
|
||||
|
||||
if (cert->verify_store)
|
||||
{
|
||||
CRYPTO_add(&cert->verify_store->references, 1, CRYPTO_LOCK_X509_STORE);
|
||||
ret->verify_store = cert->verify_store;
|
||||
}
|
||||
|
||||
if (cert->chain_store)
|
||||
{
|
||||
CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE);
|
||||
ret->chain_store = cert->chain_store;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
|
||||
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
|
||||
@ -500,6 +512,10 @@ void ssl_cert_free(CERT *c)
|
||||
OPENSSL_free(c->shared_sigalgs);
|
||||
if (c->ctypes)
|
||||
OPENSSL_free(c->ctypes);
|
||||
if (c->verify_store)
|
||||
X509_STORE_free(c->verify_store);
|
||||
if (c->chain_store)
|
||||
X509_STORE_free(c->chain_store);
|
||||
OPENSSL_free(c);
|
||||
}
|
||||
|
||||
@ -671,13 +687,19 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
|
||||
{
|
||||
X509 *x;
|
||||
int i;
|
||||
X509_STORE *verify_store;
|
||||
X509_STORE_CTX ctx;
|
||||
|
||||
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);
|
||||
|
||||
x=sk_X509_value(sk,0);
|
||||
if(!X509_STORE_CTX_init(&ctx,s->ctx->cert_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);
|
||||
@ -1042,12 +1064,18 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
|
||||
|
||||
X509 *x;
|
||||
STACK_OF(X509) *extra_certs;
|
||||
X509_STORE *chain_store;
|
||||
|
||||
if (cpk)
|
||||
x = cpk->x509;
|
||||
else
|
||||
x = NULL;
|
||||
|
||||
if (s->cert->chain_store)
|
||||
chain_store = s->cert->chain_store;
|
||||
else
|
||||
chain_store = s->ctx->cert_store;
|
||||
|
||||
/* If we have a certificate specific chain use it, else use
|
||||
* parent ctx.
|
||||
*/
|
||||
@ -1078,7 +1106,7 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
|
||||
{
|
||||
X509_STORE_CTX xs_ctx;
|
||||
|
||||
if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
|
||||
if (!X509_STORE_CTX_init(&xs_ctx,chain_store,x,NULL))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_ADD_CERT_CHAIN,ERR_R_X509_LIB);
|
||||
return(0);
|
||||
@ -1109,3 +1137,69 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Build a certificate chain for current certificate */
|
||||
int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags)
|
||||
{
|
||||
CERT_PKEY *cpk = c->key;
|
||||
X509_STORE_CTX xs_ctx;
|
||||
STACK_OF(X509) *chain = NULL, *untrusted = NULL;
|
||||
X509 *x;
|
||||
int i;
|
||||
|
||||
if (!cpk->x509)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_NO_CERTIFICATE_SET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (c->chain_store)
|
||||
chain_store = c->chain_store;
|
||||
|
||||
if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED)
|
||||
untrusted = cpk->chain;
|
||||
|
||||
if (!X509_STORE_CTX_init(&xs_ctx, chain_store, cpk->x509, untrusted))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_X509_LIB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
i = X509_verify_cert(&xs_ctx);
|
||||
if (i > 0)
|
||||
chain = X509_STORE_CTX_get1_chain(&xs_ctx);
|
||||
X509_STORE_CTX_cleanup(&xs_ctx);
|
||||
if (i <= 0)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_CERTIFICATE_VERIFY_FAILED);
|
||||
return 0;
|
||||
}
|
||||
if (cpk->chain)
|
||||
sk_X509_pop_free(cpk->chain, X509_free);
|
||||
/* Remove EE certificate from chain */
|
||||
x = sk_X509_shift(chain);
|
||||
X509_free(x);
|
||||
if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT)
|
||||
{
|
||||
x = sk_X509_pop(chain);
|
||||
X509_free(x);
|
||||
}
|
||||
cpk->chain = chain;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref)
|
||||
{
|
||||
X509_STORE **pstore;
|
||||
if (chain)
|
||||
pstore = &c->chain_store;
|
||||
else
|
||||
pstore = &c->verify_store;
|
||||
if (*pstore)
|
||||
X509_STORE_free(*pstore);
|
||||
*pstore = store;
|
||||
if (ref && store)
|
||||
CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -195,6 +195,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT), "ssl_add_serverhello_tlsext"},
|
||||
{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT), "ssl_add_serverhello_use_srtp_ext"},
|
||||
{ERR_FUNC(SSL_F_SSL_BAD_METHOD), "ssl_bad_method"},
|
||||
{ERR_FUNC(SSL_F_SSL_BUILD_CERT_CHAIN), "ssl_build_cert_chain"},
|
||||
{ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST), "ssl_bytes_to_cipher_list"},
|
||||
{ERR_FUNC(SSL_F_SSL_CERT_DUP), "ssl_cert_dup"},
|
||||
{ERR_FUNC(SSL_F_SSL_CERT_INST), "ssl_cert_inst"},
|
||||
|
@ -583,6 +583,12 @@ typedef struct cert_st
|
||||
int (*cert_cb)(SSL *ssl, void *arg);
|
||||
void *cert_cb_arg;
|
||||
|
||||
/* Optional X509_STORE for chain building or certificate validation
|
||||
* If NULL the parent SSL_CTX store is used instead.
|
||||
*/
|
||||
X509_STORE *chain_store;
|
||||
X509_STORE *verify_store;
|
||||
|
||||
int references; /* >1 only if SSL_copy_session_id is used */
|
||||
} CERT;
|
||||
|
||||
@ -925,6 +931,8 @@ 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);
|
||||
int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l);
|
||||
int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags);
|
||||
int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref);
|
||||
int ssl_undefined_function(SSL *s);
|
||||
int ssl_undefined_void_function(void);
|
||||
int ssl_undefined_const_function(const SSL *s);
|
||||
|
Loading…
Reference in New Issue
Block a user