172445Sassar/* 2178825Sdfr * Copyright (c) 2000 - 2004 Kungliga Tekniska H�gskolan 372445Sassar * (Royal Institute of Technology, Stockholm, Sweden). 472445Sassar * All rights reserved. 572445Sassar * 672445Sassar * Redistribution and use in source and binary forms, with or without 772445Sassar * modification, are permitted provided that the following conditions 872445Sassar * are met: 972445Sassar * 1072445Sassar * 1. Redistributions of source code must retain the above copyright 1172445Sassar * notice, this list of conditions and the following disclaimer. 1272445Sassar * 1372445Sassar * 2. Redistributions in binary form must reproduce the above copyright 1472445Sassar * notice, this list of conditions and the following disclaimer in the 1572445Sassar * documentation and/or other materials provided with the distribution. 1672445Sassar * 1772445Sassar * 3. Neither the name of the Institute nor the names of its contributors 1872445Sassar * may be used to endorse or promote products derived from this software 1972445Sassar * without specific prior written permission. 2072445Sassar * 2172445Sassar * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2272445Sassar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2372445Sassar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2472445Sassar * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2572445Sassar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2672445Sassar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2772445Sassar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2872445Sassar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2972445Sassar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3072445Sassar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3172445Sassar * SUCH DAMAGE. 3272445Sassar */ 3372445Sassar 3472445Sassar#include "hdb_locl.h" 3572445Sassar#ifndef O_BINARY 3672445Sassar#define O_BINARY 0 3772445Sassar#endif 3872445Sassar 39178825SdfrRCSID("$Id: mkey.c 21745 2007-07-31 16:11:25Z lha $"); 4072445Sassar 4172445Sassarstruct hdb_master_key_data { 4272445Sassar krb5_keytab_entry keytab; 4372445Sassar krb5_crypto crypto; 4472445Sassar struct hdb_master_key_data *next; 4572445Sassar}; 4672445Sassar 4772445Sassarvoid 4872445Sassarhdb_free_master_key(krb5_context context, hdb_master_key mkey) 4972445Sassar{ 5072445Sassar struct hdb_master_key_data *ptr; 5172445Sassar while(mkey) { 5272445Sassar krb5_kt_free_entry(context, &mkey->keytab); 5390926Snectar if (mkey->crypto) 5490926Snectar krb5_crypto_destroy(context, mkey->crypto); 5572445Sassar ptr = mkey; 5672445Sassar mkey = mkey->next; 5772445Sassar free(ptr); 5872445Sassar } 5972445Sassar} 6072445Sassar 6172445Sassarkrb5_error_code 6272445Sassarhdb_process_master_key(krb5_context context, 6372445Sassar int kvno, krb5_keyblock *key, krb5_enctype etype, 6472445Sassar hdb_master_key *mkey) 6572445Sassar{ 6672445Sassar krb5_error_code ret; 6790926Snectar 6872445Sassar *mkey = calloc(1, sizeof(**mkey)); 6990926Snectar if(*mkey == NULL) { 7090926Snectar krb5_set_error_string(context, "malloc: out of memory"); 7172445Sassar return ENOMEM; 7290926Snectar } 7372445Sassar (*mkey)->keytab.vno = kvno; 7472445Sassar ret = krb5_parse_name(context, "K/M", &(*mkey)->keytab.principal); 7590926Snectar if(ret) 7690926Snectar goto fail; 7772445Sassar ret = krb5_copy_keyblock_contents(context, key, &(*mkey)->keytab.keyblock); 7890926Snectar if(ret) 7990926Snectar goto fail; 8072445Sassar if(etype != 0) 8172445Sassar (*mkey)->keytab.keyblock.keytype = etype; 8272445Sassar (*mkey)->keytab.timestamp = time(NULL); 8372445Sassar ret = krb5_crypto_init(context, key, etype, &(*mkey)->crypto); 8490926Snectar if(ret) 8590926Snectar goto fail; 8690926Snectar return 0; 8790926Snectar fail: 8890926Snectar hdb_free_master_key(context, *mkey); 8990926Snectar *mkey = NULL; 9072445Sassar return ret; 9172445Sassar} 9272445Sassar 9372445Sassarkrb5_error_code 9472445Sassarhdb_add_master_key(krb5_context context, krb5_keyblock *key, 9572445Sassar hdb_master_key *inout) 9672445Sassar{ 9772445Sassar int vno = 0; 9872445Sassar hdb_master_key p; 9972445Sassar krb5_error_code ret; 10072445Sassar 10172445Sassar for(p = *inout; p; p = p->next) 10272445Sassar vno = max(vno, p->keytab.vno); 10372445Sassar vno++; 10472445Sassar ret = hdb_process_master_key(context, vno, key, 0, &p); 10572445Sassar if(ret) 10672445Sassar return ret; 10772445Sassar p->next = *inout; 10872445Sassar *inout = p; 10972445Sassar return 0; 11072445Sassar} 11172445Sassar 11272445Sassarstatic krb5_error_code 11372445Sassarread_master_keytab(krb5_context context, const char *filename, 11472445Sassar hdb_master_key *mkey) 11572445Sassar{ 11672445Sassar krb5_error_code ret; 11772445Sassar krb5_keytab id; 11872445Sassar krb5_kt_cursor cursor; 11972445Sassar krb5_keytab_entry entry; 12072445Sassar hdb_master_key p; 12172445Sassar 12272445Sassar ret = krb5_kt_resolve(context, filename, &id); 12372445Sassar if(ret) 12472445Sassar return ret; 12572445Sassar 12672445Sassar ret = krb5_kt_start_seq_get(context, id, &cursor); 12772445Sassar if(ret) 12872445Sassar goto out; 12972445Sassar *mkey = NULL; 13072445Sassar while(krb5_kt_next_entry(context, id, &entry, &cursor) == 0) { 13172445Sassar p = calloc(1, sizeof(*p)); 132178825Sdfr if(p == NULL) { 133178825Sdfr krb5_kt_end_seq_get(context, id, &cursor); 134178825Sdfr ret = ENOMEM; 135178825Sdfr goto out; 136178825Sdfr } 13772445Sassar p->keytab = entry; 13872445Sassar ret = krb5_crypto_init(context, &p->keytab.keyblock, 0, &p->crypto); 13972445Sassar p->next = *mkey; 14072445Sassar *mkey = p; 14172445Sassar } 14272445Sassar krb5_kt_end_seq_get(context, id, &cursor); 14372445Sassar out: 14472445Sassar krb5_kt_close(context, id); 14572445Sassar return ret; 14672445Sassar} 14772445Sassar 14872445Sassar/* read a MIT master keyfile */ 14972445Sassarstatic krb5_error_code 15072445Sassarread_master_mit(krb5_context context, const char *filename, 15172445Sassar hdb_master_key *mkey) 15272445Sassar{ 15372445Sassar int fd; 15472445Sassar krb5_error_code ret; 15572445Sassar krb5_storage *sp; 156178825Sdfr int16_t enctype; 15772445Sassar krb5_keyblock key; 15872445Sassar 15972445Sassar fd = open(filename, O_RDONLY | O_BINARY); 16090926Snectar if(fd < 0) { 16190926Snectar int save_errno = errno; 16290926Snectar krb5_set_error_string(context, "failed to open %s: %s", filename, 16390926Snectar strerror(save_errno)); 16490926Snectar return save_errno; 16590926Snectar } 16672445Sassar sp = krb5_storage_from_fd(fd); 16772445Sassar if(sp == NULL) { 16872445Sassar close(fd); 16972445Sassar return errno; 17072445Sassar } 17172445Sassar krb5_storage_set_flags(sp, KRB5_STORAGE_HOST_BYTEORDER); 17272445Sassar#if 0 17372445Sassar /* could possibly use ret_keyblock here, but do it with more 17472445Sassar checks for now */ 17572445Sassar ret = krb5_ret_keyblock(sp, &key); 17672445Sassar#else 17772445Sassar ret = krb5_ret_int16(sp, &enctype); 17872445Sassar if((htons(enctype) & 0xff00) == 0x3000) { 17990926Snectar krb5_set_error_string(context, "unknown keytype in %s: %#x, expected %#x", 18090926Snectar filename, htons(enctype), 0x3000); 18172445Sassar ret = HEIM_ERR_BAD_MKEY; 18272445Sassar goto out; 18372445Sassar } 18472445Sassar key.keytype = enctype; 18572445Sassar ret = krb5_ret_data(sp, &key.keyvalue); 18672445Sassar if(ret) 18772445Sassar goto out; 18872445Sassar#endif 18972445Sassar ret = hdb_process_master_key(context, 0, &key, 0, mkey); 19072445Sassar krb5_free_keyblock_contents(context, &key); 19172445Sassar out: 19272445Sassar krb5_storage_free(sp); 19372445Sassar close(fd); 19472445Sassar return ret; 19572445Sassar} 19672445Sassar 19772445Sassar/* read an old master key file */ 19872445Sassarstatic krb5_error_code 19972445Sassarread_master_encryptionkey(krb5_context context, const char *filename, 20072445Sassar hdb_master_key *mkey) 20172445Sassar{ 20272445Sassar int fd; 20372445Sassar krb5_keyblock key; 20472445Sassar krb5_error_code ret; 20572445Sassar unsigned char buf[256]; 20672445Sassar ssize_t len; 207102644Snectar size_t ret_len; 20872445Sassar 20972445Sassar fd = open(filename, O_RDONLY | O_BINARY); 21090926Snectar if(fd < 0) { 21190926Snectar int save_errno = errno; 21290926Snectar krb5_set_error_string(context, "failed to open %s: %s", 21390926Snectar filename, strerror(save_errno)); 21490926Snectar return save_errno; 21590926Snectar } 21672445Sassar 21772445Sassar len = read(fd, buf, sizeof(buf)); 21872445Sassar close(fd); 21990926Snectar if(len < 0) { 22090926Snectar int save_errno = errno; 22190926Snectar krb5_set_error_string(context, "error reading %s: %s", 22290926Snectar filename, strerror(save_errno)); 22390926Snectar return save_errno; 22490926Snectar } 22572445Sassar 226102644Snectar ret = decode_EncryptionKey(buf, len, &key, &ret_len); 22772445Sassar memset(buf, 0, sizeof(buf)); 22872445Sassar if(ret) 22972445Sassar return ret; 23072445Sassar 23172445Sassar /* Originally, the keytype was just that, and later it got changed 23272445Sassar to des-cbc-md5, but we always used des in cfb64 mode. This 23372445Sassar should cover all cases, but will break if someone has hacked 23472445Sassar this code to really use des-cbc-md5 -- but then that's not my 23572445Sassar problem. */ 23672445Sassar if(key.keytype == KEYTYPE_DES || key.keytype == ETYPE_DES_CBC_MD5) 23772445Sassar key.keytype = ETYPE_DES_CFB64_NONE; 23872445Sassar 23972445Sassar ret = hdb_process_master_key(context, 0, &key, 0, mkey); 24072445Sassar krb5_free_keyblock_contents(context, &key); 24172445Sassar return ret; 24272445Sassar} 24372445Sassar 24472445Sassar/* read a krb4 /.k style file */ 24572445Sassarstatic krb5_error_code 24672445Sassarread_master_krb4(krb5_context context, const char *filename, 24772445Sassar hdb_master_key *mkey) 24872445Sassar{ 24972445Sassar int fd; 25072445Sassar krb5_keyblock key; 25172445Sassar krb5_error_code ret; 25272445Sassar unsigned char buf[256]; 25372445Sassar ssize_t len; 25472445Sassar 25572445Sassar fd = open(filename, O_RDONLY | O_BINARY); 25690926Snectar if(fd < 0) { 25790926Snectar int save_errno = errno; 25890926Snectar krb5_set_error_string(context, "failed to open %s: %s", 25990926Snectar filename, strerror(save_errno)); 26090926Snectar return save_errno; 26190926Snectar } 26272445Sassar 26372445Sassar len = read(fd, buf, sizeof(buf)); 26472445Sassar close(fd); 26590926Snectar if(len < 0) { 26690926Snectar int save_errno = errno; 26790926Snectar krb5_set_error_string(context, "error reading %s: %s", 26890926Snectar filename, strerror(save_errno)); 26990926Snectar return save_errno; 27090926Snectar } 27190926Snectar if(len != 8) { 27290926Snectar krb5_set_error_string(context, "bad contents of %s", filename); 27390926Snectar return HEIM_ERR_EOF; /* XXX file might be too large */ 27490926Snectar } 27572445Sassar 27672445Sassar memset(&key, 0, sizeof(key)); 27772445Sassar key.keytype = ETYPE_DES_PCBC_NONE; 27872445Sassar ret = krb5_data_copy(&key.keyvalue, buf, len); 27972445Sassar memset(buf, 0, sizeof(buf)); 28072445Sassar if(ret) 28172445Sassar return ret; 28272445Sassar 28372445Sassar ret = hdb_process_master_key(context, 0, &key, 0, mkey); 28472445Sassar krb5_free_keyblock_contents(context, &key); 28572445Sassar return ret; 28672445Sassar} 28772445Sassar 28872445Sassarkrb5_error_code 28972445Sassarhdb_read_master_key(krb5_context context, const char *filename, 29072445Sassar hdb_master_key *mkey) 29172445Sassar{ 29272445Sassar FILE *f; 29372445Sassar unsigned char buf[16]; 29472445Sassar krb5_error_code ret; 29572445Sassar 29672445Sassar off_t len; 29772445Sassar 29872445Sassar *mkey = NULL; 29972445Sassar 30072445Sassar if(filename == NULL) 30172445Sassar filename = HDB_DB_DIR "/m-key"; 30272445Sassar 30372445Sassar f = fopen(filename, "r"); 30490926Snectar if(f == NULL) { 30590926Snectar int save_errno = errno; 30690926Snectar krb5_set_error_string(context, "failed to open %s: %s", 30790926Snectar filename, strerror(save_errno)); 30890926Snectar return save_errno; 30990926Snectar } 31072445Sassar 31172445Sassar if(fread(buf, 1, 2, f) != 2) { 31290926Snectar krb5_set_error_string(context, "end of file reading %s", filename); 31372445Sassar fclose(f); 31472445Sassar return HEIM_ERR_EOF; 31572445Sassar } 31672445Sassar 31772445Sassar fseek(f, 0, SEEK_END); 31872445Sassar len = ftell(f); 31972445Sassar 32072445Sassar if(fclose(f) != 0) 32172445Sassar return errno; 32272445Sassar 32372445Sassar if(len < 0) 32472445Sassar return errno; 32572445Sassar 32672445Sassar if(len == 8) { 32772445Sassar ret = read_master_krb4(context, filename, mkey); 32872445Sassar } else if(buf[0] == 0x30 && len <= 127 && buf[1] == len - 2) { 32972445Sassar ret = read_master_encryptionkey(context, filename, mkey); 33072445Sassar } else if(buf[0] == 5 && buf[1] >= 1 && buf[1] <= 2) { 33172445Sassar ret = read_master_keytab(context, filename, mkey); 33272445Sassar } else { 33372445Sassar ret = read_master_mit(context, filename, mkey); 33472445Sassar } 33572445Sassar return ret; 33672445Sassar} 33772445Sassar 33872445Sassarkrb5_error_code 33972445Sassarhdb_write_master_key(krb5_context context, const char *filename, 34072445Sassar hdb_master_key mkey) 34172445Sassar{ 34272445Sassar krb5_error_code ret; 34372445Sassar hdb_master_key p; 34472445Sassar krb5_keytab kt; 34572445Sassar 34672445Sassar if(filename == NULL) 34772445Sassar filename = HDB_DB_DIR "/m-key"; 34872445Sassar 34972445Sassar ret = krb5_kt_resolve(context, filename, &kt); 35072445Sassar if(ret) 35172445Sassar return ret; 35272445Sassar 35372445Sassar for(p = mkey; p; p = p->next) { 35472445Sassar ret = krb5_kt_add_entry(context, kt, &p->keytab); 35572445Sassar } 35672445Sassar 35772445Sassar krb5_kt_close(context, kt); 35872445Sassar 35972445Sassar return ret; 36072445Sassar} 36172445Sassar 362178825Sdfrhdb_master_key 363178825Sdfr_hdb_find_master_key(uint32_t *mkvno, hdb_master_key mkey) 36472445Sassar{ 36572445Sassar hdb_master_key ret = NULL; 36672445Sassar while(mkey) { 36772445Sassar if(ret == NULL && mkey->keytab.vno == 0) 36872445Sassar ret = mkey; 369178825Sdfr if(mkvno == NULL) { 37072445Sassar if(ret == NULL || mkey->keytab.vno > ret->keytab.vno) 37172445Sassar ret = mkey; 372178825Sdfr } else if(mkey->keytab.vno == *mkvno) 37372445Sassar return mkey; 37472445Sassar mkey = mkey->next; 37572445Sassar } 37672445Sassar return ret; 37772445Sassar} 37872445Sassar 379178825Sdfrint 380178825Sdfr_hdb_mkey_version(hdb_master_key mkey) 381178825Sdfr{ 382178825Sdfr return mkey->keytab.vno; 383178825Sdfr} 384178825Sdfr 385178825Sdfrint 386178825Sdfr_hdb_mkey_decrypt(krb5_context context, hdb_master_key key, 387178825Sdfr krb5_key_usage usage, 388178825Sdfr void *ptr, size_t size, krb5_data *res) 389178825Sdfr{ 390178825Sdfr return krb5_decrypt(context, key->crypto, usage, 391178825Sdfr ptr, size, res); 392178825Sdfr} 393178825Sdfr 394178825Sdfrint 395178825Sdfr_hdb_mkey_encrypt(krb5_context context, hdb_master_key key, 396178825Sdfr krb5_key_usage usage, 397178825Sdfr const void *ptr, size_t size, krb5_data *res) 398178825Sdfr{ 399178825Sdfr return krb5_encrypt(context, key->crypto, usage, 400178825Sdfr ptr, size, res); 401178825Sdfr} 402178825Sdfr 40372445Sassarkrb5_error_code 404178825Sdfrhdb_unseal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) 40572445Sassar{ 406178825Sdfr 40772445Sassar krb5_error_code ret; 40872445Sassar krb5_data res; 409120945Snectar size_t keysize; 41072445Sassar 411178825Sdfr hdb_master_key key; 41272445Sassar 413178825Sdfr if(k->mkvno == NULL) 414178825Sdfr return 0; 415178825Sdfr 416178825Sdfr key = _hdb_find_master_key(k->mkvno, mkey); 41772445Sassar 418178825Sdfr if (key == NULL) 419178825Sdfr return HDB_ERR_NO_MKEY; 42072445Sassar 421178825Sdfr ret = _hdb_mkey_decrypt(context, key, HDB_KU_MKEY, 422178825Sdfr k->key.keyvalue.data, 423178825Sdfr k->key.keyvalue.length, 424178825Sdfr &res); 425178825Sdfr if(ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) { 426178825Sdfr /* try to decrypt with MIT key usage */ 427178825Sdfr ret = _hdb_mkey_decrypt(context, key, 0, 428178825Sdfr k->key.keyvalue.data, 429178825Sdfr k->key.keyvalue.length, 430178825Sdfr &res); 431178825Sdfr } 432178825Sdfr if (ret) 433178825Sdfr return ret; 43472445Sassar 435178825Sdfr /* fixup keylength if the key got padded when encrypting it */ 436178825Sdfr ret = krb5_enctype_keysize(context, k->key.keytype, &keysize); 437178825Sdfr if (ret) { 438178825Sdfr krb5_data_free(&res); 439178825Sdfr return ret; 440178825Sdfr } 441178825Sdfr if (keysize > res.length) { 442178825Sdfr krb5_data_free(&res); 443178825Sdfr return KRB5_BAD_KEYSIZE; 444178825Sdfr } 44572445Sassar 446178825Sdfr memset(k->key.keyvalue.data, 0, k->key.keyvalue.length); 447178825Sdfr free(k->key.keyvalue.data); 448178825Sdfr k->key.keyvalue = res; 449178825Sdfr k->key.keyvalue.length = keysize; 450178825Sdfr free(k->mkvno); 451178825Sdfr k->mkvno = NULL; 452178825Sdfr 453178825Sdfr return 0; 454178825Sdfr} 455178825Sdfr 456178825Sdfrkrb5_error_code 457178825Sdfrhdb_unseal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey) 458178825Sdfr{ 459178825Sdfr int i; 460178825Sdfr 461178825Sdfr for(i = 0; i < ent->keys.len; i++){ 462178825Sdfr krb5_error_code ret; 463178825Sdfr 464178825Sdfr ret = hdb_unseal_key_mkey(context, &ent->keys.val[i], mkey); 465178825Sdfr if (ret) 466120945Snectar return ret; 46772445Sassar } 46872445Sassar return 0; 46972445Sassar} 47072445Sassar 47172445Sassarkrb5_error_code 47272445Sassarhdb_unseal_keys(krb5_context context, HDB *db, hdb_entry *ent) 47372445Sassar{ 474178825Sdfr if (db->hdb_master_key_set == 0) 47572445Sassar return 0; 476178825Sdfr return hdb_unseal_keys_mkey(context, ent, db->hdb_master_key); 47772445Sassar} 47872445Sassar 47972445Sassarkrb5_error_code 480178825Sdfrhdb_unseal_key(krb5_context context, HDB *db, Key *k) 48172445Sassar{ 482178825Sdfr if (db->hdb_master_key_set == 0) 483178825Sdfr return 0; 484178825Sdfr return hdb_unseal_key_mkey(context, k, db->hdb_master_key); 485178825Sdfr} 486178825Sdfr 487178825Sdfrkrb5_error_code 488178825Sdfrhdb_seal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) 489178825Sdfr{ 49072445Sassar krb5_error_code ret; 49172445Sassar krb5_data res; 492178825Sdfr hdb_master_key key; 49372445Sassar 494178825Sdfr if(k->mkvno != NULL) 495178825Sdfr return 0; 49672445Sassar 497178825Sdfr key = _hdb_find_master_key(k->mkvno, mkey); 49872445Sassar 499178825Sdfr if (key == NULL) 500178825Sdfr return HDB_ERR_NO_MKEY; 50172445Sassar 502178825Sdfr ret = _hdb_mkey_encrypt(context, key, HDB_KU_MKEY, 503178825Sdfr k->key.keyvalue.data, 504178825Sdfr k->key.keyvalue.length, 505178825Sdfr &res); 506178825Sdfr if (ret) 507178825Sdfr return ret; 50872445Sassar 509178825Sdfr memset(k->key.keyvalue.data, 0, k->key.keyvalue.length); 510178825Sdfr free(k->key.keyvalue.data); 511178825Sdfr k->key.keyvalue = res; 51272445Sassar 513178825Sdfr if (k->mkvno == NULL) { 51472445Sassar k->mkvno = malloc(sizeof(*k->mkvno)); 51572445Sassar if (k->mkvno == NULL) 51672445Sassar return ENOMEM; 51772445Sassar } 518178825Sdfr *k->mkvno = key->keytab.vno; 519178825Sdfr 52072445Sassar return 0; 52172445Sassar} 52272445Sassar 52372445Sassarkrb5_error_code 524178825Sdfrhdb_seal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey) 525178825Sdfr{ 526178825Sdfr int i; 527178825Sdfr for(i = 0; i < ent->keys.len; i++){ 528178825Sdfr krb5_error_code ret; 529178825Sdfr 530178825Sdfr ret = hdb_seal_key_mkey(context, &ent->keys.val[i], mkey); 531178825Sdfr if (ret) 532178825Sdfr return ret; 533178825Sdfr } 534178825Sdfr return 0; 535178825Sdfr} 536178825Sdfr 537178825Sdfrkrb5_error_code 53872445Sassarhdb_seal_keys(krb5_context context, HDB *db, hdb_entry *ent) 53972445Sassar{ 540178825Sdfr if (db->hdb_master_key_set == 0) 54172445Sassar return 0; 54272445Sassar 543178825Sdfr return hdb_seal_keys_mkey(context, ent, db->hdb_master_key); 54472445Sassar} 54572445Sassar 54672445Sassarkrb5_error_code 547178825Sdfrhdb_seal_key(krb5_context context, HDB *db, Key *k) 548178825Sdfr{ 549178825Sdfr if (db->hdb_master_key_set == 0) 550178825Sdfr return 0; 551178825Sdfr 552178825Sdfr return hdb_seal_key_mkey(context, k, db->hdb_master_key); 553178825Sdfr} 554178825Sdfr 555178825Sdfrkrb5_error_code 55672445Sassarhdb_set_master_key (krb5_context context, 55772445Sassar HDB *db, 55872445Sassar krb5_keyblock *key) 55972445Sassar{ 56072445Sassar krb5_error_code ret; 56172445Sassar hdb_master_key mkey; 56272445Sassar 56372445Sassar ret = hdb_process_master_key(context, 0, key, 0, &mkey); 56472445Sassar if (ret) 56572445Sassar return ret; 566178825Sdfr db->hdb_master_key = mkey; 56772445Sassar#if 0 /* XXX - why? */ 56872445Sassar des_set_random_generator_seed(key.keyvalue.data); 56972445Sassar#endif 570178825Sdfr db->hdb_master_key_set = 1; 57172445Sassar return 0; 57272445Sassar} 57372445Sassar 57472445Sassarkrb5_error_code 57572445Sassarhdb_set_master_keyfile (krb5_context context, 57672445Sassar HDB *db, 57772445Sassar const char *keyfile) 57872445Sassar{ 57972445Sassar hdb_master_key key; 58072445Sassar krb5_error_code ret; 58172445Sassar 58272445Sassar ret = hdb_read_master_key(context, keyfile, &key); 58372445Sassar if (ret) { 58472445Sassar if (ret != ENOENT) 58572445Sassar return ret; 58690926Snectar krb5_clear_error_string(context); 58772445Sassar return 0; 58872445Sassar } 589178825Sdfr db->hdb_master_key = key; 590178825Sdfr db->hdb_master_key_set = 1; 59172445Sassar return ret; 59272445Sassar} 59372445Sassar 59472445Sassarkrb5_error_code 59572445Sassarhdb_clear_master_key (krb5_context context, 59672445Sassar HDB *db) 59772445Sassar{ 598178825Sdfr if (db->hdb_master_key_set) { 599178825Sdfr hdb_free_master_key(context, db->hdb_master_key); 600178825Sdfr db->hdb_master_key_set = 0; 60172445Sassar } 60272445Sassar return 0; 60372445Sassar} 604