|
|
|
@ -319,41 +319,52 @@ static inline int check_session_keys(struct crypto_context *c) { |
|
|
|
if (c->have_session_key) |
|
|
|
return 0; |
|
|
|
if (!c->crypto_suite) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
|
|
|
|
str_init_len(&s, c->session_key, c->crypto_suite->session_key_len / 8); |
|
|
|
if (crypto_gen_session_key(c, &s, 0x03, 4)) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
str_init_len(&s, c->session_auth_key, c->crypto_suite->srtcp_auth_key_len / 8); |
|
|
|
if (crypto_gen_session_key(c, &s, 0x04, 4)) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
str_init_len(&s, c->session_salt, c->crypto_suite->session_salt_len / 8); |
|
|
|
if (crypto_gen_session_key(c, &s, 0x05, 4)) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
|
|
|
|
c->have_session_key = 1; |
|
|
|
return 0; |
|
|
|
|
|
|
|
error: |
|
|
|
mylog(LOG_ERROR, "Error generating SRTP session keys"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
static int rtcp_payload(struct rtcp_packet **out, str *p, const str *s) { |
|
|
|
struct rtcp_packet *rtcp; |
|
|
|
const char *err; |
|
|
|
|
|
|
|
err = "short packet (header)"; |
|
|
|
if (s->len < sizeof(*rtcp)) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
|
|
|
|
rtcp = (void *) s->s; |
|
|
|
|
|
|
|
err = "invalid header version"; |
|
|
|
if ((rtcp->header.v_p_x & 0xc0) != 0x80) /* version 2 */ |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
err = "invalid packet type"; |
|
|
|
if (rtcp->header.pt != RTCP_PT_SR |
|
|
|
&& rtcp->header.pt != RTCP_PT_RR) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
|
|
|
|
*p = *s; |
|
|
|
str_shift(p, sizeof(*rtcp)); |
|
|
|
*out = rtcp; |
|
|
|
|
|
|
|
return 0; |
|
|
|
error: |
|
|
|
mylog(LOG_WARNING, "Error parsing RTCP header: %s", err); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
/* rfc 3711 section 3.4 */ |
|
|
|
@ -391,6 +402,7 @@ int rtcp_savp2avp(str *s, struct crypto_context *c) { |
|
|
|
str payload, to_auth, to_decrypt, auth_tag; |
|
|
|
u_int32_t idx, *idx_p; |
|
|
|
char hmac[20]; |
|
|
|
const char *err; |
|
|
|
|
|
|
|
if (rtcp_payload(&rtcp, &payload, s)) |
|
|
|
return -1; |
|
|
|
@ -402,16 +414,18 @@ int rtcp_savp2avp(str *s, struct crypto_context *c) { |
|
|
|
s, &payload)) |
|
|
|
return -1; |
|
|
|
|
|
|
|
err = "short packet"; |
|
|
|
if (to_decrypt.len < sizeof(idx)) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
to_decrypt.len -= sizeof(idx); |
|
|
|
idx_p = (void *) to_decrypt.s + to_decrypt.len; |
|
|
|
idx = ntohl(*idx_p); |
|
|
|
|
|
|
|
assert(sizeof(hmac) >= auth_tag.len); |
|
|
|
c->crypto_suite->hash_rtcp(c, hmac, &to_auth); |
|
|
|
err = "authentication failed"; |
|
|
|
if (str_memcmp(&auth_tag, hmac)) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
|
|
|
|
if (idx & 0x80000000ULL) { |
|
|
|
if (crypto_decrypt_rtcp(c, rtcp, &to_decrypt, idx & 0x7fffffffULL)) |
|
|
|
@ -422,4 +436,8 @@ int rtcp_savp2avp(str *s, struct crypto_context *c) { |
|
|
|
to_auth.len -= sizeof(idx); |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
error: |
|
|
|
mylog(LOG_WARNING, "Discarded invalid SRTCP packet: %s", err); |
|
|
|
return -1; |
|
|
|
} |