Browse Source

Mutualized gnutls and openssl helper functions

Paul-Louis Ageneau 5 years ago
parent
commit
749ac31290
12 changed files with 309 additions and 307 deletions
  1. 1 0
      CMakeLists.txt
  2. 37 93
      src/certificate.cpp
  3. 1 6
      src/certificate.hpp
  4. 18 17
      src/dtlssrtptransport.cpp
  5. 0 1
      src/dtlssrtptransport.hpp
  6. 26 89
      src/dtlstransport.cpp
  7. 1 6
      src/dtlstransport.hpp
  8. 2 10
      src/init.cpp
  9. 132 0
      src/tls.cpp
  10. 73 0
      src/tls.hpp
  11. 17 79
      src/tlstransport.cpp
  12. 1 6
      src/tlstransport.hpp

+ 1 - 0
CMakeLists.txt

@@ -35,6 +35,7 @@ set(LIBDATACHANNEL_SOURCES
 	${CMAKE_CURRENT_SOURCE_DIR}/src/peerconnection.cpp
 	${CMAKE_CURRENT_SOURCE_DIR}/src/peerconnection.cpp
 	${CMAKE_CURRENT_SOURCE_DIR}/src/rtc.cpp
 	${CMAKE_CURRENT_SOURCE_DIR}/src/rtc.cpp
 	${CMAKE_CURRENT_SOURCE_DIR}/src/sctptransport.cpp
 	${CMAKE_CURRENT_SOURCE_DIR}/src/sctptransport.cpp
+	${CMAKE_CURRENT_SOURCE_DIR}/src/tls.cpp
 )
 )
 
 
 set(LIBDATACHANNEL_WEBSOCKET_SOURCES
 set(LIBDATACHANNEL_WEBSOCKET_SOURCES

+ 37 - 93
src/certificate.cpp

@@ -31,93 +31,43 @@ using std::unique_ptr;
 
 
 #if USE_GNUTLS
 #if USE_GNUTLS
 
 
-#include <gnutls/crypto.h>
-
-namespace {
-
-void check_gnutls(int ret, const string &message = "GnuTLS error") {
-	if (ret != GNUTLS_E_SUCCESS)
-		throw std::runtime_error(message + ": " + gnutls_strerror(ret));
-}
-
-gnutls_certificate_credentials_t *create_credentials() {
-	auto creds = new gnutls_certificate_credentials_t;
-	check_gnutls(gnutls_certificate_allocate_credentials(creds));
-	return creds;
-}
-
-void delete_credentials(gnutls_certificate_credentials_t *creds) {
-	gnutls_certificate_free_credentials(*creds);
-	delete creds;
-}
-
-gnutls_x509_crt_t *create_crt() {
-	auto crt = new gnutls_x509_crt_t;
-	check_gnutls(gnutls_x509_crt_init(crt));
-	return crt;
-}
-
-void delete_crt(gnutls_x509_crt_t *crt) {
-	gnutls_x509_crt_deinit(*crt);
-	delete crt;
-}
-
-gnutls_x509_privkey_t *create_privkey() {
-	auto privkey = new gnutls_x509_privkey_t;
-	check_gnutls(gnutls_x509_privkey_init(privkey));
-	return privkey;
-}
-
-void delete_privkey(gnutls_x509_privkey_t *privkey) {
-	gnutls_x509_privkey_deinit(*privkey);
-	delete privkey;
-}
-
-gnutls_datum_t make_datum(char *data, size_t size) {
-	gnutls_datum_t datum;
-	datum.data = reinterpret_cast<unsigned char *>(data);
-	datum.size = size;
-	return datum;
-}
-
-} // namespace
-
 namespace rtc {
 namespace rtc {
 
 
 Certificate::Certificate(string crt_pem, string key_pem)
 Certificate::Certificate(string crt_pem, string key_pem)
-    : mCredentials(create_credentials(), delete_credentials) {
+    : mCredentials(gnutls::new_credentials(), gnutls::free_credentials) {
 
 
-	gnutls_datum_t crt_datum = make_datum(crt_pem.data(), crt_pem.size());
-	gnutls_datum_t key_datum = make_datum(key_pem.data(), key_pem.size());
+	gnutls_datum_t crt_datum = gnutls::make_datum(crt_pem.data(), crt_pem.size());
+	gnutls_datum_t key_datum = gnutls::make_datum(key_pem.data(), key_pem.size());
 
 
-	check_gnutls(gnutls_certificate_set_x509_key_mem(*mCredentials, &crt_datum, &key_datum,
-	                                                 GNUTLS_X509_FMT_PEM),
-	             "Unable to import PEM");
+	gnutls::check(gnutls_certificate_set_x509_key_mem(*mCredentials, &crt_datum, &key_datum,
+	                                                  GNUTLS_X509_FMT_PEM),
+	              "Unable to import PEM");
 
 
-	auto create_crt_list = [this]() -> gnutls_x509_crt_t * {
+	auto new_crt_list = [this]() -> gnutls_x509_crt_t * {
 		gnutls_x509_crt_t *crt_list = nullptr;
 		gnutls_x509_crt_t *crt_list = nullptr;
 		unsigned int crt_list_size = 0;
 		unsigned int crt_list_size = 0;
-		check_gnutls(gnutls_certificate_get_x509_crt(*mCredentials, 0, &crt_list, &crt_list_size));
+		gnutls::check(gnutls_certificate_get_x509_crt(*mCredentials, 0, &crt_list, &crt_list_size));
 		assert(crt_list_size == 1);
 		assert(crt_list_size == 1);
 		return crt_list;
 		return crt_list;
 	};
 	};
 
 
-	auto delete_crt_list = [](gnutls_x509_crt_t *crt_list) {
+	auto free_crt_list = [](gnutls_x509_crt_t *crt_list) {
 		gnutls_x509_crt_deinit(crt_list[0]);
 		gnutls_x509_crt_deinit(crt_list[0]);
 		gnutls_free(crt_list);
 		gnutls_free(crt_list);
 	};
 	};
 
 
-	std::unique_ptr<gnutls_x509_crt_t, decltype(delete_crt_list)> crt_list(create_crt_list(),
-	                                                                       delete_crt_list);
+	std::unique_ptr<gnutls_x509_crt_t, decltype(free_crt_list)> crt_list(new_crt_list(),
+	                                                                     free_crt_list);
 
 
 	mFingerprint = make_fingerprint(*crt_list);
 	mFingerprint = make_fingerprint(*crt_list);
 }
 }
 
 
 Certificate::Certificate(gnutls_x509_crt_t crt, gnutls_x509_privkey_t privkey)
 Certificate::Certificate(gnutls_x509_crt_t crt, gnutls_x509_privkey_t privkey)
-    : mCredentials(create_credentials(), delete_credentials), mFingerprint(make_fingerprint(crt)) {
+    : mCredentials(gnutls::new_credentials(), gnutls::free_credentials),
+      mFingerprint(make_fingerprint(crt)) {
 
 
-	check_gnutls(gnutls_certificate_set_x509_key(*mCredentials, &crt, 1, privkey),
-	             "Unable to set certificate and key pair in credentials");
+	gnutls::check(gnutls_certificate_set_x509_key(*mCredentials, &crt, 1, privkey),
+	              "Unable to set certificate and key pair in credentials");
 }
 }
 
 
 gnutls_certificate_credentials_t Certificate::credentials() const { return *mCredentials; }
 gnutls_certificate_credentials_t Certificate::credentials() const { return *mCredentials; }
@@ -128,8 +78,8 @@ string make_fingerprint(gnutls_x509_crt_t crt) {
 	const size_t size = 32;
 	const size_t size = 32;
 	unsigned char buffer[size];
 	unsigned char buffer[size];
 	size_t len = size;
 	size_t len = size;
-	check_gnutls(gnutls_x509_crt_get_fingerprint(crt, GNUTLS_DIG_SHA256, buffer, &len),
-	             "X509 fingerprint error");
+	gnutls::check(gnutls_x509_crt_get_fingerprint(crt, GNUTLS_DIG_SHA256, buffer, &len),
+	              "X509 fingerprint error");
 
 
 	std::ostringstream oss;
 	std::ostringstream oss;
 	oss << std::hex << std::uppercase << std::setfill('0');
 	oss << std::hex << std::uppercase << std::setfill('0');
@@ -149,13 +99,13 @@ shared_ptr<Certificate> make_certificate(const string &commonName) {
 	if (auto it = cache.find(commonName); it != cache.end())
 	if (auto it = cache.find(commonName); it != cache.end())
 		return it->second;
 		return it->second;
 
 
-	std::unique_ptr<gnutls_x509_crt_t, decltype(&delete_crt)> crt(create_crt(), delete_crt);
-	std::unique_ptr<gnutls_x509_privkey_t, decltype(&delete_privkey)> privkey(create_privkey(),
-	                                                                          delete_privkey);
+	using namespace gnutls;
+	unique_ptr<gnutls_x509_crt_t, decltype(&free_crt)> crt(new_crt(), free_crt);
+	unique_ptr<gnutls_x509_privkey_t, decltype(&free_privkey)> privkey(new_privkey(), free_privkey);
 
 
 	const unsigned int bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_RSA, GNUTLS_SEC_PARAM_HIGH);
 	const unsigned int bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_RSA, GNUTLS_SEC_PARAM_HIGH);
-	check_gnutls(gnutls_x509_privkey_generate(*privkey, GNUTLS_PK_RSA, bits, 0),
-	             "Unable to generate key pair");
+	gnutls::check(gnutls_x509_privkey_generate(*privkey, GNUTLS_PK_RSA, bits, 0),
+	              "Unable to generate key pair");
 
 
 	using namespace std::chrono;
 	using namespace std::chrono;
 	auto now = time_point_cast<seconds>(system_clock::now());
 	auto now = time_point_cast<seconds>(system_clock::now());
@@ -171,8 +121,8 @@ shared_ptr<Certificate> make_certificate(const string &commonName) {
 	gnutls_rnd(GNUTLS_RND_NONCE, serial, serialSize);
 	gnutls_rnd(GNUTLS_RND_NONCE, serial, serialSize);
 	gnutls_x509_crt_set_serial(*crt, serial, serialSize);
 	gnutls_x509_crt_set_serial(*crt, serial, serialSize);
 
 
-	check_gnutls(gnutls_x509_crt_sign2(*crt, *crt, *privkey, GNUTLS_DIG_SHA256, 0),
-	             "Unable to auto-sign certificate");
+	gnutls::check(gnutls_x509_crt_sign2(*crt, *crt, *privkey, GNUTLS_DIG_SHA256, 0),
+	              "Unable to auto-sign certificate");
 
 
 	auto certificate = std::make_shared<Certificate>(*crt, *privkey);
 	auto certificate = std::make_shared<Certificate>(*crt, *privkey);
 	cache.emplace(std::make_pair(commonName, certificate));
 	cache.emplace(std::make_pair(commonName, certificate));
@@ -181,30 +131,24 @@ shared_ptr<Certificate> make_certificate(const string &commonName) {
 
 
 } // namespace rtc
 } // namespace rtc
 
 
-#else
-
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/ssl.h>
+#else // USE_GNUTLS==0
 
 
 namespace rtc {
 namespace rtc {
 
 
 Certificate::Certificate(string crt_pem, string key_pem) {
 Certificate::Certificate(string crt_pem, string key_pem) {
-    BIO *bio;
-
-    bio = BIO_new(BIO_s_mem());
-    BIO_write(bio, crt_pem.data(), crt_pem.size());
-    mX509 = shared_ptr<X509>(PEM_read_bio_X509(bio, nullptr, 0, 0), X509_free);
-    BIO_free(bio);
-    if (!mX509)
-      throw std::invalid_argument("Unable to import certificate PEM");
-
-    bio = BIO_new(BIO_s_mem());
-    BIO_write(bio, key_pem.data(), key_pem.size());
+	BIO *bio = BIO_new(BIO_s_mem());
+	BIO_write(bio, crt_pem.data(), crt_pem.size());
+	mX509 = shared_ptr<X509>(PEM_read_bio_X509(bio, nullptr, 0, 0), X509_free);
+	BIO_free(bio);
+	if (!mX509)
+		throw std::invalid_argument("Unable to import certificate PEM");
+
+	bio = BIO_new(BIO_s_mem());
+	BIO_write(bio, key_pem.data(), key_pem.size());
 	mPKey = shared_ptr<EVP_PKEY>(PEM_read_bio_PrivateKey(bio, nullptr, 0, 0), EVP_PKEY_free);
 	mPKey = shared_ptr<EVP_PKEY>(PEM_read_bio_PrivateKey(bio, nullptr, 0, 0), EVP_PKEY_free);
-    BIO_free(bio);
-    if (!mPKey)
-      throw std::invalid_argument("Unable to import PEM key PEM");
+	BIO_free(bio);
+	if (!mPKey)
+		throw std::invalid_argument("Unable to import PEM key PEM");
 
 
 	mFingerprint = make_fingerprint(mX509.get());
 	mFingerprint = make_fingerprint(mX509.get());
 }
 }

+ 1 - 6
src/certificate.hpp

@@ -20,15 +20,10 @@
 #define RTC_CERTIFICATE_H
 #define RTC_CERTIFICATE_H
 
 
 #include "include.hpp"
 #include "include.hpp"
+#include "tls.hpp"
 
 
 #include <tuple>
 #include <tuple>
 
 
-#if USE_GNUTLS
-#include <gnutls/x509.h>
-#else
-#include <openssl/x509.h>
-#endif
-
 namespace rtc {
 namespace rtc {
 
 
 class Certificate {
 class Certificate {

+ 18 - 17
src/dtlssrtptransport.cpp

@@ -17,6 +17,7 @@
  */
  */
 
 
 #include "dtlssrtptransport.hpp"
 #include "dtlssrtptransport.hpp"
+#include "tls.hpp"
 
 
 #include <cstring>
 #include <cstring>
 #include <exception>
 #include <exception>
@@ -44,22 +45,20 @@ DtlsSrtpTransport::DtlsSrtpTransport(std::shared_ptr<IceTransport> lower,
 	PLOG_DEBUG << "Initializing SRTP transport";
 	PLOG_DEBUG << "Initializing SRTP transport";
 
 
 #if USE_GNUTLS
 #if USE_GNUTLS
-	// TODO: check_gnutls
-	gnutls_srtp_set_profile(mSession, GNUTLS_SRTP_AES128_CM_HMAC_SHA1_80);
+	PLOG_DEBUG << "Initializing DTLS-SRTP transport (GnuTLS)";
+	gnutls::check(gnutls_srtp_set_profile(mSession, GNUTLS_SRTP_AES128_CM_HMAC_SHA1_80),
+	              "Failed to set SRTP profile");
 #else
 #else
-	// TODO: check_openssl
-	SSL_set_tlsext_use_srtp(mSsl, "SRTP_AES128_CM_SHA1_80");
+	PLOG_DEBUG << "Initializing DTLS-SRTP transport (OpenSSL)";
+	openssl::check(SSL_set_tlsext_use_srtp(mSsl, "SRTP_AES128_CM_SHA1_80"),
+	               "Failed to set SRTP profile");
 #endif
 #endif
 }
 }
 
 
-DtlsSrtpTransport::~DtlsSrtpTransport() { stop(); }
-
-bool DtlsSrtpTransport::stop() {
-	if (!Transport::stop())
-		return false;
+DtlsSrtpTransport::~DtlsSrtpTransport() {
+	stop();
 
 
 	srtp_dealloc(mSrtp);
 	srtp_dealloc(mSrtp);
-	return true;
 }
 }
 
 
 bool DtlsSrtpTransport::send(message_ptr message) {
 bool DtlsSrtpTransport::send(message_ptr message) {
@@ -76,7 +75,8 @@ bool DtlsSrtpTransport::send(message_ptr message) {
 		if (err == srtp_err_status_replay_fail)
 		if (err == srtp_err_status_replay_fail)
 			throw std::runtime_error("SRTP packet is a replay");
 			throw std::runtime_error("SRTP packet is a replay");
 		else
 		else
-			throw std::runtime_error("SRTP protect error");
+			throw std::runtime_error("SRTP protect error, status=" +
+			                         to_string(static_cast<int>(err)));
 	}
 	}
 	PLOG_VERBOSE << "Protected SRTP packet, size=" << size;
 	PLOG_VERBOSE << "Protected SRTP packet, size=" << size;
 	message->resize(size);
 	message->resize(size);
@@ -120,9 +120,9 @@ void DtlsSrtpTransport::postHandshake() {
 
 
 #if USE_GNUTLS
 #if USE_GNUTLS
 	gnutls_datum_t clientKeyDatum, clientSaltDatum, serverKeyDatum, serverSaltDatum;
 	gnutls_datum_t clientKeyDatum, clientSaltDatum, serverKeyDatum, serverSaltDatum;
-	// TODO: check_gnutls
-	gnutls_srtp_get_keys(mSession, material, materialLen, &clientKeyDatum, &clientSaltDatum,
-	                     &serverKeyDatum, &serverSaltDatum);
+	gnutls::check(gnutls_srtp_get_keys(mSession, material, materialLen, &clientKeyDatum,
+	                                   &clientSaltDatum, &serverKeyDatum, &serverSaltDatum),
+	              "Failed to derive SRTP keys");
 
 
 	if (clientKeyDatum.size != SRTP_AES_128_KEY_LEN)
 	if (clientKeyDatum.size != SRTP_AES_128_KEY_LEN)
 		throw std::logic_error("Unexpected SRTP master key length: " +
 		throw std::logic_error("Unexpected SRTP master key length: " +
@@ -144,9 +144,10 @@ void DtlsSrtpTransport::postHandshake() {
 	// This provides the client write master key, the server write master key, the client write
 	// This provides the client write master key, the server write master key, the client write
 	// master salt and the server write master salt in that order.
 	// master salt and the server write master salt in that order.
 	const string label = "EXTRACTOR-dtls_srtp";
 	const string label = "EXTRACTOR-dtls_srtp";
-	// TODO: check OpenSSL
-	SSL_export_keying_material(mSsl, material, materialLen, label.c_str(), label.size(), nullptr, 0,
-	                           0);
+	openssl::check(SSL_export_keying_material(mSsl, material, materialLen, label.c_str(),
+	                                          label.size(), nullptr, 0, 0),
+	               "Failed to derive SRTP keys");
+
 	clientKey = material;
 	clientKey = material;
 	clientSalt = clientKey + SRTP_AES_128_KEY_LEN;
 	clientSalt = clientKey + SRTP_AES_128_KEY_LEN;
 
 

+ 0 - 1
src/dtlssrtptransport.hpp

@@ -36,7 +36,6 @@ public:
 	                  state_callback stateChangeCallback);
 	                  state_callback stateChangeCallback);
 	~DtlsSrtpTransport();
 	~DtlsSrtpTransport();
 
 
-	bool stop() override;
 	bool send(message_ptr message) override;
 	bool send(message_ptr message) override;
 
 
 private:
 private:

+ 26 - 89
src/dtlstransport.cpp

@@ -31,28 +31,10 @@ using std::string;
 using std::unique_ptr;
 using std::unique_ptr;
 using std::weak_ptr;
 using std::weak_ptr;
 
 
-#if USE_GNUTLS
-
-#include <gnutls/dtls.h>
-
-namespace {
-
-static bool check_gnutls(int ret, const string &message = "GnuTLS error") {
-	if (ret < 0) {
-		if (!gnutls_error_is_fatal(ret)) {
-			PLOG_INFO << gnutls_strerror(ret);
-			return false;
-		}
-		PLOG_ERROR << message << ": " << gnutls_strerror(ret);
-		throw std::runtime_error(message + ": " + gnutls_strerror(ret));
-	}
-	return true;
-}
-
-} // namespace
-
 namespace rtc {
 namespace rtc {
 
 
+#if USE_GNUTLS
+
 void DtlsTransport::Init() {
 void DtlsTransport::Init() {
 	// Nothing to do
 	// Nothing to do
 }
 }
@@ -69,9 +51,11 @@ DtlsTransport::DtlsTransport(shared_ptr<IceTransport> lower, shared_ptr<Certific
 
 
 	PLOG_DEBUG << "Initializing DTLS transport (GnuTLS)";
 	PLOG_DEBUG << "Initializing DTLS transport (GnuTLS)";
 
 
-	unsigned int flags = GNUTLS_DATAGRAM | (mIsClient ? GNUTLS_CLIENT : GNUTLS_SERVER);
+	gnutls_certificate_credentials_t creds = mCertificate->credentials();
+	gnutls_certificate_set_verify_function(creds, CertificateCallback);
 
 
-	check_gnutls(gnutls_init(&mSession, flags));
+	unsigned int flags = GNUTLS_DATAGRAM | (mIsClient ? GNUTLS_CLIENT : GNUTLS_SERVER);
+	gnutls::check(gnutls_init(&mSession, flags));
 
 
 	try {
 	try {
 		// RFC 8261: SCTP performs segmentation and reassembly based on the path MTU.
 		// RFC 8261: SCTP performs segmentation and reassembly based on the path MTU.
@@ -79,12 +63,10 @@ DtlsTransport::DtlsTransport(shared_ptr<IceTransport> lower, shared_ptr<Certific
 		// See https://tools.ietf.org/html/rfc8261#section-5
 		// See https://tools.ietf.org/html/rfc8261#section-5
 		const char *priorities = "SECURE128:-VERS-SSL3.0:-ARCFOUR-128:-COMP-ALL:+COMP-NULL";
 		const char *priorities = "SECURE128:-VERS-SSL3.0:-ARCFOUR-128:-COMP-ALL:+COMP-NULL";
 		const char *err_pos = NULL;
 		const char *err_pos = NULL;
-		check_gnutls(gnutls_priority_set_direct(mSession, priorities, &err_pos),
-		             "Failed to set TLS priorities");
+		gnutls::check(gnutls_priority_set_direct(mSession, priorities, &err_pos),
+		              "Failed to set TLS priorities");
 
 
-		gnutls_certificate_set_verify_function(mCertificate->credentials(), CertificateCallback);
-		check_gnutls(
-		    gnutls_credentials_set(mSession, GNUTLS_CRD_CERTIFICATE, mCertificate->credentials()));
+		gnutls::check(gnutls_credentials_set(mSession, GNUTLS_CRD_CERTIFICATE, creds));
 
 
 		gnutls_dtls_set_timeouts(mSession,
 		gnutls_dtls_set_timeouts(mSession,
 		                         1000,   // 1s retransmission timeout recommended by RFC 6347
 		                         1000,   // 1s retransmission timeout recommended by RFC 6347
@@ -136,7 +118,7 @@ bool DtlsTransport::send(message_ptr message) {
 	if (ret == GNUTLS_E_LARGE_PACKET)
 	if (ret == GNUTLS_E_LARGE_PACKET)
 		return false;
 		return false;
 
 
-	return check_gnutls(ret);
+	return gnutls::check(ret);
 }
 }
 
 
 void DtlsTransport::incoming(message_ptr message) {
 void DtlsTransport::incoming(message_ptr message) {
@@ -169,7 +151,7 @@ void DtlsTransport::runRecvLoop() {
 				throw std::runtime_error("MTU is too low");
 				throw std::runtime_error("MTU is too low");
 
 
 		} while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN ||
 		} while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN ||
-		         !check_gnutls(ret, "DTLS handshake failed"));
+		         !gnutls::check(ret, "DTLS handshake failed"));
 
 
 		// RFC 8261: DTLS MUST support sending messages larger than the current path MTU
 		// RFC 8261: DTLS MUST support sending messages larger than the current path MTU
 		// See https://tools.ietf.org/html/rfc8261#section-5
 		// See https://tools.ietf.org/html/rfc8261#section-5
@@ -202,7 +184,7 @@ void DtlsTransport::runRecvLoop() {
 				break;
 				break;
 			}
 			}
 
 
-			if (check_gnutls(ret)) {
+			if (gnutls::check(ret)) {
 				if (ret == 0) {
 				if (ret == 0) {
 					// Closed
 					// Closed
 					PLOG_DEBUG << "DTLS connection cleanly closed";
 					PLOG_DEBUG << "DTLS connection cleanly closed";
@@ -238,7 +220,7 @@ int DtlsTransport::CertificateCallback(gnutls_session_t session) {
 	}
 	}
 
 
 	gnutls_x509_crt_t crt;
 	gnutls_x509_crt_t crt;
-	check_gnutls(gnutls_x509_crt_init(&crt));
+	gnutls::check(gnutls_x509_crt_init(&crt));
 	int ret = gnutls_x509_crt_import(crt, &array[0], GNUTLS_X509_FMT_DER);
 	int ret = gnutls_x509_crt_import(crt, &array[0], GNUTLS_X509_FMT_DER);
 	if (ret != GNUTLS_E_SUCCESS) {
 	if (ret != GNUTLS_E_SUCCESS) {
 		gnutls_x509_crt_deinit(crt);
 		gnutls_x509_crt_deinit(crt);
@@ -283,62 +265,17 @@ int DtlsTransport::TimeoutCallback(gnutls_transport_ptr_t ptr, unsigned int ms)
 	return !t->mIncomingQueue.empty() ? 1 : 0;
 	return !t->mIncomingQueue.empty() ? 1 : 0;
 }
 }
 
 
-} // namespace rtc
-
 #else // USE_GNUTLS==0
 #else // USE_GNUTLS==0
 
 
-#include <openssl/bio.h>
-#include <openssl/ec.h>
-#include <openssl/err.h>
-#include <openssl/ssl.h>
-
-namespace {
-
-const int BIO_EOF = -1;
-
-string openssl_error_string(unsigned long err) {
-	const size_t bufferSize = 256;
-	char buffer[bufferSize];
-	ERR_error_string_n(err, buffer, bufferSize);
-	return string(buffer);
-}
-
-bool check_openssl(int success, const string &message = "OpenSSL error") {
-	if (success)
-		return true;
-
-	string str = openssl_error_string(ERR_get_error());
-	PLOG_ERROR << message << ": " << str;
-	throw std::runtime_error(message + ": " + str);
-}
-
-bool check_openssl_ret(SSL *ssl, int ret, const string &message = "OpenSSL error") {
-	if (ret == BIO_EOF)
-		return true;
-
-	unsigned long err = SSL_get_error(ssl, ret);
-	if (err == SSL_ERROR_NONE || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
-		return true;
-	}
-	if (err == SSL_ERROR_ZERO_RETURN) {
-		PLOG_DEBUG << "DTLS connection cleanly closed";
-		return false;
-	}
-	string str = openssl_error_string(err);
-	PLOG_ERROR << str;
-	throw std::runtime_error(message + ": " + str);
-}
-
-} // namespace
-
-namespace rtc {
-
 BIO_METHOD *DtlsTransport::BioMethods = NULL;
 BIO_METHOD *DtlsTransport::BioMethods = NULL;
 int DtlsTransport::TransportExIndex = -1;
 int DtlsTransport::TransportExIndex = -1;
 std::mutex DtlsTransport::GlobalMutex;
 std::mutex DtlsTransport::GlobalMutex;
 
 
 void DtlsTransport::Init() {
 void DtlsTransport::Init() {
 	std::lock_guard lock(GlobalMutex);
 	std::lock_guard lock(GlobalMutex);
+
+	openssl::init();
+
 	if (!BioMethods) {
 	if (!BioMethods) {
 		BioMethods = BIO_meth_new(BIO_TYPE_BIO, "DTLS writer");
 		BioMethods = BIO_meth_new(BIO_TYPE_BIO, "DTLS writer");
 		if (!BioMethods)
 		if (!BioMethods)
@@ -368,8 +305,8 @@ DtlsTransport::DtlsTransport(shared_ptr<IceTransport> lower, shared_ptr<Certific
 		if (!(mCtx = SSL_CTX_new(DTLS_method())))
 		if (!(mCtx = SSL_CTX_new(DTLS_method())))
 			throw std::runtime_error("Failed to create SSL context");
 			throw std::runtime_error("Failed to create SSL context");
 
 
-		check_openssl(SSL_CTX_set_cipher_list(mCtx, "ALL:!LOW:!EXP:!RC4:!MD5:@STRENGTH"),
-		              "Failed to set SSL priorities");
+		openssl::check(SSL_CTX_set_cipher_list(mCtx, "ALL:!LOW:!EXP:!RC4:!MD5:@STRENGTH"),
+		               "Failed to set SSL priorities");
 
 
 		// RFC 8261: SCTP performs segmentation and reassembly based on the path MTU.
 		// RFC 8261: SCTP performs segmentation and reassembly based on the path MTU.
 		// Therefore, the DTLS layer MUST NOT use any compression algorithm.
 		// Therefore, the DTLS layer MUST NOT use any compression algorithm.
@@ -387,7 +324,7 @@ DtlsTransport::DtlsTransport(shared_ptr<IceTransport> lower, shared_ptr<Certific
 		SSL_CTX_use_certificate(mCtx, x509);
 		SSL_CTX_use_certificate(mCtx, x509);
 		SSL_CTX_use_PrivateKey(mCtx, pkey);
 		SSL_CTX_use_PrivateKey(mCtx, pkey);
 
 
-		check_openssl(SSL_CTX_check_private_key(mCtx), "SSL local private key check failed");
+		openssl::check(SSL_CTX_check_private_key(mCtx), "SSL local private key check failed");
 
 
 		if (!(mSsl = SSL_new(mCtx)))
 		if (!(mSsl = SSL_new(mCtx)))
 			throw std::runtime_error("Failed to create SSL instance");
 			throw std::runtime_error("Failed to create SSL instance");
@@ -448,7 +385,7 @@ bool DtlsTransport::send(message_ptr message) {
 	PLOG_VERBOSE << "Send size=" << message->size();
 	PLOG_VERBOSE << "Send size=" << message->size();
 
 
 	int ret = SSL_write(mSsl, message->data(), message->size());
 	int ret = SSL_write(mSsl, message->data(), message->size());
-	return check_openssl_ret(mSsl, ret);
+	return openssl::check(mSsl, ret);
 }
 }
 
 
 void DtlsTransport::incoming(message_ptr message) {
 void DtlsTransport::incoming(message_ptr message) {
@@ -473,7 +410,7 @@ void DtlsTransport::runRecvLoop() {
 
 
 		// Initiate the handshake
 		// Initiate the handshake
 		int ret = SSL_do_handshake(mSsl);
 		int ret = SSL_do_handshake(mSsl);
-		check_openssl_ret(mSsl, ret, "Handshake failed");
+		openssl::check(mSsl, ret, "Handshake failed");
 
 
 		const size_t bufferSize = maxMtu;
 		const size_t bufferSize = maxMtu;
 		byte buffer[bufferSize];
 		byte buffer[bufferSize];
@@ -486,7 +423,7 @@ void DtlsTransport::runRecvLoop() {
 				if (state() == State::Connecting) {
 				if (state() == State::Connecting) {
 					// Continue the handshake
 					// Continue the handshake
 					int ret = SSL_do_handshake(mSsl);
 					int ret = SSL_do_handshake(mSsl);
-					if (!check_openssl_ret(mSsl, ret, "Handshake failed"))
+					if (!openssl::check(mSsl, ret, "Handshake failed"))
 						break;
 						break;
 
 
 					if (SSL_is_init_finished(mSsl)) {
 					if (SSL_is_init_finished(mSsl)) {
@@ -500,7 +437,7 @@ void DtlsTransport::runRecvLoop() {
 					}
 					}
 				} else {
 				} else {
 					int ret = SSL_read(mSsl, buffer, bufferSize);
 					int ret = SSL_read(mSsl, buffer, bufferSize);
-					if (!check_openssl_ret(mSsl, ret))
+					if (!openssl::check(mSsl, ret))
 						break;
 						break;
 					if (ret > 0)
 					if (ret > 0)
 						recv(make_message(buffer, buffer + ret));
 						recv(make_message(buffer, buffer + ret));
@@ -557,7 +494,7 @@ int DtlsTransport::CertificateCallback(int preverify_ok, X509_STORE_CTX *ctx) {
 	    static_cast<DtlsTransport *>(SSL_get_ex_data(ssl, DtlsTransport::TransportExIndex));
 	    static_cast<DtlsTransport *>(SSL_get_ex_data(ssl, DtlsTransport::TransportExIndex));
 
 
 	X509 *crt = X509_STORE_CTX_get_current_cert(ctx);
 	X509 *crt = X509_STORE_CTX_get_current_cert(ctx);
-	std::string fingerprint = make_fingerprint(crt);
+	string fingerprint = make_fingerprint(crt);
 
 
 	return t->mVerifierCallback(fingerprint) ? 1 : 0;
 	return t->mVerifierCallback(fingerprint) ? 1 : 0;
 }
 }
@@ -614,7 +551,7 @@ long DtlsTransport::BioMethodCtrl(BIO *bio, int cmd, long num, void *ptr) {
 	return 0;
 	return 0;
 }
 }
 
 
-} // namespace rtc
-
 #endif
 #endif
 
 
+} // namespace rtc
+

+ 1 - 6
src/dtlstransport.hpp

@@ -23,6 +23,7 @@
 #include "include.hpp"
 #include "include.hpp"
 #include "peerconnection.hpp"
 #include "peerconnection.hpp"
 #include "queue.hpp"
 #include "queue.hpp"
+#include "tls.hpp"
 #include "transport.hpp"
 #include "transport.hpp"
 
 
 #include <atomic>
 #include <atomic>
@@ -31,12 +32,6 @@
 #include <mutex>
 #include <mutex>
 #include <thread>
 #include <thread>
 
 
-#if USE_GNUTLS
-#include <gnutls/gnutls.h>
-#else
-#include <openssl/ssl.h>
-#endif
-
 namespace rtc {
 namespace rtc {
 
 
 class IceTransport;
 class IceTransport;

+ 2 - 10
src/init.cpp

@@ -20,6 +20,7 @@
 
 
 #include "dtlstransport.hpp"
 #include "dtlstransport.hpp"
 #include "sctptransport.hpp"
 #include "sctptransport.hpp"
+#include "tls.hpp"
 
 
 #if RTC_ENABLE_WEBSOCKET
 #if RTC_ENABLE_WEBSOCKET
 #include "tlstransport.hpp"
 #include "tlstransport.hpp"
@@ -29,13 +30,6 @@
 #include <winsock2.h>
 #include <winsock2.h>
 #endif
 #endif
 
 
-#if USE_GNUTLS
-// Nothing to do
-#else
-#include <openssl/err.h>
-#include <openssl/ssl.h>
-#endif
-
 using std::shared_ptr;
 using std::shared_ptr;
 
 
 namespace rtc {
 namespace rtc {
@@ -68,9 +62,7 @@ Init::Init() {
 #if USE_GNUTLS
 #if USE_GNUTLS
 		// Nothing to do
 		// Nothing to do
 #else
 #else
-	OPENSSL_init_ssl(0, NULL);
-	SSL_load_error_strings();
-	ERR_load_crypto_strings();
+	openssl::init();
 #endif
 #endif
 
 
 	SctpTransport::Init();
 	SctpTransport::Init();

+ 132 - 0
src/tls.cpp

@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2019-2020 Paul-Louis Ageneau
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "tls.hpp"
+
+#if USE_GNUTLS
+
+namespace rtc::gnutls {
+
+bool check(int ret, const string &message) {
+	if (ret < 0) {
+		if (!gnutls_error_is_fatal(ret)) {
+			PLOG_INFO << gnutls_strerror(ret);
+			return false;
+		}
+		PLOG_ERROR << message << ": " << gnutls_strerror(ret);
+		throw std::runtime_error(message + ": " + gnutls_strerror(ret));
+	}
+	return true;
+}
+
+gnutls_certificate_credentials_t *new_credentials() {
+	auto creds = new gnutls_certificate_credentials_t;
+	gnutls::check(gnutls_certificate_allocate_credentials(creds));
+	return creds;
+}
+
+void free_credentials(gnutls_certificate_credentials_t *creds) {
+	gnutls_certificate_free_credentials(*creds);
+	delete creds;
+}
+
+gnutls_x509_crt_t *new_crt() {
+	auto crt = new gnutls_x509_crt_t;
+	gnutls::check(gnutls_x509_crt_init(crt));
+	return crt;
+}
+
+void free_crt(gnutls_x509_crt_t *crt) {
+	gnutls_x509_crt_deinit(*crt);
+	delete crt;
+}
+
+gnutls_x509_privkey_t *new_privkey() {
+	auto privkey = new gnutls_x509_privkey_t;
+	gnutls::check(gnutls_x509_privkey_init(privkey));
+	return privkey;
+}
+
+void free_privkey(gnutls_x509_privkey_t *privkey) {
+	gnutls_x509_privkey_deinit(*privkey);
+	delete privkey;
+}
+
+gnutls_datum_t make_datum(char *data, size_t size) {
+	gnutls_datum_t datum;
+	datum.data = reinterpret_cast<unsigned char *>(data);
+	datum.size = size;
+	return datum;
+}
+
+} // namespace rtc::gnutls
+
+#else // USE_GNUTLS==0
+
+namespace rtc::openssl {
+
+void init() {
+	static std::mutex mutex;
+	static bool done = false;
+
+	std::lock_guard lock(mutex);
+	if (!done) {
+		OPENSSL_init_ssl(0, NULL);
+		SSL_load_error_strings();
+		ERR_load_crypto_strings();
+		done = true;
+	}
+}
+
+string error_string(unsigned long err) {
+	const size_t bufferSize = 256;
+	char buffer[bufferSize];
+	ERR_error_string_n(err, buffer, bufferSize);
+	return string(buffer);
+}
+
+bool check(int success, const string &message) {
+	if (success)
+		return true;
+
+	string str = error_string(ERR_get_error());
+	PLOG_ERROR << message << ": " << str;
+	throw std::runtime_error(message + ": " + str);
+}
+
+bool check(SSL *ssl, int ret, const string &message) {
+	if (ret == BIO_EOF)
+		return true;
+
+	unsigned long err = SSL_get_error(ssl, ret);
+	if (err == SSL_ERROR_NONE || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
+		return true;
+	}
+	if (err == SSL_ERROR_ZERO_RETURN) {
+		PLOG_DEBUG << "DTLS connection cleanly closed";
+		return false;
+	}
+	string str = error_string(err);
+	PLOG_ERROR << str;
+	throw std::runtime_error(message + ": " + str);
+}
+
+} // namespace rtc::openssl
+
+#endif
+

+ 73 - 0
src/tls.hpp

@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2019-2020 Paul-Louis Ageneau
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef RTC_TLS_H
+#define RTC_TLS_H
+
+#include "include.hpp"
+
+#if USE_GNUTLS
+
+#include <gnutls/crypto.h>
+#include <gnutls/dtls.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+
+namespace rtc::gnutls {
+
+bool check(int ret, const string &message = "GnuTLS error");
+
+gnutls_certificate_credentials_t *new_credentials();
+void free_credentials(gnutls_certificate_credentials_t *creds);
+
+gnutls_x509_crt_t *new_crt();
+void free_crt(gnutls_x509_crt_t *crt);
+
+gnutls_x509_privkey_t *new_privkey();
+void free_privkey(gnutls_x509_privkey_t *privkey);
+
+gnutls_datum_t make_datum(char *data, size_t size);
+
+} // namespace rtc::gnutls
+
+#else // USE_GNUTLS==0
+
+#include <openssl/bio.h>
+#include <openssl/ec.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+
+#ifndef BIO_EOF
+#define BIO_EOF -1
+#endif
+
+namespace rtc::openssl {
+
+void init();
+string error_string(unsigned long err);
+
+bool check(int success, const string &message = "OpenSSL error");
+bool check(SSL *ssl, int ret, const string &message = "OpenSSL error");
+
+} // namespace rtc::openssl
+
+#endif
+
+#endif

+ 17 - 79
src/tlstransport.cpp

@@ -33,26 +33,10 @@ using std::string;
 using std::unique_ptr;
 using std::unique_ptr;
 using std::weak_ptr;
 using std::weak_ptr;
 
 
-#if USE_GNUTLS
-
-namespace {
-
-static bool check_gnutls(int ret, const string &message = "GnuTLS error") {
-	if (ret < 0) {
-		if (!gnutls_error_is_fatal(ret)) {
-			PLOG_INFO << gnutls_strerror(ret);
-			return false;
-		}
-		PLOG_ERROR << message << ": " << gnutls_strerror(ret);
-		throw std::runtime_error(message + ": " + gnutls_strerror(ret));
-	}
-	return true;
-}
-
-} // namespace
-
 namespace rtc {
 namespace rtc {
 
 
+#if USE_GNUTLS
+
 void TlsTransport::Init() {
 void TlsTransport::Init() {
 	// Nothing to do
 	// Nothing to do
 }
 }
@@ -66,13 +50,13 @@ TlsTransport::TlsTransport(shared_ptr<TcpTransport> lower, string host, state_ca
 
 
 	PLOG_DEBUG << "Initializing TLS transport (GnuTLS)";
 	PLOG_DEBUG << "Initializing TLS transport (GnuTLS)";
 
 
-	check_gnutls(gnutls_init(&mSession, GNUTLS_CLIENT));
+	gnutls::check(gnutls_init(&mSession, GNUTLS_CLIENT));
 
 
 	try {
 	try {
 		const char *priorities = "SECURE128:-VERS-SSL3.0:-ARCFOUR-128";
 		const char *priorities = "SECURE128:-VERS-SSL3.0:-ARCFOUR-128";
 		const char *err_pos = NULL;
 		const char *err_pos = NULL;
-		check_gnutls(gnutls_priority_set_direct(mSession, priorities, &err_pos),
-		             "Failed to set TLS priorities");
+		gnutls::check(gnutls_priority_set_direct(mSession, priorities, &err_pos),
+		              "Failed to set TLS priorities");
 
 
 		gnutls_session_set_ptr(mSession, this);
 		gnutls_session_set_ptr(mSession, this);
 		gnutls_transport_set_ptr(mSession, this);
 		gnutls_transport_set_ptr(mSession, this);
@@ -86,7 +70,6 @@ TlsTransport::TlsTransport(shared_ptr<TcpTransport> lower, string host, state_ca
 		registerIncoming();
 		registerIncoming();
 
 
 	} catch (...) {
 	} catch (...) {
-
 		gnutls_deinit(mSession);
 		gnutls_deinit(mSession);
 		throw;
 		throw;
 	}
 	}
@@ -94,6 +77,7 @@ TlsTransport::TlsTransport(shared_ptr<TcpTransport> lower, string host, state_ca
 
 
 TlsTransport::~TlsTransport() {
 TlsTransport::~TlsTransport() {
 	stop();
 	stop();
+
 	gnutls_deinit(mSession);
 	gnutls_deinit(mSession);
 }
 }
 
 
@@ -118,7 +102,7 @@ bool TlsTransport::send(message_ptr message) {
 		ret = gnutls_record_send(mSession, message->data(), message->size());
 		ret = gnutls_record_send(mSession, message->data(), message->size());
 	} while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
 	} while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
 
 
-	return check_gnutls(ret);
+	return gnutls::check(ret);
 }
 }
 
 
 void TlsTransport::incoming(message_ptr message) {
 void TlsTransport::incoming(message_ptr message) {
@@ -140,7 +124,7 @@ void TlsTransport::runRecvLoop() {
 		do {
 		do {
 			ret = gnutls_handshake(mSession);
 			ret = gnutls_handshake(mSession);
 		} while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN ||
 		} while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN ||
-		         !check_gnutls(ret, "TLS handshake failed"));
+		         !gnutls::check(ret, "TLS handshake failed"));
 
 
 	} catch (const std::exception &e) {
 	} catch (const std::exception &e) {
 		PLOG_ERROR << "TLS handshake: " << e.what();
 		PLOG_ERROR << "TLS handshake: " << e.what();
@@ -165,7 +149,7 @@ void TlsTransport::runRecvLoop() {
 				break;
 				break;
 			}
 			}
 
 
-			if (check_gnutls(ret)) {
+			if (gnutls::check(ret)) {
 				if (ret == 0) {
 				if (ret == 0) {
 					// Closed
 					// Closed
 					PLOG_DEBUG << "TLS connection cleanly closed";
 					PLOG_DEBUG << "TLS connection cleanly closed";
@@ -219,59 +203,13 @@ int TlsTransport::TimeoutCallback(gnutls_transport_ptr_t ptr, unsigned int ms) {
 	return !t->mIncomingQueue.empty() ? 1 : 0;
 	return !t->mIncomingQueue.empty() ? 1 : 0;
 }
 }
 
 
-} // namespace rtc
-
 #else // USE_GNUTLS==0
 #else // USE_GNUTLS==0
 
 
-#include <openssl/bio.h>
-#include <openssl/ec.h>
-#include <openssl/err.h>
-#include <openssl/ssl.h>
-
-namespace {
-
-const int BIO_EOF = -1;
-
-string openssl_error_string(unsigned long err) {
-	const size_t bufferSize = 256;
-	char buffer[bufferSize];
-	ERR_error_string_n(err, buffer, bufferSize);
-	return string(buffer);
-}
-
-bool check_openssl(int success, const string &message = "OpenSSL error") {
-	if (success)
-		return true;
-
-	string str = openssl_error_string(ERR_get_error());
-	PLOG_ERROR << message << ": " << str;
-	throw std::runtime_error(message + ": " + str);
-}
-
-bool check_openssl_ret(SSL *ssl, int ret, const string &message = "OpenSSL error") {
-	if (ret == BIO_EOF)
-		return true;
-
-	unsigned long err = SSL_get_error(ssl, ret);
-	if (err == SSL_ERROR_NONE || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
-		return true;
-	}
-	if (err == SSL_ERROR_ZERO_RETURN) {
-		PLOG_DEBUG << "TLS connection cleanly closed";
-		return false;
-	}
-	string str = openssl_error_string(err);
-	PLOG_ERROR << str;
-	throw std::runtime_error(message + ": " + str);
-}
-
-} // namespace
-
-namespace rtc {
-
 int TlsTransport::TransportExIndex = -1;
 int TlsTransport::TransportExIndex = -1;
 
 
 void TlsTransport::Init() {
 void TlsTransport::Init() {
+	openssl::init();
+
 	if (TransportExIndex < 0) {
 	if (TransportExIndex < 0) {
 		TransportExIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
 		TransportExIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
 	}
 	}
@@ -289,8 +227,8 @@ TlsTransport::TlsTransport(shared_ptr<TcpTransport> lower, string host, state_ca
 	if (!(mCtx = SSL_CTX_new(SSLv23_method()))) // version-flexible
 	if (!(mCtx = SSL_CTX_new(SSLv23_method()))) // version-flexible
 		throw std::runtime_error("Failed to create SSL context");
 		throw std::runtime_error("Failed to create SSL context");
 
 
-	check_openssl(SSL_CTX_set_cipher_list(mCtx, "ALL:!LOW:!EXP:!RC4:!MD5:@STRENGTH"),
-	              "Failed to set SSL priorities");
+	openssl::check(SSL_CTX_set_cipher_list(mCtx, "ALL:!LOW:!EXP:!RC4:!MD5:@STRENGTH"),
+	               "Failed to set SSL priorities");
 
 
 	SSL_CTX_set_options(mCtx, SSL_OP_NO_SSLv3);
 	SSL_CTX_set_options(mCtx, SSL_OP_NO_SSLv3);
 	SSL_CTX_set_min_proto_version(mCtx, TLS1_VERSION);
 	SSL_CTX_set_min_proto_version(mCtx, TLS1_VERSION);
@@ -348,7 +286,7 @@ bool TlsTransport::send(message_ptr message) {
 		return false;
 		return false;
 
 
 	int ret = SSL_write(mSsl, message->data(), message->size());
 	int ret = SSL_write(mSsl, message->data(), message->size());
-	if (!check_openssl_ret(mSsl, ret))
+	if (!openssl::check(mSsl, ret))
 		return false;
 		return false;
 
 
 	const size_t bufferSize = 4096;
 	const size_t bufferSize = 4096;
@@ -384,7 +322,7 @@ void TlsTransport::runRecvLoop() {
 			BIO_write(mInBio, message->data(), message->size());
 			BIO_write(mInBio, message->data(), message->size());
 
 
 			int ret = SSL_read(mSsl, buffer, bufferSize);
 			int ret = SSL_read(mSsl, buffer, bufferSize);
-			if (!check_openssl_ret(mSsl, ret))
+			if (!openssl::check(mSsl, ret))
 				break;
 				break;
 
 
 			if (ret > 0)
 			if (ret > 0)
@@ -425,8 +363,8 @@ void TlsTransport::InfoCallback(const SSL *ssl, int where, int ret) {
 	}
 	}
 }
 }
 
 
-} // namespace rtc
-
 #endif
 #endif
 
 
+} // namespace rtc
+
 #endif
 #endif

+ 1 - 6
src/tlstransport.hpp

@@ -23,18 +23,13 @@
 
 
 #include "include.hpp"
 #include "include.hpp"
 #include "queue.hpp"
 #include "queue.hpp"
+#include "tls.hpp"
 #include "transport.hpp"
 #include "transport.hpp"
 
 
 #include <memory>
 #include <memory>
 #include <mutex>
 #include <mutex>
 #include <thread>
 #include <thread>
 
 
-#if USE_GNUTLS
-#include <gnutls/gnutls.h>
-#else
-#include <openssl/ssl.h>
-#endif
-
 namespace rtc {
 namespace rtc {
 
 
 class TcpTransport;
 class TcpTransport;