From a5f7941f49160021506ecae0da090f0b204b75ea Mon Sep 17 00:00:00 2001 From: Olivier Roques Date: Thu, 17 Nov 2022 11:26:23 +0000 Subject: feat(auth): add support for ED25519 and ED448 Ref: HICN-818 Signed-off-by: Olivier Roques Change-Id: I8672f022b74be387e16496660a78edf3c1da4bf1 --- .../includes/hicn/transport/auth/crypto_hash.h | 8 +- .../includes/hicn/transport/auth/crypto_suite.h | 20 ++- libtransport/includes/hicn/transport/auth/signer.h | 2 + .../includes/hicn/transport/auth/verifier.h | 28 +++- libtransport/src/auth/crypto_hash.cc | 73 +++------ libtransport/src/auth/crypto_suite.cc | 36 ++++- libtransport/src/auth/signer.cc | 118 +++++--------- libtransport/src/auth/verifier.cc | 172 ++++++++------------- libtransport/src/test/test_auth.cc | 8 +- 9 files changed, 194 insertions(+), 271 deletions(-) diff --git a/libtransport/includes/hicn/transport/auth/crypto_hash.h b/libtransport/includes/hicn/transport/auth/crypto_hash.h index 29ea27114..fbe1d5160 100644 --- a/libtransport/includes/hicn/transport/auth/crypto_hash.h +++ b/libtransport/includes/hicn/transport/auth/crypto_hash.h @@ -27,8 +27,6 @@ extern "C" { namespace transport { namespace auth { -typedef const EVP_MD *(*CryptoHashEVP)(void); - enum class CryptoHashType : uint8_t { UNKNOWN, SHA256, @@ -57,8 +55,6 @@ class CryptoHash { // Compute the hash of given buffer void computeDigest(const uint8_t *buffer, std::size_t len); void computeDigest(const std::vector &buffer); - - // Compute the hash of given membuf void computeDigest(const utils::MemBuf *buffer); // Return the computed hash @@ -82,8 +78,8 @@ class CryptoHash { // Reset hash void reset(); - // Return OpenSSL EVP function associated to a given hash type - static CryptoHashEVP getEVP(CryptoHashType hash_type); + // Return the OpenSSL EVP_MD pointer associated to a given hash type + static const EVP_MD *getMD(CryptoHashType hash_type); // Return hash size static std::size_t getSize(CryptoHashType hash_type); diff --git a/libtransport/includes/hicn/transport/auth/crypto_suite.h b/libtransport/includes/hicn/transport/auth/crypto_suite.h index ed21abb91..f3b535264 100644 --- a/libtransport/includes/hicn/transport/auth/crypto_suite.h +++ b/libtransport/includes/hicn/transport/auth/crypto_suite.h @@ -26,22 +26,24 @@ namespace auth { enum class CryptoSuite : uint8_t { UNKNOWN, + DSA_BLAKE2B512, + DSA_BLAKE2S256, + DSA_SHA256, + DSA_SHA512, ECDSA_BLAKE2B512, ECDSA_BLAKE2S256, ECDSA_SHA256, ECDSA_SHA512, - RSA_BLAKE2B512, - RSA_BLAKE2S256, - RSA_SHA256, - RSA_SHA512, + ED25519, + ED448, HMAC_BLAKE2B512, HMAC_BLAKE2S256, HMAC_SHA256, HMAC_SHA512, - DSA_BLAKE2B512, - DSA_BLAKE2S256, - DSA_SHA256, - DSA_SHA512, + RSA_BLAKE2B512, + RSA_BLAKE2S256, + RSA_SHA256, + RSA_SHA512, }; // Return the suite associated to the given NID @@ -53,5 +55,7 @@ std::string getStringSuite(CryptoSuite suite); // Return the hash type associated to the given suite CryptoHashType getHashType(CryptoSuite suite); +// Return the OpenSSL EVP_MD pointer associated to a given suite +const EVP_MD *getMD(CryptoSuite suite); } // namespace auth } // namespace transport diff --git a/libtransport/includes/hicn/transport/auth/signer.h b/libtransport/includes/hicn/transport/auth/signer.h index e1b3cae5c..f9e07efae 100644 --- a/libtransport/includes/hicn/transport/auth/signer.h +++ b/libtransport/includes/hicn/transport/auth/signer.h @@ -42,6 +42,7 @@ class Signer { // Sign a packet. virtual void signPacket(PacketPtr packet); + virtual void signBuffer(const uint8_t *buffer, std::size_t len); virtual void signBuffer(const std::vector &buffer); virtual void signBuffer(const utils::MemBuf *buffer); @@ -82,6 +83,7 @@ class VoidSigner : public Signer { VoidSigner() = default; void signPacket(PacketPtr packet) override; + void signBuffer(const uint8_t *buffer, std::size_t len) override; void signBuffer(const std::vector &buffer) override; void signBuffer(const utils::MemBuf *buffer) override; }; diff --git a/libtransport/includes/hicn/transport/auth/verifier.h b/libtransport/includes/hicn/transport/auth/verifier.h index c89138339..2e086df4f 100644 --- a/libtransport/includes/hicn/transport/auth/verifier.h +++ b/libtransport/includes/hicn/transport/auth/verifier.h @@ -54,12 +54,15 @@ class Verifier { // Verify a single packet or buffer. virtual bool verifyPacket(PacketPtr packet); + virtual bool verifyBuffer(const uint8_t *buffer, std::size_t len, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) = 0; virtual bool verifyBuffer(const std::vector &buffer, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) = 0; + CryptoSuite suite) = 0; virtual bool verifyBuffer(const utils::MemBuf *buffer, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) = 0; + CryptoSuite suite) = 0; // Verify a batch of packets. Return a mapping from packet suffixes to their // VerificationPolicy. @@ -110,12 +113,15 @@ class VoidVerifier : public Verifier { // and always returns true. public: bool verifyPacket(PacketPtr packet) override; + bool verifyBuffer(const uint8_t *buffer, std::size_t len, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) override; bool verifyBuffer(const std::vector &buffer, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) override; + CryptoSuite suite) override; bool verifyBuffer(const utils::MemBuf *buffer, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) override; + CryptoSuite suite) override; PolicyMap verifyPackets(const std::vector &packets) override; @@ -143,12 +149,15 @@ class AsymmetricVerifier : public Verifier { void useCertificate(const std::string &cert_path); void useCertificate(std::shared_ptr cert); + bool verifyBuffer(const uint8_t *buffer, std::size_t len, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) override; bool verifyBuffer(const std::vector &buffer, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) override; + CryptoSuite suite) override; bool verifyBuffer(const utils::MemBuf *buffer, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) override; + CryptoSuite suite) override; private: std::shared_ptr key_; @@ -166,12 +175,15 @@ class SymmetricVerifier : public Verifier { // Create and set a symmetric key from a passphrase. void setPassphrase(const std::string &passphrase); + bool verifyBuffer(const uint8_t *buffer, std::size_t len, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) override; bool verifyBuffer(const std::vector &buffer, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) override; + CryptoSuite suite) override; bool verifyBuffer(const utils::MemBuf *buffer, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) override; + CryptoSuite suite) override; protected: std::shared_ptr key_; diff --git a/libtransport/src/auth/crypto_hash.cc b/libtransport/src/auth/crypto_hash.cc index bc2d5248e..0f6e9ab53 100644 --- a/libtransport/src/auth/crypto_hash.cc +++ b/libtransport/src/auth/crypto_hash.cc @@ -63,14 +63,16 @@ bool CryptoHash::operator==(const CryptoHash &other) const { } void CryptoHash::computeDigest(const uint8_t *buffer, size_t len) { - CryptoHashEVP hash_evp = CryptoHash::getEVP(digest_type_); - - if (hash_evp == nullptr) { + const EVP_MD *hash_md = CryptoHash::getMD(digest_type_); + if (hash_md == nullptr) { throw errors::RuntimeException("Unknown hash type"); } - EVP_Digest(buffer, len, digest_->writableData(), - (unsigned int *)&digest_size_, (*hash_evp)(), nullptr); + if (EVP_Digest(buffer, len, digest_->writableData(), + reinterpret_cast(&digest_size_), hash_md, + nullptr) != 1) { + throw errors::RuntimeException("Digest computation failed."); + }; } void CryptoHash::computeDigest(const std::vector &buffer) { @@ -78,33 +80,12 @@ void CryptoHash::computeDigest(const std::vector &buffer) { } void CryptoHash::computeDigest(const utils::MemBuf *buffer) { - CryptoHashEVP hash_evp = CryptoHash::getEVP(digest_type_); - - if (hash_evp == nullptr) { - throw errors::RuntimeException("Unknown hash type"); - } - - EVP_MD_CTX *mcdtx = EVP_MD_CTX_new(); - const utils::MemBuf *p = buffer; - - if (EVP_DigestInit_ex(mcdtx, (*hash_evp)(), nullptr) == 0) { - throw errors::RuntimeException("Digest initialization failed"); - } - - do { - if (EVP_DigestUpdate(mcdtx, p->data(), p->length()) != 1) { - throw errors::RuntimeException("Digest update failed"); - } - - p = p->next(); - } while (p != buffer); - - if (EVP_DigestFinal_ex(mcdtx, digest_->writableData(), - (unsigned int *)&digest_size_) != 1) { - throw errors::RuntimeException("Digest computation failed"); + if (buffer->isChained()) { + throw errors::RuntimeException( + "Digest of chained membuf is not supported."); } - EVP_MD_CTX_free(mcdtx); + computeDigest(buffer->data(), buffer->length()); } const utils::MemBuf::Ptr &CryptoHash::getDigest() const { return digest_; } @@ -159,41 +140,33 @@ void CryptoHash::reset() { digest_->setLength(0); } -CryptoHashEVP CryptoHash::getEVP(CryptoHashType hash_type) { +const EVP_MD *CryptoHash::getMD(CryptoHashType hash_type) { switch (hash_type) { case CryptoHashType::SHA256: - return &EVP_sha256; + return EVP_sha256(); case CryptoHashType::SHA512: - return &EVP_sha512; + return EVP_sha512(); case CryptoHashType::BLAKE2S256: - return &EVP_blake2s256; + return EVP_blake2s256(); case CryptoHashType::BLAKE2B512: - return &EVP_blake2b512; + return EVP_blake2b512(); default: return nullptr; } } size_t CryptoHash::getSize(CryptoHashType hash_type) { - CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type); - - if (hash_evp == nullptr) { - return 0; - } - - return EVP_MD_size((*hash_evp)()); + const EVP_MD *hash_md = CryptoHash::getMD(hash_type); + return hash_md == nullptr ? 0 : EVP_MD_size(hash_md); } bool CryptoHash::compareDigest(const uint8_t *digest1, const uint8_t *digest2, CryptoHashType hash_type) { - CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type); - - if (hash_evp == nullptr) { - return false; - } - - return !static_cast( - memcmp(digest1, digest2, CryptoHash::getSize(hash_type))); + const EVP_MD *hash_md = CryptoHash::getMD(hash_type); + return hash_md == nullptr + ? false + : !static_cast( + memcmp(digest1, digest2, CryptoHash::getSize(hash_type))); } } // namespace auth diff --git a/libtransport/src/auth/crypto_suite.cc b/libtransport/src/auth/crypto_suite.cc index 44de85212..e7b097ac4 100644 --- a/libtransport/src/auth/crypto_suite.cc +++ b/libtransport/src/auth/crypto_suite.cc @@ -20,6 +20,10 @@ namespace auth { CryptoSuite getSuite(int nid) { switch (nid) { + case NID_ED25519: + return CryptoSuite::ED25519; + case NID_ED448: + return CryptoSuite::ED448; case NID_ecdsa_with_SHA256: return CryptoSuite::ECDSA_SHA256; case NID_ecdsa_with_SHA512: @@ -43,6 +47,10 @@ CryptoSuite getSuite(int nid) { std::string getStringSuite(CryptoSuite suite) { switch (suite) { + case CryptoSuite::ED25519: + return "ED25519"; + case CryptoSuite::ED448: + return "ED448"; case CryptoSuite::ECDSA_BLAKE2B512: return "ECDSA_BLAKE2B512"; case CryptoSuite::ECDSA_BLAKE2S256: @@ -82,30 +90,42 @@ std::string getStringSuite(CryptoSuite suite) { CryptoHashType getHashType(CryptoSuite suite) { switch (suite) { + case CryptoSuite::DSA_BLAKE2B512: case CryptoSuite::ECDSA_BLAKE2B512: - case CryptoSuite::RSA_BLAKE2B512: case CryptoSuite::HMAC_BLAKE2B512: - case CryptoSuite::DSA_BLAKE2B512: + case CryptoSuite::RSA_BLAKE2B512: return CryptoHashType::BLAKE2B512; + case CryptoSuite::DSA_BLAKE2S256: case CryptoSuite::ECDSA_BLAKE2S256: - case CryptoSuite::RSA_BLAKE2S256: case CryptoSuite::HMAC_BLAKE2S256: - case CryptoSuite::DSA_BLAKE2S256: + case CryptoSuite::RSA_BLAKE2S256: return CryptoHashType::BLAKE2S256; + case CryptoSuite::DSA_SHA256: case CryptoSuite::ECDSA_SHA256: - case CryptoSuite::RSA_SHA256: + case CryptoSuite::ED25519: + case CryptoSuite::ED448: case CryptoSuite::HMAC_SHA256: - case CryptoSuite::DSA_SHA256: + case CryptoSuite::RSA_SHA256: return CryptoHashType::SHA256; + case CryptoSuite::DSA_SHA512: case CryptoSuite::ECDSA_SHA512: - case CryptoSuite::RSA_SHA512: case CryptoSuite::HMAC_SHA512: - case CryptoSuite::DSA_SHA512: + case CryptoSuite::RSA_SHA512: return CryptoHashType::SHA512; default: return CryptoHashType::UNKNOWN; } } +const EVP_MD *getMD(CryptoSuite suite) { + switch (suite) { + case CryptoSuite::ED25519: + case CryptoSuite::ED448: + return nullptr; + default: + return CryptoHash::getMD(getHashType(suite)); + } +} + } // namespace auth } // namespace transport diff --git a/libtransport/src/auth/signer.cc b/libtransport/src/auth/signer.cc index 484180108..5fcb242be 100644 --- a/libtransport/src/auth/signer.cc +++ b/libtransport/src/auth/signer.cc @@ -86,87 +86,47 @@ void Signer::signPacket(PacketPtr packet) { } } -void Signer::signBuffer(const std::vector &buffer) { - DCHECK(key_ != nullptr); - CryptoHashEVP hash_evp = CryptoHash::getEVP(getHashType()); - - if (hash_evp == nullptr) { - throw errors::RuntimeException("Unknown hash type"); - } - - std::shared_ptr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); +void Signer::signBuffer(const uint8_t *buffer, std::size_t len) { + const EVP_MD *hash_md = getMD(suite_); - if (mdctx == nullptr) { - throw errors::RuntimeException("Digest context allocation failed"); + std::shared_ptr md_ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free); + if (md_ctx == nullptr) { + throw errors::RuntimeException("Signature context allocation failed"); } - if (EVP_DigestSignInit(mdctx.get(), nullptr, (*hash_evp)(), nullptr, - key_.get()) != 1) { - throw errors::RuntimeException("Digest initialization failed"); - } - - if (EVP_DigestSignUpdate(mdctx.get(), buffer.data(), buffer.size()) != 1) { - throw errors::RuntimeException("Digest update failed"); + if (EVP_DigestSignInit(md_ctx.get(), nullptr, hash_md, nullptr, key_.get()) != + 1) { + throw errors::RuntimeException("Signature initialization failed"); } - if (EVP_DigestSignFinal(mdctx.get(), nullptr, &signature_len_) != 1) { - throw errors::RuntimeException("Digest computation failed"); - } + if (EVP_DigestSign(md_ctx.get(), nullptr, &signature_len_, buffer, len) != + 1) { + throw errors::RuntimeException("Signature length computation failed"); + }; DCHECK(signature_len_ <= signature_->tailroom()); signature_->setLength(signature_len_); - if (EVP_DigestSignFinal(mdctx.get(), signature_->writableData(), - &signature_len_) != 1) { - throw errors::RuntimeException("Digest computation failed"); - } + if (EVP_DigestSign(md_ctx.get(), signature_->writableData(), &signature_len_, + buffer, len) != 1) { + throw errors::RuntimeException("Signature computation failed"); + }; DCHECK(signature_len_ <= signature_->tailroom()); signature_->setLength(signature_len_); } -void Signer::signBuffer(const utils::MemBuf *buffer) { - DCHECK(key_ != nullptr); - CryptoHashEVP hash_evp = CryptoHash::getEVP(getHashType()); - - if (hash_evp == nullptr) { - throw errors::RuntimeException("Unknown hash type"); - } - - const utils::MemBuf *p = buffer; - std::shared_ptr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); - - if (mdctx == nullptr) { - throw errors::RuntimeException("Digest context allocation failed"); - } - - if (EVP_DigestSignInit(mdctx.get(), nullptr, (*hash_evp)(), nullptr, - key_.get()) != 1) { - throw errors::RuntimeException("Digest initialization failed"); - } - - do { - if (EVP_DigestSignUpdate(mdctx.get(), p->data(), p->length()) != 1) { - throw errors::RuntimeException("Digest update failed"); - } - - p = p->next(); - } while (p != buffer); - - if (EVP_DigestSignFinal(mdctx.get(), nullptr, &signature_len_) != 1) { - throw errors::RuntimeException("Digest computation failed"); - } - - DCHECK(signature_len_ <= signature_->tailroom()); - signature_->setLength(signature_len_); +void Signer::signBuffer(const std::vector &buffer) { + signBuffer(buffer.data(), buffer.size()); +} - if (EVP_DigestSignFinal(mdctx.get(), signature_->writableData(), - &signature_len_) != 1) { - throw errors::RuntimeException("Digest computation failed"); +void Signer::signBuffer(const utils::MemBuf *buffer) { + if (buffer->isChained()) { + throw errors::RuntimeException( + "Signature of chained membuf is not supported."); } - DCHECK(signature_len_ <= signature_->tailroom()); - signature_->setLength(signature_len_); + signBuffer(buffer->data(), buffer->length()); } const utils::MemBuf::Ptr &Signer::getSignature() const { return signature_; } @@ -208,6 +168,8 @@ void Signer::display() { // --------------------------------------------------------- void VoidSigner::signPacket(PacketPtr packet) {} +void VoidSigner::signBuffer(const uint8_t *buffer, std::size_t len) {} + void VoidSigner::signBuffer(const std::vector &buffer) {} void VoidSigner::signBuffer(const utils::MemBuf *buffer) {} @@ -258,20 +220,12 @@ void AsymmetricSigner::setKey(CryptoSuite suite, std::shared_ptr key, signature_len_ = EVP_PKEY_size(key_.get()); DCHECK(signature_len_ <= signature_->tailroom()); - signature_->setLength(signature_len_); - size_t enc_pbk_len = i2d_PublicKey(pub_key.get(), nullptr); - DCHECK(enc_pbk_len >= 0); - - uint8_t *enc_pbkey_raw = nullptr; - i2d_PublicKey(pub_key.get(), &enc_pbkey_raw); - DCHECK(enc_pbkey_raw != nullptr); - + // Key ID is not supported yet. + uint8_t id[8] = {0}; key_id_ = CryptoHash(getHashType()); - key_id_.computeDigest(enc_pbkey_raw, enc_pbk_len); - - OPENSSL_free(enc_pbkey_raw); + key_id_.computeDigest(id, 8); } size_t AsymmetricSigner::getSignatureFieldSize() const { @@ -296,18 +250,20 @@ SymmetricSigner::SymmetricSigner(CryptoSuite suite, (const unsigned char *)passphrase.c_str(), passphrase.size()), EVP_PKEY_free); - key_id_ = CryptoHash(getHashType()); - - CryptoHashEVP hash_evp = CryptoHash::getEVP(getHashType()); - if (hash_evp == nullptr) { + const EVP_MD *hash_md = getMD(suite_); + if (hash_md == nullptr) { throw errors::RuntimeException("Unknown hash type"); } - signature_len_ = EVP_MD_size((*hash_evp)()); + signature_len_ = EVP_MD_size(hash_md); DCHECK(signature_len_ <= signature_->tailroom()); signature_->setLength(signature_len_); - key_id_.computeDigest((uint8_t *)passphrase.c_str(), passphrase.size()); + + // Key ID is not supported yet. + uint8_t id[8] = {0}; + key_id_ = CryptoHash(getHashType()); + key_id_.computeDigest(id, 8); } } // namespace auth diff --git a/libtransport/src/auth/verifier.cc b/libtransport/src/auth/verifier.cc index f930383e6..0919aec7d 100644 --- a/libtransport/src/auth/verifier.cc +++ b/libtransport/src/auth/verifier.cc @@ -42,9 +42,8 @@ bool Verifier::verifyPacket(PacketPtr packet) { throw errors::MalformedAHPacketException(); } - // Get crypto suite, hash type, signature length + // Get crypto suite CryptoSuite suite = packet->getValidationAlgorithm(); - CryptoHashType hash_type = getHashType(suite); // Copy IP+TCP / ICMP header before zeroing them u8 header_copy[HICN_HDRLEN_MAX]; @@ -69,8 +68,8 @@ bool Verifier::verifyPacket(PacketPtr packet) { packet->resetForHash(); // Check signatures - bool valid_packet = verifyBuffer(static_cast(packet), - signature_raw, hash_type); + bool valid_packet = + verifyBuffer(static_cast(packet), signature_raw, suite); // Restore header packet->loadHeader(header_copy, header_len); @@ -183,15 +182,21 @@ void Verifier::callVerificationFailedCallback(Suffix suffix, // --------------------------------------------------------- bool VoidVerifier::verifyPacket(PacketPtr packet) { return true; } +bool VoidVerifier::verifyBuffer(const uint8_t *buffer, std::size_t len, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) { + return true; +} + bool VoidVerifier::verifyBuffer(const std::vector &buffer, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) { + CryptoSuite suite) { return true; } bool VoidVerifier::verifyBuffer(const utils::MemBuf *buffer, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) { + CryptoSuite suite) { return true; } @@ -250,65 +255,40 @@ void AsymmetricVerifier::useCertificate(std::shared_ptr cert) { std::shared_ptr(X509_get_pubkey(cert.get()), ::EVP_PKEY_free); } -bool AsymmetricVerifier::verifyBuffer(const std::vector &buffer, +bool AsymmetricVerifier::verifyBuffer(const uint8_t *buffer, std::size_t len, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) { - CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type); + CryptoSuite suite) { + const EVP_MD *hash_md = getMD(suite); - if (hash_evp == nullptr) { - throw errors::RuntimeException("Unknown hash type"); + std::shared_ptr md_ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free); + if (md_ctx == nullptr) { + throw errors::RuntimeException("Signature context allocation failed"); } - std::shared_ptr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); - - if (mdctx == nullptr) { - throw errors::RuntimeException("Digest context allocation failed"); - } - - if (EVP_DigestVerifyInit(mdctx.get(), nullptr, (*hash_evp)(), nullptr, + if (EVP_DigestVerifyInit(md_ctx.get(), nullptr, hash_md, nullptr, key_.get()) != 1) { - throw errors::RuntimeException("Digest initialization failed"); + throw errors::RuntimeException("Signature initialization failed"); } - if (EVP_DigestVerifyUpdate(mdctx.get(), buffer.data(), buffer.size()) != 1) { - throw errors::RuntimeException("Digest update failed"); - } + return EVP_DigestVerify(md_ctx.get(), signature->data(), signature->length(), + buffer, len) == 1; +}; - return EVP_DigestVerifyFinal(mdctx.get(), signature->data(), - signature->length()) == 1; +bool AsymmetricVerifier::verifyBuffer(const std::vector &buffer, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) { + return verifyBuffer(buffer.data(), buffer.size(), signature, suite); } bool AsymmetricVerifier::verifyBuffer(const utils::MemBuf *buffer, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) { - CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type); - - if (hash_evp == nullptr) { - throw errors::RuntimeException("Unknown hash type"); + CryptoSuite suite) { + if (buffer->isChained()) { + throw errors::RuntimeException( + "Signature of chained membuf is not supported."); } - const utils::MemBuf *p = buffer; - std::shared_ptr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); - - if (mdctx == nullptr) { - throw errors::RuntimeException("Digest context allocation failed"); - } - - if (EVP_DigestVerifyInit(mdctx.get(), nullptr, (*hash_evp)(), nullptr, - key_.get()) != 1) { - throw errors::RuntimeException("Digest initialization failed"); - } - - do { - if (EVP_DigestVerifyUpdate(mdctx.get(), p->data(), p->length()) != 1) { - throw errors::RuntimeException("Digest update failed"); - } - - p = p->next(); - } while (p != buffer); - - return EVP_DigestVerifyFinal(mdctx.get(), signature->data(), - signature->length()) == 1; + return verifyBuffer(buffer->data(), buffer->length(), signature, suite); } // --------------------------------------------------------- @@ -327,83 +307,63 @@ void SymmetricVerifier::setPassphrase(const std::string &passphrase) { EVP_PKEY_free); } -bool SymmetricVerifier::verifyBuffer(const std::vector &buffer, +bool SymmetricVerifier::verifyBuffer(const uint8_t *buffer, std::size_t len, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) { - CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type); - - if (hash_evp == nullptr) { + CryptoSuite suite) { + const EVP_MD *hash_md = getMD(suite); + if (hash_md == nullptr) { throw errors::RuntimeException("Unknown hash type"); } const utils::MemBuf::Ptr &signature_bis = core::PacketManager<>::getInstance().getMemBuf(); - signature_bis->append(signature->length()); size_t signature_bis_len; - std::shared_ptr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); - if (mdctx == nullptr) { - throw errors::RuntimeException("Digest context allocation failed"); + std::shared_ptr md_ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free); + if (md_ctx == nullptr) { + throw errors::RuntimeException("Signature context allocation failed"); } - if (EVP_DigestSignInit(mdctx.get(), nullptr, (*hash_evp)(), nullptr, - key_.get()) != 1) { - throw errors::RuntimeException("Digest initialization failed"); + if (EVP_DigestSignInit(md_ctx.get(), nullptr, hash_md, nullptr, key_.get()) != + 1) { + throw errors::RuntimeException("Signature initialization failed"); } - if (EVP_DigestSignUpdate(mdctx.get(), buffer.data(), buffer.size()) != 1) { - throw errors::RuntimeException("Digest update failed"); - } + if (EVP_DigestSign(md_ctx.get(), nullptr, &signature_bis_len, buffer, len) != + 1) { + throw errors::RuntimeException("Signature length computation failed"); + }; - if (EVP_DigestSignFinal(mdctx.get(), signature_bis->writableData(), - &signature_bis_len) != 1) { - throw errors::RuntimeException("Digest computation failed"); - } + DCHECK(signature_bis_len <= signature_bis->tailroom()); + signature_bis->append(signature_bis_len); + + if (EVP_DigestSign(md_ctx.get(), signature_bis->writableData(), + &signature_bis_len, buffer, len) != 1) { + throw errors::RuntimeException("Signature computation failed"); + }; + + DCHECK(signature_bis_len <= signature_bis->tailroom()); + signature_bis->setLength(signature_bis_len); return signature->length() == signature_bis_len && *signature == *signature_bis; } -bool SymmetricVerifier::verifyBuffer(const utils::MemBuf *buffer, +bool SymmetricVerifier::verifyBuffer(const std::vector &buffer, const utils::MemBuf::Ptr &signature, - CryptoHashType hash_type) { - CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type); - - if (hash_evp == nullptr) { - throw errors::RuntimeException("Unknown hash type"); - } - - const utils::MemBuf *p = buffer; - const utils::MemBuf::Ptr &signature_bis = - core::PacketManager<>::getInstance().getMemBuf(); - signature_bis->append(signature->length()); - size_t signature_bis_len; - std::shared_ptr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); - - if (mdctx == nullptr) { - throw errors::RuntimeException("Digest context allocation failed"); - } - - if (EVP_DigestSignInit(mdctx.get(), nullptr, (*hash_evp)(), nullptr, - key_.get()) != 1) { - throw errors::RuntimeException("Digest initialization failed"); - } - - do { - if (EVP_DigestSignUpdate(mdctx.get(), p->data(), p->length()) != 1) { - throw errors::RuntimeException("Digest update failed"); - } - - p = p->next(); - } while (p != buffer); + CryptoSuite suite) { + return verifyBuffer(buffer.data(), buffer.size(), signature, suite); +} - if (EVP_DigestSignFinal(mdctx.get(), signature_bis->writableData(), - &signature_bis_len) != 1) { - throw errors::RuntimeException("Digest computation failed"); +bool SymmetricVerifier::verifyBuffer(const utils::MemBuf *buffer, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) { + if (buffer->isChained()) { + throw errors::RuntimeException( + "Signature of chained membuf is not supported."); } - return signature->length() == signature_bis_len && - *signature == *signature_bis; + return verifyBuffer(buffer->data(), buffer->length(), signature, suite); } } // namespace auth diff --git a/libtransport/src/test/test_auth.cc b/libtransport/src/test/test_auth.cc index 2ee3c0776..5440d3741 100644 --- a/libtransport/src/test/test_auth.cc +++ b/libtransport/src/test/test_auth.cc @@ -122,7 +122,7 @@ TEST_F(AuthTest, AsymmetricBufferRSA) { std::shared_ptr verif = std::make_shared(pubKey); - bool res = verif->verifyBuffer(buffer, sig, CryptoHashType::SHA256); + bool res = verif->verifyBuffer(buffer, sig, CryptoSuite::RSA_SHA256); EXPECT_EQ(res, true); } @@ -160,7 +160,7 @@ TEST_F(AuthTest, AsymmetricBufferDSA) { std::shared_ptr verif = std::make_shared(pubKey); - bool res = verif->verifyBuffer(buffer, sig, CryptoHashType::SHA256); + bool res = verif->verifyBuffer(buffer, sig, CryptoSuite::RSA_SHA256); EXPECT_EQ(res, true); } @@ -235,7 +235,7 @@ TEST_F(AuthTest, AsymmetricBufferECDSA) { std::shared_ptr verif = std::make_shared(pubKey); - bool res = verif->verifyBuffer(buffer, sig, CryptoHashType::SHA256); + bool res = verif->verifyBuffer(buffer, sig, CryptoSuite::RSA_SHA256); EXPECT_EQ(res, true); } // namespace auth @@ -290,7 +290,7 @@ TEST_F(AuthTest, HMACbuffer) { signer->signBuffer(buffer); utils::MemBuf::Ptr sig = signer->getSignature(); SymmetricVerifier hmac(PASSPHRASE); - bool res = hmac.verifyBuffer(buffer, sig, CryptoHashType::SHA256); + bool res = hmac.verifyBuffer(buffer, sig, CryptoSuite::RSA_SHA256); EXPECT_EQ(res, true); } -- cgit 1.2.3-korg