1/* 2 * Copyright (c) 2008-2010 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2008-2010 Apple Inc. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#define KRB5_OLD_CRYPTO 1 37 38#include "heim.h" 39#include <string.h> 40 41 42mit_krb5_error_code KRB5_CALLCONV 43krb5_c_string_to_key(mit_krb5_context context, 44 mit_krb5_enctype enctype, 45 const mit_krb5_data *string, 46 const mit_krb5_data *salt, 47 mit_krb5_keyblock *key) 48{ 49 krb5_data hstring; 50 krb5_error_code ret; 51 krb5_salt hsalt; 52 krb5_keyblock hkey; 53 54 LOG_ENTRY(); 55 56 mshim_mdata2hdata(string, &hstring); 57 hsalt.salttype = (krb5_salttype)KRB5_PADATA_PW_SALT; 58 mshim_mdata2hdata(salt, &hsalt.saltvalue); 59 60 ret = heim_krb5_string_to_key_data_salt(HC(context), enctype, 61 hstring, hsalt, &hkey); 62 heim_krb5_data_free(&hstring); 63 heim_krb5_data_free(&hsalt.saltvalue); 64 if (ret) 65 return ret; 66 67 mshim_hkeyblock2mkeyblock(&hkey, key); 68 heim_krb5_free_keyblock_contents(HC(context), &hkey); 69 return 0; 70} 71 72mit_krb5_error_code KRB5_CALLCONV 73krb5_string_to_key(mit_krb5_context context, 74 const mit_krb5_encrypt_block * eblock, 75 mit_krb5_keyblock * keyblock, 76 const mit_krb5_data * data, 77 const mit_krb5_data * salt) 78{ 79 LOG_ENTRY(); 80 return krb5_c_string_to_key(context, 81 eblock->crypto_entry, 82 data, 83 salt, 84 keyblock); 85} 86 87 88mit_krb5_error_code KRB5_CALLCONV 89krb5_principal2salt(mit_krb5_context context, 90 mit_krb5_const_principal principal, 91 mit_krb5_data *salt) 92{ 93 struct comb_principal *c = (struct comb_principal *)principal; 94 krb5_error_code ret; 95 krb5_salt hsalt; 96 97 memset(salt, 0, sizeof(*salt)); 98 99 ret = heim_krb5_get_pw_salt(HC(context), c->heim, &hsalt); 100 if (ret) 101 return ret; 102 mshim_hdata2mdata(&hsalt.saltvalue, salt); 103 heim_krb5_free_salt(HC(context), hsalt); 104 return 0; 105} 106 107 108mit_krb5_error_code KRB5_CALLCONV 109krb5_set_default_tgs_ktypes(mit_krb5_context, const mit_krb5_enctype *); 110 111 112mit_krb5_error_code KRB5_CALLCONV 113krb5_set_default_tgs_ktypes(mit_krb5_context context, 114 const mit_krb5_enctype *enc) 115{ 116 LOG_ENTRY(); 117 return heim_krb5_set_default_in_tkt_etypes(HC(context), (krb5_enctype *)enc); 118} 119 120mit_krb5_error_code KRB5_CALLCONV 121krb5_set_default_tgs_enctypes(mit_krb5_context context, 122 const mit_krb5_enctype *enc) 123{ 124 LOG_ENTRY(); 125 return heim_krb5_set_default_in_tkt_etypes(HC(context), (krb5_enctype *)enc); 126} 127 128krb5_error_code KRB5_CALLCONV 129krb5_use_enctype(mit_krb5_context context, 130 mit_krb5_encrypt_block *encrypt_block, 131 mit_krb5_enctype enctype) 132{ 133 LOG_ENTRY(); 134 encrypt_block->crypto_entry = enctype; 135 return 0; 136} 137 138mit_krb5_error_code KRB5_CALLCONV 139krb5_c_decrypt(mit_krb5_context context, 140 const mit_krb5_keyblock *key, 141 mit_krb5_keyusage usage, 142 const mit_krb5_data *ivec, 143 const mit_krb5_enc_data *input, 144 mit_krb5_data *output) 145{ 146 krb5_error_code ret; 147 krb5_crypto crypto; 148 krb5_keyblock keyblock; 149 krb5_data odata; 150 151 LOG_ENTRY(); 152 153 mshim_mkeyblock2hkeyblock(key, &keyblock); 154 155 ret = heim_krb5_crypto_init(HC(context), &keyblock, input->enctype, &crypto); 156 heim_krb5_free_keyblock_contents(HC(context), &keyblock); 157 if (ret) 158 return ret; 159 160 if (ivec) { 161 size_t blocksize; 162 163 ret = heim_krb5_crypto_getblocksize(HC(context), crypto, &blocksize); 164 if (ret) { 165 heim_krb5_crypto_destroy(HC(context), crypto); 166 return ret; 167 } 168 169 if (blocksize > ivec->length) { 170 heim_krb5_crypto_destroy(HC(context), crypto); 171 return KRB5_BAD_MSIZE; 172 } 173 } 174 175 ret = heim_krb5_decrypt_ivec(HC(context), crypto, usage, 176 input->ciphertext.data, input->ciphertext.length, 177 &odata, 178 ivec ? (void *)ivec->data : NULL); 179 180 heim_krb5_crypto_destroy(HC(context), crypto); 181 if (ret == 0) { 182 mshim_hdata2mdata(&odata, output); 183 heim_krb5_data_free(&odata); 184 } 185 186 return ret ; 187} 188 189mit_krb5_error_code KRB5_CALLCONV 190krb5_c_encrypt(mit_krb5_context context, 191 const mit_krb5_keyblock *key, 192 mit_krb5_keyusage usage, 193 const mit_krb5_data *ivec, 194 const mit_krb5_data *input, 195 mit_krb5_enc_data *output) 196{ 197 LOG_ENTRY(); 198 krb5_error_code ret; 199 krb5_crypto crypto; 200 krb5_keyblock keyblock; 201 krb5_data odata; 202 203 mshim_mkeyblock2hkeyblock(key, &keyblock); 204 205 ret = heim_krb5_crypto_init(HC(context), &keyblock, 0, &crypto); 206 heim_krb5_free_keyblock_contents(HC(context), &keyblock); 207 if (ret) 208 return ret; 209 210 if (ivec) { 211 size_t blocksize; 212 213 ret = heim_krb5_crypto_getblocksize(HC(context), crypto, &blocksize); 214 if (ret) { 215 heim_krb5_crypto_destroy(HC(context), crypto); 216 return ret; 217 } 218 219 if (blocksize > ivec->length) { 220 heim_krb5_crypto_destroy(HC(context), crypto); 221 return KRB5_BAD_MSIZE; 222 } 223 } 224 225 ret = heim_krb5_encrypt_ivec(HC(context), crypto, usage, 226 input->data, input->length, 227 &odata, 228 ivec ? ivec->data : NULL); 229// output->magic = KV5M_ENC_DATA; 230 output->kvno = 0; 231 if (ret == 0) { 232 heim_krb5_crypto_getenctype(HC(context), crypto, &output->enctype); 233 mshim_hdata2mdata(&odata, &output->ciphertext); 234 heim_krb5_data_free(&odata); 235 } 236 heim_krb5_crypto_destroy(HC(context), crypto); 237 238 return ret ; 239} 240 241mit_krb5_error_code KRB5_CALLCONV 242krb5_c_encrypt_length(mit_krb5_context context, 243 mit_krb5_enctype enctype, 244 size_t inputlen, size_t *length) 245{ 246 LOG_ENTRY(); 247 krb5_error_code ret; 248 krb5_crypto crypto; 249 krb5_keyblock key; 250 251 ret = heim_krb5_generate_random_keyblock(HC(context), enctype, &key); 252 if (ret) 253 return ret; 254 255 ret = heim_krb5_crypto_init(HC(context), &key, 0, &crypto); 256 heim_krb5_free_keyblock_contents(HC(context), &key); 257 if (ret) 258 return ret; 259 260 *length = heim_krb5_get_wrapped_length(HC(context), crypto, inputlen); 261 heim_krb5_crypto_destroy(HC(context), crypto); 262 263 return 0; 264} 265 266mit_krb5_error_code KRB5_CALLCONV 267krb5_change_password(mit_krb5_context context, 268 mit_krb5_creds *creds, 269 char *newpw, 270 int *result_code, 271 mit_krb5_data *result_code_string, 272 mit_krb5_data *result_string) 273{ 274 LOG_ENTRY(); 275 return krb5_set_password(context, creds, newpw, NULL, result_code, result_code_string, result_string); 276} 277