summaryrefslogtreecommitdiff
path: root/source4/auth/gensec
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-09-11 11:19:02 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:38:04 -0500
commit5edbeca14108a9b2c3badafce0b0b3447a8280f6 (patch)
tree55129f66d1eff5ab537fea11c0be494be6f08230 /source4/auth/gensec
parentcfdcc32f8480e538246ca1771e58e9a4835f22b6 (diff)
downloadsamba-5edbeca14108a9b2c3badafce0b0b3447a8280f6.tar.gz
samba-5edbeca14108a9b2c3badafce0b0b3447a8280f6.tar.bz2
samba-5edbeca14108a9b2c3badafce0b0b3447a8280f6.zip
r10153: This patch adds a new parameter to gensec_sig_size(), the size of the
data to be signed/sealed. We can use this to split the data from the signature portion of the resultant wrapped packet. This required merging the gsskrb5_wrap_size patch from lorikeet-heimdal, and fixes AES encrption issues on DCE/RPC (we no longer use a static 45 byte value). This fixes one of the krb5 issues in my list. Andrew Bartlett (This used to be commit e4f2afc34362953f56a026b66ae1aea81e9db104)
Diffstat (limited to 'source4/auth/gensec')
-rw-r--r--source4/auth/gensec/gensec.c4
-rw-r--r--source4/auth/gensec/gensec.h2
-rw-r--r--source4/auth/gensec/gensec_gssapi.c55
-rw-r--r--source4/auth/gensec/schannel.c2
-rw-r--r--source4/auth/gensec/spnego.c4
5 files changed, 52 insertions, 15 deletions
diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c
index 87c60da84f..f0256b9668 100644
--- a/source4/auth/gensec/gensec.c
+++ b/source4/auth/gensec/gensec.c
@@ -559,7 +559,7 @@ NTSTATUS gensec_sign_packet(struct gensec_security *gensec_security,
return gensec_security->ops->sign_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig);
}
-size_t gensec_sig_size(struct gensec_security *gensec_security)
+size_t gensec_sig_size(struct gensec_security *gensec_security, size_t data_size)
{
if (!gensec_security->ops->sig_size) {
return 0;
@@ -568,7 +568,7 @@ size_t gensec_sig_size(struct gensec_security *gensec_security)
return 0;
}
- return gensec_security->ops->sig_size(gensec_security);
+ return gensec_security->ops->sig_size(gensec_security, data_size);
}
NTSTATUS gensec_wrap(struct gensec_security *gensec_security,
diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h
index f55e5354ad..4ff09d2066 100644
--- a/source4/auth/gensec/gensec.h
+++ b/source4/auth/gensec/gensec.h
@@ -73,7 +73,7 @@ struct gensec_security_ops {
const uint8_t *data, size_t length,
const uint8_t *whole_pdu, size_t pdu_length,
DATA_BLOB *sig);
- size_t (*sig_size)(struct gensec_security *gensec_security);
+ size_t (*sig_size)(struct gensec_security *gensec_security, size_t data_size);
NTSTATUS (*check_packet)(struct gensec_security *gensec_security, TALLOC_CTX *sig_mem_ctx,
const uint8_t *data, size_t length,
const uint8_t *whole_pdu, size_t pdu_length,
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index c3f7c52085..69f219fe07 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -480,10 +480,38 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security,
return NT_STATUS_OK;
}
-static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security)
+static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t data_size)
{
- /* 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 output_size;
+ if ((gensec_gssapi_state->gss_oid->length != gss_mech_krb5->length)
+ || (memcmp(gensec_gssapi_state->gss_oid->elements, gss_mech_krb5->elements,
+ gensec_gssapi_state->gss_oid->length) != 0)) {
+ DEBUG(1, ("NO sig size available for this mech\n"));
+ return 0;
+ }
+
+ maj_stat = gsskrb5_wrap_size(&min_stat,
+ gensec_gssapi_state->gssapi_context,
+ gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL),
+ GSS_C_QOP_DEFAULT,
+ data_size,
+ &output_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;
+ }
+
+ if (output_size < data_size) {
+ return 0;
+ }
+
+ /* The difference between the max output and the max input must be the signature */
+ return output_size - data_size;
}
static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_security,
@@ -496,7 +524,7 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit
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 +542,15 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit
return NT_STATUS_ACCESS_DENIED;
}
- if (output_token.length < length) {
+ sig_length = gensec_gssapi_sig_size(gensec_security, length);
+
+ /* 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);
@@ -618,9 +649,15 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit
return NT_STATUS_INTERNAL_ERROR;
}
- sig_length = 45;
+ sig_length = gensec_gssapi_sig_size(gensec_security, length);
+
+ /* Caller must pad to right boundary */
+ if (output_token.length != (length + sig_length)) {
+ DEBUG(1, ("gensec_gssapi_sign_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;
+ }
- /*memcpy(data, ((uint8_t *)output_token.value) + sig_length, length);*/
*sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length);
dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length);
diff --git a/source4/auth/gensec/schannel.c b/source4/auth/gensec/schannel.c
index fc961d8eaa..a4561ee996 100644
--- a/source4/auth/gensec/schannel.c
+++ b/source4/auth/gensec/schannel.c
@@ -26,7 +26,7 @@
#include "auth/auth.h"
#include "auth/gensec/schannel.h"
-static size_t schannel_sig_size(struct gensec_security *gensec_security)
+static size_t schannel_sig_size(struct gensec_security *gensec_security, size_t data_size)
{
return 32;
}
diff --git a/source4/auth/gensec/spnego.c b/source4/auth/gensec/spnego.c
index 3efbf65a3d..133530833b 100644
--- a/source4/auth/gensec/spnego.c
+++ b/source4/auth/gensec/spnego.c
@@ -198,7 +198,7 @@ static NTSTATUS gensec_spnego_unwrap(struct gensec_security *gensec_security,
mem_ctx, in, out);
}
-static size_t gensec_spnego_sig_size(struct gensec_security *gensec_security)
+static size_t gensec_spnego_sig_size(struct gensec_security *gensec_security, size_t data_size)
{
struct spnego_state *spnego_state = gensec_security->private_data;
@@ -207,7 +207,7 @@ static size_t gensec_spnego_sig_size(struct gensec_security *gensec_security)
return 0;
}
- return gensec_sig_size(spnego_state->sub_sec_security);
+ return gensec_sig_size(spnego_state->sub_sec_security, data_size);
}
static NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_security,