LCOV - code coverage report
Current view: top level - source4/heimdal/lib/gssapi/krb5 - 8003.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 65 112 58.0 %
Date: 2021-09-23 10:06:22 Functions: 6 7 85.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
       3             :  * (Royal Institute of Technology, Stockholm, Sweden).
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  *
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  *
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * 3. Neither the name of the Institute nor the names of its contributors
      18             :  *    may be used to endorse or promote products derived from this software
      19             :  *    without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include "gsskrb5_locl.h"
      35             : 
      36             : krb5_error_code
      37       41880 : _gsskrb5_encode_om_uint32(OM_uint32 n, u_char *p)
      38             : {
      39       41880 :   p[0] = (n >> 0)  & 0xFF;
      40       41880 :   p[1] = (n >> 8)  & 0xFF;
      41       41880 :   p[2] = (n >> 16) & 0xFF;
      42       41880 :   p[3] = (n >> 24) & 0xFF;
      43       41880 :   return 0;
      44             : }
      45             : 
      46             : krb5_error_code
      47     3174579 : _gsskrb5_encode_be_om_uint32(OM_uint32 n, u_char *p)
      48             : {
      49     3174579 :   p[0] = (n >> 24) & 0xFF;
      50     3174579 :   p[1] = (n >> 16) & 0xFF;
      51     3174579 :   p[2] = (n >> 8)  & 0xFF;
      52     3174579 :   p[3] = (n >> 0)  & 0xFF;
      53     3174579 :   return 0;
      54             : }
      55             : 
      56             : krb5_error_code
      57       89284 : _gsskrb5_decode_om_uint32(const void *ptr, OM_uint32 *n)
      58             : {
      59       89284 :     const u_char *p = ptr;
      60       89284 :     *n = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
      61       89284 :     return 0;
      62             : }
      63             : 
      64             : krb5_error_code
      65     1984516 : _gsskrb5_decode_be_om_uint32(const void *ptr, OM_uint32 *n)
      66             : {
      67     1984516 :     const u_char *p = ptr;
      68     1984516 :     *n = (p[0] <<24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
      69     1984516 :     return 0;
      70             : }
      71             : 
      72             : static krb5_error_code
      73           0 : hash_input_chan_bindings (const gss_channel_bindings_t b,
      74             :                           u_char *p)
      75             : {
      76             :   u_char num[4];
      77             :   EVP_MD_CTX *ctx;
      78             : 
      79           0 :   ctx = EVP_MD_CTX_create();
      80           0 :   EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
      81             : 
      82           0 :   _gsskrb5_encode_om_uint32 (b->initiator_addrtype, num);
      83           0 :   EVP_DigestUpdate(ctx, num, sizeof(num));
      84           0 :   _gsskrb5_encode_om_uint32 (b->initiator_address.length, num);
      85           0 :   EVP_DigestUpdate(ctx, num, sizeof(num));
      86           0 :   if (b->initiator_address.length)
      87           0 :       EVP_DigestUpdate(ctx,
      88           0 :                        b->initiator_address.value,
      89             :                        b->initiator_address.length);
      90           0 :   _gsskrb5_encode_om_uint32 (b->acceptor_addrtype, num);
      91           0 :   EVP_DigestUpdate(ctx, num, sizeof(num));
      92           0 :   _gsskrb5_encode_om_uint32 (b->acceptor_address.length, num);
      93           0 :   EVP_DigestUpdate(ctx, num, sizeof(num));
      94           0 :   if (b->acceptor_address.length)
      95           0 :       EVP_DigestUpdate(ctx,
      96           0 :                        b->acceptor_address.value,
      97             :                        b->acceptor_address.length);
      98           0 :   _gsskrb5_encode_om_uint32 (b->application_data.length, num);
      99           0 :   EVP_DigestUpdate(ctx, num, sizeof(num));
     100           0 :   if (b->application_data.length)
     101           0 :       EVP_DigestUpdate(ctx,
     102           0 :                        b->application_data.value,
     103             :                        b->application_data.length);
     104           0 :   EVP_DigestFinal_ex(ctx, p, NULL);
     105           0 :   EVP_MD_CTX_destroy(ctx);
     106             : 
     107           0 :   return 0;
     108             : }
     109             : 
     110             : /*
     111             :  * create a checksum over the chanel bindings in
     112             :  * `input_chan_bindings', `flags' and `fwd_data' and return it in
     113             :  * `result'
     114             :  */
     115             : 
     116             : OM_uint32
     117       20940 : _gsskrb5_create_8003_checksum (
     118             :                       OM_uint32 *minor_status,
     119             :                       const gss_channel_bindings_t input_chan_bindings,
     120             :                       OM_uint32 flags,
     121             :                       const krb5_data *fwd_data,
     122             :                       Checksum *result)
     123             : {
     124             :     u_char *p;
     125             : 
     126             :     /*
     127             :      * see rfc1964 (section 1.1.1 (Initial Token), and the checksum value
     128             :      * field's format) */
     129       20940 :     result->cksumtype = CKSUMTYPE_GSSAPI;
     130       20940 :     if (fwd_data->length > 0 && (flags & GSS_C_DELEG_FLAG))
     131       19792 :         result->checksum.length = 24 + 4 + fwd_data->length;
     132             :     else
     133        1148 :         result->checksum.length = 24;
     134       20940 :     result->checksum.data   = malloc (result->checksum.length);
     135       20940 :     if (result->checksum.data == NULL) {
     136           0 :         *minor_status = ENOMEM;
     137           0 :         return GSS_S_FAILURE;
     138             :     }
     139             : 
     140       20940 :     p = result->checksum.data;
     141       20940 :     _gsskrb5_encode_om_uint32 (16, p);
     142       20940 :     p += 4;
     143       20940 :     if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS) {
     144       20190 :         memset (p, 0, 16);
     145             :     } else {
     146           0 :         hash_input_chan_bindings (input_chan_bindings, p);
     147             :     }
     148       20940 :     p += 16;
     149       20940 :     _gsskrb5_encode_om_uint32 (flags, p);
     150       20940 :     p += 4;
     151             : 
     152       20940 :     if (fwd_data->length > 0 && (flags & GSS_C_DELEG_FLAG)) {
     153             : 
     154       19792 :         *p++ = (1 >> 0) & 0xFF;                   /* DlgOpt */ /* == 1 */
     155       19792 :         *p++ = (1 >> 8) & 0xFF;                   /* DlgOpt */ /* == 0 */
     156       19792 :         *p++ = (fwd_data->length >> 0) & 0xFF;    /* Dlgth  */
     157       19792 :         *p++ = (fwd_data->length >> 8) & 0xFF;    /* Dlgth  */
     158       20542 :         memcpy(p, (unsigned char *) fwd_data->data, fwd_data->length);
     159             : 
     160       19792 :         p += fwd_data->length;
     161             :     }
     162             : 
     163       20190 :     return GSS_S_COMPLETE;
     164             : }
     165             : 
     166             : /*
     167             :  * verify the checksum in `cksum' over `input_chan_bindings'
     168             :  * returning  `flags' and `fwd_data'
     169             :  */
     170             : 
     171             : OM_uint32
     172       44642 : _gsskrb5_verify_8003_checksum(
     173             :                       OM_uint32 *minor_status,
     174             :                       const gss_channel_bindings_t input_chan_bindings,
     175             :                       const Checksum *cksum,
     176             :                       OM_uint32 *flags,
     177             :                       krb5_data *fwd_data)
     178             : {
     179             :     unsigned char hash[16];
     180             :     unsigned char *p;
     181             :     OM_uint32 length;
     182             :     int DlgOpt;
     183             :     static unsigned char zeros[16];
     184             : 
     185             :     /* XXX should handle checksums > 24 bytes */
     186       44642 :     if(cksum->cksumtype != CKSUMTYPE_GSSAPI || cksum->checksum.length < 24) {
     187           0 :         *minor_status = 0;
     188           0 :         return GSS_S_BAD_BINDINGS;
     189             :     }
     190             : 
     191       44642 :     p = cksum->checksum.data;
     192       44642 :     _gsskrb5_decode_om_uint32(p, &length);
     193       44642 :     if(length != sizeof(hash)) {
     194           0 :         *minor_status = 0;
     195           0 :         return GSS_S_BAD_BINDINGS;
     196             :     }
     197             : 
     198       44642 :     p += 4;
     199             : 
     200       44642 :     if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS
     201           0 :         && memcmp(p, zeros, sizeof(zeros)) != 0) {
     202           0 :         if(hash_input_chan_bindings(input_chan_bindings, hash) != 0) {
     203           0 :             *minor_status = 0;
     204           0 :             return GSS_S_BAD_BINDINGS;
     205             :         }
     206           0 :         if(ct_memcmp(hash, p, sizeof(hash)) != 0) {
     207           0 :             *minor_status = 0;
     208           0 :             return GSS_S_BAD_BINDINGS;
     209             :         }
     210             :     }
     211             : 
     212       44642 :     p += sizeof(hash);
     213             : 
     214       44642 :     _gsskrb5_decode_om_uint32(p, flags);
     215       44642 :     p += 4;
     216             : 
     217       44642 :     if (cksum->checksum.length > 24 && (*flags & GSS_C_DELEG_FLAG)) {
     218       42166 :         if(cksum->checksum.length < 28) {
     219           0 :             *minor_status = 0;
     220           0 :             return GSS_S_BAD_BINDINGS;
     221             :         }
     222             : 
     223       42166 :         DlgOpt = (p[0] << 0) | (p[1] << 8);
     224       42166 :         p += 2;
     225       42166 :         if (DlgOpt != 1) {
     226           0 :             *minor_status = 0;
     227           0 :             return GSS_S_BAD_BINDINGS;
     228             :         }
     229             : 
     230       42166 :         fwd_data->length = (p[0] << 0) | (p[1] << 8);
     231       42166 :         p += 2;
     232       42166 :         if(cksum->checksum.length < 28 + fwd_data->length) {
     233           0 :             *minor_status = 0;
     234           0 :             return GSS_S_BAD_BINDINGS;
     235             :         }
     236       42166 :         fwd_data->data = malloc(fwd_data->length);
     237       42166 :         if (fwd_data->data == NULL) {
     238           0 :             *minor_status = ENOMEM;
     239           0 :             return GSS_S_FAILURE;
     240             :         }
     241       42166 :         memcpy(fwd_data->data, p, fwd_data->length);
     242             :     }
     243             : 
     244       43904 :     return GSS_S_COMPLETE;
     245             : }

Generated by: LCOV version 1.13