diff options
Diffstat (limited to 'libtransport/includes/hicn/transport/auth')
8 files changed, 584 insertions, 0 deletions
diff --git a/libtransport/includes/hicn/transport/auth/CMakeLists.txt b/libtransport/includes/hicn/transport/auth/CMakeLists.txt new file mode 100644 index 000000000..0b5ae1836 --- /dev/null +++ b/libtransport/includes/hicn/transport/auth/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright (c) 2021 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: +# +# 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. + +list(APPEND HEADER_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/common.h + ${CMAKE_CURRENT_SOURCE_DIR}/crypto_hash.h + ${CMAKE_CURRENT_SOURCE_DIR}/crypto_suite.h + ${CMAKE_CURRENT_SOURCE_DIR}/key_id.h + ${CMAKE_CURRENT_SOURCE_DIR}/policies.h + ${CMAKE_CURRENT_SOURCE_DIR}/signer.h + ${CMAKE_CURRENT_SOURCE_DIR}/verifier.h +) + +set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) diff --git a/libtransport/includes/hicn/transport/auth/common.h b/libtransport/includes/hicn/transport/auth/common.h new file mode 100644 index 000000000..d2282436e --- /dev/null +++ b/libtransport/includes/hicn/transport/auth/common.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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: + * + * 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. + */ + +#pragma once + +#include <hicn/transport/core/packet.h> + +namespace transport { +namespace auth { + +using PacketPtr = core::Packet *; +using Suffix = uint32_t; + +} // namespace auth +} // namespace transport diff --git a/libtransport/includes/hicn/transport/auth/crypto_hash.h b/libtransport/includes/hicn/transport/auth/crypto_hash.h new file mode 100644 index 000000000..9535e07c7 --- /dev/null +++ b/libtransport/includes/hicn/transport/auth/crypto_hash.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 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: + * + * 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. + */ + +#pragma once + +#include <hicn/transport/errors/runtime_exception.h> +#include <hicn/transport/utils/membuf.h> + +#include <iomanip> + +extern "C" { +#include <openssl/evp.h> +} + +namespace transport { +namespace auth { + +enum class CryptoHashType : uint8_t { + UNKNOWN, + SHA256, + SHA512, + BLAKE2B512, + BLAKE2S256, +}; + +class CryptoHash { + public: + // Constructors + CryptoHash(); + CryptoHash(const CryptoHash &other); + CryptoHash(CryptoHash &&other) noexcept; + CryptoHash(CryptoHashType hash_type); + CryptoHash(const uint8_t *hash, std::size_t size, CryptoHashType hash_type); + CryptoHash(const std::vector<uint8_t> &hash, CryptoHashType hash_type); + + // Destructor + ~CryptoHash() = default; + + // Operators + CryptoHash &operator=(const CryptoHash &other); + bool operator==(const CryptoHash &other) const; + + // Compute the hash of given buffer + void computeDigest(const uint8_t *buffer, std::size_t len); + void computeDigest(const std::vector<uint8_t> &buffer); + void computeDigest(const utils::MemBuf *buffer); + + // Return the computed hash + const utils::MemBuf::Ptr &getDigest() const; + + // Return the computed hash as a string + std::string getStringDigest() const; + + // Return hash type + CryptoHashType getType() const; + + // Return hash size + std::size_t getSize() const; + + // Change hash type + void setType(CryptoHashType hash_type); + + // Print hash to stdout + void display(); + + // Reset hash + void reset(); + + // 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); + + // Compare two raw buffers + static bool compareDigest(const uint8_t *digest1, const uint8_t *digest2, + CryptoHashType hash_type); + + private: + CryptoHashType digest_type_; + utils::MemBuf::Ptr digest_; + std::size_t digest_size_; +}; + +} // namespace auth +} // namespace transport diff --git a/libtransport/includes/hicn/transport/auth/crypto_suite.h b/libtransport/includes/hicn/transport/auth/crypto_suite.h new file mode 100644 index 000000000..f3b535264 --- /dev/null +++ b/libtransport/includes/hicn/transport/auth/crypto_suite.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 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: + * + * 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. + */ + +#pragma once + +#include <hicn/transport/auth/crypto_hash.h> + +extern "C" { +#include <openssl/obj_mac.h> +} + +namespace transport { +namespace auth { + +enum class CryptoSuite : uint8_t { + UNKNOWN, + DSA_BLAKE2B512, + DSA_BLAKE2S256, + DSA_SHA256, + DSA_SHA512, + ECDSA_BLAKE2B512, + ECDSA_BLAKE2S256, + ECDSA_SHA256, + ECDSA_SHA512, + ED25519, + ED448, + HMAC_BLAKE2B512, + HMAC_BLAKE2S256, + HMAC_SHA256, + HMAC_SHA512, + RSA_BLAKE2B512, + RSA_BLAKE2S256, + RSA_SHA256, + RSA_SHA512, +}; + +// Return the suite associated to the given NID +CryptoSuite getSuite(int nid); + +// Return the string representation of given suite +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/key_id.h b/libtransport/includes/hicn/transport/auth/key_id.h new file mode 100644 index 000000000..8723ae698 --- /dev/null +++ b/libtransport/includes/hicn/transport/auth/key_id.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 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: + * + * 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. + */ + +#pragma once + +#include <cstdint> +#include <utility> + +namespace transport { +namespace auth { + +using KeyId = std::pair<uint8_t *, uint8_t>; + +} // namespace auth +} // namespace transport diff --git a/libtransport/includes/hicn/transport/auth/policies.h b/libtransport/includes/hicn/transport/auth/policies.h new file mode 100644 index 000000000..b9755595c --- /dev/null +++ b/libtransport/includes/hicn/transport/auth/policies.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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: + * + * 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. + */ + +#pragma once + +namespace transport { +namespace auth { + +/** + * These policies allows the verifier to tell the transport what action to + * perform after verification. + */ +enum class VerificationPolicy { + UNKNOWN, + ABORT, + DROP, + ACCEPT, +}; + +} // namespace auth +} // namespace transport diff --git a/libtransport/includes/hicn/transport/auth/signer.h b/libtransport/includes/hicn/transport/auth/signer.h new file mode 100644 index 000000000..f9e07efae --- /dev/null +++ b/libtransport/includes/hicn/transport/auth/signer.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021 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: + * + * 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. + */ + +#pragma once + +#include <hicn/transport/auth/common.h> +#include <hicn/transport/auth/crypto_hash.h> +#include <hicn/transport/auth/crypto_suite.h> +#include <hicn/transport/errors/errors.h> +#include <hicn/transport/utils/membuf.h> + +#include <memory> +extern "C" { +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/pkcs12.h> +#include <openssl/x509.h> +} + +namespace transport { +namespace auth { + +class Signer { + // The base class from which all signer classes derive. + + public: + Signer(); + + virtual ~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<uint8_t> &buffer); + virtual void signBuffer(const utils::MemBuf *buffer); + + // Return the signature. + const utils::MemBuf::Ptr &getSignature() const; + + // Return the signature as a string. + std::string getStringSignature() const; + + // Return the signature size in bytes. + virtual std::size_t getSignatureSize() const; + + // Return the field size necessary to hold the signature. The field size is + // always a multiple of 4. Use this function when allocating the signature + // packet header. + virtual std::size_t getSignatureFieldSize() const; + + // Return the crypto suite associated to the signer. + CryptoSuite getSuite() const; + + // Return the hash algorithm associated to the signer. + CryptoHashType getHashType() const; + + // Print signature to stdout. + void display(); + + protected: + CryptoSuite suite_; + utils::MemBuf::Ptr signature_; + std::size_t signature_len_; + std::shared_ptr<EVP_PKEY> key_; + CryptoHash key_id_; +}; + +class VoidSigner : public Signer { + // This class is the default socket signer. It does not sign packet. + public: + VoidSigner() = default; + + void signPacket(PacketPtr packet) override; + void signBuffer(const uint8_t *buffer, std::size_t len) override; + void signBuffer(const std::vector<uint8_t> &buffer) override; + void signBuffer(const utils::MemBuf *buffer) override; +}; + +class AsymmetricSigner : public Signer { + // This class uses asymmetric verification to sign packets. + public: + AsymmetricSigner() = default; + + // Create an AsymmetricSigner from a keystore file (.p12). + AsymmetricSigner(std::string keystore_path, std::string password); + + // Construct an AsymmetricSigner from a key store and a given crypto + // suite. + AsymmetricSigner(CryptoSuite suite, std::shared_ptr<EVP_PKEY> key, + std::shared_ptr<EVP_PKEY> pub_key); + + void setKey(CryptoSuite suite, std::shared_ptr<EVP_PKEY> key, + std::shared_ptr<EVP_PKEY> pub_key); + + std::size_t getSignatureFieldSize() const override; +}; + +class SymmetricSigner : public Signer { + // This class uses symmetric verification to sign packets. The symmetric + // key is derived from a passphrase. + public: + SymmetricSigner() = default; + + // Construct a SymmetricSigner from a passphrase and a given crypto suite. + SymmetricSigner(CryptoSuite suite, const std::string &passphrase); +}; + +} // namespace auth +} // namespace transport diff --git a/libtransport/includes/hicn/transport/auth/verifier.h b/libtransport/includes/hicn/transport/auth/verifier.h new file mode 100644 index 000000000..2e086df4f --- /dev/null +++ b/libtransport/includes/hicn/transport/auth/verifier.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2021 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: + * + * 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. + */ + +#pragma once + +#include <hicn/transport/auth/common.h> +#include <hicn/transport/auth/policies.h> +#include <hicn/transport/core/content_object.h> +#include <hicn/transport/errors/errors.h> +#include <hicn/transport/interfaces/callbacks.h> + +extern "C" { +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/pem.h> +#include <openssl/x509.h> +} + +namespace transport { +namespace auth { + +class Verifier { + // The base Verifier class. + public: + using SuffixMap = std::unordered_map<Suffix, CryptoHash>; + using PolicyMap = std::unordered_map<Suffix, VerificationPolicy>; + + // The VerificationFailedCallback will be called by the transport if a + // data packet (either a manifest or a content object) was not validated. + // The application decides what to do then by returning a + // new VerificationPolicy. + using VerificationFailedCallback = std::function<auth::VerificationPolicy( + Suffix suffix, VerificationPolicy policy)>; + + // The list of VerificationPolicy that will trigger the + // VerificationFailedCallback. + static const std::vector<VerificationPolicy> DEFAULT_FAILED_POLICIES; + + Verifier(); + + virtual ~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<uint8_t> &buffer, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) = 0; + virtual bool verifyBuffer(const utils::MemBuf *buffer, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) = 0; + + // Verify a batch of packets. Return a mapping from packet suffixes to their + // VerificationPolicy. + virtual PolicyMap verifyPackets(const std::vector<PacketPtr> &packets); + VerificationPolicy verifyPackets(PacketPtr packet) { + return verifyPackets(std::vector<PacketPtr>{packet}) + .at(packet->getName().getSuffix()); + } + + // Verify that a set of packet hashes are present in another set of hashes + // that was extracted from manifests. Return a mapping from packet suffixes to + // their VerificationPolicy. + virtual PolicyMap verifyHashes(const SuffixMap &packet_map, + const SuffixMap &suffix_map); + + // Verify that a batch of packets are valid using a map from packet suffixes + // to hashes. A packet is considered valid if its hash is present in the map. + // Return a mapping from packet suffixes to their VerificationPolicy. + virtual PolicyMap verifyPackets(const std::vector<PacketPtr> &packets, + const SuffixMap &suffix_map); + VerificationPolicy verifyPackets(PacketPtr packet, + const SuffixMap &suffix_map) { + return verifyPackets(std::vector<PacketPtr>{packet}, suffix_map) + .at(packet->getName().getSuffix()); + } + + // Set the callback called when packet verification fails. + void setVerificationFailedCallback( + VerificationFailedCallback verification_failed_cb, + const std::vector<VerificationPolicy> &failed_policies = + DEFAULT_FAILED_POLICIES); + + // Retrieve the VerificationFailedCallback function. + void getVerificationFailedCallback( + VerificationFailedCallback **verification_failed_cb); + + // Call VerificationFailedCallback if it is set and update the packet policy. + void callVerificationFailedCallback(Suffix suffix, + VerificationPolicy &policy); + + protected: + VerificationFailedCallback verification_failed_cb_; + std::vector<VerificationPolicy> failed_policies_; +}; + +class VoidVerifier : public Verifier { + // This class is the default socket verifier. It ignores any packet signature + // 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<uint8_t> &buffer, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) override; + bool verifyBuffer(const utils::MemBuf *buffer, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) override; + + PolicyMap verifyPackets(const std::vector<PacketPtr> &packets) override; + + PolicyMap verifyPackets(const std::vector<PacketPtr> &packets, + const SuffixMap &suffix_map) override; +}; + +class AsymmetricVerifier : public Verifier { + // This class uses asymmetric verification to validate packets. The public key + // can be directly set or extracted from a certificate. + public: + AsymmetricVerifier() = default; + + // Construct an AsymmetricVerifier from an asymmetric key. + AsymmetricVerifier(std::shared_ptr<EVP_PKEY> key); + + // Construct an AsymmetricVerifier from a certificate file. + AsymmetricVerifier(const std::string &cert_path); + AsymmetricVerifier(std::shared_ptr<X509> cert); + + // Set the asymmetric key. + void setKey(std::shared_ptr<EVP_PKEY> key); + + // Extract the public key from a certificate. + void useCertificate(const std::string &cert_path); + void useCertificate(std::shared_ptr<X509> cert); + + bool verifyBuffer(const uint8_t *buffer, std::size_t len, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) override; + bool verifyBuffer(const std::vector<uint8_t> &buffer, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) override; + bool verifyBuffer(const utils::MemBuf *buffer, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) override; + + private: + std::shared_ptr<EVP_PKEY> key_; +}; + +class SymmetricVerifier : public Verifier { + // This class uses symmetric verification to validate packets. The symmetric + // key is derived from a passphrase. + public: + SymmetricVerifier() = default; + + // Construct a SymmetricVerifier from a passphrase. + SymmetricVerifier(const std::string &passphrase); + + // 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<uint8_t> &buffer, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) override; + bool verifyBuffer(const utils::MemBuf *buffer, + const utils::MemBuf::Ptr &signature, + CryptoSuite suite) override; + + protected: + std::shared_ptr<EVP_PKEY> key_; +}; + +} // namespace auth +} // namespace transport |