aboutsummaryrefslogtreecommitdiffstats
path: root/asn1
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2013-02-26 11:38:39 +0000
committerMichael Mann <mmann78@netscape.net>2013-02-26 11:38:39 +0000
commit8c0d526f5886af36d1c887528a6796c3f4886e8e (patch)
treef8d36d10aa979b591960a6440b365afd8035bf0e /asn1
parentccc78e6b63876184a88d3cd5c9f7240685ab05de (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.c143
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",