Previous section.

DCE 1.1: Authentication and Security Services
Copyright © 1997 The Open Group

Key Distribution (Authentication) Services

This chapter specifies the key distribution, or authentication, services supported by DCE, together with the protocols associated with them. Currently, only one such service is supported, namely the Kerberos Key Distribution Service (KDS), so this whole chapter is devoted to that. The KDS is comprised of two specialised (sub-)services, the Authentication (Sub-)Service (AS) (not to be confused with the generic terminology "authentication service") and the Ticket-granting (Sub-)Service (TGS)- and for that reason the KDS is sometimes also referred to as the AS/TGS.

For an overview of this chapter, see Kerberos Key Distribution (Authentication) Service (KDS) through Cells-Cross-cell Authentication and Authorisation -which are considered a prerequisite for this whole chapter.

Notes:

  1. This chapter is based on, and (unless stated otherwise) is technically aligned with, (a subset of) RFC 1510. However, for editorial reasons, this chapter stands independently, and no familiarity with RFC 1510 is required. (Thus, the part of this chapter that duplicates information in RFC 1510 is intended to be technically equivalent to that document, rewritten for the expository purposes of this document, and any technical discrepancies between the two are inadvertent and to be reconciled.) Differences between the two documents are minor and are readily justified, but the reader should note in particular the following changes:

    1. What is called "cell" in DCE is called "realm" in RFC 1510.

    2. The service called Key Distribution Service (KDS) here is called Key Distribution Center (KDC) there (the difference in terminology merely indicating their preferred communications medium, RPC or raw UDP).

    3. The data type identifiers in the two documents are conservatively different, in an attempt to improve clarity and consistency (instead of, for example, using a mixture of ASN.1, C and other identifiers, such as "AP-REQ", "KRB_AP_REQ" and "authentication header" all referring to the same object in RFC 1510, Section 5.5.1), without affecting interoperability or placing conformance requirements on implementations.

    For the convenience of the reader, cross-references between this document and RFC 1510 are explicitly indicated generously throughout this chapter, using notation of the form "[RFC 1510: x.y.z]" as a reference to RFC 1510, Section x.y.z.

  2. Extensive use is made in this chapter of natural-language algorithmic descriptions. In them, it is the mainline "success" (non-error) case that is emphasised-in particular, this document permits different implementations to encounter errors (exceptions) in different orders, and so report different errors under the same external conditions. This is indicated by marking error conditions in algorithms by "{errStatusCode-NAME-OF-ERROR}" (perhaps with some explanatory material), leaving to implementations the decision at what point to abort a failed algorithm, and which error to report.

  3. [RFC 1510: 5.1]

    This chapter employs the "ASN.1/BER/DER" standards for data description/representation (IDL is used only in The krb5rpc RPC Interface ), which are defined in three CCITT (now ITU-T) Recommendations. The data description language used is Abstract Syntax Notation One (ASN.1), which is defined in CCITT X.208. The data representation (encoding) used for data described by ASN.1 is the Basic Encoding Rules (BER), which are defined in CCITT X.209. Familiarity with those documents, including the data types defined in them, is required for this chapter.

    Additionally, the following Distinguished Encoding Restrictions (DER) to BER, as specified in CCITT X.509, Section 8.7- (only) the ones actually used in this chapter are repeated here, in order that this chapter can stand independently of CCITT X.509- are in effect:

    1. The definite form of length encoding shall be used, encoded in the minimum number of octets.

    2. For string types, the constructed form of encoding shall not be used.

    3. Each unused bit in the final octet of the encoding of a BIT STRING value, if there are any, shall be reset (to 0).

    Furthermore, implementations that transmit any currently unspecified bits of BIT STRING must reset them, for reasons of future extensibility and compatibility. (Note that some existing implementations emit full BER, not just the DER subset-new implementations that want to interoperate with those old implementations should therefore accept full BER, but in order to be conformant to this document they must generate DER.)

    Finally, when ASN.1 descriptions are referenced during the course of pseudocode expositions, ASN.1 is augmented with the familiar (but non-ASN.1-standard) pseudocode dot notation for field elements. For SEQUENCEs, this takes the form illustrated by the example: if seq is a value of type SeqType ::= SEQUENCE {int [0] INTEGER, oct [1] OCTET}, then the values of the fields of seq are denoted seq.int and seq.oct, respectively. For BIT STRINGs, it takes a similar form: for example, if bits is a value of type Bits ::= BIT STRING {bit0 (0), bit1 (1), bit2 (2)}, then the values of the bits of bits are denoted bits.bit0, bits.bit1 and bits.bit2, respectively. If the value in question (for example, seq or bits) is implicitly understood from context, it (and the dot immediately following it) may even be omitted if no confusion will result. For SEQUENCE OFs, ASN.1 is further augmented with the familiar pseudocode bracket notation for arrays: if seqof is a value of type, say, SeqOfType ::= SEQUENCE OF {SeqType}, having 2 entries, then its entries are denoted seqof[0] and seqof[1].

Fundamental Concepts

[RFC 1510: 1]

This chapter deals with the authentication of (RPC) clients and servers, in the context of cells. The following general notational conventions will be used for these concepts. Recall that the home cell of a principal is the cell whose RS datastore holds the security information for the principal. (More precisely, "a" home cell of a principal should be spoken of, since some principals may be registered in multiple cells-though this is not to be recommended in general. DCE specifies just one, very specific, kind of multiply registered principal, namely cross-cell surrogate KDS server principals (see below), and in that case care should be taken to indicate which cell is being considered its home cell in a given situation. For non-KDS principals, continue to speak of "the" home cell, leaving to the reader the (easy) translation to the case of multiple-registration.)

These (especially cells) often appear as subscripts (for example, KDSZ, KDSX,Y), but in order to improve legibility of embedded subscripts they will upgraded when they themselves appear in subscripts (for example, KKDSZ, KKDSXY instead of KKDSZ, KKDS\dX,Y).

The KDS is a distributed, partitioned RPC service, instantiated by a (conceptually unitary, but potentially replicated) RPC server in each cell Z, denoted KDSZ. If the name of cell Z is, say, /.../cellZ, then the RPC service name of KDSZ (used for RPC binding purposes) is determined from /.../cellZ/cell-profile via the krb5rpc interface UUID and version number (specified in The krb5rpc RPC Interface ) -typically, the name associated with this profile element will be /.../cellZ/sec, which will be an RPC server group pointing to the individual (replicated) KDSZ server(s). (See RPC Binding Models for more details on binding models.) (The principal names of KDS servers (used for security purposes)- as opposed to their RPC server names (used for communications purposes) -are introduced in RS Names and Principal Names .)

The krb5rpc RPC Interface

[RFC 1510: 8.2]

Each KDS server, KDSZ, supports the following RPC interface (data types not defined in this specification are defined in the referenced Open Group DCE 1.1 RPC Specification):

[uuid(8f73de50-768c-11ca-bffc-08001e039431), version(1.0)] interface krb5rpc { /* begin running listing of krb5rpc interface */ [idempotent] void kds_request ( [in] handle_t rpc_handle, [in] unsigned32 request_count, [in, size_is(request_count)] byte request[], [in] unsigned32 response_count_max, [out] unsigned32 *response_count, [out, size_is(response_count_max), length_is(*response_count)] byte response[], [out] error_status_t *status ); } /* end running listing of krb5rpc interface */

The semantics of kds_request() are that a client, C, invokes kds_request() to "send a KDS Request message" to a KDS server, KDSZ; C receives a KDS Response message from KDSZ when kds_request() returns. Its parameters are the following:

The contents, formats and semantics of request[] and response[] (including their lengths, request_count and response_count) are defined below (beginning in AS and TGS Services , but their full elaboration consumes this entire chapter).

Note:
RFC 1510 specifies security protocols that can be supported (with the same security guarantees) over various communications mechanisms. Typical non-DCE implementations use UDP (port 88) as the communications mechanism (in conformance with RFC 1510). The krb5rpc interface as specified in this document uses RPC as the communications mechanism.

AS and TGS Services

[RFC 1510: 1]

There is no single service known as "the KDS service" supported by KDS servers. Instead, KDS servers support two services, each of which is associated with a specific kind of corresponding pair of request/response messages, as follows (for definitions of "initial" and "subsequent" tickets, see Tickets, Keys, and Cross-Registration ):

Thus, a KDS Request message is either an AS Request or TGS Request message, and a KDS Response message is either an AS Response or TGS Response message. The KDS supports one additional kind of response message, for reporting errors:

Tickets, Keys, and Cross-Registration

[RFC 1510: 1, 1.1, 2.1]

(Kerberos) tickets are the (trusted) information objects that the KDS manages (and which are returned by kds_request(), as will be seen in this chapter). Tickets have three kinds of identities associated with them:

As will be seen below, there are relationships amongst A, B, X, Y and Z´, ···, Z´´ that must be satisfied for a ticket to be valid, namely a trust chain must be established:

A -> TCBX -> TCBZ´ -> ··· -> TCBZ´´ -> TCBY -> B

Here, the arrows denote links in the trust chain, not communicated messages; more precisely (as discussed below), the above trust chain notation is actually shorthand for the trust chain of principals:

A -> KDSX,X -> KDSX,Z´ -> ··· -> KDSZ´´,Y -> KDSY,Y -> B

The following notation can be used:

TktA,X,Z´,···,Z´´,Y,B or TktA,Z´,···,Z´´,B

for a ticket as described above. The home cells X and Y can be omitted from the notation because they are implicitly known from knowledge of A and B, but it is convenient to include them for information. All the issuing authorities can even be omitted from the notation if they are implicitly understood or are uninteresting in a given context:

TktA,···,B or TktA,B

The simple special case of intra-cell tickets can be abbreviated:

TktA,X,B (instead of TktA,X,X,B)

As described in Key-based Security: Kerckhoffs' Doctrine , encryption keys are the a priori trusted objects upon which the DCE trusted environment in general is leveraged (in accordance with Kerckhoffs' Doctrine), and in particular are the means by which tickets are protected. These keys come in 2 "flavours" (actually, as discussed below, encryption keys in general depend also on a selected encryption type and optionally a key version number, but these can be mostly omitted from the discussion and notation):

Tickets carry a short-term key in them, called a session key, and are protected by the long-term key of their targeted server. It is this session key that is the concrete manifestation of the abstract notion of "authentication" between a client and server. As will be seen, a client C can successfully use a ticket to authenticate to the targeted server only if C knows the ticket's session key (though C need not be the ticket's named client). That is, "stolen" tickets (obtained, say, by "wiretapping") are useless (assuming the keys involved are not compromised). Application data communicated between client and server is protected by a session key (transmitted by a ticket) or by a negotiated conversation key (transmitted by an authentication header or reverse-authentication header).

Tickets are further classified into two broad kinds of category:

This categorisation divides tickets into 4 classes (initial ticket-granting-tickets, subsequent ticket-granting-tickets, initial service-tickets and subsequent service-tickets), all of which can and do actually occur in practice. However, the category of initial service-tickets is rather rare. (An example would be a "password-changing" program that insisted on an initial ticket to guarantee that the user changing his/her password has "recent knowledge" of the old password (as opposed to an intruder requesting a password change via an unattended seat or hijacked session); if the password-changing program is running under an identity other than the KDS, this initial ticket will be an initial service ticket.)

