-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add client cert manager for delegated credentials
Summary: As title says, since we added a client cert manager for regular certs we should have one for DCs as well. Reviewed By: knekritz Differential Revision: D56521549 fbshipit-source-id: 839dfe16f662dc2b173765774dd944129375e6ee
- Loading branch information
1 parent
6fa91bd
commit f6507dd
Showing
6 changed files
with
272 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
fizz/extensions/delegatedcred/DelegatedCredentialClientCertManager.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (c) 2019-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
#include <fizz/extensions/delegatedcred/DelegatedCredentialClientCertManager.h> | ||
#include <fizz/extensions/delegatedcred/Types.h> | ||
|
||
namespace fizz { | ||
namespace extensions { | ||
|
||
fizz::client::CertManager::CertMatch | ||
DelegatedCredentialClientCertManager::getCert( | ||
const folly::Optional<std::string>& sni, | ||
const std::vector<SignatureScheme>& supportedSigSchemes, | ||
const std::vector<SignatureScheme>& peerSigSchemes, | ||
const std::vector<Extension>& peerExtensions) const { | ||
auto credential = getExtension<DelegatedCredentialSupport>(peerExtensions); | ||
|
||
if (credential) { | ||
auto dcRes = dcMgr_.getCert( | ||
sni, | ||
supportedSigSchemes, | ||
credential->supported_signature_algorithms, | ||
peerExtensions); | ||
if (dcRes) { | ||
return dcRes; | ||
} | ||
} | ||
return mainMgr_.getCert( | ||
sni, supportedSigSchemes, peerSigSchemes, peerExtensions); | ||
} | ||
|
||
void DelegatedCredentialClientCertManager::addCert( | ||
std::shared_ptr<SelfCert> cert, | ||
bool overrideExistingEntry) { | ||
VLOG(8) << "Adding undelegated cert"; | ||
mainMgr_.addCert(std::move(cert), overrideExistingEntry); | ||
} | ||
|
||
void DelegatedCredentialClientCertManager::addDelegatedCredential( | ||
std::shared_ptr<SelfCert> cert, | ||
bool overrideExistingEntry) { | ||
VLOG(8) << "Adding delegated credential"; | ||
dcMgr_.addCert(std::move(cert), overrideExistingEntry); | ||
} | ||
} // namespace extensions | ||
} // namespace fizz |
50 changes: 50 additions & 0 deletions
50
fizz/extensions/delegatedcred/DelegatedCredentialClientCertManager.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (c) 2019-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
#pragma once | ||
#include <fizz/client/CertManager.h> | ||
|
||
namespace fizz { | ||
namespace extensions { | ||
|
||
// CertManager implementation that maintains two sets of certs, one with | ||
// delegated credential extensions and one without. Certs are selected based | ||
// on the usual rules with the addition of the split between delegated and | ||
// non-delegated certs. | ||
class DelegatedCredentialClientCertManager : public fizz::client::CertManager { | ||
public: | ||
/** | ||
* Select a cert given the servers sig schemes, our own supported sig schemes | ||
* and peer extensions. The sni value is ignored. Note this implementation | ||
* makes use of the peer extensions to pick a delegated credential or a x509 | ||
* cert | ||
*/ | ||
CertMatch getCert( | ||
const folly::Optional<std::string>& sni, | ||
const std::vector<SignatureScheme>& supportedSigSchemes, | ||
const std::vector<SignatureScheme>& peerSigSchemes, | ||
const std::vector<Extension>& peerExtensions) const override; | ||
|
||
void addCert( | ||
std::shared_ptr<SelfCert> cert, | ||
bool overrideExistingEntry = true) override; | ||
|
||
/* | ||
* It is the callers responsibility to call this with an actual delegated | ||
* cred. The override flag here has the same meaning as above, if there is | ||
* already a dc for the signature scheme we will replace the existing entry. | ||
*/ | ||
void addDelegatedCredential( | ||
std::shared_ptr<SelfCert> cert, | ||
bool overrideExistingEntry = true); | ||
|
||
protected: | ||
client::CertManager mainMgr_; | ||
client::CertManager dcMgr_; | ||
}; | ||
} // namespace extensions | ||
} // namespace fizz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 141 additions & 0 deletions
141
fizz/extensions/delegatedcred/test/DelegatedCredentialClientCertManagerTest.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
/* | ||
* Copyright (c) 2018-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#include <folly/portability/GMock.h> | ||
#include <folly/portability/GTest.h> | ||
|
||
#include <fizz/extensions/delegatedcred/DelegatedCredentialClientCertManager.h> | ||
#include <fizz/extensions/delegatedcred/Types.h> | ||
|
||
#include <fizz/protocol/test/Mocks.h> | ||
|
||
using namespace fizz::test; | ||
|
||
namespace fizz { | ||
namespace extensions { | ||
namespace test { | ||
|
||
static const std::vector<SignatureScheme> kRsa{SignatureScheme::rsa_pss_sha256}; | ||
|
||
std::vector<Extension> getDelegatedExt( | ||
const std::vector<SignatureScheme>& schemes = kRsa) { | ||
std::vector<Extension> exts; | ||
DelegatedCredentialSupport supp; | ||
supp.supported_signature_algorithms = schemes; | ||
exts.push_back(encodeExtension(supp)); | ||
return exts; | ||
} | ||
|
||
class DelegatedClientCertManagerTest : public Test { | ||
protected: | ||
std::shared_ptr<MockSelfCert> getCert(std::vector<SignatureScheme> schemes) { | ||
auto cert = std::make_shared<MockSelfCert>(); | ||
ON_CALL(*cert, getSigSchemes()).WillByDefault(Return(schemes)); | ||
return cert; | ||
} | ||
DelegatedCredentialClientCertManager manager_; | ||
}; | ||
|
||
TEST_F(DelegatedClientCertManagerTest, TestNoCert) { | ||
auto res = manager_.getCert(folly::none, kRsa, kRsa, {}); | ||
EXPECT_FALSE(res.hasValue()); | ||
} | ||
|
||
TEST_F(DelegatedClientCertManagerTest, TestBasicMatch) { | ||
// Only non dc cert must be returned | ||
auto cert = getCert(kRsa); | ||
manager_.addCert(cert); | ||
auto res = manager_.getCert(folly::none, kRsa, kRsa, {}); | ||
EXPECT_EQ(res->cert, cert); | ||
} | ||
|
||
TEST_F(DelegatedClientCertManagerTest, TestBasicMatchNoExt) { | ||
auto cert1 = getCert(kRsa); | ||
auto cert2 = getCert(kRsa); | ||
manager_.addCert(cert1); | ||
// Let's just pretend here the impl of the self cert doesnt really matter | ||
manager_.addDelegatedCredential(cert2); | ||
{ | ||
auto res = manager_.getCert(folly::none, kRsa, kRsa, {}); | ||
EXPECT_EQ(res->cert, cert1); | ||
} | ||
{ | ||
auto res = manager_.getCert(folly::none, kRsa, kRsa, getDelegatedExt()); | ||
EXPECT_EQ(res->cert, cert2); | ||
} | ||
} | ||
|
||
TEST_F(DelegatedClientCertManagerTest, TestSigSchemes) { | ||
auto cert = getCert({SignatureScheme::rsa_pss_sha256}); | ||
manager_.addCert(cert); | ||
auto dcCert = getCert({SignatureScheme::rsa_pss_sha512}); | ||
manager_.addDelegatedCredential(dcCert); | ||
|
||
{ | ||
auto res = manager_.getCert( | ||
folly::none, | ||
{SignatureScheme::rsa_pss_sha256, SignatureScheme::rsa_pss_sha512}, | ||
{SignatureScheme::rsa_pss_sha256}, | ||
{}); | ||
// Only non dc cert supports sig schemes | ||
EXPECT_EQ(res->cert, cert); | ||
EXPECT_EQ(res->scheme, SignatureScheme::rsa_pss_sha256); | ||
} | ||
{ | ||
auto res = manager_.getCert( | ||
folly::none, | ||
{SignatureScheme::rsa_pss_sha256, SignatureScheme::rsa_pss_sha512}, | ||
{SignatureScheme::rsa_pss_sha256}, | ||
getDelegatedExt()); | ||
// Only non dc cert supports sig schemes | ||
EXPECT_EQ(res->cert, cert); | ||
EXPECT_EQ(res->scheme, SignatureScheme::rsa_pss_sha256); | ||
} | ||
|
||
{ | ||
auto res = manager_.getCert( | ||
folly::none, | ||
{SignatureScheme::rsa_pss_sha512, SignatureScheme::rsa_pss_sha256}, | ||
{SignatureScheme::rsa_pss_sha512}, | ||
{}); | ||
// Dc doesn't match due to no ext | ||
EXPECT_FALSE(res.hasValue()); | ||
} | ||
{ | ||
auto res = manager_.getCert( | ||
folly::none, | ||
{SignatureScheme::rsa_pss_sha512, SignatureScheme::rsa_pss_sha256}, | ||
{SignatureScheme::rsa_pss_sha512}, | ||
getDelegatedExt()); | ||
// Dc still doesn't match since the ext doesn't support 512 | ||
EXPECT_FALSE(res.hasValue()); | ||
} | ||
{ | ||
auto res = manager_.getCert( | ||
folly::none, | ||
{SignatureScheme::rsa_pss_sha512, SignatureScheme::rsa_pss_sha256}, | ||
{SignatureScheme::rsa_pss_sha512}, | ||
getDelegatedExt({SignatureScheme::rsa_pss_sha512})); | ||
EXPECT_EQ(res->cert, dcCert); | ||
EXPECT_EQ(res->scheme, SignatureScheme::rsa_pss_sha512); | ||
} | ||
} | ||
|
||
TEST_F(DelegatedClientCertManagerTest, TestNoSigSchemeMatch) { | ||
auto cert = getCert({SignatureScheme::rsa_pss_sha256}); | ||
manager_.addCert(cert); | ||
auto res = manager_.getCert( | ||
folly::none, | ||
{SignatureScheme::rsa_pss_sha256}, | ||
{SignatureScheme::rsa_pss_sha512}, | ||
{}); | ||
EXPECT_FALSE(res); | ||
} | ||
} // namespace test | ||
} // namespace extensions | ||
} // namespace fizz |