mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-26 18:42:41 +01:00
HTTPDigestCredentials added support for RFC7616 algorithms (#3026)
This commit is contained in:
@@ -38,10 +38,12 @@ class Foundation_API SHA2Engine: public DigestEngine
|
|||||||
public:
|
public:
|
||||||
enum ALGORITHM
|
enum ALGORITHM
|
||||||
{
|
{
|
||||||
SHA_224 = 224,
|
SHA_224 = 1,
|
||||||
SHA_256 = 256,
|
SHA_256,
|
||||||
SHA_384 = 384,
|
SHA_384,
|
||||||
SHA_512 = 512
|
SHA_512,
|
||||||
|
SHA_512_224,
|
||||||
|
SHA_512_256
|
||||||
};
|
};
|
||||||
|
|
||||||
SHA2Engine(ALGORITHM algorithm = SHA_256);
|
SHA2Engine(ALGORITHM algorithm = SHA_256);
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ typedef struct
|
|||||||
Poco::UInt64 state64[8];
|
Poco::UInt64 state64[8];
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
SHA2Engine::ALGORITHM size;
|
|
||||||
unsigned char buffer[128];
|
unsigned char buffer[128];
|
||||||
} HASHCONTEXT;
|
} HASHCONTEXT;
|
||||||
|
|
||||||
@@ -274,7 +273,7 @@ void SHA2Engine::updateImpl(const void* buffer_, std::size_t count)
|
|||||||
Poco::UInt32 left = 0;
|
Poco::UInt32 left = 0;
|
||||||
HASHCONTEXT* pContext = (HASHCONTEXT*)_context;
|
HASHCONTEXT* pContext = (HASHCONTEXT*)_context;
|
||||||
unsigned char* data = (unsigned char*)buffer_;
|
unsigned char* data = (unsigned char*)buffer_;
|
||||||
if (pContext->size > SHA_256)
|
if (_algorithm > SHA_256)
|
||||||
{
|
{
|
||||||
left = (Poco::UInt32)(pContext->total.total64[0] & 0x7F);
|
left = (Poco::UInt32)(pContext->total.total64[0] & 0x7F);
|
||||||
size_t fill = 128 - left;
|
size_t fill = 128 - left;
|
||||||
@@ -323,7 +322,31 @@ void SHA2Engine::updateImpl(const void* buffer_, std::size_t count)
|
|||||||
|
|
||||||
std::size_t SHA2Engine::digestLength() const
|
std::size_t SHA2Engine::digestLength() const
|
||||||
{
|
{
|
||||||
return (size_t)((int)_algorithm / 8);
|
size_t result = 0;
|
||||||
|
|
||||||
|
switch (_algorithm)
|
||||||
|
{
|
||||||
|
case SHA_224:
|
||||||
|
result = 224;
|
||||||
|
break;
|
||||||
|
case SHA_256:
|
||||||
|
result = 256;
|
||||||
|
break;
|
||||||
|
case SHA_384:
|
||||||
|
result = 384;
|
||||||
|
break;
|
||||||
|
case SHA_512:
|
||||||
|
result = 512;
|
||||||
|
break;
|
||||||
|
case SHA_512_224:
|
||||||
|
result = 224;
|
||||||
|
break;
|
||||||
|
case SHA_512_256:
|
||||||
|
result = 256;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -332,7 +355,6 @@ void SHA2Engine::reset()
|
|||||||
if (_context != NULL) free(_context);
|
if (_context != NULL) free(_context);
|
||||||
_context = calloc(1, sizeof(HASHCONTEXT));
|
_context = calloc(1, sizeof(HASHCONTEXT));
|
||||||
HASHCONTEXT* pContext = (HASHCONTEXT*)_context;
|
HASHCONTEXT* pContext = (HASHCONTEXT*)_context;
|
||||||
pContext->size = _algorithm;
|
|
||||||
if (_algorithm == SHA_224)
|
if (_algorithm == SHA_224)
|
||||||
{
|
{
|
||||||
pContext->state.state32[0] = 0xC1059ED8;
|
pContext->state.state32[0] = 0xC1059ED8;
|
||||||
@@ -366,7 +388,7 @@ void SHA2Engine::reset()
|
|||||||
pContext->state.state64[6] = UL64(0xDB0C2E0D64F98FA7);
|
pContext->state.state64[6] = UL64(0xDB0C2E0D64F98FA7);
|
||||||
pContext->state.state64[7] = UL64(0x47B5481DBEFA4FA4);
|
pContext->state.state64[7] = UL64(0x47B5481DBEFA4FA4);
|
||||||
}
|
}
|
||||||
else
|
else if (_algorithm == SHA_512)
|
||||||
{
|
{
|
||||||
pContext->state.state64[0] = UL64(0x6A09E667F3BCC908);
|
pContext->state.state64[0] = UL64(0x6A09E667F3BCC908);
|
||||||
pContext->state.state64[1] = UL64(0xBB67AE8584CAA73B);
|
pContext->state.state64[1] = UL64(0xBB67AE8584CAA73B);
|
||||||
@@ -377,6 +399,27 @@ void SHA2Engine::reset()
|
|||||||
pContext->state.state64[6] = UL64(0x1F83D9ABFB41BD6B);
|
pContext->state.state64[6] = UL64(0x1F83D9ABFB41BD6B);
|
||||||
pContext->state.state64[7] = UL64(0x5BE0CD19137E2179);
|
pContext->state.state64[7] = UL64(0x5BE0CD19137E2179);
|
||||||
}
|
}
|
||||||
|
else if (_algorithm == SHA_512_224)
|
||||||
|
{
|
||||||
|
pContext->state.state64[0] = UL64(0x8C3D37C819544DA2);
|
||||||
|
pContext->state.state64[1] = UL64(0x73E1996689DCD4D6);
|
||||||
|
pContext->state.state64[2] = UL64(0x1DFAB7AE32FF9C82);
|
||||||
|
pContext->state.state64[3] = UL64(0x679DD514582F9FCF);
|
||||||
|
pContext->state.state64[4] = UL64(0x0F6D2B697BD44DA8);
|
||||||
|
pContext->state.state64[5] = UL64(0x77E36F7304C48942);
|
||||||
|
pContext->state.state64[6] = UL64(0x3F9D85A86A1D36C8);
|
||||||
|
pContext->state.state64[7] = UL64(0x1112E6AD91D692A1);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
pContext->state.state64[0] = UL64(0x22312194FC2BF72C);
|
||||||
|
pContext->state.state64[1] = UL64(0x9F555FA3C84C64C2);
|
||||||
|
pContext->state.state64[2] = UL64(0x2393B86B6F53B151);
|
||||||
|
pContext->state.state64[3] = UL64(0x963877195940EABD);
|
||||||
|
pContext->state.state64[4] = UL64(0x96283EE2A88EFFE3);
|
||||||
|
pContext->state.state64[5] = UL64(0xBE5E1E2553863992);
|
||||||
|
pContext->state.state64[6] = UL64(0x2B0199FC2C85B8AA);
|
||||||
|
pContext->state.state64[7] = UL64(0x0EB72DDC81C52CA2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -388,7 +431,8 @@ const DigestEngine::Digest& SHA2Engine::digest()
|
|||||||
size_t last, padn;
|
size_t last, padn;
|
||||||
unsigned char hash[64];
|
unsigned char hash[64];
|
||||||
memset(hash, 0, 64);
|
memset(hash, 0, 64);
|
||||||
if (pContext->size > SHA_256)
|
|
||||||
|
if (_algorithm > SHA_256)
|
||||||
{
|
{
|
||||||
unsigned char msglen[16];
|
unsigned char msglen[16];
|
||||||
Poco::UInt64 high = (pContext->total.total64[0] >> 61) | (pContext->total.total64[1] << 3);
|
Poco::UInt64 high = (pContext->total.total64[0] >> 61) | (pContext->total.total64[1] << 3);
|
||||||
@@ -405,7 +449,7 @@ const DigestEngine::Digest& SHA2Engine::digest()
|
|||||||
PUT_UINT64(pContext->state.state64[3], hash, 24);
|
PUT_UINT64(pContext->state.state64[3], hash, 24);
|
||||||
PUT_UINT64(pContext->state.state64[4], hash, 32);
|
PUT_UINT64(pContext->state.state64[4], hash, 32);
|
||||||
PUT_UINT64(pContext->state.state64[5], hash, 40);
|
PUT_UINT64(pContext->state.state64[5], hash, 40);
|
||||||
if (pContext->size > SHA_384)
|
if (_algorithm > SHA_384)
|
||||||
{
|
{
|
||||||
PUT_UINT64(pContext->state.state64[6], hash, 48);
|
PUT_UINT64(pContext->state.state64[6], hash, 48);
|
||||||
PUT_UINT64(pContext->state.state64[7], hash, 56);
|
PUT_UINT64(pContext->state.state64[7], hash, 56);
|
||||||
@@ -429,7 +473,7 @@ const DigestEngine::Digest& SHA2Engine::digest()
|
|||||||
PUT_UINT32(pContext->state.state32[4], hash, 16);
|
PUT_UINT32(pContext->state.state32[4], hash, 16);
|
||||||
PUT_UINT32(pContext->state.state32[5], hash, 20);
|
PUT_UINT32(pContext->state.state32[5], hash, 20);
|
||||||
PUT_UINT32(pContext->state.state32[6], hash, 24);
|
PUT_UINT32(pContext->state.state32[6], hash, 24);
|
||||||
if (pContext->size > SHA_224) PUT_UINT32(pContext->state.state32[7], hash, 28);
|
if (_algorithm > SHA_224) PUT_UINT32(pContext->state.state32[7], hash, 28);
|
||||||
}
|
}
|
||||||
_digest.insert(_digest.begin(), hash, hash + digestLength());
|
_digest.insert(_digest.begin(), hash, hash + digestLength());
|
||||||
reset();
|
reset();
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ void SHA2EngineTest::testSHA224()
|
|||||||
{
|
{
|
||||||
SHA2Engine engine(SHA2Engine::SHA_224);
|
SHA2Engine engine(SHA2Engine::SHA_224);
|
||||||
|
|
||||||
|
engine.update("");
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f");
|
||||||
|
|
||||||
engine.update("abc");
|
engine.update("abc");
|
||||||
assertTrue (DigestEngine::digestToHex(engine.digest()) == "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7");
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7");
|
||||||
|
|
||||||
@@ -55,6 +58,9 @@ void SHA2EngineTest::testSHA256()
|
|||||||
{
|
{
|
||||||
SHA2Engine engine(SHA2Engine::SHA_256);
|
SHA2Engine engine(SHA2Engine::SHA_256);
|
||||||
|
|
||||||
|
engine.update("");
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
|
||||||
|
|
||||||
engine.update("abc");
|
engine.update("abc");
|
||||||
assertTrue (DigestEngine::digestToHex(engine.digest()) == "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
|
||||||
|
|
||||||
@@ -74,6 +80,9 @@ void SHA2EngineTest::testSHA384()
|
|||||||
{
|
{
|
||||||
SHA2Engine engine(SHA2Engine::SHA_384);
|
SHA2Engine engine(SHA2Engine::SHA_384);
|
||||||
|
|
||||||
|
engine.update("");
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b");
|
||||||
|
|
||||||
engine.update("abc");
|
engine.update("abc");
|
||||||
assertTrue (DigestEngine::digestToHex(engine.digest()) == "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7");
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7");
|
||||||
|
|
||||||
@@ -93,6 +102,9 @@ void SHA2EngineTest::testSHA512()
|
|||||||
{
|
{
|
||||||
SHA2Engine engine(SHA2Engine::SHA_512);
|
SHA2Engine engine(SHA2Engine::SHA_512);
|
||||||
|
|
||||||
|
engine.update("");
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e");
|
||||||
|
|
||||||
engine.update("abc");
|
engine.update("abc");
|
||||||
assertTrue (DigestEngine::digestToHex(engine.digest()) == "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f");
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f");
|
||||||
|
|
||||||
@@ -107,6 +119,47 @@ void SHA2EngineTest::testSHA512()
|
|||||||
assertTrue (DigestEngine::digestToHex(engine.digest()) == "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b");
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHA2EngineTest::testSHA512_224()
|
||||||
|
{
|
||||||
|
SHA2Engine engine(SHA2Engine::SHA_512_224);
|
||||||
|
|
||||||
|
engine.update("");
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4");
|
||||||
|
|
||||||
|
engine.update("abc");
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa");
|
||||||
|
|
||||||
|
engine.update("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "e5302d6d54bb242275d1e7622d68df6eb02dedd13f564c13dbda2174");
|
||||||
|
|
||||||
|
engine.update("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "23fec5bb94d60b23308192640b0c453335d664734fe40e7268674af9");
|
||||||
|
|
||||||
|
for (int i = 0; i < 1000000; ++i)
|
||||||
|
engine.update('a');
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "37ab331d76f0d36de422bd0edeb22a28accd487b7a8453ae965dd287");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHA2EngineTest::testSHA512_256()
|
||||||
|
{
|
||||||
|
SHA2Engine engine(SHA2Engine::SHA_512_256);
|
||||||
|
|
||||||
|
engine.update("");
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a");
|
||||||
|
|
||||||
|
engine.update("abc");
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23");
|
||||||
|
|
||||||
|
engine.update("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "bde8e1f9f19bb9fd3406c90ec6bc47bd36d8ada9f11880dbc8a22a7078b6a461");
|
||||||
|
|
||||||
|
engine.update("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "3928e184fb8690f840da3988121d31be65cb9d3ef83ee6146feac861e19b563a");
|
||||||
|
|
||||||
|
for (int i = 0; i < 1000000; ++i)
|
||||||
|
engine.update('a');
|
||||||
|
assertTrue (DigestEngine::digestToHex(engine.digest()) == "9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21");
|
||||||
|
}
|
||||||
|
|
||||||
void SHA2EngineTest::setUp()
|
void SHA2EngineTest::setUp()
|
||||||
{
|
{
|
||||||
@@ -126,6 +179,7 @@ CppUnit::Test* SHA2EngineTest::suite()
|
|||||||
CppUnit_addTest(pSuite, SHA2EngineTest, testSHA256);
|
CppUnit_addTest(pSuite, SHA2EngineTest, testSHA256);
|
||||||
CppUnit_addTest(pSuite, SHA2EngineTest, testSHA384);
|
CppUnit_addTest(pSuite, SHA2EngineTest, testSHA384);
|
||||||
CppUnit_addTest(pSuite, SHA2EngineTest, testSHA512);
|
CppUnit_addTest(pSuite, SHA2EngineTest, testSHA512);
|
||||||
|
CppUnit_addTest(pSuite, SHA2EngineTest, testSHA512_224);
|
||||||
|
CppUnit_addTest(pSuite, SHA2EngineTest, testSHA512_256);
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ public:
|
|||||||
void testSHA256();
|
void testSHA256();
|
||||||
void testSHA384();
|
void testSHA384();
|
||||||
void testSHA512();
|
void testSHA512();
|
||||||
|
void testSHA512_224();
|
||||||
|
void testSHA512_256();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
|||||||
@@ -120,6 +120,9 @@ public:
|
|||||||
/// and HTTPAuthenticationParams by recomputing the response and comparing
|
/// and HTTPAuthenticationParams by recomputing the response and comparing
|
||||||
/// it with what's in the request.
|
/// it with what's in the request.
|
||||||
|
|
||||||
|
bool isAlgorithmSupported(const std::string& algorithm) const;
|
||||||
|
/// Check if digest algorithm is supported
|
||||||
|
|
||||||
static std::string createNonce();
|
static std::string createNonce();
|
||||||
/// Creates a random nonce string.
|
/// Creates a random nonce string.
|
||||||
|
|
||||||
@@ -133,7 +136,19 @@ private:
|
|||||||
void updateAuthParams(const HTTPRequest& request);
|
void updateAuthParams(const HTTPRequest& request);
|
||||||
int updateNonceCounter(const std::string& nonce);
|
int updateNonceCounter(const std::string& nonce);
|
||||||
|
|
||||||
static const std::string DEFAULT_ALGORITHM;
|
class DigestEngineProvider;
|
||||||
|
|
||||||
|
static const std::string MD_5_ALGORITHM;
|
||||||
|
static const std::string MD_5_SESS_ALGORITHM;
|
||||||
|
static const std::string SHA_ALGORITHM;
|
||||||
|
static const std::string SHA_SESS_ALGORITHM;
|
||||||
|
static const std::string SHA_256_ALGORITHM;
|
||||||
|
static const std::string SHA_256_SESS_ALGORITHM;
|
||||||
|
static const std::string SHA_512_256_ALGORITHM;
|
||||||
|
static const std::string SHA_512_256_SESS_ALGORITHM;
|
||||||
|
static const std::string SHA_512_ALGORITHM;
|
||||||
|
static const std::string SHA_512_SESS_ALGORITHM;
|
||||||
|
static const std::vector<std::string> SUPPORTED_ALGORITHMS;
|
||||||
static const std::string DEFAULT_QOP;
|
static const std::string DEFAULT_QOP;
|
||||||
static const std::string NONCE_PARAM;
|
static const std::string NONCE_PARAM;
|
||||||
static const std::string REALM_PARAM;
|
static const std::string REALM_PARAM;
|
||||||
|
|||||||
@@ -18,12 +18,15 @@
|
|||||||
#include "Poco/DateTimeFormatter.h"
|
#include "Poco/DateTimeFormatter.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include "Poco/MD5Engine.h"
|
#include "Poco/MD5Engine.h"
|
||||||
|
#include "Poco/SHA1Engine.h"
|
||||||
|
#include "Poco/SHA2Engine.h"
|
||||||
#include "Poco/Net/HTTPDigestCredentials.h"
|
#include "Poco/Net/HTTPDigestCredentials.h"
|
||||||
#include "Poco/Net/HTTPRequest.h"
|
#include "Poco/Net/HTTPRequest.h"
|
||||||
#include "Poco/Net/HTTPResponse.h"
|
#include "Poco/Net/HTTPResponse.h"
|
||||||
#include "Poco/NumberFormatter.h"
|
#include "Poco/NumberFormatter.h"
|
||||||
#include "Poco/StringTokenizer.h"
|
#include "Poco/StringTokenizer.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -68,7 +71,28 @@ namespace Net {
|
|||||||
|
|
||||||
|
|
||||||
const std::string HTTPDigestCredentials::SCHEME = "Digest";
|
const std::string HTTPDigestCredentials::SCHEME = "Digest";
|
||||||
const std::string HTTPDigestCredentials::DEFAULT_ALGORITHM("MD5");
|
const std::vector<std::string> HTTPDigestCredentials::SUPPORTED_ALGORITHMS = {
|
||||||
|
"MD5",
|
||||||
|
"MD5-sess",
|
||||||
|
"SHA",
|
||||||
|
"SHA-sess",
|
||||||
|
"SHA-256",
|
||||||
|
"SHA-256-sess",
|
||||||
|
"SHA-512-256",
|
||||||
|
"SHA-512-256-sess",
|
||||||
|
"SHA-512",
|
||||||
|
"SHA-512-sess"
|
||||||
|
};
|
||||||
|
const std::string HTTPDigestCredentials::MD_5_ALGORITHM = "MD5";
|
||||||
|
const std::string HTTPDigestCredentials::MD_5_SESS_ALGORITHM = "MD5-sess";
|
||||||
|
const std::string HTTPDigestCredentials::SHA_ALGORITHM = "SHA";
|
||||||
|
const std::string HTTPDigestCredentials::SHA_SESS_ALGORITHM = "SHA-sess";
|
||||||
|
const std::string HTTPDigestCredentials::SHA_256_ALGORITHM = "SHA-256";
|
||||||
|
const std::string HTTPDigestCredentials::SHA_256_SESS_ALGORITHM = "SHA-256-sess";
|
||||||
|
const std::string HTTPDigestCredentials::SHA_512_256_ALGORITHM = "SHA-512-256";
|
||||||
|
const std::string HTTPDigestCredentials::SHA_512_256_SESS_ALGORITHM = "SHA-512-256-sess";
|
||||||
|
const std::string HTTPDigestCredentials::SHA_512_ALGORITHM = "SHA-512";
|
||||||
|
const std::string HTTPDigestCredentials::SHA_512_SESS_ALGORITHM = "SHA-512-sess";
|
||||||
const std::string HTTPDigestCredentials::DEFAULT_QOP("");
|
const std::string HTTPDigestCredentials::DEFAULT_QOP("");
|
||||||
const std::string HTTPDigestCredentials::NONCE_PARAM("nonce");
|
const std::string HTTPDigestCredentials::NONCE_PARAM("nonce");
|
||||||
const std::string HTTPDigestCredentials::REALM_PARAM("realm");
|
const std::string HTTPDigestCredentials::REALM_PARAM("realm");
|
||||||
@@ -84,6 +108,44 @@ const std::string HTTPDigestCredentials::NC_PARAM("nc");
|
|||||||
int HTTPDigestCredentials::_nonceCounter(0);
|
int HTTPDigestCredentials::_nonceCounter(0);
|
||||||
Poco::FastMutex HTTPDigestCredentials::_nonceMutex;
|
Poco::FastMutex HTTPDigestCredentials::_nonceMutex;
|
||||||
|
|
||||||
|
class HTTPDigestCredentials::DigestEngineProvider {
|
||||||
|
public:
|
||||||
|
DigestEngineProvider(std::string algorithm): _algorithm(algorithm) {
|
||||||
|
_isSessionAlgorithm = _algorithm.find("sess") != std::string::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
DigestEngine& engine() {
|
||||||
|
if (icompare(_algorithm, SHA_ALGORITHM) == 0 || icompare(_algorithm, SHA_SESS_ALGORITHM) == 0)
|
||||||
|
{
|
||||||
|
return _sha1Engine;
|
||||||
|
}
|
||||||
|
if (icompare(_algorithm, SHA_256_ALGORITHM) == 0 || icompare(_algorithm, SHA_256_SESS_ALGORITHM) == 0)
|
||||||
|
{
|
||||||
|
return _sha256Engine;
|
||||||
|
} else if (icompare(_algorithm, SHA_512_256_ALGORITHM) == 0 || icompare(_algorithm, SHA_512_256_SESS_ALGORITHM) == 0)
|
||||||
|
{
|
||||||
|
return _sha512_256Engine;
|
||||||
|
} else if (icompare(_algorithm, SHA_512_ALGORITHM) == 0 || icompare(_algorithm, SHA_512_SESS_ALGORITHM) == 0)
|
||||||
|
{
|
||||||
|
return _sha512;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return _md5Engine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSessionAlgorithm() {
|
||||||
|
return _isSessionAlgorithm;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string _algorithm;
|
||||||
|
SHA1Engine _sha1Engine;
|
||||||
|
MD5Engine _md5Engine;
|
||||||
|
SHA2Engine _sha256Engine { SHA2Engine::ALGORITHM::SHA_256 };
|
||||||
|
SHA2Engine _sha512_256Engine { SHA2Engine::ALGORITHM::SHA_512_256 };
|
||||||
|
SHA2Engine _sha512 { SHA2Engine::ALGORITHM::SHA_512 };
|
||||||
|
bool _isSessionAlgorithm;
|
||||||
|
};
|
||||||
|
|
||||||
HTTPDigestCredentials::HTTPDigestCredentials()
|
HTTPDigestCredentials::HTTPDigestCredentials()
|
||||||
{
|
{
|
||||||
@@ -191,11 +253,6 @@ void HTTPDigestCredentials::createAuthParams(const HTTPRequest& request, const H
|
|||||||
if (!responseAuthParams.has(NONCE_PARAM) || !responseAuthParams.has(REALM_PARAM))
|
if (!responseAuthParams.has(NONCE_PARAM) || !responseAuthParams.has(REALM_PARAM))
|
||||||
throw InvalidArgumentException("Invalid HTTP authentication parameters");
|
throw InvalidArgumentException("Invalid HTTP authentication parameters");
|
||||||
|
|
||||||
const std::string& algorithm = responseAuthParams.get(ALGORITHM_PARAM, DEFAULT_ALGORITHM);
|
|
||||||
|
|
||||||
if (icompare(algorithm, DEFAULT_ALGORITHM) != 0)
|
|
||||||
throw NotImplementedException("Unsupported digest algorithm", algorithm);
|
|
||||||
|
|
||||||
const std::string& nonce = responseAuthParams.get(NONCE_PARAM);
|
const std::string& nonce = responseAuthParams.get(NONCE_PARAM);
|
||||||
const std::string& qop = responseAuthParams.get(QOP_PARAM, DEFAULT_QOP);
|
const std::string& qop = responseAuthParams.get(QOP_PARAM, DEFAULT_QOP);
|
||||||
const std::string& realm = responseAuthParams.getRealm();
|
const std::string& realm = responseAuthParams.getRealm();
|
||||||
@@ -208,6 +265,10 @@ void HTTPDigestCredentials::createAuthParams(const HTTPRequest& request, const H
|
|||||||
{
|
{
|
||||||
_requestAuthParams.set(OPAQUE_PARAM, responseAuthParams.get(OPAQUE_PARAM));
|
_requestAuthParams.set(OPAQUE_PARAM, responseAuthParams.get(OPAQUE_PARAM));
|
||||||
}
|
}
|
||||||
|
if (responseAuthParams.has(ALGORITHM_PARAM))
|
||||||
|
{
|
||||||
|
_requestAuthParams.set(ALGORITHM_PARAM, responseAuthParams.get(ALGORITHM_PARAM));
|
||||||
|
}
|
||||||
|
|
||||||
if (qop.empty())
|
if (qop.empty())
|
||||||
{
|
{
|
||||||
@@ -233,10 +294,8 @@ void HTTPDigestCredentials::createAuthParams(const HTTPRequest& request, const H
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void HTTPDigestCredentials::updateAuthParams(const HTTPRequest& request)
|
void HTTPDigestCredentials::updateAuthParams(const HTTPRequest& request)
|
||||||
{
|
{
|
||||||
MD5Engine engine;
|
|
||||||
const std::string qop = _requestAuthParams.get(QOP_PARAM, DEFAULT_QOP);
|
const std::string qop = _requestAuthParams.get(QOP_PARAM, DEFAULT_QOP);
|
||||||
const std::string realm = _requestAuthParams.getRealm();
|
const std::string realm = _requestAuthParams.getRealm();
|
||||||
const std::string nonce = _requestAuthParams.get(NONCE_PARAM);
|
const std::string nonce = _requestAuthParams.get(NONCE_PARAM);
|
||||||
@@ -245,6 +304,11 @@ void HTTPDigestCredentials::updateAuthParams(const HTTPRequest& request)
|
|||||||
|
|
||||||
if (qop.empty())
|
if (qop.empty())
|
||||||
{
|
{
|
||||||
|
/// Assume that https://tools.ietf.org/html/rfc7616 does not supported
|
||||||
|
/// and still using https://tools.ietf.org/html/rfc2069#section-2.4
|
||||||
|
|
||||||
|
MD5Engine engine;
|
||||||
|
|
||||||
const std::string ha1 = digest(engine, _username, realm, _password);
|
const std::string ha1 = digest(engine, _username, realm, _password);
|
||||||
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
||||||
|
|
||||||
@@ -252,13 +316,28 @@ void HTTPDigestCredentials::updateAuthParams(const HTTPRequest& request)
|
|||||||
}
|
}
|
||||||
else if (icompare(qop, AUTH_PARAM) == 0)
|
else if (icompare(qop, AUTH_PARAM) == 0)
|
||||||
{
|
{
|
||||||
const std::string cnonce = _requestAuthParams.get(CNONCE_PARAM);
|
const std::string algorithm = _requestAuthParams.get(ALGORITHM_PARAM, MD_5_ALGORITHM);
|
||||||
|
|
||||||
const std::string ha1 = digest(engine, _username, realm, _password);
|
if (!isAlgorithmSupported(algorithm)) {
|
||||||
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
throw NotImplementedException("Unsupported digest algorithm", algorithm);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string cnonce = _requestAuthParams.get(CNONCE_PARAM);
|
||||||
const std::string nc = formatNonceCounter(updateNonceCounter(nonce));
|
const std::string nc = formatNonceCounter(updateNonceCounter(nonce));
|
||||||
|
|
||||||
|
DigestEngineProvider engineProvider(algorithm);
|
||||||
|
DigestEngine &engine = engineProvider.engine();
|
||||||
|
|
||||||
|
std::string ha1 = digest(engine, _username, realm, _password);
|
||||||
|
|
||||||
|
if (engineProvider.isSessionAlgorithm()) {
|
||||||
|
ha1 = digest(engine, ha1, nonce, cnonce);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
||||||
|
|
||||||
_requestAuthParams.set(NC_PARAM, nc);
|
_requestAuthParams.set(NC_PARAM, nc);
|
||||||
|
_requestAuthParams.set(CNONCE_PARAM, cnonce);
|
||||||
_requestAuthParams.set(RESPONSE_PARAM, digest(engine, ha1, nonce, nc, cnonce, qop, ha2));
|
_requestAuthParams.set(RESPONSE_PARAM, digest(engine, ha1, nonce, nc, cnonce, qop, ha2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,18 +356,34 @@ bool HTTPDigestCredentials::verifyAuthParams(const HTTPRequest& request, const H
|
|||||||
const std::string& realm = params.getRealm();
|
const std::string& realm = params.getRealm();
|
||||||
const std::string& qop = params.get(QOP_PARAM, DEFAULT_QOP);
|
const std::string& qop = params.get(QOP_PARAM, DEFAULT_QOP);
|
||||||
std::string response;
|
std::string response;
|
||||||
MD5Engine engine;
|
|
||||||
if (qop.empty())
|
if (qop.empty())
|
||||||
{
|
{
|
||||||
|
MD5Engine engine;
|
||||||
|
|
||||||
const std::string ha1 = digest(engine, _username, realm, _password);
|
const std::string ha1 = digest(engine, _username, realm, _password);
|
||||||
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
||||||
response = digest(engine, ha1, nonce, ha2);
|
response = digest(engine, ha1, nonce, ha2);
|
||||||
}
|
}
|
||||||
else if (icompare(qop, AUTH_PARAM) == 0)
|
else if (icompare(qop, AUTH_PARAM) == 0)
|
||||||
{
|
{
|
||||||
|
const std::string& algorithm = params.get(ALGORITHM_PARAM, MD_5_ALGORITHM);
|
||||||
|
|
||||||
|
if (!isAlgorithmSupported(algorithm)) {
|
||||||
|
throw NotImplementedException("Unsupported digest algorithm", algorithm);
|
||||||
|
}
|
||||||
|
|
||||||
|
DigestEngineProvider engineProvider(algorithm);
|
||||||
|
DigestEngine& engine = engineProvider.engine();
|
||||||
|
|
||||||
const std::string& cnonce = params.get(CNONCE_PARAM);
|
const std::string& cnonce = params.get(CNONCE_PARAM);
|
||||||
const std::string& nc = params.get(NC_PARAM);
|
const std::string& nc = params.get(NC_PARAM);
|
||||||
const std::string ha1 = digest(engine, _username, realm, _password);
|
|
||||||
|
std::string ha1 = digest(engine, _username, realm, _password);
|
||||||
|
|
||||||
|
if (engineProvider.isSessionAlgorithm()) {
|
||||||
|
ha1 = digest(engine, ha1, nonce, cnonce);
|
||||||
|
}
|
||||||
|
|
||||||
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
const std::string ha2 = digest(engine, request.getMethod(), request.getURI());
|
||||||
response = digest(engine, ha1, nonce, nc, cnonce, qop, ha2);
|
response = digest(engine, ha1, nonce, nc, cnonce, qop, ha2);
|
||||||
}
|
}
|
||||||
@@ -309,5 +404,15 @@ int HTTPDigestCredentials::updateNonceCounter(const std::string& nonce)
|
|||||||
return iter->second;
|
return iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HTTPDigestCredentials::isAlgorithmSupported(const std::string& algorithm) const
|
||||||
|
{
|
||||||
|
bool isAlgorithmSupported = std::find_if(std::begin(SUPPORTED_ALGORITHMS),
|
||||||
|
std::end(SUPPORTED_ALGORITHMS),
|
||||||
|
[&algorithm](const std::string& supportedAlgorithm) {
|
||||||
|
return icompare(algorithm, supportedAlgorithm) == 0;
|
||||||
|
}) != std::end(SUPPORTED_ALGORITHMS);
|
||||||
|
|
||||||
|
return isAlgorithmSupported;
|
||||||
|
}
|
||||||
|
|
||||||
} } // namespace Poco::Net
|
} } // namespace Poco::Net
|
||||||
|
|||||||
@@ -214,6 +214,45 @@ void HTTPCredentialsTest::testDigestCredentialsQoP()
|
|||||||
assertTrue (params.size() == 9);
|
assertTrue (params.size() == 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HTTPCredentialsTest::testDigestCredentialsQoPSHA256()
|
||||||
|
{
|
||||||
|
HTTPDigestCredentials creds("user", "s3cr3t");
|
||||||
|
HTTPRequest request(HTTPRequest::HTTP_GET, "/digest/");
|
||||||
|
HTTPResponse response;
|
||||||
|
response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\", opaque=\"opaque\", qop=\"auth,auth-int\", algorithm=SHA-256");
|
||||||
|
creds.authenticate(request, response);
|
||||||
|
|
||||||
|
HTTPAuthenticationParams params(request);
|
||||||
|
assertTrue (params["nonce"] == "212573bb90170538efad012978ab811f%lu");
|
||||||
|
assertTrue (params["realm"] == "TestDigest");
|
||||||
|
assertTrue (params["response"] != "40e4889cfbd0e561f71e3107a2863bc4");
|
||||||
|
assertTrue (params["uri"] == "/digest/");
|
||||||
|
assertTrue (params["username"] == "user");
|
||||||
|
assertTrue (params["opaque"] == "opaque");
|
||||||
|
assertTrue (params["cnonce"] != "");
|
||||||
|
assertTrue (params["nc"] == "00000001");
|
||||||
|
assertTrue (params["qop"] == "auth");
|
||||||
|
assertTrue (params["algorithm"] == "SHA-256");
|
||||||
|
assertTrue (params.size() == 10);
|
||||||
|
|
||||||
|
std::string cnonce = params["cnonce"];
|
||||||
|
std::string aresp = params["response"];
|
||||||
|
|
||||||
|
params.clear();
|
||||||
|
|
||||||
|
creds.updateAuthInfo(request);
|
||||||
|
params.fromRequest(request);
|
||||||
|
assertTrue (params["nonce"] == "212573bb90170538efad012978ab811f%lu");
|
||||||
|
assertTrue (params["realm"] == "TestDigest");
|
||||||
|
assertTrue (params["response"] != aresp);
|
||||||
|
assertTrue (params["uri"] == "/digest/");
|
||||||
|
assertTrue (params["username"] == "user");
|
||||||
|
assertTrue (params["opaque"] == "opaque");
|
||||||
|
assertTrue (params["cnonce"] == cnonce);
|
||||||
|
assertTrue (params["nc"] == "00000002");
|
||||||
|
assertTrue (params["qop"] == "auth");
|
||||||
|
assertTrue (params.size() == 10);
|
||||||
|
}
|
||||||
|
|
||||||
void HTTPCredentialsTest::testCredentialsBasic()
|
void HTTPCredentialsTest::testCredentialsBasic()
|
||||||
{
|
{
|
||||||
@@ -311,6 +350,43 @@ void HTTPCredentialsTest::testVerifyAuthInfoQoP()
|
|||||||
assertTrue (!creds.verifyAuthInfo(request));
|
assertTrue (!creds.verifyAuthInfo(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HTTPCredentialsTest::testVerifyAuthInfoQoPSHA256() {
|
||||||
|
HTTPDigestCredentials sha256Creds("user", "s3cr3t");
|
||||||
|
HTTPRequest sha256Request(HTTPRequest::HTTP_GET, "/digest/");
|
||||||
|
HTTPResponse sha256Response;
|
||||||
|
sha256Response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\", opaque=\"opaque\", qop=\"auth,auth-int\", algorithm=SHA-256");
|
||||||
|
sha256Creds.authenticate(sha256Request, sha256Response);
|
||||||
|
assertTrue (sha256Creds.verifyAuthInfo(sha256Request));
|
||||||
|
|
||||||
|
sha256Request.set("Authorization", "Digest cnonce=\"f9c80ffd1c3bc4ee47ed92b704ba75a4\", nc=00000001, nonce=\"212573bb90170538efad012978ab811f%lu\", opaque=\"opaque\", qop=\"auth\", realm=\"TestDigest\", response=\"ff0e90b9aa019120ea0ed6e23ce95d9a\", uri=\"/digest/\", username=\"user\", algorithm=SHA-256");
|
||||||
|
assertTrue (!sha256Creds.verifyAuthInfo(sha256Request));
|
||||||
|
|
||||||
|
HTTPDigestCredentials sha256SessCreds("user", "s3cr3t");
|
||||||
|
HTTPRequest sha256SessRequest(HTTPRequest::HTTP_GET, "/digest/");
|
||||||
|
HTTPResponse sha256SessResponse;
|
||||||
|
sha256SessResponse.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\", opaque=\"opaque\", qop=\"auth,auth-int\", algorithm=SHA-256-sess");
|
||||||
|
sha256SessCreds.authenticate(sha256SessRequest, sha256SessResponse);
|
||||||
|
assertTrue (sha256SessCreds.verifyAuthInfo(sha256SessRequest));
|
||||||
|
|
||||||
|
sha256SessRequest.set("Authorization", "Digest cnonce=\"f9c80ffd1c3bc4ee47ed92b704ba75a4\", nc=00000001, nonce=\"212573bb90170538efad012978ab811f%lu\", opaque=\"opaque\", qop=\"auth\", realm=\"TestDigest\", response=\"ff0e90b9aa019120ea0ed6e23ce95d9a\", uri=\"/digest/\", username=\"user\", algorithm=SHA-256-sess");
|
||||||
|
assertTrue (!sha256SessCreds.verifyAuthInfo(sha256SessRequest));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HTTPCredentialsTest::testIsAlgorithmSupported() {
|
||||||
|
HTTPDigestCredentials sha256Creds("user", "s3cr3t");
|
||||||
|
|
||||||
|
assertTrue (sha256Creds.isAlgorithmSupported("MD5"));
|
||||||
|
assertTrue (sha256Creds.isAlgorithmSupported("MD5-sess"));
|
||||||
|
assertTrue (sha256Creds.isAlgorithmSupported("SHA"));
|
||||||
|
assertTrue (sha256Creds.isAlgorithmSupported("SHA-sess"));
|
||||||
|
assertTrue (sha256Creds.isAlgorithmSupported("SHA-256"));
|
||||||
|
assertTrue (sha256Creds.isAlgorithmSupported("SHA-256-sess"));
|
||||||
|
assertTrue (sha256Creds.isAlgorithmSupported("SHA-512-256"));
|
||||||
|
assertTrue (sha256Creds.isAlgorithmSupported("SHA-512-256-sess"));
|
||||||
|
assertTrue (sha256Creds.isAlgorithmSupported("SHA-512"));
|
||||||
|
assertTrue (sha256Creds.isAlgorithmSupported("SHA-512-sess"));
|
||||||
|
assertFalse (sha256Creds.isAlgorithmSupported("random_algorithm"));
|
||||||
|
}
|
||||||
|
|
||||||
void HTTPCredentialsTest::setUp()
|
void HTTPCredentialsTest::setUp()
|
||||||
{
|
{
|
||||||
@@ -333,6 +409,7 @@ CppUnit::Test* HTTPCredentialsTest::suite()
|
|||||||
CppUnit_addTest(pSuite, HTTPCredentialsTest, testAuthenticationParamsMultipleHeaders);
|
CppUnit_addTest(pSuite, HTTPCredentialsTest, testAuthenticationParamsMultipleHeaders);
|
||||||
CppUnit_addTest(pSuite, HTTPCredentialsTest, testDigestCredentials);
|
CppUnit_addTest(pSuite, HTTPCredentialsTest, testDigestCredentials);
|
||||||
CppUnit_addTest(pSuite, HTTPCredentialsTest, testDigestCredentialsQoP);
|
CppUnit_addTest(pSuite, HTTPCredentialsTest, testDigestCredentialsQoP);
|
||||||
|
CppUnit_addTest(pSuite, HTTPCredentialsTest, testDigestCredentialsQoPSHA256);
|
||||||
CppUnit_addTest(pSuite, HTTPCredentialsTest, testCredentialsBasic);
|
CppUnit_addTest(pSuite, HTTPCredentialsTest, testCredentialsBasic);
|
||||||
CppUnit_addTest(pSuite, HTTPCredentialsTest, testProxyCredentialsBasic);
|
CppUnit_addTest(pSuite, HTTPCredentialsTest, testProxyCredentialsBasic);
|
||||||
CppUnit_addTest(pSuite, HTTPCredentialsTest, testCredentialsDigest);
|
CppUnit_addTest(pSuite, HTTPCredentialsTest, testCredentialsDigest);
|
||||||
@@ -341,6 +418,8 @@ CppUnit::Test* HTTPCredentialsTest::suite()
|
|||||||
CppUnit_addTest(pSuite, HTTPCredentialsTest, testExtractCredentials);
|
CppUnit_addTest(pSuite, HTTPCredentialsTest, testExtractCredentials);
|
||||||
CppUnit_addTest(pSuite, HTTPCredentialsTest, testVerifyAuthInfo);
|
CppUnit_addTest(pSuite, HTTPCredentialsTest, testVerifyAuthInfo);
|
||||||
CppUnit_addTest(pSuite, HTTPCredentialsTest, testVerifyAuthInfoQoP);
|
CppUnit_addTest(pSuite, HTTPCredentialsTest, testVerifyAuthInfoQoP);
|
||||||
|
CppUnit_addTest(pSuite, HTTPCredentialsTest, testVerifyAuthInfoQoPSHA256);
|
||||||
|
CppUnit_addTest(pSuite, HTTPCredentialsTest, testIsAlgorithmSupported);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ public:
|
|||||||
void testAuthenticationParamsMultipleHeaders();
|
void testAuthenticationParamsMultipleHeaders();
|
||||||
void testDigestCredentials();
|
void testDigestCredentials();
|
||||||
void testDigestCredentialsQoP();
|
void testDigestCredentialsQoP();
|
||||||
|
void testDigestCredentialsQoPSHA256();
|
||||||
void testCredentialsBasic();
|
void testCredentialsBasic();
|
||||||
void testProxyCredentialsBasic();
|
void testProxyCredentialsBasic();
|
||||||
void testCredentialsDigest();
|
void testCredentialsDigest();
|
||||||
@@ -39,6 +40,8 @@ public:
|
|||||||
void testExtractCredentials();
|
void testExtractCredentials();
|
||||||
void testVerifyAuthInfo();
|
void testVerifyAuthInfo();
|
||||||
void testVerifyAuthInfoQoP();
|
void testVerifyAuthInfoQoP();
|
||||||
|
void testVerifyAuthInfoQoPSHA256();
|
||||||
|
void testIsAlgorithmSupported();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
|||||||
Reference in New Issue
Block a user