From 74ecfab401fe65d23d9b297bf396efca3e419e47 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 23 Jul 2012 23:34:28 +0000 Subject: [PATCH] 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. --- CHANGES | 13 +++++++ apps/s_apps.h | 2 +- apps/s_cb.c | 32 ++++++++++++++-- apps/s_client.c | 8 +++- apps/s_server.c | 72 ++++++++++++++++++++++++++++++++++-- ssl/s3_lib.c | 18 +++++++++ ssl/ssl.h | 32 ++++++++++++++++ ssl/ssl_cert.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++- ssl/ssl_err.c | 1 + ssl/ssl_locl.h | 8 ++++ 10 files changed, 271 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index 8759585721..7e9e7c5395 100644 --- a/CHANGES +++ b/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. diff --git a/apps/s_apps.h b/apps/s_apps.h index c04e2d3611..c7e6926a27 100644 --- a/apps/s_apps.h +++ b/apps/s_apps.h @@ -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); diff --git a/apps/s_cb.c b/apps/s_cb.c index afc30f2650..2ac3f969a8 100644 --- a/apps/s_cb.c +++ b/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; diff --git a/apps/s_client.c b/apps/s_client.c index 97f7cbd922..783a49e083 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -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)) { diff --git a/apps/s_server.c b/apps/s_server.c index 5dd9e8e059..bbe24929fb 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -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; + } diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 457a5c7b5c..3bc5ce952a 100644 --- a/ssl/s3_lib.c +++ b/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; diff --git a/ssl/ssl.h b/ssl/ssl.h index 0e78fb7d66..ff6dcd7d11 100644 --- a/ssl/ssl.h +++ b/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 diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 59a8544431..95478141a8 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -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; + } + diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index a51937b93f..9301013727 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -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"}, diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index e64228fbac..7b1c12c662 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -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); -- 2.25.1