[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SAMBA4][PATCH] Fix up AES sign/seal on DCE/RPC



This patch, inspired by the lukeh's heimdal-mechglue branch appears to
fix up gesnec_gssapi for sign/seal, samba->samba when using AES.  It
also works Samba->Windows and Windows->Samba.

However, I'm not sure if I've broken the original intent of this
function, and it might make more sense to have a direct
gss_sig_length(conext, data_len, &length) function.  I'm going to have a
look at that approach now.

Andrew Bartlett
-- 
Andrew Bartlett                                http://samba.org/~abartlet/
Samba Developer, SuSE Labs, Novell Inc.        http://suse.de
Authentication Developer, Samba Team           http://samba.org
Student Network Administrator, Hawker College  http://hawkerc.net
Index: auth/gensec/gensec_gssapi.c
===================================================================
--- auth/gensec/gensec_gssapi.c	(revision 10115)
+++ auth/gensec/gensec_gssapi.c	(working copy)
@@ -482,8 +482,26 @@
 
 static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security) 
 {
-	/* not const but work for DCERPC packets and arcfour */
-	return 45;
+	struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
+	OM_uint32 maj_stat, min_stat;
+	OM_uint32 req_output_size = (1 << 6);
+	OM_uint32 max_input_size;
+	maj_stat = gss_wrap_size_limit(&min_stat, 
+				       gensec_gssapi_state->gssapi_context,
+				       gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL),
+				       GSS_C_QOP_DEFAULT,
+				       req_output_size, 
+				       &max_input_size);
+	if (GSS_ERROR(maj_stat)) {
+		TALLOC_CTX *mem_ctx = talloc_new(NULL); 
+		DEBUG(1, ("gensec_gssapi_seal_packet: determinaing signature size with gss_wrap_size_limit failed: %s\n", 
+			  gssapi_error_string(mem_ctx, maj_stat, min_stat)));
+		talloc_free(mem_ctx);
+		return 0;
+	}
+
+	/* The difference between the max output and the max input must be the signature */
+	return req_output_size - max_input_size;
 }
 
 static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_security, 
@@ -496,7 +514,7 @@
 	OM_uint32 maj_stat, min_stat;
 	gss_buffer_desc input_token, output_token;
 	int conf_state;
-	ssize_t sig_length = 0;
+	ssize_t sig_length;
 
 	input_token.length = length;
 	input_token.value = data;
@@ -514,12 +532,15 @@
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
-	if (output_token.length < length) {
+	sig_length = gensec_gssapi_sig_size(gensec_security);
+
+	/* Caller must pad to right boundary */
+	if (output_token.length != (length + sig_length)) {
+		DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap length [%d] does not match caller length [%d] plus sig size [%d] = [%d]\n", 
+			  output_token.length, length, sig_length, length + sig_length));
 		return NT_STATUS_INTERNAL_ERROR;
 	}
 
-	sig_length = 45;
-
 	memcpy(data, ((uint8_t *)output_token.value) + sig_length, length);
 	*sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length);
 
Index: heimdal/lib/gssapi/wrap.c
===================================================================
--- heimdal/lib/gssapi/wrap.c	(revision 10115)
+++ heimdal/lib/gssapi/wrap.c	(working copy)
@@ -167,13 +167,17 @@
 
   switch (keytype) {
   case KEYTYPE_DES :
-  case KEYTYPE_ARCFOUR:
-  case KEYTYPE_ARCFOUR_56:
       ret = sub_wrap_size(req_output_size, max_input_size, 8, 22);
       break;
   case KEYTYPE_DES3 :
       ret = sub_wrap_size(req_output_size, max_input_size, 8, 34);
       break;
+  case KEYTYPE_ARCFOUR:
+  case KEYTYPE_ARCFOUR_56:
+      ret = _gssapi_wrap_size_arcfour(minor_status, context_handle, 
+				      conf_req_flag, qop_req, 
+				      req_output_size, max_input_size, key);
+      break;
   default :
       ret = _gssapi_wrap_size_cfx(minor_status, context_handle, 
 				  conf_req_flag, qop_req, 
Index: heimdal/lib/gssapi/cfx.c
===================================================================
--- heimdal/lib/gssapi/cfx.c	(revision 10115)
+++ heimdal/lib/gssapi/cfx.c	(working copy)
@@ -127,6 +127,7 @@
 	return GSS_S_FAILURE;
     }
 
+    output_length -= req_output_size; /* token length */
     if (output_length < req_output_size) {
 	*max_input_size = (req_output_size - output_length);
 	*max_input_size -= padlength;
Index: heimdal/lib/gssapi/arcfour.c
===================================================================
--- heimdal/lib/gssapi/arcfour.c	(revision 10115)
+++ heimdal/lib/gssapi/arcfour.c	(working copy)
@@ -326,6 +326,35 @@
 }
 
 OM_uint32
+_gssapi_wrap_size_arcfour(OM_uint32 * minor_status,
+			  const gss_ctx_id_t context_handle,
+			  int conf_req_flag,
+			  gss_qop_t qop_req,
+			  OM_uint32 req_output_size,
+			  OM_uint32 * max_input_size,
+			  krb5_keyblock *key)
+{
+    size_t len, total_len;
+    len = GSS_ARCFOUR_WRAP_TOKEN_SIZE + req_output_size;
+    /* if GSS_C_DCE_STYLE is in use:
+     *  - we only need to encapsulate the WRAP token
+     *  - we should not add padding
+     */
+    if (!(context_handle->flags & GSS_C_DCE_STYLE)) {
+    	len += 1 /* padding */;
+    }
+    _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
+
+    total_len -= req_output_size; /* token length */
+    if (total_len < req_output_size) {
+        *max_input_size = (req_output_size - total_len);
+    } else {
+        *max_input_size = 0;
+    }
+    return GSS_S_COMPLETE;
+}
+	
+OM_uint32
 _gssapi_wrap_arcfour(OM_uint32 * minor_status,
 		     const gss_ctx_id_t context_handle,
 		     int conf_req_flag,
Index: heimdal/lib/gssapi/arcfour.h
===================================================================
--- heimdal/lib/gssapi/arcfour.h	(revision 10115)
+++ heimdal/lib/gssapi/arcfour.h	(working copy)
@@ -70,5 +70,12 @@
 				     gss_qop_t *qop_state,
 				     krb5_keyblock *key,
 				     char *type);
+OM_uint32 _gssapi_wrap_size_arcfour(OM_uint32 * minor_status,
+				    const gss_ctx_id_t context_handle,
+				    int conf_req_flag,
+				    gss_qop_t qop_req,
+				    OM_uint32 req_output_size,
+				    OM_uint32 * max_input_size,
+				    krb5_keyblock *key);
 
 #endif /* GSSAPI_ARCFOUR_H_ */

This is a digitally signed message part