Add SSL_(CTX_)?get0_(verify|chain)_cert_store functions

Currently we do not have any way to retrieve these values once set.

Fixes #18035.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18038)
This commit is contained in:
Hugo Landau 2022-04-04 14:36:20 +01:00 committed by Tomas Mraz
parent ed7c64fc54
commit 948cf52179
7 changed files with 214 additions and 1 deletions

View File

@ -5,7 +5,9 @@
SSL_CTX_set0_verify_cert_store, SSL_CTX_set1_verify_cert_store, SSL_CTX_set0_verify_cert_store, SSL_CTX_set1_verify_cert_store,
SSL_CTX_set0_chain_cert_store, SSL_CTX_set1_chain_cert_store, SSL_CTX_set0_chain_cert_store, SSL_CTX_set1_chain_cert_store,
SSL_set0_verify_cert_store, SSL_set1_verify_cert_store, SSL_set0_verify_cert_store, SSL_set1_verify_cert_store,
SSL_set0_chain_cert_store, SSL_set1_chain_cert_store - set certificate SSL_set0_chain_cert_store, SSL_set1_chain_cert_store,
SSL_CTX_get0_verify_cert_store, SSL_CTX_get0_chain_cert_store,
SSL_get0_verify_cert_store, SSL_get0_chain_cert_store - set certificate
verification or chain store verification or chain store
=head1 SYNOPSIS =head1 SYNOPSIS
@ -16,11 +18,15 @@ verification or chain store
int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, X509_STORE *st); int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, X509_STORE *st);
int SSL_CTX_set0_chain_cert_store(SSL_CTX *ctx, X509_STORE *st); int SSL_CTX_set0_chain_cert_store(SSL_CTX *ctx, X509_STORE *st);
int SSL_CTX_set1_chain_cert_store(SSL_CTX *ctx, X509_STORE *st); int SSL_CTX_set1_chain_cert_store(SSL_CTX *ctx, X509_STORE *st);
int SSL_CTX_get0_verify_cert_store(SSL_CTX *ctx, X509_STORE **st);
int SSL_CTX_get0_chain_cert_store(SSL_CTX *ctx, X509_STORE **st);
int SSL_set0_verify_cert_store(SSL *ctx, X509_STORE *st); int SSL_set0_verify_cert_store(SSL *ctx, X509_STORE *st);
int SSL_set1_verify_cert_store(SSL *ctx, X509_STORE *st); int SSL_set1_verify_cert_store(SSL *ctx, X509_STORE *st);
int SSL_set0_chain_cert_store(SSL *ctx, X509_STORE *st); int SSL_set0_chain_cert_store(SSL *ctx, X509_STORE *st);
int SSL_set1_chain_cert_store(SSL *ctx, X509_STORE *st); int SSL_set1_chain_cert_store(SSL *ctx, X509_STORE *st);
int SSL_get0_verify_cert_store(SSL *ctx, X509_STORE **st);
int SSL_get0_chain_cert_store(SSL *ctx, X509_STORE **st);
=head1 DESCRIPTION =head1 DESCRIPTION
@ -34,6 +40,11 @@ SSL_set0_verify_cert_store(), SSL_set1_verify_cert_store(),
SSL_set0_chain_cert_store() and SSL_set1_chain_cert_store() are similar SSL_set0_chain_cert_store() and SSL_set1_chain_cert_store() are similar
except they apply to SSL structure B<ssl>. except they apply to SSL structure B<ssl>.
SSL_CTX_get0_verify_chain_store(), SSL_get0_verify_chain_store(),
SSL_CTX_get0_chain_cert_store() and SSL_get0_chain_cert_store() retrieve the
objects previously set via the above calls. A pointer to the object (or NULL if
no such object has been set) is written to B<*st>.
All these functions are implemented as macros. Those containing a B<1> All these functions are implemented as macros. Those containing a B<1>
increment the reference count of the supplied store so it must increment the reference count of the supplied store so it must
be freed at some point after the operation. Those containing a B<0> do be freed at some point after the operation. Those containing a B<0> do

View File

