1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef NET_HTTP_HTTP_AUTH_HANDLER_DIGEST_H_
6 #define NET_HTTP_HTTP_AUTH_HANDLER_DIGEST_H_
10 #include "base/basictypes.h"
11 #include "base/gtest_prod_util.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "net/base/net_export.h"
14 #include "net/http/http_auth_handler.h"
15 #include "net/http/http_auth_handler_factory.h"
19 // Code for handling http digest authentication.
20 class NET_EXPORT_PRIVATE HttpAuthHandlerDigest
: public HttpAuthHandler
{
22 // A NonceGenerator is a simple interface for generating client nonces.
23 // Unit tests can override the default client nonce behavior with fixed
24 // nonce generation to get reproducible results.
25 class NET_EXPORT_PRIVATE NonceGenerator
{
28 virtual ~NonceGenerator();
30 // Generates a client nonce.
31 virtual std::string
GenerateNonce() const = 0;
33 DISALLOW_COPY_AND_ASSIGN(NonceGenerator
);
36 // DynamicNonceGenerator does a random shuffle of 16
37 // characters to generate a client nonce.
38 class DynamicNonceGenerator
: public NonceGenerator
{
40 DynamicNonceGenerator();
41 virtual std::string
GenerateNonce() const OVERRIDE
;
43 DISALLOW_COPY_AND_ASSIGN(DynamicNonceGenerator
);
46 // FixedNonceGenerator always uses the same string specified at
47 // construction time as the client nonce.
48 class NET_EXPORT_PRIVATE FixedNonceGenerator
: public NonceGenerator
{
50 explicit FixedNonceGenerator(const std::string
& nonce
);
52 virtual std::string
GenerateNonce() const OVERRIDE
;
55 const std::string nonce_
;
56 DISALLOW_COPY_AND_ASSIGN(FixedNonceGenerator
);
59 class NET_EXPORT_PRIVATE Factory
: public HttpAuthHandlerFactory
{
64 // This factory owns the passed in |nonce_generator|.
65 void set_nonce_generator(const NonceGenerator
* nonce_generator
);
67 virtual int CreateAuthHandler(
68 HttpAuth::ChallengeTokenizer
* challenge
,
69 HttpAuth::Target target
,
72 int digest_nonce_count
,
73 const BoundNetLog
& net_log
,
74 scoped_ptr
<HttpAuthHandler
>* handler
) OVERRIDE
;
77 scoped_ptr
<const NonceGenerator
> nonce_generator_
;
80 virtual HttpAuth::AuthorizationResult
HandleAnotherChallenge(
81 HttpAuth::ChallengeTokenizer
* challenge
) OVERRIDE
;
84 virtual bool Init(HttpAuth::ChallengeTokenizer
* challenge
) OVERRIDE
;
86 virtual int GenerateAuthTokenImpl(const AuthCredentials
* credentials
,
87 const HttpRequestInfo
* request
,
88 const CompletionCallback
& callback
,
89 std::string
* auth_token
) OVERRIDE
;
92 FRIEND_TEST_ALL_PREFIXES(HttpAuthHandlerDigestTest
, ParseChallenge
);
93 FRIEND_TEST_ALL_PREFIXES(HttpAuthHandlerDigestTest
, AssembleCredentials
);
94 FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest
, DigestPreAuthNonceCount
);
96 // Possible values for the "algorithm" property.
97 enum DigestAlgorithm
{
98 // No algorithm was specified. According to RFC 2617 this means
99 // we should default to ALGORITHM_MD5.
100 ALGORITHM_UNSPECIFIED
,
102 // Hashes are run for every request.
105 // Hash is run only once during the first WWW-Authenticate handshake.
106 // (SESS means session).
110 // Possible values for QualityOfProtection.
111 // auth-int is not supported, see http://crbug.com/62890 for justification.
112 enum QualityOfProtection
{
117 // |nonce_count| indicates how many times the server-specified nonce has
119 // |nonce_generator| is used to create a client nonce, and is not owned by
120 // the handler. The lifetime of the |nonce_generator| must exceed that of this
122 HttpAuthHandlerDigest(int nonce_count
, const NonceGenerator
* nonce_generator
);
123 virtual ~HttpAuthHandlerDigest();
125 // Parse the challenge, saving the results into this instance.
126 // Returns true on success.
127 bool ParseChallenge(HttpAuth::ChallengeTokenizer
* challenge
);
129 // Parse an individual property. Returns true on success.
130 bool ParseChallengeProperty(const std::string
& name
,
131 const std::string
& value
);
133 // Generates a random string, to be used for client-nonce.
134 static std::string
GenerateNonce();
136 // Convert enum value back to string.
137 static std::string
QopToString(QualityOfProtection qop
);
138 static std::string
AlgorithmToString(DigestAlgorithm algorithm
);
140 // Extract the method and path of the request, as needed by
141 // the 'A2' production. (path may be a hostname for proxy).
142 void GetRequestMethodAndPath(const HttpRequestInfo
* request
,
144 std::string
* path
) const;
146 // Build up the 'response' production.
147 std::string
AssembleResponseDigest(const std::string
& method
,
148 const std::string
& path
,
149 const AuthCredentials
& credentials
,
150 const std::string
& cnonce
,
151 const std::string
& nc
) const;
153 // Build up the value for (Authorization/Proxy-Authorization).
154 std::string
AssembleCredentials(const std::string
& method
,
155 const std::string
& path
,
156 const AuthCredentials
& credentials
,
157 const std::string
& cnonce
,
158 int nonce_count
) const;
160 // Information parsed from the challenge.
165 DigestAlgorithm algorithm_
;
166 QualityOfProtection qop_
;
168 // The realm as initially encoded over-the-wire. This is used in the
169 // challenge text, rather than |realm_| which has been converted to
171 std::string original_realm_
;
174 const NonceGenerator
* nonce_generator_
;
179 #endif // NET_HTTP_HTTP_AUTH_HANDLER_DIGEST_H_