KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_keyblock_init(krb5_context context, krb5_enctype type, const void *data, size_t size, krb5_keyblock *key) { krb5_error_code ret; size_t len; memset(key, 0, sizeof(*key)); ret = krb5_enctype_keysize(context, type, &len); if (ret) return ret; if (len != size) { krb5_heim_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, "Encryption key %d is %lu bytes " "long, %lu was passed in", type, (unsigned long)len, (unsigned long)size); return KRB5_PROG_ETYPE_NOSUPP; } ret = krb5_heim_data_copy(&key->keyvalue, data, len); if(ret) { krb5_heim_set_error_message(context, ret, N_("malloc: out of memory", "")); return ret; } key->keytype = type; return 0; }
static int do_check_entry(krb5_principal principal, void *data) { krb5_error_code ret; kadm5_principal_ent_rec princ; char *name; int i; ret = krb5_unparse_name(context, principal, &name); if (ret) return 1; memset (&princ, 0, sizeof(princ)); ret = kadm5_get_principal(kadm_handle, principal, &princ, KADM5_PRINCIPAL | KADM5_KEY_DATA); if(ret) { krb5_warn(context, ret, "Failed to get principal: %s", name); free(name); return 0; } for (i = 0; i < princ.n_key_data; i++) { size_t keysize; ret = krb5_enctype_keysize(context, princ.key_data[i].key_data_type[0], &keysize); if (ret == 0 && keysize != princ.key_data[i].key_data_length[0]) { krb5_warnx(context, "Principal %s enctype %d, wrong length: %lu\n", name, princ.key_data[i].key_data_type[0], (unsigned long)princ.key_data[i].key_data_length); } } free(name); kadm5_free_principal_ent(kadm_handle, &princ); return 0; }
static ssize_t append_mit_key(krb5_context context, krb5_storage *sp, krb5_const_principal princ, unsigned int kvno, Key *key) { krb5_error_code ret; krb5_salt k5salt; ssize_t sz; size_t key_versions = key->salt ? 2 : 1; size_t decrypted_key_length; char buf[2]; krb5_data keylenbytes; unsigned int salttype; sz = append_string(context, sp, "\t%u\t%u\t%d\t%d\t", key_versions, kvno, key->key.keytype, key->key.keyvalue.length + 2); if (sz == -1) return sz; ret = krb5_enctype_keysize(context, key->key.keytype, &decrypted_key_length); if (ret) return -1; /* XXX we lose the error code */ buf[0] = decrypted_key_length & 0xff; buf[1] = (decrypted_key_length & 0xff00) >> 8; keylenbytes.data = buf; keylenbytes.length = sizeof (buf); sz = append_hex(context, sp, 1, 1, &keylenbytes); if (sz == -1) return sz; sz = append_hex(context, sp, 1, 1, &key->key.keyvalue); if (!key->salt) return sz; /* Map salt to MIT KDB style */ switch (key->salt->type) { case KRB5_PADATA_PW_SALT: /* * Compute normal salt and then see whether it matches the stored one */ ret = krb5_get_pw_salt(context, princ, &k5salt); if (ret) return -1; if (k5salt.saltvalue.length == key->salt->salt.length && memcmp(k5salt.saltvalue.data, key->salt->salt.data, k5salt.saltvalue.length) == 0) salttype = KRB5_KDB_SALTTYPE_NORMAL; /* matches */ else if (key->salt->salt.length == strlen(princ->realm) && memcmp(key->salt->salt.data, princ->realm, key->salt->salt.length) == 0) salttype = KRB5_KDB_SALTTYPE_ONLYREALM; /* matches realm */ else if (key->salt->salt.length == k5salt.saltvalue.length - strlen(princ->realm) && memcmp((char *)k5salt.saltvalue.data + strlen(princ->realm), key->salt->salt.data, key->salt->salt.length) == 0) salttype = KRB5_KDB_SALTTYPE_NOREALM; /* matches w/o realm */ else salttype = KRB5_KDB_SALTTYPE_NORMAL; /* hope for best */ break; case KRB5_PADATA_AFS3_SALT: salttype = KRB5_KDB_SALTTYPE_AFS3; break; default: return -1; } sz = append_string(context, sp, "\t%u\t%u\t", salttype, key->salt->salt.length); if (sz == -1) return sz; return append_hex(context, sp, 1, 1, &key->salt->salt); }