LCOV - code coverage report
Current view: top level - libs/crypto - keys_manager_impl.cpp (source / functions) Hit Total Coverage
Test: coverage_cleared.info Lines: 61 63 96.8 %
Date: 2018-12-05 17:11:35 Functions: 17 18 94.4 %

          Line data    Source code
       1             : /**
       2             :  * Copyright Soramitsu Co., Ltd. All Rights Reserved.
       3             :  * SPDX-License-Identifier: Apache-2.0
       4             :  */
       5             : 
       6             : #include "crypto/keys_manager_impl.hpp"
       7             : 
       8             : #include <fstream>
       9             : 
      10             : #include "common/byteutils.hpp"
      11             : #include "cryptography/crypto_provider/crypto_defaults.hpp"
      12             : 
      13             : using namespace shared_model::crypto;
      14             : 
      15             : using iroha::operator|;
      16             : 
      17             : namespace iroha {
      18             :   /**
      19             :    * Function for the key encryption via XOR
      20             :    * @tparam is a key type
      21             :    * @param privkey is a private key
      22             :    * @param pass_phrase is a key for encryption
      23             :    * @return encrypted string
      24             :    */
      25             :   template <typename T>
      26             :   static std::string encrypt(const T &key, const std::string &pass_phrase) {
      27          18 :     std::string ciphertext(key.size(), '\0');
      28          18 :     const size_t min_pass_size = 1;
      29             :     // pass_size will always be > 0
      30          18 :     const auto pass_size = std::max(min_pass_size, pass_phrase.size());
      31             :     // When pass_phrase is empty it, pass_phrase[0] is "\0", so no out_of_range
      32             :     // exception is possible
      33         562 :     for (size_t i = 0; i < key.size(); i++) {
      34         544 :       ciphertext[i] = key[i] ^ pass_phrase[i % pass_size];
      35         544 :     }
      36          18 :     return ciphertext;
      37          18 :   }
      38             : 
      39             :   /**
      40             :    * Function for XOR decryption
      41             :    */
      42             :   static constexpr auto decrypt = encrypt<Blob::Bytes>;
      43             : 
      44             :   KeysManagerImpl::KeysManagerImpl(
      45             :       const std::string &account_id,
      46             :       const boost::filesystem::path &path_to_keypair)
      47          18 :       : path_to_keypair_(path_to_keypair),
      48          18 :         account_id_(account_id),
      49          18 :         log_(logger::log("KeysManagerImpl")) {}
      50             : 
      51             :   /**
      52             :    * Here we use an empty string as a default value of path to file,
      53             :    * since there are usages of KeysManagerImpl with path passed as a part of
      54             :    * account_id.
      55             :    */
      56             :   KeysManagerImpl::KeysManagerImpl(const std::string account_id)
      57          13 :       : KeysManagerImpl(account_id, "") {}
      58             : 
      59             :   bool KeysManagerImpl::validate(const Keypair &keypair) const {
      60             :     try {
      61          13 :       auto test = Blob("12345");
      62          13 :       auto sig = DefaultCryptoAlgorithmType::sign(test, keypair);
      63          11 :       if (not DefaultCryptoAlgorithmType::verify(
      64          11 :               sig, test, keypair.publicKey())) {
      65           3 :         log_->error("key validation failed");
      66           3 :         return false;
      67             :       }
      68          19 :     } catch (const BadFormatException &exception) {
      69           2 :       log_->error("Cannot validate keyapir: {}", exception.what());
      70           2 :       return false;
      71           2 :     }
      72           8 :     return true;
      73          13 :   }
      74             : 
      75             :   boost::optional<std::string> KeysManagerImpl::loadFile(
      76             :       const boost::filesystem::path &path) const {
      77          32 :     auto file_path = path.string();
      78          32 :     std::ifstream file(file_path);
      79          32 :     if (not file) {
      80           4 :       log_->error("Cannot read '" + file_path + "'");
      81           4 :       return {};
      82             :     }
      83             : 
      84          28 :     std::string contents;
      85          28 :     file >> contents;
      86          28 :     return contents;
      87          32 :   }
      88             : 
      89             :   boost::optional<Keypair> KeysManagerImpl::loadKeys() {
      90          13 :     return loadKeys("");
      91           0 :   }
      92             : 
      93             :   boost::optional<Keypair> KeysManagerImpl::loadKeys(
      94             :       const std::string &pass_phrase) {
      95             :     auto public_key =
      96          16 :         loadFile(path_to_keypair_ / (account_id_ + kPublicKeyExtension));
      97             :     auto private_key =
      98          16 :         loadFile(path_to_keypair_ / (account_id_ + kPrivateKeyExtension));
      99             : 
     100          16 :     if (not public_key or not private_key) {
     101           3 :       return boost::none;
     102             :     }
     103             : 
     104          13 :     Keypair keypair = Keypair(
     105          13 :         PublicKey(Blob::fromHexString(public_key.get())),
     106          13 :         PrivateKey(decrypt(Blob::fromHexString(private_key.get()).blob(),
     107          13 :                            pass_phrase)));
     108             : 
     109          13 :     return validate(keypair) ? boost::make_optional(keypair) : boost::none;
     110          16 :   }
     111             : 
     112             :   bool KeysManagerImpl::createKeys() {
     113           1 :     return createKeys("");
     114           0 :   }
     115             : 
     116             :   bool KeysManagerImpl::createKeys(const std::string &pass_phrase) {
     117           5 :     Keypair keypair = DefaultCryptoAlgorithmType::generateKeypair();
     118             : 
     119           5 :     auto pub = keypair.publicKey().hex();
     120           5 :     auto priv = bytestringToHexstring(
     121           5 :         encrypt(keypair.privateKey().blob(), pass_phrase));
     122           5 :     return store(pub, priv);
     123           5 :   }
     124             : 
     125             :   bool KeysManagerImpl::store(const std::string &pub, const std::string &priv) {
     126           5 :     std::ofstream pub_file(
     127           5 :         (path_to_keypair_ / (account_id_ + kPublicKeyExtension)).string());
     128           5 :     std::ofstream priv_file(
     129           5 :         (path_to_keypair_ / (account_id_ + kPrivateKeyExtension)).string());
     130           5 :     if (not pub_file or not priv_file) {
     131           1 :       return false;
     132             :     }
     133             : 
     134           4 :     pub_file << pub;
     135           4 :     priv_file << priv;
     136           4 :     return pub_file.good() && priv_file.good();
     137           5 :   }
     138             : 
     139             :   const std::string KeysManagerImpl::kPublicKeyExtension = ".pub";
     140             :   const std::string KeysManagerImpl::kPrivateKeyExtension = ".priv";
     141             : }  // namespace iroha

Generated by: LCOV version 1.13