void KRB5Keyblock::from_string(krb5_enctype enctype, const std::string &password, const std::string &salt) { #ifdef HEIMDAL krb5_data pass_data; krb5_salt salt_data; salt_data.salttype = KRB5_PW_SALT; salt_data.saltvalue.data = const_cast<char *>(salt.c_str()); salt_data.saltvalue.length = salt.length(); pass_data.data = const_cast<char *>(password.c_str()); pass_data.length = password.length(); krb5_error_code ret = krb5_string_to_key_data_salt(g_context.get(), enctype, pass_data, salt_data, &m_keyblock); if (ret) { throw KRB5Exception("krb5_string_to_key_data_salt", ret); } #else krb5_data salt_data, pass_data; salt_data.data = const_cast<char *>(salt.c_str()); salt_data.length = salt.length(); pass_data.data = const_cast<char *>(password.c_str()); pass_data.length = password.length(); krb5_error_code ret = krb5_c_string_to_key(g_context.get(), enctype, &pass_data, &salt_data, &m_keyblock); if (ret) { throw KRB5Exception("krb5_c_string_to_key", ret); } #endif }
static krb5_error_code update_keytab_entry(krb5_context context, kcm_ccache ccache, krb5_enctype etype, char *cpn, char *spn, char *newpw, krb5_salt salt, unsigned kvno) { krb5_error_code ret; krb5_keytab_entry entry; krb5_data pw; memset(&entry, 0, sizeof(entry)); pw.data = (char *)newpw; pw.length = strlen(newpw); ret = krb5_string_to_key_data_salt(context, etype, pw, salt, &entry.keyblock); if (ret) { kcm_log(0, "String to key conversion failed for principal %s " "and etype %d: %s", cpn, etype, krb5_get_err_text(context, ret)); return ret; } if (spn == NULL) { ret = krb5_copy_principal(context, ccache->client, &entry.principal); if (ret) { kcm_log(0, "Failed to copy principal name %s: %s", cpn, krb5_get_err_text(context, ret)); return ret; } } else { ret = krb5_parse_name(context, spn, &entry.principal); if (ret) { kcm_log(0, "Failed to parse SPN alias %s: %s", spn, krb5_get_err_text(context, ret)); return ret; } } entry.vno = kvno; entry.timestamp = time(NULL); ret = krb5_kt_add_entry(context, ccache->key.keytab, &entry); if (ret) { kcm_log(0, "Failed to update keytab for principal %s " "and etype %d: %s", cpn, etype, krb5_get_err_text(context, ret)); } krb5_kt_free_entry(context, &entry); return ret; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_string_to_key_salt (krb5_context context, krb5_enctype enctype, const char *password, krb5_salt salt, krb5_keyblock *key) { krb5_data pw; pw.data = rk_UNCONST(password); pw.length = strlen(password); return krb5_string_to_key_data_salt(context, enctype, pw, salt, key); }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_string_to_key_data (krb5_context context, krb5_enctype enctype, krb5_data password, krb5_principal principal, krb5_keyblock *key) { krb5_error_code ret; krb5_salt salt; ret = krb5_get_pw_salt(context, principal, &salt); if(ret) return ret; ret = krb5_string_to_key_data_salt(context, enctype, password, salt, key); krb5_free_salt(context, salt); return ret; }
static void test_cf2(krb5_context context) { krb5_error_code ret; krb5_data pw, p1, p2; krb5_salt salt; krb5_keyblock k1, k2, k3; krb5_crypto c1, c2; unsigned int i; unsigned int errors = 0; ret = krb5_allow_weak_crypto(context, 1); if (ret) krb5_err(context, 1, ret, "krb5_allow_weak_crypto"); for (i = 0; i < sizeof(cf2)/sizeof(cf2[0]); i++) { pw.data = cf2[i].p1; pw.length = strlen(cf2[i].p1); salt.salttype = (krb5_salttype)KRB5_PADATA_PW_SALT; salt.saltvalue.data = cf2[i].p1; salt.saltvalue.length = strlen(cf2[i].p1); ret = krb5_string_to_key_data_salt(context, cf2[i].e1, pw, salt, &k1); if (ret) krb5_err(context, 1, ret, "krb5_string_to_key_data_salt"); ret = krb5_crypto_init(context, &k1, 0, &c1); if (ret) krb5_err(context, 1, ret, "krb5_crypto_init"); pw.data = cf2[i].p2; pw.length = strlen(cf2[i].p2); salt.saltvalue.data = cf2[i].p2; salt.saltvalue.length = strlen(cf2[i].p2); ret = krb5_string_to_key_data_salt(context, cf2[i].e2, pw, salt, &k2); if (ret) krb5_err(context, 1, ret, "krb5_string_to_key_data_salt"); ret = krb5_crypto_init(context, &k2, 0, &c2); if (ret) krb5_err(context, 1, ret, "krb5_crypto_init"); p1.data = cf2[i].pepper1; p1.length = strlen(cf2[i].pepper1); p2.data = cf2[i].pepper2; p2.length = strlen(cf2[i].pepper2); ret = krb5_crypto_fx_cf2(context, c1, c2, &p1, &p2, cf2[i].e3, &k3); if (ret == KRB5_PROG_ETYPE_NOSUPP) { krb5_warn(context, ret, "KRB-FX-CF2 not supported for enctype %d", cf2[i].e1); continue; } else if (ret) { krb5_err(context, 1, ret, "krb5_crypto_fx_cf2"); } if (k3.keytype != cf2[i].e3) { errors++; krb5_warnx(context, "length not right for enctype %d", cf2[i].e3); continue; } if (k3.keyvalue.length != cf2[i].len || memcmp(k3.keyvalue.data, cf2[i].key, cf2[i].len) != 0) { errors++; krb5_warnx(context, "key not same for enctypes %d %d %d", cf2[i].e1, cf2[i].e2, cf2[i].e3); continue; } krb5_crypto_destroy(context, c1); krb5_crypto_destroy(context, c2); krb5_free_keyblock_contents(context, &k1); krb5_free_keyblock_contents(context, &k2); krb5_free_keyblock_contents(context, &k3); } if (errors) krb5_errx(context, 1, "%u KRB-FX-CF2 vectors failed", errors); }
int kt_add(struct add_options *opt, int argc, char **argv) { krb5_error_code ret; krb5_keytab keytab; krb5_keytab_entry entry; char buf[1024]; krb5_enctype enctype; if((keytab = ktutil_open_keytab()) == NULL) return 1; memset(&entry, 0, sizeof(entry)); if(opt->principal_string == NULL) { if(readstring("Principal: ", buf, sizeof(buf)) == NULL) return 1; opt->principal_string = buf; } ret = krb5_parse_name(context, opt->principal_string, &entry.principal); if(ret) { krb5_warn(context, ret, "%s", opt->principal_string); goto out; } if(opt->enctype_string == NULL) { if(readstring("Encryption type: ", buf, sizeof(buf)) == NULL) { ret = 1; goto out; } opt->enctype_string = buf; } ret = krb5_string_to_enctype(context, opt->enctype_string, &enctype); if(ret) { int t; if(sscanf(opt->enctype_string, "%d", &t) == 1) enctype = t; else { krb5_warn(context, ret, "%s", opt->enctype_string); goto out; } } if(opt->kvno_integer == -1) { if(readstring("Key version: ", buf, sizeof(buf)) == NULL) { ret = 1; goto out; } if(sscanf(buf, "%u", &opt->kvno_integer) != 1) goto out; } if(opt->password_string == NULL && opt->random_flag == 0) { if(UI_UTIL_read_pw_string(buf, sizeof(buf), "Password: "******"malloc"); goto out; } if ((size_t)hex_decode(opt->password_string, data, len) != len) { free(data); krb5_warn(context, ENOMEM, "hex decode failed"); goto out; } ret = krb5_keyblock_init(context, enctype, data, len, &entry.keyblock); free(data); } else if (!opt->salt_flag) { krb5_salt salt; krb5_data pw; salt.salttype = KRB5_PW_SALT; salt.saltvalue.data = NULL; salt.saltvalue.length = 0; pw.data = (void*)opt->password_string; pw.length = strlen(opt->password_string); ret = krb5_string_to_key_data_salt(context, enctype, pw, salt, &entry.keyblock); } else { ret = krb5_string_to_key(context, enctype, opt->password_string, entry.principal, &entry.keyblock); } memset (opt->password_string, 0, strlen(opt->password_string)); } else { ret = krb5_generate_random_keyblock(context, enctype, &entry.keyblock); } if(ret) { krb5_warn(context, ret, "add"); goto out; } entry.vno = opt->kvno_integer; entry.timestamp = time (NULL); ret = krb5_kt_add_entry(context, keytab, &entry); if(ret) krb5_warn(context, ret, "add"); out: krb5_kt_free_entry(context, &entry); krb5_kt_close(context, keytab); return ret != 0; }