diff options
author | Stefan Metzmacher <metze@samba.org> | 2020-05-21 02:46:41 +0200 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2020-05-26 09:16:45 +0000 |
commit | 8edf1cf549f2baa37378d19f4e4ebeda4a9ca06e (patch) | |
tree | aea439b22cc0d8acee6f6cbd33c2f22365ed8d6e | |
parent | 3a289703efec502f03f6a40aa70cd57919d1124c (diff) |
packet-kerberos: let decrypt_krb5_with_cb() use kerberos_all_keys
For now we use kerberos_all_keys, but in future we may select the
map based on passed usage.
Change-Id: I1f29e97aa60a41be3694b75bc4353b3a5dae0eae
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-on: https://code.wireshark.org/review/37288
Petri-Dish: Anders Broman <a.broman58@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r-- | epan/dissectors/asn1/kerberos/packet-kerberos-template.c | 94 | ||||
-rw-r--r-- | epan/dissectors/packet-kerberos.c | 100 |
2 files changed, 157 insertions, 37 deletions
diff --git a/epan/dissectors/asn1/kerberos/packet-kerberos-template.c b/epan/dissectors/asn1/kerberos/packet-kerberos-template.c index e0422f6161..31586987bf 100644 --- a/epan/dissectors/asn1/kerberos/packet-kerberos-template.c +++ b/epan/dissectors/asn1/kerberos/packet-kerberos-template.c @@ -761,6 +761,66 @@ read_keytab_file(const char *filename) } } +struct decrypt_krb5_with_cb_state { + proto_tree *tree; + packet_info *pinfo; + kerberos_private_data_t *private_data; + int usage; + int keytype; + tvbuff_t *cryptotvb; + krb5_error_code (*decrypt_cb_fn)( + const krb5_keyblock *key, + int usage, + void *decrypt_cb_data); + void *decrypt_cb_data; + enc_key_t *ek; +}; + +static void +decrypt_krb5_with_cb_try_key(gpointer __key _U_, gpointer value, gpointer userdata) +{ + struct decrypt_krb5_with_cb_state *state = + (struct decrypt_krb5_with_cb_state *)userdata; + enc_key_t *ek = (enc_key_t *)value; + krb5_error_code ret; + krb5_keytab_entry key; + + if (state->ek != NULL) { + /* + * we're done. + */ + return; + } + + /* shortcircuit and bail out if enctypes are not matching */ + if ((state->keytype != -1) && (ek->keytype != state->keytype)) { + /* + * don't stop traversing... + * try the next one... + */ + return; + } + + key.key.enctype=ek->keytype; + key.key.length=ek->keylength; + key.key.contents=ek->keyvalue; + ret = state->decrypt_cb_fn(&(key.key), + state->usage, + state->decrypt_cb_data); + if (ret != 0) { + /* + * don't stop traversing... + * try the next one... + */ + return; + } + + /* + * we're done, remember the key + */ + state->ek = ek; +} + static krb5_error_code decrypt_krb5_with_cb(proto_tree *tree, packet_info *pinfo, @@ -774,27 +834,27 @@ decrypt_krb5_with_cb(proto_tree *tree, void *decrypt_cb_data), void *decrypt_cb_data) { - krb5_error_code ret; - enc_key_t *ek; - krb5_keytab_entry key; + wmem_map_t *key_map = kerberos_all_keys; + struct decrypt_krb5_with_cb_state state = { + .tree = tree, + .pinfo = pinfo, + .private_data = private_data, + .usage = usage, + .cryptotvb = cryptotvb, + .keytype = keytype, + .decrypt_cb_fn = decrypt_cb_fn, + .decrypt_cb_data = decrypt_cb_data, + }; read_keytab_file_from_preferences(); - for(ek=enc_key_list;ek;ek=ek->next){ - /* shortcircuit and bail out if enctypes are not matching */ - if((keytype != -1) && (ek->keytype != keytype)) { - continue; - } + insert_longterm_keys_into_key_map(key_map); - key.key.enctype=ek->keytype; - key.key.length=ek->keylength; - key.key.contents=ek->keyvalue; - ret = decrypt_cb_fn(&(key.key), usage, decrypt_cb_data); - if(ret == 0) { - used_encryption_key(tree, pinfo, private_data, - ek, usage, cryptotvb); - return 0; - } + wmem_map_foreach(key_map, decrypt_krb5_with_cb_try_key, &state); + if (state.ek != NULL) { + used_encryption_key(tree, pinfo, private_data, + state.ek, usage, cryptotvb); + return 0; } return -1; diff --git a/epan/dissectors/packet-kerberos.c b/epan/dissectors/packet-kerberos.c index 07ece999d3..3281dff998 100644 --- a/epan/dissectors/packet-kerberos.c +++ b/epan/dissectors/packet-kerberos.c @@ -1170,6 +1170,66 @@ read_keytab_file(const char *filename) } } +struct decrypt_krb5_with_cb_state { + proto_tree *tree; + packet_info *pinfo; + kerberos_private_data_t *private_data; + int usage; + int keytype; + tvbuff_t *cryptotvb; + krb5_error_code (*decrypt_cb_fn)( + const krb5_keyblock *key, + int usage, + void *decrypt_cb_data); + void *decrypt_cb_data; + enc_key_t *ek; +}; + +static void +decrypt_krb5_with_cb_try_key(gpointer __key _U_, gpointer value, gpointer userdata) +{ + struct decrypt_krb5_with_cb_state *state = + (struct decrypt_krb5_with_cb_state *)userdata; + enc_key_t *ek = (enc_key_t *)value; + krb5_error_code ret; + krb5_keytab_entry key; + + if (state->ek != NULL) { + /* + * we're done. + */ + return; + } + + /* shortcircuit and bail out if enctypes are not matching */ + if ((state->keytype != -1) && (ek->keytype != state->keytype)) { + /* + * don't stop traversing... + * try the next one... + */ + return; + } + + key.key.enctype=ek->keytype; + key.key.length=ek->keylength; + key.key.contents=ek->keyvalue; + ret = state->decrypt_cb_fn(&(key.key), + state->usage, + state->decrypt_cb_data); + if (ret != 0) { + /* + * don't stop traversing... + * try the next one... + */ + return; + } + + /* + * we're done, remember the key + */ + state->ek = ek; +} + static krb5_error_code decrypt_krb5_with_cb(proto_tree *tree, packet_info *pinfo, @@ -1183,27 +1243,27 @@ decrypt_krb5_with_cb(proto_tree *tree, void *decrypt_cb_data), void *decrypt_cb_data) { - krb5_error_code ret; - enc_key_t *ek; - krb5_keytab_entry key; + wmem_map_t *key_map = kerberos_all_keys; + struct decrypt_krb5_with_cb_state state = { + .tree = tree, + .pinfo = pinfo, + .private_data = private_data, + .usage = usage, + .cryptotvb = cryptotvb, + .keytype = keytype, + .decrypt_cb_fn = decrypt_cb_fn, + .decrypt_cb_data = decrypt_cb_data, + }; read_keytab_file_from_preferences(); - for(ek=enc_key_list;ek;ek=ek->next){ - /* shortcircuit and bail out if enctypes are not matching */ - if((keytype != -1) && (ek->keytype != keytype)) { - continue; - } + insert_longterm_keys_into_key_map(key_map); - key.key.enctype=ek->keytype; - key.key.length=ek->keylength; - key.key.contents=ek->keyvalue; - ret = decrypt_cb_fn(&(key.key), usage, decrypt_cb_data); - if(ret == 0) { - used_encryption_key(tree, pinfo, private_data, - ek, usage, cryptotvb); - return 0; - } + wmem_map_foreach(key_map, decrypt_krb5_with_cb_try_key, &state); + if (state.ek != NULL) { + used_encryption_key(tree, pinfo, private_data, + state.ek, usage, cryptotvb); + return 0; } return -1; @@ -5967,7 +6027,7 @@ dissect_kerberos_EncryptedChallenge(gboolean implicit_tag _U_, tvbuff_t *tvb _U_ /*--- End of included file: packet-kerberos-fn.c ---*/ -#line 2913 "./asn1/kerberos/packet-kerberos-template.c" +#line 2973 "./asn1/kerberos/packet-kerberos-template.c" #ifdef HAVE_KERBEROS static const ber_sequence_t PA_ENC_TS_ENC_sequence[] = { @@ -7282,7 +7342,7 @@ void proto_register_kerberos(void) { NULL, HFILL }}, /*--- End of included file: packet-kerberos-hfarr.c ---*/ -#line 3383 "./asn1/kerberos/packet-kerberos-template.c" +#line 3443 "./asn1/kerberos/packet-kerberos-template.c" }; /* List of subtrees */ @@ -7381,7 +7441,7 @@ void proto_register_kerberos(void) { &ett_kerberos_KrbFastArmoredRep, /*--- End of included file: packet-kerberos-ettarr.c ---*/ -#line 3406 "./asn1/kerberos/packet-kerberos-template.c" +#line 3466 "./asn1/kerberos/packet-kerberos-template.c" }; static ei_register_info ei[] = { |