bridged__validate_components_for_login, and fixed up some ref passing

pull/29/head
Paul Shapiro 6 years ago
parent 4aaef3ddd9
commit 45b2d42366

@ -92,7 +92,7 @@ bool monero_wallet_utils::bytes_to_words(
} }
// //
bool monero_wallet_utils::new_wallet( bool monero_wallet_utils::new_wallet(
std::string mnemonic_language, const string &mnemonic_language,
WalletDescriptionRetVals &retVals, WalletDescriptionRetVals &retVals,
cryptonote::network_type nettype cryptonote::network_type nettype
) { ) {
@ -133,8 +133,8 @@ const uint32_t stable_32B_seed_mnemonic_word_count = 25;
const uint32_t legacy_16B_seed_mnemonic_word_count = 13; const uint32_t legacy_16B_seed_mnemonic_word_count = 13;
bool monero_wallet_utils::decoded_seed( bool monero_wallet_utils::decoded_seed(
std::string mnemonic_string, string mnemonic_string,
std::string mnemonic_language, string mnemonic_language,
MnemonicDecodedSeed_RetVals &retVals MnemonicDecodedSeed_RetVals &retVals
) { ) {
retVals = {}; retVals = {};
@ -235,8 +235,8 @@ SeedDecodedMnemonic_RetVals monero_wallet_utils::mnemonic_string_from_seed_hex_s
} }
// //
bool monero_wallet_utils::wallet_with( bool monero_wallet_utils::wallet_with(
std::string mnemonic_string, const string &mnemonic_string,
std::string mnemonic_language, const string &mnemonic_language,
WalletDescriptionRetVals &retVals, WalletDescriptionRetVals &retVals,
cryptonote::network_type nettype cryptonote::network_type nettype
) { ) {
@ -272,34 +272,37 @@ bool monero_wallet_utils::wallet_with(
return true; return true;
} }
bool monero_wallet_utils::validate_wallet_components_with( bool monero_wallet_utils::validate_wallet_components_with( // returns !did_error
const WalletComponentsToValidate &inputs, const string &address_string,
WalletComponentsValidationResults &outputs const string &sec_viewKey_string,
) optional<string> sec_spendKey_string,
{ // TODO: how can the err_strings be prepared for localization? optional<string> sec_seed_string,
outputs = {}; cryptonote::network_type nettype,
WalletComponentsValidationResults &retVals
) { // TODO: how can the err_strings be prepared for localization?
retVals = {};
bool r = false; bool r = false;
// //
// Address // Address
cryptonote::address_parse_info decoded_address_info; cryptonote::address_parse_info decoded_address_info;
r = cryptonote::get_account_address_from_str( r = cryptonote::get_account_address_from_str(
decoded_address_info, decoded_address_info,
inputs.nettype, nettype,
inputs.address_string address_string
); );
if (r == false) { if (r == false) {
outputs.did_error = true; retVals.did_error = true;
outputs.err_string = "Invalid address"; retVals.err_string = "Invalid address";
// //
return false; return false;
} }
// //
// View key: // View key:
crypto::secret_key sec_viewKey; crypto::secret_key sec_viewKey;
r = string_tools::hex_to_pod(inputs.sec_viewKey_string, sec_viewKey); r = string_tools::hex_to_pod(sec_viewKey_string, sec_viewKey);
if (r == false) { if (r == false) {
outputs.did_error = true; retVals.did_error = true;
outputs.err_string = "Invalid view key"; retVals.err_string = "Invalid view key";
// //
return false; return false;
} }
@ -307,29 +310,29 @@ bool monero_wallet_utils::validate_wallet_components_with(
crypto::public_key expected_pub_viewKey; crypto::public_key expected_pub_viewKey;
r = crypto::secret_key_to_public_key(sec_viewKey, expected_pub_viewKey); r = crypto::secret_key_to_public_key(sec_viewKey, expected_pub_viewKey);
if (r == false) { if (r == false) {
outputs.did_error = true; retVals.did_error = true;
outputs.err_string = "Invalid view key"; retVals.err_string = "Invalid view key";
// //
return false; return false;
} }
if (decoded_address_info.address.m_view_public_key != expected_pub_viewKey) { if (decoded_address_info.address.m_view_public_key != expected_pub_viewKey) {
outputs.did_error = true; retVals.did_error = true;
outputs.err_string = "View key does not match address"; retVals.err_string = "View key does not match address";
// //
return false; return false;
} }
// //
// View-only vs spend-key/seed // View-only vs spend-key/seed
outputs.isInViewOnlyMode = true; // setting the ground state retVals.isInViewOnlyMode = true; // setting the ground state
// //
crypto::secret_key sec_spendKey; // may be initialized crypto::secret_key sec_spendKey; // may be initialized
if (inputs.optl__sec_spendKey_string) { if (sec_spendKey_string != none) {
// First check if spend key content actually exists before passing to valid_sec_key_from - so that a spend key decode error can be treated as a failure instead of detecting empty spend keys too // First check if spend key content actually exists before passing to valid_sec_key_from - so that a spend key decode error can be treated as a failure instead of detecting empty spend keys too
if ((*inputs.optl__sec_spendKey_string).empty() == false) { if ((*sec_spendKey_string).empty() == false) {
r = string_tools::hex_to_pod(*inputs.optl__sec_spendKey_string, sec_spendKey); r = string_tools::hex_to_pod(*sec_spendKey_string, sec_spendKey);
if (r == false) { // this is an actual parse error exit condition if (r == false) { // this is an actual parse error exit condition
outputs.did_error = true; retVals.did_error = true;
outputs.err_string = "Invalid spend key"; retVals.err_string = "Invalid spend key";
// //
return false; return false;
} }
@ -337,41 +340,41 @@ bool monero_wallet_utils::validate_wallet_components_with(
crypto::public_key expected_pub_spendKey; crypto::public_key expected_pub_spendKey;
r = crypto::secret_key_to_public_key(sec_spendKey, expected_pub_spendKey); r = crypto::secret_key_to_public_key(sec_spendKey, expected_pub_spendKey);
if (r == false) { if (r == false) {
outputs.did_error = true; retVals.did_error = true;
outputs.err_string = "Invalid spend key"; retVals.err_string = "Invalid spend key";
// //
return false; return false;
} }
if (decoded_address_info.address.m_spend_public_key != expected_pub_spendKey) { if (decoded_address_info.address.m_spend_public_key != expected_pub_spendKey) {
outputs.did_error = true; retVals.did_error = true;
outputs.err_string = "Spend key does not match address"; retVals.err_string = "Spend key does not match address";
// //
return false; return false;
} }
outputs.isInViewOnlyMode = false; retVals.isInViewOnlyMode = false;
} }
} }
if (inputs.optl__sec_seed_string) { if (sec_seed_string != none) {
if ((*inputs.optl__sec_seed_string).empty() == false) { if ((*sec_seed_string).empty() == false) {
unsigned long sec_seed_string_length = (*inputs.optl__sec_seed_string).length(); unsigned long sec_seed_string_length = (*sec_seed_string).length();
crypto::secret_key sec_seed; crypto::secret_key sec_seed;
bool from_legacy16B_lw_seed = false; bool from_legacy16B_lw_seed = false;
if (sec_seed_string_length == sec_seed_hex_string_length) { // normal seed if (sec_seed_string_length == sec_seed_hex_string_length) { // normal seed
from_legacy16B_lw_seed = false; // to be clear from_legacy16B_lw_seed = false; // to be clear
bool r = string_tools::hex_to_pod((*inputs.optl__sec_seed_string), sec_seed); bool r = string_tools::hex_to_pod((*sec_seed_string), sec_seed);
if (!r) { if (!r) {
outputs.did_error = true; retVals.did_error = true;
outputs.err_string = "Invalid seed"; retVals.err_string = "Invalid seed";
// //
return false; return false;
} }
} else if (sec_seed_string_length == legacy16B__sec_seed_hex_string_length) { } else if (sec_seed_string_length == legacy16B__sec_seed_hex_string_length) {
from_legacy16B_lw_seed = true; from_legacy16B_lw_seed = true;
legacy16B_secret_key legacy16B_sec_seed; legacy16B_secret_key legacy16B_sec_seed;
bool r = string_tools::hex_to_pod((*inputs.optl__sec_seed_string), legacy16B_sec_seed); bool r = string_tools::hex_to_pod((*sec_seed_string), legacy16B_sec_seed);
if (!r) { if (!r) {
outputs.did_error = true; retVals.did_error = true;
outputs.err_string = "Invalid seed"; retVals.err_string = "Invalid seed";
// //
return false; return false;
} }
@ -382,36 +385,36 @@ bool monero_wallet_utils::validate_wallet_components_with(
const cryptonote::account_keys& expected_account_keys = expected_account.get_keys(); const cryptonote::account_keys& expected_account_keys = expected_account.get_keys();
// TODO: assert sec_spendKey initialized? // TODO: assert sec_spendKey initialized?
if (expected_account_keys.m_view_secret_key != sec_viewKey) { if (expected_account_keys.m_view_secret_key != sec_viewKey) {
outputs.did_error = true; retVals.did_error = true;
outputs.err_string = "Private view key does not match generated key"; retVals.err_string = "Private view key does not match generated key";
// //
return false; return false;
} }
if (expected_account_keys.m_spend_secret_key != sec_spendKey) { if (expected_account_keys.m_spend_secret_key != sec_spendKey) {
outputs.did_error = true; retVals.did_error = true;
outputs.err_string = "Private spend key does not match generated key"; retVals.err_string = "Private spend key does not match generated key";
// //
return false; return false;
} }
if (expected_account_keys.m_account_address.m_view_public_key != decoded_address_info.address.m_view_public_key) { if (expected_account_keys.m_account_address.m_view_public_key != decoded_address_info.address.m_view_public_key) {
outputs.did_error = true; retVals.did_error = true;
outputs.err_string = "Public view key does not match generated key"; retVals.err_string = "Public view key does not match generated key";
// //
return false; return false;
} }
if (expected_account_keys.m_account_address.m_spend_public_key != decoded_address_info.address.m_spend_public_key) { if (expected_account_keys.m_account_address.m_spend_public_key != decoded_address_info.address.m_spend_public_key) {
outputs.did_error = true; retVals.did_error = true;
outputs.err_string = "Public spend key does not match generated key"; retVals.err_string = "Public spend key does not match generated key";
// //
return false; return false;
} }
// //
outputs.isInViewOnlyMode = false; // TODO: should this ensure that sec_spendKey is not nil? spendKey should always be available if the seed is… retVals.isInViewOnlyMode = false; // TODO: should this ensure that sec_spendKey is not nil? spendKey should always be available if the seed is…
} }
} }
outputs.pub_viewKey_string = string_tools::pod_to_hex(decoded_address_info.address.m_view_public_key); retVals.pub_viewKey_string = string_tools::pod_to_hex(decoded_address_info.address.m_view_public_key);
outputs.pub_spendKey_string = string_tools::pod_to_hex(decoded_address_info.address.m_spend_public_key); retVals.pub_spendKey_string = string_tools::pod_to_hex(decoded_address_info.address.m_spend_public_key);
outputs.isValid = true; retVals.isValid = true;
// //
return true; return true;
} }

@ -77,13 +77,13 @@ namespace monero_wallet_utils
struct MnemonicDecodedSeed_RetVals: RetVals_base struct MnemonicDecodedSeed_RetVals: RetVals_base
{ {
optional<crypto::secret_key> optl__sec_seed = none; optional<crypto::secret_key> optl__sec_seed = none;
optional<std::string> optl__sec_seed_string = none; optional<string> optl__sec_seed_string = none;
optional<std::string> optl__mnemonic_string = none; optional<string> optl__mnemonic_string = none;
bool from_legacy16B_lw_seed = false; bool from_legacy16B_lw_seed = false;
}; };
bool decoded_seed( bool decoded_seed(
string mnemonic_string, string mnemonic_string,
string mnemonic_language_string, string mnemonic_language,
// //
MnemonicDecodedSeed_RetVals &retVals MnemonicDecodedSeed_RetVals &retVals
); );
@ -116,35 +116,31 @@ namespace monero_wallet_utils
boost::optional<WalletDescription> optl__desc = boost::none; boost::optional<WalletDescription> optl__desc = boost::none;
}; };
bool new_wallet( bool new_wallet(
std::string mnemonic_language, const string &mnemonic_language,
WalletDescriptionRetVals &retVals, WalletDescriptionRetVals &retVals,
cryptonote::network_type nettype = cryptonote::MAINNET cryptonote::network_type nettype = cryptonote::MAINNET
); );
bool wallet_with( bool wallet_with(
std::string mnemonic_string, const string &mnemonic_string,
std::string mnemonic_language, const string &mnemonic_language,
WalletDescriptionRetVals &retVals, WalletDescriptionRetVals &retVals,
cryptonote::network_type nettype = cryptonote::MAINNET cryptonote::network_type nettype = cryptonote::MAINNET
); );
// //
struct WalletComponentsToValidate
{
std::string address_string; // Required
std::string sec_viewKey_string; // Required
const std::string *optl__sec_spendKey_string;
const std::string *optl__sec_seed_string;
cryptonote::network_type nettype;
};
struct WalletComponentsValidationResults: RetVals_base struct WalletComponentsValidationResults: RetVals_base
{ {
bool isValid; // this will naturally remain false if did_error=true bool isValid; // this will naturally remain false if did_error=true
std::string pub_spendKey_string; string pub_spendKey_string;
std::string pub_viewKey_string; string pub_viewKey_string;
bool isInViewOnlyMode; // !sec_seed && !sec_spendKey bool isInViewOnlyMode; // !sec_seed && !sec_spendKey
}; };
bool validate_wallet_components_with( // returns !did_error bool validate_wallet_components_with( // returns !did_error
const WalletComponentsToValidate &inputs, const string &address_string,
WalletComponentsValidationResults &outputs const string &sec_viewKey_string,
optional<string> sec_spendKey_string,
optional<string> sec_seed_string,
cryptonote::network_type nettype,
WalletComponentsValidationResults &retVals
); );
} }

@ -316,9 +316,38 @@ string serial_bridge::seed_and_keys_from_mnemonic(const string &args_string)
// //
return ret_ss.str(); return ret_ss.str();
} }
string serial_bridge::verified_components_for_login(const string &args_string) string serial_bridge::validate_components_for_login(const string &args_string)
{ {
boost::property_tree::ptree json_root;
if (!parsed_json_root(args_string, json_root)) {
// it will already have thrown an exception
return error_ret_json_from_message("Invalid JSON");
}
monero_wallet_utils::WalletComponentsValidationResults retVals;
bool r = monero_wallet_utils::validate_wallet_components_with( // returns !did_error
json_root.get<string>("address_string"),
json_root.get<string>("sec_viewKey_string"),
json_root.get<string>("sec_spendKey_string"),
json_root.get<string>("seed_string"),
nettype_from_string(json_root.get<string>("nettype_string")),
retVals
);
bool did_error = retVals.did_error;
if (!r) {
THROW_WALLET_EXCEPTION_IF(!did_error, error::wallet_internal_error, "Illegal fail flag but !did_error");
return error_ret_json_from_message(*retVals.err_string);
}
THROW_WALLET_EXCEPTION_IF(did_error, error::wallet_internal_error, "Illegal success flag but did_error");
//
boost::property_tree::ptree root;
root.put(ret_json_key__isValid(), retVals.isValid);
root.put(ret_json_key__isInViewOnlyMode(), retVals.isInViewOnlyMode);
root.put(ret_json_key__pub_viewKey_string(), std::move(retVals.pub_viewKey_string));
root.put(ret_json_key__pub_spendKey_string(), std::move(retVals.pub_spendKey_string));
stringstream ret_ss;
boost::property_tree::write_json(ret_ss, root);
//
return ret_ss.str();
} }
// //
string serial_bridge::estimate_rct_size(const string &args_string) string serial_bridge::estimate_rct_size(const string &args_string)

