From 9b36ac3dd3bd65fda3402951e88475eb7a591d47 Mon Sep 17 00:00:00 2001 From: Paul-Louis Ageneau Date: Mon, 22 Mar 2021 19:05:43 +0100 Subject: [PATCH 1/6] Implemented ECDSA certificates support and removed certificate cache --- CMakeLists.txt | 6 -- include/rtc/configuration.hpp | 12 ++- src/impl/certificate.cpp | 135 +++++++++++++++++++++------------- src/impl/certificate.hpp | 5 +- src/impl/peerconnection.cpp | 2 +- src/impl/tls.hpp | 1 + src/init.cpp | 4 - 7 files changed, 97 insertions(+), 68 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a2ac464..dee6c23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,6 @@ option(NO_MEDIA "Disable media transport support" OFF) option(NO_EXAMPLES "Disable examples" OFF) option(NO_TESTS "Disable tests build" OFF) option(WARNINGS_AS_ERRORS "Treat warnings as errors" OFF) -option(RSA_KEY_BITS_2048 "Use 2048-bit RSA key instead of 3072-bit" OFF) option(CAPI_STDCALL "Set calling convention of C API callbacks stdcall" OFF) if(USE_NICE) @@ -308,11 +307,6 @@ else() target_link_libraries(datachannel-static PRIVATE LibJuice::LibJuiceStatic) endif() -if(RSA_KEY_BITS_2048) - target_compile_definitions(datachannel PUBLIC RSA_KEY_BITS_2048) - target_compile_definitions(datachannel-static PUBLIC RSA_KEY_BITS_2048) -endif() - if(CAPI_STDCALL) target_compile_definitions(datachannel PUBLIC CAPI_STDCALL) target_compile_definitions(datachannel-static PUBLIC CAPI_STDCALL) diff --git a/include/rtc/configuration.hpp b/include/rtc/configuration.hpp index 39424e1..a2f8f62 100644 --- a/include/rtc/configuration.hpp +++ b/include/rtc/configuration.hpp @@ -64,13 +64,23 @@ struct RTC_CPP_EXPORT ProxyServer { string password; }; +enum class CertificateType { Ecdsa = 0, Rsa }; + struct RTC_CPP_EXPORT Configuration { + // ICE settings std::vector iceServers; - optional proxyServer; + optional proxyServer; // libnice only + + // Options + CertificateType certificateType = CertificateType::Ecdsa; bool enableIceTcp = false; bool disableAutoNegotiation = false; + + // Port range uint16_t portRangeBegin = 1024; uint16_t portRangeEnd = 65535; + + // MTU optional mtu; }; diff --git a/src/impl/certificate.cpp b/src/impl/certificate.cpp index 3be5f9f..331f3f0 100644 --- a/src/impl/certificate.cpp +++ b/src/impl/certificate.cpp @@ -28,6 +28,8 @@ namespace rtc::impl { +const string COMMON_NAME = "libdatachannel"; + #if USE_GNUTLS Certificate::Certificate(string crt_pem, string key_pem) @@ -53,8 +55,7 @@ Certificate::Certificate(string crt_pem, string key_pem) gnutls_free(crt_list); }; - unique_ptr crt_list(new_crt_list(), - free_crt_list); + unique_ptr crt_list(new_crt_list(), free_crt_list); mFingerprint = make_fingerprint(*crt_list); } @@ -90,18 +91,33 @@ string make_fingerprint(gnutls_x509_crt_t crt) { namespace { -certificate_ptr make_certificate_impl(string commonName) { - using namespace gnutls; +certificate_ptr make_certificate_impl(CertificateType type) { + PLOG_DEBUG << "Generating certificate (GnuTLS)"; + unique_ptr crt(new_crt(), free_crt); unique_ptr privkey(new_privkey(), free_privkey); -#ifdef RSA_KEY_BITS_2048 - const unsigned int bits = 2048; -#else - const unsigned int bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_RSA, GNUTLS_SEC_PARAM_HIGH); -#endif - gnutls::check(gnutls_x509_privkey_generate(*privkey, GNUTLS_PK_RSA, bits, 0), - "Unable to generate key pair"); + switch (type) { + // RFC 8827 WebRTC Security Architecture 6.5. Communications Security + // All implementations MUST support DTLS 1.2 with the TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + // cipher suite and the P-256 curve + // See https://tools.ietf.org/html/rfc8827#section-6.5 + case CertificateType::Ecdsa: { + gnutls::check(gnutls_x509_privkey_generate(*privkey, GNUTLS_PK_ECDSA, + GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_SECP256R1), + 0), + "Unable to generate ECDSA P-256 key pair"); + break; + } + case CertificateType::Rsa: { + const unsigned int bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_RSA, GNUTLS_SEC_PARAM_HIGH); + gnutls::check(gnutls_x509_privkey_generate(*privkey, GNUTLS_PK_RSA, bits, 0), + "Unable to generate RSA key pair"); + break; + } + default: + throw std::invalid_argument("Unknown certificate type"); + } using namespace std::chrono; auto now = time_point_cast(system_clock::now()); @@ -109,8 +125,8 @@ certificate_ptr make_certificate_impl(string commonName) { gnutls_x509_crt_set_expiration_time(*crt, (now + hours(24 * 365)).time_since_epoch().count()); gnutls_x509_crt_set_version(*crt, 1); gnutls_x509_crt_set_key(*crt, *privkey); - gnutls_x509_crt_set_dn_by_oid(*crt, GNUTLS_OID_X520_COMMON_NAME, 0, commonName.data(), - commonName.size()); + gnutls_x509_crt_set_dn_by_oid(*crt, GNUTLS_OID_X520_COMMON_NAME, 0, COMMON_NAME.data(), + COMMON_NAME.size()); const size_t serialSize = 16; char serial[serialSize]; @@ -175,37 +191,70 @@ string make_fingerprint(X509 *x509) { namespace { -certificate_ptr make_certificate_impl(string commonName) { +certificate_ptr make_certificate_impl(CertificateType type) { + PLOG_DEBUG << "Generating certificate (OpenSSL)"; + shared_ptr x509(X509_new(), X509_free); shared_ptr pkey(EVP_PKEY_new(), EVP_PKEY_free); - - unique_ptr rsa(RSA_new(), RSA_free); - unique_ptr exponent(BN_new(), BN_free); unique_ptr serial_number(BN_new(), BN_free); unique_ptr name(X509_NAME_new(), X509_NAME_free); + if (!x509 || !pkey || !serial_number || !name) + throw std::runtime_error("Unable to allocate structures for certificate generation"); - if (!x509 || !pkey || !rsa || !exponent || !serial_number || !name) - throw std::runtime_error("Unable allocate structures for certificate generation"); + switch (type) { + // RFC 8827 WebRTC Security Architecture 6.5. Communications Security + // All implementations MUST support DTLS 1.2 with the TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + // cipher suite and the P-256 curve + // See https://tools.ietf.org/html/rfc8827#section-6.5 + case CertificateType::Ecdsa: { + PLOG_VERBOSE << "Generating ECDSA P-256 key pair"; -#ifdef RSA_KEY_BITS_2048 - const int bits = 2048; -#else - const int bits = 3072; -#endif - const unsigned int e = 65537; // 2^16 + 1 + unique_ptr ecc(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1), + EC_KEY_free); + if (!ecc) + throw std::runtime_error("Unable to allocate structure for ECDSA P-256 key pair"); - if (!pkey || !rsa || !exponent || !BN_set_word(exponent.get(), e) || - !RSA_generate_key_ex(rsa.get(), bits, exponent.get(), NULL) || - !EVP_PKEY_assign_RSA(pkey.get(), rsa.release())) // the key will be freed when pkey is freed - throw std::runtime_error("Unable to generate key pair"); + EC_KEY_set_asn1_flag(ecc.get(), OPENSSL_EC_NAMED_CURVE); // Set ASN1 OID + if (!EC_KEY_generate_key(ecc.get()) || + !EVP_PKEY_assign_EC_KEY(pkey.get(), + ecc.release())) // the key will be freed when pkey is freed + throw std::runtime_error("Unable to generate ECDSA P-256 key pair"); + + break; + } + case CertificateType::Rsa: { + PLOG_VERBOSE << "Generating RSA key pair"; + + const int bits = 3072; + const unsigned int e = 65537; // 2^16 + 1 + + unique_ptr rsa(RSA_new(), RSA_free); + unique_ptr exponent(BN_new(), BN_free); + if (!rsa || !exponent) + throw std::runtime_error("Unable to allocate structures for RSA key pair"); + + if (!BN_set_word(exponent.get(), e) || + !RSA_generate_key_ex(rsa.get(), bits, exponent.get(), NULL) || + !EVP_PKEY_assign_RSA(pkey.get(), + rsa.release())) // the key will be freed when pkey is freed + throw std::runtime_error("Unable to generate RSA key pair"); + + break; + } + default: + throw std::invalid_argument("Unknown certificate type"); + } const size_t serialSize = 16; auto *commonNameBytes = - reinterpret_cast(const_cast(commonName.c_str())); + reinterpret_cast(const_cast(COMMON_NAME.c_str())); + + if (!X509_set_pubkey(x509.get(), pkey.get())) + throw std::runtime_error("Unable to set certificate public key"); if (!X509_gmtime_adj(X509_getm_notBefore(x509.get()), 3600 * -1) || !X509_gmtime_adj(X509_getm_notAfter(x509.get()), 3600 * 24 * 365) || - !X509_set_version(x509.get(), 1) || !X509_set_pubkey(x509.get(), pkey.get()) || + !X509_set_version(x509.get(), 1) || !BN_pseudo_rand(serial_number.get(), serialSize, 0, 0) || !BN_to_ASN1_INTEGER(serial_number.get(), X509_get_serialNumber(x509.get())) || !X509_NAME_add_entry_by_NID(name.get(), NID_commonName, MBSTRING_UTF8, commonNameBytes, -1, @@ -226,28 +275,8 @@ certificate_ptr make_certificate_impl(string commonName) { // Common for GnuTLS and OpenSSL -namespace { - -static std::unordered_map CertificateCache; -static std::mutex CertificateCacheMutex; - -} // namespace - -future_certificate_ptr make_certificate(string commonName) { - std::lock_guard lock(CertificateCacheMutex); - - if (auto it = CertificateCache.find(commonName); it != CertificateCache.end()) - return it->second; - - auto future = ThreadPool::Instance().enqueue(make_certificate_impl, commonName); - auto shared = future.share(); - CertificateCache.emplace(std::move(commonName), shared); - return shared; -} - -void CleanupCertificateCache() { - std::lock_guard lock(CertificateCacheMutex); - CertificateCache.clear(); +future_certificate_ptr make_certificate(CertificateType type) { + return ThreadPool::Instance().enqueue(make_certificate_impl, type); } } // namespace rtc::impl diff --git a/src/impl/certificate.hpp b/src/impl/certificate.hpp index 9111b8c..ca3b8ed 100644 --- a/src/impl/certificate.hpp +++ b/src/impl/certificate.hpp @@ -21,6 +21,7 @@ #include "common.hpp" #include "tls.hpp" +#include "configuration.hpp" // for CertificateType #include #include @@ -61,9 +62,7 @@ string make_fingerprint(X509 *x509); using certificate_ptr = shared_ptr; using future_certificate_ptr = std::shared_future; -future_certificate_ptr make_certificate(string commonName = "libdatachannel"); // cached - -void CleanupCertificateCache(); +future_certificate_ptr make_certificate(CertificateType type = CertificateType::Ecdsa); } // namespace rtc::impl diff --git a/src/impl/peerconnection.cpp b/src/impl/peerconnection.cpp index 4b9552a..b45d160 100644 --- a/src/impl/peerconnection.cpp +++ b/src/impl/peerconnection.cpp @@ -53,7 +53,7 @@ static LogCounter "Number of unknown RTCP packet types over past second"); PeerConnection::PeerConnection(Configuration config_) - : config(std::move(config_)), mCertificate(make_certificate()), + : config(std::move(config_)), mCertificate(make_certificate(config.certificateType)), mProcessor(std::make_unique()) { PLOG_VERBOSE << "Creating PeerConnection"; diff --git a/src/impl/tls.hpp b/src/impl/tls.hpp index da94e1a..897c012 100644 --- a/src/impl/tls.hpp +++ b/src/impl/tls.hpp @@ -58,6 +58,7 @@ gnutls_datum_t make_datum(char *data, size_t size); #include #include #include +#include #include #include #include diff --git a/src/init.cpp b/src/init.cpp index dcfc156..c713059 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -72,7 +72,6 @@ void doCleanup() { PLOG_DEBUG << "Global cleanup"; impl::ThreadPool::Instance().join(); - impl::CleanupCertificateCache(); impl::SctpTransport::Cleanup(); impl::DtlsTransport::Cleanup(); @@ -111,9 +110,6 @@ void Init::Preload() { auto token = Token(); if (!Global) Global = new shared_ptr(token); - - PLOG_DEBUG << "Preloading certificate"; - impl::make_certificate().wait(); } void Init::Cleanup() { From 1a99ad8e91b997774212508e0d0540930a5f8aad Mon Sep 17 00:00:00 2001 From: Paul-Louis Ageneau Date: Mon, 22 Mar 2021 19:06:28 +0100 Subject: [PATCH 2/6] Disabled renegociation with no_renegociation alert --- src/impl/dtlstransport.cpp | 19 +++++++++++++++++-- src/impl/dtlstransport.hpp | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/impl/dtlstransport.cpp b/src/impl/dtlstransport.cpp index 55cc213..6757c02 100644 --- a/src/impl/dtlstransport.cpp +++ b/src/impl/dtlstransport.cpp @@ -119,9 +119,10 @@ bool DtlsTransport::send(message_ptr message) { PLOG_VERBOSE << "Send size=" << message->size(); - mCurrentDscp = message->dscp; ssize_t ret; do { + std::lock_guard lock(mSendMutex); + mCurrentDscp = message->dscp; ret = gnutls_record_send(mSession, message->data(), message->size()); } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); @@ -197,6 +198,17 @@ void DtlsTransport::runRecvLoop() { ret = gnutls_record_recv(mSession, buffer, bufferSize); } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); + // RFC 8827: Implementations MUST NOT implement DTLS renegotiation and MUST reject it + // with a "no_renegotiation" alert if offered. + // See https://tools.ietf.org/html/rfc8827#section-6.5 + if (ret == GNUTLS_E_REHANDSHAKE) { + do { + std::lock_guard lock(mSendMutex); + ret = gnutls_alert_send(mSession, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION) + } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); + continue; + } + // Consider premature termination as remote closing if (ret == GNUTLS_E_PREMATURE_TERMINATION) { PLOG_DEBUG << "DTLS connection terminated"; @@ -332,7 +344,10 @@ DtlsTransport::DtlsTransport(shared_ptr lower, shared_ptr Date: Mon, 22 Mar 2021 19:07:20 +0100 Subject: [PATCH 3/6] Updated Readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6212e84..3cd39d9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # libdatachannel - C/C++ WebRTC Data Channels -libdatachannel is a standalone implementation of WebRTC Data Channels, WebRTC Media Transport, and WebSockets in C++17 with C bindings for POSIX platforms (including GNU/Linux, Android, and Apple macOS) and Microsoft Windows. It enables direct connectivity between native applications and web browsers without the pain of importing the entire WebRTC stack. The interface consists of simplified versions of the JavaScript WebRTC and WebSocket APIs present in browsers, in order to ease the design of cross-environment applications. +libdatachannel is a standalone implementation of WebRTC Data Channels, WebRTC Media Transport, and WebSockets in C++17 with C bindings for POSIX platforms (including GNU/Linux, Android, and Apple macOS) and Microsoft Windows. It aims at being both straightforward and lightweight with a minimum of external dependencies, to enable direct connectivity between native applications and web browsers without the pain of importing the bloated [Google reference library](https://webrtc.googlesource.com/src/). The interface consists of somewhat simplified versions of the JavaScript WebRTC and WebSocket APIs present in browsers, in order to ease the design of cross-environment applications. It can be compiled with multiple backends: - The security layer can be provided through [OpenSSL](https://www.openssl.org/) or [GnuTLS](https://www.gnutls.org/). - The connectivity for WebRTC can be provided through my ad-hoc ICE library [libjuice](https://github.com/paullouisageneau/libjuice) as submodule or through [libnice](https://github.com/libnice/libnice). @@ -26,6 +26,7 @@ Features: - Trickle ICE ([draft-ietf-ice-trickle-21](https://tools.ietf.org/html/draft-ietf-ice-trickle-21)) - JSEP compatible ([draft-ietf-rtcweb-jsep-26](https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-26)) - Multicast DNS candidates ([draft-ietf-rtcweb-mdns-ice-candidates-04](https://tools.ietf.org/html/draft-ietf-rtcweb-mdns-ice-candidates-04)) +- DTLS with ECDSA or RSA keys ([RFC8824](https://tools.ietf.org/html/rfc8827)) - SRTP and SRTCP key derivation from DTLS ([RFC5764](https://tools.ietf.org/html/rfc5764)) - Differentiated Services QoS ([draft-ietf-tsvwg-rtcweb-qos-18](https://tools.ietf.org/html/draft-ietf-tsvwg-rtcweb-qos-18)) From 08a6c5c45b9c70d15ee6487b60d8eadbd0485375 Mon Sep 17 00:00:00 2001 From: Paul-Louis Ageneau Date: Mon, 22 Mar 2021 19:07:48 +0100 Subject: [PATCH 4/6] Lowered RSA bits to 2048 --- src/impl/certificate.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/impl/certificate.cpp b/src/impl/certificate.cpp index 331f3f0..da26241 100644 --- a/src/impl/certificate.cpp +++ b/src/impl/certificate.cpp @@ -110,7 +110,7 @@ certificate_ptr make_certificate_impl(CertificateType type) { break; } case CertificateType::Rsa: { - const unsigned int bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_RSA, GNUTLS_SEC_PARAM_HIGH); + const unsigned int bits = 2048; gnutls::check(gnutls_x509_privkey_generate(*privkey, GNUTLS_PK_RSA, bits, 0), "Unable to generate RSA key pair"); break; @@ -225,7 +225,7 @@ certificate_ptr make_certificate_impl(CertificateType type) { case CertificateType::Rsa: { PLOG_VERBOSE << "Generating RSA key pair"; - const int bits = 3072; + const int bits = 2048; const unsigned int e = 65537; // 2^16 + 1 unique_ptr rsa(RSA_new(), RSA_free); From fff1912d30524512fa62dbce1bbfa1372f3b4085 Mon Sep 17 00:00:00 2001 From: Paul-Louis Ageneau Date: Mon, 22 Mar 2021 19:57:33 +0100 Subject: [PATCH 5/6] Added certificateType option to C API --- include/rtc/configuration.hpp | 6 +++++- include/rtc/rtc.h | 7 +++++++ src/capi.cpp | 1 + src/impl/certificate.cpp | 2 ++ src/impl/certificate.hpp | 2 +- 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/rtc/configuration.hpp b/include/rtc/configuration.hpp index a2f8f62..edc65f9 100644 --- a/include/rtc/configuration.hpp +++ b/include/rtc/configuration.hpp @@ -64,7 +64,11 @@ struct RTC_CPP_EXPORT ProxyServer { string password; }; -enum class CertificateType { Ecdsa = 0, Rsa }; +enum class CertificateType { + Default = RTC_CERTIFICATE_DEFAULT, // ECDSA + Ecdsa = RTC_CERTIFICATE_ECDSA, + Rsa = RTC_CERTIFICATE_RSA +}; struct RTC_CPP_EXPORT Configuration { // ICE settings diff --git a/include/rtc/rtc.h b/include/rtc/rtc.h index 4cc9200..9f26240 100644 --- a/include/rtc/rtc.h +++ b/include/rtc/rtc.h @@ -88,6 +88,12 @@ typedef enum { // Don't change, it must match plog severity RTC_LOG_VERBOSE = 6 } rtcLogLevel; +typedef enum { + RTC_CERTIFICATE_DEFAULT = 0, + RTC_CERTIFICATE_ECDSA = 1, + RTC_CERTIFICATE_RSA = 2, +} rtcCertificateType; + #if RTC_ENABLE_MEDIA typedef enum { @@ -119,6 +125,7 @@ typedef enum { typedef struct { const char **iceServers; int iceServersCount; + rtcCertificateType certificateType; bool enableIceTcp; bool disableAutoNegotiation; uint16_t portRangeBegin; diff --git a/src/capi.cpp b/src/capi.cpp index 7b1e183..1eed18e 100644 --- a/src/capi.cpp +++ b/src/capi.cpp @@ -351,6 +351,7 @@ int rtcCreatePeerConnection(const rtcConfiguration *config) { for (int i = 0; i < config->iceServersCount; ++i) c.iceServers.emplace_back(string(config->iceServers[i])); + c.certificateType = static_cast(config->certificateType); c.enableIceTcp = config->enableIceTcp; c.disableAutoNegotiation = config->disableAutoNegotiation; diff --git a/src/impl/certificate.cpp b/src/impl/certificate.cpp index da26241..dc00094 100644 --- a/src/impl/certificate.cpp +++ b/src/impl/certificate.cpp @@ -102,6 +102,7 @@ certificate_ptr make_certificate_impl(CertificateType type) { // All implementations MUST support DTLS 1.2 with the TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 // cipher suite and the P-256 curve // See https://tools.ietf.org/html/rfc8827#section-6.5 + case CertificateType::Default: case CertificateType::Ecdsa: { gnutls::check(gnutls_x509_privkey_generate(*privkey, GNUTLS_PK_ECDSA, GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_SECP256R1), @@ -206,6 +207,7 @@ certificate_ptr make_certificate_impl(CertificateType type) { // All implementations MUST support DTLS 1.2 with the TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 // cipher suite and the P-256 curve // See https://tools.ietf.org/html/rfc8827#section-6.5 + case CertificateType::Default: case CertificateType::Ecdsa: { PLOG_VERBOSE << "Generating ECDSA P-256 key pair"; diff --git a/src/impl/certificate.hpp b/src/impl/certificate.hpp index ca3b8ed..03df672 100644 --- a/src/impl/certificate.hpp +++ b/src/impl/certificate.hpp @@ -62,7 +62,7 @@ string make_fingerprint(X509 *x509); using certificate_ptr = shared_ptr; using future_certificate_ptr = std::shared_future; -future_certificate_ptr make_certificate(CertificateType type = CertificateType::Ecdsa); +future_certificate_ptr make_certificate(CertificateType type = CertificateType::Default); } // namespace rtc::impl From 50a6832fb342a4945aa7db2823f208edaa7aa678 Mon Sep 17 00:00:00 2001 From: Paul-Louis Ageneau Date: Mon, 22 Mar 2021 20:52:40 +0100 Subject: [PATCH 6/6] Fixed compilation with GnuTLS --- src/impl/certificate.cpp | 1 + src/impl/dtlstransport.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/impl/certificate.cpp b/src/impl/certificate.cpp index dc00094..32adac3 100644 --- a/src/impl/certificate.cpp +++ b/src/impl/certificate.cpp @@ -94,6 +94,7 @@ namespace { certificate_ptr make_certificate_impl(CertificateType type) { PLOG_DEBUG << "Generating certificate (GnuTLS)"; + using namespace gnutls; unique_ptr crt(new_crt(), free_crt); unique_ptr privkey(new_privkey(), free_privkey); diff --git a/src/impl/dtlstransport.cpp b/src/impl/dtlstransport.cpp index 6757c02..5fb3ace 100644 --- a/src/impl/dtlstransport.cpp +++ b/src/impl/dtlstransport.cpp @@ -204,7 +204,7 @@ void DtlsTransport::runRecvLoop() { if (ret == GNUTLS_E_REHANDSHAKE) { do { std::lock_guard lock(mSendMutex); - ret = gnutls_alert_send(mSession, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION) + ret = gnutls_alert_send(mSession, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); continue; }