From bac3da61644515f05663789b122554dc77549286 Mon Sep 17 00:00:00 2001 From: Luca Muscariello Date: Thu, 17 Jan 2019 13:47:57 +0100 Subject: This is the first commit of the hicn project Change-Id: I6f2544ad9b9f8891c88cc4bcce3cf19bd3cc863f Signed-off-by: Luca Muscariello --- libtransport/src/hicn/transport/utils/signer.cc | 173 ++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100755 libtransport/src/hicn/transport/utils/signer.cc (limited to 'libtransport/src/hicn/transport/utils/signer.cc') diff --git a/libtransport/src/hicn/transport/utils/signer.cc b/libtransport/src/hicn/transport/utils/signer.cc new file mode 100755 index 000000000..c11d5e183 --- /dev/null +++ b/libtransport/src/hicn/transport/utils/signer.cc @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright 2017 Facebook, Inc. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + + +extern "C" { +TRANSPORT_CLANG_DISABLE_WARNING("-Wextern-c-compat") +#include +#include +#include +#include +} + +#include + +#define ALLOW_UNALIGNED_READS 1 + +namespace utils { + +uint8_t Signer::zeros[200] = {0}; + +/*One signer_ per Private Key*/ +Signer::Signer(PARCKeyStore *keyStore, PARCCryptoSuite suite) { + switch (suite) { + case PARCCryptoSuite_NULL_CRC32C: + break; + case PARCCryptoSuite_ECDSA_SHA256: + case PARCCryptoSuite_RSA_SHA256: + case PARCCryptoSuite_DSA_SHA256: + case PARCCryptoSuite_RSA_SHA512: + this->signer_ = + parcSigner_Create(parcPublicKeySigner_Create(keyStore, suite), + PARCPublicKeySignerAsSigner); + this->key_id_ = parcSigner_CreateKeyId(this->signer_); + break; + + case PARCCryptoSuite_HMAC_SHA512: + case PARCCryptoSuite_HMAC_SHA256: + default: + this->signer_ = parcSigner_Create( + parcSymmetricKeySigner_Create((PARCSymmetricKeyStore *)keyStore, + parcCryptoSuite_GetCryptoHash(suite)), + PARCSymmetricKeySignerAsSigner); + this->key_id_ = parcSigner_CreateKeyId(this->signer_); + break; + } +} + +Signer::Signer(const PARCSigner *signer) + : signer_(parcSigner_Acquire(signer)), + key_id_(parcSigner_CreateKeyId(this->signer_)) {} + +Signer::~Signer() { + parcSigner_Release(&signer_); + parcKeyId_Release(&key_id_); +} + +void Signer::sign(Packet &packet) { + // header chain points to the IP + TCP hicn header + utils::MemBuf *header_chain = packet.header_head_; + utils::MemBuf * payload_chain = packet.payload_head_; + uint8_t *hicn_packet = header_chain->writableData(); + Packet::Format format = packet.getFormat(); + std::size_t sign_len_bytes = parcSigner_GetSignatureSize(signer_); + + if (!(format & HFO_AH)) { + throw errors::MalformedAHPacketException(); + } + + // Copy IP+TCP/ICMP header before zeroing them + hicn_header_t header_copy; + if (format & HFO_INET) { + memcpy(&header_copy, hicn_packet, sizeof(hicn_v4_hdr_t)); + } else if (format & HFO_INET6) { + memcpy(&header_copy, hicn_packet, sizeof(hicn_v6_hdr_t)); + } + + std::size_t header_len = Packet::getHeaderSizeFromFormat(format); + + packet.resetForHash(); + packet.setSignatureSize(sign_len_bytes); + + /* Fill the hicn_ah header */ + using namespace std::chrono; + auto now = duration_cast(system_clock::now().time_since_epoch()).count(); + packet.setSignatureTimestamp(now); + // *reinterpret_cast(ah->signTime) = utils::hton(now); + // // std::memcpy(&ah->hicn_ah.signTime, &sign_time, sizeof(ah->hicn_ah.signTime)); + + packet.setValidationAlgorithm(CryptoSuite(parcSigner_GetCryptoSuite(this->signer_))); + // ah->validationAlgorithm = parcSigner_GetCryptoSuite(this->signer_); + + KeyId key_id; + key_id.first = (uint8_t *)parcBuffer_Overlay((PARCBuffer *) parcKeyId_GetKeyId(this->key_id_), 0); + packet.setKeyId(key_id); + + // memcpy(ah->keyId, + // parcBuffer_Overlay((PARCBuffer *) parcKeyId_GetKeyId(this->key_id_), 0), + // sizeof(_ah_header_t::keyId)); + + // Calculate hash + utils::CryptoHasher hasher(parcSigner_GetCryptoHasher(signer_)); + hasher.init(); + hasher.updateBytes(hicn_packet, header_len); + hasher.updateBytes(zeros, sign_len_bytes); + + for (utils::MemBuf *current = payload_chain; current != header_chain; current = current->next()) { + hasher.updateBytes(current->data(), current->length()); + } + + utils::CryptoHash hash = hasher.finalize(); + + PARCSignature *signature = parcSigner_SignDigest(this->signer_, hash.hash_); + PARCBuffer *buffer = parcSignature_GetSignature(signature); + + PARCByteArray * byte_array = parcBuffer_Array(buffer); + uint8_t * bytes = parcByteArray_Array(byte_array); + size_t bytes_len = parcBuffer_Remaining(buffer); + + if (bytes_len > sign_len_bytes) { + throw errors::MalformedAHPacketException(); + } + + /* Restore the resetted fields */ + if (format & HFO_INET) { + memcpy(hicn_packet, &header_copy, sizeof(hicn_v4_hdr_t)); + } else if (format & HFO_INET6) { + memcpy(hicn_packet, &header_copy, sizeof(hicn_v6_hdr_t)); + } + + int offset = sign_len_bytes - bytes_len; + + std::unique_ptr signature_buffer; + std::unique_ptr tmp_buf = utils::MemBuf::takeOwnership( + bytes, + bytes_len, + bytes_len, + [](void* buf, void* userData){ parcSignature_Release((PARCSignature **)&userData); }, + signature, + true); + + if (offset) { + signature_buffer = utils::MemBuf::create(offset); + memset(signature_buffer->writableData(), 0, offset); + signature_buffer->append(offset); + signature_buffer->appendChain(std::move(tmp_buf)); + } else { + signature_buffer = std::move(tmp_buf); + } + + packet.setSignature(std::move(signature_buffer)); +} + +} // namespace utils -- cgit 1.2.3-korg