dtlstransport.cpp 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099
  1. /**
  2. * Copyright (c) 2019 Paul-Louis Ageneau
  3. *
  4. * This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  7. */
  8. #include "dtlstransport.hpp"
  9. #include "dtlssrtptransport.hpp"
  10. #include "icetransport.hpp"
  11. #include "internals.hpp"
  12. #include "threadpool.hpp"
  13. #include <algorithm>
  14. #include <chrono>
  15. #include <cstring>
  16. #include <exception>
  17. #if !USE_GNUTLS
  18. #ifdef _WIN32
  19. #include <winsock2.h> // for timeval
  20. #else
  21. #include <sys/time.h> // for timeval
  22. #endif
  23. #endif
  24. using namespace std::chrono;
  25. namespace rtc::impl {
  26. void DtlsTransport::enqueueRecv() {
  27. if (mPendingRecvCount > 0)
  28. return;
  29. if (auto shared_this = weak_from_this().lock()) {
  30. ++mPendingRecvCount;
  31. ThreadPool::Instance().enqueue(&DtlsTransport::doRecv, std::move(shared_this));
  32. }
  33. }
  34. #if USE_GNUTLS
  35. void DtlsTransport::Init() {
  36. gnutls_global_init(); // optional
  37. }
  38. void DtlsTransport::Cleanup() { gnutls_global_deinit(); }
  39. DtlsTransport::DtlsTransport(shared_ptr<IceTransport> lower, certificate_ptr certificate,
  40. optional<size_t> mtu,
  41. CertificateFingerprint::Algorithm fingerprintAlgorithm,
  42. verifier_callback verifierCallback, state_callback stateChangeCallback)
  43. : Transport(lower, std::move(stateChangeCallback)), mMtu(mtu), mCertificate(certificate),
  44. mFingerprintAlgorithm(fingerprintAlgorithm), mVerifierCallback(std::move(verifierCallback)),
  45. mIsClient(lower->role() == Description::Role::Active),
  46. mIncomingQueue(RECV_QUEUE_LIMIT, message_size_func) {
  47. PLOG_DEBUG << "Initializing DTLS transport (GnuTLS)";
  48. if (!mCertificate)
  49. throw std::invalid_argument("DTLS certificate is null");
  50. gnutls_certificate_credentials_t creds = mCertificate->credentials();
  51. gnutls_certificate_set_verify_function(creds, CertificateCallback);
  52. unsigned int flags =
  53. GNUTLS_DATAGRAM | GNUTLS_NONBLOCK | (mIsClient ? GNUTLS_CLIENT : GNUTLS_SERVER);
  54. gnutls::check(gnutls_init(&mSession, flags));
  55. try {
  56. // RFC 8261: SCTP performs segmentation and reassembly based on the path MTU.
  57. // Therefore, the DTLS layer MUST NOT use any compression algorithm.
  58. // See https://www.rfc-editor.org/rfc/rfc8261.html#section-5
  59. const char *priorities = "SECURE128:-VERS-SSL3.0:-ARCFOUR-128:-COMP-ALL:+COMP-NULL";
  60. const char *err_pos = NULL;
  61. gnutls::check(gnutls_priority_set_direct(mSession, priorities, &err_pos),
  62. "Failed to set TLS priorities");
  63. // RFC 8827: The DTLS-SRTP protection profile SRTP_AES128_CM_HMAC_SHA1_80 MUST be supported
  64. // See https://www.rfc-editor.org/rfc/rfc8827.html#section-6.5
  65. gnutls::check(gnutls_srtp_set_profile(mSession, GNUTLS_SRTP_AES128_CM_HMAC_SHA1_80),
  66. "Failed to set SRTP profile");
  67. gnutls::check(gnutls_credentials_set(mSession, GNUTLS_CRD_CERTIFICATE, creds));
  68. gnutls_dtls_set_timeouts(mSession,
  69. 1000, // 1s retransmission timeout recommended by RFC 6347
  70. 30000); // 30s total timeout
  71. gnutls_handshake_set_timeout(mSession, 30000);
  72. gnutls_session_set_ptr(mSession, this);
  73. gnutls_transport_set_ptr(mSession, this);
  74. gnutls_transport_set_push_function(mSession, WriteCallback);
  75. gnutls_transport_set_pull_function(mSession, ReadCallback);
  76. gnutls_transport_set_pull_timeout_function(mSession, TimeoutCallback);
  77. } catch (...) {
  78. gnutls_deinit(mSession);
  79. throw;
  80. }
  81. // Set recommended medium-priority DSCP value for handshake
  82. // See https://www.rfc-editor.org/rfc/rfc8837.html#section-5
  83. mCurrentDscp = 10; // AF11: Assured Forwarding class 1, low drop probability
  84. }
  85. DtlsTransport::~DtlsTransport() {
  86. stop();
  87. PLOG_DEBUG << "Destroying DTLS transport";
  88. gnutls_deinit(mSession);
  89. }
  90. void DtlsTransport::start() {
  91. PLOG_DEBUG << "Starting DTLS transport";
  92. registerIncoming();
  93. changeState(State::Connecting);
  94. size_t mtu = mMtu.value_or(DEFAULT_MTU) - 8 - 40; // UDP/IPv6
  95. gnutls_dtls_set_mtu(mSession, static_cast<unsigned int>(mtu));
  96. PLOG_VERBOSE << "DTLS MTU set to " << mtu;
  97. enqueueRecv(); // to initiate the handshake
  98. }
  99. void DtlsTransport::stop() {
  100. PLOG_DEBUG << "Stopping DTLS transport";
  101. unregisterIncoming();
  102. mIncomingQueue.stop();
  103. enqueueRecv();
  104. }
  105. bool DtlsTransport::send(message_ptr message) {
  106. if (!message || state() != State::Connected)
  107. return false;
  108. PLOG_VERBOSE << "Send size=" << message->size();
  109. ssize_t ret;
  110. do {
  111. std::lock_guard lock(mSendMutex);
  112. mCurrentDscp = message->dscp;
  113. ret = gnutls_record_send(mSession, message->data(), message->size());
  114. } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
  115. if (ret == GNUTLS_E_LARGE_PACKET)
  116. return false;
  117. if (!gnutls::check(ret))
  118. return false;
  119. return mOutgoingResult;
  120. }
  121. void DtlsTransport::incoming(message_ptr message) {
  122. if (!message) {
  123. mIncomingQueue.stop();
  124. return;
  125. }
  126. PLOG_VERBOSE << "Incoming size=" << message->size();
  127. mIncomingQueue.push(message);
  128. enqueueRecv();
  129. }
  130. bool DtlsTransport::outgoing(message_ptr message) {
  131. message->dscp = mCurrentDscp;
  132. bool result = Transport::outgoing(std::move(message));
  133. mOutgoingResult = result;
  134. return result;
  135. }
  136. bool DtlsTransport::demuxMessage(message_ptr) {
  137. // Dummy
  138. return false;
  139. }
  140. void DtlsTransport::postHandshake() {
  141. // Dummy
  142. }
  143. void DtlsTransport::doRecv() {
  144. std::lock_guard lock(mRecvMutex);
  145. --mPendingRecvCount;
  146. if (state() != State::Connecting && state() != State::Connected)
  147. return;
  148. try {
  149. const size_t bufferSize = 4096;
  150. char buffer[bufferSize];
  151. // Handle handshake if connecting
  152. if (state() == State::Connecting) {
  153. int ret;
  154. do {
  155. ret = gnutls_handshake(mSession);
  156. if (ret == GNUTLS_E_AGAIN) {
  157. // Schedule next call on timeout and return
  158. auto timeout = milliseconds(gnutls_dtls_get_timeout(mSession));
  159. ThreadPool::Instance().schedule(timeout, [weak_this = weak_from_this()]() {
  160. if (auto locked = weak_this.lock())
  161. locked->doRecv();
  162. });
  163. return;
  164. }
  165. if (ret == GNUTLS_E_LARGE_PACKET) {
  166. throw std::runtime_error("MTU is too low");
  167. }
  168. } while (!gnutls::check(ret, "Handshake failed")); // Re-call on non-fatal error
  169. // RFC 8261: DTLS MUST support sending messages larger than the current path MTU
  170. // See https://www.rfc-editor.org/rfc/rfc8261.html#section-5
  171. gnutls_dtls_set_mtu(mSession, bufferSize + 1);
  172. PLOG_INFO << "DTLS handshake finished";
  173. changeState(State::Connected);
  174. postHandshake();
  175. }
  176. if (state() == State::Connected) {
  177. while (true) {
  178. ssize_t ret = gnutls_record_recv(mSession, buffer, bufferSize);
  179. if (ret == GNUTLS_E_AGAIN) {
  180. return;
  181. }
  182. // RFC 8827: Implementations MUST NOT implement DTLS renegotiation and MUST reject
  183. // it with a "no_renegotiation" alert if offered. See
  184. // https://www.rfc-editor.org/rfc/rfc8827.html#section-6.5
  185. if (ret == GNUTLS_E_REHANDSHAKE) {
  186. do {
  187. std::lock_guard lock(mSendMutex);
  188. ret = gnutls_alert_send(mSession, GNUTLS_AL_WARNING,
  189. GNUTLS_A_NO_RENEGOTIATION);
  190. } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
  191. continue;
  192. }
  193. // Consider premature termination as remote closing
  194. if (ret == GNUTLS_E_PREMATURE_TERMINATION) {
  195. PLOG_DEBUG << "DTLS connection terminated";
  196. break;
  197. }
  198. if (gnutls::check(ret)) {
  199. if (ret == 0) {
  200. // Closed
  201. PLOG_DEBUG << "DTLS connection cleanly closed";
  202. break;
  203. }
  204. auto *b = reinterpret_cast<byte *>(buffer);
  205. recv(make_message(b, b + ret));
  206. }
  207. }
  208. }
  209. } catch (const std::exception &e) {
  210. PLOG_ERROR << "DTLS recv: " << e.what();
  211. }
  212. gnutls_bye(mSession, GNUTLS_SHUT_WR);
  213. if (state() == State::Connected) {
  214. PLOG_INFO << "DTLS closed";
  215. changeState(State::Disconnected);
  216. recv(nullptr);
  217. } else {
  218. PLOG_ERROR << "DTLS handshake failed";
  219. changeState(State::Failed);
  220. }
  221. }
  222. int DtlsTransport::CertificateCallback(gnutls_session_t session) {
  223. DtlsTransport *t = static_cast<DtlsTransport *>(gnutls_session_get_ptr(session));
  224. try {
  225. if (gnutls_certificate_type_get(session) != GNUTLS_CRT_X509) {
  226. return GNUTLS_E_CERTIFICATE_ERROR;
  227. }
  228. unsigned int count = 0;
  229. const gnutls_datum_t *array = gnutls_certificate_get_peers(session, &count);
  230. if (!array || count == 0) {
  231. return GNUTLS_E_CERTIFICATE_ERROR;
  232. }
  233. gnutls_x509_crt_t crt;
  234. gnutls::check(gnutls_x509_crt_init(&crt));
  235. int ret = gnutls_x509_crt_import(crt, &array[0], GNUTLS_X509_FMT_DER);
  236. if (ret != GNUTLS_E_SUCCESS) {
  237. gnutls_x509_crt_deinit(crt);
  238. return GNUTLS_E_CERTIFICATE_ERROR;
  239. }
  240. string fingerprint = make_fingerprint(crt, t->mFingerprintAlgorithm);
  241. gnutls_x509_crt_deinit(crt);
  242. bool success = t->mVerifierCallback(fingerprint);
  243. return success ? GNUTLS_E_SUCCESS : GNUTLS_E_CERTIFICATE_ERROR;
  244. } catch (const std::exception &e) {
  245. PLOG_WARNING << e.what();
  246. return GNUTLS_E_CERTIFICATE_ERROR;
  247. }
  248. }
  249. ssize_t DtlsTransport::WriteCallback(gnutls_transport_ptr_t ptr, const void *data, size_t len) {
  250. DtlsTransport *t = static_cast<DtlsTransport *>(ptr);
  251. try {
  252. if (len > 0) {
  253. auto b = reinterpret_cast<const byte *>(data);
  254. t->outgoing(make_message(b, b + len));
  255. }
  256. gnutls_transport_set_errno(t->mSession, 0);
  257. return ssize_t(len);
  258. } catch (const std::exception &e) {
  259. PLOG_WARNING << e.what();
  260. gnutls_transport_set_errno(t->mSession, ECONNRESET);
  261. return -1;
  262. }
  263. }
  264. ssize_t DtlsTransport::ReadCallback(gnutls_transport_ptr_t ptr, void *data, size_t maxlen) {
  265. DtlsTransport *t = static_cast<DtlsTransport *>(ptr);
  266. try {
  267. while (t->mIncomingQueue.running()) {
  268. auto next = t->mIncomingQueue.pop();
  269. if (!next) {
  270. gnutls_transport_set_errno(t->mSession, EAGAIN);
  271. return -1;
  272. }
  273. message_ptr message = std::move(*next);
  274. if (t->demuxMessage(message))
  275. continue;
  276. ssize_t len = std::min(maxlen, message->size());
  277. std::memcpy(data, message->data(), len);
  278. gnutls_transport_set_errno(t->mSession, 0);
  279. return len;
  280. }
  281. // Closed
  282. gnutls_transport_set_errno(t->mSession, 0);
  283. return 0;
  284. } catch (const std::exception &e) {
  285. PLOG_WARNING << e.what();
  286. gnutls_transport_set_errno(t->mSession, ECONNRESET);
  287. return -1;
  288. }
  289. }
  290. int DtlsTransport::TimeoutCallback(gnutls_transport_ptr_t ptr, unsigned int /* ms */) {
  291. DtlsTransport *t = static_cast<DtlsTransport *>(ptr);
  292. try {
  293. return !t->mIncomingQueue.empty() ? 1 : 0;
  294. } catch (const std::exception &e) {
  295. PLOG_WARNING << e.what();
  296. return 1;
  297. }
  298. }
  299. #elif USE_MBEDTLS
  300. const mbedtls_ssl_srtp_profile srtpSupportedProtectionProfiles[] = {
  301. MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80,
  302. MBEDTLS_TLS_SRTP_UNSET,
  303. };
  304. DtlsTransport::DtlsTransport(shared_ptr<IceTransport> lower, certificate_ptr certificate,
  305. optional<size_t> mtu,
  306. CertificateFingerprint::Algorithm fingerprintAlgorithm,
  307. verifier_callback verifierCallback, state_callback stateChangeCallback)
  308. : Transport(lower, std::move(stateChangeCallback)), mMtu(mtu), mCertificate(certificate),
  309. mFingerprintAlgorithm(fingerprintAlgorithm), mVerifierCallback(std::move(verifierCallback)),
  310. mIsClient(lower->role() == Description::Role::Active),
  311. mIncomingQueue(RECV_QUEUE_LIMIT, message_size_func) {
  312. PLOG_DEBUG << "Initializing DTLS transport (MbedTLS)";
  313. if (!mCertificate)
  314. throw std::invalid_argument("DTLS certificate is null");
  315. mbedtls_entropy_init(&mEntropy);
  316. mbedtls_ctr_drbg_init(&mDrbg);
  317. mbedtls_ssl_init(&mSsl);
  318. mbedtls_ssl_config_init(&mConf);
  319. mbedtls_ctr_drbg_set_prediction_resistance(&mDrbg, MBEDTLS_CTR_DRBG_PR_ON);
  320. try {
  321. mbedtls::check(mbedtls_ctr_drbg_seed(&mDrbg, mbedtls_entropy_func, &mEntropy, NULL, 0));
  322. mbedtls::check(mbedtls_ssl_config_defaults(
  323. &mConf, mIsClient ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
  324. MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT));
  325. mbedtls_ssl_conf_max_version(&mConf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); // TLS 1.2
  326. mbedtls_ssl_conf_authmode(&mConf, MBEDTLS_SSL_VERIFY_OPTIONAL);
  327. mbedtls_ssl_conf_verify(&mConf, DtlsTransport::CertificateCallback, this);
  328. mbedtls_ssl_conf_rng(&mConf, mbedtls_ctr_drbg_random, &mDrbg);
  329. auto [crt, pk] = mCertificate->credentials();
  330. mbedtls::check(mbedtls_ssl_conf_own_cert(&mConf, crt.get(), pk.get()));
  331. mbedtls_ssl_conf_dtls_cookies(&mConf, NULL, NULL, NULL);
  332. mbedtls_ssl_conf_dtls_srtp_protection_profiles(&mConf, srtpSupportedProtectionProfiles);
  333. mbedtls::check(mbedtls_ssl_setup(&mSsl, &mConf));
  334. mbedtls_ssl_set_export_keys_cb(&mSsl, DtlsTransport::ExportKeysCallback, this);
  335. mbedtls_ssl_set_bio(&mSsl, this, WriteCallback, ReadCallback, NULL);
  336. mbedtls_ssl_set_timer_cb(&mSsl, this, SetTimerCallback, GetTimerCallback);
  337. } catch (...) {
  338. mbedtls_entropy_free(&mEntropy);
  339. mbedtls_ctr_drbg_free(&mDrbg);
  340. mbedtls_ssl_free(&mSsl);
  341. mbedtls_ssl_config_free(&mConf);
  342. throw;
  343. }
  344. // Set recommended medium-priority DSCP value for handshake
  345. // See https://www.rfc-editor.org/rfc/rfc8837.html#section-5
  346. mCurrentDscp = 10; // AF11: Assured Forwarding class 1, low drop probability
  347. }
  348. DtlsTransport::~DtlsTransport() {
  349. stop();
  350. PLOG_DEBUG << "Destroying DTLS transport";
  351. mbedtls_entropy_free(&mEntropy);
  352. mbedtls_ctr_drbg_free(&mDrbg);
  353. mbedtls_ssl_free(&mSsl);
  354. mbedtls_ssl_config_free(&mConf);
  355. }
  356. void DtlsTransport::Init() {
  357. // Nothing to do
  358. }
  359. void DtlsTransport::Cleanup() {
  360. // Nothing to do
  361. }
  362. void DtlsTransport::start() {
  363. PLOG_DEBUG << "Starting DTLS transport";
  364. registerIncoming();
  365. changeState(State::Connecting);
  366. {
  367. std::lock_guard lock(mSslMutex);
  368. size_t mtu = mMtu.value_or(DEFAULT_MTU) - 8 - 40; // UDP/IPv6
  369. mbedtls_ssl_set_mtu(&mSsl, static_cast<unsigned int>(mtu));
  370. PLOG_VERBOSE << "DTLS MTU set to " << mtu;
  371. }
  372. enqueueRecv(); // to initiate the handshake
  373. }
  374. void DtlsTransport::stop() {
  375. PLOG_DEBUG << "Stopping DTLS transport";
  376. unregisterIncoming();
  377. mIncomingQueue.stop();
  378. enqueueRecv();
  379. }
  380. bool DtlsTransport::send(message_ptr message) {
  381. if (!message || state() != State::Connected)
  382. return false;
  383. PLOG_VERBOSE << "Send size=" << message->size();
  384. int ret;
  385. do {
  386. std::lock_guard lock(mSslMutex);
  387. if (message->size() > size_t(mbedtls_ssl_get_max_out_record_payload(&mSsl)))
  388. return false;
  389. mCurrentDscp = message->dscp;
  390. ret = mbedtls_ssl_write(&mSsl, reinterpret_cast<const unsigned char *>(message->data()),
  391. message->size());
  392. } while (!mbedtls::check(ret));
  393. return mOutgoingResult;
  394. }
  395. void DtlsTransport::incoming(message_ptr message) {
  396. if (!message) {
  397. mIncomingQueue.stop();
  398. return;
  399. }
  400. PLOG_VERBOSE << "Incoming size=" << message->size();
  401. mIncomingQueue.push(message);
  402. enqueueRecv();
  403. }
  404. bool DtlsTransport::outgoing(message_ptr message) {
  405. message->dscp = mCurrentDscp;
  406. bool result = Transport::outgoing(std::move(message));
  407. mOutgoingResult = result;
  408. return result;
  409. }
  410. bool DtlsTransport::demuxMessage(message_ptr) {
  411. // Dummy
  412. return false;
  413. }
  414. void DtlsTransport::postHandshake() {
  415. // Dummy
  416. }
  417. void DtlsTransport::doRecv() {
  418. std::lock_guard lock(mRecvMutex);
  419. --mPendingRecvCount;
  420. if (state() != State::Connecting && state() != State::Connected)
  421. return;
  422. try {
  423. const size_t bufferSize = 4096;
  424. char buffer[bufferSize];
  425. // Handle handshake if connecting
  426. if (state() == State::Connecting) {
  427. while (true) {
  428. int ret;
  429. {
  430. std::lock_guard lock(mSslMutex);
  431. ret = mbedtls_ssl_handshake(&mSsl);
  432. }
  433. if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
  434. ThreadPool::Instance().schedule(mTimerSetAt + milliseconds(mFinMs),
  435. [weak_this = weak_from_this()]() {
  436. if (auto locked = weak_this.lock())
  437. locked->doRecv();
  438. });
  439. return;
  440. }
  441. if (mbedtls::check(ret, "Handshake failed")) {
  442. // RFC 8261: DTLS MUST support sending messages larger than the current path MTU
  443. // See https://www.rfc-editor.org/rfc/rfc8261.html#section-5
  444. {
  445. std::lock_guard lock(mSslMutex);
  446. mbedtls_ssl_set_mtu(&mSsl, static_cast<unsigned int>(bufferSize + 1));
  447. }
  448. PLOG_INFO << "DTLS handshake finished";
  449. changeState(State::Connected);
  450. postHandshake();
  451. break;
  452. }
  453. }
  454. }
  455. if (state() == State::Connected) {
  456. while (true) {
  457. int ret;
  458. {
  459. std::lock_guard lock(mSslMutex);
  460. ret = mbedtls_ssl_read(&mSsl, reinterpret_cast<unsigned char *>(buffer),
  461. bufferSize);
  462. }
  463. if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
  464. return;
  465. }
  466. if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
  467. PLOG_DEBUG << "DTLS connection cleanly closed";
  468. break;
  469. }
  470. if (mbedtls::check(ret)) {
  471. if (ret == 0) {
  472. PLOG_DEBUG << "DTLS connection terminated";
  473. break;
  474. }
  475. auto *b = reinterpret_cast<byte *>(buffer);
  476. recv(make_message(b, b + ret));
  477. }
  478. }
  479. }
  480. } catch (const std::exception &e) {
  481. PLOG_ERROR << "DTLS recv: " << e.what();
  482. }
  483. if (state() == State::Connected) {
  484. PLOG_INFO << "DTLS closed";
  485. changeState(State::Disconnected);
  486. recv(nullptr);
  487. } else {
  488. PLOG_ERROR << "DTLS handshake failed";
  489. changeState(State::Failed);
  490. }
  491. }
  492. int DtlsTransport::CertificateCallback(void *ctx, mbedtls_x509_crt *crt, int /*depth*/,
  493. uint32_t * /*flags*/) {
  494. auto this_ = static_cast<DtlsTransport *>(ctx);
  495. string fingerprint = make_fingerprint(crt, this_->mFingerprintAlgorithm);
  496. std::transform(fingerprint.begin(), fingerprint.end(), fingerprint.begin(),
  497. [](char c) { return char(std::toupper(c)); });
  498. return this_->mVerifierCallback(fingerprint) ? 0 : 1;
  499. }
  500. void DtlsTransport::ExportKeysCallback(void *ctx, mbedtls_ssl_key_export_type /*type*/,
  501. const unsigned char *secret, size_t secret_len,
  502. const unsigned char client_random[32],
  503. const unsigned char server_random[32],
  504. mbedtls_tls_prf_types tls_prf_type) {
  505. auto dtlsTransport = static_cast<DtlsTransport *>(ctx);
  506. std::memcpy(dtlsTransport->mMasterSecret, secret, secret_len);
  507. std::memcpy(dtlsTransport->mRandBytes, client_random, 32);
  508. std::memcpy(dtlsTransport->mRandBytes + 32, server_random, 32);
  509. dtlsTransport->mTlsProfile = tls_prf_type;
  510. }
  511. int DtlsTransport::WriteCallback(void *ctx, const unsigned char *buf, size_t len) {
  512. auto *t = static_cast<DtlsTransport *>(ctx);
  513. try {
  514. if (len > 0) {
  515. auto b = reinterpret_cast<const byte *>(buf);
  516. t->outgoing(make_message(b, b + len));
  517. }
  518. return int(len);
  519. } catch (const std::exception &e) {
  520. PLOG_WARNING << e.what();
  521. return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
  522. }
  523. }
  524. int DtlsTransport::ReadCallback(void *ctx, unsigned char *buf, size_t len) {
  525. auto *t = static_cast<DtlsTransport *>(ctx);
  526. try {
  527. while (t->mIncomingQueue.running()) {
  528. auto next = t->mIncomingQueue.pop();
  529. if (!next) {
  530. return MBEDTLS_ERR_SSL_WANT_READ;
  531. }
  532. message_ptr message = std::move(*next);
  533. if (t->demuxMessage(message))
  534. continue;
  535. auto bufMin = std::min(len, size_t(message->size()));
  536. std::memcpy(buf, message->data(), bufMin);
  537. return int(len);
  538. }
  539. // Closed
  540. return 0;
  541. } catch (const std::exception &e) {
  542. PLOG_WARNING << e.what();
  543. return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
  544. ;
  545. }
  546. }
  547. void DtlsTransport::SetTimerCallback(void *ctx, uint32_t int_ms, uint32_t fin_ms) {
  548. auto dtlsTransport = static_cast<DtlsTransport *>(ctx);
  549. dtlsTransport->mIntMs = int_ms;
  550. dtlsTransport->mFinMs = fin_ms;
  551. if (fin_ms != 0) {
  552. dtlsTransport->mTimerSetAt = std::chrono::steady_clock::now();
  553. }
  554. }
  555. int DtlsTransport::GetTimerCallback(void *ctx) {
  556. auto dtlsTransport = static_cast<DtlsTransport *>(ctx);
  557. auto now = std::chrono::steady_clock::now();
  558. if (dtlsTransport->mFinMs == 0) {
  559. return -1;
  560. } else if (now >= dtlsTransport->mTimerSetAt + milliseconds(dtlsTransport->mFinMs)) {
  561. return 2;
  562. } else if (now >= dtlsTransport->mTimerSetAt + milliseconds(dtlsTransport->mIntMs)) {
  563. return 1;
  564. } else {
  565. return 0;
  566. }
  567. }
  568. #else // OPENSSL
  569. BIO_METHOD *DtlsTransport::BioMethods = NULL;
  570. int DtlsTransport::TransportExIndex = -1;
  571. std::mutex DtlsTransport::GlobalMutex;
  572. void DtlsTransport::Init() {
  573. std::lock_guard lock(GlobalMutex);
  574. openssl::init();
  575. if (!BioMethods) {
  576. BioMethods = BIO_meth_new(BIO_TYPE_BIO, "DTLS writer");
  577. if (!BioMethods)
  578. throw std::runtime_error("Failed to create BIO methods for DTLS writer");
  579. BIO_meth_set_create(BioMethods, BioMethodNew);
  580. BIO_meth_set_destroy(BioMethods, BioMethodFree);
  581. BIO_meth_set_write(BioMethods, BioMethodWrite);
  582. BIO_meth_set_ctrl(BioMethods, BioMethodCtrl);
  583. }
  584. if (TransportExIndex < 0) {
  585. TransportExIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
  586. }
  587. }
  588. void DtlsTransport::Cleanup() {
  589. // Nothing to do
  590. }
  591. DtlsTransport::DtlsTransport(shared_ptr<IceTransport> lower, certificate_ptr certificate,
  592. optional<size_t> mtu,
  593. CertificateFingerprint::Algorithm fingerprintAlgorithm,
  594. verifier_callback verifierCallback, state_callback stateChangeCallback)
  595. : Transport(lower, std::move(stateChangeCallback)), mMtu(mtu), mCertificate(certificate),
  596. mFingerprintAlgorithm(fingerprintAlgorithm), mVerifierCallback(std::move(verifierCallback)),
  597. mIsClient(lower->role() == Description::Role::Active),
  598. mIncomingQueue(RECV_QUEUE_LIMIT, message_size_func) {
  599. PLOG_DEBUG << "Initializing DTLS transport (OpenSSL)";
  600. if (!mCertificate)
  601. throw std::invalid_argument("DTLS certificate is null");
  602. try {
  603. mCtx = SSL_CTX_new(DTLS_method());
  604. if (!mCtx)
  605. throw std::runtime_error("Failed to create SSL context");
  606. // RFC 8261: SCTP performs segmentation and reassembly based on the path MTU.
  607. // Therefore, the DTLS layer MUST NOT use any compression algorithm.
  608. // See https://www.rfc-editor.org/rfc/rfc8261.html#section-5
  609. // RFC 8827: Implementations MUST NOT implement DTLS renegotiation
  610. // See https://www.rfc-editor.org/rfc/rfc8827.html#section-6.5
  611. SSL_CTX_set_options(mCtx, SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION | SSL_OP_NO_QUERY_MTU |
  612. SSL_OP_NO_RENEGOTIATION);
  613. SSL_CTX_set_min_proto_version(mCtx, DTLS1_VERSION);
  614. SSL_CTX_set_read_ahead(mCtx, 1);
  615. SSL_CTX_set_quiet_shutdown(mCtx, 0); // send the close_notify alert
  616. SSL_CTX_set_info_callback(mCtx, InfoCallback);
  617. SSL_CTX_set_verify(mCtx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
  618. CertificateCallback);
  619. SSL_CTX_set_verify_depth(mCtx, 1);
  620. openssl::check(SSL_CTX_set_cipher_list(mCtx, "ALL:!SHA256:!SHA384:!aPSK:!ECDSA+SHA1:!ADH:!LOW:!EXP:!MD5:!3DES:!SSLv3:!TLSv1"),
  621. "Failed to set SSL priorities");
  622. #if OPENSSL_VERSION_NUMBER >= 0x30000000
  623. openssl::check(SSL_CTX_set1_groups_list(mCtx, "P-256"), "Failed to set SSL groups");
  624. #else
  625. auto ecdh = unique_ptr<EC_KEY, decltype(&EC_KEY_free)>(
  626. EC_KEY_new_by_curve_name(NID_X9_62_prime256v1), EC_KEY_free);
  627. SSL_CTX_set_tmp_ecdh(mCtx, ecdh.get());
  628. #endif
  629. auto [x509, pkey] = mCertificate->credentials();
  630. SSL_CTX_use_certificate(mCtx, x509);
  631. SSL_CTX_use_PrivateKey(mCtx, pkey);
  632. openssl::check(SSL_CTX_check_private_key(mCtx), "SSL local private key check failed");
  633. mSsl = SSL_new(mCtx);
  634. if (!mSsl)
  635. throw std::runtime_error("Failed to create SSL instance");
  636. SSL_set_ex_data(mSsl, TransportExIndex, this);
  637. if (mIsClient)
  638. SSL_set_connect_state(mSsl);
  639. else
  640. SSL_set_accept_state(mSsl);
  641. mInBio = BIO_new(BIO_s_mem());
  642. mOutBio = BIO_new(BioMethods);
  643. if (!mInBio || !mOutBio)
  644. throw std::runtime_error("Failed to create BIO");
  645. BIO_set_mem_eof_return(mInBio, BIO_EOF);
  646. BIO_set_data(mOutBio, this);
  647. SSL_set_bio(mSsl, mInBio, mOutBio);
  648. // RFC 8827: The DTLS-SRTP protection profile SRTP_AES128_CM_HMAC_SHA1_80 MUST be supported
  649. // See https://www.rfc-editor.org/rfc/rfc8827.html#section-6.5
  650. // Warning: SSL_set_tlsext_use_srtp() returns 0 on success and 1 on error
  651. #if RTC_ENABLE_MEDIA
  652. // Try to use GCM suite
  653. if (!DtlsSrtpTransport::IsGcmSupported() ||
  654. SSL_set_tlsext_use_srtp(
  655. mSsl, "SRTP_AEAD_AES_256_GCM:SRTP_AEAD_AES_128_GCM:SRTP_AES128_CM_SHA1_80")) {
  656. PLOG_WARNING << "AES-GCM for SRTP is not supported, falling back to default profile";
  657. if (SSL_set_tlsext_use_srtp(mSsl, "SRTP_AES128_CM_SHA1_80"))
  658. throw std::runtime_error("Failed to set SRTP profile: " +
  659. openssl::error_string(ERR_get_error()));
  660. }
  661. #else
  662. if (SSL_set_tlsext_use_srtp(mSsl, "SRTP_AES128_CM_SHA1_80"))
  663. throw std::runtime_error("Failed to set SRTP profile: " +
  664. openssl::error_string(ERR_get_error()));
  665. #endif
  666. } catch (...) {
  667. if (mSsl)
  668. SSL_free(mSsl);
  669. if (mCtx)
  670. SSL_CTX_free(mCtx);
  671. throw;
  672. }
  673. // Set recommended medium-priority DSCP value for handshake
  674. // See https://www.rfc-editor.org/rfc/rfc8837.html#section-5
  675. mCurrentDscp = 10; // AF11: Assured Forwarding class 1, low drop probability
  676. }
  677. DtlsTransport::~DtlsTransport() {
  678. stop();
  679. PLOG_DEBUG << "Destroying DTLS transport";
  680. SSL_free(mSsl);
  681. SSL_CTX_free(mCtx);
  682. }
  683. void DtlsTransport::start() {
  684. PLOG_DEBUG << "Starting DTLS transport";
  685. registerIncoming();
  686. changeState(State::Connecting);
  687. int ret, err;
  688. {
  689. std::lock_guard lock(mSslMutex);
  690. size_t mtu = mMtu.value_or(DEFAULT_MTU) - 8 - 40; // UDP/IPv6
  691. SSL_set_mtu(mSsl, static_cast<unsigned int>(mtu));
  692. PLOG_VERBOSE << "DTLS MTU set to " << mtu;
  693. // Initiate the handshake
  694. ret = SSL_do_handshake(mSsl);
  695. err = SSL_get_error(mSsl, ret);
  696. }
  697. openssl::check_error(err, "Handshake failed");
  698. handleTimeout();
  699. }
  700. void DtlsTransport::stop() {
  701. PLOG_DEBUG << "Stopping DTLS transport";
  702. unregisterIncoming();
  703. mIncomingQueue.stop();
  704. enqueueRecv();
  705. }
  706. bool DtlsTransport::send(message_ptr message) {
  707. if (!message || state() != State::Connected)
  708. return false;
  709. PLOG_VERBOSE << "Send size=" << message->size();
  710. int ret, err;
  711. {
  712. std::lock_guard lock(mSslMutex);
  713. mCurrentDscp = message->dscp;
  714. ret = SSL_write(mSsl, message->data(), int(message->size()));
  715. err = SSL_get_error(mSsl, ret);
  716. }
  717. if (!openssl::check_error(err))
  718. return false;
  719. return mOutgoingResult;
  720. }
  721. void DtlsTransport::incoming(message_ptr message) {
  722. if (!message) {
  723. mIncomingQueue.stop();
  724. enqueueRecv();
  725. return;
  726. }
  727. PLOG_VERBOSE << "Incoming size=" << message->size();
  728. mIncomingQueue.push(message);
  729. enqueueRecv();
  730. }
  731. bool DtlsTransport::outgoing(message_ptr message) {
  732. message->dscp = mCurrentDscp;
  733. bool result = Transport::outgoing(std::move(message));
  734. mOutgoingResult = result;
  735. return result;
  736. }
  737. bool DtlsTransport::demuxMessage(message_ptr) {
  738. // Dummy
  739. return false;
  740. }
  741. void DtlsTransport::postHandshake() {
  742. // Dummy
  743. }
  744. void DtlsTransport::doRecv() {
  745. std::lock_guard lock(mRecvMutex);
  746. --mPendingRecvCount;
  747. if (state() != State::Connecting && state() != State::Connected)
  748. return;
  749. try {
  750. const size_t bufferSize = 4096;
  751. byte buffer[bufferSize];
  752. // Process pending messages
  753. while (mIncomingQueue.running()) {
  754. auto next = mIncomingQueue.pop();
  755. if (!next) {
  756. // No more messages pending, handle timeout if connecting
  757. if (state() == State::Connecting)
  758. handleTimeout();
  759. return;
  760. }
  761. message_ptr message = std::move(*next);
  762. if (demuxMessage(message))
  763. continue;
  764. BIO_write(mInBio, message->data(), int(message->size()));
  765. if (state() == State::Connecting) {
  766. // Continue the handshake
  767. int ret, err;
  768. {
  769. std::lock_guard lock(mSslMutex);
  770. ret = SSL_do_handshake(mSsl);
  771. err = SSL_get_error(mSsl, ret);
  772. }
  773. if (openssl::check_error(err, "Handshake failed")) {
  774. // RFC 8261: DTLS MUST support sending messages larger than the current path MTU
  775. // See https://www.rfc-editor.org/rfc/rfc8261.html#section-5
  776. {
  777. std::lock_guard lock(mSslMutex);
  778. SSL_set_mtu(mSsl, bufferSize + 1);
  779. }
  780. PLOG_INFO << "DTLS handshake finished";
  781. postHandshake();
  782. changeState(State::Connected);
  783. }
  784. }
  785. if (state() == State::Connected) {
  786. int ret, err;
  787. {
  788. std::lock_guard lock(mSslMutex);
  789. ret = SSL_read(mSsl, buffer, bufferSize);
  790. err = SSL_get_error(mSsl, ret);
  791. }
  792. if (err == SSL_ERROR_ZERO_RETURN) {
  793. PLOG_DEBUG << "TLS connection cleanly closed";
  794. break;
  795. }
  796. if (openssl::check_error(err))
  797. recv(make_message(buffer, buffer + ret));
  798. }
  799. }
  800. std::lock_guard lock(mSslMutex);
  801. SSL_shutdown(mSsl);
  802. } catch (const std::exception &e) {
  803. PLOG_ERROR << "DTLS recv: " << e.what();
  804. }
  805. if (state() == State::Connected) {
  806. PLOG_INFO << "DTLS closed";
  807. changeState(State::Disconnected);
  808. recv(nullptr);
  809. } else {
  810. PLOG_ERROR << "DTLS handshake failed";
  811. changeState(State::Failed);
  812. }
  813. }
  814. void DtlsTransport::handleTimeout() {
  815. std::lock_guard lock(mSslMutex);
  816. // Warning: This function breaks the usual return value convention
  817. int ret = DTLSv1_handle_timeout(mSsl);
  818. if (ret < 0) {
  819. throw std::runtime_error("Handshake timeout"); // write BIO can't fail
  820. } else if (ret > 0) {
  821. LOG_VERBOSE << "DTLS retransmit done";
  822. }
  823. struct timeval tv = {};
  824. if (DTLSv1_get_timeout(mSsl, &tv)) {
  825. auto timeout = milliseconds(tv.tv_sec * 1000 + tv.tv_usec / 1000);
  826. // Also handle handshake timeout manually because OpenSSL actually
  827. // doesn't... OpenSSL backs off exponentially in base 2 starting from the
  828. // recommended 1s so this allows for 5 retransmissions and fails after
  829. // roughly 30s.
  830. if (timeout > 30s)
  831. throw std::runtime_error("Handshake timeout");
  832. LOG_VERBOSE << "DTLS retransmit timeout is " << timeout.count() << "ms";
  833. ThreadPool::Instance().schedule(timeout, [weak_this = weak_from_this()]() {
  834. if (auto locked = weak_this.lock())
  835. locked->doRecv();
  836. });
  837. }
  838. }
  839. int DtlsTransport::CertificateCallback(int /*preverify_ok*/, X509_STORE_CTX *ctx) {
  840. SSL *ssl =
  841. static_cast<SSL *>(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
  842. DtlsTransport *t =
  843. static_cast<DtlsTransport *>(SSL_get_ex_data(ssl, DtlsTransport::TransportExIndex));
  844. X509 *crt = X509_STORE_CTX_get_current_cert(ctx);
  845. string fingerprint = make_fingerprint(crt, t->mFingerprintAlgorithm);
  846. return t->mVerifierCallback(fingerprint) ? 1 : 0;
  847. }
  848. void DtlsTransport::InfoCallback(const SSL *ssl, int where, int ret) {
  849. DtlsTransport *t =
  850. static_cast<DtlsTransport *>(SSL_get_ex_data(ssl, DtlsTransport::TransportExIndex));
  851. if (where & SSL_CB_ALERT) {
  852. if (ret != 256) { // Close Notify
  853. PLOG_ERROR << "DTLS alert: " << SSL_alert_desc_string_long(ret);
  854. }
  855. t->mIncomingQueue.stop(); // Close the connection
  856. }
  857. }
  858. int DtlsTransport::BioMethodNew(BIO *bio) {
  859. BIO_set_init(bio, 1);
  860. BIO_set_data(bio, NULL);
  861. BIO_set_shutdown(bio, 0);
  862. return 1;
  863. }
  864. int DtlsTransport::BioMethodFree(BIO *bio) {
  865. if (!bio)
  866. return 0;
  867. BIO_set_data(bio, NULL);
  868. return 1;
  869. }
  870. int DtlsTransport::BioMethodWrite(BIO *bio, const char *in, int inl) {
  871. if (inl <= 0)
  872. return inl;
  873. auto transport = reinterpret_cast<DtlsTransport *>(BIO_get_data(bio));
  874. if (!transport)
  875. return -1;
  876. auto b = reinterpret_cast<const byte *>(in);
  877. transport->outgoing(make_message(b, b + inl));
  878. return inl; // can't fail
  879. }
  880. long DtlsTransport::BioMethodCtrl(BIO * /*bio*/, int cmd, long /*num*/, void * /*ptr*/) {
  881. switch (cmd) {
  882. case BIO_CTRL_FLUSH:
  883. return 1;
  884. case BIO_CTRL_DGRAM_QUERY_MTU:
  885. return 0; // SSL_OP_NO_QUERY_MTU must be set
  886. case BIO_CTRL_WPENDING:
  887. case BIO_CTRL_PENDING:
  888. return 0;
  889. default:
  890. break;
  891. }
  892. return 0;
  893. }
  894. #endif
  895. } // namespace rtc::impl