static void test_enctype(krb5_enctype enctype) { krb5_error_code ret; krb5_keyblock keyblock; krb5_enc_data input; krb5_data output; krb5_crypto_iov iov[2]; unsigned int dummy; size_t min_len, len; printf("Testing enctype %d\n", (int) enctype); x(krb5_c_encrypt_length(NULL, enctype, 0, &min_len)); x(krb5_c_make_random_key(NULL, enctype, &keyblock)); input.enctype = enctype; /* Try each length up to the minimum length. */ for (len = 0; len <= min_len; len++) { input.ciphertext.data = calloc(len, 1); input.ciphertext.length = len; output.data = calloc(len, 1); output.length = len; /* Attempt a normal decryption. */ ret = krb5_c_decrypt(NULL, &keyblock, 0, NULL, &input, &output); check_decrypt_result(ret, len, min_len); if (krb5_c_crypto_length(NULL, enctype, KRB5_CRYPTO_TYPE_HEADER, &dummy) == 0) { /* Attempt an IOV stream decryption. */ iov[0].flags = KRB5_CRYPTO_TYPE_STREAM; iov[0].data = input.ciphertext; iov[1].flags = KRB5_CRYPTO_TYPE_DATA; iov[1].data.data = NULL; iov[1].data.length = 0; ret = krb5_c_decrypt_iov(NULL, &keyblock, 0, NULL, iov, 2); check_decrypt_result(ret, len, min_len); } free(input.ciphertext.data); free(output.data); } krb5int_c_free_keyblock_contents (NULL, &keyblock); }
void KRB5_CALLCONV krb5_free_keyblock_contents(krb5_context context, register krb5_keyblock *key) { krb5int_c_free_keyblock_contents (context, key); }
/* * Generate a krb5_key_data set by encrypting keys according to * enctype/salttype preferences */ krb5_error_code ipa_krb5_generate_key_data(krb5_context krbctx, krb5_principal principal, krb5_data pwd, int kvno, krb5_keyblock *kmkey, int num_encsalts, krb5_key_salt_tuple *encsalts, int *_num_keys, krb5_key_data **_keys) { krb5_error_code kerr; krb5_key_data *keys; int num_keys; int i; num_keys = num_encsalts; keys = calloc(num_keys, sizeof(krb5_key_data)); if (!keys) { return ENOMEM; } for (i = 0; i < num_keys; i++) { krb5_keyblock key; krb5_data salt; krb5_octet *ptr; krb5_data plain; krb5_enc_data cipher; krb5_int16 t; size_t len; salt.data = NULL; keys[i].key_data_ver = 2; /* we always have a salt */ keys[i].key_data_kvno = kvno; switch (encsalts[i].ks_salttype) { case KRB5_KDB_SALTTYPE_ONLYREALM: if (!principal->realm.data) { kerr = EINVAL; goto done; } salt.length = principal->realm.length; salt.data = malloc(salt.length); if (!salt.data) { kerr = ENOMEM; goto done; } memcpy(salt.data, principal->realm.data, salt.length); break; case KRB5_KDB_SALTTYPE_NOREALM: kerr = ipa_krb5_principal2salt_norealm(krbctx, principal, &salt); if (kerr) { goto done; } break; case KRB5_KDB_SALTTYPE_NORMAL: kerr = krb5_principal2salt(krbctx, principal, &salt); if (kerr) { goto done; } break; case KRB5_KDB_SALTTYPE_SPECIAL: kerr = ipa_get_random_salt(krbctx, &salt); if (kerr) { goto done; } break; case KRB5_KDB_SALTTYPE_V4: salt.length = 0; break; case KRB5_KDB_SALTTYPE_AFS3: if (!principal->realm.data) { kerr = EINVAL; goto done; } salt.data = strndup((char *)principal->realm.data, principal->realm.length); if (!salt.data) { kerr = ENOMEM; goto done; } salt.length = SALT_TYPE_AFS_LENGTH; /* special value */ break; default: kerr = EINVAL; goto done; } /* need to build the key now to manage the AFS salt.length * special case */ kerr = krb5_c_string_to_key(krbctx, encsalts[i].ks_enctype, &pwd, &salt, &key); if (kerr) { krb5_free_data_contents(krbctx, &salt); goto done; } if (salt.length == SALT_TYPE_AFS_LENGTH) { salt.length = strlen(salt.data); } kerr = krb5_c_encrypt_length(krbctx, kmkey->enctype, key.length, &len); if (kerr) { krb5int_c_free_keyblock_contents(krbctx, &key); krb5_free_data_contents(krbctx, &salt); goto done; } if ((ptr = (krb5_octet *) malloc(2 + len)) == NULL) { kerr = ENOMEM; krb5int_c_free_keyblock_contents(krbctx, &key); krb5_free_data_contents(krbctx, &salt); goto done; } t = htole16(key.length); memcpy(ptr, &t, 2); plain.length = key.length; plain.data = (char *)key.contents; cipher.ciphertext.length = len; cipher.ciphertext.data = (char *)ptr+2; kerr = krb5_c_encrypt(krbctx, kmkey, 0, 0, &plain, &cipher); if (kerr) { krb5int_c_free_keyblock_contents(krbctx, &key); krb5_free_data_contents(krbctx, &salt); free(ptr); goto done; } /* KrbSalt */ keys[i].key_data_type[1] = encsalts[i].ks_salttype; if (salt.length) { keys[i].key_data_length[1] = salt.length; keys[i].key_data_contents[1] = (krb5_octet *)salt.data; } /* EncryptionKey */ keys[i].key_data_type[0] = key.enctype; keys[i].key_data_length[0] = len + 2; keys[i].key_data_contents[0] = malloc(len + 2); if (!keys[i].key_data_contents[0]) { kerr = ENOMEM; krb5int_c_free_keyblock_contents(krbctx, &key); free(ptr); goto done; } memcpy(keys[i].key_data_contents[0], ptr, len + 2); /* make sure we free the memory used now that we are done with it */ krb5int_c_free_keyblock_contents(krbctx, &key); free(ptr); } *_num_keys = num_keys; *_keys = keys; kerr = 0; done: if (kerr) { ipa_krb5_free_key_data(keys, num_keys); } return kerr; }
void krb5int_c_free_keyblock(krb5_context context, register krb5_keyblock *val) { krb5int_c_free_keyblock_contents(context, val); free(val); }