LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/gssapi/krb5 - get_mic.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 16 114 14.0 %
Date: 2024-04-21 15:09:00 Functions: 1 2 50.0 %

          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             : #ifdef HEIM_WEAK_CRYPTO
      37             : 
      38             : static OM_uint32
      39             : mic_des
      40             :            (OM_uint32 * minor_status,
      41             :             const gsskrb5_ctx ctx,
      42             :             krb5_context context,
      43             :             gss_qop_t qop_req,
      44             :             const gss_buffer_t message_buffer,
      45             :             gss_buffer_t message_token,
      46             :             krb5_keyblock *key
      47             :            )
      48             : {
      49             :   u_char *p;
      50             :   EVP_MD_CTX *md5;
      51             :   u_char hash[16];
      52             :   DES_key_schedule schedule;
      53             :   EVP_CIPHER_CTX des_ctx;
      54             :   DES_cblock deskey;
      55             :   DES_cblock zero;
      56             :   int32_t seq_number;
      57             :   size_t len, total_len;
      58             : 
      59             :   _gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
      60             : 
      61             :   message_token->length = total_len;
      62             :   message_token->value  = malloc (total_len);
      63             :   if (message_token->value == NULL) {
      64             :     message_token->length = 0;
      65             :     *minor_status = ENOMEM;
      66             :     return GSS_S_FAILURE;
      67             :   }
      68             : 
      69             :   p = _gsskrb5_make_header(message_token->value,
      70             :                               len,
      71             :                               "\x01\x01", /* TOK_ID */
      72             :                               GSS_KRB5_MECHANISM);
      73             : 
      74             :   memcpy (p, "\x00\x00", 2);  /* SGN_ALG = DES MAC MD5 */
      75             :   p += 2;
      76             : 
      77             :   memcpy (p, "\xff\xff\xff\xff", 4); /* Filler */
      78             :   p += 4;
      79             : 
      80             :   /* Fill in later (SND-SEQ) */
      81             :   memset (p, 0, 16);
      82             :   p += 16;
      83             : 
      84             :   /* checksum */
      85             :   md5 = EVP_MD_CTX_create();
      86             :   EVP_DigestInit_ex(md5, EVP_md5(), NULL);
      87             :   EVP_DigestUpdate(md5, p - 24, 8);
      88             :   EVP_DigestUpdate(md5, message_buffer->value, message_buffer->length);
      89             :   EVP_DigestFinal_ex(md5, hash, NULL);
      90             :   EVP_MD_CTX_destroy(md5);
      91             : 
      92             :   memset (&zero, 0, sizeof(zero));
      93             :   memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
      94             :   DES_set_key_unchecked (&deskey, &schedule);
      95             :   DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
      96             :                  &schedule, &zero);
      97             :   memcpy (p - 8, hash, 8);      /* SGN_CKSUM */
      98             : 
      99             :   HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
     100             :   /* sequence number */
     101             :   krb5_auth_con_getlocalseqnumber (context,
     102             :                                    ctx->auth_context,
     103             :                                    &seq_number);
     104             : 
     105             :   p -= 16;                      /* SND_SEQ */
     106             :   p[0] = (seq_number >> 0)  & 0xFF;
     107             :   p[1] = (seq_number >> 8)  & 0xFF;
     108             :   p[2] = (seq_number >> 16) & 0xFF;
     109             :   p[3] = (seq_number >> 24) & 0xFF;
     110             :   memset (p + 4,
     111             :           (ctx->more_flags & LOCAL) ? 0 : 0xFF,
     112             :           4);
     113             : 
     114             :   EVP_CIPHER_CTX_init(&des_ctx);
     115             :   EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, p + 8, 1);
     116             :   EVP_Cipher(&des_ctx, p, p, 8);
     117             :   EVP_CIPHER_CTX_cleanup(&des_ctx);
     118             : 
     119             :   krb5_auth_con_setlocalseqnumber (context,
     120             :                                ctx->auth_context,
     121             :                                ++seq_number);
     122             :   HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
     123             : 
     124             :   memset_s(deskey, sizeof(deskey), 0, sizeof(deskey));
     125             :   memset_s(&schedule, sizeof(schedule), 0, sizeof(schedule));
     126             : 
     127             :   *minor_status = 0;
     128             :   return GSS_S_COMPLETE;
     129             : }
     130             : #endif
     131             : 
     132             : static OM_uint32
     133           0 : mic_des3
     134             :            (OM_uint32 * minor_status,
     135             :             const gsskrb5_ctx ctx,
     136             :             krb5_context context,
     137             :             gss_qop_t qop_req,
     138             :             const gss_buffer_t message_buffer,
     139             :             gss_buffer_t message_token,
     140             :             krb5_keyblock *key
     141             :            )
     142             : {
     143           0 :   u_char *p;
     144           0 :   Checksum cksum;
     145           0 :   u_char seq[8];
     146             : 
     147           0 :   int32_t seq_number;
     148           0 :   size_t len, total_len;
     149             : 
     150           0 :   krb5_crypto crypto;
     151           0 :   krb5_error_code kret;
     152           0 :   krb5_data encdata;
     153           0 :   char *tmp;
     154           0 :   char ivec[8];
     155             : 
     156           0 :   _gsskrb5_encap_length (36, &len, &total_len, GSS_KRB5_MECHANISM);
     157             : 
     158           0 :   message_token->length = total_len;
     159           0 :   message_token->value  = malloc (total_len);
     160           0 :   if (message_token->value == NULL) {
     161           0 :       message_token->length = 0;
     162           0 :       *minor_status = ENOMEM;
     163           0 :       return GSS_S_FAILURE;
     164             :   }
     165             : 
     166           0 :   p = _gsskrb5_make_header(message_token->value,
     167             :                               len,
     168             :                               "\x01\x01", /* TOK-ID */
     169             :                               GSS_KRB5_MECHANISM);
     170             : 
     171           0 :   memcpy (p, "\x04\x00", 2);  /* SGN_ALG = HMAC SHA1 DES3-KD */
     172           0 :   p += 2;
     173             : 
     174           0 :   memcpy (p, "\xff\xff\xff\xff", 4); /* filler */
     175           0 :   p += 4;
     176             : 
     177             :   /* this should be done in parts */
     178             : 
     179           0 :   tmp = malloc (message_buffer->length + 8);
     180           0 :   if (tmp == NULL) {
     181           0 :       free (message_token->value);
     182           0 :       message_token->value = NULL;
     183           0 :       message_token->length = 0;
     184           0 :       *minor_status = ENOMEM;
     185           0 :       return GSS_S_FAILURE;
     186             :   }
     187           0 :   memcpy (tmp, p - 8, 8);
     188           0 :   memcpy (tmp + 8, message_buffer->value, message_buffer->length);
     189             : 
     190           0 :   kret = krb5_crypto_init(context, key, 0, &crypto);
     191           0 :   if (kret) {
     192           0 :       free (message_token->value);
     193           0 :       message_token->value = NULL;
     194           0 :       message_token->length = 0;
     195           0 :       free (tmp);
     196           0 :       *minor_status = kret;
     197           0 :       return GSS_S_FAILURE;
     198             :   }
     199             : 
     200           0 :   kret = krb5_create_checksum (context,
     201             :                                crypto,
     202             :                                KRB5_KU_USAGE_SIGN,
     203             :                                0,
     204             :                                tmp,
     205           0 :                                message_buffer->length + 8,
     206             :                                &cksum);
     207           0 :   free (tmp);
     208           0 :   krb5_crypto_destroy (context, crypto);
     209           0 :   if (kret) {
     210           0 :       free (message_token->value);
     211           0 :       message_token->value = NULL;
     212           0 :       message_token->length = 0;
     213           0 :       *minor_status = kret;
     214           0 :       return GSS_S_FAILURE;
     215             :   }
     216             : 
     217           0 :   memcpy (p + 8, cksum.checksum.data, cksum.checksum.length);
     218             : 
     219           0 :   HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
     220             :   /* sequence number */
     221           0 :   krb5_auth_con_getlocalseqnumber (context,
     222             :                                ctx->auth_context,
     223             :                                &seq_number);
     224             : 
     225           0 :   seq[0] = (seq_number >> 0)  & 0xFF;
     226           0 :   seq[1] = (seq_number >> 8)  & 0xFF;
     227           0 :   seq[2] = (seq_number >> 16) & 0xFF;
     228           0 :   seq[3] = (seq_number >> 24) & 0xFF;
     229           0 :   memset (seq + 4,
     230           0 :           (ctx->more_flags & LOCAL) ? 0 : 0xFF,
     231             :           4);
     232             : 
     233           0 :   kret = krb5_crypto_init(context, key,
     234             :                           ETYPE_DES3_CBC_NONE, &crypto);
     235           0 :   if (kret) {
     236           0 :       free (message_token->value);
     237           0 :       message_token->value = NULL;
     238           0 :       message_token->length = 0;
     239           0 :       *minor_status = kret;
     240           0 :       return GSS_S_FAILURE;
     241             :   }
     242             : 
     243           0 :   if (ctx->more_flags & COMPAT_OLD_DES3)
     244           0 :       memset(ivec, 0, 8);
     245             :   else
     246           0 :       memcpy(ivec, p + 8, 8);
     247             : 
     248           0 :   kret = krb5_encrypt_ivec (context,
     249             :                             crypto,
     250             :                             KRB5_KU_USAGE_SEQ,
     251             :                             seq, 8, &encdata, ivec);
     252           0 :   krb5_crypto_destroy (context, crypto);
     253           0 :   if (kret) {
     254           0 :       free (message_token->value);
     255           0 :       message_token->value = NULL;
     256           0 :       message_token->length = 0;
     257           0 :       *minor_status = kret;
     258           0 :       return GSS_S_FAILURE;
     259             :   }
     260             : 
     261           0 :   assert (encdata.length == 8);
     262             : 
     263           0 :   memcpy (p, encdata.data, encdata.length);
     264           0 :   krb5_data_free (&encdata);
     265             : 
     266           0 :   krb5_auth_con_setlocalseqnumber (context,
     267             :                                ctx->auth_context,
     268             :                                ++seq_number);
     269           0 :   HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
     270             : 
     271           0 :   free_Checksum (&cksum);
     272           0 :   *minor_status = 0;
     273           0 :   return GSS_S_COMPLETE;
     274             : }
     275             : 
     276      251509 : OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic
     277             :            (OM_uint32 * minor_status,
     278             :             gss_const_ctx_id_t context_handle,
     279             :             gss_qop_t qop_req,
     280             :             const gss_buffer_t message_buffer,
     281             :             gss_buffer_t message_token
     282             :            )
     283             : {
     284         317 :   krb5_context context;
     285      251509 :   const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
     286         317 :   krb5_keyblock *key;
     287         317 :   OM_uint32 ret;
     288             : 
     289      251509 :   GSSAPI_KRB5_INIT (&context);
     290             : 
     291      251509 :   if (ctx->more_flags & IS_CFX)
     292      236340 :       return _gssapi_mic_cfx (minor_status, ctx, context, qop_req,
     293             :                               message_buffer, message_token);
     294             : 
     295           0 :   HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
     296       15169 :   ret = _gsskrb5i_get_token_key(ctx, context, &key);
     297           0 :   HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
     298       15169 :   if (ret) {
     299           0 :       *minor_status = ret;
     300           0 :       return GSS_S_FAILURE;
     301             :   }
     302             : 
     303       15169 :   switch (key->keytype) {
     304           0 :   case KRB5_ENCTYPE_DES_CBC_CRC :
     305             :   case KRB5_ENCTYPE_DES_CBC_MD4 :
     306             :   case KRB5_ENCTYPE_DES_CBC_MD5 :
     307             : #ifdef HEIM_WEAK_CRYPTO
     308             :       ret = mic_des (minor_status, ctx, context, qop_req,
     309             :                      message_buffer, message_token, key);
     310             : #else
     311           0 :       ret = GSS_S_FAILURE;
     312             : #endif
     313           0 :       break;
     314           0 :   case KRB5_ENCTYPE_DES3_CBC_MD5 :
     315             :   case KRB5_ENCTYPE_DES3_CBC_SHA1 :
     316           0 :       ret = mic_des3 (minor_status, ctx, context, qop_req,
     317             :                       message_buffer, message_token, key);
     318           0 :       break;
     319       15169 :   case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
     320             :   case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
     321       15169 :       ret = _gssapi_get_mic_arcfour (minor_status, ctx, context, qop_req,
     322             :                                      message_buffer, message_token, key);
     323       15169 :       break;
     324           0 :   default :
     325           0 :       abort();
     326           0 :       break;
     327             :   }
     328       15169 :   krb5_free_keyblock (context, key);
     329       15169 :   return ret;
     330             : }

Generated by: LCOV version 1.14