aboutsummaryrefslogtreecommitdiffstats
path: root/libtransport/src/auth/signer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libtransport/src/auth/signer.cc')
-rw-r--r--libtransport/src/auth/signer.cc277
1 files changed, 149 insertions, 128 deletions
diff --git a/libtransport/src/auth/signer.cc b/libtransport/src/auth/signer.cc
index 99c3d099d..884e850ca 100644
--- a/libtransport/src/auth/signer.cc
+++ b/libtransport/src/auth/signer.cc
@@ -15,193 +15,214 @@
#include <hicn/transport/auth/signer.h>
-extern "C" {
-#ifndef _WIN32
-TRANSPORT_CLANG_DISABLE_WARNING("-Wextern-c-compat")
-#endif
-#include <hicn/hicn.h>
-}
-
-#include <chrono>
-
-#define ALLOW_UNALIGNED_READS 1
-
using namespace std;
namespace transport {
namespace auth {
-Signer::Signer() : signer_(nullptr), key_id_(nullptr) { parcSecurity_Init(); }
+// ---------------------------------------------------------
+// Base Signer
+// ---------------------------------------------------------
+Signer::Signer()
+ : suite_(CryptoSuite::UNKNOWN), signature_len_(0), key_(nullptr) {}
-Signer::Signer(PARCSigner *signer) : Signer() { setSigner(signer); }
-
-Signer::~Signer() {
- if (signer_) parcSigner_Release(&signer_);
- if (key_id_) parcKeyId_Release(&key_id_);
- parcSecurity_Fini();
-}
+Signer::~Signer() {}
void Signer::signPacket(PacketPtr packet) {
- parcAssertNotNull(signer_, "Expected non-null signer");
-
- const utils::MemBuf &header_chain = *packet;
+ assert(key_ != nullptr);
core::Packet::Format format = packet->getFormat();
- auto suite = getCryptoSuite();
- size_t signature_len = getSignatureSize();
if (!packet->authenticationHeader()) {
throw errors::MalformedAHPacketException();
}
- packet->setSignatureSize(signature_len);
+ // Set signature size
+ size_t signature_field_len = getSignatureFieldSize();
+ packet->setSignatureSize(signature_field_len);
+ packet->setSignatureSizeGap(0u);
// 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->resetForHash();
- // Fill in the HICN_AH header
+ // Fill in the hICN AH header
auto now = chrono::duration_cast<chrono::milliseconds>(
chrono::system_clock::now().time_since_epoch())
.count();
packet->setSignatureTimestamp(now);
- packet->setValidationAlgorithm(suite);
+ packet->setValidationAlgorithm(suite_);
- // Set the key ID
- KeyId key_id;
- key_id.first = static_cast<uint8_t *>(
- parcBuffer_Overlay((PARCBuffer *)parcKeyId_GetKeyId(key_id_), 0));
- packet->setKeyId(key_id);
+ // Set key ID
+ vector<uint8_t> key_id = key_id_.getDigest();
+ packet->setKeyId({key_id.data(), key_id.size()});
- // Calculate hash
- CryptoHasher hasher(parcSigner_GetCryptoHasher(signer_));
- const utils::MemBuf *current = &header_chain;
+ // Reset fields to compute the packet hash
+ packet->resetForHash();
- hasher.init();
+ // Compute the signature and put it in the packet
+ signBuffer(packet);
+ hicn_packet_copy_header(format, &header_copy, packet->packet_start_, false);
- do {
- hasher.updateBytes(current->data(), current->length());
- current = current->next();
- } while (current != &header_chain);
+ // Set the gap between the signature field size and the signature real size.
+ packet->setSignatureSizeGap(signature_field_len - signature_len_);
+ memcpy(packet->getSignature(), signature_.data(), signature_len_);
+}
- CryptoHash hash = hasher.finalize();
+void Signer::signBuffer(const std::vector<uint8_t> &buffer) {
+ assert(key_ != nullptr);
+ CryptoHashEVP hash_evp = CryptoHash::getEVP(getHashType());
- // Compute signature
- PARCSignature *signature = parcSigner_SignDigestNoAlloc(
- signer_, hash.hash_, packet->getSignature(), (uint32_t)signature_len);
- PARCBuffer *buffer = parcSignature_GetSignature(signature);
- size_t bytes_len = parcBuffer_Remaining(buffer);
+ if (hash_evp == nullptr) {
+ throw errors::RuntimeException("Unknown hash type");
+ }
- if (bytes_len > signature_len) {
- throw errors::MalformedAHPacketException();
+ shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free);
+
+ if (mdctx == nullptr) {
+ throw errors::RuntimeException("Digest context allocation failed");
}
- // Put signature in AH header
- hicn_packet_copy_header(format, &header_copy, packet->packet_start_, false);
+ if (EVP_DigestSignInit(mdctx.get(), nullptr, (*hash_evp)(), nullptr,
+ key_.get()) != 1) {
+ throw errors::RuntimeException("Digest initialization failed");
+ }
- // Release allocated objects
- parcSignature_Release(&signature);
-}
+ if (EVP_DigestSignUpdate(mdctx.get(), buffer.data(), buffer.size()) != 1) {
+ throw errors::RuntimeException("Digest update failed");
+ }
-void Signer::setSigner(PARCSigner *signer) {
- parcAssertNotNull(signer, "Expected non-null signer");
+ if (EVP_DigestSignFinal(mdctx.get(), nullptr, &signature_len_) != 1) {
+ throw errors::RuntimeException("Digest computation failed");
+ }
- if (signer_) parcSigner_Release(&signer_);
- if (key_id_) parcKeyId_Release(&key_id_);
+ signature_.resize(signature_len_);
- signer_ = parcSigner_Acquire(signer);
- key_id_ = parcSigner_CreateKeyId(signer_);
-}
+ if (EVP_DigestSignFinal(mdctx.get(), signature_.data(), &signature_len_) !=
+ 1) {
+ throw errors::RuntimeException("Digest computation failed");
+ }
-size_t Signer::getSignatureSize() const {
- parcAssertNotNull(signer_, "Expected non-null signer");
- return parcSigner_GetSignatureSize(signer_);
+ signature_.resize(signature_len_);
}
-CryptoSuite Signer::getCryptoSuite() const {
- parcAssertNotNull(signer_, "Expected non-null signer");
- return static_cast<CryptoSuite>(parcSigner_GetCryptoSuite(signer_));
-}
+void Signer::signBuffer(const utils::MemBuf *buffer) {
+ assert(key_ != nullptr);
+ CryptoHashEVP hash_evp = CryptoHash::getEVP(getHashType());
-CryptoHashType Signer::getCryptoHashType() const {
- parcAssertNotNull(signer_, "Expected non-null signer");
- return static_cast<CryptoHashType>(parcSigner_GetCryptoHashType(signer_));
-}
+ if (hash_evp == nullptr) {
+ throw errors::RuntimeException("Unknown hash type");
+ }
-PARCSigner *Signer::getParcSigner() const { return signer_; }
+ const utils::MemBuf *p = buffer;
+ shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free);
-PARCKeyStore *Signer::getParcKeyStore() const {
- parcAssertNotNull(signer_, "Expected non-null signer");
- return parcSigner_GetKeyStore(signer_);
-}
+ 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");
+ }
-AsymmetricSigner::AsymmetricSigner(CryptoSuite suite, PARCKeyStore *key_store) {
- parcAssertNotNull(key_store, "Expected non-null key_store");
+ p = p->next();
+ } while (p != buffer);
- auto crypto_suite = static_cast<PARCCryptoSuite>(suite);
+ if (EVP_DigestSignFinal(mdctx.get(), nullptr, &signature_len_) != 1) {
+ throw errors::RuntimeException("Digest computation failed");
+ }
+
+ signature_.resize(signature_len_);
- switch (suite) {
- case CryptoSuite::DSA_SHA256:
- case CryptoSuite::RSA_SHA256:
- case CryptoSuite::RSA_SHA512:
- case CryptoSuite::ECDSA_256K1:
- break;
- default:
- throw errors::RuntimeException(
- "Invalid crypto suite for asymmetric signer");
+ if (EVP_DigestSignFinal(mdctx.get(), signature_.data(), &signature_len_) !=
+ 1) {
+ throw errors::RuntimeException("Digest computation failed");
}
- setSigner(
- parcSigner_Create(parcPublicKeySigner_Create(key_store, crypto_suite),
- PARCPublicKeySignerAsSigner));
+ signature_.resize(signature_len_);
}
-SymmetricSigner::SymmetricSigner(CryptoSuite suite, PARCKeyStore *key_store) {
- parcAssertNotNull(key_store, "Expected non-null key_store");
+vector<uint8_t> Signer::getSignature() const { return signature_; }
- auto crypto_suite = static_cast<PARCCryptoSuite>(suite);
+size_t Signer::getSignatureSize() const { return signature_len_; }
- switch (suite) {
- case CryptoSuite::HMAC_SHA256:
- case CryptoSuite::HMAC_SHA512:
- break;
- default:
- throw errors::RuntimeException(
- "Invalid crypto suite for symmetric signer");
+size_t Signer::getSignatureFieldSize() const {
+ if (signature_len_ % 4 == 0) {
+ return signature_len_;
}
- setSigner(parcSigner_Create(parcSymmetricKeySigner_Create(
- (PARCSymmetricKeyStore *)key_store,
- parcCryptoSuite_GetCryptoHash(crypto_suite)),
- PARCSymmetricKeySignerAsSigner));
+ return (signature_len_ + 4) - (signature_len_ % 4);
}
-SymmetricSigner::SymmetricSigner(CryptoSuite suite, const string &passphrase) {
- auto crypto_suite = static_cast<PARCCryptoSuite>(suite);
-
- switch (suite) {
- case CryptoSuite::HMAC_SHA256:
- case CryptoSuite::HMAC_SHA512:
- break;
- default:
- throw errors::RuntimeException(
- "Invalid crypto suite for symmetric signer");
- }
+CryptoHashType Signer::getHashType() const {
+ return ::transport::auth::getHashType(suite_);
+}
+
+CryptoSuite Signer::getSuite() const { return suite_; }
- PARCBufferComposer *composer = parcBufferComposer_Create();
- parcBufferComposer_PutString(composer, passphrase.c_str());
- PARCBuffer *key_buf = parcBufferComposer_ProduceBuffer(composer);
- parcBufferComposer_Release(&composer);
+// ---------------------------------------------------------
+// Void Signer
+// ---------------------------------------------------------
+void VoidSigner::signPacket(PacketPtr packet){};
- PARCSymmetricKeyStore *key_store = parcSymmetricKeyStore_Create(key_buf);
- PARCSymmetricKeySigner *key_signer = parcSymmetricKeySigner_Create(
- key_store, parcCryptoSuite_GetCryptoHash(crypto_suite));
+void VoidSigner::signBuffer(const std::vector<uint8_t> &buffer){};
- setSigner(parcSigner_Create(key_signer, PARCSymmetricKeySignerAsSigner));
+void VoidSigner::signBuffer(const utils::MemBuf *buffer){};
+
+// ---------------------------------------------------------
+// Asymmetric Signer
+// ---------------------------------------------------------
+AsymmetricSigner::AsymmetricSigner(CryptoSuite suite, shared_ptr<EVP_PKEY> key,
+ shared_ptr<EVP_PKEY> pub_key) {
+ suite_ = suite;
+ key_ = key;
+ key_id_ = CryptoHash(getHashType());
+
+ vector<uint8_t> pbk(i2d_PublicKey(pub_key.get(), nullptr));
+ uint8_t *pbk_ptr = pbk.data();
+ int len = i2d_PublicKey(pub_key.get(), &pbk_ptr);
+
+ signature_len_ = EVP_PKEY_size(key.get());
+ signature_.resize(signature_len_);
+ key_id_.computeDigest(pbk_ptr, len);
+}
+
+size_t AsymmetricSigner::getSignatureFieldSize() const {
+ size_t field_size = EVP_PKEY_size(key_.get());
+
+ if (field_size % 4 == 0) {
+ return field_size;
+ }
+
+ return (field_size + 4) - (field_size % 4);
+}
+
+// ---------------------------------------------------------
+// Symmetric Signer
+// ---------------------------------------------------------
+SymmetricSigner::SymmetricSigner(CryptoSuite suite, const string &passphrase) {
+ suite_ = suite;
+ key_ = 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);
+ key_id_ = CryptoHash(getHashType());
+
+ CryptoHashEVP hash_evp = CryptoHash::getEVP(getHashType());
+
+ if (hash_evp == nullptr) {
+ throw errors::RuntimeException("Unknown hash type");
+ }
- parcSymmetricKeySigner_Release(&key_signer);
- parcSymmetricKeyStore_Release(&key_store);
- parcBuffer_Release(&key_buf);
+ signature_len_ = EVP_MD_size((*hash_evp)());
+ signature_.resize(signature_len_);
+ key_id_.computeDigest((uint8_t *)passphrase.c_str(), passphrase.size());
}
} // namespace auth