提交 74ecfab4 编写于 作者: D Dr. Stephen Henson

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.
上级 5818a07a
...@@ -4,6 +4,19 @@ ...@@ -4,6 +4,19 @@
Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] 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 *) New function ssl_set_client_disabled to set a ciphersuite disabled
mask based on the current session, check mask when sending client mask based on the current session, check mask when sending client
hello and checking the requested ciphersuite. hello and checking the requested ciphersuite.
......
...@@ -155,7 +155,7 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx); ...@@ -155,7 +155,7 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
#ifdef HEADER_SSL_H #ifdef HEADER_SSL_H
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); 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, 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 # ifndef OPENSSL_NO_TLSEXT
int set_cert_key_and_authz(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key, int set_cert_key_and_authz(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
unsigned char *authz, size_t authz_length); unsigned char *authz, size_t authz_length);
......
...@@ -251,7 +251,7 @@ int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file) ...@@ -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, 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) if (cert == NULL)
return 1; return 1;
...@@ -282,6 +282,13 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key, ...@@ -282,6 +282,13 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
ERR_print_errors(bio_err); ERR_print_errors(bio_err);
return 0; 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; return 1;
} }
...@@ -1123,6 +1130,7 @@ struct ssl_excert_st ...@@ -1123,6 +1130,7 @@ struct ssl_excert_st
X509 *cert; X509 *cert;
EVP_PKEY *key; EVP_PKEY *key;
STACK_OF(X509) *chain; STACK_OF(X509) *chain;
int build_chain;
struct ssl_excert_st *next, *prev; struct ssl_excert_st *next, *prev;
}; };
...@@ -1150,7 +1158,16 @@ static int set_cert_cb(SSL *ssl, void *arg) ...@@ -1150,7 +1158,16 @@ static int set_cert_cb(SSL *ssl, void *arg)
{ {
SSL_use_certificate(ssl, exc->cert); SSL_use_certificate(ssl, exc->cert);
SSL_use_PrivateKey(ssl, exc->key); 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); SSL_set1_chain(ssl, exc->chain);
} }
exc = exc->prev; exc = exc->prev;
...@@ -1176,6 +1193,7 @@ static int ssl_excert_prepend(SSL_EXCERT **pexc) ...@@ -1176,6 +1193,7 @@ static int ssl_excert_prepend(SSL_EXCERT **pexc)
exc->key = NULL; exc->key = NULL;
exc->chain = NULL; exc->chain = NULL;
exc->prev = NULL; exc->prev = NULL;
exc->build_chain = 0;
exc->next = *pexc; exc->next = *pexc;
*pexc = exc; *pexc = exc;
...@@ -1260,6 +1278,7 @@ int args_excert(char ***pargs, int *pargc, ...@@ -1260,6 +1278,7 @@ int args_excert(char ***pargs, int *pargc,
{ {
char *arg = **pargs, *argn = (*pargs)[1]; char *arg = **pargs, *argn = (*pargs)[1];
SSL_EXCERT *exc = *pexc; SSL_EXCERT *exc = *pexc;
int narg = 2;
if (!exc) if (!exc)
{ {
if (ssl_excert_prepend(&exc)) if (ssl_excert_prepend(&exc))
...@@ -1316,6 +1335,11 @@ int args_excert(char ***pargs, int *pargc, ...@@ -1316,6 +1335,11 @@ int args_excert(char ***pargs, int *pargc,
} }
exc->chainfile = argn; exc->chainfile = argn;
} }
else if (strcmp(arg,"-xchain_build") == 0)
{
narg = 1;
exc->build_chain = 1;
}
else if (strcmp(arg,"-xcertform") == 0) else if (strcmp(arg,"-xcertform") == 0)
{ {
if (!argn) if (!argn)
...@@ -1337,10 +1361,10 @@ int args_excert(char ***pargs, int *pargc, ...@@ -1337,10 +1361,10 @@ int args_excert(char ***pargs, int *pargc,
else else
return 0; return 0;
(*pargs) += 2; (*pargs) += narg;
if (pargc) if (pargc)
*pargc -= 2; *pargc -= narg;
*pexc = exc; *pexc = exc;
......
...@@ -559,6 +559,7 @@ int MAIN(int argc, char **argv) ...@@ -559,6 +559,7 @@ int MAIN(int argc, char **argv)
{ {
unsigned int off=0, clr=0; unsigned int off=0, clr=0;
unsigned int cert_flags=0; unsigned int cert_flags=0;
int build_chain = 0;
SSL *con=NULL; SSL *con=NULL;
#ifndef OPENSSL_NO_KRB5 #ifndef OPENSSL_NO_KRB5
KSSL_CTX *kctx; KSSL_CTX *kctx;
...@@ -877,6 +878,8 @@ int MAIN(int argc, char **argv) ...@@ -877,6 +878,8 @@ int MAIN(int argc, char **argv)
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
CApath= *(++argv); CApath= *(++argv);
} }
else if (strcmp(*argv,"-build_chain") == 0)
build_chain = 1;
else if (strcmp(*argv,"-CAfile") == 0) else if (strcmp(*argv,"-CAfile") == 0)
{ {
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
...@@ -1212,8 +1215,6 @@ bad: ...@@ -1212,8 +1215,6 @@ bad:
#endif #endif
SSL_CTX_set_verify(ctx,verify,verify_callback); 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)) || if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
(!SSL_CTX_set_default_verify_paths(ctx))) (!SSL_CTX_set_default_verify_paths(ctx)))
...@@ -1223,6 +1224,9 @@ bad: ...@@ -1223,6 +1224,9 @@ bad:
/* goto end; */ /* goto end; */
} }
if (!set_cert_key_stuff(ctx,cert,key, NULL, build_chain))
goto end;
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
if (curves != NULL) if (curves != NULL)
if(!SSL_CTX_set1_curves_list(ctx,curves)) { if(!SSL_CTX_set1_curves_list(ctx,curves)) {
......
...@@ -215,6 +215,9 @@ static int generate_session_id(const SSL *ssl, unsigned char *id, ...@@ -215,6 +215,9 @@ static int generate_session_id(const SSL *ssl, unsigned char *id,
unsigned int *id_len); unsigned int *id_len);
static void init_session_cache_ctx(SSL_CTX *sctx); static void init_session_cache_ctx(SSL_CTX *sctx);
static void free_sessions(void); 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 #ifndef OPENSSL_NO_DH
static DH *load_dh_param(const char *dhfile); static DH *load_dh_param(const char *dhfile);
static DH *get_dh512(void); static DH *get_dh512(void);
...@@ -952,6 +955,8 @@ int MAIN(int argc, char *argv[]) ...@@ -952,6 +955,8 @@ int MAIN(int argc, char *argv[])
int badarg = 0; int badarg = 0;
short port=PORT; short port=PORT;
char *CApath=NULL,*CAfile=NULL; char *CApath=NULL,*CAfile=NULL;
char *chCApath=NULL,*chCAfile=NULL;
char *vfyCApath=NULL,*vfyCAfile=NULL;
unsigned char *context = NULL; unsigned char *context = NULL;
char *dhfile = NULL; char *dhfile = NULL;
#ifndef OPENSSL_NO_ECDH #ifndef OPENSSL_NO_ECDH
...@@ -961,6 +966,7 @@ int MAIN(int argc, char *argv[]) ...@@ -961,6 +966,7 @@ int MAIN(int argc, char *argv[])
int ret=1; int ret=1;
int off=0; int off=0;
unsigned int cert_flags = 0; unsigned int cert_flags = 0;
int build_chain = 0;
int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0; int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
int state=0; int state=0;
const SSL_METHOD *meth=NULL; const SSL_METHOD *meth=NULL;
...@@ -1135,6 +1141,16 @@ int MAIN(int argc, char *argv[]) ...@@ -1135,6 +1141,16 @@ int MAIN(int argc, char *argv[])
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
CApath= *(++argv); 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) else if (strcmp(*argv,"-no_cache") == 0)
no_cache = 1; no_cache = 1;
else if (strcmp(*argv,"-ext_cache") == 0) else if (strcmp(*argv,"-ext_cache") == 0)
...@@ -1162,11 +1178,23 @@ int MAIN(int argc, char *argv[]) ...@@ -1162,11 +1178,23 @@ int MAIN(int argc, char *argv[])
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
cipher= *(++argv); cipher= *(++argv);
} }
else if (strcmp(*argv,"-build_chain") == 0)
build_chain = 1;
else if (strcmp(*argv,"-CAfile") == 0) else if (strcmp(*argv,"-CAfile") == 0)
{ {
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
CAfile= *(++argv); 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 #ifdef FIONBIO
else if (strcmp(*argv,"-nbio") == 0) else if (strcmp(*argv,"-nbio") == 0)
{ s_nbio=1; } { s_nbio=1; }
...@@ -1672,6 +1700,13 @@ bad: ...@@ -1672,6 +1700,13 @@ bad:
if (vpm) if (vpm)
SSL_CTX_set1_param(ctx, 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 #ifndef OPENSSL_NO_TLSEXT
if (s_cert2) if (s_cert2)
{ {
...@@ -1834,19 +1869,19 @@ bad: ...@@ -1834,19 +1869,19 @@ bad:
} }
#endif #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; goto end;
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
if (s_authz_file != NULL && !SSL_CTX_use_authz_file(ctx, s_authz_file)) if (s_authz_file != NULL && !SSL_CTX_use_authz_file(ctx, s_authz_file))
goto end; goto end;
#endif #endif
#ifndef OPENSSL_NO_TLSEXT #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; goto end;
#endif #endif
if (s_dcert != NULL) 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; goto end;
} }
...@@ -3305,7 +3340,36 @@ static void free_sessions(void) ...@@ -3305,7 +3340,36 @@ static void free_sessions(void)
} }
first = NULL; 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;
}
......
...@@ -3449,6 +3449,15 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) ...@@ -3449,6 +3449,15 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
return 0; return 0;
return ssl3_set_req_cert_type(s->cert, parg, larg); 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: default:
break; break;
} }
...@@ -3746,6 +3755,15 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) ...@@ -3746,6 +3755,15 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
case SSL_CTRL_SET_CLIENT_CERT_TYPES: case SSL_CTRL_SET_CLIENT_CERT_TYPES:
return ssl3_set_req_cert_type(ctx->cert, parg, larg); 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: case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG:
ctx->tlsext_authz_server_audit_proof_cb_arg = parg; ctx->tlsext_authz_server_audit_proof_cb_arg = parg;
break; break;
......
...@@ -656,6 +656,12 @@ struct ssl_session_st ...@@ -656,6 +656,12 @@ struct ssl_session_st
*/ */
#define SSL_CERT_FLAG_TLS_STRICT 0x00000001L #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, /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
* they cannot be used to clear bits. */ * they cannot be used to clear bits. */
...@@ -1666,6 +1672,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) ...@@ -1666,6 +1672,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102 #define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102
#define SSL_CTRL_GET_CLIENT_CERT_TYPES 103 #define SSL_CTRL_GET_CLIENT_CERT_TYPES 103
#define SSL_CTRL_SET_CLIENT_CERT_TYPES 104 #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) \ #define DTLSv1_get_timeout(ssl, arg) \
SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
...@@ -1716,6 +1725,17 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) ...@@ -1716,6 +1725,17 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509) SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509)
#define SSL_CTX_add1_chain_cert(ctx,x509) \ #define SSL_CTX_add1_chain_cert(ctx,x509) \
SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)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) \ #define SSL_set0_chain(ctx,sk) \
SSL_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk) SSL_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk)
...@@ -1725,6 +1745,17 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) ...@@ -1725,6 +1745,17 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509) SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509)
#define SSL_add1_chain_cert(ctx,x509) \ #define SSL_add1_chain_cert(ctx,x509) \
SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)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) \ #define SSL_get1_curves(ctx, s) \
SSL_ctrl(ctx,SSL_CTRL_GET_CURVES,0,(char *)s) SSL_ctrl(ctx,SSL_CTRL_GET_CURVES,0,(char *)s)
#define SSL_CTX_set1_curves(ctx, clist, clistlen) \ #define SSL_CTX_set1_curves(ctx, clist, clistlen) \
...@@ -2328,6 +2359,7 @@ void ERR_load_SSL_strings(void); ...@@ -2328,6 +2359,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278 #define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278
#define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 308 #define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 308
#define SSL_F_SSL_BAD_METHOD 160 #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_BYTES_TO_CIPHER_LIST 161
#define SSL_F_SSL_CERT_DUP 221 #define SSL_F_SSL_CERT_DUP 221
#define SSL_F_SSL_CERT_INST 222 #define SSL_F_SSL_CERT_INST 222
......
...@@ -403,6 +403,18 @@ CERT *ssl_cert_dup(CERT *cert) ...@@ -403,6 +403,18 @@ CERT *ssl_cert_dup(CERT *cert)
ret->cert_cb = cert->cert_cb; ret->cert_cb = cert->cert_cb;
ret->cert_cb_arg = cert->cert_cb_arg; 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); return(ret);
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH) #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
...@@ -500,6 +512,10 @@ void ssl_cert_free(CERT *c) ...@@ -500,6 +512,10 @@ void ssl_cert_free(CERT *c)
OPENSSL_free(c->shared_sigalgs); OPENSSL_free(c->shared_sigalgs);
if (c->ctypes) if (c->ctypes)
OPENSSL_free(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); OPENSSL_free(c);
} }
...@@ -671,13 +687,19 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk) ...@@ -671,13 +687,19 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
{ {
X509 *x; X509 *x;
int i; int i;
X509_STORE *verify_store;
X509_STORE_CTX ctx; 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)) if ((sk == NULL) || (sk_X509_num(sk) == 0))
return(0); return(0);
x=sk_X509_value(sk,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); SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,ERR_R_X509_LIB);
return(0); return(0);
...@@ -1042,12 +1064,18 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) ...@@ -1042,12 +1064,18 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
X509 *x; X509 *x;
STACK_OF(X509) *extra_certs; STACK_OF(X509) *extra_certs;
X509_STORE *chain_store;
if (cpk) if (cpk)
x = cpk->x509; x = cpk->x509;
else else
x = NULL; 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 /* If we have a certificate specific chain use it, else use
* parent ctx. * parent ctx.
*/ */
...@@ -1078,7 +1106,7 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) ...@@ -1078,7 +1106,7 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
{ {
X509_STORE_CTX xs_ctx; 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); SSLerr(SSL_F_SSL_ADD_CERT_CHAIN,ERR_R_X509_LIB);
return(0); return(0);
...@@ -1109,3 +1137,69 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) ...@@ -1109,3 +1137,69 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
return 1; 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[]= ...@@ -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_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_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_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_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_DUP), "ssl_cert_dup"},
{ERR_FUNC(SSL_F_SSL_CERT_INST), "ssl_cert_inst"}, {ERR_FUNC(SSL_F_SSL_CERT_INST), "ssl_cert_inst"},
......
...@@ -583,6 +583,12 @@ typedef struct cert_st ...@@ -583,6 +583,12 @@ typedef struct cert_st
int (*cert_cb)(SSL *ssl, void *arg); int (*cert_cb)(SSL *ssl, void *arg);
void *cert_cb_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 */ int references; /* >1 only if SSL_copy_session_id is used */
} CERT; } CERT;
...@@ -925,6 +931,8 @@ void ssl_cert_set_cert_cb(CERT *c, int (*cb)(SSL *ssl, void *arg), void *arg); ...@@ -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_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);
int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l); 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_function(SSL *s);
int ssl_undefined_void_function(void); int ssl_undefined_void_function(void);
int ssl_undefined_const_function(const SSL *s); int ssl_undefined_const_function(const SSL *s);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册