summaryrefslogtreecommitdiff
path: root/src/mongo/crypto/mechanism_scram.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/crypto/mechanism_scram.h')
-rw-r--r--src/mongo/crypto/mechanism_scram.h64
1 files changed, 49 insertions, 15 deletions
diff --git a/src/mongo/crypto/mechanism_scram.h b/src/mongo/crypto/mechanism_scram.h
index 3ffe382609c..75b4f52f1e5 100644
--- a/src/mongo/crypto/mechanism_scram.h
+++ b/src/mongo/crypto/mechanism_scram.h
@@ -140,6 +140,47 @@ template <typename T>
bool operator!=(const Presecrets<T>& lhs, const Presecrets<T>& rhs) {
return !(lhs == rhs);
}
+template <typename HashBlock>
+struct SecretsHolder {
+ HashBlock clientKey;
+ HashBlock storedKey;
+ HashBlock serverKey;
+};
+
+template <typename HashBlock>
+class LockedSecretsPolicy {
+public:
+ LockedSecretsPolicy() = default;
+
+ const SecretsHolder<HashBlock>* operator->() const {
+ return &(*_holder);
+ }
+ SecretsHolder<HashBlock>* operator->() {
+ return &(*_holder);
+ }
+
+private:
+ using SecureSecrets = SecureAllocatorAuthDomain::SecureHandle<SecretsHolder<HashBlock>>;
+
+ SecureSecrets _holder;
+};
+
+template <typename HashBlock>
+class UnlockedSecretsPolicy {
+public:
+ UnlockedSecretsPolicy() = default;
+
+ const SecretsHolder<HashBlock>* operator->() const {
+ return &_holder;
+ }
+
+ SecretsHolder<HashBlock>* operator->() {
+ return &_holder;
+ }
+
+private:
+ SecretsHolder<HashBlock> _holder;
+};
/* Stores all of the keys, generated from a password, needed for a client or server to perform a
* SCRAM handshake.
@@ -147,21 +188,13 @@ bool operator!=(const Presecrets<T>& lhs, const Presecrets<T>& rhs) {
* May be unpopulated. SCRAMSecrets created via the default constructor are unpopulated.
* The behavior is undefined if the accessors are called when unpopulated.
*/
-template <typename HashBlock>
+template <typename HashBlock, template <typename> class MemoryPolicy = LockedSecretsPolicy>
class Secrets {
-private:
- struct SecretsHolder {
- HashBlock clientKey;
- HashBlock storedKey;
- HashBlock serverKey;
- };
- using SecureSecrets = SecureAllocatorAuthDomain::SecureHandle<SecretsHolder>;
-
public:
Secrets() = default;
Secrets(StringData client, StringData stored, StringData server)
- : _ptr(std::make_shared<SecureSecrets>()) {
+ : _ptr(std::make_shared<MemoryPolicy<HashBlock>>()) {
if (!client.empty()) {
(*_ptr)->clientKey = uassertStatusOK(HashBlock::fromBuffer(
reinterpret_cast<const unsigned char*>(client.rawData()), client.size()));
@@ -172,13 +205,13 @@ public:
reinterpret_cast<const unsigned char*>(server.rawData()), stored.size()));
}
- Secrets(const HashBlock& saltedPassword) : _ptr(std::make_shared<SecureSecrets>()) {
+ Secrets(const HashBlock& saltedPassword) : _ptr(std::make_shared<MemoryPolicy<HashBlock>>()) {
// ClientKey := HMAC(saltedPassword, "Client Key")
- (*_ptr)->clientKey = HashBlock::computeHmac(
+ (*_ptr)->clientKey = (HashBlock::computeHmac(
saltedPassword.data(),
saltedPassword.size(),
reinterpret_cast<const unsigned char*>(kClientKeyConst.rawData()),
- kClientKeyConst.size());
+ kClientKeyConst.size()));
// StoredKey := H(clientKey)
(*_ptr)->storedKey = HashBlock::computeHash(clientKey().data(), clientKey().size());
@@ -250,7 +283,8 @@ public:
static BSONObj generateCredentials(std::string password, int iterationCount) {
auto salt = Presecrets<HashBlock>::generateSecureRandomSalt();
- Secrets<HashBlock> secrets(Presecrets<HashBlock>(password, salt, iterationCount));
+ Secrets<HashBlock, MemoryPolicy> secrets(
+ Presecrets<HashBlock>(password, salt, iterationCount));
const auto encodedSalt = base64::encode(reinterpret_cast<char*>(salt.data()), salt.size());
return BSON(kIterationCountFieldName << iterationCount << kSaltFieldName << encodedSalt
<< kStoredKeyFieldName
@@ -283,7 +317,7 @@ public:
}
private:
- std::shared_ptr<SecureSecrets> _ptr;
+ std::shared_ptr<MemoryPolicy<HashBlock>> _ptr;
};
} // namespace scram