Merge pull request #136 from fancycode/unprotect_empty_payload
Allow empty payloads when unprotecting.
diff --git a/srtp/srtp.c b/srtp/srtp.c
index f60c5fb..c9a5bee 100644
--- a/srtp/srtp.c
+++ b/srtp/srtp.c
@@ -141,6 +141,33 @@
return rv;
}
+/* Release (maybe partially allocated) stream. */
+static void
+srtp_stream_free(srtp_stream_ctx_t *str) {
+ if (str->rtp_xtn_hdr_cipher) {
+ srtp_cipher_dealloc(str->rtp_xtn_hdr_cipher);
+ }
+ if (str->enc_xtn_hdr) {
+ srtp_crypto_free(str->enc_xtn_hdr);
+ }
+ if (str->rtcp_auth) {
+ auth_dealloc(str->rtcp_auth);
+ }
+ if (str->rtcp_cipher) {
+ srtp_cipher_dealloc(str->rtcp_cipher);
+ }
+ if (str->limit) {
+ srtp_crypto_free(str->limit);
+ }
+ if (str->rtp_auth) {
+ auth_dealloc(str->rtp_auth);
+ }
+ if (str->rtp_cipher) {
+ srtp_cipher_dealloc(str->rtp_cipher);
+ }
+ srtp_crypto_free(str);
+}
+
srtp_err_status_t
srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
const srtp_policy_t *p) {
@@ -159,15 +186,17 @@
str = (srtp_stream_ctx_t *) srtp_crypto_alloc(sizeof(srtp_stream_ctx_t));
if (str == NULL)
return srtp_err_status_alloc_fail;
- *str_ptr = str;
-
+
+ memset(str, 0, sizeof(srtp_stream_ctx_t));
+ *str_ptr = str;
+
/* allocate cipher */
stat = srtp_crypto_kernel_alloc_cipher(p->rtp.cipher_type,
&str->rtp_cipher,
p->rtp.cipher_key_len,
p->rtp.auth_tag_len);
if (stat) {
- srtp_crypto_free(str);
+ srtp_stream_free(str);
return stat;
}
@@ -177,17 +206,14 @@
p->rtp.auth_key_len,
p->rtp.auth_tag_len);
if (stat) {
- srtp_cipher_dealloc(str->rtp_cipher);
- srtp_crypto_free(str);
+ srtp_stream_free(str);
return stat;
}
/* allocate key limit structure */
str->limit = (srtp_key_limit_ctx_t*) srtp_crypto_alloc(sizeof(srtp_key_limit_ctx_t));
if (str->limit == NULL) {
- auth_dealloc(str->rtp_auth);
- srtp_cipher_dealloc(str->rtp_cipher);
- srtp_crypto_free(str);
+ srtp_stream_free(str);
return srtp_err_status_alloc_fail;
}
@@ -200,10 +226,7 @@
p->rtcp.cipher_key_len,
p->rtcp.auth_tag_len);
if (stat) {
- auth_dealloc(str->rtp_auth);
- srtp_cipher_dealloc(str->rtp_cipher);
- srtp_crypto_free(str->limit);
- srtp_crypto_free(str);
+ srtp_stream_free(str);
return stat;
}
@@ -213,24 +236,15 @@
p->rtcp.auth_key_len,
p->rtcp.auth_tag_len);
if (stat) {
- srtp_cipher_dealloc(str->rtcp_cipher);
- auth_dealloc(str->rtp_auth);
- srtp_cipher_dealloc(str->rtp_cipher);
- srtp_crypto_free(str->limit);
- srtp_crypto_free(str);
- return stat;
+ srtp_stream_free(str);
+ return stat;
}
/* allocate ekt data associated with stream */
stat = srtp_ekt_alloc(&str->ekt, p->ekt);
if (stat) {
- auth_dealloc(str->rtcp_auth);
- srtp_cipher_dealloc(str->rtcp_cipher);
- auth_dealloc(str->rtp_auth);
- srtp_cipher_dealloc(str->rtp_cipher);
- srtp_crypto_free(str->limit);
- srtp_crypto_free(str);
- return stat;
+ srtp_stream_free(str);
+ return stat;
}
if (p->enc_xtn_hdr && p->enc_xtn_hdr_count > 0) {
@@ -239,12 +253,7 @@
str->enc_xtn_hdr = (int*) srtp_crypto_alloc(p->enc_xtn_hdr_count * sizeof(p->enc_xtn_hdr[0]));
if (!str->enc_xtn_hdr) {
- auth_dealloc(str->rtcp_auth);
- srtp_cipher_dealloc(str->rtcp_cipher);
- auth_dealloc(str->rtp_auth);
- srtp_cipher_dealloc(str->rtp_cipher);
- srtp_crypto_free(str->limit);
- srtp_crypto_free(str);
+ srtp_stream_free(str);
return srtp_err_status_alloc_fail;
}
memcpy(str->enc_xtn_hdr, p->enc_xtn_hdr, p->enc_xtn_hdr_count * sizeof(p->enc_xtn_hdr[0]));
@@ -272,13 +281,7 @@
enc_xtn_hdr_cipher_key_len,
0);
if (stat) {
- srtp_crypto_free(str->enc_xtn_hdr);
- auth_dealloc(str->rtcp_auth);
- srtp_cipher_dealloc(str->rtcp_cipher);
- auth_dealloc(str->rtp_auth);
- srtp_cipher_dealloc(str->rtp_cipher);
- srtp_crypto_free(str->limit);
- srtp_crypto_free(str);
+ srtp_stream_free(str);
return stat;
}
} else {
@@ -819,6 +822,15 @@
octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
return srtp_err_status_init_fail;
}
+
+ if (xtn_hdr_kdf != &kdf) {
+ /* release memory for custom header extension encryption kdf */
+ stat = srtp_kdf_clear(xtn_hdr_kdf);
+ if (stat) {
+ octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+ return srtp_err_status_init_fail;
+ }
+ }
}
/* generate authentication key */
diff --git a/test/srtp_driver.c b/test/srtp_driver.c
index 44bd502..4929ca4 100644
--- a/test/srtp_driver.c
+++ b/test/srtp_driver.c
@@ -1651,8 +1651,11 @@
* unprotect ciphertext, then compare with plaintext
*/
status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
- if (status || (len != 28))
+ if (status) {
return status;
+ } else if (len != sizeof(srtp_plaintext_ref)) {
+ return srtp_err_status_fail;
+ }
if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
return srtp_err_status_fail;
@@ -1670,6 +1673,7 @@
#ifdef OPENSSL
+
/*
* Headers of test vectors taken from RFC 6904, Appendix A
*/
@@ -1766,8 +1770,11 @@
* unprotect ciphertext, then compare with plaintext
*/
status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
- if (status || (len != 28))
+ if (status) {
return status;
+ } else if (len != sizeof(srtp_plaintext_ref)) {
+ return srtp_err_status_fail;
+ }
if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
return srtp_err_status_fail;
@@ -2231,6 +2238,7 @@
srtp_t srtp_snd, srtp_recv;
srtp_policy_t policy;
+ memset(&policy, 0, sizeof(policy));
srtp_crypto_policy_set_rtp_default(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
policy.ekt = NULL;