In order for the definition of ticket to make sense, KDS servers must in fact "be principals", in the sense of being registered in the RS datastores in their cells, and this is always assumed to be the case. The principal corresponding to the KDS server in cell X is denoted by the same notation, KDSX, if no confusion will result, or by the expanded notation KDSX,X if emphasis is needed. (Strictly speaking, the notation KDSX should be reserved for the KDS server "as for TCB component (communicating entity)", and KDSX,X should be reserved to denote the KDS server "as for principal".)

More generally, it is possible for a KDS server, KDSX, to issue a ticket targeted to a KDS server, KDSY, other than itself. In order for this to happen, KDSY must know the key of a principal registered in RSX- that principal is denoted by KDSX,Y. This arrangement is called a cross-cell registration of KDS servers; KDSX,Y is called a surrogate (principal) of KDSY in cell X, and its long-term key stored in RSX, KKDSXY, is called a cross-cell key. At the same time, this same principal KDSX,Y is also registered in RSY, with a different principal stringname (because it's in a different cell) but with the same cross-cell key, KKDSXY-and principal (in RSY) is also called a surrogate (principal) of KDSY. Thus, in this terminology, "surrogate" refers to the principal KDSX,Y registered in both RSX and in RSY (with the same key KKDSXY), the only distinction between the two being their principal names (which reflects the cells they are being considered in; that is, which RS datastore their principal information is held in)-and for that reason, the combined terminology cross-cell surrogate (double principal) is sometimes used; and this principal is also said to mediate the X -> Y trust link. Finally, cross-cell registration also always entails the symmetrically defined surrogate registration of KDSX in RSY: thus, KDSY,X is the surrogate of KDSX in cell Y (and in cell X), both with the same long-term key KKDSYX, mediating the Y -> X trust link. (See Cells-Cross-cell Authentication and Authorisation for more discussion.)

Some Basic Data Types

A number of common, non-security-specific data types are defined in this section. Note that the descriptions of the semantics of the data types in this section through KDS Errors are supported by descriptions of the KDS services in AS Request/Response Processing through KDS Error Processing , giving the rationale by which applications can evaluate the trust to be placed in the KDS's support of these semantics.

Protocol Version Numbers

[RFC 1510: 8.3]

Protocol version numbers are represented by the ProtocolVersionNumber data type, which is defined as follows:

ProtocolVersionNumber ::= INTEGER

Its semantics are that it identifies the KDS protocol version in use. Values for protocol version numbers are centrally registered. Currently registered values are collected in Registered Protocol Version Numbers .

Registered Protocol Version Numbers

[RFC 1510: 8.3]

The currently registered values for ProtocolVersionNumber are the following:

Protocol Message Types

[RFC 1510: 8.3]

Protocol message types are represented by the ProtocolMessageType data type, which is defined as follows:

ProtocolMessageType ::= INTEGER

Its semantics are that it identifies KDS protocol messages. Values for protocol message types are centrally registered. Currently registered values are collected in Registered Protocol Message Types .

Registered Protocol Message Types

[RFC 1510: 8.3]

The currently registered values for ProtocolMessageType are the following (the format and semantics of these messages are defined in Authentication Headers through KDS Errors ).

(Note that the other protocol message types defined in RFC 1510 are not defined or used in DCE.)

Timestamps, Microseconds, and Clock Skew

[RFC 1510: 5.2, 5.3.2]

Timestamps are represented by the TimeStamp data type, which is defined as follows:

TimeStamp ::= GeneralizedTime -- X.208 32.3b

Its semantics are that it indicates the generating system clock's UTC time (see the referenced Open Group DCE 1.1 Time Services Specification), in the syntax of CCITT X.208, Section 32.3b, measured to the granularity of seconds. This syntax is a string of 15 characters, the first 14 of which are the first 14 decimal digits of a DTS string format timestamp, and the 15th of which is the character "Z". Thus, if this syntax is denoted by "CCYYMMDDhhmmssZ", then CCYY indicates the (century and) year, MM the month, DD the day, hh the hour, mm the minute, and ss the second. For example, the TimeStamp "19950825163947Z" indicates the UTC time: "AD August 25, 1995, at 4:39:47 PM".

Note:
The appearance of the character "Z" is historical. It is a reference to the "Z" (usually verbalised as "Zulu") time zone. See the referenced Open Group DCE 1.1 Time Services Specification for more information.

Note that although the TimeStamp data type is a string type on which no ordering is defined a priori, there is an obvious sense (of "earlier" and "later") in which timestamps can be compared (see also the referenced Open Group DCE 1.1 Time Services Specification), and this ordering of TimeStamps will be assumed throughout this chapter. Similarly, there is an obvious sense in which arithmetic operations can be applied to TimeStamps. Namely, the ordering and arithmetic operations are those resulting from regarding the 14 digits of a TimeStamp as representing an integer, instead of merely a character string.

One particular timestamp is singled out for special attention (see KDS Request Body ); this is the "end-of-time" timestamp, which is defined as follows (midnight, January 1, 1970):

endOfTimeStamp TimeStamp ::= "197001010000Z"

Furthermore, endOfTimeStamp is considered to occur "later" than any other timestamp, in the order mentioned above.

Finally, some protocol elements require, in addition to a timestamp, a microsecondstamp (that is, "microsecond-granularity timestamp"). This is represented by the MicroSecond data type, which is defined as follows:

MicroSecond ::= INTEGER -- 0..999999

The only allowable values of this data type are in the range [0, 999999]. Nominally, the semantic of this data type is to indicate the number of microseconds past an accompanying (second-granularity) timestamp. However, the real security semantic of this data type is to function as a per-second nonce (see Nonces below).

Note:
Thus, implementations of the DCE security services on systems that do not have hardware clocks supporting microsecond granularity can finesse the MicroSecond data type by simply supporting its security semantic. This can be accomplished, for example, by a "pseudo-microsecond register", which merely increments by one (mod 1,000,000) after each request for a microsecondstamp (resetting the register to 0 every second is unnecessary). (In order to preserve the semantics of nonces, this assumes the hardware is incapable of servicing more than 1,000,000 such requests per second.)
Maximum Allowable Clock Skew

[RFC 1510: 1.2]

No two clocks in a distributed environment can be synchronised perfectly. In a DCE environment, the DTS service keeps clocks closely synchronised, and even maintains a measure of their inaccuracy (distance from UTC). The KDS's use of timestamps depends also on near-synchronisation with UTC, but further requires only, instead of the fine-grained DTS inaccuracies, a very coarse measure of clock skew (distance between the clock producing a timestamp and the clock interpreting it, independently of UTC). Namely, the KDS protocols require that clocks are synchronised with one another (and hence, because of DTS, with UTC) to within a maximum allowable clock skew, denoted maxClockSkew -which is not a single, fixed quantity, but is maintained separately for each clock (and can even be variable (for example, time-dependent or session-dependent) per clock, depending on local policy).

The maxClockSkew takes into consideration not only the non-perfect synchronisation of distinct clocks, but also the various expected (and, to some extent, the unexpected) delays due to communications transmission ("networking") and other processing. Typically, the values of maxClockSkew are on the order of 5 minutes-a figure that is much less than the typical lifetime of tickets, and is chosen so as not to introduce unwarranted security risks into the protocols described below. (Five minutes is so much greater than the typical inaccuracies guaranteed by DTS clock synchronisation that the granularity of seconds in TimeStamps (without including the DTS inaccuracies) is quite sufficient.)

All timestamp interpretations in this chapter are to be understood "modulo maxClockSkew" (where the word "modulo" is here used in its common English sense, not in its technical mathematical sense, for which the short form "mod" is reserved). For example, to say that two timestamps, T0 and T1, are "equal" means that 1T0 - T1| <= maxClockSkew (where maxClockSkew is the maximum allowable clock skew appropriate to the interpreting clock). Similarly, the "lifetime" of a ticket (introduced below), which is nominally the (closed) time interval [tkt-StartTime, tkt-ExpireTime], is in actuality to be interpreted as [tkt-StartTime - maxClockSkew, tkt-ExpireTime + maxClockSkew] (where maxClockSkew is the one appropriate to the interpreting clock).

Note:
In accordance with the actual semantic of the MicroSecond data type as a nonce instead of its nominal semantic as a microsecond, maxClockSkew is applied only to timestamps T, not to pairs <T, M> of timestamps and microsecondstamps. See the discussion of server "replay caches" (which is the only place that the semantics MicroSeconds are actually used), in Authenticators .

Cell Names

[RFC 1510: 5.2]

Cell (or, equivalently, realm) names are represented by the CellName data type, which is defined as follows:

CellName ::= GeneralString -- X.208 31.2; ISO 2022, 2375

Its semantics are that it provides references to cells by means of a "global naming/directory service" (see the referenced Open Group DCE 1.1 Directory Services Specification), which is "external" to security services (contrast this with RS names, below). Cell names themselves carry enough syntactic information to distinguish amongst different global naming services (hence a separate "-Type" field is not necessary for cell names, as it is for RS names). Acceptable syntaxes for cell names are centrally registered. Currently registered syntaxes are collected in Registered Syntaxes for Cell Names .

Note that global naming services are typically hierarchically organised, and interpret certain syntactic metacharacters (such as "/") as separators of hierarchical naming components. However, for the purposes of the security services provided by the KDS, cell names are uninterpreted ("opaque") (that is, not manipulated or processed, such as decomposing them into hierarchical components), except for testing for equality.

Registered Syntaxes for Cell Names

[RFC 1510: 7.1]

The currently registered syntaxes for CellNames are the following. Note that these syntaxes do not begin with an initial "/.../"; when these syntaxes are considered in conjunction with the fully qualified DCE syntax, an initial "/.../" is to be prepended, as specified in the referenced Open Group DCE 1.1 Directory Services Specification.

Transit Paths

[RFC 1510: 5.3.1]

Transit paths are represented by the TransitPath data type, which is defined as follows:

TransitPathType ::= INTEGER TransitPathValue ::= OCTET STRING TransitPath ::= SEQUENCE { transitPath-Type [0] TransitPathType, transitPath-Value [1] TransitPathValue }

Its semantics are that it indicates the trust chain of KDS servers that have participated in a cross-cell authentication. Its fields are the following:

Values of TransitPathType are reserved for centrally registered transit path data types. The currently registered values are collected in Registered Transit Path Types .

Note:
Negative values of TransitPathType do not appear to be specified as unreserved (and therefore available for local assignment) by [RFC 1510: 5.3.1].
Registered Transit Path Types

[RFC 1510: 8.3, 3.3.3.1]

The currently registered values for TransitPathType are as follows:

The transit paths (values of type transitPath-Value) of this transit path type represent the (underlying OCTET STRINGs of the) cell names (that is, CellName GeneralStrings) of the successive transited cells, treated as an unordered set (in other words, not necessarily in the order in which they were visited), expressed in a syntax that supports lexical compression (to conserve communications bandwidth), as specified below. This transit path type depends on the Internet DNS and DCE X.500 syntaxes being the only cell name types in effect; transit paths of this type typically contain no upper-case letters (since the "canonicalised" forms of names in these syntaxes contain no upper-case letters), though implementations must accept both cases on input.

Note:
It must be emphasised that the "compression" component of this syntax is of a lexical nature only. TransitPaths must always faithfully represent every cell that has actually participated in a cross-cell authentication, and never short-circuit transit paths (for example, by recording only "third legs of trust triangles"). That is, transit paths are intended to give a complete secure record only of the sequence of individual links of cross-cell trust chains-the global evaluation of transit path trust (that is, of the "overall shape of the trust chain") is a higher-level function. In the DCE environment, this function is carried out by the PS, not the KDS (see Privilege (Authorisation) Services ).

In the transitPathType-DNS-X500 syntax, the initial "/.../" of the DCE naming syntax is always omitted (that is, it is implicitly present). Also for this syntax, the following characters are metacharacters; that is, they have special properties discussed in this section (and are to be distinguished from the metacharacters for the DNS and X.500 syntaxes-for those, see the referenced Open Group DCE 1.1 Directory Services Specification):

","
This metacharacter separates the (potentially compressed) representations of successive cell names of a transit path. These are called the components of the transit path, and they can be empty (that is, two ","s can occur successively, and "," can occur at the beginning and/or at the end of a transit path).

"\"
An "escape" metacharacter. Any metacharacter (including "\" itself) can be escaped by (immediately) preceding it with a "\" (with the semantic that the escaped metacharacter is no longer considered to be a metacharacter; that is, it no longer has the special properties discussed here). Unless explicitly indicated otherwise, metacharacters appearing in this specification are assumed to be unescaped (that is, the character immediately preceding them, if any, is not a "\" character).

"/"
When it occurs at the beginning of a component (otherwise, it's a non-metacharacter).

"*"
(This notation is used in this section to denote a "space" character, for visual clarity.) When it occurs at the beginning of a component (otherwise, it's a non-metacharacter).

"."
When it occurs at the end of a component (otherwise, it's a non-metacharcter).

In the transitPathType-DNS-X500 syntax, no component can both begin with a "/" and end with a ".". A component that is empty, or begins with "/", or ends with "." is said to be compressed; otherwise, it is said to be expanded. A transit path that contains one or more compressed components, or which begins or ends with a ",", is said to be compressed; otherwise, it is said to be expanded.

In any application of the transitPathType-DNS-X500 syntax, two cells will be singled out for special treatment: a "client" and a "server" cell (relative to a posited "client-server relationship", which will always be clear from context). Conceptually, the client cell always occurs at the beginning of a transit path, and the server cell always occurs at the end; however, these occurrences of these cells are always implicit, and are never indicated explicitly in a transit path (either compressed or expanded).

An empty transit path (one having no components) is represented by a character string of length 0; it indicates either a trust chain of length 0 (that is, an intra-cell trust path), or of length 1 (that is, a cross-cell trust path with a direct cross-cell registration between the client's cell and the server's cell, with no intermediaries). A non-empty expanded component "stands for itself" (that is, directly represents a cell name, in the DNS or X.500 naming syntax). A non-empty compressed component must consist of a non-empty string of non-metacharacters, prepended with an initial "/" or "*", or appended with a terminal ".", but not both.

Compressed transit paths represent expanded transit paths, by expanding their compressed components one at a time, left to right, according to the following rules (examples are given below):

Here are some examples of some compressed transit paths, and their expansions (where, for clarity in the expansions, the client and server cells are shown explicitly, and the symbol "->" is used with them and also in place of the "," metacharacter). (Recall that the initial "/.../" of the DCE naming syntax is only implicitly, not explicitly, present.)

RS Names

[RFC 1510: 5.2]

Registry Service (RS) names are represented by the RSName data type, which is defined as follows:

RSNameType ::= INTEGER RSNameValue ::= SEQUENCE OF GeneralString RSName ::= SEQUENCE { rsName-Type [0] RSNameType, rsName-Value [1] RSNameValue }

Its semantics are that it indicates the per-cell hierarchical names supported by the RS datastores. Its fields are the following:

Values of RSNameType are reserved for centrally registered principal names types.

Note:
Negative values of RSNameType do not appear to be specified as unreserved (and therefore available for local assignment) by [RFC 1510: 5.2].

The currently registered values are collected in Registered RS Name Types .

Registered RS Name Types

[RFC 1510: 7.2, 8.2.3]

The currently registered values for RSNameType are the following:

Note:
The RS datastore contains various named items other than principals (for example, groups and organisations), however these are irrelevant to the Kerberos authentication architecture specified in this chapter, so they do not rate an RSNameType. In particular, there is no architectural relationship between server instances (as defined here) and RS groups.

As discussed in RS Editor RPC Interfaces , the RS identifies principals via a hierarchical ("/"-separated) string-based namespace whose syntax is identical to the CDS naming syntax (which is specified in the referenced Open Group DCE 1.1 Directory Services Specification). The sequence of components of those string-names map canonically to the sequence of (underlying GeneralStrings of the) components of rsName-Value of type rsNameType-PRINCIPAL.

The main use of the RS name type rsNameType-SERVER-INSTANCE is for the KDS itself, especially in cross-cell registrations. In that application, rsName-Value[0] is krbtgt (a name which is reserved for this use), and (the underlying GeneralString of) rsName-Value[1] is identical to the string-name of the cross-registered cell's KDS. This is illustrated by the following examples, assuming X and Y are cells with names cellX and cellY, respectively (actually, "cellX" and "cellY" denote cell names with an internal syntactic structure (for example, Internet DNS syntax or DCE X.500 syntax), but that is irrelevant for this example):

Unless stated otherwise, all RS names in this chapter identifying KDSs (including their surrogates) are assumed to have type rsNameType-SERVER-INSTANCE, and all non-KDSs are assumed to have type rsNameType-PRINCIPAL.

Note:
There are no security mechanisms in place to enforce adherence to these conventions. In particular, the mere occurrence in an RS name of a type indicator, such as rsNameType-SERVER-INSTANCE (indicating, according to the convention just articulated, a KDS surrogate), does not in itself imply any degree of trust in the RS name: all parts of the KDS protocol treat RS names of all types exactly the same. See also the uniqueness requirement in Principal Names . (This is sometimes expressed by saying that the RS name's type is "merely a hint".)

Principal Names

[RFC 1510: 5.2]

Principal names are represented by the CellAndRSName data type, which is defined as follows:

CellAndRSName ::= SEQUENCE { cellName [0] CellName, rsName [1] RSName }

Its semantics are that it represents a "fully qualified" (in the semantic sense, not the syntactic sense) principal name, consisting of a cell name and an RS name.

The relationship between the semantic CellAndRSName data type and the DCE syntactic string forms of principal names (or just stringnames, for short) is as follows: if cellAndRSName is a value of type CellAndRSName, whose underlying cellName is, say, cellX, and whose underlying rsName-Values (that is, their underlying GeneralStrings, disregarding their rsName-Types) are, say, <rsName0, ···, rsNamer-1>, then the corresponding string form of cellAndRSName is:

/.../cellX/rsName0/···/ rsNamer-1

Implementations of the DCE security services must guarantee that these stringnames are unique or unambiguous, in the sense that every such stringname refers to at most one principal. Users, including administrators, trust the implementation to guarantee this. In particular, in cross-cell operations, a cell's security administrator must not establish a trust link (that is, exchange KDS registrations) with multiple foreign cells having the same cell name, or whose RS namespace is not trusted to guarantee this uniqueness.

Note that the CellAndRSName data type doesn't occur directly in the remaining data types and protocols defined in the remainder of this chapter: the concept of principal name is used throughout, though its two component fields (cellName and rsName) appear separately, not bound together in a CellAndRSName data type.

Note:
It would make sense to use the identifier "PrincipalName" instead of "CellAndRSName" for the data type defined above. However, that would conflict with the terminology of RFC 1510, which uses the identifier "PrincipalName" to denote the data type called "RSName" in DCE. Unfortunately, RFC 1510's definition of "PrincipalName" conflicts with the commonsense notion of "principal name" (and with RFC 1510's own expository use of the notion of "principal name"), which connotes global uniqueness, not the mere per-cell-context local uniqueness of RSNames. Hence, to avoid confusion, the identifier "PrincipalName" is avoided altogether in DCE.

Host Addresses

[RFC 1510: 5.2]

Note:
The notion of "(transport-level) host addresses" properly belongs to the realm of communications (see the referenced Open Group DCE 1.1 RPC Specification), as opposed to that of security, and arguably should play no role in a security specification. Nevertheless, RFC 1510 does specify usages of host addresses for security purposes, namely that servers may (depending on policy) deny service to clients on the basis of the client's host address, unless such clients exhibit the appropriate "proxied" or "forwarded" credentials. In order to support coexistence of RFC 1510 environments and DCE environments, host addresses are therefore supported by DCE. However, KDS servers conformant to DCE must not issue initial tickets (to AS Requests) to clients that do not supply at least one host address, and non-KDS servers conformant to DCE must not deny service to clients on the basis of the client's host address(es) (these requirements could change in future revisions of DCE). Thus, host addresses do not currently figure into the DCE security model with nearly the significance they have in RFC 1510. See Part of Ticket to be Encrypted .

Host addresses are represented by the HostAddresses data type, which is defined as follows:

HostAddressType ::= INTEGER HostAddressValue ::= OCTET STRING HostAddresses ::= SEQUENCE OF SEQUENCE { hostAddr-Type [0] HostAddressType, hostAddr-Value [1] HostAddressValue }

Its semantics are that it represents the host (that is, computer) address(es) (zero or more of them) at which a host is connected to a communications (network) substrate. Its fields are the following:

Non-negative values of HostAddressType are reserved for centrally registered host address types; negative values are unreserved (and may, therefore, be assigned locally). The currently registered values are collected in Registered Host Address Types .

Registered Host Address Types

[RFC 1510: 8.1]

Note:
In order for this specification to be complete, it should supply references to definitive specifications for the host address types listed below. However, that is not done in RFC 1510 (and therefore, in order not to preempt RFC 1510 on this point, it is not done here). Furthermore, it is not necessary to do so in DCE, because this information is insignificant in DCE environments (as explained in the Note in Host Addresses ; see also Part of Ticket to be Encrypted ). Therefore, such references are not given here, and so for the purposes of this specification the following list is supplied only because it is "suggestive".

The currently registered values for HostAddressType are the following:

Sequence Numbers

[RFC 1510: 3.2.2, 5.3.2]

Sequence numbers are represented by the SequenceNumber data type, which is defined as follows:

SequenceNumber ::= INTEGER

Its semantics are that it indicates the sequence number of a message in a multi-message sequence (for example, the (potentially) several fragments of a fragmented message). The detailed use of sequence numbers is application-specific. Typically, the initial sequence number is chosen randomly (see below for "random" numbers), and subsequent sequence numbers are unit increments from the initial one. For security purposes, the individual messages (fragments) and the sequence numbers themselves must be bound together and protected in an appropriate application-specific way. (In the case of DCE RPC applications, the use of sequence numbers is specified as part of the RPC protocol specifications-see Protected RPC .)

Last Requests

[RFC 1510: 5.2]

Last requests are represented by the LastRequests data type, which is defined as follows:

LastRequestType ::= INTEGER LastRequestValue ::= TimeStamp LastRequests ::= SEQUENCE OF SEQUENCE { lastReq-Type [0] LastRequestType, lastReq-Value [1] LastRequestValue }

Its semantics are that it indicates information maintained by a principal's home KDS of the principal's most recent KDS service requests. Its fields are the following:

All values of LastRequestType are reserved for centrally registered last request types. The currently registered values are collected in Registered Last Request Types .

Registered Last Request Types

[RFC 1510: 5.2]

The currently registered values for LastRequestType are the following, together with the interpretation of corresponding values of LastRequestValue. Positive values pertain to the whole cell of the responding KDS server (which cell may contain multiple instances or replicas of KDS servers); negative values pertain only to the individual responding KDS server itself.

Error Status Codes/Text/Data

[RFC 1510: 5.9.1]

Error status codes are represented by the ErrorStatusCode data type; error status text is represented by the ErrorStatusText data type; error status data is represented by the ErrorStatusData data type. These are defined as follows:

ErrorStatusCode ::= INTEGER ErrorStatusText ::= GeneralString ErrorStatusData ::= OCTET STRING

Their semantics are that they indicate error conditions of a failed KDS Request. Values of these three data types always occur as a triple consisting of an ErrorStatusCode, an ErrorStatusText (optionally) and an ErrorStatusData (optionally). The value of ErrorStatusCode identifies an error that occurred; ErrorStatusText is a character string accompanying ErrorStatusCode explaining the error in a human-readable fashion, and ErrorStatusData is supplementary information further explaining the error in machine-readable fashion. Note that since ErrorStatusData is merely an "opaque" OCTET STRING, its interpretation must be implicit from the corresponding ErrorStatusCode.

Values of error status codes (with associated error text and data) are centrally registered. The currently registered values are collected in Registered Error Status Codes/Text/Data .

Notes:

  1. Negative values of ErrorStatusCode do not appear to be specified as unreserved (and therefore available for local assignment) by [RFC 1510: 5.9.1].

  2. In addition to reporting error codes not specified here, implementations are also permitted to report errors at algorithmic execution points other than those specified in this chapter. For example, a server's failure to allocate memory for a data structure may be reported to the client.

Registered Error Status Codes/Text/Data

[RFC 1510: 8.3]

The currently registered values for error codes/text/data are the following. The notational convention is used where NAME-OF-ERROR denotes a string specific to each error condition:

Registered status codes without accompanying registered status text and/or status data indicates that the latter are not currently specified (but may be in a later revision of this document). (Some terminology is used in these descriptions that won't be formally introduced until later.)

Cryptography- and Security-Related Data Types

The data types defined in this section are specifically related to cryptography and security.

Nonces

[RFC 1510: 5.4.1, 5.8.1]

Nonces are represented by the Nonce data type, which is defined as follows:

Nonce ::= INTEGER

Its semantics are that it indicates a per-context unique (or distinct, or "one-time") number; that is, a number which is always distinguishable from any other when used in a given context (where an appropriate notion of "context" must be specified whenever nonces are used). In the particular application of nonces in this chapter (.cX sec4-12-3 and Client Receives TGS Response ), they are used to distinguish a client's KDS Requests from one another (to help thwart "replay attacks"). Therefore, the security semantics of nonces in this chapter are that client principals need to believe (to a degree compatible with the security policies in effect) that the nonces associated with distinct KDS Requests from the same client principal will always be distinct. Implementations must, for example, take into consideration that "instances" of the same client principal may be active in different login sessions, perhaps even simultaneously (but that is an implementation-specific consideration not discussed further here).

Notes:

  1. Even though a nonce generator of "cryptographically high quality" is necessary for security, this notion is not further specified in DCE. In particular, no specific nonce algorithm is (currently) specified. (This lack of specification does not affect interoperability.)

  2. In Conversation Manager in_data , nonces are introduced that are byte-vectors, instead of integers. However, the same principles as described above apply with appropriate modification of detail to that case, and need not be elaborated here.

Random Numbers

[RFC 1510: 3.1.3, 3.2.6]

Random "numbers" (actually, byte vectors) are represented by the Random data type, which is defined as follows:

Random ::= OCTET STRING

Its semantics are that it indicates a number which is unpredictable. That is, it is required that random number generators used in any implementation of the DCE Security Services are of cryptographic high-quality; that is, it must be computationally infeasible to predict the next random number to be generated, even if the sequence of all previously generated random numbers are known. In essence, this means that every possible value has equal probability of being generated as every other value, at every invocation of the random number generator, but there may be occasions when slight modifications of this idea are warranted (for example, when keys are "changed", the "new" key should be guaranteed to be different than the "old" key).

Notes:

  1. Even though a random number generator of "cryptographically high quality" is necessary for security, this notion is not further specified in DCE. In particular, no specific random algorithm is (currently) specified. (This lack of specification does not affect interoperability.)

  2. The BER encoding respects the (big-endian) identification that has been made between bit-sequences of length a multiple of 8 and byte sequences. Therefore, random "numbers" can be spoken of equivalently either as byte-vectors or as bit-vectors (but not as integers), without possibility of confusion.

Encryption Keys

[RFC 1510: 6.2]

Encryption keys are represented by the EncryptionKey data type, which is defined as follows:

EncryptionKeyType ::= INTEGER EncryptionKeyValue ::= Random EncryptionKey ::= SEQUENCE { encKey-Type [0] EncryptionKeyType, encKey-Value [1] EncryptionKeyValue }

Its semantics are that it indicates the key for (one or more) encryption mechanism(s) and/or checksum mechanisms (see below). Its fields are the following:

Non-negative values of EncryptionKeyType are reserved for centrally registered encryption key types; negative values are unreserved (and may, therefore, be assigned locally). The currently registered values are collected in Registered Encryption Key Types .

Registered Encryption Key Types

[RFC 1510: 6.3.1, 8.3]

The currently registered values for EncryptionKeyType are the following:

Checksums

[RFC 1510: 6.4]

Checksums are represented by the CheckSum data type, which is defined as follows:

CheckSumType ::= INTEGER CheckSumValue ::= OCTET STRING CheckSum ::= SEQUENCE { cksum-Type [0] CheckSumType, cksum-Value [1] CheckSumValue }

Its semantics are that it indicates a (non-invertible) checksum (or message digest, or one-way function) of some plaintext (which must be specified in context). Its fields are the following:

Non-negative values of CheckSumType are reserved for centrally registered checksum mechanism types; negative values are unreserved (and may, therefore, be assigned locally). The currently registered values are collected in Registered Checksum Types .

Registered Checksum Types

[RFC 1510: 6.4.5, 8.3, 9.1]

The currently registered values for CheckSumType are the following.

Notes:

  1. The DES-CBC checksum was defined in DES-CBC Checksum , but it does not occur in the following list.)

  2. DCE does not specify a trivial checksum, say "cksumType-TRIVIAL", paralleling the encKeyType-TRIVIAL of Registered Encryption Key Types . It would be possible to specify such a trivial checksum (having, say cksumType-TRIVIAL = 0, and whose corresponding checksumtext, cksum-Value is always the bit-vector of length 0), but it is unnecessary to do so. The reason is that the only place the checkSum data type occurs in DCE is as the authnr-Cksum field of authenticators (see Authenticators ), which is an optional field. Therefore, any application that wants to "transmit a checksum of type cksumType-TRIVIAL" needs merely to omit this field.

    [RFC 1510: 6.3.1]

Encrypted Data

[RFC 1510: 6.1]

Note:
This section and its subsection give the detailed definition of the notation "{M}K" introduced in Kerberos Key Distribution (Authentication) Service (KDS) .
Encrypted data is represented (after it has been encrypted) by the EncryptedData data type, which is defined as follows:
EncryptionType ::= INTEGER EncKeyVersionNumber ::= INTEGER CipherText ::= OCTET STRING EncryptedData ::= SEQUENCE { encData-EncType [0] EncryptionType, encData-KeyVersNum [1] EncKeyVersionNumber OPTIONAL, encData-CipherText [2] CipherText }

Its semantics are that it indicates an (invertible) encryption of some plaintext (which must be specified in context). Its fields are the following:

Non-negative values of EncryptionType are reserved for centrally registered encryption types; negative values are unreserved (and may, therefore, be assigned locally). The currently registered values are collected in Registered Encryption Types .

Registered Encryption Types

[RFC 1510: 6.1, 6.3.1, 6.3.2, 6.3.3, 6.3.4, 8.3, 9.1]

The currently registered values for EncryptionType are the following:

Note that, by including a checksum in the ciphertext itself, the DES-CBC-CRC DES-CBC-MD4 and DES-CBC-MD5 ciphertexts exhibit built-in integrity; that is, correct decryption can be determined solely by inspecting the internal consistency of the resulting plaintext itself, without relying on information external to it. Said another way: "integrity (at this level) is the concern of the cryptography layer itself, not of the consumer of cryptographic services". In particular, the length of the plaintext need not be conveyed explicitly (at "application level"; that is, by the consumer of cryptographic services) for the purposes of integrity. (However, if the plaintext P is derived from an "original" application-level message M which has been padded to an integral number of DES blocks, then conveying the number of padding bytes is usually a convenient thing to do, and conveying the length of M is a common way to do that.)

Note:
It is intended that all encryption mechanisms (except for encType-TRIVIAL) registered in this document shall incorporate built-in integrity similar to that of encType-DES-CBC-CRC, encType-DES-CBC-MD4 and encType-DES-CBC-MD5.

Note that the degree of assurance of this built-in integrity depends upon the strength of the cryptographic algorithms involved. In particular, non-collision-proof checksums (such as CRC-32) may be susceptible to attacks (such as truncation attacks) that render some assertions invalid (such as the one in the preceding paragraph about not needing to explicitly convey the length of the plaintext).

Passwords

[RFC 1510: 1.2, 6]

Passwords are represented by the PassWord data type, which is defined here to be merely a byte-string.

Its semantics are that it indicates a (byte string representation of a) character string (typically a "memorisable but unguessable" one, relative to some natural language) associated with a principal, C, from which the long-term encryption key KC for C (relative to a specified encryption type encType), held in the RS datastore, is derived. The notion of passwords exists because there is a need for humans to be able to securely store a secret, and the best way to do that is to memorise it ("store it in their brain"), which is within normal human capabilities for passwords but not for random ("strong") encryption keys. DCE specifies one or more password-to-encryption-key mapping for each supported encryption key type, and these mappings are centrally registered. The currently registered ones are collected in Registered Password-to-Key Mappings .

Note:
Passwords per se are irrelevant to the KDS (because they do not appear in kds_request()); they are relevant only to the Login Facility. However, password-to-key mappings do have security significance and depend on cryptography, so it is appropriate to define them in this chapter. Note furthermore that implementations may further restrict (on an implementation-specific basis) the passwords they accept (for example, to avoid easily guessable passwords, or passwords that map into possibly weak keys, and so on-such things are presently beyond the scope of this specification).
Registered Password-to-Key Mappings

[RFC 1510: 6.3.4]

The password-to-key mappings supported by DCE return as an output parameter an encryption key of an appropriate type, and take as input parameters the following two data items:

Corresponding to the input parameters cellName and rsName (which are GeneralStrings), the underlying BER string of "contents octets" of their GeneralStrings is denoted (that is, the BER encoding stripped of its "identifier octets" and "length octets"-no "end-of-contents octets" are present because of the DER in force), which are strings of octets, by respectively:

The default salt, mentioned above but not yet specified explicitly, is now defined to be:

DEFAULTSALT = <CN, RSN0, ···, RSNr-1>

In words: DEFAULTSALT is the concatenation of (the underlying strings of octets of) CN and of the components of RSN.

With the above notations, the currently registered password-to-key mappings, corresponding to the currently registered encryption key types, are defined as follows.

Minimum Implementation Requirements

All implementations must support passwords and salts consisting of characters drawn from the DCE Portable Character Set (PCS) (see Appendix A, Universal Unique Identifier, of the referenced Open Group DCE 1.1 Directory Services Specification).

Note:
Some implementations may support passwords consisting of characters beyond the PCS. Users should be aware, however, that there are practical limitations on the makeup of passwords, associated with "seat portability". Namely, "input methods" for all GeneralStrings do not necessarily exist at all "seats" from which the user may want to login. Therefore, users must restrict the choice of characters in their passwords to the characters they know will be supported at all the seats from which they will want to login. For universal seat portability, users must restrict their passwords to the DCE PCS (because of the PCS minimal implementation requirement for all implementations of DCE stated in this section).

Authentication Data

[RFC 1510: 5.4.1]

Authentication data is represented by the AuthnData data type, which is defined as follows:

AuthnDataType ::= INTEGER AuthnDataValue ::= OCTET STRING AuthnData ::= SEQUENCE { authnData-Type [1] AuthnDataType, authnData-Value [2] AuthnDataValue }

Its semantics are that it indicates information that is exchanged between clients and KDS servers (in KDS Request/Response exchanges), which may be required before KDS services (that is, ticket issuance) can be accessed. (Note that the KDS does not support ACLs for access control to its AS/TGS services-just the opposite: tickets are required before PACs can be obtained, on which ACLs are based.) In the case of AS Request/Responses (as opposed to TGS Request/Responses), this information is usually referred to as pre-authentication data, because AS Request/Responses are, in fact, "unauthenticated" (in the sense of not containing an "authentication header" as defined in Authentication Headers ). Its fields are the following:

Non-negative values of AuthnDataType are reserved for centrally registered authentication data types; negative values are unreserved (and may, therefore, be assigned locally). The currently registered values are collected in Registered Authentication Data Types .

Registered Authentication Data Types

[RFC 1510: 8.3]

The currently registered values for AuthnDataType are the following:

Authorisation Data

[RFC 1510: 5.2]

Authorisation data is represented by the AuthzData data type, which is defined as follows:

AuthzDataType ::= INTEGER AuthzDataValue ::= OCTET STRING AuthzData ::= SEQUENCE OF SEQUENCE { authzData-Type [0] AuthzDataType, authzData-Value [1] AuthzDataValue }

Its semantics are that it indicates information that may be (depending on application-specific authorisation policy) needed by a server in order to determine a client's access to the server's services. Its fields are the following:

Non-negative values of AuthzDataType are reserved for centrally registered authorisation data types; negative values are unreserved (and may, therefore, be assigned locally). The currently registered values are collected in Registered Authorisation Data Types .

Note:
The usage semantics to be attached to authorisation data is application-specific, but typically a value authzData of data type AuthzData is used for access based on the so-called "AND model"; that is, the elements of the array, authzData[0], ···, authzData[n-1], all "further restrict" one another. That is to say, it is typically used to determine access in the following manner:
if (authzData[0], ···, authzData[n-1] all grant access) { GRANT access; } else { DENY access; }
Registered Authorisation Data Types

[RFC 1510: 8.3]

The currently registered values for AuthzDataType are the following:

Tickets

[RFC 1510: 5.3.1]

Tickets are represented by the Ticket data type, which is defined as follows:

Ticket ::= [APPLICATION 1] SEQUENCE { tkt-ProtoVersNum [0] ProtocolVersionNumber, tkt-ServerCell [1] CellName, tkt-ServerName [2] RSName, tkt-EncryptedPart [3] EncryptedData }

Its semantics have been described in Tickets, Keys, and Cross-Registration , where the notation TktA,B for a ticket with named client A in cell X and targeted server B in cell Y are introduced (eliding, here, any issuing authority(ies), KDSZ´, ···, KDSZ´´ from the notation). In terms of this notation, its fields are the following:

Part of Ticket to be Encrypted

[RFC 1510: 5.3.1]

The encrypted data carried in a ticket is represented (before it is encrypted) by the TicketEncryptPart data type, which is defined as follows:

TicketEncryptPart ::= [APPLICATION 3] SEQUENCE { tkt-Flags [ 0] TicketFlags, tkt-SessionKey [ 1] EncryptionKey, tkt-ClientCell [ 2] CellName, tkt-ClientName [ 3] RSName, tkt-TransitPath [ 4] TransitPath, tkt-AuthnTime [ 5] TimeStamp, tkt-StartTime [ 6] TimeStamp OPTIONAL, tkt-ExpireTime [ 7] TimeStamp, tkt-MaxExpireTime [ 8] TimeStamp OPTIONAL, tkt-ClientAddrs [ 9] HostAddresses OPTIONAL, tkt-AuthzData [10] AuthzData OPTIONAL }

Its fields are the following:

Note that tickets are not in general interpretable (in the sense of being decryptable) by their named clients (except in the case where the named client also happens to be the targeted server). Nevertheless, the information in them is otherwise (securely) available to the named client. Namely (as seen in Client Receives AS Response and Client Receives TGS Response ), all the fields except tkt-TransitPath and tkt-AuthzData are available in the KDS Response that delivers the ticket to the client. The client knows tkt-TransitPath because it is itself involved in passing this ticket to the corresponding issuing authorities identified by the transit path. The tkt-AuthzData field is not dealt with in this chapter, but as seen in Privilege (Authorisation) Services , this information is communicated to the client by the PS in a DCE environment.

Ticket Flags

[RFC 1510: 2, 5.2, 5.3.1]

The options that may be selected by a ticket, TktA,B (that is, requested by the named client A, specified by issuing authority(ies), or interpreted by the targeted server B), are represented by the TicketFlags data type, which is defined as follows:

TicketFlags ::= BIT STRING { tkt-Forwardable (1), tkt-Forwarded (2), tkt-Proxiable (3), tkt-Proxied (4), tkt-Postdatable (5), tkt-Postdated (6), tkt-Invalid (7), tkt-Renewable (8), tkt-Initial (9) }

The semantics of these bits are that if a value of type TicketFlags has the corresponding bit set (to 1) then the option is selected; if the bit is reset (to 0), the option is deselected. The bits indicate the following options (bits not currently specified are reserved for future usage):

Note that the above descriptions do not give complete details. For that, see that detailed descriptions of these flags, in AS Request/Response Processing and TGS Request/Response Processing .

Authenticators

[RFC 1510: 3.2.3, 5.3.2]

Authenticators are represented by the Authenticator data type, which is defined as follows:

Authenticator ::= [APPLICATION 2] SEQUENCE { authnr-ProtoVersNum [0] ProtocolVersionNumber, authnr-ClientCell [1] CellName, authnr-ClientName [2] RSName, authnr-Cksum [3] CheckSum OPTIONAL, authnr-ClientMicroSec [4] MicroSecond, authnr-ClientTime [5] TimeStamp, authnr-ConversationKey [6] EncryptionKey OPTIONAL, authnr-SeqNum [7] SequenceNumber OPTIONAL, authnr-AuthzData [8] AuthzData OPTIONAL }

Its semantics are that it accompanies TktA,B in a client-server service request, and proves to B that this request is "really from A", in the sense that it was sent from A "now" (modulo maxClockSkew). Its fields are the following:

This can be used to support "least privilege" access policies.

Authentication Headers

[RFC 1510: 5.5.1]

Authentication headers are represented by the AuthnHeader data type, which is defined as follows (where APPLICATION 14 indicates protoMsgType-AUTHN-HEADER-see Registered Protocol Message Types ):

AuthnHeader ::= [APPLICATION 14] SEQUENCE { authnHdr-ProtoVersNum [0] ProtocolVersionNumber, authnHdr-ProtoMsgType [1] ProtocolMessageType, authnHdr-Flags [2] AuthnHeaderFlags, authnHdr-Tkt [3] Ticket, authnHdr-EncryptedAuthnr [4] EncryptedData }

Its semantics are that it supplies the forward authentication information that actually "authenticates a client A to a server B", by binding together an authenticator and a ticket, TktA,B (naming A and targeted to B), associated with one another. Its fields are the following:

Of course, it is the final two fields that are the most significant -and for that reason, an authentication header is sometimes referred to as a "ticket and authenticator" (both of which are cryptographically protected).

Authentication Header Flags

[RFC 1510: 5.2, 5.5.1]

The options that may be selected by an authentication header (that is, specified by the client A named by TktA,B (authnHdr-Tkt), or interpreted by the targeted server B) are represented by the AuthnHeaderFlags data type, which is defined as follows:

AuthnHeaderFlags ::= BIT STRING { authnHdr-UseSessionKey (1), authnHdr-MutualRequired (2) }

The semantics of these bits are that if a value of type AuthnHeaderFlags has the corresponding bit set then the option is selected; if the bit is reset, the option is deselected. The bits represent the following options (bits not currently specified are reserved for future usage):

The use-session-key Option

[RFC 1510: 3.2.3]

The use-session-key option is not used anywhere in DCE. therefore a detailed explanation of it would lead too far afield and is not appropriate here. However, a rough explanation of how it might be used at application level is given in this section, as an indication of its potential. Such an application-level usage is said to be a "user-to-user authentication protocol". (In this section a shorthand notation is used; for example, omitting ticket fields that are unnecessary for the purposes here.)

Recall (see Kerberos Key Distribution (Authentication) Service (KDS) ) that the basic Kerberos protocol for a client A to authenticate to a server B begins by having the client A obtain a session key KA,KDS and a ticket, TktA,KDS, from the AS, and then proceeds with the following series of exchanges (retaining here only those terms that are critical to the discussion at hand):

where TktA,B = {A, KA,B}KB. The main point to focus on for the purposes of this discussion is that TktA,B is protected with the long-term key KB of B. This requires, in order for B to be able to decrypt TktA,B, that B "knows" (has access to) its long-term key. But the requirement of having its long-term key readily accessible could be a risk for B, especially if the machine on which B runs is not physically secured (for example, a "public workstation").

The above protocol can be modified so that TktA,B is replaced by another ticket, Tkt*A,B, which is protected with a short-term (session) key (whose compromise represents a much smaller risk), K* = KB,KDS, as follows. Suppose that A has obtained a copy of B's (ticket-granting-)ticket, TktB,KDS, (= {B, KB,KDS}KKDS); note this is not a security risk to A or B, and the manner of A's obtaining B's ticket need not be secure -for example, B might have sent a copy of TktB,KDS to A, or B might have "published" its TktB,KDS in a public place (such as in a directory service datastore) and A retrieved a copy of it. Then the required protocol can be achieved by:

where TktB,KDS (also denoted "Tkt*", without subscripts, in this context) is an "additional ticket" (trusted by B) that conveys to the KDS (via the use-session-key option) the session key KB,KDS (also denoted "K*", without subscripts, in this context) that is used to protect Tkt*A,B; that is, Tkt*A,B = {A, KA,B}K*.

As presented in this brief discussion, the advantage of using Tkt*A,B instead of TktA,B is by no means apparent. But it becomes a powerful tool when embedded in an overall architecture of so-called secret-key certificates (as opposed to public-key certificates), here implemented as tickets used in new ways, because it permits many of the advantages of public-key protocols to be implemented using secret-key encryption. The deeper exploration of this is, however, beyond the scope of this specification.

Reverse-Authentication Headers

[RFC 1510: 5.5.2]

Reverse-authenticator headers are represented by the RevAuthnHeader data type, which is defined as follows (where APPLICATION 15 indicates protoMsgType-REVAUTHN-HEADER-see Registered Protocol Message Types ):

RevAuthnHeader ::= [APPLICATION 15] SEQUENCE { revAuthnHdr-ProtoVersNum [0] ProtocolVersionNumber, revAuthnHdr-ProtoMsgType [1] ProtocolMessageType, revAuthnHdr-EncryptedPart [2] EncryptedData }

Its semantics are that it supplies the reverse authentication information that actually "authenticates a server B to a client A", by extracting certain information from a corresponding authentication header (that the client trusts is only accessible by the legitimate server) and returning it (securely) to the client. Its fields are the following:

Part of Reverse-authentication Header to be Encrypted

[RFC 1510: 5.5.2]

The part of a reverse-authentication header to be encrypted is represented (before it is encrypted) by the RevAuthnHeaderEncryptPart data type, which is defined as follows:

RevAuthnHeaderEncryptPart ::= [APPLICATION 27] SEQUENCE { revAuthnHdr-ClientTime [0] TimeStamp, revAuthnHdr-ClientMicroSec [1] MicroSecond, revAuthnHdr-ConversationKey [2] EncryptionKey OPTIONAL, revAuthnHdr-SeqNum [3] SequenceNumber OPTIONAL }

Its fields are the following:

KDS (AS and TGS) Requests

[RFC 1510: 5.4.1]

AS Requests are represented by the ASRequest data type, and TGS Requests are represented by the TGSRequest data type. These are defined in terms of a common underlying data type, KDSRequest, as follows (where APPLICATION 10 indicates protoMsgType-AS-REQUEST, and APPLICATION 12 indicates protoMsgType-AS-RESPONSE-see Registered Protocol Message Types ):

ASRequest ::= [APPLICATION 10] KDSRequest TGSRequest ::= [APPLICATION 12] KDSRequest KDSRequest ::= SEQUENCE { req-ProtoVersNum [1] ProtocolVersionNumber, req-ProtoMsgType [2] ProtocolMessageType, req-AuthnData [3] SEQUENCE OF AuthnData OPTIONAL, req-Body [4] KDSRequestBody }

Its semantics are to indicate a calling client A's request to a KDS server KDSZ to return a TktA,B targeted to a server B (where B may be another KDS server, KDSZ´). KDS servers (such as KDSZ) support requests for the following two distinct kinds of services:


The fields of KDSRequest are the following:

KDS Request Body

[RFC 1510: 5.4.1]

KDS Request message bodies are represented by the KDSRequestBody data type, which is defined as follows:

KDSRequestBody ::= SEQUENCE { req-Flags [ 0] KDSRequestFlags, req-ClientName [ 1] RSName OPTIONAL, req-ServerCell [ 2] CellName, req-ServerName [ 3] RSName, req-StartTime [ 4] TimeStamp OPTIONAL, req-ExpireTime [ 5] TimeStamp, req-MaxExpireTime [ 6] TimeStamp OPTIONAL, req-Nonce [ 7] Nonce, req-EncTypes [ 8] SEQUENCE OF EncryptionType, req-ClientAddrs [ 9] HostAddresses OPTIONAL, req-EncryptedAuthzData [10] EncryptedData OPTIONAL, req-AdditionalTkts [11] SEQUENCE OF Ticket OPTIONAL }

Its fields are the following:

KDS Request Flags

[RFC 1510: 5.2, 5.4.1]

The options that may be requested in a KDS Request are represented by the KDSRequestFlags data type, which is defined as follows:

KDSRequestFlags ::= BIT STRING { req-Forwardable ( 1), req-Forward ( 2), req-Proxiable ( 3), req-Proxy ( 4), req-Postdatable ( 5), req-Postdate ( 6), req-Renewable ( 8), req-RenewableOK (27), req-UseSessionKey (28), req-Renew (30), req-Validate (31) }

The semantics of these bits are that if a value of type KDSRequestFlags has the corresponding bit set then the option is selected; if the bit is reset, the option is deselected. The bits represent the following options (bits not currently specified are reserved for future usage):

KDS (AS and TGS) Responses

[RFC 1510: 5.4.2]

AS Responses are represented by the ASResponse data type, and TGS Responses are represented by the TGSResponse data type. These are defined in terms of a common underlying data type, KDSResponse, which is defined as follows (where APPLICATION 11 indicates protoMsgType-TGS-REQUEST, and APPLICATION 13 indicates protoMsgType-TGS-RESPONSE-see Registered Protocol Message Types ):

ASResponse ::= [APPLICATION 11] KDSResponse TGSResponse ::= [APPLICATION 13] KDSResponse KDSResponse ::= SEQUENCE { resp-ProtoVersNum [0] ProtocolVersionNumber, resp-ProtoMsgType [1] ProtocolMessageType, resp-AuthnData [2] AuthnData OPTIONAL, resp-ClientCell [3] CellName, resp-ClientName [4] RSName, resp-Tkt [5] Ticket, resp-EncryptedPart [6] EncryptedData }

Its semantics are to indicate the called KDSZ's response to a client A's request for a ticket. Its fields are the following:

Part of KDS Response to be Encrypted

[RFC 1510: 5.4.2]

The encrypted data carried in a KDS Response is represented (before it is encrypted) by the KDSResponseEncryptPart data type, which is defined as follows:

ASResponseEncryptPart ::= [APPLICATION 25] KDSResponseEncryptPart TGSResponseEncryptPart ::= [APPLICATION 26] KDSResponseEncryptPart KDSResponseEncryptPart ::= SEQUENCE { resp-SessionKey [ 0] EncryptionKey, resp-LastRequests [ 1] LastRequests, resp-Nonce [ 2] Nonce, resp-KeyExpireDate [ 3] TimeStamp OPTIONAL, resp-Flags [ 4] TicketFlags, resp-AuthnTime [ 5] TimeStamp, resp-StartTime [ 6] TimeStamp OPTIONAL, resp-ExpireTime [ 7] TimeStamp, resp-MaxExpireTime [ 8] TimeStamp OPTIONAL, resp-ServerCell [ 9] CellName, resp-ServerName [10] RSName, resp-ClientAddrs [11] HostAddresses OPTIONAL }

Its fields are the following. Note that most of this duplicates information that is present in the enclosed TktA,B (resp-Tkt), so that A can check its conformance to what it had requested in the corresponding KDS Request (A cannot actually decrypt TktA,B itself, unless A happens to know the long-term key of the targeted server B). (The only information in TktA,B that is not repeated in KDSResponseEncryptPart are its transit path and authorisation data.)

KDS Errors

[RFC 1510: 5.9.1]

KDS Errors are represented by the KDSError data type, which is defined as follows (where APPLICATION 30 indicates protoMsgType-KDS-ERROR -see Registered Protocol Message Types ):

KDSError ::= [APPLICATION 30] SEQUENCE { err-ProtoVersNum [ 0] ProtocolVersionNumber, err-ProtoMsgType [ 1] ProtocolMessageType, err-ClientTime [ 2] TimeStamp OPTIONAL, err-ClientMicroSec [ 3] MicroSecond OPTIONAL, err-ServerTime [ 4] TimeStamp, err-ServerMicroSec [ 5] MicroSecond, err-StatusCode [ 6] ErrorStatusCode, err-ClientCell [ 7] CellName OPTIONAL, err-ClientName [ 8] RSName OPTIONAL, err-ServerCell [ 9] CellName, err-ServerName [10] RSName, err-StatusText [11] ErrorStatusText OPTIONAL, err-StatusData [12] ErrorStatusData OPTIONAL }

Its semantics are that it indicates diagnostic information returned from a server C to a calling client A concerning a failed (in the security sense) service request. The primary usage is when C is a KDS server KDSZ, but it can also be used by applications if they so desire. In any case, KDS Error messages are unprotected, therefore the information carried in them must be viewed with suspicion in a hostile environment. Its fields are the following:

RS Information

[RFC 1510: 4]

Every KDSZ requires access to certain (non-volatile) information. Such information is held in the RSZ datastore, not in the KDSZ itself. RSZ maintains local cell-wide property and policy information, as well as information pertaining to individual principals, relevant to KDSZ's processing of KDS Requests (below). These information items, together with the KDS Error status code values associated with them, are the following:

AS Request/Response Processing

[RFC 1510: 1, 3.1]

This section specifies in detail the processing that occurs during an AS Request/Response exchange; that is, this section specifies the issuing of new initial tickets. There are three steps involved:

  1. A client prepares an AS Request and sends it to a KDS server.

  2. A KDS server receives the AS Request from a client, processes it, prepares an AS Response (success case) or KDS Error (failure case), and returns that to the client.

  3. A client receives an AS Response or KDS Error.

The details of the three steps of the success case are specified next. (For the failure case, see KDS Error Processing .)

Client Sends AS Request to KDS

[RFC 1510: 3.1.1, A.1]

Consider a client A that wants to obtain an initial ticket, TktA,B, from KDSX, where X is A's home cell. (Usually, though not necessarily, an initial ticket is a ticket-granting-ticket; that is, the target server B will usually be KDSX itself. In any case, B must be in cell X, or the AS Request will fail.) Then A prepares an AS Request, asReq (a value of the data type ASRequest), and "sends it" (that is, calls kds_request()) to KDSX, according to the following algorithm. Note that it is A's responsibility to know (or to securely determine) all the information necessary to correctly formulate the AS Request message-especially, KDSX's cell name and RS name (that's why "well-known principal names" (involving the component krbtgt) are used for KDS servers), as well as the RS names of A itself and of B. Since the AS Request is unauthenticated, KDSX cannot know with certainty the principal identity of this calling client, A-in particular, A may request (or its request may be modified in transit) that the initial ticket in question be issued "in the name of" (that is, name) a client A´ other than A itself (though in that case the resulting TktA´,KDSX will be unusable by A, unless A knows A´'s long-term key-except perhaps for cryptanalysis; for example, for an "offline dictionary attack").

At this point, the asReq message is well-formed, and A sends it to KDSX.

KDS Server Receives AS Request and Sends AS Response

[RFC 1510: 2.1, 3.1.2, 3.1.3, A.2]

Consider an AS Request, asReq, received by KDSX. That is, asReq is a value of type ASRequest, with protocol version number (asReq.req-ProtoVersNum) protoVersNum-KRB5 and protocol message type (asReq.req-ProtoMsgType) protoMsgType-AS-REQUEST. Denote by A the client requested (asReq.req-Body.req-ClientName) to be named in the to-be-issued initial TktA,B. Then KDSX executes the algorithm below. If the algorithm executes successfully, KDSX prepares an AS Response (asResp, of type ASResponse) containing the newly issued initial TktA,B (asResp.resp-Tkt) and "returns" it (that is, returns from the kds_request() invocation) to the calling client (which may be different from the requested client, A). If unsuccessful, KDSX prepares a KDS Error (kdsErr, of type KDSError) and returns it to the calling client.

The following algorithm first discusses how KDSX constructs TktA,B-also denoted asTkt when the emphasis is on the details of AS Request processing-and then how it constructs the rest of the AS Response, asResp.

At this point, TktA,B is well-formed, and KDSX turns its attention to completing the construction of the AS Response message, asResp.

At this point, the KDS Response is well-formed, and KDSX returns it to the calling client.

Client Receives AS Response

[RFC 1510: 3.1.5, A.3, A.4]

Consider a client A that receives an AS Response, asResp (that is, asResp is a value of type ASResponse, with protocol version number (asResp.resp-ProtoVersNum) protoVersNum-KRB5 and protocol message type (asResp.resp-ProtoMsgType) protoMsgType-AS-RESPONSE), in response to an AS Request, asReq (as the result of calling kds_request()) to KDSX. Then A processes asResp according to the following algorithm. In the case this algorithm completes successfully, A is justified in believing that the returned TktA,B (or asTkt; that is, asResp.resp-Tkt) is correctly and securely targeted to KDSX, and that it contains the values returned elsewhere in asResp (in particular, that A is the client named by TktA,B), and using it (especially, its session key, KA,KDSX) in subsequent TGS Requests and Authentication Headers it sends to KDSX. In the case the algorithm fails, A takes (application-specific) recovery action.

Here, the notions of "success" or "failure" of this algorithm are taken to mean "conforming to A's request (asReq)", where the criteria of "conformance" are application-specific. Typically, but not necessarily, A will be satisfied only if KDSX formulates TktA,B exactly as A requested. For example, A may have requested a very long maximum expiration time but KDSX issued only a somewhat shorter one-whether A views that as a success or failure is an application-specific determination. (Note that A cannot inspect TktA,B directly, because A cannot decrypt it -A has to rely on the other, unencrypted, fields of the AS Response message.)

This completes the specification of the AS Request/Response exchange.

(Reverse-)Authentication Header Processing

[RFC 1510: 1, 3.2.1]

This section specifies in detail the processing that occurs during an authentication/reverse-authentication header exchange. There are three steps involved:

  1. A client prepares an authentication header and sends it to a target server as part of an "authenticated request for (RPC) service" (for example, this could be a TGS Request, in which case the target server is a KDS server). Typically, this authentication header will be merely a part of the whole message sent from client to server, and the rest of the message will contain RPC protocol information and the input parameters for the RPC service request.

  2. A server receives an authentication header from a client, processes it, prepares a reverse-authentication header (in the case of a successful client-to-server authentication, and the client has requested the mutual authentication option) or an error message (in the case of a failed client-to-server authentication), and returns that to the client (though some servers may not return errors depending on their policy). Typically, in the success case, the server will also proceed to perform the requested service (subject to authorisation constraints) and return the output RPC parameters to the client in addition to the reverse-authentication header.

  3. A client receives a reverse-authentication header (success case, if it had requested mutual authentication in its authentication header) or an error (failure case). Typically, in the success case, it also receives the results of its RPC service request, which it will then decide to accept or reject (on the basis of the reverse-authentication header).

The details of the three steps of the success case are specified next.

Note that it is A's responsibility to know (or to securely determine) all the information necessary to correctly formulate its message to B-especially, B's cell name and RS name.

Finally, note that not every RPC request/response needs to carry an authentication/reverse-authentication header; only those that need to establish a session or conversation (either initial or re-established) key need do so. Once such a key has been established (and trusted by both client and server), it can be used to protect numerous subsequent RPCs-see Protected RPC for details.

Notes:

  1. It should be noted that the descriptions here are "typical" of authentication/reverse-authentication header processing. But since the interpreters (A and B) of the authentication/reverse-authentication headers are in general application-specific, this whole discussion should be understood to implicitly accommodate some such wording as "··· or other such processing as the application requires or allows ···". For example, an especially cautious server may refuse to accept proxied tickets, or an especially lenient one may provide a "grace period" during which it will accept tickets that expire during a session. Another example is that a password-changing program might demand an initial ticket, to guard against the possibility of a miscreant's hijacking a user session by simply sitting down at an unattended seat. See also TGS Request/Response Processing , which is the only place authentication/reverse-authentication headers are used internally in the KDS protocol "application".

  2. The presentation of Client Sends Authentication Header through Client Receives Reverse-Authentication Header is cast in terms of: "client A using TktA,B (with session key KA,B) to authenticate to server B". It will be observed, though, that a third principal A´ could be injected into the discussion, and the whole presentation recast as: "client A using TktA´,B (with session key KA´,B) to authenticate to server B, provided that A knows the session key KA´,B". This notation becomes burdensome to the exposition, so it won't be employed here. Far from being a minor consequence of the authentication architecture, systematic use of this idea is central to the privilege architecture (with A´ = PS, the Privilege Server-see Introduction to Security Services and Privilege (Authorisation) Services ).

Client Sends Authentication Header

[RFC 1510: 3.2.2, A.9]

Consider a client A in cell X which has successfully executed a KDS Request (.Fn kds_request ), that is, whose KDS Response it accepts (in the sense of Client Receives AS Response and/or Client Receives TGS Response ). Thus, A is in possession of a TktA,B received from KDSY, kdsTkt, whose contents it knows, especially its session key KA,B (and its encryption type encType), and now A wants to use TktA,B to "authenticate to" (that is, engage in protected communications with) server B in cell Y. The following algorithm specifies how A prepares an authentication header, authnHdr (a value of the AuthnHeader data type) containing TktA,B (authnHdr.authnHdr-Tkt), and a newly generated authenticator authnr (authnHdr.authnHdr-EncryptAuthnr, of type Authenticator), and sends it to B for this purpose.

The following algorithm first discusses how A constructs the newly generated authenticator, authnr, and then how it constructs the rest of the authentication header, authnHdr.

At this point, authnr is well-formed and encrypted, and A turns its attention to completing the construction of the authentication header, authnHdr.

At this point, authnHdr is well-formed, and A sends it to B.

Server Receives Authentication Header and Sends Reverse-Authentication Header

[RFC 1510: 3.2.3, 3.2.4, A.10, A.11]

Consider an authentication header, authnHdr, received by a server, B in cell Y, containing a TktA,B (ahTkt, authnHdr.authnHdr-Tkt) and an authenticator, authnr (authnHdr.authnHdr-EncryptAuthnr). (For example, KDS servers receive such an authentication header in the first authentication data field of a TGS Request (tgsReq.req-AuthnData[0].authnData-Value, with tgsReq.req-AuthnData[0].authnData-Type = authnDataType-TGS-REQ)-see KDS Server Receives TGS Request and Sends TGS Response .) Thus, authnHdr is a value of type AuthnHeader, with protocol version number (authnHdr.authnHdr-ProtoVersNum) protoVersNum-KRB5 and protocol message type (authnHdr.authnHdr-ProtoMsgType) protoMsgType-AUTHN-HEADER. Then B executes the algorithm below. If the algorithm executes successfully, B is justified in believing that it can at this time engage in secure communications with the client A named in TktA,B, protecting their communications with the session key KA,B carried in TktA,B, or with the conversation key K^A,B carried in the authentication header itself (authnHdr.authnHdr-EncryptAuthnr.authnr-ConversationKey) (or with another conversation key, Kx^^'1xu'A,B, of B's own choosing-see below). That is, the authentication header "authenticates the client A to the server B".

The following algorithm first discusses how B processes authnHdr, and then, if the mutual authentication option (authnHdr.authnHdr-Flags.authnHdr-MutualRequired) has been selected, how B constructs a reverse-authentication header, revAuthnHdr (of type RevAuthnHeader), to return to A.

At this point, B has completed its processing of authnHdr. If A has not requested mutual authentication (by the authnHdr.authnHdr-Flags.authnHdr-MutualRequired option), B proceeds with the application-specific performance of its service (which might include checking authorisation controls, and sending return parameters (potentially protected with a session or conversation key) back to A without a reverse-authentication header, and so on). Otherwise, B turns its attention to constructing a reverse-authentication header, revAuthnHdr, to be sent back to A, as follows:

At this point, the revAuthnHdr is well-formed, and B returns it to the calling client.

Client Receives Reverse-Authentication Header

[RFC 1510: 3.2.5, A.12]

Consider a reverse-authentication header, revAuthnHdr, received by a client A, in response to an authentication header, authnHdr (with the mutual authentication option selected), that A had earlier sent to a server B. (This is a purely application-level scenario, not a system-level scenario, as the KDS rejects TGS Requests that request mutual authentication-see KDS Server Receives TGS Request and Sends TGS Response .) Thus, revAuthnHdr is a value of type RevAuthnHeader, with protocol version number (revAuthnHdr.revAuthnHdr-ProtoVersNum) protoVersNum-KRB5 and protocol message number (revAuthnHdr.revAuthnHdr-ProtoMsgType) protoMsgType-REVAUTHN-HEADER. Then A executes the algorithm below. If the algorithm executes successfully, A is justified in believing that it can at this time participate in secure communications with the server B targeted by the TktA,B in the corresponding authentication header (authnHdr.authnHdr-Tkt.tkt-ServerCell and authnHdr.authnHdr-Tkt.tkt-ServerName), protecting their communications with the session key KA,B (authnHdr.authnHdr-Tkt.tkt-EncryptPart.tkt-SessionKey), or with a negotiated conversation key K^A,B (authnHdrauthnHdr-EncryptPart.authnr-ConversationKey) or Kx^^'1xu'A,B (revAuthnHdr.revAuthnHdr-EncryptPart.revAuthnHdr-ConversationKey) if these exist (if multiples of these exist, the choice of which to use is dependent on application-specific negotiation-resolution policy). That is, the reverse-authentication header "authenticates the server B to the client A".

This completes the specification of the Authentication/Reverse-authentication Header exchange.

TGS Request/Response Processing

[RFC 1510: 1, 3.3]

This section specifies in detail the processing that occurs during a TGS Request/Response exchange. That is, this section specifies the manipulating of old tickets, as well as the issuing of new tickets (both service-tickets and ticket-granting-tickets which are used in cross-cell authentication). There are three steps involved:

  1. A client prepares a TGS Request and sends it to a KDS server.

  2. A KDS server receives the TGS Request from a client, processes it, prepares an TGS Response (success case) or KDS Error (failure case), and returns that to the client.

  3. A client receives a TGS Response or KDS Error.

The details of the three steps of the success case are specified next.

Note:
It has been argued by some that there is no compelling security-related reason that the TGS service needs to be authenticated (in the sense of (Reverse-)Authentication Header Processing ; that is, an Authentication Header accompanies the TGS Request). (As seen in KDS Server Receives TGS Request and Sends TGS Response , the TGS service is not mutually authenticated; that is, no Reverse-authentication Header accompanies the TGS Response). Nevertheless, the TGS service as specified below is indeed authenticated.

Client Sends TGS Request

[RFC 1510: 3.3.1, A.5]

Consider a client A in cell X which has in its possession some ticket, say TktA,···,B, naming A and targeted to some server B in some cell Y (possibly X = Y-this important special case is included in everything written in this section). When it is necessary in this section to write out in full the trust chain of this ticket, it will be written as:

TktA,···,B = TktA,X,···,W,Y,B

As always, TktA,···,B is one of two kinds of ticket, depending on the kind of server (B) it is targeted to:

Since TktA,···,B names A, A knows the contents of TktA,···,B, especially its session key, which is denoted KA,B (which is of the same encryption type, encType, as is used to protect TktA,···,B). Note that the key KA,B can always be used as a session key between A and KDSY (even though it is nominally only a session key between A and B, with possibly B != KDSY). This is because TktA,···,B is protected in the long-term key of B, which KDSY knows, so KDSY has access to KA,B too.

What A wants to do is "present" TktA,···,B to KDSY, and receive in return another ticket, which is denoted:

Tkt*A,···,B*

which is "based on TktA,···,B", naming A, and targeted to another (perhaps the same) server B* in Y. That is, A wants to send to KDSY a TGS Request tgsReq (a value of the data type TGSRequest) containing TktA,···,B (ahTkt, in its tgsReq.req-AuthnData field, as the authnHdr.authnHdr-Tkt field of an authentication header authnHdr), and receive in response a TGS Response tgsResp (a value of data type TGSResponse) containing Tkt*A,···,B* (tgsTkt, in its tgsResp.resp-Tkt field). A prepares tgsReq according to the algorithm below and "sends it" (that is, calls kds_request()) to KDSY.

There are two distinct cases to consider throughout, according to what kind of service A requests:

Clients (such as A) do not typically intentionally request cross-cell referral tickets. Except for their initial ticket-granting-ticket they only intentionally request ultimate service-tickets. But if such a request cannot be fulfilled, a cross-cell referral ticket is returned as a by-product of the algorithm, as described below:

At this point, the tgsReq message is well-formed, and A sends it to KDSY.

KDS Server Receives TGS Request and Sends TGS Response

[RFC 1510: 3.3.2, 3.3.3, A.6]

Consider a TGS Request, tgsReq, received by KDSY from A. Thus, tgsReq is a value of data type TGSRequest, with protocol version number (tgsReq.req-ProtoVersNum) protoVersNum-KRB5 and protocol message type (tgsReq.req-ProtoMsgType) protoMsgType-TGS-REQUEST. Then KDSY executes the algorithm below. If the algorithm executes successfully, KDSY returns a TGS Response (tgsResp, of type TGSResponse), containing the "manipulated old" or "newly issued" ticket, Tkt*A,···,B* (tgsResp.resp-Tkt, also denoted tgsTkt), to A. If unsuccessful, KDSY returns a KDS Error (kdsErr, of type KDSError).

The following algorithm discusses (in an appropriate order) how KDSY handles the authentication header authnHdr (and therefore the authenticator authnr and presented ticket, ahTkt (TktA,···,B)) accompanying tgsReq, how it manipulates the old or issues the new ticket Tkt*A,···,B*, and how it constructs the remainder of the TGS Response, tgsResp (which does not include a reverse-authentication header). (The manner in which KDSY handles the authentication header is an extension of the "mainline" usage of the authentication header by not-necessarily-KDS servers as specified in Server Receives Authentication Header and Sends Reverse-Authentication Header , but it is all repeated here, both because its processing is intertwined with the processing of other parts of the TGS Request, and to indicate error conditions specific to KDS servers.)

At this point, KDSY has completed its preliminary processing of the authentication header authnHdr (including authnr and ahTkt (TktA,···,B)), and now turns its attention to constructing the manipulated old or newly-to-be-issued tgsTkt (Tkt*A,···,B*).

At this point, tgsTkt (Tkt*A,···,B*) is well-formed, and KDSY turns its attention to completing the construction of the TGS Response message, tgsResp.

At this point, the KDS Response is well-formed, and the KDS returns it to the calling client.

Client Receives TGS Response

[RFC 1510: 3.3.4, A.4, A.7]

Consider a client A that receives a TGS Response, tgsResp (that is, tgsResp is a value of data type TGSResponse, with protocol version number (tgsResp.resp-ProtoVersNum) protoVersNum-KRB5 and protocol message type (tgsResp.resp-ProtoMsgType) protoMsgType-TGS-RESPONSE), in response to a TGS Request, tgsReq (as the result of calling kds_request()) to KDSY. A processes tgsResp according to the algorithm below. In the case this algorithm completes successfully, A is justified in believing that the returned tgsTkt (or Tkt*A,···,B*; that is, tgsResp.resp-Tkt) is correctly and securely targeted to the server B* specified (tgsResp.resp-EncryptPart.resp-ServerCell and tgsResp.resp-EncryptPart.resp-ServerName), and that it contains the values returned elsewhere in the tgsResp (in particular, that A is the client named by tgsTkt), and using it (especially, its session key, K*A,B*, of encryption type encType*) in subsequent Authentication Headers it sends in service requests to the targeted server, or in subsequent TGS Requests. In the case the algorithm fails, A takes (application-specific) recovery action.

Here, the notions of "success" or "failure" of this algorithm are taken to mean "conforming to A's request (tgsReq)", where the criteria of "conformance" are application-specific. Typically, but not necessarily, A will be satisfied only if KDSY formulates the TGS Response exactly as A requested. For example, A may have requested a very long maximum expiration time but KDSY issued only a somewhat shorter one -whether A views that as a success or failure is an application-specific determination.

This completes the specification of the TGS Request/Response exchange.

KDS Error Processing

[RFC 1510: 3.1.6, A.20]

This section specifies in detail the processing that occurs when a KDS server encounters a failure during its processing of an AS Request or a TGS Request, and returns a KDS Error to the requesting client. (Actually, KDS Error messages may be of some use to arbitrary application servers, not just KDS servers. That scenario is not examined in this section, though the discussion given here can easily be generalised to that situation.)

Consider a KDS Request, kdsReq, received by KDSY from a client A. This KDS Request is either an AS Request or a TGS Request, and KDSY performs the algorithm specified above accordingly. If it encounters one or more algorithmic failures, it chooses one (normally, the first one it encounters dynamically) to return in a KDS Error message. KDSY then proceeds to execute the algorithm below. This results in KDSY returning a KDS Error kdsErr (of type KDSError) to A.

authnr is written for the authenticator accompanying a KDS Request (carried in kdsReq.req-AuthnData as described previously), provided it is present and KDSY can decrypt the encrypted authenticator successfully. In that case, the description is authnr (and the information in it) "is available".

This completes the specification of the KDS Error message processing.

Cross-Cell Authentication

[RFC 1510: 1.1]

As seen in AS Request/Response Processing and TGS Request/Response Processing , the authentication of a client A in cell X to a server B in cell Y is quite straightforward if X = Y. But the case X != Y requires a sequence of non-obvious cross-cell referrals. The low-level details have already been specified above (in TGS Request/Response Processing ), but without a higher-level understanding of cross-cell referrals the whole scenario remains obscure and mysterious. This section presents this higher-level view (see also Cells-Cross-cell Authentication and Authorisation ).

Consider a client A in cell X that wants to authenticate to an ultimate non-KDS end-server B in cell Y, with X != Y. A begins by obtaining an (initial or subsequent) ticket, TktA,KDSX, protected with KDSX's long-term key KKDSX.

A then sends a TGS Request to KDSX, presenting TktA,KDSX (in req-AuthnData) to KDSX, requesting a service-ticket targeted to B in Y. Note that A must know the principal name of B (comprising the cell name of Y and the RS name of B in Y), but A does not a priori know the intermediate cells in the trust chain between X and Y-that is, A knows the structure of the namespace, but only the network of KDS servers knows the structure of the trust graph (consisting of the cross-cell registrations of KDS servers with one another).

Since B's home cell is Y (!= X), KDSX does not know B's long-term key KB+3, and so it cannot construct the requested service-ticket targeted to B. Instead, KDSX chooses a cell Z which is cross-registered with X to be used as the next hop towards Y, and returns to A a TGS Response which contains (in resp-Tkt) a cross-cell referral ticket, TktA,X,KDSXZ. This TGS Response and TktA,X,KDSXZ contain a newly generated session key KA,KDSXZ between A and KDSX,Z, and TktA,X,KDSXZ is protected with the long-term key KKDSXZ shared between the two surrogate KDS principals KDSX,Z cross-registered in RSX and in RSZ.

When A receives this TGS Response from KDSX, it recognises that it has received (resp-Tkt) a cross-cell referral ticket instead of the service-ticket it had requested, because the TGS Response contains information (in resp-ServerCell and resp-ServerName) telling A that the target of resp-Tkt is not the server B that A had requested (and a cross-cell referral ticket is the only instance in which a KDS server ever issues a ticket targeted to a server other than that requested by the client). Accordingly, A now formulates a new TGS Request, to KDSZ (KDSX,Z) this time, again requesting a service-ticket targeted to B. The ticket A present (in req-AuthnData) in this TGS Request to KDSZ is the cross-cell referral ticket, TktA,X,KDSXZ, A just received from KDSX.

When KDSZ receives this TGS Request, it decrypts TktA,X,KDSXZ with the long-term key KKDSXZ, thereby learning its session key KA,KDSZ (this authenticates A to KDSZ and secures communications between them, and establishes the A -> KDSX -> KDSZ trust chain).

Now shift notation slightly (for purposes of an inductive argument) and write Z´ instead of Z. If Z´ = Y, then KDSZ´ = KDSY can satisfy A's TGS Request, and can return to A the TktA,X,Y,B A requested. Otherwise, the above procedure is iterated: KDSZ´ returns (if possible) to A another new cross-cell referral ticket, TktA,X,Z´,KDSZ´Z´´, to a next-hop cell Z´´ which is even closer to the desired cell Y. This process continues through a sequence of cross-cell referrals, Z´, Z´´, ···, Z´´´, until it eventually terminates (if no errors are encountered) when the desired cell Z´´´´ = Y is ultimately reached. For at that point, A's TGS Request to KDSY (KDSZ´´´Y) for a service-ticket targeted to B (protected in B's long-term key KB+3) will finally be satisfied, and is returned to A in the TGS Response from KDSY. A recognises that it has finally received a service-ticket targeted to its desired end-server B, so can then proceed to use this Tkt\dA,X,Z´,Z´´,···,Z´´´,Y,B to authenticate itself to, and protect its communications with, B.

In particular, note that the successive steps of this cross-cell authentication scenario are all secure, because the referral information (cell name and RS name of successive KDS servers to be contacted, session keys, and so on) is securely determined by a chain of trusted KDS servers and securely transmitted to A at each stage.

Finally, it is to be noted that this chapter has not explained how authorisation data or UUIDs make their appearance in the protocol. That is the province of the Privilege Service, as specified in Privilege (Authorisation) Services .

Please note that the html version of this specification may contain formatting aberrations. The definitive version is available as an electronic publication on CD-ROM from The Open Group.

Contents Next section Index