Skip to content

Commit 10f7035

Browse files
authored
feat: Support for using OS certs in Rust (#47)
1 parent fa10c59 commit 10f7035

File tree

18 files changed

+318
-27
lines changed

18 files changed

+318
-27
lines changed

CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,18 @@ if(WIN32)
4141
DEFINE_SYMBOL "LINESENDER_DYN_LIB")
4242
target_link_libraries(
4343
questdb_client-shared
44-
INTERFACE wsock32 ws2_32 ntdll)
44+
INTERFACE wsock32 ws2_32 ntdll crypt32 Secur32 Ncrypt)
4545
target_link_libraries(
4646
questdb_client-static
47-
INTERFACE wsock32 ws2_32 ntdll)
47+
INTERFACE wsock32 ws2_32 ntdll crypt32 Secur32 Ncrypt)
4848
endif(WIN32)
4949
if(APPLE)
5050
target_link_libraries(
5151
questdb_client
5252
INTERFACE "-framework Security")
53+
target_link_libraries(
54+
questdb_client
55+
INTERFACE "-framework CoreFoundation")
5356
endif()
5457

5558
function(set_compile_flags TARGET_NAME)

cpp_test/test_line_sender.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,15 @@ TEST_CASE("Bad CA path")
548548
}
549549
}
550550