@ -55,7 +55,7 @@ namespace serial_bridge
string newly_created_wallet(const string &args_string); // TODO: maybe expose random scalar as arg string newly_created_wallet(const string &args_string); // TODO: maybe expose random scalar as arg
string mnemonic_from_seed(const string &args_string); string mnemonic_from_seed(const string &args_string);
string seed_and_keys_from_mnemonic(const string &args_string); string seed_and_keys_from_mnemonic(const string &args_string);
string verified_components_for_login(const string &args_string); string validate_components_for_login(const string &args_string);
// //
string estimate_rct_size(const string &args_string); string estimate_rct_size(const string &args_string);
string calculate_fee(const string &args_string); string calculate_fee(const string &args_string);
@ -86,8 +86,8 @@ namespace serial_bridge
static inline string ret_json_key__pub_spendKey_string() { return "pub_spendKey_string"; } static inline string ret_json_key__pub_spendKey_string() { return "pub_spendKey_string"; }
static inline string ret_json_key__sec_viewKey_string() { return "sec_viewKey_string"; } static inline string ret_json_key__sec_viewKey_string() { return "sec_viewKey_string"; }
static inline string ret_json_key__sec_spendKey_string() { return "sec_spendKey_string"; } static inline string ret_json_key__sec_spendKey_string() { return "sec_spendKey_string"; }
static inline string ret_json_key__isValid() { return "isValid"; }
static inline string ret_json_key__isInViewOnlyMode() { return "isInViewOnlyMode"; }
// JSON keys - Args // JSON keys - Args
// TODO: // TODO:
// static inline string args_json_key__ // static inline string args_json_key__

