aboutsummaryrefslogtreecommitdiffstats
path: root/libtransport/src/auth/verifier.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libtransport/src/auth/verifier.cc')
-rw-r--r--libtransport/src/auth/verifier.cc284
1 files changed, 134 insertions, 150 deletions
diff --git a/libtransport/src/auth/verifier.cc b/libtransport/src/auth/verifier.cc
index c9ac1650f..0919aec7d 100644
--- a/libtransport/src/auth/verifier.cc
+++ b/libtransport/src/auth/verifier.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -14,14 +14,16 @@
*/
#include <hicn/transport/auth/verifier.h>
+#include <hicn/transport/core/global_object_pool.h>
+#include <hicn/transport/core/interest.h>
#include <protocols/errors.h>
-using namespace std;
+#include "glog/logging.h"
namespace transport {
namespace auth {
-const vector<VerificationPolicy> Verifier::DEFAULT_FAILED_POLICIES = {
+const std::vector<VerificationPolicy> Verifier::DEFAULT_FAILED_POLICIES = {
VerificationPolicy::DROP,
VerificationPolicy::ABORT,
};
@@ -36,42 +38,55 @@ Verifier::Verifier()
Verifier::~Verifier() {}
bool Verifier::verifyPacket(PacketPtr packet) {
- core::Packet::Format format = packet->getFormat();
-
- if (!packet->authenticationHeader()) {
+ if (!packet->hasAH()) {
throw errors::MalformedAHPacketException();
}
- // Get crypto suite, hash type, signature length
+ // Get crypto suite
CryptoSuite suite = packet->getValidationAlgorithm();
- CryptoHashType hash_type = getHashType(suite);
- size_t signature_len = packet->getSignatureSizeReal();
// Copy IP+TCP / ICMP header before zeroing them
- hicn_header_t header_copy;
- hicn_packet_copy_header(format, packet->packet_start_, &header_copy, false);
- packet->setSignatureSizeGap(0u);
+ u8 header_copy[HICN_HDRLEN_MAX];
+ size_t header_len;
+ packet->saveHeader(header_copy, &header_len);
+
+ // Copy bitmap from interest manifest
+ uint32_t request_bitmap[BITMAP_SIZE] = {0};
+ if (packet->isInterest()) {
+ core::Interest *interest = dynamic_cast<core::Interest *>(packet);
+ memcpy(request_bitmap, interest->getRequestBitmap(),
+ BITMAP_SIZE * sizeof(uint32_t));
+ }
// Retrieve packet signature
- uint8_t *packet_signature = packet->getSignature();
- vector<uint8_t> signature_raw(packet_signature,
- packet_signature + signature_len);
+ utils::MemBuf::Ptr signature_raw = packet->getSignature();
+ std::size_t signature_len = packet->getSignatureSize();
+ DCHECK(signature_len <= signature_raw->tailroom());
+ signature_raw->setLength(signature_len);
// Reset fields that are not used to compute signature
packet->resetForHash();
// Check signatures
- bool valid_packet = verifyBuffer(static_cast<utils::MemBuf *>(packet),
- signature_raw, hash_type);
+ bool valid_packet =
+ verifyBuffer(static_cast<utils::MemBuf *>(packet), signature_raw, suite);
// Restore header
- hicn_packet_copy_header(format, &header_copy, packet->packet_start_, false);
- packet->setSignatureSizeGap(packet->getSignatureSize() - signature_len);
+ packet->loadHeader(header_copy, header_len);
+ packet->setSignature(signature_raw);
+ packet->setSignatureSize(signature_raw->length());
+
+ // Restore bitmap in interest manifest
+ if (packet->isInterest()) {
+ core::Interest *interest = dynamic_cast<core::Interest *>(packet);
+ interest->setRequestBitmap(request_bitmap);
+ }
return valid_packet;
}
-Verifier::PolicyMap Verifier::verifyPackets(const vector<PacketPtr> &packets) {
+Verifier::PolicyMap Verifier::verifyPackets(
+ const std::vector<PacketPtr> &packets) {
PolicyMap policies;
for (const auto &packet : packets) {
@@ -82,8 +97,8 @@ Verifier::PolicyMap Verifier::verifyPackets(const vector<PacketPtr> &packets) {
policy = VerificationPolicy::ACCEPT;
}
+ callVerificationFailedCallback(suffix, policy);
policies[suffix] = policy;
- callVerificationFailedCallback(packet, policy);
}
return policies;
@@ -105,14 +120,15 @@ Verifier::PolicyMap Verifier::verifyHashes(const SuffixMap &packet_map,
}
}
+ callVerificationFailedCallback(packet_hash.first, policy);
policies[packet_hash.first] = policy;
}
return policies;
}
-Verifier::PolicyMap Verifier::verifyPackets(const vector<PacketPtr> &packets,
- const SuffixMap &suffix_map) {
+Verifier::PolicyMap Verifier::verifyPackets(
+ const std::vector<PacketPtr> &packets, const SuffixMap &suffix_map) {
PolicyMap policies;
for (const auto &packet : packets) {
@@ -130,8 +146,8 @@ Verifier::PolicyMap Verifier::verifyPackets(const vector<PacketPtr> &packets,
}
}
+ callVerificationFailedCallback(suffix, policy);
policies[suffix] = policy;
- callVerificationFailedCallback(packet, policy);
}
return policies;
@@ -139,7 +155,7 @@ Verifier::PolicyMap Verifier::verifyPackets(const vector<PacketPtr> &packets,
void Verifier::setVerificationFailedCallback(
VerificationFailedCallback verfication_failed_cb,
- const vector<VerificationPolicy> &failed_policies) {
+ const std::vector<VerificationPolicy> &failed_policies) {
verification_failed_cb_ = verfication_failed_cb;
failed_policies_ = failed_policies;
}
@@ -149,7 +165,7 @@ void Verifier::getVerificationFailedCallback(
*verfication_failed_cb = &verification_failed_cb_;
}
-void Verifier::callVerificationFailedCallback(PacketPtr packet,
+void Verifier::callVerificationFailedCallback(Suffix suffix,
VerificationPolicy &policy) {
if (verification_failed_cb_ == interface::VOID_HANDLER) {
return;
@@ -157,10 +173,7 @@ void Verifier::callVerificationFailedCallback(PacketPtr packet,
if (find(failed_policies_.begin(), failed_policies_.end(), policy) !=
failed_policies_.end()) {
- policy = verification_failed_cb_(
- static_cast<const core::ContentObject &>(*packet),
- make_error_code(
- protocol::protocol_error::signature_verification_failed));
+ policy = verification_failed_cb_(suffix, policy);
}
}
@@ -169,217 +182,188 @@ void Verifier::callVerificationFailedCallback(PacketPtr packet,
// ---------------------------------------------------------
bool VoidVerifier::verifyPacket(PacketPtr packet) { return true; }
-bool VoidVerifier::verifyBuffer(const vector<uint8_t> &buffer,
- const vector<uint8_t> &signature,
- CryptoHashType hash_type) {
+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<uint8_t> &buffer,
+ const utils::MemBuf::Ptr &signature,
+ CryptoSuite suite) {
return true;
}
bool VoidVerifier::verifyBuffer(const utils::MemBuf *buffer,
- const vector<uint8_t> &signature,
- CryptoHashType hash_type) {
+ const utils::MemBuf::Ptr &signature,
+ CryptoSuite suite) {
return true;
}
Verifier::PolicyMap VoidVerifier::verifyPackets(
- const vector<PacketPtr> &packets) {
+ const std::vector<PacketPtr> &packets) {
PolicyMap policies;
for (const auto &packet : packets) {
- policies[packet->getName().getSuffix()] = VerificationPolicy::ACCEPT;
+ auth::Suffix suffix = packet->getName().getSuffix();
+ VerificationPolicy policy = VerificationPolicy::ACCEPT;
+ callVerificationFailedCallback(suffix, policy);
+ policies[suffix] = policy;
}
return policies;
}
Verifier::PolicyMap VoidVerifier::verifyPackets(
- const vector<PacketPtr> &packets, const SuffixMap &suffix_map) {
+ const std::vector<PacketPtr> &packets, const SuffixMap &suffix_map) {
return verifyPackets(packets);
}
// ---------------------------------------------------------
// Asymmetric Verifier
// ---------------------------------------------------------
-AsymmetricVerifier::AsymmetricVerifier(shared_ptr<EVP_PKEY> key) {
+AsymmetricVerifier::AsymmetricVerifier(std::shared_ptr<EVP_PKEY> key) {
setKey(key);
}
-AsymmetricVerifier::AsymmetricVerifier(const string &cert_path) {
+AsymmetricVerifier::AsymmetricVerifier(const std::string &cert_path) {
useCertificate(cert_path);
}
-AsymmetricVerifier::AsymmetricVerifier(shared_ptr<X509> cert) {
+AsymmetricVerifier::AsymmetricVerifier(std::shared_ptr<X509> cert) {
useCertificate(cert);
}
-void AsymmetricVerifier::setKey(shared_ptr<EVP_PKEY> key) { key_ = key; };
+void AsymmetricVerifier::setKey(std::shared_ptr<EVP_PKEY> key) { key_ = key; };
-void AsymmetricVerifier::useCertificate(const string &cert_path) {
+void AsymmetricVerifier::useCertificate(const std::string &cert_path) {
FILE *certf = fopen(cert_path.c_str(), "rb");
if (certf == nullptr) {
throw errors::RuntimeException("Certificate not found");
}
- shared_ptr<X509> cert = shared_ptr<X509>(
+ std::shared_ptr<X509> cert = std::shared_ptr<X509>(
PEM_read_X509(certf, nullptr, nullptr, nullptr), ::X509_free);
useCertificate(cert);
fclose(certf);
}
-void AsymmetricVerifier::useCertificate(shared_ptr<X509> cert) {
- key_ = shared_ptr<EVP_PKEY>(X509_get_pubkey(cert.get()), ::EVP_PKEY_free);
+void AsymmetricVerifier::useCertificate(std::shared_ptr<X509> cert) {
+ key_ =
+ std::shared_ptr<EVP_PKEY>(X509_get_pubkey(cert.get()), ::EVP_PKEY_free);
}
-bool AsymmetricVerifier::verifyBuffer(const vector<uint8_t> &buffer,
- const vector<uint8_t> &signature,
- CryptoHashType hash_type) {
- CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type);
-
- if (hash_evp == nullptr) {
- throw errors::RuntimeException("Unknown hash type");
- }
-
- shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free);
+bool AsymmetricVerifier::verifyBuffer(const uint8_t *buffer, std::size_t len,
+ const utils::MemBuf::Ptr &signature,
+ CryptoSuite suite) {
+ const EVP_MD *hash_md = getMD(suite);
- if (mdctx == nullptr) {
- throw errors::RuntimeException("Digest context allocation failed");
+ std::shared_ptr<EVP_MD_CTX> md_ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free);
+ if (md_ctx == nullptr) {
+ throw errors::RuntimeException("Signature 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.size()) == 1;
+bool AsymmetricVerifier::verifyBuffer(const std::vector<uint8_t> &buffer,
+ const utils::MemBuf::Ptr &signature,
+ CryptoSuite suite) {
+ return verifyBuffer(buffer.data(), buffer.size(), signature, suite);
}
bool AsymmetricVerifier::verifyBuffer(const utils::MemBuf *buffer,
- const vector<uint8_t> &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;
- shared_ptr<EVP_MD_CTX> 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");
+ const utils::MemBuf::Ptr &signature,
+ CryptoSuite suite) {
+ if (buffer->isChained()) {
+ throw errors::RuntimeException(
+ "Signature of chained membuf is not supported.");
}
- 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.size()) == 1;
+ return verifyBuffer(buffer->data(), buffer->length(), signature, suite);
}
// ---------------------------------------------------------
// Symmetric Verifier
// ---------------------------------------------------------
-SymmetricVerifier::SymmetricVerifier(const string &passphrase) {
+SymmetricVerifier::SymmetricVerifier(const std::string &passphrase) {
setPassphrase(passphrase);
}
// Create and set a symmetric key from a passphrase.
-void SymmetricVerifier::setPassphrase(const string &passphrase) {
- key_ = shared_ptr<EVP_PKEY>(
+void SymmetricVerifier::setPassphrase(const std::string &passphrase) {
+ key_ = std::shared_ptr<EVP_PKEY>(
EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, nullptr,
(const unsigned char *)passphrase.c_str(),
passphrase.size()),
EVP_PKEY_free);
}
-bool SymmetricVerifier::verifyBuffer(const vector<uint8_t> &buffer,
- const vector<uint8_t> &signature,
- CryptoHashType hash_type) {
- CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type);
-
- if (hash_evp == nullptr) {
+bool SymmetricVerifier::verifyBuffer(const uint8_t *buffer, std::size_t len,
+ const utils::MemBuf::Ptr &signature,
+ CryptoSuite suite) {
+ const EVP_MD *hash_md = getMD(suite);
+ if (hash_md == nullptr) {
throw errors::RuntimeException("Unknown hash type");
}
- vector<uint8_t> signature_bis(signature.size());
+ const utils::MemBuf::Ptr &signature_bis =
+ core::PacketManager<>::getInstance().getMemBuf();
size_t signature_bis_len;
- shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free);
- if (mdctx == nullptr) {
- throw errors::RuntimeException("Digest context allocation failed");
+ std::shared_ptr<EVP_MD_CTX> 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.data(),
- &signature_bis_len) != 1) {
- throw errors::RuntimeException("Digest computation failed");
- }
+ DCHECK(signature_bis_len <= signature_bis->tailroom());
+ signature_bis->append(signature_bis_len);
- return signature == signature_bis && signature.size() == signature_bis_len;
-}
-
-bool SymmetricVerifier::verifyBuffer(const utils::MemBuf *buffer,
- const vector<uint8_t> &signature,
- CryptoHashType hash_type) {
- CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type);
+ if (EVP_DigestSign(md_ctx.get(), signature_bis->writableData(),
+ &signature_bis_len, buffer, len) != 1) {
+ throw errors::RuntimeException("Signature computation failed");
+ };
- if (hash_evp == nullptr) {
- throw errors::RuntimeException("Unknown hash type");
- }
+ DCHECK(signature_bis_len <= signature_bis->tailroom());
+ signature_bis->setLength(signature_bis_len);
- const utils::MemBuf *p = buffer;
- vector<uint8_t> signature_bis(signature.size());
- size_t signature_bis_len;
- shared_ptr<EVP_MD_CTX> 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");
- }
+ return signature->length() == signature_bis_len &&
+ *signature == *signature_bis;
+}
- p = p->next();
- } while (p != buffer);
+bool SymmetricVerifier::verifyBuffer(const std::vector<uint8_t> &buffer,
+ const utils::MemBuf::Ptr &signature,
+ CryptoSuite suite) {
+ return verifyBuffer(buffer.data(), buffer.size(), signature, suite);
+}
- if (EVP_DigestSignFinal(mdctx.get(), signature_bis.data(),
- &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 == signature_bis && signature.size() == signature_bis_len;
+ return verifyBuffer(buffer->data(), buffer->length(), signature, suite);
}
} // namespace auth