static krb5_error_code pac_checksum(krb5_context context, const krb5_keyblock *key, uint32_t *cksumtype, size_t *cksumsize) { krb5_cksumtype cktype; krb5_error_code ret; krb5_crypto crypto = NULL; ret = krb5_crypto_init(context, key, 0, &crypto); if (ret) return ret; ret = krb5_crypto_get_checksum_type(context, crypto, &cktype); krb5_crypto_destroy(context, crypto); if (ret) return ret; if (krb5_checksum_is_keyed(context, cktype) == FALSE) { *cksumtype = CKSUMTYPE_HMAC_MD5; *cksumsize = 16; } ret = krb5_checksumsize(context, cktype, cksumsize); if (ret) return ret; *cksumtype = (uint32_t)cktype; return 0; }
krb5_error_code _gsskrb5cfx_wrap_length_cfx(krb5_context context, krb5_crypto crypto, int conf_req_flag, int dce_style, size_t input_length, size_t *output_length, size_t *cksumsize, uint16_t *padlength) { krb5_error_code ret; krb5_cksumtype type; /* 16-byte header is always first */ *output_length = sizeof(gss_cfx_wrap_token_desc); *padlength = 0; ret = krb5_crypto_get_checksum_type(context, crypto, &type); if (ret) return ret; ret = krb5_checksumsize(context, type, cksumsize); if (ret) return ret; if (conf_req_flag) { size_t padsize; /* Header is concatenated with data before encryption */ input_length += sizeof(gss_cfx_wrap_token_desc); if (dce_style) { ret = krb5_crypto_getblocksize(context, crypto, &padsize); } else { ret = krb5_crypto_getpadsize(context, crypto, &padsize); } if (ret) { return ret; } if (padsize > 1) { /* XXX check this */ *padlength = padsize - (input_length % padsize); /* We add the pad ourselves (noted here for completeness only) */ input_length += *padlength; } *output_length += krb5_get_wrapped_length(context, crypto, input_length); } else { /* Checksum is concatenated with data */ *output_length += input_length + *cksumsize; } assert(*output_length > input_length); return 0; }
OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status, const gsskrb5_ctx ctx, krb5_context context, int conf_req_flag, gss_qop_t qop_req, OM_uint32 req_output_size, OM_uint32 *max_input_size) { krb5_error_code ret; *max_input_size = 0; /* 16-byte header is always first */ if (req_output_size < 16) return 0; req_output_size -= 16; if (conf_req_flag) { size_t wrapped_size, sz; wrapped_size = req_output_size + 1; do { wrapped_size--; sz = krb5_get_wrapped_length(context, ctx->crypto, wrapped_size); } while (wrapped_size && sz > req_output_size); if (wrapped_size == 0) return 0; /* inner header */ if (wrapped_size < 16) return 0; wrapped_size -= 16; *max_input_size = wrapped_size; } else { krb5_cksumtype type; size_t cksumsize; ret = krb5_crypto_get_checksum_type(context, ctx->crypto, &type); if (ret) return ret; ret = krb5_checksumsize(context, type, &cksumsize); if (ret) return ret; if (req_output_size < cksumsize) return 0; /* Checksum is concatenated with data */ *max_input_size = req_output_size - cksumsize; } return 0; }