@ -731,8 +731,43 @@ BOOST_AUTO_TEST_CASE(bridged__seed_and_keys_from_mnemonic)
BOOST_REQUIRE((*sec_spendKey_string).size() > 0); BOOST_REQUIRE((*sec_spendKey_string).size() > 0);
cout << "bridged: seed_and_keys_from_mnemonic: sec_spendKey_string: " << *sec_spendKey_string << endl; cout << "bridged: seed_and_keys_from_mnemonic: sec_spendKey_string: " << *sec_spendKey_string << endl;
} }
BOOST_AUTO_TEST_CASE(bridged__verified_components_for_login)
BOOST_AUTO_TEST_CASE(bridged__validate_components_for_login)
{ {
using namespace serial_bridge;
//
boost::property_tree::ptree root;
root.put("address_string", "43zxvpcj5Xv9SEkNXbMCG7LPQStHMpFCQCmkmR4u5nzjWwq5Xkv5VmGgYEsHXg4ja2FGRD5wMWbBVMijDTqmmVqm93wHGkg");
root.put("sec_viewKey_string", "7bea1907940afdd480eff7c4bcadb478a0fbb626df9e3ed74ae801e18f53e104");
root.put("sec_spendKey_string", "4e6d43cd03812b803c6f3206689f5fcc910005fc7e91d50d79b0776dbefcd803");
root.put("seed_string", "9c973aa296b79bbf452781dd3d32ad7f");
root.put("nettype_string", string_from_nettype(MAINNET));
//
stringstream args_ss;
boost::property_tree::write_json(args_ss, root);
auto ret_string = serial_bridge::validate_components_for_login(args_ss.str());
stringstream ret_stream;
ret_stream << ret_string;
boost::property_tree::ptree ret_tree;
boost::property_tree::read_json(ret_stream, ret_tree);
optional<string> err_string = ret_tree.get_optional<string>(ret_json_key__any__err_msg());
if (err_string != none) {
BOOST_REQUIRE_MESSAGE(false, *err_string);
}
optional<bool> isValid = ret_tree.get_optional<bool>(ret_json_key__isValid());
BOOST_REQUIRE(isValid == true);
cout << "bridged: validate_components_for_login: isValid: " << isValid << endl;
optional<bool> isInViewOnlyMode = ret_tree.get_optional<bool>(ret_json_key__isInViewOnlyMode());
BOOST_REQUIRE(isInViewOnlyMode == false);
cout << "bridged: validate_components_for_login: isInViewOnlyMode: " << isInViewOnlyMode << endl;
optional<string> pub_viewKey_string = ret_tree.get_optional<string>(ret_json_key__pub_viewKey_string());
BOOST_REQUIRE(pub_viewKey_string != none);
BOOST_REQUIRE((*pub_viewKey_string).size() > 0);
cout << "bridged: validate_components_for_login: pub_viewKey_string: " << *pub_viewKey_string << endl;
optional<string> pub_spendKey_string = ret_tree.get_optional<string>(ret_json_key__pub_spendKey_string());
BOOST_REQUIRE(pub_spendKey_string != none);
BOOST_REQUIRE((*pub_spendKey_string).size() > 0);
cout << "bridged: validate_components_for_login: pub_spendKey_string: " << *pub_spendKey_string << endl;
} }
BOOST_AUTO_TEST_CASE(bridged__estimate_rct_size) BOOST_AUTO_TEST_CASE(bridged__estimate_rct_size)

Loading…
Cancel
Save