diff options
Diffstat (limited to 'libtransport/src/auth')
-rw-r--r-- | libtransport/src/auth/CMakeLists.txt | 3 | ||||
-rw-r--r-- | libtransport/src/auth/crypto_hash.cc | 46 | ||||
-rw-r--r-- | libtransport/src/auth/crypto_suite.cc | 50 | ||||
-rw-r--r-- | libtransport/src/auth/identity.cc | 288 | ||||
-rw-r--r-- | libtransport/src/auth/signer.cc | 113 | ||||
-rw-r--r-- | libtransport/src/auth/verifier.cc | 101 |
6 files changed, 193 insertions, 408 deletions
diff --git a/libtransport/src/auth/CMakeLists.txt b/libtransport/src/auth/CMakeLists.txt index 699bc1050..8d3286338 100644 --- a/libtransport/src/auth/CMakeLists.txt +++ b/libtransport/src/auth/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# 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: @@ -14,7 +14,6 @@ list(APPEND SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/signer.cc ${CMAKE_CURRENT_SOURCE_DIR}/verifier.cc - ${CMAKE_CURRENT_SOURCE_DIR}/identity.cc ${CMAKE_CURRENT_SOURCE_DIR}/crypto_hash.cc ${CMAKE_CURRENT_SOURCE_DIR}/crypto_suite.cc ) diff --git a/libtransport/src/auth/crypto_hash.cc b/libtransport/src/auth/crypto_hash.cc index b4b0a8b81..f60f46051 100644 --- a/libtransport/src/auth/crypto_hash.cc +++ b/libtransport/src/auth/crypto_hash.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * 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: @@ -15,8 +15,6 @@ #include <hicn/transport/auth/crypto_hash.h> -using namespace std; - namespace transport { namespace auth { @@ -28,7 +26,7 @@ CryptoHash::CryptoHash(const CryptoHash &other) digest_size_(other.digest_size_) {} CryptoHash::CryptoHash(CryptoHash &&other) - : digest_type_(move(other.digest_type_)), + : digest_type_(std::move(other.digest_type_)), digest_(other.digest_), digest_size_(other.digest_size_) { other.reset(); @@ -43,13 +41,16 @@ CryptoHash::CryptoHash(const uint8_t *hash, size_t size, memcpy(digest_.data(), hash, size); } -CryptoHash::CryptoHash(const vector<uint8_t> &hash, CryptoHashType hash_type) +CryptoHash::CryptoHash(const std::vector<uint8_t> &hash, + CryptoHashType hash_type) : CryptoHash(hash.data(), hash.size(), hash_type) {} CryptoHash &CryptoHash::operator=(const CryptoHash &other) { - digest_type_ = other.digest_type_; - digest_ = other.digest_; - digest_size_ = other.digest_size_; + if (this != &other) { + digest_type_ = other.digest_type_; + digest_ = other.digest_; + digest_size_ = other.digest_size_; + } return *this; } @@ -68,7 +69,7 @@ void CryptoHash::computeDigest(const uint8_t *buffer, size_t len) { (*hash_evp)(), nullptr); } -void CryptoHash::computeDigest(const vector<uint8_t> &buffer) { +void CryptoHash::computeDigest(const std::vector<uint8_t> &buffer) { computeDigest(buffer.data(), buffer.size()); } @@ -102,15 +103,15 @@ void CryptoHash::computeDigest(const utils::MemBuf *buffer) { EVP_MD_CTX_free(mcdtx); } -vector<uint8_t> CryptoHash::getDigest() const { return digest_; } +std::vector<uint8_t> CryptoHash::getDigest() const { return digest_; } -string CryptoHash::getStringDigest() const { - stringstream string_digest; +std::string CryptoHash::getStringDigest() const { + std::stringstream string_digest; - string_digest << hex << setfill('0'); + string_digest << std::hex << std::setfill('0'); for (auto byte : digest_) { - string_digest << hex << setw(2) << static_cast<int>(byte); + string_digest << std::hex << std::setw(2) << static_cast<int>(byte); } return string_digest.str(); @@ -130,23 +131,23 @@ void CryptoHash::setType(CryptoHashType hash_type) { void CryptoHash::display() { switch (digest_type_) { case CryptoHashType::SHA256: - cout << "SHA256"; + std::cout << "SHA256"; break; case CryptoHashType::SHA512: - cout << "SHA512"; + std::cout << "SHA512"; break; case CryptoHashType::BLAKE2S256: - cout << "BLAKE2s256"; + std::cout << "BLAKE2s256"; break; case CryptoHashType::BLAKE2B512: - cout << "BLAKE2b512"; + std::cout << "BLAKE2b512"; break; default: - cout << "UNKNOWN"; + std::cout << "UNKNOWN"; break; } - cout << ": " << getStringDigest() << endl; + std::cout << ": " << getStringDigest() << std::endl; } void CryptoHash::reset() { @@ -159,19 +160,14 @@ CryptoHashEVP CryptoHash::getEVP(CryptoHashType hash_type) { switch (hash_type) { case CryptoHashType::SHA256: return &EVP_sha256; - break; case CryptoHashType::SHA512: return &EVP_sha512; - break; case CryptoHashType::BLAKE2S256: return &EVP_blake2s256; - break; case CryptoHashType::BLAKE2B512: return &EVP_blake2b512; - break; default: return nullptr; - break; } } diff --git a/libtransport/src/auth/crypto_suite.cc b/libtransport/src/auth/crypto_suite.cc index 7e898ef09..44de85212 100644 --- a/libtransport/src/auth/crypto_suite.cc +++ b/libtransport/src/auth/crypto_suite.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * 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: @@ -22,31 +22,61 @@ CryptoSuite getSuite(int nid) { switch (nid) { case NID_ecdsa_with_SHA256: return CryptoSuite::ECDSA_SHA256; - break; case NID_ecdsa_with_SHA512: return CryptoSuite::ECDSA_SHA512; - break; case NID_sha256WithRSAEncryption: return CryptoSuite::RSA_SHA256; - break; case NID_sha512WithRSAEncryption: return CryptoSuite::RSA_SHA512; - break; case NID_hmacWithSHA256: return CryptoSuite::HMAC_SHA256; - break; case NID_hmacWithSHA512: return CryptoSuite::HMAC_SHA512; - break; case NID_dsa_with_SHA256: return CryptoSuite::DSA_SHA256; - break; case NID_dsa_with_SHA512: return CryptoSuite::DSA_SHA512; - break; default: return CryptoSuite::UNKNOWN; - break; + } +} + +std::string getStringSuite(CryptoSuite suite) { + switch (suite) { + case CryptoSuite::ECDSA_BLAKE2B512: + return "ECDSA_BLAKE2B512"; + case CryptoSuite::ECDSA_BLAKE2S256: + return "ECDSA_BLAKE2S256"; + case CryptoSuite::ECDSA_SHA256: + return "ECDSA_SHA256"; + case CryptoSuite::ECDSA_SHA512: + return "ECDSA_SHA512"; + case CryptoSuite::RSA_BLAKE2B512: + return "RSA_BLAKE2B512"; + case CryptoSuite::RSA_BLAKE2S256: + return "RSA_BLAKE2S256"; + case CryptoSuite::RSA_SHA256: + return "RSA_SHA256"; + case CryptoSuite::RSA_SHA512: + return "RSA_SHA512"; + case CryptoSuite::HMAC_BLAKE2B512: + return "HMAC_BLAKE2B512"; + case CryptoSuite::HMAC_BLAKE2S256: + return "HMAC_BLAKE2S256"; + case CryptoSuite::HMAC_SHA256: + return "HMAC_SHA256"; + case CryptoSuite::HMAC_SHA512: + return "HMAC_SHA512"; + case CryptoSuite::DSA_BLAKE2B512: + return "DSA_BLAKE2B512"; + case CryptoSuite::DSA_BLAKE2S256: + return "DSA_BLAKE2S256"; + case CryptoSuite::DSA_SHA256: + return "DSA_SHA256"; + case CryptoSuite::DSA_SHA512: + return "DSA_SHA512"; + default: + return "UNKNOWN"; } } diff --git a/libtransport/src/auth/identity.cc b/libtransport/src/auth/identity.cc deleted file mode 100644 index f56532033..000000000 --- a/libtransport/src/auth/identity.cc +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) 2017-2019 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. - */ - -#include <hicn/transport/auth/identity.h> - -using namespace std; - -// function needed to create the a certificate -static bool _addRandomSerial(X509 *cert) { - unsigned long serial = 0; - unsigned char serial_bytes[sizeof(serial)]; - - // Construct random positive serial number. - RAND_bytes(serial_bytes, sizeof(serial_bytes)); - serial_bytes[0] &= 0x7F; - serial = 0; - for (size_t i = 0; i < sizeof(serial_bytes); i++) { - serial = (256 * serial) + serial_bytes[i]; - } - ASN1_INTEGER_set(X509_get_serialNumber(cert), serial); - return true; -} - -static bool _addValidityPeriod(X509 *cert, size_t validityDays) { - // Set the validity from now for the specified number of days. - X509_gmtime_adj(X509_get_notBefore(cert), (long)0); - X509_gmtime_adj(X509_get_notAfter(cert), (long)(60 * 60 * 24 * validityDays)); - return true; -} - -static bool _addSubjectName(X509 *cert, const char *subjectname) { - // Set up the simple subject name and issuer name for the certificate. - X509_NAME *name = X509_get_subject_name(cert); - - if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, - (unsigned char *)subjectname, -1, -1, 0)) { - if (X509_set_issuer_name(cert, name)) { - return true; - } - } - return false; -} -static bool _addCertificateExtensionWithContext(X509 *cert, int nid, - const char *value) { - X509_EXTENSION *extension; - X509V3_CTX context; - - X509V3_set_ctx_nodb(&context); - X509V3_set_ctx(&context, cert, cert, NULL, NULL, 0); - extension = X509V3_EXT_conf_nid(NULL, &context, nid, value); - if (extension == NULL) { - return false; - } - X509_add_ext(cert, extension, -1); - X509_EXTENSION_free(extension); - return true; -} -static bool _addCertificateExtension(X509 *cert, int nid, const char *value) { - X509_EXTENSION *extension = X509V3_EXT_conf_nid(NULL, NULL, nid, value); - if (extension == NULL) { - return false; - } - X509_add_ext(cert, extension, -1); - X509_EXTENSION_free(extension); - return true; -} - -static bool _addExtensions(X509 *cert) { - // Add the necessary extensions. - if (_addCertificateExtension(cert, NID_basic_constraints, - "critical,CA:FALSE") == true) { - if (_addCertificateExtension( - cert, NID_key_usage, - "digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment," - "keyAgreement") == true) { - if (_addCertificateExtension(cert, NID_ext_key_usage, "clientAuth") == - true) { - return true; - } - } - } - return false; -} -static bool _addKeyIdentifier(X509 *cert) { - unsigned char spkid[SHA256_DIGEST_LENGTH]; - char spkid_hex[1 + 2 * SHA256_DIGEST_LENGTH]; - if (ASN1_item_digest(ASN1_ITEM_rptr(X509_PUBKEY), EVP_sha256(), - X509_get_X509_PUBKEY(cert), spkid, NULL)) { - for (int i = 0; i < 32; i++) { - snprintf(&spkid_hex[2 * i], 3, "%02X", (unsigned)spkid[i]); - } - if (_addCertificateExtension(cert, NID_subject_key_identifier, spkid_hex) == - true) { - if (_addCertificateExtensionWithContext( - cert, NID_authority_key_identifier, "keyid:always") == true) { - return true; - } - } - } - return false; -} - -namespace transport { -namespace auth { - -Identity::Identity(const string &keystore_path, const string &keystore_pwd, - CryptoSuite suite, unsigned int signature_len, - unsigned int validity_days, const string &subject_name) - : cert_(X509_new(), ::X509_free) { - // create the file and complete it. - // first we create the certificate - - // to create the cert we will need a private key - - std::shared_ptr<EVP_PKEY> privateKey(EVP_PKEY_new(), EVP_PKEY_free); - - if (suite == CryptoSuite::RSA_SHA512 || suite == CryptoSuite::RSA_SHA256) { - RSA *rsa = RSA_new(); - BIGNUM *pub_exp; - - pub_exp = BN_new(); - - BN_set_word(pub_exp, RSA_F4); - if (1 != RSA_generate_key_ex(rsa, signature_len, pub_exp, NULL)) - throw errors::RuntimeException("can't generate the key"); - if (1 != EVP_PKEY_set1_RSA(privateKey.get(), rsa)) - throw errors::RuntimeException("can't generate the key"); - } else if (suite == CryptoSuite::ECDSA_SHA256) { - int curve_params; - switch (signature_len) { - case 160u: - curve_params = NID_secp160k1; - break; - case 192u: - curve_params = NID_secp192k1; - break; - case 224u: - curve_params = NID_secp224k1; - break; - case 256u: - curve_params = NID_secp256k1; - break; - default: - curve_params = -1; - break; - } - if (curve_params == -1) - throw errors::RuntimeException("can't generate the key"); - EC_KEY *ec_key = EC_KEY_new_by_curve_name(curve_params); - if (ec_key == NULL) - throw errors::RuntimeException("can't create ecdsa key from curve"); - EC_KEY_set_asn1_flag(ec_key, OPENSSL_EC_NAMED_CURVE); - if (EC_KEY_generate_key(ec_key) == 0) - throw errors::RuntimeException("can't generate the ecdsa key"); - if (EVP_PKEY_set1_EC_KEY(privateKey.get(), ec_key) == 0) - throw errors::RuntimeException("can't generate the ecdsa key"); - } else if (suite == CryptoSuite::DSA_SHA256) { - DSA *dsa = DSA_new(); - unsigned char buffer[32]; - if (RAND_bytes(buffer, sizeof(buffer)) != 1) { - throw errors::RuntimeException("can't generate the key"); - } - if (DSA_generate_parameters_ex(dsa, signature_len, buffer, sizeof(buffer), - NULL, NULL, NULL) != 1) - throw errors::RuntimeException("can't generate the key"); - if (DSA_generate_key(dsa) != 1) - throw errors::RuntimeException("can't generate the key"); - if (EVP_PKEY_set1_DSA(privateKey.get(), dsa) != 1) - throw errors::RuntimeException("can't generate the key"); - } - bool success = true; - success = success && (X509_set_version(cert_.get(), 2) == 1); // 2 => X509v3 - success = success && _addRandomSerial(cert_.get()); - success = success && _addValidityPeriod(cert_.get(), validity_days); - success = success && (X509_set_pubkey(cert_.get(), privateKey.get()) == 1); - success = success && _addSubjectName(cert_.get(), subject_name.c_str()); - success = success && _addExtensions(cert_.get()); - success = - success && (X509_sign(cert_.get(), privateKey.get(), EVP_sha256()) != 0); - success = success && _addKeyIdentifier(cert_.get()); - if (!success) { - throw errors::RuntimeException("error while creating the certificate"); - } - // the certificate is created. We create the pkcs12 object to write the p12 - // file - PKCS12 *p12 = PKCS12_create( - keystore_pwd.c_str(), "ccnxuser", privateKey.get(), cert_.get(), NULL, 0, - 0, 0 /*default iter*/, PKCS12_DEFAULT_ITER /*mac_iter*/, 0); - filename_ = keystore_path; - int fp = open(filename_.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0600); - if (fp == -1) throw errors::RuntimeException("impossible to create the file"); - FILE *fp_f = fdopen(fp, "wb"); - if (fp_f == NULL) - throw errors::RuntimeException("impossible to create the file"); - i2d_PKCS12_fp(fp_f, p12); - fclose(fp_f); - close(fp); - std::shared_ptr<EVP_PKEY> publickey(X509_get_pubkey(cert_.get()), - EVP_PKEY_free); - signer_ = std::shared_ptr<AsymmetricSigner>( - new AsymmetricSigner(suite, privateKey, publickey)); - signer_->signature_len_ = signature_len; -} - -Identity::Identity(string &keystore_path, string &keystore_pwd, - CryptoHashType hash_type) - : cert_(X509_new(), ::X509_free) { - filename_ = keystore_path; - pwd_ = keystore_path; - // get the key and certificate by first opening the keystore file - FILE *p12file = fopen(keystore_path.c_str(), "r"); - if (p12file == NULL) - throw errors::RuntimeException("impossible open keystore"); - PKCS12 *p12 = d2i_PKCS12_fp(p12file, NULL); - EVP_PKEY *privatekey; - EVP_PKEY *publickey; - X509 *cert = cert_.get(); - // now we parse the file to get the first key and certificate - if (1 != PKCS12_parse(p12, keystore_pwd.c_str(), &privatekey, &cert, NULL)) - throw errors::RuntimeException("impossible to get the private key"); - publickey = X509_get_pubkey(cert); - // to have the cryptosuite we use the nid number that is used to identify the - // suite. - CryptoSuite suite = getSuite(X509_get_signature_nid(cert)); - signer_ = std::shared_ptr<AsymmetricSigner>(new AsymmetricSigner( - suite, std::shared_ptr<EVP_PKEY>(privatekey, EVP_PKEY_free), - std::shared_ptr<EVP_PKEY>(publickey, EVP_PKEY_free))); - PKCS12_free(p12); -} - -Identity::Identity(const Identity &other) { - pwd_ = other.pwd_; - filename_ = other.filename_; - signer_ = other.signer_; - cert_ = other.cert_; -} - -Identity::Identity(Identity &&other) { - signer_ = std::move(other.signer_); - other.signer_.reset(); - cert_ = std::move(other.cert_); - other.cert_.reset(); - pwd_ = other.pwd_; - other.pwd_ = ""; - filename_ = other.filename_; - other.filename_ = ""; - signer_ = other.signer_; - other.signer_ = nullptr; -} - -Identity::~Identity() {} - -shared_ptr<AsymmetricSigner> Identity::getSigner() const { return signer_; } - -string Identity::getFilename() const { return filename_; } - -std::shared_ptr<X509> Identity::getCertificate() const { return cert_; } -std::shared_ptr<EVP_PKEY> Identity::getPrivateKey() const { - return signer_->key_; -} - -string Identity::getPassword() const { return pwd_; } - -Identity Identity::generateIdentity(const string &subject_name) { - string keystore_name = "keystore"; - string keystore_password = "password"; - size_t key_length = 1024; - unsigned int validity_days = 30; - CryptoSuite suite = CryptoSuite::RSA_SHA256; - - return Identity(keystore_name, keystore_password, suite, - (unsigned int)key_length, validity_days, subject_name); -} - -} // namespace auth -} // namespace transport diff --git a/libtransport/src/auth/signer.cc b/libtransport/src/auth/signer.cc index 884e850ca..e74e2f1b8 100644 --- a/libtransport/src/auth/signer.cc +++ b/libtransport/src/auth/signer.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 Cisco and/or its affiliates. + * 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: @@ -13,9 +13,9 @@ * limitations under the License. */ +#include <glog/logging.h> #include <hicn/transport/auth/signer.h> - -using namespace std; +#include <hicn/transport/utils/chrono_typedefs.h> namespace transport { namespace auth { @@ -29,31 +29,29 @@ Signer::Signer() Signer::~Signer() {} void Signer::signPacket(PacketPtr packet) { - assert(key_ != nullptr); + DCHECK(key_ != nullptr); core::Packet::Format format = packet->getFormat(); - if (!packet->authenticationHeader()) { + if (!packet->hasAH()) { throw errors::MalformedAHPacketException(); } // Set signature size size_t signature_field_len = getSignatureFieldSize(); - packet->setSignatureSize(signature_field_len); - packet->setSignatureSizeGap(0u); + packet->setSignatureFieldSize(signature_field_len); + packet->updateLength(); // update IP payload length // Copy IP+TCP / ICMP header before zeroing them hicn_header_t header_copy; hicn_packet_copy_header(format, packet->packet_start_, &header_copy, false); // Fill in the hICN AH header - auto now = chrono::duration_cast<chrono::milliseconds>( - chrono::system_clock::now().time_since_epoch()) - .count(); + auto now = utils::SteadyTime::nowMs().count(); packet->setSignatureTimestamp(now); packet->setValidationAlgorithm(suite_); // Set key ID - vector<uint8_t> key_id = key_id_.getDigest(); + std::vector<uint8_t> key_id = key_id_.getDigest(); packet->setKeyId({key_id.data(), key_id.size()}); // Reset fields to compute the packet hash @@ -61,22 +59,22 @@ void Signer::signPacket(PacketPtr packet) { // Compute the signature and put it in the packet signBuffer(packet); - hicn_packet_copy_header(format, &header_copy, packet->packet_start_, false); + packet->setSignature(signature_); + packet->setSignatureSize(signature_len_); - // 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_); + // Restore header + hicn_packet_copy_header(format, &header_copy, packet->packet_start_, false); } void Signer::signBuffer(const std::vector<uint8_t> &buffer) { - assert(key_ != nullptr); + DCHECK(key_ != nullptr); CryptoHashEVP hash_evp = CryptoHash::getEVP(getHashType()); if (hash_evp == nullptr) { throw errors::RuntimeException("Unknown hash type"); } - shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); + std::shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); if (mdctx == nullptr) { throw errors::RuntimeException("Digest context allocation failed"); @@ -106,7 +104,7 @@ void Signer::signBuffer(const std::vector<uint8_t> &buffer) { } void Signer::signBuffer(const utils::MemBuf *buffer) { - assert(key_ != nullptr); + DCHECK(key_ != nullptr); CryptoHashEVP hash_evp = CryptoHash::getEVP(getHashType()); if (hash_evp == nullptr) { @@ -114,7 +112,7 @@ void Signer::signBuffer(const utils::MemBuf *buffer) { } const utils::MemBuf *p = buffer; - shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); + std::shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); if (mdctx == nullptr) { throw errors::RuntimeException("Digest context allocation failed"); @@ -147,7 +145,18 @@ void Signer::signBuffer(const utils::MemBuf *buffer) { signature_.resize(signature_len_); } -vector<uint8_t> Signer::getSignature() const { return signature_; } +std::vector<uint8_t> Signer::getSignature() const { return signature_; } + +std::string Signer::getStringSignature() const { + std::stringstream string_sig; + string_sig << std::hex << std::setfill('0'); + + for (auto byte : signature_) { + string_sig << std::hex << std::setw(2) << static_cast<int>(byte); + } + + return string_sig.str(); +} size_t Signer::getSignatureSize() const { return signature_len_; } @@ -159,36 +168,75 @@ size_t Signer::getSignatureFieldSize() const { return (signature_len_ + 4) - (signature_len_ % 4); } +CryptoSuite Signer::getSuite() const { return suite_; } + CryptoHashType Signer::getHashType() const { return ::transport::auth::getHashType(suite_); } -CryptoSuite Signer::getSuite() const { return suite_; } +void Signer::display() { + std::cout << getStringSuite(suite_) << ": " << getStringSignature() + << std::endl; +} // --------------------------------------------------------- // Void Signer // --------------------------------------------------------- -void VoidSigner::signPacket(PacketPtr packet){}; +void VoidSigner::signPacket(PacketPtr packet) {} -void VoidSigner::signBuffer(const std::vector<uint8_t> &buffer){}; +void VoidSigner::signBuffer(const std::vector<uint8_t> &buffer) {} -void VoidSigner::signBuffer(const utils::MemBuf *buffer){}; +void VoidSigner::signBuffer(const utils::MemBuf *buffer) {} // --------------------------------------------------------- // Asymmetric Signer // --------------------------------------------------------- -AsymmetricSigner::AsymmetricSigner(CryptoSuite suite, shared_ptr<EVP_PKEY> key, - shared_ptr<EVP_PKEY> pub_key) { +AsymmetricSigner::AsymmetricSigner(CryptoSuite suite, + std::shared_ptr<EVP_PKEY> key, + std::shared_ptr<EVP_PKEY> pub_key) { + setKey(suite, key, pub_key); +} + +AsymmetricSigner::AsymmetricSigner(std::string keystore_path, + std::string password) { + FILE *p12file = fopen(keystore_path.c_str(), "r"); + + if (p12file == nullptr) { + throw errors::RuntimeException("failed to read keystore"); + } + + std::unique_ptr<PKCS12, decltype(&PKCS12_free)> p12( + d2i_PKCS12_fp(p12file, nullptr), &PKCS12_free); + X509 *cert_raw; + EVP_PKEY *key_raw; + + if (PKCS12_parse(p12.get(), password.c_str(), &key_raw, &cert_raw, nullptr) != + 1) { + fclose(p12file); + throw errors::RuntimeException("failed to parse keystore"); + } + + std::shared_ptr<EVP_PKEY> key(key_raw, EVP_PKEY_free); + std::shared_ptr<EVP_PKEY> pub_key(X509_get_pubkey(cert_raw), EVP_PKEY_free); + + setKey(transport::auth::getSuite(X509_get_signature_nid(cert_raw)), key, + pub_key); + + fclose(p12file); +} + +void AsymmetricSigner::setKey(CryptoSuite suite, std::shared_ptr<EVP_PKEY> key, + std::shared_ptr<EVP_PKEY> pub_key) { suite_ = suite; key_ = key; - key_id_ = CryptoHash(getHashType()); + signature_len_ = EVP_PKEY_size(key.get()); + signature_.resize(signature_len_); - vector<uint8_t> pbk(i2d_PublicKey(pub_key.get(), nullptr)); + std::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_ = CryptoHash(getHashType()); key_id_.computeDigest(pbk_ptr, len); } @@ -205,9 +253,10 @@ size_t AsymmetricSigner::getSignatureFieldSize() const { // --------------------------------------------------------- // Symmetric Signer // --------------------------------------------------------- -SymmetricSigner::SymmetricSigner(CryptoSuite suite, const string &passphrase) { +SymmetricSigner::SymmetricSigner(CryptoSuite suite, + const std::string &passphrase) { suite_ = suite; - key_ = shared_ptr<EVP_PKEY>( + key_ = std::shared_ptr<EVP_PKEY>( EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, nullptr, (const unsigned char *)passphrase.c_str(), passphrase.size()), diff --git a/libtransport/src/auth/verifier.cc b/libtransport/src/auth/verifier.cc index c9ac1650f..0c35437f3 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 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: @@ -16,12 +16,10 @@ #include <hicn/transport/auth/verifier.h> #include <protocols/errors.h> -using namespace std; - namespace transport { namespace auth { -const vector<VerificationPolicy> Verifier::DEFAULT_FAILED_POLICIES = { +const std::vector<VerificationPolicy> Verifier::DEFAULT_FAILED_POLICIES = { VerificationPolicy::DROP, VerificationPolicy::ABORT, }; @@ -38,24 +36,21 @@ 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 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); // Retrieve packet signature - uint8_t *packet_signature = packet->getSignature(); - vector<uint8_t> signature_raw(packet_signature, - packet_signature + signature_len); + std::vector<uint8_t> signature_raw = packet->getSignature(); + signature_raw.resize(packet->getSignatureSize()); // Reset fields that are not used to compute signature packet->resetForHash(); @@ -66,12 +61,14 @@ bool Verifier::verifyPacket(PacketPtr packet) { // Restore header hicn_packet_copy_header(format, &header_copy, packet->packet_start_, false); - packet->setSignatureSizeGap(packet->getSignatureSize() - signature_len); + packet->setSignature(signature_raw); + packet->setSignatureSize(signature_raw.size()); 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 +79,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 +102,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 +128,8 @@ Verifier::PolicyMap Verifier::verifyPackets(const vector<PacketPtr> &packets, } } + callVerificationFailedCallback(suffix, policy); policies[suffix] = policy; - callVerificationFailedCallback(packet, policy); } return policies; @@ -139,7 +137,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 +147,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 +155,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,71 +164,75 @@ 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, +bool VoidVerifier::verifyBuffer(const std::vector<uint8_t> &buffer, + const std::vector<uint8_t> &signature, CryptoHashType hash_type) { return true; } bool VoidVerifier::verifyBuffer(const utils::MemBuf *buffer, - const vector<uint8_t> &signature, + const std::vector<uint8_t> &signature, CryptoHashType hash_type) { 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, +bool AsymmetricVerifier::verifyBuffer(const std::vector<uint8_t> &buffer, + const std::vector<uint8_t> &signature, CryptoHashType hash_type) { CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type); @@ -241,7 +240,7 @@ bool AsymmetricVerifier::verifyBuffer(const vector<uint8_t> &buffer, throw errors::RuntimeException("Unknown hash type"); } - shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); + std::shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); if (mdctx == nullptr) { throw errors::RuntimeException("Digest context allocation failed"); @@ -261,7 +260,7 @@ bool AsymmetricVerifier::verifyBuffer(const vector<uint8_t> &buffer, } bool AsymmetricVerifier::verifyBuffer(const utils::MemBuf *buffer, - const vector<uint8_t> &signature, + const std::vector<uint8_t> &signature, CryptoHashType hash_type) { CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type); @@ -270,7 +269,7 @@ bool AsymmetricVerifier::verifyBuffer(const utils::MemBuf *buffer, } const utils::MemBuf *p = buffer; - shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); + std::shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); if (mdctx == nullptr) { throw errors::RuntimeException("Digest context allocation failed"); @@ -296,21 +295,21 @@ bool AsymmetricVerifier::verifyBuffer(const utils::MemBuf *buffer, // --------------------------------------------------------- // 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, +bool SymmetricVerifier::verifyBuffer(const std::vector<uint8_t> &buffer, + const std::vector<uint8_t> &signature, CryptoHashType hash_type) { CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type); @@ -318,9 +317,9 @@ bool SymmetricVerifier::verifyBuffer(const vector<uint8_t> &buffer, throw errors::RuntimeException("Unknown hash type"); } - vector<uint8_t> signature_bis(signature.size()); + std::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); + std::shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); if (mdctx == nullptr) { throw errors::RuntimeException("Digest context allocation failed"); @@ -344,7 +343,7 @@ bool SymmetricVerifier::verifyBuffer(const vector<uint8_t> &buffer, } bool SymmetricVerifier::verifyBuffer(const utils::MemBuf *buffer, - const vector<uint8_t> &signature, + const std::vector<uint8_t> &signature, CryptoHashType hash_type) { CryptoHashEVP hash_evp = CryptoHash::getEVP(hash_type); @@ -353,9 +352,9 @@ bool SymmetricVerifier::verifyBuffer(const utils::MemBuf *buffer, } const utils::MemBuf *p = buffer; - vector<uint8_t> signature_bis(signature.size()); + std::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); + std::shared_ptr<EVP_MD_CTX> mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_free); if (mdctx == nullptr) { throw errors::RuntimeException("Digest context allocation failed"); |