diff options
author | Hugo Landau <hlandau@openssl.org> | 2022-04-27 10:11:08 +0100 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2022-05-05 17:54:46 +1000 |
commit | ec1b4bf26c1b2440546f323873c578374f60b2de (patch) | |
tree | 0d34185c2981facb2984b20a28220873d0f2fcae | |
parent | 988c7b2d9361dd0ade5ef7ef068fb4ed770ce2a2 (diff) |
(1.1) Add SSL_(CTX_)?get0_(verify|chain)_cert_store functions
Backport of #18038 to 1.1.
Fixes #18035.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/18190)
-rw-r--r-- | doc/man3/SSL_CTX_set1_verify_cert_store.pod | 13 | ||||
-rw-r--r-- | include/openssl/ssl.h | 10 | ||||
-rw-r--r-- | ssl/s3_lib.c | 12 | ||||
-rw-r--r-- | ssl/ssl_cert.c | 6 | ||||
-rw-r--r-- | ssl/ssl_local.h | 1 | ||||
-rw-r--r-- | test/sslapitest.c | 167 | ||||
-rw-r--r-- | util/private.num | 4 |
7 files changed, 212 insertions, 1 deletions
diff --git a/doc/man3/SSL_CTX_set1_verify_cert_store.pod b/doc/man3/SSL_CTX_set1_verify_cert_store.pod index b42f2a499f..1b86826776 100644 --- a/doc/man3/SSL_CTX_set1_verify_cert_store.pod +++ b/doc/man3/SSL_CTX_set1_verify_cert_store.pod @@ -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 @@ -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 @@ -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 diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index fd0c5a9996..b744f6ccc1 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1305,6 +1305,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) # define SSL_CTRL_GET_MAX_PROTO_VERSION 131 # define SSL_CTRL_GET_SIGNATURE_NID 132 # define SSL_CTRL_GET_TMP_KEY 133 +# 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 @@ -1360,10 +1362,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) \ @@ -1386,10 +1392,14 @@ 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_CTX_set1_groups(ctx, glist, glistlen) \ diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index e4cf007f82..32f9b25710 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -3676,6 +3676,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; @@ -3949,6 +3955,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) { diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index eba96b207e..b615e7048d 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -876,6 +876,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; diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 9f346e30e8..4c36cd5c89 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -2301,6 +2301,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, diff --git a/test/sslapitest.c b/test/sslapitest.c index 6b5d9449a0..7197e15cac 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -6870,6 +6870,171 @@ end: 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(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(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; @@ -7039,6 +7204,8 @@ int setup_tests(void) ADD_ALL_TESTS(test_ticket_lifetime, 2); #endif ADD_TEST(test_set_alpn); + ADD_TEST(test_set_verify_cert_store_ssl_ctx); + ADD_TEST(test_set_verify_cert_store_ssl); ADD_TEST(test_inherit_verify_param); return 1; } diff --git a/util/private.num b/util/private.num index bc7d967b5d..27790ab8a7 100644 --- a/util/private.num +++ b/util/private.num @@ -323,6 +323,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_max_cert_list define SSL_CTX_get_max_proto_version define @@ -388,6 +390,8 @@ SSL_clear_mode define SSL_disable_ct define SSL_get0_chain_certs 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 |