From 735a20f5cd6358b576c8dad660eca69043659e30 Mon Sep 17 00:00:00 2001 From: Zale Young Date: Fri, 12 Jan 2024 12:18:16 -0800 Subject: [PATCH] split out CertUtils and (Peer|Self)CertImpl from Certificate.h Summary: As part of the ongoing work to create a version of fizz that does depend on OpenSSL, this diff begins the refactors of `Certificate.h`. In this diff: - since `CertUtils`, `PeerCertImpl` and `SelfCertImpl` need to depend on OpenSSL, move them to different translation units than the `PeerCert` and `SelfCert` interfaces - rename `(Peer|Self)CertImpl` to `OpenSSL(Peer|Self)CertImpl` Main changes are in: - `protocol/Certificate.h` and `.cpp`, deleted `-inl.h` - `protocol/OpenSSLSelfCertImpl.h` and `-inl.h` (split from Certificate.h and renamed from SelfCertImpl) - `protocol/OpenSSLPeerCertImpl.h` and `-inl.h` (split from Certificate.h and renamed from PeerCertImpl) - `protocol/CertUtils.h`, `.cpp`and`-inl.h` (Split from Certificate.h) - `protocol/TARGETS` and `BUCK` - new targets `protocol:cert_utils`, `protocol:openssl_self_cert_impl`, `protocol:openssl_peer_cert_impl` - added new includes and targets to various dependencies. In the next diff, we'll use a compler flag `#if` guard the PeerCert and SelfCert interfaces to conditionally inherit from OpenSSL. This makes it so that the `Factory` interface and `ClientProtocol` do not need to depend on OpenSSL. We'll also create a buck config to conditionally select the openssl depednencies (and pass in the compiler flag). Reviewed By: mingtaoy Differential Revision: D51866623 fbshipit-source-id: d91cc4a39cabc2ac6879f16845ab8a7487d64c11 --- fizz/CMakeLists.txt | 1 + fizz/client/PskSerializationUtils.cpp | 1 + .../experimental/batcher/test/BatcherTest.cpp | 20 +- .../test/BatchSignaturePeerCertTest.cpp | 20 +- .../ktls/test/AsyncFizzBaseKTLSTest.cpp | 1 + .../test/BatchSignatureAsyncSelfCertTest.cpp | 12 +- .../DelegatedCredentialUtils.cpp | 1 + .../PeerDelegatedCredential-inl.h | 12 +- .../delegatedcred/PeerDelegatedCredential.h | 4 +- .../SelfDelegatedCredential-inl.h | 2 +- .../delegatedcred/SelfDelegatedCredential.h | 17 +- .../test/DelegatedCredentialFactoryTest.cpp | 5 +- .../test/SelfDelegatedCredentialTest.cpp | 7 +- .../exportedauth/ExportedAuthenticator.cpp | 1 + .../test/ExportedAuthenticatorTest.cpp | 7 +- .../javacrypto/JavaCryptoPeerCert.cpp | 1 + fizz/protocol/CertUtils-inl.h | 40 +++ fizz/protocol/CertUtils.cpp | 300 ++++++++++++++++++ fizz/protocol/CertUtils.h | 96 ++++++ fizz/protocol/Certificate-inl.h | 279 ---------------- fizz/protocol/Certificate.cpp | 279 ---------------- fizz/protocol/Certificate.h | 144 --------- fizz/protocol/DefaultFactory.h | 6 - fizz/protocol/OpenSSLFactory.cpp | 8 + fizz/protocol/OpenSSLFactory.h | 4 + fizz/protocol/OpenSSLPeerCertImpl-inl.h | 121 +++++++ fizz/protocol/OpenSSLPeerCertImpl.h | 41 +++ fizz/protocol/OpenSSLSelfCertImpl-inl.h | 156 +++++++++ fizz/protocol/OpenSSLSelfCertImpl.h | 62 ++++ fizz/protocol/test/CertTest.cpp | 44 ++- .../test/DefaultCertificateVerifierTest.cpp | 1 + fizz/protocol/test/Utilities.h | 4 +- fizz/server/TicketCodec.cpp | 1 + fizz/server/test/Utils.h | 4 +- fizz/test/BogoShim.cpp | 9 +- fizz/test/HandshakeTest.cpp | 9 +- fizz/test/HandshakeTest.h | 11 +- fizz/tool/FizzClientCommand.cpp | 1 + ...FizzGenerateDelegatedCredentialCommand.cpp | 1 + fizz/tool/FizzServerCommand.cpp | 4 +- 40 files changed, 949 insertions(+), 788 deletions(-) create mode 100644 fizz/protocol/CertUtils-inl.h create mode 100644 fizz/protocol/CertUtils.cpp create mode 100644 fizz/protocol/CertUtils.h delete mode 100644 fizz/protocol/Certificate-inl.h create mode 100644 fizz/protocol/OpenSSLPeerCertImpl-inl.h create mode 100644 fizz/protocol/OpenSSLPeerCertImpl.h create mode 100644 fizz/protocol/OpenSSLSelfCertImpl-inl.h create mode 100644 fizz/protocol/OpenSSLSelfCertImpl.h diff --git a/fizz/CMakeLists.txt b/fizz/CMakeLists.txt index 85ddfe42dc0..73fb275bad5 100644 --- a/fizz/CMakeLists.txt +++ b/fizz/CMakeLists.txt @@ -220,6 +220,7 @@ set(FIZZ_SOURCES protocol/Events.cpp protocol/KeyScheduler.cpp protocol/Certificate.cpp + protocol/CertUtils.cpp protocol/OpenSSLFactory.cpp protocol/Params.cpp protocol/clock/SystemClock.cpp diff --git a/fizz/client/PskSerializationUtils.cpp b/fizz/client/PskSerializationUtils.cpp index f2780d2159d..e813f5fac88 100644 --- a/fizz/client/PskSerializationUtils.cpp +++ b/fizz/client/PskSerializationUtils.cpp @@ -3,6 +3,7 @@ #include "fizz/client/PskSerializationUtils.h" #include +#include using namespace folly; diff --git a/fizz/experimental/batcher/test/BatcherTest.cpp b/fizz/experimental/batcher/test/BatcherTest.cpp index 62e9d93afed..3dac425b0ac 100644 --- a/fizz/experimental/batcher/test/BatcherTest.cpp +++ b/fizz/experimental/batcher/test/BatcherTest.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include @@ -56,7 +58,7 @@ TEST(BatchSignatureTest, TestSynchronizedBatcherSingleThread) { useMockRandom(); std::vector certs; certs.emplace_back(getCert(kRSACertificate)); - auto certificate = std::make_shared>( + auto certificate = std::make_shared>( getPrivateKey(kRSAKey), std::move(certs)); auto batcher = std::make_shared>( @@ -89,7 +91,7 @@ TEST(BatchSignatureTest, TestSynchronizedBatcherMultiThread) { size_t numMsgThreshold = 3; std::vector certs; certs.emplace_back(getCert(kRSACertificate)); - auto certificate = std::make_shared>( + auto certificate = std::make_shared>( getPrivateKey(kRSAKey), std::move(certs)); auto batcher = std::make_shared>( @@ -122,7 +124,7 @@ TEST(BatchSignatureTest, TestSynchronizedBatcherWithSelfCertP256) { size_t numMsgThreshold = 3; std::vector certs; certs.emplace_back(getCert(kP256Certificate)); - auto certificate = std::make_shared>( + auto certificate = std::make_shared>( getPrivateKey(kP256Key), std::move(certs)); auto batcher = std::make_shared>( numMsgThreshold, certificate, CertificateVerifyContext::Server); @@ -150,8 +152,8 @@ TEST(BatchSignatureTest, TestSynchronizedBatcherWithSelfCertP256) { } // verify - auto peerCert = - std::make_shared>(getCert(kP256Certificate)); + auto peerCert = std::make_shared>( + getCert(kP256Certificate)); BatchSignaturePeerCert batchPeerCert(peerCert); for (size_t i = 0; i < results.size(); i++) { batchPeerCert.verify( @@ -167,7 +169,7 @@ TEST(BatchSignatureTest, TestThreadLocalBatcher) { std::vector certs; certs.emplace_back(getCert(kRSACertificate)); - auto certificate = std::make_shared>( + auto certificate = std::make_shared>( getPrivateKey(kRSAKey), std::move(certs)); auto batcher = std::make_shared>( 2, certificate, CertificateVerifyContext::Server); @@ -202,7 +204,7 @@ TEST(BatchSignatureTest, TestThreadLocalBatcher) { TEST(BatchSignatureTest, TestThreadLocalBatcherWithSelfCertP256) { std::vector certs; certs.emplace_back(getCert(kP256Certificate)); - auto certificate = std::make_shared>( + auto certificate = std::make_shared>( getPrivateKey(kP256Key), std::move(certs)); auto batcher = std::make_shared>( 3, certificate, CertificateVerifyContext::Server); @@ -248,8 +250,8 @@ TEST(BatchSignatureTest, TestThreadLocalBatcherWithSelfCertP256) { t.join(); } // verify - auto peerCert = - std::make_shared>(getCert(kP256Certificate)); + auto peerCert = std::make_shared>( + getCert(kP256Certificate)); BatchSignaturePeerCert batchPeerCert(peerCert); for (size_t i = 0; i < results.size(); i++) { batchPeerCert.verify( diff --git a/fizz/experimental/client/test/BatchSignaturePeerCertTest.cpp b/fizz/experimental/client/test/BatchSignaturePeerCertTest.cpp index 09aac8c45ef..b83ce9c1776 100644 --- a/fizz/experimental/client/test/BatchSignaturePeerCertTest.cpp +++ b/fizz/experimental/client/test/BatchSignaturePeerCertTest.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include @@ -58,7 +60,7 @@ TEST(BatchSignaturePeerCertTest, TestSignVerifyP256) { // sign std::vector certs; certs.emplace_back(getCert(kP256Certificate)); - auto certificate = std::make_shared>( + auto certificate = std::make_shared>( getPrivateKey(kP256Key), std::move(certs)); auto batcher = std::make_shared>( 1, certificate, CertificateVerifyContext::Server); @@ -71,8 +73,8 @@ TEST(BatchSignaturePeerCertTest, TestSignVerifyP256) { executor.drain(); // verify - auto peerCert = - std::make_shared>(getCert(kP256Certificate)); + auto peerCert = std::make_shared>( + getCert(kP256Certificate)); BatchSignaturePeerCert batchPeerCert(peerCert); batchPeerCert.verify( SignatureScheme::ecdsa_secp256r1_sha256_batch, @@ -96,7 +98,7 @@ TEST(BatchSignaturePeerCertTest, TestSignVerifyRSA) { // sign std::vector certs; certs.emplace_back(getCert(kRSACertificate)); - auto certificate = std::make_shared>( + auto certificate = std::make_shared>( getPrivateKey(kRSAKey), std::move(certs)); auto batcher = std::make_shared>( 1, certificate, CertificateVerifyContext::Server); @@ -109,8 +111,8 @@ TEST(BatchSignaturePeerCertTest, TestSignVerifyRSA) { executor.drain(); // verify - auto peerCert = - std::make_shared>(getCert(kRSACertificate)); + auto peerCert = std::make_shared>( + getCert(kRSACertificate)); BatchSignaturePeerCert batchPeerCert(peerCert); batchPeerCert.verify( SignatureScheme::rsa_pss_sha256_batch, @@ -134,7 +136,7 @@ TEST(BatchSignaturePeerCertTest, TestWrongBatchSignature) { // sign std::vector certs; certs.emplace_back(getCert(kP256Certificate)); - auto certificate = std::make_shared>( + auto certificate = std::make_shared>( getPrivateKey(kP256Key), std::move(certs)); auto batcher = std::make_shared>( 1, certificate, CertificateVerifyContext::Server); @@ -147,8 +149,8 @@ TEST(BatchSignaturePeerCertTest, TestWrongBatchSignature) { executor.drain(); auto signatureBuf = *std::move(signature).get(); - auto peerCert = - std::make_shared>(getCert(kP256Certificate)); + auto peerCert = std::make_shared>( + getCert(kP256Certificate)); BatchSignaturePeerCert batchPeerCert(peerCert); // normal verify EXPECT_NO_THROW(batchPeerCert.verify( diff --git a/fizz/experimental/ktls/test/AsyncFizzBaseKTLSTest.cpp b/fizz/experimental/ktls/test/AsyncFizzBaseKTLSTest.cpp index 905cc89ec65..268d19d685e 100644 --- a/fizz/experimental/ktls/test/AsyncFizzBaseKTLSTest.cpp +++ b/fizz/experimental/ktls/test/AsyncFizzBaseKTLSTest.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/fizz/experimental/server/test/BatchSignatureAsyncSelfCertTest.cpp b/fizz/experimental/server/test/BatchSignatureAsyncSelfCertTest.cpp index 740069fb1a2..c10286ddfce 100644 --- a/fizz/experimental/server/test/BatchSignatureAsyncSelfCertTest.cpp +++ b/fizz/experimental/server/test/BatchSignatureAsyncSelfCertTest.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include #include @@ -117,7 +119,7 @@ TEST(BatchSignatureAsyncSelfCertTest, TestSignAndVerifyP256) { // sign std::vector certs; certs.emplace_back(getCert(kP256Certificate)); - auto certificate = std::make_shared>( + auto certificate = std::make_shared>( getPrivateKey(kP256Key), std::move(certs)); auto batcher = std::make_shared>( 1, certificate, CertificateVerifyContext::Server); @@ -128,7 +130,7 @@ TEST(BatchSignatureAsyncSelfCertTest, TestSignAndVerifyP256) { SignatureScheme::ecdsa_secp256r1_sha256, CertificateVerifyContext::Server, folly::IOBuf::copyBuffer(folly::StringPiece("Message1"))); - PeerCertImpl peerCert(getCert(kP256Certificate)); + OpenSSLPeerCertImpl peerCert(getCert(kP256Certificate)); peerCert.verify( SignatureScheme::ecdsa_secp256r1_sha256, CertificateVerifyContext::Server, @@ -154,7 +156,7 @@ TEST(BatchSignatureAsyncSelfCertTest, TestSignAndVerifyRSA) { // sign std::vector certs; certs.emplace_back(getCert(kRSACertificate)); - auto certificate = std::make_shared>( + auto certificate = std::make_shared>( getPrivateKey(kRSAKey), std::move(certs)); auto batcher = std::make_shared>( 1, certificate, CertificateVerifyContext::Server); @@ -165,7 +167,7 @@ TEST(BatchSignatureAsyncSelfCertTest, TestSignAndVerifyRSA) { SignatureScheme::rsa_pss_sha256, CertificateVerifyContext::Server, folly::IOBuf::copyBuffer(folly::StringPiece("Message1"))); - PeerCertImpl peerCert(getCert(kRSACertificate)); + OpenSSLPeerCertImpl peerCert(getCert(kRSACertificate)); peerCert.verify( SignatureScheme::rsa_pss_sha256, CertificateVerifyContext::Server, @@ -191,7 +193,7 @@ TEST(BatchSignatureAsyncSelfCertTest, TestUnsuportedHash) { // sign std::vector certs; certs.emplace_back(getCert(kP384Certificate)); - auto certificate = std::make_shared>( + auto certificate = std::make_shared>( getPrivateKey(kP384Key), std::move(certs)); auto batcher = std::make_shared>( 1, certificate, CertificateVerifyContext::Server); diff --git a/fizz/extensions/delegatedcred/DelegatedCredentialUtils.cpp b/fizz/extensions/delegatedcred/DelegatedCredentialUtils.cpp index af2dc4e17c7..3db09f4ef74 100644 --- a/fizz/extensions/delegatedcred/DelegatedCredentialUtils.cpp +++ b/fizz/extensions/delegatedcred/DelegatedCredentialUtils.cpp @@ -6,6 +6,7 @@ * LICENSE file in the root directory of this source tree. */ #include +#include #include namespace fizz { diff --git a/fizz/extensions/delegatedcred/PeerDelegatedCredential-inl.h b/fizz/extensions/delegatedcred/PeerDelegatedCredential-inl.h index a9120b5b59f..d34818adf9b 100644 --- a/fizz/extensions/delegatedcred/PeerDelegatedCredential-inl.h +++ b/fizz/extensions/delegatedcred/PeerDelegatedCredential-inl.h @@ -15,7 +15,8 @@ PeerDelegatedCredential::PeerDelegatedCredential( folly::ssl::X509UniquePtr cert, folly::ssl::EvpPkeyUniquePtr pubKey, DelegatedCredential credential) - : PeerCertImpl(std::move(cert)), credential_(std::move(credential)) { + : OpenSSLPeerCertImpl(std::move(cert)), + credential_(std::move(credential)) { this->signature_.setKey(std::move(pubKey)); } @@ -33,11 +34,12 @@ void PeerDelegatedCredential::verify( } // Verify signature - auto parentCert = - std::make_unique>(PeerCertImpl::getX509()); + auto parentCert = std::make_unique>( + OpenSSLPeerCertImpl::getX509()); auto credSignBuf = DelegatedCredentialUtils::prepareSignatureBuffer( credential_, - folly::ssl::OpenSSLCertUtils::derEncode(*PeerCertImpl::getX509())); + folly::ssl::OpenSSLCertUtils::derEncode( + *OpenSSLPeerCertImpl::getX509())); try { parentCert->verify( @@ -53,7 +55,7 @@ void PeerDelegatedCredential::verify( } // Call the parent verify method - PeerCertImpl::verify( + OpenSSLPeerCertImpl::verify( scheme, context, std::move(toBeSigned), std::move(signature)); } diff --git a/fizz/extensions/delegatedcred/PeerDelegatedCredential.h b/fizz/extensions/delegatedcred/PeerDelegatedCredential.h index 0c0636fec26..5356363e3ce 100644 --- a/fizz/extensions/delegatedcred/PeerDelegatedCredential.h +++ b/fizz/extensions/delegatedcred/PeerDelegatedCredential.h @@ -9,13 +9,13 @@ #pragma once #include -#include +#include namespace fizz { namespace extensions { template -class PeerDelegatedCredential : public PeerCertImpl { +class PeerDelegatedCredential : public OpenSSLPeerCertImpl { public: explicit PeerDelegatedCredential( folly::ssl::X509UniquePtr cert, diff --git a/fizz/extensions/delegatedcred/SelfDelegatedCredential-inl.h b/fizz/extensions/delegatedcred/SelfDelegatedCredential-inl.h index fe520c381e0..a4a297fbcf8 100644 --- a/fizz/extensions/delegatedcred/SelfDelegatedCredential-inl.h +++ b/fizz/extensions/delegatedcred/SelfDelegatedCredential-inl.h @@ -16,7 +16,7 @@ template SelfDelegatedCredentialImpl::InternalSelfCert::InternalSelfCert( std::vector certs, folly::ssl::EvpPkeyUniquePtr privateKey) - : SelfCertImpl(std::move(certs)) { + : OpenSSLSelfCertImpl(std::move(certs)) { if (certs_.empty()) { throw std::runtime_error("Must supply at least 1 cert"); } diff --git a/fizz/extensions/delegatedcred/SelfDelegatedCredential.h b/fizz/extensions/delegatedcred/SelfDelegatedCredential.h index cd7a2229562..69be997aee8 100644 --- a/fizz/extensions/delegatedcred/SelfDelegatedCredential.h +++ b/fizz/extensions/delegatedcred/SelfDelegatedCredential.h @@ -8,7 +8,7 @@ #pragma once #include -#include +#include namespace fizz { namespace extensions { @@ -25,10 +25,11 @@ class SelfDelegatedCredential : public SelfCert { // // The inheritance is a bit funny cause we want to derive from SelfCert directly // to inherit the pure virtual base (for tests) but we also want the -// implementation to inherit from SelfCertImpl (to share logic). To achieve that -// without diamond inheritance, the implementation class derives from the -// interface, and it has an internal private class that derives from the -// corresponding SelfCertImpl class to provide the implementation logic. +// implementation to inherit from OpenSSLSelfCertImpl (to share logic). To +// achieve that without diamond inheritance, the implementation class derives +// from the interface, and it has an internal private class that derives from +// the corresponding OpenSSLSelfCertImpl class to provide the implementation +// logic. template class SelfDelegatedCredentialImpl : public SelfDelegatedCredential { public: @@ -63,15 +64,15 @@ class SelfDelegatedCredentialImpl : public SelfDelegatedCredential { const DelegatedCredential& getDelegatedCredential() const override; private: - class InternalSelfCert : public SelfCertImpl { + class InternalSelfCert : public OpenSSLSelfCertImpl { public: ~InternalSelfCert() override = default; InternalSelfCert( std::vector certs, folly::ssl::EvpPkeyUniquePtr privateKey); - using SelfCertImpl::certs_; - using SelfCertImpl::signature_; + using OpenSSLSelfCertImpl::certs_; + using OpenSSLSelfCertImpl::signature_; }; InternalSelfCert selfCertImpl_; DelegatedCredential credential_; diff --git a/fizz/extensions/delegatedcred/test/DelegatedCredentialFactoryTest.cpp b/fizz/extensions/delegatedcred/test/DelegatedCredentialFactoryTest.cpp index f8c22d62ef9..50ce9f050d8 100644 --- a/fizz/extensions/delegatedcred/test/DelegatedCredentialFactoryTest.cpp +++ b/fizz/extensions/delegatedcred/test/DelegatedCredentialFactoryTest.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include using namespace folly; @@ -144,7 +145,7 @@ TEST_F(DelegatedCredentialFactoryTest, TestCredentialParsingNonLeaf) { auto entry = generateEntry(); auto cert = factory_.makePeerCert(std::move(entry), false); EXPECT_TRUE(cert); - EXPECT_TRUE(typeid(*cert) == typeid(PeerCertImpl)); + EXPECT_TRUE(typeid(*cert) == typeid(OpenSSLPeerCertImpl)); } TEST_F(DelegatedCredentialFactoryTest, TestCredentialNoX509Extension) { @@ -195,7 +196,7 @@ TEST_F(DelegatedCredentialFactoryTest, TestCredentialNoCertEntryExtension) { entry.extensions.clear(); auto cert = factory_.makePeerCert(std::move(entry), true); EXPECT_TRUE(cert); - EXPECT_TRUE(typeid(*cert) == typeid(PeerCertImpl)); + EXPECT_TRUE(typeid(*cert) == typeid(OpenSSLPeerCertImpl)); } TEST_F(DelegatedCredentialFactoryTest, TestCertExpiredCredential) { diff --git a/fizz/extensions/delegatedcred/test/SelfDelegatedCredentialTest.cpp b/fizz/extensions/delegatedcred/test/SelfDelegatedCredentialTest.cpp index b664ced93c4..9a638e70ac9 100644 --- a/fizz/extensions/delegatedcred/test/SelfDelegatedCredentialTest.cpp +++ b/fizz/extensions/delegatedcred/test/SelfDelegatedCredentialTest.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using namespace folly; @@ -52,8 +53,8 @@ class SelfDelegatedCredentialTest : public Test { public: void SetUp() override { CryptoUtils::init(); - parentCert_ = - std::make_unique>(getKey(), getCertVec()); + parentCert_ = std::make_unique>( + getKey(), getCertVec()); } #if FIZZ_OPENSSL_HAS_ED25519 @@ -208,7 +209,7 @@ class SelfDelegatedCredentialTest : public Test { return cred; } - std::unique_ptr> parentCert_; + std::unique_ptr> parentCert_; }; TEST_F(SelfDelegatedCredentialTest, TestConstruction) { diff --git a/fizz/extensions/exportedauth/ExportedAuthenticator.cpp b/fizz/extensions/exportedauth/ExportedAuthenticator.cpp index 3003e2d5237..db2aaec05d5 100644 --- a/fizz/extensions/exportedauth/ExportedAuthenticator.cpp +++ b/fizz/extensions/exportedauth/ExportedAuthenticator.cpp @@ -8,6 +8,7 @@ #include #include +#include #include namespace fizz { diff --git a/fizz/extensions/exportedauth/test/ExportedAuthenticatorTest.cpp b/fizz/extensions/exportedauth/test/ExportedAuthenticatorTest.cpp index f1fd0e90473..2013b76beb8 100644 --- a/fizz/extensions/exportedauth/test/ExportedAuthenticatorTest.cpp +++ b/fizz/extensions/exportedauth/test/ExportedAuthenticatorTest.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -169,7 +170,8 @@ TEST_F(ValidateAuthenticatorTest, TestValidateValidAuthenticator) { auto key = fizz::test::getPrivateKey(kP256Key); std::vector certs; certs.push_back(std::move(cert)); - SelfCertImpl certificate(std::move(key), std::move(certs)); + OpenSSLSelfCertImpl certificate( + std::move(key), std::move(certs)); auto authenticatorRequest = folly::IOBuf::copyBuffer(unhexlify(authrequest_)); auto handshakeContext = folly::IOBuf::copyBuffer(unhexlify(handshakeContext_)); @@ -205,7 +207,8 @@ TEST_F(ValidateAuthenticatorTest, TestValidateEmptyAuthenticator) { auto key = fizz::test::getPrivateKey(kP256Key); std::vector certs; certs.push_back(std::move(cert)); - SelfCertImpl certificate(std::move(key), std::move(certs)); + OpenSSLSelfCertImpl certificate( + std::move(key), std::move(certs)); schemes_.clear(); auto authenticatorRequest = folly::IOBuf::copyBuffer(unhexlify(authrequest_)); auto handshakeContext = diff --git a/fizz/extensions/javacrypto/JavaCryptoPeerCert.cpp b/fizz/extensions/javacrypto/JavaCryptoPeerCert.cpp index 84ee0adf4be..9ab551c00f5 100644 --- a/fizz/extensions/javacrypto/JavaCryptoPeerCert.cpp +++ b/fizz/extensions/javacrypto/JavaCryptoPeerCert.cpp @@ -8,6 +8,7 @@ #include #include +#include namespace fizz { diff --git a/fizz/protocol/CertUtils-inl.h b/fizz/protocol/CertUtils-inl.h new file mode 100644 index 00000000000..39c40898b18 --- /dev/null +++ b/fizz/protocol/CertUtils-inl.h @@ -0,0 +1,40 @@ +/* + * 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. + */ + +namespace fizz { + +namespace detail { +folly::Optional getIdentityFromX509(X509* x); +} + +template <> +inline std::vector CertUtils::getSigSchemes() { + return {SignatureScheme::ecdsa_secp256r1_sha256}; +} + +template <> +inline std::vector CertUtils::getSigSchemes() { + return {SignatureScheme::ecdsa_secp384r1_sha384}; +} + +template <> +inline std::vector CertUtils::getSigSchemes() { + return {SignatureScheme::ecdsa_secp521r1_sha512}; +} + +template <> +inline std::vector CertUtils::getSigSchemes() { + return {SignatureScheme::rsa_pss_sha256}; +} + +template <> +inline std::vector +CertUtils::getSigSchemes() { + return {SignatureScheme::ed25519}; +} +} // namespace fizz diff --git a/fizz/protocol/CertUtils.cpp b/fizz/protocol/CertUtils.cpp new file mode 100644 index 00000000000..c33ff00557d --- /dev/null +++ b/fizz/protocol/CertUtils.cpp @@ -0,0 +1,300 @@ +/* + * 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 +#include +#include +#include +#include +#include + +namespace { +int getCurveName(EVP_PKEY* key) { + auto ecKey = EVP_PKEY_get0_EC_KEY(key); + if (ecKey) { + return EC_GROUP_get_curve_name(EC_KEY_get0_group(ecKey)); + } + return 0; +} +} // namespace + +namespace fizz { + +namespace detail { + +folly::Optional getIdentityFromX509(X509* x) { + auto cn = folly::ssl::OpenSSLCertUtils::getCommonName(*x); + if (cn.has_value()) { + return std::move(cn).value(); + } + + return folly::ssl::OpenSSLCertUtils::getSubject(*x); +} +} // namespace detail + +Buf CertUtils::prepareSignData( + CertificateVerifyContext context, + folly::ByteRange toBeSigned) { + static constexpr folly::StringPiece kServerLabel = + "TLS 1.3, server CertificateVerify"; + static constexpr folly::StringPiece kClientLabel = + "TLS 1.3, client CertificateVerify"; + static constexpr folly::StringPiece kAuthLabel = "Exported Authenticator"; + static constexpr folly::StringPiece kDelegatedCredLabel = + "TLS, server delegated credentials"; + static constexpr size_t kSigPrefixLen = 64; + static constexpr uint8_t kSigPrefix = 32; + + folly::StringPiece label; + if (context == CertificateVerifyContext::Server) { + label = kServerLabel; + } else if (context == CertificateVerifyContext::Client) { + label = kClientLabel; + } else if (context == CertificateVerifyContext::Authenticator) { + label = kAuthLabel; + } else { + label = kDelegatedCredLabel; + } + + size_t sigDataLen = kSigPrefixLen + label.size() + 1 + toBeSigned.size(); + auto buf = folly::IOBuf::create(sigDataLen); + buf->append(sigDataLen); + + // Place bytes in the right order. + size_t offset = 0; + memset(buf->writableData(), kSigPrefix, kSigPrefixLen); + offset += kSigPrefixLen; + memcpy(buf->writableData() + offset, label.data(), label.size()); + offset += label.size(); + memset(buf->writableData() + offset, 0, 1); + offset += 1; + memcpy(buf->writableData() + offset, toBeSigned.data(), toBeSigned.size()); + return buf; +} + +CertificateMsg CertUtils::getCertMessage( + const std::vector& certs, + Buf certificateRequestContext) { + // compose the cert entry list + std::vector entries; + for (const auto& cert : certs) { + CertificateEntry entry; + int len = i2d_X509(cert.get(), nullptr); + if (len < 0) { + throw std::runtime_error("Error computing length"); + } + entry.cert_data = folly::IOBuf::create(len); + auto dataPtr = entry.cert_data->writableData(); + len = i2d_X509(cert.get(), &dataPtr); + if (len < 0) { + throw std::runtime_error("Error converting cert to DER"); + } + entry.cert_data->append(len); + // TODO: add any extensions. + entries.push_back(std::move(entry)); + } + + CertificateMsg msg; + msg.certificate_request_context = std::move(certificateRequestContext); + msg.certificate_list = std::move(entries); + return msg; +} + +std::unique_ptr CertUtils::makePeerCert(Buf certData) { + if (certData->empty()) { + throw std::runtime_error("empty peer cert"); + } + + auto range = certData->coalesce(); + const unsigned char* begin = range.data(); + folly::ssl::X509UniquePtr cert(d2i_X509(nullptr, &begin, range.size())); + if (!cert) { + throw std::runtime_error("could not read cert"); + } + if (begin != range.data() + range.size()) { + VLOG(1) << "Did not read to end of certificate"; + } + return makePeerCert(std::move(cert)); +} + +std::unique_ptr CertUtils::makePeerCert( + folly::ssl::X509UniquePtr cert) { + folly::ssl::EvpPkeyUniquePtr pubKey(X509_get_pubkey(cert.get())); + if (!pubKey) { + throw std::runtime_error("couldn't get pubkey from peer cert"); + } + const auto pkeyID = EVP_PKEY_id(pubKey.get()); + if (pkeyID == EVP_PKEY_RSA) { + return std::make_unique>(std::move(cert)); + } else if (pkeyID == EVP_PKEY_EC) { + switch (getCurveName(pubKey.get())) { + case NID_X9_62_prime256v1: + return std::make_unique>( + std::move(cert)); + case NID_secp384r1: + return std::make_unique>( + std::move(cert)); + case NID_secp521r1: + return std::make_unique>( + std::move(cert)); + default: + break; + } + } +#if FIZZ_OPENSSL_HAS_ED25519 + else if (pkeyID == EVP_PKEY_ED25519) { + return std::make_unique>( + std::move(cert)); + } +#endif + throw std::runtime_error("unknown peer cert type"); +} + +folly::ssl::EvpPkeyUniquePtr CertUtils::readPrivateKeyFromBuffer( + std::string keyData, + char* password) { + folly::ssl::BioUniquePtr b(BIO_new_mem_buf( + const_cast( // needed by openssl 1.0.2d at least + reinterpret_cast(keyData.data())), + keyData.size())); + + if (!b) { + throw std::runtime_error("failed to create BIO"); + } + + folly::ssl::EvpPkeyUniquePtr key( + PEM_read_bio_PrivateKey(b.get(), nullptr, nullptr, password)); + + if (!key) { + throw std::runtime_error("Failed to read key"); + } + + return key; +} + +namespace { + +std::unique_ptr selfCertFromDataInternal( + std::string certData, + std::string keyData, + char* password, + const std::vector>& compressors) { + auto certs = folly::ssl::OpenSSLCertUtils::readCertsFromBuffer( + folly::StringPiece(certData)); + if (certs.empty()) { + throw std::runtime_error("no certificates read"); + } + + auto key = CertUtils::readPrivateKeyFromBuffer(std::move(keyData), password); + + return CertUtils::makeSelfCert(std::move(certs), std::move(key), compressors); +} + +} // namespace + +std::unique_ptr CertUtils::makeSelfCert( + std::string certData, + std::string keyData, + const std::vector>& compressors) { + return selfCertFromDataInternal( + std::move(certData), std::move(keyData), nullptr, compressors); +} + +std::unique_ptr CertUtils::makeSelfCert( + std::string certData, + std::string encryptedKeyData, + std::string password, + const std::vector>& compressors) { + return selfCertFromDataInternal( + std::move(certData), + std::move(encryptedKeyData), + &password[0], + compressors); +} + +KeyType CertUtils::getKeyType(const folly::ssl::EvpPkeyUniquePtr& key) { + const auto pkeyID = EVP_PKEY_id(key.get()); + if (pkeyID == EVP_PKEY_RSA) { + return KeyType::RSA; + } else if (pkeyID == EVP_PKEY_EC) { + switch (getCurveName(key.get())) { + case NID_X9_62_prime256v1: + return KeyType::P256; + case NID_secp384r1: + return KeyType::P384; + case NID_secp521r1: + return KeyType::P521; + } + } +#if FIZZ_OPENSSL_HAS_ED25519 + else if (pkeyID == EVP_PKEY_ED25519) { + return KeyType::ED25519; + } +#endif + + throw std::runtime_error("unknown key type"); +} + +std::vector CertUtils::getSigSchemes(KeyType type) { + switch (type) { + case KeyType::RSA: + return getSigSchemes(); + case KeyType::P256: + return getSigSchemes(); + case KeyType::P384: + return getSigSchemes(); + case KeyType::P521: + return getSigSchemes(); + case KeyType::ED25519: + return getSigSchemes(); + } + + throw std::runtime_error("unknown key type"); +} + +std::unique_ptr CertUtils::makeSelfCert( + std::vector certs, + folly::ssl::EvpPkeyUniquePtr key, + const std::vector>& compressors) { + folly::ssl::EvpPkeyUniquePtr pubKey(X509_get_pubkey(certs.front().get())); + if (!pubKey) { + throw std::runtime_error("Failed to read public key"); + } + + switch (getKeyType(pubKey)) { + case KeyType::RSA: + return std::make_unique>( + std::move(key), std::move(certs), compressors); + case KeyType::P256: + return std::make_unique>( + std::move(key), std::move(certs), compressors); + case KeyType::P384: + return std::make_unique>( + std::move(key), std::move(certs), compressors); + case KeyType::P521: + return std::make_unique>( + std::move(key), std::move(certs), compressors); + case KeyType::ED25519: + return std::make_unique>( + std::move(key), std::move(certs), compressors); + } + + throw std::runtime_error("unknown self cert type"); +} + +CompressedCertificate CertUtils::cloneCompressedCert( + const CompressedCertificate& src) { + CompressedCertificate ret; + ret.algorithm = src.algorithm; + ret.compressed_certificate_message = + src.compressed_certificate_message->clone(); + ret.uncompressed_length = src.uncompressed_length; + return ret; +} + +} // namespace fizz diff --git a/fizz/protocol/CertUtils.h b/fizz/protocol/CertUtils.h new file mode 100644 index 00000000000..7e333fe5486 --- /dev/null +++ b/fizz/protocol/CertUtils.h @@ -0,0 +1,96 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +namespace fizz { +class SelfCert; +class PeerCert; +enum class CertificateVerifyContext; + +class CertUtils { + public: + /** + * Adds the appropriate context data to prepare toBeSigned for a signature + * scheme's signing function. + */ + static Buf prepareSignData( + CertificateVerifyContext context, + folly::ByteRange toBeSigned); + + static CertificateMsg getCertMessage( + const std::vector& certs, + Buf certificateRequestContext); + + template + static std::vector getSigSchemes(); + + static std::vector getSigSchemes(KeyType type); + + /** + * Create a PeerCert from the ASN1 encoded certData. + */ + static std::unique_ptr makePeerCert(Buf certData); + + /** + * Create a PeerCert from a given X509 + */ + static std::unique_ptr makePeerCert(folly::ssl::X509UniquePtr cert); + + /** + * Creates a SelfCert using the supplied certificate/key file data and + * compressors. + * Throws std::runtime_error on error. + */ + static std::unique_ptr makeSelfCert( + std::string certData, + std::string keyData, + const std::vector>& compressors = + {}); + + static folly::ssl::EvpPkeyUniquePtr readPrivateKeyFromBuffer( + std::string keyData, + char* password = nullptr); + + /** + * Returns the key type for a public/private key. + */ + static KeyType getKeyType(const folly::ssl::EvpPkeyUniquePtr& key); + + /** + * Creates a SelfCert using the supplied certificate, encrypted key data, + * and password. Throws std::runtime_error on error. + */ + static std::unique_ptr makeSelfCert( + std::string certData, + std::string encryptedKeyData, + std::string password, + const std::vector>& compressors = + {}); + + static std::unique_ptr makeSelfCert( + std::vector certs, + folly::ssl::EvpPkeyUniquePtr key, + const std::vector>& compressors = + {}); + + /** + * Clones a compressed cert by copying the relevant fields and cloning the + * underlying data IOBuf. + */ + static CompressedCertificate cloneCompressedCert( + const CompressedCertificate& src); +}; +} // namespace fizz + +#include diff --git a/fizz/protocol/Certificate-inl.h b/fizz/protocol/Certificate-inl.h deleted file mode 100644 index a5ab7bef271..00000000000 --- a/fizz/protocol/Certificate-inl.h +++ /dev/null @@ -1,279 +0,0 @@ -/* - * 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 -#include -#include -#include - -namespace fizz { - -namespace detail { -folly::Optional getIdentityFromX509(X509* x); -} - -template <> -inline std::vector CertUtils::getSigSchemes() { - return {SignatureScheme::ecdsa_secp256r1_sha256}; -} - -template <> -inline std::vector CertUtils::getSigSchemes() { - return {SignatureScheme::ecdsa_secp384r1_sha384}; -} - -template <> -inline std::vector CertUtils::getSigSchemes() { - return {SignatureScheme::ecdsa_secp521r1_sha512}; -} - -template <> -inline std::vector CertUtils::getSigSchemes() { - return {SignatureScheme::rsa_pss_sha256}; -} - -template <> -inline std::vector -CertUtils::getSigSchemes() { - return {SignatureScheme::ed25519}; -} - -template -SelfCertImpl::SelfCertImpl(std::vector certs) - : certs_(std::move(certs)) {} - -template -SelfCertImpl::SelfCertImpl( - folly::ssl::EvpPkeyUniquePtr pkey, - std::vector certs, - const std::vector>& - compressors) { - if (certs.size() == 0) { - throw std::runtime_error("Must supply at least 1 cert"); - } - if (X509_check_private_key(certs[0].get(), pkey.get()) != 1) { - throw std::runtime_error("Cert does not match private key"); - } - // TODO: more strict validation of chaining requirements. - signature_.setKey(std::move(pkey)); - certs_ = std::move(certs); - for (const auto& compressor : compressors) { - compressedCerts_[compressor->getAlgorithm()] = - compressor->compress(getCertMessage()); - } -} - -template -std::string SelfCertImpl::getIdentity() const { - return detail::getIdentityFromX509(certs_.front().get()).value_or(""); -} - -template -std::vector SelfCertImpl::getAltIdentities() const { - return folly::ssl::OpenSSLCertUtils::getSubjectAltNames(*certs_.front()); -} - -template -CertificateMsg SelfCertImpl::getCertMessage( - Buf certificateRequestContext) const { - return CertUtils::getCertMessage( - certs_, std::move(certificateRequestContext)); -} - -template -CompressedCertificate SelfCertImpl::getCompressedCert( - CertificateCompressionAlgorithm algo) const { - return CertUtils::cloneCompressedCert(compressedCerts_.at(algo)); -} - -template -std::vector SelfCertImpl::getSigSchemes() const { - return CertUtils::getSigSchemes(); -} - -template <> -inline Buf SelfCertImpl::sign( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned) const { - auto signData = CertUtils::prepareSignData(context, toBeSigned); - switch (scheme) { - case SignatureScheme::ecdsa_secp256r1_sha256: - return signature_.sign( - signData->coalesce()); - default: - throw std::runtime_error("Unsupported signature scheme"); - } -} - -template <> -inline Buf SelfCertImpl::sign( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned) const { - auto signData = CertUtils::prepareSignData(context, toBeSigned); - switch (scheme) { - case SignatureScheme::ecdsa_secp384r1_sha384: - return signature_.sign( - signData->coalesce()); - default: - throw std::runtime_error("Unsupported signature scheme"); - } -} - -template <> -inline Buf SelfCertImpl::sign( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned) const { - auto signData = CertUtils::prepareSignData(context, toBeSigned); - switch (scheme) { - case SignatureScheme::ecdsa_secp521r1_sha512: - return signature_.sign( - signData->coalesce()); - default: - throw std::runtime_error("Unsupported signature scheme"); - } -} - -template <> -inline Buf SelfCertImpl::sign( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned) const { - auto signData = CertUtils::prepareSignData(context, toBeSigned); - switch (scheme) { - case SignatureScheme::ed25519: - return signature_.sign(signData->coalesce()); - default: - throw std::runtime_error("Unsupported signature scheme"); - } -} - -template <> -inline Buf SelfCertImpl::sign( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned) const { - auto signData = CertUtils::prepareSignData(context, toBeSigned); - switch (scheme) { - case SignatureScheme::rsa_pss_sha256: - return signature_.sign( - signData->coalesce()); - default: - throw std::runtime_error("Unsupported signature scheme"); - } -} - -template -PeerCertImpl::PeerCertImpl(folly::ssl::X509UniquePtr cert) { - folly::ssl::EvpPkeyUniquePtr key(X509_get_pubkey(cert.get())); - if (!key) { - throw std::runtime_error("could not get key from cert"); - } - signature_.setKey(std::move(key)); - cert_ = std::move(cert); -} - -template -std::string PeerCertImpl::getIdentity() const { - return detail::getIdentityFromX509(cert_.get()).value_or(""); -} - -template <> -inline void PeerCertImpl::verify( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned, - folly::ByteRange signature) const { - auto signData = CertUtils::prepareSignData(context, toBeSigned); - switch (scheme) { - case SignatureScheme::ecdsa_secp256r1_sha256: - return signature_.verify( - signData->coalesce(), signature); - default: - throw std::runtime_error("Unsupported signature scheme"); - } -} - -template <> -inline void PeerCertImpl::verify( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned, - folly::ByteRange signature) const { - auto signData = CertUtils::prepareSignData(context, toBeSigned); - switch (scheme) { - case SignatureScheme::ecdsa_secp384r1_sha384: - return signature_.verify( - signData->coalesce(), signature); - default: - throw std::runtime_error("Unsupported signature scheme"); - } -} - -template <> -inline void PeerCertImpl::verify( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned, - folly::ByteRange signature) const { - auto signData = CertUtils::prepareSignData(context, toBeSigned); - switch (scheme) { - case SignatureScheme::ecdsa_secp521r1_sha512: - return signature_.verify( - signData->coalesce(), signature); - default: - throw std::runtime_error("Unsupported signature scheme"); - } -} - -template <> -inline void PeerCertImpl::verify( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned, - folly::ByteRange signature) const { - auto signData = CertUtils::prepareSignData(context, toBeSigned); - switch (scheme) { - case SignatureScheme::ed25519: - return signature_.verify( - signData->coalesce(), signature); - default: - throw std::runtime_error("Unsupported signature scheme"); - } -} - -template <> -inline void PeerCertImpl::verify( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned, - folly::ByteRange signature) const { - auto signData = CertUtils::prepareSignData(context, toBeSigned); - switch (scheme) { - case SignatureScheme::rsa_pss_sha256: - return signature_.verify( - signData->coalesce(), signature); - default: - throw std::runtime_error("Unsupported signature scheme"); - } -} - -template -folly::ssl::X509UniquePtr PeerCertImpl::getX509() const { - X509_up_ref(cert_.get()); - return folly::ssl::X509UniquePtr(cert_.get()); -} - -template -folly::ssl::X509UniquePtr SelfCertImpl::getX509() const { - X509_up_ref(certs_.front().get()); - return folly::ssl::X509UniquePtr(certs_.front().get()); -} -} // namespace fizz diff --git a/fizz/protocol/Certificate.cpp b/fizz/protocol/Certificate.cpp index cdadbd201ef..dae847dba4a 100644 --- a/fizz/protocol/Certificate.cpp +++ b/fizz/protocol/Certificate.cpp @@ -7,288 +7,9 @@ */ #include -#include - -namespace { -int getCurveName(EVP_PKEY* key) { - auto ecKey = EVP_PKEY_get0_EC_KEY(key); - if (ecKey) { - return EC_GROUP_get_curve_name(EC_KEY_get0_group(ecKey)); - } - return 0; -} -} // namespace namespace fizz { -namespace detail { - -folly::Optional getIdentityFromX509(X509* x) { - auto cn = folly::ssl::OpenSSLCertUtils::getCommonName(*x); - if (cn.has_value()) { - return std::move(cn).value(); - } - - return folly::ssl::OpenSSLCertUtils::getSubject(*x); -} -} // namespace detail - -Buf CertUtils::prepareSignData( - CertificateVerifyContext context, - folly::ByteRange toBeSigned) { - static constexpr folly::StringPiece kServerLabel = - "TLS 1.3, server CertificateVerify"; - static constexpr folly::StringPiece kClientLabel = - "TLS 1.3, client CertificateVerify"; - static constexpr folly::StringPiece kAuthLabel = "Exported Authenticator"; - static constexpr folly::StringPiece kDelegatedCredLabel = - "TLS, server delegated credentials"; - static constexpr size_t kSigPrefixLen = 64; - static constexpr uint8_t kSigPrefix = 32; - - folly::StringPiece label; - if (context == CertificateVerifyContext::Server) { - label = kServerLabel; - } else if (context == CertificateVerifyContext::Client) { - label = kClientLabel; - } else if (context == CertificateVerifyContext::Authenticator) { - label = kAuthLabel; - } else { - label = kDelegatedCredLabel; - } - - size_t sigDataLen = kSigPrefixLen + label.size() + 1 + toBeSigned.size(); - auto buf = folly::IOBuf::create(sigDataLen); - buf->append(sigDataLen); - - // Place bytes in the right order. - size_t offset = 0; - memset(buf->writableData(), kSigPrefix, kSigPrefixLen); - offset += kSigPrefixLen; - memcpy(buf->writableData() + offset, label.data(), label.size()); - offset += label.size(); - memset(buf->writableData() + offset, 0, 1); - offset += 1; - memcpy(buf->writableData() + offset, toBeSigned.data(), toBeSigned.size()); - return buf; -} - -CertificateMsg CertUtils::getCertMessage( - const std::vector& certs, - Buf certificateRequestContext) { - // compose the cert entry list - std::vector entries; - for (const auto& cert : certs) { - CertificateEntry entry; - int len = i2d_X509(cert.get(), nullptr); - if (len < 0) { - throw std::runtime_error("Error computing length"); - } - entry.cert_data = folly::IOBuf::create(len); - auto dataPtr = entry.cert_data->writableData(); - len = i2d_X509(cert.get(), &dataPtr); - if (len < 0) { - throw std::runtime_error("Error converting cert to DER"); - } - entry.cert_data->append(len); - // TODO: add any extensions. - entries.push_back(std::move(entry)); - } - - CertificateMsg msg; - msg.certificate_request_context = std::move(certificateRequestContext); - msg.certificate_list = std::move(entries); - return msg; -} - -std::unique_ptr CertUtils::makePeerCert(Buf certData) { - if (certData->empty()) { - throw std::runtime_error("empty peer cert"); - } - - auto range = certData->coalesce(); - const unsigned char* begin = range.data(); - folly::ssl::X509UniquePtr cert(d2i_X509(nullptr, &begin, range.size())); - if (!cert) { - throw std::runtime_error("could not read cert"); - } - if (begin != range.data() + range.size()) { - VLOG(1) << "Did not read to end of certificate"; - } - return makePeerCert(std::move(cert)); -} - -std::unique_ptr CertUtils::makePeerCert( - folly::ssl::X509UniquePtr cert) { - folly::ssl::EvpPkeyUniquePtr pubKey(X509_get_pubkey(cert.get())); - if (!pubKey) { - throw std::runtime_error("couldn't get pubkey from peer cert"); - } - const auto pkeyID = EVP_PKEY_id(pubKey.get()); - if (pkeyID == EVP_PKEY_RSA) { - return std::make_unique>(std::move(cert)); - } else if (pkeyID == EVP_PKEY_EC) { - switch (getCurveName(pubKey.get())) { - case NID_X9_62_prime256v1: - return std::make_unique>(std::move(cert)); - case NID_secp384r1: - return std::make_unique>(std::move(cert)); - case NID_secp521r1: - return std::make_unique>(std::move(cert)); - default: - break; - } - } -#if FIZZ_OPENSSL_HAS_ED25519 - else if (pkeyID == EVP_PKEY_ED25519) { - return std::make_unique>(std::move(cert)); - } -#endif - throw std::runtime_error("unknown peer cert type"); -} - -folly::ssl::EvpPkeyUniquePtr CertUtils::readPrivateKeyFromBuffer( - std::string keyData, - char* password) { - folly::ssl::BioUniquePtr b(BIO_new_mem_buf( - const_cast( // needed by openssl 1.0.2d at least - reinterpret_cast(keyData.data())), - keyData.size())); - - if (!b) { - throw std::runtime_error("failed to create BIO"); - } - - folly::ssl::EvpPkeyUniquePtr key( - PEM_read_bio_PrivateKey(b.get(), nullptr, nullptr, password)); - - if (!key) { - throw std::runtime_error("Failed to read key"); - } - - return key; -} - -namespace { - -std::unique_ptr selfCertFromDataInternal( - std::string certData, - std::string keyData, - char* password, - const std::vector>& compressors) { - auto certs = folly::ssl::OpenSSLCertUtils::readCertsFromBuffer( - folly::StringPiece(certData)); - if (certs.empty()) { - throw std::runtime_error("no certificates read"); - } - - auto key = CertUtils::readPrivateKeyFromBuffer(std::move(keyData), password); - - return CertUtils::makeSelfCert(std::move(certs), std::move(key), compressors); -} - -} // namespace - -std::unique_ptr CertUtils::makeSelfCert( - std::string certData, - std::string keyData, - const std::vector>& compressors) { - return selfCertFromDataInternal( - std::move(certData), std::move(keyData), nullptr, compressors); -} - -std::unique_ptr CertUtils::makeSelfCert( - std::string certData, - std::string encryptedKeyData, - std::string password, - const std::vector>& compressors) { - return selfCertFromDataInternal( - std::move(certData), - std::move(encryptedKeyData), - &password[0], - compressors); -} - -KeyType CertUtils::getKeyType(const folly::ssl::EvpPkeyUniquePtr& key) { - const auto pkeyID = EVP_PKEY_id(key.get()); - if (pkeyID == EVP_PKEY_RSA) { - return KeyType::RSA; - } else if (pkeyID == EVP_PKEY_EC) { - switch (getCurveName(key.get())) { - case NID_X9_62_prime256v1: - return KeyType::P256; - case NID_secp384r1: - return KeyType::P384; - case NID_secp521r1: - return KeyType::P521; - } - } -#if FIZZ_OPENSSL_HAS_ED25519 - else if (pkeyID == EVP_PKEY_ED25519) { - return KeyType::ED25519; - } -#endif - - throw std::runtime_error("unknown key type"); -} - -std::vector CertUtils::getSigSchemes(KeyType type) { - switch (type) { - case KeyType::RSA: - return getSigSchemes(); - case KeyType::P256: - return getSigSchemes(); - case KeyType::P384: - return getSigSchemes(); - case KeyType::P521: - return getSigSchemes(); - case KeyType::ED25519: - return getSigSchemes(); - } - - throw std::runtime_error("unknown key type"); -} - -std::unique_ptr CertUtils::makeSelfCert( - std::vector certs, - folly::ssl::EvpPkeyUniquePtr key, - const std::vector>& compressors) { - folly::ssl::EvpPkeyUniquePtr pubKey(X509_get_pubkey(certs.front().get())); - if (!pubKey) { - throw std::runtime_error("Failed to read public key"); - } - - switch (getKeyType(pubKey)) { - case KeyType::RSA: - return std::make_unique>( - std::move(key), std::move(certs), compressors); - case KeyType::P256: - return std::make_unique>( - std::move(key), std::move(certs), compressors); - case KeyType::P384: - return std::make_unique>( - std::move(key), std::move(certs), compressors); - case KeyType::P521: - return std::make_unique>( - std::move(key), std::move(certs), compressors); - case KeyType::ED25519: - return std::make_unique>( - std::move(key), std::move(certs), compressors); - } - - throw std::runtime_error("unknown self cert type"); -} - -CompressedCertificate CertUtils::cloneCompressedCert( - const CompressedCertificate& src) { - CompressedCertificate ret; - ret.algorithm = src.algorithm; - ret.compressed_certificate_message = - src.compressed_certificate_message->clone(); - ret.uncompressed_length = src.uncompressed_length; - return ret; -} - IdentityCert::IdentityCert(std::string identity) : identity_(identity) {} std::string IdentityCert::getIdentity() const { diff --git a/fizz/protocol/Certificate.h b/fizz/protocol/Certificate.h index 253b14c5a0c..81e9b763e37 100644 --- a/fizz/protocol/Certificate.h +++ b/fizz/protocol/Certificate.h @@ -8,8 +8,6 @@ #pragma once -#include -#include #include #include #include @@ -80,146 +78,4 @@ class PeerCert : public OpenSSLCert { folly::ByteRange toBeSigned, folly::ByteRange signature) const = 0; }; - -class CertUtils { - public: - /** - * Adds the appropriate context data to prepare toBeSigned for a signature - * scheme's signing function. - */ - static Buf prepareSignData( - CertificateVerifyContext context, - folly::ByteRange toBeSigned); - - static CertificateMsg getCertMessage( - const std::vector& certs, - Buf certificateRequestContext); - - template - static std::vector getSigSchemes(); - - static std::vector getSigSchemes(KeyType type); - - /** - * Create a PeerCert from the ASN1 encoded certData. - */ - static std::unique_ptr makePeerCert(Buf certData); - - /** - * Create a PeerCert from a given X509 - */ - static std::unique_ptr makePeerCert(folly::ssl::X509UniquePtr cert); - - /** - * Creates a SelfCert using the supplied certificate/key file data and - * compressors. - * Throws std::runtime_error on error. - */ - static std::unique_ptr makeSelfCert( - std::string certData, - std::string keyData, - const std::vector>& compressors = - {}); - - static folly::ssl::EvpPkeyUniquePtr readPrivateKeyFromBuffer( - std::string keyData, - char* password = nullptr); - - /** - * Returns the key type for a public/private key. - */ - static KeyType getKeyType(const folly::ssl::EvpPkeyUniquePtr& key); - - /** - * Creates a SelfCert using the supplied certificate, encrypted key data, - * and password. Throws std::runtime_error on error. - */ - static std::unique_ptr makeSelfCert( - std::string certData, - std::string encryptedKeyData, - std::string password, - const std::vector>& compressors = - {}); - - static std::unique_ptr makeSelfCert( - std::vector certs, - folly::ssl::EvpPkeyUniquePtr key, - const std::vector>& compressors = - {}); - - /** - * Clones a compressed cert by copying the relevant fields and cloning the - * underlying data IOBuf. - */ - static CompressedCertificate cloneCompressedCert( - const CompressedCertificate& src); -}; - -template -class SelfCertImpl : public SelfCert { - public: - /** - * Private key is the private key associated with the leaf cert. - * certs is a list of certs in the chain with the leaf first. - */ - SelfCertImpl( - folly::ssl::EvpPkeyUniquePtr pkey, - std::vector certs, - const std::vector>& - compressors = {}); - - ~SelfCertImpl() override = default; - - std::string getIdentity() const override; - - std::vector getAltIdentities() const override; - - std::vector getSigSchemes() const override; - - CertificateMsg getCertMessage( - Buf certificateRequestContext = nullptr) const override; - - CompressedCertificate getCompressedCert( - CertificateCompressionAlgorithm algo) const override; - - Buf sign( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned) const override; - - folly::ssl::X509UniquePtr getX509() const override; - - protected: - // Allows derived classes to handle init - explicit SelfCertImpl(std::vector certs); - OpenSSLSignature signature_; - std::vector certs_; - std::map - compressedCerts_; -}; - -template -class PeerCertImpl : public PeerCert { - public: - explicit PeerCertImpl(folly::ssl::X509UniquePtr cert); - - ~PeerCertImpl() override = default; - - std::string getIdentity() const override; - - void verify( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned, - folly::ByteRange signature) const override; - - folly::ssl::X509UniquePtr getX509() const override; - - protected: - OpenSSLSignature signature_; - folly::ssl::X509UniquePtr cert_; -}; - } // namespace fizz - -#include diff --git a/fizz/protocol/DefaultFactory.h b/fizz/protocol/DefaultFactory.h index 846bff331a8..5494bb25758 100644 --- a/fizz/protocol/DefaultFactory.h +++ b/fizz/protocol/DefaultFactory.h @@ -57,12 +57,6 @@ class DefaultFactory : public Factory { return RandomBufGenerator(count).generateRandom(); } - [[nodiscard]] std::shared_ptr makePeerCert( - CertificateEntry certEntry, - bool /*leaf*/) const override { - return CertUtils::makePeerCert(std::move(certEntry.cert_data)); - } - [[nodiscard]] std::shared_ptr makeIdentityOnlyCert( std::string ident) const override { return std::make_shared(std::move(ident)); diff --git a/fizz/protocol/OpenSSLFactory.cpp b/fizz/protocol/OpenSSLFactory.cpp index 30a9d391023..b1c3a7e2e61 100644 --- a/fizz/protocol/OpenSSLFactory.cpp +++ b/fizz/protocol/OpenSSLFactory.cpp @@ -6,6 +6,7 @@ * LICENSE file in the root directory of this source tree. */ +#include #include namespace fizz { @@ -80,4 +81,11 @@ std::unique_ptr OpenSSLFactory::makeHandshakeContext( throw std::runtime_error("hs: not implemented"); } } + +std::shared_ptr OpenSSLFactory::makePeerCert( + CertificateEntry certEntry, + bool /*leaf*/) const { + return CertUtils::makePeerCert(std::move(certEntry.cert_data)); +} + } // namespace fizz diff --git a/fizz/protocol/OpenSSLFactory.h b/fizz/protocol/OpenSSLFactory.h index d26e7db89c5..f2ed92a5303 100644 --- a/fizz/protocol/OpenSSLFactory.h +++ b/fizz/protocol/OpenSSLFactory.h @@ -36,5 +36,9 @@ class OpenSSLFactory : public DefaultFactory { std::unique_ptr makeHandshakeContext( CipherSuite cipher) const override; + + [[nodiscard]] std::shared_ptr makePeerCert( + CertificateEntry certEntry, + bool /*leaf*/) const override; }; } // namespace fizz diff --git a/fizz/protocol/OpenSSLPeerCertImpl-inl.h b/fizz/protocol/OpenSSLPeerCertImpl-inl.h new file mode 100644 index 00000000000..e12efc118d0 --- /dev/null +++ b/fizz/protocol/OpenSSLPeerCertImpl-inl.h @@ -0,0 +1,121 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include + +namespace fizz { + +namespace detail { +extern folly::Optional getIdentityFromX509(X509* x); +} + +template +OpenSSLPeerCertImpl::OpenSSLPeerCertImpl(folly::ssl::X509UniquePtr cert) { + folly::ssl::EvpPkeyUniquePtr key(X509_get_pubkey(cert.get())); + if (!key) { + throw std::runtime_error("could not get key from cert"); + } + signature_.setKey(std::move(key)); + cert_ = std::move(cert); +} + +template +std::string OpenSSLPeerCertImpl::getIdentity() const { + return detail::getIdentityFromX509(cert_.get()).value_or(""); +} + +template <> +inline void OpenSSLPeerCertImpl::verify( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned, + folly::ByteRange signature) const { + auto signData = CertUtils::prepareSignData(context, toBeSigned); + switch (scheme) { + case SignatureScheme::ecdsa_secp256r1_sha256: + return signature_.verify( + signData->coalesce(), signature); + default: + throw std::runtime_error("Unsupported signature scheme"); + } +} + +template <> +inline void OpenSSLPeerCertImpl::verify( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned, + folly::ByteRange signature) const { + auto signData = CertUtils::prepareSignData(context, toBeSigned); + switch (scheme) { + case SignatureScheme::ecdsa_secp384r1_sha384: + return signature_.verify( + signData->coalesce(), signature); + default: + throw std::runtime_error("Unsupported signature scheme"); + } +} + +template <> +inline void OpenSSLPeerCertImpl::verify( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned, + folly::ByteRange signature) const { + auto signData = CertUtils::prepareSignData(context, toBeSigned); + switch (scheme) { + case SignatureScheme::ecdsa_secp521r1_sha512: + return signature_.verify( + signData->coalesce(), signature); + default: + throw std::runtime_error("Unsupported signature scheme"); + } +} + +template <> +inline void OpenSSLPeerCertImpl::verify( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned, + folly::ByteRange signature) const { + auto signData = CertUtils::prepareSignData(context, toBeSigned); + switch (scheme) { + case SignatureScheme::ed25519: + return signature_.verify( + signData->coalesce(), signature); + default: + throw std::runtime_error("Unsupported signature scheme"); + } +} + +template <> +inline void OpenSSLPeerCertImpl::verify( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned, + folly::ByteRange signature) const { + auto signData = CertUtils::prepareSignData(context, toBeSigned); + switch (scheme) { + case SignatureScheme::rsa_pss_sha256: + return signature_.verify( + signData->coalesce(), signature); + default: + throw std::runtime_error("Unsupported signature scheme"); + } +} + +template +folly::ssl::X509UniquePtr OpenSSLPeerCertImpl::getX509() const { + X509_up_ref(cert_.get()); + return folly::ssl::X509UniquePtr(cert_.get()); +} +} // namespace fizz diff --git a/fizz/protocol/OpenSSLPeerCertImpl.h b/fizz/protocol/OpenSSLPeerCertImpl.h new file mode 100644 index 00000000000..4354db28d74 --- /dev/null +++ b/fizz/protocol/OpenSSLPeerCertImpl.h @@ -0,0 +1,41 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include + +namespace fizz { + +template +class OpenSSLPeerCertImpl : public PeerCert { + public: + explicit OpenSSLPeerCertImpl(folly::ssl::X509UniquePtr cert); + + ~OpenSSLPeerCertImpl() override = default; + + std::string getIdentity() const override; + + void verify( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned, + folly::ByteRange signature) const override; + + folly::ssl::X509UniquePtr getX509() const override; + + protected: + OpenSSLSignature signature_; + folly::ssl::X509UniquePtr cert_; +}; + +} // namespace fizz + +#include diff --git a/fizz/protocol/OpenSSLSelfCertImpl-inl.h b/fizz/protocol/OpenSSLSelfCertImpl-inl.h new file mode 100644 index 00000000000..4cc700c5291 --- /dev/null +++ b/fizz/protocol/OpenSSLSelfCertImpl-inl.h @@ -0,0 +1,156 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +namespace fizz { + +namespace detail { +extern folly::Optional getIdentityFromX509(X509* x); +} + +template +OpenSSLSelfCertImpl::OpenSSLSelfCertImpl( + std::vector certs) + : certs_(std::move(certs)) {} + +template +OpenSSLSelfCertImpl::OpenSSLSelfCertImpl( + folly::ssl::EvpPkeyUniquePtr pkey, + std::vector certs, + const std::vector>& + compressors) { + if (certs.size() == 0) { + throw std::runtime_error("Must supply at least 1 cert"); + } + if (X509_check_private_key(certs[0].get(), pkey.get()) != 1) { + throw std::runtime_error("Cert does not match private key"); + } + // TODO: more strict validation of chaining requirements. + signature_.setKey(std::move(pkey)); + certs_ = std::move(certs); + for (const auto& compressor : compressors) { + compressedCerts_[compressor->getAlgorithm()] = + compressor->compress(getCertMessage()); + } +} + +template +std::string OpenSSLSelfCertImpl::getIdentity() const { + return detail::getIdentityFromX509(certs_.front().get()).value_or(""); +} + +template +std::vector OpenSSLSelfCertImpl::getAltIdentities() const { + return folly::ssl::OpenSSLCertUtils::getSubjectAltNames(*certs_.front()); +} + +template +CertificateMsg OpenSSLSelfCertImpl::getCertMessage( + Buf certificateRequestContext) const { + return CertUtils::getCertMessage( + certs_, std::move(certificateRequestContext)); +} + +template +CompressedCertificate OpenSSLSelfCertImpl::getCompressedCert( + CertificateCompressionAlgorithm algo) const { + return CertUtils::cloneCompressedCert(compressedCerts_.at(algo)); +} + +template +std::vector OpenSSLSelfCertImpl::getSigSchemes() const { + return CertUtils::getSigSchemes(); +} + +template <> +inline Buf OpenSSLSelfCertImpl::sign( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned) const { + auto signData = CertUtils::prepareSignData(context, toBeSigned); + switch (scheme) { + case SignatureScheme::ecdsa_secp256r1_sha256: + return signature_.sign( + signData->coalesce()); + default: + throw std::runtime_error("Unsupported signature scheme"); + } +} + +template <> +inline Buf OpenSSLSelfCertImpl::sign( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned) const { + auto signData = CertUtils::prepareSignData(context, toBeSigned); + switch (scheme) { + case SignatureScheme::ecdsa_secp384r1_sha384: + return signature_.sign( + signData->coalesce()); + default: + throw std::runtime_error("Unsupported signature scheme"); + } +} + +template <> +inline Buf OpenSSLSelfCertImpl::sign( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned) const { + auto signData = CertUtils::prepareSignData(context, toBeSigned); + switch (scheme) { + case SignatureScheme::ecdsa_secp521r1_sha512: + return signature_.sign( + signData->coalesce()); + default: + throw std::runtime_error("Unsupported signature scheme"); + } +} + +template <> +inline Buf OpenSSLSelfCertImpl::sign( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned) const { + auto signData = CertUtils::prepareSignData(context, toBeSigned); + switch (scheme) { + case SignatureScheme::ed25519: + return signature_.sign(signData->coalesce()); + default: + throw std::runtime_error("Unsupported signature scheme"); + } +} + +template <> +inline Buf OpenSSLSelfCertImpl::sign( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned) const { + auto signData = CertUtils::prepareSignData(context, toBeSigned); + switch (scheme) { + case SignatureScheme::rsa_pss_sha256: + return signature_.sign( + signData->coalesce()); + default: + throw std::runtime_error("Unsupported signature scheme"); + } +} + +template +folly::ssl::X509UniquePtr OpenSSLSelfCertImpl::getX509() const { + X509_up_ref(certs_.front().get()); + return folly::ssl::X509UniquePtr(certs_.front().get()); +} + +} // namespace fizz diff --git a/fizz/protocol/OpenSSLSelfCertImpl.h b/fizz/protocol/OpenSSLSelfCertImpl.h new file mode 100644 index 00000000000..4aac521a7f6 --- /dev/null +++ b/fizz/protocol/OpenSSLSelfCertImpl.h @@ -0,0 +1,62 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +namespace fizz { + +template +class OpenSSLSelfCertImpl : public SelfCert { + public: + /** + * Private key is the private key associated with the leaf cert. + * certs is a list of certs in the chain with the leaf first. + */ + OpenSSLSelfCertImpl( + folly::ssl::EvpPkeyUniquePtr pkey, + std::vector certs, + const std::vector>& + compressors = {}); + + ~OpenSSLSelfCertImpl() override = default; + + std::string getIdentity() const override; + + std::vector getAltIdentities() const override; + + std::vector getSigSchemes() const override; + + CertificateMsg getCertMessage( + Buf certificateRequestContext = nullptr) const override; + + CompressedCertificate getCompressedCert( + CertificateCompressionAlgorithm algo) const override; + + Buf sign( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned) const override; + + folly::ssl::X509UniquePtr getX509() const override; + + protected: + // Allows derived classes to handle init + explicit OpenSSLSelfCertImpl(std::vector certs); + OpenSSLSignature signature_; + std::vector certs_; + std::map + compressedCerts_; +}; +} // namespace fizz + +#include diff --git a/fizz/protocol/test/CertTest.cpp b/fizz/protocol/test/CertTest.cpp index 7feb56f5f9c..7316fde10f0 100644 --- a/fizz/protocol/test/CertTest.cpp +++ b/fizz/protocol/test/CertTest.cpp @@ -9,7 +9,9 @@ #include #include -#include +#include +#include +#include #include using namespace folly; @@ -140,7 +142,8 @@ TEST(CertTest, GetIdentity) { auto key = getPrivateKey(kP256Key); std::vector certs; certs.push_back(std::move(cert)); - SelfCertImpl certificate(std::move(key), std::move(certs)); + OpenSSLSelfCertImpl certificate( + std::move(key), std::move(certs)); EXPECT_EQ(certificate.getIdentity(), "Fizz"); EXPECT_EQ(certificate.getAltIdentities().size(), 0); } @@ -150,7 +153,8 @@ TEST(CertTest, GetAltIdentity) { auto key = getPrivateKey(kRSAKey); std::vector certs; certs.push_back(std::move(cert)); - SelfCertImpl certificate(std::move(key), std::move(certs)); + OpenSSLSelfCertImpl certificate( + std::move(key), std::move(certs)); EXPECT_EQ(certificate.getIdentity(), "Fizz"); auto alts = certificate.getAltIdentities(); EXPECT_EQ(alts.size(), 3); @@ -164,7 +168,8 @@ TEST(CertTest, GetCertMessage) { auto key = getPrivateKey(kP256Key); std::vector certs; certs.push_back(std::move(cert)); - SelfCertImpl certificate(std::move(key), std::move(certs)); + OpenSSLSelfCertImpl certificate( + std::move(key), std::move(certs)); auto msg = certificate.getCertMessage(); ASSERT_EQ(msg.certificate_list.size(), 1); auto& firstCertEntry = msg.certificate_list[0]; @@ -206,7 +211,7 @@ TEST(CertTest, MakePeerCertJunk) { } TEST(CertTest, PeerCertGetX509) { - PeerCertImpl peerCert(getCert(kP256Certificate)); + OpenSSLPeerCertImpl peerCert(getCert(kP256Certificate)); auto x509 = peerCert.getX509(); EXPECT_NE(x509.get(), nullptr); } @@ -224,7 +229,7 @@ TEST(CertTest, GetIdentityLogic) { TYPED_TEST(CertTestTyped, MatchingCert) { std::vector certs; certs.push_back(getCert()); - SelfCertImpl certificate( + OpenSSLSelfCertImpl certificate( getKey(), std::move(certs)); } @@ -232,7 +237,7 @@ TYPED_TEST(CertTestTyped, MismatchedCert) { std::vector certs; certs.push_back(getCert()); EXPECT_THROW( - SelfCertImpl certificate( + OpenSSLSelfCertImpl certificate( getKey(), std::move(certs)), std::runtime_error); } @@ -240,7 +245,7 @@ TYPED_TEST(CertTestTyped, MismatchedCert) { TYPED_TEST(CertTestTyped, SigSchemes) { std::vector certs; certs.push_back(getCert()); - SelfCertImpl certificate( + OpenSSLSelfCertImpl certificate( getKey(), std::move(certs)); std::vector expected{TypeParam::Scheme}; @@ -248,10 +253,11 @@ TYPED_TEST(CertTestTyped, SigSchemes) { } TYPED_TEST(CertTestTyped, TestSignVerify) { - PeerCertImpl peerCert(getCert()); + OpenSSLPeerCertImpl peerCert(getCert()); std::vector certs; certs.push_back(getCert()); - SelfCertImpl selfCert(getKey(), std::move(certs)); + OpenSSLSelfCertImpl selfCert( + getKey(), std::move(certs)); StringPiece tbs{"ToBeSigned"}; auto sig = @@ -264,10 +270,11 @@ TYPED_TEST(CertTestTyped, TestSignVerify) { } TYPED_TEST(CertTestTyped, TestSignVerifyBitFlip) { - PeerCertImpl peerCert(getCert()); + OpenSSLPeerCertImpl peerCert(getCert()); std::vector certs; certs.push_back(getCert()); - SelfCertImpl selfCert(getKey(), std::move(certs)); + OpenSSLSelfCertImpl selfCert( + getKey(), std::move(certs)); StringPiece tbs{"ToBeSigned"}; auto sig = @@ -283,10 +290,11 @@ TYPED_TEST(CertTestTyped, TestSignVerifyBitFlip) { } TYPED_TEST(CertTestTyped, TestSignVerifyWrongSize) { - PeerCertImpl peerCert(getCert()); + OpenSSLPeerCertImpl peerCert(getCert()); std::vector certs; certs.push_back(getCert()); - SelfCertImpl selfCert(getKey(), std::move(certs)); + OpenSSLSelfCertImpl selfCert( + getKey(), std::move(certs)); StringPiece tbs{"ToBeSigned"}; auto sig = @@ -302,10 +310,11 @@ TYPED_TEST(CertTestTyped, TestSignVerifyWrongSize) { } TYPED_TEST(CertTestTyped, TestVerifyWrongScheme) { - PeerCertImpl peerCert(getCert()); + OpenSSLPeerCertImpl peerCert(getCert()); std::vector certs; certs.push_back(getCert()); - SelfCertImpl selfCert(getKey(), std::move(certs)); + OpenSSLSelfCertImpl selfCert( + getKey(), std::move(certs)); StringPiece tbs{"ToBeSigned"}; auto sig = @@ -323,7 +332,8 @@ TYPED_TEST(CertTestTyped, TestVerifyDecodedCert) { std::vector certs; certs.push_back(getCert()); auto msg = CertUtils::getCertMessage(certs, nullptr); - SelfCertImpl selfCert(getKey(), std::move(certs)); + OpenSSLSelfCertImpl selfCert( + getKey(), std::move(certs)); auto peerCert = CertUtils::makePeerCert( std::move(msg.certificate_list.front().cert_data)); diff --git a/fizz/protocol/test/DefaultCertificateVerifierTest.cpp b/fizz/protocol/test/DefaultCertificateVerifierTest.cpp index a9b5afe61a1..923f91bff91 100644 --- a/fizz/protocol/test/DefaultCertificateVerifierTest.cpp +++ b/fizz/protocol/test/DefaultCertificateVerifierTest.cpp @@ -10,6 +10,7 @@ #include #include +#include namespace fizz { namespace test { diff --git a/fizz/protocol/test/Utilities.h b/fizz/protocol/test/Utilities.h index 1a185b5bc50..be7b506c099 100644 --- a/fizz/protocol/test/Utilities.h +++ b/fizz/protocol/test/Utilities.h @@ -8,7 +8,7 @@ #pragma once -#include +#include namespace fizz { namespace test { @@ -120,7 +120,7 @@ inline CertAndKey createCert(std::string cn, bool ca, CertAndKey* issuer) { } inline std::shared_ptr getPeerCert(const CertAndKey& cert) { - return std::make_shared>( + return std::make_shared>( folly::ssl::X509UniquePtr(X509_dup(cert.cert.get()))); } diff --git a/fizz/server/TicketCodec.cpp b/fizz/server/TicketCodec.cpp index 28d427b87d3..b39a9fea165 100644 --- a/fizz/server/TicketCodec.cpp +++ b/fizz/server/TicketCodec.cpp @@ -7,6 +7,7 @@ */ #include +#include namespace fizz { std::string toString(fizz::server::CertificateStorage storage) { diff --git a/fizz/server/test/Utils.h b/fizz/server/test/Utils.h index 5c4ae79915b..478e9ca4da3 100644 --- a/fizz/server/test/Utils.h +++ b/fizz/server/test/Utils.h @@ -9,8 +9,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -39,7 +41,7 @@ class FizzTestServer : public folly::AsyncServerSocket::AcceptCallback { fizz::test::createCert("fizz-test-selfsign", false, nullptr); std::vector certChain; certChain.push_back(std::move(certData.cert)); - auto fizzCert = std::make_unique>( + auto fizzCert = std::make_unique>( std::move(certData.key), std::move(certChain)); auto certManager = std::make_unique(); certManager->addCert(std::move(fizzCert), true); diff --git a/fizz/test/BogoShim.cpp b/fizz/test/BogoShim.cpp index 4712655efb3..3f8b93fdddf 100644 --- a/fizz/test/BogoShim.cpp +++ b/fizz/test/BogoShim.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -254,17 +255,17 @@ class BogoTestClient : public AsyncSocket::ConnectCallback, Optional success_; }; -class TestRsaCert : public SelfCertImpl { +class TestRsaCert : public OpenSSLSelfCertImpl { public: - using SelfCertImpl::SelfCertImpl; + using OpenSSLSelfCertImpl::OpenSSLSelfCertImpl; std::string getIdentity() const override { return "testrsacert"; } }; -class TestP256Cert : public SelfCertImpl { +class TestP256Cert : public OpenSSLSelfCertImpl { public: - using SelfCertImpl::SelfCertImpl; + using OpenSSLSelfCertImpl::OpenSSLSelfCertImpl; std::string getIdentity() const override { return "testp256cert"; } diff --git a/fizz/test/HandshakeTest.cpp b/fizz/test/HandshakeTest.cpp index df712bf6c3b..20bf9b7439a 100644 --- a/fizz/test/HandshakeTest.cpp +++ b/fizz/test/HandshakeTest.cpp @@ -5,6 +5,7 @@ * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ +#include #include namespace fizz { @@ -359,7 +360,7 @@ TEST_F(HandshakeTest, TestExtensions) { TEST_F(HandshakeTest, BasicCertRequest) { expectSuccess(); serverContext_->setClientAuthMode(ClientAuthMode::Required); - expected_.clientCert = std::make_shared>( + expected_.clientCert = std::make_shared>( getCert(kClientAuthClientCert)); doHandshake(); verifyParameters(); @@ -380,7 +381,7 @@ TEST_P(SigSchemeTest, Schemes) { TEST_F(HandshakeTest, CertRequestPskPreservesIdentity) { serverContext_->setClientAuthMode(ClientAuthMode::Required); - expected_.clientCert = std::make_shared>( + expected_.clientCert = std::make_shared>( getCert(kClientAuthClientCert)); setupResume(); @@ -413,7 +414,7 @@ TEST_F(HandshakeTest, CertRequestBadCert) { std::vector certVec; certVec.emplace_back(std::move(badCert.cert)); clientContext_->setClientCertificate( - std::make_shared>( + std::make_shared>( std::move(badCert.key), std::move(certVec))); expectServerError("alert: bad_certificate", "client certificate failure"); doHandshake(); @@ -588,7 +589,7 @@ TEST_F(HandshakeTest, EarlyDataTrickleSendRejected) { expected_.pskMode = none; expected_.earlyDataType = EarlyDataType::Rejected; expected_.scheme = SignatureScheme::ecdsa_secp256r1_sha256; - expected_.clientCert = std::make_shared>( + expected_.clientCert = std::make_shared>( getCert(kClientAuthClientCert)); expectEarlyDataRejectError(); diff --git a/fizz/test/HandshakeTest.h b/fizz/test/HandshakeTest.h index 97e173c1b27..8e94a33a0ea 100644 --- a/fizz/test/HandshakeTest.h +++ b/fizz/test/HandshakeTest.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -71,7 +72,7 @@ class HandshakeTest : public Test { std::vector rsaCerts; rsaCerts.emplace_back(getCert(kRSACertificate)); certManager->addCert( - std::make_shared>( + std::make_shared>( getPrivateKey(kRSAKey), std::move(rsaCerts), compressors), true); std::vector p256Certs; @@ -80,11 +81,11 @@ class HandshakeTest : public Test { p256Certs.emplace_back(getCert(kP256Certificate)); p384Certs.emplace_back(getCert(kP384Certificate)); p521Certs.emplace_back(getCert(kP521Certificate)); - certManager->addCert(std::make_shared>( + certManager->addCert(std::make_shared>( getPrivateKey(kP256Key), std::move(p256Certs), compressors)); - certManager->addCert(std::make_shared>( + certManager->addCert(std::make_shared>( getPrivateKey(kP384Key), std::move(p384Certs), compressors)); - certManager->addCert(std::make_shared>( + certManager->addCert(std::make_shared>( getPrivateKey(kP521Key), std::move(p521Certs), compressors)); serverContext_->setCertManager(certManager); serverContext_->setEarlyDataSettings( @@ -102,7 +103,7 @@ class HandshakeTest : public Test { serverContext_->setClientCertVerifier(verifier); std::vector certVec; certVec.emplace_back(std::move(clientCert)); - auto clientSelfCert = std::make_shared>( + auto clientSelfCert = std::make_shared>( std::move(clientKey), std::move(certVec)); clientContext_->setClientCertificate(std::move(clientSelfCert)); diff --git a/fizz/tool/FizzClientCommand.cpp b/fizz/tool/FizzClientCommand.cpp index 02ee86a42bc..e9f7d3cb38b 100644 --- a/fizz/tool/FizzClientCommand.cpp +++ b/fizz/tool/FizzClientCommand.cpp @@ -21,6 +21,7 @@ #ifdef FIZZ_TOOL_ENABLE_OQS #include #endif +#include #include #include #include diff --git a/fizz/tool/FizzGenerateDelegatedCredentialCommand.cpp b/fizz/tool/FizzGenerateDelegatedCredentialCommand.cpp index fd9e04000fe..99006abcd79 100644 --- a/fizz/tool/FizzGenerateDelegatedCredentialCommand.cpp +++ b/fizz/tool/FizzGenerateDelegatedCredentialCommand.cpp @@ -7,6 +7,7 @@ */ #include +#include #include #include #include diff --git a/fizz/tool/FizzServerCommand.cpp b/fizz/tool/FizzServerCommand.cpp index e2da1621c72..93e265aa4a2 100644 --- a/fizz/tool/FizzServerCommand.cpp +++ b/fizz/tool/FizzServerCommand.cpp @@ -19,6 +19,8 @@ #ifdef FIZZ_TOOL_ENABLE_ZSTD #include #endif +#include +#include #include #include #include @@ -1126,7 +1128,7 @@ int fizzServerCommand(const std::vector& args) { auto certData = fizz::test::createCert("fizz-self-signed", false, nullptr); std::vector certChain; certChain.push_back(std::move(certData.cert)); - auto cert = std::make_unique>( + auto cert = std::make_unique>( std::move(certData.key), std::move(certChain), compressors); certManager->addCert(std::move(cert), true); }