Json::Value walletPropose (Json::Value const& params) { boost::optional<Seed> seed; KeyType keyType = KeyType::secp256k1; if (params.isMember (jss::key_type)) { if (! params[jss::key_type].isString()) { return RPC::expected_field_error ( jss::key_type, "string"); } keyType = keyTypeFromString ( params[jss::key_type].asString()); if (keyType == KeyType::invalid) return rpcError(rpcINVALID_PARAMS); } if (params.isMember (jss::passphrase) || params.isMember (jss::seed) || params.isMember (jss::seed_hex)) { Json::Value err; seed = RPC::getSeedFromRPC (params, err); if (!seed) return err; } else { seed = randomSeed (); } auto const publicKey = generateKeyPair (keyType, *seed).first; Json::Value obj (Json::objectValue); obj[jss::master_seed] = toBase58 (*seed); obj[jss::master_seed_hex] = strHex (seed->data(), seed->size()); obj[jss::master_key] = seedAs1751 (*seed); obj[jss::account_id] = toBase58(calcAccountID(publicKey)); obj[jss::public_key] = toBase58(TOKEN_ACCOUNT_PUBLIC, publicKey); obj[jss::key_type] = to_string (keyType); obj[jss::public_key_hex] = strHex (publicKey.data(), publicKey.size()); if (params.isMember (jss::passphrase)) { auto const entropy = estimate_entropy ( params[jss::passphrase].asString()); // 80 bits of entropy isn't bad, but it's better to // err on the side of caution and be conservative. if (entropy < 80.0) obj[jss::warning] = "This wallet was generated using a user-supplied " "passphrase that has low entropy and is vulnerable " "to brute-force attacks."; else obj[jss::warning] = "This wallet was generated using a user-supplied " "passphrase. It may be vulnerable to brute-force " "attacks."; } return obj; }
Json::Value walletPropose (Json::Value const& params) { boost::optional<KeyType> keyType; boost::optional<Seed> seed; bool rippleLibSeed = false; if (params.isMember (jss::key_type)) { if (! params[jss::key_type].isString()) { return RPC::expected_field_error ( jss::key_type, "string"); } keyType = keyTypeFromString ( params[jss::key_type].asString()); if (!keyType) return rpcError(rpcINVALID_PARAMS); } // ripple-lib encodes seed used to generate an Ed25519 wallet in a // non-standard way. While we never encode seeds that way, we try // to detect such keys to avoid user confusion. { if (params.isMember(jss::passphrase)) seed = RPC::parseRippleLibSeed(params[jss::passphrase]); else if (params.isMember(jss::seed)) seed = RPC::parseRippleLibSeed(params[jss::seed]); if(seed) { rippleLibSeed = true; // If the user *explicitly* requests a key type other than // Ed25519 we return an error. if (keyType.value_or(KeyType::ed25519) != KeyType::ed25519) return rpcError(rpcBAD_SEED); keyType = KeyType::ed25519; } } if (!seed) { if (params.isMember(jss::passphrase) || params.isMember(jss::seed) || params.isMember(jss::seed_hex)) { Json::Value err; seed = RPC::getSeedFromRPC(params, err); if (!seed) return err; } else { seed = randomSeed(); } } if (!keyType) keyType = KeyType::secp256k1; auto const publicKey = generateKeyPair (*keyType, *seed).first; Json::Value obj (Json::objectValue); auto const seed1751 = seedAs1751 (*seed); auto const seedHex = strHex (*seed); auto const seedBase58 = toBase58 (*seed); obj[jss::master_seed] = seedBase58; obj[jss::master_seed_hex] = seedHex; obj[jss::master_key] = seed1751; obj[jss::account_id] = toBase58(calcAccountID(publicKey)); obj[jss::public_key] = toBase58(TokenType::AccountPublic, publicKey); obj[jss::key_type] = to_string (*keyType); obj[jss::public_key_hex] = strHex (publicKey); // If a passphrase was specified, and it was hashed and used as a seed // run a quick entropy check and add an appropriate warning, because // "brain wallets" can be easily attacked. if (!rippleLibSeed && params.isMember (jss::passphrase)) { auto const passphrase = params[jss::passphrase].asString(); if (passphrase != seed1751 && passphrase != seedBase58 && passphrase != seedHex) { // 80 bits of entropy isn't bad, but it's better to // err on the side of caution and be conservative. if (estimate_entropy (passphrase) < 80.0) obj[jss::warning] = "This wallet was generated using a user-supplied " "passphrase that has low entropy and is vulnerable " "to brute-force attacks."; else obj[jss::warning] = "This wallet was generated using a user-supplied " "passphrase. It may be vulnerable to brute-force " "attacks."; } } return obj; }