Subject: AS -- The Authentication Service Exchange
Author: Alex_Raj
In response to: Kerberos Authentication Protocol (V5) -- RFC 1510
Posted on: 11/08/2006 07:10:51 PM
1. Client sends a request to KDC: KRB_AS_REQ
KRB_AS_REQ generation:
request.pvno := protocol version; /* pvno = 5 */
request.msg-type := message type; /* type = KRB_AS_REQ */
if(pa_enc_timestamp_required) then
request.padata.padata-type = PA-ENC-TIMESTAMP;
get system_time;
padata-body.patimestamp,pausec = system_time;
encrypt padata-body into request.padata.padata-value
using client.key; /* derived from password */
endif
body.kdc-options := users's preferences;
body.cname := user's name;
body.realm := user's realm;
body.sname := service's name; /* usually "krbtgt",
"localrealm" */
if (body.kdc-options.POSTDATED is set) then
body.from := requested starting time;
else
omit body.from;
endif
body.till := requested end time;
if (body.kdc-options.RENEWABLE is set) then
body.rtime := requested final renewal time;
endif
body.nonce := random_nonce();
body.etype := requested etypes;
if (user supplied addresses) then
body.addresses := user's addresses;
else
omit body.addresses;
endif
omit body.enc-authorization-data;
request.req-body := body;
kerberos := lookup(name of local kerberos server (or servers));
send(packet,kerberos);
wait(for response);
if (timed_out) then
retry or use alternate server;
endif
2. KDC sneds a reply to client: KRB_AS_REP or KRB_ERROR
KRB_AS_REQ verification and KRB_AS_REP generation
decode message into req;
client := lookup(req.cname,req.realm);
server := lookup(req.sname,req.realm);
get system_time;
kdc_time := system_time.seconds;
if (!client) then
/* no client in Database */
error_out(KDC_ERR_C_PRINCIPAL_UNKNOWN);
endif
if (!server) then
/* no server in Database */
error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
endif
if(client.pa_enc_timestamp_required and
pa_enc_timestamp not present) then
error_out(KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP));
endif
if(pa_enc_timestamp present) then
decrypt req.padata-value into decrypted_enc_timestamp
using client.key;
using auth_hdr.authenticator.subkey;
if (decrypt_error()) then
error_out(KRB_AP_ERR_BAD_INTEGRITY);
if(decrypted_enc_timestamp is not within allowable
skew) then error_out(KDC_ERR_PREAUTH_FAILED);
endif
if(decrypted_enc_timestamp and usec is replay)
error_out(KDC_ERR_PREAUTH_FAILED);
endif
add decrypted_enc_timestamp and usec to replay cache;
endif
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 := req.srealm;
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 */
if (req.kdc-options.FORWARDABLE is set) then
set new_tkt.flags.FORWARDABLE;
endif
if (req.kdc-options.PROXIABLE is set) then
set new_tkt.flags.PROXIABLE;
endif
if (req.kdc-options.ALLOW-POSTDATE is set) then
set new_tkt.flags.ALLOW-POSTDATE;
endif
if ((req.kdc-options.RENEW is set) or
(req.kdc-options.VALIDATE is set) or
(req.kdc-options.PROXY is set) or
(req.kdc-options.FORWARDED is set) or
(req.kdc-options.ENC-TKT-IN-SKEY is set)) then
error_out(KDC_ERR_BADOPTION);
endif
new_tkt.session := random_session_key();
new_tkt.cname := req.cname;
new_tkt.crealm := req.crealm;
new_tkt.transited := empty_transited_field();
new_tkt.authtime := kdc_time;
if (req.kdc-options.POSTDATED is set) then
if (against_postdate_policy(req.from)) then
error_out(KDC_ERR_POLICY);
endif
set new_tkt.flags.INVALID;
new_tkt.starttime := req.from;
else
omit new_tkt.starttime; /* treated as authtime when
omitted */
endif
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);
if ((req.kdc-options.RENEWABLE-OK is set) and
(new_tkt.endtime < req.till)) then
/* we set the RENEWABLE option for later processing */
set req.kdc-options.RENEWABLE;
req.rtime := req.till;
endif
if (req.rtime = 0) then
rtime := infinity;
else
rtime := req.rtime;
endif
if (req.kdc-options.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);
else
omit new_tkt.renew-till; /* only present if RENEWABLE */
endif
if (req.addresses) then
new_tkt.caddr := req.addresses;
else
omit new_tkt.caddr;
endif
new_tkt.authorization_data := empty_authorization_data();
encode to-be-encrypted part of ticket into OCTET STRING;
new_tkt.enc-part := encrypt OCTET STRING
using etype_for_key(server.key), server.key, server.p_kvno;
/* Start processing the response */
resp.pvno := 5;
resp.msg-type := KRB_AS_REP;
resp.cname := req.cname;
resp.crealm := req.realm;
resp.ticket := new_tkt;
resp.key := new_tkt.session;
resp.last-req := fetch_last_request_info(client);
resp.nonce := req.nonce;
resp.key-expiration := client.expiration;
resp.flags := new_tkt.flags;
resp.authtime := new_tkt.authtime;
resp.starttime := new_tkt.starttime;
resp.endtime := new_tkt.endtime;
if (new_tkt.flags.RENEWABLE) then
resp.renew-till := new_tkt.renew-till;
endif
resp.realm := new_tkt.realm;
resp.sname := new_tkt.sname;
resp.caddr := new_tkt.caddr;
encode body of reply into OCTET STRING;
resp.enc-part := encrypt OCTET STRING
using use_etype, client.key, client.p_kvno;
send(resp);
3. KRB_AS_REP verification
decode response into resp;
if (resp.msg-type = KRB_ERROR) then
if(error = KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP))
then set pa_enc_timestamp_required;
goto KRB_AS_REQ;
endif
process_error(resp);
return;
endif
/* On error, discard the response, and zero the session key */
/* from the response immediately */
key = get_decryption_key(resp.enc-part.kvno, resp.enc-part.etype,
resp.padata);
unencrypted part of resp := decode of decrypt of resp.enc-part
using resp.enc-part.etype and key;
zero(key);
if (common_as_rep_tgs_rep_checks fail) then
destroy resp.key;
return error;
endif
if near(resp.princ_exp) then
print(warning message);
endif
save_for_later(ticket,session,client,server,times,flags);
4. KRB_AS_REP and KRB_TGS_REP common checks
if (decryption_error() or
(req.cname != resp.cname) or
(req.realm != resp.crealm) or
(req.sname != resp.sname) or
(req.realm != resp.realm) or
(req.nonce != resp.nonce) or
(req.addresses != resp.caddr)) then
destroy resp.key;
return KRB_AP_ERR_MODIFIED;
endif
/* make sure no flags are set that shouldn't be, and that */
/* all that should be are set */
if (!check_flags_for_compatability(req.kdc-options,resp.flags))
then destroy resp.key;
return KRB_AP_ERR_MODIFIED;
endif
if ((req.from = 0) and
(resp.starttime is not within allowable skew)) then
destroy resp.key;
return KRB_AP_ERR_SKEW;
endif
if ((req.from != 0) and (req.from != resp.starttime)) then
destroy resp.key;
return KRB_AP_ERR_MODIFIED;
endif
if ((req.till != 0) and (resp.endtime > req.till)) then
destroy resp.key;
return KRB_AP_ERR_MODIFIED;
endif
if ((req.kdc-options.RENEWABLE is set) and
(req.rtime != 0) and (resp.renew-till > req.rtime)) then
destroy resp.key;
return KRB_AP_ERR_MODIFIED;
endif
if ((req.kdc-options.RENEWABLE-OK is set) and
(resp.flags.RENEWABLE) and
(req.till != 0) and
(resp.renew-till > req.till)) then
destroy resp.key;
return KRB_AP_ERR_MODIFIED;
endif
>
> On 11/08/2006 06:47:42 PM
Alex_Raj wrote:
The authentication process proceeds as follows: A client sends a request to the authentication server (AS) requesting "credentials" for a given server. The AS responds with these credentials, encrypted in the client's key. The credentials consist of 1) a "ticket" for the server and 2) a temporary encryption key (often called a "session key"). The client transmits the ticket (which contains the client's identity and a copy of the session key, all encrypted in the server's key) to the server. The session key (now shared by the client and server) is used to authenticate the client, and may optionally be used to authenticate the server. It may also be used to encrypt further communication between the two parties or to exchange a separate sub-session key to be used to encrypt further communication.
The Kerberos protocol consists of several sub-protocols (or exchanges):
AS -- The Authentication Service Exchange
TGS-- The Ticket-Granting Service Exchange
CS -- The Client/Server Authentication Exchange
References: