LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/krb5 - salt.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 39 183 21.3 %
Date: 2024-04-13 12:30:31 Functions: 5 12 41.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1997 - 2008 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 "krb5_locl.h"
      35             : 
      36             : /* coverity[+alloc : arg-*3] */
      37             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
      38           0 : krb5_salttype_to_string (krb5_context context,
      39             :                          krb5_enctype etype,
      40             :                          krb5_salttype stype,
      41             :                          char **string)
      42             : {
      43           0 :     struct _krb5_encryption_type *e;
      44           0 :     struct salt_type *st;
      45             : 
      46           0 :     *string = NULL;
      47           0 :     e = _krb5_find_enctype (etype);
      48           0 :     if (e == NULL) {
      49           0 :         krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
      50             :                                "encryption type %d not supported",
      51             :                                etype);
      52           0 :         return KRB5_PROG_ETYPE_NOSUPP;
      53             :     }
      54           0 :     for (st = e->keytype->string_to_key; st && st->type; st++) {
      55           0 :         if (st->type == stype) {
      56           0 :             *string = strdup (st->name);
      57           0 :             if (*string == NULL)
      58           0 :                 return krb5_enomem(context);
      59           0 :             return 0;
      60             :         }
      61             :     }
      62           0 :     krb5_set_error_message (context, HEIM_ERR_SALTTYPE_NOSUPP,
      63             :                             "salttype %d not supported", stype);
      64           0 :     return HEIM_ERR_SALTTYPE_NOSUPP;
      65             : }
      66             : 
      67             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
      68           0 : krb5_string_to_salttype (krb5_context context,
      69             :                          krb5_enctype etype,
      70             :                          const char *string,
      71             :                          krb5_salttype *salttype)
      72             : {
      73           0 :     struct _krb5_encryption_type *e;
      74           0 :     struct salt_type *st;
      75             : 
      76           0 :     e = _krb5_find_enctype (etype);
      77           0 :     if (e == NULL) {
      78           0 :         krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
      79           0 :                                N_("encryption type %d not supported", ""),
      80             :                                etype);
      81           0 :         return KRB5_PROG_ETYPE_NOSUPP;
      82             :     }
      83           0 :     for (st = e->keytype->string_to_key; st && st->type; st++) {
      84           0 :         if (strcasecmp (st->name, string) == 0) {
      85           0 :             *salttype = st->type;
      86           0 :             return 0;
      87             :         }
      88             :     }
      89           0 :     krb5_set_error_message(context, HEIM_ERR_SALTTYPE_NOSUPP,
      90           0 :                            N_("salttype %s not supported", ""), string);
      91           0 :     return HEIM_ERR_SALTTYPE_NOSUPP;
      92             : }
      93             : 
      94             : /*
      95             :  * Like MIT's krb5_string_to_keysalts(), but simpler and with a context
      96             :  * argument.
      97             :  */
      98             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
      99           0 : krb5_string_to_keysalts2(krb5_context context, const char *string,
     100             :                          size_t *nksaltp, krb5_key_salt_tuple **ksaltp)
     101             : {
     102             :     /* deleted: tupleseps, ksaltseps, dups */
     103           0 :     krb5_key_salt_tuple *tmp = NULL;
     104           0 :     krb5_error_code ret = 0;
     105           0 :     char *copy, *token, *stype_str;
     106           0 :     char *lasts = NULL;
     107           0 :     krb5_enctype etype;
     108           0 :     krb5_salttype stype;
     109           0 :     size_t i;
     110             : 
     111           0 :     *ksaltp = NULL;
     112           0 :     *nksaltp = 0;
     113           0 :     if ((copy = strdup(string)) == NULL)
     114           0 :         return krb5_enomem(context);
     115           0 :     for (token = strtok_r(copy, ", \t", &lasts), ret = 0;
     116           0 :          token != NULL;
     117           0 :          token = strtok_r(NULL, ", \t", &lasts)) {
     118           0 :         if ((stype_str = strchr(token, ':')) != NULL)
     119           0 :             *(stype_str++) = '\0';
     120           0 :         if ((ret = krb5_string_to_enctype(context, token, &etype)))
     121           0 :             continue;
     122           0 :         if (stype_str == NULL)
     123           0 :             stype = KRB5_PW_SALT;
     124           0 :         else if ((ret = krb5_string_to_salttype(context, etype, stype_str, &stype)))
     125           0 :             continue;
     126           0 :         for (i = 0; i < *nksaltp; i++) {
     127           0 :             if ((*ksaltp)[i].ks_enctype == etype &&
     128           0 :                 (*ksaltp)[i].ks_salttype == stype)
     129           0 :                 goto skip;
     130             :         }
     131           0 :         tmp = realloc(*ksaltp, ((*nksaltp) + 1) * sizeof(**ksaltp));
     132           0 :         if (tmp == NULL) {
     133           0 :             ret = krb5_enomem(context);
     134           0 :             break;
     135             :         }
     136           0 :         *ksaltp = tmp;
     137           0 :         (*ksaltp)[*nksaltp].ks_enctype = etype;
     138           0 :         (*ksaltp)[*nksaltp].ks_salttype = stype;
     139           0 :         (*nksaltp)++;
     140           0 : skip:
     141           0 :         (void)1;
     142             :     }
     143           0 :     free(copy);
     144           0 :     if (ret == ENOMEM) {
     145           0 :         free(*ksaltp);
     146           0 :         *nksaltp = 0;
     147           0 :         *ksaltp = NULL;
     148           0 :     } else if (*nksaltp) {
     149           0 :         return 0;
     150           0 :     } else if (ret == 0) {
     151           0 :         return KRB5_PROG_ETYPE_NOSUPP;
     152             :     }
     153           0 :     return ret;
     154             : }
     155             : 
     156             : 
     157             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     158       44450 : krb5_get_pw_salt(krb5_context context,
     159             :                  krb5_const_principal principal,
     160             :                  krb5_salt *salt)
     161             : {
     162         839 :     size_t len;
     163         839 :     size_t i;
     164         839 :     krb5_error_code ret;
     165         839 :     char *p;
     166             : 
     167       44450 :     salt->salttype = KRB5_PW_SALT;
     168       44450 :     len = strlen(principal->realm);
     169      103154 :     for (i = 0; i < principal->name.name_string.len; ++i)
     170       58704 :         len += strlen(principal->name.name_string.val[i]);
     171       44450 :     ret = krb5_data_alloc (&salt->saltvalue, len);
     172       44450 :     if (ret)
     173           0 :         return ret;
     174       44450 :     p = salt->saltvalue.data;
     175       44450 :     memcpy (p, principal->realm, strlen(principal->realm));
     176       44450 :     p += strlen(principal->realm);
     177      103154 :     for (i = 0; i < principal->name.name_string.len; ++i) {
     178       58704 :         memcpy (p,
     179       57694 :                 principal->name.name_string.val[i],
     180       58704 :                 strlen(principal->name.name_string.val[i]));
     181       58704 :         p += strlen(principal->name.name_string.val[i]);
     182             :     }
     183       43611 :     return 0;
     184             : }
     185             : 
     186             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     187       83316 : krb5_free_salt(krb5_context context,
     188             :                krb5_salt salt)
     189             : {
     190       83316 :     krb5_data_free(&salt.saltvalue);
     191       83316 :     return 0;
     192             : }
     193             : 
     194             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     195           0 : krb5_string_to_key_data (krb5_context context,
     196             :                          krb5_enctype enctype,
     197             :                          krb5_data password,
     198             :                          krb5_const_principal principal,
     199             :                          krb5_keyblock *key)
     200             : {
     201           0 :     krb5_error_code ret;
     202           0 :     krb5_salt salt;
     203             : 
     204           0 :     ret = krb5_get_pw_salt(context, principal, &salt);
     205           0 :     if(ret)
     206           0 :         return ret;
     207           0 :     ret = krb5_string_to_key_data_salt(context, enctype, password, salt, key);
     208           0 :     krb5_free_salt(context, salt);
     209           0 :     return ret;
     210             : }
     211             : 
     212             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     213           0 : krb5_string_to_key (krb5_context context,
     214             :                     krb5_enctype enctype,
     215             :                     const char *password,
     216             :                     krb5_const_principal principal,
     217             :                     krb5_keyblock *key)
     218             : {
     219           0 :     krb5_data pw;
     220           0 :     pw.data = rk_UNCONST(password);
     221           0 :     pw.length = strlen(password);
     222           0 :     return krb5_string_to_key_data(context, enctype, pw, principal, key);
     223             : }
     224             : 
     225             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     226       57671 : krb5_string_to_key_data_salt (krb5_context context,
     227             :                               krb5_enctype enctype,
     228             :                               krb5_data password,
     229             :                               krb5_salt salt,
     230             :                               krb5_keyblock *key)
     231             : {
     232         482 :     krb5_data opaque;
     233       57671 :     krb5_data_zero(&opaque);
     234       57671 :     return krb5_string_to_key_data_salt_opaque(context, enctype, password,
     235             :                                                salt, opaque, key);
     236             : }
     237             : 
     238             : /*
     239             :  * Do a string -> key for encryption type `enctype' operation on
     240             :  * `password' (with salt `salt' and the enctype specific data string
     241             :  * `opaque'), returning the resulting key in `key'
     242             :  */
     243             : 
     244             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     245       85419 : krb5_string_to_key_data_salt_opaque (krb5_context context,
     246             :                                      krb5_enctype enctype,
     247             :                                      krb5_data password,
     248             :                                      krb5_salt salt,
     249             :                                      krb5_data opaque,
     250             :                                      krb5_keyblock *key)
     251             : {
     252       85419 :     struct _krb5_encryption_type *et =_krb5_find_enctype(enctype);
     253        1646 :     struct salt_type *st;
     254       85419 :     if(et == NULL) {
     255           0 :         krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP,
     256           0 :                                N_("encryption type %d not supported", ""),
     257             :                                enctype);
     258           0 :         return KRB5_PROG_ETYPE_NOSUPP;
     259             :     }
     260       85419 :     for(st = et->keytype->string_to_key; st && st->type; st++)
     261       85419 :         if(st->type == salt.salttype)
     262       85419 :             return (*st->string_to_key)(context, enctype, password,
     263             :                                         salt, opaque, key);
     264           0 :     krb5_set_error_message(context, HEIM_ERR_SALTTYPE_NOSUPP,
     265           0 :                            N_("salt type %d not supported", ""),
     266           0 :                            salt.salttype);
     267           0 :     return HEIM_ERR_SALTTYPE_NOSUPP;
     268             : }
     269             : 
     270             : /*
     271             :  * Do a string -> key for encryption type `enctype' operation on the
     272             :  * string `password' (with salt `salt'), returning the resulting key
     273             :  * in `key'
     274             :  */
     275             : 
     276             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     277       57671 : krb5_string_to_key_salt (krb5_context context,
     278             :                          krb5_enctype enctype,
     279             :                          const char *password,
     280             :                          krb5_salt salt,
     281             :                          krb5_keyblock *key)
     282             : {
     283         482 :     krb5_data pw;
     284       57671 :     pw.data = rk_UNCONST(password);
     285       57671 :     pw.length = strlen(password);
     286       57671 :     return krb5_string_to_key_data_salt(context, enctype, pw, salt, key);
     287             : }
     288             : 
     289             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     290           0 : krb5_string_to_key_salt_opaque (krb5_context context,
     291             :                                 krb5_enctype enctype,
     292             :                                 const char *password,
     293             :                                 krb5_salt salt,
     294             :                                 krb5_data opaque,
     295             :                                 krb5_keyblock *key)
     296             : {
     297           0 :     krb5_data pw;
     298           0 :     pw.data = rk_UNCONST(password);
     299           0 :     pw.length = strlen(password);
     300           0 :     return krb5_string_to_key_data_salt_opaque(context, enctype,
     301             :                                                pw, salt, opaque, key);
     302             : }
     303             : 
     304             : 
     305             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     306           0 : krb5_string_to_key_derived(krb5_context context,
     307             :                            const void *str,
     308             :                            size_t len,
     309             :                            krb5_enctype etype,
     310             :                            krb5_keyblock *key)
     311             : {
     312           0 :     struct _krb5_encryption_type *et = _krb5_find_enctype(etype);
     313           0 :     krb5_error_code ret;
     314           0 :     struct _krb5_key_data kd;
     315           0 :     size_t keylen;
     316           0 :     u_char *tmp;
     317             : 
     318           0 :     if(et == NULL) {
     319           0 :         krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP,
     320           0 :                                 N_("encryption type %d not supported", ""),
     321             :                                 etype);
     322           0 :         return KRB5_PROG_ETYPE_NOSUPP;
     323             :     }
     324           0 :     keylen = et->keytype->bits / 8;
     325             : 
     326           0 :     ALLOC(kd.key, 1);
     327           0 :     if (kd.key == NULL)
     328           0 :         return krb5_enomem(context);
     329           0 :     ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size);
     330           0 :     if(ret) {
     331           0 :         free(kd.key);
     332           0 :         return ret;
     333             :     }
     334           0 :     kd.key->keytype = etype;
     335           0 :     tmp = malloc (keylen);
     336           0 :     if(tmp == NULL) {
     337           0 :         krb5_free_keyblock(context, kd.key);
     338           0 :         return krb5_enomem(context);
     339             :     }
     340           0 :     ret = _krb5_n_fold(str, len, tmp, keylen);
     341           0 :     if (ret) {
     342           0 :         free(tmp);
     343           0 :         krb5_enomem(context);
     344           0 :         return ret;
     345             :     }
     346           0 :     kd.schedule = NULL;
     347           0 :     _krb5_DES3_random_to_key(context, kd.key, tmp, keylen);
     348           0 :     memset(tmp, 0, keylen);
     349           0 :     free(tmp);
     350           0 :     ret = _krb5_derive_key(context,
     351             :                            et,
     352             :                            &kd,
     353             :                            "kerberos", /* XXX well known constant */
     354             :                            strlen("kerberos"));
     355           0 :     if (ret) {
     356           0 :         _krb5_free_key_data(context, &kd, et);
     357           0 :         return ret;
     358             :     }
     359           0 :     ret = krb5_copy_keyblock_contents(context, kd.key, key);
     360           0 :     _krb5_free_key_data(context, &kd, et);
     361           0 :     return ret;
     362             : }

Generated by: LCOV version 1.14