Add srt caller mode and stream encryption support. (#4088)

Add srt caller mode and stream encryption support.
1. Support srt caller mode, realize srt proxy pull stream proxy push
stream;
url parameter format such as: srt://127.0.0.1:9000?streamid=#!
::r=live/test11
2. Support srt stream encrypted transmission in caller and listener
mode.

---------

Co-authored-by: xiongguangjie <xiong_panda@163.com>
This commit is contained in:
baigao-X
2024-12-28 20:21:29 +08:00
committed by GitHub
parent cb4db80502
commit 1c8ed1c55a
27 changed files with 3002 additions and 17 deletions

View File

@@ -131,4 +131,162 @@ std::string HSExtStreamID::dump() {
return std::move(printer);
}
} // namespace SRT
size_t KeyMaterial::getContentSize() {
size_t variable_width = _slen + _warpped_key.size();
size_t content_size = variable_width + 16;
return content_size;
}
bool KeyMaterial::loadFromData(uint8_t *buf, size_t len) {
if (buf == NULL || len < 16) {
return false;
}
uint8_t *ptr = (uint8_t *)buf;
_km_version = (*ptr & 0x70) >> 4;
_pt = *ptr & 0x0f;
ptr += 1;
_sign = loadUint16(ptr);
ptr += 2;
_kk = *ptr & 0x03;
auto sek_num = 1;
if (_kk == KEY_BASED_ENCRYPTION_BOTH_SEK) {
sek_num = 2;
}
ptr += 1;
_keki = loadUint32(ptr);
ptr += 4;
_cipher = *ptr;
ptr += 1;
_auth = *ptr;
ptr += 1;
_se = *ptr;
ptr += 1;
//Resv2
ptr += 1;
//Resv3
ptr += 2;
_slen = *ptr *4;
ptr += 1;
_klen = *ptr *4;
ptr += 1;
size_t wrapped_key_len = 8 + sek_num * _klen;
size_t variable_width = _slen + wrapped_key_len;
if (len < variable_width + 16) {
return false;
}
_salt.assign((const char*)ptr, (size_t)_slen);
ptr += _slen;
_warpped_key.assign((const char*)ptr, (size_t)wrapped_key_len);
return true;
}
bool KeyMaterial::storeToData(uint8_t *buf, size_t len) {
auto content_size = getContentSize();
if (len < content_size) {
return false;
}
uint8_t *ptr = (uint8_t *)buf;
memset(ptr, 0, len);
*ptr = ((_km_version << 4)& 0x70) | (_pt & 0x0f);
ptr += 1;
storeUint16(ptr, _sign);
ptr += 2;
*ptr = _kk & 0x03;
ptr += 1;
storeUint32(ptr, _keki);
ptr += 4;
*ptr = _cipher;
ptr += 1;
*ptr = _auth;
ptr += 1;
*ptr = _se;
ptr += 1;
*ptr = 0; //Resv2
ptr += 1;
storeUint16(ptr, 0);//Resv3
ptr += 2;
*ptr = (uint8_t)(_slen/4);
ptr += 1;
*ptr = (uint8_t)(_klen/4);
ptr += 1;
const char *src = _salt.data();
for (size_t i = 0; i < _salt.size(); ptr++, src++, i++) {
*ptr = *src;
}
src = _warpped_key.data();
for (size_t i = 0; i < _warpped_key.size(); ptr++, src++, i++) {
*ptr = *src;
}
return true;
}
std::string KeyMaterial::dump() {
_StrPrinter printer;
printer << "kmVersion: " << _km_version
<< " pt : " << _pt
<< " sign : " << std::hex << _sign
<< " kk : " << _kk
<< " keki : " << _keki
<< " cipher : " << _cipher
<< " auth : " << _auth
<< " se : " << _se
<< " sLen : " << _slen
<< " salt : " << std::hex << _salt.data()
<< " kLen : " << _klen;
return std::move(printer);
}
bool HSExtKeyMaterial::loadFromData(uint8_t *buf, size_t len) {
if (buf == NULL || len < 4) {
return false;
}
HSExt::_data = BufferRaw::create();
HSExt::_data->assign((char *)buf, len);
HSExt::loadHeader();
assert(extension_type == SRT_CMD_KMREQ || extension_type == SRT_CMD_KMRSP);
return KeyMaterial::loadFromData(buf +4, len -4);
}
bool HSExtKeyMaterial::storeToData() {
size_t content_size = ((KeyMaterial::getContentSize() + 4) + 3) / 4 * 4;
HSExt::_data = BufferRaw::create();
HSExt::_data->setCapacity(content_size);
HSExt::_data->setSize(content_size);
extension_length = (content_size - 4) / 4;
HSExt::storeHeader();
return KeyMaterial::storeToData((uint8_t*)_data->data() + 4, content_size - 4);
}
std::string HSExtKeyMaterial::dump() {
return KeyMaterial::dump();
}
} // namespace SRT