Skip to content

Commit 7f785ff

Browse files
committed
CDRIVER-3508 add OCSP URI options
- revert changes to schannel that do not account for CRL
1 parent 5489fde commit 7f785ff

22 files changed

+773
-96
lines changed

.evergreen/run-ocsp-test.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,18 @@ if [ "TEST_1" = "$TEST_COLUMN" ]; then
128128
elif [ "TEST_2" = "$TEST_COLUMN" ]; then
129129
expect_failure
130130
elif [ "TEST_3" = "$TEST_COLUMN" ]; then
131+
# Window does not soft-fail by default, users can disable revocation checking.
132+
if [ "$OS" = "WINDOWS" ]; then
133+
MONGODB_URI="$MONGODB_URI&tlsDisableCertificateRevocationCheck=true"
134+
fi
131135
expect_success
132136
elif [ "TEST_4" = "$TEST_COLUMN" ]; then
133137
expect_failure
134138
elif [ "SOFT_FAIL_TEST" = "$TEST_COLUMN" ]; then
139+
# Window does not soft-fail by default, users can disable revocation checking.
140+
if [ "$OS" = "WINDOWS" ]; then
141+
MONGODB_URI="$MONGODB_URI&tlsDisableCertificateRevocationCheck=true"
142+
fi
135143
expect_success
136144
elif [ "MALICIOUS_SERVER_TEST_1" = "$TEST_COLUMN" ]; then
137145
expect_failure

src/libmongoc/doc/configuring_tls.rst

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,6 @@
33
Configuring TLS
44
===============
55

6-
Building libmongoc with TLS support
7-
-----------------------------------
8-
9-
By default, libmongoc will attempt to find a supported TLS library and enable TLS support. This is controlled by the cmake flag ``ENABLE_SSL``, which is set to ``AUTO`` by default. Valid values are:
10-
11-
- ``AUTO`` the default behavior. Link to the system's native TLS library, or attempt to find OpenSSL.
12-
- ``DARWIN`` link to Secure Transport, the native TLS library on macOS.
13-
- ``WINDOWS`` link to Secure Channel, the native TLS on Windows.
14-
- ``OPENSSL`` link to OpenSSL (libssl). An optional install path may be specified with ``OPENSSL_ROOT``.
15-
- ``LIBRESSL`` link to LibreSSL's libtls. (LibreSSL's compatible libssl may be linked to by setting ``OPENSSL``).
16-
- ``OFF`` disable TLS support.
17-
186
Configuration with URI options
197
------------------------------
208

@@ -54,7 +42,7 @@ Client Authentication
5442

5543
When MongoDB is started with TLS enabled, it will by default require the client to provide a client certificate issued by a certificate authority specified by ``--tlsCAFile``, or an authority trusted by the native certificate store in use on the server.
5644

57-
To provide the client certificate, set the ``tlscertificatekeyfile`` in the URI to a PEM armored certificate file.
45+
To provide the client certificate, set the ``tlsCertificateKeyFile`` in the URI to a PEM armored certificate file.
5846

5947
.. code-block:: c
6048
@@ -69,10 +57,26 @@ Server Certificate Verification
6957

7058
The MongoDB C Driver will automatically verify the validity of the server certificate, such as issued by configured Certificate Authority, hostname validation, and expiration.
7159

72-
To overwrite this behaviour, it is possible to disable hostname validation, and/or allow otherwise invalid certificates. This behaviour is controlled using the ``tlsallowinvalidhostnames`` and ``tlsallowinvalidcertificates`` options. By default, both are set to ``false``. It is not recommended to change these defaults as it exposes the client to *Man In The Middle* attacks (when ``tlsallowinvalidhostnames`` is set) and otherwise invalid certificates when ``tlsallowinvalidcertificates`` is set to ``true``.
60+
To overwrite this behaviour, it is possible to disable hostname validation, OCSP endpoint revocation checking, revocation checking entirely, and allow invalid certificates.
61+
62+
This behaviour is controlled using the ``tlsAllowInvalidHostnames``, ``tlsDisableOCSPEndpointCheck``, ``tlsDisableCertificateRevocationCheck``, and ``tlsAllowInvalidCertificates`` options respectively. By default, all are set to ``false``.
63+
64+
It is not recommended to change these defaults as it exposes the client to *Man In The Middle* attacks (when ``tlsAllowInvalidHostnames`` is set), invalid certificates (when ``tlsAllowInvalidCertificates`` is set), or potentially revoked certificates (when ``tlsDisableOCSPEndpointCheck`` or ``tlsDisableCertificateRevocationCheck`` are set).
65+
66+
Supported Libraries
67+
-------------------
68+
69+
By default, libmongoc will attempt to find a supported TLS library and enable TLS support. This is controlled by the cmake flag ``ENABLE_SSL``, which is set to ``AUTO`` by default. Valid values are:
70+
71+
- ``AUTO`` the default behavior. Link to the system's native TLS library, or attempt to find OpenSSL.
72+
- ``DARWIN`` link to Secure Transport, the native TLS library on macOS.
73+
- ``WINDOWS`` link to Secure Channel, the native TLS on Windows.
74+
- ``OPENSSL`` link to OpenSSL (libssl). An optional install path may be specified with ``OPENSSL_ROOT``.
75+
- ``LIBRESSL`` link to LibreSSL's libtls. (LibreSSL's compatible libssl may be linked to by setting ``OPENSSL``).
76+
- ``OFF`` disable TLS support.
7377