@ -1310,6 +1310,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
# define SSL_CTRL_GET_NEGOTIATED_GROUP 134 # define SSL_CTRL_GET_NEGOTIATED_GROUP 134
# define SSL_CTRL_GET_IANA_GROUPS 135 # define SSL_CTRL_GET_IANA_GROUPS 135
# define SSL_CTRL_SET_RETRY_VERIFY 136 # define SSL_CTRL_SET_RETRY_VERIFY 136
# define SSL_CTRL_GET_VERIFY_CERT_STORE 137
# define SSL_CTRL_GET_CHAIN_CERT_STORE 138
# define SSL_CERT_SET_FIRST 1 # define SSL_CERT_SET_FIRST 1
# define SSL_CERT_SET_NEXT 2 # define SSL_CERT_SET_NEXT 2
# define SSL_CERT_SET_SERVER 3 # define SSL_CERT_SET_SERVER 3
@ -1371,10 +1373,14 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st)) SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st))
# define SSL_CTX_set1_verify_cert_store(ctx,st) \ # define SSL_CTX_set1_verify_cert_store(ctx,st) \
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st)) SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st))
# define SSL_CTX_get0_verify_cert_store(ctx,st) \
SSL_CTX_ctrl(ctx,SSL_CTRL_GET_VERIFY_CERT_STORE,0,(char *)(st))
# define SSL_CTX_set0_chain_cert_store(ctx,st) \ # define SSL_CTX_set0_chain_cert_store(ctx,st) \
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st)) SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st))
# define SSL_CTX_set1_chain_cert_store(ctx,st) \ # define SSL_CTX_set1_chain_cert_store(ctx,st) \
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st)) SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st))
# define SSL_CTX_get0_chain_cert_store(ctx,st) \
SSL_CTX_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERT_STORE,0,(char *)(st))
# define SSL_set0_chain(s,sk) \ # define SSL_set0_chain(s,sk) \
SSL_ctrl(s,SSL_CTRL_CHAIN,0,(char *)(sk)) SSL_ctrl(s,SSL_CTRL_CHAIN,0,(char *)(sk))
# define SSL_set1_chain(s,sk) \ # define SSL_set1_chain(s,sk) \
@ -1397,10 +1403,15 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st)) SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st))
# define SSL_set1_verify_cert_store(s,st) \ # define SSL_set1_verify_cert_store(s,st) \
SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st)) SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st))
#define SSL_get0_verify_cert_store(s,st) \
SSL_ctrl(s,SSL_CTRL_GET_VERIFY_CERT_STORE,0,(char *)(st))
# define SSL_set0_chain_cert_store(s,st) \ # define SSL_set0_chain_cert_store(s,st) \
SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st)) SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st))
# define SSL_set1_chain_cert_store(s,st) \ # define SSL_set1_chain_cert_store(s,st) \
SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st)) SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st))
#define SSL_get0_chain_cert_store(s,st) \
SSL_ctrl(s,SSL_CTRL_GET_CHAIN_CERT_STORE,0,(char *)(st))
# define SSL_get1_groups(s, glist) \ # define SSL_get1_groups(s, glist) \
SSL_ctrl(s,SSL_CTRL_GET_GROUPS,0,(int*)(glist)) SSL_ctrl(s,SSL_CTRL_GET_GROUPS,0,(int*)(glist))
# define SSL_get0_iana_groups(s, plst) \ # define SSL_get0_iana_groups(s, plst) \

View File

