- improved SRTP support
This commit is contained in:
parent
e6cb2a22f7
commit
d4a47807d8
|
|
@ -203,6 +203,7 @@ set (RTPHONE_SOURCES
|
||||||
${E}/helper/HL_Time.cpp
|
${E}/helper/HL_Time.cpp
|
||||||
${E}/helper/HL_Time.h
|
${E}/helper/HL_Time.h
|
||||||
${E}/helper/HL_Types.h
|
${E}/helper/HL_Types.h
|
||||||
|
${E}/helper/HL_Types.cpp
|
||||||
${E}/helper/HL_Usb.cpp
|
${E}/helper/HL_Usb.cpp
|
||||||
${E}/helper/HL_Usb.h
|
${E}/helper/HL_Usb.h
|
||||||
${E}/helper/HL_Uuid.cpp
|
${E}/helper/HL_Uuid.cpp
|
||||||
|
|
|
||||||
|
|
@ -303,26 +303,12 @@ std::string AudioProvider::createCryptoAttribute(SrtpSuite suite)
|
||||||
if (!mActiveStream)
|
if (!mActiveStream)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
// Use tag 1 - it is ok, as we use only single crypto attribute
|
|
||||||
int srtpTag = 1;
|
|
||||||
|
|
||||||
// Print key to base64 string
|
// Print key to base64 string
|
||||||
PByteBuffer keyBuffer = mActiveStream->srtp().outgoingKey(suite).first;
|
PByteBuffer keyBuffer = mActiveStream->srtp().outgoingKey(suite).first;
|
||||||
resip::Data d(keyBuffer->data(), keyBuffer->size());
|
resip::Data d(keyBuffer->data(), keyBuffer->size());
|
||||||
resip::Data keyText = d.base64encode();
|
resip::Data keyText = d.base64encode();
|
||||||
|
|
||||||
// Create "crypto" attribute value
|
return std::format("{} {} inline:{}", 1, toString(suite), keyText.c_str());
|
||||||
char buffer[512];
|
|
||||||
const char* suiteName = NULL;
|
|
||||||
switch (suite)
|
|
||||||
{
|
|
||||||
case SRTP_AES_128_AUTH_80: suiteName = SRTP_SUITE_NAME_1; break;
|
|
||||||
case SRTP_AES_256_AUTH_80: suiteName = SRTP_SUITE_NAME_2; break;
|
|
||||||
default: assert(0);
|
|
||||||
}
|
|
||||||
sprintf(buffer, "%d %s inline:%s", srtpTag, suiteName, keyText.c_str());
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SrtpSuite AudioProvider::processCryptoAttribute(const resip::Data& value, ByteBuffer& key)
|
SrtpSuite AudioProvider::processCryptoAttribute(const resip::Data& value, ByteBuffer& key)
|
||||||
|
|
@ -343,15 +329,7 @@ SrtpSuite AudioProvider::processCryptoAttribute(const resip::Data& value, ByteBu
|
||||||
resip::Data rawkey = keyText.base64decode();
|
resip::Data rawkey = keyText.base64decode();
|
||||||
key = ByteBuffer(rawkey.c_str(), rawkey.size());
|
key = ByteBuffer(rawkey.c_str(), rawkey.size());
|
||||||
|
|
||||||
// Open srtp
|
return toSrtpSuite(suite);
|
||||||
SrtpSuite result = SRTP_NONE;
|
|
||||||
if (strcmp(suite, SRTP_SUITE_NAME_1) == 0)
|
|
||||||
result = SRTP_AES_128_AUTH_80;
|
|
||||||
else
|
|
||||||
if (strcmp(suite, SRTP_SUITE_NAME_2) == 0)
|
|
||||||
result = SRTP_AES_256_AUTH_80;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioProvider::findRfc2833(const resip::SdpContents::Session::Medium::CodecContainer& codecs)
|
void AudioProvider::findRfc2833(const resip::SdpContents::Session::Medium::CodecContainer& codecs)
|
||||||
|
|
|
||||||
|
|
@ -17,4 +17,4 @@ target_include_directories(helper_lib PUBLIC ../../libs/ ../../engine ../ .)
|
||||||
target_compile_definitions(helper_lib PRIVATE -D_CRT_SECURE_NO_WARNINGS -D_UNICODE)
|
target_compile_definitions(helper_lib PRIVATE -D_CRT_SECURE_NO_WARNINGS -D_UNICODE)
|
||||||
if (TARGET_LINUX)
|
if (TARGET_LINUX)
|
||||||
target_link_libraries (helper_lib PUBLIC uuid)
|
target_link_libraries (helper_lib PUBLIC uuid)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
#include "HL_Types.h"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com)
|
/* Copyright(C) 2007-2025 VoIP objects (voipobjects.com)
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
@ -26,4 +26,135 @@ enum SdpDirection
|
||||||
Sdp_Offer
|
Sdp_Offer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
template<
|
||||||
|
class K, class V,
|
||||||
|
class HashK = std::hash<K>, class EqK = std::equal_to<K>,
|
||||||
|
class HashV = std::hash<V>, class EqV = std::equal_to<V>
|
||||||
|
>
|
||||||
|
class BiMap {
|
||||||
|
public:
|
||||||
|
using key_type = K;
|
||||||
|
using mapped_type = V;
|
||||||
|
|
||||||
|
BiMap(const std::map<K,V>& initializers) {
|
||||||
|
for (const auto& item: initializers) {
|
||||||
|
insert(item.first, item.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert a new (key, value) pair. Returns false if either key or value already exists.
|
||||||
|
bool insert(const K& k, const V& v) {
|
||||||
|
if (contains_key(k) || contains_value(v)) return false;
|
||||||
|
auto ok = forward_.emplace(k, v);
|
||||||
|
try {
|
||||||
|
auto ov = reverse_.emplace(v, k);
|
||||||
|
if (!ov.second) { // shouldn't happen given the guard above
|
||||||
|
forward_.erase(k);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
forward_.erase(k);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
return ok.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool insert(K&& k, V&& v) {
|
||||||
|
if (contains_key(k) || contains_value(v)) return false;
|
||||||
|
auto ok = forward_.emplace(std::move(k), std::move(v));
|
||||||
|
try {
|
||||||
|
auto ov = reverse_.emplace(ok.first->second, ok.first->first); // use stored refs
|
||||||
|
if (!ov.second) {
|
||||||
|
forward_.erase(ok.first);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
forward_.erase(ok.first);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
return ok.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace value for existing key (and update reverse map). Returns false if value is already bound elsewhere.
|
||||||
|
bool replace_by_key(const K& k, const V& new_v) {
|
||||||
|
auto it = forward_.find(k);
|
||||||
|
if (it == forward_.end()) return false;
|
||||||
|
if (contains_value(new_v)) return false;
|
||||||
|
// remove old reverse, insert new reverse, then update forward
|
||||||
|
reverse_.erase(it->second);
|
||||||
|
reverse_.emplace(new_v, k);
|
||||||
|
it->second = new_v;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace key for existing value (and update forward map). Returns false if key is already bound elsewhere.
|
||||||
|
bool replace_by_value(const V& v, const K& new_k) {
|
||||||
|
auto it = reverse_.find(v);
|
||||||
|
if (it == reverse_.end()) return false;
|
||||||
|
if (contains_key(new_k)) return false;
|
||||||
|
forward_.erase(it->second);
|
||||||
|
forward_.emplace(new_k, v);
|
||||||
|
it->second = new_k;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erase by key/value. Return number erased (0 or 1).
|
||||||
|
size_t erase_key(const K& k) {
|
||||||
|
auto it = forward_.find(k);
|
||||||
|
if (it == forward_.end()) return 0;
|
||||||
|
reverse_.erase(it->second);
|
||||||
|
forward_.erase(it);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t erase_value(const V& v) {
|
||||||
|
auto it = reverse_.find(v);
|
||||||
|
if (it == reverse_.end()) return 0;
|
||||||
|
forward_.erase(it->second);
|
||||||
|
reverse_.erase(it);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup
|
||||||
|
bool contains_key(const K& k) const { return forward_.find(k) != forward_.end(); }
|
||||||
|
bool contains_value(const V& v) const { return reverse_.find(v) != reverse_.end(); }
|
||||||
|
|
||||||
|
const V* find_by_key(const K& k) const {
|
||||||
|
auto it = forward_.find(k);
|
||||||
|
return (it == forward_.end()) ? nullptr : &it->second;
|
||||||
|
}
|
||||||
|
const K* find_by_value(const V& v) const {
|
||||||
|
auto it = reverse_.find(v);
|
||||||
|
return (it == reverse_.end()) ? nullptr : &it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// at() variants throw std::out_of_range on missing entries
|
||||||
|
const V& at_key(const K& k) const { return forward_.at(k); }
|
||||||
|
const K& at_value(const V& v) const { return reverse_.at(v); }
|
||||||
|
|
||||||
|
void clear() noexcept {
|
||||||
|
forward_.clear();
|
||||||
|
reverse_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const noexcept { return forward_.empty(); }
|
||||||
|
size_t size() const noexcept { return forward_.size(); }
|
||||||
|
|
||||||
|
// Reserve buckets for performance (optional)
|
||||||
|
void reserve(size_t n) {
|
||||||
|
forward_.reserve(n);
|
||||||
|
reverse_.reserve(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<K, V, HashK, EqK> forward_;
|
||||||
|
std::unordered_map<V, K, HashV, EqV> reverse_;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,50 @@
|
||||||
#include "../helper/HL_Rtp.h"
|
#include "../helper/HL_Rtp.h"
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
|
BiMap<SrtpSuite, std::string_view> SrtpSuiteNames{{
|
||||||
|
{SRTP_AES_256_AUTH_80, "AES_CM_256_HMAC_SHA1_80"},
|
||||||
|
{SRTP_AES_128_AUTH_80, "AES_CM_128_HMAC_SHA1_80"},
|
||||||
|
{SRTP_AES_192_AUTH_80, "AES_CM_192_HMAC_SHA1_80"},
|
||||||
|
{SRTP_AES_256_AUTH_32, "AES_CM_256_HMAC_SHA1_32"},
|
||||||
|
{SRTP_AES_192_AUTH_32, "AES_CM_192_HMAC_SHA1_32"},
|
||||||
|
{SRTP_AES_128_AUTH_32, "AES_CM_128_HMAC_SHA1_32"},
|
||||||
|
{SRTP_AES_128_AUTH_NULL, "AES_CM_128_NULL_AUTH"},
|
||||||
|
{SRTP_AED_AES_256_GCM, "AEAD_AES_256_GCM"},
|
||||||
|
{SRTP_AED_AES_128_GCM, "AEAD_AES_128_GCM"}}};
|
||||||
|
|
||||||
|
extern SrtpSuite toSrtpSuite(const std::string_view& s)
|
||||||
|
{
|
||||||
|
auto* suite = SrtpSuiteNames.find_by_value(s);
|
||||||
|
return !suite ? SRTP_NONE : *suite;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern std::string_view toString(SrtpSuite suite)
|
||||||
|
{
|
||||||
|
auto* s = SrtpSuiteNames.find_by_key(suite);
|
||||||
|
return s ? *s : std::string_view();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void (*set_srtp_policy_function) (srtp_crypto_policy_t*);
|
||||||
|
|
||||||
|
set_srtp_policy_function findPolicyFunction(SrtpSuite suite)
|
||||||
|
{
|
||||||
|
switch (suite)
|
||||||
|
{
|
||||||
|
case SRTP_AES_128_AUTH_80: return &srtp_crypto_policy_set_rtp_default; break;
|
||||||
|
case SRTP_AES_192_AUTH_80: return &srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80; break;
|
||||||
|
case SRTP_AES_256_AUTH_80: return &srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80; break;
|
||||||
|
case SRTP_AES_128_AUTH_32: return &srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32; break;
|
||||||
|
case SRTP_AES_192_AUTH_32: return &srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32; break;
|
||||||
|
case SRTP_AES_256_AUTH_32: return &srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32; break;
|
||||||
|
case SRTP_AES_128_AUTH_NULL: return &srtp_crypto_policy_set_aes_cm_128_null_auth; break;
|
||||||
|
case SRTP_AED_AES_256_GCM: return &srtp_crypto_policy_set_aes_gcm_256_16_auth; break;
|
||||||
|
case SRTP_AED_AES_128_GCM: return &srtp_crypto_policy_set_aes_gcm_128_16_auth; break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error(std::format("SRTP suite {} is not supported", toString(suite)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- SrtpStream ---
|
// --- SrtpStream ---
|
||||||
static void configureSrtpStream(SrtpStream& s, uint16_t ssrc, SrtpSuite suite)
|
static void configureSrtpStream(SrtpStream& s, uint16_t ssrc, SrtpSuite suite)
|
||||||
|
|
@ -17,21 +61,11 @@ static void configureSrtpStream(SrtpStream& s, uint16_t ssrc, SrtpSuite suite)
|
||||||
s.second.ssrc.type = ssrc_specific;
|
s.second.ssrc.type = ssrc_specific;
|
||||||
s.second.ssrc.value = ntohl(ssrc);
|
s.second.ssrc.value = ntohl(ssrc);
|
||||||
s.second.next = nullptr;
|
s.second.next = nullptr;
|
||||||
switch (suite)
|
set_srtp_policy_function func = findPolicyFunction(suite);
|
||||||
{
|
if (!func)
|
||||||
case SRTP_AES_128_AUTH_80:
|
throw std::runtime_error(std::format("SRTP suite {} is not supported", toString(suite)));
|
||||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&s.second.rtp);
|
func(&s.second.rtp);
|
||||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&s.second.rtcp);
|
func(&s.second.rtcp);
|
||||||
break;
|
|
||||||
|
|
||||||
case SRTP_AES_256_AUTH_80:
|
|
||||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&s.second.rtp);
|
|
||||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&s.second.rtcp);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SrtpSession::SrtpSession()
|
SrtpSession::SrtpSession()
|
||||||
|
|
@ -45,14 +79,19 @@ SrtpSession::SrtpSession()
|
||||||
memset(&mOutboundPolicy, 0, sizeof mOutboundPolicy);
|
memset(&mOutboundPolicy, 0, sizeof mOutboundPolicy);
|
||||||
mOutboundPolicy.ssrc.type = ssrc_specific;
|
mOutboundPolicy.ssrc.type = ssrc_specific;
|
||||||
|
|
||||||
// Generate outgoing keys
|
// Generate outgoing keys for all ciphers
|
||||||
mOutgoingKey[SRTP_AES_128_AUTH_80-1].first = std::make_shared<ByteBuffer>();
|
auto putKey = [this](SrtpSuite suite, size_t length){
|
||||||
mOutgoingKey[SRTP_AES_128_AUTH_80-1].first->resize(30);
|
auto key = std::make_shared<ByteBuffer>();
|
||||||
RAND_bytes((unsigned char*)mOutgoingKey[SRTP_AES_128_AUTH_80-1].first->mutableData(), 30);
|
key->resize(length);
|
||||||
|
RAND_bytes(key->mutableData(), key->size());
|
||||||
|
mOutgoingKey[suite].first = key;
|
||||||
|
};
|
||||||
|
putKey(SRTP_AES_128_AUTH_80, 30); putKey(SRTP_AES_128_AUTH_32, 30);
|
||||||
|
putKey(SRTP_AES_192_AUTH_80, 38); putKey(SRTP_AES_192_AUTH_32, 38);
|
||||||
|
putKey(SRTP_AES_256_AUTH_80, 46); putKey(SRTP_AES_256_AUTH_32, 46);
|
||||||
|
putKey(SRTP_AED_AES_128_GCM, 28);
|
||||||
|
putKey(SRTP_AED_AES_256_GCM, 44);
|
||||||
|
|
||||||
mOutgoingKey[SRTP_AES_256_AUTH_80-1].first = std::make_shared<ByteBuffer>();
|
|
||||||
mOutgoingKey[SRTP_AES_256_AUTH_80-1].first->resize(46);
|
|
||||||
RAND_bytes((unsigned char*)mOutgoingKey[SRTP_AES_256_AUTH_80-1].first->mutableData(), 46);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SrtpSession::~SrtpSession()
|
SrtpSession::~SrtpSession()
|
||||||
|
|
@ -106,27 +145,17 @@ void SrtpSession::open(ByteBuffer& incomingKey, SrtpSuite suite)
|
||||||
// Save key
|
// Save key
|
||||||
mIncomingKey.first = std::make_shared<ByteBuffer>(incomingKey);
|
mIncomingKey.first = std::make_shared<ByteBuffer>(incomingKey);
|
||||||
|
|
||||||
// Update policy
|
auto policyFunction = findPolicyFunction(suite);
|
||||||
switch (suite)
|
if (!policyFunction)
|
||||||
{
|
throw std::runtime_error(std::format("SRTP suite {} not found", toString(suite)));
|
||||||
case SRTP_AES_128_AUTH_80:
|
|
||||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&mInboundPolicy.rtp);
|
|
||||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&mInboundPolicy.rtcp);
|
|
||||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&mOutboundPolicy.rtp);
|
|
||||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&mOutboundPolicy.rtcp);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SRTP_AES_256_AUTH_80:
|
// Configure policies
|
||||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&mInboundPolicy.rtp);
|
policyFunction(&mInboundPolicy.rtp);
|
||||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&mInboundPolicy.rtcp);
|
policyFunction(&mInboundPolicy.rtcp);
|
||||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&mOutboundPolicy.rtp);
|
policyFunction(&mOutboundPolicy.rtp);
|
||||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&mOutboundPolicy.rtcp);
|
policyFunction(&mOutboundPolicy.rtcp);
|
||||||
break;
|
|
||||||
|
|
||||||
case SRTP_NONE:
|
mOutboundPolicy.key = (unsigned char*)mOutgoingKey[int(suite)].first->mutableData();
|
||||||
break;
|
|
||||||
}
|
|
||||||
mOutboundPolicy.key = (unsigned char*)mOutgoingKey[int(suite)-1].first->mutableData();
|
|
||||||
mInboundPolicy.key = (unsigned char*)mIncomingKey.first->mutableData();
|
mInboundPolicy.key = (unsigned char*)mIncomingKey.first->mutableData();
|
||||||
|
|
||||||
// Create SRTP session
|
// Create SRTP session
|
||||||
|
|
|
||||||
|
|
@ -11,63 +11,77 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "libsrtp/include/srtp.h"
|
#include "libsrtp/include/srtp.h"
|
||||||
#include "../helper/HL_Sync.h"
|
#include "HL_Sync.h"
|
||||||
#include "../helper/HL_ByteBuffer.h"
|
#include "HL_ByteBuffer.h"
|
||||||
|
#include "HL_Types.h"
|
||||||
|
|
||||||
#define SRTP_SUITE_NAME_2 "AES_CM_256_HMAC_SHA1_80"
|
#define NAME_SRTP_AES_256_AUTH_80 "AES_CM_256_HMAC_SHA1_80"
|
||||||
#define SRTP_SUITE_NAME_1 "AES_CM_128_HMAC_SHA1_80"
|
#define NAME_SRTP_AES_128_AUTH_80 "AES_CM_128_HMAC_SHA1_80"
|
||||||
|
|
||||||
enum SrtpSuite
|
enum SrtpSuite
|
||||||
{
|
{
|
||||||
SRTP_NONE,
|
SRTP_NONE,
|
||||||
SRTP_AES_128_AUTH_80,
|
SRTP_AES_128_AUTH_80,
|
||||||
SRTP_AES_256_AUTH_80,
|
SRTP_AES_256_AUTH_80,
|
||||||
SRTP_LAST = SRTP_AES_256_AUTH_80
|
SRTP_AES_192_AUTH_80,
|
||||||
|
SRTP_AES_128_AUTH_32,
|
||||||
|
SRTP_AES_256_AUTH_32,
|
||||||
|
SRTP_AES_192_AUTH_32,
|
||||||
|
SRTP_AES_128_AUTH_NULL,
|
||||||
|
SRTP_AED_AES_256_GCM,
|
||||||
|
SRTP_AED_AES_128_GCM,
|
||||||
|
SRTP_LAST = SRTP_AED_AES_128_GCM
|
||||||
|
// ToDo:
|
||||||
|
// a=crypto:1 AEAD_AES_256_GCM_8 inline:tN2A0vRjFBimpQsW2GasuJuPe7hKE26gki30APC8DVuySqCOYTs8lYBPR5I=
|
||||||
|
// a=crypto:3 AEAD_AES_128_GCM_8 inline:Ok7VL8SmBHSbZLw4dK6iQgpliYKGdY9BHLJcRw==
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern SrtpSuite toSrtpSuite(const std::string_view& s);
|
||||||
|
extern std::string_view toString(SrtpSuite suite);
|
||||||
|
|
||||||
typedef std::pair<PByteBuffer, PByteBuffer> SrtpKeySalt;
|
typedef std::pair<PByteBuffer, PByteBuffer> SrtpKeySalt;
|
||||||
typedef std::pair<unsigned, srtp_policy_t> SrtpStream;
|
typedef std::pair<unsigned, srtp_policy_t> SrtpStream;
|
||||||
|
|
||||||
class SrtpSession
|
class SrtpSession
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrtpSession();
|
SrtpSession();
|
||||||
~SrtpSession();
|
~SrtpSession();
|
||||||
|
|
||||||
enum SsrcDirection
|
|
||||||
{
|
|
||||||
sdIncoming,
|
|
||||||
sdOutgoing
|
|
||||||
};
|
|
||||||
SrtpKeySalt& outgoingKey(SrtpSuite suite);
|
|
||||||
|
|
||||||
void open(ByteBuffer& incomingKey, SrtpSuite suite);
|
enum SsrcDirection
|
||||||
void close();
|
{
|
||||||
bool active();
|
sdIncoming,
|
||||||
|
sdOutgoing
|
||||||
|
};
|
||||||
|
SrtpKeySalt& outgoingKey(SrtpSuite suite);
|
||||||
|
|
||||||
/* bufferPtr is RTP packet data i.e. header + payload. Buffer must be big enough to hold encrypted data. */
|
void open(ByteBuffer& incomingKey, SrtpSuite suite);
|
||||||
bool protectRtp(void* buffer, int* length);
|
void close();
|
||||||
bool protectRtcp(void* buffer, int* length);
|
bool active();
|
||||||
bool unprotectRtp(const void* src, size_t srcLength, void* dst, size_t* dstLength);
|
|
||||||
bool unprotectRtcp(const void* src, size_t srcLength, void* dst, size_t* dstLength);
|
|
||||||
|
|
||||||
|
|
||||||
static void initSrtp();
|
/* bufferPtr is RTP packet data i.e. header + payload. Buffer must be big enough to hold encrypted data. */
|
||||||
|
bool protectRtp(void* buffer, int* length);
|
||||||
|
bool protectRtcp(void* buffer, int* length);
|
||||||
|
bool unprotectRtp(const void* src, size_t srcLength, void* dst, size_t* dstLength);
|
||||||
|
bool unprotectRtcp(const void* src, size_t srcLength, void* dst, size_t* dstLength);
|
||||||
|
|
||||||
|
|
||||||
|
static void initSrtp();
|
||||||
protected:
|
protected:
|
||||||
srtp_t mInboundSession,
|
srtp_t mInboundSession,
|
||||||
mOutboundSession;
|
mOutboundSession;
|
||||||
|
|
||||||
SrtpKeySalt mIncomingKey,
|
SrtpKeySalt mIncomingKey,
|
||||||
mOutgoingKey[SRTP_LAST];
|
mOutgoingKey[SRTP_LAST];
|
||||||
srtp_policy_t mInboundPolicy;
|
srtp_policy_t mInboundPolicy;
|
||||||
srtp_policy_t mOutboundPolicy;
|
srtp_policy_t mOutboundPolicy;
|
||||||
SrtpSuite mSuite;
|
SrtpSuite mSuite;
|
||||||
|
|
||||||
typedef std::map<unsigned, SrtpStream> SrtpStreamMap;
|
typedef std::map<unsigned, SrtpStream> SrtpStreamMap;
|
||||||
SrtpStreamMap mIncomingMap, mOutgoingMap;
|
SrtpStreamMap mIncomingMap, mOutgoingMap;
|
||||||
Mutex mGuard;
|
Mutex mGuard;
|
||||||
|
|
||||||
void addSsrc(unsigned ssrc, SsrcDirection d);
|
void addSsrc(unsigned ssrc, SsrcDirection d);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -304,3 +304,10 @@ Logger::operator << (const std::string& data)
|
||||||
*mStream << data.c_str();
|
*mStream << data.c_str();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger&
|
||||||
|
Logger::operator << (const std::string_view& data)
|
||||||
|
{
|
||||||
|
*mStream << data;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,7 @@ public:
|
||||||
Logger& operator << (const int data);
|
Logger& operator << (const int data);
|
||||||
Logger& operator << (const float data);
|
Logger& operator << (const float data);
|
||||||
Logger& operator << (const std::string& data);
|
Logger& operator << (const std::string& data);
|
||||||
|
Logger& operator << (const std::string_view& data);
|
||||||
Logger& operator << (const int64_t data);
|
Logger& operator << (const int64_t data);
|
||||||
Logger& operator << (const unsigned int data);
|
Logger& operator << (const unsigned int data);
|
||||||
Logger& operator << (const uint64_t data);
|
Logger& operator << (const uint64_t data);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue