On Fri, Oct 24, 2008 at 4:50 AM, Asiri Rathnayake < [email protected]> wrote:
I have hit a wall trying to implement Digest Access Authentication for the xwiki-webdav module. I'll try to be clear as much as possible.
*+ INTRO* : Digest Access Authentication is used to avoid the transmission of clear text passwords over http for authenticating users. Instead of the clear text password, following hash (RESPONSE) will be transferred to the server by client,
HA1 = MD5(username,password,realm) HA2 = MD5(method,digestURI) RESPONSE = MD5(HA1,nonce,HA2)
Here the 'nonce' is some weird string token generated by the server for that particular client for a particular session. So the RESPONSE instead of the clear text password will be transferred to the server. For more specific information about Digest Authentication, you may refer [1].
FYI, a nonce isn't that weird ( http://en.wikipedia.org/wiki/Cryptographic_nonce ) Cryptographic nonce: In security engineering<http://en.wikipedia.org/wiki/Security_engineering>, a *nonce* stands for *number used once*[1]<http://en.wikipedia.org/wiki/Cryptographic_nonce#cite_note-0>(it is similar in spirit to a Nonce word <http://en.wikipedia.org/wiki/Nonce_word>). It is often a random<http://en.wikipedia.org/wiki/Randomness>or pseudo-random <http://en.wikipedia.org/wiki/Pseudo-random> number issued in an authentication protocol<http://en.wikipedia.org/wiki/Authentication_protocol>to ensure that old communications cannot be reused in *replay attacks <http://en.wikipedia.org/wiki/Replay_attack>*. For instance, nonces are used in HTTP <http://en.wikipedia.org/wiki/HTTP> digest access authentication <http://en.wikipedia.org/wiki/Digest_access_authentication>to calculate an MD5 <http://en.wikipedia.org/wiki/MD5>password<http://en.wikipedia.org/wiki/Password>. The nonces are different each time that the 401 authentication challenge response code <http://en.wikipedia.org/wiki/List_of_HTTP_status_codes> is presented, and each client request has a unique sequence number, thus making replay attacks and dictionary attacks<http://en.wikipedia.org/wiki/Dictionary_attack>virtually impossible. *+ PROBLEM* : Simply put, the way xwiki handles authentication requires the
presentation of a clear text password by the client (which is not available with Digest Authentication scheme). What we have with xwiki (on the server side) is a crypted version of the original password.
One possible solution to overcome this limitation is to store the HA1 value in our databases (is this possible ?). This is one of the limitations of Digest Authentication scheme as mentioned in [1] :
*"There is an important problem with implementing Digest access authentication. This is the requirement that either cleartext passwords or the HA1 hashes must be known in order to perform client response validation"
It appears that the presented password response is crypted by a one-time-pad or session-key <http://en.wikipedia.org/wiki/Session_key>. One thought is a quick hack: Have an external "login" mechanism outside of Xwiki accessible over HTTPS:// which changes the password expected to be presented on Xwiki's end to "RESPONSE=MD5(HA1,nonce,HA2)." In other words, each DAV session, you need to call "davlogin" presenting the new session key. On successful authentication, "davlogin" sets Xwiki's mysql db password for the given user to "RESPONSE=MD5(HA1,nonce,HA2)." Where "nonce" is the current DAV session key. In other words, you sort of reach-around into the db and twiddle the Xwiki password of the given user, so that you can directly present your MD5password, transmit it in the clear (it's already encrypted), and authenticate directly on that MD5password-string matching exactly -- a sort of "one time password" version of a "one time pad." Xwiki then authenticates based on it's understanding of a password (in the clear), when actually the password is the MD5password setup specifically for that session. (just disable the "feature" for "Admin" :-) ) I'm sure there's some better way of doing, this... Also has this situation changed and how does it affect your plans in the microsoft world: http://en.wikipedia.org/wiki/Digest_access_authentication#Browser_Implementa...:: A 2002 analysis by eWeek Labs concluded that Internet Explorer<http://en.wikipedia.org/wiki/Internet_Explorer>Version 5.0, as well as later versions, implements digest authentication in a way that does not comply with RFC 2617<http://tools.ietf.org/html/rfc2617>. As a result, Internet Explorer cannot be used as a web client for a server that complies with the digest authentication standard.[1]<http://en.wikipedia.org/wiki/Digest_access_authentication#cite_note-eweek-0> Finally, is there any ways to reuse existing work. For example, in Struts this appears relatively straightforward: ( http://www.ddj.com/security/184405885?pgno=1 ) Struts distribution includes a comprehensive JSP HTML tag library that provides support for interacting with input forms. These tags let you define HTML forms, checkboxes, input text fields, text areas, radio buttons, and the like. From Listing One <http://www.ddj.com/security/184405885?pgno=1#l1>, you can see that integration requires two things be done: - Calling JavaScript library's *fsSignData* function in HTML form's *onSubmit *event. - Defining a hidden variable to receive PKCS#7 digital signature. HTML TagLib's *form* tag handles the rendering of HTML forms in the Struts framework. I introduced a new tag called *signform* that extends the functionality of the form tag to handle the just mentioned changes. For this, I created a new Java Class called *SignFormTag* in the org.apache.struts.taglib.html package that extends and overwrites some of the methods of the class *FormTag*, which is also in the same package. Methods *renderFormStartElement()* and *renderSignFormScript()* are overwritten to call the *fsSignData* function on HTML form's *onsubmit*event handler. Method *doEndTag()* is overwritten to introduce the hidden variable that receives the returned digital signature. Figure 3<http://www.ddj.com/showArticle.jhtml?documentID=ddj0411b&pgno=4>depicts the UML class diagram. This tag creates the hidden variable *<formname>_signature* into which the digital signature is stored. For example, if the form name is *leaveform* as defined in Listing One <http://www.ddj.com/security/184405885?pgno=1#l1>, this tag introduces a hidden variable named *leaveform_signature,* which can be accessed in the server-side script (Controller). Further, the *SignForm* tag generates a JavaScript function named*<formname_sign(form, sigHolder)> *, where *formname* is the name of the form defined as part of the * <html:signform>* tag. *form* and *sigHolder* are variables representing HTML *form* and hidden variable to store a digital signature, respectively. It also creates a suitable form *onsubmit* event handler that calls the * formname_sign* function when users press the Submit button on *form*. Any * onSubmit* function that is defined as part of the Struts framework will be internally called by this new generated function. This is done behind the scenes and Struts developers are completely oblivious from this. The only modification that you have to do is to use the *<html:signform>* tag in place of the *<html:form>* tag to design signed web forms. This greatly simplifies the development effort required to create secure web form applications. Listing Two <http://www.ddj.com/security/184405885?pgno=1#l2>demonstrates the aforementioned leave example in Listing One <http://www.ddj.com/security/184405885?pgno=1#l1>, but is now using the extended Struts framework. -- Niels http://nielsmayer.com