Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting CA certificate during TLS connection #1009

Merged
merged 1 commit into from Oct 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions include/rtc/websocket.hpp
Expand Up @@ -39,6 +39,7 @@ class RTC_CPP_EXPORT WebSocket final : private CheshireCat<impl::WebSocket>, pub
optional<std::chrono::milliseconds> connectionTimeout; // zero to disable
optional<std::chrono::milliseconds> pingInterval; // zero to disable
optional<int> maxOutstandingPings;
optional<string> caCertificatePemFile;
};

WebSocket();
Expand Down
29 changes: 27 additions & 2 deletions src/impl/verifiedtlstransport.cpp
Expand Up @@ -13,9 +13,11 @@

namespace rtc::impl {

static const string PemBeginCertificateTag = "-----BEGIN CERTIFICATE-----";

VerifiedTlsTransport::VerifiedTlsTransport(
variant<shared_ptr<TcpTransport>, shared_ptr<HttpProxyTransport>> lower, string host,
certificate_ptr certificate, state_callback callback)
certificate_ptr certificate, state_callback callback, [[maybe_unused]] optional<string> cacert)
: TlsTransport(std::move(lower), std::move(host), std::move(certificate), std::move(callback)) {

PLOG_DEBUG << "Setting up TLS certificate verification";
Expand All @@ -24,13 +26,36 @@ VerifiedTlsTransport::VerifiedTlsTransport(
gnutls_session_set_verify_cert(mSession, mHost->c_str(), 0);
#elif USE_MBEDTLS
mbedtls_ssl_conf_authmode(&mConf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_x509_crt_init(&mCaCert);
try {
if (cacert) {
if (cacert->find(PemBeginCertificateTag) == string::npos) {
// *cacert is a file path
mbedtls::check(mbedtls_x509_crt_parse_file(&mCaCert, cacert->c_str()));
} else {
// *cacert is a PEM content
mbedtls::check(mbedtls_x509_crt_parse(
&mCaCert, reinterpret_cast<const unsigned char *>(cacert->c_str()),
cacert->size()));
}
mbedtls_ssl_conf_ca_chain(&mConf, &mCaCert, NULL);
}
} catch (...) {
mbedtls_x509_crt_free(&mCaCert);
throw;
}
#else
SSL_set_verify(mSsl, SSL_VERIFY_PEER, NULL);
SSL_set_verify_depth(mSsl, 4);
#endif
}

VerifiedTlsTransport::~VerifiedTlsTransport() { stop(); }
VerifiedTlsTransport::~VerifiedTlsTransport() {
stop();
#if USE_MBEDTLS
mbedtls_x509_crt_free(&mCaCert);
#endif
}

} // namespace rtc::impl

Expand Down
8 changes: 7 additions & 1 deletion src/impl/verifiedtlstransport.hpp
Expand Up @@ -18,8 +18,14 @@ namespace rtc::impl {
class VerifiedTlsTransport final : public TlsTransport {
public:
VerifiedTlsTransport(variant<shared_ptr<TcpTransport>, shared_ptr<HttpProxyTransport>> lower,
string host, certificate_ptr certificate, state_callback callback);
string host, certificate_ptr certificate, state_callback callback,
optional<string> cacert);
~VerifiedTlsTransport();

private:
#if USE_MBEDTLS
mbedtls_x509_crt mCaCert;
#endif
};

} // namespace rtc::impl
Expand Down
3 changes: 2 additions & 1 deletion src/impl/websocket.cpp
Expand Up @@ -358,7 +358,8 @@ shared_ptr<TlsTransport> WebSocket::initTlsTransport() {
shared_ptr<TlsTransport> transport;
if (verify)
transport = std::make_shared<VerifiedTlsTransport>(lower, mHostname.value(),
mCertificate, stateChangeCallback);
mCertificate, stateChangeCallback,
config.caCertificatePemFile);
else
transport =
std::make_shared<TlsTransport>(lower, mHostname, mCertificate, stateChangeCallback);
Expand Down