7478
OpenSSL
75-
-------
79+
```````
7680

7781
The MongoDB C Driver uses OpenSSL, if available, on Linux and Unix platforms (besides macOS). Industry best practices and some regulations require the use of TLS 1.1 or newer, which requires at least OpenSSL 1.0.1. Check your OpenSSL version like so::
7882

@@ -82,33 +86,43 @@ Ensure your system's OpenSSL is a recent version (at least 1.0.1), or install a
8286

8387
cmake -DOPENSSL_ROOT_DIR=/absolute/path/to/openssl
8488

85-
When compiled against OpenSSL, the driver will attempt to load the system default certificate store, as configured by the distribution. That can be overridden by setting the ``tlscafile`` URI option or with the fields ``ca_file`` and ``ca_dir`` in the :symbol:`mongoc_ssl_opt_t`.
89+
When compiled against OpenSSL, the driver will attempt to load the system default certificate store, as configured by the distribution. That can be overridden by setting the ``tlsCAFile`` URI option or with the fields ``ca_file`` and ``ca_dir`` in the :symbol:`mongoc_ssl_opt_t`.
90+
91+
Setting ``tlsDisableOCSPEndpointCheck`` and ``tlsDisableCertificateRevocationCheck`` has no effect.
8692

8793
LibreSSL / libtls
88-
-----------------
94+
`````````````````
8995

9096
The MongoDB C Driver supports LibreSSL through the use of OpenSSL compatibility checks when configured to compile against ``openssl``. It also supports the new ``libtls`` library when configured to build against ``libressl``.
9197

98+
Setting ``tlsDisableOCSPEndpointCheck`` and ``tlsDisableCertificateRevocationCheck`` has no effect.
99+
92100
Native TLS Support on Windows (Secure Channel)
93-
----------------------------------------------
101+
``````````````````````````````````````````````
94102

95103
The MongoDB C Driver supports the Windows native TLS library (Secure Channel, or SChannel), and its native crypto library (Cryptography API: Next Generation, or CNG).
96104

97105
When compiled against the Windows native libraries, the ``ca_dir`` option of a :symbol:`mongoc_ssl_opt_t` is not supported, and will issue an error if used.
98106

99-
Encrypted PEM files (e.g., setting ``tlscertificatekeypassword``) are also not supported, and will result in error when attempting to load them.
107+
Encrypted PEM files (e.g., setting ``tlsCertificateKeyPassword``) are also not supported, and will result in error when attempting to load them.
100108

101-
When ``tlscafile`` is set, the driver will only allow server certificates issued by the authority (or authorities) provided. When no ``tlscafile`` is set, the driver will look up the Certificate Authority using the ``System Local Machine Root`` certificate store to confirm the provided certificate or the ``Current user certificate store`` if the ``System Local Machine Root`` certificate store is unavailable.
109+
When ``tlsCAFile`` is set, the driver will only allow server certificates issued by the authority (or authorities) provided. When no ``tlsCAFile`` is set, the driver will look up the Certificate Authority using the ``System Local Machine Root`` certificate store to confirm the provided certificate or the ``Current user certificate store`` if the ``System Local Machine Root`` certificate store is unavailable.
102110

103111
When ``crl_file`` is set with :symbol:`mongoc_ssl_opt_t`, the driver will import the revocation list to the ``System Local Machine Root`` certificate store.
104112

