diff --git a/kdc/pkinit.c b/kdc/pkinit.c index 87621e371..66c27504a 100644 --- a/kdc/pkinit.c +++ b/kdc/pkinit.c @@ -1370,16 +1370,86 @@ _kdc_pk_mk_pa_reply(krb5_context context, if (rep.u.encKeyPack.length != size) krb5_abortx(context, "Internal ASN.1 encoder error"); - /* XXX KRB-FX-CF2 */ - ret = krb5_generate_random_keyblock(context, sessionetype, - sessionkey); - if (ret) { - free_PA_PK_AS_REP(&rep); - goto out; + /* generate the session key using the method from RFC6112 */ + { + krb5_keyblock kdc_contribution_key; + krb5_crypto reply_crypto; + krb5_crypto kdccont_crypto; + krb5_data p1 = { strlen("PKINIT"), "PKINIT"}; + krb5_data p2 = { strlen("KEYEXCHANGE"), "KEYEXCHANGE"}; + void *kckdata; + size_t kcklen; + EncryptedData kx; + void *kxdata; + size_t kxlen; + + ret = krb5_generate_random_keyblock(context, sessionetype, + &kdc_contribution_key); + if (ret) { + free_PA_PK_AS_REP(&rep); + goto out; + } + ret = krb5_crypto_init(context, &cp->reply_key, enctype, &reply_crypto); + if (ret) { + krb5_free_keyblock_contents(context, &kdc_contribution_key); + free_PA_PK_AS_REP(&rep); + goto out; + } + ret = krb5_crypto_init(context, &kdc_contribution_key, sessionetype, &kdccont_crypto); + if (ret) { + krb5_crypto_destroy(context, reply_crypto); + krb5_free_keyblock_contents(context, &kdc_contribution_key); + free_PA_PK_AS_REP(&rep); + goto out; + } + /* KRB-FX-CF2 */ + ret = krb5_crypto_fx_cf2(context, kdccont_crypto, reply_crypto, + &p1, &p2, sessionetype, sessionkey); + krb5_crypto_destroy(context, kdccont_crypto); + if (ret) { + krb5_crypto_destroy(context, reply_crypto); + krb5_free_keyblock_contents(context, &kdc_contribution_key); + free_PA_PK_AS_REP(&rep); + goto out; + } + ASN1_MALLOC_ENCODE(EncryptionKey, kckdata, kcklen, + &kdc_contribution_key, &size, ret); + krb5_free_keyblock_contents(context, &kdc_contribution_key); + if (ret) { + krb5_set_error_message(context, ret, "encoding of PKINIT-KX Key failed %d", ret); + krb5_crypto_destroy(context, reply_crypto); + free_PA_PK_AS_REP(&rep); + goto out; + } + if (kcklen != size) + krb5_abortx(context, "Internal ASN.1 encoder error"); + ret = krb5_encrypt_EncryptedData(context, reply_crypto, KRB5_KU_PA_PKINIT_KX, + kckdata, kcklen, 0, &kx); + krb5_crypto_destroy(context, reply_crypto); + free(kckdata); + if (ret) { + free_PA_PK_AS_REP(&rep); + goto out; + } + ASN1_MALLOC_ENCODE(EncryptedData, kxdata, kxlen, + &kx, &size, ret); + free_EncryptedData(&kx); + if (ret) { + krb5_set_error_message(context, ret, "encoding of PKINIT-KX failed %d", ret); + free_PA_PK_AS_REP(&rep); + goto out; + } + if (kxlen != size) + krb5_abortx(context, "Internal ASN.1 encoder error"); + /* Add PA-PKINIT-KX */ + ret = krb5_padata_add(context, md, KRB5_PADATA_PKINIT_KX, kxdata, kxlen); + if (ret) { + krb5_set_error_message(context, ret, + "Failed adding PKINIT-KX %d", ret); + free(buf); + goto out; + } } - - /* XXX Add PA-PKINIT-KX */ - } #define use_btmm_with_enckey 0