aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorJohn Thacker <johnthacker@gmail.com>2022-01-25 23:14:24 -0500
committerA Wireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2022-01-26 14:50:59 +0000
commit36521f27b384b13cc1359c5c16d10e3ed1094b60 (patch)
tree1d9ec6c8814c2d06e0d8c0cb8ee1ae159e6a4060 /epan/dissectors
parentac164db3ac993dfd2e896c734a6919b6054cb20e (diff)
DTLS-SRTP: Set up SRTP and SRTCP sessions
Use the information in a use_srtp Extension in a Server Hello to set up SRTP and SRTCP sessions according to RFC 5764. It is RECOMMENDED that symmetric RTP be used with DTLS-SRTP, and RTP and RTCP traffic may be multiplexed, so set up all four possible connections. Fix #17905.
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-dtls.c92
-rw-r--r--epan/dissectors/packet-dtls.h5
-rw-r--r--epan/dissectors/packet-rtcp.h2
-rw-r--r--epan/dissectors/packet-rtp.h3
-rw-r--r--epan/dissectors/packet-tls-utils.c6
5 files changed, 93 insertions, 15 deletions
diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c
index 44da2f38c8..f7eff590ff 100644
--- a/epan/dissectors/packet-dtls.c
+++ b/epan/dissectors/packet-dtls.c
@@ -53,6 +53,8 @@
#include <wsutil/rsa.h>
#include "packet-tls-utils.h"
#include "packet-dtls.h"
+#include "packet-rtp.h"
+#include "packet-rtcp.h"
void proto_register_dtls(void);
@@ -74,13 +76,21 @@ static proto_tree *top_tree;
*********************************************************************/
/* https://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml */
+
+#define SRTP_AES128_CM_HMAC_SHA1_80 0x0001
+#define SRTP_AES128_CM_HMAC_SHA1_32 0x0002
+#define SRTP_NULL_HMAC_SHA1_80 0x0005
+#define SRTP_NULL_HMAC_SHA1_32 0x0006
+#define SRTP_AEAD_AES_128_GCM 0x0007
+#define SRTP_AEAD_AES_256_GCM 0x0008
+
static const value_string srtp_protection_profile_vals[] = {
- { 0x0001, "SRTP_AES128_CM_HMAC_SHA1_80" }, /* RFC 5764 */
- { 0x0002, "SRTP_AES128_CM_HMAC_SHA1_32" },
- { 0x0005, "SRTP_NULL_HMAC_SHA1_80" },
- { 0x0006, "SRTP_NULL_HMAC_SHA1_32" },
- { 0x0007, "SRTP_AEAD_AES_128_GCM" }, /* RFC 7714 */
- { 0x0008, "SRTP_AEAD_AES_256_GCM" },
+ { SRTP_AES128_CM_HMAC_SHA1_80, "SRTP_AES128_CM_HMAC_SHA1_80" }, /* RFC 5764 */
+ { SRTP_AES128_CM_HMAC_SHA1_32, "SRTP_AES128_CM_HMAC_SHA1_32" },
+ { SRTP_NULL_HMAC_SHA1_80, "SRTP_NULL_HMAC_SHA1_80" },
+ { SRTP_NULL_HMAC_SHA1_32, "SRTP_NULL_HMAC_SHA1_32" },
+ { SRTP_AEAD_AES_128_GCM, "SRTP_AEAD_AES_128_GCM" }, /* RFC 7714 */
+ { SRTP_AEAD_AES_256_GCM, "SRTP_AEAD_AES_256_GCM" },
{ 0x00, NULL },
};
@@ -1655,8 +1665,9 @@ dissect_dtls_hnd_hello_verify_request(ssl_common_dissect_t *hf, tvbuff_t *tvb,
}
gint
-dtls_dissect_hnd_hello_ext_use_srtp(tvbuff_t *tvb, proto_tree *tree,
- guint32 offset, guint32 ext_len)
+dtls_dissect_hnd_hello_ext_use_srtp(packet_info *pinfo, tvbuff_t *tvb,
+ proto_tree *tree, guint32 offset,
+ guint32 ext_len, gboolean is_server)
{
/* From https://tools.ietf.org/html/rfc5764#section-4.1.1
*
@@ -1670,7 +1681,7 @@ dtls_dissect_hnd_hello_ext_use_srtp(tvbuff_t *tvb, proto_tree *tree,
* SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
*/
- guint32 profiles_length, profiles_end, mki_length;
+ guint32 profiles_length, profiles_end, profile, mki_length;
if (ext_len < 2) {
/* XXX expert info, record too small */
@@ -1689,8 +1700,13 @@ dtls_dissect_hnd_hello_ext_use_srtp(tvbuff_t *tvb, proto_tree *tree,
/* SRTPProtectionProfiles list items */
profiles_end = offset + profiles_length;
while (offset < profiles_end) {
- proto_tree_add_item(tree, hf_dtls_hs_ext_use_srtp_protection_profile,
- tvb, offset, 2, ENC_BIG_ENDIAN);
+ /* The server, if sending the use_srtp extension, MUST return a
+ * single chosen profile that the client has offered. We will
+ * use that to set up the connection.
+ */
+ proto_tree_add_item_ret_uint(tree,
+ hf_dtls_hs_ext_use_srtp_protection_profile, tvb, offset, 2,
+ ENC_BIG_ENDIAN, &profile);
offset += 2;
}
@@ -1704,6 +1720,60 @@ dtls_dissect_hnd_hello_ext_use_srtp(tvbuff_t *tvb, proto_tree *tree,
offset += mki_length;
}
+ if (is_server) {
+ struct srtp_info *srtp_info = wmem_new0(wmem_file_scope(), struct srtp_info);
+ switch(profile) {
+ case SRTP_AES128_CM_HMAC_SHA1_80:
+ srtp_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM;
+ srtp_info->auth_algorithm = SRTP_AUTH_ALG_HMAC_SHA1;
+ srtp_info->auth_tag_len = 10;
+ break;
+ case SRTP_AES128_CM_HMAC_SHA1_32:
+ srtp_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM;
+ srtp_info->auth_algorithm = SRTP_AUTH_ALG_HMAC_SHA1;
+ srtp_info->auth_tag_len = 4;
+ break;
+ case SRTP_NULL_HMAC_SHA1_80:
+ srtp_info->encryption_algorithm = SRTP_ENC_ALG_NULL;
+ srtp_info->auth_algorithm = SRTP_AUTH_ALG_HMAC_SHA1;
+ srtp_info->auth_tag_len = 10;
+ break;
+ case SRTP_NULL_HMAC_SHA1_32:
+ srtp_info->encryption_algorithm = SRTP_ENC_ALG_NULL;
+ srtp_info->auth_algorithm = SRTP_AUTH_ALG_HMAC_SHA1;
+ srtp_info->auth_tag_len = 4;
+ break;
+ case SRTP_AEAD_AES_128_GCM:
+ srtp_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM;
+ srtp_info->auth_algorithm = SRTP_AUTH_ALG_GMAC;
+ srtp_info->auth_tag_len = 16;
+ break;
+ case SRTP_AEAD_AES_256_GCM:
+ srtp_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM;
+ srtp_info->auth_algorithm = SRTP_AUTH_ALG_GMAC;
+ srtp_info->auth_tag_len = 16;
+ break;
+ default:
+ srtp_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM;
+ srtp_info->auth_algorithm = SRTP_AUTH_ALG_HMAC_SHA1;
+ srtp_info->auth_tag_len = 10;
+ }
+ srtp_info->mki_len = mki_length;
+ /* RFC 5764: It is RECOMMENDED that symmetric RTP be used with DTLS-SRTP.
+ * RTP and RTCP traffic MAY be multiplexed on a single UDP port. (RFC 5761)
+ *
+ * XXX: We call srtp_add_address last because both it and srtcp_add_address
+ * set the conversation dissector to themselves, but while the [S]RTP
+ * dissector forwards [S]RTCP payload types to the RTCP dissector, the RTCP
+ * dissector does not do the reverse, so it's better to have the RTP
+ * dissector take a look first. Perhaps that should be changed, along with
+ * some other things to better support multiplexed RFC 5761 connections.
+ */
+ srtcp_add_address(pinfo, &pinfo->net_src, pinfo->srcport, pinfo->destport, "DTLS-SRTP", pinfo->num, srtp_info);
+ srtcp_add_address(pinfo, &pinfo->net_dst, pinfo->destport, pinfo->srcport, "DTLS-SRTP", pinfo->num, srtp_info);
+ srtp_add_address(pinfo, PT_UDP, &pinfo->net_src, pinfo->srcport, pinfo->destport, "DTLS-SRTP", pinfo->num, RTP_MEDIA_AUDIO, NULL, srtp_info, NULL);
+ srtp_add_address(pinfo, PT_UDP, &pinfo->net_dst, pinfo->destport, pinfo->srcport, "DTLS-SRTP", pinfo->num, RTP_MEDIA_AUDIO, NULL, srtp_info, NULL);
+ }
return offset;
}
diff --git a/epan/dissectors/packet-dtls.h b/epan/dissectors/packet-dtls.h
index 8e07a3bbba..1351282b04 100644
--- a/epan/dissectors/packet-dtls.h
+++ b/epan/dissectors/packet-dtls.h
@@ -21,7 +21,8 @@ WS_DLL_PUBLIC void dtls_dissector_delete(guint port, dissector_handle_t handle);
/* Shared with packet-tls-utils.c */
gint
-dtls_dissect_hnd_hello_ext_use_srtp(tvbuff_t *tvb, proto_tree *tree,
- guint32 offset, guint32 ext_len);
+dtls_dissect_hnd_hello_ext_use_srtp(packet_info *pinfo, tvbuff_t *tvb,
+ proto_tree *tree, guint32 offset,
+ guint32 ext_len, gboolean is_server);
#endif /* __PACKET_DTLS_H__ */
diff --git a/epan/dissectors/packet-rtcp.h b/epan/dissectors/packet-rtcp.h
index b18c7a0f21..bdbb1de50c 100644
--- a/epan/dissectors/packet-rtcp.h
+++ b/epan/dissectors/packet-rtcp.h
@@ -18,7 +18,7 @@
/* Info to save in RTCP conversation / packet-info.
Note that this structure applies to the destination end of
an RTP session */
-#define MAX_RTCP_SETUP_METHOD_SIZE 7
+#define MAX_RTCP_SETUP_METHOD_SIZE 10
struct _rtcp_conversation_info
{
/* Setup info is relevant to traffic whose dest is the conversation address */
diff --git a/epan/dissectors/packet-rtp.h b/epan/dissectors/packet-rtp.h
index 748165cdd8..8c88c1ddc1 100644
--- a/epan/dissectors/packet-rtp.h
+++ b/epan/dissectors/packet-rtp.h
@@ -60,16 +60,19 @@ struct _rtp_info {
};
/* definitions for SRTP dissection */
+/* https://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml */
/* Encryption algorithms */
#define SRTP_ENC_ALG_NOT_SET 0 /* Data not available/empty record */
#define SRTP_ENC_ALG_NULL 1 /* non-encrypted SRTP payload - may still be authenticated */
#define SRTP_ENC_ALG_AES_CM 2 /* SRTP default algorithm */
#define SRTP_ENC_ALG_AES_F8 3
+#define SRTP_ENC_ALG_AES_GCM 4 /* RFC 7714 */
/* Authentication algorithms */
#define SRTP_AUTH_ALG_NONE 0 /* no auth tag in SRTP/RTP payload */
#define SRTP_AUTH_ALG_HMAC_SHA1 1 /* SRTP default algorithm */
+#define SRTP_AUTH_ALG_GMAC 2 /* RFC 7714 */
#if 0 /* these are only needed once the dissector include the crypto functions to decrypt and/or authenticate */
diff --git a/epan/dissectors/packet-tls-utils.c b/epan/dissectors/packet-tls-utils.c
index a0b1239aba..13428de959 100644
--- a/epan/dissectors/packet-tls-utils.c
+++ b/epan/dissectors/packet-tls-utils.c
@@ -9674,7 +9674,11 @@ ssl_dissect_hnd_extension(ssl_common_dissect_t *hf, tvbuff_t *tvb, proto_tree *t
break;
case SSL_HND_HELLO_EXT_USE_SRTP:
if (is_dtls) {
- offset = dtls_dissect_hnd_hello_ext_use_srtp(tvb, ext_tree, offset, next_offset);
+ if (hnd_type == SSL_HND_CLIENT_HELLO) {
+ offset = dtls_dissect_hnd_hello_ext_use_srtp(pinfo, tvb, ext_tree, offset, next_offset, FALSE);
+ } else if (hnd_type == SSL_HND_SERVER_HELLO) {
+ offset = dtls_dissect_hnd_hello_ext_use_srtp(pinfo, tvb, ext_tree, offset, next_offset, TRUE);
+ }
} else {
// XXX expert info: This extension MUST only be used with DTLS, and not with TLS.
}