mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-24 19:50:38 +08:00
避免对外传递 srtp 依赖
This commit is contained in:
parent
388bf71813
commit
0fc38bbadb
@ -20,18 +20,23 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||||||
// #define MS_LOG_DEV_LEVEL 3
|
// #define MS_LOG_DEV_LEVEL 3
|
||||||
|
|
||||||
#include "SrtpSession.hpp"
|
#include "SrtpSession.hpp"
|
||||||
#include <cstring> // std::memset(), std::memcpy()
|
|
||||||
#include "logger.h"
|
|
||||||
#include "Util/util.h"
|
|
||||||
#include "Util/logger.h"
|
#include "Util/logger.h"
|
||||||
|
#include "Util/util.h"
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
|
#include <srtp2/srtp.h>
|
||||||
|
|
||||||
|
#include <cstring> // std::memset(), std::memcpy()
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
namespace RTC
|
namespace RTC {
|
||||||
{
|
|
||||||
/* Static. */
|
|
||||||
|
|
||||||
static std::vector<const char *> errors = {
|
/* Static. */
|
||||||
|
|
||||||
|
static std::vector<const char *> errors = {
|
||||||
// From 0 (srtp_err_status_ok) to 24 (srtp_err_status_pfkey_err).
|
// From 0 (srtp_err_status_ok) to 24 (srtp_err_status_pfkey_err).
|
||||||
"success (srtp_err_status_ok)",
|
"success (srtp_err_status_ok)",
|
||||||
"unspecified failure (srtp_err_status_fail)",
|
"unspecified failure (srtp_err_status_fail)",
|
||||||
@ -57,23 +62,36 @@ namespace RTC
|
|||||||
"error parsing data (srtp_err_status_parse_err)",
|
"error parsing data (srtp_err_status_parse_err)",
|
||||||
"error encoding data (srtp_err_status_encode_err)",
|
"error encoding data (srtp_err_status_encode_err)",
|
||||||
"error while using semaphores (srtp_err_status_semaphore_err)",
|
"error while using semaphores (srtp_err_status_semaphore_err)",
|
||||||
"error while using pfkey (srtp_err_status_pfkey_err)"};
|
"error while using pfkey (srtp_err_status_pfkey_err)"
|
||||||
// clang-format on
|
};
|
||||||
|
|
||||||
/* Static methods. */
|
/* Static methods. */
|
||||||
|
|
||||||
const char *DepLibSRTP::GetErrorString(srtp_err_status_t code) {
|
class DepLibSRTP : public std::enable_shared_from_this<DepLibSRTP> {
|
||||||
|
public:
|
||||||
|
using Ptr = std::shared_ptr<DepLibSRTP>;
|
||||||
|
~DepLibSRTP();
|
||||||
|
|
||||||
|
static bool IsError(srtp_err_status_t code);
|
||||||
|
static const char *GetErrorString(srtp_err_status_t code);
|
||||||
|
static DepLibSRTP &Instance();
|
||||||
|
|
||||||
|
private:
|
||||||
|
DepLibSRTP();
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *DepLibSRTP::GetErrorString(srtp_err_status_t code) {
|
||||||
// This throws out_of_range if the given index is not in the vector.
|
// This throws out_of_range if the given index is not in the vector.
|
||||||
return errors.at(code);
|
return errors.at(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DepLibSRTP::IsError(srtp_err_status_t code) {
|
bool DepLibSRTP::IsError(srtp_err_status_t code) {
|
||||||
return (code != srtp_err_status_ok);
|
return (code != srtp_err_status_ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANCE_IMP(DepLibSRTP);
|
INSTANCE_IMP(DepLibSRTP);
|
||||||
|
|
||||||
DepLibSRTP::DepLibSRTP(){
|
DepLibSRTP::DepLibSRTP() {
|
||||||
MS_TRACE();
|
MS_TRACE();
|
||||||
|
|
||||||
MS_DEBUG_TAG(info, "libsrtp version: \"%s\"", srtp_get_version_string());
|
MS_DEBUG_TAG(info, "libsrtp version: \"%s\"", srtp_get_version_string());
|
||||||
@ -102,10 +120,9 @@ namespace RTC
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set libsrtp event handler.
|
// Set libsrtp event handler.
|
||||||
err = srtp_install_event_handler([](srtp_event_data_t *data){
|
err = srtp_install_event_handler([](srtp_event_data_t *data) {
|
||||||
MS_TRACE();
|
MS_TRACE();
|
||||||
switch (data->event)
|
switch (data->event) {
|
||||||
{
|
|
||||||
case event_ssrc_collision:
|
case event_ssrc_collision:
|
||||||
MS_WARN_TAG(srtp, "SSRC collision occurred");
|
MS_WARN_TAG(srtp, "SSRC collision occurred");
|
||||||
break;
|
break;
|
||||||
@ -124,23 +141,21 @@ namespace RTC
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (DepLibSRTP::IsError(err))
|
if (DepLibSRTP::IsError(err)) {
|
||||||
{
|
|
||||||
MS_THROW_ERROR("srtp_install_event_handler() failed: %s", DepLibSRTP::GetErrorString(err));
|
MS_THROW_ERROR("srtp_install_event_handler() failed: %s", DepLibSRTP::GetErrorString(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DepLibSRTP::~DepLibSRTP(){
|
DepLibSRTP::~DepLibSRTP() {
|
||||||
MS_TRACE();
|
MS_TRACE();
|
||||||
srtp_shutdown();
|
srtp_shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/* Instance methods. */
|
/* Instance methods. */
|
||||||
|
|
||||||
SrtpSession::SrtpSession(Type type, CryptoSuite cryptoSuite, uint8_t* key, size_t keyLen)
|
SrtpSession::SrtpSession(Type type, CryptoSuite cryptoSuite, uint8_t *key, size_t keyLen) {
|
||||||
{
|
|
||||||
_env = DepLibSRTP::Instance().shared_from_this();
|
_env = DepLibSRTP::Instance().shared_from_this();
|
||||||
MS_TRACE();
|
MS_TRACE();
|
||||||
|
|
||||||
@ -149,18 +164,15 @@ namespace RTC
|
|||||||
// Set all policy fields to 0.
|
// Set all policy fields to 0.
|
||||||
std::memset(&policy, 0, sizeof(srtp_policy_t));
|
std::memset(&policy, 0, sizeof(srtp_policy_t));
|
||||||
|
|
||||||
switch (cryptoSuite)
|
switch (cryptoSuite) {
|
||||||
{
|
case CryptoSuite::AES_CM_128_HMAC_SHA1_80: {
|
||||||
case CryptoSuite::AES_CM_128_HMAC_SHA1_80:
|
|
||||||
{
|
|
||||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
|
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
|
||||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
|
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CryptoSuite::AES_CM_128_HMAC_SHA1_32:
|
case CryptoSuite::AES_CM_128_HMAC_SHA1_32: {
|
||||||
{
|
|
||||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
|
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
|
||||||
// NOTE: Must be 80 for RTCP.
|
// NOTE: Must be 80 for RTCP.
|
||||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
|
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
|
||||||
@ -168,34 +180,28 @@ namespace RTC
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CryptoSuite::AEAD_AES_256_GCM:
|
case CryptoSuite::AEAD_AES_256_GCM: {
|
||||||
{
|
|
||||||
srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp);
|
srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp);
|
||||||
srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtcp);
|
srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtcp);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CryptoSuite::AEAD_AES_128_GCM:
|
case CryptoSuite::AEAD_AES_128_GCM: {
|
||||||
{
|
|
||||||
srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
|
srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
|
||||||
srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp);
|
srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default: {
|
||||||
{
|
|
||||||
MS_ABORT("unknown SRTP crypto suite");
|
MS_ABORT("unknown SRTP crypto suite");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MS_ASSERT(
|
MS_ASSERT((int)keyLen == policy.rtp.cipher_key_len, "given keyLen does not match policy.rtp.cipher_keyLen");
|
||||||
(int)keyLen == policy.rtp.cipher_key_len,
|
|
||||||
"given keyLen does not match policy.rtp.cipher_keyLen");
|
|
||||||
|
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
|
||||||
case Type::INBOUND:
|
case Type::INBOUND:
|
||||||
policy.ssrc.type = ssrc_any_inbound;
|
policy.ssrc.type = ssrc_any_inbound;
|
||||||
break;
|
break;
|
||||||
@ -217,80 +223,71 @@ namespace RTC
|
|||||||
|
|
||||||
if (DepLibSRTP::IsError(err))
|
if (DepLibSRTP::IsError(err))
|
||||||
MS_THROW_ERROR("srtp_create() failed: %s", DepLibSRTP::GetErrorString(err));
|
MS_THROW_ERROR("srtp_create() failed: %s", DepLibSRTP::GetErrorString(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
SrtpSession::~SrtpSession()
|
SrtpSession::~SrtpSession() {
|
||||||
{
|
|
||||||
MS_TRACE();
|
MS_TRACE();
|
||||||
|
|
||||||
if (this->session != nullptr)
|
if (this->session != nullptr) {
|
||||||
{
|
|
||||||
srtp_err_status_t err = srtp_dealloc(this->session);
|
srtp_err_status_t err = srtp_dealloc(this->session);
|
||||||
|
|
||||||
if (DepLibSRTP::IsError(err))
|
if (DepLibSRTP::IsError(err))
|
||||||
MS_ABORT("srtp_dealloc() failed: %s", DepLibSRTP::GetErrorString(err));
|
MS_ABORT("srtp_dealloc() failed: %s", DepLibSRTP::GetErrorString(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrtpSession::EncryptRtp(uint8_t* data, int* len)
|
bool SrtpSession::EncryptRtp(uint8_t *data, int *len) {
|
||||||
{
|
|
||||||
MS_TRACE();
|
MS_TRACE();
|
||||||
srtp_err_status_t err =
|
srtp_err_status_t err = srtp_protect(this->session, static_cast<void *>(data), reinterpret_cast<int *>(len));
|
||||||
srtp_protect(this->session, static_cast<void*>(data), reinterpret_cast<int*>(len));
|
|
||||||
|
|
||||||
if (DepLibSRTP::IsError(err))
|
if (DepLibSRTP::IsError(err)) {
|
||||||
{
|
|
||||||
WarnL << "srtp_protect() failed:" << DepLibSRTP::GetErrorString(err);
|
WarnL << "srtp_protect() failed:" << DepLibSRTP::GetErrorString(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrtpSession::DecryptSrtp(uint8_t* data, int* len)
|
bool SrtpSession::DecryptSrtp(uint8_t *data, int *len) {
|
||||||
{
|
|
||||||
MS_TRACE();
|
MS_TRACE();
|
||||||
|
|
||||||
srtp_err_status_t err =
|
srtp_err_status_t err = srtp_unprotect(this->session, static_cast<void *>(data), reinterpret_cast<int *>(len));
|
||||||
srtp_unprotect(this->session, static_cast<void*>(data), reinterpret_cast<int*>(len));
|
|
||||||
|
|
||||||
if (DepLibSRTP::IsError(err))
|
if (DepLibSRTP::IsError(err)) {
|
||||||
{
|
|
||||||
WarnL << "srtp_unprotect() failed:" << DepLibSRTP::GetErrorString(err);
|
WarnL << "srtp_unprotect() failed:" << DepLibSRTP::GetErrorString(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrtpSession::EncryptRtcp(uint8_t* data, int* len)
|
bool SrtpSession::EncryptRtcp(uint8_t *data, int *len) {
|
||||||
{
|
|
||||||
MS_TRACE();
|
MS_TRACE();
|
||||||
srtp_err_status_t err = srtp_protect_rtcp(
|
srtp_err_status_t err = srtp_protect_rtcp(this->session, static_cast<void *>(data), reinterpret_cast<int *>(len));
|
||||||
this->session, static_cast<void*>(data), reinterpret_cast<int*>(len));
|
|
||||||
|
|
||||||
if (DepLibSRTP::IsError(err))
|
if (DepLibSRTP::IsError(err)) {
|
||||||
{
|
|
||||||
WarnL << "srtp_protect_rtcp() failed:" << DepLibSRTP::GetErrorString(err);
|
WarnL << "srtp_protect_rtcp() failed:" << DepLibSRTP::GetErrorString(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrtpSession::DecryptSrtcp(uint8_t* data, int* len)
|
bool SrtpSession::DecryptSrtcp(uint8_t *data, int *len) {
|
||||||
{
|
|
||||||
MS_TRACE();
|
MS_TRACE();
|
||||||
|
|
||||||
srtp_err_status_t err =
|
srtp_err_status_t err = srtp_unprotect_rtcp(this->session, static_cast<void *>(data), reinterpret_cast<int *>(len));
|
||||||
srtp_unprotect_rtcp(this->session, static_cast<void*>(data), reinterpret_cast<int*>(len));
|
|
||||||
|
|
||||||
if (DepLibSRTP::IsError(err))
|
if (DepLibSRTP::IsError(err)) {
|
||||||
{
|
|
||||||
WarnL << "srtp_unprotect_rtcp() failed:" << DepLibSRTP::GetErrorString(err);
|
WarnL << "srtp_unprotect_rtcp() failed:" << DepLibSRTP::GetErrorString(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrtpSession::RemoveStream(uint32_t ssrc) {
|
||||||
|
srtp_remove_stream(this->session, uint32_t { htonl(ssrc) });
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace RTC
|
} // namespace RTC
|
||||||
|
@ -20,31 +20,18 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||||||
#define MS_RTC_SRTP_SESSION_HPP
|
#define MS_RTC_SRTP_SESSION_HPP
|
||||||
|
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include <srtp2/srtp.h>
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace RTC
|
typedef struct srtp_ctx_t_ *srtp_t;
|
||||||
{
|
|
||||||
class DepLibSRTP : public std::enable_shared_from_this<DepLibSRTP>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using Ptr = std::shared_ptr<DepLibSRTP>;
|
|
||||||
~DepLibSRTP();
|
|
||||||
|
|
||||||
static bool IsError(srtp_err_status_t code);
|
namespace RTC {
|
||||||
static const char *GetErrorString(srtp_err_status_t code);
|
|
||||||
static DepLibSRTP &Instance();
|
|
||||||
|
|
||||||
private:
|
class DepLibSRTP;
|
||||||
DepLibSRTP();
|
|
||||||
};
|
|
||||||
|
|
||||||
class SrtpSession
|
class SrtpSession {
|
||||||
{
|
public:
|
||||||
public:
|
enum class CryptoSuite {
|
||||||
enum class CryptoSuite
|
|
||||||
{
|
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
AES_CM_128_HMAC_SHA1_80 = 1,
|
AES_CM_128_HMAC_SHA1_80 = 1,
|
||||||
AES_CM_128_HMAC_SHA1_32,
|
AES_CM_128_HMAC_SHA1_32,
|
||||||
@ -52,32 +39,26 @@ namespace RTC
|
|||||||
AEAD_AES_128_GCM
|
AEAD_AES_128_GCM
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class Type
|
enum class Type { INBOUND = 1, OUTBOUND };
|
||||||
{
|
|
||||||
INBOUND = 1,
|
|
||||||
OUTBOUND
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SrtpSession(Type type, CryptoSuite cryptoSuite, uint8_t* key, size_t keyLen);
|
SrtpSession(Type type, CryptoSuite cryptoSuite, uint8_t *key, size_t keyLen);
|
||||||
~SrtpSession();
|
~SrtpSession();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool EncryptRtp(uint8_t* data, int* len);
|
bool EncryptRtp(uint8_t *data, int *len);
|
||||||
bool DecryptSrtp(uint8_t* data, int* len);
|
bool DecryptSrtp(uint8_t *data, int *len);
|
||||||
bool EncryptRtcp(uint8_t* data, int* len);
|
bool EncryptRtcp(uint8_t *data, int *len);
|
||||||
bool DecryptSrtcp(uint8_t* data, int* len);
|
bool DecryptSrtcp(uint8_t *data, int *len);
|
||||||
void RemoveStream(uint32_t ssrc)
|
void RemoveStream(uint32_t ssrc);
|
||||||
{
|
|
||||||
srtp_remove_stream(this->session, uint32_t{ htonl(ssrc) });
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Allocated by this.
|
// Allocated by this.
|
||||||
srtp_t session{ nullptr };
|
srtp_t session { nullptr };
|
||||||
DepLibSRTP::Ptr _env;
|
std::shared_ptr<DepLibSRTP> _env;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RTC
|
} // namespace RTC
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
#include "Rtcp/RtcpFCI.h"
|
#include "Rtcp/RtcpFCI.h"
|
||||||
#include "RtpExt.h"
|
#include "RtpExt.h"
|
||||||
#include "Rtsp/RtpReceiver.h"
|
#include "Rtsp/RtpReceiver.h"
|
||||||
|
|
||||||
|
#include <srtp2/srtp.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#define RTP_SSRC_OFFSET 1
|
#define RTP_SSRC_OFFSET 1
|
||||||
|
Loading…
Reference in New Issue
Block a user