|
|
|
@ -6,6 +6,7 @@ |
|
|
|
|
|
|
|
#include "str.h" |
|
|
|
#include "crypto.h" |
|
|
|
#include "log.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -16,20 +17,24 @@ 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); |
|
|
|
if (crypto_gen_session_key(c, &s, 0x00, 6)) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
str_init_len(&s, c->session_auth_key, c->crypto_suite->srtp_auth_key_len); |
|
|
|
if (crypto_gen_session_key(c, &s, 0x01, 6)) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
str_init_len(&s, c->session_salt, c->crypto_suite->session_salt_len); |
|
|
|
if (crypto_gen_session_key(c, &s, 0x02, 6)) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
|
|
|
|
c->have_session_key = 1; |
|
|
|
return 0; |
|
|
|
|
|
|
|
error: |
|
|
|
mylog(LOG_WARNING, "Error generating SRTP session keys"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
static int rtp_payload(struct rtp_header **out, str *p, const str *s) { |
|
|
|
@ -37,31 +42,35 @@ static int rtp_payload(struct rtp_header **out, str *p, const str *s) { |
|
|
|
struct rtp_extension *ext; |
|
|
|
|
|
|
|
if (s->len < sizeof(*rtp)) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
|
|
|
|
rtp = (void *) s->s; |
|
|
|
if ((rtp->v_p_x_cc & 0xc0) != 0x80) /* version 2 */ |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
|
|
|
|
*p = *s; |
|
|
|
/* fixed header */ |
|
|
|
str_shift(p, sizeof(*rtp)); |
|
|
|
/* csrc list */ |
|
|
|
if (str_shift(p, (rtp->v_p_x_cc & 0xf) * 4)) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
|
|
|
|
if ((rtp->v_p_x_cc & 0x10)) { |
|
|
|
/* extension */ |
|
|
|
if (p->len < sizeof(*ext)) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
ext = (void *) p->s; |
|
|
|
if (str_shift(p, 4 + ntohs(ext->length) * 4)) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
} |
|
|
|
|
|
|
|
*out = rtp; |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
error: |
|
|
|
mylog(LOG_WARNING, "Error parsing RTP header"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
static u_int64_t packet_index(struct crypto_context *c, struct rtp_header *rtp) { |
|
|
|
@ -125,7 +134,6 @@ void rtp_append_mki(str *s, struct crypto_context *c) { |
|
|
|
} |
|
|
|
|
|
|
|
/* rfc 3711, section 3.3 */ |
|
|
|
/* XXX some error handling/logging here */ |
|
|
|
int rtp_avp2savp(str *s, struct crypto_context *c) { |
|
|
|
struct rtp_header *rtp; |
|
|
|
str payload, to_auth; |
|
|
|
@ -203,7 +211,7 @@ int srtp_payloads(str *to_auth, str *to_decrypt, str *auth_tag, str *mki, |
|
|
|
*auth_tag = STR_NULL; |
|
|
|
if (auth_len) { |
|
|
|
if (to_decrypt->len < auth_len) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
|
|
|
|
str_init_len(auth_tag, to_decrypt->s + to_decrypt->len - auth_len, auth_len); |
|
|
|
to_decrypt->len -= auth_len; |
|
|
|
@ -214,7 +222,7 @@ int srtp_payloads(str *to_auth, str *to_decrypt, str *auth_tag, str *mki, |
|
|
|
*mki = STR_NULL; |
|
|
|
if (mki_len) { |
|
|
|
if (to_decrypt->len < mki_len) |
|
|
|
return -1; |
|
|
|
goto error; |
|
|
|
|
|
|
|
if (mki) |
|
|
|
str_init_len(mki, to_decrypt->s - mki_len, mki_len); |
|
|
|
@ -223,4 +231,8 @@ int srtp_payloads(str *to_auth, str *to_decrypt, str *auth_tag, str *mki, |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
error: |
|
|
|
mylog(LOG_WARNING, "Invalid SRTP packet received"); |
|
|
|
return -1; |
|
|
|
} |