[HEIMDAL-533] KDC sends TGS-REP encrypted in session key not authenticator
From RFC 4120, page 35 In preparing the authentication header, the client can select a sub- session key under which the response from the Kerberos server will be encrypted. If the client selects a sub-session key, care must be taken to ensure the randomness of the selected sub-session key. The client library alread handle this case. Thanks to Sam Hartman to report this though Debian
This commit is contained in:
@@ -261,6 +261,7 @@ _kdc_encode_reply(krb5_context context,
|
||||
krb5_enctype etype,
|
||||
int skvno, const EncryptionKey *skey,
|
||||
int ckvno, const EncryptionKey *reply_key,
|
||||
int rk_is_subkey,
|
||||
const char **e_text,
|
||||
krb5_data *reply)
|
||||
{
|
||||
@@ -341,7 +342,7 @@ _kdc_encode_reply(krb5_context context,
|
||||
} else {
|
||||
krb5_encrypt_EncryptedData(context,
|
||||
crypto,
|
||||
KRB5_KU_TGS_REP_ENC_PART_SESSION,
|
||||
rk_is_subkey ? KRB5_KU_TGS_REP_ENC_PART_SUB_KEY : KRB5_KU_TGS_REP_ENC_PART_SESSION,
|
||||
buf,
|
||||
len,
|
||||
ckvno,
|
||||
@@ -1757,7 +1758,7 @@ _kdc_as_rep(krb5_context context,
|
||||
ret = _kdc_encode_reply(context, config,
|
||||
&rep, &et, &ek, setype, server->entry.kvno,
|
||||
&skey->key, client->entry.kvno,
|
||||
reply_key, &e_text, reply);
|
||||
reply_key, 0, &e_text, reply);
|
||||
free_EncTicketPart(&et);
|
||||
free_EncKDCRepPart(&ek);
|
||||
if (ret)
|
||||
|
@@ -671,6 +671,8 @@ tgs_make_reply(krb5_context context,
|
||||
KDC_REQ_BODY *b,
|
||||
krb5_const_principal tgt_name,
|
||||
const EncTicketPart *tgt,
|
||||
const krb5_keyblock *replykey,
|
||||
int rk_is_subkey,
|
||||
const EncryptionKey *serverkey,
|
||||
const krb5_keyblock *sessionkey,
|
||||
krb5_kvno kvno,
|
||||
@@ -931,7 +933,8 @@ tgs_make_reply(krb5_context context,
|
||||
ret = _kdc_encode_reply(context, config,
|
||||
&rep, &et, &ek, et.key.keytype,
|
||||
kvno,
|
||||
serverkey, 0, &tgt->key, e_text, reply);
|
||||
serverkey, 0, replykey, rk_is_subkey,
|
||||
e_text, reply);
|
||||
if (is_weak)
|
||||
krb5_enctype_disable(context, et.key.keytype);
|
||||
|
||||
@@ -1081,7 +1084,9 @@ tgs_parse_request(krb5_context context,
|
||||
const struct sockaddr *from_addr,
|
||||
time_t **csec,
|
||||
int **cusec,
|
||||
AuthorizationData **auth_data)
|
||||
AuthorizationData **auth_data,
|
||||
krb5_keyblock **replykey,
|
||||
int *rk_is_subkey)
|
||||
{
|
||||
krb5_ap_req ap_req;
|
||||
krb5_error_code ret;
|
||||
@@ -1091,10 +1096,13 @@ tgs_parse_request(krb5_context context,
|
||||
krb5_flags verify_ap_req_flags;
|
||||
krb5_crypto crypto;
|
||||
Key *tkey;
|
||||
krb5_keyblock *subkey = NULL;
|
||||
unsigned usage;
|
||||
|
||||
*auth_data = NULL;
|
||||
*csec = NULL;
|
||||
*cusec = NULL;
|
||||
*replykey = NULL;
|
||||
|
||||
memset(&ap_req, 0, sizeof(ap_req));
|
||||
ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req);
|
||||
@@ -1223,37 +1231,42 @@ tgs_parse_request(krb5_context context,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (b->enc_authorization_data) {
|
||||
unsigned usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
|
||||
krb5_keyblock *subkey;
|
||||
krb5_data ad;
|
||||
usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
|
||||
*rk_is_subkey = 1;
|
||||
|
||||
ret = krb5_auth_con_getremotesubkey(context, ac, &subkey);
|
||||
if(ret){
|
||||
ret = krb5_auth_con_getremotesubkey(context, ac, &subkey);
|
||||
if(ret){
|
||||
krb5_auth_con_free(context, ac);
|
||||
kdc_log(context, config, 0, "Failed to get remote subkey: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
goto out;
|
||||
}
|
||||
if(subkey == NULL){
|
||||
usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION;
|
||||
*rk_is_subkey = 0;
|
||||
|
||||
ret = krb5_auth_con_getkey(context, ac, &subkey);
|
||||
if(ret) {
|
||||
krb5_auth_con_free(context, ac);
|
||||
kdc_log(context, config, 0, "Failed to get remote subkey: %s",
|
||||
kdc_log(context, config, 0, "Failed to get session key: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
goto out;
|
||||
}
|
||||
if(subkey == NULL){
|
||||
usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION;
|
||||
ret = krb5_auth_con_getkey(context, ac, &subkey);
|
||||
if(ret) {
|
||||
krb5_auth_con_free(context, ac);
|
||||
kdc_log(context, config, 0, "Failed to get session key: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if(subkey == NULL){
|
||||
krb5_auth_con_free(context, ac);
|
||||
kdc_log(context, config, 0,
|
||||
"Failed to get key for enc-authorization-data");
|
||||
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if(subkey == NULL){
|
||||
krb5_auth_con_free(context, ac);
|
||||
kdc_log(context, config, 0,
|
||||
"Failed to get key for enc-authorization-data");
|
||||
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
|
||||
goto out;
|
||||
}
|
||||
|
||||
*replykey = subkey;
|
||||
|
||||
if (b->enc_authorization_data) {
|
||||
krb5_data ad;
|
||||
|
||||
ret = krb5_crypto_init(context, subkey, 0, &crypto);
|
||||
krb5_free_keyblock(context, subkey);
|
||||
if (ret) {
|
||||
krb5_auth_con_free(context, ac);
|
||||
kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
|
||||
@@ -1381,6 +1394,8 @@ tgs_build_reply(krb5_context context,
|
||||
KDC_REQ_BODY *b,
|
||||
hdb_entry_ex *krbtgt,
|
||||
krb5_enctype krbtgt_etype,
|
||||
const krb5_keyblock *replykey,
|
||||
int rk_is_subkey,
|
||||
krb5_ticket *ticket,
|
||||
krb5_data *reply,
|
||||
const char *from,
|
||||
@@ -1954,6 +1969,8 @@ server_lookup:
|
||||
b,
|
||||
client_principal,
|
||||
tgt,
|
||||
replykey,
|
||||
rk_is_subkey,
|
||||
ekey,
|
||||
&sessionkey,
|
||||
kvno,
|
||||
@@ -2020,6 +2037,8 @@ _kdc_tgs_rep(krb5_context context,
|
||||
const char *e_text = NULL;
|
||||
krb5_enctype krbtgt_etype = ETYPE_NULL;
|
||||
|
||||
krb5_keyblock *replykey = NULL;
|
||||
int rk_is_subkey = 0;
|
||||
time_t *csec = NULL;
|
||||
int *cusec = NULL;
|
||||
|
||||
@@ -2047,7 +2066,9 @@ _kdc_tgs_rep(krb5_context context,
|
||||
&e_text,
|
||||
from, from_addr,
|
||||
&csec, &cusec,
|
||||
&auth_data);
|
||||
&auth_data,
|
||||
&replykey,
|
||||
&rk_is_subkey);
|
||||
if (ret) {
|
||||
kdc_log(context, config, 0,
|
||||
"Failed parsing TGS-REQ from %s", from);
|
||||
@@ -2060,6 +2081,8 @@ _kdc_tgs_rep(krb5_context context,
|
||||
&req->req_body,
|
||||
krbtgt,
|
||||
krbtgt_etype,
|
||||
replykey,
|
||||
rk_is_subkey,
|
||||
ticket,
|
||||
data,
|
||||
from,
|
||||
@@ -2080,6 +2103,8 @@ _kdc_tgs_rep(krb5_context context,
|
||||
}
|
||||
|
||||
out:
|
||||
if (replykey)
|
||||
krb5_free_keyblock(context, replykey);
|
||||
if(ret && data->data == NULL){
|
||||
krb5_mk_error(context,
|
||||
ret,
|
||||
|
Reference in New Issue
Block a user