551+
TEST_CASE("os certs")
552+
{
553+
// We're just checking these APIs don't throw.
554+
questdb::ingress::test::mock_server server;
555+
questdb::ingress::opts opts{"localhost", server.port()};
556+
opts.tls_os_roots();
557+
opts.tls_webpki_and_os_roots();
558+
}
559+
551560
TEST_CASE("Opts copy ctor, assignment and move testing.")
552561
{
553562
{

doc/SECURITY.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,27 @@ Authentication can be used independently of TLS encryption.
1515

1616
## TLS Encryption
1717

18-
As of writing, whilst QuestDB itself can't be configured to support TLS natively
19-
it is recommended that you use [HAProxy](http://www.haproxy.org/) or other
18+
As of writing, only QuestDB Enterprise can be configured to support TLS natively.
19+
If you're using the open source edition, you can still use TLS encryption by setting
20+
up [HAProxy](http://www.haproxy.org/) or other proxy
2021
to secure the connection for any public-facing servers.
2122

2223
TLS can be used independently and provides no authentication itself.
2324

2425
The `tls_certs` directory of this project contains tests certificates, its
25-
[README](../tls_certs/README.md) page describes generating your own certs.
26+
[README](../tls_certs/README.md) page describes generating your own test certs.
27+
28+
A few important technical details on TLS:
29+
* The libraries use the `rustls` Rust crate for TLS support.
30+
* They also, by default, use the `webpki_roots` Rust crate for root certificate verification
31+
which require no OS-specific configuration.
32+
* Alternatively, If you want to use your operating system's root certificates,
33+
you can do so calling the `tls_os_roots` method when building the "sender" object.
34+
The latter is especially desireable in corporate environments where the certificates
35+
are managed centrally.
2636

2737
For API usage:
2838
* Rust: `SenderBuilder`'s [`auth`](https://docs.rs/questdb-rs/3.0.0/questdb/ingress/struct.SenderBuilder.html#method.auth)
2939
and [`tls`](https://docs.rs/questdb-rs/3.0.0/questdb/ingress/struct.SenderBuilder.html#method.tls) methods.
3040
* C: [examples/line_sender_c_example_auth.c](../examples/line_sender_c_example_auth.c)
31-
* C++: [examples/line_sender_cpp_example_auth.cpp](../examples/line_sender_cpp_example_auth.cpp)
41+
* C++: [examples/line_sender_cpp_example_auth.cpp](../examples/line_sender_cpp_example_auth.cpp)

examples/line_sender_c_example_auth_tls.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ static bool example(const char* host, const char* port)
2424
// Enable TLS to accept connections using common trusted CAs.
2525
line_sender_opts_tls(opts);
2626

27+
//// Alternatively, to use the OS-provided root certificates:
28+
// line_sender_opts_tls_os_roots(opts);
29+
2730
// Use `QDB_UTF_8_FROM_STR_OR` to init from `const char*`.
2831
line_sender_utf8 key_id = QDB_UTF8_LITERAL("testUser1");
2932
line_sender_utf8 priv_key = QDB_UTF8_LITERAL(

examples/line_sender_cpp_example_auth_tls.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ static bool example(
1515
// Enable TLS to accept connections using common trusted CAs.
1616
opts.tls();
1717

18+
//// Alternatively, to use the OS-provided root certificates:
19+
// opts.tls_os_roots(opts);
20+
1821
// Follow our authentication documentation to generate your own keys:
1922
// https://questdb.io/docs/reference/api/ilp/authenticate
2023
opts.auth(

include/questdb/ingress/line_sender.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,20 @@ void line_sender_opts_auth(
559559
LINESENDER_API
560560
void line_sender_opts_tls(line_sender_opts* opts);
561561

562+
/**
563+
* Enable full connection encryption via TLS, using OS-provided certificate roots.
564+
*/
565+
LINESENDER_API
566+
void line_sender_opts_tls_os_roots(line_sender_opts* opts);
567+
568+
/*
569+
* Enable full connection encryption via TLS, accepting certificates signed by either
570+
* the OS-provided certificate roots or well-known certificate authorities as per
571+
* the "webpki-roots" Rust crate.
572+
*/
573+
LINESENDER_API
574+
void line_sender_opts_tls_webpki_and_os_roots(line_sender_opts* opts);
575+
562576
/**
563577
* Enable full connection encryption via TLS.
564578
* The connection will accept certificates by the specified certificate

include/questdb/ingress/line_sender.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,26 @@ namespace questdb::ingress
743743
return *this;
744744
}
745745

746+
/*
747+
* Enable full connection encryption via TLS, using OS-provided certificate roots.
748+
*/
749+
opts& tls_os_roots() noexcept
750+
{
751+
::line_sender_opts_tls_os_roots(_impl);
752+
return *this;
753+
}
754+
755+
/*
756+
* Enable full connection encryption via TLS, accepting certificates signed by either
757+
* the OS-provided certificate roots or well-known certificate authorities as per
758+
* the "webpki-roots" Rust crate.
759+
*/
760+
opts& tls_webpki_and_os_roots() noexcept
761+
{
762+
::line_sender_opts_tls_webpki_and_os_roots(_impl);
763+
return *this;
764+
}
765+
746766
/**
747767
* Enable full connection encryption via TLS.
748768
* The connection will accept certificates by the specified certificate

questdb-rs-ffi/Cargo.lock

Lines changed: 120 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

questdb-rs-ffi/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ name = "questdb_client"
99
crate-type = ["cdylib", "staticlib"]
1010

1111
[dependencies]
12-
questdb-rs = { path = "../questdb-rs", features = ["insecure-skip-verify"] }
12+
questdb-rs = { path = "../questdb-rs", features = ["insecure-skip-verify", "tls-native-certs"] }
1313
libc = "0.2"
1414

1515
[build-dependencies]

questdb-rs-ffi/src/lib.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,24 @@ pub unsafe extern "C" fn line_sender_opts_tls(opts: *mut line_sender_opts) {
476476
upd_opts!(opts, tls, Tls::Enabled(CertificateAuthority::WebpkiRoots));
477477
}
478478

479+
/// Enable full connection encryption via TLS, using OS-provided certificate roots.
480+
#[no_mangle]
481+
pub unsafe extern "C" fn line_sender_opts_tls_os_roots(opts: *mut line_sender_opts) {
482+
upd_opts!(opts, tls, Tls::Enabled(CertificateAuthority::OsRoots));
483+
}
484+
485+
/// Enable full connection encryption via TLS, accepting certificates signed by either
486+
/// the OS-provided certificate roots or well-known certificate authorities as per
487+
/// the "webpki-roots" Rust crate.
488+
#[no_mangle]
489+
pub unsafe extern "C" fn line_sender_opts_tls_webpki_and_os_roots(opts: *mut line_sender_opts) {
490+
upd_opts!(
491+
opts,
492+
tls,
493+
Tls::Enabled(CertificateAuthority::WebpkiAndOsRoots)
494+
);
495+
}
496+
479497
/// Enable full connection encryption via TLS.
480498
/// The connection will accept certificates by the specified certificate
481499
/// authority file.

0 commit comments

Comments
 (0)