📄 crypto.c
字号:
RC4_set_key (kd->schedule->data, kd->key->keyvalue.length, kd->key->keyvalue.data);}static krb5_error_codeARCFOUR_string_to_key(krb5_context context, krb5_enctype enctype, krb5_data password, krb5_salt salt, krb5_data opaque, krb5_keyblock *key){ char *s, *p; size_t len; int i; MD4_CTX m; krb5_error_code ret; len = 2 * password.length; s = malloc (len); if (len != 0 && s == NULL) { krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } for (p = s, i = 0; i < password.length; ++i) { *p++ = ((char *)password.data)[i]; *p++ = 0; } MD4_Init (&m); MD4_Update (&m, s, len); key->keytype = enctype; ret = krb5_data_alloc (&key->keyvalue, 16); if (ret) { krb5_set_error_string(context, "malloc: out of memory"); goto out; } MD4_Final (key->keyvalue.data, &m); memset (s, 0, len); ret = 0;out: free (s); return ret;}/* * AES */int _krb5_AES_string_to_default_iterator = 4096;static krb5_error_codeAES_string_to_key(krb5_context context, krb5_enctype enctype, krb5_data password, krb5_salt salt, krb5_data opaque, krb5_keyblock *key){ krb5_error_code ret; uint32_t iter; struct encryption_type *et; struct key_data kd; if (opaque.length == 0) iter = _krb5_AES_string_to_default_iterator; else if (opaque.length == 4) { unsigned long v; _krb5_get_int(opaque.data, &v, 4); iter = ((uint32_t)v); } else return KRB5_PROG_KEYTYPE_NOSUPP; /* XXX */ et = _find_enctype(enctype); if (et == NULL) return KRB5_PROG_KEYTYPE_NOSUPP; kd.schedule = NULL; ALLOC(kd.key, 1); if(kd.key == NULL) { krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } kd.key->keytype = enctype; ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size); if (ret) { krb5_set_error_string(context, "Failed to allocate pkcs5 key"); return ret; } ret = PKCS5_PBKDF2_HMAC_SHA1(password.data, password.length, salt.saltvalue.data, salt.saltvalue.length, iter, et->keytype->size, kd.key->keyvalue.data); if (ret != 1) { free_key_data(context, &kd); krb5_set_error_string(context, "Error calculating s2k"); return KRB5_PROG_KEYTYPE_NOSUPP; } ret = derive_key(context, et, &kd, "kerberos", strlen("kerberos")); if (ret == 0) ret = krb5_copy_keyblock_contents(context, kd.key, key); free_key_data(context, &kd); return ret;}struct krb5_aes_schedule { AES_KEY ekey; AES_KEY dkey;};static voidAES_schedule(krb5_context context, struct key_data *kd){ struct krb5_aes_schedule *key = kd->schedule->data; int bits = kd->key->keyvalue.length * 8; memset(key, 0, sizeof(*key)); AES_set_encrypt_key(kd->key->keyvalue.data, bits, &key->ekey); AES_set_decrypt_key(kd->key->keyvalue.data, bits, &key->dkey);}/* * */static struct salt_type des_salt[] = { { KRB5_PW_SALT, "pw-salt", krb5_DES_string_to_key },#ifdef ENABLE_AFS_STRING_TO_KEY { KRB5_AFS3_SALT, "afs3-salt", DES_AFS3_string_to_key },#endif { 0 }};static struct salt_type des3_salt[] = { { KRB5_PW_SALT, "pw-salt", DES3_string_to_key }, { 0 }};static struct salt_type des3_salt_derived[] = { { KRB5_PW_SALT, "pw-salt", DES3_string_to_key_derived }, { 0 }};static struct salt_type AES_salt[] = { { KRB5_PW_SALT, "pw-salt", AES_string_to_key }, { 0 }};static struct salt_type arcfour_salt[] = { { KRB5_PW_SALT, "pw-salt", ARCFOUR_string_to_key }, { 0 }};/* * */static struct key_type keytype_null = { KEYTYPE_NULL, "null", 0, 0, 0, NULL, NULL, NULL};static struct key_type keytype_des = { KEYTYPE_DES, "des", 56, sizeof(DES_cblock), sizeof(DES_key_schedule), krb5_DES_random_key, krb5_DES_schedule, des_salt, krb5_DES_random_to_key};static struct key_type keytype_des3 = { KEYTYPE_DES3, "des3", 168, 3 * sizeof(DES_cblock), 3 * sizeof(DES_key_schedule), DES3_random_key, DES3_schedule, des3_salt, DES3_random_to_key};static struct key_type keytype_des3_derived = { KEYTYPE_DES3, "des3", 168, 3 * sizeof(DES_cblock), 3 * sizeof(DES_key_schedule), DES3_random_key, DES3_schedule, des3_salt_derived, DES3_random_to_key};static struct key_type keytype_aes128 = { KEYTYPE_AES128, "aes-128", 128, 16, sizeof(struct krb5_aes_schedule), NULL, AES_schedule, AES_salt};static struct key_type keytype_aes256 = { KEYTYPE_AES256, "aes-256", 256, 32, sizeof(struct krb5_aes_schedule), NULL, AES_schedule, AES_salt};static struct key_type keytype_arcfour = { KEYTYPE_ARCFOUR, "arcfour", 128, 16, sizeof(RC4_KEY), NULL, ARCFOUR_schedule, arcfour_salt};static struct key_type *keytypes[] = { &keytype_null, &keytype_des, &keytype_des3_derived, &keytype_des3, &keytype_aes128, &keytype_aes256, &keytype_arcfour};static int num_keytypes = sizeof(keytypes) / sizeof(keytypes[0]);static struct key_type *_find_keytype(krb5_keytype type){ int i; for(i = 0; i < num_keytypes; i++) if(keytypes[i]->type == type) return keytypes[i]; return NULL;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_salttype_to_string (krb5_context context, krb5_enctype etype, krb5_salttype stype, char **string){ struct encryption_type *e; struct salt_type *st; e = _find_enctype (etype); if (e == NULL) { krb5_set_error_string(context, "encryption type %d not supported", etype); return KRB5_PROG_ETYPE_NOSUPP; } for (st = e->keytype->string_to_key; st && st->type; st++) { if (st->type == stype) { *string = strdup (st->name); if (*string == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } return 0; } } krb5_set_error_string(context, "salttype %d not supported", stype); return HEIM_ERR_SALTTYPE_NOSUPP;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_string_to_salttype (krb5_context context, krb5_enctype etype, const char *string, krb5_salttype *salttype){ struct encryption_type *e; struct salt_type *st; e = _find_enctype (etype); if (e == NULL) { krb5_set_error_string(context, "encryption type %d not supported", etype); return KRB5_PROG_ETYPE_NOSUPP; } for (st = e->keytype->string_to_key; st && st->type; st++) { if (strcasecmp (st->name, string) == 0) { *salttype = st->type; return 0; } } krb5_set_error_string(context, "salttype %s not supported", string); return HEIM_ERR_SALTTYPE_NOSUPP;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_get_pw_salt(krb5_context context, krb5_const_principal principal, krb5_salt *salt){ size_t len; int i; krb5_error_code ret; char *p; salt->salttype = KRB5_PW_SALT; len = strlen(principal->realm); for (i = 0; i < principal->name.name_string.len; ++i) len += strlen(principal->name.name_string.val[i]); ret = krb5_data_alloc (&salt->saltvalue, len); if (ret) return ret; p = salt->saltvalue.data; memcpy (p, principal->realm, strlen(principal->realm)); p += strlen(principal->realm); for (i = 0; i < principal->name.name_string.len; ++i) { memcpy (p, principal->name.name_string.val[i], strlen(principal->name.name_string.val[i])); p += strlen(principal->name.name_string.val[i]); } return 0;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_free_salt(krb5_context context, krb5_salt salt){ krb5_data_free(&salt.saltvalue); return 0;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_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;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_string_to_key (krb5_context context, krb5_enctype enctype, const char *password, krb5_principal principal, krb5_keyblock *key){ krb5_data pw; pw.data = rk_UNCONST(password); pw.length = strlen(password); return krb5_string_to_key_data(context, enctype, pw, principal, key);}krb5_error_code KRB5_LIB_FUNCTIONkrb5_string_to_key_data_salt (krb5_context context, krb5_enctype enctype, krb5_data password, krb5_salt salt, krb5_keyblock *key){ krb5_data opaque; krb5_data_zero(&opaque); return krb5_string_to_key_data_salt_opaque(context, enctype, password, salt, opaque, key);}/* * Do a string -> key for encryption type `enctype' operation on * `password' (with salt `salt' and the enctype specific data string * `opaque'), returning the resulting key in `key' */krb5_error_code KRB5_LIB_FUNCTIONkrb5_string_to_key_data_salt_opaque (krb5_context context, krb5_enctype enctype, krb5_data password, krb5_salt salt, krb5_data opaque, krb5_keyblock *key){ struct encryption_type *et =_find_enctype(enctype); struct salt_type *st; if(et == NULL) { krb5_set_error_string(context, "encryption type %d not supported", enctype); return KRB5_PROG_ETYPE_NOSUPP; } for(st = et->keytype->string_to_key; st && st->type; st++) if(st->type == salt.salttype) return (*st->string_to_key)(context, enctype, password, salt, opaque, key); krb5_set_error_string(context, "salt type %d not supported", salt.salttype); return HEIM_ERR_SALTTYPE_NOSUPP;}/* * Do a string -> key for encryption type `enctype' operation on the * string `password' (with salt `salt'), returning the resulting key * in `key' */krb5_error_code KRB5_LIB_FUNCTIONkrb5_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_error_code KRB5_LIB_FUNCTIONkrb5_string_to_key_salt_opaque (krb5_context context, krb5_enctype enctype, const char *password, krb5_salt salt, krb5_data opaque, krb5_keyblock *key){ krb5_data pw; pw.data = rk_UNCONST(password); pw.length = strlen(password); return krb5_string_to_key_data_salt_opaque(context, enctype, pw, salt, opaque, key);}krb5_error_code KRB5_LIB_FUNCTIONkrb5_keytype_to_string(krb5_context context, krb5_keytype keytype, char **string){ struct key_type *kt = _find_keytype(keytype); if(kt == NULL) { krb5_set_error_string(context, "key type %d not supported", keytype); return KRB5_PROG_KEYTYPE_NOSUPP; } *string = strdup(kt->name); if(*string == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } return 0;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_string_to_keytype(krb5_context context, const char *string, krb5_keytype *keytype){ int i; for(i = 0; i < num_keytypes; i++) if(strcasecmp(keytypes[i]->name, string) == 0){ *keytype = keytypes[i]->type; return 0; } krb5_set_error_string(context, "key type %s not supported", string); return KRB5_PROG_KEYTYPE_NOSUPP;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_enctype_keysize(krb5_context context, krb5_enctype type, size_t *keysize){ struct encryption_type *et = _find_enctype(type); if(et == NULL) { krb5_set_error_string(context, "encryption type %d not supported", type); return KRB5_PROG_ETYPE_NOSUPP; } *keysize = et->keytype->size; return 0;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_enctype_keybits(krb5_context context, krb5_enctype type, size_t *keybits){ struct encryption_type *et = _find_enctype(type); if(et == NULL) { krb5_set_error_string(context, "encryption type %d not supported", type); return KRB5_PROG_ETYPE_NOSUPP; } *keybits = et->keytype->bits; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -