go to  ForumEasy.com   
LdapPro  
 
 
   Home  |  MyForum  |  FAQ  |  Archive    You are not logged in. [Login] or [Register]  
Forum Home » SIMPLE & SASL Binding » DIGEST-MD5 -- Digest Authentication as a SASL Mechanism
Email To Friend  |   Set Alert To This Topic Rewarding Points Availabe: 0 (What's this) New Topic  |   Post Reply
Author Topic: DIGEST-MD5 -- Digest Authentication as a SASL Mechanism
SteveHB
member
offline   
 
posts: 113
joined: 05/31/2006
from: Mountain View, CA
  posted on: 06/13/2006 01:08:03 PM    Edit  |   Quote  |   Report 
DIGEST-MD5 -- Digest Authentication as a SASL Mechanism

What's DIGEST-MD5?

DIGEST-MD5 is a challenge-response authentication protocol used in conjunction with SASL for digest authentication and optional establishment of a security layer. It specifies the following ciphers for use with the security layer: Triple DES, DES and RC4 (128, 56, and 40 bits).

SASL DIGEST-MD5 employs a challenge-response mechanism for authentication, in which clients are able to prove their identities without sending a password to the server. It consists of three messages, commonly referred to as Type 1 (negotiation), Type 2 (challenge) and Type 3 (response). It basically works like this:


  • The client first sends a Type 1 message containing a request for DIGEST-MD5 to the server.

  • The server responds with a Type 2 message containing a set of flags supported or required by the server (thus enabling an agreement on the authentication algorithm and ciphers between the server and the client) and, more importantly, a random challenge -- commonly referred to as nonce.

  • The client uses the challenge obtained from the Type 2 message and the user's credentials to calculate the response. The calculation methods differ based on the DIGEST-MD5 algorithms and ciphers negotiated previously. The client then sends the 'digest-response' to the server in a Type 3 message.

  • Finally, the server receives and validates the "digest-response". The server checks that the nonce-count is "00000001". If it supports subsequent authentication, it saves the value of the nonce and the nonce-count.

  •  Profile | Reply Points Earned: 0
    SteveHB
    member
    offline   
     
    posts: 113
    joined: 05/31/2006
    from: Mountain View, CA
      posted on: 06/13/2006 01:17:32 PM    Edit  |   Quote  |   Report 
    Type 2 -- The DIGEST-MD5 digest-challenge
    Structure:
       digest-challenge  =
             1#( realm | nonce | qop-options | stale | maxbuf | charset
                   algorithm | cipher-opts | auth-param )
    
            realm             = "realm" "=" <"> realm-value <">
            realm-value       = qdstr-val
            nonce             = "nonce" "=" <"> nonce-value <">
            nonce-value       = qdstr-val
            qop-options       = "qop" "=" <"> qop-list <">
            qop-list          = 1#qop-value
            qop-value         = "auth" | "auth-int" | "auth-conf" |
                                 token
            stale             = "stale" "=" "true"
            maxbuf            = "maxbuf" "=" maxbuf-value
            maxbuf-value      = 1*DIGIT
            charset           = "charset" "=" "utf-8"
            algorithm         = "algorithm" "=" "md5-sess"
            cipher-opts       = "cipher" "=" <"> 1#cipher-value <">
            cipher-value      = "3des" | "des" | "rc4-40" | "rc4" |
                                "rc4-56" | token
            auth-param        = token "=" ( token | quoted-string )
    


    The meanings of the values of the directives used above are as follows:

    realm
    Mechanistically, a string which can enable users to know which username and password to use, in case they might have different ones for different servers. Conceptually, it is the name of a collection of accounts that might include the user's account. This string should contain at least the name of the host performing the authentication and might additionally indicate the collection of users who might have access. An example might be "registered_users@gotham.news.example.com". This directive is optional; if not present, the client SHOULD solicit it from the user or be able to compute a default; a plausible default might be the realm supplied by the user when they logged in to the client system. Multiple realm directives are allowed, in which case the user or client must choose one as the realm for which to supply to username and password.

    nonce
    A server-specified data string which MUST be different each time a digest-challenge is sent as part of initial authentication. It is recommended that this string be base64 or hexadecimal data. Note that since the string is passed as a quoted string, the double-quote character is not allowed unless escaped. The contents of the nonce are implementation dependent. The security of the implementation depends on a good choice. It is RECOMMENDED that it contain at least 64 bits of entropy. The nonce is opaque to the client. This directive is required and MUST appear exactly once; if not present, or if multiple instances are present, the client should abort the authentication exchange.

    qop-options
    A quoted string of one or more tokens indicating the "quality of protection" values supported by the server. The value "auth" indicates authentication; the value "auth-int" indicates authentication with integrity protection; the value "auth-conf" indicates authentication with integrity protection and encryption. This directive is optional; if not present it defaults to "auth". The client MUST ignore unrecognized options; if the client recognizes no option, it should abort the authentication exchange.

    stale
    The "stale" directive is not used in initial authentication. This directive may appear at most once; if multiple instances are present, the client should abort the authentication exchange.

    maxbuf
    A number indicating the size of the largest buffer the server is able to receive when using "auth-int" or "auth-conf". If this directive is missing, the default value is 65536. This directive may appear at most once; if multiple instances are present, the client should abort the authentication exchange.

    charset
    This directive, if present, specifies that the server supports UTF-8 encoding for the username and password. If not present, the username and password must be encoded in ISO 8859-1 (of which US-ASCII is a subset). The directive is needed for backwards compatibility with HTTP Digest, which only supports ISO 8859-1. This directive may appear at most once; if multiple instances are present, the client should abort the authentication exchange.

    algorithm
    This directive is required for backwards compatibility with HTTP Digest., which supports other algorithms. . This directive is required and MUST appear exactly once; if not present, or if multiple instances are present, the client should abort the authentication exchange.

    cipher-opts
    A list of ciphers that the server supports. This directive must be present exactly once if "auth-conf" is offered in the "qop-options" directive, in which case the "3des" and "des" modes are mandatory-to-implement. The client MUST ignore unrecognized options; if the client recognizes no option, it should abort the authentication exchange.

    des
    the Data Encryption Standard (DES) cipher [FIPS] in cipher block chaining (CBC) mode with a 56 bit key.

    3des
    the "triple DES" cipher in CBC mode with EDE with the same key for each E stage (aka "two keys mode") for a total key length of 112 bits.

    rc4, rc4-40, rc4-56
    the RC4 cipher with a 128 bit, 40 bit, and 56 bit key, respectively.

    auth-param
    This construct allows for future extensions; it may appear more than once. The client MUST ignore any unrecognized directives.

    For use as a SASL mechanism, note that the following changes are made to "digest-challenge" from HTTP: the following Digest options (called "directives" in HTTP terminology) are unused (i.e., MUST NOT be sent, and MUST be ignored if received):

  • opaque
  • domain

    The size of a digest-challenge MUST be less than 2048 bytes.

  •  Profile | Reply Points Earned: 0
    SteveHB
    member
    offline   
     
    posts: 113
    joined: 05/31/2006
    from: Mountain View, CA
      posted on: 06/13/2006 01:34:35 PM    Edit  |   Quote  |   Report 
    Type 3 -- The DIGEST-MD5 Digest-Response

    Structure:

    digest-response  = 1#( username | realm | nonce | cnonce |
                              nonce-count | qop | digest-uri | response |
                              maxbuf | charset | cipher | authzid |
                              auth-param )
    
           username         = "username" "=" <"> username-value <">
           username-value   = qdstr-val
           cnonce           = "cnonce" "=" <"> cnonce-value <">
           cnonce-value     = qdstr-val
           nonce-count      = "nc" "=" nc-value
           nc-value         = 8LHEX
           qop              = "qop" "=" qop-value
           digest-uri       = "digest-uri" "=" <"> digest-uri-value <">
           digest-uri-value  = serv-type "/" host [ "/" serv-name ]
           serv-type        = 1*ALPHA
           host             = 1*( ALPHA | DIGIT | "-" | "." )
           serv-name        = host
           response         = "response" "=" response-value
           response-value   = 32LHEX
           LHEX             = "0" | "1" | "2" | "3" |
                              "4" | "5" | "6" | "7" |
                              "8" | "9" | "a" | "b" |
                              "c" | "d" | "e" | "f"
           cipher           = "cipher" "=" cipher-value
           authzid          = "authzid" "=" <"> authzid-value <">
           authzid-value    = qdstr-val
    



    username
    The user's name in the specified realm, encoded according to the value of the "charset" directive. This directive is required and MUST be present exactly once; otherwise, authentication fails.

    realm
    The realm containing the user's account. This directive is required if the server provided any realms in the "digest-challenge", in which case it may appear exactly once and its value SHOULD be one of those realms. If the directive is missing, "realm-value" will set to the empty string when computing A1 (see below for details).

    nonce
    The server-specified data string received in the preceding digest-challenge. This directive is required and MUST be present exactly once; otherwise, authentication fails.

    cnonce
    A client-specified data string which MUST be different each time a digest-response is sent as part of initial authentication. The cnonce-value is an opaque quoted string value provided by the client and used by both client and server to avoid chosen plaintext attacks, and to provide mutual authentication. The security of the implementation depends on a good choice. It is RECOMMENDED that it contain at least 64 bits of entropy. This directive is required and MUST be present exactly once; otherwise, authentication fails.

    nonce-count
    The nc-value is the hexadecimal count of the number of requests (including the current request) that the client has sent with the nonce value in this request. For example, in the first request sent in response to a given nonce value, the client sends "nc=00000001". The purpose of this directive is to allow the server to detect request replays by maintaining its own copy of this count - if the same nc-value is seen twice, then the request is a replay. See the description below of the construction of the response value. This directive may appear at most once; if multiple instances are present, the client should abort the authentication exchange.

    qop
    Indicates what "quality of protection" the client accepted. If present, it may appear exactly once and its value MUST be one of the alternatives in qop-options. If not present, it defaults to "auth". These values affect the computation of the response. Note that this is a single token, not a quoted list of alternatives.

    serv-type
    Indicates the type of service, such as "www" for web service, "ftp" for FTP service, "smtp" for mail delivery service, etc. The service name as defined in the SASL profile for the protocol see section 4 of [RFC 2222], registered in the IANA registry of "service" elements for the GSSAPI host-based service name form [RFC 2078].

    host
    The DNS host name or IP address for the service requested. The DNS host name must be the fully-qualified canonical name of the host. The DNS host name is the preferred form; see notes on server processing of the digest-uri.

    serv-name
    Indicates the name of the service if it is replicated. The service is considered to be replicated if the client's service-location process involves resolution using standard DNS lookup operations, and if these operations involve DNS records (such as SRV, or MX) which resolve one DNS name into a set of other DNS names. In this case, the initial name used by the client is the "serv-name", and the final name is the "host" component. For example, the incoming mail service for "example.com" may be replicated through the use of MX records stored in the DNS, one of which points at an SMTP server called "mail3.example.com"; it's "serv-name" would be "example.com", it's "host" would be "mail3.example.com". If the service is not replicated, or the serv-name is identical to the host, then the serv-name component MUST be omitted.

    digest-uri
    Indicates the principal name of the service with which the client wishes to connect, formed from the serv-type, host, and serv-name. For example, the FTP service on "ftp.example.com" would have a "digest-uri" value of "ftp/ftp.example.com"; the SMTP server from the example above would have a "digest-uri" value of "smtp/mail3.example.com/example.com".

    Servers SHOULD check that the supplied value is correct. This will detect accidental connection to the incorrect server. It is also so that clients will be trained to provide values that will work with implementations that use a shared back-end authentication service that can provide server authentication.

    The serv-type component should match the service being offered. The host component should match one of the host names of the host on which the service is running, or it's IP address. Servers SHOULD NOT normally support the IP address form, because server authentication by IP address is not very useful; they should only do so if the DNS is unavailable or unreliable. The serv-name component should match one of the service's configured service names.

    This directive may appear at most once; if multiple instances are present, the client should abort the authentication exchange.

    Note: In the HTTP use of Digest authentication, the digest-uri is the URI (usually a URL) of the resource requested -- hence the name of the directive.

    response
    A string of 32 hex digits computed as defined below, which proves that the user knows a password. This directive is required and MUST be present exactly once; otherwise, authentication fails.

    maxbuf
    A number indicating the size of the largest buffer the client is able to receive. If this directive is missing, the default value is 65536. This directive may appear at most once; if multiple instances are present, the server should abort the authentication exchange.

    charset
    This directive, if present, specifies that the client has used UTF-8 encoding for the username and password. If not present, the username and password must be encoded in ISO 8859-1 (of which US-ASCII is a subset). The client should send this directive only if the server has indicated it supports UTF-8. The directive is needed for backwards compatibility with HTTP Digest, which only supports ISO 8859-1.

    LHEX
    32 hex digits, where the alphabetic characters MUST be lower case, because MD5 is not case insensitive.

    cipher
    The cipher chosen by the client. This directive MUST appear exactly once if "auth-conf" is negotiated; if required and not present, authentication fails.

    authzid
    The "authorization ID" as per RFC 2222, encoded in UTF-8. This directive is optional. If present, and the authenticating user has sufficient privilege, and the server supports it, then after authentication the server will use this identity for making all accesses and access checks. If the client specifies it, and the server does not support it, then the response-value will be incorrect, and authentication will fail.

    The size of a digest-response MUST be less than 4096 bytes.

     Profile | Reply Points Earned: 0
    SteveHB
    member
    offline   
     
    posts: 113
    joined: 05/31/2006
    from: Mountain View, CA
      posted on: 06/13/2006 01:42:35 PM    Edit  |   Quote  |   Report 
    How To Calculate
    The definition of "response-value" above indicates the encoding for its value -- 32 lower case hex characters. The following definitions show how the value is computed.

    Although qop-value and components of digest-uri-value may be case-insensitive, the case which the client supplies in step two is preserved for the purpose of computing and verifying the response-value.

          response-value  =
             HEX( KD ( HEX(H(A1)),
                     { nonce-value, ":" nc-value, ":",
                       cnonce-value, ":", qop-value, ":", HEX(H(A2)) }))
    


    If authzid is specified, then A1 is

          A1 = { H( { username-value, ":", realm-value, ":", passwd } ),
               ":", nonce-value, ":", cnonce-value, ":", authzid-value }
    


    If authzid is not specified, then A1 is

          A1 = { H( { username-value, ":", realm-value, ":", passwd } ),
               ":", nonce-value, ":", cnonce-value }
    


    where
             passwd   = *OCTET
    


    The "username-value", "realm-value" and "passwd" are encoded according to the value of the "charset" directive. If "charset=UTF-8" is present, and all the characters of either "username-value" or "passwd" are in the ISO 8859-1 character set, then it must be converted to ISO 8859-1 before being hashed. This is so that authentication databases that store the hashed username, realm and password (which is common) can be shared compatibly with HTTP, which specifies ISO 8859-1.

    If the "qop" directive's value is "auth", then A2 is:
          A2       = { "AUTHENTICATE:", digest-uri-value }
    

    If the "qop" value is "auth-int" or "auth-conf" then A2 is:
          A2       = { "AUTHENTICATE:", digest-uri-value,
                   ":00000000000000000000000000000000" }
    

    Note that "AUTHENTICATE:" must be in upper case, and the second string constant is a string with a colon followed by 32 zeros.

    These apparently strange values of A2 are for compatibility with HTTP; they were arrived at by setting "Method" to "AUTHENTICATE" and the hash of the entity body to zero in the HTTP digest calculation of A2.

    Also, in the HTTP usage of Digest, several directives in the "digest-challenge" sent by the server have to be returned by the client in the "digest-response". These are:

  • opaque
  • algorithm

    These directives are not needed when Digest is used as a SASL mechanism (i.e., MUST NOT be sent, and MUST be ignored if received).

  •  Profile | Reply Points Earned: 0
    SteveHB
    member
    offline   
     
    posts: 113
    joined: 05/31/2006
    from: Mountain View, CA
      posted on: 06/13/2006 01:50:41 PM    Edit  |   Quote  |   Report 
    Type 4 -- The DIGEST-MD5 Digest-Response Validation

    Structure:

        response-auth = "rspauth" "=" response-value
    


    The server receives and validates the "digest-response". The server checks that the nonce-count is "00000001". If it supports subsequent authentication, it saves the value of the nonce and the nonce-count. It sends 'response-auth' with the 'response-value' being calculated as above, except that if qop is "auth", then A2 is
           A2 = { ":", digest-uri-value }
    

    And if qop is "auth-int" or "auth-conf" then A2 is
           A2 = { ":", digest-uri-value, ":00000000000000000000000000000000" }
    


    Compared to its use in HTTP, the following Digest directives in the "digest-response" are unused:

  • nextnonce
  • qop
  • cnonce
  • nonce-count

  •  Profile | Reply Points Earned: 0
    SteveHB
    member
    offline   
     
    posts: 113
    joined: 05/31/2006
    from: Mountain View, CA
      posted on: 06/13/2006 02:04:06 PM    Edit  |   Quote  |   Report 
    A Example of SASL DIGEST-MD5 Digest Authentication

    This example shows the use of the Digest SASL mechanism with the IMAP4 AUTHENTICATE command [RFC 2060].

    In this example, "C:" and "S:" represent a line sent by the client or server respectively including a CRLF at the end. Linebreaks and indentation within a "C:" or "S:" are editorial and not part of the protocol. The password in this example was "secret". Note that the base64 encoding of the challenges and responses is part of the IMAP4 AUTHENTICATE command, not part of the Digest specification itself.

        C: a AUTHENTICATE DIGEST-MD5
        S: + cmVhbG09ImVsd29vZC5pbm5vc29mdC5jb20iLG5vbmNlPSJPQTZNRzl0
             RVFHbTJoaCIscW9wPSJhdXRoIixhbGdvcml0aG09bWQ1LXNlc3MsY2hh
             cnNldD11dGYtOA==
        C: Y2hhcnNldD11dGYtOCx1c2VybmFtZT0iY2hyaXMiLHJlYWxtPSJlbHdvb2
           QuaW5ub3NvZnQuY29tIixub25jZT0iT0E2TUc5dEVRR20yaGgiLG5jPTAw
           MDAwMDAxLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLGRpZ2VzdC11cmk9Im
           ltYXAvZWx3b29kLmlubm9zb2Z0LmNvbSIscmVzcG9uc2U9ZDM4OGRhZDkw
           ZDRiYmQ3NjBhMTUyMzIxZjIxNDNhZjcscW9wPWF1dGg=
        S: + cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZA==
        C:
        S: a OK User logged in
    


    The base64-decoded version of the SASL exchange is:
        S: realm="elwood.innosoft.com",nonce="OA6MG9tEQGm2hh",qop="auth",
           algorithm=md5-sess,charset=utf-8
        C: charset=utf-8,username="chris",realm="elwood.innosoft.com",
           nonce="OA6MG9tEQGm2hh",nc=00000001,cnonce="OA6MHXh6VqTrRk",
           digest-uri="imap/elwood.innosoft.com",
           response=d388dad90d4bbd760a152321f2143af7,qop=auth
        S: rspauth=ea40f60335c427b5527b84dbabcdfffd
    

     Profile | Reply Points Earned: 0
    SteveHB
    member
    offline   
     
    posts: 113
    joined: 05/31/2006
    from: Mountain View, CA
      posted on: 06/13/2006 06:20:48 PM    Edit  |   Quote  |   Report 
    DIGEST-MD5 Integrity Protection
    If the server offered "qop=auth-int" and the client responded "qop=auth-int", then subsequent messages, up to but not including the next subsequent authentication, between the client and the server MUST be integrity protected. Using as a base session key the value of H(A1) as defined above the client and server calculate a pair of message integrity keys as follows.

    The key for integrity protecting messages from client to server is:
       Kic = MD5({H(A1),
               "Digest session key to client-to-server signing key magic constant"})
    


    The key for integrity protecting messages from server to client is:
       Kis = MD5({H(A1),
               "Digest session key to server-to-client signing key magic constant"})
    


    where MD5 is as specified in [RFC 1321]. If message integrity is negotiated, a MAC block for each message is appended to the message. The MAC block is 16 bytes: the first 10 bytes of the HMAC-MD5 [RFC 2104] of the message, a 2-byte message type number in network byte order with value 1, and the 4-byte sequence number in network byte order. The message type is to allow for future extensions such as rekeying.
       MAC(Ki, SeqNum, msg) = (HMAC(Ki, {SeqNum, msg})[0..9], 0x0001,
                                              SeqNum)
    


    where Ki is Kic for messages sent by the client and Kis for those sent by the server. The sequence number is initialized to zero, and incremented by one for each message sent.

    Upon receipt, MAC(Ki, SeqNum, msg) is computed and compared with the received value; the message is discarded if they differ.

     Profile | Reply Points Earned: 0
    SteveHB
    member
    offline   
     
    posts: 113
    joined: 05/31/2006
    from: Mountain View, CA
      posted on: 06/13/2006 06:28:52 PM    Edit  |   Quote  |   Report 
    DIGEST-MD5 Confidentiality Protection

    If the server sent a "cipher-opts" directive and the client responded with a "cipher" directive, then subsequent messages between the client and the server MUST be confidentiality protected. Using as a base session key the value of H(A1) as defined above the client and server calculate a pair of message integrity keys as follows.

    The key for confidentiality protecting messages from client to server is:
       Kcc = MD5({H(A1)[0..n],
               "Digest H(A1) to client-to-server sealing key magic constant"})
    


    The key for confidentiality protecting messages from server to client is:
       Kcs = MD5({H(A1)[0..n],
       "Digest H(A1) to server-to-client sealing key magic constant"})
    

    where MD5 is as specified in [RFC 1321]. For cipher "rc4-40" n is 5; for "rc4-56" n is 7; for the rest n is 16. The key for the "rc-*" ciphers is all 16 bytes of Kcc or Kcs; the key for "des" is the first 7 bytes; the key for "3des" is the first 14 bytes. The IV for "des" and "3des" is the last 8 bytes of Kcc or Kcs.

    If message confidentiality is negotiated, each message is encrypted with the chosen cipher and a MAC block is appended to the message.

    The MAC block is a variable length padding prefix followed by 16 bytes formatted as follows: the first 10 bytes of the HMAC-MD5 [RFC 2104] of the message, a 2-byte message type number in network byte order with value 1, and the 4-byte sequence number in network byte order. If the blocksize of the chosen cipher is not 1 byte, the padding prefix is one or more octets each containing the number of padding bytes, such that total length of the encrypted part of the message is a multiple of the blocksize. The padding and first 10 bytes of the MAC block are encrypted along with the message.
       SEAL(Ki, Kc, SeqNum, msg) =
             {CIPHER(Kc, {msg, pad, HMAC(Ki, {SeqNum, msg})[0..9])}), 0x0001,
              SeqNum}
    

    where CIPHER is the chosen cipher, Ki and Kc are Kic and Kcc for messages sent by the client and Kis and Kcs for those sent by the server. The sequence number is initialized to zero, and incremented by one for each message sent.

    Upon receipt, the message is decrypted, HMAC(Ki, {SeqNum, msg}) is computed and compared with the received value; the message is discarded if they differ.

     Profile | Reply Points Earned: 0

     
    Powered by ForumEasy © 2003-2005, All Rights Reserved. | Privacy Policy | Terms of Use
     
    Get your own forum today. It's easy and free.