forked from osmocom/wireshark
From Frederic Roudaut:
I updated my previous patch of ESP : * It now check authentication for (similar to the ICMP checksum): - NULL Authentication - HMAC-SHA1-96 [RFC2404] - HMAC-SHA256 - HMAC-MD5-96 [RFC2403] (2) I put aside AES-XCBC-MAC-96 [RFC3566] because I did not succeed to have a working implementation. I added a field for any authenticator of 12bytes length (without authentication process) * I also correct the printing of this authenticator field which was decrypted :-[ . Thus, with this patch if libgcrypt is linked withe ethereal you should have the availability to : - decrypt packets - check authentication at the same time or not. If noone of these options are set (or libgcrypt is not available) you also may use the previous heuristic. svn path=/trunk/; revision=17858
This commit is contained in:
parent
336cc54807
commit
93e95ca62b
|
@ -26,12 +26,12 @@
|
|||
|
||||
/*
|
||||
|
||||
Addon:
|
||||
Addon: ESP Decryption and Authentication Checking
|
||||
|
||||
Frederic ROUDAUT (frederic.roudaut@free.fr)
|
||||
Copyright 2006 Frederic ROUDAUT
|
||||
|
||||
- Decrypt ESP Payload with the following Algorithms defined in RFC 4305:
|
||||
- Decrypt ESP Payload for the following Algorithms defined in RFC 4305:
|
||||
|
||||
Encryption Algorithm
|
||||
--------------------
|
||||
|
@ -41,20 +41,26 @@ AES-CBC with 128-bit keys [RFC3602] : keylen 128 and 192/256 bits.
|
|||
AES-CTR [RFC3686] : keylen 160/224/288 bits. The remaining 32 bits will be used as nonce.
|
||||
DES-CBC [RFC2405] : keylen 64 bits
|
||||
|
||||
Authentication Algorithm (in fact all Algorithms since it uses 12 bytes in the Auth field)
|
||||
------------------------
|
||||
HMAC-SHA1-96 [RFC2404]
|
||||
NULL
|
||||
AES-XCBC-MAC-96 [RFC3566]
|
||||
HMAC-MD5-96 [RFC2403]
|
||||
|
||||
- Add ESP Payload Decryption support for the following Encryption Algorithms :
|
||||
[BLOWFISH-CBC] : keylen 128 bits.
|
||||
[TWOFISH-CBC] : keylen 128/256 bits.
|
||||
BLOWFISH-CBC : keylen 128 bits.
|
||||
TWOFISH-CBC : keylen 128/256 bits.
|
||||
|
||||
- Check ESP Authentication for the following Algorithms defined in RFC 4305:
|
||||
|
||||
Authentication Algorithm
|
||||
------------------------
|
||||
NULL
|
||||
HMAC-SHA1-96 [RFC2404] : any keylen
|
||||
HMAC-MD5-96 [RFC2403] : any keylen
|
||||
AES-XCBC-MAC-96 [RFC3566] : Not available because no implementation found.
|
||||
|
||||
- Add ESP Authentication checking for the following Authentication Algorithm :
|
||||
HMAC-SHA256 : any keylen
|
||||
|
||||
*/
|
||||
|
||||
/* If you want to be able to decrypt ESP packets you MUST define this : */
|
||||
/* If you want to be able to decrypt or Check Authentication of ESP packets you MUST define this : */
|
||||
|
||||
#ifdef HAVE_LIBCRYPT
|
||||
#define __USE_LIBGCRYPT__
|
||||
#endif
|
||||
|
@ -79,13 +85,13 @@ HMAC-MD5-96 [RFC2403]
|
|||
#include <gcrypt.h>
|
||||
#endif
|
||||
|
||||
static int proto_ah = -1;
|
||||
static int proto_ah = -1;
|
||||
static int hf_ah_spi = -1;
|
||||
static int hf_ah_sequence = -1;
|
||||
static int proto_esp = -1;
|
||||
static int hf_esp_spi = -1;
|
||||
static int hf_esp_sequence = -1;
|
||||
static int hf_esp_pad = -1;
|
||||
static int hf_esp_pad_len = -1;
|
||||
static int hf_esp_protocol = -1;
|
||||
static int proto_ipcomp = -1;
|
||||
static int hf_ipcomp_flags = -1;
|
||||
|
@ -112,8 +118,10 @@ static dissector_table_t ip_dissector_table;
|
|||
/* Authentication algorithms defined in RFC 4305 */
|
||||
#define IPSEC_AUTH_NULL 0
|
||||
#define IPSEC_AUTH_HMAC_SHA1_96 1
|
||||
#define IPSEC_AUTH_AES_XCBC_MAC_96 2
|
||||
#define IPSEC_AUTH_HMAC_SHA256 2
|
||||
#define IPSEC_AUTH_HMAC_MD5_96 3
|
||||
#define IPSEC_AUTH_ANY_12BYTES 5
|
||||
/* define IPSEC_AUTH_AES_XCBC_MAC_96 6 */
|
||||
#endif
|
||||
|
||||
/* well-known algorithm number (in CPI), from RFC2409 */
|
||||
|
@ -135,7 +143,7 @@ static dissector_table_t ip_dissector_table;
|
|||
#define IPSEC_SA_ADDR_LEN_SEPARATOR '/'
|
||||
|
||||
/* Number of Security Associations */
|
||||
#define IPSEC_NB_SA 5
|
||||
#define IPSEC_NB_SA 4
|
||||
#endif
|
||||
|
||||
static const value_string cpi2val[] = {
|
||||
|
@ -188,11 +196,7 @@ typedef struct {
|
|||
gint encryption_algo;
|
||||
gint authentication_algo;
|
||||
const gchar *encryption_key;
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
/*
|
||||
const gchar *authentication_key;
|
||||
*/
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
gboolean is_valid;
|
||||
} g_esp_sa;
|
||||
|
||||
|
@ -206,7 +210,11 @@ static g_esp_sa_database g_esp_sad;
|
|||
|
||||
/* Default ESP payload decode to off */
|
||||
static gboolean g_esp_enable_encryption_decode = FALSE;
|
||||
|
||||
/* Default ESP payload Authentication Checking to off */
|
||||
static gboolean g_esp_enable_authentication_check = FALSE;
|
||||
#endif
|
||||
|
||||
/*
|
||||
Default ESP payload heuristic decode to off
|
||||
(only works if payload is NULL encrypted and ESP payload decode is off or payload is NULL encrypted
|
||||
|
@ -733,7 +741,7 @@ esp_sa_parse_protocol_typ(const gchar *sa, guint index_start, gint *pt_protocol_
|
|||
*/
|
||||
#ifdef __USE_LIBGCRYPT__
|
||||
static gboolean
|
||||
esp_sa_parse_addr_len(const gchar *sa, guint index_start, guint *len, guint *index_end)
|
||||
esp_sa_parse_addr_len(const gchar *sa, guint index_start, gint *len, guint *index_end)
|
||||
{
|
||||
guint cpt = 0;
|
||||
guint strlen_max = 3;
|
||||
|
@ -872,8 +880,8 @@ esp_sa_parse_filter(const gchar *sa_src, gint *pt_protocol_typ, gchar **pt_src,
|
|||
gchar *src_string;
|
||||
gchar *dst_string;
|
||||
gchar *spi_string;
|
||||
guint src_len = 0;
|
||||
guint dst_len = 0;
|
||||
gint src_len = 0;
|
||||
gint dst_len = 0;
|
||||
gchar *src;
|
||||
gchar *dst;
|
||||
gchar *sa;
|
||||
|
@ -1149,14 +1157,8 @@ static gboolean
|
|||
get_esp_sa(g_esp_sa_database *sad, gint protocol_typ, gchar *src, gchar *dst, gint spi, gint *entry_index,
|
||||
gint *encryption_algo,
|
||||
gint *authentication_algo,
|
||||
gchar **encryption_key
|
||||
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
/*
|
||||
,gchar **authentication_key
|
||||
*/
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
|
||||
gchar **encryption_key,
|
||||
gchar **authentication_key
|
||||
)
|
||||
|
||||
{
|
||||
|
@ -1189,13 +1191,7 @@ get_esp_sa(g_esp_sa_database *sad, gint protocol_typ, gchar *src, gchar *dst,
|
|||
*entry_index = i;
|
||||
*encryption_algo = sad -> table[i].encryption_algo;
|
||||
*authentication_algo = sad -> table[i].authentication_algo;
|
||||
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
/*
|
||||
*authentication_key = (gchar *)sad -> table[i].authentication_key;
|
||||
*/
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
|
||||
*encryption_key = (gchar *)sad -> table[i].encryption_key;
|
||||
found = TRUE;
|
||||
|
||||
|
@ -1318,6 +1314,62 @@ dissect_ah_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
return advance;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Name : dissect_esp_authentication(proto_tree *tree, tvbuff_t *tvb, gint len, gint esp_auth_len, guint8 *authenticator_data_computed,
|
||||
gboolean authentication_ok, gboolean authentication_checking_ok)
|
||||
Description : used to print Authenticator field when linked with libgcrypt. Print the expected authenticator value
|
||||
if requested and if it is wrong.
|
||||
Return : void
|
||||
Params:
|
||||
- proto_tree *tree : the current tree
|
||||
- tvbuff_t *tvb : the tvbuffer
|
||||
- gint len : length of the data availabale in tvbuff
|
||||
- gint esp_auth_len : size of authenticator field
|
||||
- guint8 *authenticator_data_computed : give the authenticator computed (only needed when authentication_ok and !authentication_checking_ok
|
||||
- gboolean authentication_ok : set to true if the authentication checking has been run successfully
|
||||
- gboolean authentication_checking_ok : set to true if the authentication was the one expected
|
||||
*/
|
||||
#ifdef __USE_LIBGCRYPT__
|
||||
static void
|
||||
dissect_esp_authentication(proto_tree *tree, tvbuff_t *tvb, gint len, gint esp_auth_len, guint8 *authenticator_data_computed,
|
||||
gboolean authentication_ok, gboolean authentication_checking_ok)
|
||||
{
|
||||
if(esp_auth_len == 0)
|
||||
{
|
||||
proto_tree_add_text(tree, tvb, len, 0,
|
||||
"NULL Authentication");
|
||||
}
|
||||
|
||||
/* Make sure we have the auth trailer data */
|
||||
else if(tvb_bytes_exist(tvb, len - esp_auth_len, esp_auth_len))
|
||||
{
|
||||
if((authentication_ok) && (authentication_checking_ok))
|
||||
{
|
||||
proto_tree_add_text(tree, tvb, len - esp_auth_len, esp_auth_len,
|
||||
"Authentication Data [correct]");
|
||||
}
|
||||
|
||||
else if((authentication_ok) && (!authentication_checking_ok))
|
||||
{
|
||||
proto_tree_add_text(tree, tvb, len - esp_auth_len, esp_auth_len,
|
||||
"Authentication Data [incorrect, should be 0x%s]", authenticator_data_computed);
|
||||
|
||||
g_free(authenticator_data_computed);
|
||||
}
|
||||
|
||||
else proto_tree_add_text(tree, tvb, len - esp_auth_len, esp_auth_len,
|
||||
"Authentication Data");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Truncated so just display what we have */
|
||||
proto_tree_add_text(tree, tvb, len - esp_auth_len, esp_auth_len - (len - tvb_length(tvb)),
|
||||
"Authentication Data (truncated)");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
|
@ -1338,13 +1390,15 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
#endif
|
||||
|
||||
guint encapsulated_protocol = 0;
|
||||
gboolean auth_decode_ok = FALSE;
|
||||
gboolean decrypt_dissect_ok = FALSE;
|
||||
|
||||
#ifdef __USE_LIBGCRYPT__
|
||||
gboolean get_address_ok = FALSE;
|
||||
gboolean null_encryption_decode_heuristic = FALSE;
|
||||
guint8 *decrypted_data = NULL;
|
||||
guint8 *encrypted_data = NULL;
|
||||
guint8 *authenticator_data = NULL;
|
||||
guint8 *esp_data = NULL;
|
||||
tvbuff_t *tvb_decrypted;
|
||||
gint entry_index;
|
||||
|
||||
|
@ -1353,27 +1407,32 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
gint esp_crypt_algo = IPSEC_ENCRYPT_NULL;
|
||||
gint esp_auth_algo = IPSEC_AUTH_NULL;
|
||||
gchar *esp_crypt_key;
|
||||
gchar *esp_auth_key;
|
||||
gint esp_iv_len = 0;
|
||||
gint esp_auth_len = 0;
|
||||
gint decrypted_len = 0;
|
||||
gboolean decrypt_ok = FALSE;
|
||||
gboolean decrypt_using_libgcrypt = FALSE;
|
||||
gboolean authentication_check_using_hmac_libgcrypt = FALSE;
|
||||
gboolean authentication_ok = FALSE;
|
||||
gboolean authentication_checking_ok = FALSE;
|
||||
gboolean sad_is_present = FALSE;
|
||||
#endif
|
||||
gint esp_pad_len = 0;
|
||||
|
||||
#ifdef __USE_LIBGCRYPT__
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
/*
|
||||
gchar *esp_auth_key;
|
||||
*/
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
|
||||
/* Variables for decryption used for libgrypt */
|
||||
/* Variables for decryption and authentication checking used for libgrypt */
|
||||
int decrypted_len_alloc = 0;
|
||||
gcry_cipher_hd_t hd;
|
||||
gcry_cipher_hd_t cypher_hd;
|
||||
gcry_md_hd_t md_hd;
|
||||
int md_len = 0;
|
||||
gcry_error_t err = 0;
|
||||
int crypt_algo_libgcrypt = 0;
|
||||
int crypt_mode_libgcrypt = 0;
|
||||
int auth_algo_libgcrypt = 0;
|
||||
unsigned char *authenticator_data_computed = NULL;
|
||||
unsigned char *authenticator_data_computed_md;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1403,7 +1462,7 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
|
||||
if(tree) {
|
||||
len = 0, encapsulated_protocol = 0;
|
||||
auth_decode_ok = FALSE;
|
||||
decrypt_dissect_ok = FALSE;
|
||||
i = 0;
|
||||
|
||||
ti = proto_tree_add_item(tree, proto_esp, tvb, 0, -1, FALSE);
|
||||
|
@ -1420,7 +1479,7 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
/* The SAD is not activated */
|
||||
if(g_esp_enable_null_encryption_decode_heuristic && !g_esp_enable_encryption_decode) null_encryption_decode_heuristic = TRUE;
|
||||
|
||||
if(g_esp_enable_encryption_decode)
|
||||
if(g_esp_enable_encryption_decode || g_esp_enable_authentication_check)
|
||||
{
|
||||
/* Get Dource & Destination Addresses in gchar * with all the bytes available. */
|
||||
switch (pinfo -> src.type)
|
||||
|
@ -1526,16 +1585,8 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
It would have been better to do it in the proto registration, but because there is no way to add a crossbar, you have to do a parsing and have a SA Rule.
|
||||
*/
|
||||
|
||||
if(get_esp_sa(&g_esp_sad, protocol_typ, ip_src, ip_dst, spi, &entry_index, &esp_crypt_algo, &esp_auth_algo, &esp_crypt_key
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
/*
|
||||
, &esp_auth_key
|
||||
*/
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
))
|
||||
if((sad_is_present = get_esp_sa(&g_esp_sad, protocol_typ, ip_src, ip_dst, spi, &entry_index, &esp_crypt_algo, &esp_auth_algo, &esp_crypt_key, &esp_auth_key)))
|
||||
{
|
||||
/* Desactivation of the Heuristic to decrypt using the NULL encryption algorithm since the packet is matching a SA */
|
||||
null_encryption_decode_heuristic = FALSE;
|
||||
|
||||
/* Get length of whole ESP packet. */
|
||||
len = tvb_reported_length(tvb);
|
||||
|
@ -1549,17 +1600,25 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
break;
|
||||
}
|
||||
|
||||
case IPSEC_AUTH_HMAC_SHA256:
|
||||
{
|
||||
esp_auth_len = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
case IPSEC_AUTH_NULL:
|
||||
{
|
||||
esp_auth_len = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
case IPSEC_AUTH_AES_XCBC_MAC_96:
|
||||
{
|
||||
esp_auth_len = 12;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
case IPSEC_AUTH_HMAC_MD5_96:
|
||||
{
|
||||
|
@ -1567,8 +1626,173 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
break;
|
||||
}
|
||||
|
||||
case IPSEC_AUTH_ANY_12BYTES:
|
||||
default:
|
||||
{
|
||||
esp_auth_len = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(g_esp_enable_authentication_check)
|
||||
{
|
||||
switch(esp_auth_algo)
|
||||
{
|
||||
|
||||
case IPSEC_AUTH_HMAC_SHA1_96:
|
||||
/*
|
||||
RFC 2404 : HMAC-SHA-1-96 is a secret key algorithm. While no fixed
|
||||
key length is specified in [RFC-2104], for use with either ESP
|
||||
or AH a fixed key length of 160-bits MUST be supported. Key
|
||||
lengths other than 160-bits MUST NOT be supported (i.e. only 160-bit keys
|
||||
are to be used by HMAC-SHA-1-96). A key length of 160-bits was chosen
|
||||
based on the recommendations in [RFC-2104] (i.e. key lengths less
|
||||
than the authenticator length decrease security strength and keys
|
||||
longer than the authenticator length do not significantly increase security
|
||||
strength).
|
||||
*/
|
||||
{
|
||||
auth_algo_libgcrypt = GCRY_MD_SHA1;
|
||||
authentication_check_using_hmac_libgcrypt = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
case IPSEC_AUTH_NULL:
|
||||
{
|
||||
authentication_check_using_hmac_libgcrypt = FALSE;
|
||||
authentication_checking_ok = TRUE;
|
||||
authentication_ok = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
case IPSEC_AUTH_AES_XCBC_MAC_96:
|
||||
{
|
||||
auth_algo_libgcrypt =
|
||||
authentication_check_using_libgcrypt = TRUE;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
case IPSEC_AUTH_HMAC_SHA256:
|
||||
{
|
||||
auth_algo_libgcrypt = GCRY_MD_SHA256;
|
||||
authentication_check_using_hmac_libgcrypt = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
case IPSEC_AUTH_HMAC_MD5_96:
|
||||
/*
|
||||
RFC 2403 : HMAC-MD5-96 is a secret key algorithm. While no fixed key length is
|
||||
specified in [RFC-2104], for use with either ESP or AH a fixed key
|
||||
length of 128-bits MUST be supported. Key lengths other than 128-
|
||||
bits MUST NOT be supported (i.e. only 128-bit keys are to be used by
|
||||
HMAC-MD5-96). A key length of 128-bits was chosen based on the
|
||||
recommendations in [RFC-2104] (i.e. key lengths less than the
|
||||
authenticator length decrease security strength and keys longer than
|
||||
the authenticator length do not significantly increase security
|
||||
strength).
|
||||
*/
|
||||
{
|
||||
auth_algo_libgcrypt = GCRY_MD_MD5;
|
||||
authentication_check_using_hmac_libgcrypt = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
case IPSEC_AUTH_ANY_12BYTES:
|
||||
default:
|
||||
{
|
||||
authentication_ok = FALSE;
|
||||
authentication_check_using_hmac_libgcrypt = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if((authentication_check_using_hmac_libgcrypt) && (!authentication_ok))
|
||||
{
|
||||
gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
|
||||
/* Allocate Buffers for Authenticator Field */
|
||||
authenticator_data = (guint8 *) g_malloc (( esp_auth_len + 1) * sizeof(guint8));
|
||||
memset(authenticator_data,0, esp_auth_len + 1);
|
||||
tvb_memcpy(tvb, authenticator_data, len - esp_auth_len, esp_auth_len);
|
||||
|
||||
esp_data = (guint8 *) g_malloc (( len - esp_auth_len + 1) * sizeof(guint8));
|
||||
memset(esp_data,0, len - esp_auth_len + 1);
|
||||
tvb_memcpy(tvb, esp_data, 0, len - esp_auth_len);
|
||||
|
||||
err = gcry_md_open (&md_hd, auth_algo_libgcrypt, GCRY_MD_FLAG_HMAC);
|
||||
if (err)
|
||||
{
|
||||
fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s, gcry_md_open failed: %s\n", gcry_md_algo_name(auth_algo_libgcrypt), gpg_strerror (err));
|
||||
authentication_ok = FALSE;
|
||||
g_free(authenticator_data);
|
||||
g_free(esp_data);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
md_len = gcry_md_get_algo_dlen (auth_algo_libgcrypt);
|
||||
if (md_len < 1 || md_len < esp_auth_len)
|
||||
{
|
||||
fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s, grcy_md_get_algo_dlen failed: %d\n", gcry_md_algo_name(auth_algo_libgcrypt), md_len);
|
||||
authentication_ok = FALSE;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
gcry_md_setkey( md_hd, esp_auth_key, strlen(esp_auth_key) );
|
||||
|
||||
gcry_md_write (md_hd, esp_data, len - esp_auth_len);
|
||||
|
||||
authenticator_data_computed_md = gcry_md_read (md_hd, auth_algo_libgcrypt);
|
||||
if (authenticator_data_computed_md == 0)
|
||||
{
|
||||
fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s, gcry_md_read failed\n", gcry_md_algo_name(auth_algo_libgcrypt));
|
||||
authentication_ok = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(memcmp (authenticator_data_computed_md, authenticator_data, esp_auth_len))
|
||||
{
|
||||
authenticator_data_computed = (guint8 *) g_malloc (( esp_auth_len * 2 + 1) * sizeof(guint8));
|
||||
unsigned char authenticator_data_computed_car[3];
|
||||
for (i = 0; i < esp_auth_len; i++)
|
||||
{
|
||||
g_snprintf((char *)authenticator_data_computed_car, 3, "%02X", authenticator_data_computed_md[i] & 0xFF);
|
||||
authenticator_data_computed[i*2] = authenticator_data_computed_car[0];
|
||||
authenticator_data_computed[i*2 + 1] = authenticator_data_computed_car[1];
|
||||
}
|
||||
|
||||
authenticator_data_computed[esp_auth_len * 2] ='\0';
|
||||
|
||||
authentication_ok = TRUE;
|
||||
authentication_checking_ok = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
authentication_ok = TRUE;
|
||||
authentication_checking_ok = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gcry_md_close (md_hd);
|
||||
g_free(authenticator_data);
|
||||
g_free(esp_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(g_esp_enable_encryption_decode)
|
||||
{
|
||||
/* Desactivation of the Heuristic to decrypt using the NULL encryption algorithm since the packet is matching a SA */
|
||||
null_encryption_decode_heuristic = FALSE;
|
||||
|
||||
switch(esp_crypt_algo)
|
||||
{
|
||||
|
||||
|
@ -1854,7 +2078,7 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
decrypted_data = (guint8 *) g_malloc ((decrypted_len_alloc + esp_iv_len)* sizeof(guint8));
|
||||
tvb_memcpy(tvb, encrypted_data , sizeof(struct newesp), decrypted_len);
|
||||
|
||||
err = gcry_cipher_open (&hd, crypt_algo_libgcrypt, crypt_mode_libgcrypt, 0);
|
||||
err = gcry_cipher_open (&cypher_hd, crypt_algo_libgcrypt, crypt_mode_libgcrypt, 0);
|
||||
if (err)
|
||||
{
|
||||
fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s Mode %d, grcy_open_cipher failed: %s\n",
|
||||
|
@ -1866,31 +2090,42 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
|
||||
else
|
||||
{
|
||||
err = gcry_cipher_setkey (hd, esp_crypt_key, strlen(esp_crypt_key));
|
||||
err = gcry_cipher_setkey (cypher_hd, esp_crypt_key, strlen(esp_crypt_key));
|
||||
if (err)
|
||||
{
|
||||
fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s Mode %d, gcry_cipher_setkey failed: %s\n",
|
||||
gcry_cipher_algo_name(crypt_algo_libgcrypt), crypt_mode_libgcrypt, gpg_strerror (err));
|
||||
gcry_cipher_close (hd);
|
||||
gcry_cipher_close (cypher_hd);
|
||||
g_free(encrypted_data);
|
||||
g_free(decrypted_data);
|
||||
decrypt_ok = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = gcry_cipher_decrypt (hd, decrypted_data, decrypted_len_alloc + esp_iv_len, encrypted_data, decrypted_len_alloc);
|
||||
err = gcry_cipher_decrypt (cypher_hd, decrypted_data, decrypted_len_alloc + esp_iv_len, encrypted_data, decrypted_len_alloc);
|
||||
if (err)
|
||||
{
|
||||
fprintf (stderr,"<IPsec/ESP Dissector> Error in Algorithm %s, Mode %d, gcry_cipher_decrypt failed: %s\n",
|
||||
gcry_cipher_algo_name(crypt_algo_libgcrypt), crypt_mode_libgcrypt, gpg_strerror (err));
|
||||
gcry_cipher_close (hd);
|
||||
gcry_cipher_close (cypher_hd);
|
||||
g_free(encrypted_data);
|
||||
g_free(decrypted_data);
|
||||
decrypt_ok = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gcry_cipher_close (hd);
|
||||
gcry_cipher_close (cypher_hd);
|
||||
|
||||
/* Add the Authentication which was not encrypted */
|
||||
if(decrypted_len >= esp_auth_len)
|
||||
{
|
||||
for(i = 0; i < esp_auth_len; i++)
|
||||
{
|
||||
decrypted_data[i + decrypted_len -esp_auth_len] = encrypted_data[i + decrypted_len - esp_auth_len];
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr,"\n\n ");
|
||||
g_free(encrypted_data);
|
||||
decrypt_ok = TRUE;
|
||||
}
|
||||
|
@ -1941,49 +2176,37 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
pinfo,
|
||||
esp_tree)) /*tree))*/
|
||||
{
|
||||
auth_decode_ok = TRUE;
|
||||
decrypt_dissect_ok = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(auth_decode_ok)
|
||||
if(decrypt_dissect_ok)
|
||||
{
|
||||
if(esp_pad_len !=0)
|
||||
{
|
||||
proto_tree_add_text(esp_tree, tvb_decrypted, decrypted_len - esp_auth_len - 2 - esp_pad_len, esp_pad_len,"PAD");
|
||||
proto_tree_add_text(esp_tree, tvb_decrypted, decrypted_len - esp_auth_len - 2 - esp_pad_len, esp_pad_len,"Pad");
|
||||
}
|
||||
proto_tree_add_uint(esp_tree, hf_esp_pad, tvb_decrypted,
|
||||
|
||||
proto_tree_add_uint(esp_tree, hf_esp_pad_len, tvb_decrypted,
|
||||
decrypted_len - esp_auth_len - 2, 1,
|
||||
esp_pad_len);
|
||||
proto_tree_add_uint(esp_tree, hf_esp_protocol, tvb_decrypted,
|
||||
decrypted_len - esp_auth_len - 1, 1,
|
||||
encapsulated_protocol);
|
||||
|
||||
if(esp_auth_len == 0)
|
||||
{
|
||||
proto_tree_add_text(esp_tree, tvb_decrypted, decrypted_len, decrypted_len,
|
||||
"NULL Authentication");
|
||||
}
|
||||
dissect_esp_authentication(esp_tree, tvb_decrypted, decrypted_len, esp_auth_len, authenticator_data_computed, authentication_ok, authentication_checking_ok );
|
||||
|
||||
/* Make sure we have the auth trailer data */
|
||||
else if(tvb_bytes_exist(tvb, decrypted_len - esp_auth_len, esp_auth_len))
|
||||
{
|
||||
proto_tree_add_text(esp_tree, tvb_decrypted, decrypted_len - esp_auth_len, esp_auth_len,
|
||||
"Authentication Data");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Truncated so just display what we have */
|
||||
proto_tree_add_text(esp_tree, tvb_decrypted, decrypted_len - esp_auth_len, esp_auth_len - (decrypted_len - tvb_length(tvb_decrypted)),
|
||||
"Authentication Data (truncated)");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
call_dissector(data_handle,
|
||||
tvb_new_subset(tvb_decrypted, 0, -1, -1),
|
||||
tvb_new_subset(tvb_decrypted, 0, decrypted_len - esp_auth_len, decrypted_len - esp_auth_len),
|
||||
pinfo, esp_tree);
|
||||
|
||||
dissect_esp_authentication(esp_tree, tvb_decrypted, decrypted_len, esp_auth_len, authenticator_data_computed, authentication_ok, authentication_checking_ok );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2000,12 +2223,27 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
If the packet is present in the security association database and the field g_esp_enable_authentication_check set.
|
||||
*/
|
||||
if(!g_esp_enable_encryption_decode && g_esp_enable_authentication_check && sad_is_present)
|
||||
{
|
||||
sad_is_present = FALSE;
|
||||
call_dissector(data_handle,
|
||||
tvb_new_subset(tvb, sizeof(struct newesp), len - sizeof(struct newesp) - esp_auth_len, -1),
|
||||
pinfo, esp_tree);
|
||||
|
||||
dissect_esp_authentication(esp_tree, tvb, len , esp_auth_len, authenticator_data_computed, authentication_ok, authentication_checking_ok );
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(null_encryption_decode_heuristic)
|
||||
/* The packet does not belong to a security association and the field g_esp_enable_null_encryption_decode_heuristic is set */
|
||||
else if(null_encryption_decode_heuristic)
|
||||
{
|
||||
#endif
|
||||
|
||||
if(g_esp_enable_null_encryption_decode_heuristic)
|
||||
{
|
||||
/* Get length of whole ESP packet. */
|
||||
|
@ -2026,25 +2264,27 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
pinfo,
|
||||
esp_tree))
|
||||
{
|
||||
auth_decode_ok = TRUE;
|
||||
decrypt_dissect_ok = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(auth_decode_ok)
|
||||
if(decrypt_dissect_ok)
|
||||
{
|
||||
proto_tree_add_uint(esp_tree, hf_esp_pad, tvb,
|
||||
proto_tree_add_uint(esp_tree, hf_esp_pad_len, tvb,
|
||||
len - 14, 1,
|
||||
esp_pad_len);
|
||||
proto_tree_add_uint(esp_tree, hf_esp_protocol, tvb,
|
||||
len - 13, 1,
|
||||
encapsulated_protocol);
|
||||
|
||||
/* Make sure we have the auth trailer data */
|
||||
if(tvb_bytes_exist(tvb, len - 12, 12))
|
||||
{
|
||||
proto_tree_add_text(esp_tree, tvb, len - 12, 12,
|
||||
"Authentication Data");
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Truncated so just display what we have */
|
||||
|
@ -2052,14 +2292,9 @@ dissect_esp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
"Authentication Data (truncated)");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
call_dissector(data_handle,
|
||||
tvb_new_subset(tvb, sizeof(struct newesp), -1, -1),
|
||||
pinfo, esp_tree);
|
||||
}
|
||||
}
|
||||
#ifdef __USE_LIBGCRYPT__
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2142,8 +2377,8 @@ proto_register_ipsec(void)
|
|||
{ &hf_esp_sequence,
|
||||
{ "Sequence", "esp.sequence", FT_UINT32, BASE_DEC, NULL, 0x0,
|
||||
"", HFILL }},
|
||||
{ &hf_esp_pad,
|
||||
{ "Pad Length", "esp.pad", FT_UINT8, BASE_DEC, NULL, 0x0,
|
||||
{ &hf_esp_pad_len,
|
||||
{ "Pad Length", "esp.pad_len", FT_UINT8, BASE_DEC, NULL, 0x0,
|
||||
"", HFILL }},
|
||||
{ &hf_esp_protocol,
|
||||
{ "Next Header", "esp.protocol", FT_UINT8, BASE_HEX, NULL, 0x0,
|
||||
|
@ -2204,8 +2439,10 @@ proto_register_ipsec(void)
|
|||
|
||||
{"null", "NULL", IPSEC_AUTH_NULL},
|
||||
{"hmacsha196", "HMAC-SHA1-96 [RFC2404]", IPSEC_AUTH_HMAC_SHA1_96},
|
||||
{"aesxcbcmac96", "AES-XCBC-MAC-96 [RFC3566]", IPSEC_AUTH_AES_XCBC_MAC_96},
|
||||
{"hmacsha256", "HMAC-SHA256", IPSEC_AUTH_HMAC_SHA256},
|
||||
{"hmacmd596", "HMAC-MD5-96 [RFC2403]", IPSEC_AUTH_HMAC_MD5_96},
|
||||
/* {"aesxcbcmac96", "AES-XCBC-MAC-96 [RFC3566]", IPSEC_AUTH_AES_XCBC_MAC_96}, */
|
||||
{"any12bytes", "ANY 12-bytes of Authentication [No Checking]", IPSEC_AUTH_ANY_12BYTES},
|
||||
{NULL,NULL,0}
|
||||
};
|
||||
#endif
|
||||
|
@ -2227,11 +2464,7 @@ proto_register_ipsec(void)
|
|||
g_esp_sad.table[i].encryption_algo = IPSEC_ENCRYPT_NULL;
|
||||
g_esp_sad.table[i].authentication_algo = IPSEC_AUTH_NULL;
|
||||
g_esp_sad.table[i].encryption_key = NULL;
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
/*
|
||||
g_esp_sad.table[i].authentication_key = NULL;
|
||||
*/
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
g_esp_sad.table[i].is_valid = FALSE;
|
||||
}
|
||||
#endif
|
||||
|
@ -2248,6 +2481,11 @@ proto_register_ipsec(void)
|
|||
"Attempt to decode based on the SAD described hereafter.",
|
||||
&g_esp_enable_encryption_decode);
|
||||
|
||||
prefs_register_bool_preference(esp_module, "enable_authentication_check",
|
||||
"Attempt to Check ESP Authentication",
|
||||
"Attempt to Check ESP Authentication based on the SAD described hereafter.",
|
||||
&g_esp_enable_authentication_check);
|
||||
|
||||
|
||||
/* prefs_register_uint_preference(esp_module, "nb_sa",
|
||||
"Number of Security Associations",
|
||||
|
@ -2271,7 +2509,7 @@ proto_register_ipsec(void)
|
|||
|
||||
prefs_register_string_preference(esp_module, str_sa,
|
||||
str_sa_comment,
|
||||
"This field uses the following syntax : \042<Protocol|Source Address|Destination Adress|SPI\042. "
|
||||
"This field uses the following syntax : \042Protocol|Source Address|Destination Adress|SPI\042. "
|
||||
"<Protocol>: either IPv4, IPv6 (upper and/or lowercase letters). <SPI> : the Security Parameter Index "
|
||||
"of the Security Association. You may indicate it in decimal (ex: 123) or in hexadecimal (ex: 0x45). "
|
||||
"The special keywords '*' may be used to match any SPI.Nevertheless, if you use more than one '*', "
|
||||
|
@ -2313,7 +2551,7 @@ proto_register_ipsec(void)
|
|||
|
||||
prefs_register_enum_preference(esp_module, str_authentication_algorithm,
|
||||
str_authentication_algorithm_comment,
|
||||
"According to RFC 4305 Authentication Algorithms Requirements are the following : HMAC-SHA1-96 [RFC2404] (MUST), NULL (MUST), AES-XCBC-MAC-96 [RFC3566] (SHOULD+), HMAC-MD5-96 [RFC2403] (MAY).",
|
||||
"According to RFC 4305 Authentication Algorithms Requirements are the following : HMAC-SHA1-96 [RFC2404] (MUST), NULL (MUST), AES-XCBC-MAC-96 [RFC3566] (SHOULD+/Not Available), HMAC-MD5-96 [RFC2403] (MAY). It will also Check authentication for HMAC-SHA256",
|
||||
&g_esp_sad.table[i].authentication_algo, esp_authentication_algo, FALSE);
|
||||
|
||||
|
||||
|
@ -2329,8 +2567,6 @@ proto_register_ipsec(void)
|
|||
&g_esp_sad.table[i].encryption_key);
|
||||
|
||||
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
/*
|
||||
char *str_authentication_key = (char *) g_malloc(19 + g_max_esp_size_nb_sa + 2);
|
||||
g_snprintf(str_authentication_key,19 + g_max_esp_size_nb_sa + 2,"%s%s","authentication_key_",str_sa_num);
|
||||
|
||||
|
@ -2339,11 +2575,9 @@ proto_register_ipsec(void)
|
|||
|
||||
prefs_register_string_preference(esp_module, str_authentication_key,
|
||||
str_authentication_key_comment,
|
||||
"Authentication Key"
|
||||
"The key sizes supported are the following : [HMAC-SHA1-96] : Any. [HMAC-SHA256] : Any. [HMAC-MD5] : Any."
|
||||
,
|
||||
&g_esp_sad.table[i].authentication_key);
|
||||
*/
|
||||
/************** UNCOMMENT THIS PART IF YOU WANT TO ADD CHECKING OF AUTHENTICATION *********************/
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue