rippled
KeyGeneration_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2015 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/basics/StringUtilities.h>
21 #include <ripple/json/json_value.h>
22 #include <ripple/json/json_writer.h>
23 #include <ripple/protocol/ErrorCodes.h>
24 #include <ripple/protocol/jss.h>
25 #include <ripple/rpc/handlers/WalletPropose.h>
26 #include <ripple/rpc/impl/RPCHelpers.h>
27 #include <test/jtx/TestSuite.h>
28 
29 namespace ripple {
30 
31 namespace RPC {
32 
34 {
35  char const* account_id;
36  char const* master_key;
37  char const* master_seed;
38  char const* master_seed_hex;
39  char const* public_key;
40  char const* public_key_hex;
41  char const* secret_key_hex;
42  char const* passphrase;
43  char const* passphrase_warning;
44 };
45 
46 namespace common {
47 static char const* passphrase = "REINDEER FLOTILLA";
48 static char const* master_key =
49  "SCAT BERN ISLE FOR ROIL BUS SOAK AQUA FREE FOR DRAM BRIG";
50 static char const* master_seed = "snMwVWs2hZzfDUF3p2tHZ3EgmyhFs";
51 static char const* master_seed_hex = "BE6A670A19B209E112146D0A7ED2AAD7";
52 } // namespace common
53 
55  "r4Vtj2jrfmTVZGfSP3gH9hQPMqFPQFin8f",
59  "aBQxK2YFNqzmAaXNczYcjqDjfiKkLsJUizsr1UBf44RCF8FHdrmX",
60  "038AAE247B2344B1837FBED8F57389C8C11774510A3F7D784F2A09F0CB6843236C",
61  "1949ECD889EA71324BC7A30C8E81F4E93CB73EE19D59E9082111E78CC3DDABC2",
63  "This wallet was generated using a user-supplied "
64  "passphrase that has low entropy and is vulnerable "
65  "to brute-force attacks.",
66 };
67 
68 static key_strings const ed25519_strings = {
69  "r4qV6xTXerqaZav3MJfSY79ynmc1BSBev1",
73  "aKEQmgLMyZPMruJFejUuedp169LgW6DbJt1rej1DJ5hWUMH4pHJ7",
74  "ED54C3F5BEDA8BD588B203D23A27398FAD9D20F88A974007D6994659CD7273FE1D",
75  "77AAED2698D56D6676323629160F4EEF21CFD9EE3D0745CC78FA291461F98278",
77  "This wallet was generated using a user-supplied "
78  "passphrase that has low entropy and is vulnerable "
79  "to brute-force attacks.",
80 };
81 
83  "rBcvXmNb7KPkNdMkpckdWPpbvkWgcV3nir",
84  "TED AVON CAVE HOUR BRAG JEFF RIFT NEAL TOLD FAT SEW SAN",
85  "shKdhWka8hS7Es3bpctCZXBiAwfUN",
86  "74BA8389B44F98CF41E795CD91F9C93F",
87  "aBRL2sqVuzrsM6zikPB4v8UBHGn1aKkrsxhYEffhcQxB2LKyywE5",
88  "03BD334FB9E06C58D69603E9922686528B18A754BC2F2E1ADA095FFE67DE952C64",
89  "84262FB16AA25BE407174C7EDAB531220C30FA4D8A28AA9D564673FB3D34502C",
90  "A4yKIRGdzrw0YQ$2%TFKYG9HP*&ok^!sy7E@RwICs",
91  "This wallet was generated using a user-supplied "
92  "passphrase. It may be vulnerable to brute-force "
93  "attacks.",
94 };
95 
97 {
98 public:
99  void
101  {
102  Json::Value params;
103  if (keyType)
104  params[jss::key_type] = *keyType;
105  Json::Value result = walletPropose(params);
106 
107  BEAST_EXPECT(!contains_error(result));
108  BEAST_EXPECT(result.isMember(jss::account_id));
109  BEAST_EXPECT(result.isMember(jss::master_seed));
110  BEAST_EXPECT(result.isMember(jss::master_seed_hex));
111  BEAST_EXPECT(result.isMember(jss::public_key));
112  BEAST_EXPECT(result.isMember(jss::public_key_hex));
113  BEAST_EXPECT(result.isMember(jss::key_type));
114 
115  expectEquals(
116  result[jss::key_type],
117  params.isMember(jss::key_type) ? params[jss::key_type]
118  : "secp256k1");
119  BEAST_EXPECT(!result.isMember(jss::warning));
120 
121  std::string seed = result[jss::master_seed].asString();
122 
123  result = walletPropose(params);
124 
125  // We asked for two random seeds, so they shouldn't match.
126  BEAST_EXPECT(result[jss::master_seed].asString() != seed);
127  }
128 
130  testSecretWallet(Json::Value const& params, key_strings const& s)
131  {
132  Json::Value result = walletPropose(params);
133 
134  BEAST_EXPECT(!contains_error(result));
135  expectEquals(result[jss::account_id], s.account_id);
136  expectEquals(result[jss::master_seed], s.master_seed);
137  expectEquals(result[jss::master_seed_hex], s.master_seed_hex);
138  expectEquals(result[jss::public_key], s.public_key);
139  expectEquals(result[jss::public_key_hex], s.public_key_hex);
140  expectEquals(
141  result[jss::key_type],
142  params.isMember(jss::key_type) ? params[jss::key_type]
143  : "secp256k1");
144  return result;
145  }
146 
147  void
149  std::optional<std::string> const& keyType,
150  key_strings const& strings)
151  {
152  testcase("seed");
153 
154  Json::Value params;
155  if (keyType)
156  params[jss::key_type] = *keyType;
157  params[jss::seed] = strings.master_seed;
158 
159  auto const wallet = testSecretWallet(params, strings);
160  BEAST_EXPECT(!wallet.isMember(jss::warning));
161  }
162 
163  void
165  std::optional<std::string> const& keyType,
166  key_strings const& strings)
167  {
168  testcase("seed_hex");
169 
170  Json::Value params;
171  if (keyType)
172  params[jss::key_type] = *keyType;
173  params[jss::seed_hex] = strings.master_seed_hex;
174 
175  auto const wallet = testSecretWallet(params, strings);
176  BEAST_EXPECT(!wallet.isMember(jss::warning));
177  }
178 
179  void
181  char const* value,
182  std::optional<std::string> const& keyType,
183  key_strings const& strings)
184  {
185  Json::Value params;
186  if (keyType)
187  params[jss::key_type] = *keyType;
188  params[jss::passphrase] = value;
189 
190  auto const wallet = testSecretWallet(params, strings);
191  if (value == strings.passphrase)
192  BEAST_EXPECT(wallet[jss::warning] == strings.passphrase_warning);
193  else
194  BEAST_EXPECT(!wallet.isMember(jss::warning));
195  }
196 
197  void
199  std::optional<std::string> const& keyType,
200  key_strings const& strings)
201  {
202  testcase("passphrase");
203 
204  testLegacyPassphrase(strings.passphrase, keyType, strings);
205  testLegacyPassphrase(strings.master_key, keyType, strings);
206  testLegacyPassphrase(strings.master_seed, keyType, strings);
207  testLegacyPassphrase(strings.master_seed_hex, keyType, strings);
208  }
209 
210  void
212  std::optional<std::string> const& keyType,
213  key_strings const& strings)
214  {
215  testcase(keyType ? *keyType : "no key_type");
216 
217  testRandomWallet(keyType);
218  testSeed(keyType, strings);
219  testSeedHex(keyType, strings);
220  testLegacyPassphrase(keyType, strings);
221 
222  Json::Value params;
223  if (keyType)
224  params[jss::key_type] = *keyType;
225  params[jss::seed] = strings.master_seed;
226  params[jss::seed_hex] = strings.master_seed_hex;
227 
228  // Secret fields are mutually exclusive.
229  BEAST_EXPECT(contains_error(walletPropose(params)));
230  }
231 
232  void
234  {
235  testcase("Bad inputs");
236 
237  // Passing non-strings where strings are required
238  {
239  Json::Value params;
240  params[jss::key_type] = "secp256k1";
241  params[jss::passphrase] = 20160506;
242  auto result = walletPropose(params);
243  BEAST_EXPECT(contains_error(result));
244  BEAST_EXPECT(
245  result[jss::error_message] ==
246  "Invalid field 'passphrase', not string.");
247  }
248 
249  {
250  Json::Value params;
251  params[jss::key_type] = "secp256k1";
252  params[jss::seed] = Json::objectValue;
253  auto result = walletPropose(params);
254  BEAST_EXPECT(contains_error(result));
255  BEAST_EXPECT(
256  result[jss::error_message] ==
257  "Invalid field 'seed', not string.");
258  }
259 
260  {
261  Json::Value params;
262  params[jss::key_type] = "ed25519";
263  params[jss::seed_hex] = Json::arrayValue;
264  auto result = walletPropose(params);
265  BEAST_EXPECT(contains_error(result));
266  BEAST_EXPECT(
267  result[jss::error_message] ==
268  "Invalid field 'seed_hex', not string.");
269  }
270 
271  // Specifying multiple items at once
272  {
273  Json::Value params;
274  params[jss::key_type] = "secp256k1";
275  params[jss::passphrase] = common::master_key;
276  params[jss::seed_hex] = common::master_seed_hex;
277  params[jss::seed] = common::master_seed;
278  auto result = walletPropose(params);
279  BEAST_EXPECT(contains_error(result));
280  BEAST_EXPECT(
281  result[jss::error_message] ==
282  "Exactly one of the following must be specified: passphrase, "
283  "seed or seed_hex");
284  }
285 
286  // Specifying bad key types:
287  {
288  Json::Value params;
289  params[jss::key_type] = "prime256v1";
290  params[jss::passphrase] = common::master_key;
291  auto result = walletPropose(params);
292  BEAST_EXPECT(contains_error(result));
293  BEAST_EXPECT(result[jss::error_message] == "Invalid parameters.");
294  }
295 
296  {
297  Json::Value params;
298  params[jss::key_type] = Json::objectValue;
299  params[jss::seed_hex] = common::master_seed_hex;
300  auto result = walletPropose(params);
301  BEAST_EXPECT(contains_error(result));
302  BEAST_EXPECT(
303  result[jss::error_message] ==
304  "Invalid field 'key_type', not string.");
305  }
306 
307  {
308  Json::Value params;
309  params[jss::key_type] = Json::arrayValue;
310  params[jss::seed] = common::master_seed;
311  auto result = walletPropose(params);
312  BEAST_EXPECT(contains_error(result));
313  BEAST_EXPECT(
314  result[jss::error_message] ==
315  "Invalid field 'key_type', not string.");
316  }
317  }
318 
319  void
322  key_strings const& strings)
323  {
324  testcase(
325  "keypairForSignature - " + (keyType ? *keyType : "no key_type"));
326 
327  auto const publicKey = parseBase58<PublicKey>(
329  BEAST_EXPECT(publicKey);
330 
331  if (!keyType)
332  {
333  {
334  Json::Value params;
335  Json::Value error;
336  params[jss::secret] = strings.master_seed;
337 
338  auto ret = keypairForSignature(params, error);
339  BEAST_EXPECT(!contains_error(error));
340  BEAST_EXPECT(ret.first.size() != 0);
341  BEAST_EXPECT(ret.first == publicKey);
342  }
343 
344  {
345  Json::Value params;
346  Json::Value error;
347  params[jss::secret] = strings.master_seed_hex;
348 
349  auto ret = keypairForSignature(params, error);
350  BEAST_EXPECT(!contains_error(error));
351  BEAST_EXPECT(ret.first.size() != 0);
352  BEAST_EXPECT(ret.first == publicKey);
353  }
354 
355  {
356  Json::Value params;
357  Json::Value error;
358  params[jss::secret] = strings.master_key;
359 
360  auto ret = keypairForSignature(params, error);
361  BEAST_EXPECT(!contains_error(error));
362  BEAST_EXPECT(ret.first.size() != 0);
363  BEAST_EXPECT(ret.first == publicKey);
364  }
365 
366  keyType.emplace("secp256k1");
367  }
368 
369  {
370  Json::Value params;
371  Json::Value error;
372 
373  params[jss::key_type] = *keyType;
374  params[jss::seed] = strings.master_seed;
375 
376  auto ret = keypairForSignature(params, error);
377  BEAST_EXPECT(!contains_error(error));
378  BEAST_EXPECT(ret.first.size() != 0);
379  BEAST_EXPECT(ret.first == publicKey);
380  }
381 
382  {
383  Json::Value params;
384  Json::Value error;
385 
386  params[jss::key_type] = *keyType;
387  params[jss::seed_hex] = strings.master_seed_hex;
388 
389  auto ret = keypairForSignature(params, error);
390  BEAST_EXPECT(!contains_error(error));
391  BEAST_EXPECT(ret.first.size() != 0);
392  BEAST_EXPECT(ret.first == publicKey);
393  }
394 
395  {
396  Json::Value params;
397  Json::Value error;
398 
399  params[jss::key_type] = *keyType;
400  params[jss::passphrase] = strings.master_key;
401 
402  auto ret = keypairForSignature(params, error);
403  BEAST_EXPECT(!contains_error(error));
404  BEAST_EXPECT(ret.first.size() != 0);
405  BEAST_EXPECT(ret.first == publicKey);
406  }
407  }
408 
409  void
411  {
412  // Specify invalid "secret"
413  {
414  Json::Value params;
415  Json::Value error;
416  params[jss::secret] = 314159265;
417  auto ret = keypairForSignature(params, error);
418  BEAST_EXPECT(contains_error(error));
419  BEAST_EXPECT(
420  error[jss::error_message] ==
421  "Invalid field 'secret', not string.");
422  BEAST_EXPECT(ret.first.size() == 0);
423  }
424 
425  {
426  Json::Value params;
427  Json::Value error;
428  params[jss::secret] = Json::arrayValue;
429  params[jss::secret].append("array:0");
430 
431  auto ret = keypairForSignature(params, error);
432  BEAST_EXPECT(contains_error(error));
433  BEAST_EXPECT(
434  error[jss::error_message] ==
435  "Invalid field 'secret', not string.");
436  BEAST_EXPECT(ret.first.size() == 0);
437  }
438 
439  {
440  Json::Value params;
441  Json::Value error;
442  params[jss::secret] = Json::objectValue;
443  params[jss::secret]["string"] = "string";
444  params[jss::secret]["number"] = 702;
445 
446  auto ret = keypairForSignature(params, error);
447  BEAST_EXPECT(contains_error(error));
448  BEAST_EXPECT(ret.first.size() == 0);
449  BEAST_EXPECT(
450  error[jss::error_message] ==
451  "Invalid field 'secret', not string.");
452  }
453 
454  // Specify "secret" and "key_type"
455  {
456  Json::Value params;
457  Json::Value error;
458  params[jss::key_type] = "ed25519";
459  params[jss::secret] = common::master_seed;
460 
461  auto ret = keypairForSignature(params, error);
462  BEAST_EXPECT(contains_error(error));
463  BEAST_EXPECT(
464  error[jss::error_message] ==
465  "The secret field is not allowed if key_type is used.");
466  BEAST_EXPECT(ret.first.size() == 0);
467  }
468 
469  // Specify unknown or bad "key_type"
470  {
471  Json::Value params;
472  Json::Value error;
473  params[jss::key_type] = "prime256v1";
474  params[jss::passphrase] = common::master_key;
475 
476  auto ret = keypairForSignature(params, error);
477  BEAST_EXPECT(contains_error(error));
478  BEAST_EXPECT(
479  error[jss::error_message] == "Invalid field 'key_type'.");
480  BEAST_EXPECT(ret.first.size() == 0);
481  }
482 
483  {
484  Json::Value params;
485  Json::Value error;
486  params[jss::key_type] = Json::objectValue;
487  params[jss::seed_hex] = common::master_seed_hex;
488 
489  auto ret = keypairForSignature(params, error);
490  BEAST_EXPECT(contains_error(error));
491  BEAST_EXPECT(
492  error[jss::error_message] ==
493  "Invalid field 'key_type', not string.");
494  BEAST_EXPECT(ret.first.size() == 0);
495  }
496 
497  {
498  Json::Value params;
499  Json::Value error;
500  params[jss::key_type] = Json::arrayValue;
501  params[jss::seed] = common::master_seed;
502 
503  auto ret = keypairForSignature(params, error);
504  BEAST_EXPECT(contains_error(error));
505  BEAST_EXPECT(
506  error[jss::error_message] ==
507  "Invalid field 'key_type', not string.");
508  BEAST_EXPECT(ret.first.size() == 0);
509  }
510 
511  // Specify non-string passphrase
512  { // not a passphrase: number
513  Json::Value params;
514  Json::Value error;
515  params[jss::key_type] = "secp256k1";
516  params[jss::passphrase] = 1234567890;
517 
518  auto ret = keypairForSignature(params, error);
519  BEAST_EXPECT(contains_error(error));
520  BEAST_EXPECT(
521  error[jss::error_message] ==
522  "Invalid field 'passphrase', not string.");
523  BEAST_EXPECT(ret.first.size() == 0);
524  }
525 
526  { // not a passphrase: object
527  Json::Value params;
528  Json::Value error;
529  params[jss::key_type] = "secp256k1";
530  params[jss::passphrase] = Json::objectValue;
531 
532  auto ret = keypairForSignature(params, error);
533  BEAST_EXPECT(contains_error(error));
534  BEAST_EXPECT(
535  error[jss::error_message] ==
536  "Invalid field 'passphrase', not string.");
537  BEAST_EXPECT(ret.first.size() == 0);
538  }
539 
540  { // not a passphrase: array
541  Json::Value params;
542  Json::Value error;
543  params[jss::key_type] = "secp256k1";
544  params[jss::passphrase] = Json::arrayValue;
545 
546  auto ret = keypairForSignature(params, error);
547  BEAST_EXPECT(contains_error(error));
548  BEAST_EXPECT(
549  error[jss::error_message] ==
550  "Invalid field 'passphrase', not string.");
551  BEAST_EXPECT(ret.first.size() == 0);
552  }
553 
554  { // not a passphrase: empty string
555  Json::Value params;
556  Json::Value error;
557  params[jss::key_type] = "secp256k1";
558  params[jss::passphrase] = "";
559 
560  auto ret = keypairForSignature(params, error);
561  BEAST_EXPECT(contains_error(error));
562  BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
563  BEAST_EXPECT(ret.first.size() == 0);
564  }
565 
566  // Specify non-string or invalid seed
567  { // not a seed: number
568  Json::Value params;
569  Json::Value error;
570  params[jss::key_type] = "secp256k1";
571  params[jss::seed] = 443556;
572 
573  auto ret = keypairForSignature(params, error);
574  BEAST_EXPECT(contains_error(error));
575  BEAST_EXPECT(
576  error[jss::error_message] ==
577  "Invalid field 'seed', not string.");
578  BEAST_EXPECT(ret.first.size() == 0);
579  }
580 
581  { // not a string: object
582  Json::Value params;
583  Json::Value error;
584  params[jss::key_type] = "secp256k1";
585  params[jss::seed] = Json::objectValue;
586 
587  auto ret = keypairForSignature(params, error);
588  BEAST_EXPECT(contains_error(error));
589  BEAST_EXPECT(
590  error[jss::error_message] ==
591  "Invalid field 'seed', not string.");
592  BEAST_EXPECT(ret.first.size() == 0);
593  }
594 
595  { // not a string: array
596  Json::Value params;
597  Json::Value error;
598  params[jss::key_type] = "secp256k1";
599  params[jss::seed] = Json::arrayValue;
600 
601  auto ret = keypairForSignature(params, error);
602  BEAST_EXPECT(contains_error(error));
603  BEAST_EXPECT(
604  error[jss::error_message] ==
605  "Invalid field 'seed', not string.");
606  BEAST_EXPECT(ret.first.size() == 0);
607  }
608 
609  { // not a seed: empty
610  Json::Value params;
611  Json::Value error;
612  params[jss::key_type] = "secp256k1";
613  params[jss::seed] = "";
614 
615  auto ret = keypairForSignature(params, error);
616  BEAST_EXPECT(contains_error(error));
617  BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
618  BEAST_EXPECT(ret.first.size() == 0);
619  }
620 
621  { // not a seed: invalid characters
622  Json::Value params;
623  Json::Value error;
624  params[jss::key_type] = "secp256k1";
625  params[jss::seed] = "s M V s h z D F p t Z E m h s";
626 
627  auto ret = keypairForSignature(params, error);
628  BEAST_EXPECT(contains_error(error));
629  BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
630  BEAST_EXPECT(ret.first.size() == 0);
631  }
632 
633  { // not a seed: random string
634  Json::Value params;
635  Json::Value error;
636  params[jss::key_type] = "secp256k1";
637  params[jss::seed] = "pnnjkbnobnml43679nbvjdsklnbjs";
638 
639  auto ret = keypairForSignature(params, error);
640  BEAST_EXPECT(contains_error(error));
641  BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
642  BEAST_EXPECT(ret.first.size() == 0);
643  }
644 
645  // Specify non-string or invalid seed_hex
646  { // not a string: number
647  Json::Value params;
648  Json::Value error;
649  params[jss::key_type] = "secp256k1";
650  params[jss::seed_hex] = 443556;
651 
652  auto ret = keypairForSignature(params, error);
653  BEAST_EXPECT(contains_error(error));
654  BEAST_EXPECT(
655  error[jss::error_message] ==
656  "Invalid field 'seed_hex', not string.");
657  BEAST_EXPECT(ret.first.size() == 0);
658  }
659 
660  { // not a string: object
661  Json::Value params;
662  Json::Value error;
663  params[jss::key_type] = "secp256k1";
664  params[jss::seed_hex] = Json::objectValue;
665 
666  auto ret = keypairForSignature(params, error);
667  BEAST_EXPECT(contains_error(error));
668  BEAST_EXPECT(
669  error[jss::error_message] ==
670  "Invalid field 'seed_hex', not string.");
671  BEAST_EXPECT(ret.first.size() == 0);
672  }
673 
674  { // not a string: array
675  Json::Value params;
676  Json::Value error;
677  params[jss::key_type] = "secp256k1";
678  params[jss::seed_hex] = Json::arrayValue;
679 
680  auto ret = keypairForSignature(params, error);
681  BEAST_EXPECT(contains_error(error));
682  BEAST_EXPECT(
683  error[jss::error_message] ==
684  "Invalid field 'seed_hex', not string.");
685  BEAST_EXPECT(ret.first.size() == 0);
686  }
687 
688  { // empty
689  Json::Value params;
690  Json::Value error;
691  params[jss::key_type] = "secp256k1";
692  params[jss::seed_hex] = "";
693 
694  auto ret = keypairForSignature(params, error);
695  BEAST_EXPECT(contains_error(error));
696  BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
697  BEAST_EXPECT(ret.first.size() == 0);
698  }
699 
700  { // short
701  Json::Value params;
702  Json::Value error;
703  params[jss::key_type] = "secp256k1";
704  params[jss::seed_hex] = "A670A19B";
705 
706  auto ret = keypairForSignature(params, error);
707  BEAST_EXPECT(contains_error(error));
708  BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
709  BEAST_EXPECT(ret.first.size() == 0);
710  }
711 
712  { // not hex
713  Json::Value params;
714  Json::Value error;
715  params[jss::key_type] = "secp256k1";
716  params[jss::seed_hex] = common::passphrase;
717 
718  auto ret = keypairForSignature(params, error);
719  BEAST_EXPECT(contains_error(error));
720  BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
721  BEAST_EXPECT(ret.first.size() == 0);
722  }
723 
724  { // overlong
725  Json::Value params;
726  Json::Value error;
727  params[jss::key_type] = "secp256k1";
728  params[jss::seed_hex] =
729  "BE6A670A19B209E112146D0A7ED2AAD72567D0FC913";
730 
731  auto ret = keypairForSignature(params, error);
732  BEAST_EXPECT(contains_error(error));
733  BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
734  BEAST_EXPECT(ret.first.size() == 0);
735  }
736  }
737 
738  void
740  {
741  testcase("ripple-lib encoded Ed25519 keys");
742 
743  auto test = [this](char const* seed, char const* addr) {
744  {
745  Json::Value params;
746  Json::Value error;
747 
748  params[jss::passphrase] = seed;
749 
750  auto ret = keypairForSignature(params, error);
751 
752  BEAST_EXPECT(!contains_error(error));
753  BEAST_EXPECT(ret.first.size() != 0);
754  BEAST_EXPECT(toBase58(calcAccountID(ret.first)) == addr);
755  }
756 
757  {
758  Json::Value params;
759  Json::Value error;
760 
761  params[jss::key_type] = "secp256k1";
762  params[jss::passphrase] = seed;
763 
764  auto ret = keypairForSignature(params, error);
765 
766  BEAST_EXPECT(contains_error(error));
767  BEAST_EXPECT(
768  error[jss::error_message] ==
769  "Specified seed is for an Ed25519 wallet.");
770  }
771 
772  {
773  Json::Value params;
774  Json::Value error;
775 
776  params[jss::key_type] = "ed25519";
777  params[jss::seed] = seed;
778 
779  auto ret = keypairForSignature(params, error);
780 
781  BEAST_EXPECT(!contains_error(error));
782  BEAST_EXPECT(ret.first.size() != 0);
783  BEAST_EXPECT(toBase58(calcAccountID(ret.first)) == addr);
784  }
785 
786  {
787  Json::Value params;
788  Json::Value error;
789 
790  params[jss::key_type] = "secp256k1";
791  params[jss::seed] = seed;
792 
793  auto ret = keypairForSignature(params, error);
794 
795  BEAST_EXPECT(contains_error(error));
796  BEAST_EXPECT(
797  error[jss::error_message] ==
798  "Specified seed is for an Ed25519 wallet.");
799  }
800  };
801 
802  test(
803  "sEdVWZmeUDgQdMEFKTK9kYVX71FKB7o",
804  "r34XnDB2zS11NZ1wKJzpU1mjWExGVugTaQ");
805  test(
806  "sEd7zJoVnqg1FxB9EuaHC1AB5UPfHWz",
807  "rDw51qRrBEeMw7Na1Nh79LN7HYZDo7nZFE");
808  test(
809  "sEdSxVntbihdLyabbfttMCqsaaucVR9",
810  "rwiyBDfAYegXZyaQcN2L1vAbKRYn2wNFMq");
811  test(
812  "sEdSVwJjEXTYCztqDK4JD9WByH3otDX",
813  "rQJ4hZzNGkLQhLtKPCmu1ywEw1ai2vgUJN");
814  test(
815  "sEdV3jXjKuUoQTSr1Rb4yw8Kyn9r46U",
816  "rERRw2Pxbau4tevE61V5vZUwD7Rus5Y6vW");
817  test(
818  "sEdVeUZjuYT47Uy51FQCnzivsuWyiwB",
819  "rszewT5gRjUgWNEmnfMjvVYzJCkhvWY32i");
820  test(
821  "sEd7MHTewdw4tFYeS7rk7XT4qHiA9jH",
822  "rBB2rvnf4ztwjgNhinFXQJ91nAZjkFgR3p");
823  test(
824  "sEd7A5jFBSdWbNeKGriQvLr1thBScJh",
825  "rLAXz8Nz7aDivz7PwThsLFqaKrizepNCdA");
826  test(
827  "sEdVPU9M2uyzVNT4Yb5Dn4tUtYjbFAw",
828  "rHbHRFPCxD5fnn98TBzsQHJ7SsRq7eHkRj");
829  test(
830  "sEdVfF2zhAmS8gfMYzJ4yWBMeR4BZKc",
831  "r9PsneKHcAE7kUfiTixomM5Mnwi28tCc7h");
832  test(
833  "sEdTjRtcsQkwthDXUSLi9DHNyJcR8GW",
834  "rM4soF4XS3wZrmLurvE6ZmudG16Lk5Dur5");
835  test(
836  "sEdVNKeu1Lhpfh7Nf6tRDbxnmMyZ4Dv",
837  "r4ZwJxq6FDtWjapDtCGhjG6mtNm1nWdJcD");
838  test(
839  "sEd7bK4gf5BHJ1WbaEWx8pKMA9MLHpC",
840  "rD6tnn51m4o1uXeEK9CFrZ3HR7DcFhiYnp");
841  test(
842  "sEd7jCh3ppnQMsLdGcZ6TZayZaHhBLg",
843  "rTcBkiRQ1EfFQ4FCCwqXNHpn1yUTAACkj");
844  test(
845  "sEdTFJezurQwSJAbkLygj2gQXBut2wh",
846  "rnXaMacNbRwcJddbbPbqdcpSUQcfzFmrR8");
847  test(
848  "sEdSWajfQAAWFuDvVZF3AiGucReByLt",
849  "rBJtow6V3GTdsWMamrxetRDwWs6wwTxcKa");
850  }
851 
852  void
853  run() override
854  {
855  testKeyType(std::nullopt, secp256k1_strings);
859  testBadInput();
860 
865 
867 
869  }
870 };
871 
872 BEAST_DEFINE_TESTSUITE(WalletPropose, ripple_basics, ripple);
873 
874 } // namespace RPC
875 } // namespace ripple
ripple::RPC::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountLinesRPC, app, ripple)
ripple::RPC::strong_brain_strings
static const key_strings strong_brain_strings
Definition: KeyGeneration_test.cpp:82
std::string
STL class.
ripple::RPC::key_strings::public_key
char const * public_key
Definition: KeyGeneration_test.cpp:39
ripple::RPC::key_strings::master_seed
char const * master_seed
Definition: KeyGeneration_test.cpp:37
Json::arrayValue
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
ripple::RPC::WalletPropose_test::testBadInput
void testBadInput()
Definition: KeyGeneration_test.cpp:233
ripple::TestSuite::expectEquals
bool expectEquals(S actual, T expected, std::string const &message="")
Definition: TestSuite.h:33
ripple::RPC::key_strings::account_id
char const * account_id
Definition: KeyGeneration_test.cpp:35
ripple::RPC::WalletPropose_test::run
void run() override
Definition: KeyGeneration_test.cpp:853
ripple::RPC::key_strings::public_key_hex
char const * public_key_hex
Definition: KeyGeneration_test.cpp:40
ripple::RPC::common::master_seed
static char const * master_seed
Definition: KeyGeneration_test.cpp:50
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:104
ripple::RPC::key_strings
Definition: KeyGeneration_test.cpp:33
ripple::RPC::WalletPropose_test::testKeypairForSignatureErrors
void testKeypairForSignatureErrors()
Definition: KeyGeneration_test.cpp:410
ripple::RPC::secp256k1_strings
static const key_strings secp256k1_strings
Definition: KeyGeneration_test.cpp:54
Json::Value::append
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:882
ripple::RPC::key_strings::master_seed_hex
char const * master_seed_hex
Definition: KeyGeneration_test.cpp:38
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::RPC::contains_error
bool contains_error(Json::Value const &json)
Returns true if the json contains an rpc error specification.
Definition: ErrorCodes.cpp:194
ripple::RPC::WalletPropose_test
Definition: KeyGeneration_test.cpp:96
ripple::RPC::WalletPropose_test::testSeedHex
void testSeedHex(std::optional< std::string > const &keyType, key_strings const &strings)
Definition: KeyGeneration_test.cpp:164
ripple::RPC::WalletPropose_test::testLegacyPassphrase
void testLegacyPassphrase(std::optional< std::string > const &keyType, key_strings const &strings)
Definition: KeyGeneration_test.cpp:198
ripple::calcAccountID
AccountID calcAccountID(PublicKey const &pk)
Definition: AccountID.cpp:158
ripple::RPC::WalletPropose_test::testKeypairForSignature
void testKeypairForSignature(std::optional< std::string > keyType, key_strings const &strings)
Definition: KeyGeneration_test.cpp:320
ripple::RPC::WalletPropose_test::testRandomWallet
void testRandomWallet(std::optional< std::string > const &keyType)
Definition: KeyGeneration_test.cpp:100
ripple::RPC::common::master_seed_hex
static char const * master_seed_hex
Definition: KeyGeneration_test.cpp:51
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:932
ripple::TestSuite
Definition: TestSuite.h:28
ripple::RPC::WalletPropose_test::testRippleLibEd25519
void testRippleLibEd25519()
Definition: KeyGeneration_test.cpp:739
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::RPC::keypairForSignature
std::pair< PublicKey, SecretKey > keypairForSignature(Json::Value const &params, Json::Value &error)
Definition: RPCHelpers.cpp:849
ripple::TokenType::AccountPublic
@ AccountPublic
ripple::RPC::WalletPropose_test::testSecretWallet
Json::Value testSecretWallet(Json::Value const &params, key_strings const &s)
Definition: KeyGeneration_test.cpp:130
ripple::RPC::common::passphrase
static char const * passphrase
Definition: KeyGeneration_test.cpp:47
ripple::RPC::ed25519_strings
static const key_strings ed25519_strings
Definition: KeyGeneration_test.cpp:68
std::optional< std::string >
ripple::RPC::key_strings::passphrase
char const * passphrase
Definition: KeyGeneration_test.cpp:42
ripple::RPC::WalletPropose_test::testLegacyPassphrase
void testLegacyPassphrase(char const *value, std::optional< std::string > const &keyType, key_strings const &strings)
Definition: KeyGeneration_test.cpp:180
ripple::RPC::common::master_key
static char const * master_key
Definition: KeyGeneration_test.cpp:48
ripple::walletPropose
Json::Value walletPropose(Json::Value const &params)
Definition: WalletPropose.cpp:73
ripple::RPC::WalletPropose_test::testKeyType
void testKeyType(std::optional< std::string > const &keyType, key_strings const &strings)
Definition: KeyGeneration_test.cpp:211
ripple::RPC::key_strings::secret_key_hex
char const * secret_key_hex
Definition: KeyGeneration_test.cpp:41
ripple::RPC::WalletPropose_test::testSeed
void testSeed(std::optional< std::string > const &keyType, key_strings const &strings)
Definition: KeyGeneration_test.cpp:148
Json::Value
Represents a JSON value.
Definition: json_value.h:145
Json::Value::asString
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:469
ripple::RPC::key_strings::master_key
char const * master_key
Definition: KeyGeneration_test.cpp:36
ripple::RPC::key_strings::passphrase_warning
char const * passphrase_warning
Definition: KeyGeneration_test.cpp:43