summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSara Golemon <sara.golemon@mongodb.com>2022-12-08 10:06:45 -0600
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-12-20 00:04:57 +0000
commit61f4394d50b28e43267f335e1acf1360cb041efd (patch)
treeb522ba2f8455da5726cb2ae45c1efa762a824815 /src
parent3b4da58b3d7b9ecae207fad1791b9e7f9a9a5a7d (diff)
downloadmongo-61f4394d50b28e43267f335e1acf1360cb041efd.tar.gz
SERVER-70702 Improve JWKManager APIs
Diffstat (limited to 'src')
-rw-r--r--src/mongo/base/error_codes.yml2
-rw-r--r--src/mongo/crypto/SConscript6
-rw-r--r--src/mongo/crypto/jwk_manager.cpp22
-rw-r--r--src/mongo/crypto/jwk_manager.h25
-rw-r--r--src/mongo/crypto/jwt_test.cpp2
5 files changed, 38 insertions, 19 deletions
diff --git a/src/mongo/base/error_codes.yml b/src/mongo/base/error_codes.yml
index e1054f1b471..cec467176fb 100644
--- a/src/mongo/base/error_codes.yml
+++ b/src/mongo/base/error_codes.yml
@@ -511,8 +511,8 @@ error_codes:
- {code: 389, name: LibmongocryptError}
- {code: 390, name: InvalidSignature}
-
- {code: 391, name: ReauthenticationRequired}
+ - {code: 392, name: InvalidJWT}
# Error codes 4000-8999 are reserved.
# Non-sequential error codes for compatibility only)
diff --git a/src/mongo/crypto/SConscript b/src/mongo/crypto/SConscript
index 0bcf8da8b0a..3e1211051b8 100644
--- a/src/mongo/crypto/SConscript
+++ b/src/mongo/crypto/SConscript
@@ -152,6 +152,7 @@ env.CppUnitTest(
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/base/secure_allocator',
'$BUILD_DIR/mongo/shell/kms_idl',
+ '$BUILD_DIR/mongo/util/net/http_client_impl',
'$BUILD_DIR/mongo/util/net/openssl_init' if ssl_provider == 'openssl' else [],
'aead_encryption',
'encrypted_field_config',
@@ -171,11 +172,12 @@ env.Library(
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
- '$BUILD_DIR/mongo/client/sasl_client',
- '$BUILD_DIR/mongo/util/net/http_client_impl',
],
LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/client/sasl_client',
+ '$BUILD_DIR/mongo/db/commands/test_commands_enabled',
'$BUILD_DIR/mongo/idl/idl_parser',
+ '$BUILD_DIR/mongo/util/net/http_client_impl',
],
)
diff --git a/src/mongo/crypto/jwk_manager.cpp b/src/mongo/crypto/jwk_manager.cpp
index 71e2619f33e..29ee470517d 100644
--- a/src/mongo/crypto/jwk_manager.cpp
+++ b/src/mongo/crypto/jwk_manager.cpp
@@ -32,6 +32,7 @@
#include "mongo/bson/json.h"
#include "mongo/crypto/jws_validator.h"
#include "mongo/crypto/jwt_types_gen.h"
+#include "mongo/db/commands/test_commands_enabled.h"
#include "mongo/logv2/log.h"
#include "mongo/util/base64.h"
#include "mongo/util/net/http_client.h"
@@ -58,8 +59,9 @@ StringData reduceInt(StringData value) {
JWKManager::JWKManager(StringData source) : _keyURI(source) {
auto httpClient = HttpClient::createWithoutConnectionPool();
httpClient->setHeaders({"Accept: */*"});
+ httpClient->allowInsecureHTTP(getTestCommandsEnabled());
- DataBuilder getJWKs = httpClient->get(source);
+ auto getJWKs = httpClient->get(source);
ConstDataRange cdr = getJWKs.getCursor();
StringData str;
@@ -73,11 +75,11 @@ JWKManager::JWKManager(BSONObj keys) {
_setAndValidateKeys(keys);
}
-const BSONObj& JWKManager::getKey(StringData keyId) const {
+StatusWith<BSONObj> JWKManager::getKey(StringData keyId) const {
auto it = _keyMaterial.find(keyId.toString());
- uassert(ErrorCodes::NoSuchKey,
- str::stream() << "Unknown key '" << keyId << "'",
- it != _keyMaterial.end());
+ if (it == _keyMaterial.end()) {
+ return {ErrorCodes::NoSuchKey, str::stream() << "Unknown key '" << keyId << "'"};
+ }
return it->second;
}
@@ -132,7 +134,17 @@ void JWKManager::_setAndValidateKeys(const BSONObj& keys) {
SharedValidator shValidator = std::move(swValidator.getValue());
_validators->insert({keyId, shValidator});
+ LOGV2_DEBUG(7070202, 3, "Loaded JWK key", "kid"_attr = keyId, "typ"_attr = JWK.getType());
}
}
+std::vector<std::string> JWKManager::getKeyIds() const {
+ std::vector<std::string> ids;
+ std::transform(_validators->cbegin(),
+ _validators->cend(),
+ std::back_inserter(ids),
+ [](const auto& it) { return it.first; });
+ return ids;
+}
+
} // namespace mongo::crypto
diff --git a/src/mongo/crypto/jwk_manager.h b/src/mongo/crypto/jwk_manager.h
index 47aa8fc753a..bba9a276388 100644
--- a/src/mongo/crypto/jwk_manager.h
+++ b/src/mongo/crypto/jwk_manager.h
@@ -44,22 +44,22 @@ public:
using SharedValidator = std::shared_ptr<JWSValidator>;
/**
- Fetch a JWKS file from the specified URL, parse them as keys,
- and instantiate JWSValidator instances.
- */
+ * Fetch a JWKS file from the specified URL, parse them as keys,
+ * and instantiate JWSValidator instances.
+ */
explicit JWKManager(StringData source);
/**
- Parse a BSONObj array of keys, and instantiate JWSValidator instances.
- This was added for testing purposes.
- */
+ * Parse a BSONObj array of keys, and instantiate JWSValidator instances.
+ * This was added for testing purposes.
+ */
explicit JWKManager(BSONObj keys);
/**
- Given a unique keyId it will return the matching JWK.
- If no key is found for the given keyId, a uassert will be thrown.
- */
- const BSONObj& getKey(StringData keyId) const;
+ * Given a unique keyId it will return the matching JWK.
+ * If no key is found for the given keyId, a
+ */
+ StatusWith<BSONObj> getKey(StringData keyId) const;
/**
* Fetch a specific JWSValidator from the JWKManager by keyId.
@@ -74,6 +74,11 @@ public:
return _validators->size();
}
+ /**
+ * Get the list of keyIds held by this key manager.
+ */
+ std::vector<std::string> getKeyIds() const;
+
private:
void _setAndValidateKeys(const BSONObj& keys);
diff --git a/src/mongo/crypto/jwt_test.cpp b/src/mongo/crypto/jwt_test.cpp
index 41e8059bbfe..b43b929b08a 100644
--- a/src/mongo/crypto/jwt_test.cpp
+++ b/src/mongo/crypto/jwt_test.cpp
@@ -54,7 +54,7 @@ TEST(JWKManager, parseJWKSetBasicFromSource) {
JWKManager manager(source);
for (const auto& key : data["keys"_sd].Obj()) {
- auto keyFromKid = manager.getKey(key["kid"_sd].str());
+ auto keyFromKid = uassertStatusOK(manager.getKey(key["kid"_sd].str()));
ASSERT_BSONOBJ_EQ(key.Obj(), keyFromKid);
}