summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/auth/sasl_plain_server_conversation.cpp19
-rw-r--r--src/mongo/db/auth/sasl_scramsha1_server_conversation.cpp53
-rw-r--r--src/mongo/db/auth/sasl_scramsha1_test.cpp78
3 files changed, 94 insertions, 56 deletions
diff --git a/src/mongo/db/auth/sasl_plain_server_conversation.cpp b/src/mongo/db/auth/sasl_plain_server_conversation.cpp
index 31945f6e9a6..cf7f2cdeaa5 100644
--- a/src/mongo/db/auth/sasl_plain_server_conversation.cpp
+++ b/src/mongo/db/auth/sasl_plain_server_conversation.cpp
@@ -28,7 +28,6 @@
#include "mongo/db/auth/sasl_plain_server_conversation.h"
-#include "mongo/base/secure_allocator.h"
#include "mongo/crypto/mechanism_scram.h"
#include "mongo/db/auth/sasl_authentication_session.h"
#include "mongo/util/base64.h"
@@ -115,18 +114,16 @@ StatusWith<bool> SaslPLAINServerConversation::step(StringData inputData, std::st
}
} else {
// Handle schemaVersion28SCRAM (SCRAM only mode)
- unsigned char storedKey[scram::hashSize];
- unsigned char serverKey[scram::hashSize];
-
- scram::generateSecrets(
+ std::string decodedSalt = base64::decode(creds.scram.salt);
+ scram::SCRAMSecrets secrets = scram::generateSecrets(scram::SCRAMPresecrets(
authDigest,
- reinterpret_cast<const unsigned char*>(base64::decode(creds.scram.salt).c_str()),
- 16,
- creds.scram.iterationCount,
- storedKey,
- serverKey);
+ std::vector<std::uint8_t>(reinterpret_cast<const std::uint8_t*>(decodedSalt.c_str()),
+ reinterpret_cast<const std::uint8_t*>(decodedSalt.c_str()) +
+ 16),
+ creds.scram.iterationCount));
if (creds.scram.storedKey !=
- base64::encode(reinterpret_cast<const char*>(storedKey), scram::hashSize)) {
+ base64::encode(reinterpret_cast<const char*>(secrets.storedKey->data()),
+ secrets.storedKey->size())) {
return StatusWith<bool>(ErrorCodes::AuthenticationFailed,
mongoutils::str::stream() << "Incorrect user name or password");
}
diff --git a/src/mongo/db/auth/sasl_scramsha1_server_conversation.cpp b/src/mongo/db/auth/sasl_scramsha1_server_conversation.cpp
index ed812ddb27f..a98dc6d7dcc 100644
--- a/src/mongo/db/auth/sasl_scramsha1_server_conversation.cpp
+++ b/src/mongo/db/auth/sasl_scramsha1_server_conversation.cpp
@@ -281,60 +281,23 @@ StatusWith<bool> SaslSCRAMSHA1ServerConversation::_secondStep(const std::vector<
// ClientKey := ClientSignature XOR ClientProof
// ServerSignature := HMAC(ServerKey, AuthMessage)
- unsigned int hashLen = 0;
- unsigned char clientSignature[scram::hashSize];
-
- std::string decodedStoredKey = base64::decode(_creds.scram.storedKey);
- // ClientSignature := HMAC(StoredKey, AuthMessage)
- fassert(18662,
- crypto::hmacSha1(reinterpret_cast<const unsigned char*>(decodedStoredKey.c_str()),
- scram::hashSize,
- reinterpret_cast<const unsigned char*>(_authMessage.c_str()),
- _authMessage.size(),
- clientSignature,
- &hashLen));
-
- fassert(18658, hashLen == scram::hashSize);
-
- try {
- clientProof = base64::decode(clientProof);
- } catch (const DBException& ex) {
- return StatusWith<bool>(ex.toStatus());
- }
- const unsigned char* decodedClientProof =
- reinterpret_cast<const unsigned char*>(clientProof.c_str());
-
- // ClientKey := ClientSignature XOR ClientProof
- unsigned char clientKey[scram::hashSize];
- for (size_t i = 0; i < scram::hashSize; i++) {
- clientKey[i] = clientSignature[i] ^ decodedClientProof[i];
- }
-
- // StoredKey := H(ClientKey)
- unsigned char computedStoredKey[scram::hashSize];
- fassert(18659, crypto::sha1(clientKey, scram::hashSize, computedStoredKey));
-
- if (memcmp(decodedStoredKey.c_str(), computedStoredKey, scram::hashSize) != 0) {
+ if (!scram::verifyClientProof(
+ base64::decode(clientProof), base64::decode(_creds.scram.storedKey), _authMessage)) {
return StatusWith<bool>(ErrorCodes::AuthenticationFailed,
mongoutils::str::stream()
<< "SCRAM-SHA-1 authentication failed, storedKey mismatch");
}
// ServerSignature := HMAC(ServerKey, AuthMessage)
- unsigned char serverSignature[scram::hashSize];
std::string decodedServerKey = base64::decode(_creds.scram.serverKey);
- fassert(18660,
- crypto::hmacSha1(reinterpret_cast<const unsigned char*>(decodedServerKey.c_str()),
- scram::hashSize,
- reinterpret_cast<const unsigned char*>(_authMessage.c_str()),
- _authMessage.size(),
- serverSignature,
- &hashLen));
-
- fassert(18661, hashLen == scram::hashSize);
+ SHA1Hash serverSignature =
+ crypto::hmacSha1(reinterpret_cast<const unsigned char*>(decodedServerKey.c_str()),
+ decodedServerKey.size(),
+ reinterpret_cast<const unsigned char*>(_authMessage.c_str()),
+ _authMessage.size());
StringBuilder sb;
- sb << "v=" << base64::encode(reinterpret_cast<char*>(serverSignature), scram::hashSize);
+ sb << "v=" << scram::hashToBase64(serverSignature);
*outputData = sb.str();
return StatusWith<bool>(false);
diff --git a/src/mongo/db/auth/sasl_scramsha1_test.cpp b/src/mongo/db/auth/sasl_scramsha1_test.cpp
index 72b817bc95d..b7a214af68e 100644
--- a/src/mongo/db/auth/sasl_scramsha1_test.cpp
+++ b/src/mongo/db/auth/sasl_scramsha1_test.cpp
@@ -29,6 +29,7 @@
#include "mongo/platform/basic.h"
#include "mongo/client/native_sasl_client_session.h"
+#include "mongo/client/scram_sha1_client_cache.h"
#include "mongo/crypto/mechanism_scram.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authz_manager_external_state_mock.h"
@@ -246,6 +247,8 @@ protected:
saslClientSession->setParameter(NativeSaslClientSession::parameterServiceName, "mongodb");
saslClientSession->setParameter(NativeSaslClientSession::parameterServiceHostname,
"MockServer.test");
+ saslClientSession->setParameter(NativeSaslClientSession::parameterServiceHostAndPort,
+ "MockServer.test:27017");
}
};
@@ -435,4 +438,79 @@ TEST_F(SCRAMSHA1Fixture, testMONGODBCR) {
ASSERT_EQ(goalState, runSteps(saslServerSession.get(), saslClientSession.get()));
}
+TEST(SCRAMSHA1Cache, testGetFromEmptyCache) {
+ SCRAMSHA1ClientCache cache;
+ std::string saltStr("saltsaltsaltsalt");
+ std::vector<std::uint8_t> salt(saltStr.begin(), saltStr.end());
+ HostAndPort host("localhost:27017");
+
+ ASSERT_FALSE(cache.getCachedSecrets(host, scram::SCRAMPresecrets("aaa", salt, 10000)));
+}
+
+
+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());
+ HostAndPort host("localhost:27017");
+
+ auto secret = scram::generateSecrets(scram::SCRAMPresecrets("aaa", salt, 10000));
+ cache.setCachedSecrets(host, scram::SCRAMPresecrets("aaa", salt, 10000), secret);
+ auto cachedSecret = cache.getCachedSecrets(host, scram::SCRAMPresecrets("aaa", salt, 10000));
+ ASSERT_TRUE(cachedSecret);
+ ASSERT_TRUE(std::equal(
+ secret.clientKey->begin(), secret.clientKey->end(), cachedSecret->clientKey->begin()));
+ ASSERT_TRUE(std::equal(
+ secret.serverKey->begin(), secret.serverKey->end(), cachedSecret->serverKey->begin()));
+ ASSERT_TRUE(std::equal(
+ secret.storedKey->begin(), secret.storedKey->end(), cachedSecret->storedKey->begin()));
+}
+
+
+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());
+ HostAndPort host("localhost:27017");
+
+ auto secret = scram::generateSecrets(scram::SCRAMPresecrets("aaa", salt, 10000));
+ cache.setCachedSecrets(host, scram::SCRAMPresecrets("aaa", salt, 10000), secret);
+
+ ASSERT_FALSE(cache.getCachedSecrets(HostAndPort("localhost:27018"),
+ scram::SCRAMPresecrets("aaa", salt, 10000)));
+ ASSERT_FALSE(cache.getCachedSecrets(host, scram::SCRAMPresecrets("aab", salt, 10000)));
+ ASSERT_FALSE(cache.getCachedSecrets(host, scram::SCRAMPresecrets("aaa", badSalt, 10000)));
+ ASSERT_FALSE(cache.getCachedSecrets(host, scram::SCRAMPresecrets("aaa", salt, 10001)));
+}
+
+
+TEST(SCRAMSHA1Cache, testSetAndReset) {
+ SCRAMSHA1ClientCache cache;
+ StringData saltStr("saltsaltsaltsalt");
+ std::vector<std::uint8_t> salt(saltStr.begin(), saltStr.end());
+ HostAndPort host("localhost:27017");
+
+ auto secret = scram::generateSecrets(scram::SCRAMPresecrets("aaa", salt, 10000));
+ cache.setCachedSecrets(host, scram::SCRAMPresecrets("aaa", salt, 10000), secret);
+ auto newSecret = scram::generateSecrets(scram::SCRAMPresecrets("aab", salt, 10000));
+ cache.setCachedSecrets(host, scram::SCRAMPresecrets("aab", salt, 10000), newSecret);
+
+ ASSERT_FALSE(cache.getCachedSecrets(host, scram::SCRAMPresecrets("aaa", salt, 10000)));
+ auto cachedSecret = cache.getCachedSecrets(host, scram::SCRAMPresecrets("aab", salt, 10000));
+ ASSERT_TRUE(cachedSecret);
+ ASSERT_TRUE(std::equal(newSecret.clientKey->begin(),
+ newSecret.clientKey->end(),
+ cachedSecret->clientKey->begin()));
+ ASSERT_TRUE(std::equal(newSecret.serverKey->begin(),
+ newSecret.serverKey->end(),
+ cachedSecret->serverKey->begin()));
+ ASSERT_TRUE(std::equal(newSecret.storedKey->begin(),
+ newSecret.storedKey->end(),
+ cachedSecret->storedKey->begin()));
+}
+
} // namespace mongo