packet-spnego: fix decryption of DCERPC packets in decrypt_gssapi_krb_cfx_wrap()
authorStefan Metzmacher <metze@samba.org>
Sat, 25 Jul 2009 07:47:36 +0000 (09:47 +0200)
committerStefan Metzmacher <metze@samba.org>
Sat, 25 Jul 2009 07:47:36 +0000 (09:47 +0200)
There the checksum and the encrypted data are no 2 different buffers
and we need to combine them before we try to rotate and decrypt them.

metze

asn1/spnego/packet-spnego-template.c
epan/dissectors/packet-spnego.c

index c9029979c212b9afbeb98b4e313cb38a7e22b52d..1f408f546d7ee9da15730cf52fe554fb4d37f963 100644 (file)
@@ -692,7 +692,15 @@ rrc_rotate(void *data, int len, guint16 rrc, int unrotate)
 #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)
+decrypt_gssapi_krb_cfx_wrap(proto_tree *tree _U_,
+                           packet_info *pinfo,
+                           tvbuff_t *checksum_tvb,
+                           tvbuff_t *encrypted_tvb,
+                           guint16 ec,
+                           guint16 rrc,
+                           gboolean is_dce,
+                           int keytype,
+                           unsigned int usage)
 {
        int res;
        char *rotated;
@@ -704,25 +712,34 @@ decrypt_gssapi_krb_cfx_wrap(proto_tree *tree _U_, packet_info *pinfo _U_, tvbuff
                return;
        }
 
-       rotated = ep_alloc(tvb_length(tvb));
+       datalen = tvb_length(checksum_tvb) + tvb_length(encrypted_tvb);
+       rotated = ep_alloc(datalen);
 
-       tvb_memcpy(tvb, rotated, 0, tvb_length(tvb));
-       res = rrc_rotate(rotated, tvb_length(tvb), rrc, TRUE);
+       tvb_memcpy(checksum_tvb, rotated,
+                  0, tvb_length(checksum_tvb));
+       tvb_memcpy(encrypted_tvb, rotated + tvb_length(checksum_tvb),
+                  0, tvb_length(encrypted_tvb));
 
-       output = decrypt_krb5_data(tree, pinfo, usage, tvb_length(tvb),
+       if (is_dce) {
+               rrc += ec;
+       }
+
+       res = rrc_rotate(rotated, datalen, rrc, TRUE);
+
+       output = decrypt_krb5_data(tree, pinfo, usage, datalen,
                  rotated, keytype, &datalen);
 
        if (output) {
                char *outdata;
 
-               outdata = ep_alloc(tvb_length(tvb));
-               memcpy(outdata, output, tvb_length(tvb));
+               outdata = ep_alloc(tvb_length(encrypted_tvb));
+               memcpy(outdata, output, tvb_length(encrypted_tvb));
                g_free(output);
 
-               pinfo->gssapi_decrypted_tvb=tvb_new_child_real_data(tvb,
+               pinfo->gssapi_decrypted_tvb=tvb_new_child_real_data(encrypted_tvb,
                        outdata,
-                       datalen-16,
-                       datalen-16);
+                       tvb_length(encrypted_tvb),
+                       tvb_length(encrypted_tvb));
                add_new_data_source(pinfo, pinfo->gssapi_decrypted_tvb, "Decrypted GSS-Krb5");
                return;
        }
@@ -1059,21 +1076,25 @@ 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);
+{
+       tvbuff_t *checksum_tvb = tvb_new_subset(tvb, 16, checksum_size, checksum_size);
 
-       if (flags & 0x0002) {
+       if (pinfo->gssapi_data_encrypted) {
                if(pinfo->gssapi_encrypted_tvb){
                        decrypt_gssapi_krb_cfx_wrap(tree,
                                pinfo,
+                               checksum_tvb,
                                pinfo->gssapi_encrypted_tvb,
                                ec,
                                rrc,
+                               (pinfo->decrypt_gssapi_tvb==DECRYPT_GSSAPI_DCE)?TRUE:FALSE,
                                -1,
                                (flags & 0x0001)?
                                KRB5_KU_USAGE_ACCEPTOR_SEAL:
                                KRB5_KU_USAGE_INITIATOR_SEAL);
                }
        }
+}
 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
 
        /*
index f9b10a418f2551d7a751aa34b49e69e3160eea8f..99aea785261b8a6dab0e1315d584736421162274 100644 (file)
@@ -1191,7 +1191,15 @@ rrc_rotate(void *data, int len, guint16 rrc, int unrotate)
 #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)
+decrypt_gssapi_krb_cfx_wrap(proto_tree *tree _U_,
+                           packet_info *pinfo,
+                           tvbuff_t *checksum_tvb,
+                           tvbuff_t *encrypted_tvb,
+                           guint16 ec,
+                           guint16 rrc,
+                           gboolean is_dce,
+                           int keytype,
+                           unsigned int usage)
 {
        int res;
        char *rotated;
@@ -1203,25 +1211,34 @@ decrypt_gssapi_krb_cfx_wrap(proto_tree *tree _U_, packet_info *pinfo _U_, tvbuff
                return;
        }
 
-       rotated = ep_alloc(tvb_length(tvb));
+       datalen = tvb_length(checksum_tvb) + tvb_length(encrypted_tvb);
+       rotated = ep_alloc(datalen);
 
-       tvb_memcpy(tvb, rotated, 0, tvb_length(tvb));
-       res = rrc_rotate(rotated, tvb_length(tvb), rrc, TRUE);
+       tvb_memcpy(checksum_tvb, rotated,
+                  0, tvb_length(checksum_tvb));
+       tvb_memcpy(encrypted_tvb, rotated + tvb_length(checksum_tvb),
+                  0, tvb_length(encrypted_tvb));
 
-       output = decrypt_krb5_data(tree, pinfo, usage, tvb_length(tvb),
+       if (is_dce) {
+               rrc += ec;
+       }
+
+       res = rrc_rotate(rotated, datalen, rrc, TRUE);
+
+       output = decrypt_krb5_data(tree, pinfo, usage, datalen,
                  rotated, keytype, &datalen);
 
        if (output) {
                char *outdata;
 
-               outdata = ep_alloc(tvb_length(tvb));
-               memcpy(outdata, output, tvb_length(tvb));
+               outdata = ep_alloc(tvb_length(encrypted_tvb));
+               memcpy(outdata, output, tvb_length(encrypted_tvb));
                g_free(output);
 
-               pinfo->gssapi_decrypted_tvb=tvb_new_child_real_data(tvb,
+               pinfo->gssapi_decrypted_tvb=tvb_new_child_real_data(encrypted_tvb,
                        outdata,
-                       datalen-16,
-                       datalen-16);
+                       tvb_length(encrypted_tvb),
+                       tvb_length(encrypted_tvb));
                add_new_data_source(pinfo, pinfo->gssapi_decrypted_tvb, "Decrypted GSS-Krb5");
                return;
        }
@@ -1558,21 +1575,25 @@ 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);
+{
+       tvbuff_t *checksum_tvb = tvb_new_subset(tvb, 16, checksum_size, checksum_size);
 
-       if (flags & 0x0002) {
+       if (pinfo->gssapi_data_encrypted) {
                if(pinfo->gssapi_encrypted_tvb){
                        decrypt_gssapi_krb_cfx_wrap(tree,
                                pinfo,
+                               checksum_tvb,
                                pinfo->gssapi_encrypted_tvb,
                                ec,
                                rrc,
+                               (pinfo->decrypt_gssapi_tvb==DECRYPT_GSSAPI_DCE)?TRUE:FALSE,
                                -1,
                                (flags & 0x0001)?
                                KRB5_KU_USAGE_ACCEPTOR_SEAL:
                                KRB5_KU_USAGE_INITIATOR_SEAL);
                }
        }
+}
 #endif /* HAVE_HEIMDAL_KERBEROS || HAVE_MIT_KERBEROS */
 
        /*
@@ -1959,7 +1980,7 @@ void proto_register_spnego(void) {
         NULL, HFILL }},
 
 /*--- End of included file: packet-spnego-hfarr.c ---*/
-#line 1375 "packet-spnego-template.c"
+#line 1396 "packet-spnego-template.c"
        };
 
        /* List of subtrees */
@@ -1981,7 +2002,7 @@ void proto_register_spnego(void) {
     &ett_spnego_InitialContextToken_U,
 
 /*--- End of included file: packet-spnego-ettarr.c ---*/
-#line 1385 "packet-spnego-template.c"
+#line 1406 "packet-spnego-template.c"
        };
 
        /* Register protocol */