Exemple #1
0
void Wallet::doLoad(std::istream& source) {
  try
  {
    std::unique_lock<std::mutex> lock(m_cacheMutex);

    boost::archive::binary_iarchive ar(source);

    crypto::chacha8_iv iv;
    std::string chacha_str;;
    ar >> chacha_str;

    ::serialization::parse_binary(chacha_str, iv);

    std::string cipher;
    ar >> cipher;

    std::string plain;
    decrypt(cipher, plain, iv, m_password);

    std::stringstream restore(plain);

    try
    {
      //boost archive ctor throws an exception if password is wrong (i.e. there's garbage in a stream)
      boost::archive::binary_iarchive dataArchive(restore);

      dataArchive >> m_account;

      throwIfKeysMissmatch(m_account.get_keys().m_view_secret_key, m_account.get_keys().m_account_address.m_view_public_key);
      throwIfKeysMissmatch(m_account.get_keys().m_spend_secret_key, m_account.get_keys().m_account_address.m_spend_public_key);

      dataArchive >> m_blockchain;

      m_transferDetails.load(dataArchive);
      m_unconfirmedTransactions.load(dataArchive);
      m_transactionsCache.load(dataArchive);
    }
    catch (std::exception&) {
      throw std::system_error(make_error_code(cryptonote::error::WRONG_PASSWORD));
    }

    m_sender.init(m_account.get_keys());
  }
  catch (std::system_error& e) {
    runAtomic(m_cacheMutex, [this] () {this->m_state = Wallet::NOT_INITIALIZED;} );
    m_observerManager.notify(&IWalletObserver::initCompleted, e.code());
    return;
  }
  catch (std::exception&) {
    runAtomic(m_cacheMutex, [this] () {this->m_state = Wallet::NOT_INITIALIZED;} );
    m_observerManager.notify(&IWalletObserver::initCompleted, make_error_code(cryptonote::error::INTERNAL_WALLET_ERROR));
    return;
  }

  runAtomic(m_cacheMutex, [this] () {this->m_state = Wallet::INITIALIZED;} );

  m_observerManager.notify(&IWalletObserver::initCompleted, std::error_code());

  refresh();
}
void WalletLegacySerializer::deserialize(std::istream& stream, const std::string& password, std::string& cache) {
  StdInputStream stdStream(stream);
  CryptoNote::BinaryInputStreamSerializer serializerEncrypted(stdStream);

  serializerEncrypted.beginObject("wallet");

  uint32_t version;
  serializerEncrypted(version, "version");

  Crypto::chacha_iv iv;
  serializerEncrypted(iv, "iv");

  std::string cipher;
  serializerEncrypted(cipher, "data");

  serializerEncrypted.endObject();

  std::string plain;
  decrypt(cipher, plain, iv, password);

  MemoryInputStream decryptedStream(plain.data(), plain.size()); 
  CryptoNote::BinaryInputStreamSerializer serializer(decryptedStream);

  loadKeys(serializer);
  throwIfKeysMissmatch(account.getAccountKeys().viewSecretKey, account.getAccountKeys().address.viewPublicKey);

  if (account.getAccountKeys().spendSecretKey != NULL_SECRET_KEY) {
    throwIfKeysMissmatch(account.getAccountKeys().spendSecretKey, account.getAccountKeys().address.spendPublicKey);
  } else {
    if (!Crypto::check_key(account.getAccountKeys().address.spendPublicKey)) {
      throw std::system_error(make_error_code(CryptoNote::error::WRONG_PASSWORD));
    }
  }

  bool detailsSaved;

  serializer(detailsSaved, "has_details");

  if (detailsSaved) {
    if (version == 1) {
      transactionsCache.deserializeLegacyV1(serializer);
    } else {
      serializer(transactionsCache, "details");
    }
  }

  serializer.binary(cache, "cache");
}
void WalletSerializer::deserialize(std::istream& stream, const std::string& password, std::string& cache) {
  cryptonote::BinaryInputStreamSerializer serializerEncrypted(stream);

  serializerEncrypted.beginObject("wallet");

  uint32_t version;
  serializerEncrypted(version, "version");

  crypto::chacha8_iv iv;
  serializerEncrypted(iv, "iv");

  std::string cipher;
  serializerEncrypted(cipher, "data");

  serializerEncrypted.endObject();

  std::string plain;
  decrypt(cipher, plain, iv, password);

  std::stringstream decryptedStream(plain);

  cryptonote::BinaryInputStreamSerializer serializer(decryptedStream);

  try
  {
    loadKeys(serializer);
    throwIfKeysMissmatch(account.get_keys().m_view_secret_key, account.get_keys().m_account_address.m_viewPublicKey);
    throwIfKeysMissmatch(account.get_keys().m_spend_secret_key, account.get_keys().m_account_address.m_spendPublicKey);
  }
  catch (std::exception&) {
    throw std::system_error(make_error_code(cryptonote::error::WRONG_PASSWORD));
  }

  bool detailsSaved;

  serializer(detailsSaved, "has_details");

  if (detailsSaved) {
    serializer(transactionsCache, "details");
  }

  serializer.binary(cache, "cache");
}
void WalletSerializer::checkKeys() {
  throwIfKeysMissmatch(m_viewSecretKey, m_viewPublicKey);
}