summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSara Golemon <sara.golemon@mongodb.com>2018-02-13 15:39:46 -0500
committerSara Golemon <sara.golemon@mongodb.com>2018-02-24 16:13:04 -0500
commit10c09477dd67543a417423254b1e7c4dd4f9d05c (patch)
tree3228ffd4ee8694a282bd724932f62df6d5969946
parentd9453ada059e2e6315d55ab92781b64f0076db97 (diff)
downloadmongo-10c09477dd67543a417423254b1e7c4dd4f9d05c.tar.gz
SERVER-33305 Expand scramsha1 tests to include SHA256
-rw-r--r--src/mongo/client/scram_client_cache.h2
-rw-r--r--src/mongo/crypto/mechanism_scram.h3
-rw-r--r--src/mongo/crypto/mechanism_scram_test.cpp78
-rw-r--r--src/mongo/db/auth/SConscript4
-rw-r--r--src/mongo/db/auth/authorization_manager_test.cpp11
-rw-r--r--src/mongo/db/auth/authorization_session_test.cpp10
-rw-r--r--src/mongo/db/auth/sasl_scram_test.cpp (renamed from src/mongo/db/auth/sasl_scramsha1_test.cpp)268
-rw-r--r--src/mongo/db/auth/security_key.cpp3
-rw-r--r--src/mongo/db/logical_session_id_test.cpp8
9 files changed, 234 insertions, 153 deletions
diff --git a/src/mongo/client/scram_client_cache.h b/src/mongo/client/scram_client_cache.h
index 0f8d6f8a55a..6b8b7b20d7b 100644
--- a/src/mongo/client/scram_client_cache.h
+++ b/src/mongo/client/scram_client_cache.h
@@ -120,6 +120,4 @@ private:
HostToSecretsMap _hostToSecrets;
};
-using SCRAMSHA1ClientCache = SCRAMClientCache<SHA1Block>;
-
} // namespace mongo
diff --git a/src/mongo/crypto/mechanism_scram.h b/src/mongo/crypto/mechanism_scram.h
index 741566252ab..8ff6d488c06 100644
--- a/src/mongo/crypto/mechanism_scram.h
+++ b/src/mongo/crypto/mechanism_scram.h
@@ -284,8 +284,5 @@ private:
std::shared_ptr<SecureSecrets> _ptr;
};
-using SHA1Presecrets = Presecrets<SHA1Block>;
-using SHA1Secrets = Secrets<SHA1Block>;
-
} // namespace scram
} // namespace mongo
diff --git a/src/mongo/crypto/mechanism_scram_test.cpp b/src/mongo/crypto/mechanism_scram_test.cpp
index 5e67a1dfaa9..88a10bc3569 100644
--- a/src/mongo/crypto/mechanism_scram_test.cpp
+++ b/src/mongo/crypto/mechanism_scram_test.cpp
@@ -31,6 +31,8 @@
#include "mongo/platform/basic.h"
#include "mongo/crypto/mechanism_scram.h"
+#include "mongo/crypto/sha1_block.h"
+#include "mongo/crypto/sha256_block.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/log.h"
@@ -38,47 +40,77 @@ namespace mongo {
namespace scram {
namespace {
-TEST(MechanismScram, BasicVectors) {
- const std::vector<uint8_t> kBadSha1Salt{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
-
- ASSERT_EQ(kBadSha1Salt.size(), SHA1Block::kHashLength - 4);
-
- SHA1Presecrets presecrets("password", kBadSha1Salt, 4096);
- ASSERT_EQ(presecrets.generateSaltedPassword().toString(), "531aYHrF581Skow4E0gCWLw/Ibo=");
-
- SHA1Secrets secrets(presecrets);
- ASSERT_EQ(secrets.clientKey().toString(), "wiHbIsPcvJo230S6Qf5xYCDrhb0=");
- ASSERT_EQ(secrets.storedKey().toString(), "SjXiaB2hLRr8aMUyXMVEw7H1jSI=");
- ASSERT_EQ(secrets.serverKey().toString(), "FilAoFIclBukd3xZxBvYMXTU3HM=");
+template <typename HashBlock>
+void testBasicVectors(StringData saltedPw,
+ StringData clientKey,
+ StringData storedKey,
+ StringData serverKey,
+ StringData proof,
+ StringData signature) {
+ // Predictable salts yield predictable secrets.
+ // salt = {0, 1, 2, 3, ..., n-1}
+ std::vector<uint8_t> salt;
+ salt.resize(HashBlock::kHashLength - 4);
+ int i = 0;
+ std::generate(salt.begin(), salt.end(), [&i] { return i++; });
+
+ Presecrets<HashBlock> presecrets("password", salt, 4096);
+ ASSERT_EQ(presecrets.generateSaltedPassword().toString(), saltedPw);
+
+ Secrets<HashBlock> secrets(presecrets);
+ ASSERT_EQ(secrets.clientKey().toString(), clientKey);
+ ASSERT_EQ(secrets.storedKey().toString(), storedKey);
+ ASSERT_EQ(secrets.serverKey().toString(), serverKey);
const StringData authMessage("secret");
- auto proof = secrets.generateClientProof(authMessage);
- ASSERT_EQ(proof, "y+cpoAm0YlN30GuNgN4B9xghi4E=");
- ASSERT_TRUE(secrets.verifyClientProof(authMessage, base64::decode(proof)));
+ const auto generatedProof = secrets.generateClientProof(authMessage);
+ ASSERT_EQ(generatedProof, proof);
+ ASSERT_TRUE(secrets.verifyClientProof(authMessage, base64::decode(generatedProof)));
- auto sig = secrets.generateServerSignature(authMessage);
- ASSERT_EQ(sig, "kiZS90Kz4/yaYZn9JieHtcRzXR0=");
- ASSERT_TRUE(secrets.verifyServerSignature(authMessage, base64::decode(sig)));
+ const auto generatedSig = secrets.generateServerSignature(authMessage);
+ ASSERT_EQ(generatedSig, signature);
+ ASSERT_TRUE(secrets.verifyServerSignature(authMessage, base64::decode(generatedSig)));
}
-TEST(MechanismScram, generateCredentials) {
- const auto bson = SHA1Secrets::generateCredentials("password", 4096);
+TEST(MechanismScram, BasicVectors) {
+ testBasicVectors<SHA1Block>("531aYHrF581Skow4E0gCWLw/Ibo=",
+ "wiHbIsPcvJo230S6Qf5xYCDrhb0=",
+ "SjXiaB2hLRr8aMUyXMVEw7H1jSI=",
+ "FilAoFIclBukd3xZxBvYMXTU3HM=",
+ "y+cpoAm0YlN30GuNgN4B9xghi4E=",
+ "kiZS90Kz4/yaYZn9JieHtcRzXR0=");
+ testBasicVectors<SHA256Block>("UA7rgIQG0u7EQJuOrJ99qaWVlcWnY0e/ijWBuyzSN0M=",
+ "xdYqTeBpV5U7m/j9EdpKT1Ls+5ublIEeYGND2RUB18k=",
+ "w4nwnR0Mck11lMY3EeF4pCcpJMgaToIguPbEk/ipNGY=",
+ "oKgZqeFO8FDpB14Y8QDLbiX1TurT6XZTdlexUt/Ny5g=",
+ "D6x37wuGhm1HegzIrJhedSb26XOdg5IRyR47oFqzKIo=",
+ "ybHsTJuRLmeT0/1YvQZKrlsgDE40RobAX7o8fu9sbdk=");
+}
+
+template <typename HashBlock>
+void testGenerateCredentials() {
+ const auto bson = Secrets<HashBlock>::generateCredentials("password", 4096);
ASSERT_EQ(bson.nFields(), 4);
ASSERT_TRUE(bson.hasField("salt"));
- ASSERT_EQ(base64::decode(bson.getStringField("salt")).size(), SHA1Block::kHashLength - 4);
+ ASSERT_EQ(base64::decode(bson.getStringField("salt")).size(), HashBlock::kHashLength - 4);
ASSERT_TRUE(bson.hasField("storedKey"));
- ASSERT_EQ(base64::decode(bson.getStringField("storedKey")).size(), SHA1Block::kHashLength);
+ ASSERT_EQ(base64::decode(bson.getStringField("storedKey")).size(), HashBlock::kHashLength);
ASSERT_TRUE(bson.hasField("serverKey"));
- ASSERT_EQ(base64::decode(bson.getStringField("serverKey")).size(), SHA1Block::kHashLength);
+ ASSERT_EQ(base64::decode(bson.getStringField("serverKey")).size(), HashBlock::kHashLength);
ASSERT_TRUE(bson.hasField("iterationCount"));
ASSERT_EQ(bson.getIntField("iterationCount"), 4096);
}
+TEST(MechanismScram, generateCredentials) {
+ testGenerateCredentials<SHA1Block>();
+ testGenerateCredentials<SHA256Block>();
+}
+
} // namespace
} // namespace scram
} // namespace mongo
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript
index 42873a49826..db4f9cfce13 100644
--- a/src/mongo/db/auth/SConscript
+++ b/src/mongo/db/auth/SConscript
@@ -295,10 +295,10 @@ env.CppUnitTest(
)
env.CppUnitTest(
- target='sasl_scramsha1_test',
+ target='sasl_scram_test',
source=[
'sasl_authentication_session_test.cpp',
- 'sasl_scramsha1_test.cpp',
+ 'sasl_scram_test.cpp',
],
LIBDEPS_PRIVATE=[
'saslauth',
diff --git a/src/mongo/db/auth/authorization_manager_test.cpp b/src/mongo/db/auth/authorization_manager_test.cpp
index 603cc770bb3..a2c14d71be9 100644
--- a/src/mongo/db/auth/authorization_manager_test.cpp
+++ b/src/mongo/db/auth/authorization_manager_test.cpp
@@ -33,6 +33,8 @@
#include "mongo/base/status.h"
#include "mongo/bson/mutable/document.h"
#include "mongo/crypto/mechanism_scram.h"
+#include "mongo/crypto/sha1_block.h"
+#include "mongo/crypto/sha256_block.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
@@ -173,13 +175,16 @@ public:
void setUp() override {
auto localExternalState = stdx::make_unique<AuthzManagerExternalStateMock>();
externalState = localExternalState.get();
- externalState->setAuthzVersion(AuthorizationManager::schemaVersion26Final);
authzManager = stdx::make_unique<AuthorizationManager>(std::move(localExternalState));
externalState->setAuthorizationManager(authzManager.get());
authzManager->setAuthEnabled(true);
- credentials = BSON("SCRAM-SHA-1" << scram::SHA1Secrets::generateCredentials(
- "password", saslGlobalParams.scramSHA1IterationCount.load()));
+ credentials = BSON("SCRAM-SHA-1"
+ << scram::Secrets<SHA1Block>::generateCredentials(
+ "password", saslGlobalParams.scramSHA1IterationCount.load())
+ << "SCRAM-SHA-256"
+ << scram::Secrets<SHA256Block>::generateCredentials(
+ "password", saslGlobalParams.scramSHA256IterationCount.load()));
}
std::unique_ptr<AuthorizationManager> authzManager;
diff --git a/src/mongo/db/auth/authorization_session_test.cpp b/src/mongo/db/auth/authorization_session_test.cpp
index 4bbca4e2e17..7933bb8f46b 100644
--- a/src/mongo/db/auth/authorization_session_test.cpp
+++ b/src/mongo/db/auth/authorization_session_test.cpp
@@ -33,6 +33,8 @@
#include "mongo/base/status.h"
#include "mongo/bson/bson_depth.h"
#include "mongo/crypto/mechanism_scram.h"
+#include "mongo/crypto/sha1_block.h"
+#include "mongo/crypto/sha256_block.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authorization_session_for_test.h"
@@ -112,8 +114,12 @@ public:
authzSession = stdx::make_unique<AuthorizationSessionForTest>(std::move(localSessionState));
authzManager->setAuthEnabled(true);
- credentials = BSON("SCRAM-SHA-1" << scram::SHA1Secrets::generateCredentials(
- "a", saslGlobalParams.scramSHA1IterationCount.load()));
+ credentials =
+ BSON("SCRAM-SHA-1" << scram::Secrets<SHA1Block>::generateCredentials(
+ "a", saslGlobalParams.scramSHA1IterationCount.load())
+ << "SCRAM-SHA-256"
+ << scram::Secrets<SHA256Block>::generateCredentials(
+ "a", saslGlobalParams.scramSHA256IterationCount.load()));
}
};
diff --git a/src/mongo/db/auth/sasl_scramsha1_test.cpp b/src/mongo/db/auth/sasl_scram_test.cpp
index d0c326ea570..c75cae5f260 100644
--- a/src/mongo/db/auth/sasl_scramsha1_test.cpp
+++ b/src/mongo/db/auth/sasl_scram_test.cpp
@@ -26,11 +26,15 @@
* it in the license file.
*/
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
+
#include "mongo/platform/basic.h"
#include "mongo/client/native_sasl_client_session.h"
#include "mongo/client/scram_client_cache.h"
#include "mongo/crypto/mechanism_scram.h"
+#include "mongo/crypto/sha1_block.h"
+#include "mongo/crypto/sha256_block.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authz_manager_external_state_mock.h"
#include "mongo/db/auth/authz_session_external_state_mock.h"
@@ -40,23 +44,26 @@
#include "mongo/stdx/memory.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/base64.h"
+#include "mongo/util/log.h"
#include "mongo/util/password_digest.h"
namespace mongo {
+namespace {
BSONObj generateSCRAMUserDocument(StringData username, StringData password) {
- const size_t scramIterationCount = 10000;
- auto database = "test"_sd;
+ const auto database = "test"_sd;
- std::string digested = createPasswordDigest(username, password);
- auto scramCred = scram::SHA1Secrets::generateCredentials(digested, scramIterationCount);
+ const auto digested = createPasswordDigest(username, password);
+ const auto sha1Cred = scram::Secrets<SHA1Block>::generateCredentials(digested, 10000);
+ const auto sha256Cred =
+ scram::Secrets<SHA256Block>::generateCredentials(password.toString(), 15000);
return BSON("_id" << (str::stream() << database << "." << username).operator StringData()
<< AuthorizationManager::USER_NAME_FIELD_NAME
<< username
<< AuthorizationManager::USER_DB_FIELD_NAME
<< database
<< "credentials"
- << BSON("SCRAM-SHA-1" << scramCred)
+ << BSON("SCRAM-SHA-1" << sha1Cred << "SCRAM-SHA-256" << sha256Cred)
<< "roles"
<< BSONArray()
<< "privileges"
@@ -194,7 +201,7 @@ SCRAMStepsResult runSteps(NativeSaslAuthenticationSession* saslServerSession,
return result;
}
-class SCRAMSHA1Fixture : public mongo::unittest::Test {
+class SCRAMFixture : public mongo::unittest::Test {
protected:
const SCRAMStepsResult goalState =
SCRAMStepsResult(SaslTestState(SaslTestState::kClient, 4), Status::OK());
@@ -210,7 +217,7 @@ protected:
std::unique_ptr<NativeSaslAuthenticationSession> saslServerSession;
std::unique_ptr<NativeSaslClientSession> saslClientSession;
- void setUp() {
+ void setUp() final {
client = serviceContext.makeClient("test");
opCtx = serviceContext.makeOperationContext(client.get());
@@ -224,23 +231,55 @@ protected:
saslServerSession = stdx::make_unique<NativeSaslAuthenticationSession>(authzSession.get());
saslServerSession->setOpCtxt(opCtx.get());
- saslServerSession->start("test", "SCRAM-SHA-1", "mongodb", "MockServer.test", 1, false)
- .transitional_ignore();
+ ASSERT_OK(
+ saslServerSession->start("test", _mechanism, "mongodb", "MockServer.test", 1, false));
saslClientSession = stdx::make_unique<NativeSaslClientSession>();
- saslClientSession->setParameter(NativeSaslClientSession::parameterMechanism, "SCRAM-SHA-1");
+ saslClientSession->setParameter(NativeSaslClientSession::parameterMechanism, _mechanism);
saslClientSession->setParameter(NativeSaslClientSession::parameterServiceName, "mongodb");
saslClientSession->setParameter(NativeSaslClientSession::parameterServiceHostname,
"MockServer.test");
saslClientSession->setParameter(NativeSaslClientSession::parameterServiceHostAndPort,
"MockServer.test:27017");
}
+
+ void tearDown() final {
+ saslClientSession.reset();
+ saslServerSession.reset();
+ authzSession.reset();
+ authzManager.reset();
+ authzManagerExternalState = nullptr;
+ opCtx.reset();
+ client.reset();
+ }
+
+ std::string createPasswordDigest(StringData username, StringData password) {
+ if (_digestPassword) {
+ return mongo::createPasswordDigest(username, password);
+ } else {
+ return password.toString();
+ }
+ }
+
+ std::string _mechanism;
+ bool _digestPassword;
+
+public:
+ void run() {
+ log() << "SCRAM-SHA-1 variant";
+ _mechanism = "SCRAM-SHA-1";
+ _digestPassword = true;
+ Test::run();
+
+ log() << "SCRAM-SHA-256 variant";
+ _mechanism = "SCRAM-SHA-256";
+ _digestPassword = false;
+ Test::run();
+ }
};
-TEST_F(SCRAMSHA1Fixture, testServerStep1DoesNotIncludeNonceFromClientStep1) {
- authzManagerExternalState
- ->insertPrivilegeDocument(
- opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj())
- .transitional_ignore();
+TEST_F(SCRAMFixture, testServerStep1DoesNotIncludeNonceFromClientStep1) {
+ ASSERT_OK(authzManagerExternalState->insertPrivilegeDocument(
+ opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj()));
saslClientSession->setParameter(NativeSaslClientSession::parameterUser, "sajack");
saslClientSession->setParameter(NativeSaslClientSession::parameterPassword,
@@ -261,11 +300,9 @@ TEST_F(SCRAMSHA1Fixture, testServerStep1DoesNotIncludeNonceFromClientStep1) {
runSteps(saslServerSession.get(), saslClientSession.get(), mutator));
}
-TEST_F(SCRAMSHA1Fixture, testClientStep2DoesNotIncludeNonceFromServerStep1) {
- authzManagerExternalState
- ->insertPrivilegeDocument(
- opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj())
- .transitional_ignore();
+TEST_F(SCRAMFixture, testClientStep2DoesNotIncludeNonceFromServerStep1) {
+ ASSERT_OK(authzManagerExternalState->insertPrivilegeDocument(
+ opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj()));
saslClientSession->setParameter(NativeSaslClientSession::parameterUser, "sajack");
saslClientSession->setParameter(NativeSaslClientSession::parameterPassword,
@@ -285,11 +322,9 @@ TEST_F(SCRAMSHA1Fixture, testClientStep2DoesNotIncludeNonceFromServerStep1) {
runSteps(saslServerSession.get(), saslClientSession.get(), mutator));
}
-TEST_F(SCRAMSHA1Fixture, testClientStep2GivesBadProof) {
- authzManagerExternalState
- ->insertPrivilegeDocument(
- opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj())
- .transitional_ignore();
+TEST_F(SCRAMFixture, testClientStep2GivesBadProof) {
+ ASSERT_OK(authzManagerExternalState->insertPrivilegeDocument(
+ opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj()));
saslClientSession->setParameter(NativeSaslClientSession::parameterUser, "sajack");
saslClientSession->setParameter(NativeSaslClientSession::parameterPassword,
@@ -313,11 +348,9 @@ TEST_F(SCRAMSHA1Fixture, testClientStep2GivesBadProof) {
runSteps(saslServerSession.get(), saslClientSession.get(), mutator));
}
-TEST_F(SCRAMSHA1Fixture, testServerStep2GivesBadVerifier) {
- authzManagerExternalState
- ->insertPrivilegeDocument(
- opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj())
- .transitional_ignore();
+TEST_F(SCRAMFixture, testServerStep2GivesBadVerifier) {
+ ASSERT_OK(authzManagerExternalState->insertPrivilegeDocument(
+ opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj()));
saslClientSession->setParameter(NativeSaslClientSession::parameterUser, "sajack");
saslClientSession->setParameter(NativeSaslClientSession::parameterPassword,
@@ -349,11 +382,9 @@ TEST_F(SCRAMSHA1Fixture, testServerStep2GivesBadVerifier) {
}
-TEST_F(SCRAMSHA1Fixture, testSCRAM) {
- authzManagerExternalState
- ->insertPrivilegeDocument(
- opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj())
- .transitional_ignore();
+TEST_F(SCRAMFixture, testSCRAM) {
+ ASSERT_OK(authzManagerExternalState->insertPrivilegeDocument(
+ opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj()));
saslClientSession->setParameter(NativeSaslClientSession::parameterUser, "sajack");
saslClientSession->setParameter(NativeSaslClientSession::parameterPassword,
@@ -364,11 +395,9 @@ TEST_F(SCRAMSHA1Fixture, testSCRAM) {
ASSERT_EQ(goalState, runSteps(saslServerSession.get(), saslClientSession.get()));
}
-TEST_F(SCRAMSHA1Fixture, testSCRAMWithChannelBindingSupportedByClient) {
- authzManagerExternalState
- ->insertPrivilegeDocument(
- opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj())
- .transitional_ignore();
+TEST_F(SCRAMFixture, testSCRAMWithChannelBindingSupportedByClient) {
+ ASSERT_OK(authzManagerExternalState->insertPrivilegeDocument(
+ opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj()));
saslClientSession->setParameter(NativeSaslClientSession::parameterUser, "sajack");
saslClientSession->setParameter(NativeSaslClientSession::parameterPassword,
@@ -384,11 +413,9 @@ TEST_F(SCRAMSHA1Fixture, testSCRAMWithChannelBindingSupportedByClient) {
ASSERT_EQ(goalState, runSteps(saslServerSession.get(), saslClientSession.get(), mutator));
}
-TEST_F(SCRAMSHA1Fixture, testSCRAMWithChannelBindingRequiredByClient) {
- authzManagerExternalState
- ->insertPrivilegeDocument(
- opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj())
- .transitional_ignore();
+TEST_F(SCRAMFixture, testSCRAMWithChannelBindingRequiredByClient) {
+ ASSERT_OK(authzManagerExternalState->insertPrivilegeDocument(
+ opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj()));
saslClientSession->setParameter(NativeSaslClientSession::parameterUser, "sajack");
saslClientSession->setParameter(NativeSaslClientSession::parameterPassword,
@@ -407,11 +434,9 @@ TEST_F(SCRAMSHA1Fixture, testSCRAMWithChannelBindingRequiredByClient) {
runSteps(saslServerSession.get(), saslClientSession.get(), mutator));
}
-TEST_F(SCRAMSHA1Fixture, testSCRAMWithInvalidChannelBinding) {
- authzManagerExternalState
- ->insertPrivilegeDocument(
- opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj())
- .transitional_ignore();
+TEST_F(SCRAMFixture, testSCRAMWithInvalidChannelBinding) {
+ ASSERT_OK(authzManagerExternalState->insertPrivilegeDocument(
+ opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj()));
saslClientSession->setParameter(NativeSaslClientSession::parameterUser, "sajack");
saslClientSession->setParameter(NativeSaslClientSession::parameterPassword,
@@ -430,11 +455,9 @@ TEST_F(SCRAMSHA1Fixture, testSCRAMWithInvalidChannelBinding) {
runSteps(saslServerSession.get(), saslClientSession.get(), mutator));
}
-TEST_F(SCRAMSHA1Fixture, testNULLInPassword) {
- authzManagerExternalState
- ->insertPrivilegeDocument(
- opCtx.get(), generateSCRAMUserDocument("sajack", "saj\0ack"), BSONObj())
- .transitional_ignore();
+TEST_F(SCRAMFixture, testNULLInPassword) {
+ ASSERT_OK(authzManagerExternalState->insertPrivilegeDocument(
+ opCtx.get(), generateSCRAMUserDocument("sajack", "saj\0ack"), BSONObj()));
saslClientSession->setParameter(NativeSaslClientSession::parameterUser, "sajack");
saslClientSession->setParameter(NativeSaslClientSession::parameterPassword,
@@ -446,11 +469,9 @@ TEST_F(SCRAMSHA1Fixture, testNULLInPassword) {
}
-TEST_F(SCRAMSHA1Fixture, testCommasInUsernameAndPassword) {
- authzManagerExternalState
- ->insertPrivilegeDocument(
- opCtx.get(), generateSCRAMUserDocument("s,a,jack", "s,a,jack"), BSONObj())
- .transitional_ignore();
+TEST_F(SCRAMFixture, testCommasInUsernameAndPassword) {
+ ASSERT_OK(authzManagerExternalState->insertPrivilegeDocument(
+ opCtx.get(), generateSCRAMUserDocument("s,a,jack", "s,a,jack"), BSONObj()));
saslClientSession->setParameter(NativeSaslClientSession::parameterUser, "s,a,jack");
saslClientSession->setParameter(NativeSaslClientSession::parameterPassword,
@@ -461,7 +482,7 @@ TEST_F(SCRAMSHA1Fixture, testCommasInUsernameAndPassword) {
ASSERT_EQ(goalState, runSteps(saslServerSession.get(), saslClientSession.get()));
}
-TEST_F(SCRAMSHA1Fixture, testIncorrectUser) {
+TEST_F(SCRAMFixture, testIncorrectUser) {
saslClientSession->setParameter(NativeSaslClientSession::parameterUser, "sajack");
saslClientSession->setParameter(NativeSaslClientSession::parameterPassword,
createPasswordDigest("sajack", "sajack"));
@@ -473,11 +494,9 @@ TEST_F(SCRAMSHA1Fixture, testIncorrectUser) {
runSteps(saslServerSession.get(), saslClientSession.get()));
}
-TEST_F(SCRAMSHA1Fixture, testIncorrectPassword) {
- authzManagerExternalState
- ->insertPrivilegeDocument(
- opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj())
- .transitional_ignore();
+TEST_F(SCRAMFixture, testIncorrectPassword) {
+ ASSERT_OK(authzManagerExternalState->insertPrivilegeDocument(
+ opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj()));
saslClientSession->setParameter(NativeSaslClientSession::parameterUser, "sajack");
saslClientSession->setParameter(NativeSaslClientSession::parameterPassword,
@@ -491,7 +510,7 @@ TEST_F(SCRAMSHA1Fixture, testIncorrectPassword) {
runSteps(saslServerSession.get(), saslClientSession.get()));
}
-TEST_F(SCRAMSHA1Fixture, testOptionalClientExtensions) {
+TEST_F(SCRAMFixture, testOptionalClientExtensions) {
// Verify server ignores unknown/optional extensions sent by client.
ASSERT_OK(authzManagerExternalState->insertPrivilegeDocument(
opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj()));
@@ -515,7 +534,7 @@ TEST_F(SCRAMSHA1Fixture, testOptionalClientExtensions) {
runSteps(saslServerSession.get(), saslClientSession.get(), mutator));
}
-TEST_F(SCRAMSHA1Fixture, testOptionalServerExtensions) {
+TEST_F(SCRAMFixture, testOptionalServerExtensions) {
// Verify client errors on unknown/optional extensions sent by server.
ASSERT_OK(authzManagerExternalState->insertPrivilegeDocument(
opCtx.get(), generateSCRAMUserDocument("sajack", "sajack"), BSONObj()));
@@ -540,70 +559,91 @@ TEST_F(SCRAMSHA1Fixture, testOptionalServerExtensions) {
runSteps(saslServerSession.get(), saslClientSession.get(), mutator));
}
-TEST(SCRAMSHA1Cache, testGetFromEmptyCache) {
- SCRAMSHA1ClientCache cache;
- std::string saltStr("saltsaltsaltsalt");
- std::vector<std::uint8_t> salt(saltStr.begin(), saltStr.end());
+template <typename HashBlock>
+void testGetFromEmptyCache() {
+ SCRAMClientCache<HashBlock> cache;
+ const auto salt = scram::Presecrets<HashBlock>::generateSecureRandomSalt();
HostAndPort host("localhost:27017");
-
- ASSERT_FALSE(cache.getCachedSecrets(host, scram::SHA1Presecrets("aaa", salt, 10000)));
+ ASSERT_FALSE(cache.getCachedSecrets(host, scram::Presecrets<HashBlock>("aaa", salt, 10000)));
}
+TEST(SCRAMCache, testGetFromEmptyCache) {
+ testGetFromEmptyCache<SHA1Block>();
+ testGetFromEmptyCache<SHA256Block>();
+}
-TEST(SCRAMSHA1Cache, testSetAndGet) {
- SCRAMSHA1ClientCache cache;
- std::string saltStr("saltsaltsaltsalt");
- std::string badSaltStr("s@lts@lts@lts@lt");
- std::vector<std::uint8_t> salt(saltStr.begin(), saltStr.end());
- std::vector<std::uint8_t> badSalt(badSaltStr.begin(), badSaltStr.end());
+template <typename HashBlock>
+void testSetAndGet() {
+ SCRAMClientCache<HashBlock> cache;
+ const auto salt = scram::Presecrets<HashBlock>::generateSecureRandomSalt();
HostAndPort host("localhost:27017");
- auto secret = scram::SHA1Secrets(scram::SHA1Presecrets("aaa", salt, 10000));
- cache.setCachedSecrets(host, scram::SHA1Presecrets("aaa", salt, 10000), secret);
- auto cachedSecret = cache.getCachedSecrets(host, scram::SHA1Presecrets("aaa", salt, 10000));
- ASSERT_TRUE(cachedSecret);
- ASSERT_TRUE(secret.clientKey() == cachedSecret.clientKey());
- ASSERT_TRUE(secret.serverKey() == cachedSecret.serverKey());
- ASSERT_TRUE(secret.storedKey() == cachedSecret.storedKey());
+ const auto presecrets = scram::Presecrets<HashBlock>("aaa", salt, 10000);
+ const auto secrets = scram::Secrets<HashBlock>(presecrets);
+ cache.setCachedSecrets(host, presecrets, secrets);
+ const auto cachedSecrets = cache.getCachedSecrets(host, presecrets);
+
+ ASSERT_TRUE(cachedSecrets);
+ ASSERT_TRUE(secrets.clientKey() == cachedSecrets.clientKey());
+ ASSERT_TRUE(secrets.serverKey() == cachedSecrets.serverKey());
+ ASSERT_TRUE(secrets.storedKey() == cachedSecrets.storedKey());
}
+TEST(SCRAMCache, testSetAndGet) {
+ testSetAndGet<SHA1Block>();
+ testSetAndGet<SHA256Block>();
+}
-TEST(SCRAMSHA1Cache, testSetAndGetWithDifferentParameters) {
- SCRAMSHA1ClientCache cache;
- std::string saltStr("saltsaltsaltsalt");
- std::string badSaltStr("s@lts@lts@lts@lt");
- std::vector<std::uint8_t> salt(saltStr.begin(), saltStr.end());
- std::vector<std::uint8_t> badSalt(badSaltStr.begin(), badSaltStr.end());
+template <typename HashBlock>
+void testSetAndGetWithDifferentParameters() {
+ SCRAMClientCache<HashBlock> cache;
+ const auto salt = scram::Presecrets<HashBlock>::generateSecureRandomSalt();
HostAndPort host("localhost:27017");
- auto secret = scram::SHA1Secrets(scram::SHA1Presecrets("aaa", salt, 10000));
- cache.setCachedSecrets(host, scram::SHA1Presecrets("aaa", salt, 10000), secret);
-
- ASSERT_FALSE(cache.getCachedSecrets(HostAndPort("localhost:27018"),
- scram::SHA1Presecrets("aaa", salt, 10000)));
- ASSERT_FALSE(cache.getCachedSecrets(host, scram::SHA1Presecrets("aab", salt, 10000)));
- ASSERT_FALSE(cache.getCachedSecrets(host, scram::SHA1Presecrets("aaa", badSalt, 10000)));
- ASSERT_FALSE(cache.getCachedSecrets(host, scram::SHA1Presecrets("aaa", salt, 10001)));
+ const auto presecrets = scram::Presecrets<HashBlock>("aaa", salt, 10000);
+ const auto secrets = scram::Secrets<HashBlock>(presecrets);
+ cache.setCachedSecrets(host, presecrets, secrets);
+ ASSERT_TRUE(cache.getCachedSecrets(host, presecrets));
+
+ // Alter each of: host, password, salt, iterationCount.
+ // Any one of which should fail to retreive from cache.
+ ASSERT_FALSE(cache.getCachedSecrets(HostAndPort("localhost:27018"), presecrets));
+ ASSERT_FALSE(cache.getCachedSecrets(host, scram::Presecrets<HashBlock>("aab", salt, 10000)));
+ const auto badSalt = scram::Presecrets<HashBlock>::generateSecureRandomSalt();
+ ASSERT_FALSE(cache.getCachedSecrets(host, scram::Presecrets<HashBlock>("aaa", badSalt, 10000)));
+ ASSERT_FALSE(cache.getCachedSecrets(host, scram::Presecrets<HashBlock>("aaa", salt, 10001)));
}
+TEST(SCRAMCache, testSetAndGetWithDifferentParameters) {
+ testSetAndGetWithDifferentParameters<SHA1Block>();
+ testSetAndGetWithDifferentParameters<SHA256Block>();
+}
-TEST(SCRAMSHA1Cache, testSetAndReset) {
- SCRAMSHA1ClientCache cache;
- StringData saltStr("saltsaltsaltsalt");
- std::vector<std::uint8_t> salt(saltStr.begin(), saltStr.end());
+template <typename HashBlock>
+void testSetAndReset() {
+ SCRAMClientCache<HashBlock> cache;
+ const auto salt = scram::Presecrets<HashBlock>::generateSecureRandomSalt();
HostAndPort host("localhost:27017");
- scram::SHA1Secrets secret(scram::SHA1Presecrets("aaa", salt, 10000));
- cache.setCachedSecrets(host, scram::SHA1Presecrets("aaa", salt, 10000), secret);
- scram::SHA1Secrets newSecret(scram::SHA1Presecrets("aab", salt, 10000));
- cache.setCachedSecrets(host, scram::SHA1Presecrets("aab", salt, 10000), newSecret);
+ const auto presecretsA = scram::Presecrets<HashBlock>("aaa", salt, 10000);
+ const auto secretsA = scram::Secrets<HashBlock>(presecretsA);
+ cache.setCachedSecrets(host, presecretsA, secretsA);
+ const auto presecretsB = scram::Presecrets<HashBlock>("aab", salt, 10000);
+ const auto secretsB = scram::Secrets<HashBlock>(presecretsB);
+ cache.setCachedSecrets(host, presecretsB, secretsB);
- ASSERT_FALSE(cache.getCachedSecrets(host, scram::SHA1Presecrets("aaa", salt, 10000)));
- auto cachedSecret = cache.getCachedSecrets(host, scram::SHA1Presecrets("aab", salt, 10000));
+ ASSERT_FALSE(cache.getCachedSecrets(host, presecretsA));
+ const auto cachedSecret = cache.getCachedSecrets(host, presecretsB);
ASSERT_TRUE(cachedSecret);
- ASSERT_TRUE(newSecret.clientKey() == cachedSecret.clientKey());
- ASSERT_TRUE(newSecret.serverKey() == cachedSecret.serverKey());
- ASSERT_TRUE(newSecret.storedKey() == cachedSecret.storedKey());
+ ASSERT_TRUE(secretsB.clientKey() == cachedSecret.clientKey());
+ ASSERT_TRUE(secretsB.serverKey() == cachedSecret.serverKey());
+ ASSERT_TRUE(secretsB.storedKey() == cachedSecret.storedKey());
+}
+
+TEST(SCRAMCache, testSetAndReset) {
+ testSetAndReset<SHA1Block>();
+ testSetAndReset<SHA256Block>();
}
+} // namespace
} // namespace mongo
diff --git a/src/mongo/db/auth/security_key.cpp b/src/mongo/db/auth/security_key.cpp
index 04c46e3e4dd..3e14d65c00e 100644
--- a/src/mongo/db/auth/security_key.cpp
+++ b/src/mongo/db/auth/security_key.cpp
@@ -39,6 +39,7 @@
#include "mongo/base/status_with.h"
#include "mongo/client/sasl_client_authenticate.h"
#include "mongo/crypto/mechanism_scram.h"
+#include "mongo/crypto/sha1_block.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
@@ -76,7 +77,7 @@ bool setUpSecurityKey(const string& filename) {
const auto password =
mongo::createPasswordDigest(internalSecurity.user->getName().getUser().toString(), str);
- auto creds = scram::SHA1Secrets::generateCredentials(
+ auto creds = scram::Secrets<SHA1Block>::generateCredentials(
password, saslGlobalParams.scramSHA1IterationCount.load());
credentials.scram_sha1.iterationCount = creds[scram::kIterationCountFieldName].Int();
credentials.scram_sha1.salt = creds[scram::kSaltFieldName].String();
diff --git a/src/mongo/db/logical_session_id_test.cpp b/src/mongo/db/logical_session_id_test.cpp
index c2e0bf17105..f80d4eca0f4 100644
--- a/src/mongo/db/logical_session_id_test.cpp
+++ b/src/mongo/db/logical_session_id_test.cpp
@@ -33,6 +33,8 @@
#include "mongo/db/logical_session_id.h"
#include "mongo/crypto/mechanism_scram.h"
+#include "mongo/crypto/sha1_block.h"
+#include "mongo/crypto/sha256_block.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
@@ -105,7 +107,7 @@ public:
}
User* addSimpleUser(UserName un) {
- const auto creds = BSON("SCRAM-SHA-1" << scram::SHA1Secrets::generateCredentials(
+ const auto creds = BSON("SCRAM-SHA-1" << scram::Secrets<SHA1Block>::generateCredentials(
"a", saslGlobalParams.scramSHA1IterationCount.load()));
ASSERT_OK(managerState->insertPrivilegeDocument(
_opCtx.get(),
@@ -120,8 +122,8 @@ public:
}
User* addClusterUser(UserName un) {
- const auto creds = BSON("SCRAM-SHA-1" << scram::SHA1Secrets::generateCredentials(
- "a", saslGlobalParams.scramSHA1IterationCount.load()));
+ const auto creds = BSON("SCRAM-SHA-256" << scram::Secrets<SHA256Block>::generateCredentials(
+ "a", saslGlobalParams.scramSHA256IterationCount.load()));
ASSERT_OK(managerState->insertPrivilegeDocument(
_opCtx.get(),
BSON("user" << un.getUser() << "db" << un.getDB() << "credentials" << creds << "roles"