4. Certificate and message formats 4.1 ASN.1 encoding Some definitions are taken from X.501 and X.509. Dass DEFINITIONS ::= BEGIN --CCITT Definitions: joint-iso-ccitt OBJECT IDENTIFIER ::= {2}
ds OBJECT IDENTIFIER ::= {joint-iso-ccitt 5} algorithm OBJECT IDENTIFIER ::= {ds 8} encryptionAlgorithm OBJECT IDENTIFIER ::= {algorithm 1} hashAlgorithm OBJECT IDENTIFIER ::= {algorithm 2} signatureAlgorithm OBJECT IDENTIFIER ::= {algorithm 3} rsa OBJECT IDENTIFIER ::= {encryptionAlgorithm 1} iso OBJECT IDENTIFIER ::= {1} identified-organization OBJECT IDENTIFIER ::= {iso 3} ecma OBJECT IDENTIFIER ::= {identified-organization 12} member-company OBJECT IDENTIFIER ::= {ecma 2} digital OBJECT IDENTIFIER ::= {member-company 1011} --1989 OSI Implementors Workshop "Stable" Agreements oiw OBJECT IDENTIFIER ::= {identified-organization 14} dssig OBJECT IDENTIFIER ::= {oiw 7} oiwAlgorithm OBJECT IDENTIFIER ::= {dssig 2} oiwEncryptionAlgorithm OBJECT IDENTIFIER ::= {oiwAlgorithm 1} oiwHashAlgorithm OBJECT IDENTIFIER ::= {oiwAlgorithm 2} oiwSignatureAlgorithm OBJECT IDENTIFIER ::= {oiwAlgorithm 3} oiwMD2 OBJECT IDENTIFIER ::= {oiwHashAlgorithm 1} --null parameter oiwMD2withRSA OBJECT IDENTIFIER ::= {oiwSignatureAlgorithm 1} --null parameter --X.501 definitions AttributeType ::= OBJECT IDENTIFIER AttributeValue ::= ANY AttributeValueAssertion ::= SEQUENCE {AttributeType,AttributeValue} Name ::= CHOICE { --only one for now RDNSequence } RDNSequence ::= SEQUENCE OF RelativeDistinguishedName DistinguishedName ::= RDNSequence RelativeDistinguishedName ::= SET OF AttributeValueAssertion --X.509 definitions (with proposed 1992 extensions presumed) ENCRYPTED MACRO ::= BEGIN TYPE NOTATION ::= type(ToBeEnciphered) VALUE NOTATION ::= value(VALUE BIT STRING) END -- of ENCRYPTED
SIGNED MACRO ::= BEGIN TYPE NOTATION ::= type (ToBeSigned) VALUE NOTATION ::= value (VALUE SEQUENCE{ ToBeSigned, AlgorithmIdentifier, --of the algorithm used to --generate the signature ENCRYPTED OCTET STRING --where the octet string is the --result of the hashing of the --value of "ToBeSigned" } ) END -- of SIGNED SIGNATURE MACRO ::= BEGIN TYPE NOTATION ::= type (OfSignature) VALUE NOTATION ::= value (VALUE SEQUENCE { AlgorithmIdentifier, --of the algorithm used to compute ENCRYPTED OCTET STRING -- the signature where the octet -- string is a function (e.g., a -- compressed or hashed version) -- of the value 'OfSignature', -- which may include the -- identifier of the algorithm -- used to compute the signature } ) END -- of SIGNATURE Certificate ::= SIGNED SEQUENCE { version [0] Version DEFAULT v1988, serialNumber CertificateSerialNumber, signature AlgorithmIdentifier, issuer Name, valid Validity, subject Name, subjectPublicKey SubjectPublicKeyInfo, issuerUID [1] IMPLICIT UID OPTIONAL, -- v1992 subjectUID [2] IMPLICIT UID OPTIONAL -- v1992 } --The Algorithm Identifier for both the signature field
--and in the signature itself is: -- oiwMD2withRSA (1.3.14.7.2.3.1) Version ::= INTEGER {v1988(0), v1992(1)} CertificateSerialNumber ::= INTEGER Validity ::= SEQUENCE { NotBefore UTCTime, NotAfter UTCTime } AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameter ANY DEFINED BY algorithm OPTIONAL } --The algorithms we support in one context or another are: --oiwMD2withRSA (1.3.14.7.2.3.1) with parameter NULL --rsa (2.5.8.1.1) with parameter keysize INTEGER which is -- the keysize in bits --decDEA (1.3.12.1001.7.1.2) with optional parameter -- missing --decDEAMAC (1.3.12.2.1011.7.3.3) with optional parameter -- missing SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, -- rsa (2.5.8.1.1) subjectPublicKey BIT STRING -- the "bits" further decode into a DASS public key } UID ::= BIT STRING -- the following definitions are for Digital specified Algorithms cryptoAlgorithm OBJECT IDENTIFIER ::= {digital 7} decEncryptionAlgorithm OBJECT IDENTIFIER ::= {cryptoAlgorithm 1} decHashAlgorithm OBJECT IDENTIFIER ::= {cryptoAlgorithm 2} decSignatureAlgorithm OBJECT IDENTIFIER ::= {cryptoAlgorithm 3} decDASSLessness OBJECT IDENTIFIER ::= {cryptoAlgorithm 6} decMD2withRSA OBJECT IDENTIFIER ::= {decSignatureAlgorithm 1} decMD4withRSA OBJECT IDENTIFIER ::= {decSignatureAlgorithm 2} decDEAMAC OBJECT IDENTIFIER ::= {decSignatureAlgorithm 3}
decDEA OBJECT IDENTIFIER ::= {decEncryptionAlgorithm 2} decMD2 OBJECT IDENTIFIER ::= {decHashAlgorithm 1} decMD4 OBJECT IDENTIFIER ::= {decHashAlgorithm 2} ShortPosixTime ::= INTEGER -- number of seconds since base time LongPosixTime ::= SEQUENCE { INTEGER, -- number of seconds since base time INTEGER -- number of nanoseconds since second } ShortPosixValidity ::= SEQUENCE { notBefore ShortPosixTime, notAfter ShortPosixTime } -- Note: Annex C of X.509 prescribes the following format for the -- representation of a public key, but does not give the structure -- a name. DASSPublicKey ::= SEQUENCE { modulus INTEGER, exponent INTEGER } DASSPrivateKey ::= SEQUENCE { p INTEGER , -- prime p q [0] IMPLICIT INTEGER OPTIONAL , -- prime q mod[1] IMPLICIT INTEGER OPTIONAL, -- modulus exp [2] IMPLICIT INTEGER OPTIONAL, -- public exponent dp [3] IMPLICIT INTEGER OPTIONAL , -- exponent mod p dq [4] IMPLICIT INTEGER OPTIONAL , -- exponent mod q cr [5] IMPLICIT INTEGER OPTIONAL , -- Chinese --remainder coefficient uid[6] IMPLICIT UID OPTIONAL, more[7] IMPLICIT BIT STRING OPTIONAL --Reserved for --future use } LocalUserName ::= OCTET STRING ChannelId ::= OCTET STRING VersionNumber ::= OCTET STRING (SIZE(3)) -- first octet is major version -- second octet is minor version -- third octet is ECO rev. versionZero VersionNumber ::= '000000'H
Authenticator ::= SIGNED SEQUENCE { type BIT STRING, -- first bit `delegation required' -- second bit `Mutual Authentication Requested' whenSigned LongPosixTime , channelId [3] IMPLICIT ChannelId OPTIONAL -- channel bindings are included when doing the -- signature, but excluded when transmitting the -- Authenticator } -- uses decDEAMAC (1.3.12.2.1011.7.3.3) EncryptedKey ::= SEQUENCE { algorithm AlgorithmIdentifier, -- uses rsa (2.5.8.1.1) encryptedAuthKey BIT STRING -- as defined in section 4.4.5 } SignatureOnEncryptedKey ::= SIGNATURE EncryptedKey -- uses oiwMD2withRSA (1.3.14.7.2.3.1) -- Signature bits computed over EncryptedKey structure LoginTicket ::= SIGNED SEQUENCE { version [0] IMPLICIT VersionNumber DEFAULT versionZero, validity ShortPosixValidity , subjectUID UID , delegatingPublicKey SubjectPublicKeyInfo } -- uses oiwMD2withRSA (1.3.14.7.2.3.1) Delegator ::= SEQUENCE { algorithm AlgorithmIdentifier -- decDEA encryption (1.3.12.1001.7.1.2) encryptedPrivKey ENCRYPTED DASSPrivateKey, -- (only p is included) } UserClaimant ::= SEQUENCE { userTicket [0] IMPLICIT LoginTicket, evidence CHOICE { delegator [1] IMPLICIT Delegator , -- encrypted delegation private key -- under DES authenticating key -- present if delegating sharedKeyTicketSignature [2]
IMPLICIT SignatureOnEncryptedKey -- present if not delegating } , userName [3] IMPLICIT Name OPTIONAL -- name of user principal } EncryptedKeyandUserName ::= SEQUENCE { encryptedKey EncryptedKey , username LocalUserName } SignatureOnEncryptedKeyandUserName ::= SIGNATURE EncryptedKeyandUserName -- uses oiwMD2withRSA (1.3.14.7.2.3.1) -- Signature bits computed over -- EncryptedKeyandUserName structure -- using node private key } NodeClaimant ::= SEQUENCE { nodeTicket Signature[0] IMPLICIT SignatureOnEncryptedKeyandUserName, nodeName [1] IMPLICIT Name OPTIONAL, username [2] IMPLICIT LocalUserName OPTIONAL } AuthenticationToken ::= SEQUENCE { version [0] IMPLICIT VersionNumber DEFAULT versionZero, authenticator [1] IMPLICIT Authenticator , encryptedKey [2] IMPLICIT EncryptedKey OPTIONAL , -- required if initiating token userclaimant [3] IMPLICIT UserClaimant OPTIONAL , -- missing if only doing node authentication -- required if not doing node authentication nodeclaimant [4] IMPLICIT NodeClaimant OPTIONAL -- missing if only doing principal authentication -- required if not doing principal authentication } MutualAuthenticationToken ::= CHOICE { v1Response [0] IMPLICIT OCTET STRING (SIZE(6)) -- Constructed as follows: A single DES block -- of eight octets is constructed from the two -- integers in the timestamp. First four bytes -- are the high order integer encoded MSB -- first; Last four bytes are the low order
-- integer encoded MSB first. The block is -- encrypted using the shared DES key, and -- the first six bytes are the OCTET STRING. -- With the [0] type and 6-byte length, the -- MutualAuthenticationToken has a fixed -- length of eight bytes. } END 4.2 Encoding Rules Whenever a structure is to be signed it must always be constructed the same way. This is particularly important where a signed structure has to be reconstructed by the recipient before the signature is verified. The rules listed below are taken from X.509. - the definite form of length encoding shall be used, encoded in the minimum number of octets; - for string types, the constructed form of encoding shall not be used; - if the value of a type is its default value, it shall be absent; - the components of a Set type shall be encoded in ascending order of their tag value; - the components of a Set-of type shall be encoded in ascending order of their octet value; - if the value of a Boolean type is true, the encoding shall have its contents octet set to `FF'16; - each unused bits in the final octet of the encoding of a BitString value, if there are any, shall be set to zero; - the encoding of a Real type shall be such that bases 8, 10 and 16 shall not be used, and the binary scaling factor shall be zero. 4.3 Version numbers and forward compatibility The LoginTicket and AuthenticationToken structures contain a three octet version identifier which is intended to ease transition to future revisions of this architecture. The default value, and the value which should always be supplied by implementations of this version of the architecture is 0.0.0
(three zero octets). The first octet is the major version. An implementation of this version of the architecture should refuse to process data structures where it is other than zero, because changing it indicates that the interpretation of some subsidiary data structure has changed. The second octet is the minor version. An implementation of this version of the architecture should ignore the value of this octet. Some future version of the architecture may set a value other than zero and may specify some different processing of the remainder of the structure based on that different value. Such a change would be backward compatible and interoperable. The third octet is the ECO revision. No implementation should make any processing decisions based on the value of that octet. It may be logged, however, to help in debugging interoperability problems. In the CDC protocol, there is also a three octet version numbering scheme, where versions 1.0.0 and 2.0.0 have been defined. Implementations should follow the same rules above and reject major version numbers greater than 2. ASN.1 is inherently extensible because it allows new fields to be added "onto the end" of existing data structures in an unambiguous way. Implementations of DASS are encouraged to ignore any such additional fields in order to enhance backwards compatibility with future versions of the architecture. Unfortunately, commonly available ASN.1 compilers lack this capability, so this behavior cannot reasonably be required and may limit options for future extensions. 4.4 Cryptographic Encoding Some of the substructures listed in the previous sections are specified as ENCRYPTED OCTET STRINGs containing encrypted information. DASS uses the DES, RSA, and MD2 cryptosystems Each of those cryptosystems specifies a function from octet string into another in the presence of a key (except MD2, which is keyless). This section describes how to form the octet strings on which the DES and RSA operations are performed. 4.4.1 Algorithm Independence vs. Key Parity All of the defined encodings for DASS for secret key encryption are based on DES. It is intended, however, that other cryptosystems could be substituted without any other changes for formats or algorithms. The required "form factor" for such a cryptosystem is that it have a 64 bit key and operate on 64 bit blocks (this appears to be a common form factor for a cryptosystem). For this reason, DES keys are in all places
treated as though they were 64 bits long rather than 56. Only in the operation of the algorithm itself are eight bits of the key dropped and key parity bits substituted. Choosing a key always involves picking a 64 bit random number. 4.4.2 Password Hashing Encrypted credentials are encrypted using DES as described in the next section. The key for that encryption is derived from the user's password and name by the following algorithm: a) Put the rightmost RDN of the user's name in canonical form according to BER and the X.509 encoding rules. For any string types that are case insensitive, map to upper case, and where matching is independent of number of spaces collapse all multiple spaces to a single space and delete leading and trailing spaces. Note: the RDN is used to add "salt" to the hash calculation so that someone can't precompute the hash of all the words in a dictionary and then apply them against all names. Deriving the salt from the last RDN of the name is a compromise. If it were derived from the whole name, all encrypted keys would be obsoleted when a branch of the namespace was renamed. If it were independent of name, interaction with a login agent would take two extra messages to retrieve the salt. With this scheme, encrypted keys are obsoleted by a change in the last RDN and if a final RDN is common to a large number of users, dictionary attacks against them are easier; but the common case works as desired. b) Compute TEMP as the MD2 message digest of the concatenation of the password and the RDN computed above. c) Repeat the following 40 times: Use the first 64 bits of TEMP as a DES key to encrypt the second 64 bits; XOR the result with the first 64 bits of TEMP; and compute a new TEMP as MD2 of the 128 bit result. d) Use the final 64 bits of the result (called hash1) as the key to decrypt the encrypted credentials. Use the first 64 bits (called hash2) as the proof of knowledge of the password for presentation to a login agent (if any).
4.4.3 Digital DEA encryption DES encryption is used in the following places: - In the encryption of the encrypted credentials structure - To encrypt the delegator in authentication tokens - To encrypt the time in the mutual authenticator In the first two cases, a varying length block of information coded in ASN.1 is encrypted. This is done by dividing the block of information into 8 octet blocks, padding the last block with zero bytes if necessary, and encrypting the result using the CBC mode of DES. A zero IV is used. In the third case, a fixed length (8 byte) quantity (a timestamp) is encrypted. The timestamp is mapped to a byte string using "big endian" order and the block is encrypted using the ECB mode of DES. 4.4.4 Digital MAC Signing DES signing is used in the Authenticator. Here, the signature is computed over an ASN.1 structure. The signature is the CBC residue of the structure padded to a multiple of eight bytes with zeros. The CBC is computed with an IV of zero. 4.4.5 RSA Encryption RSA encryption is used in the Encrypted Shared Key. RSA encryption is best thought of as operating on blocks which are integers rather than octet strings and the results are also integers. Because an RSA encryption permutes the integers between zero and (modulus-1), it is generally thought of as acting on a block of size (keysizeinbits-1) and producing a block of size (keysizeinbits) where keysizeinbits is the smallest number of bits in which the modulus can be represented. DASS only supports key sizes which are a multiple of eight bits (This restriction is only required to support interoperation with certain existing implementations. If the key size is not a multiple of eight bits, the high order byte may not be able to hold values as large as the mandated '64'. This is not a problem so long as the two high order bytes together are non-zero, but certain early implementations check for the value '64' and will not interoperate with implementations that use some other value.). The encrypted shared key structure is laid out as follows:
- The DES key to be shared is placed in the last eight bytes - The POSIX format creation time encoded in four bytes using big endian byte order is placed in the next four (from the end) bytes - The POSIX format expiration time encoded in four bytes using big endian byte order is placed in the next four (from the end) bytes - Four zero bytes are placed in the next four (from the end) bytes - The first byte contains the constant '64' (decimal) - All remaining bytes are filled with random bytes (the security of the system does not depend on the cryptographic randomness of these bytes, but they should not be a frequently repeating or predictable value. Repeating the DES key from the last bytes would be good). The RSA algorithm is applied to the integer formed by treating the bytes above as an integer in big endian order and the resulting integer is converted to a BIT STRING by laying out the integer in 'big endian' order. On decryption, the process is reversed; the decryptor should verify the four explicitly zero bytes but should not verify the contents of the high order byte or the random bytes. 4.4.6 oiwMD2withRSA Signatures RSA-MD2 signatures are used on certificates, login tickets, shared key tickets, and node tickets. In all cases, a signature is computed on an ASN.1 encoded string using an RSA private key. This is done as follows: - The MD2 algorithm is applied to the ASN.1 encoded string to produce a 128 bit message digest - The message digest is placed in the low order bytes of the RSA block (big endian) - The next two lowest order bytes are the ASN.1 'T' and 'L' for an OCTET STRING. - The remainder of the RSA block is filled with zeros
- The RSA operation is performed, and the resulting integer is converted to an octet string by laying out the bytes in big endian order. On verification, a value like the above or one where the message digest is present but the 'T' and 'L' are missing (zero) should be accepted for backwards compatibility with an earlier definition of this crypto algorithm. 4.4.7 decMD2withRSA Signatures This algorithm is the same as the oiwMD2withRSA algorithm as defined above. We allocated an algorithm object identifier from the Digital space in case the definition of that OID should change. It will not be used unless the meaning of oiwMD2withRSA becomes unstable. Annex A Typical Usage This annex describes one way a system could use DASS services (as described in section 3) to provide security services. While this example provided motivation for some of the properties of DASS, it is not intended to represent the only way that DASS may be used. This goes through the steps that would be needed to install DASS "from scratch". A.1 Creating a CA A CA is created by initializing its state. Each CA can sign certificates that will be placed in some directory in the name service. Before these certificates will be believed in a wider context than the sub-tree of the name space which is headed by that directory, the CA must be certified by a CA for the parent directory. The procedure below accomplishes this. For most secure operation, the CA should run on an off-line system and communicate with the rest of the network by interchanging files using a simple specialized mechanism such as an RS232 line or a floppy disk. It is assumed that access to the CA is controlled and that the CA will accept instructions from an operator. - Call Install_CA to create the CA State. This state is saved within the CA system and is never disclosed. - If this is the first CA in the namespace and the CA is intended to certify only members of a single directory, we are done. Otherwise, the new CA must be linked into the CA
hierarchy by cross-certifying the parent and children of this CA. There is no requirement that CA hierarchies be created from the root down, but to simplify exposition, only this case will be described. The newly created CA must learn its name, its UID, the UID of its parent directory, and the public key of the parent directory CA by some out of band reliable means. Most likely, this would be done by looking up the information in the naming service and asking the CA operator to verify it. The CA then forms this information into a parent certificate and signs it using the Create_certificate function. It communicates the certificate to the network and posts it in the naming service. - This name, UID, and public key of the new CA are taken to the CA of the parent directory, which verifies it (again by some unspecified out-of-band mechanism) and calls Create_Certificate to create a child certificate using its own Name and UID in the issuer fields. This certificate is also placed in the naming service. A CA can sign certificates for more than one directory. In this case it is possible that a single CA will take the role of both CAs in the example above. The above procedure can be simplified in this case, as no interchange of information is required. A.2 Creating a User Principal A system manager may create a new user principal by invoking the Create_principal function supplying the principal's name, UID, and the public key/UID of the parent CA. The public key and UID must be obtained in a reliable out of band manner. This is probably by having knowledge of that information "wired into" the utility which creates new principals. At account creation time, the system manager must supply what will become the user's password. This might be done by having the user present and directly enter a password or by having the password selected by some random generator. The trusted authority certificate and corresponding user public key generated by the Create_principal function are sent to the CA which verifies its contents (again by an out-of-band mechanism) and signs a corresponding certificate. The encrypted credentials, CA signed certificate, and trusted authority certificates are all placed in the naming service. The process by which the password is made known to the user must be protected by some out-of-band mechanism. In some cases the principal may wish to generate its own key, and not use the Encrypted_Credentials. (e.g., if the Principal is represented by a Smart Card). This may be done using a procedure similar to the
one for creating a new CA. A.3 Creating a Server Principal A server also has a public/private key pair. Conceptually, the same procedure used to create a user principal can be used to create a server. In practice, the most important difference is likely to be how the password is protected when installing it on a server compared to giving it to a user. A server may wish to retrieve (and store) its Encrypted Credentials directly and never have them placed in the naming service. In this case some other mechanism can be used (e.g., passing the floppy disk containing the encrypted credentials to the server). This would require a variant of the Initialize_Server routine which does not fetch the Encrypted Credentials from the naming service. A.4 Booting a Server Principal When the server first boots it needs its name (unreliably) and password (reliably). It then calls Initialize_Server to obtain its credentials and trusted authority certificates (which it will later need in order to authenticate users). These credentials never time out, and are expected to be saved for a long time. In particular the associated Incoming Timestamp List must be preserved while there are any timestamps on it. It is desirable to preserve the Cached Incoming Contexts as long as there are any contexts likely to be reused. If a server wants to initiate associations on its own behalf then it must call Generate_Server_Ticket. It must repeat this at intervals if the expiration period expires. A node that wishes to do node authentication (or which acts as a server under its own name) must be created as a server. A.5 A user logs on to the network The system that the user logs onto finds the user's name and password. It then calls Network_Login to obtain credentials for the user. These credentials are saved until the user wants to make a network connection. The credentials have a time limit, so the user will have to obtain new credentials in order to make connections after the time limit. The credentials are then checked by calling Verify_Principal_Name, in order to check that the key specified in the encrypted credentials has been certified by the CA. If the system does source node authentication it will call Combine_credentials, once the local username has been found. (This
can either be found by looking the principal's global name up in a file, or the user can be asked to give the local name directly. Alternatively the user can be asked to give his local username, which the system looks up to find the global name). A.6 An Rlogin (TCP/IP) connection is made When the user calls a modified version of the rlogin utility, it calls Create_token in order to create the Initial Authentication Token, which is passed to the other system as part of the rlogin protocol. The rlogind utility at the destination node calls Accept_token to verify it. It then looks up in a local rhosts-like database to determine whether this global user is allowed access to the requested destination account. It calls Verify_principal_name and/or Verify_node_name to confirm the identity of the requester. If access is allowed, the connection is accepted and the Mutual Authentication Token is returned in the response message. The source receives the returned Mutual Authentication Token and uses it to confirm it communicating with the correct destination node. Rlogind then calls Combine_credentials to combine its node/account information with the global user identification in the received credentials in case the user accesses any network resources from the destination system. A.7 A Transport-Independent Connection As an alternative to the description in A.6, an application wishing to be portable between different underlying transports may call create_token to create an authentication token which it then sends to its peer. The peer can then call accept_token and verify_principal_name and learn the identity of the requester. Annex B Support of the GSSAPI In order to support applications which need to be portable across a variety of underlying security mechanisms, a "Generic Security Service API" (or GSSAPI) was designed which gives access to a common core of security services expected to be provided by several mechanisms. The GSSAPI was designed with DASS, Kerberos V4, and Kerberos V5 in mind, and could be written as a front end to any or all of those systems. It is hoped that it could serve as an interface to other security systems as well. Application portability requires that the security services supported
be comparable. Applications using the GSSAPI will not be able to access all of the features of the underlying security mechanisms. For example, the GSSAPI does not allow access to the "node authentication" features of DASS. To the extent the underlying security mechanisms do not support all the features of GSSAPI, applications using those features will not be portable to those security mechanisms. For example, Kerberos V4 does not support delegation, so applications using that feature of the GSSAPI will not be portable to Kerberos V4. This annex explains how the GSSAPI can be implemented using the primitive services provided by DASS. B.1 Summary of GSSAPI The latest draft of the GSSAPI specification is available as an internet draft. The following is a brief summary of that evolving document and should not be taken as definitive. Included here are only those aspects of GSSAPI whose implementation would be DASS specific. The GSSAPI provides four classes of functions: Credential Management, Context-Level Calls, Per-message calls, and Support Calls; two types of objects: Credentials and Contexts; and two kinds of data structures to be transmitted as opaque byte strings: Tokens and Messages. Credentials hold keys and support information used in creating tokens. Contexts hold keys and support information used in signing and encrypting messages. The Credential Management functions of GSSAPI are "incomplete" in the sense that one could not build a useful security implementation using only GSSAPI. Functions which create credentials based on passwords or smart cards are needed but not provided by GSSAPI. It is envisioned that such functions would be invoked by security mechanism specific functions at user login or via some separate utility rather than from within applications intended to be portable. The Credential Management functions available to portable applications are: - GSS_Acquire_cred: get a handle to an existing credential structure based on a name or process default. - GSS_Release_cred: release credentials after use. The Context-Level Calls use credentials to establish contexts. Contexts are like connections: they are created in pairs and are generally used at the two ends of a connection to process messages associated with that connection. The Context-Level Calls of interest
are: - GSS_Init_sec_context: given credentials and the name of a destination, create a new context and a token which will permit the destination to create a corresponding context. - GSS_Accept_sec_context: given credentials and an incoming token, create a context corresponding to the one at the initiating end and provide information identifying the initiator. - GSS_Delete_sec_context: delete a context after use. The Per-Message Calls use contexts to sign, verify, encrypt, and decrypt messages between the holders of matching contexts. The Per- Message Calls are: - GSS_Sign: Given a context and a message, produces a string of bytes which constitute a signature on a provided message. - GSS_Verify: Given a context, a message, and the bytes returned by GSS_Sign, verifies the message to be authentic (unaltered since it was signed by the corresponding context). - GSS_Seal: Given a context and a message, produces a string of bytes which include the message and a signature; the message may optionally be encrypted. - GSS_Unseal: Given a context and the string of bytes from GSS_Seal, returns the original message and a status indicating its authenticity. The Support Calls provide utilities like translating names and status codes into printable strings. B.2 Implementation of GSSAPI over DASS B.2.1 Data Structures The objects and data structures of the GSSAPI do not map neatly into the objects and data structures of the DASS architecture. This section describes how those data structures can be implemented using the DASS data structures and primitives Credential handles correspond to the credentials structures in DASS, where the portable API assumes that the credential structures themselves are kept from applications and handles are passed to and
from the various subroutines. Context initialization tokens correspond to the tokens of DASS. The GSSAPI prescribes a particular ASN.1 encoded form for tokens which includes a mechanism specific bit string within it. An implementation of GSSAPI should enclose the DASS token within the GSSAPI "wrapper". Context handles have no corresponding structure in DASS. The Create_token and Accept_token calls of DASS return a shared key and instance identifier. An implementation of the GSSAPI must take those values along with some other status information and package it as a "context" opaque structure. These data structures must be allocated and freed with the appropriate calls. Per-message tokens and sealed messages have no corresponding data structure within DASS. To fully support the GSSAPI functionality, DASS must be extended to include this functionality. These data structures are created by cryptographic routines given the keys and status information in context structures and the messages passed to them. While not properly part of the DASS architecture, the formats of these data structures are included in section C.3. B.2.2 Procedures This section explains how the functions of the GSSAPI can be provided in terms of the Services Provided by DASS. Not all of the DASS features are accessible through the GSSAPI. B.2.2.1 GSS_Acquire_cred The GSSAPI does not provide a mechanism for logging in users or establishing server credentials. It assumes that some system specific mechanism created those credentials and that applications need some mechanism for getting at them. A model implementation might save all credentials in a node-global pool indexed by some sort of credential name. The credentials in the pool would be access controlled by some local policy which is not concern of portable applications. Those applications would simply call GSS_Acquire_cred and if they passed the access control check, they would get a handle to the credentials which could be used in subsequent calls. B.2.2.2 GSS_Release_cred This call corresponds to the "delete_credentials" call of DASS.
B.2.2.3 GSS_Init_sec_context In the course of a normal mutual authentication, this routine will be called twice. The procedure can determine whether this is the first or second call by seeing whether the "input_context_handle" is zero (it will be on the first call). On the first call, it will use the DASS Create_token service to create a token and it will also allocate and populate a "context" structure. That structure will hold the key, instance identifier, and mutual authentication token returned by Create_token and will in addition hold the flags which were passed into the Init_sec_context call. The token returned by Init_sec_context will be the DASS token included in the GSSAPI token "wrapper". The DASS token will include the optional principal name. If mutual authentication is not requested in the GSSAPI call, the mutual authentication token returned by DASS will be ignored and the initial call will return a COMPLETE status. If mutual authentication is requested, the mutual authentication token will be stored in the context information and a CONTINUE_NEEDED status returned. On the second call to GSS_Init_sec_context (with input_context_handle non-zero), the returned token will be compared to the one in the context information using the Compare_mutual_token procedure and a COMPLETE status will be returned if they match. B.2.2.4 GSS_Accept_sec_context This routine in GSSAPI accepts an incoming token and creates a context. It combines the effects of a series of DASS functions. It could be implemented as follows: - Remove the GSSAPI "wrapper" from the incoming token and pass the rest and the credentials to "Accept_token". Accept_token produces a mutual authentication token and a new credentials structure. If delegation was requested, the new credentials structure will be an output of GSS_Accept_sec_context. In any case, it will be used in the subsequent steps of this procedure. - Use the DASS Get_principal_name function to extract the principal name from the credentials produced by Accept_token. This name is one of the outputs of "GSS_Accept_sec_context. - Apply the DASS Verify_principal_name to the new credentials and the retrieved name to authenticate the token as having come from the named principal. - Create and populate a context structure with the key and
timestamp returned by Accept_token and a status of COMPLETE. Return a handle to that context. - If delegation was requested, return the new credentials from GSS_Accept_sec_context. Otherwise, call Delete_credentials. - If mutual authentication was requested, wrap the mutual authentication token from Accept_token in a GSSAPI "wrapper" and return it. Otherwise return a null string. B.2.2.5 GSS_Delete_sec_context This routine simply deletes the context state. No calls to DASS are required. B.2.2.6 GSS_Sign This routine takes as input a context handle and a message. It creates a per_msg_token by computing a digital signature on the message using the key and timestamp in the context block. No DASS services are required. If additional cryptographic services were requested (replay detection or sequencing), a timestamp or sequence number must be prepended to the message and sent with the signature. The syntax for this message is listed in section C.3. B.2.2.7 GSS_Verify This routine repeats the calculation of the sign routine and verifies the signature provided. If replay detection or sequencing services are provided, the context must maintain as part of its state information containing the sequence numbers or timestamps of messages already received and this one must be checked for acceptability. B.2.2.8 GSS_Seal This routine performs the same functions as Sign but also optionally encrypts the message for privacy using the shared key and encapsulates the whole thing in a GSSAPI specified ASN.1 wrapper. B.2.2.9 GSS_Unseal This routine performs the same functions as GSS_Verify but also parses the data structure including the signature and message and decrypts the message if necessary.
B.3 Syntax The GSSAPI specification recommends the following ASN.1 encoding for the tokens and messages generated through the GSSAPI: --optional top-level token definitions to frame -- different mechanisms GSSAPI DEFINITIONS ::= BEGIN MechType ::= OBJECT IDENTIFIER -- data structure definitions ContextToken ::= -- option indication (delegation, etc.) indicated -- within mechanism-specific token [APPLICATION 0] IMPLICIT SEQUENCE { thisMech MechType, responseExpected BOOLEAN, innerContextToken ANY DEFINED BY MechType -- contents mechanism-specific } PerMsgToken ::= -- as emitted by GSS_Sign and processed by -- GSS_Verify [APPLICATION 1] IMPLICIT SEQUENCE { thisMech MechType, innerMsgToken ANY DEFINED BY MechType -- contents mechanism-specific } SealedMessage ::= -- as emitted by GSS_Seal and processed by -- GSS_Unseal [APPLICATION 2] IMPLICIT SEQUENCE { sealingToken PERMSGTOKEN, confFlag BOOLEAN, userData OCTET STRING -- encrypted if confFlag TRUE } The object identifier for the DASS MechType is 1.3.12.2.1011.7.5. The innerContextToken of a token is a DASS token or mutual authentication token. The innerMsgToken is a null string in the case where the message is encrypted and the token is included as part of a SealedMessage.
Otherwise, it is an eight octet sequence computed as the CBC residue computed using a key and string of bytes defined as follows: - Pad the message provided by the application with 1-8 bytes of pad to produce a string whose length is a multiple of 8 octets. Each pad byte has a value equal to the number of pad bytes. - Compute the key by taking the timestamp of the association (two four byte integers laid out in big endian order with the most significant integer first), complementing the high order bit (to avoid aliasing with mutual authenticators), and encrypting the block in ECB mode with the shared key of the association. The userData field of a SealedMessage is exactly the application provided byte string if confFlag=FALSE. Otherwise, it is the application supplied message encrypted as follows: - Pad the message provided by the application with 1-8 bytes of pad to produce a string whose length = 4 (mod 8). Each pad byte has a value equal to the number of pad bytes. - Append a four byte CRC32 computed over the message + pad. - Compute a key by taking the timestamp of the association (two four byte integers laid out in big endian order with the most significant integer first), complementing the high order bit (to avoid aliasing with mutual authenticators), and encrypting the block in ECB mode with the shared key of the association. - Encrypt the message + pad + CRC32 using CBC and the key computed in the previous step. A note of the logic behind the above: - Because the shared key of an association may be reused by many associations between the same pair of principals, it is necessary to bind the association timestamp into the messages somehow to prevent messages from a previous association being replayed into a new sequence. The technique above of generating an association key accomplishes this and has a side benefit. An implementation may with to keep the long term keys out of the hands of applications for purposes of confinement but may wish to put the encryption associated with an association in process context for reasons of performance. Defining an association key makes that possible.
- The reason that the association specific key is not specified as the output of Create_token and Accept_token is that the DCE RPC security implementation requires that a series of associations between two principals always have the same key and we did not want to have to support a different interface in that application. - The CRC32 after pad constitutes a cheap integrity check when data is encrypted. - The fact that padding is done differently for encrypted and signed messages means that there are no threats related to sending the same message encrypted and unencrypted and using the last block of the encrypted message as a signature on the unencrypted one. Annex C Imported ASN.1 definitions This annex contains extracts from the ASN.1 description of X.509 and X.500 definitions referenced by the DASS ASN.1 definitions. CCITT DEFINITIONS ::= BEGIN joint-iso-ccitt OBJECT IDENTIFIER ::= {2} ds OBJECT IDENTIFIER ::= {joint-iso-ccitt 5} algorithm OBJECT IDENTIFIER ::= {ds 8} iso OBJECT IDENTIFIER ::= {1} identified- organization OBJECT IDENTIFIER ::= {iso 3} ecma OBJECT IDENTIFIER ::= {identified-organization 12} digital OBJECT IDENTIFIER ::= { ecma 1011 } -- X.501 definitions AttributeType ::= OBJECT IDENTIFIER AttributeValue ::= ANY -- useful ones are -- OCTET STRING , -- PrintableString , -- NumericString , -- T61String , -- VisibleString AttributeValueAssertion ::= SEQUENCE {AttributeType, AttributeValue} Name ::= CHOICE {-- only one possibility for now -- RDNSequence}
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName DistinguishedName ::= RDNSequence RelativeDistinguishedName ::= SET OF AttributeValueAssertion -- X.509 definitions Certificate ::= SIGNED SEQUENCE { version [0] Version DEFAULT 1988 , serialNumber SerialNumber , signature AlgorithmIdentifier , issuer Name, valid Validity, subject Name, subjectPublicKey SubjectPublicKeyInfo } Version ::= INTEGER { 1988(0)} SerialNumber ::= INTEGER Validity ::= SEQUENCE{ notBefore UTCTime, notAfter UTCTime} SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier , subjectPublicKey BIT STRING } AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER , parameters ANY DEFINED BY algorithm OPTIONAL} ALGORITHM MACRO BEGIN TYPE NOTATION ::= "PARAMETER" type VALUE NOTATION ::= value (VALUE OBJECT IDENTIFIER) END -- of ALGORITHM ENCRYPTED MACRO BEGIN TYPE NOTATION ::=type(ToBeEnciphered) VALUE NOTATION ::= value(VALUE BIT STRING) -- the value of the bit string is generated by -- taking the octets which form the complete -- encoding (using the ASN.1 Basic Encoding Rules) -- of the value of the ToBeEnciphered type and -- applying an encipherment procedure to those octets-- END SIGNED MACRO ::= BEGIN TYPE NOTATION ::= type (ToBeSigned) VALUE NOTATION ::= value(VALUE SEQUENCE{ ToBeSigned, AlgorithIdentifier, -- of the algorithm used to generate -- the signature ENCRYPTED OCTET STRING -- where the octet string is the result
-- of the hashing of the value of "ToBeSigned" END -- of SIGNED SIGNATURE MACRO ::= BEGIN TYPE NOTATION ::= type(OfSignature) VALUE NOTATION ::= value(VALUE SEQUENCE{ AlgorithmIdentifier, -- of the algorithm used to compute the signature ENCRYPTED OCTET STRING -- where the octet string is a function (e.g., a -- compressed or hashed version) of the value -- "OfSignature", which may include the identifier -- of the algorithm used to compute -- the signature--} ) END -- of SIGNATURE -- X.509 Annex H (not part of the standard) encryptionAlgorithm OBJECT IDENTIFIER ::= {algorithm 1} rsa ALGORITHM PARAMETER KeySize ::= {encryptionAlgorithm 1} KeySize ::= INTEGER END Glossary authentication The process of determining the identity (usually the name) of the other party in some communication exchange. authentication context Cached information used during a particular instance of authentication and including a shared symmetric (DES) key as well as components of the authentication token conveyed during establishment of this context. authentication token Information conveyed during a strong authentication exchange that can be used to authenticate its sender. An authentication token can, but is not necessarily limited to, include the claimant identity and ticket, as well as signed and encrypted secret key exchange messages conveying a secret key to be used in future cryptographic operations. An
authentication token names a particular protocol data structure component. authorization The process of determining the rights associated with a particular principal. certificate The public key of a particular principal, together with some other information relating to the names of the principal and the certifying authority, rendered unforgeable by encipherment with the private key of the certification authority that issued it. certification authority An authority trusted by one or more principals to create and assign certificates. claimant The party that initiates the authentication process. In the DASS architecture, claimants possess credentials which include their identity, authenticating private key and a ticket certifying their authenticating public key. credentials Information "state" required by principals in order to for them to authenticate. Credentials may contain information used to initiate the authentication process (claimant information), information used to respond to an authentication request (verifier information), and cached information useful in improving performance. cryptographic checksum Information which is derived by performing a cryptographic transformation on the data unit. This information can be used by the receiver to verify the authenticity of data passed in cleartext decipher To reverse the effects of encipherment and render a message comprehensible by use of a cryptographic key. delegation The granting of temporary credentials that allow a process to act on behalf of a principal.
delegation key A short term public/private key pair used by a claimant to act on behalf of a principal for a bounded period. The delegation public key appears in the ticket, whereas the delegation private key is used to sign secret key exchange messages. DES Data Encryption Standard: a symmetric (secret key) encryption algorithm used by DASS. An alternate encryption algorithm could be substituted with little or no disruption to the architecture. DES key A 56-bit secret quantity used as a parameter to the DES encryption algorithm. digital signature A value computed from a block of data and a key which could only be computed by someone knowing the key. A digital signature computed with a secret key can only be verified by someone knowing that secret key. A digital signature computed with a private key can be verified by anyone knowing the corresponding public key. encipher To render incomprehensible except to the holder of a particular key. If you encipher with a secret key, only the holder of the same secret can decipher the message. If you encipher with a public key, only the holder of the corresponding private key can decipher it. initial trust certificate A certificate signed by a principal for its own use which states the name and public key of a trusted authority. global user name A hierarchical name for a user which is unique within the entire domain of discussion (typically the network). local user name A simple (non-hierarchical) name by which a user is known within a limited context such as on a single computer.
principal Abstract entity which can be authenticated by name. In DASS there are user principals and server principals. private key Cryptographic key used in asymmetric (public key) cryptography to decrypt and/or sign messages. In asymmetric cryptography, knowing the encryption key is independent of knowing the decryption key. The decryption (or signing) private key cannot be derived from the encrypting (or verifying) public key. proxy A mapping from an external name to a local account name for purposes of establishing a set of local access rights. Note that this differs from the definition in ECMA TR/46. public key Cryptographic key used in asymmetric cryptography to encrypt messages and/or verify signatures. RSA The Rivest-Shamir-Adelman public key cryptosystem based on modular exponentiation where the modulus is the product of two large primes. When the term RSA key is used, it should be clear from context whether the public key, the private key, or the public/private pair is intended. secret key Cryptographic key used in symmetric cryptography to encrypt, sign, decrypt and verify messages. In symmetric cryptography, knowledge of the decryption key implies knowledge of the encryption key, and vice-versa. sign A process which takes a piece of data and a key and produces a digital signature which can only be calculated by someone with the key. The holder of a corresponding key can verify the signature. source The initiator of an authentication exchange. strong authentication Authentication by means of cryptographically derived authentication tokens and credentials. The actual working definition is closer to that of "zero knowledge" proof:
authentication so as to not reveal any information usable by either the verifier, or by an eavesdropping third party, to further their potential ability to impersonate the claimant. target The intended second party (other than the source) to an authentication exchange. ticket A data structure certifying an authenticating (public) key by virtue of being signed by a user principal using their (long term) private key. The ticket also includes the UID of the principal. trusted authority The public key, name and UID of a certification authority trusted in some context to certify the public keys of other principals. UID A 128 bit unique identifier produced according to OSF standard specifications. user key A "long term" RSA key whose private portion authenticates its holder as having the access rights of a particular person. verify To cryptographically process a piece of data and a digital signature to determine that the holder of a particular key signed the data. verifier The party who will perform the operations necessary to verify the claimed identity of a claimant.
Security Considerations Security issues are discussed throughout this memo. Author's Address Charles Kaufman Digital Equipment Corporation ZKO3-3/U14 110 Spit Brook Road Nashua, NH 03062 Phone: (603) 881-1495 Email: kaufman@zk3.dec.com General comments on this document should be sent to cat-ietf@mit.edu. Minor corrections should be sent to the author.