diff --git a/CHANGES.md b/CHANGES.md index 5e96e7b1..18d0c4ea 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,11 @@ ## develop +## 2023.16.0 (2023-11-19) + +- [ADD] SRTP keying material を取得する機能を実装 + - @melpon + ## 2023.15.1 (2023-11-09) - [FIX] macOS で USB 接続されたカメラが利用できなくなっていた問題を修正する diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f368571..01f734de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,6 +111,7 @@ target_sources(sora src/sora_signaling.cpp src/sora_video_decoder_factory.cpp src/sora_video_encoder_factory.cpp + src/srtp_keying_material_exporter.cpp src/ssl_verifier.cpp src/url_parts.cpp src/version.cpp diff --git a/VERSION b/VERSION index 550a6ad7..9bff1492 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ -SORA_CPP_SDK_VERSION=2023.15.1 +SORA_CPP_SDK_VERSION=2023.16.0 WEBRTC_BUILD_VERSION=m119.6045.2.1 BOOST_VERSION=1.83.0 CMAKE_VERSION=3.27.7 diff --git a/include/sora/sora_signaling.h b/include/sora/sora_signaling.h index c9682842..0721887c 100644 --- a/include/sora/sora_signaling.h +++ b/include/sora/sora_signaling.h @@ -262,6 +262,7 @@ class SoraSignaling : public std::enable_shared_from_this, std::lock_guard lock(m); this->s = s; } + private: std::string s; mutable std::mutex m; diff --git a/include/sora/srtp_keying_material_exporter.h b/include/sora/srtp_keying_material_exporter.h new file mode 100644 index 00000000..becc844d --- /dev/null +++ b/include/sora/srtp_keying_material_exporter.h @@ -0,0 +1,24 @@ +#ifndef SORA_SRTP_KEYING_MATERIAL_EXPORTER_H_ +#define SORA_SRTP_KEYING_MATERIAL_EXPORTER_H_ + +#include + +#include +#include + +namespace sora { + +struct KeyingMaterial { + std::vector client_write_key; + std::vector server_write_key; + std::vector client_write_salt; + std::vector server_write_salt; +}; + +absl::optional ExportKeyingMaterial( + rtc::scoped_refptr pc, + const std::string& mid); + +} // namespace sora + +#endif diff --git a/run.py b/run.py index 1b23e4cb..c9bdd358 100644 --- a/run.py +++ b/run.py @@ -408,10 +408,10 @@ def build_install_webrtc(version, source_dir, build_dir, install_dir, platform, # インクルードディレクトリを増やしたくないので、 # __config_site を libc++ のディレクトリにコピーしておく - libcxx_dir = os.path.join(source_dir, 'webrtc', 'src', 'third_party', 'libc++') - if not os.path.exists(os.path.join(libcxx_dir, 'src', 'include', '__config_site')): - shutil.copyfile(os.path.join(libcxx_dir, '__config_site'), - os.path.join(libcxx_dir, 'src', 'include', '__config_site')) + src_config = os.path.join(source_dir, 'webrtc', 'src', 'buildtools', 'third_party', 'libc++', '__config_site') + dst_config = os.path.join(source_dir, 'webrtc', 'src', 'third_party', 'libc++', 'src', 'include', '__config_site') + if not os.path.exists(dst_config): + shutil.copyfile(src_config, dst_config) class WebrtcInfo(NamedTuple): diff --git a/src/sora_signaling.cpp b/src/sora_signaling.cpp index d1ea023e..9a78fb7d 100644 --- a/src/sora_signaling.cpp +++ b/src/sora_signaling.cpp @@ -9,6 +9,7 @@ #include "sora/rtc_ssl_verifier.h" #include "sora/rtc_stats.h" #include "sora/session_description.h" +#include "sora/srtp_keying_material_exporter.h" #include "sora/url_parts.h" #include "sora/version.h" #include "sora/zlib_helper.h" diff --git a/src/srtp_keying_material_exporter.cpp b/src/srtp_keying_material_exporter.cpp new file mode 100644 index 00000000..f21a4d25 --- /dev/null +++ b/src/srtp_keying_material_exporter.cpp @@ -0,0 +1,78 @@ +#include "sora/srtp_keying_material_exporter.h" + +#include +#include +#include +#include + +namespace sora { + +// Value specified in RFC 5764. +static const char kDtlsSrtpExporterLabel[] = "EXTRACTOR-dtls_srtp"; + +absl::optional ExportKeyingMaterial( + rtc::scoped_refptr pc, + const std::string& mid) { + rtc::scoped_refptr dtls_interface = + pc->LookupDtlsTransportByMid(mid); + if (dtls_interface == nullptr) { + RTC_LOG(LS_ERROR) << "Failed to lookup DtlsTransportInterface"; + return absl::nullopt; + } + + // shiguredo-webrtc-build/webrtc-build の libwebrtc は + // RTTI を有効にしてるので dynamic_cast ができる + webrtc::DtlsTransport* dtls_impl = + dynamic_cast(dtls_interface.get()); + if (dtls_impl == nullptr) { + RTC_LOG(LS_ERROR) << "Failed to cast webrtc::DtlsTransport"; + return absl::nullopt; + } + + cricket::DtlsTransport* dtls = + dynamic_cast(dtls_impl->internal()); + if (dtls == nullptr) { + RTC_LOG(LS_ERROR) << "Failed to cast cricket::DtlsTransport"; + return absl::nullopt; + } + + int crypto_suite; + if (!dtls->GetSrtpCryptoSuite(&crypto_suite)) { + RTC_LOG(LS_ERROR) << "Failed to get SrtpCryptoSuite"; + return absl::nullopt; + } + + int key_len; + int salt_len; + if (!rtc::GetSrtpKeyAndSaltLengths(crypto_suite, &key_len, &salt_len)) { + RTC_LOG(LS_ERROR) << "Failed to get SrtpKeyAndSaltLengths"; + return absl::nullopt; + } + + std::vector buf(key_len * 2 + salt_len * 2); + + if (!dtls->ExportKeyingMaterial(kDtlsSrtpExporterLabel, nullptr, 0, false, + buf.data(), buf.size())) { + RTC_LOG(LS_ERROR) << "Failed to ExportKeyingMaterial"; + return absl::nullopt; + }; + + KeyingMaterial km; + km.client_write_key.resize(key_len); + km.server_write_key.resize(key_len); + km.client_write_salt.resize(salt_len); + km.server_write_salt.resize(salt_len); + int n = 0; + memcpy(km.client_write_key.data(), buf.data() + n, key_len); + n += key_len; + memcpy(km.server_write_key.data(), buf.data() + n, key_len); + n += key_len; + memcpy(km.client_write_salt.data(), buf.data() + n, salt_len); + n += salt_len; + memcpy(km.server_write_salt.data(), buf.data() + n, salt_len); + n += salt_len; + + return km; +} + +} // namespace sora \ No newline at end of file