diff options
Diffstat (limited to 'src/lib/gssapi/krb5/wrap_size_limit.c')
-rw-r--r-- | src/lib/gssapi/krb5/wrap_size_limit.c | 108 |
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); } |