1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

RTC: refine srtp layer

This commit is contained in:
jinxue.cgh 2020-06-25 14:50:14 +08:00 committed by winlin
parent 81d2e10f65
commit b6ecb0a18f
4 changed files with 181 additions and 165 deletions

View file

@ -427,13 +427,148 @@ srs_error_t SrsDtls::do_handshake()
return handshake();
}
srs_error_t SrsDtls::export_keying_material(unsigned char *out, size_t olen, const char *label, size_t llen, const unsigned char *p, size_t plen, int use_context)
const int SRTP_MASTER_KEY_KEY_LEN = 16;
const int SRTP_MASTER_KEY_SALT_LEN = 14;
srs_error_t SrsDtls::get_srtp_key(std::string& client_key, std::string& server_key)
{
srs_error_t err = srs_success;
if (!SSL_export_keying_material(dtls, out, olen, label, llen, p, plen, use_context)) {
unsigned char material[SRTP_MASTER_KEY_LEN * 2] = {0}; // client(SRTP_MASTER_KEY_KEY_LEN + SRTP_MASTER_KEY_SALT_LEN) + server
static const string dtls_srtp_lable = "EXTRACTOR-dtls_srtp";
if (!SSL_export_keying_material(dtls, material, sizeof(material), dtls_srtp_lable.c_str(), dtls_srtp_lable.size(), NULL, 0, 0)) {
return srs_error_new(ERROR_RTC_SRTP_INIT, "SSL_export_keying_material failed");
}
size_t offset = 0;
std::string client_master_key(reinterpret_cast<char*>(material), SRTP_MASTER_KEY_KEY_LEN);
offset += SRTP_MASTER_KEY_KEY_LEN;
std::string server_master_key(reinterpret_cast<char*>(material + offset), SRTP_MASTER_KEY_KEY_LEN);
offset += SRTP_MASTER_KEY_KEY_LEN;
std::string client_master_salt(reinterpret_cast<char*>(material + offset), SRTP_MASTER_KEY_SALT_LEN);
offset += SRTP_MASTER_KEY_SALT_LEN;
std::string server_master_salt(reinterpret_cast<char*>(material + offset), SRTP_MASTER_KEY_SALT_LEN);
client_key = client_master_key + client_master_salt;
server_key = server_master_key + server_master_salt;
return err;
}
SrsSRTP::SrsSRTP()
{
srtp_ctx = NULL;
}
SrsSRTP::~SrsSRTP()
{
if (srtp_ctx) {
srtp_dealloc(srtp_ctx);
}
}
srs_error_t SrsSRTP::initialize(string srtp_key, bool send)
{
srs_error_t err = srs_success;
srtp_policy_t policy;
bzero(&policy, sizeof(policy));
// TODO: Maybe we can use SRTP-GCM in future.
// @see https://bugs.chromium.org/p/chromium/issues/detail?id=713701
// @see https://groups.google.com/forum/#!topic/discuss-webrtc/PvCbWSetVAQ
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
if (send) {
policy.ssrc.type = ssrc_any_outbound;
} else {
policy.ssrc.type = ssrc_any_inbound;
}
policy.ssrc.value = 0;
// TODO: adjust window_size
policy.window_size = 8192;
policy.allow_repeat_tx = 1;
policy.next = NULL;
//uint8_t *key = new uint8_t[server_key.size()];
//memcpy(key, server_key.data(), server_key.size());
uint8_t *key = new uint8_t[srtp_key.size()];
memcpy(key, srtp_key.data(), srtp_key.size());
policy.key = key;
if (srtp_create(&srtp_ctx, &policy) != srtp_err_status_ok) {
srs_freepa(key);
return srs_error_new(ERROR_RTC_SRTP_INIT, "srtp_create failed");
}
srs_freepa(key);
return err;
}
srs_error_t SrsSRTP::protect_rtp(char* out_buf, const char* in_buf, int& nb_out_buf)
{
srs_error_t err = srs_success;
memcpy(out_buf, in_buf, nb_out_buf);
// TODO: FIXME: Wrap error code.
if (srtp_protect(srtp_ctx, out_buf, &nb_out_buf) != 0) {
return srs_error_new(ERROR_RTC_SRTP_PROTECT, "rtp protect failed");
}
return err;
}
srs_error_t SrsSRTP::protect_rtp2(void* rtp_hdr, int* len_ptr)
{
srs_error_t err = srs_success;
// TODO: FIXME: Wrap error code.
if (srtp_protect(srtp_ctx, rtp_hdr, len_ptr) != 0) {
return srs_error_new(ERROR_RTC_SRTP_PROTECT, "rtp protect");
}
return err;
}
srs_error_t SrsSRTP::unprotect_rtp(char* out_buf, const char* in_buf, int& nb_out_buf)
{
srs_error_t err = srs_success;
memcpy(out_buf, in_buf, nb_out_buf);
srtp_err_status_t r0 = srtp_unprotect(srtp_ctx, out_buf, &nb_out_buf);
if (r0 != srtp_err_status_ok) {
return srs_error_new(ERROR_RTC_SRTP_UNPROTECT, "unprotect r0=%u", r0);
}
return err;
}
srs_error_t SrsSRTP::protect_rtcp(char* out_buf, const char* in_buf, int& nb_out_buf)
{
srs_error_t err = srs_success;
memcpy(out_buf, in_buf, nb_out_buf);
// TODO: FIXME: Wrap error code.
if (srtp_protect_rtcp(srtp_ctx, out_buf, &nb_out_buf) != 0) {
return srs_error_new(ERROR_RTC_SRTP_PROTECT, "rtcp protect failed");
}
return err;
}
srs_error_t SrsSRTP::unprotect_rtcp(char* out_buf, const char* in_buf, int& nb_out_buf)
{
srs_error_t err = srs_success;
memcpy(out_buf, in_buf, nb_out_buf);
// TODO: FIXME: Wrap error code.
if (srtp_unprotect_rtcp(srtp_ctx, out_buf, &nb_out_buf) != srtp_err_status_ok) {
return srs_error_new(ERROR_RTC_SRTP_UNPROTECT, "rtcp unprotect failed");
}
return err;
}