summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/gssapi/krb5/cfx.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/gssapi/krb5/cfx.c')
-rwxr-xr-xsource4/heimdal/lib/gssapi/krb5/cfx.c228
1 files changed, 69 insertions, 159 deletions
diff --git a/source4/heimdal/lib/gssapi/krb5/cfx.c b/source4/heimdal/lib/gssapi/krb5/cfx.c
index d029f55ce4..7ae26e2e7a 100755
--- a/source4/heimdal/lib/gssapi/krb5/cfx.c
+++ b/source4/heimdal/lib/gssapi/krb5/cfx.c
@@ -30,7 +30,7 @@
* SUCH DAMAGE.
*/
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
RCSID("$Id$");
@@ -101,49 +101,47 @@ _gsskrb5cfx_wrap_length_cfx(const gsskrb5_ctx context_handle,
return 0;
}
-krb5_error_code
-_gsskrb5cfx_max_wrap_length_cfx(krb5_context context,
- krb5_crypto crypto,
+OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
int conf_req_flag,
- size_t input_length,
- OM_uint32 *output_length)
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 *max_input_size)
{
krb5_error_code ret;
- *output_length = 0;
+ *max_input_size = 0;
/* 16-byte header is always first */
- if (input_length < 16)
+ if (req_output_size < 16)
return 0;
- input_length -= 16;
+ req_output_size -= 16;
if (conf_req_flag) {
size_t wrapped_size, sz;
- wrapped_size = input_length + 1;
+ wrapped_size = req_output_size + 1;
do {
wrapped_size--;
sz = krb5_get_wrapped_length(context,
- crypto, wrapped_size);
- } while (wrapped_size && sz > input_length);
- if (wrapped_size == 0) {
- *output_length = 0;
+ ctx->crypto, wrapped_size);
+ } while (wrapped_size && sz > req_output_size);
+ if (wrapped_size == 0)
return 0;
- }
/* inner header */
- if (wrapped_size < 16) {
- *output_length = 0;
+ if (wrapped_size < 16)
return 0;
- }
+
wrapped_size -= 16;
- *output_length = wrapped_size;
+ *max_input_size = wrapped_size;
} else {
krb5_cksumtype type;
size_t cksumsize;
- ret = krb5_crypto_get_checksum_type(context, crypto, &type);
+ ret = krb5_crypto_get_checksum_type(context, ctx->crypto, &type);
if (ret)
return ret;
@@ -151,48 +149,16 @@ _gsskrb5cfx_max_wrap_length_cfx(krb5_context context,
if (ret)
return ret;
- if (input_length < cksumsize)
+ if (req_output_size < cksumsize)
return 0;
/* Checksum is concatenated with data */
- *output_length = input_length - cksumsize;
+ *max_input_size = req_output_size - cksumsize;
}
return 0;
}
-
-OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
- const gsskrb5_ctx context_handle,
- krb5_context context,
- int conf_req_flag,
- gss_qop_t qop_req,
- OM_uint32 req_output_size,
- OM_uint32 *max_input_size,
- krb5_keyblock *key)
-{
- krb5_error_code ret;
- krb5_crypto crypto;
-
- ret = krb5_crypto_init(context, key, 0, &crypto);
- if (ret != 0) {
- *minor_status = ret;
- return GSS_S_FAILURE;
- }
-
- ret = _gsskrb5cfx_max_wrap_length_cfx(context, crypto, conf_req_flag,
- req_output_size, max_input_size);
- if (ret != 0) {
- *minor_status = ret;
- krb5_crypto_destroy(context, crypto);
- return GSS_S_FAILURE;
- }
-
- krb5_crypto_destroy(context, crypto);
-
- return GSS_S_COMPLETE;
-}
-
/*
* Rotate "rrc" bytes to the front or back
*/
@@ -238,16 +204,14 @@ rrc_rotate(void *data, size_t len, uint16_t rrc, krb5_boolean unrotate)
}
OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
- const gsskrb5_ctx context_handle,
+ const gsskrb5_ctx ctx,
krb5_context context,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
int *conf_state,
- gss_buffer_t output_message_buffer,
- krb5_keyblock *key)
+ gss_buffer_t output_message_buffer)
{
- krb5_crypto crypto;
gss_cfx_wrap_token token;
krb5_error_code ret;
unsigned usage;
@@ -257,19 +221,12 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
int32_t seq_number;
u_char *p;
- ret = krb5_crypto_init(context, key, 0, &crypto);
- if (ret != 0) {
- *minor_status = ret;
- return GSS_S_FAILURE;
- }
-
- ret = _gsskrb5cfx_wrap_length_cfx(context_handle, context,
- crypto, conf_req_flag,
+ ret = _gsskrb5cfx_wrap_length_cfx(ctx, context,
+ ctx->crypto, conf_req_flag,
input_message_buffer->length,
&wrapped_len, &cksumsize, &padlength);
if (ret != 0) {
*minor_status = ret;
- krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
@@ -280,7 +237,6 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
output_message_buffer->value = malloc(output_message_buffer->length);
if (output_message_buffer->value == NULL) {
*minor_status = ENOMEM;
- krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
@@ -290,9 +246,9 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
token->TOK_ID[1] = 0x04;
token->Flags = 0;
token->Filler = 0xFF;
- if ((context_handle->more_flags & LOCAL) == 0)
+ if ((ctx->more_flags & LOCAL) == 0)
token->Flags |= CFXSentByAcceptor;
- if (context_handle->more_flags & ACCEPTOR_SUBKEY)
+ if (ctx->more_flags & ACCEPTOR_SUBKEY)
token->Flags |= CFXAcceptorSubkey;
if (conf_req_flag) {
/*
@@ -329,16 +285,16 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
token->RRC[0] = 0;
token->RRC[1] = 0;
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
krb5_auth_con_getlocalseqnumber(context,
- context_handle->auth_context,
+ ctx->auth_context,
&seq_number);
_gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]);
_gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
krb5_auth_con_setlocalseqnumber(context,
- context_handle->auth_context,
+ ctx->auth_context,
++seq_number);
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
/*
* If confidentiality is requested, the token header is
@@ -349,7 +305,7 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
* calculated over the plaintext concatenated with the
* token header.
*/
- if (context_handle->more_flags & LOCAL) {
+ if (ctx->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_INITIATOR_SEAL;
} else {
usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
@@ -370,14 +326,13 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
memcpy(p + input_message_buffer->length + padlength,
token, sizeof(*token));
- ret = krb5_encrypt(context, crypto,
+ ret = krb5_encrypt(context, ctx->crypto,
usage, p,
input_message_buffer->length + padlength +
sizeof(*token),
&cipher);
if (ret != 0) {
*minor_status = ret;
- krb5_crypto_destroy(context, crypto);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
@@ -389,14 +344,13 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
* this is really ugly, but needed against windows
* for DCERPC, as windows rotates by EC+RRC.
*/
- if (IS_DCE_STYLE(context_handle)) {
+ if (IS_DCE_STYLE(ctx)) {
ret = rrc_rotate(cipher.data, cipher.length, rrc+padlength, FALSE);
} else {
ret = rrc_rotate(cipher.data, cipher.length, rrc, FALSE);
}
if (ret != 0) {
*minor_status = ret;
- krb5_crypto_destroy(context, crypto);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
@@ -409,21 +363,19 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
buf = malloc(input_message_buffer->length + sizeof(*token));
if (buf == NULL) {
*minor_status = ENOMEM;
- krb5_crypto_destroy(context, crypto);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
memcpy(buf, input_message_buffer->value, input_message_buffer->length);
memcpy(buf + input_message_buffer->length, token, sizeof(*token));
- ret = krb5_create_checksum(context, crypto,
+ ret = krb5_create_checksum(context, ctx->crypto,
usage, 0, buf,
input_message_buffer->length +
sizeof(*token),
&cksum);
if (ret != 0) {
*minor_status = ret;
- krb5_crypto_destroy(context, crypto);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
free(buf);
return GSS_S_FAILURE;
@@ -446,7 +398,6 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
input_message_buffer->length + cksum.checksum.length, rrc, FALSE);
if (ret != 0) {
*minor_status = ret;
- krb5_crypto_destroy(context, crypto);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
free_Checksum(&cksum);
return GSS_S_FAILURE;
@@ -454,8 +405,6 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
free_Checksum(&cksum);
}
- krb5_crypto_destroy(context, crypto);
-
if (conf_state != NULL) {
*conf_state = conf_req_flag;
}
@@ -465,15 +414,13 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
}
OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
- const gsskrb5_ctx context_handle,
+ const gsskrb5_ctx ctx,
krb5_context context,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int *conf_state,
- gss_qop_t *qop_state,
- krb5_keyblock *key)
+ gss_qop_t *qop_state)
{
- krb5_crypto crypto;
gss_cfx_wrap_token token;
u_char token_flags;
krb5_error_code ret;
@@ -503,11 +450,11 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
(CFXSentByAcceptor | CFXSealed | CFXAcceptorSubkey);
if (token_flags & CFXSentByAcceptor) {
- if ((context_handle->more_flags & LOCAL) == 0)
+ if ((ctx->more_flags & LOCAL) == 0)
return GSS_S_DEFECTIVE_TOKEN;
}
- if (context_handle->more_flags & ACCEPTOR_SUBKEY) {
+ if (ctx->more_flags & ACCEPTOR_SUBKEY) {
if ((token_flags & CFXAcceptorSubkey) == 0)
return GSS_S_DEFECTIVE_TOKEN;
} else {
@@ -537,26 +484,21 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
return GSS_S_UNSEQ_TOKEN;
}
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
- ret = _gssapi_msg_order_check(context_handle->order, seq_number_lo);
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
if (ret != 0) {
*minor_status = 0;
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
return ret;
}
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
/*
* Decrypt and/or verify checksum
*/
- ret = krb5_crypto_init(context, key, 0, &crypto);
- if (ret != 0) {
- *minor_status = ret;
- return GSS_S_FAILURE;
- }
- if (context_handle->more_flags & LOCAL) {
+ if (ctx->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
} else {
usage = KRB5_KU_USAGE_INITIATOR_SEAL;
@@ -571,27 +513,24 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
* this is really ugly, but needed against windows
* for DCERPC, as windows rotates by EC+RRC.
*/
- if (IS_DCE_STYLE(context_handle)) {
+ if (IS_DCE_STYLE(ctx)) {
*minor_status = rrc_rotate(p, len, rrc+ec, TRUE);
} else {
*minor_status = rrc_rotate(p, len, rrc, TRUE);
}
if (*minor_status != 0) {
- krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
- ret = krb5_decrypt(context, crypto, usage,
+ ret = krb5_decrypt(context, ctx->crypto, usage,
p, len, &data);
if (ret != 0) {
*minor_status = ret;
- krb5_crypto_destroy(context, crypto);
return GSS_S_BAD_MIC;
}
/* Check that there is room for the pad and token header */
if (data.length < ec + sizeof(*token)) {
- krb5_crypto_destroy(context, crypto);
krb5_data_free(&data);
return GSS_S_DEFECTIVE_TOKEN;
}
@@ -604,7 +543,6 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
/* Check the integrity of the header */
if (memcmp(p, token, sizeof(*token)) != 0) {
- krb5_crypto_destroy(context, crypto);
krb5_data_free(&data);
return GSS_S_BAD_MIC;
}
@@ -617,16 +555,15 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
/* Rotate by RRC; bogus to do this in-place XXX */
*minor_status = rrc_rotate(p, len, rrc, TRUE);
if (*minor_status != 0) {
- krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
/* Determine checksum type */
ret = krb5_crypto_get_checksum_type(context,
- crypto, &cksum.cksumtype);
+ ctx->crypto,
+ &cksum.cksumtype);
if (ret != 0) {
*minor_status = ret;
- krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
@@ -635,7 +572,6 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
/* Check we have at least as much data as the checksum */
if (len < cksum.checksum.length) {
*minor_status = ERANGE;
- krb5_crypto_destroy(context, crypto);
return GSS_S_BAD_MIC;
}
@@ -647,7 +583,6 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
output_message_buffer->value = malloc(len + sizeof(*token));
if (output_message_buffer->value == NULL) {
*minor_status = ENOMEM;
- krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
@@ -664,21 +599,18 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
token->RRC[0] = 0;
token->RRC[1] = 0;
- ret = krb5_verify_checksum(context, crypto,
+ ret = krb5_verify_checksum(context, ctx->crypto,
usage,
output_message_buffer->value,
len + sizeof(*token),
&cksum);
if (ret != 0) {
*minor_status = ret;
- krb5_crypto_destroy(context, crypto);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
return GSS_S_BAD_MIC;
}
}
- krb5_crypto_destroy(context, crypto);
-
if (qop_state != NULL) {
*qop_state = GSS_C_QOP_DEFAULT;
}
@@ -688,14 +620,12 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
}
OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
- const gsskrb5_ctx context_handle,
+ const gsskrb5_ctx ctx,
krb5_context context,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
- gss_buffer_t message_token,
- krb5_keyblock *key)
+ gss_buffer_t message_token)
{
- krb5_crypto crypto;
gss_cfx_mic_token token;
krb5_error_code ret;
unsigned usage;
@@ -704,17 +634,10 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
size_t len;
int32_t seq_number;
- ret = krb5_crypto_init(context, key, 0, &crypto);
- if (ret != 0) {
- *minor_status = ret;
- return GSS_S_FAILURE;
- }
-
len = message_buffer->length + sizeof(*token);
buf = malloc(len);
if (buf == NULL) {
*minor_status = ENOMEM;
- krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
@@ -724,38 +647,36 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
token->TOK_ID[0] = 0x04;
token->TOK_ID[1] = 0x04;
token->Flags = 0;
- if ((context_handle->more_flags & LOCAL) == 0)
+ if ((ctx->more_flags & LOCAL) == 0)
token->Flags |= CFXSentByAcceptor;
- if (context_handle->more_flags & ACCEPTOR_SUBKEY)
+ if (ctx->more_flags & ACCEPTOR_SUBKEY)
token->Flags |= CFXAcceptorSubkey;
memset(token->Filler, 0xFF, 5);
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
krb5_auth_con_getlocalseqnumber(context,
- context_handle->auth_context,
+ ctx->auth_context,
&seq_number);
_gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]);
_gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
krb5_auth_con_setlocalseqnumber(context,
- context_handle->auth_context,
+ ctx->auth_context,
++seq_number);
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
- if (context_handle->more_flags & LOCAL) {
+ if (ctx->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_INITIATOR_SIGN;
} else {
usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
}
- ret = krb5_create_checksum(context, crypto,
+ ret = krb5_create_checksum(context, ctx->crypto,
usage, 0, buf, len, &cksum);
if (ret != 0) {
*minor_status = ret;
- krb5_crypto_destroy(context, crypto);
free(buf);
return GSS_S_FAILURE;
}
- krb5_crypto_destroy(context, crypto);
/* Determine MIC length */
message_token->length = sizeof(*token) + cksum.checksum.length;
@@ -780,14 +701,12 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
}
OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
- const gsskrb5_ctx context_handle,
+ const gsskrb5_ctx ctx,
krb5_context context,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
- gss_qop_t *qop_state,
- krb5_keyblock *key)
+ gss_qop_t *qop_state)
{
- krb5_crypto crypto;
gss_cfx_mic_token token;
u_char token_flags;
krb5_error_code ret;
@@ -814,10 +733,10 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
token_flags = token->Flags & (CFXSentByAcceptor | CFXAcceptorSubkey);
if (token_flags & CFXSentByAcceptor) {
- if ((context_handle->more_flags & LOCAL) == 0)
+ if ((ctx->more_flags & LOCAL) == 0)
return GSS_S_DEFECTIVE_TOKEN;
}
- if (context_handle->more_flags & ACCEPTOR_SUBKEY) {
+ if (ctx->more_flags & ACCEPTOR_SUBKEY) {
if ((token_flags & CFXAcceptorSubkey) == 0)
return GSS_S_DEFECTIVE_TOKEN;
} else {
@@ -839,36 +758,29 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
return GSS_S_UNSEQ_TOKEN;
}
- HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
- ret = _gssapi_msg_order_check(context_handle->order, seq_number_lo);
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
if (ret != 0) {
*minor_status = 0;
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
return ret;
}
- HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
/*
* Verify checksum
*/
- ret = krb5_crypto_init(context, key, 0, &crypto);
- if (ret != 0) {
- *minor_status = ret;
- return GSS_S_FAILURE;
- }
-
- ret = krb5_crypto_get_checksum_type(context, crypto,
+ ret = krb5_crypto_get_checksum_type(context, ctx->crypto,
&cksum.cksumtype);
if (ret != 0) {
*minor_status = ret;
- krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
cksum.checksum.data = p + sizeof(*token);
cksum.checksum.length = token_buffer->length - sizeof(*token);
- if (context_handle->more_flags & LOCAL) {
+ if (ctx->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
} else {
usage = KRB5_KU_USAGE_INITIATOR_SIGN;
@@ -877,18 +789,16 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
buf = malloc(message_buffer->length + sizeof(*token));
if (buf == NULL) {
*minor_status = ENOMEM;
- krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
memcpy(buf, message_buffer->value, message_buffer->length);
memcpy(buf + message_buffer->length, token, sizeof(*token));
- ret = krb5_verify_checksum(context, crypto,
+ ret = krb5_verify_checksum(context, ctx->crypto,
usage,
buf,
sizeof(*token) + message_buffer->length,
&cksum);
- krb5_crypto_destroy(context, crypto);
if (ret != 0) {
*minor_status = ret;
free(buf);