Connected: An Internet Encyclopedia
A.6. KRB_TGS_REQ verification and KRB_TGS_REP generation
Up:
Connected: An Internet Encyclopedia
Up:
Requests For Comments
Up:
RFC 1510
Up:
A. Pseudo-code for protocol processing
Prev: A.5. KRB_TGS_REQ generation
Next: A.7. KRB_TGS_REP verification
A.6. KRB_TGS_REQ verification and KRB_TGS_REP generation
A.6. KRB_TGS_REQ verification and KRB_TGS_REP generation
/* note that reading the application request requires first
determining the server for which a ticket was issued, and
choosing the correct key for decryption. The name of the
server appears in the plaintext part of the ticket. */
if (no KRB_AP_REQ in req.padata) then
error_out(KDC_ERR_PADATA_TYPE_NOSUPP);
endif
verify KRB_AP_REQ in req.padata;
/* Note that the realm in which the Kerberos server is
operating is determined by the instance from the
ticket-granting ticket. The realm in the ticket-granting
ticket is the realm under which the ticket granting ticket was
issued. It is possible for a single Kerberos server to
support more than one realm. */
auth_hdr := KRB_AP_REQ;
tgt := auth_hdr.ticket;
if (tgt.sname is not a TGT for local realm and is not
req.sname) then error_out(KRB_AP_ERR_NOT_US);
realm := realm_tgt_is_for(tgt);
decode remainder of request;
if (auth_hdr.authenticator.cksum is missing) then
error_out(KRB_AP_ERR_INAPP_CKSUM);
endif
if (auth_hdr.authenticator.cksum type is not supported) then
error_out(KDC_ERR_SUMTYPE_NOSUPP);
endif
if (auth_hdr.authenticator.cksum is not both collision-proof
and keyed) then
error_out(KRB_AP_ERR_INAPP_CKSUM);
endif
set computed_checksum := checksum(req);
if (computed_checksum != auth_hdr.authenticatory.cksum) then
error_out(KRB_AP_ERR_MODIFIED);
endif
server := lookup(req.sname,realm);
if (!server) then
if (is_foreign_tgt_name(server)) then
server := best_intermediate_tgs(server);
else
/* no server in Database */
error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
endif
endif
session := generate_random_session_key();
use_etype := first supported etype in req.etypes;
if (no support for req.etypes) then
error_out(KDC_ERR_ETYPE_NOSUPP);
endif
new_tkt.vno := ticket version; /* = 5 */
new_tkt.sname := req.sname;
new_tkt.srealm := realm;
reset all flags in new_tkt.flags;
/* It should be noted that local policy may affect the */
/* processing of any of these flags. For example, some */
/* realms may refuse to issue renewable tickets */
new_tkt.caddr := tgt.caddr;
resp.caddr := NULL; /* We only include this if they change */
if (req.kdc-options.FORWARDABLE is set) then
if (tgt.flags.FORWARDABLE is reset) then
error_out(KDC_ERR_BADOPTION);
endif
set new_tkt.flags.FORWARDABLE;
endif
if (req.kdc-options.FORWARDED is set) then
if (tgt.flags.FORWARDABLE is reset) then
error_out(KDC_ERR_BADOPTION);
endif
set new_tkt.flags.FORWARDED;
new_tkt.caddr := req.addresses;
resp.caddr := req.addresses;
endif
if (tgt.flags.FORWARDED is set) then
set new_tkt.flags.FORWARDED;
endif
if (req.kdc-options.PROXIABLE is set) then
if (tgt.flags.PROXIABLE is reset)
error_out(KDC_ERR_BADOPTION);
endif
set new_tkt.flags.PROXIABLE;
endif
if (req.kdc-options.PROXY is set) then
if (tgt.flags.PROXIABLE is reset) then
error_out(KDC_ERR_BADOPTION);
endif
set new_tkt.flags.PROXY;
new_tkt.caddr := req.addresses;
resp.caddr := req.addresses;
endif
if (req.kdc-options.POSTDATE is set) then
if (tgt.flags.POSTDATE is reset)
error_out(KDC_ERR_BADOPTION);
endif
set new_tkt.flags.POSTDATE;
endif
if (req.kdc-options.POSTDATED is set) then
if (tgt.flags.POSTDATE is reset) then
error_out(KDC_ERR_BADOPTION);
endif
set new_tkt.flags.POSTDATED;
set new_tkt.flags.INVALID;
if (against_postdate_policy(req.from)) then
error_out(KDC_ERR_POLICY);
endif
new_tkt.starttime := req.from;
endif
if (req.kdc-options.VALIDATE is set) then
if (tgt.flags.INVALID is reset) then
error_out(KDC_ERR_POLICY);
endif
if (tgt.starttime > kdc_time) then
error_out(KRB_AP_ERR_NYV);
endif
if (check_hot_list(tgt)) then
error_out(KRB_AP_ERR_REPEAT);
endif
tkt := tgt;
reset new_tkt.flags.INVALID;
endif
if (req.kdc-options.(any flag except ENC-TKT-IN-SKEY, RENEW,
and those already processed) is set) then
error_out(KDC_ERR_BADOPTION);
endif
new_tkt.authtime := tgt.authtime;
if (req.kdc-options.RENEW is set) then
/* Note that if the endtime has already passed, the ticket */
/* would have been rejected in the initial authentication */
/* stage, so there is no need to check again here */
if (tgt.flags.RENEWABLE is reset) then
error_out(KDC_ERR_BADOPTION);
endif
if (tgt.renew-till >= kdc_time) then
error_out(KRB_AP_ERR_TKT_EXPIRED);
endif
tkt := tgt;
new_tkt.starttime := kdc_time;
old_life := tgt.endttime - tgt.starttime;
new_tkt.endtime := min(tgt.renew-till,
new_tkt.starttime + old_life);
else
new_tkt.starttime := kdc_time;
if (req.till = 0) then
till := infinity;
else
till := req.till;
endif
new_tkt.endtime := min(till,
new_tkt.starttime+client.max_life,
new_tkt.starttime+server.max_life,
new_tkt.starttime+max_life_for_realm,
tgt.endtime);
if ((req.kdc-options.RENEWABLE-OK is set) and
(new_tkt.endtime < req.till) and
(tgt.flags.RENEWABLE is set) then
/* we set the RENEWABLE option for later */
/* processing */
set req.kdc-options.RENEWABLE;
req.rtime := min(req.till, tgt.renew-till);
endif
endif
if (req.rtime = 0) then
rtime := infinity;
else
rtime := req.rtime;
endif
if ((req.kdc-options.RENEWABLE is set) and
(tgt.flags.RENEWABLE is set)) then
set new_tkt.flags.RENEWABLE;
new_tkt.renew-till := min(rtime,
new_tkt.starttime+client.max_rlife,
new_tkt.starttime+server.max_rlife,
new_tkt.starttime+max_rlife_for_realm,
tgt.renew-till);
else
new_tkt.renew-till := OMIT;
/* leave the renew-till field out */
endif
if (req.enc-authorization-data is present) then
decrypt req.enc-authorization-data
into decrypted_authorization_data
using auth_hdr.authenticator.subkey;
if (decrypt_error()) then
error_out(KRB_AP_ERR_BAD_INTEGRITY);
endif
endif
new_tkt.authorization_data :=
req.auth_hdr.ticket.authorization_data +
decrypted_authorization_data;
new_tkt.key := session;
new_tkt.crealm := tgt.crealm;
new_tkt.cname := req.auth_hdr.ticket.cname;
if (realm_tgt_is_for(tgt) := tgt.realm) then
/* tgt issued by local realm */
new_tkt.transited := tgt.transited;
else
/* was issued for this realm by some other realm */
if (tgt.transited.tr-type not supported) then
error_out(KDC_ERR_TRTYPE_NOSUPP);
endif
new_tkt.transited
:= compress_transited(tgt.transited + tgt.realm)
endif
encode encrypted part of new_tkt into OCTET STRING;
if (req.kdc-options.ENC-TKT-IN-SKEY is set) then
if (server not specified) then
server = req.second_ticket.client;
endif
if ((req.second_ticket is not a TGT) or
(req.second_ticket.client != server)) then
error_out(KDC_ERR_POLICY);
endif
new_tkt.enc-part := encrypt OCTET STRING using
using etype_for_key(second-ticket.key),
second-ticket.key;
else
new_tkt.enc-part := encrypt OCTET STRING
using etype_for_key(server.key), server.key,
server.p_kvno;
endif
resp.pvno := 5;
resp.msg-type := KRB_TGS_REP;
resp.crealm := tgt.crealm;
resp.cname := tgt.cname;
resp.ticket := new_tkt;
resp.key := session;
resp.nonce := req.nonce;
resp.last-req := fetch_last_request_info(client);
resp.flags := new_tkt.flags;
resp.authtime := new_tkt.authtime;
resp.starttime := new_tkt.starttime;
resp.endtime := new_tkt.endtime;
omit resp.key-expiration;
resp.sname := new_tkt.sname;
resp.realm := new_tkt.realm;
if (new_tkt.flags.RENEWABLE) then
resp.renew-till := new_tkt.renew-till;
endif
encode body of reply into OCTET STRING;
if (req.padata.authenticator.subkey)
resp.enc-part := encrypt OCTET STRING using use_etype,
req.padata.authenticator.subkey;
else resp.enc-part := encrypt OCTET STRING
using use_etype, tgt.key;
send(resp);
Next: A.7. KRB_TGS_REP verification
Connected: An Internet Encyclopedia
A.6. KRB_TGS_REQ verification and KRB_TGS_REP generation