Somewhat fix the etype usage. The list sent by the client is used to

select wich key to encrypt the kdc rep with (in case of as-req), and
with the server info to select the session key type. The server key
the ticket is encrypted is based purely on the keys in the database.


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@3533 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
1997-09-22 18:28:07 +00:00
parent dadf39203d
commit 5c600d0ba3

View File

@@ -74,7 +74,8 @@ as_rep(KDC_REQ *req,
AS_REP rep; AS_REP rep;
KDCOptions f = b->kdc_options; KDCOptions f = b->kdc_options;
hdb_entry *client = NULL, *server = NULL; hdb_entry *client = NULL, *server = NULL;
int etype; krb5_enctype cetype, setype;
krb5_keytype sess_ktype;
EncTicketPart et; EncTicketPart et;
EncKDCRepPart ek; EncKDCRepPart ek;
krb5_principal client_princ, server_princ; krb5_principal client_princ, server_princ;
@@ -179,25 +180,6 @@ as_rep(KDC_REQ *req,
goto out; goto out;
} }
/* Find appropriate key */
for(i = 0; i < b->etype.len; i++){
ret = hdb_etype2key(context, client, b->etype.val[i], &ckey);
if(ret)
continue;
ret = hdb_etype2key(context, server, b->etype.val[i], &skey);
if(ret)
continue;
break;
}
if(ret){
ret = KRB5KDC_ERR_ETYPE_NOSUPP;
kdc_log(0, "No support for etypes -- %s", client_name);
goto out;
}
etype = b->etype.val[i];
memset(&et, 0, sizeof(et)); memset(&et, 0, sizeof(et));
memset(&ek, 0, sizeof(ek)); memset(&ek, 0, sizeof(ek));
@@ -214,6 +196,7 @@ as_rep(KDC_REQ *req,
time_t patime; time_t patime;
size_t len; size_t len;
EncryptedData enc_data; EncryptedData enc_data;
Key *pa_key;
kdc_log(5, "Found pa-enc-timestamp -- %s", kdc_log(5, "Found pa-enc-timestamp -- %s",
client_name); client_name);
@@ -230,7 +213,13 @@ as_rep(KDC_REQ *req,
goto out; goto out;
} }
ekey = unseal_key(ckey); ret = hdb_etype2key(context, client, enc_data.etype, &pa_key);
if(ret){
free_EncryptedData(&enc_data);
continue;
}
ekey = unseal_key(pa_key);
ret = krb5_decrypt (context, ret = krb5_decrypt (context,
enc_data.cipher.data, enc_data.cipher.data,
@@ -294,8 +283,7 @@ as_rep(KDC_REQ *req,
e_text = NULL; e_text = NULL;
goto out; goto out;
} }
}else if (require_preauth }else if (require_preauth || client->flags.require_preauth) {
|| client->flags.require_preauth) {
METHOD_DATA method_data; METHOD_DATA method_data;
PA_DATA pa_data; PA_DATA pa_data;
u_char buf[16]; u_char buf[16];
@@ -331,7 +319,62 @@ as_rep(KDC_REQ *req,
goto out2; goto out2;
} }
kdc_log(2, "Using etype %d -- %s", etype, client_name); /* find client key */
for(i = 0; i < b->etype.len; i++){
ret = hdb_etype2key(context, client, b->etype.val[i], &ckey);
if(ret == 0)
break;
}
if(ret){
ret = KRB5KDC_ERR_ETYPE_NOSUPP;
kdc_log(0, "No support for etypes -- %s", client_name);
goto out;
}
cetype = b->etype.val[i];
/* find sesion key type */
for(i = 0; i < b->etype.len; i++){
ret = hdb_etype2key(context, server, b->etype.val[i], &skey);
if(ret == 0)
break;
}
if(ret){
ret = KRB5KDC_ERR_ETYPE_NOSUPP;
kdc_log(0, "No support for etypes -- %s", client_name);
goto out;
}
sess_ktype = skey->key.keytype;
/* find server key */
skey = NULL;
#define is_better(x, y) ((x) > (y))
for(i = 0; i < server->keys.len; i++){
if(skey == NULL || is_better(server->keys.val[i].key.keytype,
skey->key.keytype))
skey = &server->keys.val[i];
}
if(skey == NULL){
ret = KRB5KDC_ERR_NULL_KEY;
kdc_log(0, "No key found for server");
goto out;
}
ret = krb5_keytype_to_etype(context, skey->key.keytype, &setype);
{
char *cet, *set, *skt;
krb5_etype_to_string(context, cetype, &cet);
if(cetype != setype)
krb5_etype_to_string(context, setype, &set);
krb5_keytype_to_string(context, sess_ktype, &skt);
if(cetype != setype)
kdc_log(5, "Using %s/%s/%s", cet, set, skt);
else
kdc_log(5, "Using %s/%s", cet, skt);
free(cet);
if(cetype != setype)
free(set);
free(skt);
}
memset(&rep, 0, sizeof(rep)); memset(&rep, 0, sizeof(rep));
rep.pvno = 5; rep.pvno = 5;
@@ -371,7 +414,7 @@ as_rep(KDC_REQ *req,
goto out; goto out;
} }
krb5_generate_random_keyblock(context, ckey->key.keytype, &et.key); krb5_generate_random_keyblock(context, sess_ktype, &et.key);
copy_PrincipalName(b->cname, &et.cname); copy_PrincipalName(b->cname, &et.cname);
copy_Realm(&b->realm, &et.crealm); copy_Realm(&b->realm, &et.crealm);
@@ -508,7 +551,7 @@ as_rep(KDC_REQ *req,
krb5_encrypt_EncryptedData(context, krb5_encrypt_EncryptedData(context,
buf + sizeof(buf) - len, buf + sizeof(buf) - len,
len, len,
etype, setype,
server->kvno, server->kvno,
&ekey->key, &ekey->key,
&rep.ticket.enc_part); &rep.ticket.enc_part);
@@ -525,7 +568,7 @@ as_rep(KDC_REQ *req,
krb5_encrypt_EncryptedData(context, krb5_encrypt_EncryptedData(context,
buf + sizeof(buf) - len, buf + sizeof(buf) - len,
len, len,
etype, cetype,
client->kvno, client->kvno,
&ekey->key, &ekey->key,
&rep.enc_part); &rep.enc_part);
@@ -733,6 +776,7 @@ tgs_make_reply(KDC_REQ_BODY *b, EncTicketPart *tgt,
hdb_entry *server, hdb_entry *client, hdb_entry *server, hdb_entry *client,
krb5_principal client_principal, krb5_principal client_principal,
hdb_entry *krbtgt, hdb_entry *krbtgt,
krb5_enctype cetype,
krb5_data *reply) krb5_data *reply)
{ {
KDC_REP rep; KDC_REP rep;
@@ -741,8 +785,9 @@ tgs_make_reply(KDC_REQ_BODY *b, EncTicketPart *tgt,
KDCOptions f = b->kdc_options; KDCOptions f = b->kdc_options;
krb5_error_code ret; krb5_error_code ret;
int i; int i;
krb5_enctype etype; krb5_enctype setype;
Key *skey, *ekey; Key *skey, *ekey;
krb5_keytype sess_ktype;
/* Find appropriate key */ /* Find appropriate key */
for(i = 0; i < b->etype.len; i++){ for(i = 0; i < b->etype.len; i++){
@@ -755,8 +800,20 @@ tgs_make_reply(KDC_REQ_BODY *b, EncTicketPart *tgt,
kdc_log(0, "Failed to find requested etype"); kdc_log(0, "Failed to find requested etype");
return KRB5KDC_ERR_ETYPE_NOSUPP; return KRB5KDC_ERR_ETYPE_NOSUPP;
} }
sess_ktype = skey->key.keytype;
etype = b->etype.val[i]; skey = NULL;
for(i = 0; i < server->keys.len; i++){
if(skey == NULL || is_better(server->keys.val[i].key.keytype,
skey->key.keytype))
skey = &server->keys.val[i];
}
if(skey == NULL){
ret = KRB5KDC_ERR_NULL_KEY;
kdc_log(0, "No key found for server");
goto out;
}
ret = krb5_keytype_to_etype(context, skey->key.keytype, &setype);
memset(&rep, 0, sizeof(rep)); memset(&rep, 0, sizeof(rep));
memset(&et, 0, sizeof(et)); memset(&et, 0, sizeof(et));
@@ -845,9 +902,7 @@ tgs_make_reply(KDC_REQ_BODY *b, EncTicketPart *tgt,
/* XXX Check enc-authorization-data */ /* XXX Check enc-authorization-data */
krb5_generate_random_keyblock(context, krb5_generate_random_keyblock(context, sess_ktype, &et.key);
skey->key.keytype,
&et.key);
et.crealm = tgt->crealm; et.crealm = tgt->crealm;
et.cname = tgt->cname; et.cname = tgt->cname;
@@ -877,7 +932,7 @@ tgs_make_reply(KDC_REQ_BODY *b, EncTicketPart *tgt,
} }
ekey = unseal_key(skey); ekey = unseal_key(skey);
krb5_encrypt_EncryptedData(context, buf + sizeof(buf) - len, len, krb5_encrypt_EncryptedData(context, buf + sizeof(buf) - len, len,
etype, setype,
server->kvno, server->kvno,
&ekey->key, &ekey->key,
&rep.ticket.enc_part); &rep.ticket.enc_part);
@@ -905,7 +960,7 @@ tgs_make_reply(KDC_REQ_BODY *b, EncTicketPart *tgt,
krb5_encrypt_EncryptedData(context, krb5_encrypt_EncryptedData(context,
buf + sizeof(buf) - len, len, buf + sizeof(buf) - len, len,
etype, /* XXX */ cetype,
0, 0,
&tgt->key, &tgt->key,
&rep.enc_part); &rep.enc_part);
@@ -1015,7 +1070,8 @@ tgs_rep2(KDC_REQ_BODY *b,
hdb_entry *krbtgt; hdb_entry *krbtgt;
EncTicketPart *tgt; EncTicketPart *tgt;
Key *ekey; Key *tkey, *ekey;
krb5_enctype cetype;
krb5_principal cp = NULL; krb5_principal cp = NULL;
krb5_principal sp = NULL; krb5_principal sp = NULL;
@@ -1048,7 +1104,17 @@ tgs_rep2(KDC_REQ_BODY *b,
goto out2; goto out2;
} }
ekey = unseal_key(&krbtgt->keys.val[0]); /* XXX */ ret = hdb_etype2key(context, krbtgt, ap_req.ticket.enc_part.etype, &tkey);
if(ret){
char *str;
krb5_etype_to_string(context, ap_req.ticket.enc_part.etype, &str);
kdc_log(0, "No server key found for %s", str);
free(str);
ret = KRB5KRB_AP_ERR_BADKEYVER;
goto out2;
}
ekey = unseal_key(tkey);
ret = krb5_verify_ap_req(context, ret = krb5_verify_ap_req(context,
&ac, &ac,
&ap_req, &ap_req,
@@ -1065,6 +1131,8 @@ tgs_rep2(KDC_REQ_BODY *b,
goto out2; goto out2;
} }
cetype = ap_req.authenticator.etype;
tgt = &ticket->ticket; tgt = &ticket->ticket;
ret = tgs_check_authenticator(ac, b, &tgt->key); ret = tgs_check_authenticator(ac, b, &tgt->key);
@@ -1087,27 +1155,47 @@ tgs_rep2(KDC_REQ_BODY *b,
s = b->sname; s = b->sname;
r = b->realm; r = b->realm;
#if 0
if(s == NULL) if(b->kdc_options.enc_tkt_in_skey){
if(b->kdc_options.enc_tkt_in_skey && Ticket *t;
b->additional_tickets &&
b->additional_tickets->len >= 1){
krb5_principal p;
hdb_entry *uu; hdb_entry *uu;
principalname2krb5_principal(&p, krb5_principal p;
b->additional_tickets->val[0].sname, Key *tkey;
b->additional_tickets->val[0].realm); if(b->additional_tickets == NULL){
ret = KRB5KDC_ERR_BADOPTION; /* ? */
kdc_log(0, "No second ticket present in request");
goto out;
}
t = &b->additional_tickets->val[0];
principalname2krb5_principal(&p, t->sname, t->realm);
uu = db_fetch(p); uu = db_fetch(p);
krb5_free_principal(context, p); krb5_free_principal(context, p);
if(uu == NULL){ if(uu == NULL){
ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
goto out; goto out;
} }
/* XXX */ ret = hdb_etype2key(context, uu, t->enc_part.etype, &tkey);
}else{ if(ret){
ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
goto out; goto out;
} }
ekey = unseal_key(tkey);
ret = krb5_decrypt_EncryptedData(context, &t->enc_part,
&ekey->key, &result);
if(ret){
/* XXX */
goto out;
}
ret = decode_EncTicketPart(result.data, result.length, &ct, &len);
if(ret){
goto out;
}
s = ct.cname;
r = ct.crealm;
}
#endif
principalname2krb5_principal(&sp, *s, r); principalname2krb5_principal(&sp, *s, r);
krb5_unparse_name(context, sp, &spn); krb5_unparse_name(context, sp, &spn);
@@ -1160,7 +1248,8 @@ tgs_rep2(KDC_REQ_BODY *b,
goto out; goto out;
} }
ret = tgs_make_reply(b, tgt, server, client, cp, krbtgt, reply); ret = tgs_make_reply(b, tgt, server, client, cp,
krbtgt, cetype, reply);
out: out:
free(spn); free(spn);