Path: blob/main/crypto/heimdal/lib/gssapi/krb5/8003.c
34923 views
/*1* Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* 3. Neither the name of the Institute nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*/3233#include "gsskrb5_locl.h"3435krb5_error_code36_gsskrb5_encode_om_uint32(OM_uint32 n, u_char *p)37{38p[0] = (n >> 0) & 0xFF;39p[1] = (n >> 8) & 0xFF;40p[2] = (n >> 16) & 0xFF;41p[3] = (n >> 24) & 0xFF;42return 0;43}4445krb5_error_code46_gsskrb5_encode_be_om_uint32(OM_uint32 n, u_char *p)47{48p[0] = (n >> 24) & 0xFF;49p[1] = (n >> 16) & 0xFF;50p[2] = (n >> 8) & 0xFF;51p[3] = (n >> 0) & 0xFF;52return 0;53}5455krb5_error_code56_gsskrb5_decode_om_uint32(const void *ptr, OM_uint32 *n)57{58const u_char *p = ptr;59*n = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);60return 0;61}6263krb5_error_code64_gsskrb5_decode_be_om_uint32(const void *ptr, OM_uint32 *n)65{66const u_char *p = ptr;67*n = (p[0] <<24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);68return 0;69}7071static krb5_error_code72hash_input_chan_bindings (const gss_channel_bindings_t b,73u_char *p)74{75u_char num[4];76EVP_MD_CTX *ctx;7778ctx = EVP_MD_CTX_create();79EVP_DigestInit_ex(ctx, EVP_md5(), NULL);8081_gsskrb5_encode_om_uint32 (b->initiator_addrtype, num);82EVP_DigestUpdate(ctx, num, sizeof(num));83_gsskrb5_encode_om_uint32 (b->initiator_address.length, num);84EVP_DigestUpdate(ctx, num, sizeof(num));85if (b->initiator_address.length)86EVP_DigestUpdate(ctx,87b->initiator_address.value,88b->initiator_address.length);89_gsskrb5_encode_om_uint32 (b->acceptor_addrtype, num);90EVP_DigestUpdate(ctx, num, sizeof(num));91_gsskrb5_encode_om_uint32 (b->acceptor_address.length, num);92EVP_DigestUpdate(ctx, num, sizeof(num));93if (b->acceptor_address.length)94EVP_DigestUpdate(ctx,95b->acceptor_address.value,96b->acceptor_address.length);97_gsskrb5_encode_om_uint32 (b->application_data.length, num);98EVP_DigestUpdate(ctx, num, sizeof(num));99if (b->application_data.length)100EVP_DigestUpdate(ctx,101b->application_data.value,102b->application_data.length);103EVP_DigestFinal_ex(ctx, p, NULL);104EVP_MD_CTX_destroy(ctx);105106return 0;107}108109/*110* create a checksum over the chanel bindings in111* `input_chan_bindings', `flags' and `fwd_data' and return it in112* `result'113*/114115OM_uint32116_gsskrb5_create_8003_checksum (117OM_uint32 *minor_status,118const gss_channel_bindings_t input_chan_bindings,119OM_uint32 flags,120const krb5_data *fwd_data,121Checksum *result)122{123u_char *p;124125/*126* see rfc1964 (section 1.1.1 (Initial Token), and the checksum value127* field's format) */128result->cksumtype = CKSUMTYPE_GSSAPI;129if (fwd_data->length > 0 && (flags & GSS_C_DELEG_FLAG))130result->checksum.length = 24 + 4 + fwd_data->length;131else132result->checksum.length = 24;133result->checksum.data = malloc (result->checksum.length);134if (result->checksum.data == NULL) {135*minor_status = ENOMEM;136return GSS_S_FAILURE;137}138139p = result->checksum.data;140_gsskrb5_encode_om_uint32 (16, p);141p += 4;142if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS) {143memset (p, 0, 16);144} else {145hash_input_chan_bindings (input_chan_bindings, p);146}147p += 16;148_gsskrb5_encode_om_uint32 (flags, p);149p += 4;150151if (fwd_data->length > 0 && (flags & GSS_C_DELEG_FLAG)) {152153*p++ = (1 >> 0) & 0xFF; /* DlgOpt */ /* == 1 */154*p++ = (1 >> 8) & 0xFF; /* DlgOpt */ /* == 0 */155*p++ = (fwd_data->length >> 0) & 0xFF; /* Dlgth */156*p++ = (fwd_data->length >> 8) & 0xFF; /* Dlgth */157memcpy(p, (unsigned char *) fwd_data->data, fwd_data->length);158159p += fwd_data->length;160}161162return GSS_S_COMPLETE;163}164165/*166* verify the checksum in `cksum' over `input_chan_bindings'167* returning `flags' and `fwd_data'168*/169170OM_uint32171_gsskrb5_verify_8003_checksum(172OM_uint32 *minor_status,173const gss_channel_bindings_t input_chan_bindings,174const Checksum *cksum,175OM_uint32 *flags,176krb5_data *fwd_data)177{178unsigned char hash[16];179unsigned char *p;180OM_uint32 length;181int DlgOpt;182static unsigned char zeros[16];183184/* XXX should handle checksums > 24 bytes */185if(cksum->cksumtype != CKSUMTYPE_GSSAPI || cksum->checksum.length < 24) {186*minor_status = 0;187return GSS_S_BAD_BINDINGS;188}189190p = cksum->checksum.data;191_gsskrb5_decode_om_uint32(p, &length);192if(length != sizeof(hash)) {193*minor_status = 0;194return GSS_S_BAD_BINDINGS;195}196197p += 4;198199if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS200&& memcmp(p, zeros, sizeof(zeros)) != 0) {201if(hash_input_chan_bindings(input_chan_bindings, hash) != 0) {202*minor_status = 0;203return GSS_S_BAD_BINDINGS;204}205if(ct_memcmp(hash, p, sizeof(hash)) != 0) {206*minor_status = 0;207return GSS_S_BAD_BINDINGS;208}209}210211p += sizeof(hash);212213_gsskrb5_decode_om_uint32(p, flags);214p += 4;215216if (cksum->checksum.length > 24 && (*flags & GSS_C_DELEG_FLAG)) {217if(cksum->checksum.length < 28) {218*minor_status = 0;219return GSS_S_BAD_BINDINGS;220}221222DlgOpt = (p[0] << 0) | (p[1] << 8);223p += 2;224if (DlgOpt != 1) {225*minor_status = 0;226return GSS_S_BAD_BINDINGS;227}228229fwd_data->length = (p[0] << 0) | (p[1] << 8);230p += 2;231if(cksum->checksum.length < 28 + fwd_data->length) {232*minor_status = 0;233return GSS_S_BAD_BINDINGS;234}235fwd_data->data = malloc(fwd_data->length);236if (fwd_data->data == NULL) {237*minor_status = ENOMEM;238return GSS_S_FAILURE;239}240memcpy(fwd_data->data, p, fwd_data->length);241}242243return GSS_S_COMPLETE;244}245246247