diff options
author | Anders Broman <anders.broman@ericsson.com> | 2012-09-17 15:37:28 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2012-09-17 15:37:28 +0000 |
commit | d3334cb21dad067b8b858a168c1e9fee3843964a (patch) | |
tree | 6455634089f84ccdb762643bbf6c48eccf3ecc75 /epan | |
parent | 31c1f7d11dda78f4a0f3093491a12564087bd246 (diff) |
Handle SDP_CRYPTO optional parameters better.
svn path=/trunk/; revision=44946
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-sdp.c | 305 |
1 files changed, 158 insertions, 147 deletions
diff --git a/epan/dissectors/packet-sdp.c b/epan/dissectors/packet-sdp.c index 72b9ae65c0..4e2977527b 100644 --- a/epan/dissectors/packet-sdp.c +++ b/epan/dissectors/packet-sdp.c @@ -1811,159 +1811,170 @@ static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto } break; case SDP_CRYPTO: - /* http://tools.ietf.org/html/rfc4568 - * 9.1. Generic "Crypto" Attribute Grammar - * - * The ABNF grammar for the crypto attribute is defined below: - * - * "a=crypto:" tag 1*WSP crypto-suite 1*WSP key-params - * *(1*WSP session-param) - * - * tag = 1*9DIGIT - * crypto-suite = 1*(ALPHA / DIGIT / "_") - * - * key-params = key-param *(";" key-param) - * key-param = key-method ":" key-info - * key-method = "inline" / key-method-ext - * key-method-ext = 1*(ALPHA / DIGIT / "_") - * key-info = 1*(%x21-3A / %x3C-7E) ; visible (printing) chars - * ; except semi-colon - * session-param = 1*(VCHAR) ; visible (printing) characters - * - * where WSP, ALPHA, DIGIT, and VCHAR are defined in [RFC4234]. - * - */ - - /* We are at the first colon */ - /* tag */ - next_offset = tvb_find_guint8(tvb, offset, -1, ' '); - tokenlen = next_offset - offset; - proto_tree_add_uint(sdp_media_attribute_tree, hf_sdp_crypto_tag, tvb, offset, tokenlen, - atoi((char*)tvb_get_ephemeral_string(tvb, offset, tokenlen))); - offset = next_offset + 1; - - /* crypto-suite */ - next_offset = tvb_find_guint8(tvb, offset, -1, ' '); - tokenlen = next_offset - offset; - proto_tree_add_item(sdp_media_attribute_tree, hf_sdp_crypto_crypto_suite, - tvb, offset, tokenlen, ENC_ASCII|ENC_NA); - if (tvb_strncaseeql(tvb, offset, "AES_CM_128_HMAC_SHA1_80", tokenlen) == 0) { - - /* XXX This may only work in simple cases */ - if (transport_info->encryption_algorithm == SRTP_ENC_ALG_NOT_SET) { - transport_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM; - transport_info->auth_algorithm = SRTP_AUTH_ALG_HMAC_SHA1; - /* number of octets used for the Auth Tag in the RTP payload */ - transport_info->auth_tag_len = 10; - } - master_key_length = 16; /* 128 bits = 16 octets */ - master_salt_length = 14; /* 112 bits = 14 octets */ - } else if (tvb_strncaseeql(tvb, offset, "AES_CM_128_HMAC_SHA1_32", tokenlen) == 0) { - /* XXX This may only work in simple cases */ - if (transport_info->encryption_algorithm == SRTP_ENC_ALG_NOT_SET) { - transport_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM; - transport_info->auth_algorithm = SRTP_AUTH_ALG_HMAC_SHA1; - /* number of octets used for the Auth Tag in the RTP payload */ - transport_info->auth_tag_len = 4; - } - master_key_length = 16; /* 128 bits = 16 octets */ - master_salt_length = 14; /* 112 bits = 14 octets */ - } else if (tvb_strncaseeql(tvb, offset, "F8_128_HMAC_SHA1_80", tokenlen) == 0) { - if (transport_info->encryption_algorithm == SRTP_ENC_ALG_NOT_SET) { - /* XXX This may only work in simple cases */ - transport_info->encryption_algorithm = SRTP_ENC_ALG_AES_F8; - transport_info->auth_algorithm = SRTP_AUTH_ALG_HMAC_SHA1; - /* number of octets used for the Auth Tag in the RTP payload */ - transport_info->auth_tag_len = 10; - } - master_key_length = 16; /* 128 bits = 16 octets */ - master_salt_length = 14; /* 112 bits = 14 octets */ - } - offset = next_offset + 1; + /* http://tools.ietf.org/html/rfc4568 + * 9.1. Generic "Crypto" Attribute Grammar + * + * The ABNF grammar for the crypto attribute is defined below: + * + * "a=crypto:" tag 1*WSP crypto-suite 1*WSP key-params + * *(1*WSP session-param) + * + * tag = 1*9DIGIT + * crypto-suite = 1*(ALPHA / DIGIT / "_") + * + * key-params = key-param *(";" key-param) + * key-param = key-method ":" key-info + * key-method = "inline" / key-method-ext + * key-method-ext = 1*(ALPHA / DIGIT / "_") + * key-info = 1*(%x21-3A / %x3C-7E) ; visible (printing) chars + * ; except semi-colon + * session-param = 1*(VCHAR) ; visible (printing) characters + * + * where WSP, ALPHA, DIGIT, and VCHAR are defined in [RFC4234]. + * + */ - /* key-params */ - while (has_more_pars == TRUE) { - int param_end_offset; - tvbuff_t *key_salt_tvb; - gchar *data_p = NULL; + /* We are at the first colon */ + /* tag */ + next_offset = tvb_find_guint8(tvb, offset, -1, ' '); + tokenlen = next_offset - offset; + proto_tree_add_uint(sdp_media_attribute_tree, hf_sdp_crypto_tag, tvb, offset, tokenlen, + atoi((char*)tvb_get_ephemeral_string(tvb, offset, tokenlen))); + offset = next_offset + 1; - param_end_offset = tvb_find_guint8(tvb, offset, -1, ';'); - if (param_end_offset == -1) { - has_more_pars = FALSE; - param_end_offset = tvb_length(tvb); - } - parameter_item = proto_tree_add_text(sdp_media_attribute_tree, - tvb, offset, param_end_offset-offset, "Key parameters"); - parameter_tree = proto_item_add_subtree(parameter_item, ett_sdp_crypto_key_parameters); - - /* key-method or key-method-ext */ - next_offset = tvb_find_guint8(tvb, offset, -1, ':'); - if (next_offset == -1) { - expert_add_info_format(pinfo, parameter_item, PI_MALFORMED, PI_NOTE, - "Invalid key-param (no ':' delimiter)"); - break; + /* crypto-suite */ + next_offset = tvb_find_guint8(tvb, offset, -1, ' '); + tokenlen = next_offset - offset; + proto_tree_add_item(sdp_media_attribute_tree, hf_sdp_crypto_crypto_suite, + tvb, offset, tokenlen, ENC_ASCII|ENC_NA); + if (tvb_strncaseeql(tvb, offset, "AES_CM_128_HMAC_SHA1_80", tokenlen) == 0) { + + /* XXX This may only work in simple cases */ + if (transport_info->encryption_algorithm == SRTP_ENC_ALG_NOT_SET) { + transport_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM; + transport_info->auth_algorithm = SRTP_AUTH_ALG_HMAC_SHA1; + /* number of octets used for the Auth Tag in the RTP payload */ + transport_info->auth_tag_len = 10; + } + master_key_length = 16; /* 128 bits = 16 octets */ + master_salt_length = 14; /* 112 bits = 14 octets */ + } else if (tvb_strncaseeql(tvb, offset, "AES_CM_128_HMAC_SHA1_32", tokenlen) == 0) { + /* XXX This may only work in simple cases */ + if (transport_info->encryption_algorithm == SRTP_ENC_ALG_NOT_SET) { + transport_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM; + transport_info->auth_algorithm = SRTP_AUTH_ALG_HMAC_SHA1; + /* number of octets used for the Auth Tag in the RTP payload */ + transport_info->auth_tag_len = 4; + } + master_key_length = 16; /* 128 bits = 16 octets */ + master_salt_length = 14; /* 112 bits = 14 octets */ + } else if (tvb_strncaseeql(tvb, offset, "F8_128_HMAC_SHA1_80", tokenlen) == 0) { + if (transport_info->encryption_algorithm == SRTP_ENC_ALG_NOT_SET) { + /* XXX This may only work in simple cases */ + transport_info->encryption_algorithm = SRTP_ENC_ALG_AES_F8; + transport_info->auth_algorithm = SRTP_AUTH_ALG_HMAC_SHA1; + /* number of octets used for the Auth Tag in the RTP payload */ + transport_info->auth_tag_len = 10; + } + master_key_length = 16; /* 128 bits = 16 octets */ + master_salt_length = 14; /* 112 bits = 14 octets */ } - if (tvb_strncaseeql(tvb, offset, "inline", next_offset-offset) == 0) { - /* XXX only for SRTP? */ - /* srtp-key-info = key-salt ["|" lifetime] ["|" mki] */ - offset = next_offset +1; - next_offset = tvb_find_guint8(tvb, offset, -1, '|'); - if (next_offset == -1) { - tokenlen = param_end_offset - offset; - } else { - tokenlen = next_offset - offset; - } - data_p = tvb_get_ephemeral_string(tvb, offset, tokenlen); - key_salt_tvb = base64_to_tvb(tvb, data_p); - add_new_data_source(pinfo, key_salt_tvb, "Key_Salt_tvb"); - if (master_key_length != 0) { - proto_tree_add_text(parameter_tree, tvb, offset, tokenlen, "Key and Salt"); - proto_tree_add_item(parameter_tree, hf_sdp_crypto_master_key, - key_salt_tvb, 0, master_key_length, ENC_ASCII|ENC_NA); - proto_tree_add_item(parameter_tree, hf_sdp_crypto_master_salt, - key_salt_tvb, master_key_length, master_salt_length, ENC_ASCII|ENC_NA); - } else { - proto_tree_add_text(parameter_tree, key_salt_tvb, 0, -1, "Key and Salt"); - } + offset = next_offset + 1; - /* ["|" lifetime] ["|" mki] are optional */ - if (next_offset != -1) { - offset = next_offset + 1; - next_offset = tvb_find_guint8(tvb, offset, -1, '|'); - if (next_offset != -1) { - /*lifetime = ["2^"] 1*(DIGIT) ; see section 6.1 for "2^" */ - tokenlen = next_offset - offset; - proto_tree_add_item(parameter_tree, hf_sdp_crypto_lifetime, - tvb, offset, tokenlen, ENC_ASCII|ENC_NA); - offset = next_offset + 1; + /* key-params */ + while (has_more_pars == TRUE) { + int param_end_offset; + tvbuff_t *key_salt_tvb; + gchar *data_p = NULL; + + param_end_offset = tvb_find_guint8(tvb, offset, -1, ';'); + if (param_end_offset == -1) { + has_more_pars = FALSE; + param_end_offset = tvb_length(tvb); } - /* mki = mki-value ":" mki-length - * - * mki-value = 1*DIGIT - */ + parameter_item = proto_tree_add_text(sdp_media_attribute_tree, + tvb, offset, param_end_offset-offset, "Key parameters"); + parameter_tree = proto_item_add_subtree(parameter_item, ett_sdp_crypto_key_parameters); + + /* key-method or key-method-ext */ next_offset = tvb_find_guint8(tvb, offset, -1, ':'); - tokenlen = next_offset - offset; - proto_tree_add_item(parameter_tree, hf_sdp_crypto_mki, tvb, offset, tokenlen, ENC_ASCII|ENC_NA); - offset = next_offset + 1; - - /* mki-length = 1*3DIGIT ; range 1..128. */ - next_offset = param_end_offset; - tokenlen = next_offset - offset; - - /* This will not work if more than one parameter */ - /* number of octets used for the MKI in the RTP payload */ - transport_info->mki_len = atoi((char*)tvb_get_ephemeral_string(tvb, offset, tokenlen)); - proto_tree_add_item(parameter_tree, hf_sdp_crypto_mki_length, - tvb, offset, tokenlen, ENC_ASCII|ENC_NA); - } - offset = param_end_offset; - } else { - tokenlen = param_end_offset - next_offset + 1; - proto_tree_add_text(parameter_tree, tvb, next_offset + 1, tokenlen, - "%s", tvb_get_ephemeral_string(tvb, next_offset + 1, tokenlen)); - offset = param_end_offset; + if (next_offset == -1) { + expert_add_info_format(pinfo, parameter_item, PI_MALFORMED, PI_NOTE, + "Invalid key-param (no ':' delimiter)"); + break; + } + if (tvb_strncaseeql(tvb, offset, "inline", next_offset-offset) == 0) { + /* XXX only for SRTP? */ + /* srtp-key-info = key-salt ["|" lifetime] ["|" mki] */ + offset = next_offset +1; + next_offset = tvb_find_guint8(tvb, offset, -1, '|'); + if (next_offset == -1) { + tokenlen = param_end_offset - offset; + } else { + tokenlen = next_offset - offset; + } + data_p = tvb_get_ephemeral_string(tvb, offset, tokenlen); + key_salt_tvb = base64_to_tvb(tvb, data_p); + add_new_data_source(pinfo, key_salt_tvb, "Key_Salt_tvb"); + if (master_key_length != 0) { + proto_tree_add_text(parameter_tree, tvb, offset, tokenlen, "Key and Salt"); + proto_tree_add_item(parameter_tree, hf_sdp_crypto_master_key, + key_salt_tvb, 0, master_key_length, ENC_ASCII|ENC_NA); + proto_tree_add_item(parameter_tree, hf_sdp_crypto_master_salt, + key_salt_tvb, master_key_length, master_salt_length, ENC_ASCII|ENC_NA); + } else { + proto_tree_add_text(parameter_tree, key_salt_tvb, 0, -1, "Key and Salt"); + } + + /* ["|" lifetime] ["|" mki] are optional */ + if (next_offset != -1) { + offset = next_offset + 1; + next_offset = tvb_find_guint8(tvb, offset, -1, '|'); + if(next_offset == -1){ + if(next_offset < param_end_offset){ + next_offset = param_end_offset; + } + } + if (next_offset != -1) { + /*lifetime = ["2^"] 1*(DIGIT) ; see section 6.1 for "2^" */ + tokenlen = next_offset - offset; + proto_tree_add_item(parameter_tree, hf_sdp_crypto_lifetime, + tvb, offset, tokenlen, ENC_ASCII|ENC_NA); + offset = next_offset + 1; + } + /* mki = mki-value ":" mki-length + * + * mki-value = 1*DIGIT + */ + if(offset>param_end_offset){ + next_offset = -1; + }else{ + next_offset = tvb_find_guint8(tvb, offset, -1, ':'); + } + if (next_offset != -1) { + tokenlen = next_offset - offset; + proto_tree_add_item(parameter_tree, hf_sdp_crypto_mki, tvb, offset, tokenlen, ENC_ASCII|ENC_NA); + offset = next_offset + 1; + + /* mki-length = 1*3DIGIT ; range 1..128. */ + next_offset = param_end_offset; + tokenlen = next_offset - offset; + + /* This will not work if more than one parameter */ + /* number of octets used for the MKI in the RTP payload */ + transport_info->mki_len = atoi((char*)tvb_get_ephemeral_string(tvb, offset, tokenlen)); + proto_tree_add_item(parameter_tree, hf_sdp_crypto_mki_length, + tvb, offset, tokenlen, ENC_ASCII|ENC_NA); + } + } + offset = param_end_offset; + } else { + tokenlen = param_end_offset - next_offset + 1; + proto_tree_add_text(parameter_tree, tvb, next_offset + 1, tokenlen, + "%s", tvb_get_ephemeral_string(tvb, next_offset + 1, tokenlen)); + offset = param_end_offset; + } } - } break; default: @@ -2309,7 +2320,7 @@ proto_register_sdp(void) NULL, HFILL } }, { &hf_sdp_crypto_master_salt, - { "Mater salt", "sdp.crypto.master_salt", + { "Master salt", "sdp.crypto.master_salt", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, |