aboutsummaryrefslogtreecommitdiff
path: root/src/lib/gssapi
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2000-06-27 21:00:02 +0000
committerKen Raeburn <raeburn@mit.edu>2000-06-27 21:00:02 +0000
commit9fe2a01ec0fefa8b764bb6e9d7f9a09d11fed7ff (patch)
tree2d4fd8b1bf6272f1286ffb7af9ae1d351a347e71 /src/lib/gssapi
parent0d54ee19a3e5a159f0b86097ebfe193a0d9c26d8 (diff)
downloadkrb5-9fe2a01ec0fefa8b764bb6e9d7f9a09d11fed7ff.zip
krb5-9fe2a01ec0fefa8b764bb6e9d7f9a09d11fed7ff.tar.gz
krb5-9fe2a01ec0fefa8b764bb6e9d7f9a09d11fed7ff.tar.bz2
pullup from 1.2 branch
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12442 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/gssapi')
-rw-r--r--src/lib/gssapi/ChangeLog4
-rw-r--r--src/lib/gssapi/Makefile.in2
-rw-r--r--src/lib/gssapi/krb5/ChangeLog61
-rw-r--r--src/lib/gssapi/krb5/accept_sec_context.c396
-rw-r--r--src/lib/gssapi/krb5/acquire_cred.c41
-rw-r--r--src/lib/gssapi/krb5/add_cred.c42
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h77
-rw-r--r--src/lib/gssapi/krb5/init_sec_context.c476
-rw-r--r--src/lib/gssapi/krb5/inq_cred.c28
-rw-r--r--src/lib/gssapi/krb5/k5seal.c852
-rw-r--r--src/lib/gssapi/krb5/k5unseal.c1084
-rw-r--r--src/lib/gssapi/krb5/ser_sctx.c5
-rw-r--r--src/lib/gssapi/krb5/util_cksum.c5
-rw-r--r--src/lib/gssapi/krb5/util_crypt.c38
-rw-r--r--src/lib/gssapi/krb5/util_seed.c6
-rw-r--r--src/lib/gssapi/krb5/util_seqnum.c4
-rw-r--r--src/lib/gssapi/krb5/wrap_size_limit.c133
17 files changed, 1143 insertions, 2111 deletions
diff --git a/src/lib/gssapi/ChangeLog b/src/lib/gssapi/ChangeLog
index 7dc9b00..b8da271 100644
--- a/src/lib/gssapi/ChangeLog
+++ b/src/lib/gssapi/ChangeLog
@@ -1,3 +1,7 @@
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in(LIBMINOR): Bump library version.
+
2000-05-31 Wilfredo Sanchez <tritan@mit.edu>
* configure.in: Check for existance of <memory.h>.
diff --git a/src/lib/gssapi/Makefile.in b/src/lib/gssapi/Makefile.in
index bee2b85..20936da 100644
--- a/src/lib/gssapi/Makefile.in
+++ b/src/lib/gssapi/Makefile.in
@@ -24,7 +24,7 @@ SRCS=\
LIB=gssapi_krb5
LIBMAJOR=2
-LIBMINOR=1
+LIBMINOR=2
STOBJLISTS=OBJS.ST generic/OBJS.ST krb5/OBJS.ST
SHLIB_EXPDEPS=\
$(TOPLIBD)/libkrb5$(SHLIBEXT) \
diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog
index ccb16f4..087104e 100644
--- a/src/lib/gssapi/krb5/ChangeLog
+++ b/src/lib/gssapi/krb5/ChangeLog
@@ -1,3 +1,62 @@
+2000-06-09 Tom Yu <tlyu@mit.edu>
+ Ken Raeburn <raeburn@mit.edu>
+
+ * accept_sec_context.c (krb5_gss_accept_sec_context): Remove
+ explicit check of mech OID against credential.
+
+ * util_crypt.c (kg_encrypt): Copy ivec, since c_encrypt() now
+ updates ivecs.
+ (kg_decrypt): Copy ivec, since c_decrypt() now updates ivecs.
+
+ * init_sec_context.c (get_credentials): Don't check each enctype
+ against a list from the krb5 library; instead, just try to use it,
+ and go on to the next if the error code indicates we can't use it.
+
+ * gssapiP_krb5.h (enum qop): New type, derived from spec but
+ currently not used.
+ * util_crypt.c (kg_encrypt, kg_decrypt): Added key derivation
+ usage value as an argument. Prototypes and callers updated; all
+ callers use KG_USAGE_SEAL, except KG_USAGE_SEQ when encrypting
+ sequence numbers.
+ * 3des.txt: New file.
+
+ * gssapiP_krb5.h (struct _krb5_gss_ctx_id_rec): Delete field
+ gsskrb5_version.
+ (struct _krb5_gss_cred_id_rec): Delete field rfcv2_mech.
+ * accept_sec_context.c, acquire_cred.c, add_cred.c, inq_cred.c,
+ k5seal.c, k5unseal.c, ser_ctx.c:
+ Delete krb5-mech2 support.
+
+ * init_sec_context.c (get_credentials): Enctype argument is now a
+ pointer to a list of enctypes. Explicitly try each in order until
+ success or an error other than cryptosystem not being supported.
+ (krb5_gss_init_sec_context): Pass list of cryptosystems, starting
+ with 3DES.
+
+ * gssapiP_krb5.h (enum sgn_alg, enum seal_alg): New types,
+ giving symbolic names for values from RFC 1964, a Microsoft win2k
+ I-D, and our proposed 3des-sha1 values.
+ (KG_USAGE_SEAL, KG_USAGE_SIGN, KG_USAGE_SEQ): New macros.
+
+ * accept_sec_context.c (rd_req_keyproc): Already-disabled routine
+ deleted.
+ (krb5_gss_accept_sec_context): Use sgn_alg and seal_alg symbolic
+ names. Add a case for des3-hmac-sha1.
+ * k5seal.c (make_seal_token_v1): Likewise. Do key derivation for
+ checksums.
+ * k5unseal.c (kg_unseal_v1): Likewise.
+ * util_crypt.c (kg_encrypt, kg_decrypt): Do key derivation for
+ encryption.
+
+ * util_crypt.c (zeros): Unused variable deleted.
+
+ * wrap_size_limit.c: Remove mech2 support. Add MIT copyright.
+
+2000-06-09 Nalin Dahyabhai <nalin@redhat.com>
+
+ * add_cred.c (krb5_gss_add_cred): Don't overflow buffers "ktboth"
+ or "ccboth".
+
2000-05-31 Wilfredo Sanchez <tritan@mit.edu>
* accept_sec_context.c, gssapiP_krb5.h, init_sec_context.c,
@@ -21,7 +80,7 @@
The rfc1964 mech always pads and confounds regardless of whether
confidentiality is requested.
-2000-01-27 Ken Raeburn <raeburn@raeburn.org>
+2000-01-27 Ken Raeburn <raeburn@mit.edu>
* init_sec_context.c (krb5_gss_init_sec_context): Default to
des-cbc-crc.
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index 075d0e4..0d2aaa5 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -51,38 +75,7 @@
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
-
-/*
- * $Id$
- */
-
-#if 0
-
-/* XXXX This widen/narrow stuff is bletcherous, but it seems to be
- necessary. Perhaps there is a "better" way, but I don't know what it
- is */
-
-#include <krb5/widen.h>
-static krb5_error_code
-rd_req_keyproc(krb5_pointer keyprocarg, krb5_principal server,
- krb5_kvno kvno, krb5_keyblock **keyblock)
-#include <krb5/narrow.h>
-{
- krb5_error_code code;
- krb5_keytab_entry ktentry;
-
- if (code = krb5_kt_get_entry((krb5_keytab) keyprocarg, server, kvno,
- &ktentry))
- return(code);
-
- code = krb5_copy_keyblock(&ktentry.key, keyblock);
-
- (void) krb5_kt_free_entry(&ktentry);
-
- return(code);
-}
-
-#endif
+#include <assert.h>
/* Decode, decrypt and store the forwarded creds in the local ccache. */
static krb5_error_code
@@ -147,7 +140,6 @@ rd_and_store_for_creds(context, inbuf, out_cred)
/* cred->princ already set */
cred->prerfc_mech = 1; /* this cred will work with all three mechs */
cred->rfc_mech = 1;
- cred->rfcv2_mech = 1;
cred->keytab = NULL; /* no keytab associated with this... */
cred->ccache = ccache; /* but there is a credential cache */
cred->tgt_expire = creds[0]->times.endtime; /* store the end time */
@@ -208,11 +200,10 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
krb5_ui_4 gss_flags = 0;
int decode_req_message = 0;
krb5_gss_ctx_id_rec *ctx = 0;
-#if 0
krb5_enctype enctype;
-#endif
krb5_timestamp now;
gss_buffer_desc token;
+ int err;
krb5_auth_context auth_context = NULL;
krb5_ticket * ticket = NULL;
int option_id;
@@ -224,7 +215,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
gss_cred_id_t cred_handle = NULL;
krb5_gss_cred_id_t deleg_cred = NULL;
int token_length;
- int gsskrb5_vers;
int nctypes;
krb5_cksumtype *ctypes = 0;
struct kg2_option fwcred;
@@ -298,13 +288,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
&(ap_req.length),
&ptr, KG_TOK_CTX_AP_REQ,
input_token->length))) {
- if (! cred->rfc_mech) {
- code = G_WRONG_MECH;
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
mech_used = gss_mech_krb5;
- gsskrb5_vers = 1000;
} else if ((code == G_WRONG_MECH) &&
!(code = g_verify_token_header((gss_OID) gss_mech_krb5_old,
&(ap_req.length),
@@ -317,56 +301,15 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
* compatibility, and use it to decide when to use the
* old behavior.
*/
- if (! cred->prerfc_mech) {
- code = G_WRONG_MECH;
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
mech_used = gss_mech_krb5_old;
- gsskrb5_vers = 1000;
- } else if ((code == G_WRONG_MECH) &&
- !(code = g_verify_token_header((gss_OID) gss_mech_krb5_v2,
- &token_length,
- &ptr, KG2_TOK_INITIAL,
- input_token->length))) {
- if (! cred->rfcv2_mech) {
- code = G_WRONG_MECH;
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
- mech_used = gss_mech_krb5_v2;
- gsskrb5_vers = 2000;
} else {
major_status = GSS_S_DEFECTIVE_TOKEN;
goto fail;
}
- if (gsskrb5_vers == 2000) {
- /* gss krb5 v2 */
-
- fwcred.option_id = KRB5_GSS_FOR_CREDS_OPTION;
- fwcred.data = NULL;
-
- if (GSS_ERROR(major_status =
- kg2_parse_token(&code, ptr, token_length,
- &gss_flags, &nctypes, &ctypes,
- delegated_cred_handle?1:0,
- &fwcred, &ap_req, NULL))) {
- goto fail;
- }
-
- gss_flags = (ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3];
-
- gss_flags &= ~GSS_C_DELEG_FLAG; /* mask out the delegation flag;
- if there's a delegation, we'll
- set it below */
- } else {
- /* gss krb5 v1 */
-
- sptr = (char *) ptr;
- TREAD_STR(sptr, ap_req.data, ap_req.length);
- decode_req_message = 1;
- }
+ sptr = (char *) ptr;
+ TREAD_STR(sptr, ap_req.data, ap_req.length);
+ decode_req_message = 1;
/* construct the sender_addr */
@@ -418,9 +361,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
}
#endif
- if (gsskrb5_vers == 2000) {
- bigend = 1;
- } else {
+ {
/* gss krb5 v1 */
/* stash this now, for later. */
@@ -559,7 +500,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
ctx->gss_flags = KG_IMPLFLAGS(gss_flags);
ctx->seed_init = 0;
ctx->big_endian = bigend;
- ctx->gsskrb5_version = gsskrb5_vers;
/* Intern the ctx pointer so that delete_sec_context works */
if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
@@ -605,114 +545,37 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
goto fail;
}
- if (gsskrb5_vers == 2000) {
- int cblen;
- krb5_boolean valid;
-
- /* intersect the token ctypes with the local ctypes */
-
- if (code = krb5_c_keyed_checksum_types(context, ctx->subkey->enctype,
- &ctx->nctypes, &ctx->ctypes))
- goto fail;
-
- if (nctypes == 0) {
- code = KRB5_CRYPTO_INTERNAL;
- goto fail;
- }
-
- kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes);
+ switch(ctx->subkey->enctype) {
+ case ENCTYPE_DES_CBC_MD5:
+ case ENCTYPE_DES_CBC_CRC:
+ ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
+ ctx->signalg = SGN_ALG_DES_MAC_MD5;
+ ctx->cksum_size = 8;
+ ctx->sealalg = SEAL_ALG_DES;
- if (nctypes == 0) {
- code = KG_NO_CTYPES;
- goto fail;
- }
-
- /* process the delegated cred, if any */
-
- if (fwcred.data) {
- krb5_data option;
-
- option.length = fwcred.length;
- option.data = fwcred.data;
-
- if (code = rd_and_store_for_creds(context, &option, &deleg_cred)) {
- major_status = GSS_S_FAILURE;
- goto fail;
- }
-
- gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */
- }
-
- /* construct the checksum buffer */
-
- cblen = 4*5;
- if (input_chan_bindings)
- cblen += (input_chan_bindings->initiator_address.length+
- input_chan_bindings->acceptor_address.length+
- input_chan_bindings->application_data.length);
-
- cksumdata.length = cblen + ((char *)(ap_req.data-2) - (char *)(ptr-2));
+ /* fill in the encryption descriptors */
- if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) {
- code = ENOMEM;
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) {
major_status = GSS_S_FAILURE;
goto fail;
}
- ptr2 = cksumdata.data;
-
- if (input_chan_bindings) {
- TWRITE_INT(ptr2, input_chan_bindings->initiator_addrtype, 1);
- TWRITE_BUF(ptr2, input_chan_bindings->initiator_address, 1);
- TWRITE_INT(ptr2, input_chan_bindings->acceptor_addrtype, 1);
- TWRITE_BUF(ptr2, input_chan_bindings->acceptor_address, 1);
- TWRITE_BUF(ptr2, input_chan_bindings->application_data, 1);
- } else {
- memset(ptr2, 0, cblen);
- ptr2 += cblen;
- }
-
- memcpy(ptr2, ptr-2, ((char *)(ap_req.data-2) - (char *)(ptr-2)));
+ for (i=0; i<ctx->enc->length; i++)
+ /*SUPPRESS 113*/
+ ctx->enc->contents[i] ^= 0xf0;
- if (code = krb5_c_verify_checksum(context, ctx->subkey,
- KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
- &cksumdata, authdat->checksum,
- &valid)) {
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) {
major_status = GSS_S_FAILURE;
goto fail;
}
- free(cksumdata.data);
- cksumdata.data = 0;
+ break;
- if (!valid) {
- code = 0;
- major_status = GSS_S_BAD_SIG;
- goto fail;
- }
- } else {
- /* gss krb5 v1 */
-
- switch(ctx->subkey->enctype) {
- case ENCTYPE_DES_CBC_MD5:
- case ENCTYPE_DES_CBC_CRC:
- ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
- ctx->signalg = 0;
- ctx->cksum_size = 8;
- ctx->sealalg = 0;
- break;
-#if 0
- case ENCTYPE_DES3_CBC_MD5:
- enctype = ENCTYPE_DES3_CBC_RAW;
- ctx->signalg = 3;
- ctx->cksum_size = 16;
- ctx->sealalg = 1;
- break;
-#endif
- default:
- code = KRB5_BAD_ENCTYPE;
- goto fail;
- }
+ case ENCTYPE_DES3_CBC_SHA1:
+ ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
+ ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
+ ctx->cksum_size = 20;
+ ctx->sealalg = SEAL_ALG_DES3KD;
/* fill in the encryption descriptors */
@@ -721,14 +584,16 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
goto fail;
}
- for (i=0; i<ctx->enc->length; i++)
- /*SUPPRESS 113*/
- ctx->enc->contents[i] ^= 0xf0;
-
if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) {
major_status = GSS_S_FAILURE;
goto fail;
}
+
+ break;
+
+ default:
+ code = KRB5_BAD_ENCTYPE;
+ goto fail;
}
ctx->endtime = ticket->enc_part2->times.endtime;
@@ -771,122 +636,22 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
/* the reply token hasn't been sent yet, but that's ok. */
ctx->established = 1;
- if (ctx->gsskrb5_version == 2000) {
- krb5_ui_4 tok_flags;
-
- tok_flags =
- (ctx->gss_flags & GSS_C_DELEG_FLAG)?KG2_RESP_FLAG_DELEG_OK:0;
-
- cksumdata.length = 8 + 4*ctx->nctypes + 4;
-
- if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) {
- code = ENOMEM;
- major_status = GSS_S_FAILURE;
- goto fail;
- }
-
- /* construct the token fields */
-
- ptr = cksumdata.data;
-
- ptr[0] = (KG2_TOK_RESPONSE >> 8) & 0xff;
- ptr[1] = KG2_TOK_RESPONSE & 0xff;
-
- ptr[2] = (tok_flags >> 24) & 0xff;
- ptr[3] = (tok_flags >> 16) & 0xff;
- ptr[4] = (tok_flags >> 8) & 0xff;
- ptr[5] = tok_flags & 0xff;
-
- ptr[6] = (ctx->nctypes >> 8) & 0xff;
- ptr[7] = ctx->nctypes & 0xff;
-
- ptr += 8;
-
- for (i=0; i<ctx->nctypes; i++) {
- ptr[i] = (ctx->ctypes[i] >> 24) & 0xff;
- ptr[i+1] = (ctx->ctypes[i] >> 16) & 0xff;
- ptr[i+2] = (ctx->ctypes[i] >> 8) & 0xff;
- ptr[i+3] = ctx->ctypes[i] & 0xff;
-
- ptr += 4;
- }
-
- memset(ptr, 0, 4);
-
- /* make the MIC token */
+ token.length = g_token_size((gss_OID) mech_used, ap_rep.length);
- {
- gss_buffer_desc text, token;
-
- text.length = cksumdata.length;
- text.value = cksumdata.data;
-
- /* ctx->seq_send must be set before this call */
-
- if (GSS_ERROR(major_status =
- krb5_gss_get_mic(&code, ctx,
- GSS_C_QOP_DEFAULT,
- &text, &token)))
- goto fail;
-
- mic.length = token.length;
- mic.data = token.value;
- }
-
- token.length = g_token_size((gss_OID) mech_used,
- (cksumdata.length-2)+4+ap_rep.length+
- mic.length);
-
- if ((token.value = (unsigned char *) xmalloc(token.length))
- == NULL) {
- code = ENOMEM;
- major_status = GSS_S_FAILURE;
- goto fail;
- }
- ptr = token.value;
- g_make_token_header((gss_OID) mech_used,
- (cksumdata.length-2)+4+ap_rep.length+mic.length,
- &ptr, KG2_TOK_RESPONSE);
-
- memcpy(ptr, cksumdata.data+2, cksumdata.length-2);
- ptr += cksumdata.length-2;
-
- ptr[0] = (ap_rep.length >> 8) & 0xff;
- ptr[1] = ap_rep.length & 0xff;
- memcpy(ptr+2, ap_rep.data, ap_rep.length);
-
- ptr += (2+ap_rep.length);
-
- ptr[0] = (mic.length >> 8) & 0xff;
- ptr[1] = mic.length & 0xff;
- memcpy(ptr+2, mic.data, mic.length);
-
- ptr += (2+mic.length);
-
- free(cksumdata.data);
- cksumdata.data = 0;
-
- /* gss krb5 v2 */
- } else {
- /* gss krb5 v1 */
-
- token.length = g_token_size((gss_OID) mech_used, ap_rep.length);
-
- if ((token.value = (unsigned char *) xmalloc(token.length))
- == NULL) {
- major_status = GSS_S_FAILURE;
- code = ENOMEM;
- goto fail;
- }
- ptr = token.value;
- g_make_token_header((gss_OID) mech_used, ap_rep.length,
- &ptr, KG_TOK_CTX_AP_REP);
+ if ((token.value = (unsigned char *) xmalloc(token.length))
+ == NULL) {
+ major_status = GSS_S_FAILURE;
+ code = ENOMEM;
+ goto fail;
+ }
+ ptr = token.value;
+ g_make_token_header((gss_OID) mech_used, ap_rep.length,
+ &ptr, KG_TOK_CTX_AP_REP);
- TWRITE_STR(ptr, ap_rep.data, ap_rep.length);
+ TWRITE_STR(ptr, ap_rep.data, ap_rep.length);
- ctx->established = 1;
+ ctx->established = 1;
- }
} else {
token.length = 0;
token.value = NULL;
@@ -1016,13 +781,8 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
if (code)
return (major_status);
- if (gsskrb5_vers == 2000) {
- tmsglen = 12+scratch.length;
- toktype = KG2_TOK_RESPONSE;
- } else {
- tmsglen = scratch.length;
- toktype = KG_TOK_CTX_ERROR;
- }
+ tmsglen = scratch.length;
+ toktype = KG_TOK_CTX_ERROR;
token.length = g_token_size((gss_OID) mech_used, tmsglen);
token.value = (unsigned char *) xmalloc(token.length);
@@ -1032,24 +792,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
ptr = token.value;
g_make_token_header((gss_OID) mech_used, tmsglen, &ptr, toktype);
- if (gsskrb5_vers == 2000) {
- krb5_ui_4 flags;
-
- flags = KG2_RESP_FLAG_ERROR;
-
- ptr[0] = (flags << 24) & 0xff;
- ptr[1] = (flags << 16) & 0xff;
- ptr[2] = (flags << 8) & 0xff;
- ptr[3] = flags & 0xff;
-
- memset(ptr+4, 0, 6);
-
- ptr[10] = (scratch.length << 8) & 0xff;
- ptr[11] = scratch.length & 0xff;
-
- ptr += 12;
- }
-
TWRITE_STR(ptr, scratch.data, scratch.length);
xfree(scratch.data);
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
index 78e8c29..33946e7 100644
--- a/src/lib/gssapi/krb5/acquire_cred.c
+++ b/src/lib/gssapi/krb5/acquire_cred.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -53,10 +77,6 @@
#include <strings.h>
#endif
-/*
- * $Id$
- */
-
/* get credentials corresponding to a key in the krb5 keytab.
If the default name is requested, return the name in output_princ.
If output_princ is non-NULL, the caller will use or free it, regardless
@@ -283,7 +303,7 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
size_t i;
krb5_gss_cred_id_t cred;
gss_OID_set ret_mechs;
- int req_old, req_new, req_v2;
+ int req_old, req_new;
OM_uint32 ret;
krb5_error_code code;
@@ -313,22 +333,18 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
if (desired_mechs == GSS_C_NULL_OID_SET) {
req_old = 1;
req_new = 1;
- req_v2 = 1;
} else {
req_old = 0;
req_new = 0;
- req_v2 = 0;
for (i=0; i<desired_mechs->count; i++) {
if (g_OID_equal(gss_mech_krb5_old, &(desired_mechs->elements[i])))
req_old++;
if (g_OID_equal(gss_mech_krb5, &(desired_mechs->elements[i])))
req_new++;
- if (g_OID_equal(gss_mech_krb5_v2, &(desired_mechs->elements[i])))
- req_v2++;
}
- if (!req_old && !req_new && !req_v2) {
+ if (!req_old && !req_new) {
*minor_status = 0;
return(GSS_S_BAD_MECH);
}
@@ -347,7 +363,6 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
cred->princ = NULL;
cred->prerfc_mech = req_old;
cred->rfc_mech = req_new;
- cred->rfcv2_mech = req_v2;
cred->keytab = NULL;
cred->ccache = NULL;
@@ -447,10 +462,6 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
(cred->rfc_mech &&
GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
gss_mech_krb5,
- &ret_mechs))) ||
- (cred->rfcv2_mech &&
- GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- gss_mech_krb5_v2,
&ret_mechs)))) {
if (cred->ccache)
(void)krb5_cc_close(context, cred->ccache);
diff --git a/src/lib/gssapi/krb5/add_cred.c b/src/lib/gssapi/krb5/add_cred.c
index 2a6fdb4..918c264 100644
--- a/src/lib/gssapi/krb5/add_cred.c
+++ b/src/lib/gssapi/krb5/add_cred.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
* All rights reserved.
@@ -110,8 +134,7 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
/* check that desired_mech isn't already in the credential */
if ((g_OID_equal(desired_mech, gss_mech_krb5_old) && cred->prerfc_mech) ||
- (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech) ||
- (g_OID_equal(desired_mech, gss_mech_krb5_v2) && cred->rfcv2_mech)) {
+ (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech)) {
*minor_status = 0;
return(GSS_S_DUPLICATE_ELEMENT);
}
@@ -156,7 +179,6 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
new_cred->usage = cred_usage;
new_cred->prerfc_mech = cred->prerfc_mech;
new_cred->rfc_mech = cred->rfc_mech;
- new_cred->rfcv2_mech = cred->rfcv2_mech;
new_cred->tgt_expire = cred->tgt_expire;
if (code = krb5_copy_principal(context, cred->princ,
@@ -177,8 +199,9 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
return(GSS_S_FAILURE);
}
- strcpy(ktboth, kttype);
- strcat(ktboth, ":");
+ strncpy(ktboth, kttype, sizeof(ktboth) - 1);
+ ktboth[sizeof(ktboth) - 1] = '\0';
+ strncat(ktboth, ":", sizeof(ktboth) - 1 - strlen(ktboth));
if (code = krb5_kt_get_name(context, cred->keytab,
ktboth+strlen(ktboth),
@@ -234,9 +257,10 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
return(GSS_S_FAILURE);
}
- strcpy(ccboth, cctype);
- strcat(ccboth, ":");
- strcat(ccboth, ccname);
+ strncpy(ccboth, cctype, sizeof(ccboth) - 1);
+ ccboth[sizeof(ccboth) - 1] = '\0';
+ strncat(ccboth, ":", sizeof(ccboth) - 1 - strlen(ccboth));
+ strncat(ccboth, ccname, sizeof(ccboth) - 1 - strlen(ccboth));
if (code = krb5_cc_resolve(context, ccboth, &new_cred->ccache)) {
if (new_cred->rcache)
@@ -280,8 +304,6 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
cred->prerfc_mech = 1;
else if (g_OID_equal(desired_mech, gss_mech_krb5))
cred->rfc_mech = 1;
- else if (g_OID_equal(desired_mech, gss_mech_krb5_v2))
- cred->rfcv2_mech = 1;
/* set the outputs */
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index a22cd8d..ed09569 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -23,10 +47,6 @@
#ifndef _GSSAPIP_KRB5_H_
#define _GSSAPIP_KRB5_H_
-/*
- * $Id$
- */
-
#include <krb5.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
@@ -81,6 +101,39 @@
#define KG2_RESP_FLAG_ERROR 0x0001
#define KG2_RESP_FLAG_DELEG_OK 0x0002
+/* These are to be stored in little-endian order, i.e., des-mac is
+ stored as 02 00. */
+enum sgn_alg {
+ SGN_ALG_DES_MAC_MD5 = 0x0000,
+ SGN_ALG_MD2_5 = 0x0001,
+ SGN_ALG_DES_MAC = 0x0002,
+ SGN_ALG_3 = 0x0003, /* not published */
+ SGN_ALG_HMAC_MD5 = 0x0011, /* microsoft w2k; no support */
+ SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004
+};
+enum seal_alg {
+ SEAL_ALG_NONE = 0xffff,
+ SEAL_ALG_DES = 0x0000,
+ SEAL_ALG_1 = 0x0001, /* not published */
+ SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; no support */
+ SEAL_ALG_DES3KD = 0x0002
+};
+
+#define KG_USAGE_SEAL 22
+#define KG_USAGE_SIGN 23
+#define KG_USAGE_SEQ 24
+
+enum qop {
+ GSS_KRB5_INTEG_C_QOP_MD5 = 0x0001, /* *partial* MD5 = "MD2.5" */
+ GSS_KRB5_INTEG_C_QOP_DES_MD5 = 0x0002,
+ GSS_KRB5_INTEG_C_QOP_DES_MAC = 0x0003,
+ GSS_KRB5_INTEG_C_QOP_HMAC_SHA1 = 0x0004,
+ GSS_KRB5_INTEG_C_QOP_MASK = 0x00ff,
+ GSS_KRB5_CONF_C_QOP_DES = 0x0100,
+ GSS_KRB5_CONF_C_QOP_DES3_KD = 0x0200,
+ GSS_KRB5_CONF_C_QOP_MASK = 0xff00
+};
+
/** internal types **/
typedef krb5_principal krb5_gss_name_t;
@@ -91,7 +144,6 @@ typedef struct _krb5_gss_cred_id_rec {
krb5_principal princ; /* this is not interned as a gss_name_t */
int prerfc_mech;
int rfc_mech;
- int rfcv2_mech;
/* keytab (accept) data */
krb5_keytab keytab;
@@ -127,7 +179,6 @@ typedef struct _krb5_gss_ctx_id_rec {
int big_endian;
krb5_auth_context auth_context;
gss_OID_desc *mech_used;
- int gsskrb5_version;
int nctypes;
krb5_cksumtype *ctypes;
} krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t;
@@ -192,12 +243,18 @@ int kg_encrypt_size PROTOTYPE((krb5_context context,
krb5_keyblock *key, int n));
krb5_error_code kg_encrypt PROTOTYPE((krb5_context context,
- krb5_keyblock *key,
- krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length));
+ krb5_keyblock *key, int usage,
+ krb5_pointer iv,
+ krb5_pointer in,
+ krb5_pointer out,
+ int length));
krb5_error_code kg_decrypt PROTOTYPE((krb5_context context,
- krb5_keyblock *key,
- krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length));
+ krb5_keyblock *key, int usage,
+ krb5_pointer iv,
+ krb5_pointer in,
+ krb5_pointer out,
+ int length));
OM_uint32 kg_seal PROTOTYPE((krb5_context context,
OM_uint32 *minor_status,
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
index 8baad8c..13a971f 100644
--- a/src/lib/gssapi/krb5/init_sec_context.c
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -51,10 +75,7 @@
#include <memory.h>
#endif
#include <stdlib.h>
-
-/*
- * $Id$
- */
+#include <assert.h>
/* XXX This is for debugging only!!! Should become a real bitfield
at some point */
@@ -65,17 +86,18 @@ int krb5_gss_dbg_client_expcreds = 0;
* ccache.
*/
static krb5_error_code get_credentials(context, cred, server, now,
- endtime, enctype, out_creds)
+ endtime, enctypes, out_creds)
krb5_context context;
krb5_gss_cred_id_t cred;
krb5_principal server;
krb5_timestamp now;
krb5_timestamp endtime;
- krb5_enctype enctype;
+ const krb5_enctype *enctypes;
krb5_creds **out_creds;
{
krb5_error_code code;
krb5_creds in_creds;
+ int i;
memset((char *) &in_creds, 0, sizeof(krb5_creds));
@@ -84,10 +106,21 @@ static krb5_error_code get_credentials(context, cred, server, now,
if ((code = krb5_copy_principal(context, server, &in_creds.server)))
goto cleanup;
in_creds.times.endtime = endtime;
- in_creds.keyblock.enctype = enctype;
- if ((code = krb5_get_credentials(context, 0, cred->ccache,
- &in_creds, out_creds)))
+ in_creds.keyblock.enctype = 0;
+
+ for (i = 0; enctypes[i]; i++) {
+ in_creds.keyblock.enctype = enctypes[i];
+ code = krb5_get_credentials(context, 0, cred->ccache,
+ &in_creds, out_creds);
+ if (code != KRB5_CC_NOT_KTYPE && code != KRB5KDC_ERR_ETYPE_NOSUPP)
+ break;
+ }
+ if (enctypes[i] == 0) {
+ code = KRB5_CONFIG_ETYPE_NOSUPP;
+ goto cleanup;
+ }
+ if (code)
goto cleanup;
/*
@@ -95,7 +128,8 @@ static krb5_error_code get_credentials(context, cred, server, now,
* boundaries) because accept_sec_context code is also similarly
* non-forgiving.
*/
- if (!krb5_gss_dbg_client_expcreds && (*out_creds)->times.endtime < now) {
+ if (!krb5_gss_dbg_client_expcreds && *out_creds != NULL &&
+ (*out_creds)->times.endtime < now) {
code = KRB5KRB_AP_ERR_TKT_EXPIRED;
goto cleanup;
}
@@ -119,196 +153,8 @@ make_ap_req_v2(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
gss_OID mech_type;
gss_buffer_t token;
{
- krb5_flags mk_req_flags = 0;
- krb5_int32 con_flags;
- krb5_error_code code;
- krb5_data credmsg, cksumdata, ap_req;
- int i, tlen, cblen, nctypes;
- krb5_cksumtype *ctypes;
- unsigned char *t, *ptr;
-
- credmsg.data = 0;
- cksumdata.data = 0;
- ap_req.data = 0;
- ctypes = 0;
-
- /* create the option data if necessary */
- if (ctx->gss_flags & GSS_C_DELEG_FLAG) {
- /* first get KRB_CRED message, so we know its length */
-
- /* clear the time check flag that was set in krb5_auth_con_init() */
- krb5_auth_con_getflags(context, ctx->auth_context, &con_flags);
- krb5_auth_con_setflags(context, ctx->auth_context,
- con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME);
-
- code = krb5_fwd_tgt_creds(context, ctx->auth_context, 0,
- cred->princ, ctx->there, cred->ccache, 1,
- &credmsg);
-
- /* turn KRB5_AUTH_CONTEXT_DO_TIME back on */
- krb5_auth_con_setflags(context, ctx->auth_context, con_flags);
-
- if (code) {
- /* don't fail here; just don't accept/do the delegation
- request */
- ctx->gss_flags &= ~GSS_C_DELEG_FLAG;
- } else {
- if (credmsg.length > KRB5_INT16_MAX) {
- krb5_free_data_contents(context, &credmsg);
- return(KRB5KRB_ERR_FIELD_TOOLONG);
- }
- }
- } else {
- credmsg.length = 0;
- }
-
- /* construct the list of compatible cksum types */
-
- if ((code = krb5_c_keyed_checksum_types(context,
- k_cred->keyblock.enctype,
- &nctypes, &ctypes)))
- goto cleanup;
-
- if (nctypes == 0) {
- code = KRB5_CRYPTO_INTERNAL;
- goto cleanup;
- }
-
- /* construct the checksum fields */
-
- cblen = 4*5;
- if (chan_bindings)
- cblen += (chan_bindings->initiator_address.length+
- chan_bindings->acceptor_address.length+
- chan_bindings->application_data.length);
-
- cksumdata.length = cblen + 8 + 4*nctypes + 4;
- if (credmsg.length)
- cksumdata.length += 4 + credmsg.length;
-
- if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL)
- goto cleanup;
-
- /* helper macros. This code currently depends on a long being 32
- bits, and htonl dtrt. */
-
- ptr = cksumdata.data;
-
- if (chan_bindings) {
- TWRITE_INT(ptr, chan_bindings->initiator_addrtype, 1);
- TWRITE_BUF(ptr, chan_bindings->initiator_address, 1);
- TWRITE_INT(ptr, chan_bindings->acceptor_addrtype, 1);
- TWRITE_BUF(ptr, chan_bindings->acceptor_address, 1);
- TWRITE_BUF(ptr, chan_bindings->application_data, 1);
- } else {
- memset(ptr, 0, cblen);
- ptr += cblen;
- }
-
- /* construct the token fields */
-
- ptr[0] = (KG2_TOK_INITIAL >> 8) & 0xff;
- ptr[1] = KG2_TOK_INITIAL & 0xff;
-
- ptr[2] = (ctx->gss_flags >> 24) & 0xff;
- ptr[3] = (ctx->gss_flags >> 16) & 0xff;
- ptr[4] = (ctx->gss_flags >> 8) & 0xff;
- ptr[5] = ctx->gss_flags & 0xff;
-
- ptr[6] = (nctypes >> 8) & 0xff;
- ptr[7] = nctypes & 0xff;
-
- ptr += 8;
-
- for (i=0; i<nctypes; i++) {
- ptr[0] = (ctypes[i] >> 24) & 0xff;
- ptr[1] = (ctypes[i] >> 16) & 0xff;
- ptr[2] = (ctypes[i] >> 8) & 0xff;
- ptr[3] = ctypes[i] & 0xff;
-
- ptr += 4;
- }
-
- if (credmsg.length) {
- ptr[0] = (KRB5_GSS_FOR_CREDS_OPTION >> 8) & 0xff;
- ptr[1] = KRB5_GSS_FOR_CREDS_OPTION & 0xff;
-
- ptr[2] = (credmsg.length >> 8) & 0xff;
- ptr[3] = credmsg.length & 0xff;
-
- ptr += 4;
-
- memcpy(ptr, credmsg.data, credmsg.length);
-
- ptr += credmsg.length;
- }
-
- memset(ptr, 0, 4);
-
- /* call mk_req. subkey and ap_req need to be used or destroyed */
-
- mk_req_flags = AP_OPTS_USE_SUBKEY;
-
- if (ctx->gss_flags & GSS_C_MUTUAL_FLAG)
- mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED;
-
- if ((code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags,
- &cksumdata, k_cred, &ap_req)))
- goto cleanup;
-
- /* store the interesting stuff from creds and authent */
- ctx->endtime = k_cred->times.endtime;
- ctx->krb_flags = k_cred->ticket_flags;
-
- /* build up the token */
-
- /* allocate space for the token */
- tlen = g_token_size((gss_OID) mech_type,
- (cksumdata.length-(2+cblen))+2+ap_req.length);
-
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL) {
- code = ENOMEM;
- goto cleanup;
- }
-
- ptr = t;
-
- g_make_token_header((gss_OID) mech_type,
- (cksumdata.length-(2+cblen))+2+ap_req.length,
- &ptr, KG2_TOK_INITIAL);
-
- /* skip over the channel bindings and the token id */
- memcpy(ptr, cksumdata.data+cblen+2, cksumdata.length-(cblen+2));
- ptr += cksumdata.length-(cblen+2);
- ptr[0] = (ap_req.length >> 8) & 0xff;
- ptr[1] = ap_req.length & 0xff;
- ptr += 2;
- memcpy(ptr, ap_req.data, ap_req.length);
-
- /* pass allocated data back */
-
- ctx->nctypes = nctypes;
- ctx->ctypes = ctypes;
-
- token->length = tlen;
- token->value = (void *) t;
-
- code = 0;
-
-cleanup:
- if (code) {
- if (ctypes)
- krb5_free_cksumtypes(context, ctypes);
- }
-
- if (credmsg.data)
- free(credmsg.data);
- if (ap_req.data)
- free(ap_req.data);
- if (cksumdata.data)
- free(cksumdata.data);
-
- return(code);
+ int krb5_mech2_supported = 0;
+ assert(krb5_mech2_supported);
}
static krb5_error_code
@@ -482,13 +328,19 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
krb5_context context;
krb5_gss_cred_id_t cred;
krb5_creds *k_cred = 0;
- krb5_enctype enctype = ENCTYPE_DES_CBC_CRC;
+ static const krb5_enctype wanted_enctypes[] = {
+#if 1
+ ENCTYPE_DES3_CBC_SHA1,
+#endif
+ ENCTYPE_DES_CBC_CRC,
+ ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_MD4,
+ 0
+ };
krb5_error_code code;
krb5_gss_ctx_id_rec *ctx, *ctx_free;
krb5_timestamp now;
gss_buffer_desc token;
- int gsskrb5_vers = 0;
- int i, err;
+ int i, j, err;
int default_mech = 0;
krb5_ui_4 resp_flags;
OM_uint32 major_status;
@@ -530,32 +382,19 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
err = 0;
if (mech_type == GSS_C_NULL_OID) {
default_mech = 1;
- if (cred->rfcv2_mech) {
- mech_type = gss_mech_krb5_v2;
- gsskrb5_vers = 2000;
- } else if (cred->rfc_mech) {
+ if (cred->rfc_mech) {
mech_type = gss_mech_krb5;
- gsskrb5_vers = 1000;
- enctype = ENCTYPE_DES_CBC_CRC;
} else if (cred->prerfc_mech) {
mech_type = gss_mech_krb5_old;
- gsskrb5_vers = 1000;
- enctype = ENCTYPE_DES_CBC_CRC;
} else {
err = 1;
}
- } else if (g_OID_equal(mech_type, gss_mech_krb5_v2)) {
- if (!cred->rfcv2_mech)
- err = 1;
- gsskrb5_vers = 2000;
} else if (g_OID_equal(mech_type, gss_mech_krb5)) {
if (!cred->rfc_mech)
err = 1;
- gsskrb5_vers = 1000;
} else if (g_OID_equal(mech_type, gss_mech_krb5_old)) {
if (!cred->prerfc_mech)
err = 1;
- gsskrb5_vers = 1000;
} else {
err = 1;
}
@@ -609,7 +448,6 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
ctx->seed_init = 0;
ctx->big_endian = 0; /* all initiators do little-endian, as per spec */
ctx->seqstate = 0;
- ctx->gsskrb5_version = gsskrb5_vers;
ctx->nctypes = 0;
ctx->ctypes = 0;
@@ -630,27 +468,12 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
goto fail;
if ((code = get_credentials(context, cred, ctx->there, now,
- ctx->endtime, enctype, &k_cred)))
+ ctx->endtime, wanted_enctypes, &k_cred)))
goto fail;
- /*
- * If the default mechanism was requested, and the keytype is
- * DES_CBC, force the old mechanism
- */
- if (default_mech &&
- ((k_cred->keyblock.enctype == ENCTYPE_DES_CBC_CRC) ||
- (k_cred->keyblock.enctype == ENCTYPE_DES_CBC_MD4) ||
- (k_cred->keyblock.enctype == ENCTYPE_DES_CBC_MD5))) {
- ctx->gsskrb5_version = gsskrb5_vers = 1000;
+ if (default_mech) {
mech_type = gss_mech_krb5;
- if (k_cred->keyblock.enctype != ENCTYPE_DES_CBC_CRC) {
- krb5_free_creds(context, k_cred);
- enctype = ENCTYPE_DES_CBC_CRC;
- if ((code = get_credentials(context, cred, ctx->there, now,
- ctx->endtime, enctype, &k_cred)))
- goto fail;
- }
- }
+ }
if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used)
!= GSS_S_COMPLETE) {
@@ -662,24 +485,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
*/
ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
- if (ctx->gsskrb5_version == 2000) {
- /* gsskrb5 v2 */
- if ((code = make_ap_req_v2(context, ctx,
- cred, k_cred, input_chan_bindings,
- mech_type, &token))) {
- if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) ||
- (code == KG_EMPTY_CCACHE))
- major_status = GSS_S_NO_CRED;
- if (code == KRB5KRB_AP_ERR_TKT_EXPIRED)
- major_status = GSS_S_CREDENTIALS_EXPIRED;
- goto fail;
- }
-
- krb5_auth_con_getlocalseqnumber(context, ctx->auth_context,
- &ctx->seq_send);
- krb5_auth_con_getlocalsubkey(context, ctx->auth_context,
- &ctx->subkey);
- } else {
+ {
/* gsskrb5 v1 */
if ((code = make_ap_req_v1(context, ctx,
cred, k_cred, input_chan_bindings,
@@ -701,11 +507,41 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
switch(ctx->subkey->enctype) {
case ENCTYPE_DES_CBC_MD5:
+ case ENCTYPE_DES_CBC_MD4:
case ENCTYPE_DES_CBC_CRC:
ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
- ctx->signalg = 0;
+ ctx->signalg = SGN_ALG_DES_MAC_MD5;
ctx->cksum_size = 8;
- ctx->sealalg = 0;
+ ctx->sealalg = SEAL_ALG_DES;
+
+ /* The encryption key is the session key XOR
+ 0xf0f0f0f0f0f0f0f0. */
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
+ goto fail;
+
+ for (i=0; i<ctx->enc->length; i++)
+ /*SUPPRESS 113*/
+ ctx->enc->contents[i] ^= 0xf0;
+
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq)))
+ goto fail;
+
+ break;
+
+ case ENCTYPE_DES3_CBC_SHA1:
+ ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
+ ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
+ ctx->cksum_size = 20;
+ ctx->sealalg = SEAL_ALG_DES3KD;
+
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
+ if (code)
+ goto fail;
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
+ if (code) {
+ krb5_free_keyblock (context, ctx->enc);
+ goto fail;
+ }
break;
#if 0
case ENCTYPE_DES3_CBC_MD5:
@@ -716,20 +552,10 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
break;
#endif
default:
+ *minor_status = KRB5_BAD_ENCTYPE;
return GSS_S_FAILURE;
}
- /* the encryption key is the session key XOR 0xf0f0f0f0f0f0f0f0 */
-
- if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
- goto fail;
-
- for (i=0; i<ctx->enc->length; i++)
- /*SUPPRESS 113*/
- ctx->enc->contents[i] ^= 0xf0;
-
- if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq)))
- goto fail;
}
if (k_cred) {
@@ -826,94 +652,38 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
ptr = (unsigned char *) input_token->value;
- if (ctx->gsskrb5_version == 2000) {
- int token_length;
- int nctypes;
- krb5_cksumtype *ctypes = 0;
-
- /* gsskrb5 v2 */
-
- if ((code = g_verify_token_header((gss_OID) ctx->mech_used,
- &token_length,
- &ptr, KG2_TOK_RESPONSE,
- input_token->length))) {
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
-
- if (GSS_ERROR(major_status =
- kg2_parse_token(minor_status, ptr, token_length,
- &resp_flags, &nctypes, &ctypes,
- 0, NULL, &ap_rep, &mic))) {
- if (ctypes)
- free(ctypes);
- code = *minor_status;
- goto fail;
- }
- major_status = GSS_S_FAILURE;
-
- kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes);
-
- free(ctypes);
+ if ((err = g_verify_token_header((gss_OID) ctx->mech_used,
+ &(ap_rep.length),
+ &ptr, KG_TOK_CTX_AP_REP,
+ input_token->length))) {
+ if (g_verify_token_header((gss_OID) ctx->mech_used,
+ &(ap_rep.length),
+ &ptr, KG_TOK_CTX_ERROR,
+ input_token->length) == 0) {
- if (ctx->nctypes == 0) {
- code = KG_NO_CTYPES;
- goto fail;
- }
+ /* Handle a KRB_ERROR message from the server */
- if (resp_flags & KG2_RESP_FLAG_ERROR) {
- if ((code = krb5_rd_error(context, &ap_rep, &krb_error)))
+ sptr = (char *) ptr; /* PC compiler bug */
+ TREAD_STR(sptr, ap_rep.data, ap_rep.length);
+
+ code = krb5_rd_error(context, &ap_rep, &krb_error);
+ if (code)
goto fail;
-
if (krb_error->error)
code = krb_error->error + ERROR_TABLE_BASE_krb5;
else
code = 0;
-
krb5_free_error(context, krb_error);
goto fail;
+ } else {
+ *minor_status = 0;
+ return(GSS_S_DEFECTIVE_TOKEN);
}
-
- if (resp_flags & KG2_RESP_FLAG_DELEG_OK)
- ctx->gss_flags |= GSS_C_DELEG_FLAG;
-
- /* drop through to ap_rep handling */
- } else {
- /* gsskrb5 v1 */
-
- if ((err = g_verify_token_header((gss_OID) ctx->mech_used,
- &(ap_rep.length),
- &ptr, KG_TOK_CTX_AP_REP,
- input_token->length))) {
- if (g_verify_token_header((gss_OID) ctx->mech_used,
- &(ap_rep.length),
- &ptr, KG_TOK_CTX_ERROR,
- input_token->length) == 0) {
-
- /* Handle a KRB_ERROR message from the server */
-
- sptr = (char *) ptr; /* PC compiler bug */
- TREAD_STR(sptr, ap_rep.data, ap_rep.length);
-
- code = krb5_rd_error(context, &ap_rep, &krb_error);
- if (code)
- goto fail;
- if (krb_error->error)
- code = krb_error->error + ERROR_TABLE_BASE_krb5;
- else
- code = 0;
- krb5_free_error(context, krb_error);
- goto fail;
- } else {
- *minor_status = 0;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
- }
-
- sptr = (char *) ptr; /* PC compiler bug */
- TREAD_STR(sptr, ap_rep.data, ap_rep.length);
}
+ sptr = (char *) ptr; /* PC compiler bug */
+ TREAD_STR(sptr, ap_rep.data, ap_rep.length);
+
/* decode the ap_rep */
if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep,
&ap_rep_data))) {
@@ -940,26 +710,6 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
/* set established */
ctx->established = 1;
- if (ctx->gsskrb5_version == 2000) {
- gss_buffer_desc mic_data, mic_token;
-
- /* start with the token id */
- mic_data.value = ptr-2;
- /* end before the ap-rep length */
- mic_data.length = ((char*)(ap_rep.data-2)-(char*)(ptr-2));
-
- mic_token.length = mic.length;
- mic_token.value = mic.data;
-
- if (GSS_ERROR(major_status =
- krb5_gss_verify_mic(minor_status, *context_handle,
- &mic_data, &mic_token, NULL))) {
- code = *minor_status;
- goto fail;
- }
- major_status = GSS_S_FAILURE;
- }
-
/* set returns */
if (time_rec) {
diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c
index c800012..6da0a52 100644
--- a/src/lib/gssapi/krb5/inq_cred.c
+++ b/src/lib/gssapi/krb5/inq_cred.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -121,10 +145,6 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
(cred->rfc_mech &&
GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
gss_mech_krb5,
- &mechs))) ||
- (cred->rfcv2_mech &&
- GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- gss_mech_krb5_v2,
&mechs)))) {
krb5_free_principal(context, ret_name);
/* *minor_status set above */
diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c
index ae8cc75..1ca108e 100644
--- a/src/lib/gssapi/krb5/k5seal.c
+++ b/src/lib/gssapi/krb5/k5seal.c
@@ -1,6 +1,6 @@
/*
* Copyright 1993 by OpenVision Technologies, Inc.
- *
+ *
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appears in all copies and
@@ -10,7 +10,7 @@
* without specific, written prior permission. OpenVision makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
- *
+ *
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -22,14 +22,14 @@
/*
* Copyright (C) 1998 by the FundsXpress, INC.
- *
+ *
* All rights reserved.
- *
+ *
* Export of this software from the United States of America may require
* a specific license from the United States Government. It is the
* responsibility of any person or organization contemplating export to
* obtain such a license before exporting.
- *
+ *
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
@@ -40,7 +40,7 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
@@ -49,196 +49,280 @@
#include "gssapiP_krb5.h"
static krb5_error_code
-make_priv_token_v2 PROTOTYPE((krb5_context context,
- krb5_keyblock *subkey,
+make_seal_token_v1 PROTOTYPE((krb5_context context,
+ krb5_keyblock *enc,
+ krb5_keyblock *seq,
krb5_int32 *seqnum,
int direction,
gss_buffer_t text,
gss_buffer_t token,
+ int signalg,
+ int cksum_size,
+ int sealalg,
+ int encrypt,
+ int toktype,
+ int bigend,
gss_OID oid));
static krb5_error_code
-make_priv_token_v2(context, subkey, seqnum, direction, text, token, oid)
- krb5_context context;
- krb5_keyblock *subkey;
- krb5_int32 *seqnum;
- int direction;
- gss_buffer_t text;
- gss_buffer_t token;
- gss_OID oid;
-{
- krb5_data plain;
- krb5_enc_data cipher;
- krb5_error_code code;
- size_t enclen;
- int tlen;
- unsigned char *t, *ptr;
-
- plain.data = 0;
- cipher.ciphertext.data = 0;
- t = 0;
-
- plain.length = 7+text->length;
- if ((plain.data = (void *) malloc(plain.length)) == NULL) {
- code = ENOMEM;
- goto cleanup;
- }
-
- plain.data[0] = (*seqnum >> 24) & 0xff;
- plain.data[1] = (*seqnum >> 16) & 0xff;
- plain.data[2] = (*seqnum >> 8) & 0xff;
- plain.data[3] = *seqnum & 0xff;
-
- plain.data[4] = direction?0:0xff;
-
- plain.data[5] = (text->length >> 8) & 0xff;
- plain.data[6] = text->length & 0xff;
-
- memcpy(plain.data+7, text->value, text->length);
-
- if (code = krb5_c_encrypt_length(context, subkey->enctype,
- plain.length, &enclen))
- goto cleanup;
-
- tlen = g_token_size((gss_OID) oid, 2+enclen);
-
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
- return(ENOMEM);
-
- ptr = t;
-
- g_make_token_header((gss_OID) oid, 2+enclen, &ptr,
- KG2_TOK_WRAP_PRIV);
-
- ptr[0] = (enclen >> 8) & 0xff;
- ptr[1] = enclen & 0xff;
-
- cipher.ciphertext.length = enclen;
- cipher.ciphertext.data = ptr+2;
-
- if (code = krb5_c_encrypt(context, subkey,
- KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV,
- 0, &plain, &cipher))
- goto cleanup;
-
- /* that's it. return the token */
-
- (*seqnum)++;
-
- token->length = tlen;
- token->value = (void *) t;
-
- code = 0;
-
-cleanup:
- if (plain.data)
- free(plain.data);
- if (code) {
- if (t)
- free(t);
- }
-
- return(code);
-}
-
-static krb5_error_code
-make_integ_token_v2 PROTOTYPE((krb5_context context,
- krb5_keyblock *subkey,
- krb5_cksumtype ctype,
- krb5_int32 *seqnum,
- int direction,
- gss_buffer_t text,
- gss_buffer_t token,
- int toktype,
- gss_OID oid));
-
-static krb5_error_code
-make_integ_token_v2(context, subkey, ctype, seqnum, direction, text, token,
- toktype, oid)
- krb5_context context;
- krb5_keyblock *subkey;
- krb5_cksumtype ctype;
- krb5_int32 *seqnum;
- int direction;
- gss_buffer_t text;
- gss_buffer_t token;
- int toktype;
- gss_OID oid;
+make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
+ signalg, cksum_size, sealalg, encrypt, toktype,
+ bigend, oid)
+ krb5_context context;
+ krb5_keyblock *enc;
+ krb5_keyblock *seq;
+ krb5_int32 *seqnum;
+ int direction;
+ gss_buffer_t text;
+ gss_buffer_t token;
+ int signalg;
+ int cksum_size;
+ int sealalg;
+ int encrypt;
+ int toktype;
+ int bigend;
+ gss_OID oid;
{
krb5_error_code code;
- int tmp, tlen;
- unsigned char *t, *ptr;
- krb5_data plain;
+ size_t sumlen;
+ char *data_ptr;
+ krb5_data plaind;
+ krb5_checksum md5cksum;
krb5_checksum cksum;
+ int conflen=0, tmsglen, tlen;
+ unsigned char *t, *ptr;
- plain.data = 0;
- t = 0;
- cksum.contents = 0;
+ int encblksize, sumblksize;
+
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ case SGN_ALG_HMAC_MD5:
+ sumblksize = 1;
+ break;
+ case SGN_ALG_DES_MAC:
+ sumblksize = 8;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ sumblksize = 1;
+ break;
+ default:
+ abort ();
+ return 123; /* find error code */
+ }
- /* assemble the checksum buffer and compute the checksum */
+ switch (sealalg) {
+ case SEAL_ALG_NONE:
+ case SEAL_ALG_DES:
+ case SEAL_ALG_DES3KD:
+ encblksize = 8;
+ break;
+ default:
+ abort ();
+ return 12345654321;
+ }
- plain.length = 7+text->length;
+ /* create the token buffer */
- if ((plain.data = (char *) malloc(plain.length)) == NULL) {
- code = errno;
- goto cleanup;
+ if (toktype == KG_TOK_SEAL_MSG) {
+ if (bigend && !encrypt) {
+ tmsglen = text->length;
+ } else {
+ conflen = kg_confounder_size(context, enc);
+ /* XXX knows that des block size is 8 */
+ tmsglen = (conflen+text->length+8)&(~7);
+ }
+ } else {
+ tmsglen = 0;
}
- plain.data[0] = (*seqnum >> 24) & 0xff;
- plain.data[1] = (*seqnum >> 16) & 0xff;
- plain.data[2] = (*seqnum >> 8) & 0xff;
- plain.data[3] = *seqnum & 0xff;
+ tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen);
- plain.data[4] = direction?0:0xff;
+ if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
+ return(ENOMEM);
- plain.data[5] = (text->length >> 8) & 0xff;
- plain.data[6] = text->length & 0xff;
+ /*** fill in the token */
- memcpy(plain.data+7, text->value, text->length);
+ ptr = t;
- if (code = krb5_c_make_checksum(context, ctype, subkey,
- (toktype == KG2_TOK_WRAP_INTEG)?
- KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG:
- KRB5_KEYUSAGE_GSS_TOK_MIC,
- &plain, &cksum))
- goto cleanup;
+ g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype);
- /* assemble the token itself */
+ /* 0..1 SIGN_ALG */
- if (toktype == KG2_TOK_WRAP_INTEG)
- tmp = 4+(7+text->length)+2+cksum.length;
- else
- tmp = 4+(5)+2+cksum.length;
+ ptr[0] = signalg & 0xff;
+ ptr[1] = (signalg >> 8) & 0xff;
- tlen = g_token_size((gss_OID) oid, tmp);
+ /* 2..3 SEAL_ALG or Filler */
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
- return(ENOMEM);
+ if ((toktype == KG_TOK_SEAL_MSG) && encrypt) {
+ ptr[2] = sealalg & 0xff;
+ ptr[3] = (sealalg >> 8) & 0xff;
+ } else {
+ /* No seal */
+ ptr[2] = 0xff;
+ ptr[3] = 0xff;
+ }
- ptr = t;
+ /* 4..5 Filler */
+
+ ptr[4] = 0xff;
+ ptr[5] = 0xff;
+
+ /* pad the plaintext, encrypt if needed, and stick it in the token */
+
+ /* initialize the the cksum */
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ case SGN_ALG_HMAC_MD5:
+ md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3;
+ break;
+ default:
+ case SGN_ALG_DES_MAC:
+ abort ();
+ }
- g_make_token_header((gss_OID) oid, tmp, &ptr, toktype);
+ if (code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen))
+ return(code);
+ md5cksum.length = sumlen;
+
+ if (toktype == KG_TOK_SEAL_MSG) {
+ unsigned char *plain;
+ unsigned char pad;
+
+ if (!bigend || encrypt) {
+ if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
+ xfree(t);
+ return(ENOMEM);
+ }
+
+ if ((code = kg_make_confounder(context, enc, plain))) {
+ xfree(plain);
+ xfree(t);
+ return(code);
+ }
+
+ memcpy(plain+conflen, text->value, text->length);
+
+ /* XXX 8 is DES cblock size */
+ pad = 8-(text->length%8);
+
+ memset(plain+conflen+text->length, pad, pad);
+ } else {
+ /* plain is never used in the bigend && !encrypt case */
+ plain = NULL;
+ }
+
+ if (encrypt) {
+ if ((code = kg_encrypt(context, enc, KG_USAGE_SEAL, NULL,
+ (krb5_pointer) plain,
+ (krb5_pointer) (ptr+cksum_size+14),
+ tmsglen))) {
+ if (plain)
+ xfree(plain);
+ xfree(t);
+ return(code);
+ }
+ } else {
+ if (bigend)
+ memcpy(ptr+14+cksum_size, text->value, text->length);
+ else
+ memcpy(ptr+14+cksum_size, plain, tmsglen);
+ }
+
+ /* compute the checksum */
+
+ /* 8 = head of token body as specified by mech spec */
+ if (! (data_ptr =
+ (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) {
+ if (plain)
+ xfree(plain);
+ xfree(t);
+ return(ENOMEM);
+ }
+ (void) memcpy(data_ptr, ptr-2, 8);
+ if (bigend)
+ (void) memcpy(data_ptr+8, text->value, text->length);
+ else
+ (void) memcpy(data_ptr+8, plain, tmsglen);
+ plaind.length = 8 + (bigend ? text->length : tmsglen);
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq,
+ KG_USAGE_SIGN, &plaind, &md5cksum);
+ xfree(data_ptr);
+
+ if (code) {
+ if (plain)
+ xfree(plain);
+ xfree(t);
+ return(code);
+ }
- ptr[0] = (ctype >> 24) & 0xff;
- ptr[1] = (ctype >> 16) & 0xff;
- ptr[2] = (ctype >> 8) & 0xff;
- ptr[3] = ctype & 0xff;
+ if (plain)
+ xfree(plain);
+ } else {
+ /* Sign only. */
+ /* compute the checksum */
- ptr += 4;
+ if (! (data_ptr = (char *) xmalloc(8 + text->length))) {
+ xfree(t);
+ return(ENOMEM);
+ }
+ (void) memcpy(data_ptr, ptr-2, 8);
+ (void) memcpy(data_ptr+8, text->value, text->length);
+ plaind.length = 8 + text->length;
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq,
+ KG_USAGE_SIGN, &plaind, &md5cksum);
+ xfree(data_ptr);
+ if (code) {
+ xfree(t);
+ return(code);
+ }
+ }
- if (toktype == KG2_TOK_WRAP_INTEG) {
- memcpy(ptr, plain.data, 7+text->length);
- ptr += 7+text->length;
- } else {
- memcpy(ptr, plain.data, 5);
- ptr += 5;
+ switch(signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case 3:
+
+ if ((code = kg_encrypt(context, seq, KG_USAGE_SEAL,
+ (g_OID_equal(oid, gss_mech_krb5_old) ?
+ seq->contents : NULL),
+ md5cksum.contents, md5cksum.contents, 16))) {
+ xfree(md5cksum.contents);
+ xfree(t);
+ return code;
+ }
+
+ cksum.length = cksum_size;
+ cksum.contents = md5cksum.contents + 16 - cksum.length;
+
+ memcpy(ptr+14, cksum.contents, cksum.length);
+ break;
+
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ /*
+ * Using key derivation, the call to krb5_c_make_checksum
+ * already dealt with encrypting.
+ */
+ if (md5cksum.length != cksum_size)
+ abort ();
+ memcpy (ptr+14, md5cksum.contents, md5cksum.length);
+ break;
}
- ptr[0] = (cksum.length >> 8) & 0xff;
- ptr[1] = cksum.length & 0xff;
- ptr += 2;
+ xfree(md5cksum.contents);
+
+ /* create the seq_num */
- memcpy(ptr, cksum.contents, cksum.length);
+ if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum,
+ ptr+14, ptr+6))) {
+ xfree(t);
+ return(code);
+ }
/* that's it. return the token */
@@ -247,372 +331,110 @@ make_integ_token_v2(context, subkey, ctype, seqnum, direction, text, token,
token->length = tlen;
token->value = (void *) t;
- code = 0;
-
-cleanup:
- if (plain.data)
- free(plain.data);
- if (cksum.contents)
- krb5_free_checksum_contents(context, &cksum);
- if (code) {
- if (t)
- free(t);
- }
-
- return(code);
+ return(0);
}
-static krb5_error_code
-make_seal_token_v1 PROTOTYPE((krb5_context context,
- krb5_keyblock *enc,
- krb5_keyblock *seq,
- krb5_int32 *seqnum,
- int direction,
- gss_buffer_t text,
- gss_buffer_t token,
- int signalg,
- int cksum_size,
- int sealalg,
- int encrypt,
- int toktype,
- int bigend,
- gss_OID oid));
+/* if signonly is true, ignore conf_req, conf_state,
+ and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */
-static krb5_error_code
-make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
- signalg, cksum_size, sealalg, encrypt, toktype,
- bigend, oid)
- krb5_context context;
- krb5_keyblock *enc;
- krb5_keyblock *seq;
- krb5_int32 *seqnum;
- int direction;
- gss_buffer_t text;
- gss_buffer_t token;
- int signalg;
- int cksum_size;
- int sealalg;
- int encrypt;
- int toktype;
- int bigend;
- gss_OID oid;
+OM_uint32
+kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req,
+ input_message_buffer, conf_state, output_message_buffer, toktype)
+ krb5_context context;
+ OM_uint32 *minor_status;
+ gss_ctx_id_t context_handle;
+ int conf_req_flag;
+ int qop_req;
+ gss_buffer_t input_message_buffer;
+ int *conf_state;
+ gss_buffer_t output_message_buffer;
+ int toktype;
{
- krb5_error_code code;
- size_t sumlen;
- char *data_ptr;
- krb5_data plaind;
- krb5_checksum md5cksum;
- krb5_checksum cksum;
- int conflen=0, tmsglen, tlen;
- unsigned char *t, *ptr;
-
- /* create the token buffer */
-
- if (toktype == KG_TOK_SEAL_MSG) {
- if (bigend && !encrypt) {
- tmsglen = text->length;
- } else {
- conflen = kg_confounder_size(context, enc);
- /* XXX knows that des block size is 8 */
- tmsglen = (conflen+text->length+8)&(~7);
- }
- } else {
- tmsglen = 0;
- }
-
- tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen);
-
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
- return(ENOMEM);
-
- /*** fill in the token */
-
- ptr = t;
-
- g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype);
-
- /* 0..1 SIGN_ALG */
-
- ptr[0] = signalg;
- ptr[1] = 0;
-
- /* 2..3 SEAL_ALG or Filler */
-
- if ((toktype == KG_TOK_SEAL_MSG) && encrypt) {
- ptr[2] = sealalg;
- ptr[3] = 0;
- } else {
- /* No seal */
- ptr[2] = 0xff;
- ptr[3] = 0xff;
- }
-
- /* 4..5 Filler */
-
- ptr[4] = 0xff;
- ptr[5] = 0xff;
-
- /* pad the plaintext, encrypt if needed, and stick it in the token */
-
- /* initialize the the cksum */
- if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen))
- return(code);
-
- md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
- md5cksum.length = sumlen;
- if (toktype == KG_TOK_SEAL_MSG) {
- unsigned char *plain;
- unsigned char pad;
-
- if (!bigend || encrypt) {
- if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
- xfree(t);
- return(ENOMEM);
- }
-
- if ((code = kg_make_confounder(context, enc, plain))) {
- xfree(plain);
- xfree(t);
- return(code);
- }
-
- memcpy(plain+conflen, text->value, text->length);
-
- /* XXX 8 is DES cblock size */
- pad = 8-(text->length%8);
-
- memset(plain+conflen+text->length, pad, pad);
- } else {
- /* plain is never used in the bigend && !encrypt case */
- plain = NULL;
- }
+ krb5_gss_ctx_id_rec *ctx;
+ krb5_error_code code;
+ krb5_timestamp now;
- if (encrypt) {
- if ((code = kg_encrypt(context, enc, NULL, (krb5_pointer) plain,
- (krb5_pointer) (ptr+cksum_size+14),
- tmsglen))) {
- if (plain)
- xfree(plain);
- xfree(t);
- return(code);
- }
- } else {
- if (bigend)
- memcpy(ptr+14+cksum_size, text->value, text->length);
- else
- memcpy(ptr+14+cksum_size, plain, tmsglen);
- }
-
- /* compute the checksum */
-
- /* 8 = head of token body as specified by mech spec */
- if (! (data_ptr =
- (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) {
- if (plain)
- xfree(plain);
- xfree(t);
- return(ENOMEM);
- }
- (void) memcpy(data_ptr, ptr-2, 8);
- if (bigend)
- (void) memcpy(data_ptr+8, text->value, text->length);
- else
- (void) memcpy(data_ptr+8, plain, tmsglen);
- plaind.length = 8 + (bigend ? text->length : tmsglen);
- plaind.data = data_ptr;
- code = krb5_c_make_checksum(context, md5cksum.checksum_type,
- 0, 0, &plaind, &md5cksum);
- xfree(data_ptr);
-
- if (code) {
- if (plain)
- xfree(plain);
- xfree(t);
- return(code);
- memcpy(ptr+14+cksum_size, plain, tmsglen);
- }
-
- if (plain)
- xfree(plain);
- } else {
- /* compute the checksum */
-
- if (! (data_ptr = (char *) xmalloc(8 + text->length))) {
- xfree(t);
- return(ENOMEM);
- }
- (void) memcpy(data_ptr, ptr-2, 8);
- (void) memcpy(data_ptr+8, text->value, text->length);
- plaind.length = 8 + text->length;
- plaind.data = data_ptr;
- code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0,
- &plaind, &md5cksum);
- xfree(data_ptr);
- if (code) {
- xfree(t);
- return(code);
- }
- }
-
- switch(signalg) {
- case 0:
- case 3:
+ output_message_buffer->length = 0;
+ output_message_buffer->value = NULL;
+ /* only default qop or matching established cryptosystem is allowed */
+
#if 0
- /* XXX this depends on the key being a single-des key */
-
- /* DES CBC doesn't use a zero IV like it should in some
- krb5 implementations (beta5+). So we just do the
- DES encryption the long way, and keep the last block
- as the MAC */
-
- /* XXX not converted to new api since it's inside an #if 0 */
-
- /* initialize the the cksum and allocate the contents buffer */
- cksum.checksum_type = CKSUMTYPE_DESCBC;
- cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC);
- if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL)
- return(ENOMEM);
-
- /* XXX not converted to new api since it's inside an #if 0 */
- if (code = krb5_calculate_checksum(context, cksum.checksum_type,
- md5cksum.contents, 16,
- seq->contents,
- seq->length,
- &cksum)) {
- xfree(cksum.contents);
- xfree(md5cksum.contents);
- xfree(t);
- return(code);
- }
-
- memcpy(ptr+14, cksum.contents, 8);
-
- xfree(cksum.contents);
+ switch (qop_req & GSS_KRB5_CONF_C_QOP_MASK) {
+ case GSS_C_QOP_DEFAULT:
+ break;
+ default:
+ unknown_qop:
+ *minor_status = (OM_uint32) G_UNKNOWN_QOP;
+ return GSS_S_FAILURE;
+ case GSS_KRB5_CONF_C_QOP_DES:
+ if (ctx->sealalg != SEAL_ALG_DES) {
+ bad_qop:
+ *minor_status = (OM_uint32) G_BAD_QOP;
+ return GSS_S_FAILURE;
+ }
+ break;
+ case GSS_KRB5_CONF_C_QOP_DES3:
+ if (ctx->sealalg != SEAL_ALG_DES3)
+ goto bad_qop;
+ break;
+ }
+ switch (qop_req & GSS_KRB5_INTEG_C_QOP_MASK) {
+ case GSS_C_QOP_DEFAULT:
+ break;
+ default:
+ goto unknown_qop;
+ case GSS_KRB5_INTEG_C_QOP_MD5:
+ case GSS_KRB5_INTEG_C_QOP_DES_MD5:
+ case GSS_KRB5_INTEG_C_QOP_DES_MAC:
+ if (ctx->sealalg != SEAL_ALG_DES)
+ goto bad_qop;
+ break;
+ case GSS_KRB5_INTEG_C_QOP_HMAC_SHA1:
+ if (ctx->sealalg != SEAL_ALG_DES3KD)
+ goto bad_qop;
+ break;
+ }
#else
- if ((code = kg_encrypt(context, seq,
- (g_OID_equal(oid, gss_mech_krb5_old) ?
- seq->contents : NULL),
- md5cksum.contents, md5cksum.contents, 16))) {
- xfree(md5cksum.contents);
- xfree(t);
- return code;
- }
-
- cksum.length = cksum_size;
- cksum.contents = md5cksum.contents + 16 - cksum.length;
-
- memcpy(ptr+14, cksum.contents, cksum.length);
+ if (qop_req != 0) {
+ *minor_status = (OM_uint32) G_UNKNOWN_QOP;
+ return GSS_S_FAILURE;
+ }
#endif
- break;
- }
-
- xfree(md5cksum.contents);
-
- /* create the seq_num */
+ /* validate the context handle */
+ if (! kg_validate_ctx_id(context_handle)) {
+ *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+ return(GSS_S_NO_CONTEXT);
+ }
- if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum,
- ptr+14, ptr+6))) {
- xfree(t);
- return(code);
- }
+ ctx = (krb5_gss_ctx_id_rec *) context_handle;
- /* that's it. return the token */
+ if (! ctx->established) {
+ *minor_status = KG_CTX_INCOMPLETE;
+ return(GSS_S_NO_CONTEXT);
+ }
- (*seqnum)++;
+ if ((code = krb5_timeofday(context, &now))) {
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- token->length = tlen;
- token->value = (void *) t;
+ code = make_seal_token_v1(context, ctx->enc, ctx->seq,
+ &ctx->seq_send, ctx->initiate,
+ input_message_buffer, output_message_buffer,
+ ctx->signalg, ctx->cksum_size, ctx->sealalg,
+ conf_req_flag, toktype, ctx->big_endian,
+ ctx->mech_used);
- return(0);
-}
+ if (code) {
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
-/* if signonly is true, ignore conf_req, conf_state,
- and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */
+ if (conf_state)
+ *conf_state = conf_req_flag;
-OM_uint32
-kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req,
- input_message_buffer, conf_state, output_message_buffer, toktype)
- krb5_context context;
- OM_uint32 *minor_status;
- gss_ctx_id_t context_handle;
- int conf_req_flag;
- int qop_req;
- gss_buffer_t input_message_buffer;
- int *conf_state;
- gss_buffer_t output_message_buffer;
- int toktype;
-{
- krb5_gss_ctx_id_rec *ctx;
- krb5_error_code code;
- krb5_timestamp now;
-
- output_message_buffer->length = 0;
- output_message_buffer->value = NULL;
-
- /* only default qop is allowed */
- if (qop_req != GSS_C_QOP_DEFAULT) {
- *minor_status = (OM_uint32) G_UNKNOWN_QOP;
- return(GSS_S_FAILURE);
- }
-
- /* validate the context handle */
- if (! kg_validate_ctx_id(context_handle)) {
- *minor_status = (OM_uint32) G_VALIDATE_FAILED;
- return(GSS_S_NO_CONTEXT);
- }
-
- ctx = (krb5_gss_ctx_id_rec *) context_handle;
-
- if (! ctx->established) {
- *minor_status = KG_CTX_INCOMPLETE;
- return(GSS_S_NO_CONTEXT);
- }
-
- if ((code = krb5_timeofday(context, &now))) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (ctx->gsskrb5_version == 2000) {
- if (toktype == KG_TOK_WRAP_MSG) {
- if (conf_req_flag)
- toktype = KG2_TOK_WRAP_PRIV;
- else
- toktype = KG2_TOK_WRAP_INTEG;
- } else {
- toktype = KG2_TOK_MIC;
- }
-
- if (conf_req_flag) {
- code = make_priv_token_v2(context, ctx->subkey, &ctx->seq_send,
- ctx->initiate, input_message_buffer,
- output_message_buffer, ctx->mech_used);
- } else {
- code = make_integ_token_v2(context, ctx->subkey, ctx->ctypes[0],
- &ctx->seq_send, ctx->initiate,
- input_message_buffer,
- output_message_buffer, toktype,
- ctx->mech_used);
- }
- } else {
- code = make_seal_token_v1(context, ctx->enc, ctx->seq,
- &ctx->seq_send, ctx->initiate,
- input_message_buffer, output_message_buffer,
- ctx->signalg, ctx->cksum_size, ctx->sealalg,
- conf_req_flag, toktype, ctx->big_endian,
- ctx->mech_used);
- }
-
- if (code) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (conf_state)
- *conf_state = conf_req_flag;
-
- *minor_status = 0;
- return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
+ *minor_status = 0;
+ return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
}
diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
index da5966f..bc35e70 100644
--- a/src/lib/gssapi/krb5/k5unseal.c
+++ b/src/lib/gssapi/krb5/k5unseal.c
@@ -1,6 +1,6 @@
/*
* Copyright 1993 by OpenVision Technologies, Inc.
- *
+ *
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appears in all copies and
@@ -10,7 +10,7 @@
* without specific, written prior permission. OpenVision makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
- *
+ *
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -22,14 +22,14 @@
/*
* Copyright (C) 1998 by the FundsXpress, INC.
- *
+ *
* All rights reserved.
- *
+ *
* Export of this software from the United States of America may require
* a specific license from the United States Government. It is the
* responsibility of any person or organization contemplating export to
* obtain such a license before exporting.
- *
+ *
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
@@ -40,7 +40,7 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
@@ -51,838 +51,438 @@
#include <memory.h>
#endif
-/*
- * $Id$
- */
+/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
+ conf_state is only valid if SEAL. */
-static OM_uint32
-kg2_verify_mic(context, minor_status, ctx, ptr, bodysize,
- text, qop_state)
- krb5_context context;
- OM_uint32 *minor_status;
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- gss_buffer_t text;
- gss_qop_t *qop_state;
+OM_uint32
+kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
+ conf_state, qop_state, toktype)
+ krb5_context context;
+ OM_uint32 *minor_status;
+ krb5_gss_ctx_id_rec *ctx;
+ unsigned char *ptr;
+ int bodysize;
+ gss_buffer_t message_buffer;
+ int *conf_state;
+ int *qop_state;
+ int toktype;
{
- size_t cksumlen;
krb5_error_code code;
- krb5_data plain;
- krb5_cksumtype tctype;
- krb5_ui_4 tseqnum;
- int tdirection;
+ int tmsglen;
+ int conflen = 0;
+ int signalg;
+ int sealalg;
+ gss_buffer_desc token;
krb5_checksum cksum;
- krb5_boolean ckvalid;
+ krb5_checksum md5cksum;
+ krb5_data plaind;
+ char *data_ptr;
krb5_timestamp now;
+ unsigned char *plain;
+ int cksum_len = 0;
+ int plainlen;
+ int direction;
+ krb5_int32 seqnum;
OM_uint32 retval;
+ size_t sumlen;
- plain.data = 0;
- cksum.contents = 0;
-
- /* verify the header */
-
- if (bodysize < 11) {
- free(plain.data);
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
+ if (toktype == KG_TOK_SEAL_MSG) {
+ message_buffer->length = 0;
+ message_buffer->value = NULL;
}
- /* allocate the checksum buffer */
-
- plain.length = 7+text->length;
+ /* get the sign and seal algorithms */
- if ((plain.data = (char *) malloc(plain.length)) == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
+ signalg = ptr[0] + (ptr[1]<<8);
+ sealalg = ptr[2] + (ptr[3]<<8);
- /* suck out the body parts from the token */
+ /* Sanity checks */
- tctype = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) |
- (ptr[2]<<8) | ptr[3]);
- ptr += 4;
-
- memcpy(plain.data, ptr, 5);
- tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
- ptr += 4;
- tdirection = ptr[0];
- ptr += 1;
-
- cksum.length = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 11;
-
- if (cksum.length != bodysize) {
- free(plain.data);
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
+ if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
}
- cksum.contents = ptr;
- cksum.checksum_type = tctype;
+ if ((toktype != KG_TOK_SEAL_MSG) &&
+ (sealalg != 0xffff)) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
- /* finish assembling the checksum buffer and compute the checksum */
+ /* in the current spec, there is only one valid seal algorithm per
+ key type, so a simple comparison is ok */
- plain.data[5] = (text->length >> 8) & 0xff;
- plain.data[6] = text->length & 0xff;
+ if ((toktype == KG_TOK_SEAL_MSG) &&
+ !((sealalg == 0xffff) ||
+ (sealalg == ctx->sealalg))) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
- memcpy(plain.data+7, text->value, text->length);
+ /* there are several mappings of seal algorithms to sign algorithms,
+ but few enough that we can try them all. */
- if (code = krb5_c_verify_checksum(context, ctx->subkey,
- KRB5_KEYUSAGE_GSS_TOK_MIC,
- &plain, &cksum, &ckvalid)) {
- free(plain.data);
- *minor_status = code;
- return(GSS_S_FAILURE);
+ if ((ctx->sealalg == SEAL_ALG_NONE && signalg > 1) ||
+ (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) ||
+ (ctx->sealalg == SEAL_ALG_DES3KD &&
+ signalg != SGN_ALG_HMAC_SHA1_DES3_KD)) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
}
- if (!ckvalid) {
- free(plain.data);
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ cksum_len = 8;
+ break;
+ case SGN_ALG_3:
+ cksum_len = 16;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ cksum_len = 20;
+ break;
+ default:
*minor_status = 0;
- return(GSS_S_BAD_SIG);
+ return GSS_S_DEFECTIVE_TOKEN;
}
- /* check context expiry */
+ if (toktype == KG_TOK_SEAL_MSG)
+ tmsglen = bodysize-(14+cksum_len);
- if ((code = krb5_timeofday(context, &now))) {
- free(plain.data);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
+ /* get the token parameters */
- if (now > ctx->endtime) {
- free(plain.data);
- *minor_status = 0;
- return(GSS_S_CONTEXT_EXPIRED);
- }
+ /* decode the message, if SEAL */
- /* do sequencing checks */
+ if (toktype == KG_TOK_SEAL_MSG) {
+ if (sealalg != 0xffff) {
+ if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
- if ((ctx->initiate && tdirection != 0xff) ||
- (!ctx->initiate && tdirection != 0)) {
- free(plain.data);
- *minor_status = G_BAD_DIRECTION;
- return(GSS_S_BAD_SIG);
- }
+ if ((code = kg_decrypt(context, ctx->enc, KG_USAGE_SEAL, NULL,
+ ptr+14+cksum_len, plain, tmsglen))) {
+ xfree(plain);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
+ } else {
+ plain = ptr+14+cksum_len;
+ }
- retval = g_order_check(&(ctx->seqstate), tseqnum);
+ plainlen = tmsglen;
- free(plain.data);
+ if ((sealalg == 0xffff) && ctx->big_endian) {
+ token.length = tmsglen;
+ } else {
+ conflen = kg_confounder_size(context, ctx->enc);
+ token.length = tmsglen - conflen - plain[tmsglen-1];
+ }
- if (retval) {
- *minor_status = 0;
- return(retval);
- }
+ if (token.length) {
+ if ((token.value = (void *) xmalloc(token.length)) == NULL) {
+ if (sealalg != 0xffff)
+ xfree(plain);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
+ memcpy(token.value, plain+conflen, token.length);
+ }
+ } else if (toktype == KG_TOK_SIGN_MSG) {
+ token = *message_buffer;
+ plain = token.value;
+ plainlen = token.length;
+ } else {
+ token.length = 0;
+ token.value = NULL;
+ plain = token.value;
+ plainlen = token.length;
+ }
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
+ /* compute the checksum of the message */
+
+ /* initialize the the cksum */
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ case SGN_ALG_HMAC_MD5:
+ case SGN_ALG_DES_MAC:
+ case SGN_ALG_3:
+ md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3;
+ break;
+ default:
+ abort ();
+ }
- *minor_status = 0;
- return(GSS_S_COMPLETE);
-}
+ if (code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen))
+ return(code);
+ md5cksum.length = sumlen;
-static OM_uint32
-kg2_unwrap_integ(context, minor_status, ctx, ptr, bodysize, output, qop_state)
- krb5_context context;
- OM_uint32 *minor_status;
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- gss_buffer_t output;
- gss_qop_t *qop_state;
-{
- krb5_error_code code;
- OM_uint32 retval;
- krb5_ui_4 tseqnum;
- int tdirection;
- int tmsglen;
- unsigned char *tmsg;
- krb5_data plain;
- krb5_checksum tcksum;
- krb5_boolean ckvalid;
- krb5_timestamp now;
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_3:
+ /* compute the checksum of the message */
- output->length = 0;
- output->value = NULL;
+ /* 8 = bytes of token body to be checksummed according to spec */
- /* read the body parts out of the message */
+ if (! (data_ptr = (void *)
+ xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) {
+ if (sealalg != 0xffff)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
- if (bodysize < 11) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ (void) memcpy(data_ptr, ptr-2, 8);
+
+ if (ctx->big_endian)
+ (void) memcpy(data_ptr+8, token.value, token.length);
+ else
+ (void) memcpy(data_ptr+8, plain, plainlen);
- tcksum.checksum_type = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) |
- (ptr[2]<<8) | ptr[3]);
- ptr += 4;
+ plaind.length = 8 + (ctx->big_endian ? token.length : plainlen);
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+ ctx->seq, KG_USAGE_SIGN,
+ &plaind, &md5cksum);
+ xfree(data_ptr);
- plain.data = ptr;
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
- ptr += 4;
- tdirection = ptr[0];
- ptr += 1;
+ if ((code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL,
+ (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
+ ctx->seq->contents : NULL),
+ md5cksum.contents, md5cksum.contents, 16))) {
+ xfree(md5cksum.contents);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return GSS_S_FAILURE;
+ }
- tmsglen = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 11;
+ if (signalg == 0)
+ cksum.length = 8;
+ else
+ cksum.length = 16;
+ cksum.contents = md5cksum.contents + 16 - cksum.length;
- if (bodysize < tmsglen) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ code = memcmp(cksum.contents, ptr+14, cksum.length);
+ break;
- tmsg = ptr;
- ptr += tmsglen;
- bodysize -= tmsglen;
+ case SGN_ALG_MD2_5:
+ if (!ctx->seed_init &&
+ (code = kg_make_seed(context, ctx->subkey, ctx->seed))) {
+ xfree(md5cksum.contents);
+ if (sealalg != 0xffff)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return GSS_S_FAILURE;
+ }
- plain.length = ((char*)ptr) - ((char *)plain.data);
+ if (! (data_ptr = (void *)
+ xmalloc(sizeof(ctx->seed) + 8 +
+ (ctx->big_endian ? token.length : plainlen)))) {
+ xfree(md5cksum.contents);
+ if (sealalg == 0)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
+ (void) memcpy(data_ptr, ptr-2, 8);
+ (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed));
+ if (ctx->big_endian)
+ (void) memcpy(data_ptr+8+sizeof(ctx->seed),
+ token.value, token.length);
+ else
+ (void) memcpy(data_ptr+8+sizeof(ctx->seed),
+ plain, plainlen);
+ plaind.length = 8 + sizeof(ctx->seed) +
+ (ctx->big_endian ? token.length : plainlen);
+ plaind.data = data_ptr;
+ xfree(md5cksum.contents);
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+ ctx->seq, KG_USAGE_SIGN,
+ &plaind, &md5cksum);
+ xfree(data_ptr);
+
+ if (code) {
+ if (sealalg == 0)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- tcksum.length = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 2;
+ code = memcmp(md5cksum.contents, ptr+14, 8);
+ /* Falls through to defective-token?? */
- if (bodysize != tcksum.length) {
- *minor_status = G_TOK_TRUNC;
+ default:
+ *minor_status = 0;
return(GSS_S_DEFECTIVE_TOKEN);
- }
- tcksum.contents = ptr;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ /* compute the checksum of the message */
- /* verify the MIC */
+ /* 8 = bytes of token body to be checksummed according to spec */
- if (code = krb5_c_verify_checksum(context, ctx->subkey,
- KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG,
- &plain, &tcksum, &ckvalid)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (!ckvalid) {
- *minor_status = 0;
- return(GSS_S_BAD_SIG);
- }
+ if (! (data_ptr = (void *)
+ xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) {
+ if (sealalg != 0xffff)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
- /* check context expiry */
-
- if ((code = krb5_timeofday(context, &now))) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (now > ctx->endtime) {
- *minor_status = 0;
- return(GSS_S_CONTEXT_EXPIRED);
- }
-
- /* do sequencing checks */
-
- if ((ctx->initiate && tdirection != 0xff) ||
- (!ctx->initiate && tdirection != 0)) {
- *minor_status = G_BAD_DIRECTION;
- return(GSS_S_BAD_SIG);
- }
-
- if (retval = g_order_check(&(ctx->seqstate), tseqnum)) {
- *minor_status = 0;
- return(retval);
- }
-
- if (tmsglen) {
- if ((output->value = (void *) malloc(tmsglen)) == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- memcpy(output->value, tmsg, tmsglen);
- output->length = tmsglen;
- }
-
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
-
- *minor_status = 0;
- return(GSS_S_COMPLETE);
-}
+ (void) memcpy(data_ptr, ptr-2, 8);
-static OM_uint32
-kg2_unwrap_priv(context, minor_status, ctx, ptr, bodysize, output, qop_state)
- krb5_context context;
- OM_uint32 *minor_status;
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- gss_buffer_t output;
- gss_qop_t *qop_state;
-{
- krb5_error_code code;
- OM_uint32 retval;
- krb5_enc_data cipher;
- krb5_data plain;
- krb5_ui_4 tseqnum;
- int tdirection;
- int tmsglen;
- unsigned char *tmsg;
- krb5_timestamp now;
+ if (ctx->big_endian)
+ (void) memcpy(data_ptr+8, token.value, token.length);
+ else
+ (void) memcpy(data_ptr+8, plain, plainlen);
- output->length = 0;
- output->value = NULL;
+ plaind.length = 8 + (ctx->big_endian ? token.length : plainlen);
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+ ctx->seq, KG_USAGE_SIGN,
+ &plaind, &md5cksum);
+ xfree(data_ptr);
- /* read the body parts out of the message */
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- if (bodysize < 2) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
+ code = memcmp(md5cksum.contents, ptr+14, md5cksum.length);
+ break;
}
- cipher.ciphertext.length = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 2;
-
- if (bodysize != cipher.ciphertext.length) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ xfree(md5cksum.contents);
+ if (sealalg != 0xffff)
+ xfree(plain);
- cipher.ciphertext.data = ptr;
- cipher.enctype = ENCTYPE_UNKNOWN;
+ /* compare the computed checksum against the transmitted checksum */
- plain.length = cipher.ciphertext.length;
- if ((plain.data = (char *) malloc(plain.length)) == NULL) {
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
*minor_status = 0;
- return(GSS_S_FAILURE);
- }
-
- /* decrypt (and implicitly verify) the encrypted data */
-
- if (code = krb5_c_decrypt(context, ctx->subkey,
- KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV,
- 0, &cipher, &plain)) {
- free(plain.data);
- *minor_status = code;
- return(GSS_S_FAILURE);
+ return(GSS_S_BAD_SIG);
}
- /* parse out the encrypted fields */
- ptr = plain.data;
- bodysize = plain.length;
+ /* it got through unscathed. Make sure the context is unexpired */
- if (bodysize < 7) {
- free(plain.data);
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
-
- tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
- ptr += 4;
- tdirection = ptr[0];
- ptr += 1;
+ if (toktype == KG_TOK_SEAL_MSG)
+ *message_buffer = token;
- tmsglen = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 7;
+ if (conf_state)
+ *conf_state = (sealalg != 0xffff);
- /* check context expiry */
+ if (qop_state)
+ *qop_state = GSS_C_QOP_DEFAULT;
if ((code = krb5_timeofday(context, &now))) {
- free(plain.data);
*minor_status = code;
return(GSS_S_FAILURE);
}
if (now > ctx->endtime) {
- free(plain.data);
*minor_status = 0;
return(GSS_S_CONTEXT_EXPIRED);
}
/* do sequencing checks */
- if ((ctx->initiate && tdirection != 0xff) ||
- (!ctx->initiate && tdirection != 0)) {
- free(plain.data);
- *minor_status = G_BAD_DIRECTION;
+ if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction,
+ &seqnum))) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
return(GSS_S_BAD_SIG);
}
- if (retval = g_order_check(&(ctx->seqstate), tseqnum)) {
- free(plain.data);
- *minor_status = 0;
- return(retval);
- }
-
- /* now copy out the data. can't do a strict equality check here,
- since the output could be padded. */
-
- if (bodysize < tmsglen) {
- free(plain.data);
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
-
- tmsg = ptr;
-
- if (tmsglen) {
- if ((output->value = (void *) malloc(tmsglen)) == NULL) {
- free(plain.data);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- memcpy(output->value, tmsg, tmsglen);
- output->length = tmsglen;
+ if ((ctx->initiate && direction != 0xff) ||
+ (!ctx->initiate && direction != 0)) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = G_BAD_DIRECTION;
+ return(GSS_S_BAD_SIG);
}
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
+ retval = g_order_check(&(ctx->seqstate), seqnum);
- free(plain.data);
+ /* success or ordering violation */
*minor_status = 0;
- return(GSS_S_COMPLETE);
+ return(retval);
}
/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
conf_state is only valid if SEAL. */
OM_uint32
-kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
- conf_state, qop_state, toktype)
- krb5_context context;
- OM_uint32 *minor_status;
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- gss_buffer_t message_buffer;
- int *conf_state;
- int *qop_state;
- int toktype;
+kg_unseal(context, minor_status, context_handle, input_token_buffer,
+ message_buffer, conf_state, qop_state, toktype)
+ krb5_context context;
+ OM_uint32 *minor_status;
+ gss_ctx_id_t context_handle;
+ gss_buffer_t input_token_buffer;
+ gss_buffer_t message_buffer;
+ int *conf_state;
+ int *qop_state;
+ int toktype;
{
- krb5_error_code code;
- int tmsglen;
- int conflen = 0;
- int signalg;
- int sealalg;
- gss_buffer_desc token;
- krb5_checksum cksum;
- krb5_checksum desmac;
- krb5_checksum md5cksum;
- krb5_data plaind;
- char *data_ptr;
- krb5_timestamp now;
- unsigned char *plain;
- int cksum_len = 0;
- int plainlen;
- int err;
- int direction;
- krb5_int32 seqnum;
- OM_uint32 retval;
- size_t sumlen;
-
- if (toktype == KG_TOK_SEAL_MSG) {
- message_buffer->length = 0;
- message_buffer->value = NULL;
- }
-
- /* get the sign and seal algorithms */
-
- signalg = ptr[0] + (ptr[1]<<8);
- sealalg = ptr[2] + (ptr[3]<<8);
-
- /* Sanity checks */
-
- if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- if ((toktype != KG_TOK_SEAL_MSG) &&
- (sealalg != 0xffff)) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- /* in the current spec, there is only one valid seal algorithm per
- key type, so a simple comparison is ok */
-
- if ((toktype == KG_TOK_SEAL_MSG) &&
- !((sealalg == 0xffff) ||
- (sealalg == ctx->sealalg))) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- /* there are several mappings of seal algorithms to sign algorithms,
- but few enough that we can try them all. */
-
- if (((ctx->sealalg == 0) &&
- (signalg > 1)) ||
- ((ctx->sealalg == 1) &&
- (signalg != 3))) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- switch (signalg) {
- case 0:
- case 1:
- cksum_len = 8;
- break;
- case 3:
- cksum_len = 16;
- break;
- }
-
- if (toktype == KG_TOK_SEAL_MSG)
- tmsglen = bodysize-(14+cksum_len);
-
- /* get the token parameters */
-
- /* decode the message, if SEAL */
-
- if (toktype == KG_TOK_SEAL_MSG) {
- if (sealalg != 0xffff) {
- if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
+ krb5_gss_ctx_id_rec *ctx;
+ unsigned char *ptr;
+ int bodysize;
+ int err;
+
+ /* validate the context handle */
+ if (! kg_validate_ctx_id(context_handle)) {
+ *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+ return(GSS_S_NO_CONTEXT);
+ }
- if ((code = kg_decrypt(context, ctx->enc, NULL,
- ptr+14+cksum_len, plain, tmsglen))) {
- xfree(plain);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
- } else {
- plain = ptr+14+cksum_len;
- }
-
- plainlen = tmsglen;
-
- if ((sealalg == 0xffff) && ctx->big_endian) {
- token.length = tmsglen;
- } else {
- conflen = kg_confounder_size(context, ctx->enc);
- token.length = tmsglen - conflen - plain[tmsglen-1];
- }
-
- if (token.length) {
- if ((token.value = (void *) xmalloc(token.length)) == NULL) {
- if (sealalg != 0xffff)
- xfree(plain);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- memcpy(token.value, plain+conflen, token.length);
- }
- } else if (toktype == KG_TOK_SIGN_MSG) {
- token = *message_buffer;
- plain = token.value;
- plainlen = token.length;
- } else {
- token.length = 0;
- token.value = NULL;
- plain = token.value;
- plainlen = token.length;
- }
-
- /* compute the checksum of the message */
-
- /* initialize the the cksum */
- if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen))
- return(code);
-
- md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
- md5cksum.length = sumlen;
-
- switch (signalg) {
- case 0:
- case 3:
- /* compute the checksum of the message */
-
- /* 8 = bytes of token body to be checksummed according to spec */
-
- if (! (data_ptr = (void *)
- xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) {
- if (sealalg != 0xffff)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
-
- (void) memcpy(data_ptr, ptr-2, 8);
-
- if (ctx->big_endian)
- (void) memcpy(data_ptr+8, token.value, token.length);
- else
- (void) memcpy(data_ptr+8, plain, plainlen);
-
- plaind.length = 8 + (ctx->big_endian ? token.length : plainlen);
- plaind.data = data_ptr;
- code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0,
- &plaind, &md5cksum);
- xfree(data_ptr);
-
- if (code) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
-#if 0
- /* XXX this depends on the key being a single-des key, but that's
- all that kerberos supports right now */
-
- /* initialize the the cksum and allocate the contents buffer */
- cksum.checksum_type = CKSUMTYPE_DESCBC;
- cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC);
- if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL) {
- xfree(md5cksum.contents);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
-
- /* XXX not converted to new api since it's inside an #if 0 */
- if (code = krb5_calculate_checksum(context, cksum.checksum_type,
- md5cksum.contents, 16,
- ctx->seq.key->contents,
- ctx->seq.key->length,
- &cksum)) {
- xfree(cksum.contents);
- xfree(md5cksum.contents);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- code = memcmp(cksum.contents, ptr+14, cksum.length);
-
- xfree(cksum.contents);
-#else
- if ((code = kg_encrypt(context, ctx->seq,
- (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
- ctx->seq->contents : NULL),
- md5cksum.contents, md5cksum.contents, 16))) {
- xfree(md5cksum.contents);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return GSS_S_FAILURE;
- }
+ ctx = (krb5_gss_ctx_id_rec *) context_handle;
- if (signalg == 0)
- cksum.length = 8;
- else
- cksum.length = 16;
- cksum.contents = md5cksum.contents + 16 - cksum.length;
+ if (! ctx->established) {
+ *minor_status = KG_CTX_INCOMPLETE;
+ return(GSS_S_NO_CONTEXT);
+ }
- code = memcmp(cksum.contents, ptr+14, cksum.length);
-#endif
- break;
-
- case 1:
- if (!ctx->seed_init &&
- (code = kg_make_seed(context, ctx->subkey, ctx->seed))) {
- xfree(md5cksum.contents);
- if (sealalg != 0xffff)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return GSS_S_FAILURE;
- }
-
- if (! (data_ptr = (void *)
- xmalloc(sizeof(ctx->seed) + 8 +
- (ctx->big_endian ? token.length : plainlen)))) {
- xfree(md5cksum.contents);
- if (sealalg == 0)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- (void) memcpy(data_ptr, ptr-2, 8);
- (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed));
- if (ctx->big_endian)
- (void) memcpy(data_ptr+8+sizeof(ctx->seed),
- token.value, token.length);
- else
- (void) memcpy(data_ptr+8+sizeof(ctx->seed),
- plain, plainlen);
- plaind.length = 8 + sizeof(ctx->seed) +
- (ctx->big_endian ? token.length : plainlen);
- plaind.data = data_ptr;
- xfree(md5cksum.contents);
- code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0,
- &plaind, &md5cksum);
- xfree(data_ptr);
-
- if (code) {
- if (sealalg == 0)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- code = memcmp(md5cksum.contents, ptr+14, 8);
-
- default:
- *minor_status = 0;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
-
- xfree(md5cksum.contents);
- if (sealalg != 0xffff)
- xfree(plain);
-
- /* compare the computed checksum against the transmitted checksum */
-
- if (code) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = 0;
- return(GSS_S_BAD_SIG);
- }
-
-
- /* it got through unscathed. Make sure the context is unexpired */
-
- if (toktype == KG_TOK_SEAL_MSG)
- *message_buffer = token;
-
- if (conf_state)
- *conf_state = (sealalg != 0xffff);
-
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
-
- if ((code = krb5_timeofday(context, &now))) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (now > ctx->endtime) {
- *minor_status = 0;
- return(GSS_S_CONTEXT_EXPIRED);
- }
-
- /* do sequencing checks */
-
- if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction,
- &seqnum))) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_BAD_SIG);
- }
-
- if ((ctx->initiate && direction != 0xff) ||
- (!ctx->initiate && direction != 0)) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = G_BAD_DIRECTION;
- return(GSS_S_BAD_SIG);
- }
-
- retval = g_order_check(&(ctx->seqstate), seqnum);
-
- /* success or ordering violation */
-
- *minor_status = 0;
- return(retval);
-}
+ /* parse the token, leave the data in message_buffer, setting conf_state */
-/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
- conf_state is only valid if SEAL. */
+ /* verify the header */
-OM_uint32
-kg_unseal(context, minor_status, context_handle, input_token_buffer,
- message_buffer, conf_state, qop_state, toktype)
- krb5_context context;
- OM_uint32 *minor_status;
- gss_ctx_id_t context_handle;
- gss_buffer_t input_token_buffer;
- gss_buffer_t message_buffer;
- int *conf_state;
- int *qop_state;
- int toktype;
-{
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- int err;
- OM_uint32 retval;
-
- /* validate the context handle */
- if (! kg_validate_ctx_id(context_handle)) {
- *minor_status = (OM_uint32) G_VALIDATE_FAILED;
- return(GSS_S_NO_CONTEXT);
- }
-
- ctx = (krb5_gss_ctx_id_rec *) context_handle;
-
- if (! ctx->established) {
- *minor_status = KG_CTX_INCOMPLETE;
- return(GSS_S_NO_CONTEXT);
- }
-
- /* parse the token, leave the data in message_buffer, setting conf_state */
-
- /* verify the header */
-
- ptr = (unsigned char *) input_token_buffer->value;
-
- if (ctx->gsskrb5_version == 2000) {
- if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
- &bodysize, &ptr, KG2_TOK_MIC,
- input_token_buffer->length))) {
- return(kg2_verify_mic(context, minor_status, ctx, ptr, bodysize,
- message_buffer, qop_state));
- } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
- &bodysize, &ptr,
- KG2_TOK_WRAP_INTEG,
- input_token_buffer->length))) {
- if (GSS_ERROR(retval = kg2_unwrap_integ(context, minor_status,
- ctx, ptr, bodysize,
- message_buffer, qop_state)))
- return(retval);
-
- if (conf_state)
- *conf_state = 0;
- return(GSS_S_COMPLETE);
- } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
- &bodysize, &ptr,
- KG2_TOK_WRAP_PRIV,
- input_token_buffer->length))) {
- if (GSS_ERROR(retval = kg2_unwrap_priv(context, minor_status,
- ctx, ptr, bodysize,
- message_buffer, qop_state)))
- return(retval);
-
- if (conf_state)
- *conf_state = 1;
- return(GSS_S_COMPLETE);
- }
- } else {
- if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
- &bodysize, &ptr, toktype,
- input_token_buffer->length))) {
- return(kg_unseal_v1(context, minor_status, ctx, ptr, bodysize,
- message_buffer, conf_state, qop_state,
- toktype));
- }
- }
-
- *minor_status = err;
- return(GSS_S_DEFECTIVE_TOKEN);
+ ptr = (unsigned char *) input_token_buffer->value;
+
+ if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
+ &bodysize, &ptr, toktype,
+ input_token_buffer->length))) {
+ return(kg_unseal_v1(context, minor_status, ctx, ptr, bodysize,
+ message_buffer, conf_state, qop_state,
+ toktype));
+ }
+
+ *minor_status = err;
+ return(GSS_S_DEFECTIVE_TOKEN);
}
diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c
index 2a6231e..1989a7d 100644
--- a/src/lib/gssapi/krb5/ser_sctx.c
+++ b/src/lib/gssapi/krb5/ser_sctx.c
@@ -233,7 +233,6 @@ kg_ctx_size(kcontext, arg, sizep)
* krb5_int32 for seq_recv.
* krb5_int32 for established.
* krb5_int32 for big_endian.
- * krb5_int32 for gsskrb5_version.
* krb5_int32 for nctypes.
* krb5_int32 for trailer.
*/
@@ -349,8 +348,6 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain)
&bp, &remain);
(void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian,
&bp, &remain);
- (void) krb5_ser_pack_int32((krb5_int32) ctx->gsskrb5_version,
- &bp, &remain);
(void) krb5_ser_pack_int32((krb5_int32) ctx->nctypes,
&bp, &remain);
@@ -477,8 +474,6 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
(void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
ctx->big_endian = (int) ibuf;
(void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
- ctx->gsskrb5_version = (int) ibuf;
- (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
ctx->nctypes = (int) ibuf;
if ((kret = kg_oid_internalize(kcontext, &ctx->mech_used, &bp,
diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c
index 61fbc66..77feade 100644
--- a/src/lib/gssapi/krb5/util_cksum.c
+++ b/src/lib/gssapi/krb5/util_cksum.c
@@ -20,15 +20,12 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/*
- * $Id$
- */
-
#include "gssapiP_krb5.h"
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
+/* Checksumming the channel bindings always uses plain MD5. */
krb5_error_code
kg_checksum_channel_bindings(context, cb, cksum, bigend)
krb5_context context;
diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c
index 8792e5f..3e40236 100644
--- a/src/lib/gssapi/krb5/util_crypt.c
+++ b/src/lib/gssapi/krb5/util_crypt.c
@@ -52,12 +52,6 @@
#include <memory.h>
#endif
-/*
- * $Id$
- */
-
-static unsigned char zeros[8] = {0,0,0,0,0,0,0,0};
-
int
kg_confounder_size(context, key)
krb5_context context;
@@ -107,9 +101,10 @@ kg_encrypt_size(context, key, n)
}
krb5_error_code
-kg_encrypt(context, key, iv, in, out, length)
+kg_encrypt(context, key, usage, iv, in, out, length)
krb5_context context;
krb5_keyblock *key;
+ int usage;
krb5_pointer iv;
krb5_pointer in;
krb5_pointer out;
@@ -125,7 +120,10 @@ kg_encrypt(context, key, iv, in, out, length)
return(code);
ivd.length = blocksize;
- ivd.data = iv;
+ ivd.data = malloc(ivd.length);
+ if (ivd.data == NULL)
+ return ENOMEM;
+ memcpy(ivd.data, iv, ivd.length);
pivd = &ivd;
} else {
pivd = NULL;
@@ -137,18 +135,19 @@ kg_encrypt(context, key, iv, in, out, length)
outputd.ciphertext.length = length;
outputd.ciphertext.data = out;
- return(krb5_c_encrypt(context, key,
- /* XXX this routine is only used for the old
- bare-des stuff which doesn't use the
- key usage */ 0, pivd, &inputd, &outputd));
+ code = krb5_c_encrypt(context, key, usage, pivd, &inputd, &outputd);
+ if (pivd != NULL)
+ krb5_free_data_contents(context, pivd);
+ return code;
}
/* length is the length of the cleartext. */
krb5_error_code
-kg_decrypt(context, key, iv, in, out, length)
+kg_decrypt(context, key, usage, iv, in, out, length)
krb5_context context;
krb5_keyblock *key;
+ int usage;
krb5_pointer iv;
krb5_pointer in;
krb5_pointer out;
@@ -164,7 +163,10 @@ kg_decrypt(context, key, iv, in, out, length)
return(code);
ivd.length = blocksize;
- ivd.data = iv;
+ ivd.data = malloc(ivd.length);
+ if (ivd.data == NULL)
+ return ENOMEM;
+ memcpy(ivd.data, iv, ivd.length);
pivd = &ivd;
} else {
pivd = NULL;
@@ -177,8 +179,8 @@ kg_decrypt(context, key, iv, in, out, length)
outputd.length = length;
outputd.data = out;
- return(krb5_c_decrypt(context, key,
- /* XXX this routine is only used for the old
- bare-des stuff which doesn't use the
- key usage */ 0, pivd, &inputd, &outputd));
+ code = krb5_c_decrypt(context, key, usage, pivd, &inputd, &outputd);
+ if (pivd != NULL)
+ krb5_free_data_contents(context, pivd);
+ return code;
}
diff --git a/src/lib/gssapi/krb5/util_seed.c b/src/lib/gssapi/krb5/util_seed.c
index 24ae7f3..3f6eb47 100644
--- a/src/lib/gssapi/krb5/util_seed.c
+++ b/src/lib/gssapi/krb5/util_seed.c
@@ -25,10 +25,6 @@
#include <memory.h>
#endif
-/*
- * $Id$
- */
-
static unsigned char zeros[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
krb5_error_code
@@ -49,7 +45,7 @@ kg_make_seed(context, key, seed)
for (i=0; i<tmpkey->length; i++)
tmpkey->contents[i] = key->contents[key->length - 1 - i];
- code = kg_encrypt(context, tmpkey, NULL, zeros, seed, 16);
+ code = kg_encrypt(context, tmpkey, KG_USAGE_SEAL, NULL, zeros, seed, 16);
krb5_free_keyblock(context, tmpkey);
diff --git a/src/lib/gssapi/krb5/util_seqnum.c b/src/lib/gssapi/krb5/util_seqnum.c
index e14b2f3..b8f2b38 100644
--- a/src/lib/gssapi/krb5/util_seqnum.c
+++ b/src/lib/gssapi/krb5/util_seqnum.c
@@ -47,7 +47,7 @@ kg_make_seq_num(context, key, direction, seqnum, cksum, buf)
plain[6] = direction;
plain[7] = direction;
- return(kg_encrypt(context, key, cksum, plain, buf, 8));
+ return(kg_encrypt(context, key, KG_USAGE_SEQ, cksum, plain, buf, 8));
}
krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum)
@@ -61,7 +61,7 @@ krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum)
krb5_error_code code;
unsigned char plain[8];
- if (code = kg_decrypt(context, key, cksum, buf, plain, 8))
+ if (code = kg_decrypt(context, key, KG_USAGE_SEQ, cksum, buf, plain, 8))
return(code);
if ((plain[4] != plain[5]) ||
diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c
index d71a3f8..a3c05df4 100644
--- a/src/lib/gssapi/krb5/wrap_size_limit.c
+++ b/src/lib/gssapi/krb5/wrap_size_limit.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -48,10 +72,6 @@
#include "gssapiP_krb5.h"
-/*
- * $Id$
- */
-
/* V2 interface */
OM_uint32
krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
@@ -66,6 +86,9 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
krb5_context context;
krb5_gss_ctx_id_rec *ctx;
krb5_error_code code;
+ OM_uint32 data_size, conflen;
+ OM_uint32 ohlen;
+ int overhead;
if (GSS_ERROR(kg_get_context(minor_status, &context)))
return(GSS_S_FAILURE);
@@ -88,91 +111,23 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
return(GSS_S_NO_CONTEXT);
}
- if (ctx->gsskrb5_version == 2000) {
- if (conf_req_flag) {
- /* this is pretty gross. take the max output, and call
- krb5_c_encrypt_length to see how much overhead is added
- on. subtract that much, and see if it fits in the
- requested space. If not, start subtracting 1 until it
- does. This doesn't necessarily give us the optimal
- packing, but I think that's ok (I could start adding 1
- until I went over, but that seems like it's not worth
- the effort). This is probably O(blocksize), but that's
- never going to be large. */
-
- OM_uint32 headerlen, plainlen;
- size_t enclen;
-
- headerlen = g_token_size((gss_OID) ctx->mech_used, 2);
- plainlen = req_output_size - headerlen;
-
- if (code = krb5_c_encrypt_length(context, ctx->enc->enctype,
- plainlen, &enclen)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- plainlen -= plainlen - (enclen - plainlen);
-
- if (code = krb5_c_encrypt_length(context, ctx->enc->enctype,
- plainlen, &enclen)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- while (headerlen + enclen > req_output_size) {
- plainlen--;
-
- if (code = krb5_c_encrypt_length(context, ctx->enc->enctype,
- plainlen, &enclen)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
- }
-
- /* subtract off the fixed size inside the encrypted part */
-
- plainlen -= 7;
-
- *max_input_size = plainlen;
- } else {
- size_t cksumlen;
- OM_uint32 headerlen;
-
- if (code = krb5_c_checksum_length(context, ctx->ctypes[0],
- &cksumlen)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- headerlen = g_token_size((gss_OID) ctx->mech_used, 13 + cksumlen);
-
- *max_input_size = req_output_size - headerlen;
- }
- } else {
- OM_uint32 data_size, conflen;
- OM_uint32 ohlen;
- int overhead;
-
- /* Calculate the token size and subtract that from the output size */
- overhead = 7 + ctx->mech_used->length;
- data_size = req_output_size;
- conflen = kg_confounder_size(context, ctx->enc);
- data_size = (conflen + data_size + 8) & (~(OM_uint32)7);
- ohlen = g_token_size((gss_OID) ctx->mech_used,
- (unsigned int) (data_size + ctx->cksum_size + 14))
- - req_output_size;
-
- if (ohlen+overhead < req_output_size)
- /*
- * Cannot have trailer length that will cause us to pad over
- * our length
- */
- *max_input_size = (req_output_size - ohlen - overhead)
- & (~(OM_uint32)7);
- else
- *max_input_size = 0;
- }
+ /* Calculate the token size and subtract that from the output size */
+ overhead = 7 + ctx->mech_used->length;
+ data_size = req_output_size;
+ conflen = kg_confounder_size(context, ctx->enc);
+ data_size = (conflen + data_size + 8) & (~(OM_uint32)7);
+ ohlen = g_token_size((gss_OID) ctx->mech_used,
+ (unsigned int) (data_size + ctx->cksum_size + 14))
+ - req_output_size;
+
+ if (ohlen+overhead < req_output_size)
+ /*
+ * Cannot have trailer length that will cause us to pad over our
+ * length.
+ */
+ *max_input_size = (req_output_size - ohlen - overhead) & (~(OM_uint32)7);
+ else
+ *max_input_size = 0;
*minor_status = 0;
return(GSS_S_COMPLETE);