113+
Setting ``tlsDisableOCSPEndpointCheck`` has no effect.
114+
115+
Setting ``tlsAllowInvalidHostnames`` additionally consider certificates with no revocation mechanisms specified (CRL / OCSP) a non-error.
116+
105117
.. _Secure Transport:
106118

107119
Native TLS Support on macOS / Darwin (Secure Transport)
108-
-------------------------------------------------------
120+
```````````````````````````````````````````````````````
109121

110122
The MongoDB C Driver supports the Darwin (OS X, macOS, iOS, etc.) native TLS library (Secure Transport), and its native crypto library (Common Crypto, or CC).
111123

112124
When compiled against Secure Transport, the ``ca_dir`` option of a :symbol:`mongoc_ssl_opt_t` is not supported, and will issue an error if used.
113125

114-
When ``tlscafile`` is set, the driver will only allow server certificates issued by the authority (or authorities) provided. When no ``tlscafile`` is set, the driver will use the Certificate Authorities in the currently unlocked keychains.
126+
When ``tlsCAFile`` is set, the driver will only allow server certificates issued by the authority (or authorities) provided. When no ``tlsCAFile`` is set, the driver will use the Certificate Authorities in the currently unlocked keychains.
127+
128+
Setting ``tlsDisableOCSPEndpointCheck`` and ``tlsDisableCertificateRevocationCheck`` has no effect.

src/libmongoc/doc/includes/tls-options.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,10 @@
2424
- Ignore hostname verification of the certificate (e.g. Man In The Middle, using valid certificate, but issued for another hostname)
2525
* - MONGOC_URI_TLSINSECURE
2626
- tlsinsecure
27-
- {true|false}, indicating if insecure TLS options should be used. Currently this implies MONGOC_URI_TLSALLOWINVALIDCERTIFICATES and MONGOC_URI_TLSALLOWINVALIDHOSTNAMES.
27+
- {true|false}, indicating if insecure TLS options should be used. Currently this implies MONGOC_URI_TLSALLOWINVALIDCERTIFICATES and MONGOC_URI_TLSALLOWINVALIDHOSTNAMES.
28+
* - MONGOC_URI_TLSDISABLECERTIFICATEREVOCATIONCHECK
29+
- tlsdisablecertificaterevocationcheck
30+
- {true|false}, indicates if revocation checking (CRL / OCSP) should be disabled.
31+
* - MONGOC_URI_TLSDISABLEOCSPENDPOINTCHECK
32+
- tlsdisableocspendpointcheck
33+
- {true|false}, indicates if OCSP responder endpoints should not be requested when an OCSP response is not stapled.

src/libmongoc/doc/mongoc_ssl_opt_t.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ Synopsis
1616
const char *crl_file;
1717
bool weak_cert_validation;
1818
bool allow_invalid_hostname;
19-
void *padding[7];
19+
void *internal;
20+
void *padding[6];
2021
} mongoc_ssl_opt_t;
2122
2223
Description

src/libmongoc/src/mongoc/mongoc-client-pool.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616

1717

18-
1918
#include "mongoc.h"
2019
#include "mongoc-apm-private.h"
2120
#include "mongoc-counters-private.h"
@@ -58,17 +57,16 @@ void
5857
mongoc_client_pool_set_ssl_opts (mongoc_client_pool_t *pool,
5958
const mongoc_ssl_opt_t *opts)
6059
{
61-
BSON_ASSERT (pool);
62-
6360
bson_mutex_lock (&pool->mutex);
6461

65-
_mongoc_ssl_opts_cleanup (&pool->ssl_opts);
62+
_mongoc_ssl_opts_cleanup (&pool->ssl_opts,
63+
false /* don't free internal opts. */);
6664

67-
memset (&pool->ssl_opts, 0, sizeof pool->ssl_opts);
6865
pool->ssl_opts_set = false;
6966

7067
if (opts) {
71-
_mongoc_ssl_opts_copy_to (opts, &pool->ssl_opts);
68+
_mongoc_ssl_opts_copy_to (
69+
opts, &pool->ssl_opts, false /* don't overwrite internal opts. */);
7270
pool->ssl_opts_set = true;
7371
}
7472

@@ -77,6 +75,20 @@ mongoc_client_pool_set_ssl_opts (mongoc_client_pool_t *pool,
7775

7876
bson_mutex_unlock (&pool->mutex);
7977
}
78+
79+
void
80+
_mongoc_client_pool_set_internal_tls_opts (
81+
mongoc_client_pool_t *pool, _mongoc_internal_tls_opts_t *internal)
82+
{
83+
bson_mutex_lock (&pool->mutex);
84+
if (!pool->ssl_opts_set) {
85+
return;
86+
}
87+
pool->ssl_opts.internal = bson_malloc (sizeof (_mongoc_internal_tls_opts_t));
88+
memcpy (
89+
pool->ssl_opts.internal, internal, sizeof (_mongoc_internal_tls_opts_t));
90+
bson_mutex_unlock (&pool->mutex);
91+
}
8092
#endif
8193

8294

@@ -143,10 +155,12 @@ mongoc_client_pool_new (const mongoc_uri_t *uri)
143155
#ifdef MONGOC_ENABLE_SSL
144156
if (mongoc_uri_get_tls (pool->uri)) {
145157
mongoc_ssl_opt_t ssl_opt = {0};
158+
_mongoc_internal_tls_opts_t internal_tls_opts = {0};
146159

147-
_mongoc_ssl_opts_from_uri (&ssl_opt, pool->uri);
160+
_mongoc_ssl_opts_from_uri (&ssl_opt, &internal_tls_opts, pool->uri);
148161
/* sets use_ssl = true */
149162
mongoc_client_pool_set_ssl_opts (pool, &ssl_opt);
163+
_mongoc_client_pool_set_internal_tls_opts (pool, &internal_tls_opts);
150164
}
151165
#endif
152166
mongoc_counter_client_pools_active_inc ();
@@ -184,7 +198,7 @@ mongoc_client_pool_destroy (mongoc_client_pool_t *pool)
184198
mongoc_cond_destroy (&pool->cond);
185199

186200
#ifdef MONGOC_ENABLE_SSL
187-
_mongoc_ssl_opts_cleanup (&pool->ssl_opts);
201+
_mongoc_ssl_opts_cleanup (&pool->ssl_opts, true);
188202
#endif
189203

190204
bson_free (pool);

src/libmongoc/src/mongoc/mongoc-client.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -975,17 +975,34 @@ mongoc_client_new (const char *uri_string)
975975
*/
976976

977977
#ifdef MONGOC_ENABLE_SSL
978+
/* Only called internally. Caller must ensure opts->internal is valid. */
979+
void
980+
_mongoc_client_set_internal_tls_opts (mongoc_client_t *client,
981+
_mongoc_internal_tls_opts_t *internal)
982+
{
983+
if (!client->use_ssl) {
984+
return;
985+
}
986+
client->ssl_opts.internal =
987+
bson_malloc (sizeof (_mongoc_internal_tls_opts_t));
988+
memcpy (client->ssl_opts.internal,
989+
internal,
990+
sizeof (_mongoc_internal_tls_opts_t));
991+
}
992+
978993
void
979994
mongoc_client_set_ssl_opts (mongoc_client_t *client,
980995
const mongoc_ssl_opt_t *opts)
981996
{
982997
BSON_ASSERT (client);
983998
BSON_ASSERT (opts);
984999

985-
_mongoc_ssl_opts_cleanup (&client->ssl_opts);
1000+
_mongoc_ssl_opts_cleanup (&client->ssl_opts,
1001+
false /* don't free internal opts */);
9861002

9871003
client->use_ssl = true;
988-
_mongoc_ssl_opts_copy_to (opts, &client->ssl_opts);
1004+
_mongoc_ssl_opts_copy_to (
1005+
opts, &client->ssl_opts, false /* don't overwrite internal opts */);
9891006

9901007
if (client->topology->single_threaded) {
9911008
mongoc_topology_scanner_set_ssl_opts (client->topology->scanner,
@@ -1091,10 +1108,12 @@ _mongoc_client_new_from_uri (mongoc_topology_t *topology)
10911108
client->use_ssl = false;
10921109
if (mongoc_uri_get_tls (client->uri)) {
10931110
mongoc_ssl_opt_t ssl_opt = {0};
1111+
_mongoc_internal_tls_opts_t internal_tls_opts = {0};
10941112

1095-
_mongoc_ssl_opts_from_uri (&ssl_opt, client->uri);
1113+
_mongoc_ssl_opts_from_uri (&ssl_opt, &internal_tls_opts, client->uri);
10961114
/* sets use_ssl = true */
10971115
mongoc_client_set_ssl_opts (client, &ssl_opt);
1116+
_mongoc_client_set_internal_tls_opts (client, &internal_tls_opts);
10981117
}
10991118
#endif
11001119

@@ -1137,7 +1156,7 @@ mongoc_client_destroy (mongoc_client_t *client)
11371156
mongoc_set_destroy (client->client_sessions);
11381157

11391158
#ifdef MONGOC_ENABLE_SSL
1140-
_mongoc_ssl_opts_cleanup (&client->ssl_opts);
1159+
_mongoc_ssl_opts_cleanup (&client->ssl_opts, true);
11411160
#endif
11421161

11431162
bson_free (client);
@@ -1638,8 +1657,9 @@ _mongoc_client_retryable_write_command_with_stream (
16381657
retry_server_stream = mongoc_cluster_stream_for_writes (
16391658
&client->cluster, parts->assembled.session, NULL, &ignored_error);
16401659

1641-
if (retry_server_stream && retry_server_stream->sd->max_wire_version >=
1642-
WIRE_VERSION_RETRY_WRITES) {
1660+
if (retry_server_stream &&
1661+
retry_server_stream->sd->max_wire_version >=
1662+
WIRE_VERSION_RETRY_WRITES) {
16431663
parts->assembled.server_stream = retry_server_stream;
16441664
bson_destroy (reply);
16451665
GOTO (retry);

src/libmongoc/src/mongoc/mongoc-secure-channel.c

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -383,17 +383,8 @@ mongoc_secure_channel_setup_ca (
383383
L"Root"); /* system store name. "My" or "Root" */
384384

385385
if (cert_store == NULL) {
386-
cert_store = CertOpenStore (
387-
CERT_STORE_PROV_SYSTEM, /* provider */
388-
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* certificate encoding */
389-
0, /* unused */
390-
CERT_SYSTEM_STORE_CURRENT_USER, /* dwFlags */
391-
L"My"); /* system store name. "My" or "Root" */
392-
393-
if (cert_store == NULL) {
394-
MONGOC_ERROR ("Error opening certificate store");
395-
return false;
396-
}
386+
MONGOC_ERROR ("Error opening certificate store");
387+
return false;
397388
}
398389

399390
if (CertAddCertificateContextToStore (
@@ -830,10 +821,10 @@ mongoc_secure_channel_handshake_step_2 (mongoc_stream_tls_t *tls,
830821
"has expired");
831822
break;
832823
case CRYPT_E_NO_REVOCATION_CHECK:
833-
/* This seems to be raised also when hostname doesn't match the
834-
* certificate */
835-
MONGOC_ERROR ("SSL Certification verification failed: failed "
836-
"revocation/hostname check");
824+
MONGOC_ERROR ("SSL Certification verification failed: certificate "
825+
"does not include revocation check. Set "
826+
"tlsDisableCertificateRevocationCheck to disable "
827+
"revocation checking");
837828
break;
838829

839830
case SEC_E_INSUFFICIENT_MEMORY:

src/libmongoc/src/mongoc/mongoc-ssl-private.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,32 @@
2525

2626
BSON_BEGIN_DECLS
2727

28+
typedef struct {
29+
bool tls_disable_certificate_revocation_check;
30+
bool tls_disable_ocsp_endpoint_check;
31+
} _mongoc_internal_tls_opts_t;
2832

2933
char *
3034
mongoc_ssl_extract_subject (const char *filename, const char *passphrase);
3135

3236
void
33-
_mongoc_ssl_opts_from_uri (mongoc_ssl_opt_t *ssl_opt, mongoc_uri_t *uri);
37+
_mongoc_ssl_opts_from_uri (mongoc_ssl_opt_t *ssl_opt,
38+
_mongoc_internal_tls_opts_t *internal,
39+
mongoc_uri_t *uri);
3440
void
35-
_mongoc_ssl_opts_copy_to (const mongoc_ssl_opt_t *src, mongoc_ssl_opt_t *dst);
41+
_mongoc_ssl_opts_copy_to (const mongoc_ssl_opt_t *src,
42+
mongoc_ssl_opt_t *dst,
43+
bool copy_internal);
44+
45+
bool
46+
_mongoc_ssl_opts_disable_certificate_revocation_check (
47+
const mongoc_ssl_opt_t *ssl_opt);
48+
49+
bool
50+
_mongoc_ssl_opts_disable_ocsp_endpoint_check (const mongoc_ssl_opt_t *ssl_opt);
51+
3652
void
37-
_mongoc_ssl_opts_cleanup (mongoc_ssl_opt_t *opt);
53+
_mongoc_ssl_opts_cleanup (mongoc_ssl_opt_t *opt, bool free_internal);
3854

3955
BSON_END_DECLS
4056

0 commit comments

Comments
 (0)