172445Sassar/* 2233294Sstas * Copyright (c) 2000 - 2004 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 572445Sassar * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 972445Sassar * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1272445Sassar * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1672445Sassar * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2072445Sassar * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3272445Sassar */ 3372445Sassar 3472445Sassar#include "hdb_locl.h" 3572445Sassar#ifndef O_BINARY 3672445Sassar#define O_BINARY 0 3772445Sassar#endif 3872445Sassar 3972445Sassarstruct hdb_master_key_data { 4072445Sassar krb5_keytab_entry keytab; 4172445Sassar krb5_crypto crypto; 4272445Sassar struct hdb_master_key_data *next; 4372445Sassar}; 4472445Sassar 4572445Sassarvoid 4672445Sassarhdb_free_master_key(krb5_context context, hdb_master_key mkey) 4772445Sassar{ 4872445Sassar struct hdb_master_key_data *ptr; 4972445Sassar while(mkey) { 5072445Sassar krb5_kt_free_entry(context, &mkey->keytab); 5190926Snectar if (mkey->crypto) 5290926Snectar krb5_crypto_destroy(context, mkey->crypto); 5372445Sassar ptr = mkey; 5472445Sassar mkey = mkey->next; 5572445Sassar free(ptr); 5672445Sassar } 5772445Sassar} 5872445Sassar 5972445Sassarkrb5_error_code 6072445Sassarhdb_process_master_key(krb5_context context, 6172445Sassar int kvno, krb5_keyblock *key, krb5_enctype etype, 6272445Sassar hdb_master_key *mkey) 6372445Sassar{ 6472445Sassar krb5_error_code ret; 6590926Snectar 6672445Sassar *mkey = calloc(1, sizeof(**mkey)); 6790926Snectar if(*mkey == NULL) { 68233294Sstas krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 6972445Sassar return ENOMEM; 7090926Snectar } 7172445Sassar (*mkey)->keytab.vno = kvno; 7272445Sassar ret = krb5_parse_name(context, "K/M", &(*mkey)->keytab.principal); 7390926Snectar if(ret) 7490926Snectar goto fail; 7572445Sassar ret = krb5_copy_keyblock_contents(context, key, &(*mkey)->keytab.keyblock); 7690926Snectar if(ret) 7790926Snectar goto fail; 7872445Sassar if(etype != 0) 7972445Sassar (*mkey)->keytab.keyblock.keytype = etype; 8072445Sassar (*mkey)->keytab.timestamp = time(NULL); 8172445Sassar ret = krb5_crypto_init(context, key, etype, &(*mkey)->crypto); 8290926Snectar if(ret) 8390926Snectar goto fail; 8490926Snectar return 0; 8590926Snectar fail: 8690926Snectar hdb_free_master_key(context, *mkey); 8790926Snectar *mkey = NULL; 8872445Sassar return ret; 8972445Sassar} 9072445Sassar 9172445Sassarkrb5_error_code 9272445Sassarhdb_add_master_key(krb5_context context, krb5_keyblock *key, 9372445Sassar hdb_master_key *inout) 9472445Sassar{ 9572445Sassar int vno = 0; 9672445Sassar hdb_master_key p; 9772445Sassar krb5_error_code ret; 9872445Sassar 9972445Sassar for(p = *inout; p; p = p->next) 10072445Sassar vno = max(vno, p->keytab.vno); 10172445Sassar vno++; 10272445Sassar ret = hdb_process_master_key(context, vno, key, 0, &p); 10372445Sassar if(ret) 10472445Sassar return ret; 10572445Sassar p->next = *inout; 10672445Sassar *inout = p; 10772445Sassar return 0; 10872445Sassar} 10972445Sassar 11072445Sassarstatic krb5_error_code 111233294Sstasread_master_keytab(krb5_context context, const char *filename, 11272445Sassar hdb_master_key *mkey) 11372445Sassar{ 11472445Sassar krb5_error_code ret; 11572445Sassar krb5_keytab id; 11672445Sassar krb5_kt_cursor cursor; 11772445Sassar krb5_keytab_entry entry; 11872445Sassar hdb_master_key p; 119233294Sstas 12072445Sassar ret = krb5_kt_resolve(context, filename, &id); 12172445Sassar if(ret) 12272445Sassar return ret; 12372445Sassar 12472445Sassar ret = krb5_kt_start_seq_get(context, id, &cursor); 12572445Sassar if(ret) 12672445Sassar goto out; 12772445Sassar *mkey = NULL; 12872445Sassar while(krb5_kt_next_entry(context, id, &entry, &cursor) == 0) { 12972445Sassar p = calloc(1, sizeof(*p)); 130178825Sdfr if(p == NULL) { 131178825Sdfr krb5_kt_end_seq_get(context, id, &cursor); 132178825Sdfr ret = ENOMEM; 133178825Sdfr goto out; 134178825Sdfr } 13572445Sassar p->keytab = entry; 13672445Sassar ret = krb5_crypto_init(context, &p->keytab.keyblock, 0, &p->crypto); 13772445Sassar p->next = *mkey; 13872445Sassar *mkey = p; 13972445Sassar } 14072445Sassar krb5_kt_end_seq_get(context, id, &cursor); 14172445Sassar out: 14272445Sassar krb5_kt_close(context, id); 14372445Sassar return ret; 14472445Sassar} 14572445Sassar 14672445Sassar/* read a MIT master keyfile */ 14772445Sassarstatic krb5_error_code 148233294Sstasread_master_mit(krb5_context context, const char *filename, 149233294Sstas int byteorder, hdb_master_key *mkey) 15072445Sassar{ 15172445Sassar int fd; 15272445Sassar krb5_error_code ret; 15372445Sassar krb5_storage *sp; 154178825Sdfr int16_t enctype; 15572445Sassar krb5_keyblock key; 156233294Sstas 15772445Sassar fd = open(filename, O_RDONLY | O_BINARY); 15890926Snectar if(fd < 0) { 15990926Snectar int save_errno = errno; 160233294Sstas krb5_set_error_message(context, save_errno, "failed to open %s: %s", 161233294Sstas filename, strerror(save_errno)); 16290926Snectar return save_errno; 16390926Snectar } 16472445Sassar sp = krb5_storage_from_fd(fd); 16572445Sassar if(sp == NULL) { 16672445Sassar close(fd); 16772445Sassar return errno; 16872445Sassar } 169233294Sstas krb5_storage_set_flags(sp, byteorder); 17072445Sassar /* could possibly use ret_keyblock here, but do it with more 17172445Sassar checks for now */ 172233294Sstas { 173233294Sstas ret = krb5_ret_int16(sp, &enctype); 174233294Sstas if (ret) 175233294Sstas goto out; 176233294Sstas ret = krb5_enctype_valid(context, enctype); 177233294Sstas if (ret) 178233294Sstas goto out; 179233294Sstas key.keytype = enctype; 180233294Sstas ret = krb5_ret_data(sp, &key.keyvalue); 181233294Sstas if(ret) 182233294Sstas goto out; 18372445Sassar } 184233294Sstas ret = hdb_process_master_key(context, 1, &key, 0, mkey); 18572445Sassar krb5_free_keyblock_contents(context, &key); 18672445Sassar out: 18772445Sassar krb5_storage_free(sp); 18872445Sassar close(fd); 18972445Sassar return ret; 19072445Sassar} 19172445Sassar 19272445Sassar/* read an old master key file */ 19372445Sassarstatic krb5_error_code 194233294Sstasread_master_encryptionkey(krb5_context context, const char *filename, 19572445Sassar hdb_master_key *mkey) 19672445Sassar{ 19772445Sassar int fd; 19872445Sassar krb5_keyblock key; 19972445Sassar krb5_error_code ret; 20072445Sassar unsigned char buf[256]; 20172445Sassar ssize_t len; 202102644Snectar size_t ret_len; 203233294Sstas 20472445Sassar fd = open(filename, O_RDONLY | O_BINARY); 20590926Snectar if(fd < 0) { 20690926Snectar int save_errno = errno; 207233294Sstas krb5_set_error_message(context, save_errno, "failed to open %s: %s", 20890926Snectar filename, strerror(save_errno)); 20990926Snectar return save_errno; 21090926Snectar } 211233294Sstas 21272445Sassar len = read(fd, buf, sizeof(buf)); 21372445Sassar close(fd); 21490926Snectar if(len < 0) { 21590926Snectar int save_errno = errno; 216233294Sstas krb5_set_error_message(context, save_errno, "error reading %s: %s", 21790926Snectar filename, strerror(save_errno)); 21890926Snectar return save_errno; 21990926Snectar } 22072445Sassar 221102644Snectar ret = decode_EncryptionKey(buf, len, &key, &ret_len); 22272445Sassar memset(buf, 0, sizeof(buf)); 22372445Sassar if(ret) 22472445Sassar return ret; 22572445Sassar 22672445Sassar /* Originally, the keytype was just that, and later it got changed 22772445Sassar to des-cbc-md5, but we always used des in cfb64 mode. This 22872445Sassar should cover all cases, but will break if someone has hacked 22972445Sassar this code to really use des-cbc-md5 -- but then that's not my 23072445Sassar problem. */ 231233294Sstas if(key.keytype == ETYPE_DES_CBC_CRC || key.keytype == ETYPE_DES_CBC_MD5) 23272445Sassar key.keytype = ETYPE_DES_CFB64_NONE; 233233294Sstas 23472445Sassar ret = hdb_process_master_key(context, 0, &key, 0, mkey); 23572445Sassar krb5_free_keyblock_contents(context, &key); 23672445Sassar return ret; 23772445Sassar} 23872445Sassar 23972445Sassar/* read a krb4 /.k style file */ 24072445Sassarstatic krb5_error_code 241233294Sstasread_master_krb4(krb5_context context, const char *filename, 24272445Sassar hdb_master_key *mkey) 24372445Sassar{ 24472445Sassar int fd; 24572445Sassar krb5_keyblock key; 24672445Sassar krb5_error_code ret; 24772445Sassar unsigned char buf[256]; 24872445Sassar ssize_t len; 249233294Sstas 25072445Sassar fd = open(filename, O_RDONLY | O_BINARY); 25190926Snectar if(fd < 0) { 25290926Snectar int save_errno = errno; 253233294Sstas krb5_set_error_message(context, save_errno, "failed to open %s: %s", 254233294Sstas filename, strerror(save_errno)); 25590926Snectar return save_errno; 25690926Snectar } 257233294Sstas 25872445Sassar len = read(fd, buf, sizeof(buf)); 25972445Sassar close(fd); 26090926Snectar if(len < 0) { 26190926Snectar int save_errno = errno; 262233294Sstas krb5_set_error_message(context, save_errno, "error reading %s: %s", 263233294Sstas filename, strerror(save_errno)); 26490926Snectar return save_errno; 26590926Snectar } 26690926Snectar if(len != 8) { 267233294Sstas krb5_set_error_message(context, HEIM_ERR_EOF, 268233294Sstas "bad contents of %s", filename); 26990926Snectar return HEIM_ERR_EOF; /* XXX file might be too large */ 27090926Snectar } 27172445Sassar 27272445Sassar memset(&key, 0, sizeof(key)); 27372445Sassar key.keytype = ETYPE_DES_PCBC_NONE; 27472445Sassar ret = krb5_data_copy(&key.keyvalue, buf, len); 27572445Sassar memset(buf, 0, sizeof(buf)); 276233294Sstas if(ret) 27772445Sassar return ret; 27872445Sassar 27972445Sassar ret = hdb_process_master_key(context, 0, &key, 0, mkey); 28072445Sassar krb5_free_keyblock_contents(context, &key); 28172445Sassar return ret; 28272445Sassar} 28372445Sassar 28472445Sassarkrb5_error_code 285233294Sstashdb_read_master_key(krb5_context context, const char *filename, 28672445Sassar hdb_master_key *mkey) 28772445Sassar{ 28872445Sassar FILE *f; 28972445Sassar unsigned char buf[16]; 29072445Sassar krb5_error_code ret; 29172445Sassar 29272445Sassar off_t len; 29372445Sassar 29472445Sassar *mkey = NULL; 29572445Sassar 29672445Sassar if(filename == NULL) 29772445Sassar filename = HDB_DB_DIR "/m-key"; 29872445Sassar 29972445Sassar f = fopen(filename, "r"); 30090926Snectar if(f == NULL) { 30190926Snectar int save_errno = errno; 302233294Sstas krb5_set_error_message(context, save_errno, "failed to open %s: %s", 303233294Sstas filename, strerror(save_errno)); 30490926Snectar return save_errno; 30590926Snectar } 306233294Sstas 30772445Sassar if(fread(buf, 1, 2, f) != 2) { 30872445Sassar fclose(f); 309233294Sstas krb5_set_error_message(context, HEIM_ERR_EOF, "end of file reading %s", filename); 31072445Sassar return HEIM_ERR_EOF; 31172445Sassar } 312233294Sstas 31372445Sassar fseek(f, 0, SEEK_END); 31472445Sassar len = ftell(f); 31572445Sassar 31672445Sassar if(fclose(f) != 0) 31772445Sassar return errno; 318233294Sstas 31972445Sassar if(len < 0) 32072445Sassar return errno; 321233294Sstas 32272445Sassar if(len == 8) { 32372445Sassar ret = read_master_krb4(context, filename, mkey); 32472445Sassar } else if(buf[0] == 0x30 && len <= 127 && buf[1] == len - 2) { 32572445Sassar ret = read_master_encryptionkey(context, filename, mkey); 32672445Sassar } else if(buf[0] == 5 && buf[1] >= 1 && buf[1] <= 2) { 32772445Sassar ret = read_master_keytab(context, filename, mkey); 32872445Sassar } else { 329233294Sstas /* 330233294Sstas * Check both LittleEndian and BigEndian since they key file 331233294Sstas * might be moved from a machine with diffrent byte order, or 332233294Sstas * its running on MacOS X that always uses BE master keys. 333233294Sstas */ 334233294Sstas ret = read_master_mit(context, filename, KRB5_STORAGE_BYTEORDER_LE, mkey); 335233294Sstas if (ret) 336233294Sstas ret = read_master_mit(context, filename, KRB5_STORAGE_BYTEORDER_BE, mkey); 33772445Sassar } 33872445Sassar return ret; 33972445Sassar} 34072445Sassar 34172445Sassarkrb5_error_code 342233294Sstashdb_write_master_key(krb5_context context, const char *filename, 34372445Sassar hdb_master_key mkey) 34472445Sassar{ 34572445Sassar krb5_error_code ret; 34672445Sassar hdb_master_key p; 34772445Sassar krb5_keytab kt; 34872445Sassar 34972445Sassar if(filename == NULL) 35072445Sassar filename = HDB_DB_DIR "/m-key"; 35172445Sassar 35272445Sassar ret = krb5_kt_resolve(context, filename, &kt); 35372445Sassar if(ret) 35472445Sassar return ret; 35572445Sassar 35672445Sassar for(p = mkey; p; p = p->next) { 35772445Sassar ret = krb5_kt_add_entry(context, kt, &p->keytab); 35872445Sassar } 35972445Sassar 36072445Sassar krb5_kt_close(context, kt); 36172445Sassar 36272445Sassar return ret; 36372445Sassar} 36472445Sassar 365178825Sdfrhdb_master_key 366178825Sdfr_hdb_find_master_key(uint32_t *mkvno, hdb_master_key mkey) 36772445Sassar{ 36872445Sassar hdb_master_key ret = NULL; 36972445Sassar while(mkey) { 37072445Sassar if(ret == NULL && mkey->keytab.vno == 0) 37172445Sassar ret = mkey; 372178825Sdfr if(mkvno == NULL) { 37372445Sassar if(ret == NULL || mkey->keytab.vno > ret->keytab.vno) 37472445Sassar ret = mkey; 375233294Sstas } else if((uint32_t)mkey->keytab.vno == *mkvno) 37672445Sassar return mkey; 37772445Sassar mkey = mkey->next; 37872445Sassar } 37972445Sassar return ret; 38072445Sassar} 38172445Sassar 382178825Sdfrint 383178825Sdfr_hdb_mkey_version(hdb_master_key mkey) 384178825Sdfr{ 385178825Sdfr return mkey->keytab.vno; 386178825Sdfr} 387178825Sdfr 388178825Sdfrint 389178825Sdfr_hdb_mkey_decrypt(krb5_context context, hdb_master_key key, 390178825Sdfr krb5_key_usage usage, 391178825Sdfr void *ptr, size_t size, krb5_data *res) 392178825Sdfr{ 393178825Sdfr return krb5_decrypt(context, key->crypto, usage, 394178825Sdfr ptr, size, res); 395178825Sdfr} 396178825Sdfr 397178825Sdfrint 398178825Sdfr_hdb_mkey_encrypt(krb5_context context, hdb_master_key key, 399178825Sdfr krb5_key_usage usage, 400178825Sdfr const void *ptr, size_t size, krb5_data *res) 401178825Sdfr{ 402178825Sdfr return krb5_encrypt(context, key->crypto, usage, 403178825Sdfr ptr, size, res); 404178825Sdfr} 405178825Sdfr 40672445Sassarkrb5_error_code 407233294Sstashdb_unseal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) 40872445Sassar{ 409233294Sstas 41072445Sassar krb5_error_code ret; 41172445Sassar krb5_data res; 412120945Snectar size_t keysize; 41372445Sassar 414178825Sdfr hdb_master_key key; 41572445Sassar 416178825Sdfr if(k->mkvno == NULL) 417178825Sdfr return 0; 418233294Sstas 419178825Sdfr key = _hdb_find_master_key(k->mkvno, mkey); 42072445Sassar 421178825Sdfr if (key == NULL) 422178825Sdfr return HDB_ERR_NO_MKEY; 42372445Sassar 424178825Sdfr ret = _hdb_mkey_decrypt(context, key, HDB_KU_MKEY, 425178825Sdfr k->key.keyvalue.data, 426178825Sdfr k->key.keyvalue.length, 427178825Sdfr &res); 428178825Sdfr if(ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) { 429178825Sdfr /* try to decrypt with MIT key usage */ 430178825Sdfr ret = _hdb_mkey_decrypt(context, key, 0, 431178825Sdfr k->key.keyvalue.data, 432178825Sdfr k->key.keyvalue.length, 433178825Sdfr &res); 434233294Sstas } 435178825Sdfr if (ret) 436178825Sdfr return ret; 43772445Sassar 438178825Sdfr /* fixup keylength if the key got padded when encrypting it */ 439178825Sdfr ret = krb5_enctype_keysize(context, k->key.keytype, &keysize); 440178825Sdfr if (ret) { 441178825Sdfr krb5_data_free(&res); 442178825Sdfr return ret; 443178825Sdfr } 444178825Sdfr if (keysize > res.length) { 445178825Sdfr krb5_data_free(&res); 446178825Sdfr return KRB5_BAD_KEYSIZE; 447178825Sdfr } 44872445Sassar 449178825Sdfr memset(k->key.keyvalue.data, 0, k->key.keyvalue.length); 450178825Sdfr free(k->key.keyvalue.data); 451178825Sdfr k->key.keyvalue = res; 452178825Sdfr k->key.keyvalue.length = keysize; 453178825Sdfr free(k->mkvno); 454178825Sdfr k->mkvno = NULL; 455178825Sdfr 456178825Sdfr return 0; 457178825Sdfr} 458178825Sdfr 459178825Sdfrkrb5_error_code 460178825Sdfrhdb_unseal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey) 461178825Sdfr{ 462233294Sstas size_t i; 463178825Sdfr 464178825Sdfr for(i = 0; i < ent->keys.len; i++){ 465178825Sdfr krb5_error_code ret; 466178825Sdfr 467178825Sdfr ret = hdb_unseal_key_mkey(context, &ent->keys.val[i], mkey); 468233294Sstas if (ret) 469120945Snectar return ret; 47072445Sassar } 47172445Sassar return 0; 47272445Sassar} 47372445Sassar 47472445Sassarkrb5_error_code 47572445Sassarhdb_unseal_keys(krb5_context context, HDB *db, hdb_entry *ent) 47672445Sassar{ 477178825Sdfr if (db->hdb_master_key_set == 0) 47872445Sassar return 0; 479178825Sdfr return hdb_unseal_keys_mkey(context, ent, db->hdb_master_key); 48072445Sassar} 48172445Sassar 48272445Sassarkrb5_error_code 483178825Sdfrhdb_unseal_key(krb5_context context, HDB *db, Key *k) 48472445Sassar{ 485178825Sdfr if (db->hdb_master_key_set == 0) 486178825Sdfr return 0; 487178825Sdfr return hdb_unseal_key_mkey(context, k, db->hdb_master_key); 488178825Sdfr} 489178825Sdfr 490178825Sdfrkrb5_error_code 491178825Sdfrhdb_seal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) 492178825Sdfr{ 49372445Sassar krb5_error_code ret; 49472445Sassar krb5_data res; 495178825Sdfr hdb_master_key key; 49672445Sassar 497178825Sdfr if(k->mkvno != NULL) 498178825Sdfr return 0; 49972445Sassar 500178825Sdfr key = _hdb_find_master_key(k->mkvno, mkey); 50172445Sassar 502178825Sdfr if (key == NULL) 503178825Sdfr return HDB_ERR_NO_MKEY; 50472445Sassar 505178825Sdfr ret = _hdb_mkey_encrypt(context, key, HDB_KU_MKEY, 506178825Sdfr k->key.keyvalue.data, 507178825Sdfr k->key.keyvalue.length, 508178825Sdfr &res); 509178825Sdfr if (ret) 510178825Sdfr return ret; 51172445Sassar 512178825Sdfr memset(k->key.keyvalue.data, 0, k->key.keyvalue.length); 513178825Sdfr free(k->key.keyvalue.data); 514178825Sdfr k->key.keyvalue = res; 51572445Sassar 516178825Sdfr if (k->mkvno == NULL) { 51772445Sassar k->mkvno = malloc(sizeof(*k->mkvno)); 51872445Sassar if (k->mkvno == NULL) 51972445Sassar return ENOMEM; 52072445Sassar } 521178825Sdfr *k->mkvno = key->keytab.vno; 522233294Sstas 52372445Sassar return 0; 52472445Sassar} 52572445Sassar 52672445Sassarkrb5_error_code 527178825Sdfrhdb_seal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey) 528178825Sdfr{ 529233294Sstas size_t i; 530178825Sdfr for(i = 0; i < ent->keys.len; i++){ 531178825Sdfr krb5_error_code ret; 532178825Sdfr 533178825Sdfr ret = hdb_seal_key_mkey(context, &ent->keys.val[i], mkey); 534178825Sdfr if (ret) 535178825Sdfr return ret; 536178825Sdfr } 537178825Sdfr return 0; 538178825Sdfr} 539178825Sdfr 540178825Sdfrkrb5_error_code 54172445Sassarhdb_seal_keys(krb5_context context, HDB *db, hdb_entry *ent) 54272445Sassar{ 543178825Sdfr if (db->hdb_master_key_set == 0) 54472445Sassar return 0; 545233294Sstas 546178825Sdfr return hdb_seal_keys_mkey(context, ent, db->hdb_master_key); 54772445Sassar} 54872445Sassar 54972445Sassarkrb5_error_code 550178825Sdfrhdb_seal_key(krb5_context context, HDB *db, Key *k) 551178825Sdfr{ 552178825Sdfr if (db->hdb_master_key_set == 0) 553178825Sdfr return 0; 554233294Sstas 555178825Sdfr return hdb_seal_key_mkey(context, k, db->hdb_master_key); 556178825Sdfr} 557178825Sdfr 558178825Sdfrkrb5_error_code 55972445Sassarhdb_set_master_key (krb5_context context, 56072445Sassar HDB *db, 56172445Sassar krb5_keyblock *key) 56272445Sassar{ 56372445Sassar krb5_error_code ret; 56472445Sassar hdb_master_key mkey; 56572445Sassar 56672445Sassar ret = hdb_process_master_key(context, 0, key, 0, &mkey); 56772445Sassar if (ret) 56872445Sassar return ret; 569178825Sdfr db->hdb_master_key = mkey; 57072445Sassar#if 0 /* XXX - why? */ 57172445Sassar des_set_random_generator_seed(key.keyvalue.data); 57272445Sassar#endif 573178825Sdfr db->hdb_master_key_set = 1; 57472445Sassar return 0; 57572445Sassar} 57672445Sassar 57772445Sassarkrb5_error_code 57872445Sassarhdb_set_master_keyfile (krb5_context context, 57972445Sassar HDB *db, 58072445Sassar const char *keyfile) 58172445Sassar{ 58272445Sassar hdb_master_key key; 58372445Sassar krb5_error_code ret; 58472445Sassar 58572445Sassar ret = hdb_read_master_key(context, keyfile, &key); 58672445Sassar if (ret) { 58772445Sassar if (ret != ENOENT) 58872445Sassar return ret; 589233294Sstas krb5_clear_error_message(context); 59072445Sassar return 0; 59172445Sassar } 592178825Sdfr db->hdb_master_key = key; 593178825Sdfr db->hdb_master_key_set = 1; 59472445Sassar return ret; 59572445Sassar} 59672445Sassar 59772445Sassarkrb5_error_code 59872445Sassarhdb_clear_master_key (krb5_context context, 59972445Sassar HDB *db) 60072445Sassar{ 601178825Sdfr if (db->hdb_master_key_set) { 602178825Sdfr hdb_free_master_key(context, db->hdb_master_key); 603178825Sdfr db->hdb_master_key_set = 0; 60472445Sassar } 60572445Sassar return 0; 60672445Sassar} 607