diff options
author | Michael Mann <mmann78@netscape.net> | 2013-02-26 11:38:39 +0000 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2013-02-26 11:38:39 +0000 |
commit | 8c0d526f5886af36d1c887528a6796c3f4886e8e (patch) | |
tree | f8d36d10aa979b591960a6440b365afd8035bf0e /asn1 | |
parent | ccc78e6b63876184a88d3cd5c9f7240685ab05de (diff) |
SNMP dissector should handle aes256 (better version than r47690)
svn path=/trunk/; revision=47902
Diffstat (limited to 'asn1')
-rw-r--r-- | asn1/snmp/packet-snmp-template.c | 143 |
1 files changed, 96 insertions, 47 deletions
diff --git a/asn1/snmp/packet-snmp-template.c b/asn1/snmp/packet-snmp-template.c index e941c25bbf..77694efd77 100644 --- a/asn1/snmp/packet-snmp-template.c +++ b/asn1/snmp/packet-snmp-template.c @@ -105,15 +105,14 @@ static int proto_smux = -1; static gboolean display_oid = TRUE; static gboolean snmp_var_in_tree = TRUE; -#ifdef HAVE_LIBGCRYPT -static gint snmp_decryption_algo = 0; -#endif static gboolean snmp_usm_auth_md5(snmp_usm_params_t* p, guint8**, guint*, gchar const**); static gboolean snmp_usm_auth_sha1(snmp_usm_params_t* p, guint8**, guint*, gchar const**); static tvbuff_t* snmp_usm_priv_des(snmp_usm_params_t*, tvbuff_t*, gchar const**); -static tvbuff_t* snmp_usm_priv_aes(snmp_usm_params_t*, tvbuff_t*, gchar const**); +static tvbuff_t* snmp_usm_priv_aes128(snmp_usm_params_t*, tvbuff_t*, gchar const**); +static tvbuff_t* snmp_usm_priv_aes192(snmp_usm_params_t*, tvbuff_t*, gchar const**); +static tvbuff_t* snmp_usm_priv_aes256(snmp_usm_params_t*, tvbuff_t*, gchar const**); static void snmp_usm_password_to_key_md5(const guint8 *password, guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key); @@ -130,21 +129,24 @@ static const value_string auth_types[] = { }; static snmp_usm_auth_model_t* auth_models[] = {&model_md5,&model_sha1}; +#define PRIV_DES 0 +#define PRIV_AES128 1 +#define PRIV_AES192 2 +#define PRIV_AES256 3 static const value_string priv_types[] = { - {0,"DES"}, - {1,"AES"}, - {0,NULL} + { PRIV_DES, "DES" }, + { PRIV_AES128, "AES" }, + { PRIV_AES192, "AES192" }, + { PRIV_AES256, "AES256" }, + { 0, NULL} }; -static snmp_usm_decoder_t priv_protos[] = {snmp_usm_priv_des, snmp_usm_priv_aes}; - -#ifdef HAVE_LIBGCRYPT -static const enum_val_t snmp_decryption_algo_type[] = { - { "aes" , "AES", 0 }, - { "aes256", "AES256", 1 }, - { NULL, NULL, 0 } +static snmp_usm_decoder_t priv_protos[] = { + snmp_usm_priv_des, + snmp_usm_priv_aes128, + snmp_usm_priv_aes192, + snmp_usm_priv_aes256 }; -#endif static snmp_ue_assoc_t* ueas = NULL; static guint num_ueas = 0; @@ -1126,13 +1128,50 @@ static void set_ue_keys(snmp_ue_assoc_t* n ) { n->engine.len, n->user.authKey.data); - n->user.privKey.data = (guint8 *)se_alloc(key_size); - n->user.privKey.len = key_size; - n->user.authModel->pass2key(n->user.privPassword.data, - n->user.privPassword.len, - n->engine.data, - n->engine.len, - n->user.privKey.data); + if (n->priv_proto == PRIV_AES128 || n->priv_proto == PRIV_AES192 || n->priv_proto == PRIV_AES256) { + guint need_key_len = + (n->priv_proto == PRIV_AES128) ? 16 : + (n->priv_proto == PRIV_AES192) ? 24 : + (n->priv_proto == PRIV_AES256) ? 32 : + 0; + + guint key_len = key_size; + + while (key_len < need_key_len) + key_len += key_size; + + n->user.privKey.data = (guint8 *)se_alloc(key_len); + n->user.privKey.len = need_key_len; + + n->user.authModel->pass2key(n->user.privPassword.data, + n->user.privPassword.len, + n->engine.data, + n->engine.len, + n->user.privKey.data); + + key_len = key_size; + + /* extend key if needed */ + while (key_len < need_key_len) { + n->user.authModel->pass2key( + n->user.privKey.data, + key_len, + n->engine.data, + n->engine.len, + n->user.privKey.data + key_len); + + key_len += key_size; + } + + } else { + n->user.privKey.data = (guint8 *)se_alloc(key_size); + n->user.privKey.len = key_size; + n->user.authModel->pass2key(n->user.privPassword.data, + n->user.privPassword.len, + n->engine.data, + n->engine.len, + n->user.privKey.data); + } } static snmp_ue_assoc_t* @@ -1451,16 +1490,16 @@ on_gcry_error: #endif } +#ifdef HAVE_LIBGCRYPT static tvbuff_t* -snmp_usm_priv_aes(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar const** error _U_) +snmp_usm_priv_aes_common(snmp_usm_params_t* p, tvbuff_t* encryptedData, gchar const** error, int algo) { -#ifdef HAVE_LIBGCRYPT gcry_error_t err; gcry_cipher_hd_t hd = NULL; - int gcry_algo = GCRY_CIPHER_AES; guint8* cleartext; - guint8* aes_key = p->user_assoc->user.privKey.data; /* first 16 bytes */ + guint8* aes_key = p->user_assoc->user.privKey.data; + int aes_key_len = p->user_assoc->user.privKey.len; guint8 iv[16]; gint priv_len; gint cryptgrm_len; @@ -1493,23 +1532,13 @@ snmp_usm_priv_aes(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar c cleartext = (guint8*)ep_alloc(cryptgrm_len); - switch(snmp_decryption_algo) - { - case 0: - gcry_algo = GCRY_CIPHER_AES; - break; - case 1: - gcry_algo = GCRY_CIPHER_AES256; - break; - } - - err = gcry_cipher_open(&hd, gcry_algo, GCRY_CIPHER_MODE_CFB, 0); + err = gcry_cipher_open(&hd, algo, GCRY_CIPHER_MODE_CFB, 0); if (err != GPG_ERR_NO_ERROR) goto on_gcry_error; err = gcry_cipher_setiv(hd, iv, 16); if (err != GPG_ERR_NO_ERROR) goto on_gcry_error; - err = gcry_cipher_setkey(hd,aes_key,16); + err = gcry_cipher_setkey(hd,aes_key,aes_key_len); if (err != GPG_ERR_NO_ERROR) goto on_gcry_error; err = gcry_cipher_decrypt(hd, cleartext, cryptgrm_len, cryptgrm, cryptgrm_len); @@ -1525,12 +1554,41 @@ on_gcry_error: *error = (void*)gpg_strerror(err); if (hd) gcry_cipher_close(hd); return NULL; +} +#endif + +static tvbuff_t* +snmp_usm_priv_aes128(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar const** error) +{ +#ifdef HAVE_LIBGCRYPT + return snmp_usm_priv_aes_common(p, encryptedData, error, GCRY_CIPHER_AES); +#else + *error = "libgcrypt not present, cannot decrypt"; + return NULL; +#endif +} + +static tvbuff_t* +snmp_usm_priv_aes192(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar const** error) +{ +#ifdef HAVE_LIBGCRYPT + return snmp_usm_priv_aes_common(p, encryptedData, error, GCRY_CIPHER_AES192); #else *error = "libgcrypt not present, cannot decrypt"; return NULL; #endif } +static tvbuff_t* +snmp_usm_priv_aes256(snmp_usm_params_t* p _U_, tvbuff_t* encryptedData _U_, gchar const** error) +{ +#ifdef HAVE_LIBGCRYPT + return snmp_usm_priv_aes_common(p, encryptedData, error, GCRY_CIPHER_AES256); +#else + *error = "libgcrypt not present, cannot decrypt"; + return NULL; +#endif +} gboolean check_ScopedPdu(tvbuff_t* tvb) @@ -2324,15 +2382,6 @@ void proto_register_snmp(void) { "Table of enterprise specific-trap type descriptions", specific_traps_uat); -#ifdef HAVE_LIBGCRYPT - prefs_register_enum_preference(snmp_module, "decrypt", - "Decryption algorithm", - "Decryption algorithm", - &snmp_decryption_algo, - snmp_decryption_algo_type, - FALSE); -#endif - #ifdef HAVE_LIBSMI prefs_register_static_text_preference(snmp_module, "info_mibs", "MIB settings can be changed in the Name Resolution preferences", |