aboutsummaryrefslogtreecommitdiff
path: root/src/lib/gssapi/krb5/wrap_size_limit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/gssapi/krb5/wrap_size_limit.c')
-rw-r--r--src/lib/gssapi/krb5/wrap_size_limit.c108
1 files changed, 100 insertions, 8 deletions
diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c
index f2366d1..7459492 100644
--- a/src/lib/gssapi/krb5/wrap_size_limit.c
+++ b/src/lib/gssapi/krb5/wrap_size_limit.c
@@ -20,6 +20,32 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
+/*
+ * 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
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * 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.
+ */
+
#include "gssapiP_krb5.h"
/*
@@ -39,8 +65,7 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
{
krb5_context context;
krb5_gss_ctx_id_rec *ctx;
- OM_uint32 cfsize;
- OM_uint32 ohlen;
+ krb5_error_code code;
if (GSS_ERROR(kg_get_context(minor_status, &context)))
return(GSS_S_FAILURE);
@@ -63,19 +88,86 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
return(GSS_S_NO_CONTEXT);
}
- /* Calculate the token size and subtract that from the output size */
- cfsize = (conf_req_flag) ? kg_confounder_size(&ctx->enc) : 0;
- ohlen = g_token_size((gss_OID) ctx->mech_used,
- (unsigned int) cfsize + ctx->cksum_size + 14);
+ 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);
+ }
- if (ohlen < req_output_size)
+ 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 cfsize;
+ OM_uint32 ohlen;
+
+ /* Calculate the token size and subtract that from the output size */
+ cfsize = (conf_req_flag) ? kg_confounder_size(context, ctx->enc) : 0;
+ ohlen = g_token_size((gss_OID) ctx->mech_used,
+ (unsigned int) cfsize + ctx->cksum_size + 14);
+
+ if (ohlen < req_output_size)
/*
* Cannot have trailer length that will cause us to pad over
* our length
*/
*max_input_size = (req_output_size - ohlen - 1) & (~7);
- else
+ else
*max_input_size = 0;
+ }
+
*minor_status = 0;
return(GSS_S_COMPLETE);
}