aboutsummaryrefslogtreecommitdiffstats
path: root/asn1
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2008-10-05 00:28:36 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2008-10-05 00:28:36 +0000
commitd83b8b03365383046cb19abad051bbdc215a3349 (patch)
treec01c048770d6d7c050b641b91d9ad140023e8610 /asn1
parentaf8ff96739d00e12b309b54adf18fddee45520a5 (diff)
kerberos/gss enhancements
add a parameter *datalen to decrypt_krb5_data() so that we can pass back the length of the decrypted blob back to the caller. This is useful for when there are "junk" at the end of the blob and thus the decrypted data is not the same size as the encrypted blob. GSS CFX is one such example. (we should have done this earlier since it might have made some other stuff easier to imlement...) make the preference setting krb_decrypt a globally visible variable so we can see its value and act on it from callers of krb decryption from outside of packet-kerberos.c i.e. from GSS CFX Make keytype == -1 a wildcard that when passed to decrypt_krb5_data() will try any/all encryption keys. This since GSS CFX does not provide the enctype in the GSS layer. (The GSS CFX enctype is only negotiated during the AP-REQ/REP so we should later pick this value up and store it in a CFX session variable. That is for a later enhancement. ) Enhance the GSS decryption (that for hitorical reasons are implemented in packet-spnego.c and not packet-gssapi.c :-) ) to also handle decryption of GSS CFX This should make wireshark able to decrypt any/all GSSAPI RFC4121 packets, if the keytab file is provided. I have successfully decrypted LDAP using GSS CFX with AES encryption with this. svn path=/trunk/; revision=26350
Diffstat (limited to 'asn1')
-rw-r--r--asn1/spnego/packet-spnego-template.c109
1 files changed, 107 insertions, 2 deletions
diff --git a/asn1/spnego/packet-spnego-template.c b/asn1/spnego/packet-spnego-template.c
index db50eef85f..9ec5b0fc3a 100644
--- a/asn1/spnego/packet-spnego-template.c
+++ b/asn1/spnego/packet-spnego-template.c
@@ -646,13 +646,100 @@ decrypt_gssapi_krb_arcfour_wrap(proto_tree *tree, packet_info *pinfo, tvbuff_t *
}
return;
}
+
+/* borrowed from heimdal */
+static int
+rrc_rotate(void *data, int len, guint16 rrc, int unrotate)
+{
+ u_char *tmp, buf[256];
+ size_t left;
+
+ if (len == 0)
+ return 0;
+
+ rrc %= len;
+
+ if (rrc == 0)
+ return 0;
+
+ left = len - rrc;
+
+ if (rrc <= sizeof(buf)) {
+ tmp = buf;
+ } else {
+ tmp = malloc(rrc);
+ if (tmp == NULL)
+ return -1;
+ }
+
+ if (unrotate) {
+ memcpy(tmp, data, rrc);
+ memmove(data, (u_char *)data + rrc, left);
+ memcpy((u_char *)data + left, tmp, rrc);
+ } else {
+ memcpy(tmp, (u_char *)data + left, rrc);
+ memmove((u_char *)data + rrc, data, left);
+ memcpy(data, tmp, rrc);
+ }
+
+ if (rrc > sizeof(buf))
+ free(tmp);
+
+ return 0;
+}
+
+
+#define KRB5_KU_USAGE_ACCEPTOR_SEAL 22
+#define KRB5_KU_USAGE_ACCEPTOR_SIGN 23
+#define KRB5_KU_USAGE_INITIATOR_SEAL 24
+#define KRB5_KU_USAGE_INITIATOR_SIGN 25
+
+static void
+decrypt_gssapi_krb_cfx_wrap(proto_tree *tree _U_, packet_info *pinfo _U_, tvbuff_t *tvb _U_, guint16 ec _U_, guint16 rrc _U_, int keytype, unsigned int usage)
+{
+ int res;
+ char *rotated;
+ char *output;
+ int datalen;
+
+ /* dont do anything if we are not attempting to decrypt data */
+ if(!krb_decrypt){
+ return;
+ }
+
+ rotated = ep_alloc(tvb_length(tvb));
+
+ tvb_memcpy(tvb, rotated, 0, tvb_length(tvb));
+ res = rrc_rotate(rotated, tvb_length(tvb), rrc, TRUE);
+
+ output = decrypt_krb5_data(tree, pinfo, usage, tvb_length(tvb),
+ rotated, keytype, &datalen);
+
+ if (output) {
+ char *outdata;
+
+ outdata = ep_alloc(tvb_length(tvb));
+ memcpy(outdata, output, tvb_length(tvb));
+ g_free(output);
+
+ pinfo->gssapi_decrypted_tvb=tvb_new_real_data(
+ outdata,
+ datalen-16,
+ datalen-16);
+ tvb_set_child_real_data_tvbuff(tvb, pinfo->gssapi_decrypted_tvb);
+ add_new_data_source(pinfo, pinfo->gssapi_decrypted_tvb, "Decrypted GSS-Krb5");
+ return;
+ }
+ return;
+}
+
#endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
#endif
/*
- * XXX - This is for GSSAPI Wrap tokens ...
+ * This is for GSSAPI Wrap tokens ...
*/
static int
dissect_spnego_krb5_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo
@@ -880,7 +967,7 @@ dissect_spnego_krb5_cfx_flags(tvbuff_t *tvb, int offset,
}
/*
- * XXX - This is for GSSAPI CFX Wrap tokens ...
+ * This is for GSSAPI CFX Wrap tokens ...
*/
static int
dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo
@@ -975,6 +1062,24 @@ dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo
}
}
+#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
+ pinfo->gssapi_encrypted_tvb = tvb_new_subset(tvb, 16, -1, -1);
+
+ if (flags & 0x0002) {
+ if(pinfo->gssapi_encrypted_tvb){
+ decrypt_gssapi_krb_cfx_wrap(tree,
+ pinfo,
+ pinfo->gssapi_encrypted_tvb,
+ ec,
+ rrc,
+ -1,
+ (flags & 0x0001)?
+ KRB5_KU_USAGE_ACCEPTOR_SEAL:
+ KRB5_KU_USAGE_INITIATOR_SEAL);
+ }
+ }
+#endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
+
/*
* Return the offset past the checksum, so that we know where
* the data we're wrapped around starts. Also, set the length