@ -3689,6 +3689,12 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
case SSL_CTRL_SET_CHAIN_CERT_STORE: case SSL_CTRL_SET_CHAIN_CERT_STORE:
return ssl_cert_set_cert_store(s->cert, parg, 1, larg); return ssl_cert_set_cert_store(s->cert, parg, 1, larg);
case SSL_CTRL_GET_VERIFY_CERT_STORE:
return ssl_cert_get_cert_store(s->cert, parg, 0);
case SSL_CTRL_GET_CHAIN_CERT_STORE:
return ssl_cert_get_cert_store(s->cert, parg, 1);
case SSL_CTRL_GET_PEER_SIGNATURE_NID: case SSL_CTRL_GET_PEER_SIGNATURE_NID:
if (s->s3.tmp.peer_sigalg == NULL) if (s->s3.tmp.peer_sigalg == NULL)
return 0; return 0;
@ -3942,6 +3948,12 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
case SSL_CTRL_SET_CHAIN_CERT_STORE: case SSL_CTRL_SET_CHAIN_CERT_STORE:
return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg); return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg);
case SSL_CTRL_GET_VERIFY_CERT_STORE:
return ssl_cert_get_cert_store(ctx->cert, parg, 0);
case SSL_CTRL_GET_CHAIN_CERT_STORE:
return ssl_cert_get_cert_store(ctx->cert, parg, 1);
/* A Thawte special :-) */ /* A Thawte special :-) */
case SSL_CTRL_EXTRA_CHAIN_CERT: case SSL_CTRL_EXTRA_CHAIN_CERT:
if (ctx->extra_certs == NULL) { if (ctx->extra_certs == NULL) {

View File

@ -971,6 +971,12 @@ int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref)
return 1; return 1;
} }
int ssl_cert_get_cert_store(CERT *c, X509_STORE **pstore, int chain)
{
*pstore = (chain ? c->chain_store : c->verify_store);
return 1;
}
int ssl_get_security_level_bits(const SSL *s, const SSL_CTX *ctx, int *levelp) int ssl_get_security_level_bits(const SSL *s, const SSL_CTX *ctx, int *levelp)
{ {
int level; int level;

View File

@ -2433,6 +2433,7 @@ __owur int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk);
__owur int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags); __owur int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags);
__owur int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, __owur int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain,
int ref); int ref);
__owur int ssl_cert_get_cert_store(CERT *c, X509_STORE **pstore, int chain);
__owur int ssl_security(const SSL *s, int op, int bits, int nid, void *other); __owur int ssl_security(const SSL *s, int op, int bits, int nid, void *other);
__owur int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid, __owur int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid,

View File

