Skip to content

Commit

Permalink
Add SSL_(CTX_)?get0_(verify|chain)_cert_store functions
Browse files Browse the repository at this point in the history
Currently we do not have any way to retrieve these values once set.

Fixes openssl#18035.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from openssl#18038)
  • Loading branch information
hlandau authored and t8m committed Apr 6, 2022
1 parent ed7c64f commit 948cf52
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 1 deletion.
13 changes: 12 additions & 1 deletion doc/man3/SSL_CTX_set1_verify_cert_store.pod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
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_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

=head1 SYNOPSIS
Expand All @@ -16,11 +18,15 @@ verification or chain store
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_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_set1_verify_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_get0_verify_cert_store(SSL *ctx, X509_STORE **st);
int SSL_get0_chain_cert_store(SSL *ctx, X509_STORE **st);

=head1 DESCRIPTION

Expand All @@ -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
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>
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
Expand Down
11 changes: 11 additions & 0 deletions include/openssl/ssl.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
# define SSL_CTRL_GET_NEGOTIATED_GROUP 134
# define SSL_CTRL_GET_IANA_GROUPS 135
# 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_NEXT 2
# define SSL_CERT_SET_SERVER 3
Expand Down Expand Up @@ -1371,10 +1373,14 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
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_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) \
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_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) \
SSL_ctrl(s,SSL_CTRL_CHAIN,0,(char *)(sk))
# define SSL_set1_chain(s,sk) \
Expand All @@ -1397,10 +1403,15 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
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_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) \
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_get0_chain_cert_store(s,st) \
SSL_ctrl(s,SSL_CTRL_GET_CHAIN_CERT_STORE,0,(char *)(st))

# define SSL_get1_groups(s, glist) \
SSL_ctrl(s,SSL_CTRL_GET_GROUPS,0,(int*)(glist))
# define SSL_get0_iana_groups(s, plst) \
Expand Down
12 changes: 12 additions & 0 deletions ssl/s3_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -3689,6 +3689,12 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
case SSL_CTRL_SET_CHAIN_CERT_STORE:
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:
if (s->s3.tmp.peer_sigalg == NULL)
return 0;
Expand Down Expand Up @@ -3942,6 +3948,12 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
case SSL_CTRL_SET_CHAIN_CERT_STORE:
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 :-) */
case SSL_CTRL_EXTRA_CHAIN_CERT:
if (ctx->extra_certs == NULL) {
Expand Down
6 changes: 6 additions & 0 deletions ssl/ssl_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,12 @@ int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref)
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 level;
Expand Down
1 change: 1 addition & 0 deletions ssl/ssl_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_cert_set_cert_store(CERT *c, X509_STORE *store, int chain,
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_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid,
Expand Down
168 changes: 168 additions & 0 deletions test/sslapitest.c
Original file line number Diff line number Diff line change
Expand Up @@ -9541,6 +9541,172 @@ static int test_set_alpn(void)
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)
{
int testresult = 0;
Expand Down Expand Up @@ -9842,6 +10008,8 @@ int setup_tests(void)
#endif
ADD_TEST(test_inherit_verify_param);
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);
return 1;

Expand Down
4 changes: 4 additions & 0 deletions util/other.syms
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,8 @@ SSL_CTX_decrypt_session_ticket_fn define
SSL_CTX_disable_ct define
SSL_CTX_generate_session_ticket_fn 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_extra_chain_certs define
SSL_CTX_get_extra_chain_certs_only define
Expand Down Expand Up @@ -540,6 +542,8 @@ SSL_disable_ct define
SSL_get0_chain_certs define
SSL_get0_iana_groups define
SSL_get0_session define
SSL_get0_chain_cert_store define
SSL_get0_verify_cert_store define
SSL_get1_curves define
SSL_get1_groups define
SSL_get_cipher define
Expand Down

0 comments on commit 948cf52

Please sign in to comment.