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