From 3b2468f5f6d4dda0a9147e71294d12462a1eff13 Mon Sep 17 00:00:00 2001 From: Zale Young Date: Thu, 25 Apr 2024 18:36:46 -0700 Subject: [PATCH] move openssl crypto components to fizz/backend/openssl Summary: As part of the work to decouple openssl from fizz, this diff begins to move openssl related component within fizz to `fizz/backend/openssl`. It also exposes all the openssl dependencies through a single target `fizz/backend:openssl`. Eventually, everything that wants to directly use openssl functionality can depend on that target. This commit will change everything *within* fizz to use the new `openssl::` namespace for the classes that have been moved, but external dependencies still reference the old `fizz::` namespace classes. To maintain compatibility we've added type aliases `fizz::A` to point to `fizz::openssl::A`. Next steps: - convert dependencies to use the new namespace - remove the old files. After that: - A few components need to be moved back out of the `backend/openssl` folder. Like the AES and Sha types. We need to split the openssl info out of those types. Slightly easier to do this in a separate change. - There are still a few things that still need to get moved behind backend/openssl, like DefaultCertificateVerifier and some operations that need to become openssl primitives and get used through the Factory rather than used directly. Reviewed By: mingtaoy Differential Revision: D56274868 fbshipit-source-id: 7ed7473fbe8ebe69b413d02d96a0b0fd85b0eebe --- fizz/CMakeLists.txt | 34 +- fizz/backend/openssl/OpenSSL.h | 36 + .../openssl}/OpenSSLFactory.cpp | 12 +- fizz/backend/openssl/OpenSSLFactory.h | 48 + .../openssl/certificate}/CertUtils-inl.h | 2 + .../openssl/certificate}/CertUtils.cpp | 8 +- fizz/backend/openssl/certificate/CertUtils.h | 100 ++ .../certificate}/OpenSSLPeerCertImpl-inl.h | 4 +- .../openssl/certificate/OpenSSLPeerCertImpl.h | 46 + .../certificate}/OpenSSLSelfCertImpl-inl.h | 4 +- .../openssl/certificate/OpenSSLSelfCertImpl.h | 68 + fizz/backend/openssl/crypto/ECCurve.h | 38 + fizz/backend/openssl/crypto/OpenSSL.h | 7 + .../openssl/crypto}/OpenSSLKeyUtils.cpp | 4 +- fizz/backend/openssl/crypto/OpenSSLKeyUtils.h | 85 ++ fizz/{ => backend/openssl}/crypto/Sha-inl.h | 2 + fizz/backend/openssl/crypto/Sha.h | 55 + fizz/{ => backend/openssl}/crypto/Sha256.cpp | 4 +- fizz/backend/openssl/crypto/Sha256.h | 28 + fizz/{ => backend/openssl}/crypto/Sha384.cpp | 4 +- fizz/backend/openssl/crypto/Sha384.h | 28 + fizz/{ => backend/openssl}/crypto/Sha512.cpp | 4 +- fizz/backend/openssl/crypto/Sha512.h | 28 + fizz/backend/openssl/crypto/aead/AESGCM128.h | 27 + fizz/backend/openssl/crypto/aead/AESGCM256.h | 27 + fizz/backend/openssl/crypto/aead/AESOCB128.h | 36 + .../openssl/crypto/aead/ChaCha20Poly1305.h | 37 + .../crypto/aead/OpenSSLEVPCipher-inl.h | 2 + .../openssl}/crypto/aead/OpenSSLEVPCipher.cpp | 4 +- .../openssl/crypto/aead/OpenSSLEVPCipher.h | 132 ++ .../crypto/aead/test/EVPCipherTest.cpp | 1106 +++++++++++++++++ .../crypto/exchange/ECCurveKeyExchange.h | 30 + .../crypto/exchange/OpenSSLKeyExchange-inl.h | 4 +- .../crypto/exchange/OpenSSLKeyExchange.h | 52 + .../exchange/test/ECKeyExchangeTest.cpp | 500 ++++++++ .../openssl}/crypto/signature/Signature-inl.h | 4 +- .../openssl}/crypto/signature/Signature.cpp | 6 +- .../openssl/crypto/signature/Signature.h | 70 ++ .../crypto/signature/test/ECSignatureTest.cpp | 221 ++++ .../crypto/signature/test/EdSignatureTest.cpp | 145 +++ .../crypto/signature/test/EdSignatureTest.h | 103 ++ .../signature/test/RSAPSSSignatureTest.cpp | 70 ++ .../crypto/test/OpenSSLKeyUtilsTest.cpp | 67 + fizz/client/FizzClientContext.cpp | 4 +- .../test/BrotliCertificateCompressorTest.cpp | 7 +- .../test/ZlibCertificateCompressorTest.cpp | 7 +- .../test/ZstdCertificateCompressorTest.cpp | 7 +- fizz/crypto/ECCurve.h | 25 +- fizz/crypto/Sha.h | 39 +- fizz/crypto/Sha256.h | 12 +- fizz/crypto/Sha384.h | 12 +- fizz/crypto/Sha512.h | 12 +- fizz/crypto/aead/AESGCM128.h | 14 +- fizz/crypto/aead/AESGCM256.h | 14 +- fizz/crypto/aead/AESOCB128.h | 23 +- fizz/crypto/aead/ChaCha20Poly1305.h | 24 +- fizz/crypto/aead/OpenSSLEVPCipher.h | 116 +- fizz/crypto/exchange/ECCurveKeyExchange.h | 21 +- fizz/crypto/exchange/OpenSSLKeyExchange.h | 37 +- fizz/crypto/hpke/Context.h | 2 +- fizz/crypto/hpke/DHKEM.h | 2 + fizz/crypto/hpke/Hpke.cpp | 2 +- fizz/crypto/hpke/Utils.cpp | 27 +- fizz/crypto/hpke/test/ContextTest.cpp | 16 +- fizz/crypto/hpke/test/DHKEMTest.cpp | 20 +- fizz/crypto/hpke/test/HpkeTest.cpp | 48 +- fizz/crypto/openssl/OpenSSL.h | 4 +- fizz/crypto/openssl/OpenSSLKeyUtils.h | 72 +- fizz/crypto/signature/Signature.h | 65 +- fizz/crypto/test/HkdfTest.cpp | 4 +- fizz/crypto/test/KeyDerivationTest.cpp | 25 +- fizz/crypto/test/TestUtil.cpp | 15 +- fizz/experimental/batcher/Batcher.h | 4 +- .../experimental/batcher/test/BatcherTest.cpp | 61 +- .../client/BatchSignaturePeerCert.cpp | 7 +- .../client/BatchSignaturePeerCert.h | 2 +- .../test/BatchSignaturePeerCertTest.cpp | 51 +- fizz/experimental/crypto/MerkleTree.h | 5 +- .../crypto/test/BatchSignatureTest.cpp | 4 +- .../crypto/test/MerkleTreeTest.cpp | 22 +- fizz/experimental/ktls/KTLS.cpp | 11 +- .../ktls/test/AsyncFizzBaseKTLSTest.cpp | 4 +- .../ktls/test/AsyncKTLSRxSocketTest.cpp | 5 +- .../ktls/test/AsyncKTLSSocketTest.cpp | 5 +- fizz/experimental/ktls/test/KTLSTest.cpp | 7 +- .../protocol/BatchSignatureTypes.cpp | 3 +- .../protocol/BatchSignatureTypes.h | 5 +- .../protocol/test/BatchSignatureTypesTest.cpp | 2 +- .../server/BatchSignatureAsyncSelfCert.h | 2 +- .../test/BatchSignatureAsyncSelfCertTest.cpp | 45 +- .../DelegatedCredentialFactory.cpp | 29 +- .../DelegatedCredentialFactory.h | 3 +- .../DelegatedCredentialUtils.cpp | 29 +- .../PeerDelegatedCredential-inl.h | 9 +- .../delegatedcred/PeerDelegatedCredential.h | 2 +- .../SelfDelegatedCredential-inl.h | 30 +- .../delegatedcred/SelfDelegatedCredential.h | 17 +- .../test/DelegatedCredentialFactoryTest.cpp | 13 +- .../test/PeerDelegatedCredentialTest.cpp | 38 +- .../test/SelfDelegatedCredentialTest.cpp | 35 +- .../exportedauth/ExportedAuthenticator.cpp | 10 +- .../test/ExportedAuthenticatorTest.cpp | 10 +- .../extensions/javacrypto/JavaCryptoFactory.h | 3 +- .../javacrypto/JavaCryptoPeerCert.cpp | 4 +- .../javacrypto/JavaCryptoPeerCert.h | 1 + .../tokenbinding/TokenBindingConstructor.cpp | 9 +- fizz/extensions/tokenbinding/Validator.cpp | 18 +- fizz/extensions/tokenbinding/Validator.h | 1 + fizz/protocol/CertUtils.h | 85 +- fizz/protocol/OpenSSLFactory.h | 21 +- fizz/protocol/OpenSSLPeerCertImpl.h | 27 +- fizz/protocol/OpenSSLSelfCertImpl.h | 48 +- fizz/protocol/Types.cpp | 6 +- fizz/protocol/ech/Encryption.cpp | 16 +- fizz/protocol/ech/test/DecrypterTest.cpp | 12 +- fizz/protocol/ech/test/EncryptionTest.cpp | 3 +- fizz/protocol/ech/test/TestUtil.cpp | 2 +- fizz/record/test/EncryptedRecordBench.cpp | 18 +- fizz/server/AeadTokenCipher.h | 7 +- fizz/server/CookieTypes.h | 1 + fizz/server/FizzServerContext.cpp | 4 +- fizz/server/TicketTypes.h | 1 + fizz/server/test/TicketCodecTest.cpp | 2 +- fizz/server/test/Utils.h | 12 +- fizz/test/BogoShim.cpp | 16 +- fizz/test/HandshakeTest.cpp | 21 +- fizz/test/HandshakeTest.h | 27 +- fizz/tool/FizzClientCommand.cpp | 8 +- fizz/tool/FizzCommandCommon.cpp | 9 +- ...FizzGenerateDelegatedCredentialCommand.cpp | 42 +- fizz/tool/FizzServerBenchmarkCommand.cpp | 20 +- fizz/tool/FizzServerCommand.cpp | 51 +- fizz/tool/test/FizzCommandCommonTest.cpp | 6 +- fizz/util/FizzUtil.cpp | 9 +- fizz/util/test/FizzUtilTest.cpp | 2 +- 135 files changed, 3887 insertions(+), 1063 deletions(-) create mode 100644 fizz/backend/openssl/OpenSSL.h rename fizz/{protocol => backend/openssl}/OpenSSLFactory.cpp (94%) create mode 100644 fizz/backend/openssl/OpenSSLFactory.h rename fizz/{protocol => backend/openssl/certificate}/CertUtils-inl.h (96%) rename fizz/{protocol => backend/openssl/certificate}/CertUtils.cpp (97%) create mode 100644 fizz/backend/openssl/certificate/CertUtils.h rename fizz/{protocol => backend/openssl/certificate}/OpenSSLPeerCertImpl-inl.h (97%) create mode 100644 fizz/backend/openssl/certificate/OpenSSLPeerCertImpl.h rename fizz/{protocol => backend/openssl/certificate}/OpenSSLSelfCertImpl-inl.h (98%) create mode 100644 fizz/backend/openssl/certificate/OpenSSLSelfCertImpl.h create mode 100644 fizz/backend/openssl/crypto/ECCurve.h create mode 100644 fizz/backend/openssl/crypto/OpenSSL.h rename fizz/{crypto/openssl => backend/openssl/crypto}/OpenSSLKeyUtils.cpp (98%) create mode 100644 fizz/backend/openssl/crypto/OpenSSLKeyUtils.h rename fizz/{ => backend/openssl}/crypto/Sha-inl.h (96%) create mode 100644 fizz/backend/openssl/crypto/Sha.h rename fizz/{ => backend/openssl}/crypto/Sha256.cpp (69%) create mode 100644 fizz/backend/openssl/crypto/Sha256.h rename fizz/{ => backend/openssl}/crypto/Sha384.cpp (69%) create mode 100644 fizz/backend/openssl/crypto/Sha384.h rename fizz/{ => backend/openssl}/crypto/Sha512.cpp (69%) create mode 100644 fizz/backend/openssl/crypto/Sha512.h create mode 100644 fizz/backend/openssl/crypto/aead/AESGCM128.h create mode 100644 fizz/backend/openssl/crypto/aead/AESGCM256.h create mode 100644 fizz/backend/openssl/crypto/aead/AESOCB128.h create mode 100644 fizz/backend/openssl/crypto/aead/ChaCha20Poly1305.h rename fizz/{ => backend/openssl}/crypto/aead/OpenSSLEVPCipher-inl.h (94%) rename fizz/{ => backend/openssl}/crypto/aead/OpenSSLEVPCipher.cpp (99%) create mode 100644 fizz/backend/openssl/crypto/aead/OpenSSLEVPCipher.h create mode 100644 fizz/backend/openssl/crypto/aead/test/EVPCipherTest.cpp create mode 100644 fizz/backend/openssl/crypto/exchange/ECCurveKeyExchange.h rename fizz/{ => backend/openssl}/crypto/exchange/OpenSSLKeyExchange-inl.h (96%) create mode 100644 fizz/backend/openssl/crypto/exchange/OpenSSLKeyExchange.h create mode 100644 fizz/backend/openssl/crypto/exchange/test/ECKeyExchangeTest.cpp rename fizz/{ => backend/openssl}/crypto/signature/Signature-inl.h (98%) rename fizz/{ => backend/openssl}/crypto/signature/Signature.cpp (97%) create mode 100644 fizz/backend/openssl/crypto/signature/Signature.h create mode 100644 fizz/backend/openssl/crypto/signature/test/ECSignatureTest.cpp create mode 100644 fizz/backend/openssl/crypto/signature/test/EdSignatureTest.cpp create mode 100644 fizz/backend/openssl/crypto/signature/test/EdSignatureTest.h create mode 100644 fizz/backend/openssl/crypto/signature/test/RSAPSSSignatureTest.cpp create mode 100644 fizz/backend/openssl/crypto/test/OpenSSLKeyUtilsTest.cpp diff --git a/fizz/CMakeLists.txt b/fizz/CMakeLists.txt index 56adfe0a8c2..a05b1a20927 100644 --- a/fizz/CMakeLists.txt +++ b/fizz/CMakeLists.txt @@ -110,15 +110,21 @@ configure_file(fizz-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/generated/fizz/fizz- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/generated/fizz/fizz-config.h DESTINATION ${INCLUDE_INSTALL_DIR}/fizz/) set(FIZZ_HEADER_DIRS + backend + backend/openssl + backend/openssl/crypto + backend/openssl/crypto/aead + backend/openssl/crypto/exchange + backend/openssl/crypto/signature client compression crypto crypto/aead - crypto/exchange - crypto/hpke crypto/signature crypto/openssl experimental/crypto/exchange + crypto/exchange + crypto/hpke experimental/ktls experimental/util extensions/delegatedcred @@ -172,20 +178,20 @@ set(FIZZ_SOURCES crypto/Utils.cpp crypto/exchange/HybridKeyExchange.cpp crypto/exchange/X25519.cpp - crypto/aead/OpenSSLEVPCipher.cpp + backend/openssl/crypto/aead/OpenSSLEVPCipher.cpp crypto/aead/IOBufUtil.cpp crypto/aead/AEGISCipher.cpp - crypto/signature/Signature.cpp + backend/openssl/crypto/signature/Signature.cpp crypto/Hkdf.cpp crypto/KeyDerivation.cpp - crypto/Sha256.cpp - crypto/Sha384.cpp + backend/openssl/crypto/Sha256.cpp + backend/openssl/crypto/Sha384.cpp crypto/hpke/Context.cpp crypto/hpke/DHKEM.cpp crypto/hpke/Hkdf.cpp crypto/hpke/Hpke.cpp crypto/hpke/Utils.cpp - crypto/openssl/OpenSSLKeyUtils.cpp + backend/openssl/crypto/OpenSSLKeyUtils.cpp record/Types.cpp record/RecordLayer.cpp record/EncryptedRecordLayer.cpp @@ -209,8 +215,8 @@ set(FIZZ_SOURCES protocol/Events.cpp protocol/KeyScheduler.cpp protocol/Certificate.cpp - protocol/CertUtils.cpp - protocol/OpenSSLFactory.cpp + backend/openssl/certificate/CertUtils.cpp + backend/openssl/OpenSSLFactory.cpp protocol/Params.cpp protocol/clock/SystemClock.cpp protocol/ech/Decrypter.cpp @@ -427,16 +433,16 @@ if(BUILD_TESTS) add_gtest(client/test/FizzClientTest.cpp FizzClientTest) add_gtest(compression/test/CertDecompressionManagerTest.cpp CertDecompressionManagerTest) add_gtest(compression/test/ZlibCertificateCompressorTest.cpp ZlibCertificateCompressorTest) - add_gtest(crypto/aead/test/EVPCipherTest.cpp EVPCipherTest) + add_gtest(backend/openssl/crypto/aead/test/EVPCipherTest.cpp EVPCipherTest) add_gtest(crypto/aead/test/IOBufUtilTest.cpp IOBufUtilTest) add_gtest(crypto/exchange/test/X25519KeyExchangeTest.cpp X25519KeyExchangeTest) - add_gtest(crypto/exchange/test/ECKeyExchangeTest.cpp ECKeyExchangeTest) + add_gtest(backend/openssl/crypto/exchange/test/ECKeyExchangeTest.cpp ECKeyExchangeTest) add_gtest(crypto/hpke/test/ContextTest.cpp ContextTest) add_gtest(crypto/hpke/test/DHKEMTest.cpp DHKEMTest) add_gtest(crypto/hpke/test/HpkeTest.cpp HpkeTest) - add_gtest(crypto/openssl/test/OpenSSLKeyUtilsTest.cpp OpenSSLKeyUtilsTest) - add_gtest(crypto/signature/test/RSAPSSSignatureTest.cpp RSAPSSSignatureTest) - add_gtest(crypto/signature/test/ECSignatureTest.cpp ECSignatureTest) + add_gtest(backend/openssl/crypto/test/OpenSSLKeyUtilsTest.cpp OpenSSLKeyUtilsTest) + add_gtest(backend/openssl/crypto/signature/test/RSAPSSSignatureTest.cpp RSAPSSSignatureTest) + add_gtest(backend/openssl/crypto/signature/test/ECSignatureTest.cpp ECSignatureTest) add_gtest(crypto/test/HkdfTest.cpp HkdfTest) add_gtest(crypto/test/KeyDerivationTest.cpp KeyDerivationTest) add_gtest(crypto/test/RandomGeneratorTest.cpp RandomGeneratorTest) diff --git a/fizz/backend/openssl/OpenSSL.h b/fizz/backend/openssl/OpenSSL.h new file mode 100644 index 00000000000..0e81e39098d --- /dev/null +++ b/fizz/backend/openssl/OpenSSL.h @@ -0,0 +1,36 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#pragma once + +/* + +This is the backend for the openssl crypto implementations. +Include this file to use openssl features. + +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CREATE_FIZZ_FN_ALIAS(newname, oldname) \ + template \ + auto newname(Args&&... args) { \ + return oldname(std::forward(args)...); \ + } diff --git a/fizz/protocol/OpenSSLFactory.cpp b/fizz/backend/openssl/OpenSSLFactory.cpp similarity index 94% rename from fizz/protocol/OpenSSLFactory.cpp rename to fizz/backend/openssl/OpenSSLFactory.cpp index abefccaf039..479bfccc13a 100644 --- a/fizz/protocol/OpenSSLFactory.cpp +++ b/fizz/backend/openssl/OpenSSLFactory.cpp @@ -6,14 +6,21 @@ * LICENSE file in the root directory of this source tree. */ -#include -#include +#include +#include +#include + #if FIZZ_HAVE_OQS #include #include #endif +#if FIZZ_BUILD_AEGIS +#include +#endif + namespace fizz { +namespace openssl { std::unique_ptr OpenSSLFactory::makeKeyExchange( NamedGroup group, @@ -119,4 +126,5 @@ std::unique_ptr OpenSSLFactory::makePeerCert( return CertUtils::makePeerCert(std::move(certEntry.cert_data)); } +} // namespace openssl } // namespace fizz diff --git a/fizz/backend/openssl/OpenSSLFactory.h b/fizz/backend/openssl/OpenSSLFactory.h new file mode 100644 index 00000000000..6e9e6542066 --- /dev/null +++ b/fizz/backend/openssl/OpenSSLFactory.h @@ -0,0 +1,48 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +namespace fizz { +class PeerCert; +namespace openssl { + +class OpenSSLFactory : public DefaultFactory { + public: + [[nodiscard]] std::unique_ptr makeKeyExchange( + NamedGroup group, + KeyExchangeMode mode) const override; + + [[nodiscard]] std::unique_ptr makeAead( + CipherSuite cipher) const override; + + std::unique_ptr makeKeyDeriver( + CipherSuite cipher) const override; + + std::unique_ptr makeHandshakeContext( + CipherSuite cipher) const override; + + [[nodiscard]] std::unique_ptr makePeerCert( + CertificateEntry certEntry, + bool /*leaf*/) const override; +}; +} // namespace openssl +} // namespace fizz diff --git a/fizz/protocol/CertUtils-inl.h b/fizz/backend/openssl/certificate/CertUtils-inl.h similarity index 96% rename from fizz/protocol/CertUtils-inl.h rename to fizz/backend/openssl/certificate/CertUtils-inl.h index 39c40898b18..3c70d70c3fa 100644 --- a/fizz/protocol/CertUtils-inl.h +++ b/fizz/backend/openssl/certificate/CertUtils-inl.h @@ -7,6 +7,7 @@ */ namespace fizz { +namespace openssl { namespace detail { folly::Optional getIdentityFromX509(X509* x); @@ -37,4 +38,5 @@ inline std::vector CertUtils::getSigSchemes() { return {SignatureScheme::ed25519}; } +} // namespace openssl } // namespace fizz diff --git a/fizz/protocol/CertUtils.cpp b/fizz/backend/openssl/certificate/CertUtils.cpp similarity index 97% rename from fizz/protocol/CertUtils.cpp rename to fizz/backend/openssl/certificate/CertUtils.cpp index c33ff00557d..4230f8956d2 100644 --- a/fizz/protocol/CertUtils.cpp +++ b/fizz/backend/openssl/certificate/CertUtils.cpp @@ -6,10 +6,10 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include +#include +#include #include -#include -#include #include #include @@ -24,6 +24,7 @@ int getCurveName(EVP_PKEY* key) { } // namespace namespace fizz { +namespace openssl { namespace detail { @@ -297,4 +298,5 @@ CompressedCertificate CertUtils::cloneCompressedCert( return ret; } +} // namespace openssl } // namespace fizz diff --git a/fizz/backend/openssl/certificate/CertUtils.h b/fizz/backend/openssl/certificate/CertUtils.h new file mode 100644 index 00000000000..13970217f07 --- /dev/null +++ b/fizz/backend/openssl/certificate/CertUtils.h @@ -0,0 +1,100 @@ +/* + * 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; + +namespace openssl { + +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 openssl +} // namespace fizz + +#include diff --git a/fizz/protocol/OpenSSLPeerCertImpl-inl.h b/fizz/backend/openssl/certificate/OpenSSLPeerCertImpl-inl.h similarity index 97% rename from fizz/protocol/OpenSSLPeerCertImpl-inl.h rename to fizz/backend/openssl/certificate/OpenSSLPeerCertImpl-inl.h index e12efc118d0..7bf9157ff03 100644 --- a/fizz/protocol/OpenSSLPeerCertImpl-inl.h +++ b/fizz/backend/openssl/certificate/OpenSSLPeerCertImpl-inl.h @@ -8,11 +8,12 @@ #pragma once -#include +#include #include #include namespace fizz { +namespace openssl { namespace detail { extern folly::Optional getIdentityFromX509(X509* x); @@ -118,4 +119,5 @@ folly::ssl::X509UniquePtr OpenSSLPeerCertImpl::getX509() const { X509_up_ref(cert_.get()); return folly::ssl::X509UniquePtr(cert_.get()); } +} // namespace openssl } // namespace fizz diff --git a/fizz/backend/openssl/certificate/OpenSSLPeerCertImpl.h b/fizz/backend/openssl/certificate/OpenSSLPeerCertImpl.h new file mode 100644 index 00000000000..9b633cfef78 --- /dev/null +++ b/fizz/backend/openssl/certificate/OpenSSLPeerCertImpl.h @@ -0,0 +1,46 @@ +/* + * 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 { +class PeerCert; +enum class CertificateVerifyContext; + +namespace openssl { + +template +class OpenSSLPeerCertImpl : public fizz::PeerCert { + public: + explicit OpenSSLPeerCertImpl(folly::ssl::X509UniquePtr cert); + + ~OpenSSLPeerCertImpl() override = default; + + [[nodiscard]] std::string getIdentity() const override; + + void verify( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned, + folly::ByteRange signature) const override; + + [[nodiscard]] folly::ssl::X509UniquePtr getX509() const override; + + protected: + OpenSSLSignature signature_; + folly::ssl::X509UniquePtr cert_; +}; + +} // namespace openssl +} // namespace fizz + +#include diff --git a/fizz/protocol/OpenSSLSelfCertImpl-inl.h b/fizz/backend/openssl/certificate/OpenSSLSelfCertImpl-inl.h similarity index 98% rename from fizz/protocol/OpenSSLSelfCertImpl-inl.h rename to fizz/backend/openssl/certificate/OpenSSLSelfCertImpl-inl.h index 60731ea72b8..fb61214e46f 100644 --- a/fizz/protocol/OpenSSLSelfCertImpl-inl.h +++ b/fizz/backend/openssl/certificate/OpenSSLSelfCertImpl-inl.h @@ -8,12 +8,13 @@ #pragma once -#include +#include #include #include #include namespace fizz { +namespace openssl { namespace detail { extern folly::Optional getIdentityFromX509(X509* x); @@ -153,4 +154,5 @@ folly::ssl::X509UniquePtr OpenSSLSelfCertImpl::getX509() const { return folly::ssl::X509UniquePtr(certs_.front().get()); } +} // namespace openssl } // namespace fizz diff --git a/fizz/backend/openssl/certificate/OpenSSLSelfCertImpl.h b/fizz/backend/openssl/certificate/OpenSSLSelfCertImpl.h new file mode 100644 index 00000000000..b2de66319c8 --- /dev/null +++ b/fizz/backend/openssl/certificate/OpenSSLSelfCertImpl.h @@ -0,0 +1,68 @@ +/* + * 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; +enum class CertificateVerifyContext; + +namespace openssl { + +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; + + [[nodiscard]] std::string getIdentity() const override; + + [[nodiscard]] std::vector getAltIdentities() const override; + + [[nodiscard]] std::vector getSigSchemes() const override; + + [[nodiscard]] CertificateMsg getCertMessage( + Buf certificateRequestContext = nullptr) const override; + + [[nodiscard]] CompressedCertificate getCompressedCert( + CertificateCompressionAlgorithm algo) const override; + + [[nodiscard]] Buf sign( + SignatureScheme scheme, + CertificateVerifyContext context, + folly::ByteRange toBeSigned) const override; + + [[nodiscard]] 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 openssl +} // namespace fizz + +#include diff --git a/fizz/backend/openssl/crypto/ECCurve.h b/fizz/backend/openssl/crypto/ECCurve.h new file mode 100644 index 00000000000..0034380752e --- /dev/null +++ b/fizz/backend/openssl/crypto/ECCurve.h @@ -0,0 +1,38 @@ +/* + * 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 + +namespace fizz { +namespace openssl { + +struct P256 { + static const int curveNid{NID_X9_62_prime256v1}; + /** + * See RFC8446 Section 4.2.8.2 + */ + static const int coordinateLength = 32; + static const int keyShareLength = coordinateLength * 2 + 1; +}; + +struct P384 { + static const int curveNid{NID_secp384r1}; + static const int coordinateLength = 48; + static const int keyShareLength = coordinateLength * 2 + 1; +}; + +struct P521 { + static const int curveNid{NID_secp521r1}; + static const int coordinateLength = 66; + static const int keyShareLength = coordinateLength * 2 + 1; +}; + +} // namespace openssl +} // namespace fizz diff --git a/fizz/backend/openssl/crypto/OpenSSL.h b/fizz/backend/openssl/crypto/OpenSSL.h new file mode 100644 index 00000000000..3c3a1bd3d30 --- /dev/null +++ b/fizz/backend/openssl/crypto/OpenSSL.h @@ -0,0 +1,7 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#pragma once + +#include + +#define FIZZ_OPENSSL_HAS_ED25519 (OPENSSL_VERSION_NUMBER >= 0x10101000L) diff --git a/fizz/crypto/openssl/OpenSSLKeyUtils.cpp b/fizz/backend/openssl/crypto/OpenSSLKeyUtils.cpp similarity index 98% rename from fizz/crypto/openssl/OpenSSLKeyUtils.cpp rename to fizz/backend/openssl/crypto/OpenSSLKeyUtils.cpp index 6f5fbb060c3..c922c4d4308 100644 --- a/fizz/crypto/openssl/OpenSSLKeyUtils.cpp +++ b/fizz/backend/openssl/crypto/OpenSSLKeyUtils.cpp @@ -6,11 +6,12 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include #include namespace fizz { +namespace openssl { /*static*/ folly::ssl::EvpPkeyUniquePtr OpenSSLKeyUtils::generateECKeyPair( int curveNid) { @@ -172,4 +173,5 @@ std::string getOpenSSLError() { return std::string(errMsg); } } // namespace detail +} // namespace openssl } // namespace fizz diff --git a/fizz/backend/openssl/crypto/OpenSSLKeyUtils.h b/fizz/backend/openssl/crypto/OpenSSLKeyUtils.h new file mode 100644 index 00000000000..98548902da0 --- /dev/null +++ b/fizz/backend/openssl/crypto/OpenSSLKeyUtils.h @@ -0,0 +1,85 @@ +/* + * 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 openssl { + +class OpenSSLKeyUtils { + public: + /** + * Generates an new EVP_PKEY on the curve. + * Throws an exception on error. + * + * This is a public interface to the namespaced private method below. + */ + static folly::ssl::EvpPkeyUniquePtr generateECKeyPair(int curveNid); +}; + +namespace detail { + +/** + * Validates whether or not the EVP_PKEY belongs to the + * curve. If not, this throws an exception. + */ +void validateECKey(const folly::ssl::EvpPkeyUniquePtr& key, int curveNid); + +#if FIZZ_OPENSSL_HAS_ED25519 +/** + * Validates whether or not the EVP_PKEY belongs to the + * Edwards curve (currently supports only Ed25519 & Ed448). + * If not, this throws an exception. + */ +void validateEdKey(const folly::ssl::EvpPkeyUniquePtr& key, int curveNid); +#endif + +/** + * Generates an new EVP_PKEY on the curve. + * Throws an exception on error. + */ +folly::ssl::EvpPkeyUniquePtr generateECKeyPair(int curveNid); + +/** + * Decodes a EC public key specified as a member of the curve + * curveNid. + */ +folly::ssl::EvpPkeyUniquePtr decodeECPublicKey( + folly::ByteRange range, + int curveNid); + +/** + * Encodes the public key and returns a buffer. + */ + +std::unique_ptr encodeECPublicKey( + const folly::ssl::EvpPkeyUniquePtr& key); + +std::unique_ptr encodeECPublicKey( + const folly::ssl::EcKeyUniquePtr& ecKey); + +/** + * Generates a shared secred from a private key, key and the + * peerKey public key. + */ +std::unique_ptr generateEvpSharedSecret( + const folly::ssl::EvpPkeyUniquePtr& key, + const folly::ssl::EvpPkeyUniquePtr& peerKey); + +/** + * Returns the current error in the thread queue as a string. + */ +std::string getOpenSSLError(); +} // namespace detail +} // namespace openssl +} // namespace fizz diff --git a/fizz/crypto/Sha-inl.h b/fizz/backend/openssl/crypto/Sha-inl.h similarity index 96% rename from fizz/crypto/Sha-inl.h rename to fizz/backend/openssl/crypto/Sha-inl.h index f9b3df4f536..7e94278c3ba 100644 --- a/fizz/crypto/Sha-inl.h +++ b/fizz/backend/openssl/crypto/Sha-inl.h @@ -9,6 +9,7 @@ #pragma once namespace fizz { +namespace openssl { template void Sha::hash_init() { @@ -44,4 +45,5 @@ void Sha::hash(const folly::IOBuf& in, folly::MutableByteRange out) { CHECK_GE(out.size(), T::HashLen); folly::ssl::OpenSSLHash::hash(out, T::HashEngine(), in); } +} // namespace openssl } // namespace fizz diff --git a/fizz/backend/openssl/crypto/Sha.h b/fizz/backend/openssl/crypto/Sha.h new file mode 100644 index 00000000000..783bfff89dd --- /dev/null +++ b/fizz/backend/openssl/crypto/Sha.h @@ -0,0 +1,55 @@ +/* + * 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 openssl { + +/** + * Hash implementation using OpenSSL. + * + * The template struct requires the following parameters: + * - HashLen: length of the hash digest + * - HashEngine: function returning EVP_MD* to use + * - BlankHash: ByteRange containing the digest of a hash of empty input + */ +template +class Sha { + public: + void hash_init(); + + void hash_update(folly::ByteRange data); + + void hash_update(const folly::IOBuf& data); + + void hash_final(folly::MutableByteRange out); + + /** + * Puts HMAC(key, in) into out. Out must be at least of size HashLen. + */ + static void hmac( + folly::ByteRange key, + const folly::IOBuf& in, + folly::MutableByteRange out); + + /** + * Puts Hash(in) into out. Out must be at least of size HashLen. + */ + static void hash(const folly::IOBuf& in, folly::MutableByteRange out); + + private: + folly::ssl::OpenSSLHash::Digest digest_; +}; +} // namespace openssl +} // namespace fizz +#include diff --git a/fizz/crypto/Sha256.cpp b/fizz/backend/openssl/crypto/Sha256.cpp similarity index 69% rename from fizz/crypto/Sha256.cpp rename to fizz/backend/openssl/crypto/Sha256.cpp index e7d8d34cc11..297858fdef7 100644 --- a/fizz/crypto/Sha256.cpp +++ b/fizz/backend/openssl/crypto/Sha256.cpp @@ -6,8 +6,8 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include #if __cplusplus < 201703L -constexpr folly::StringPiece fizz::Sha256::BlankHash; +constexpr folly::StringPiece fizz::openssl::Sha256::BlankHash; #endif diff --git a/fizz/backend/openssl/crypto/Sha256.h b/fizz/backend/openssl/crypto/Sha256.h new file mode 100644 index 00000000000..8e62eef47ad --- /dev/null +++ b/fizz/backend/openssl/crypto/Sha256.h @@ -0,0 +1,28 @@ +/* + * 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 openssl { + +class Sha256 : public Sha { + public: + static constexpr size_t HashLen = 32; + + static constexpr auto HashEngine = EVP_sha256; + + static constexpr folly::StringPiece BlankHash{ + "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55"}; +}; +} // namespace openssl +} // namespace fizz diff --git a/fizz/crypto/Sha384.cpp b/fizz/backend/openssl/crypto/Sha384.cpp similarity index 69% rename from fizz/crypto/Sha384.cpp rename to fizz/backend/openssl/crypto/Sha384.cpp index a51abad4df9..bbf9fb5cb19 100644 --- a/fizz/crypto/Sha384.cpp +++ b/fizz/backend/openssl/crypto/Sha384.cpp @@ -6,8 +6,8 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include #if __cplusplus < 201703L -constexpr folly::StringPiece fizz::Sha384::BlankHash; +constexpr folly::StringPiece fizz::openssl::Sha384::BlankHash; #endif diff --git a/fizz/backend/openssl/crypto/Sha384.h b/fizz/backend/openssl/crypto/Sha384.h new file mode 100644 index 00000000000..dd0a0504bd6 --- /dev/null +++ b/fizz/backend/openssl/crypto/Sha384.h @@ -0,0 +1,28 @@ +/* + * 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 openssl { + +class Sha384 : public Sha { + public: + static constexpr size_t HashLen = 48; + + static constexpr auto HashEngine = EVP_sha384; + + static constexpr folly::StringPiece BlankHash{ + "\x38\xb0\x60\xa7\x51\xac\x96\x38\x4c\xd9\x32\x7e\xb1\xb1\xe3\x6a\x21\xfd\xb7\x11\x14\xbe\x07\x43\x4c\x0c\xc7\xbf\x63\xf6\xe1\xda\x27\x4e\xde\xbf\xe7\x6f\x65\xfb\xd5\x1a\xd2\xf1\x48\x98\xb9\x5b"}; +}; +} // namespace openssl +} // namespace fizz diff --git a/fizz/crypto/Sha512.cpp b/fizz/backend/openssl/crypto/Sha512.cpp similarity index 69% rename from fizz/crypto/Sha512.cpp rename to fizz/backend/openssl/crypto/Sha512.cpp index 2113731f0b0..e71bfa90c2a 100644 --- a/fizz/crypto/Sha512.cpp +++ b/fizz/backend/openssl/crypto/Sha512.cpp @@ -6,8 +6,8 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include #if __cplusplus < 201703L -constexpr folly::StringPiece fizz::Sha512::BlankHash; +constexpr folly::StringPiece fizz::openssl::Sha512::BlankHash; #endif diff --git a/fizz/backend/openssl/crypto/Sha512.h b/fizz/backend/openssl/crypto/Sha512.h new file mode 100644 index 00000000000..3dab4950710 --- /dev/null +++ b/fizz/backend/openssl/crypto/Sha512.h @@ -0,0 +1,28 @@ +/* + * 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 openssl { + +class Sha512 : public Sha { + public: + static constexpr size_t HashLen = 64; + + static constexpr auto HashEngine = EVP_sha512; + + static constexpr folly::StringPiece BlankHash{ + "\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e"}; +}; +} // namespace openssl +} // namespace fizz diff --git a/fizz/backend/openssl/crypto/aead/AESGCM128.h b/fizz/backend/openssl/crypto/aead/AESGCM128.h new file mode 100644 index 00000000000..c243012a3c4 --- /dev/null +++ b/fizz/backend/openssl/crypto/aead/AESGCM128.h @@ -0,0 +1,27 @@ +/* + * 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 + +namespace fizz { +namespace openssl { + +struct AESGCM128 { + static constexpr auto Cipher = EVP_aes_128_gcm; + + static const size_t kKeyLength{16}; + static const size_t kIVLength{12}; + static const size_t kTagLength{16}; + static const bool kOperatesInBlocks{false}; + static const bool kRequiresPresetTagLen{false}; +}; + +} // namespace openssl +} // namespace fizz diff --git a/fizz/backend/openssl/crypto/aead/AESGCM256.h b/fizz/backend/openssl/crypto/aead/AESGCM256.h new file mode 100644 index 00000000000..76fd5d17d6b --- /dev/null +++ b/fizz/backend/openssl/crypto/aead/AESGCM256.h @@ -0,0 +1,27 @@ +/* + * 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 + +namespace fizz { +namespace openssl { + +struct AESGCM256 { + static constexpr auto Cipher = EVP_aes_256_gcm; + + static const size_t kKeyLength{32}; + static const size_t kIVLength{12}; + static const size_t kTagLength{16}; + static const bool kOperatesInBlocks{false}; + static const bool kRequiresPresetTagLen{false}; +}; + +} // namespace openssl +} // namespace fizz diff --git a/fizz/backend/openssl/crypto/aead/AESOCB128.h b/fizz/backend/openssl/crypto/aead/AESOCB128.h new file mode 100644 index 00000000000..8a875c7de3e --- /dev/null +++ b/fizz/backend/openssl/crypto/aead/AESOCB128.h @@ -0,0 +1,36 @@ +/* + * 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 openssl { + +struct AESOCB128 { + static const EVP_CIPHER* Cipher() { +#if !defined(OPENSSL_NO_OCB) + return EVP_aes_128_ocb(); +#else + throw std::runtime_error( + "aes-ocb support requires OpenSSL 1.1.0 with ocb enabled"); +#endif + } + + static const size_t kKeyLength{16}; + static const size_t kIVLength{12}; + static const size_t kTagLength{16}; + static const bool kOperatesInBlocks{true}; + static const bool kRequiresPresetTagLen{true}; +}; + +} // namespace openssl +} // namespace fizz diff --git a/fizz/backend/openssl/crypto/aead/ChaCha20Poly1305.h b/fizz/backend/openssl/crypto/aead/ChaCha20Poly1305.h new file mode 100644 index 00000000000..6c8195bbee3 --- /dev/null +++ b/fizz/backend/openssl/crypto/aead/ChaCha20Poly1305.h @@ -0,0 +1,37 @@ +/* + * 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 openssl { + +struct ChaCha20Poly1305 { + static const EVP_CIPHER* Cipher() { +#if FOLLY_OPENSSL_HAS_CHACHA + return EVP_chacha20_poly1305(); +#else + throw std::runtime_error( + "chacha20-poly1305 support requires OpenSSL 1.1.0"); +#endif // FOLLY_OPENSSL_HAS_CHACHA + } + + static const size_t kKeyLength{32}; + static const size_t kIVLength{12}; + static const size_t kTagLength{16}; + static const bool kOperatesInBlocks{false}; + static const bool kRequiresPresetTagLen{false}; +}; + +} // namespace openssl +} // namespace fizz diff --git a/fizz/crypto/aead/OpenSSLEVPCipher-inl.h b/fizz/backend/openssl/crypto/aead/OpenSSLEVPCipher-inl.h similarity index 94% rename from fizz/crypto/aead/OpenSSLEVPCipher-inl.h rename to fizz/backend/openssl/crypto/aead/OpenSSLEVPCipher-inl.h index 990fb6c4db4..13592e7a8db 100644 --- a/fizz/crypto/aead/OpenSSLEVPCipher-inl.h +++ b/fizz/backend/openssl/crypto/aead/OpenSSLEVPCipher-inl.h @@ -7,6 +7,7 @@ */ namespace fizz { +namespace openssl { template std::unique_ptr OpenSSLEVPCipher::makeCipher() { @@ -22,4 +23,5 @@ std::unique_ptr OpenSSLEVPCipher::makeCipher() { EVPImpl::kRequiresPresetTagLen)); } +} // namespace openssl } // namespace fizz diff --git a/fizz/crypto/aead/OpenSSLEVPCipher.cpp b/fizz/backend/openssl/crypto/aead/OpenSSLEVPCipher.cpp similarity index 99% rename from fizz/crypto/aead/OpenSSLEVPCipher.cpp rename to fizz/backend/openssl/crypto/aead/OpenSSLEVPCipher.cpp index 39df7352603..9e2dbfa8df7 100644 --- a/fizz/crypto/aead/OpenSSLEVPCipher.cpp +++ b/fizz/backend/openssl/crypto/aead/OpenSSLEVPCipher.cpp @@ -6,12 +6,13 @@ * LICENSE file in the root directory of this source tree. */ +#include #include -#include #include #include namespace fizz { +namespace openssl { namespace { void encFunc( @@ -466,4 +467,5 @@ folly::Optional> OpenSSLEVPCipher::tryDecrypt( size_t OpenSSLEVPCipher::getCipherOverhead() const { return tagLength_; } +} // namespace openssl } // namespace fizz diff --git a/fizz/backend/openssl/crypto/aead/OpenSSLEVPCipher.h b/fizz/backend/openssl/crypto/aead/OpenSSLEVPCipher.h new file mode 100644 index 00000000000..b1eff46a525 --- /dev/null +++ b/fizz/backend/openssl/crypto/aead/OpenSSLEVPCipher.h @@ -0,0 +1,132 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +namespace fizz { +namespace openssl { + +/** + * Aead implementation using an OpenSSL EvpCipher. + * + * The template struct requires the following parameters: + * - Cipher: function returning EVP_CIPHER* + * - kKeyLength: length of key required + * - kIvLength: length of iv required + * - kTagLength: authentication tag length + * - kOperatesInBlocks: if the cipher outputs data in chunks vs. streaming 1:1 + * with the input + * - kRequiresPresetTagLen: if the cipher requires setting the tag length + * explicitly + */ +class OpenSSLEVPCipher : public Aead { + public: + ~OpenSSLEVPCipher() override = default; + OpenSSLEVPCipher() = default; + + static constexpr size_t kMaxIVLength = 20; + static constexpr size_t kMaxTagLength = 20; + + template + static std::unique_ptr makeCipher(); + + OpenSSLEVPCipher(OpenSSLEVPCipher&& other) = default; + OpenSSLEVPCipher& operator=(OpenSSLEVPCipher&& other) = default; + + void setKey(TrafficKey trafficKey) override; + folly::Optional getKey() const override; + + size_t keyLength() const override { + return keyLength_; + } + + size_t ivLength() const override { + return ivLength_; + } + + // If plaintext is not shared, encrypt in place and append a tag, + // either in the tail room if available, or by appending a new buf + // If plaintext is shared, alloc a new output and encrypt to output. + // The returned buffer will have head room == headroom_ + std::unique_ptr encrypt( + std::unique_ptr&& plaintext, + const folly::IOBuf* associatedData, + uint64_t seqNum, + Aead::AeadOptions options) const override; + + std::unique_ptr encrypt( + std::unique_ptr&& plaintext, + const folly::IOBuf* associatedData, + folly::ByteRange nonce, + Aead::AeadOptions options) const override; + + // The same as encrypt(), except always do an inplace encrypt if possible, + // even if the IOBuf is shared. If there is not enough room for the tag, + // this will throw an exception. + std::unique_ptr inplaceEncrypt( + std::unique_ptr&& plaintext, + const folly::IOBuf* associatedData, + uint64_t seqNum) const override; + + folly::Optional> tryDecrypt( + std::unique_ptr&& ciphertext, + const folly::IOBuf* associatedData, + uint64_t seqNum, + Aead::AeadOptions options) const override; + + folly::Optional> tryDecrypt( + std::unique_ptr&& ciphertext, + const folly::IOBuf* associatedData, + folly::ByteRange nonce, + Aead::AeadOptions options) const override; + + size_t getCipherOverhead() const override; + + void setEncryptedBufferHeadroom(size_t headroom) override { + headroom_ = headroom; + } + + private: + OpenSSLEVPCipher( + size_t keyLength, + size_t ivLength, + size_t tagLength, + const EVP_CIPHER* cipher, + bool operatesInBlocks, + bool requiresPresetTagLen); + + TrafficKey trafficKey_; + folly::ByteRange trafficIvKey_; + size_t headroom_{5}; + + // set by the ctor + size_t keyLength_; + size_t ivLength_; + size_t tagLength_; + const EVP_CIPHER* cipher_; + bool operatesInBlocks_; + bool requiresPresetTagLen_; + + folly::ssl::EvpCipherCtxUniquePtr encryptCtx_; + folly::ssl::EvpCipherCtxUniquePtr decryptCtx_; +}; +} // namespace openssl +} // namespace fizz +#include diff --git a/fizz/backend/openssl/crypto/aead/test/EVPCipherTest.cpp b/fizz/backend/openssl/crypto/aead/test/EVPCipherTest.cpp new file mode 100644 index 00000000000..0663f9036f3 --- /dev/null +++ b/fizz/backend/openssl/crypto/aead/test/EVPCipherTest.cpp @@ -0,0 +1,1106 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace folly; + +namespace fizz { +using test::chunkIOBuf; +using test::createBufExact; +using test::toIOBuf; + +namespace openssl { +namespace test { + +struct CipherParams { + std::string key; + std::string iv; + uint64_t seqNum; + std::string aad; + std::string plaintext; + std::string ciphertext; + bool valid; + CipherSuite cipher; +}; + +constexpr size_t kHeadroom = 10; + +class EVPCipherTest : public ::testing::TestWithParam {}; + +std::unique_ptr getTestCipher(const CipherParams& params) { + std::unique_ptr cipher = ::fizz::test::getCipher(params.cipher); + + TrafficKey trafficKey; + trafficKey.key = toIOBuf(params.key); + trafficKey.iv = toIOBuf(params.iv); + cipher->setKey(std::move(trafficKey)); + return cipher; +} + +std::list getOptionPairs() { + std::list out; + for (auto aOpt : + {Aead::AllocationOption::Allow, Aead::AllocationOption::Deny}) { + for (auto bOpt : + {Aead::BufferOption::RespectSharedPolicy, + Aead::BufferOption::AllowInPlace, + Aead::BufferOption::AllowFullModification}) { + out.push_back({bOpt, aOpt}); + } + } + return out; +} + +std::unique_ptr callEncrypt( + std::unique_ptr& cipher, + const CipherParams& params, + std::unique_ptr plaintext, + Aead::BufferOption buffOption = Aead::BufferOption::RespectSharedPolicy, + Aead::AllocationOption allocOption = Aead::AllocationOption::Allow, + std::unique_ptr aad = nullptr) { + if (!aad && !params.aad.empty()) { + aad = toIOBuf(params.aad); + } + + auto origLength = plaintext->computeChainDataLength(); + + auto out = cipher->encrypt( + std::move(plaintext), + aad.get(), + params.seqNum, + {buffOption, allocOption}); + bool valid = IOBufEqualTo()(toIOBuf(params.ciphertext), out); + + EXPECT_EQ(valid, params.valid); + EXPECT_EQ( + out->computeChainDataLength(), origLength + cipher->getCipherOverhead()); + return out; +} + +std::unique_ptr callDecrypt( + std::unique_ptr& cipher, + const CipherParams& params, + std::unique_ptr ciphertext = nullptr, + Aead::BufferOption buffOption = Aead::BufferOption::RespectSharedPolicy, + Aead::AllocationOption allocOption = Aead::AllocationOption::Allow, + bool throwExceptions = false, + std::unique_ptr aad = nullptr) { + if (!ciphertext) { + ciphertext = toIOBuf(params.ciphertext); + } + if (!aad && !params.aad.empty()) { + aad = toIOBuf(params.aad); + } + try { + auto origLength = ciphertext->computeChainDataLength(); + auto out = cipher->decrypt( + std::move(ciphertext), + aad.get(), + params.seqNum, + {buffOption, allocOption}); + EXPECT_TRUE(params.valid); + EXPECT_TRUE(IOBufEqualTo()(toIOBuf(params.plaintext), out)); + EXPECT_EQ( + out->computeChainDataLength(), + origLength - cipher->getCipherOverhead()); + return out; + } catch (const std::runtime_error&) { + if (throwExceptions) { + // Indicates test case wants to receive any exceptions thrown + throw; + } else { + EXPECT_FALSE(params.valid); + } + return nullptr; + } +} + +TEST_P(EVPCipherTest, TestEncrypt) { + for (auto opts : getOptionPairs()) { + auto cipher = getTestCipher(GetParam()); + auto plaintext = toIOBuf(GetParam().plaintext); + if (opts.allocOpt == Aead::AllocationOption::Deny) { + EXPECT_THROW( + callEncrypt( + cipher, + GetParam(), + std::move(plaintext), + opts.bufferOpt, + opts.allocOpt), + std::runtime_error); + } else { + // Buffer isn't shared, so all buffer option cases should be equal + auto out = callEncrypt( + cipher, + GetParam(), + std::move(plaintext), + opts.bufferOpt, + opts.allocOpt); + EXPECT_EQ(out->headroom(), 0); + } + } +} + +TEST_P(EVPCipherTest, TestEncryptWithTagRoom) { + for (auto opts : getOptionPairs()) { + // Behavior should be identical for all, as buffer is unshared with enough + // room + auto cipher = getTestCipher(GetParam()); + auto input = toIOBuf(GetParam().plaintext, 0, cipher->getCipherOverhead()); + auto out = callEncrypt( + cipher, GetParam(), std::move(input), opts.bufferOpt, opts.allocOpt); + EXPECT_FALSE(out->isChained()); + } +} + +TEST_P(EVPCipherTest, TestEncryptReusedCipher) { + for (auto opts : getOptionPairs()) { + auto cipher = getTestCipher(GetParam()); + auto params = GetParam(); + if (opts.allocOpt == Aead::AllocationOption::Deny) { + // Again, no tag room, so we expect these to throw + EXPECT_THROW( + callEncrypt( + cipher, + params, + toIOBuf(params.plaintext), + opts.bufferOpt, + opts.allocOpt), + std::runtime_error); + EXPECT_THROW( + callEncrypt( + cipher, + GetParam(), + toIOBuf(params.plaintext), + opts.bufferOpt, + opts.allocOpt), + std::runtime_error); + } else { + callEncrypt( + cipher, + params, + toIOBuf(params.plaintext), + opts.bufferOpt, + opts.allocOpt); + callEncrypt( + cipher, + GetParam(), + toIOBuf(params.plaintext), + opts.bufferOpt, + opts.allocOpt); + } + } +} + +TEST_P(EVPCipherTest, TestEncryptReusedCipherWithTagRoom) { + for (auto opts : getOptionPairs()) { + auto cipher = getTestCipher(GetParam()); + auto params = GetParam(); + callEncrypt( + cipher, + params, + toIOBuf(params.plaintext, 0, cipher->getCipherOverhead()), + opts.bufferOpt, + opts.allocOpt); + callEncrypt( + cipher, + GetParam(), + toIOBuf(params.plaintext, 0, cipher->getCipherOverhead()), + opts.bufferOpt, + opts.allocOpt); + } +} + +TEST_P(EVPCipherTest, TestEncryptChunkedInput) { + for (auto opts : getOptionPairs()) { + auto cipher = getTestCipher(GetParam()); + auto inputLength = toIOBuf(GetParam().plaintext)->computeChainDataLength(); + for (size_t i = 2; i < inputLength; i++) { + auto input = toIOBuf(GetParam().plaintext); + auto chunkedInput = chunkIOBuf(std::move(input), i); + if (opts.allocOpt == Aead::AllocationOption::Deny) { + // No tag room + EXPECT_THROW( + callEncrypt( + cipher, + GetParam(), + std::move(chunkedInput), + opts.bufferOpt, + opts.allocOpt), + std::runtime_error); + } else { + callEncrypt( + cipher, + GetParam(), + std::move(chunkedInput), + opts.bufferOpt, + opts.allocOpt); + } + } + } +} + +TEST_P(EVPCipherTest, TestEncryptChunkedInputWithEmpty) { + for (auto opts : getOptionPairs()) { + auto cipher = getTestCipher(GetParam()); + auto input = toIOBuf(GetParam().plaintext); + auto chunkedInput = chunkIOBuf(std::move(input), 3); + // add a zero length for the second node + chunkedInput->appendChain(IOBuf::create(0)); + EXPECT_EQ(4, chunkedInput->countChainElements()); + if (opts.allocOpt == Aead::AllocationOption::Deny) { + // no tag room + EXPECT_THROW( + callEncrypt( + cipher, + GetParam(), + std::move(chunkedInput), + opts.bufferOpt, + opts.allocOpt), + std::runtime_error); + } else { + callEncrypt( + cipher, + GetParam(), + std::move(chunkedInput), + opts.bufferOpt, + opts.allocOpt); + } + } +} + +TEST_P(EVPCipherTest, TestEncryptChunkedInputWithTagRoomHead) { + for (auto opts : getOptionPairs()) { + auto cipher = getTestCipher(GetParam()); + auto input = toIOBuf(GetParam().plaintext); + auto overhead = cipher->getCipherOverhead(); + auto creator = [overhead](size_t len, size_t num) { + if (num == 0) { + // create a buffer w/ room for the tag + auto result = createBufExact(len + overhead); + result->reserve(0, overhead); + return result; + } + return createBufExact(len); + }; + auto chunkedInput = chunkIOBuf(std::move(input), 3, creator); + // even though the head element has tailroom, we don't use it since it's + // the last element that needs to have it for copying tag in directly + if (opts.allocOpt == Aead::AllocationOption::Deny) { + // Since we can't allocate room for the tag where we need it, expect to + // throw + EXPECT_THROW( + callEncrypt( + cipher, + GetParam(), + std::move(chunkedInput), + opts.bufferOpt, + opts.allocOpt), + std::runtime_error); + } else { + auto out = callEncrypt( + cipher, + GetParam(), + std::move(chunkedInput), + opts.bufferOpt, + opts.allocOpt); + // We expect the first buffer to have the tailroom unused + EXPECT_GE(out->tailroom(), overhead); + } + } +} + +TEST_P(EVPCipherTest, TestEncryptChunkedInputWithTagRoomLast) { + for (auto opts : getOptionPairs()) { + auto cipher = getTestCipher(GetParam()); + auto input = toIOBuf(GetParam().plaintext); + auto overhead = cipher->getCipherOverhead(); + size_t chunks = 3; + auto creator = [=](size_t len, size_t num) { + if (num == chunks - 1) { + // create a buffer w/ room for the tag + auto result = createBufExact(len + overhead); + result->reserve(0, overhead); + return result; + } + return createBufExact(len); + }; + auto chunkedInput = chunkIOBuf(std::move(input), chunks, creator); + auto lastTailRoom = chunkedInput->prev()->tailroom(); + auto numElements = chunkedInput->countChainElements(); + auto out = callEncrypt( + cipher, + GetParam(), + std::move(chunkedInput), + opts.bufferOpt, + opts.allocOpt); + // we expect the last element in the chain to have tailroom - overhead + // left + EXPECT_EQ(out->prev()->tailroom(), lastTailRoom - overhead); + EXPECT_EQ(out->countChainElements(), numElements); + } +} + +TEST_P(EVPCipherTest, TestEncryptChunkedSharedInput) { + for (auto opts : getOptionPairs()) { + auto cipher = getTestCipher(GetParam()); + auto input = toIOBuf(GetParam().plaintext); + auto chunkedInput = chunkIOBuf(std::move(input), 3); + if (opts.allocOpt == Aead::AllocationOption::Deny) { + // They'll all fail for lack of tag room + EXPECT_THROW( + callEncrypt( + cipher, + GetParam(), + chunkedInput->clone(), + opts.bufferOpt, + opts.allocOpt), + std::runtime_error); + } else { + auto originalHeadroom = chunkedInput->headroom(); + auto out = callEncrypt( + cipher, + GetParam(), + chunkedInput->clone(), + opts.bufferOpt, + opts.allocOpt); + if (opts.bufferOpt == Aead::BufferOption::RespectSharedPolicy) { + // we expect headroom of record size and a single buffer in the + // the chain. as it should be a new buffer, it should be unshared. + EXPECT_EQ(out->headroom(), kHeadroom); + EXPECT_FALSE(out->isChained()); + EXPECT_FALSE(out->isShared()); + } else { + // We explicitly supported in-place edits. Since there isn't tailroom, + // we expect identical behavior (new tag buffer) + EXPECT_EQ(out->headroom(), originalHeadroom); + EXPECT_TRUE(out->isChained()); + EXPECT_TRUE(out->isShared()); + EXPECT_EQ( + out->countChainElements(), chunkedInput->countChainElements() + 1); + } + } + } +} + +TEST_P(EVPCipherTest, TestEncryptChunkedSharedInputWithTagRoom) { + for (auto opts : getOptionPairs()) { + auto cipher = getTestCipher(GetParam()); + auto input = toIOBuf(GetParam().plaintext); + auto overhead = cipher->getCipherOverhead(); + size_t chunks = 3; + auto creator = [=](size_t len, size_t num) { + if (num == chunks - 1) { + // create a buffer w/ room for the tag + auto result = createBufExact(len + overhead); + result->reserve(0, overhead); + return result; + } + return createBufExact(len); + }; + auto chunkedInput = chunkIOBuf(std::move(input), chunks, creator); + if (opts.allocOpt == Aead::AllocationOption::Deny) { + if (opts.bufferOpt != Aead::BufferOption::AllowFullModification) { + // When denying allocation, edits must allow for growth + EXPECT_THROW( + callEncrypt( + cipher, + GetParam(), + chunkedInput->clone(), + opts.bufferOpt, + opts.allocOpt), + std::runtime_error); + } else { + auto originalHeadroom = chunkedInput->headroom(); + auto out = callEncrypt( + cipher, + GetParam(), + chunkedInput->clone(), + opts.bufferOpt, + opts.allocOpt); + // We expect that it edited in-place and grew the last buffer. + EXPECT_EQ(out->headroom(), originalHeadroom); + EXPECT_TRUE(out->isChained()); + EXPECT_TRUE(out->isShared()); + EXPECT_EQ( + out->countChainElements(), chunkedInput->countChainElements()); + EXPECT_EQ( + out->prev()->length(), chunkedInput->prev()->length() + overhead); + } + } else { + auto originalHeadroom = chunkedInput->headroom(); + auto out = callEncrypt( + cipher, + GetParam(), + chunkedInput->clone(), + opts.bufferOpt, + opts.allocOpt); + if (opts.bufferOpt == Aead::BufferOption::RespectSharedPolicy) { + // we expect headroom of record size and a single buffer in the + // the chain. as it should be a new buffer, it should be unshared. + EXPECT_EQ(out->headroom(), kHeadroom); + EXPECT_FALSE(out->isChained()); + EXPECT_FALSE(out->isShared()); + } else if (opts.bufferOpt == Aead::BufferOption::AllowInPlace) { + // We explicitly supported in-place edits, but not growth. + // There should be a new buffer with the tag. + EXPECT_EQ(out->headroom(), originalHeadroom); + EXPECT_TRUE(out->isChained()); + EXPECT_TRUE(out->isShared()); + EXPECT_EQ( + out->countChainElements(), chunkedInput->countChainElements() + 1); + EXPECT_EQ(out->prev()->length(), overhead); + } else { + // Should be able to do it entirely in-place, growing the last buffer. + EXPECT_EQ(out->headroom(), originalHeadroom); + EXPECT_TRUE(out->isChained()); + EXPECT_TRUE(out->isShared()); + EXPECT_EQ( + out->countChainElements(), chunkedInput->countChainElements()); + EXPECT_EQ( + out->prev()->length(), chunkedInput->prev()->length() + overhead); + } + } + } +} + +TEST_P(EVPCipherTest, TestEncryptChunkedAad) { + for (auto opts : getOptionPairs()) { + auto cipher = getTestCipher(GetParam()); + auto aadLength = toIOBuf(GetParam().aad)->computeChainDataLength(); + for (size_t i = 2; i < aadLength; i++) { + auto aad = toIOBuf(GetParam().aad); + auto chunkedAad = chunkIOBuf(std::move(aad), i); + if (opts.allocOpt == Aead::AllocationOption::Deny) { + // No tag room + EXPECT_THROW( + callEncrypt( + cipher, + GetParam(), + toIOBuf(GetParam().plaintext), + opts.bufferOpt, + opts.allocOpt, + std::move(chunkedAad)), + std::runtime_error); + } else { + callEncrypt( + cipher, + GetParam(), + toIOBuf(GetParam().plaintext), + opts.bufferOpt, + opts.allocOpt, + std::move(chunkedAad)); + } + } + } +} + +TEST_P(EVPCipherTest, TestEncryptChunkedAadWithTagRoom) { + for (auto opts : getOptionPairs()) { + // Unique input with room for growth, should always succeed. + auto cipher = getTestCipher(GetParam()); + auto aad = toIOBuf(GetParam().aad); + auto chunkedAad = chunkIOBuf(std::move(aad), 3); + callEncrypt( + cipher, + GetParam(), + toIOBuf(GetParam().plaintext, 0, cipher->getCipherOverhead()), + opts.bufferOpt, + opts.allocOpt, + std::move(chunkedAad)); + } +} + +TEST_P(EVPCipherTest, TestDecrypt) { + for (auto opts : getOptionPairs()) { + // Should work for all modes (contiguous unshared buf) + auto cipher = getTestCipher(GetParam()); + auto output = toIOBuf(GetParam().ciphertext); + auto cipherLen = output->length(); + auto out = + callDecrypt(cipher, GetParam(), nullptr, opts.bufferOpt, opts.allocOpt); + if (out) { + EXPECT_FALSE(out->isChained()); + EXPECT_FALSE(out->isShared()); + EXPECT_EQ(out->length(), cipherLen - cipher->getCipherOverhead()); + } + } +} + +TEST_P(EVPCipherTest, TestDecryptReusedCipher) { + for (auto opts : getOptionPairs()) { + // Same as before + auto cipher = getTestCipher(GetParam()); + auto params = GetParam(); + callDecrypt(cipher, params, nullptr, opts.bufferOpt, opts.allocOpt); + callDecrypt(cipher, GetParam(), nullptr, opts.bufferOpt, opts.allocOpt); + } +} + +TEST_P(EVPCipherTest, TestDecryptInputTooSmall) { + for (auto opts : getOptionPairs()) { + // This should behave identically (the input size check comes early) + auto cipher = getTestCipher(GetParam()); + auto in = IOBuf::copyBuffer("in"); + auto paramsCopy = GetParam(); + paramsCopy.valid = false; + callDecrypt( + cipher, paramsCopy, std::move(in), opts.bufferOpt, opts.allocOpt); + } +} + +TEST_P(EVPCipherTest, TestDecryptWithChunkedInput) { + for (auto opts : getOptionPairs()) { + auto cipher = getTestCipher(GetParam()); + auto output = toIOBuf(GetParam().ciphertext); + auto chunkedOutput = chunkIOBuf(std::move(output), 3); + auto lastBufLength = chunkedOutput->prev()->length(); + if (opts.allocOpt == Aead::AllocationOption::Deny && + lastBufLength < cipher->getCipherOverhead()) { + // If the last buf isn't big enough to hold the entire tag and allocation + // isn't allowed, decrypt will fail + EXPECT_THROW( + callDecrypt( + cipher, + GetParam(), + std::move(chunkedOutput), + opts.bufferOpt, + opts.allocOpt, + true), + std::runtime_error); + } else { + // In all other cases this should always succeed + callDecrypt( + cipher, + GetParam(), + std::move(chunkedOutput), + opts.bufferOpt, + opts.allocOpt); + } + } +} + +TEST_P(EVPCipherTest, TestDecryptWithChunkedSharedInput) { + for (auto opts : getOptionPairs()) { + auto cipher = getTestCipher(GetParam()); + auto ciphertextLength = + toIOBuf(GetParam().ciphertext)->computeChainDataLength(); + for (size_t i = 2; i < ciphertextLength; i++) { + auto output = toIOBuf(GetParam().ciphertext); + auto chunkedOutput = chunkIOBuf(std::move(output), i); + auto lastBufLength = chunkedOutput->prev()->length(); + if (opts.allocOpt == Aead::AllocationOption::Deny && + (lastBufLength < cipher->getCipherOverhead() || + opts.bufferOpt == Aead::BufferOption::RespectSharedPolicy)) { + EXPECT_THROW( + callDecrypt( + cipher, + GetParam(), + chunkedOutput->clone(), + opts.bufferOpt, + opts.allocOpt, + true), + std::runtime_error); + } else { + auto out = callDecrypt( + cipher, + GetParam(), + chunkedOutput->clone(), + opts.bufferOpt, + opts.allocOpt); + if (out) { + // for valid cases: + EXPECT_EQ( + out->computeChainDataLength(), + chunkedOutput->computeChainDataLength() - + cipher->getCipherOverhead()); + if (opts.bufferOpt != Aead::BufferOption::RespectSharedPolicy) { + // In-place edit + EXPECT_EQ(chunkedOutput->data(), out->data()); + EXPECT_TRUE(out->isChained()); + EXPECT_TRUE(out->isShared()); + EXPECT_EQ( + out->countChainElements(), chunkedOutput->countChainElements()); + } else { + // New buffer. + EXPECT_NE(chunkedOutput->data(), out->data()); + EXPECT_FALSE(out->isChained()); + EXPECT_FALSE(out->isShared()); + } + } + } + } + } +} + +TEST_P(EVPCipherTest, TestDecryptWithChunkedAad) { + for (auto opts : getOptionPairs()) { + // Behaviorally same as the regular decrypt test wrt variations + auto cipher = getTestCipher(GetParam()); + auto aadLength = toIOBuf(GetParam().aad)->computeChainDataLength(); + for (size_t i = 2; i < aadLength; i++) { + auto aad = toIOBuf(GetParam().aad); + auto chunkedAad = chunkIOBuf(std::move(aad), i); + callDecrypt( + cipher, + GetParam(), + nullptr, + opts.bufferOpt, + opts.allocOpt, + false, + std::move(chunkedAad)); + } + } +} + +TEST_P(EVPCipherTest, TestTryDecrypt) { + for (auto opts : getOptionPairs()) { + // Should all behave identically, as ciphertext is unshared and contiguous + auto cipher = getTestCipher(GetParam()); + auto out = cipher->tryDecrypt( + toIOBuf(GetParam().ciphertext), + toIOBuf(GetParam().aad).get(), + GetParam().seqNum, + std::move(opts)); + if (out) { + EXPECT_TRUE(GetParam().valid); + EXPECT_TRUE(IOBufEqualTo()(toIOBuf(GetParam().plaintext), *out)); + } else { + EXPECT_FALSE(GetParam().valid); + } + } +} + +TEST_P(EVPCipherTest, TestOutputBufferSizeOverflow) { + for (auto opts : getOptionPairs()) { + // new output buffer is only allocated when the plaintext input buffer is + // shared and when we are allowed to allocate more memory + if (opts.bufferOpt != Aead::BufferOption::RespectSharedPolicy || + opts.allocOpt != Aead::AllocationOption::Allow) { + continue; + } + auto cipher = getTestCipher(GetParam()); + constexpr size_t kLargeHeadroom = 0xFFFFFFFFFFFFFFFF; + cipher->setEncryptedBufferHeadroom(kLargeHeadroom); + auto plaintext = toIOBuf(GetParam().plaintext); + plaintext->markExternallyShared(); + + EXPECT_TRUE(plaintext->isShared()); + EXPECT_THROW( + callEncrypt( + cipher, + GetParam(), + std::move(plaintext), + opts.bufferOpt, + opts.allocOpt), + std::overflow_error); + } +} + +// Adapted from draft-thomson-tls-tls13-vectors +INSTANTIATE_TEST_SUITE_P( + AESGCM128TestVectors, + EVPCipherTest, + ::testing::Values( + CipherParams{ + "87f6c12b1ae8a9b7efafc65af0f5c994", + "479e25839c19e0476f95a6f5", + 1, + "", + "010015", + "9d4db5ecd768198892531eebac72cf1d477dd0", + true, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{ + "911dc107aa6eccb6706bdcc37e76a07a", + "11c7fa13e9499ed042b09e57", + 0, + "", + "14000020de15cbc8c62d0e6fef73a6d4e70e5c372c2b94fe08ea40d11166a7e6c967ba9c16", + "56a21739148c898fe807026a179d59202647a3b1e01267a3883cf5f69fd233f63ff12c1c71b4c8f3d6086affb49621f96b842e1d35", + true, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{ + "a0f49e7076cae6eb25ca23a2da0eaf12", + "3485d33f22128dff91e47062", + 0, + "", + "41424344454617", + "92fdec5c241e994fb7d889e1b61d1db2b9be6777f5a393", + true, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{"fda2a4404670808f4937478b8b6e3fe1", "b5f3a3fae1cb25c9dcd73993", 0, "", "0800001e001c000a00140012001d00170018001901000101010201030104000000000b0001b9000001b50001b0308201ac30820115a003020102020102300d06092a864886f70d01010b0500300e310c300a06035504031303727361301e170d3136303733303031323335395a170d3236303733303031323335395a300e310c300a0603550403130372736130819f300d06092a864886f70d010101050003818d0030818902818100b4bb498f8279303d980836399b36c6988c0c68de55e1bdb826d3901a2461eafd2de49a91d015abbc9a95137ace6c1af19eaa6af98c7ced43120998e187a80ee0ccb0524b1b018c3e0b63264d449a6d38e22a5fda430846748030530ef0461c8ca9d9efbfae8ea6d1d03e2bd193eff0ab9a8002c47428a6d35a8d88d79f7f1e3f0203010001a31a301830090603551d1304023000300b0603551d0f0404030205a0300d06092a864886f70d01010b05000381810085aad2a0e5b9276b908c65f73a7267170618a54c5f8a7b337d2df7a594365417f2eae8f8a58c8f8172f9319cf36b7fd6c55b80f21a03015156726096fd335e5e67f2dbf102702e608ccae6bec1fc63a42a99be5c3eb7107c3c54e9b9eb2bd5203b1c3b84e0a8b2f759409ba3eac9d91d402dcc0cc8f8961229ac9187b42b4de100000f000084080400804547d6168f2510c550bd949cd2bc631ff134fa10a827ff69b166a6bd95e249ed0daf571592ebbe9ff13de6b03acc218146781f693b5a692b7319d74fd2e53b6a2df0f6785d624f024a44030ca00b869ae81a532b19e47e525ff4a62c51a5889eb565fee268590d8a3ca3c1bc3bd5404e39720ca2eaee308f4e0700761e986389140000209efee03ebffbc0dc23d26d958744c09e3000477eff7ae3148a50e5670013aaaa16", "c1e631f81d2af221ebb6a957f58f3ee266272635e67f99a752f0df08adeb33bab8611e55f33d72cf84382461a8bfe0a659ba2dd1873f6fcc707a9841cefc1fb03526b9ca4fe343e5805e95a5c01e56570638a76a4bc8feb07be879f90568617d905fecd5b1619fb8ec4a6628d1bb2bb224c490ff97a6c0e9acd03604bc3a59d86bdab4e084c1c1450f9c9d2afeb172c07234d739868ebd62de2060a8de989414a82920dacd1cac0c6e72ecd7f4018574ceaca6d29f361bc37ee2888b8e302ca9561a9de9163edfa66badd4894884c7b359bcacae5908051b37952e10a45fe73fda126ebd67575f1bed8a992a89474d7dec1eed327824123a414adb66d5ef7d0836ff98c2cdd7fb0781e192bf0c7568bf7d890a51c332879b5037b212d622412ca48e8323817bd6d746eef683845cec4e3ef64b3a18fcce513ea951f3366693a7ff490d09d08ab1f63e13625a545961599c0d9c7a099d1163cad1b9bcf8e917d766b98853ef6877834f891df16be1fcc9c18ea1882ea3f1f4b64358e1b146cebfb3e02e153fdb73af2693f22c6f593fa475380ba6611740ad20e319a654ac5684775236162e8447ed808861bfbda6e18ec97ae090bf703475cfb90fe20a3c55bef6f5eba6e6a1da6a1996b8bde42180608ca2279def8e8153895cc850db6420561c04b5729cc6883436ea02ee07eb9baee2fb3a9e1bbda8730d6b220576e24df70af6928eb865fee8a1d1c0f1818aca68d5002ae4c65b2f49c9e6e21dcf76784adbd0e887a36832ef85beb10587f16c6ffe60d7451059ec7f1014c3efe19e56aedb5ad31a9f29dc4458cfbf0c7070c175dcad46e1675226b47c071aad3172ebd33e45d741cb91253a01a69ae3cc292bce9c03246ac951e45e97ebf04a9d51fab5cf06d9485cce746b1c077be69ad153f1656ef89fc7d1ed8c3e2da7a2", true, CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{ + "a0f49e7076cbe6eb25ca23a2da0eaf12", + "3485d33f22128dff91e47062", + 0, + "", + "41424344454617", + "92fdec5c241e994fb7d889e1b61d1db2b9be6777f5a393", + false, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{ + "a0f49e7076cae6eb25ca23a2da0eaf12", + "3485d33f22128dff91e47062", + 0, + "", + "41424344454617", + "92fdec", + false, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{ + "AD7A2BD03EAC835A6F620FDCB506B345", + "12153524C0895E81B2C28465", + 0, + "D609B1F056637A0D46DF998D88E52E00B2C2846512153524C0895E81", + "08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A0002", + "701AFA1CC039C0D765128A665DAB69243899BF7318CCDC81C9931DA17FBE8EDD7D17CB8B4C26FC81E3284F2B7FBA713D4F8D55E7D3F06FD5A13C0C29B9D5B880", + true, + CipherSuite::TLS_AES_128_GCM_SHA256}, + CipherParams{ + "AD7A2BD03EAC835A6F620FDCB506B345", + "12153524C0895E81B2C28465", + 0, + "D609B1F056637A1D46DF998D88E52E00B2C2846512153524C0895E81", + "08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A0002", + "701AFA1CC039C0D765128A665DAB69243899BF7318CCDC81C9931DA17FBE8EDD7D17CB8B4C26FC81E3284F2B7FBA713D4F8D55E7D3F06FD5A13C0C29B9D5B880", + false, + CipherSuite::TLS_AES_128_GCM_SHA256})); + +INSTANTIATE_TEST_SUITE_P( + AESGCM256TestVectors, + EVPCipherTest, + ::testing::Values( + CipherParams{ + "E3C08A8F06C6E3AD95A70557B23F75483CE33021A9C72B7025666204C69C0B72", + "12153524C0895E81B2C28465", + 0, + "D609B1F056637A0D46DF998D88E52E00B2C2846512153524C0895E81", + "08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A0002", + "E2006EB42F5277022D9B19925BC419D7A592666C925FE2EF718EB4E308EFEAA7C5273B394118860A5BE2A97F56AB78365CA597CDBB3EDB8D1A1151EA0AF7B436", + true, + CipherSuite::TLS_AES_256_GCM_SHA384}, + CipherParams{ + "E3C08A8F06C6E3AD95A70557B23F75483CE33021A9C72B7025666204C69C0B72", + "12153524C0895E81B2C28465", + 0, + "D609B1F056637A0D46DF998D88E52E00B2C2846512153524C0895E81", + "08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A0002", + "E2006EB42F5277022D9B19925BC419D7A592666C925FE2EF718EB4E308EFEAA7C5273B394118860A5BE2A97F56AB78365CA597CDBB3EDB8D1A1151EA1AF7B436", + false, + CipherSuite::TLS_AES_256_GCM_SHA384})); + +#if FOLLY_OPENSSL_HAS_CHACHA +// Adapted from libressl's chacha20-poly1305 aead tests +INSTANTIATE_TEST_SUITE_P( + ChaChaTestVectors, + EVPCipherTest, + ::testing:: + Values( + CipherParams{ + "9a97f65b9b4c721b960a672145fca8d4e32e67f9111ea979ce9c4826806aeee6", + "000000003de9c0da2bd7f91e", + 0, + "", + "", + "5a6e21f4ba6dbee57380e79e79c30def", + true, + CipherSuite::TLS_CHACHA20_POLY1305_SHA256}, + CipherParams{ + "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007", + "00000000cd7cf67be39c794a", + 0, + "", + "86d09974840bded2a5ca", + "e3e446f7ede9a19b62a4dc8dae9a28bb548811461f49f8cec5ae", + true, + CipherSuite::TLS_CHACHA20_POLY1305_SHA256}, + CipherParams{ + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "070000004041424344454647", + 0, + "", + "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e", + "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61166a23a4681fd59456aea1d29f82477216", + true, + CipherSuite::TLS_CHACHA20_POLY1305_SHA256}, + CipherParams{ + "1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0", + "000000000102030405060708", + 0, + "", + "496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d", + "64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b6e3570b1acaaf1f24f2a644f01acd12b", + true, + CipherSuite::TLS_CHACHA20_POLY1305_SHA256}, + CipherParams{ + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "a0a1a2a31011121314151617", + 0, + "", + "45000054a6f200004001e778c6336405c000020508005b7a3a080000553bec100007362708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363701020204", + "24039428b97f417e3c13753a4f05087b67c352e6a7fab1b982d466ef407ae5c614ee8099d52844eb61aa95dfab4c02f72aa71e7c4c4f64c9befe2facc638e8f3cbec163fac469b502773f6fb94e664da9165b82829f641e07e236714fca1ccb75ab26d5f253185e6", + true, + CipherSuite::TLS_CHACHA20_POLY1305_SHA256}, + CipherParams{ + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "a0a1a2a31011121314151617", + 0, + "", + "0000000c000040010000000a00", + "610394701f8d017f7c129248895c5d2b5fa5a4723e5c38e903e5178a10", + true, + CipherSuite::TLS_CHACHA20_POLY1305_SHA256}, + CipherParams{ + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "a0a1a2a31011121314151617", + 0, + "", + "0000000c000040010000000a00", + "610394701f8d017f7c129248890c5d2b5fa5a4723e5c38e903e5178a10", + false, + CipherSuite::TLS_CHACHA20_POLY1305_SHA256}, + CipherParams{ + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "a0a1a2a31011121314151617", + 0, + "", + "0000000c000040010000000a00", + "610394701f8d017f7c129248", + false, + CipherSuite::TLS_CHACHA20_POLY1305_SHA256}, + CipherParams{ + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "070000004041424344454647", + 0, + "50515253c0c1c2c3c4c5c6c7", + "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e", + "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691", + true, + CipherSuite::TLS_CHACHA20_POLY1305_SHA256}, + CipherParams{ + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "070000004041424344454647", + 0, + "51515253c0c1c2c3c4c5c6c7", + "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e", + "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691", + false, + CipherSuite::TLS_CHACHA20_POLY1305_SHA256})); +#endif +#if !defined(OPENSSL_NO_OCB) +// Adapted from openssl's evptests.txt AES OCB Test vectors +INSTANTIATE_TEST_SUITE_P( + OCBTestVectors, + EVPCipherTest, + ::testing::Values( + CipherParams{ + "000102030405060708090A0B0C0D0E0F", + "000102030405060708090A0B", + 0, + "0001020304050607", + "0001020304050607", + "92B657130A74B85A16DC76A46D47E1EAD537209E8A96D14E", + true, + CipherSuite::TLS_AES_128_OCB_SHA256_EXPERIMENTAL}, + CipherParams{ + "000102030405060708090A0B0C0D0E0F", + "000102030405060708090A0B", + 0, + "0001020304050607", + "0001020304050607", + "82B657130A74B85A16DC76A46D47E1EAD537209E8A96D14E", + false, + CipherSuite::TLS_AES_128_OCB_SHA256_EXPERIMENTAL}, + CipherParams{ + "000102030405060708090A0B0C0D0E0F", + "000102030405060708090A0B", + 0, + "000102030405060708090A0B0C0D0E0F", + "000102030405060708090A0B0C0D0E0F", + "BEA5E8798DBE7110031C144DA0B26122776C9924D6723A1FC4524532AC3E5BEB", + true, + CipherSuite::TLS_AES_128_OCB_SHA256_EXPERIMENTAL}, + CipherParams{ + "000102030405060708090A0B0C0D0E0F", + "000102030405060708090A0B", + 0, + "000102030405060708090A0B0C0D0E0F", + "000102030405060708090A0B0C0D0E0F", + "CEA5E8798DBE7110031C144DA0B26122776C9924D6723A1FC4524532AC3E5BEB", + false, + CipherSuite::TLS_AES_128_OCB_SHA256_EXPERIMENTAL}, + CipherParams{ + "000102030405060708090A0B0C0D0E0F", + "000102030405060708090A0B", + 0, + "000102030405060708090A0B0C0D0E0F1011121314151617", + "000102030405060708090A0B0C0D0E0F1011121314151617", + "BEA5E8798DBE7110031C144DA0B26122FCFCEE7A2A8D4D485FA94FC3F38820F1DC3F3D1FD4E55E1C", + true, + CipherSuite::TLS_AES_128_OCB_SHA256_EXPERIMENTAL}, + CipherParams{ + "000102030405060708090A0B0C0D0E0F", + "000102030405060708090A0B", + 0, + "000102030405060708090A0B0C0D0E0F1011121314151617", + "000102030405060708090A0B0C0D0E0F1011121314151617", + "BFA5E8798DBE7110031C144DA0B26122FCFCEE7A2A8D4D485FA94FC3F38820F1DC3F3D1FD4E55E1C", + false, + CipherSuite::TLS_AES_128_OCB_SHA256_EXPERIMENTAL}, + CipherParams{ + "000102030405060708090A0B0C0D0E0F", + "000102030405060708090A0B", + 0, + "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627", + "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627", + "BEA5E8798DBE7110031C144DA0B26122CEAAB9B05DF771A657149D53773463CB68C65778B058A635659C623211DEEA0DE30D2C381879F4C8", + true, + CipherSuite::TLS_AES_128_OCB_SHA256_EXPERIMENTAL})); +#endif + +#if FIZZ_BUILD_AEGIS +// Adapted from libsodium's aegis testing values +INSTANTIATE_TEST_SUITE_P( + AEGIS128LTestVectors, + EVPCipherTest, + ::testing::Values( + CipherParams{ + "54662e55bb4771f9711fe5301d7412fe", + "e51d417ab10a2931d8d22a9fffb98e3a", + 0, + "3b762e3ab5d06cb2896b852ea70303f289f2775401b7808e30272f", + "04f672f8cdb3e71d032d52c064bc33ecf8aad3d40c41d5806cc306766c057c50b500af5c550d076d34cc3a74a2b4bed195ffa3e8eddf953aefe9aed2bc14349c700ab7e4cb974fb31615a9ff70fb44307055523ab378b133fefc883013ce23bb01b23aeda15f85e65cdf02a291a0454900cb261872d5205737fd7410", + "d6736371f35eb067244dd7963ad2e0cd3949452cbd4c220be55082498ed3b230f579d78844311652a9958e82f172bb8072c4b1114ec531a6ccb340ddd86caf32a0d4c9c45738e9ec9c0d9154612f7d90465f3a277bebd667c0af0edb6935d8dffbdee96c1a96e4c4318f5d3bc90c1c8d5729e1a402f765bdc9b26b0853c2fd22b035bf3f3658ede47ef11b9d", + true, + CipherSuite::TLS_AEGIS_128L_SHA256}, + CipherParams{ + "46a5c72e03d900b48f829df00ecb88b9", + "b25187e4b77b6770c35c7a962584597d", + 0, + "b73c81239e01cd81b0de13247ca4e3528b87f3078e2b674a667430b1dbdc3e93657131e654a4182b4c4ab01a33b36e946f1fcc55aab06fc6f56d", + "fc8083311b38a80c04e57d069661b273264310906781eb7e4e44c6416f7336267674a44a7c54ed6361b43ef9500514e5d9e71f8b5c33aece756b64f3ed011922facbec7c3ffd27d01a853435bde551372806bd0c", + "51189448af53ae3630c06a167ceefe6b9b5eba746fb9b53f4b3104d2b15b6020fa8998e182eb9c9d6b6463939e50723780f983733206ae6f11b986d95abe83555e64f8d3242d7e8055fcb8e2df8e41d318f06728f9b7e561ac0316d2ed7debc2484cc3e1", + true, + CipherSuite::TLS_AEGIS_128L_SHA256}, + CipherParams{ + "e343d75de99e6d73543968437d3dcf6a", + "317a5808ed5debf6f527a780e0896b2d", + 0, + "323094c01e", + "247045cb40dea9c514a885444c526ac867b1b80e4728a23b63f596", + "18cb5d2fc5e27bdda5ba16f1320da42049759368548e5bd96f2dbc1659e7d7193b12b4c90ba1e4314ef055", + true, + CipherSuite::TLS_AEGIS_128L_SHA256}, + CipherParams{ + "7db9c2721a03931c880f9e714bbf2211", + "27f642398299ada7fdda1895ee4589f0", + 0, + "6dd5e43033fa6f021059a353edaf1f870387693054d0a2360fd1f6941a68f48ba972a1bc0816a446a6186e4a9a2f9df556bf709470137b8e60d9daa2", + "dc5180954df0c3391a60b44cbf70aee72b7dbb2addc90a0bf2ceac6113287eb501fe1ea9f4c51822664b82fe0279b039f4", + "c8a7d9131cebfa5388003cc30deac523aa9b09d148affff06ba40400e09ca900db770e07cedf5cd0647f6723c810ffcb596cac51edd6f49cd7be0010a3ac29e704", + true, + CipherSuite::TLS_AEGIS_128L_SHA256}, + CipherParams{ + "00000000000000000000000000000000", + "00000000000000000000000000000000", + 0, + "6dd5e43033fa6f021059a353edaf1f870387693054d0a2360fd1f6941a68f48ba972a1bc0816a446a6186e4a9a2f9df556bf709470137b8e60d9daa2", + "dc5180954df0c3391a60b44cbf70aee72b7dbb2addc90a0bf2ceac6113287eb501fe1ea9f4c51822664b82fe0279b039f4", + "c8a7d9131cebfa5388003cc30deac523aa9b09d148affff06ba40400e09ca900db770e07cedf5cd0647f6723c810ffcb596cac51edd6f49cd7be0010a3ac29e704", + false, + CipherSuite::TLS_AEGIS_128L_SHA256}, + CipherParams{ + "711a437629429db2e14058e2a826dcbf", + "eb036d6e483a212ff6ee25d970fe1ac3", + 0, + "", + "29937c0efb36ed27fe7709d7179b4f38a2fc191b5e8d9616b58f6dc9ba2ab74e13bbdcd233e8726d90f7ded06c3861582f27158732f997df9091446befe75855ab05b348d68f96e45445f44c31e9ba3e4d7be96d9c8e806535e79079139c71fcc599fea8701e0c2edf606986eff1535afdfa51d1be2dfdee", + "4a61f5d6b8e746bf6fb49ca2b16c22f4e9ffcdc89a3137b39bf5445fb6b989d5200f0c8d5538891a5e8979b5cd8c734128b4e4ad98b0cd598c40ec9be74725dbca84c65a52f17ac983330b0b74e4193540f6357c3bcde4e8d8fc6942314ba68115bf2a682756e3c42008803a81532708a0e7b5e3b843614555a819d187faaedcc36ee67d6711ee46", + true, + CipherSuite::TLS_AEGIS_128L_SHA256})); +INSTANTIATE_TEST_SUITE_P( + AEGIS256TestVectors, + EVPCipherTest, + ::testing::Values( + CipherParams{ + "7083505997f52fdf86548d86ee87c1429ed91f108cd56384dc840269ef7fdd73", + "18cd778e6f5b1d35d4ca975fd719a17aaf22c3eba01928b6a78bac5810c92c75", + 0, + "af5b16a480e6a1400be15c8e6b194c2aca175e3b5c3f3fbbeca865f9390a", + "5d6691271eb1b2261d1b34fa7560e274b83373343c2e49b2b6a82bc0f20cee85cd608d195c1a16679d720441c95fae86631f3f2cd27f38f71cedc79aaca7fdddbd4da4eeb97632366db65ca21acd85b41fd1a9de688bddff433a4757eb084e6816dbc8ff93f5995804", + "0943a3e659b86e267ffea969ddd6d6d63aa35d1a1f31fb6f47205104b132da65799cc64cc9f66ffa5ec479550c2c5dfa006f827ef02e3ab4dae3446bf93ccb5c17e1ec0393f161fca94f2944d041f162e9c964558b6b57d3bb393b9743b1f8338ff878a154800fd16c6eacac942353072bdeb9fcf85e5b6c04", + true, + CipherSuite::TLS_AEGIS_256_SHA512}, + CipherParams{ + "c88bb05b2aec1218e1a5026511e6d44de7bd502588e9e2a01591b39c5ead76ff", + "4a485f226a73f0c4e16242e8234841cdf6af1771eb278e7f35428d03eb5b4cf0", + 0, + "38a9809dbdd2579010d38bf5314f255b", + "2a4c06941ec356390542d7d7833fd68fc85a00c0452281f87dee6f10180d02182791232c7007fde35dfd5a901afa896296f9f344db717994d078fbd3a4cec8d782d2bdc205f3709827b776fd5c863a952fea97a14a6c2ee3f20432b8baa084470179078bd6a83597478b2fd9ae00ecb424822cb0d61e9a55a4", + "b8565db06c2fa493e09b6764f4d09296422095eb6e9890f606654713bfee6f362a123688b61f254f315f18b20bcc5ed8b0b4f2224de9f498e3ef03532a8bcddb361f5ace8ff491bab8b3d06550496501264f9f48ebad277e7492146789d0fc1a3b1e3e81598370a4183683d1fee25a9a1fe359c836932746b983d01767ad4b9b3d70cc917fe57e41e0", + true, + CipherSuite::TLS_AEGIS_256_SHA512}, + CipherParams{ + "77b473865175ebd5ddf9c382bac227029c25bdb836e683a138e4618cc964488b", + "f183d8de1e6dd4ccefa79fe22fabfda58e68dd29116d13408042f0713a4ee5f8", + 0, + "0679fd74a846965e33e558676115d843e440fa37092fbd5c57c82fd914210fcf948f911b04632d66be46248d772b3eb9f55b537e54b1ec751b63f035c8", + "9888b8ee03c3217a777b7558a31e331909570ea196f02c8cffad2c8dc6499b8125363c06a71c057842666bfb5c6acc937d2eecd960330c2361abdd88a4b191557ddf5102de75ddc7e09aee9862f32e24f1db3847a5f5b379fb32e2ef7ffb0d3a60", + "3464d835302583ade6ed99e23333e865d3308f31a6cb65bcefdc9a1b9b4d0e0f75513188480dac4a64922af4441324ce7de74eb9f7f4e414f6177a4814edc96313694b99ff8dd36b2f7f79c7ecd70ec475abe1c1909238767f172fd6b95e92c025b1f8c9704d7b845964e14ccb333f0d4b", + true, + CipherSuite::TLS_AEGIS_256_SHA512}, + CipherParams{ + "b8c6e8cea59ca9fd2922530ee61911c1ed1c5af98be8fb03cbb449adcea0ed83", + "af5bc1abe7bafadee790390277874cdfcc1ac1955f249d1131555d345832f555", + 0, + "d899366a0b4e4d86cce5ba61aca2a84349c8de5757e008e94e7d7a3703", + "b6c15f560be043d06aa27e15d8c901af6b19db7a15e1", + "4c8496dfa6c419ef3c4867769a9014bd17118c22eef5f0f7ed5cb9ba59df21310c274cf9a585", + true, + CipherSuite::TLS_AEGIS_256_SHA512}, + CipherParams{ + "0000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000000", + 0, + "6dd5e43033fa6f021059a353edaf1f870387693054d0a2360fd1f6941a68f48ba972a1bc0816a446a6186e4a9a2f9df556bf709470137b8e60d9daa2", + "dc5180954df0c3391a60b44cbf70aee72b7dbb2addc90a0bf2ceac6113287eb501fe1ea9f4c51822664b82fe0279b039f4", + "c8a7d9131cebfa5388003cc30deac523aa9b09d148affff06ba40400e09ca900db770e07cedf5cd0647f6723c810ffcb596cac51edd6f49cd7be0010a3ac29e704", + false, + CipherSuite::TLS_AEGIS_256_SHA512}, + CipherParams{ + "8011b1043674d753172302aa123478a121640daf4317957545749d0be6a91698", + "57bd1ac0f3db407989f88a762f60b3eabd03d3bc3bae577f3818b15c0974ae9c", + 0, + "", + "be1833fd169fd745acaa7d8584c457657433e6a3237225a086d47806804120613d78344e097ecc6a5f869d07", + "e34dff511e16bf12570a6828843c414b8fdced120db36ea0223e8700f57bea4c9dfbec5d3195caa633d52ee8e1077216251e24f81ed8cb16e829ba6c", + true, + CipherSuite::TLS_AEGIS_256_SHA512})); +#endif +} // namespace test +} // namespace openssl +} // namespace fizz diff --git a/fizz/backend/openssl/crypto/exchange/ECCurveKeyExchange.h b/fizz/backend/openssl/crypto/exchange/ECCurveKeyExchange.h new file mode 100644 index 00000000000..37db76be71a --- /dev/null +++ b/fizz/backend/openssl/crypto/exchange/ECCurveKeyExchange.h @@ -0,0 +1,30 @@ +/* + * 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 openssl { + +using P256KeyExchange = OpenSSLECKeyExchange; +using P256PublicKeyDecoder = detail::OpenSSLECKeyDecoder; +using P256PublicKeyEncoder = detail::OpenSSLECKeyEncoder; + +using P384KeyExchange = OpenSSLECKeyExchange; +using P384PublicKeyDecoder = detail::OpenSSLECKeyDecoder; +using P384PublicKeyEncoder = detail::OpenSSLECKeyEncoder; + +using P521KeyExchange = OpenSSLECKeyExchange; +using P521PublicKeyDecoder = detail::OpenSSLECKeyDecoder; +using P521PublicKeyEncoder = detail::OpenSSLECKeyEncoder; +} // namespace openssl +} // namespace fizz diff --git a/fizz/crypto/exchange/OpenSSLKeyExchange-inl.h b/fizz/backend/openssl/crypto/exchange/OpenSSLKeyExchange-inl.h similarity index 96% rename from fizz/crypto/exchange/OpenSSLKeyExchange-inl.h rename to fizz/backend/openssl/crypto/exchange/OpenSSLKeyExchange-inl.h index d54e1e75585..6a76636b41c 100644 --- a/fizz/crypto/exchange/OpenSSLKeyExchange-inl.h +++ b/fizz/backend/openssl/crypto/exchange/OpenSSLKeyExchange-inl.h @@ -6,9 +6,10 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include namespace fizz { +namespace openssl { namespace detail { template @@ -93,4 +94,5 @@ std::size_t OpenSSLECKeyExchange::getExpectedKeyShareSize() const { return T::keyShareLength; } +} // namespace openssl } // namespace fizz diff --git a/fizz/backend/openssl/crypto/exchange/OpenSSLKeyExchange.h b/fizz/backend/openssl/crypto/exchange/OpenSSLKeyExchange.h new file mode 100644 index 00000000000..c1e9767e275 --- /dev/null +++ b/fizz/backend/openssl/crypto/exchange/OpenSSLKeyExchange.h @@ -0,0 +1,52 @@ +/* + * 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 + +namespace fizz { +namespace openssl { + +/** + * Eliptic curve key exchange implementation using OpenSSL. + * + * The template struct requires the following parameters: + * - curveNid: OpenSSL NID for the named curve + */ +template +class OpenSSLECKeyExchange : public KeyExchange { + public: + ~OpenSSLECKeyExchange() override = default; + + void generateKeyPair() override; + + std::unique_ptr getKeyShare() const override; + + std::unique_ptr generateSharedSecret( + folly::ByteRange keyShare) const override; + + std::unique_ptr clone() const override; + + std::unique_ptr generateSharedSecret( + const folly::ssl::EvpPkeyUniquePtr& peerKey) const; + + void setPrivateKey(folly::ssl::EvpPkeyUniquePtr privateKey); + + const folly::ssl::EvpPkeyUniquePtr& getPrivateKey() const; + + std::size_t getExpectedKeyShareSize() const override; + + private: + folly::ssl::EvpPkeyUniquePtr key_; +}; +} // namespace openssl +} // namespace fizz + +#include diff --git a/fizz/backend/openssl/crypto/exchange/test/ECKeyExchangeTest.cpp b/fizz/backend/openssl/crypto/exchange/test/ECKeyExchangeTest.cpp new file mode 100644 index 00000000000..baf6d40634c --- /dev/null +++ b/fizz/backend/openssl/crypto/exchange/test/ECKeyExchangeTest.cpp @@ -0,0 +1,500 @@ +/* + * 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 + +#include + +using namespace folly; +using namespace folly::ssl; + +namespace fizz { +using namespace test; + +namespace openssl { +namespace test { + +struct KeyParams { + StringPiece privateKey; + StringPiece invalidPrivateKey; + // Obtained from a key share from firefox nightly for p256 + // For others openssl ec -in {KEY} -pubout -text + StringPiece encodedShare; + // Just fudged the previous share slightly + StringPiece invalidEncodedShare; + StringPiece tooSmallEncodedShare; +}; + +template +class Key : public ::testing::Test { + public: + using KeyExch = OpenSSLECKeyExchange; + using KeyEncoder = detail::OpenSSLECKeyEncoder; + using KeyDecoder = detail::OpenSSLECKeyDecoder; + + KeyParams getKeyParams(); +}; + +template <> +KeyParams Key::getKeyParams() { + return KeyParams{ + kP256Key, + kP256K1Key, + "048d5e897c896b17e1679766c14c785dd2c328c3" + "eecc7dbfd2e2e817cd35c786aceea79bf1286ab8" + "a5c3c464c46f5ba06338b24ea96ce442a4d13356" + "902dfcd1e9", + "048d5e897c896b17e1679766c14c785dd2c328c3" + "eecc7dbfd2e2e817cd35c786abeea79bf1286ab8" + "a5c3c464c46f5ba06338b24ea96ce442a4d13356" + "902dfcd1e9", + "048d5e897c896b17e1679766c14c785dd2c328c3"}; +} + +template <> +KeyParams Key::getKeyParams() { + return KeyParams{ + kP384Key, + kP256Key, + "04811041962bbac9859eb2aa19a475" + "2e573949d3f1eb8abcb131c1674e75" + "061f5e17b6a24724eeb73268ed82fd" + "3d2bfc93db88cabbf8c9da9e4c1479" + "ffdb9a54b522990aef401c1ab004aa" + "1fdf0e26aa8692ca5860ad6f6cf8ea" + "3bb95dbecb82a3", + "04811041962bbac9859eb2aa19a475" + "2e573949d3f1eb8abcb131c1674e75" + "061f5e17b6a24724eeb73268ed82fd" + "3d2bfc93db88cabbf8c9da9e4c1479" + "ffdb9a54b522990aef401c1ab004aa" + "1fdf0e26aa8621ca5860ad6f6cf8ea" + "3bb95dbecb82a3", + "3bb95dbecb82a3"}; +} + +template <> +KeyParams Key::getKeyParams() { + return KeyParams{ + kP521Key, + kP384Key, + "0401a76d5b0c42f557e418bf982b35" + "6e903f937b9d530cca8250e07c98ca" + "03293958b2fa8da20f9c4e9f7684df" + "3e872b470dac5368697b664ce4c677" + "3feb8862707b5f01434182eb962a3a" + "a8a707c868caa6edee62dd8456172e" + "f0bd738fac3abb04e87bd3e9ea9c1b" + "d09f8720a994c6162cb42546f86e32" + "8de930387e8ecc2c68ec41bcf2", + "0401a76d5b0c42f557e418bf982b35" + "6e903f937b9d530cca8250e07c98bd" + "03293958b2fa8da20f9c4e9f7684df" + "3e872b470dac5368697b664ce4c677" + "3feb8862707b5f01434182eb962a3a" + "a8a707c868caa6edee62dd8456172e" + "f0bd738fac3abb04e87bd3e9ea9c1b" + "d09f8720a994c6162cb42546f86e32" + "8de930387e8ecc2c68ec41bcf2", + "8de930387e8ecc2c68ec41bcf2"}; +} +using KeyTypes = ::testing::Types; +TYPED_TEST_SUITE(Key, KeyTypes); + +TYPED_TEST(Key, GenerateKey) { + typename TestFixture::KeyExch kex; + kex.generateKeyPair(); +} + +TYPED_TEST(Key, SharedSecret) { + typename TestFixture::KeyExch kex; + kex.generateKeyPair(); + auto shared = kex.generateSharedSecret(kex.getPrivateKey()); + EXPECT_TRUE(shared); +} + +TYPED_TEST(Key, ReadFromKey) { + typename TestFixture::KeyExch kex; + auto pkey = getPrivateKey(this->getKeyParams().privateKey); + kex.setPrivateKey(std::move(pkey)); + + auto pkey2 = getPrivateKey(this->getKeyParams().privateKey); + typename TestFixture::KeyExch kex2; + kex2.setPrivateKey(std::move(pkey2)); + auto shared = kex.generateSharedSecret(kex2.getPrivateKey()); + EXPECT_TRUE(shared); +} + +TYPED_TEST(Key, ReadWrongGroup) { + auto pkey = getPrivateKey(this->getKeyParams().invalidPrivateKey); + typename TestFixture::KeyExch kex; + EXPECT_THROW(kex.setPrivateKey(std::move(pkey)), std::runtime_error); +} + +TYPED_TEST(Key, Decode) { + std::string out = unhexlify(this->getKeyParams().encodedShare); + auto pub = detail::OpenSSLECKeyDecoder::decode(range(out)); + EXPECT_TRUE(pub); +} + +TYPED_TEST(Key, Encode) { + std::string out = unhexlify(this->getKeyParams().encodedShare); + auto pub = detail::OpenSSLECKeyDecoder::decode(range(out)); + EXPECT_TRUE(pub); + auto encoded = detail::OpenSSLECKeyEncoder::encode(pub); + + auto encodedStr = encoded->moveToFbString(); + EXPECT_EQ(encodedStr, out); +} + +TYPED_TEST(Key, DecodeInvalid) { + std::string out = unhexlify(this->getKeyParams().invalidEncodedShare); + EXPECT_THROW( + detail::OpenSSLECKeyDecoder::decode(range(out)), + std::runtime_error); +} + +TYPED_TEST(Key, DecodeInvalidSmallLength) { + std::string out = unhexlify(this->getKeyParams().tooSmallEncodedShare); + EXPECT_THROW( + detail::OpenSSLECKeyDecoder::decode(range(out)), + std::runtime_error); +} + +struct Params { + std::string peerPriv; // dsCAVS + std::string peerX; // QsCAVSx + std::string peerY; // QsCAVSy + std::string priv; // dIUT + std::string privX; // dIUTx + std::string privY; // dIUTy + std::string shared; // Z + bool success; + KeyType key; +}; + +class ECDHTest : public ::testing::TestWithParam {}; + +int getNid(const Params& param) { + switch (param.key) { + case KeyType::P256: + return P256::curveNid; + case KeyType::P384: + return P384::curveNid; + case KeyType::P521: + return P521::curveNid; + default: + throw std::runtime_error("invalid key type"); + } +} + +void setPoint(EcKeyUniquePtr& key, std::string x, std::string y) { + auto binX = unhexlify(x); + auto binY = unhexlify(y); + BIGNUMUniquePtr numX(BN_bin2bn((uint8_t*)binX.data(), binX.size(), nullptr)); + BIGNUMUniquePtr numY(BN_bin2bn((uint8_t*)binY.data(), binY.size(), nullptr)); + EC_KEY_set_public_key_affine_coordinates(key.get(), numX.get(), numY.get()); +} + +EvpPkeyUniquePtr getKey(const Params& param) { + auto privKeyBin = unhexlify(param.priv); + BIGNUMUniquePtr privateBn( + BN_bin2bn((uint8_t*)privKeyBin.c_str(), privKeyBin.size(), nullptr)); + EcKeyUniquePtr privateKey(EC_KEY_new_by_curve_name(getNid(param))); + EC_KEY_set_private_key(privateKey.get(), privateBn.get()); + setPoint(privateKey, param.privX, param.privY); + EvpPkeyUniquePtr pkeyPrivateKey(EVP_PKEY_new()); + EVP_PKEY_set1_EC_KEY(pkeyPrivateKey.get(), privateKey.get()); + return pkeyPrivateKey; +} + +void checkShared(std::unique_ptr shared, const Params& param) { + ASSERT_TRUE(shared); + auto sharedString = shared->moveToFbString(); + auto hexShared = hexlify(sharedString); + if (param.success) { + EXPECT_EQ(param.shared, hexShared); + } else { + EXPECT_NE(param.shared, hexShared); + } +} + +EvpPkeyUniquePtr createPublicKey(const Params& param) { + // Create the peer key + EcKeyUniquePtr peerKey(EC_KEY_new_by_curve_name(getNid(param))); + setPoint(peerKey, param.peerX, param.peerY); + + EvpPkeyUniquePtr pkeyPeerKey(EVP_PKEY_new()); + CHECK_EQ(1, EVP_PKEY_set1_EC_KEY(pkeyPeerKey.get(), peerKey.get())); + + return pkeyPeerKey; +} + +TEST_P(ECDHTest, TestKeyAgreement) { + try { + auto privateKey = getKey(GetParam()); + ASSERT_TRUE(privateKey); + + auto pkeyPeerKey = createPublicKey(GetParam()); + + std::unique_ptr shared; + switch (GetParam().key) { + case KeyType::P256: { + P256KeyExchange kex; + kex.setPrivateKey(std::move(privateKey)); + shared = kex.generateSharedSecret(pkeyPeerKey); + break; + } + case KeyType::P384: { + P384KeyExchange kex; + kex.setPrivateKey(std::move(privateKey)); + shared = kex.generateSharedSecret(pkeyPeerKey); + break; + } + case KeyType::P521: { + P521KeyExchange kex; + kex.setPrivateKey(std::move(privateKey)); + shared = kex.generateSharedSecret(pkeyPeerKey); + break; + } + default: + throw std::runtime_error("unknown key type"); + } + + checkShared(std::move(shared), GetParam()); + } catch (const std::runtime_error& ex) { + EXPECT_FALSE(GetParam().success) << ex.what(); + } +} + +TEST_P(ECDHTest, TestKexClone) { + try { + auto privateKey = getKey(GetParam()); + ASSERT_TRUE(privateKey); + + auto pkeyPeerKey = createPublicKey(GetParam()); + + std::unique_ptr chosenKex; + switch (GetParam().key) { + case KeyType::P256: { + P256KeyExchange kex; + kex.setPrivateKey(std::move(privateKey)); + + chosenKex = kex.clone(); + break; + } + case KeyType::P384: { + P384KeyExchange kex; + kex.setPrivateKey(std::move(privateKey)); + + chosenKex = kex.clone(); + break; + } + case KeyType::P521: { + P521KeyExchange kex; + kex.setPrivateKey(std::move(privateKey)); + + chosenKex = kex.clone(); + break; + } + default: + throw std::runtime_error("unknown key type"); + } + + folly::ssl::EcKeyUniquePtr ecKey(EVP_PKEY_get1_EC_KEY(pkeyPeerKey.get())); + auto point = EC_KEY_get0_public_key(ecKey.get()); + if (!point) { + throw std::runtime_error("public key invalid"); + } + + auto encodedPubKey = detail::encodeECPublicKey(pkeyPeerKey); + auto shared = chosenKex->generateSharedSecret(encodedPubKey->coalesce()); + + checkShared(std::move(shared), GetParam()); + } catch (const std::runtime_error& ex) { + EXPECT_FALSE(GetParam().success) << ex.what(); + } +} + +/*** + * Test vectors sourced from + * https://github.com/pyca/cryptography/blob/1a6628e55126ec1c98c98a46c04f777f77eff934/vectors/cryptography_vectors/asymmetric/ECDH/KASValidityTest_ECCStaticUnified_NOKC_ZZOnly_init.fax + * These are NIST test vectors. + */ +// clang-format off +INSTANTIATE_TEST_SUITE_P( + TestVectors, + ECDHTest, + ::testing:: + Values( + Params{ + "e19007eb245d6995ffa8b3ede1e59193aa6cfaaf4cc1e1d126948610c9b3f44c", + "758b2f0e79a3d0a94f521ae31dcff50fabd394bb4bbec8fa37d1566f463444e7", + "b981e686e53e9e9dc2e3f263e810c89b4c271e62392f59ed45ed30ac3a5bfd33", + "8171000763de347d0eb650dd6fddac2ad48ec122c162d66c3df257aea13192fb", + "c22ac2ee50e771a93b2b6a42c5e9b76b45a56e0d0011e34aa790283ede61f3d9", + "0ef754edae5e79c518f1056aa5179cbb6a3a4b7c9654b5048f4259bd2597e57d", + "5cbea453310285b22f128178bd09b906fde9e660b5a17a7cec809a5a9a1e9287", + true, + KeyType::P256}, + Params{ + "0ced658b6113979f8d05fd7b305ce0b8d70f45034d021b052cbcb318e0cfd602", + "acbcb31f5f6798a00f28aa4a634873744768db612925336efca98122a76d1b5e", + "7dcefeb3ccb530029a8b62e5a7f00c42fc7ebeac8f469c289ea77b6186d661f0", + "64e23f7a2d279930f1de66b4bc147786b168d059f581268c24f6650362246e63", + "ba393b401354aa9552c4289b7a55288d97590429a4003913a243081bacf88acf", + "d089687aa5442684d71b805ea2b36f6c1c783833346dfdd8208768ed2a7e767d", + "f70e4fc9ba68aafe07be1767620e64dd5e5bb7ab279f0657465cddeb69e36fa9", + true, + KeyType::P256}, + Params{ + "0ced658b6113979f8d05fd7b305ce0b8d70f45034d021b052cbcb318e0cfd602", + "758b2f0e79a3d0a94f521ae31dcff50fabd394bb4bbec8fa37d1566f463444e7", + "b981e686e53e9e9dc2e3f263e810c89b4c271e62392f59ed45ed30ac3a5bfd33", + "8171000763de347d0eb650dd6fddac2ad48ec122c162d66c3df257aea13192fb", + "c22ac2ee50e771a93b2b6a42c5e9b76b45a56e0d0011e34aa790283ede61f3d9", + "0ef754edae5e79c518f1056aa5179cbb6a3a4b7c9654b5048f4259bd2597e57d", + "5cbea453310285b22f128178bd09b906fde9e660b5a17a7cec809a5a9a1e9287", + true, + KeyType::P256}, + Params{ + "639ef9ee75a3888617fdd7ed89d62f7398b0eb4f20ccbd35026e150fc937c927", + "1d2dda4a3735be1f3aedfa8a7bb1410c3867c5d67f55a3dd5376b137352f113d", + "eca92fb210b1813f51ea2483ff461eb24786afb41f1a00870cf65aab5bbd725e", + "e062138981049c3b4b964fa5a28569e0142c2c51d6ca0bebdb3270e2ab77fb30", + "9aa8dd75f7d929b1f5f123aa9f3265be34f771c20bb50deea684a139a10938f8", + "2b74f503fa7b08db1c76d97c2e571cb91f68a93413daf102c47fee1b8a264d93", + "9f5f64d76f9bb2f2af24debdd47323d5df9d2b84fc7c7aac1f6d41678adec7de", + false, + KeyType::P256}, + Params{ + "305dfb4a8850cc59280891147baf457bfe5e2bae984571634a77dc8d3472fa9b", + "202cb5a224e6c2a84e624094486edf04116c8d68ec1f4a0e0ed9ee090e1a900b", + "cacf3a5789bb33954be600425d62d9eae5371f90f88167258814213e4a4f4b1a", + "72cc52808f294b64b6f7233c3d2f5d96cc1d29287320e39e1c151deef0bc14eb", + "49a768c9a4ca56e374f685dd76a461b1016c59dcded2c8d8cbd9f23ca453831f", + "b1e3bb9b5f12a3b5ae788535d4554bd8c46e0e6130075e4e437d3854cf8f1c34", + "c0147c3c2691b450b5edc08b51aea224d9f4359ff67aab6da3146f396dbceaea", + false, + KeyType::P256}, + /* + * P384 + */ + Params{ + "0e5c98ff2d2a3aab14ad0067b60dbe64e4f541ab5bed11c5a0c55ae1e60b51ff5faaf377837977d80cbfdc33c2ff542b", + "d1bf2ac21637d66d6398aac01dcd56ac6f065fb45d1f6f16747bab9e9b01b4630b59b20927aea147355bf41838acb482", + "4c9e23f1c5a41647d094086bf4ed31708651f21d996c47780688ac10f77deee2e43b5241b6caecd2fd5444bc50472e0e", + "f865418473e5bf7d2e1bbcd9bd5a9270c003a9dd35e778133ca59fcab4bb64fe24d6800e7047bdd033abc8bfa8db35b5", + "32b72ab9b558249dcbc6cbade234f58e4f7aa5d3f6420ea99a5f997e8c2a91fb7fd83779d0d2169428683771c745fd1a", + "c749e02a3719bb56bf1dfc4ba3820309c01ab6e84cb29db7cdd80f127233f5295687f8178f3a8704c1063b84c2ee472f", + "a781430e6078a179df3f9ee27cd8fdc6188f161b6c4ccc4053ef6c6ca6fc222946883a53c06db08f0a020023ced055aa", + true, + KeyType::P384}, + Params{ + "925065e50f7eae1319865720ae483de4dba7449dc144c4b50b8e96c4f4fcd9f8b3fbf693262429c91c69d8dd8355fdd8", + "4c619593e459e4aca7c572834064134d93e8b1b676388b0ff67b893722cf7e8396cd953df38a42e4131dbad29518b2af", + "dbe261af918baade39070e88f62eabe4ee9d5f2563707271cc566dd7a2380aa4707d15d6eef142a52d75a67429afd0c6", + "c40c805488115e43279c99797bcbfff8d9922ea9aec471d9ba659590034c3fb739d23661c0aae6e7ada2a1de36eb63a1", + "a95b7ad4de234e9be8b260313ddb96a404b75b3a7e0f234981f3b189d86ac31bbe3937776c0608024871ef64815784b3", + "4890ee227219ca5ce34632cbca5732accc2d276fa1b1cc9d14f6b7e4b0f5e116a92cbef743de3e69537e250f27125e82", + "128934db846099c8d8caa788b0b84bb65bd57b20774ff7f8e7f29939297d72bbc232c5d2b2c8ef1d63e3d75d3908e778", + true, + KeyType::P384}, + Params{ + "259c53eec19d01d19428f6cc5cd445ab685578c53325f6d2f157bd0328deca4ffb8c21dca891d59e34a807203f7e9a5d", + "d18832f4cf3013e514b4fb4c42bbeb15708e20ed91b982598deb2d67b37275587fcb35cf214039ec4fd1834d704c1faf", + "917c49465bef063949957256eddbece762090ef10f8c48566bd71dc0ad9eb3bc00f0b3f6a88d614210804dd633ca6e68", + "3120ee90dcce02bac90a66d30ad602e94edcce482dbc5245a136df1d0509b04f6ee305fedd290775c71f1631684f5c0a", + "7a3e0fd767acf409cebe6fe0222974438bccdefb13f0d668b8daad43a6fdbdf46845c45b9594ffd6742a615dd834f1a5", + "e3cc9f7153b6ffd3b285349996b952905466942d17f6a9685a11318b0c2c72904961d246cbe3ef98903dbbfb0fbe55b0", + "5c8d476518873208e1c97685c033a1ba6ec279b8674060cc1a99469908604353043bf488109150b9b2f9b3b1440a426c", + true, + KeyType::P384}, + Params{ + "4e422a76b085ae939a8166afb98e344b9ac30bab610e90b3d7449de0a0de6b88fadb095e4818521bb1473540a7ec73ee", + "de464ed2129eef42ef23cb1bfad27382293edad91d867b1b8b82a19bd17516daf0a73548787a733d66ca4f4d40b52da1", + "f07bd6003229de37d6293513cbace59ebc24efb571c065df2bc1465c4570928fd612a59a46805b6adce7fb94e36ad043", + "f8f6697507aeec09fe024f974e00e67f12a14c130df875732b450b3ae8d2cbbb1fcf46bac9207e89a297352eeade7df5", + "c1db2e81eca0e5b02e8736ff351aa8e59bdadd1c9c7428faf93493c7b93153ec2c55964a157025ff6ddb4523d8e0a453", + "98daa370a6610ecf604e38e1e70b7f57657c49908eb15634a3a65a175ca7b8cfe1ad535037928ae95c80107a1e018b3c", + "d80415977c3ce1737fd574596e981c767ecaf5c70084fae6c2072f0ccecc8bdda54a0bf44357981303a2ecc78b26e97c", + false, + KeyType::P384}, + Params{ + "4ee6a24b5dca82b215c92cb298d5ac24b77820c7b7e9c8fe4d05d7a297b8f6be40f8d8cf09a4bb238cfdbe05f851c493", + "1f9af3b14439d4c56b353b5892dd85b6a27053e1d23f5f05ff95ea3fa942eb463e1074b01828a79c865b16fde0fc0f24", + "01a81aaef502fe84508b054924d90078f68d8d4e9ae5299bd0ea60a97167c549011f4a024e964292d378e82b6874caad", + "3d715cd0d6490ba5607e7eae2c74361be65de413f10576c1d996658e20c78f8110c70104067922d48303f6ccb1b23f46", + "2fa7d2ea93945b41c929279a750ded758d9db93d120b5eeda3d9994e36e3381f653d19dcae0eccb1a12153ce4025a62e", + "04c6e45983485529e9dacba8d609cffaec849f7c5e5cf4a025ce2c0ff9ae6679b4564b9af58fab58c7f92837597b830b", + "5e77e466aeae9c10ff8d255e07cf0ad9eae50c8a6fd2c7cd889d73d968c423a15c0462b05bf985cbf679a629e380ce80", + false, + KeyType::P384}, + /* + * P521 + */ + Params{ + "0000002fef62381162942889a6094a6bb9ac1f4ddf66d9cda9f618232d31b90c50d7da78a47ed91d40cae946898571db972dc294b109815f38feee9eaac0d5f7c3250728", + "0000004b05ffa025113390797f2736174aa1c784f4dd34e764ee40d40e4d2442677ebea3498086c9473e5c92789cbdb02bb327bbd61d58690f6a83d9ca73bccbde37dec4", + "0000004da67cffc98070b82af61feba78787efefb13bd810d80ff92304788e49a4e5b634b3565474a8ecb1615d7b1b77a7a27875adb73a8a5d8f3f84e5e8b744cda250b0", + "00000311a5e520e238141527671a38cb6f776d96a9f82ef70dffa11dc0895f4060f1abbb9ad6fd259e4a7beaf5f7266ea1bb45bcbfebfda2705e5c551e710fb1d745f57e", + "0000010ba3778cb2cc965834c0a9593adc6a222692656d657fb0d15293edf0ab33762384a96a16fddea7540b7ccbcca46ec4ac9bcf95fdb5aa18e158aab4d91981bd733e", + "0000018522df93ddd636e5bc94daecdc600fa241686ec18634fd30b7cbdfdc9ffba1166ac08df34a31896f6fad191414929261ebd7187afb72919f8a0c926be37f99c1e5", + "01a5e4b31be4b1346e53906b6767b1fe94ec1a8a5abc28fb6f01518c056959af3bc9335dddab178b52318cc5512559931b8dc18de0ce810c2c7f15769d7ce70e719c", + false, + KeyType::P521}, + Params{ + "0000013262b7f4f36de274b2c60e4a812866740e545186953f798ac07b5d74e4f0cc1123a9bfcbf77850e2d856246065c54a2437a2816a7d79d6180a9a6ba17f18df8b65", + "000001474af758238005238b2fa253c4f9c557de664d64c66d7d88f334555997591ccc242ff3c6d0e34d07fc835aaae024c2bd21f2ba5c0b0a8ac3fdd90e1c479cb8e538", + "000000a721b04654204ca19064b37a4abf4247413a6d29e9211a0df9d50975c7d8d4654dc04a478455ea24993f0fef5460f189c4729c15fba385fd85ef42ae7610e39450", + "000001a23de55fb7ad153e7e65d21ad10c77fdf2072b2a5aa116aaf1bc31a345420c1fe8eaccbbcdeb07b73ba2fa706c7498e3a4828f348b00af9df1551780e709a7754c", + "000000ed7bc3a95ef74dc3a9893a5ec7c9fab723c16dc21b30341c374c25e1334dada7f92d62967f3bca4da70b0a77fa0732dac05a3d19cb04e50b3cd1894549ac1d3c6e", + "000001c30d23ea4c140aabfba3753ce40c788010342c15c51d2dd6e9b079194e593ba965ea419ef37746f954027fa1b8159ccd3b54aece67451c7e892d6f6e1fb44c548c", + "01e8ff7a8c57b017f8b8266adab65fe2c417173566087e15c5fc972071cc560ac93908a806468bc44b8312a8a48464886ca0d767db938447387a348f3f56c6463796", + true, + KeyType::P521}, + Params{ + "000000364b6cc953c841d2e1c8c292fadaa673ea073d150da4cec9c0c6544c92373c6a42a781283bedb080a4de720b99769869019a38023019b9d15c99b2a08a02104cc7", + "000001abbbcd3912723cbb3147145a12b8f2f40d1fe6484fa831250435ffb8eb751bccdf425e81d8e79518ec84c56bd28763c417f30a16c213abbfd8e5871d93dcb3f0d0", + "00000237c413a4527ca89dee7c8a5c45fc0207627e3db79353ee506857d68f746ea2c7b4d04ab1c10df56b1a706012f616ec9a5510467c49a56941841a1636f620dc3ac4", + "000000e04b0e32496f1d43ff48d759dc57d586c6c55efb6460fc1148021afa1943180aea2a1be7721a69ebf9d55585a4d4bdb6ff3e177448568c0b45542eddb936fbd870", + "00000195a305d23a94794e680b211b8ec4a5c2150a2002afdc4ff5da254c438b5686b12dda72bd8dbb009d07d469c3d664e67da274de7f2e2dc84661d2a054638cf6fc98", + "000000e56b77c46a997c06da59033e1c57939f6f8513329ebe93dcb00857a8ff850428473d937528e85c15a5fe46df1ffb7aeed4b17f7fc9ad08fb121045e2eea5a316b2", + "013eeaad91133eb338a4c1f27af66aa7f7614619b6c21c20f0e2d68fca2e9cbaa224104a45aa4dbefcb1e49b7f1a36171a35102d2b7d2ffbade07e600b4a7e28c05c", + false, + KeyType::P521}, + Params{ + "000001ef093db892daaa05d43e70654bd702d7e177465b00a5ff70a9a072774d7cda3893c181ad1dbb23f8352d3098025406a442c60afaf949dd37ee9c36ee2f785dc693", + "0000017e817b93e7e3eb95291545afffa2dcd1ff90b97c2b7d9cc7a46511cbdf7a7afe7a2ce126822d08bc71519542743dfece750e18f1e01bb5201e622e2697e5b1faa6", + "00000025e5e302514ccb15ed84291ba30746b1176f2b080bfa78ef7ce5721fd00d3d717421932d61ad74068c36885a9a0e6537183209a79054fcb8df43b83066f60c47d5", + "0000004e9f4ebd9f4772df7c003828210d087aa41c0154394428f5f8624536a15c157634c5200de037e46698d4f8484feb164374899b2d9d5e258080dae6b3429c965154", + "0000021fb91b2abbdd7dee5e2750a1fce602e235a6512b429ab0a3845bd8c8a630d9d35850e0ba78f01c01ffae6ca1a88c93c153a6fdc09f76fae768bdd449e7f6730b68", + "0000005cb38e5272648f2adcb5ec7a37f3b2135c93a0202f2c822383eae29468392f4baeddabf0acd3bee0cbc1dd540b435d34ecb008408ac093978976741d1afa374c72", + "01bca2f6325ccf7a6a213b2678ded8ce3e687497c7f7f46a4a06bf3e69dabb745a883d130936c786debf2fe5ef8880f1bb976a79e33b68d30d7356b5a4672e65fcea", + false, + KeyType::P521}, + Params{ + "0000014199e2e81aa1f98bf0f39d069e720820d0433222f5b8ca26606fe7c4d0cd619b415d2a629674479a6ec6171f05f657a168aad9342e8489a39cf485a396a8400c59", + "00000070ce983ca6d0a7aa7849bef13e11e3dc1d62e1ddb85b54d4a3c9de5b47a078846f92105304efe4a4e71d7ff91c19a7b4e03fd87c2d8fb70732e274b114a0bf3bd2", + "0000009f564f73a5c7282556437dc4c2fbdf87d5fcfbaab0feecf1f7a88104f15a7314b083f711bd7b3a2c74b1096fdccdac01e0a35b8fd86d99ba9d64d10e190033c3df", + "000000c0b19361224245482bbe42110f9aa44f2818b5146710c24b4825a9a3e0a4743fc7983df560bd85d30639bbdb4d7fc0c56a862e0ef349801bef06ed0a9774463e9f", + "000000231f2c5c2ad3894b81ad2c8942221d06041f37b8d520e926701b9fb38e32833f9b2b99142d0e54baef33c17b2bd0f23ec3e1b08b9a87f65942384e5863607ba65c", + "0000005e3b734d4207b51259a1fca526161250176eab1364930d7d06259f43e68202962d9bb818a44bf3bf4a385e634a8d52489c58e2c9234670ae9f30668a2f5553c261", + "01186d749c6b2a215c59df35ef6f2f6ed1745a9b2e15fca225e79faa7c5b9af44821d50765b45c3c66e210ec78d4bccb7f8c44c19cf80f5357938df48e320fa1ed88", + true, + KeyType::P521})); +// clang-format on +} // namespace test +} // namespace openssl +} // namespace fizz diff --git a/fizz/crypto/signature/Signature-inl.h b/fizz/backend/openssl/crypto/signature/Signature-inl.h similarity index 98% rename from fizz/crypto/signature/Signature-inl.h rename to fizz/backend/openssl/crypto/signature/Signature-inl.h index 65a4288022c..0edd11b5fb1 100644 --- a/fizz/crypto/signature/Signature-inl.h +++ b/fizz/backend/openssl/crypto/signature/Signature-inl.h @@ -6,11 +6,12 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include #include #include namespace fizz { +namespace openssl { namespace detail { @@ -189,4 +190,5 @@ inline void OpenSSLSignature::setKey( } pkey_ = std::move(pkey); } +} // namespace openssl } // namespace fizz diff --git a/fizz/crypto/signature/Signature.cpp b/fizz/backend/openssl/crypto/signature/Signature.cpp similarity index 97% rename from fizz/crypto/signature/Signature.cpp rename to fizz/backend/openssl/crypto/signature/Signature.cpp index c77de429e38..295a3a5a59d 100644 --- a/fizz/crypto/signature/Signature.cpp +++ b/fizz/backend/openssl/crypto/signature/Signature.cpp @@ -6,8 +6,8 @@ * LICENSE file in the root directory of this source tree. */ -#include -#include +#include +#include #include #include @@ -17,6 +17,7 @@ using namespace folly; namespace fizz { +namespace openssl { namespace detail { static const EVP_MD* getHash(int hashNid) { @@ -220,4 +221,5 @@ void rsaPssVerify( } } } // namespace detail +} // namespace openssl } // namespace fizz diff --git a/fizz/backend/openssl/crypto/signature/Signature.h b/fizz/backend/openssl/crypto/signature/Signature.h new file mode 100644 index 00000000000..62e2dd7e34d --- /dev/null +++ b/fizz/backend/openssl/crypto/signature/Signature.h @@ -0,0 +1,70 @@ +/* + * 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 openssl { + +enum class KeyType { RSA, P256, P384, P521, ED25519 }; + +/** + * Signature implementation using OpenSSL. + */ +template +class OpenSSLSignature { + public: + void setKey(folly::ssl::EvpPkeyUniquePtr pkey); + + /** + * Returns a signature of data. + * + * Only valid for SignatureSchemes that are compatible with KeyType. + * + * setKey() must be called before with a private key. + */ + template + std::unique_ptr sign(folly::ByteRange data) const; + + /** + * Verifies that signature is a valid signature over data. Throws if it's not. + * + * Only valid for SignatureSchemes that are compatible with KeyType. + * + * setKey() must be called before. + */ + template + void verify(folly::ByteRange data, folly::ByteRange signature) const; + + private: + folly::ssl::EvpPkeyUniquePtr pkey_; +}; + +#if !FIZZ_OPENSSL_HAS_ED25519 +template <> +class OpenSSLSignature { + public: + [[noreturn]] void setKey(folly::ssl::EvpPkeyUniquePtr); + + template + [[noreturn]] std::unique_ptr sign(folly::ByteRange) const; + + template + [[noreturn]] void verify(folly::ByteRange, folly::ByteRange) const; +}; +#endif + +} // namespace openssl +} // namespace fizz + +#include diff --git a/fizz/backend/openssl/crypto/signature/test/ECSignatureTest.cpp b/fizz/backend/openssl/crypto/signature/test/ECSignatureTest.cpp new file mode 100644 index 00000000000..5cc5a532b92 --- /dev/null +++ b/fizz/backend/openssl/crypto/signature/test/ECSignatureTest.cpp @@ -0,0 +1,221 @@ +/* + * 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 + +using namespace folly; +using namespace folly::ssl; + +namespace fizz { +namespace openssl { +namespace testing { + +struct Params { + std::string msg; + std::string priv; // x + std::string pubX; // Ux + std::string pubY; // Uy +}; + +class ECDSATest : public ::testing::TestWithParam { + void SetUp() override { + OpenSSL_add_all_algorithms(); + } +}; + +class ECDSA256Test : public ECDSATest {}; +class ECDSA384Test : public ECDSATest {}; +class ECDSA521Test : public ECDSATest {}; + +void setPoint(EcKeyUniquePtr& key, std::string x, std::string y) { + auto binX = unhexlify(x); + auto binY = unhexlify(y); + BIGNUMUniquePtr numX(BN_bin2bn((uint8_t*)binX.data(), binX.size(), nullptr)); + BIGNUMUniquePtr numY(BN_bin2bn((uint8_t*)binY.data(), binY.size(), nullptr)); + EC_KEY_set_public_key_affine_coordinates(key.get(), numX.get(), numY.get()); +} + +EvpPkeyUniquePtr getKey(int nid, const Params& param) { + auto privKeyBin = unhexlify(param.priv); + BIGNUMUniquePtr privateBn( + BN_bin2bn((uint8_t*)privKeyBin.c_str(), privKeyBin.size(), nullptr)); + EcKeyUniquePtr privateKey(EC_KEY_new_by_curve_name(nid)); + EC_KEY_set_private_key(privateKey.get(), privateBn.get()); + setPoint(privateKey, param.pubX, param.pubY); + EvpPkeyUniquePtr pkeyPrivateKey(EVP_PKEY_new()); + EVP_PKEY_set1_EC_KEY(pkeyPrivateKey.get(), privateKey.get()); + return pkeyPrivateKey; +} + +void modifySig(folly::IOBuf* sig) { + auto& sigPtr = sig->writableData()[10]; + if (sigPtr == 1) { + sigPtr = 2; + } else { + sigPtr = 1; + } +} + +void modifyData(folly::IOBuf* sig, std::string& msg) { + auto& sigPtr = sig->writableData()[10]; + if (sigPtr == 1) { + sigPtr = 2; + } else { + sigPtr = 1; + } + auto& msgPtr = msg[2]; + if (msgPtr == 1) { + msgPtr = 2; + } else { + msgPtr = 1; + } +} + +TEST_P(ECDSA256Test, TestSignature) { + auto key = getKey(P256::curveNid, GetParam()); + OpenSSLSignature ecdsa; + ecdsa.setKey(std::move(key)); + { + std::string msg = GetParam().msg; + auto sig = ecdsa.sign( + IOBuf::copyBuffer(msg)->coalesce()); + ecdsa.verify( + IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()); + } + { + std::string msg = GetParam().msg; + auto sig = ecdsa.sign( + IOBuf::copyBuffer(msg)->coalesce()); + modifySig(sig.get()); + EXPECT_THROW( + ecdsa.verify( + IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()), + std::runtime_error); + } + { + std::string msg = GetParam().msg; + auto sig = ecdsa.sign( + IOBuf::copyBuffer(msg)->coalesce()); + modifyData(sig.get(), msg); + EXPECT_THROW( + ecdsa.verify( + IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()), + std::runtime_error); + } +} + +TEST_P(ECDSA384Test, TestSignature) { + auto key = getKey(P384::curveNid, GetParam()); + OpenSSLSignature ecdsa; + ecdsa.setKey(std::move(key)); + { + std::string msg = GetParam().msg; + auto sig = ecdsa.sign( + IOBuf::copyBuffer(msg)->coalesce()); + ecdsa.verify( + IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()); + } + { + std::string msg = GetParam().msg; + auto sig = ecdsa.sign( + IOBuf::copyBuffer(msg)->coalesce()); + modifySig(sig.get()); + EXPECT_THROW( + ecdsa.verify( + IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()), + std::runtime_error); + } + { + std::string msg = GetParam().msg; + auto sig = ecdsa.sign( + IOBuf::copyBuffer(msg)->coalesce()); + modifyData(sig.get(), msg); + EXPECT_THROW( + ecdsa.verify( + IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()), + std::runtime_error); + } +} + +TEST_P(ECDSA521Test, TestSignature) { + auto key = getKey(P521::curveNid, GetParam()); + OpenSSLSignature ecdsa; + ecdsa.setKey(std::move(key)); + { + std::string msg = GetParam().msg; + auto sig = ecdsa.sign( + IOBuf::copyBuffer(msg)->coalesce()); + ecdsa.verify( + IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()); + } + { + std::string msg = GetParam().msg; + auto sig = ecdsa.sign( + IOBuf::copyBuffer(msg)->coalesce()); + modifySig(sig.get()); + EXPECT_THROW( + ecdsa.verify( + IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()), + std::runtime_error); + } + { + std::string msg = GetParam().msg; + auto sig = ecdsa.sign( + IOBuf::copyBuffer(msg)->coalesce()); + modifyData(sig.get(), msg); + EXPECT_THROW( + ecdsa.verify( + IOBuf::copyBuffer(msg)->coalesce(), sig->coalesce()), + std::runtime_error); + } +} + +// Test vector from https://tools.ietf.org/html/rfc6979#appendix-A.2.5 +// We can't test those directly since we'd need to use the more complicated +// API of actually setting k and dealing with ECDSA_sig objects directly. +INSTANTIATE_TEST_SUITE_P( + TestVectors, + ECDSA256Test, + ::testing::Values(Params{ + "sample", + "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721", + "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6", + "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299"})); +INSTANTIATE_TEST_SUITE_P( + TestVectors, + ECDSA384Test, + ::testing::Values(Params{ + "sample", + "6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D8" + "96D5724E4C70A825F872C9EA60D2EDF5", + "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64" + "DEF8F0EA9055866064A254515480BC13", + "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1" + "288B231C3AE0D4FE7344FD2533264720"})); +INSTANTIATE_TEST_SUITE_P( + TestVectors, + ECDSA521Test, + ::testing::Values(Params{ + "sample", + // NOTE these are 0 padded at the beginning for unhexlify + "00FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75C" + "AA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83" + "538", + "01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD3" + "71123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F502" + "3A4", + "00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A2" + "8A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDF" + "CF5"})); +} // namespace testing +} // namespace openssl +} // namespace fizz diff --git a/fizz/backend/openssl/crypto/signature/test/EdSignatureTest.cpp b/fizz/backend/openssl/crypto/signature/test/EdSignatureTest.cpp new file mode 100644 index 00000000000..ca30a032283 --- /dev/null +++ b/fizz/backend/openssl/crypto/signature/test/EdSignatureTest.cpp @@ -0,0 +1,145 @@ +/* + * 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 + +#define ED25519_FIXTURE(num) \ + Params { \ + kEd25519PrivateKey##num, kEd25519PublicKey##num, kEd25519Message##num, \ + kEd25519Signature##num \ + } + +using namespace folly; + +namespace fizz { +namespace openssl { +namespace testing { + +#if FIZZ_OPENSSL_HAS_ED25519 +TEST_P(EdDSATest, TestSignature) { + auto privateKey = fizz::test::getPrivateKey(GetParam().privateKey); + auto message = unhexlify(GetParam().hexMessage); + auto generatedSignature = + detail::edSign(IOBuf::copyBuffer(message)->coalesce(), privateKey); + EXPECT_EQ(hexlify(generatedSignature->coalesce()), GetParam().hexSignature); +} + +TEST_P(EdDSATest, TestVerify) { + auto publicKey = fizz::test::getPublicKey(GetParam().publicKey); + auto message = unhexlify(GetParam().hexMessage); + auto signature = unhexlify(GetParam().hexSignature); + + // 1. Verification should pass for the message-signature pair in our fixtures + detail::edVerify( + IOBuf::copyBuffer(message)->coalesce(), + folly::ByteRange(folly::StringPiece(signature)), + publicKey); + + // 2. Verification should fail if the message is modified + auto modifiedMessage = modifyMessage(message); + EXPECT_THROW( + detail::edVerify( + IOBuf::copyBuffer(modifiedMessage)->coalesce(), + folly::ByteRange(folly::StringPiece(signature)), + publicKey), + std::runtime_error); + + // 3. Verification should fail if the signature is modified + auto modifiedSignature = modifySignature(signature); + EXPECT_THROW( + detail::edVerify( + IOBuf::copyBuffer(message)->coalesce(), + folly::ByteRange(folly::StringPiece(modifiedSignature)), + publicKey), + std::runtime_error); +} + +TEST_P(Ed25519Test, TestOpenSSLSignature) { + auto privateKey = fizz::test::getPrivateKey(GetParam().privateKey); + auto message = unhexlify(GetParam().hexMessage); + auto signature = unhexlify(GetParam().hexSignature); + + // 1. Test instantiation of OpenSSLSignature for Ed25519 + OpenSSLSignature eddsa; + + // 2. Test setting key + eddsa.setKey(std::move(privateKey)); + + // 3. Test sign method + auto generatedSignature = eddsa.sign( + IOBuf::copyBuffer(message)->coalesce()); + EXPECT_EQ(hexlify(generatedSignature->coalesce()), GetParam().hexSignature); + + // 4. Test verify method succeeds when it should + eddsa.verify( + IOBuf::copyBuffer(message)->coalesce(), + folly::ByteRange(folly::StringPiece(signature))); + + // 5. Test verify method fails if the message is modified + auto modifiedMessage = modifyMessage(message); + EXPECT_THROW( + eddsa.verify( + IOBuf::copyBuffer(modifiedMessage)->coalesce(), + folly::ByteRange(folly::StringPiece(signature))), + std::runtime_error); + + // 6. Test verify method fails if the signature is modified + auto modifiedSignature = modifySignature(signature); + EXPECT_THROW( + eddsa.verify( + IOBuf::copyBuffer(message)->coalesce(), + folly::ByteRange(folly::StringPiece(modifiedSignature))), + std::runtime_error); +} + +// Test vectors from RFC8032 +INSTANTIATE_TEST_SUITE_P( + TestVectors, + EdDSATest, + ::testing::Values( + ED25519_FIXTURE(1), + ED25519_FIXTURE(2), + ED25519_FIXTURE(3), + ED25519_FIXTURE(4), + ED25519_FIXTURE(5))); + +// Test vectors from RFC8032 +INSTANTIATE_TEST_SUITE_P( + TestVectors, + Ed25519Test, + ::testing::Values( + ED25519_FIXTURE(1), + ED25519_FIXTURE(2), + ED25519_FIXTURE(3), + ED25519_FIXTURE(4), + ED25519_FIXTURE(5))); +#endif + +std::string modifyMessage(const std::string& input) { + if (input.size() == 0) { + return "a"; + } + auto modifiedMessage = std::string(input); + modifiedMessage[0] ^= 1; // Flip a bit in the first character + return modifiedMessage; +} + +std::string modifySignature(const std::string& input) { + CHECK_GT(input.size(), 0) << "Signatures should have positive length"; + auto modifiedMessage = std::string(input); + modifiedMessage[0] ^= 1; // Flip a bit in the first character + return modifiedMessage; +} +} // namespace testing +} // namespace openssl +} // namespace fizz diff --git a/fizz/backend/openssl/crypto/signature/test/EdSignatureTest.h b/fizz/backend/openssl/crypto/signature/test/EdSignatureTest.h new file mode 100644 index 00000000000..9f08f6599d0 --- /dev/null +++ b/fizz/backend/openssl/crypto/signature/test/EdSignatureTest.h @@ -0,0 +1,103 @@ +// Copyright 2004-present Facebook. All Rights Reserved. +// @lint-ignore-every PRIVATEKEY + +#pragma once + +#include + +namespace fizz { +namespace openssl { +namespace testing { + +struct Params { + folly::StringPiece privateKey; + folly::StringPiece publicKey; + folly::StringPiece hexMessage; + folly::StringPiece hexSignature; +}; + +class EdDSATest : public ::testing::TestWithParam {}; +class Ed25519Test : public EdDSATest {}; +class Ed448Test : public EdDSATest {}; + +// Private key fixtures from RFC8032 +constexpr folly::StringPiece kEd25519PrivateKey1 = R"( +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIJ1hsZ3v/VpguoRK9JLsLMREScVpezJpGXA7rAMcrn9g +-----END PRIVATE KEY----- +)"; +constexpr folly::StringPiece kEd25519PrivateKey2 = R"( +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIEzNCJso/5banbbDRuwRTg9bijGfNaumJNqM9u1PuKb7 +-----END PRIVATE KEY----- +)"; +constexpr folly::StringPiece kEd25519PrivateKey3 = R"( +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIMWqjfQ/n4N77bdELzHct7Fm04U1B28JS4XOOi4LRFj3 +-----END PRIVATE KEY----- +)"; +constexpr folly::StringPiece kEd25519PrivateKey4 = R"( +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIPXldnzxUzGVF2MPImh2uGyBYMxYO8ATdExr8lX1zA7l +-----END PRIVATE KEY----- +)"; +constexpr folly::StringPiece kEd25519PrivateKey5 = R"( +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIIM/5iQJI3udYux3WHUgkR6adZzsHRl1W32pAbltyj1C +-----END PRIVATE KEY----- +)"; + +// Public key fixtures from RFC8032 +constexpr folly::StringPiece kEd25519PublicKey1 = R"( +-----BEGIN PUBLIC KEY----- +MCowBQYDK2VwAyEA11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo= +-----END PUBLIC KEY----- +)"; +constexpr folly::StringPiece kEd25519PublicKey2 = R"( +-----BEGIN PUBLIC KEY----- +MCowBQYDK2VwAyEAPUAXw+hDiVqStwqnTRt+vJyYLM8uxJaMwM1V8Sr0Zgw= +-----END PUBLIC KEY----- +)"; +constexpr folly::StringPiece kEd25519PublicKey3 = R"( +-----BEGIN PUBLIC KEY----- +MCowBQYDK2VwAyEA/FHNjmIYoaONpH7QAjDwWAgW7RO6MwOsXeuRFUiQgCU= +-----END PUBLIC KEY----- +)"; +constexpr folly::StringPiece kEd25519PublicKey4 = R"( +-----BEGIN PUBLIC KEY----- +MCowBQYDK2VwAyEAJ4EX/BRMcjQPZ9DyMW6Dhs7/vyskKMnFH+98WX8dQm4= +-----END PUBLIC KEY----- +)"; +constexpr folly::StringPiece kEd25519PublicKey5 = R"( +-----BEGIN PUBLIC KEY----- +MCowBQYDK2VwAyEA7Bcrk61eVjv0kyxw4SRQNMNUZ+8u/U1k6/gZaDRn4r8= +-----END PUBLIC KEY----- +)"; + +// Message fixtures from RFC8032 +constexpr folly::StringPiece kEd25519Message1 = ""; +constexpr folly::StringPiece kEd25519Message2 = "72"; +constexpr folly::StringPiece kEd25519Message3 = "af82"; +constexpr folly::StringPiece kEd25519Message4 = + "08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0"; +constexpr folly::StringPiece kEd25519Message5 = + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"; + +// Signature fixtures from RFC8032 +constexpr folly::StringPiece kEd25519Signature1 = + "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"; +constexpr folly::StringPiece kEd25519Signature2 = + "92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00"; +constexpr folly::StringPiece kEd25519Signature3 = + "6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a"; +constexpr folly::StringPiece kEd25519Signature4 = + "0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03"; +constexpr folly::StringPiece kEd25519Signature5 = + "dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704"; + +std::string modifyMessage(const std::string& input); +std::string modifySignature(const std::string& input); + +} // namespace testing +} // namespace openssl +} // namespace fizz diff --git a/fizz/backend/openssl/crypto/signature/test/RSAPSSSignatureTest.cpp b/fizz/backend/openssl/crypto/signature/test/RSAPSSSignatureTest.cpp new file mode 100644 index 00000000000..f2b4c6770e3 --- /dev/null +++ b/fizz/backend/openssl/crypto/signature/test/RSAPSSSignatureTest.cpp @@ -0,0 +1,70 @@ +/* + * 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 + +using namespace folly; +using namespace folly::ssl; +using namespace testing; + +namespace fizz { +namespace openssl { +namespace test { + +class RSAPSSTest : public Test { + void SetUp() override { + OpenSSL_add_all_algorithms(); + } +}; + +static EvpPkeyUniquePtr generateKey() { + std::unique_ptr< + EVP_PKEY_CTX, + folly::static_function_deleter> + ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr)); + EVP_PKEY_keygen_init(ctx.get()); + EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), 2048); + EVP_PKEY* keyPtr{nullptr}; + EVP_PKEY_keygen(ctx.get(), &keyPtr); + return EvpPkeyUniquePtr(keyPtr); +} + +TEST_F(RSAPSSTest, TestSignVerify) { + OpenSSLSignature rsa; + rsa.setKey(generateKey()); + static constexpr StringPiece msg{"message"}; + auto sig = rsa.sign(msg); + rsa.verify(msg, sig->coalesce()); +} + +TEST_F(RSAPSSTest, TestVerifyDifferent) { + OpenSSLSignature rsa; + rsa.setKey(generateKey()); + static constexpr StringPiece msg1{"message"}; + static constexpr StringPiece msg2{"somethingelse"}; + auto sig = rsa.sign(msg1); + EXPECT_THROW( + rsa.verify(msg2, sig->coalesce()), + std::runtime_error); +} + +TEST_F(RSAPSSTest, TestVerifyFailure) { + OpenSSLSignature rsa; + rsa.setKey(generateKey()); + static constexpr StringPiece msg{"message"}; + auto sig = rsa.sign(msg); + sig->writableData()[1] ^= 0x2; + EXPECT_THROW( + rsa.verify(msg, sig->coalesce()), + std::runtime_error); +} +} // namespace test +} // namespace openssl +} // namespace fizz diff --git a/fizz/backend/openssl/crypto/test/OpenSSLKeyUtilsTest.cpp b/fizz/backend/openssl/crypto/test/OpenSSLKeyUtilsTest.cpp new file mode 100644 index 00000000000..03d712f35c3 --- /dev/null +++ b/fizz/backend/openssl/crypto/test/OpenSSLKeyUtilsTest.cpp @@ -0,0 +1,67 @@ +/* + * 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 { +using namespace test; + +namespace openssl { +namespace test { + +TEST(ValidateECKey, GoodPrivateKey) { + auto key = getPrivateKey(kP256Key); + detail::validateECKey(key, NID_X9_62_prime256v1); +} + +TEST(ValidateECKey, GoodPublicKey) { + auto key = getPublicKey(kP256PublicKey); + detail::validateECKey(key, NID_X9_62_prime256v1); +} + +TEST(ValidateECKey, WrongKeyType) { + auto key = getPrivateKey(kRSAKey); + EXPECT_THROW( + detail::validateECKey(key, NID_X9_62_prime256v1), std::runtime_error); +} + +TEST(ValidateECKey, WrongCurve) { + auto key = getPrivateKey(kP256Key); + EXPECT_THROW( + detail::validateECKey(key, NID_X9_62_prime239v3), std::runtime_error); +} + +#if FIZZ_OPENSSL_HAS_ED25519 +TEST(ValidateEdKey, GoodPrivateKey) { + auto key = getPrivateKey(kEd25519Key); + detail::validateEdKey(key, NID_ED25519); +} + +TEST(ValidateEdKey, GoodPublicKey) { + auto key = getPublicKey(kEd25519PublicKey); + detail::validateEdKey(key, NID_ED25519); +} + +TEST(ValidateEdKey, WrongKeyType) { + auto key = getPrivateKey(kP256Key); + EXPECT_THROW(detail::validateEdKey(key, NID_ED25519), std::runtime_error); +} + +TEST(ValidateEdKey, WrongCurve) { + auto key = getPrivateKey(kEd448Key); + EXPECT_THROW(detail::validateEdKey(key, NID_ED25519), std::runtime_error); +} +#endif +} // namespace test +} // namespace openssl +} // namespace fizz diff --git a/fizz/client/FizzClientContext.cpp b/fizz/client/FizzClientContext.cpp index 6c425e1c533..00794aa57eb 100644 --- a/fizz/client/FizzClientContext.cpp +++ b/fizz/client/FizzClientContext.cpp @@ -8,13 +8,13 @@ #include "fizz/client/FizzClientContext.h" -#include +#include namespace fizz { namespace client { FizzClientContext::FizzClientContext() - : factory_(std::make_shared()), + : factory_(std::make_shared()), clock_(std::make_shared()) {} } // namespace client diff --git a/fizz/compression/test/BrotliCertificateCompressorTest.cpp b/fizz/compression/test/BrotliCertificateCompressorTest.cpp index 486615685a5..18c949f56cb 100644 --- a/fizz/compression/test/BrotliCertificateCompressorTest.cpp +++ b/fizz/compression/test/BrotliCertificateCompressorTest.cpp @@ -76,8 +76,8 @@ TEST_F(BrotliCertificateCompressorTest, TestCompressDecompress) { auto certAndKey = createCert("fizz-selfsigned", false, nullptr); std::vector certs; certs.push_back(std::move(certAndKey.cert)); - auto cert = - CertUtils::makeSelfCert(std::move(certs), std::move(certAndKey.key)); + auto cert = openssl::CertUtils::makeSelfCert( + std::move(certs), std::move(certAndKey.key)); auto certMsg = cert->getCertMessage(); // Add extension @@ -96,7 +96,8 @@ TEST_F(BrotliCertificateCompressorTest, TestCompressDecompress) { EXPECT_EQ(decompressedCertMsg.certificate_list.size(), 1); auto& certEntry = decompressedCertMsg.certificate_list.at(0); EXPECT_EQ(certEntry.extensions.size(), 1); - auto decompressedPeer = CertUtils::makePeerCert(certEntry.cert_data->clone()); + auto decompressedPeer = + openssl::CertUtils::makePeerCert(certEntry.cert_data->clone()); EXPECT_EQ(decompressedPeer->getIdentity(), cert->getIdentity()); EXPECT_TRUE(IOBufEqualTo()(encode(certMsg), encode(decompressedCertMsg))); diff --git a/fizz/compression/test/ZlibCertificateCompressorTest.cpp b/fizz/compression/test/ZlibCertificateCompressorTest.cpp index 44f93b2d34f..7786265492d 100644 --- a/fizz/compression/test/ZlibCertificateCompressorTest.cpp +++ b/fizz/compression/test/ZlibCertificateCompressorTest.cpp @@ -215,8 +215,8 @@ TEST_F(ZlibCertificateCompressorTest, TestCompressDecompress) { auto certAndKey = createCert("fizz-selfsigned", false, nullptr); std::vector certs; certs.push_back(std::move(certAndKey.cert)); - auto cert = - CertUtils::makeSelfCert(std::move(certs), std::move(certAndKey.key)); + auto cert = openssl::CertUtils::makeSelfCert( + std::move(certs), std::move(certAndKey.key)); auto certMsg = cert->getCertMessage(); // Add extension @@ -234,7 +234,8 @@ TEST_F(ZlibCertificateCompressorTest, TestCompressDecompress) { EXPECT_EQ(decompressedCertMsg.certificate_list.size(), 1); auto& certEntry = decompressedCertMsg.certificate_list.at(0); EXPECT_EQ(certEntry.extensions.size(), 1); - auto decompressedPeer = CertUtils::makePeerCert(certEntry.cert_data->clone()); + auto decompressedPeer = + openssl::CertUtils::makePeerCert(certEntry.cert_data->clone()); EXPECT_EQ(decompressedPeer->getIdentity(), cert->getIdentity()); EXPECT_TRUE(IOBufEqualTo()(encode(certMsg), encode(decompressedCertMsg))); diff --git a/fizz/compression/test/ZstdCertificateCompressorTest.cpp b/fizz/compression/test/ZstdCertificateCompressorTest.cpp index 0e4c7c58f7b..077002b5bca 100644 --- a/fizz/compression/test/ZstdCertificateCompressorTest.cpp +++ b/fizz/compression/test/ZstdCertificateCompressorTest.cpp @@ -90,8 +90,8 @@ TEST_F(ZstdCertificateCompressorTest, TestCompressDecompress) { auto certAndKey = createCert("fizz-selfsigned", false, nullptr); std::vector certs; certs.push_back(std::move(certAndKey.cert)); - auto cert = - CertUtils::makeSelfCert(std::move(certs), std::move(certAndKey.key)); + auto cert = openssl::CertUtils::makeSelfCert( + std::move(certs), std::move(certAndKey.key)); auto certMsg = cert->getCertMessage(); // Add extension @@ -109,7 +109,8 @@ TEST_F(ZstdCertificateCompressorTest, TestCompressDecompress) { EXPECT_EQ(decompressedCertMsg.certificate_list.size(), 1); auto& certEntry = decompressedCertMsg.certificate_list.at(0); EXPECT_EQ(certEntry.extensions.size(), 1); - auto decompressedPeer = CertUtils::makePeerCert(certEntry.cert_data->clone()); + auto decompressedPeer = + openssl::CertUtils::makePeerCert(certEntry.cert_data->clone()); EXPECT_EQ(decompressedPeer->getIdentity(), cert->getIdentity()); EXPECT_TRUE(IOBufEqualTo()(encode(certMsg), encode(decompressedCertMsg))); diff --git a/fizz/crypto/ECCurve.h b/fizz/crypto/ECCurve.h index 1ed61f6950e..0dfae2d4ac4 100644 --- a/fizz/crypto/ECCurve.h +++ b/fizz/crypto/ECCurve.h @@ -8,29 +8,12 @@ #pragma once -#include +#include namespace fizz { -struct P256 { - static const int curveNid{NID_X9_62_prime256v1}; - /** - * See RFC8446 Section 4.2.8.2 - */ - static const int coordinateLength = 32; - static const int keyShareLength = coordinateLength * 2 + 1; -}; - -struct P384 { - static const int curveNid{NID_secp384r1}; - static const int coordinateLength = 48; - static const int keyShareLength = coordinateLength * 2 + 1; -}; - -struct P521 { - static const int curveNid{NID_secp521r1}; - static const int coordinateLength = 66; - static const int keyShareLength = coordinateLength * 2 + 1; -}; +using P256 = openssl::P256; +using P384 = openssl::P384; +using P521 = openssl::P521; } // namespace fizz diff --git a/fizz/crypto/Sha.h b/fizz/crypto/Sha.h index 11f292ac767..e157ad4ce63 100644 --- a/fizz/crypto/Sha.h +++ b/fizz/crypto/Sha.h @@ -8,46 +8,11 @@ #pragma once -#include -#include -#include +#include namespace fizz { -/** - * Hash implementation using OpenSSL. - * - * The template struct requires the following parameters: - * - HashLen: length of the hash digest - * - HashEngine: function returning EVP_MD* to use - * - BlankHash: ByteRange containing the digest of a hash of empty input - */ template -class Sha { - public: - void hash_init(); - - void hash_update(folly::ByteRange data); - - void hash_update(const folly::IOBuf& data); - - void hash_final(folly::MutableByteRange out); - - /** - * Puts HMAC(key, in) into out. Out must be at least of size HashLen. - */ - static void hmac( - folly::ByteRange key, - const folly::IOBuf& in, - folly::MutableByteRange out); - - /** - * Puts Hash(in) into out. Out must be at least of size HashLen. - */ - static void hash(const folly::IOBuf& in, folly::MutableByteRange out); +using Sha = openssl::Sha; - private: - folly::ssl::OpenSSLHash::Digest digest_; -}; } // namespace fizz -#include diff --git a/fizz/crypto/Sha256.h b/fizz/crypto/Sha256.h index 6aa086e828b..5637614f8f6 100644 --- a/fizz/crypto/Sha256.h +++ b/fizz/crypto/Sha256.h @@ -8,19 +8,11 @@ #pragma once +#include #include -#include -#include namespace fizz { -class Sha256 : public Sha { - public: - static constexpr size_t HashLen = 32; +using Sha256 = openssl::Sha256; - static constexpr auto HashEngine = EVP_sha256; - - static constexpr folly::StringPiece BlankHash{ - "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55"}; -}; } // namespace fizz diff --git a/fizz/crypto/Sha384.h b/fizz/crypto/Sha384.h index 55bf60b27cb..ab311dccf00 100644 --- a/fizz/crypto/Sha384.h +++ b/fizz/crypto/Sha384.h @@ -8,19 +8,11 @@ #pragma once +#include #include -#include -#include namespace fizz { -class Sha384 : public Sha { - public: - static constexpr size_t HashLen = 48; +using Sha384 = openssl::Sha384; - static constexpr auto HashEngine = EVP_sha384; - - static constexpr folly::StringPiece BlankHash{ - "\x38\xb0\x60\xa7\x51\xac\x96\x38\x4c\xd9\x32\x7e\xb1\xb1\xe3\x6a\x21\xfd\xb7\x11\x14\xbe\x07\x43\x4c\x0c\xc7\xbf\x63\xf6\xe1\xda\x27\x4e\xde\xbf\xe7\x6f\x65\xfb\xd5\x1a\xd2\xf1\x48\x98\xb9\x5b"}; -}; } // namespace fizz diff --git a/fizz/crypto/Sha512.h b/fizz/crypto/Sha512.h index fd615c58049..aadc08a5c7b 100644 --- a/fizz/crypto/Sha512.h +++ b/fizz/crypto/Sha512.h @@ -8,19 +8,11 @@ #pragma once +#include #include -#include -#include namespace fizz { -class Sha512 : public Sha { - public: - static constexpr size_t HashLen = 64; +using Sha512 = openssl::Sha512; - static constexpr auto HashEngine = EVP_sha512; - - static constexpr folly::StringPiece BlankHash{ - "\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e"}; -}; } // namespace fizz diff --git a/fizz/crypto/aead/AESGCM128.h b/fizz/crypto/aead/AESGCM128.h index df1422e3db1..73e07683f1e 100644 --- a/fizz/crypto/aead/AESGCM128.h +++ b/fizz/crypto/aead/AESGCM128.h @@ -8,18 +8,8 @@ #pragma once -#include +#include namespace fizz { - -struct AESGCM128 { - static constexpr auto Cipher = EVP_aes_128_gcm; - - static const size_t kKeyLength{16}; - static const size_t kIVLength{12}; - static const size_t kTagLength{16}; - static const bool kOperatesInBlocks{false}; - static const bool kRequiresPresetTagLen{false}; -}; - +using AESGCM128 = openssl::AESGCM128; } // namespace fizz diff --git a/fizz/crypto/aead/AESGCM256.h b/fizz/crypto/aead/AESGCM256.h index 71da6615cb8..995e42290c2 100644 --- a/fizz/crypto/aead/AESGCM256.h +++ b/fizz/crypto/aead/AESGCM256.h @@ -8,18 +8,8 @@ #pragma once -#include +#include namespace fizz { - -struct AESGCM256 { - static constexpr auto Cipher = EVP_aes_256_gcm; - - static const size_t kKeyLength{32}; - static const size_t kIVLength{12}; - static const size_t kTagLength{16}; - static const bool kOperatesInBlocks{false}; - static const bool kRequiresPresetTagLen{false}; -}; - +using AESGCM256 = openssl::AESGCM256; } // namespace fizz diff --git a/fizz/crypto/aead/AESOCB128.h b/fizz/crypto/aead/AESOCB128.h index fc1ed4d5e13..80bd34f7ada 100644 --- a/fizz/crypto/aead/AESOCB128.h +++ b/fizz/crypto/aead/AESOCB128.h @@ -8,27 +8,8 @@ #pragma once -#include -#include -#include +#include namespace fizz { - -struct AESOCB128 { - static const EVP_CIPHER* Cipher() { -#if !defined(OPENSSL_NO_OCB) - return EVP_aes_128_ocb(); -#else - throw std::runtime_error( - "aes-ocb support requires OpenSSL 1.1.0 with ocb enabled"); -#endif - } - - static const size_t kKeyLength{16}; - static const size_t kIVLength{12}; - static const size_t kTagLength{16}; - static const bool kOperatesInBlocks{true}; - static const bool kRequiresPresetTagLen{true}; -}; - +using AESOCB128 = openssl::AESOCB128; } // namespace fizz diff --git a/fizz/crypto/aead/ChaCha20Poly1305.h b/fizz/crypto/aead/ChaCha20Poly1305.h index 32e0563f734..386c747499c 100644 --- a/fizz/crypto/aead/ChaCha20Poly1305.h +++ b/fizz/crypto/aead/ChaCha20Poly1305.h @@ -8,28 +8,8 @@ #pragma once -#include - -#include -#include +#include namespace fizz { - -struct ChaCha20Poly1305 { - static const EVP_CIPHER* Cipher() { -#if FOLLY_OPENSSL_HAS_CHACHA - return EVP_chacha20_poly1305(); -#else - throw std::runtime_error( - "chacha20-poly1305 support requires OpenSSL 1.1.0"); -#endif // FOLLY_OPENSSL_HAS_CHACHA - } - - static const size_t kKeyLength{32}; - static const size_t kIVLength{12}; - static const size_t kTagLength{16}; - static const bool kOperatesInBlocks{false}; - static const bool kRequiresPresetTagLen{false}; -}; - +using ChaCha20Poly1305 = openssl::ChaCha20Poly1305; } // namespace fizz diff --git a/fizz/crypto/aead/OpenSSLEVPCipher.h b/fizz/crypto/aead/OpenSSLEVPCipher.h index a2d6e5169a4..38ba6d711e2 100644 --- a/fizz/crypto/aead/OpenSSLEVPCipher.h +++ b/fizz/crypto/aead/OpenSSLEVPCipher.h @@ -8,123 +8,11 @@ #pragma once +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include namespace fizz { -/** - * Aead implementation using an OpenSSL EvpCipher. - * - * The template struct requires the following parameters: - * - Cipher: function returning EVP_CIPHER* - * - kKeyLength: length of key required - * - kIvLength: length of iv required - * - kTagLength: authentication tag length - * - kOperatesInBlocks: if the cipher outputs data in chunks vs. streaming 1:1 - * with the input - * - kRequiresPresetTagLen: if the cipher requires setting the tag length - * explicitly - */ -class OpenSSLEVPCipher : public Aead { - public: - ~OpenSSLEVPCipher() override = default; - OpenSSLEVPCipher() = default; - - static constexpr size_t kMaxIVLength = 20; - static constexpr size_t kMaxTagLength = 20; - - template - static std::unique_ptr makeCipher(); - - OpenSSLEVPCipher(OpenSSLEVPCipher&& other) = default; - OpenSSLEVPCipher& operator=(OpenSSLEVPCipher&& other) = default; - - void setKey(TrafficKey trafficKey) override; - folly::Optional getKey() const override; - - size_t keyLength() const override { - return keyLength_; - } - - size_t ivLength() const override { - return ivLength_; - } - - // If plaintext is not shared, encrypt in place and append a tag, - // either in the tail room if available, or by appending a new buf - // If plaintext is shared, alloc a new output and encrypt to output. - // The returned buffer will have head room == headroom_ - std::unique_ptr encrypt( - std::unique_ptr&& plaintext, - const folly::IOBuf* associatedData, - uint64_t seqNum, - Aead::AeadOptions options) const override; - - std::unique_ptr encrypt( - std::unique_ptr&& plaintext, - const folly::IOBuf* associatedData, - folly::ByteRange nonce, - Aead::AeadOptions options) const override; - - // The same as encrypt(), except always do an inplace encrypt if possible, - // even if the IOBuf is shared. If there is not enough room for the tag, - // this will throw an exception. - std::unique_ptr inplaceEncrypt( - std::unique_ptr&& plaintext, - const folly::IOBuf* associatedData, - uint64_t seqNum) const override; - - folly::Optional> tryDecrypt( - std::unique_ptr&& ciphertext, - const folly::IOBuf* associatedData, - uint64_t seqNum, - Aead::AeadOptions options) const override; - - folly::Optional> tryDecrypt( - std::unique_ptr&& ciphertext, - const folly::IOBuf* associatedData, - folly::ByteRange nonce, - Aead::AeadOptions options) const override; - - size_t getCipherOverhead() const override; - - void setEncryptedBufferHeadroom(size_t headroom) override { - headroom_ = headroom; - } - - private: - OpenSSLEVPCipher( - size_t keyLength, - size_t ivLength, - size_t tagLength, - const EVP_CIPHER* cipher, - bool operatesInBlocks, - bool requiresPresetTagLen); - - TrafficKey trafficKey_; - folly::ByteRange trafficIvKey_; - size_t headroom_{5}; - - // set by the ctor - size_t keyLength_; - size_t ivLength_; - size_t tagLength_; - const EVP_CIPHER* cipher_; - bool operatesInBlocks_; - bool requiresPresetTagLen_; +using OpenSSLEVPCipher = openssl::OpenSSLEVPCipher; - folly::ssl::EvpCipherCtxUniquePtr encryptCtx_; - folly::ssl::EvpCipherCtxUniquePtr decryptCtx_; -}; } // namespace fizz -#include diff --git a/fizz/crypto/exchange/ECCurveKeyExchange.h b/fizz/crypto/exchange/ECCurveKeyExchange.h index 613f681ef25..15c9c390b75 100644 --- a/fizz/crypto/exchange/ECCurveKeyExchange.h +++ b/fizz/crypto/exchange/ECCurveKeyExchange.h @@ -8,21 +8,22 @@ #pragma once +#include #include #include -#include namespace fizz { -using P256KeyExchange = OpenSSLECKeyExchange; -using P256PublicKeyDecoder = detail::OpenSSLECKeyDecoder; -using P256PublicKeyEncoder = detail::OpenSSLECKeyEncoder; +using P256KeyExchange = openssl::P256KeyExchange; +using P256PublicKeyDecoder = openssl::P256PublicKeyDecoder; +using P256PublicKeyEncoder = openssl::P256PublicKeyEncoder; -using P384KeyExchange = OpenSSLECKeyExchange; -using P384PublicKeyDecoder = detail::OpenSSLECKeyDecoder; -using P384PublicKeyEncoder = detail::OpenSSLECKeyEncoder; +using P384KeyExchange = openssl::P384KeyExchange; +using P384PublicKeyDecoder = openssl::P384PublicKeyDecoder; +using P384PublicKeyEncoder = openssl::P384PublicKeyEncoder; + +using P521KeyExchange = openssl::P521KeyExchange; +using P521PublicKeyDecoder = openssl::P521PublicKeyDecoder; +using P521PublicKeyEncoder = openssl::P521PublicKeyEncoder; -using P521KeyExchange = OpenSSLECKeyExchange; -using P521PublicKeyDecoder = detail::OpenSSLECKeyDecoder; -using P521PublicKeyEncoder = detail::OpenSSLECKeyEncoder; } // namespace fizz diff --git a/fizz/crypto/exchange/OpenSSLKeyExchange.h b/fizz/crypto/exchange/OpenSSLKeyExchange.h index 392a24b4fc7..beb6b2870f8 100644 --- a/fizz/crypto/exchange/OpenSSLKeyExchange.h +++ b/fizz/crypto/exchange/OpenSSLKeyExchange.h @@ -8,43 +8,12 @@ #pragma once -#include -#include +#include +#include namespace fizz { -/** - * Eliptic curve key exchange implementation using OpenSSL. - * - * The template struct requires the following parameters: - * - curveNid: OpenSSL NID for the named curve - */ template -class OpenSSLECKeyExchange : public KeyExchange { - public: - ~OpenSSLECKeyExchange() override = default; - - void generateKeyPair() override; - - std::unique_ptr getKeyShare() const override; - - std::unique_ptr generateSharedSecret( - folly::ByteRange keyShare) const override; - - std::unique_ptr clone() const override; +using OpenSSLECKeyExchange = openssl::OpenSSLECKeyExchange; - std::unique_ptr generateSharedSecret( - const folly::ssl::EvpPkeyUniquePtr& peerKey) const; - - void setPrivateKey(folly::ssl::EvpPkeyUniquePtr privateKey); - - const folly::ssl::EvpPkeyUniquePtr& getPrivateKey() const; - - std::size_t getExpectedKeyShareSize() const override; - - private: - folly::ssl::EvpPkeyUniquePtr key_; -}; } // namespace fizz - -#include diff --git a/fizz/crypto/hpke/Context.h b/fizz/crypto/hpke/Context.h index 0d91e27c0e3..aef871d7ec5 100644 --- a/fizz/crypto/hpke/Context.h +++ b/fizz/crypto/hpke/Context.h @@ -8,7 +8,7 @@ #pragma once -#include +#include #include #include diff --git a/fizz/crypto/hpke/DHKEM.h b/fizz/crypto/hpke/DHKEM.h index 6f878d2ba14..8f37a58088f 100644 --- a/fizz/crypto/hpke/DHKEM.h +++ b/fizz/crypto/hpke/DHKEM.h @@ -2,7 +2,9 @@ #pragma once +#include #include +#include #include #include #include diff --git a/fizz/crypto/hpke/Hpke.cpp b/fizz/crypto/hpke/Hpke.cpp index 3f7b2a0f36f..327f718ba72 100644 --- a/fizz/crypto/hpke/Hpke.cpp +++ b/fizz/crypto/hpke/Hpke.cpp @@ -172,7 +172,7 @@ std::unique_ptr deserializePublicKey( BIO_write(bio.get(), publicKey.data(), publicKey.size()); folly::ssl::EvpPkeyUniquePtr pkey( PEM_read_bio_PUBKEY(bio.get(), nullptr, nullptr, nullptr)); - return fizz::detail::encodeECPublicKey(pkey); + return fizz::openssl::detail::encodeECPublicKey(pkey); } default: throw std::runtime_error("Unsupported KEM ID"); diff --git a/fizz/crypto/hpke/Utils.cpp b/fizz/crypto/hpke/Utils.cpp index 6436b8dfead..4f0926aaf53 100644 --- a/fizz/crypto/hpke/Utils.cpp +++ b/fizz/crypto/hpke/Utils.cpp @@ -8,14 +8,7 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include namespace fizz { @@ -139,15 +132,15 @@ std::unique_ptr makeHpkeHkdf( case KDFId::Sha256: return std::make_unique( std::move(prefix), - std::make_unique(HkdfImpl::create())); + std::make_unique(HkdfImpl::create())); case KDFId::Sha384: return std::make_unique( std::move(prefix), - std::make_unique(HkdfImpl::create())); + std::make_unique(HkdfImpl::create())); case KDFId::Sha512: return std::make_unique( std::move(prefix), - std::make_unique(HkdfImpl::create())); + std::make_unique(HkdfImpl::create())); default: throw std::runtime_error("hkdf: not implemented"); } @@ -156,11 +149,11 @@ std::unique_ptr makeHpkeHkdf( std::unique_ptr makeKeyExchange(KEMId kemId) { switch (kemId) { case KEMId::secp256r1: - return std::make_unique>(); + return std::make_unique>(); case KEMId::secp384r1: - return std::make_unique>(); + return std::make_unique>(); case KEMId::secp521r1: - return std::make_unique>(); + return std::make_unique>(); case KEMId::x25519: return std::make_unique(); default: @@ -187,11 +180,11 @@ size_t nenc(KEMId kemId) { std::unique_ptr makeCipher(AeadId aeadId) { switch (aeadId) { case AeadId::TLS_CHACHA20_POLY1305_SHA256: - return OpenSSLEVPCipher::makeCipher(); + return openssl::OpenSSLEVPCipher::makeCipher(); case AeadId::TLS_AES_128_GCM_SHA256: - return OpenSSLEVPCipher::makeCipher(); + return openssl::OpenSSLEVPCipher::makeCipher(); case AeadId::TLS_AES_256_GCM_SHA384: - return OpenSSLEVPCipher::makeCipher(); + return openssl::OpenSSLEVPCipher::makeCipher(); default: throw std::runtime_error("can't make aead: not implemented"); } diff --git a/fizz/crypto/hpke/test/ContextTest.cpp b/fizz/crypto/hpke/test/ContextTest.cpp index bc1c30a62f4..13705046775 100644 --- a/fizz/crypto/hpke/test/ContextTest.cpp +++ b/fizz/crypto/hpke/test/ContextTest.cpp @@ -8,7 +8,7 @@ #include -#include +#include #include #include #include @@ -54,7 +54,7 @@ TEST_P(HpkeContextTest, TestContext) { toIOBuf(kExportSecret), std::make_unique( kPrefix->clone(), - std::make_unique(HkdfImpl::create())), + std::make_unique(HkdfImpl::create())), suiteId->clone(), fizz::hpke::HpkeContext::Role::Sender); auto gotCiphertext = encryptContext.seal( @@ -70,7 +70,7 @@ TEST_P(HpkeContextTest, TestContext) { toIOBuf(kExportSecret), std::make_unique( kPrefix->clone(), - std::make_unique(HkdfImpl::create())), + std::make_unique(HkdfImpl::create())), std::move(suiteId), fizz::hpke::HpkeContext::Role::Receiver); auto gotPlaintext = decryptContext.open( @@ -93,7 +93,7 @@ TEST_P(HpkeContextTest, TestContextRoles) { toIOBuf(kExportSecret), std::make_unique( kPrefix->clone(), - std::make_unique(HkdfImpl::create())), + std::make_unique(HkdfImpl::create())), suiteId->clone(), fizz::hpke::HpkeContext::Role::Sender); @@ -105,7 +105,7 @@ TEST_P(HpkeContextTest, TestContextRoles) { toIOBuf(kExportSecret), std::make_unique( kPrefix->clone(), - std::make_unique(HkdfImpl::create())), + std::make_unique(HkdfImpl::create())), std::move(suiteId), fizz::hpke::HpkeContext::Role::Receiver); @@ -138,7 +138,7 @@ TEST_P(HpkeContextTest, TestExportSecret) { toIOBuf(testParam.exporterSecret), std::make_unique( kPrefix->clone(), - std::make_unique(HkdfImpl::create())), + std::make_unique(HkdfImpl::create())), std::move(suiteId), role); auto secret = context.exportSecret(std::move(exporterContext), 32); @@ -162,11 +162,11 @@ TEST_P(HpkeContextTest, TestExportSecretThrow) { HashFunction::Sha256, CipherSuite::TLS_AES_128_GCM_SHA256); HpkeContextImpl context( - OpenSSLEVPCipher::makeCipher(), + openssl::OpenSSLEVPCipher::makeCipher(), toIOBuf(testParam.exporterSecret), std::make_unique( kPrefix->clone(), - std::make_unique(HkdfImpl::create())), + std::make_unique(HkdfImpl::create())), std::move(suiteId), role); diff --git a/fizz/crypto/hpke/test/DHKEMTest.cpp b/fizz/crypto/hpke/test/DHKEMTest.cpp index 0c73e555ff8..9bb80bf7d51 100644 --- a/fizz/crypto/hpke/test/DHKEMTest.cpp +++ b/fizz/crypto/hpke/test/DHKEMTest.cpp @@ -9,9 +9,8 @@ #include #include -#include +#include #include -#include #include #include #include @@ -65,7 +64,7 @@ DHKEM getDHKEM(std::unique_ptr actualKex, NamedGroup group) { auto prefix = "HPKE-v1"; auto hkdf = std::make_unique( folly::IOBuf::copyBuffer(prefix), - std::make_unique(HkdfImpl::create())); + std::make_unique(HkdfImpl::create())); return DHKEM( std::make_unique(std::move(actualKex)), group, @@ -73,12 +72,14 @@ DHKEM getDHKEM(std::unique_ptr actualKex, NamedGroup group) { } TEST(DHKEMTest, TestP256EncapDecapEqual) { - auto actualKex = std::make_unique>(); + auto actualKex = + std::make_unique>(); auto privateKey = getPrivateKey(kP256Key); actualKex->setPrivateKey(std::move(privateKey)); auto dhkem = getDHKEM(std::move(actualKex), NamedGroup::secp256r1); - auto publicKey = detail::encodeECPublicKey(getPublicKey(kP256PublicKey)); + auto publicKey = + openssl::detail::encodeECPublicKey(getPublicKey(kP256PublicKey)); std::unique_ptr sharedKey; std::unique_ptr gotSharedKey; std::tie(sharedKey, gotSharedKey) = @@ -88,7 +89,8 @@ TEST(DHKEMTest, TestP256EncapDecapEqual) { } TEST(DHKEMTest, TestP256EncapDecapNotEqual) { - auto actualKex = std::make_unique>(); + auto actualKex = + std::make_unique>(); auto privateKey = getPrivateKey(kP256Key); actualKex->setPrivateKey(std::move(privateKey)); auto dhkem = getDHKEM(std::move(actualKex), NamedGroup::secp256r1); @@ -113,12 +115,14 @@ TEST(DHKEMTest, TestP256EncapDecapNotEqual) { } TEST(DHKEMTest, TestP384EncapDecapEqual) { - auto actualKex = std::make_unique>(); + auto actualKex = + std::make_unique>(); auto privateKey = getPrivateKey(kP384Key); actualKex->setPrivateKey(std::move(privateKey)); auto dhkem = getDHKEM(std::move(actualKex), NamedGroup::secp384r1); - auto publicKey = detail::encodeECPublicKey(getPublicKey(kP384PublicKey)); + auto publicKey = + openssl::detail::encodeECPublicKey(getPublicKey(kP384PublicKey)); std::unique_ptr sharedKey; std::unique_ptr gotSharedKey; std::tie(sharedKey, gotSharedKey) = diff --git a/fizz/crypto/hpke/test/HpkeTest.cpp b/fizz/crypto/hpke/test/HpkeTest.cpp index ddd3c3cb19a..aaf0f9f532a 100644 --- a/fizz/crypto/hpke/test/HpkeTest.cpp +++ b/fizz/crypto/hpke/test/HpkeTest.cpp @@ -6,9 +6,7 @@ * LICENSE file in the root directory of this source tree. */ -#include -#include -#include +#include #include #include #include @@ -1890,20 +1888,20 @@ class HpkeMockX25519KeyExchange : public X25519KeyExchange { }; template -class HpkeMockOpenSSLECKeyExchange : public OpenSSLECKeyExchange { +class HpkeMockOpenSSLECKeyExchange : public openssl::OpenSSLECKeyExchange { public: MOCK_METHOD0(generateKeyPair, void()); }; template void setOpenSSLPrivKey( - OpenSSLECKeyExchange* kex, + openssl::OpenSSLECKeyExchange* kex, std::string& privKey, std::string& pubKey) { auto pubKeyBuf = toIOBuf(pubKey); std::string privKeyBin = folly::unhexlify(privKey); - auto key = - fizz::detail::decodeECPublicKey(pubKeyBuf->coalesce(), T::curveNid); + auto key = fizz::openssl::detail::decodeECPublicKey( + pubKeyBuf->coalesce(), T::curveNid); folly::ssl::EcKeyUniquePtr ecKey(EVP_PKEY_get1_EC_KEY(key.get())); folly::ssl::BIGNUMUniquePtr privateBn( BN_bin2bn((uint8_t*)privKeyBin.c_str(), privKeyBin.size(), nullptr)); @@ -1930,17 +1928,20 @@ std::unique_ptr generateAuthKex( return dKex; } case NamedGroup::secp256r1: { - auto dKex = std::make_unique>(); + auto dKex = + std::make_unique>(); setOpenSSLPrivKey(dKex.get(), privateKey, publicKey); return dKex; } case NamedGroup::secp384r1: { - auto dKex = std::make_unique>(); + auto dKex = + std::make_unique>(); setOpenSSLPrivKey(dKex.get(), privateKey, publicKey); return dKex; } case NamedGroup::secp521r1: { - auto dKex = std::make_unique>(); + auto dKex = + std::make_unique>(); setOpenSSLPrivKey(dKex.get(), privateKey, publicKey); return dKex; } @@ -1972,19 +1973,22 @@ SetupParam getSetupParam( break; } case NamedGroup::secp256r1: { - auto dKex = dynamic_cast*>(kex.get()); + auto dKex = dynamic_cast*>( + kex.get()); CHECK(dKex); setOpenSSLPrivKey(dKex, privateKey, publicKey); break; } case NamedGroup::secp384r1: { - auto dKex = dynamic_cast*>(kex.get()); + auto dKex = dynamic_cast*>( + kex.get()); CHECK(dKex); setOpenSSLPrivKey(dKex, privateKey, publicKey); break; } case NamedGroup::secp521r1: { - auto dKex = dynamic_cast*>(kex.get()); + auto dKex = dynamic_cast*>( + kex.get()); CHECK(dKex); setOpenSSLPrivKey(dKex, privateKey, publicKey); break; @@ -2031,19 +2035,22 @@ TEST(HpkeTest, TestSetup) { break; } case NamedGroup::secp256r1: { - auto kex = std::make_unique>(); + auto kex = + std::make_unique>(); EXPECT_CALL(*kex, generateKeyPair()).Times(1); encapKex = std::move(kex); break; } case NamedGroup::secp384r1: { - auto kex = std::make_unique>(); + auto kex = + std::make_unique>(); EXPECT_CALL(*kex, generateKeyPair()).Times(1); encapKex = std::move(kex); break; } case NamedGroup::secp521r1: { - auto kex = std::make_unique>(); + auto kex = + std::make_unique>(); EXPECT_CALL(*kex, generateKeyPair()).Times(1); encapKex = std::move(kex); break; @@ -2086,15 +2093,18 @@ TEST(HpkeTest, TestSetup) { break; } case NamedGroup::secp256r1: { - decapKex = std::make_unique>(); + decapKex = + std::make_unique>(); break; } case NamedGroup::secp384r1: { - decapKex = std::make_unique>(); + decapKex = + std::make_unique>(); break; } case NamedGroup::secp521r1: { - decapKex = std::make_unique>(); + decapKex = + std::make_unique>(); break; } default: diff --git a/fizz/crypto/openssl/OpenSSL.h b/fizz/crypto/openssl/OpenSSL.h index 3c3a1bd3d30..920b1c53616 100644 --- a/fizz/crypto/openssl/OpenSSL.h +++ b/fizz/crypto/openssl/OpenSSL.h @@ -2,6 +2,4 @@ #pragma once -#include - -#define FIZZ_OPENSSL_HAS_ED25519 (OPENSSL_VERSION_NUMBER >= 0x10101000L) +#include diff --git a/fizz/crypto/openssl/OpenSSLKeyUtils.h b/fizz/crypto/openssl/OpenSSLKeyUtils.h index 11e20bece13..f11865f1540 100644 --- a/fizz/crypto/openssl/OpenSSLKeyUtils.h +++ b/fizz/crypto/openssl/OpenSSLKeyUtils.h @@ -8,76 +8,28 @@ #pragma once +#include +#include #include -#include -#include -#include namespace fizz { - -class OpenSSLKeyUtils { - public: - /** - * Generates an new EVP_PKEY on the curve. - * Throws an exception on error. - * - * This is a public interface to the namespaced private method below. - */ - static folly::ssl::EvpPkeyUniquePtr generateECKeyPair(int curveNid); -}; +using OpenSSLKeyUtils = openssl::OpenSSLKeyUtils; namespace detail { -/** - * Validates whether or not the EVP_PKEY belongs to the - * curve. If not, this throws an exception. - */ -void validateECKey(const folly::ssl::EvpPkeyUniquePtr& key, int curveNid); +CREATE_FIZZ_FN_ALIAS(validateECKey, openssl::detail::validateECKey) #if FIZZ_OPENSSL_HAS_ED25519 -/** - * Validates whether or not the EVP_PKEY belongs to the - * Edwards curve (currently supports only Ed25519 & Ed448). - * If not, this throws an exception. - */ -void validateEdKey(const folly::ssl::EvpPkeyUniquePtr& key, int curveNid); +CREATE_FIZZ_FN_ALIAS(validateEdKey, openssl::detail::validateEdKey) #endif -/** - * Generates an new EVP_PKEY on the curve. - * Throws an exception on error. - */ -folly::ssl::EvpPkeyUniquePtr generateECKeyPair(int curveNid); +CREATE_FIZZ_FN_ALIAS(generateECKeyPair, openssl::detail::generateECKeyPair) +CREATE_FIZZ_FN_ALIAS(decodeECPublicKey, openssl::detail::decodeECPublicKey) +CREATE_FIZZ_FN_ALIAS(encodeECPublicKey, openssl::detail::encodeECPublicKey) +CREATE_FIZZ_FN_ALIAS( + generateEvpSharedSecret, + openssl::detail::generateEvpSharedSecret) +CREATE_FIZZ_FN_ALIAS(getOpenSSLError, openssl::detail::getOpenSSLError) -/** - * Decodes a EC public key specified as a member of the curve - * curveNid. - */ -folly::ssl::EvpPkeyUniquePtr decodeECPublicKey( - folly::ByteRange range, - int curveNid); - -/** - * Encodes the public key and returns a buffer. - */ - -std::unique_ptr encodeECPublicKey( - const folly::ssl::EvpPkeyUniquePtr& key); - -std::unique_ptr encodeECPublicKey( - const folly::ssl::EcKeyUniquePtr& ecKey); - -/** - * Generates a shared secred from a private key, key and the - * peerKey public key. - */ -std::unique_ptr generateEvpSharedSecret( - const folly::ssl::EvpPkeyUniquePtr& key, - const folly::ssl::EvpPkeyUniquePtr& peerKey); - -/** - * Returns the current error in the thread queue as a string. - */ -std::string getOpenSSLError(); } // namespace detail } // namespace fizz diff --git a/fizz/crypto/signature/Signature.h b/fizz/crypto/signature/Signature.h index ffa5e65438f..d8f124b2ed6 100644 --- a/fizz/crypto/signature/Signature.h +++ b/fizz/crypto/signature/Signature.h @@ -8,61 +8,30 @@ #pragma once -#include -#include -#include -#include +#include +#include +#include namespace fizz { +using KeyType = openssl::KeyType; -enum class KeyType { RSA, P256, P384, P521, ED25519 }; - -/** - * Signature implementation using OpenSSL. - */ template -class OpenSSLSignature { - public: - void setKey(folly::ssl::EvpPkeyUniquePtr pkey); - - /** - * Returns a signature of data. - * - * Only valid for SignatureSchemes that are compatible with KeyType. - * - * setKey() must be called before with a private key. - */ - template - std::unique_ptr sign(folly::ByteRange data) const; - - /** - * Verifies that signature is a valid signature over data. Throws if it's not. - * - * Only valid for SignatureSchemes that are compatible with KeyType. - * - * setKey() must be called before. - */ - template - void verify(folly::ByteRange data, folly::ByteRange signature) const; +using OpenSSLSignature = openssl::OpenSSLSignature; - private: - folly::ssl::EvpPkeyUniquePtr pkey_; -}; +template +using SigAlg = openssl::SigAlg; -#if !FIZZ_OPENSSL_HAS_ED25519 -template <> -class OpenSSLSignature { - public: - [[noreturn]] void setKey(folly::ssl::EvpPkeyUniquePtr); +namespace detail { +CREATE_FIZZ_FN_ALIAS(ecSign, openssl::detail::ecSign) +CREATE_FIZZ_FN_ALIAS(ecVerify, openssl::detail::ecVerify) - template - [[noreturn]] std::unique_ptr sign(folly::ByteRange) const; - - template - [[noreturn]] void verify(folly::ByteRange, folly::ByteRange) const; -}; +#if FIZZ_OPENSSL_HAS_ED25519 +CREATE_FIZZ_FN_ALIAS(edSign, openssl::detail::edSign) +CREATE_FIZZ_FN_ALIAS(edVerify, openssl::detail::edVerify) #endif -} // namespace fizz +CREATE_FIZZ_FN_ALIAS(rsaPssSign, openssl::detail::rsaPssSign) +CREATE_FIZZ_FN_ALIAS(rsaPssVerify, openssl::detail::rsaPssVerify) +} // namespace detail -#include +} // namespace fizz diff --git a/fizz/crypto/test/HkdfTest.cpp b/fizz/crypto/test/HkdfTest.cpp index 7c08fd8fb8e..2a8f88e015d 100644 --- a/fizz/crypto/test/HkdfTest.cpp +++ b/fizz/crypto/test/HkdfTest.cpp @@ -8,8 +8,8 @@ #include +#include #include -#include #include namespace fizz { @@ -33,7 +33,7 @@ TEST_P(HkdfTest, TestHkdfSha256Expand) { auto expectedOkm = toIOBuf(GetParam().okm); CHECK_EQ(outputBytes, expectedOkm->length()); - auto actualOkm = HkdfImpl::create().hkdf( + auto actualOkm = HkdfImpl::create().hkdf( ikm->coalesce(), salt->coalesce(), *info, outputBytes); EXPECT_FALSE(actualOkm->isChained()); EXPECT_EQ(outputBytes, actualOkm->length()); diff --git a/fizz/crypto/test/KeyDerivationTest.cpp b/fizz/crypto/test/KeyDerivationTest.cpp index 8edd4303739..68cc397405b 100644 --- a/fizz/crypto/test/KeyDerivationTest.cpp +++ b/fizz/crypto/test/KeyDerivationTest.cpp @@ -8,8 +8,8 @@ #include +#include #include -#include #include #include @@ -35,7 +35,8 @@ TEST_P(KeyDerivationTest, ExpandLabel) { auto secret = std::vector(prk.begin(), prk.end()); - auto deriver = KeyDerivationImpl::create(kHkdfLabelPrefix.str()); + auto deriver = + KeyDerivationImpl::create(kHkdfLabelPrefix.str()); auto out = deriver.expandLabel( range(secret), GetParam().label, @@ -48,22 +49,28 @@ TEST_P(KeyDerivationTest, ExpandLabel) { TEST(KeyDerivation, DeriveSecret) { // dummy prk std::vector secret( - KeyDerivationImpl::create(kHkdfLabelPrefix.str()).hashLength()); + KeyDerivationImpl::create(kHkdfLabelPrefix.str()) + .hashLength()); std::vector messageHash( - KeyDerivationImpl::create(kHkdfLabelPrefix.str()).hashLength()); - auto deriver = KeyDerivationImpl::create(kHkdfLabelPrefix.str()); + KeyDerivationImpl::create(kHkdfLabelPrefix.str()) + .hashLength()); + auto deriver = + KeyDerivationImpl::create(kHkdfLabelPrefix.str()); deriver.deriveSecret( range(secret), "hey", range(messageHash), deriver.hashLength()); } TEST(KeyDerivation, Sha256BlankHash) { std::vector computed( - KeyDerivationImpl::create(kHkdfLabelPrefix.str()).hashLength()); + KeyDerivationImpl::create(kHkdfLabelPrefix.str()) + .hashLength()); folly::IOBuf blankBuf; - Sha256::hash(blankBuf, MutableByteRange(computed.data(), computed.size())); + openssl::Sha256::hash( + blankBuf, MutableByteRange(computed.data(), computed.size())); EXPECT_EQ( - StringPiece(KeyDerivationImpl::create(kHkdfLabelPrefix.str()) - .blankHash()), + StringPiece( + KeyDerivationImpl::create(kHkdfLabelPrefix.str()) + .blankHash()), StringPiece(folly::range(computed))); } diff --git a/fizz/crypto/test/TestUtil.cpp b/fizz/crypto/test/TestUtil.cpp index 2e57b3e866d..a30ec607ceb 100644 --- a/fizz/crypto/test/TestUtil.cpp +++ b/fizz/crypto/test/TestUtil.cpp @@ -6,6 +6,7 @@ * LICENSE file in the root directory of this source tree. */ +#include #include #include @@ -13,11 +14,6 @@ #include #endif -#include -#include -#include -#include -#include #include #include #include @@ -84,16 +80,17 @@ std::unique_ptr getCipher(CipherSuite suite) { std::unique_ptr cipher; switch (suite) { case CipherSuite::TLS_AES_128_GCM_SHA256: - cipher = OpenSSLEVPCipher::makeCipher(); + cipher = openssl::OpenSSLEVPCipher::makeCipher(); break; case CipherSuite::TLS_AES_256_GCM_SHA384: - cipher = OpenSSLEVPCipher::makeCipher(); + cipher = openssl::OpenSSLEVPCipher::makeCipher(); break; case CipherSuite::TLS_CHACHA20_POLY1305_SHA256: - cipher = OpenSSLEVPCipher::makeCipher(); + cipher = + openssl::OpenSSLEVPCipher::makeCipher(); break; case CipherSuite::TLS_AES_128_OCB_SHA256_EXPERIMENTAL: - cipher = OpenSSLEVPCipher::makeCipher(); + cipher = openssl::OpenSSLEVPCipher::makeCipher(); break; #if FIZZ_BUILD_AEGIS case CipherSuite::TLS_AEGIS_128L_SHA256: diff --git a/fizz/experimental/batcher/Batcher.h b/fizz/experimental/batcher/Batcher.h index 07c8325fb57..84c59adb422 100644 --- a/fizz/experimental/batcher/Batcher.h +++ b/fizz/experimental/batcher/Batcher.h @@ -137,7 +137,7 @@ class Batcher { * A batcher to store and manage the Merkle Tree globally for multiple threads. * The underlying Merkle Tree will be shared by all threads. */ -template +template class SynchronizedBatcher : public Batcher { public: SynchronizedBatcher( @@ -196,7 +196,7 @@ class SynchronizedBatcher : public Batcher { * A batcher to store and manage the Merkle Tree for each thread. * Each thread will have a Merkle Tree. */ -template +template class ThreadLocalBatcher : public Batcher { public: ThreadLocalBatcher( diff --git a/fizz/experimental/batcher/test/BatcherTest.cpp b/fizz/experimental/batcher/test/BatcherTest.cpp index 3dac425b0ac..9f0bc3df1e9 100644 --- a/fizz/experimental/batcher/test/BatcherTest.cpp +++ b/fizz/experimental/batcher/test/BatcherTest.cpp @@ -6,12 +6,12 @@ * LICENSE file in the root directory of this source tree. */ +#include +#include #include #include #include #include -#include -#include #include #include #include @@ -23,7 +23,7 @@ TEST(BatchSignatureTest, TestWhenSignerIsAsync) { // the future returned by addMessageAndSign() will be fulfilled when the // signature future returned by the async signer is fulfilled. auto mockBaseCert = std::make_shared(); - auto batcher = std::make_shared>( + auto batcher = std::make_shared>( 1, mockBaseCert, CertificateVerifyContext::Server); auto [promise, semiFuture] = folly::makePromiseContract>(); @@ -42,7 +42,7 @@ TEST(BatchSignatureTest, TestWhenSignerFails) { // the future returned by addMessageAndSign() will throw an error when // underlying signer returns a none signature. auto mockBaseCert = std::make_shared(); - auto batcher = std::make_shared>( + auto batcher = std::make_shared>( 1, mockBaseCert, CertificateVerifyContext::Server); EXPECT_CALL(*mockBaseCert, signFuture(_, _, _)) .Times(1) @@ -58,10 +58,11 @@ TEST(BatchSignatureTest, TestSynchronizedBatcherSingleThread) { useMockRandom(); std::vector certs; certs.emplace_back(getCert(kRSACertificate)); - auto certificate = std::make_shared>( - getPrivateKey(kRSAKey), std::move(certs)); + auto certificate = + std::make_shared>( + getPrivateKey(kRSAKey), std::move(certs)); - auto batcher = std::make_shared>( + auto batcher = std::make_shared>( 3, certificate, CertificateVerifyContext::Server); auto futureTree1 = batcher->addMessageAndSign(folly::range(folly::StringPiece("Message1"))); @@ -91,10 +92,11 @@ TEST(BatchSignatureTest, TestSynchronizedBatcherMultiThread) { size_t numMsgThreshold = 3; std::vector certs; certs.emplace_back(getCert(kRSACertificate)); - auto certificate = std::make_shared>( - getPrivateKey(kRSAKey), std::move(certs)); + auto certificate = + std::make_shared>( + getPrivateKey(kRSAKey), std::move(certs)); - auto batcher = std::make_shared>( + auto batcher = std::make_shared>( numMsgThreshold, certificate, CertificateVerifyContext::Server); std::vector threads; std::vector results; @@ -124,9 +126,10 @@ TEST(BatchSignatureTest, TestSynchronizedBatcherWithSelfCertP256) { size_t numMsgThreshold = 3; std::vector certs; certs.emplace_back(getCert(kP256Certificate)); - auto certificate = std::make_shared>( - getPrivateKey(kP256Key), std::move(certs)); - auto batcher = std::make_shared>( + auto certificate = + std::make_shared>( + getPrivateKey(kP256Key), std::move(certs)); + auto batcher = std::make_shared>( numMsgThreshold, certificate, CertificateVerifyContext::Server); std::vector threads; @@ -134,7 +137,7 @@ TEST(BatchSignatureTest, TestSynchronizedBatcherWithSelfCertP256) { results.resize(numMsgThreshold * 10); for (size_t i = 0; i < numMsgThreshold * 10; i++) { auto batchCert = - std::make_shared>(batcher); + std::make_shared>(batcher); auto& result = results[i]; // create thread to generate signature threads.emplace_back(std::thread([=, &result]() { @@ -152,8 +155,9 @@ 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( @@ -169,9 +173,10 @@ TEST(BatchSignatureTest, TestThreadLocalBatcher) { std::vector certs; certs.emplace_back(getCert(kRSACertificate)); - auto certificate = std::make_shared>( - getPrivateKey(kRSAKey), std::move(certs)); - auto batcher = std::make_shared>( + auto certificate = + std::make_shared>( + getPrivateKey(kRSAKey), std::move(certs)); + auto batcher = std::make_shared>( 2, certificate, CertificateVerifyContext::Server); std::vector threads; @@ -204,9 +209,10 @@ TEST(BatchSignatureTest, TestThreadLocalBatcher) { TEST(BatchSignatureTest, TestThreadLocalBatcherWithSelfCertP256) { std::vector certs; certs.emplace_back(getCert(kP256Certificate)); - auto certificate = std::make_shared>( - getPrivateKey(kP256Key), std::move(certs)); - auto batcher = std::make_shared>( + auto certificate = + std::make_shared>( + getPrivateKey(kP256Key), std::move(certs)); + auto batcher = std::make_shared>( 3, certificate, CertificateVerifyContext::Server); std::vector threads; @@ -217,11 +223,11 @@ TEST(BatchSignatureTest, TestThreadLocalBatcherWithSelfCertP256) { auto& result2 = results[3 * i + 1]; auto& result3 = results[3 * i + 2]; auto batchCert1 = - std::make_shared>(batcher); + std::make_shared>(batcher); auto batchCert2 = - std::make_shared>(batcher); + std::make_shared>(batcher); auto batchCert3 = - std::make_shared>(batcher); + std::make_shared>(batcher); threads.emplace_back(std::thread([=, &result1, &result2, &result3]() { auto signature1 = std::dynamic_pointer_cast(batchCert1) ->signFuture( @@ -250,8 +256,9 @@ 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/BatchSignaturePeerCert.cpp b/fizz/experimental/client/BatchSignaturePeerCert.cpp index d1b56adb2fc..252b2080324 100644 --- a/fizz/experimental/client/BatchSignaturePeerCert.cpp +++ b/fizz/experimental/client/BatchSignaturePeerCert.cpp @@ -28,13 +28,14 @@ void BatchSignaturePeerCert::batchSigVerify( } // verify path element size auto pathBuf = decoded.getPath(); - if (pathBuf->computeChainDataLength() / Sha256::HashLen > 32) { + if (pathBuf->computeChainDataLength() / openssl::Sha256::HashLen > 32) { throw std::runtime_error( "Verification failure: batch signature number of path elements must be less than 32"); } // verify signature - auto rootValue = BatchSignatureMerkleTree::computeRootFromPath( - message, decoded.getIndex(), std::move(pathBuf)); + auto rootValue = + BatchSignatureMerkleTree::computeRootFromPath( + message, decoded.getIndex(), std::move(pathBuf)); auto toBeSigned = BatchSignature::encodeToBeSigned(std::move(rootValue), scheme); verifier_->verify( diff --git a/fizz/experimental/client/BatchSignaturePeerCert.h b/fizz/experimental/client/BatchSignaturePeerCert.h index d37beb0343a..49d46bab759 100644 --- a/fizz/experimental/client/BatchSignaturePeerCert.h +++ b/fizz/experimental/client/BatchSignaturePeerCert.h @@ -53,7 +53,7 @@ class BatchSignaturePeerCert : public PeerCert { private: // TODO: the current implementation only support BatchSignature with Hash - // function Sha256. + // function openssl::Sha256. /** * Verify a batch signature. * diff --git a/fizz/experimental/client/test/BatchSignaturePeerCertTest.cpp b/fizz/experimental/client/test/BatchSignaturePeerCertTest.cpp index b83ce9c1776..e254392bb86 100644 --- a/fizz/experimental/client/test/BatchSignaturePeerCertTest.cpp +++ b/fizz/experimental/client/test/BatchSignaturePeerCertTest.cpp @@ -6,12 +6,12 @@ * LICENSE file in the root directory of this source tree. */ +#include +#include #include #include #include #include -#include -#include #include #include #include @@ -60,11 +60,12 @@ TEST(BatchSignaturePeerCertTest, TestSignVerifyP256) { // sign std::vector certs; certs.emplace_back(getCert(kP256Certificate)); - auto certificate = std::make_shared>( - getPrivateKey(kP256Key), std::move(certs)); - auto batcher = std::make_shared>( + auto certificate = + std::make_shared>( + getPrivateKey(kP256Key), std::move(certs)); + auto batcher = std::make_shared>( 1, certificate, CertificateVerifyContext::Server); - BatchSignatureAsyncSelfCert batchSelfCert(batcher); + BatchSignatureAsyncSelfCert batchSelfCert(batcher); folly::ManualExecutor executor; auto signature1 = batchSelfCert.signFuture( SignatureScheme::ecdsa_secp256r1_sha256_batch, @@ -73,8 +74,9 @@ 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, @@ -98,11 +100,12 @@ TEST(BatchSignaturePeerCertTest, TestSignVerifyRSA) { // sign std::vector certs; certs.emplace_back(getCert(kRSACertificate)); - auto certificate = std::make_shared>( - getPrivateKey(kRSAKey), std::move(certs)); - auto batcher = std::make_shared>( + auto certificate = + std::make_shared>( + getPrivateKey(kRSAKey), std::move(certs)); + auto batcher = std::make_shared>( 1, certificate, CertificateVerifyContext::Server); - BatchSignatureAsyncSelfCert batchSelfCert(batcher); + BatchSignatureAsyncSelfCert batchSelfCert(batcher); folly::ManualExecutor executor; auto signature1 = batchSelfCert.signFuture( SignatureScheme::rsa_pss_sha256_batch, @@ -111,8 +114,9 @@ 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, @@ -136,11 +140,12 @@ TEST(BatchSignaturePeerCertTest, TestWrongBatchSignature) { // sign std::vector certs; certs.emplace_back(getCert(kP256Certificate)); - auto certificate = std::make_shared>( - getPrivateKey(kP256Key), std::move(certs)); - auto batcher = std::make_shared>( + auto certificate = + std::make_shared>( + getPrivateKey(kP256Key), std::move(certs)); + auto batcher = std::make_shared>( 1, certificate, CertificateVerifyContext::Server); - BatchSignatureAsyncSelfCert batchSelfCert(batcher); + BatchSignatureAsyncSelfCert batchSelfCert(batcher); folly::ManualExecutor executor; auto signature = batchSelfCert.signFuture( SignatureScheme::ecdsa_secp256r1_sha256_batch, @@ -149,8 +154,9 @@ 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( @@ -175,10 +181,11 @@ TEST(BatchSignaturePeerCertTest, TestWrongBatchSignature) { newSig1.encode()->coalesce()), std::runtime_error); - // throw when signature's path length is larger than Sha256::HashLen * 32 + // throw when signature's path length is larger than openssl::Sha256::HashLen + // * 32 MerkleTreePath newPath2{ .index = static_cast(decodedSig.getIndex())}; - size_t badLength = Sha256::HashLen * 33; + size_t badLength = openssl::Sha256::HashLen * 33; newPath2.path = folly::IOBuf::create(badLength); newPath2.path->append(badLength); BatchSignature newSig2(std::move(newPath2), decodedSig.getSignature()); diff --git a/fizz/experimental/crypto/MerkleTree.h b/fizz/experimental/crypto/MerkleTree.h index 01023e3c9e5..a2e4fa8a07e 100644 --- a/fizz/experimental/crypto/MerkleTree.h +++ b/fizz/experimental/crypto/MerkleTree.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include @@ -54,7 +55,7 @@ struct MerkleTreePath { * preimage attacks. * @param msg, the original message. */ -template +template class MerkleTree { public: // key of Hash Map: (height, offset) @@ -270,7 +271,7 @@ class MerkleTree { * Refer to https://datatracker.ietf.org/doc/draft-ietf-tls-batch-signing for a * detailed description. */ -template +template class BatchSignatureMerkleTree : public MerkleTree, Hash> { public: diff --git a/fizz/experimental/crypto/test/BatchSignatureTest.cpp b/fizz/experimental/crypto/test/BatchSignatureTest.cpp index 74410137cd4..ad0ca7b1ae9 100644 --- a/fizz/experimental/crypto/test/BatchSignatureTest.cpp +++ b/fizz/experimental/crypto/test/BatchSignatureTest.cpp @@ -15,7 +15,7 @@ namespace fizz { namespace test { TEST(BatchSignatureTest, encodeToBeSigned) { - BatchSignatureMerkleTree mt(4); + BatchSignatureMerkleTree mt(4); mt.append(folly::range(folly::StringPiece("Message1"))); mt.append(folly::range(folly::StringPiece("Message2"))); mt.finalizeAndBuild(); @@ -33,7 +33,7 @@ TEST(BatchSignatureTest, encodeToBeSigned) { } TEST(BatchSignatureTest, signatureEncodeDecode) { - BatchSignatureMerkleTree mt(4); + BatchSignatureMerkleTree mt(4); auto index = mt.append(folly::range(folly::StringPiece("Message1"))); mt.append(folly::range(folly::StringPiece("Message2"))); mt.finalizeAndBuild(); diff --git a/fizz/experimental/crypto/test/MerkleTreeTest.cpp b/fizz/experimental/crypto/test/MerkleTreeTest.cpp index e7752d2e6d2..a255d1f1f29 100644 --- a/fizz/experimental/crypto/test/MerkleTreeTest.cpp +++ b/fizz/experimental/crypto/test/MerkleTreeTest.cpp @@ -6,7 +6,7 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include #include #include #include @@ -20,7 +20,7 @@ TEST(MerkleTreeTest, TestTree1) { * Layer 0: H(0) H(1) * Messages: Message1 Message2 */ - BatchSignatureMerkleTree mt(2); + BatchSignatureMerkleTree mt(2); auto index1 = mt.append(folly::range(folly::StringPiece("Message1"))); auto index2 = mt.append(folly::range(folly::StringPiece("Message2"))); auto node1 = mt.getNodeValue(0, 0); @@ -41,7 +41,7 @@ TEST(MerkleTreeTest, TestTree1) { auto root = mt.getRootValue(); EXPECT_EQ(mt.countHeight(), 2); EXPECT_EQ(mt.countLeaves(), 2); - size_t hashLen = Sha256::HashLen; + size_t hashLen = openssl::Sha256::HashLen; EXPECT_EQ(root->length(), hashLen); EXPECT_EQ( folly::hexlify(std::string((char*)root->data(), root->length())), @@ -53,7 +53,7 @@ TEST(MerkleTreeTest, TestTree2) { * Layer 0: H(0) * Messages: Message1 */ - BatchSignatureMerkleTree mt(2); + BatchSignatureMerkleTree mt(2); auto index1 = mt.append(folly::range(folly::StringPiece("Message1"))); EXPECT_EQ(mt.countHeight(), 1); EXPECT_EQ(mt.countLeaves(), 1); @@ -72,7 +72,7 @@ TEST(MerkleTreeTest, TestTree3) { * Layer 0: H(0) H(1) H(2) H(3)*=H(0) * Messages: Message1 Message1 Message1 */ - BatchSignatureMerkleTree mt(2); + BatchSignatureMerkleTree mt(2); mt.append(folly::range(folly::StringPiece("Message1"))); mt.append(folly::range(folly::StringPiece("Message1"))); mt.append(folly::range(folly::StringPiece("Message1"))); @@ -112,7 +112,7 @@ TEST(MerkleTreeTest, TestTLSTree) { * Layer 0: H(0) H(1) H(2) H(3) * Messages: Message1 Randomness1 Message2 Randomness2 */ - BatchSignatureMerkleTree mt(2); + BatchSignatureMerkleTree mt(2); auto index1 = mt.appendTranscript(folly::range(folly::StringPiece("Message1"))); auto index2 = @@ -125,21 +125,21 @@ TEST(MerkleTreeTest, TestTLSTree) { // generate a path used for reconstruct the root auto path = mt.getPath(index2.value()); - EXPECT_EQ(path.path->computeChainDataLength() / Sha256::HashLen, 2); + EXPECT_EQ(path.path->computeChainDataLength() / openssl::Sha256::HashLen, 2); auto expectedPathNode1 = mt.getNodeValue(0, 3); EXPECT_TRUE(std::equal( path.path->data(), - path.path->data() + Sha256::HashLen, + path.path->data() + openssl::Sha256::HashLen, expectedPathNode1.value()->data())); auto expectedPathNode2 = mt.getNodeValue(1, 0); EXPECT_TRUE(std::equal( - path.path->data() + Sha256::HashLen, - path.path->data() + 2 * Sha256::HashLen, + path.path->data() + openssl::Sha256::HashLen, + path.path->data() + 2 * openssl::Sha256::HashLen, expectedPathNode2.value()->data())); // compute the root from message, index, and path mt.finalizeAndBuild(); auto root = mt.getRootValue(); - auto root2 = BatchSignatureMerkleTree::computeRootFromPath( + auto root2 = BatchSignatureMerkleTree::computeRootFromPath( folly::range(folly::StringPiece("Message2")), std::move(path)); EXPECT_TRUE(std::equal(root->data(), root->tail(), root2->data())); } diff --git a/fizz/experimental/ktls/KTLS.cpp b/fizz/experimental/ktls/KTLS.cpp index 2bd8bc720eb..3e07b068f75 100644 --- a/fizz/experimental/ktls/KTLS.cpp +++ b/fizz/experimental/ktls/KTLS.cpp @@ -23,8 +23,7 @@ #include -#include -#include +#include namespace fizz { @@ -63,14 +62,14 @@ static folly::Optional getKTLSLayout(CipherSuite suite) { // TODO: Newer kernels support chacha20 switch (suite) { case CipherSuite::TLS_AES_128_GCM_SHA256: - ret.keyLength = AESGCM128::kKeyLength; - ret.ivLength = AESGCM128::kIVLength; + ret.keyLength = openssl::AESGCM128::kKeyLength; + ret.ivLength = openssl::AESGCM128::kIVLength; ret.ktlsAllocationSize = CRYPTO_INFO_SIZE(TLS_CIPHER_AES_GCM_128); ret.ktlsCipherType = TLS_CIPHER_AES_GCM_128; break; case CipherSuite::TLS_AES_256_GCM_SHA384: - ret.keyLength = AESGCM256::kKeyLength; - ret.ivLength = AESGCM256::kIVLength; + ret.keyLength = openssl::AESGCM256::kKeyLength; + ret.ivLength = openssl::AESGCM256::kIVLength; ret.ktlsAllocationSize = CRYPTO_INFO_SIZE(TLS_CIPHER_AES_GCM_256); ret.ktlsCipherType = TLS_CIPHER_AES_GCM_256; break; diff --git a/fizz/experimental/ktls/test/AsyncFizzBaseKTLSTest.cpp b/fizz/experimental/ktls/test/AsyncFizzBaseKTLSTest.cpp index 268d19d685e..79c80fc40fb 100644 --- a/fizz/experimental/ktls/test/AsyncFizzBaseKTLSTest.cpp +++ b/fizz/experimental/ktls/test/AsyncFizzBaseKTLSTest.cpp @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include #include #include #include #include -#include #include #include #include @@ -226,7 +226,7 @@ static std::shared_ptr makeTestServerContext() { auto certmanager = std::make_shared(); certmanager->addCert( - CertUtils::makeSelfCert( + openssl::CertUtils::makeSelfCert( fizz::test::kP256Certificate.str(), fizz::test::kP256Key.str()), true); diff --git a/fizz/experimental/ktls/test/AsyncKTLSRxSocketTest.cpp b/fizz/experimental/ktls/test/AsyncKTLSRxSocketTest.cpp index 9e984937e4e..93edbce2af9 100644 --- a/fizz/experimental/ktls/test/AsyncKTLSRxSocketTest.cpp +++ b/fizz/experimental/ktls/test/AsyncKTLSRxSocketTest.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include #include #include #include @@ -46,7 +46,8 @@ static std::unique_ptr makeEncryptedRecordLayer( // parameter static unsigned char dummy; - auto aead = fizz::OpenSSLEVPCipher::makeCipher(); + auto aead = + fizz::openssl::OpenSSLEVPCipher::makeCipher(); aead->setKey(std::move(key)); auto rl = std::make_unique(fizz::EncryptionLevel::AppTraffic); rl->setAead(folly::ByteRange(&dummy, 1), std::move(aead)); diff --git a/fizz/experimental/ktls/test/AsyncKTLSSocketTest.cpp b/fizz/experimental/ktls/test/AsyncKTLSSocketTest.cpp index 853b0130b12..6550ec027d0 100644 --- a/fizz/experimental/ktls/test/AsyncKTLSSocketTest.cpp +++ b/fizz/experimental/ktls/test/AsyncKTLSSocketTest.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include #include #include #include @@ -46,7 +46,8 @@ static std::unique_ptr makeEncryptedRecordLayer( // parameter static unsigned char dummy; - auto aead = fizz::OpenSSLEVPCipher::makeCipher(); + auto aead = + fizz::openssl::OpenSSLEVPCipher::makeCipher(); aead->setKey(std::move(key)); auto rl = std::make_unique(fizz::EncryptionLevel::AppTraffic); rl->setAead(folly::ByteRange(&dummy, 1), std::move(aead)); diff --git a/fizz/experimental/ktls/test/KTLSTest.cpp b/fizz/experimental/ktls/test/KTLSTest.cpp index 316c2155bc3..81a1819ab49 100644 --- a/fizz/experimental/ktls/test/KTLSTest.cpp +++ b/fizz/experimental/ktls/test/KTLSTest.cpp @@ -14,8 +14,7 @@ * limitations under the License. */ -#include -#include +#include #include #include #include @@ -49,8 +48,8 @@ static TrafficKey createKey() { return key; } -static const TrafficKey kAES128TrafficKey = createKey(); -static const TrafficKey kAES256TrafficKey = createKey(); +static const TrafficKey kAES128TrafficKey = createKey(); +static const TrafficKey kAES256TrafficKey = createKey(); TEST_F(KTLSTest, TestSockoptFormat) { // An unsupported ktls cipher suite should not work diff --git a/fizz/experimental/protocol/BatchSignatureTypes.cpp b/fizz/experimental/protocol/BatchSignatureTypes.cpp index fab5d484171..1527a1f4741 100644 --- a/fizz/experimental/protocol/BatchSignatureTypes.cpp +++ b/fizz/experimental/protocol/BatchSignatureTypes.cpp @@ -10,7 +10,8 @@ namespace fizz { -constexpr std::array BatchSignatureSchemes::schemes; +constexpr std::array + BatchSignatureSchemes::schemes; folly::Optional getBatchSchemeInfo( SignatureScheme batchScheme, diff --git a/fizz/experimental/protocol/BatchSignatureTypes.h b/fizz/experimental/protocol/BatchSignatureTypes.h index 3614e39cba5..d1895047fd3 100644 --- a/fizz/experimental/protocol/BatchSignatureTypes.h +++ b/fizz/experimental/protocol/BatchSignatureTypes.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include @@ -23,10 +24,10 @@ template struct BatchSignatureSchemes; /** - * Batch signature schemes based on Sha256. + * Batch signature schemes based on openssl::Sha256. */ template <> -struct BatchSignatureSchemes { +struct BatchSignatureSchemes { constexpr static std::array schemes = { SignatureScheme::ecdsa_secp256r1_sha256_batch, SignatureScheme::rsa_pss_sha256_batch, diff --git a/fizz/experimental/protocol/test/BatchSignatureTypesTest.cpp b/fizz/experimental/protocol/test/BatchSignatureTypesTest.cpp index 4ea7b11fd18..b2cc1504fd1 100644 --- a/fizz/experimental/protocol/test/BatchSignatureTypesTest.cpp +++ b/fizz/experimental/protocol/test/BatchSignatureTypesTest.cpp @@ -14,7 +14,7 @@ namespace fizz { namespace test { TEST(BatchSignatureTypesTest, TestBatchSignatureSchemes) { - BatchSignatureSchemes sha256Schemes; + BatchSignatureSchemes sha256Schemes; EXPECT_EQ( sha256Schemes.getFromBaseScheme(SignatureScheme::ed25519), folly::none); EXPECT_EQ( diff --git a/fizz/experimental/server/BatchSignatureAsyncSelfCert.h b/fizz/experimental/server/BatchSignatureAsyncSelfCert.h index d8707644500..493b4650d46 100644 --- a/fizz/experimental/server/BatchSignatureAsyncSelfCert.h +++ b/fizz/experimental/server/BatchSignatureAsyncSelfCert.h @@ -20,7 +20,7 @@ namespace fizz { * A decorator class for an exisiting SelfCert/AsyncSelfCert to support both * its existing signature schemes and corresponding batch signature schemes. */ -template +template class BatchSignatureAsyncSelfCert : public AsyncSelfCert { public: /** diff --git a/fizz/experimental/server/test/BatchSignatureAsyncSelfCertTest.cpp b/fizz/experimental/server/test/BatchSignatureAsyncSelfCertTest.cpp index c10286ddfce..bb584b5217b 100644 --- a/fizz/experimental/server/test/BatchSignatureAsyncSelfCertTest.cpp +++ b/fizz/experimental/server/test/BatchSignatureAsyncSelfCertTest.cpp @@ -6,11 +6,11 @@ * LICENSE file in the root directory of this source tree. */ +#include +#include #include #include #include -#include -#include #include #include #include @@ -25,9 +25,9 @@ TEST(BatchSignatureAsyncSelfCertTest, TestDecoratorLogicWithMockCert) { EXPECT_CALL(*mockBaseCert, getSigSchemes()) .Times(2) .WillRepeatedly(Return(schemes)); - auto batcher = std::make_shared>( + auto batcher = std::make_shared>( 1, mockBaseCert, CertificateVerifyContext::Server); - BatchSignatureAsyncSelfCert batchCert(batcher); + BatchSignatureAsyncSelfCert batchCert(batcher); EXPECT_EQ(batchCert.getSigner(), mockBaseCert); // getIdentity EXPECT_CALL(*mockBaseCert, getIdentity()) @@ -90,9 +90,9 @@ TEST(BatchSignatureAsyncSelfCertTest, TestDecoratorLogicWithMockCert) { TEST(BatchSignatureAsyncSelfCertTest, TestDecoratorLogicWithMockAsyncCert) { auto mockBaseCert = std::make_shared(); - auto batcher = std::make_shared>( + auto batcher = std::make_shared>( 1, mockBaseCert, CertificateVerifyContext::Server); - BatchSignatureAsyncSelfCert batchCert(batcher); + BatchSignatureAsyncSelfCert batchCert(batcher); EXPECT_EQ(batchCert.getSigner(), mockBaseCert); // sign EXPECT_CALL( @@ -119,18 +119,20 @@ TEST(BatchSignatureAsyncSelfCertTest, TestSignAndVerifyP256) { // sign std::vector certs; certs.emplace_back(getCert(kP256Certificate)); - auto certificate = std::make_shared>( - getPrivateKey(kP256Key), std::move(certs)); - auto batcher = std::make_shared>( + auto certificate = + std::make_shared>( + getPrivateKey(kP256Key), std::move(certs)); + auto batcher = std::make_shared>( 1, certificate, CertificateVerifyContext::Server); - BatchSignatureAsyncSelfCert batchCert(batcher); + BatchSignatureAsyncSelfCert batchCert(batcher); // non-batch signature auto signature = batchCert.signFuture( SignatureScheme::ecdsa_secp256r1_sha256, CertificateVerifyContext::Server, folly::IOBuf::copyBuffer(folly::StringPiece("Message1"))); - OpenSSLPeerCertImpl peerCert(getCert(kP256Certificate)); + openssl::OpenSSLPeerCertImpl peerCert( + getCert(kP256Certificate)); peerCert.verify( SignatureScheme::ecdsa_secp256r1_sha256, CertificateVerifyContext::Server, @@ -156,18 +158,20 @@ TEST(BatchSignatureAsyncSelfCertTest, TestSignAndVerifyRSA) { // sign std::vector certs; certs.emplace_back(getCert(kRSACertificate)); - auto certificate = std::make_shared>( - getPrivateKey(kRSAKey), std::move(certs)); - auto batcher = std::make_shared>( + auto certificate = + std::make_shared>( + getPrivateKey(kRSAKey), std::move(certs)); + auto batcher = std::make_shared>( 1, certificate, CertificateVerifyContext::Server); - BatchSignatureAsyncSelfCert batchCert(batcher); + BatchSignatureAsyncSelfCert batchCert(batcher); // non-batch signature auto signature = batchCert.signFuture( SignatureScheme::rsa_pss_sha256, CertificateVerifyContext::Server, folly::IOBuf::copyBuffer(folly::StringPiece("Message1"))); - OpenSSLPeerCertImpl peerCert(getCert(kRSACertificate)); + openssl::OpenSSLPeerCertImpl peerCert( + getCert(kRSACertificate)); peerCert.verify( SignatureScheme::rsa_pss_sha256, CertificateVerifyContext::Server, @@ -193,11 +197,12 @@ TEST(BatchSignatureAsyncSelfCertTest, TestUnsuportedHash) { // sign std::vector certs; certs.emplace_back(getCert(kP384Certificate)); - auto certificate = std::make_shared>( - getPrivateKey(kP384Key), std::move(certs)); - auto batcher = std::make_shared>( + auto certificate = + std::make_shared>( + getPrivateKey(kP384Key), std::move(certs)); + auto batcher = std::make_shared>( 1, certificate, CertificateVerifyContext::Server); - BatchSignatureAsyncSelfCert batchCert(batcher); + BatchSignatureAsyncSelfCert batchCert(batcher); // thow when signing a batch scheme whose Hash doesn't match EXPECT_THROW( diff --git a/fizz/extensions/delegatedcred/DelegatedCredentialFactory.cpp b/fizz/extensions/delegatedcred/DelegatedCredentialFactory.cpp index c27308b8fce..b4a1070f5b7 100644 --- a/fizz/extensions/delegatedcred/DelegatedCredentialFactory.cpp +++ b/fizz/extensions/delegatedcred/DelegatedCredentialFactory.cpp @@ -30,20 +30,25 @@ std::unique_ptr makeCredential( } switch (CertUtils::getKeyType(pubKey)) { - case KeyType::RSA: - return std::make_unique>( + case openssl::KeyType::RSA: + return std::make_unique< + PeerDelegatedCredentialImpl>( std::move(cert), std::move(pubKey), std::move(credential)); - case KeyType::P256: - return std::make_unique>( + case openssl::KeyType::P256: + return std::make_unique< + PeerDelegatedCredentialImpl>( std::move(cert), std::move(pubKey), std::move(credential)); - case KeyType::P384: - return std::make_unique>( + case openssl::KeyType::P384: + return std::make_unique< + PeerDelegatedCredentialImpl>( std::move(cert), std::move(pubKey), std::move(credential)); - case KeyType::P521: - return std::make_unique>( + case openssl::KeyType::P521: + return std::make_unique< + PeerDelegatedCredentialImpl>( std::move(cert), std::move(pubKey), std::move(credential)); - case KeyType::ED25519: - return std::make_unique>( + case openssl::KeyType::ED25519: + return std::make_unique< + PeerDelegatedCredentialImpl>( std::move(cert), std::move(pubKey), std::move(credential)); } @@ -57,9 +62,9 @@ std::unique_ptr DelegatedCredentialFactory::makePeerCertStatic( CertificateEntry entry, bool leaf) { if (!leaf || entry.extensions.empty()) { - return CertUtils::makePeerCert(std::move(entry.cert_data)); + return openssl::CertUtils::makePeerCert(std::move(entry.cert_data)); } - auto parentCert = CertUtils::makePeerCert(entry.cert_data->clone()); + auto parentCert = openssl::CertUtils::makePeerCert(entry.cert_data->clone()); auto parentX509 = parentCert->getX509(); auto credential = getExtension(entry.extensions); diff --git a/fizz/extensions/delegatedcred/DelegatedCredentialFactory.h b/fizz/extensions/delegatedcred/DelegatedCredentialFactory.h index 73e495dbcaf..9248dfee5f9 100644 --- a/fizz/extensions/delegatedcred/DelegatedCredentialFactory.h +++ b/fizz/extensions/delegatedcred/DelegatedCredentialFactory.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include @@ -17,7 +18,7 @@ namespace extensions { /** * This class allows delegated credentials to be parsed when sent by the server. */ -class DelegatedCredentialFactory : public OpenSSLFactory { +class DelegatedCredentialFactory : public openssl::OpenSSLFactory { public: ~DelegatedCredentialFactory() override = default; diff --git a/fizz/extensions/delegatedcred/DelegatedCredentialUtils.cpp b/fizz/extensions/delegatedcred/DelegatedCredentialUtils.cpp index 228c08e20e9..1af46a801a4 100644 --- a/fizz/extensions/delegatedcred/DelegatedCredentialUtils.cpp +++ b/fizz/extensions/delegatedcred/DelegatedCredentialUtils.cpp @@ -5,8 +5,8 @@ * 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 { @@ -95,21 +95,26 @@ DelegatedCredential DelegatedCredentialUtils::generateCredential( } std::vector credKeySchemes; - switch (CertUtils::getKeyType(credKey)) { - case KeyType::RSA: - credKeySchemes = CertUtils::getSigSchemes(); + switch (openssl::CertUtils::getKeyType(credKey)) { + case openssl::KeyType::RSA: + credKeySchemes = + openssl::CertUtils::getSigSchemes(); break; - case KeyType::P256: - credKeySchemes = CertUtils::getSigSchemes(); + case openssl::KeyType::P256: + credKeySchemes = + openssl::CertUtils::getSigSchemes(); break; - case KeyType::P384: - credKeySchemes = CertUtils::getSigSchemes(); + case openssl::KeyType::P384: + credKeySchemes = + openssl::CertUtils::getSigSchemes(); break; - case KeyType::P521: - credKeySchemes = CertUtils::getSigSchemes(); + case openssl::KeyType::P521: + credKeySchemes = + openssl::CertUtils::getSigSchemes(); break; - case KeyType::ED25519: - credKeySchemes = CertUtils::getSigSchemes(); + case openssl::KeyType::ED25519: + credKeySchemes = + openssl::CertUtils::getSigSchemes(); break; } diff --git a/fizz/extensions/delegatedcred/PeerDelegatedCredential-inl.h b/fizz/extensions/delegatedcred/PeerDelegatedCredential-inl.h index 3206cc53dac..a275e374179 100644 --- a/fizz/extensions/delegatedcred/PeerDelegatedCredential-inl.h +++ b/fizz/extensions/delegatedcred/PeerDelegatedCredential-inl.h @@ -12,7 +12,7 @@ namespace fizz { namespace extensions { -template +template PeerDelegatedCredentialImpl::InternalPeerCert::InternalPeerCert( folly::ssl::X509UniquePtr cert, folly::ssl::EvpPkeyUniquePtr pubKey) @@ -31,7 +31,7 @@ PeerDelegatedCredentialImpl::PeerDelegatedCredentialImpl( : peerCertImpl_(std::move(cert), std::move(pubKey)), credential_(std::move(credential)) {} -template +template void PeerDelegatedCredentialImpl::verify( SignatureScheme scheme, CertificateVerifyContext context, @@ -52,7 +52,8 @@ void PeerDelegatedCredentialImpl::verify( // Verify signature auto credSignBuf = DelegatedCredentialUtils::prepareSignatureBuffer( credential_, folly::ssl::OpenSSLCertUtils::derEncode(*x509)); - auto parentCert = std::make_unique>(std::move(x509)); + auto parentCert = + std::make_unique>(std::move(x509)); try { parentCert->verify( @@ -72,7 +73,7 @@ void PeerDelegatedCredentialImpl::verify( scheme, context, std::move(toBeSigned), std::move(signature)); } -template +template SignatureScheme PeerDelegatedCredentialImpl::getExpectedScheme() const { return credential_.expected_verify_scheme; } diff --git a/fizz/extensions/delegatedcred/PeerDelegatedCredential.h b/fizz/extensions/delegatedcred/PeerDelegatedCredential.h index 51792544170..7d90966d559 100644 --- a/fizz/extensions/delegatedcred/PeerDelegatedCredential.h +++ b/fizz/extensions/delegatedcred/PeerDelegatedCredential.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include @@ -15,7 +16,6 @@ namespace fizz { namespace extensions { -// This is a base class purely to differentiate between the common // peer cert impl, in case a cast is needed at some higher layer. class PeerDelegatedCredential : public PeerCert { public: diff --git a/fizz/extensions/delegatedcred/SelfDelegatedCredential-inl.h b/fizz/extensions/delegatedcred/SelfDelegatedCredential-inl.h index a4a297fbcf8..0c9e1e38b17 100644 --- a/fizz/extensions/delegatedcred/SelfDelegatedCredential-inl.h +++ b/fizz/extensions/delegatedcred/SelfDelegatedCredential-inl.h @@ -12,16 +12,16 @@ namespace fizz { namespace extensions { -template +template SelfDelegatedCredentialImpl::InternalSelfCert::InternalSelfCert( std::vector certs, folly::ssl::EvpPkeyUniquePtr privateKey) - : OpenSSLSelfCertImpl(std::move(certs)) { + : openssl::OpenSSLSelfCertImpl(std::move(certs)) { if (certs_.empty()) { throw std::runtime_error("Must supply at least 1 cert"); } - if (CertUtils::getKeyType(privateKey) != T) { + if (openssl::CertUtils::getKeyType(privateKey) != T) { throw std::runtime_error("Key and credential type don't match"); } @@ -30,7 +30,7 @@ SelfDelegatedCredentialImpl::InternalSelfCert::InternalSelfCert( signature_.setKey(std::move(privateKey)); } -template +template SelfDelegatedCredentialImpl::SelfDelegatedCredentialImpl( std::vector certs, folly::ssl::EvpPkeyUniquePtr privateKey, @@ -38,7 +38,7 @@ SelfDelegatedCredentialImpl::SelfDelegatedCredentialImpl( const std::vector>& compressors) : selfCertImpl_(std::move(certs), std::move(privateKey)), credential_(std::move(credential)) { - auto supportedAlgs = CertUtils::getSigSchemes(); + auto supportedAlgs = openssl::CertUtils::getSigSchemes(); if (std::find( supportedAlgs.begin(), supportedAlgs.end(), @@ -50,7 +50,7 @@ SelfDelegatedCredentialImpl::SelfDelegatedCredentialImpl( // Verify credential signature. auto signBuffer = DelegatedCredentialUtils::prepareSignatureBuffer( credential_, folly::ssl::OpenSSLCertUtils::derEncode(*getX509())); - auto parentCert = CertUtils::makePeerCert(getX509()); + auto parentCert = openssl::CertUtils::makePeerCert(getX509()); parentCert->verify( credential_.credential_scheme, CertificateVerifyContext::DelegatedCredential, @@ -63,24 +63,24 @@ SelfDelegatedCredentialImpl::SelfDelegatedCredentialImpl( } } -template +template std::string SelfDelegatedCredentialImpl::getIdentity() const { return selfCertImpl_.getIdentity(); } -template +template std::vector SelfDelegatedCredentialImpl::getAltIdentities() const { return selfCertImpl_.getAltIdentities(); } -template +template std::vector SelfDelegatedCredentialImpl::getSigSchemes() const { return {credential_.expected_verify_scheme}; } -template +template CertificateMsg SelfDelegatedCredentialImpl::getCertMessage( Buf certificateRequestContext) const { auto msg = selfCertImpl_.getCertMessage(); @@ -88,13 +88,13 @@ CertificateMsg SelfDelegatedCredentialImpl::getCertMessage( return msg; } -template +template CompressedCertificate SelfDelegatedCredentialImpl::getCompressedCert( CertificateCompressionAlgorithm algo) const { - return CertUtils::cloneCompressedCert(compressedCerts_.at(algo)); + return openssl::CertUtils::cloneCompressedCert(compressedCerts_.at(algo)); } -template +template Buf SelfDelegatedCredentialImpl::sign( SignatureScheme scheme, CertificateVerifyContext context, @@ -102,12 +102,12 @@ Buf SelfDelegatedCredentialImpl::sign( return selfCertImpl_.sign(scheme, context, std::move(toBeSigned)); } -template +template folly::ssl::X509UniquePtr SelfDelegatedCredentialImpl::getX509() const { return selfCertImpl_.getX509(); } -template +template const DelegatedCredential& SelfDelegatedCredentialImpl::getDelegatedCredential() const { return credential_; diff --git a/fizz/extensions/delegatedcred/SelfDelegatedCredential.h b/fizz/extensions/delegatedcred/SelfDelegatedCredential.h index 69be997aee8..ebc0ee5697b 100644 --- a/fizz/extensions/delegatedcred/SelfDelegatedCredential.h +++ b/fizz/extensions/delegatedcred/SelfDelegatedCredential.h @@ -7,6 +7,7 @@ */ #pragma once +#include #include #include @@ -25,12 +26,12 @@ 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 OpenSSLSelfCertImpl (to share logic). To -// achieve that without diamond inheritance, the implementation class derives +// implementation to inherit from openssl::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 +// the corresponding openssl::OpenSSLSelfCertImpl class to provide the +// implementation logic. +template class SelfDelegatedCredentialImpl : public SelfDelegatedCredential { public: ~SelfDelegatedCredentialImpl() override = default; @@ -64,15 +65,15 @@ class SelfDelegatedCredentialImpl : public SelfDelegatedCredential { const DelegatedCredential& getDelegatedCredential() const override; private: - class InternalSelfCert : public OpenSSLSelfCertImpl { + class InternalSelfCert : public openssl::OpenSSLSelfCertImpl { public: ~InternalSelfCert() override = default; InternalSelfCert( std::vector certs, folly::ssl::EvpPkeyUniquePtr privateKey); - using OpenSSLSelfCertImpl::certs_; - using OpenSSLSelfCertImpl::signature_; + using openssl::OpenSSLSelfCertImpl::certs_; + using openssl::OpenSSLSelfCertImpl::signature_; }; InternalSelfCert selfCertImpl_; DelegatedCredential credential_; diff --git a/fizz/extensions/delegatedcred/test/DelegatedCredentialFactoryTest.cpp b/fizz/extensions/delegatedcred/test/DelegatedCredentialFactoryTest.cpp index 725ebb53203..867fac6992f 100644 --- a/fizz/extensions/delegatedcred/test/DelegatedCredentialFactoryTest.cpp +++ b/fizz/extensions/delegatedcred/test/DelegatedCredentialFactoryTest.cpp @@ -9,11 +9,11 @@ #include #include +#include #include #include #include #include -#include using namespace folly; @@ -85,14 +85,17 @@ TEST_F(DelegatedCredentialFactoryTest, TestCredentialParsing) { auto cert = factory_.makePeerCert(std::move(entry), true); EXPECT_TRUE(cert); EXPECT_TRUE( - typeid(*cert) == typeid(PeerDelegatedCredentialImpl)); + typeid(*cert) == + typeid(PeerDelegatedCredentialImpl)); } TEST_F(DelegatedCredentialFactoryTest, TestCredentialParsingNonLeaf) { auto entry = generateEntry(); auto cert = factory_.makePeerCert(std::move(entry), false); EXPECT_TRUE(cert); - EXPECT_TRUE(typeid(*cert) == typeid(OpenSSLPeerCertImpl)); + EXPECT_TRUE( + typeid(*cert) == + typeid(openssl::OpenSSLPeerCertImpl)); } TEST_F(DelegatedCredentialFactoryTest, TestCredentialNoCertEntryExtension) { @@ -100,7 +103,9 @@ TEST_F(DelegatedCredentialFactoryTest, TestCredentialNoCertEntryExtension) { entry.extensions.clear(); auto cert = factory_.makePeerCert(std::move(entry), true); EXPECT_TRUE(cert); - EXPECT_TRUE(typeid(*cert) == typeid(OpenSSLPeerCertImpl)); + EXPECT_TRUE( + typeid(*cert) == + typeid(openssl::OpenSSLPeerCertImpl)); } } // namespace test } // namespace extensions diff --git a/fizz/extensions/delegatedcred/test/PeerDelegatedCredentialTest.cpp b/fizz/extensions/delegatedcred/test/PeerDelegatedCredentialTest.cpp index 597f98cb849..7d98002aeaa 100644 --- a/fizz/extensions/delegatedcred/test/PeerDelegatedCredentialTest.cpp +++ b/fizz/extensions/delegatedcred/test/PeerDelegatedCredentialTest.cpp @@ -26,9 +26,9 @@ namespace test { // @lint-ignore-every PRIVATEKEY /* - * Randomly generated ECDSA-P256 private key + * Randomly generated ECDSA-openssl::P256 private key * Command: openssl ecparam -name secp256r1 -genkey - * Output: Randomly generated ECDSA-P256 private key + * Output: Randomly generated ECDSA-openssl::P256 private key */ StringPiece kP256CredCertKey = R"( -----BEGIN PRIVATE KEY----- @@ -66,9 +66,9 @@ zj0EAwIDSAAwRQIgB2EWbwWohYziQ2LmY8Qmn8y0WKR6Mbm5aad0rUBvtK4CIQCv )"; /* - * Randomly generated ECDSA-P256 private key + * Randomly generated ECDSA-openssl::P256 private key * Command: openssl ecparam -name secp256r1 -genkey - * Output: Randomly generated ECDSA-P256 private key + * Output: Randomly generated ECDSA-openssl::P256 private key */ StringPiece kP256DelegatedCredKey = R"( -----BEGIN EC PARAMETERS----- @@ -174,8 +174,9 @@ TEST_F(PeerDelegatedCredentialTest, TestCredentialVerify) { ON_CALL(*clock, getCurrentTime()) .WillByDefault(Return(std::chrono::system_clock::time_point( std::chrono::seconds(1712700000)))); - auto peerCred = std::make_shared>( - std::move(cert), std::move(pubKey), std::move(cred)); + auto peerCred = + std::make_shared>( + std::move(cert), std::move(pubKey), std::move(cred)); peerCred->setClock(clock); // We expect all other verification steps to pass and only the final parent @@ -198,8 +199,9 @@ TEST_F(PeerDelegatedCredentialTest, TestCredentialVerifyNoExtension) { auto addr = pubKeyRange.data(); folly::ssl::EvpPkeyUniquePtr pubKey( d2i_PUBKEY(nullptr, &addr, pubKeyRange.size())); - auto peerCred = std::make_shared>( - std::move(cert), std::move(pubKey), std::move(cred)); + auto peerCred = + std::make_shared>( + std::move(cert), std::move(pubKey), std::move(cred)); expectThrows( [&]() { @@ -224,8 +226,9 @@ TEST_F(PeerDelegatedCredentialTest, TestCredentialVerifyBadSignature) { ON_CALL(*clock, getCurrentTime()) .WillByDefault(Return(std::chrono::system_clock::time_point( std::chrono::seconds(1570400000)))); - auto peerCred = std::make_shared>( - std::move(cert), std::move(pubKey), std::move(cred)); + auto peerCred = + std::make_shared>( + std::move(cert), std::move(pubKey), std::move(cred)); peerCred->setClock(clock); expectThrows( @@ -246,8 +249,9 @@ TEST_F(PeerDelegatedCredentialTest, TestCredentialVerifyWrongAlgo) { auto addr = pubKeyRange.data(); folly::ssl::EvpPkeyUniquePtr pubKey( d2i_PUBKEY(nullptr, &addr, pubKeyRange.size())); - auto peerCred = std::make_shared>( - std::move(cert), std::move(pubKey), std::move(cred)); + auto peerCred = + std::make_shared>( + std::move(cert), std::move(pubKey), std::move(cred)); // Should fail early due to mismatch with credential expectThrows( @@ -268,8 +272,9 @@ TEST_F(PeerDelegatedCredentialTest, TestCredentialVerifyBitFlip) { auto addr = pubKeyRange.data(); folly::ssl::EvpPkeyUniquePtr pubKey( d2i_PUBKEY(nullptr, &addr, pubKeyRange.size())); - auto peerCred = std::make_shared>( - std::move(cert), std::move(pubKey), std::move(cred)); + auto peerCred = + std::make_shared>( + std::move(cert), std::move(pubKey), std::move(cred)); auto sig = toBuf(kP256Signature); sig->writableData()[1] ^= 0x20; @@ -289,8 +294,9 @@ TEST_F(PeerDelegatedCredentialTest, TestCredentialVerifySizeMismatch) { auto addr = pubKeyRange.data(); folly::ssl::EvpPkeyUniquePtr pubKey( d2i_PUBKEY(nullptr, &addr, pubKeyRange.size())); - auto peerCred = std::make_shared>( - std::move(cert), std::move(pubKey), std::move(cred)); + auto peerCred = + std::make_shared>( + std::move(cert), std::move(pubKey), std::move(cred)); auto sig = toBuf(kP256Signature); sig->prependChain(IOBuf::copyBuffer("0")); diff --git a/fizz/extensions/delegatedcred/test/SelfDelegatedCredentialTest.cpp b/fizz/extensions/delegatedcred/test/SelfDelegatedCredentialTest.cpp index 6e71b4adba4..82dff4e426e 100644 --- a/fizz/extensions/delegatedcred/test/SelfDelegatedCredentialTest.cpp +++ b/fizz/extensions/delegatedcred/test/SelfDelegatedCredentialTest.cpp @@ -10,11 +10,11 @@ #include #include +#include #include #include #include #include -#include using namespace folly; @@ -53,8 +53,9 @@ 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 @@ -196,8 +197,8 @@ class SelfDelegatedCredentialTest : public Test { DelegatedCredential makeCredential(const folly::ssl::EvpPkeyUniquePtr& pkey) { DelegatedCredential cred; cred.valid_time = 0x1234; // This isn't checked by the self credential code - const auto keyType = CertUtils::getKeyType(pkey); - const auto sigSchemes = CertUtils::getSigSchemes(keyType); + const auto keyType = openssl::CertUtils::getKeyType(pkey); + const auto sigSchemes = openssl::CertUtils::getSigSchemes(keyType); cred.expected_verify_scheme = sigSchemes[0]; if (pkey) { cred.public_key = getPubkeyDer(pkey); @@ -209,14 +210,16 @@ class SelfDelegatedCredentialTest : public Test { return cred; } - std::unique_ptr> parentCert_; + std::unique_ptr> + parentCert_; }; TEST_F(SelfDelegatedCredentialTest, TestConstruction) { auto dcKey = generateDelegatedPrivkey(); auto credential = makeCredential(dcKey); - auto credCert = std::make_unique>( - getCertVec(), std::move(dcKey), std::move(credential)); + auto credCert = + std::make_unique>( + getCertVec(), std::move(dcKey), std::move(credential)); } #if FIZZ_OPENSSL_HAS_ED25519 @@ -224,7 +227,7 @@ TEST_F(SelfDelegatedCredentialTest, TestEd25519DCConstruction) { auto dcKey = generateEd25519PrivKey(); auto credential = makeCredential(dcKey); auto credCert = - std::make_unique>( + std::make_unique>( getCertVec(), std::move(dcKey), std::move(credential)); } #endif @@ -235,7 +238,7 @@ TEST_F(SelfDelegatedCredentialTest, TestConstructionFailureBadSignature) { credential.signature = IOBuf::copyBuffer("hash algorithm party"); EXPECT_THROW( - std::make_unique>( + std::make_unique>( getCertVec(), std::move(dcKey), std::move(credential)), std::runtime_error); } @@ -246,7 +249,7 @@ TEST_F(SelfDelegatedCredentialTest, TestConstructionFailureKeyTypeMismatch) { // RSA key with EC cert should fail EXPECT_THROW( - std::make_unique>( + std::make_unique>( getCertVec(), std::move(dcKey), std::move(credential)), std::runtime_error); } @@ -261,7 +264,7 @@ TEST_F( updateSignature(credential); EXPECT_THROW( - std::make_unique>( + std::make_unique>( getCertVec(), std::move(dcKey), std::move(credential)), std::runtime_error); } @@ -269,8 +272,9 @@ TEST_F( TEST_F(SelfDelegatedCredentialTest, TestSignatureValidity) { auto dcKey = generateDelegatedPrivkey(); auto credential = makeCredential(dcKey); - auto credCert = std::make_unique>( - getCertVec(), std::move(dcKey), std::move(credential)); + auto credCert = + std::make_unique>( + getCertVec(), std::move(dcKey), std::move(credential)); Buf toSign = IOBuf::copyBuffer("signme"); auto certSig = parentCert_->sign( @@ -282,7 +286,8 @@ TEST_F(SelfDelegatedCredentialTest, TestSignatureValidity) { CertificateVerifyContext::Server, toSign->coalesce()); - auto parentPeerCert = CertUtils::makePeerCert(parentCert_->getX509()); + auto parentPeerCert = + openssl::CertUtils::makePeerCert(parentCert_->getX509()); EXPECT_THROW( parentPeerCert->verify( diff --git a/fizz/extensions/exportedauth/ExportedAuthenticator.cpp b/fizz/extensions/exportedauth/ExportedAuthenticator.cpp index db2aaec05d5..266fb7a43b0 100644 --- a/fizz/extensions/exportedauth/ExportedAuthenticator.cpp +++ b/fizz/extensions/exportedauth/ExportedAuthenticator.cpp @@ -6,10 +6,10 @@ * LICENSE file in the root directory of this source tree. */ +#include +#include #include #include -#include -#include namespace fizz { @@ -34,7 +34,7 @@ Buf ExportedAuthenticator::getAuthenticator( const SelfCert& cert, Buf authenticatorRequest) { auto cipher = transport.getCipher(); - auto deriver = OpenSSLFactory().makeKeyDeriver(*cipher); + auto deriver = openssl::OpenSSLFactory().makeKeyDeriver(*cipher); auto hashLength = deriver->hashLength(); auto supportedSchemes = transport.getSupportedSigSchemes(); Buf handshakeContext; @@ -78,7 +78,7 @@ ExportedAuthenticator::validateAuthenticator( Buf authenticatorRequest, Buf authenticator) { auto cipher = transport.getCipher(); - auto deriver = OpenSSLFactory().makeKeyDeriver(*cipher); + auto deriver = openssl::OpenSSLFactory().makeKeyDeriver(*cipher); auto hashLength = deriver->hashLength(); Buf handshakeContext; Buf finishedMacKey; @@ -205,7 +205,7 @@ folly::Optional> ExportedAuthenticator::validate( auto leafCert = folly::IOBuf::create(capacity); folly::io::Appender appender(leafCert.get(), capacity); detail::writeBuf(certMsg->certificate_list.front().cert_data, appender); - auto peerCert = CertUtils::makePeerCert(std::move(leafCert)); + auto peerCert = openssl::CertUtils::makePeerCert(std::move(leafCert)); auto encodedCertMsg = encodeHandshake(std::move(*certMsg)); auto transcript = detail::computeTranscript( handshakeContext, authenticatorRequest, encodedCertMsg); diff --git a/fizz/extensions/exportedauth/test/ExportedAuthenticatorTest.cpp b/fizz/extensions/exportedauth/test/ExportedAuthenticatorTest.cpp index 3e45a483a91..200326e681b 100644 --- a/fizz/extensions/exportedauth/test/ExportedAuthenticatorTest.cpp +++ b/fizz/extensions/exportedauth/test/ExportedAuthenticatorTest.cpp @@ -9,9 +9,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -72,7 +72,7 @@ class AuthenticatorTest : public ::testing::Test { auto authRequest = encode(std::move(cr)); authrequest_ = std::move(authRequest); CipherSuite cipher = CipherSuite::TLS_AES_128_GCM_SHA256; - deriver_ = OpenSSLFactory().makeKeyDeriver(cipher); + deriver_ = openssl::OpenSSLFactory().makeKeyDeriver(cipher); handshakeContext_ = folly::IOBuf::copyBuffer("12345678901234567890123456789012"); finishedKey_ = folly::IOBuf::copyBuffer("12345678901234567890123456789012"); @@ -146,7 +146,7 @@ class ValidateAuthenticatorTest : public ::testing::Test { public: void SetUp() override { CipherSuite cipher = CipherSuite::TLS_AES_128_GCM_SHA256; - deriver_ = OpenSSLFactory().makeKeyDeriver(cipher); + deriver_ = openssl::OpenSSLFactory().makeKeyDeriver(cipher); schemes_.push_back(SignatureScheme::ecdsa_secp256r1_sha256); authrequest_ = { "14303132333435363738396162636465666768696a0008000d000400020403"}; @@ -167,7 +167,7 @@ TEST_F(ValidateAuthenticatorTest, TestValidateValidAuthenticator) { auto key = fizz::test::getPrivateKey(kP256Key); std::vector certs; certs.push_back(std::move(cert)); - OpenSSLSelfCertImpl certificate( + openssl::OpenSSLSelfCertImpl certificate( std::move(key), std::move(certs)); auto authenticatorRequest = folly::IOBuf::copyBuffer(unhexlify(authrequest_)); auto handshakeContext = @@ -204,7 +204,7 @@ TEST_F(ValidateAuthenticatorTest, TestValidateEmptyAuthenticator) { auto key = fizz::test::getPrivateKey(kP256Key); std::vector certs; certs.push_back(std::move(cert)); - OpenSSLSelfCertImpl certificate( + openssl::OpenSSLSelfCertImpl certificate( std::move(key), std::move(certs)); schemes_.clear(); auto authenticatorRequest = folly::IOBuf::copyBuffer(unhexlify(authrequest_)); diff --git a/fizz/extensions/javacrypto/JavaCryptoFactory.h b/fizz/extensions/javacrypto/JavaCryptoFactory.h index 43bdd6f72e5..813b30c8962 100644 --- a/fizz/extensions/javacrypto/JavaCryptoFactory.h +++ b/fizz/extensions/javacrypto/JavaCryptoFactory.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include @@ -16,7 +17,7 @@ namespace fizz { /** * This class instantiates objects using Java Crypto API instead of OpenSSL. */ -class JavaCryptoFactory : public OpenSSLFactory { +class JavaCryptoFactory : public openssl::OpenSSLFactory { public: ~JavaCryptoFactory() override = default; diff --git a/fizz/extensions/javacrypto/JavaCryptoPeerCert.cpp b/fizz/extensions/javacrypto/JavaCryptoPeerCert.cpp index 9ab551c00f5..734e91bd8bb 100644 --- a/fizz/extensions/javacrypto/JavaCryptoPeerCert.cpp +++ b/fizz/extensions/javacrypto/JavaCryptoPeerCert.cpp @@ -6,9 +6,9 @@ * LICENSE file in the root directory of this source tree. */ +#include #include #include -#include namespace fizz { @@ -71,7 +71,7 @@ void JavaCryptoPeerCert::verify( throw std::runtime_error("Unsupported signature scheme"); } auto jAlgorithm = env->NewStringUTF(algorithm.c_str()); - auto signData = CertUtils::prepareSignData(context, toBeSigned); + auto signData = openssl::CertUtils::prepareSignData(context, toBeSigned); auto jSignData = jni::createByteArray(env, std::move(signData)); auto jSignature = jni::createByteArray(env, signature); diff --git a/fizz/extensions/javacrypto/JavaCryptoPeerCert.h b/fizz/extensions/javacrypto/JavaCryptoPeerCert.h index 6d5a6d0487b..334556d22ce 100644 --- a/fizz/extensions/javacrypto/JavaCryptoPeerCert.h +++ b/fizz/extensions/javacrypto/JavaCryptoPeerCert.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include diff --git a/fizz/extensions/tokenbinding/TokenBindingConstructor.cpp b/fizz/extensions/tokenbinding/TokenBindingConstructor.cpp index 9c7b55eb2ba..232fdd39d27 100644 --- a/fizz/extensions/tokenbinding/TokenBindingConstructor.cpp +++ b/fizz/extensions/tokenbinding/TokenBindingConstructor.cpp @@ -10,8 +10,7 @@ #include -#include -#include +#include #include using namespace folly::ssl; @@ -52,8 +51,8 @@ TokenBinding TokenBindingConstructor::createTokenBinding( Buf TokenBindingConstructor::signWithEcKey( const EcKeyUniquePtr& key, const Buf& message) { - std::array hashedMessage; - fizz::Sha256::hash( + std::array hashedMessage; + fizz::openssl::Sha256::hash( *message, folly::MutableByteRange(hashedMessage.data(), hashedMessage.size())); @@ -103,7 +102,7 @@ void TokenBindingConstructor::addBignumToSignature( } Buf TokenBindingConstructor::encodeEcKey(const EcKeyUniquePtr& ecKey) { - auto ecKeyBuf = detail::encodeECPublicKey(ecKey); + auto ecKeyBuf = openssl::detail::encodeECPublicKey(ecKey); if (ecKeyBuf->isChained() || ecKeyBuf->length() != TokenBindingUtils::kP256EcKeySize + 1) { throw std::runtime_error("Incorrect encoded EC Key Length"); diff --git a/fizz/extensions/tokenbinding/Validator.cpp b/fizz/extensions/tokenbinding/Validator.cpp index 84aa9e60943..1c23bc94e5f 100644 --- a/fizz/extensions/tokenbinding/Validator.cpp +++ b/fizz/extensions/tokenbinding/Validator.cpp @@ -8,8 +8,7 @@ #include -#include -#include +#include #include using namespace folly; @@ -79,8 +78,8 @@ void Validator::verify( auto pkey = constructEcKeyFromBuf(key); auto ecdsa = constructECDSASig(signature); - std::array hashedMessage; - fizz::Sha256::hash( + std::array hashedMessage; + fizz::openssl::Sha256::hash( *message, folly::MutableByteRange(hashedMessage.data(), hashedMessage.size())); if (ECDSA_do_verify( @@ -89,7 +88,7 @@ void Validator::verify( ecdsa.get(), pkey.get()) != 1) { throw std::runtime_error(folly::to( - "Verification failed: ", detail::getOpenSSLError())); + "Verification failed: ", openssl::detail::getOpenSSLError())); } #if FIZZ_OPENSSL_HAS_ED25519 } else if (keyParams == TokenBindingKeyParameters::ed25519_experimental) { @@ -117,10 +116,11 @@ void Validator::verify( // Verify the signature try { - fizz::detail::edVerify(message->coalesce(), signature->coalesce(), pkey); + fizz::openssl::detail::edVerify( + message->coalesce(), signature->coalesce(), pkey); } catch (const std::exception&) { throw std::runtime_error(folly::to( - "Verification failed: ", detail::getOpenSSLError())); + "Verification failed: ", openssl::detail::getOpenSSLError())); } #endif } else { @@ -178,8 +178,8 @@ EcKeyUniquePtr Validator::constructEcKeyFromBuf(const Buf& key) { keyAppender.push(keyReader, keyLen); auto combinedRange = combinedKey->coalesce(); - auto evpKey = - fizz::detail::decodeECPublicKey(combinedRange, NID_X9_62_prime256v1); + auto evpKey = fizz::openssl::detail::decodeECPublicKey( + combinedRange, NID_X9_62_prime256v1); EcKeyUniquePtr publicKey(EVP_PKEY_get1_EC_KEY(evpKey.get())); if (!publicKey) { throw std::runtime_error("Error getting EC_key"); diff --git a/fizz/extensions/tokenbinding/Validator.h b/fizz/extensions/tokenbinding/Validator.h index e21e915dfa3..c5a095b993a 100644 --- a/fizz/extensions/tokenbinding/Validator.h +++ b/fizz/extensions/tokenbinding/Validator.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include diff --git a/fizz/protocol/CertUtils.h b/fizz/protocol/CertUtils.h index 7e333fe5486..0a9a792299d 100644 --- a/fizz/protocol/CertUtils.h +++ b/fizz/protocol/CertUtils.h @@ -8,89 +8,16 @@ #pragma once -#include +#include +#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); +using CertUtils = openssl::CertUtils; - static CertificateMsg getCertMessage( - const std::vector& certs, - Buf certificateRequestContext); +namespace detail { +CREATE_FIZZ_FN_ALIAS(getIdentityFromX509, openssl::detail::getIdentityFromX509) +} - 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/OpenSSLFactory.h b/fizz/protocol/OpenSSLFactory.h index 984b5eb91ff..9fdd58f1566 100644 --- a/fizz/protocol/OpenSSLFactory.h +++ b/fizz/protocol/OpenSSLFactory.h @@ -21,25 +21,10 @@ #include #include -namespace fizz { - -class OpenSSLFactory : public DefaultFactory { - public: - [[nodiscard]] std::unique_ptr makeKeyExchange( - NamedGroup group, - KeyExchangeMode mode) const override; +#include - [[nodiscard]] std::unique_ptr makeAead( - CipherSuite cipher) const override; - - std::unique_ptr makeKeyDeriver( - CipherSuite cipher) const override; +namespace fizz { - std::unique_ptr makeHandshakeContext( - CipherSuite cipher) const override; +using OpenSSLFactory = openssl::OpenSSLFactory; - [[nodiscard]] std::unique_ptr makePeerCert( - CertificateEntry certEntry, - bool /*leaf*/) const override; -}; } // namespace fizz diff --git a/fizz/protocol/OpenSSLPeerCertImpl.h b/fizz/protocol/OpenSSLPeerCertImpl.h index 387a2a6fa4e..52760e443d0 100644 --- a/fizz/protocol/OpenSSLPeerCertImpl.h +++ b/fizz/protocol/OpenSSLPeerCertImpl.h @@ -8,34 +8,13 @@ #pragma once +#include #include -#include -#include +#include namespace fizz { template -class OpenSSLPeerCertImpl : public PeerCert { - public: - explicit OpenSSLPeerCertImpl(folly::ssl::X509UniquePtr cert); - - ~OpenSSLPeerCertImpl() override = default; - - [[nodiscard]] std::string getIdentity() const override; - - void verify( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned, - folly::ByteRange signature) const override; - - [[nodiscard]] folly::ssl::X509UniquePtr getX509() const override; - - protected: - OpenSSLSignature signature_; - folly::ssl::X509UniquePtr cert_; -}; +using OpenSSLPeerCertImpl = openssl::OpenSSLPeerCertImpl; } // namespace fizz - -#include diff --git a/fizz/protocol/OpenSSLSelfCertImpl.h b/fizz/protocol/OpenSSLSelfCertImpl.h index e5741d0d0bd..91fa4f1739a 100644 --- a/fizz/protocol/OpenSSLSelfCertImpl.h +++ b/fizz/protocol/OpenSSLSelfCertImpl.h @@ -8,55 +8,13 @@ #pragma once -#include +#include #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 = {}); +using OpenSSLSelfCertImpl = openssl::OpenSSLSelfCertImpl; - ~OpenSSLSelfCertImpl() override = default; - - [[nodiscard]] std::string getIdentity() const override; - - [[nodiscard]] std::vector getAltIdentities() const override; - - [[nodiscard]] std::vector getSigSchemes() const override; - - [[nodiscard]] CertificateMsg getCertMessage( - Buf certificateRequestContext = nullptr) const override; - - [[nodiscard]] CompressedCertificate getCompressedCert( - CertificateCompressionAlgorithm algo) const override; - - [[nodiscard]] Buf sign( - SignatureScheme scheme, - CertificateVerifyContext context, - folly::ByteRange toBeSigned) const override; - - [[nodiscard]] 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/Types.cpp b/fizz/protocol/Types.cpp index 4bd7f658c48..ee4a9ba9c2a 100644 --- a/fizz/protocol/Types.cpp +++ b/fizz/protocol/Types.cpp @@ -40,11 +40,11 @@ size_t getHashSize(HashFunction hash) { folly::StringPiece toString(HashFunction hash) { switch (hash) { case HashFunction::Sha256: - return "Sha256"; + return "openssl::Sha256"; case HashFunction::Sha384: - return "Sha384"; + return "openssl::Sha384"; case HashFunction::Sha512: - return "Sha512"; + return "openssl::Sha512"; } return "Invalid HashFunction"; } diff --git a/fizz/protocol/ech/Encryption.cpp b/fizz/protocol/ech/Encryption.cpp index d7f1741bf1e..c413c7f9853 100644 --- a/fizz/protocol/ech/Encryption.cpp +++ b/fizz/protocol/ech/Encryption.cpp @@ -9,9 +9,7 @@ #include #include "fizz/record/Types.h" -#include -#include -#include +#include #include #include #include @@ -216,22 +214,22 @@ std::unique_ptr getRecordDigest( hpke::KDFId id) { switch (id) { case hpke::KDFId::Sha256: { - std::array recordDigest; - fizz::Sha256::hash( + std::array recordDigest; + fizz::openssl::Sha256::hash( *encode(echConfig), folly::MutableByteRange(recordDigest.data(), recordDigest.size())); return folly::IOBuf::copyBuffer(recordDigest); } case hpke::KDFId::Sha384: { - std::array recordDigest; - fizz::Sha384::hash( + std::array recordDigest; + fizz::openssl::Sha384::hash( *encode(echConfig), folly::MutableByteRange(recordDigest.data(), recordDigest.size())); return folly::IOBuf::copyBuffer(recordDigest); } case hpke::KDFId::Sha512: { - std::array recordDigest; - fizz::Sha512::hash( + std::array recordDigest; + fizz::openssl::Sha512::hash( *encode(echConfig), folly::MutableByteRange(recordDigest.data(), recordDigest.size())); return folly::IOBuf::copyBuffer(recordDigest); diff --git a/fizz/protocol/ech/test/DecrypterTest.cpp b/fizz/protocol/ech/test/DecrypterTest.cpp index fe7b81c68fa..aa7545e1a24 100644 --- a/fizz/protocol/ech/test/DecrypterTest.cpp +++ b/fizz/protocol/ech/test/DecrypterTest.cpp @@ -94,7 +94,7 @@ ClientHello getChloOuterHRRWithExt( } TEST(DecrypterTest, TestDecodeSuccess) { - auto kex = std::make_unique>(); + auto kex = std::make_unique>(); kex->setPrivateKey(getPrivateKey(kP256Key)); ECHConfigManager decrypter; @@ -118,7 +118,7 @@ TEST(DecrypterTest, TestDecodeSuccess) { } TEST(DecrypterTest, TestDecodeHRRSuccess) { - auto kex = std::make_unique>(); + auto kex = std::make_unique>(); kex->setPrivateKey(getPrivateKey(kP256Key)); ECHConfigManager decrypter; @@ -141,7 +141,7 @@ TEST(DecrypterTest, TestDecodeHRRSuccess) { } TEST(DecrypterTest, TestDecodeHRRWithContextSuccess) { - auto kex = std::make_unique>(); + auto kex = std::make_unique>(); kex->setPrivateKey(getPrivateKey(kP256Key)); ECHConfigManager decrypter; @@ -172,7 +172,7 @@ TEST(DecrypterTest, TestDecodeHRRWithContextSuccess) { TEST(DecrypterTest, TestDecodeFailure) { auto echConfig = getECHConfig(); - auto kex = std::make_unique>(); + auto kex = std::make_unique>(); kex->setPrivateKey(getPrivateKey(kP256Key)); ECHConfigManager decrypter; @@ -185,7 +185,7 @@ TEST(DecrypterTest, TestDecodeFailure) { TEST(DecrypterTest, TestDecodeHRRFailure) { auto echConfig = getECHConfig(); - auto kex = std::make_unique>(); + auto kex = std::make_unique>(); kex->setPrivateKey(getPrivateKey(kP256Key)); ECHConfigManager decrypter; @@ -204,7 +204,7 @@ TEST(DecrypterTest, TestDecodeHRRFailure) { TEST(DecrypterTest, TestDecodeHRRWithContextFailure) { auto echConfig = getECHConfig(); - auto kex = std::make_unique>(); + auto kex = std::make_unique>(); kex->setPrivateKey(getPrivateKey(kP256Key)); ECHConfigManager decrypter; diff --git a/fizz/protocol/ech/test/EncryptionTest.cpp b/fizz/protocol/ech/test/EncryptionTest.cpp index fb0cd72bc5a..5d6d19d7be6 100644 --- a/fizz/protocol/ech/test/EncryptionTest.cpp +++ b/fizz/protocol/ech/test/EncryptionTest.cpp @@ -35,7 +35,8 @@ static std::vector supportedAeads{ hpke::AeadId::TLS_AES_256_GCM_SHA384, hpke::AeadId::TLS_AES_128_GCM_SHA256}; -class MockOpenSSLECKeyExchange256 : public OpenSSLECKeyExchange { +class MockOpenSSLECKeyExchange256 + : public openssl::OpenSSLECKeyExchange { public: MOCK_METHOD(void, generateKeyPair, ()); }; diff --git a/fizz/protocol/ech/test/TestUtil.cpp b/fizz/protocol/ech/test/TestUtil.cpp index 41d68908aef..5f03da49b95 100644 --- a/fizz/protocol/ech/test/TestUtil.cpp +++ b/fizz/protocol/ech/test/TestUtil.cpp @@ -31,7 +31,7 @@ ECHConfigContentDraft getECHConfigContent() { ECHConfigContentDraft echConfigContent; echConfigContent.key_config.config_id = 0xFB; echConfigContent.key_config.kem_id = hpke::KEMId::secp256r1; - echConfigContent.key_config.public_key = detail::encodeECPublicKey( + echConfigContent.key_config.public_key = openssl::detail::encodeECPublicKey( ::fizz::test::getPublicKey(::fizz::test::kP256PublicKey)); echConfigContent.key_config.cipher_suites = {suite}; echConfigContent.maximum_name_length = 100; diff --git a/fizz/record/test/EncryptedRecordBench.cpp b/fizz/record/test/EncryptedRecordBench.cpp index 118ddbb8946..79e2f6294ee 100644 --- a/fizz/record/test/EncryptedRecordBench.cpp +++ b/fizz/record/test/EncryptedRecordBench.cpp @@ -6,11 +6,9 @@ #include #include +#include #include #include -#include -#include -#include #include using namespace fizz; @@ -82,7 +80,7 @@ void encryptGCM( std::vector> msg_clones; EncryptedWriteRecordLayer write{EncryptionLevel::AppTraffic}; BENCHMARK_SUSPEND { - aead = OpenSSLEVPCipher::makeCipher(); + aead = openssl::OpenSSLEVPCipher::makeCipher(); aead->setKey(getKey()); write.setAead(folly::ByteRange(), std::move(aead)); for (size_t i = 0; i < n; ++i) { @@ -110,8 +108,9 @@ void decryptGCM(uint32_t n, size_t size, IOBufAllocation iobufAllocation) { EncryptedReadRecordLayer read{EncryptionLevel::AppTraffic}; BENCHMARK_SUSPEND { EncryptedWriteRecordLayer write{EncryptionLevel::AppTraffic}; - auto writeAead = OpenSSLEVPCipher::makeCipher(); - auto readAead = OpenSSLEVPCipher::makeCipher(); + auto writeAead = + openssl::OpenSSLEVPCipher::makeCipher(); + auto readAead = openssl::OpenSSLEVPCipher::makeCipher(); writeAead->setKey(getKey()); readAead->setKey(getKey()); write.setAead(folly::ByteRange(), std::move(writeAead)); @@ -145,8 +144,9 @@ void decryptGCMNoRecord(uint32_t n, size_t size) { std::vector> contents; auto aad = folly::IOBuf::copyBuffer("aad"); BENCHMARK_SUSPEND { - std::unique_ptr writeAead = OpenSSLEVPCipher::makeCipher(); - readAead = OpenSSLEVPCipher::makeCipher(); + std::unique_ptr writeAead = + openssl::OpenSSLEVPCipher::makeCipher(); + readAead = openssl::OpenSSLEVPCipher::makeCipher(); writeAead->setKey(getKey()); readAead->setKey(getKey()); for (size_t i = 0; i < n; ++i) { @@ -215,7 +215,7 @@ void encryptOCB(uint32_t n, size_t size) { std::vector msgs; EncryptedWriteRecordLayer write{EncryptionLevel::AppTraffic}; BENCHMARK_SUSPEND { - aead = OpenSSLEVPCipher::makeCipher(); + aead = openssl::OpenSSLEVPCipher::makeCipher(); aead->setKey(getKey()); write.setAead(folly::ByteRange(), std::move(aead)); for (size_t i = 0; i < n; ++i) { diff --git a/fizz/server/AeadTokenCipher.h b/fizz/server/AeadTokenCipher.h index b056f4a8dcb..076cef0615f 100644 --- a/fizz/server/AeadTokenCipher.h +++ b/fizz/server/AeadTokenCipher.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include @@ -23,9 +24,9 @@ class Aead128GCMTokenCipher : public TokenCipher { public: static constexpr size_t kMinTokenSecretLength = 32; - using HashType = Sha256; - using AeadType = OpenSSLEVPCipher; - using CipherType = AESGCM128; + using HashType = openssl::Sha256; + using AeadType = openssl::OpenSSLEVPCipher; + using CipherType = openssl::AESGCM128; /** * Set additional context strings for use with these tokens. The strings will diff --git a/fizz/server/CookieTypes.h b/fizz/server/CookieTypes.h index c72831c0b4b..d02fe4753b8 100644 --- a/fizz/server/CookieTypes.h +++ b/fizz/server/CookieTypes.h @@ -6,6 +6,7 @@ * LICENSE file in the root directory of this source tree. */ +#include #include #include #include diff --git a/fizz/server/FizzServerContext.cpp b/fizz/server/FizzServerContext.cpp index 07a9887667e..d1263340bbb 100644 --- a/fizz/server/FizzServerContext.cpp +++ b/fizz/server/FizzServerContext.cpp @@ -8,13 +8,13 @@ #include "fizz/server/FizzServerContext.h" -#include +#include namespace fizz { namespace server { FizzServerContext::FizzServerContext() - : factory_(std::make_shared()) {} + : factory_(std::make_shared()) {} } // namespace server } // namespace fizz diff --git a/fizz/server/TicketTypes.h b/fizz/server/TicketTypes.h index e854370e460..6ede03f4930 100644 --- a/fizz/server/TicketTypes.h +++ b/fizz/server/TicketTypes.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include #include diff --git a/fizz/server/test/TicketCodecTest.cpp b/fizz/server/test/TicketCodecTest.cpp index a35a932af5d..0b0e00e62a7 100644 --- a/fizz/server/test/TicketCodecTest.cpp +++ b/fizz/server/test/TicketCodecTest.cpp @@ -54,7 +54,7 @@ static ResumptionState getTestResumptionState( } static ResumptionState x509Decode(Buf encoded) { - OpenSSLFactory factory; + openssl::OpenSSLFactory factory; CertManager certManager; return TicketCodec::decode( std::move(encoded), factory, certManager); diff --git a/fizz/server/test/Utils.h b/fizz/server/test/Utils.h index 478e9ca4da3..9ba80f16960 100644 --- a/fizz/server/test/Utils.h +++ b/fizz/server/test/Utils.h @@ -7,6 +7,10 @@ */ #pragma once +#include +#include +#include +#include #include #include #include @@ -41,8 +45,9 @@ 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>( - std::move(certData.key), std::move(certChain)); + auto fizzCert = + std::make_unique>( + std::move(certData.key), std::move(certChain)); auto certManager = std::make_unique(); certManager->addCert(std::move(fizzCert), true); ctx_ = std::make_shared(); @@ -90,7 +95,8 @@ class FizzTestServer : public folly::AsyncServerSocket::AcceptCallback { if (enable) { auto ticketCipher = std::make_shared< Aead128GCMTicketCipher>>( - std::make_shared(), std::make_shared()); + std::make_shared(), + std::make_shared()); auto ticketSeed = RandomGenerator<32>().generateRandom(); ticketCipher->setTicketSecrets({{folly::range(ticketSeed)}}); ctx_->setTicketCipher(ticketCipher); diff --git a/fizz/test/BogoShim.cpp b/fizz/test/BogoShim.cpp index 3f8b93fdddf..16753a01c44 100644 --- a/fizz/test/BogoShim.cpp +++ b/fizz/test/BogoShim.cpp @@ -6,12 +6,11 @@ * LICENSE file in the root directory of this source tree. */ +#include +#include #include #include #include -#include -#include -#include #include #include #include @@ -255,17 +254,20 @@ class BogoTestClient : public AsyncSocket::ConnectCallback, Optional success_; }; -class TestRsaCert : public OpenSSLSelfCertImpl { +class TestRsaCert : public openssl::OpenSSLSelfCertImpl { public: - using OpenSSLSelfCertImpl::OpenSSLSelfCertImpl; + using openssl::OpenSSLSelfCertImpl< + openssl::KeyType::RSA>::OpenSSLSelfCertImpl; std::string getIdentity() const override { return "testrsacert"; } }; -class TestP256Cert : public OpenSSLSelfCertImpl { +class TestP256Cert + : public openssl::OpenSSLSelfCertImpl { public: - using OpenSSLSelfCertImpl::OpenSSLSelfCertImpl; + using openssl::OpenSSLSelfCertImpl< + openssl::KeyType::P256>::OpenSSLSelfCertImpl; std::string getIdentity() const override { return "testp256cert"; } diff --git a/fizz/test/HandshakeTest.cpp b/fizz/test/HandshakeTest.cpp index 20bf9b7439a..c39dacfb0e3 100644 --- a/fizz/test/HandshakeTest.cpp +++ b/fizz/test/HandshakeTest.cpp @@ -5,9 +5,11 @@ * 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 +using namespace fizz::openssl; + namespace fizz { namespace test { @@ -360,8 +362,9 @@ TEST_F(HandshakeTest, TestExtensions) { TEST_F(HandshakeTest, BasicCertRequest) { expectSuccess(); serverContext_->setClientAuthMode(ClientAuthMode::Required); - expected_.clientCert = std::make_shared>( - getCert(kClientAuthClientCert)); + expected_.clientCert = + std::make_shared>( + getCert(kClientAuthClientCert)); doHandshake(); verifyParameters(); sendAppData(); @@ -381,8 +384,9 @@ TEST_P(SigSchemeTest, Schemes) { TEST_F(HandshakeTest, CertRequestPskPreservesIdentity) { serverContext_->setClientAuthMode(ClientAuthMode::Required); - expected_.clientCert = std::make_shared>( - getCert(kClientAuthClientCert)); + expected_.clientCert = + std::make_shared>( + getCert(kClientAuthClientCert)); setupResume(); expectSuccess(); @@ -414,7 +418,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(); @@ -589,8 +593,9 @@ TEST_F(HandshakeTest, EarlyDataTrickleSendRejected) { expected_.pskMode = none; expected_.earlyDataType = EarlyDataType::Rejected; expected_.scheme = SignatureScheme::ecdsa_secp256r1_sha256; - expected_.clientCert = std::make_shared>( - getCert(kClientAuthClientCert)); + expected_.clientCert = + std::make_shared>( + getCert(kClientAuthClientCert)); expectEarlyDataRejectError(); expectServerSuccess(); diff --git a/fizz/test/HandshakeTest.h b/fizz/test/HandshakeTest.h index 8e94a33a0ea..4c3b2273dfa 100644 --- a/fizz/test/HandshakeTest.h +++ b/fizz/test/HandshakeTest.h @@ -10,18 +10,17 @@ #include #include +#include +#include #include #include #include #include #include -#include -#include #include #include #include #include -#include #include #include #include @@ -72,7 +71,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; @@ -81,12 +80,15 @@ class HandshakeTest : public Test { p256Certs.emplace_back(getCert(kP256Certificate)); p384Certs.emplace_back(getCert(kP384Certificate)); p521Certs.emplace_back(getCert(kP521Certificate)); - certManager->addCert(std::make_shared>( - getPrivateKey(kP256Key), std::move(p256Certs), compressors)); - certManager->addCert(std::make_shared>( - getPrivateKey(kP384Key), std::move(p384Certs), compressors)); - certManager->addCert(std::make_shared>( - getPrivateKey(kP521Key), std::move(p521Certs), compressors)); + certManager->addCert( + std::make_shared>( + getPrivateKey(kP256Key), std::move(p256Certs), compressors)); + certManager->addCert( + std::make_shared>( + getPrivateKey(kP384Key), std::move(p384Certs), compressors)); + certManager->addCert( + std::make_shared>( + getPrivateKey(kP521Key), std::move(p521Certs), compressors)); serverContext_->setCertManager(certManager); serverContext_->setEarlyDataSettings( true, @@ -103,8 +105,9 @@ class HandshakeTest : public Test { serverContext_->setClientCertVerifier(verifier); std::vector certVec; certVec.emplace_back(std::move(clientCert)); - auto clientSelfCert = std::make_shared>( - std::move(clientKey), std::move(certVec)); + auto clientSelfCert = + std::make_shared>( + std::move(clientKey), std::move(certVec)); clientContext_->setClientCertificate(std::move(clientSelfCert)); auto ticketCipher = std::make_shared( diff --git a/fizz/tool/FizzClientCommand.cpp b/fizz/tool/FizzClientCommand.cpp index 7549725f6f9..d18b4b29814 100644 --- a/fizz/tool/FizzClientCommand.cpp +++ b/fizz/tool/FizzClientCommand.cpp @@ -17,8 +17,8 @@ #ifdef FIZZ_TOOL_ENABLE_ZSTD #include #endif +#include #include -#include #include #include #include @@ -487,7 +487,7 @@ class BasicPersistentPskCache : public BasicPskCache { std::string serializedPsk; readFile(loadFile_.c_str(), serializedPsk); try { - return deserializePsk(serializedPsk, OpenSSLFactory()); + return deserializePsk(serializedPsk, openssl::OpenSSLFactory()); } catch (const std::exception& e) { LOG(ERROR) << "Error deserializing: " << loadFile_ << "\n" << e.what(); throw; @@ -765,9 +765,9 @@ int fizzClientCommand(const std::vector& args) { std::unique_ptr cert; if (!keyPass.empty()) { - cert = CertUtils::makeSelfCert(certData, keyData, keyPass); + cert = openssl::CertUtils::makeSelfCert(certData, keyData, keyPass); } else { - cert = CertUtils::makeSelfCert(certData, keyData); + cert = openssl::CertUtils::makeSelfCert(certData, keyData); } clientContext->setClientCertificate(std::move(cert)); } diff --git a/fizz/tool/FizzCommandCommon.cpp b/fizz/tool/FizzCommandCommon.cpp index fe1ce10d7fa..602df3e3c25 100644 --- a/fizz/tool/FizzCommandCommon.cpp +++ b/fizz/tool/FizzCommandCommon.cpp @@ -6,8 +6,7 @@ * LICENSE file in the root directory of this source tree. */ -#include -#include +#include #include #include #include @@ -181,11 +180,11 @@ folly::Optional parseECHConfigsBase64( folly::Optional parseECHConfigs(folly::dynamic json) { auto getKDFId = [](std::string kdfStr) { - if (kdfStr == "Sha256") { + if (kdfStr == "openssl::Sha256") { return hpke::KDFId::Sha256; - } else if (kdfStr == "Sha384") { + } else if (kdfStr == "openssl::Sha384") { return hpke::KDFId::Sha384; - } else if (kdfStr == "Sha512") { + } else if (kdfStr == "openssl::Sha512") { return hpke::KDFId::Sha512; } diff --git a/fizz/tool/FizzGenerateDelegatedCredentialCommand.cpp b/fizz/tool/FizzGenerateDelegatedCredentialCommand.cpp index 99006abcd79..0af23715613 100644 --- a/fizz/tool/FizzGenerateDelegatedCredentialCommand.cpp +++ b/fizz/tool/FizzGenerateDelegatedCredentialCommand.cpp @@ -6,8 +6,8 @@ * LICENSE file in the root directory of this source tree. */ +#include #include -#include #include #include #include @@ -117,17 +117,18 @@ int fizzGenerateDelegatedCredentialCommand( try { std::shared_ptr cert; if (!certKeyPass.empty()) { - cert = CertUtils::makeSelfCert(certData, certKeyData, certKeyPass); + cert = + openssl::CertUtils::makeSelfCert(certData, certKeyData, certKeyPass); } else { - cert = CertUtils::makeSelfCert(certData, certKeyData); + cert = openssl::CertUtils::makeSelfCert(certData, certKeyData); } folly::ssl::EvpPkeyUniquePtr certPrivKey = - CertUtils::readPrivateKeyFromBuffer( + openssl::CertUtils::readPrivateKeyFromBuffer( certKeyData, certKeyPass.empty() ? nullptr : &certKeyPass[0]); folly::ssl::EvpPkeyUniquePtr credPrivKey = - CertUtils::readPrivateKeyFromBuffer( + openssl::CertUtils::readPrivateKeyFromBuffer( credKeyData, credKeyPass.empty() ? nullptr : &credKeyPass[0]); if (!credSignScheme) { @@ -135,22 +136,31 @@ int fizzGenerateDelegatedCredentialCommand( } if (!credVerifScheme) { - switch (CertUtils::getKeyType(credPrivKey)) { - case KeyType::RSA: - credVerifScheme = CertUtils::getSigSchemes().front(); + switch (openssl::CertUtils::getKeyType(credPrivKey)) { + case openssl::KeyType::RSA: + credVerifScheme = + openssl::CertUtils::getSigSchemes() + .front(); break; - case KeyType::P256: - credVerifScheme = CertUtils::getSigSchemes().front(); + case openssl::KeyType::P256: + credVerifScheme = + openssl::CertUtils::getSigSchemes() + .front(); break; - case KeyType::P384: - credVerifScheme = CertUtils::getSigSchemes().front(); + case openssl::KeyType::P384: + credVerifScheme = + openssl::CertUtils::getSigSchemes() + .front(); break; - case KeyType::P521: - credVerifScheme = CertUtils::getSigSchemes().front(); + case openssl::KeyType::P521: + credVerifScheme = + openssl::CertUtils::getSigSchemes() + .front(); break; - case KeyType::ED25519: + case openssl::KeyType::ED25519: credVerifScheme = - CertUtils::getSigSchemes().front(); + openssl::CertUtils::getSigSchemes() + .front(); break; } } diff --git a/fizz/tool/FizzServerBenchmarkCommand.cpp b/fizz/tool/FizzServerBenchmarkCommand.cpp index 4f0be2eb501..81bf75b1d11 100644 --- a/fizz/tool/FizzServerBenchmarkCommand.cpp +++ b/fizz/tool/FizzServerBenchmarkCommand.cpp @@ -6,13 +6,12 @@ * LICENSE file in the root directory of this source tree. */ -#include -#include +#include #include #include #include -#include +#include #include #include #include @@ -164,7 +163,7 @@ int fizzServerBenchmarkCommand(const std::vector& args) { ProtocolVersion::tls_1_3, ProtocolVersion::tls_1_3_28}; bool enableBatch = false; size_t batchNumMsgThreshold = 0; - std::shared_ptr> batcher; + std::shared_ptr> batcher; // Argument Handler Map // clang-format off @@ -223,7 +222,8 @@ int fizzServerBenchmarkCommand(const std::vector& args) { serverContext->setSupportedCiphers(std::move(ciphers)); auto ticketCipher = std::make_shared< Aead128GCMTicketCipher>>( - std::make_shared(), std::make_shared()); + std::make_shared(), + std::make_shared()); auto ticketSeed = RandomGenerator<32>().generateRandom(); ticketCipher->setTicketSecrets({{range(ticketSeed)}}); serverContext->setTicketCipher(ticketCipher); @@ -245,16 +245,18 @@ int fizzServerBenchmarkCommand(const std::vector& args) { } std::unique_ptr cert; if (!keyPass.empty()) { - cert = CertUtils::makeSelfCert(certData, keyData, keyPass, compressors); + cert = openssl::CertUtils::makeSelfCert( + certData, keyData, keyPass, compressors); } else { - cert = CertUtils::makeSelfCert(certData, keyData, compressors); + cert = openssl::CertUtils::makeSelfCert(certData, keyData, compressors); } std::shared_ptr sharedCert = std::move(cert); if (enableBatch) { - batcher = std::make_shared>( + batcher = std::make_shared>( batchNumMsgThreshold, sharedCert, CertificateVerifyContext::Server); auto batchCert = - std::make_shared>(batcher); + std::make_shared>( + batcher); serverContext->setSupportedSigSchemes(batchCert->getSigSchemes()); certManager->addCert(batchCert, true); } else { diff --git a/fizz/tool/FizzServerCommand.cpp b/fizz/tool/FizzServerCommand.cpp index fc8cb5a8dcf..2dbf6ae254a 100644 --- a/fizz/tool/FizzServerCommand.cpp +++ b/fizz/tool/FizzServerCommand.cpp @@ -6,11 +6,10 @@ * LICENSE file in the root directory of this source tree. */ -#include -#include +#include +#include #include #include -#include #ifdef FIZZ_TOOL_ENABLE_BROTLI #include #endif @@ -19,8 +18,8 @@ #ifdef FIZZ_TOOL_ENABLE_ZSTD #include #endif -#include -#include +#include +#include #include #include #include @@ -865,7 +864,8 @@ int fizzServerCommand(const std::vector& args) { auto ticketCipher = std::make_shared< Aead128GCMTicketCipher>>( - std::make_shared(), std::make_shared()); + std::make_shared(), + std::make_shared()); auto ticketSeed = RandomGenerator<32>().generateRandom(); ticketCipher->setTicketSecrets({{range(ticketSeed)}}); serverContext->setTicketCipher(ticketCipher); @@ -949,7 +949,7 @@ int fizzServerCommand(const std::vector& args) { } matcher.addKey( keyPath, - CertUtils::readPrivateKeyFromBuffer( + openssl::CertUtils::readPrivateKeyFromBuffer( keyData, keyPass.empty() ? nullptr : &keyPass[0])); } @@ -996,8 +996,8 @@ int fizzServerCommand(const std::vector& args) { LOG(ERROR) << "Failed to upref leaf cert"; return 1; } - auto leafPeer = - CertUtils::makePeerCert(folly::ssl::X509UniquePtr(leafCert)); + auto leafPeer = openssl::CertUtils::makePeerCert( + folly::ssl::X509UniquePtr(leafCert)); auto toSign = fizz::extensions::DelegatedCredentialUtils::prepareSignatureBuffer( *cred, folly::ssl::OpenSSLCertUtils::derEncode(*leafCert)); @@ -1025,43 +1025,47 @@ int fizzServerCommand(const std::vector& args) { } std::unique_ptr cert; - switch (CertUtils::getKeyType(credPrivKey)) { - case KeyType::RSA: + switch (openssl::CertUtils::getKeyType(credPrivKey)) { + case openssl::KeyType::RSA: cert = std::make_unique< - fizz::extensions::SelfDelegatedCredentialImpl>( + fizz::extensions::SelfDelegatedCredentialImpl< + openssl::KeyType::RSA>>( std::move(certs), std::move(credPrivKey), std::move(*cred), compressors); break; - case KeyType::P256: + case openssl::KeyType::P256: cert = std::make_unique< - fizz::extensions::SelfDelegatedCredentialImpl>( + fizz::extensions::SelfDelegatedCredentialImpl< + openssl::KeyType::P256>>( std::move(certs), std::move(credPrivKey), std::move(*cred), compressors); break; - case KeyType::P384: + case openssl::KeyType::P384: cert = std::make_unique< - fizz::extensions::SelfDelegatedCredentialImpl>( + fizz::extensions::SelfDelegatedCredentialImpl< + openssl::KeyType::P384>>( std::move(certs), std::move(credPrivKey), std::move(*cred), compressors); break; - case KeyType::P521: + case openssl::KeyType::P521: cert = std::make_unique< - fizz::extensions::SelfDelegatedCredentialImpl>( + fizz::extensions::SelfDelegatedCredentialImpl< + openssl::KeyType::P521>>( std::move(certs), std::move(credPrivKey), std::move(*cred), compressors); break; - case KeyType::ED25519: + case openssl::KeyType::ED25519: cert = std::make_unique< fizz::extensions::SelfDelegatedCredentialImpl< - KeyType::ED25519>>( + openssl::KeyType::ED25519>>( std::move(certs), std::move(credPrivKey), std::move(*cred), @@ -1088,7 +1092,7 @@ int fizzServerCommand(const std::vector& args) { return 1; } - auto cert = CertUtils::makeSelfCert( + auto cert = openssl::CertUtils::makeSelfCert( std::move(certs), std::move(pkey.second), compressors); certManager->addCert(std::move(cert), first); if (first) { @@ -1107,8 +1111,9 @@ 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>( - std::move(certData.key), std::move(certChain), compressors); + auto cert = + std::make_unique>( + std::move(certData.key), std::move(certChain), compressors); certManager->addCert(std::move(cert), true); } diff --git a/fizz/tool/test/FizzCommandCommonTest.cpp b/fizz/tool/test/FizzCommandCommonTest.cpp index 59689964a52..f6f601b3bf9 100644 --- a/fizz/tool/test/FizzCommandCommonTest.cpp +++ b/fizz/tool/test/FizzCommandCommonTest.cpp @@ -108,7 +108,7 @@ TEST(FizzCommandCommonTest, TestParseECHConfigsSuccess) { "public_key": "049d87bcaddb65d8dcf6df8b148a9679b5b710db19c95a9badfff13468cb358b4e21d24a5c826112658ebb96d64e2985dfb41c1948334391a4aa81b67837e2dbf0", "kem_id": "secp256r1", "cipher_suites": [{ - "kdf_id": "Sha256", + "kdf_id": "openssl::Sha256", "aead_id": "TLS_AES_128_GCM_SHA256" }], "maximum_name_length": 100, @@ -141,7 +141,7 @@ TEST(FizzCommandCommonTest, TestParseECHConfigsWithHexNumsSuccess) { "public_key": "049d87bcaddb65d8dcf6df8b148a9679b5b710db19c95a9badfff13468cb358b4e21d24a5c826112658ebb96d64e2985dfb41c1948334391a4aa81b67837e2dbf0", "kem_id": "secp256r1", "cipher_suites": [{ - "kdf_id": "Sha256", + "kdf_id": "openssl::Sha256", "aead_id": "TLS_AES_128_GCM_SHA256" }], "maximum_name_length": "0x64", @@ -187,7 +187,7 @@ TEST(FizzCommandCommonTest, TestParseECHConfigsJsonExceptions) { "public_key": "049d87bcaddb65d8dcf6df8b148a9679b5b710db19c95a9badfff13468cb358b4e21d24a5c826112658ebb96d64e2985dfb41c1948334391a4aa81b67837e2dbf0", "kem_id": "secp256r1", "cipher_suites": [{ - "kdf_id": "Sha256", + "kdf_id": "openssl::Sha256", "aead_id": "TLS_AES_128_GCM_SHA256" }], "maximum_name_length": 100, diff --git a/fizz/util/FizzUtil.cpp b/fizz/util/FizzUtil.cpp index ba096c4d601..29cae032f38 100644 --- a/fizz/util/FizzUtil.cpp +++ b/fizz/util/FizzUtil.cpp @@ -135,17 +135,20 @@ std::unique_ptr FizzUtil::createKeyExchangeFromBuf( folly::ByteRange privKey) { switch (kemId) { case hpke::KEMId::secp256r1: { - auto kex = std::make_unique>(); + auto kex = + std::make_unique>(); kex->setPrivateKey(readPrivateKeyFromBuf(privKey, "")); return kex; } case hpke::KEMId::secp384r1: { - auto kex = std::make_unique>(); + auto kex = + std::make_unique>(); kex->setPrivateKey(readPrivateKeyFromBuf(privKey, "")); return kex; } case hpke::KEMId::secp521r1: { - auto kex = std::make_unique>(); + auto kex = + std::make_unique>(); kex->setPrivateKey(readPrivateKeyFromBuf(privKey, "")); return kex; } diff --git a/fizz/util/test/FizzUtilTest.cpp b/fizz/util/test/FizzUtilTest.cpp index fb79022e7a4..0ba85d970a9 100644 --- a/fizz/util/test/FizzUtilTest.cpp +++ b/fizz/util/test/FizzUtilTest.cpp @@ -158,7 +158,7 @@ TEST(UtilTest, createKeyExchangeFromBuf) { } { - // Test P256 KEM + // Test openssl::P256 KEM folly::ByteRange privKeyBuf((folly::StringPiece(kP256Key))); auto kex = FizzUtil::createKeyExchangeFromBuf(hpke::KEMId::secp256r1, privKeyBuf);