#ifndef NET_HTTP_HTTP_AUTH_HANDLER_DIGEST_H_
#define NET_HTTP_HTTP_AUTH_HANDLER_DIGEST_H_
#include <memory>
#include <string>
#include <string_view>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_export.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"
namespace url {
class SchemeHostPort;
}
namespace net {
class NET_EXPORT_PRIVATE HttpAuthHandlerDigest : public HttpAuthHandler {
public:
class NET_EXPORT_PRIVATE NonceGenerator {
public:
NonceGenerator();
NonceGenerator(const NonceGenerator&) = delete;
NonceGenerator& operator=(const NonceGenerator&) = delete;
virtual ~NonceGenerator();
virtual std::string GenerateNonce() const = 0;
};
class DynamicNonceGenerator : public NonceGenerator {
public:
DynamicNonceGenerator();
DynamicNonceGenerator(const DynamicNonceGenerator&) = delete;
DynamicNonceGenerator& operator=(const DynamicNonceGenerator&) = delete;
std::string GenerateNonce() const override;
};
class NET_EXPORT_PRIVATE FixedNonceGenerator : public NonceGenerator {
public:
explicit FixedNonceGenerator(const std::string& nonce);
FixedNonceGenerator(const FixedNonceGenerator&) = delete;
FixedNonceGenerator& operator=(const FixedNonceGenerator&) = delete;
std::string GenerateNonce() const override;
private:
const std::string nonce_;
};
class NET_EXPORT_PRIVATE Factory : public HttpAuthHandlerFactory {
public:
Factory();
~Factory() override;
void set_nonce_generator(
std::unique_ptr<const NonceGenerator> nonce_generator);
int CreateAuthHandler(
HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
const NetworkAnonymizationKey& network_anonymization_key,
const url::SchemeHostPort& scheme_host_port,
CreateReason reason,
int digest_nonce_count,
const NetLogWithSource& net_log,
HostResolver* host_resolver,
std::unique_ptr<HttpAuthHandler>* handler) override;
private:
std::unique_ptr<const NonceGenerator> nonce_generator_;
};
~HttpAuthHandlerDigest() override;
private:
bool Init(HttpAuthChallengeTokenizer* challenge,
const SSLInfo& ssl_info,
const NetworkAnonymizationKey& network_anonymization_key) override;
int GenerateAuthTokenImpl(const AuthCredentials* credentials,
const HttpRequestInfo* request,
CompletionOnceCallback callback,
std::string* auth_token) override;
HttpAuth::AuthorizationResult HandleAnotherChallengeImpl(
HttpAuthChallengeTokenizer* challenge) override;
FRIEND_TEST_ALL_PREFIXES(HttpAuthHandlerDigestTest, ParseChallenge);
FRIEND_TEST_ALL_PREFIXES(HttpAuthHandlerDigestTest, AssembleCredentials);
FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, DigestPreAuthNonceCount);
enum class Algorithm {
UNSPECIFIED,
MD5,
MD5_SESS,
SHA256,
SHA256_SESS,
};
enum QualityOfProtection {
QOP_UNSPECIFIED,
QOP_AUTH,
};
HttpAuthHandlerDigest(int nonce_count, const NonceGenerator* nonce_generator);
bool ParseChallenge(HttpAuthChallengeTokenizer* challenge);
bool ParseChallengeProperty(std::string_view name, std::string_view value);
static std::string GenerateNonce();
static std::string QopToString(QualityOfProtection qop);
static std::string AlgorithmToString(Algorithm algorithm);
void GetRequestMethodAndPath(const HttpRequestInfo* request,
std::string* method,
std::string* path) const;
std::string AssembleResponseDigest(const std::string& method,
const std::string& path,
const AuthCredentials& credentials,
const std::string& cnonce,
const std::string& nc) const;
std::string AssembleCredentials(const std::string& method,
const std::string& path,
const AuthCredentials& credentials,
const std::string& cnonce,
int nonce_count) const;
std::string nonce_;
std::string domain_;
std::string opaque_;
bool stale_ = false;
Algorithm algorithm_ = Algorithm::UNSPECIFIED;
QualityOfProtection qop_ = QOP_UNSPECIFIED;
bool userhash_ = false;
std::string original_realm_;
int nonce_count_;
raw_ptr<const NonceGenerator> nonce_generator_;
class DigestContext;
};
}
#endif