@ -9541,6 +9541,172 @@ end:
return testresult; return testresult;
} }
/*
* Test SSL_CTX_set1_verify/chain_cert_store and SSL_CTX_get_verify/chain_cert_store.
*/
static int test_set_verify_cert_store_ssl_ctx(void)
{
SSL_CTX *ctx = NULL;
int testresult = 0;
X509_STORE *store = NULL, *new_store = NULL,
*cstore = NULL, *new_cstore = NULL;
/* Create an initial SSL_CTX. */
ctx = SSL_CTX_new_ex(libctx, NULL, TLS_server_method());
if (!TEST_ptr(ctx))
goto end;
/* Retrieve verify store pointer. */
if (!TEST_true(SSL_CTX_get0_verify_cert_store(ctx, &store)))
goto end;
/* Retrieve chain store pointer. */
if (!TEST_true(SSL_CTX_get0_chain_cert_store(ctx, &cstore)))
goto end;
/* We haven't set any yet, so this should be NULL. */
if (!TEST_ptr_null(store) || !TEST_ptr_null(cstore))
goto end;
/* Create stores. We use separate stores so pointers are different. */
new_store = X509_STORE_new();
if (!TEST_ptr(new_store))
goto end;
new_cstore = X509_STORE_new();
if (!TEST_ptr(new_cstore))
goto end;
/* Set stores. */
if (!TEST_true(SSL_CTX_set1_verify_cert_store(ctx, new_store)))
goto end;
if (!TEST_true(SSL_CTX_set1_chain_cert_store(ctx, new_cstore)))
goto end;
/* Should be able to retrieve the same pointer. */
if (!TEST_true(SSL_CTX_get0_verify_cert_store(ctx, &store)))
goto end;
if (!TEST_true(SSL_CTX_get0_chain_cert_store(ctx, &cstore)))
goto end;
if (!TEST_ptr_eq(store, new_store) || !TEST_ptr_eq(cstore, new_cstore))
goto end;
/* Should be able to unset again. */
if (!TEST_true(SSL_CTX_set1_verify_cert_store(ctx, NULL)))
goto end;
if (!TEST_true(SSL_CTX_set1_chain_cert_store(ctx, NULL)))
goto end;
/* Should now be NULL. */
if (!TEST_true(SSL_CTX_get0_verify_cert_store(ctx, &store)))
goto end;
if (!TEST_true(SSL_CTX_get0_chain_cert_store(ctx, &cstore)))
goto end;
if (!TEST_ptr_null(store) || !TEST_ptr_null(cstore))
goto end;
testresult = 1;
end:
X509_STORE_free(new_store);
X509_STORE_free(new_cstore);
SSL_CTX_free(ctx);
return testresult;
}
/*
* Test SSL_set1_verify/chain_cert_store and SSL_get_verify/chain_cert_store.
*/
static int test_set_verify_cert_store_ssl(void)
{
SSL_CTX *ctx = NULL;
SSL *ssl = NULL;
int testresult = 0;
X509_STORE *store = NULL, *new_store = NULL,
*cstore = NULL, *new_cstore = NULL;
/* Create an initial SSL_CTX. */
ctx = SSL_CTX_new_ex(libctx, NULL, TLS_server_method());
if (!TEST_ptr(ctx))
goto end;
/* Create an SSL object. */
ssl = SSL_new(ctx);
if (!TEST_ptr(ssl))
goto end;
/* Retrieve verify store pointer. */
if (!TEST_true(SSL_get0_verify_cert_store(ssl, &store)))
goto end;
/* Retrieve chain store pointer. */
if (!TEST_true(SSL_get0_chain_cert_store(ssl, &cstore)))
goto end;
/* We haven't set any yet, so this should be NULL. */
if (!TEST_ptr_null(store) || !TEST_ptr_null(cstore))
goto end;
/* Create stores. We use separate stores so pointers are different. */
new_store = X509_STORE_new();
if (!TEST_ptr(new_store))
goto end;
new_cstore = X509_STORE_new();
if (!TEST_ptr(new_cstore))
goto end;
/* Set stores. */
if (!TEST_true(SSL_set1_verify_cert_store(ssl, new_store)))
goto end;
if (!TEST_true(SSL_set1_chain_cert_store(ssl, new_cstore)))
goto end;
/* Should be able to retrieve the same pointer. */
if (!TEST_true(SSL_get0_verify_cert_store(ssl, &store)))
goto end;
if (!TEST_true(SSL_get0_chain_cert_store(ssl, &cstore)))
goto end;
if (!TEST_ptr_eq(store, new_store) || !TEST_ptr_eq(cstore, new_cstore))
goto end;
/* Should be able to unset again. */
if (!TEST_true(SSL_set1_verify_cert_store(ssl, NULL)))
goto end;
if (!TEST_true(SSL_set1_chain_cert_store(ssl, NULL)))
goto end;
/* Should now be NULL. */
if (!TEST_true(SSL_get0_verify_cert_store(ssl, &store)))
goto end;
if (!TEST_true(SSL_get0_chain_cert_store(ssl, &cstore)))
goto end;
if (!TEST_ptr_null(store) || !TEST_ptr_null(cstore))
goto end;
testresult = 1;
end:
X509_STORE_free(new_store);
X509_STORE_free(new_cstore);
SSL_free(ssl);
SSL_CTX_free(ctx);
return testresult;
}
static int test_inherit_verify_param(void) static int test_inherit_verify_param(void)
{ {
int testresult = 0; int testresult = 0;
@ -9842,6 +10008,8 @@ int setup_tests(void)
#endif #endif
ADD_TEST(test_inherit_verify_param); ADD_TEST(test_inherit_verify_param);
ADD_TEST(test_set_alpn); ADD_TEST(test_set_alpn);
ADD_TEST(test_set_verify_cert_store_ssl_ctx);
ADD_TEST(test_set_verify_cert_store_ssl);
ADD_ALL_TESTS(test_session_timeout, 1); ADD_ALL_TESTS(test_session_timeout, 1);
return 1; return 1;

View File

@ -467,6 +467,8 @@ SSL_CTX_decrypt_session_ticket_fn define
SSL_CTX_disable_ct define SSL_CTX_disable_ct define
SSL_CTX_generate_session_ticket_fn define SSL_CTX_generate_session_ticket_fn define
SSL_CTX_get0_chain_certs define SSL_CTX_get0_chain_certs define
SSL_CTX_get0_chain_cert_store define
SSL_CTX_get0_verify_cert_store define
SSL_CTX_get_default_read_ahead define SSL_CTX_get_default_read_ahead define
SSL_CTX_get_extra_chain_certs define SSL_CTX_get_extra_chain_certs define
SSL_CTX_get_extra_chain_certs_only define SSL_CTX_get_extra_chain_certs_only define
@ -540,6 +542,8 @@ SSL_disable_ct define
SSL_get0_chain_certs define SSL_get0_chain_certs define
SSL_get0_iana_groups define SSL_get0_iana_groups define
SSL_get0_session define SSL_get0_session define
SSL_get0_chain_cert_store define
SSL_get0_verify_cert_store define
SSL_get1_curves define SSL_get1_curves define
SSL_get1_groups define SSL_get1_groups define
SSL_get_cipher define SSL_get_cipher define