From 5edbeca14108a9b2c3badafce0b0b3447a8280f6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Sep 2005 11:19:02 +0000 Subject: 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) --- source4/auth/gensec/gensec.c | 4 +-- source4/auth/gensec/gensec.h | 2 +- source4/auth/gensec/gensec_gssapi.c | 55 +++++++++++++++++++++++++++++++------ source4/auth/gensec/schannel.c | 2 +- source4/auth/gensec/spnego.c | 4 +-- source4/auth/ntlmssp/ntlmssp_sign.c | 2 +- 6 files changed, 53 insertions(+), 16 deletions(-) (limited to 'source4/auth') 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, diff --git a/source4/auth/ntlmssp/ntlmssp_sign.c b/source4/auth/ntlmssp/ntlmssp_sign.c index 8f6c94463c..41075cd25b 100644 --- a/source4/auth/ntlmssp/ntlmssp_sign.c +++ b/source4/auth/ntlmssp/ntlmssp_sign.c @@ -431,7 +431,7 @@ NTSTATUS ntlmssp_sign_init(struct gensec_ntlmssp_state *gensec_ntlmssp_state) return NT_STATUS_OK; } -size_t gensec_ntlmssp_sig_size(struct gensec_security *gensec_security) +size_t gensec_ntlmssp_sig_size(struct gensec_security *gensec_security, size_t data_size) { return NTLMSSP_SIG_SIZE; } -- cgit