From 1d3945fb284cfe6ec482d2f40165e21bf6d0387e Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Thu, 11 Jul 2024 16:58:50 -0400 Subject: [PATCH] fix!: specify scrypt params explicitly (#333) * fix!: specify scrypt params explicitly * update readme * fmt * another golden test * fmt * doc * updated tonic * update clap * set action * update readme * fix action * setup protoc * bump action version * submodule recurse * fix cli parsing * update readme * update tofn * enable help with clap --- .github/workflows/lint.yaml | 7 +- .github/workflows/test.yaml | 7 +- .gitmodules | 1 + Cargo.lock | 446 ++++++++++-------- Cargo.toml | 14 +- README.md | 24 +- src/config/mod.rs | 43 +- src/encrypted_sled/kv.rs | 59 ++- .../chacha20poly1305_kdf_known_vector.golden | 1 + .../encrypt_with_nonce_known_vector.golden | 56 +++ src/mnemonic/bip39_bindings.rs | 19 +- .../testdata/seed_known_vector.golden | 1 + src/multisig/key_presence.rs | 4 +- src/multisig/keygen.rs | 4 +- src/multisig/sign.rs | 4 +- 15 files changed, 452 insertions(+), 238 deletions(-) create mode 100644 src/encrypted_sled/testdata/chacha20poly1305_kdf_known_vector.golden create mode 100644 src/encrypted_sled/testdata/encrypt_with_nonce_known_vector.golden create mode 100644 src/mnemonic/testdata/seed_known_vector.golden diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 16b8339d..0888bd0e 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -10,7 +10,12 @@ jobs: - name: Checkout code and submodule uses: actions/checkout@v4 with: - submodules: recursive + submodules: 'recursive' + + - name: Install protoc + uses: arduino/setup-protoc@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install stable toolchain uses: actions-rs/toolchain@v1 diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index df676882..23a04217 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -10,7 +10,12 @@ jobs: - name: Checkout code and submodule uses: actions/checkout@v4 with: - submodules: recursive + submodules: 'recursive' + + - name: Install protoc + uses: arduino/setup-protoc@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install stable toolchain uses: actions-rs/toolchain@v1 diff --git a/.gitmodules b/.gitmodules index 13d65ddd..3a8c6f88 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ [submodule "proto"] path = proto url = https://github.com/axelarnetwork/grpc-protobuf.git + fetchRecurseSubmodules = true diff --git a/Cargo.lock b/Cargo.lock index 6b7a4785..8453d12b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,6 +36,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + [[package]] name = "anyhow" version = "1.0.86" @@ -61,7 +67,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.70", + "syn", ] [[package]] @@ -72,9 +78,15 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.70", + "syn", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "atty" version = "0.2.14" @@ -92,6 +104,53 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "axum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper 1.0.1", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.73" @@ -115,9 +174,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" @@ -253,26 +312,29 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.25" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" dependencies = [ - "bitflags 1.3.2", - "clap_lex", - "indexmap 1.9.3", - "once_cell", - "textwrap", + "clap_builder", ] [[package]] -name = "clap_lex" -version = "0.2.4" +name = "clap_builder" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" dependencies = [ - "os_str_bytes", + "anstyle", + "clap_lex", ] +[[package]] +name = "clap_lex" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" + [[package]] name = "const-oid" version = "0.9.6" @@ -364,7 +426,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.70", + "syn", ] [[package]] @@ -374,20 +436,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", - "der_derive", "zeroize", ] [[package]] -name = "der_derive" -version = "0.7.3" +name = "diff" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.70", -] +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] name = "digest" @@ -441,7 +497,6 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8", "signature", ] @@ -454,9 +509,7 @@ dependencies = [ "curve25519-dalek", "ed25519", "rand_core", - "serde", "sha2", - "signature", "subtle", "zeroize", ] @@ -621,6 +674,21 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[package]] +name = "goldie" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa70c42797cac60e6182e00f33f629212e02ba80d67e8a976f6168b57568d78e" +dependencies = [ + "anyhow", + "once_cell", + "pretty_assertions", + "serde", + "serde_json", + "upon", + "yansi 1.0.1", +] + [[package]] name = "group" version = "0.13.0" @@ -634,20 +702,20 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.26" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", "http", "indexmap 2.2.6", "slab", "tokio", - "tokio-util 0.7.11", + "tokio-util", "tracing", ] @@ -665,12 +733,9 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" -version = "0.3.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -687,6 +752,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hmac" version = "0.12.1" @@ -697,33 +768,36 @@ dependencies = [ ] [[package]] -name = "home" -version = "0.5.9" +name = "http" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ - "windows-sys 0.52.0", + "bytes", + "fnv", + "itoa", ] [[package]] -name = "http" -version = "0.2.12" +name = "http-body" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "fnv", - "itoa", + "http", ] [[package]] -name = "http-body" -version = "0.4.6" +name = "http-body-util" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", + "futures-util", "http", + "http-body", "pin-project-lite", ] @@ -741,13 +815,12 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.30" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", "h2", "http", @@ -756,23 +829,42 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] [[package]] name = "hyper-timeout" -version = "0.4.1" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", "hyper", "pin-project-lite", + "socket2", "tokio", - "tokio-io-timeout", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -902,12 +994,24 @@ dependencies = [ "regex-automata 0.1.10", ] +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "miniz_oxide" version = "0.7.4" @@ -990,12 +1094,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "os_str_bytes" -version = "6.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" - [[package]] name = "overload" version = "0.1.1" @@ -1090,7 +1188,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.70", + "syn", ] [[package]] @@ -1105,16 +1203,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - [[package]] name = "poly1305" version = "0.8.0" @@ -1132,6 +1220,26 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi 0.5.1", +] + +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -1143,9 +1251,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.9.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" +checksum = "e13db3d3fde688c61e2446b4d843bc27a7e8af269a69440c0308021dc92333cc" dependencies = [ "bytes", "prost-derive", @@ -1153,44 +1261,44 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.9.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62941722fb675d463659e49c4f3fe1fe792ff24fe5bbaa9c08cd3b98a1c354f5" +checksum = "5bb182580f71dd070f88d01ce3de9f4da5021db7115d2e1c3605a754153b77c1" dependencies = [ "bytes", "heck", "itertools", - "lazy_static", "log", "multimap", + "once_cell", "petgraph", + "prettyplease", "prost", "prost-types", "regex", + "syn", "tempfile", - "which", ] [[package]] name = "prost-derive" -version = "0.9.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" +checksum = "18bec9b0adc4eba778b33684b7ba3e7137789434769ee3ce3930463ef904cfca" dependencies = [ "anyhow", "itertools", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "prost-types" -version = "0.9.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a" +checksum = "cee5168b05f49d4b0ca581206eb14a7b22fafd963efe729ac48eb03266e25cc2" dependencies = [ - "bytes", "prost", ] @@ -1371,6 +1479,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + [[package]] name = "ryu" version = "1.0.18" @@ -1443,7 +1557,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.70", + "syn", ] [[package]] @@ -1547,16 +1661,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - [[package]] name = "subtle" version = "2.6.1" @@ -1565,9 +1669,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16" dependencies = [ "proc-macro2", "quote", @@ -1575,15 +1679,16 @@ dependencies = [ ] [[package]] -name = "syn" -version = "2.0.70" +name = "sync_wrapper" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" [[package]] name = "sysinfo" @@ -1625,12 +1730,6 @@ dependencies = [ "whoami", ] -[[package]] -name = "textwrap" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" - [[package]] name = "thiserror" version = "1.0.61" @@ -1648,7 +1747,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.70", + "syn", ] [[package]] @@ -1697,13 +1796,12 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tofn" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f56caeee0bb85743d8b05e84d71877cd2eb40908a2d17456f7aceededade1ab" +checksum = "255a99b697179124254f23d05c2bc394276ba870791d99a9f5896f7f60d40eb9" dependencies = [ "bincode", "crypto-bigint", - "der", "ecdsa", "ed25519", "ed25519-dalek", @@ -1727,6 +1825,8 @@ dependencies = [ "clap", "dirs", "futures-util", + "goldie", + "hex", "lazy_static", "log", "prost", @@ -1767,16 +1867,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-macros" version = "2.3.0" @@ -1785,7 +1875,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.70", + "syn", ] [[package]] @@ -1799,20 +1889,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-util" -version = "0.6.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-util" version = "0.7.11" @@ -1828,45 +1904,45 @@ dependencies = [ [[package]] name = "tonic" -version = "0.6.2" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff08f4649d10a70ffa3522ca559031285d8e421d727ac85c60825761818f5d0a" +checksum = "f738b6a169a29bca4e39656db89c44a08e09c5b700b896ee9e7459f0652e81dd" dependencies = [ "async-stream", "async-trait", + "axum", "base64", "bytes", - "futures-core", - "futures-util", "h2", "http", "http-body", + "http-body-util", "hyper", "hyper-timeout", + "hyper-util", "percent-encoding", "pin-project", "prost", - "prost-derive", + "socket2", "tokio", "tokio-stream", - "tokio-util 0.6.10", "tower", "tower-layer", "tower-service", "tracing", - "tracing-futures", ] [[package]] name = "tonic-build" -version = "0.6.2" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9403f1bafde247186684b230dc6f38b5cd514584e8bec1dd32514be4745fa757" +checksum = "690943cc223adcdd67bb597a2e573ead1b88e999ba37528fe8e6356bf44b29b6" dependencies = [ + "prettyplease", "proc-macro2", "prost-build", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -1883,7 +1959,7 @@ dependencies = [ "rand", "slab", "tokio", - "tokio-util 0.7.11", + "tokio-util", "tower-layer", "tower-service", "tracing", @@ -1907,7 +1983,6 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1921,7 +1996,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.70", + "syn", ] [[package]] @@ -1934,16 +2009,6 @@ dependencies = [ "valuable", ] -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project", - "tracing", -] - [[package]] name = "tracing-log" version = "0.2.0" @@ -2004,7 +2069,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.70", + "syn", ] [[package]] @@ -2035,10 +2100,10 @@ dependencies = [ ] [[package]] -name = "unicode-segmentation" -version = "1.11.0" +name = "unicode-width" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "universal-hash" @@ -2050,6 +2115,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "upon" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fe29601d1624f104fa9a35ea71a5f523dd8bd1cfc8c31f8124ad2b829f013c0" +dependencies = [ + "serde", + "unicode-ident", + "unicode-width", +] + [[package]] name = "valuable" version = "0.1.0" @@ -2104,7 +2180,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.70", + "syn", "wasm-bindgen-shared", ] @@ -2126,7 +2202,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.70", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2147,18 +2223,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - [[package]] name = "whoami" version = "1.5.1" @@ -2331,6 +2395,18 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "zeroize" version = "1.8.1" @@ -2348,5 +2424,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.70", + "syn", ] diff --git a/Cargo.toml b/Cargo.toml index 51404c5b..6b8459eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ description = "A cryptographic signing service, used by the Axelar network" keywords = ["cryptography", "blockchain", "axelar", "ecdsa", "ed25519"] [dependencies] -tofn = { version = "1.0" } +tofn = { version = "1.1" } # logging log = { version = "0.4",default-features = false } @@ -17,7 +17,7 @@ tracing-subscriber = { version = "0.3", features = ["json", "env-filter"] } atty = { version = "0.2", default-features = false } # CLI args -clap = { version = "3.2", default-features = false, features = ["std", "cargo", "env"] } +clap = { version = "4.5", default-features = false, features = ["std", "cargo", "env", "string", "help"] } # kv store sled = { version = "0.34", default-features = false } @@ -31,8 +31,8 @@ rpassword = { version = "7.3", default-features = false } scrypt = { version = "0.11", default-features = false, features = ["std"] } # gRPC server -tonic = { version = "0.6" } # ensure tonic-build version matches this -prost = { version = "0.9" } +tonic = { version = "0.12" } # ensure tonic-build version matches this +prost = { version = "0.13" } # async runtime tokio = { version = "1.38", features = ["rt-multi-thread", "macros", "signal", "net", "sync"], default-features = false } @@ -48,14 +48,14 @@ thiserror = { version = "1.0", default-features = false } anyhow = { version = "1.0", default-features = false } [build-dependencies] -tonic-build = { version = "0.6" } +tonic-build = { version = "0.12" } [dev-dependencies] lazy_static = { version = "1.5", default-features = false} -# enable logging for tests tracing-test = { version = "0.2", default-features = false } - testdir = { version = "0.9", default-features = false } +goldie = { version = "0.5" } +hex = { version = "0.4" } # Don't abort in case there is a panic to clean up data [profile.dev] diff --git a/README.md b/README.md index 85ed5c30..4e725f36 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,20 @@ Tofnd is a [gRPC](https://grpc.io/) server written in Rust that wraps the [tofn] ## Setup -The gRPC protobuf file is a separate [submodule](https://github.com/axelarnetwork/grpc-protobuf/). To fetch it, please be sure that the `--recursive` flag is enabled: - ```bash git clone git@github.com:axelarnetwork/tofnd.git --recursive ``` +Install `protoc` + +```bash +# Ubuntu +sudo apt install protobuf-compiler + +# MacOS +brew install protobuf +``` + ## Build binaries Pre-built releases can be found [here](https://github.com/axelarnetwork/tofnd/releases) @@ -20,6 +28,18 @@ To build yourself, run: cargo build --release --locked ``` +Run tests: + +```bash +cargo test --release +``` + +Generate golden files for relevant tests: + +```bash +GOLDIE_UPDATE=1 cargo test --release +``` + ## Running the server ```bash diff --git a/src/config/mod.rs b/src/config/mod.rs index 0f72df95..e5f2beb7 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use clap::{builder::PossibleValuesParser, crate_version, Arg, Command}; +use clap::{builder::PossibleValuesParser, crate_version, value_parser, Arg, ArgAction, Command}; // error handling use crate::{encrypted_sled::PasswordMethod, mnemonic::Cmd, TofndResult}; @@ -11,14 +11,17 @@ const DEFAULT_PATH_ROOT: &str = ".tofnd"; const TOFND_HOME_ENV_VAR: &str = "TOFND_HOME"; const DEFAULT_MNEMONIC_CMD: &str = "existing"; const DEFAULT_IP: &str = "127.0.0.1"; -const DEFAULT_PORT: u16 = 50051; +const DEFAULT_PORT: &str = "50051"; const AVAILABLE_MNEMONIC_CMDS: &[&str] = &["existing", "create", "import", "export", "rotate"]; // default path is ~/.tofnd -fn default_tofnd_dir() -> TofndResult { +fn default_tofnd_dir() -> TofndResult { Ok(dirs::home_dir() .ok_or_else(|| anyhow!("no home dir"))? - .join(DEFAULT_PATH_ROOT)) + .join(DEFAULT_PATH_ROOT) + .to_str() + .ok_or_else(|| anyhow!("can't convert default dir to str"))? + .into()) } // TODO: move to types.rs @@ -32,14 +35,6 @@ pub struct Config { } pub fn parse_args() -> TofndResult { - // need to use let to avoid dropping temporary value - let ip = &DEFAULT_IP.to_string(); - let port = &DEFAULT_PORT.to_string(); - let default_dir = default_tofnd_dir()?; - let default_dir = default_dir - .to_str() - .ok_or_else(|| anyhow!("can't convert default dir to str"))?; - let app = Command::new("tofnd") .about("A cryptographic signing service") .version(crate_version!()) @@ -48,14 +43,15 @@ pub fn parse_args() -> TofndResult { .long("address") .short('a') .required(false) - .default_value(ip), + .default_value(DEFAULT_IP), ) .arg( Arg::new("port") .long("port") .short('p') .required(false) - .default_value(port), + .value_parser(value_parser!(u16)) + .default_value(DEFAULT_PORT), ) .arg( Arg::new("no-password") @@ -64,7 +60,7 @@ pub fn parse_args() -> TofndResult { ) .long("no-password") .required(false) - .takes_value(false) + .action(ArgAction::SetTrue) .display_order(0), ) .arg( @@ -74,7 +70,6 @@ pub fn parse_args() -> TofndResult { .required(false) .default_value(DEFAULT_MNEMONIC_CMD) .value_parser(PossibleValuesParser::new(AVAILABLE_MNEMONIC_CMDS)) - .takes_value(true), ) .arg( Arg::new("directory") @@ -82,7 +77,7 @@ pub fn parse_args() -> TofndResult { .short('d') .required(false) .env(TOFND_HOME_ENV_VAR) - .default_value(default_dir), + .default_value(default_tofnd_dir()?), ); let matches = app.get_matches(); @@ -91,10 +86,9 @@ pub fn parse_args() -> TofndResult { .get_one::("ip") .ok_or_else(|| anyhow!("ip value"))? .clone(); - let port = matches - .get_one::("port") - .ok_or_else(|| anyhow!("port value"))? - .parse::()?; + let port = *matches + .get_one::("port") + .ok_or_else(|| anyhow!("port value"))?; let mnemonic_cmd = Cmd::from_string( matches .get_one::("mnemonic") @@ -104,9 +98,10 @@ pub fn parse_args() -> TofndResult { .get_one::("directory") .ok_or_else(|| anyhow!("directory value"))? .into(); - let password_method = match matches.contains_id("no-password") { - true => PasswordMethod::NoPassword, - false => PasswordMethod::Prompt, + let password_method = if matches.get_flag("no-password") { + PasswordMethod::NoPassword + } else { + PasswordMethod::Prompt }; Ok(Config { diff --git a/src/encrypted_sled/kv.rs b/src/encrypted_sled/kv.rs index 739322c8..04a4ce28 100644 --- a/src/encrypted_sled/kv.rs +++ b/src/encrypted_sled/kv.rs @@ -69,17 +69,23 @@ impl EncryptedDb { Ok(encrypted_db) } + /// Recommended default params. Should NOT be changed without a migration of the kvstore. + /// See [scrypt::Params] for more info. These are fixed instead of using [scrypt::Params::default()] + /// to avoid regression if the default recommendation changes. + fn scrypt_params() -> EncryptedDbResult { + scrypt::Params::new(15, 8, 1, 32).map_err(PasswordScryptParams) + } + fn chacha20poly1305_kdf( password: Password, salt: PasswordSalt, ) -> EncryptedDbResult { let mut output = chacha20poly1305::Key::default(); - // default params: log_n = 15, r = 8, p = 1 scrypt::scrypt( password.as_ref(), salt.as_ref(), - &scrypt::Params::default(), + &Self::scrypt_params()?, output.as_mut_slice(), )?; @@ -100,6 +106,18 @@ impl EncryptedDb { { let nonce = Self::generate_nonce(); + self.encrypt_with_nonce(value, nonce) + } + + /// create a new [EncryptedRecord] containing an encrypted value and a given nonce. + fn encrypt_with_nonce( + &self, + value: V, + nonce: chacha20poly1305::XNonce, + ) -> EncryptedDbResult + where + V: Into, + { let mut value = value.into().to_vec(); // encrypt value @@ -184,3 +202,40 @@ impl EncryptedDb { Ok(self.kv.flush()?) } } + +#[cfg(test)] +mod tests { + use chacha20poly1305::{KeyInit, XChaCha20Poly1305, XNonce}; + + use super::EncryptedDb; + use crate::encrypted_sled::{password::PasswordSalt, Password}; + + #[test] + fn chacha20poly1305_kdf_known_vector() { + let password = Password::from("test_password"); + let salt = PasswordSalt::from([2; 32]); + + let key = hex::encode(EncryptedDb::chacha20poly1305_kdf(password, salt).unwrap()); + + goldie::assert_json!(key); + } + + #[test] + fn encrypt_with_nonce_known_vector() { + // Create a mock EncryptedDb with a deterministic cipher + let mock_db = EncryptedDb { + kv: sled::Config::new().temporary(true).open().unwrap(), + cipher: XChaCha20Poly1305::new(&chacha20poly1305::Key::from([5u8; 32])), + }; + + let value = b"test_value"; + let nonce = XNonce::from([1u8; 24]); + + let encrypted_record = mock_db.encrypt_with_nonce(value, nonce).unwrap(); + + goldie::assert_json!(&encrypted_record); + + let decrypted_value = mock_db.decrypt_record_value(encrypted_record).unwrap(); + assert_eq!(decrypted_value.as_ref(), value); + } +} diff --git a/src/encrypted_sled/testdata/chacha20poly1305_kdf_known_vector.golden b/src/encrypted_sled/testdata/chacha20poly1305_kdf_known_vector.golden new file mode 100644 index 00000000..a2a9620b --- /dev/null +++ b/src/encrypted_sled/testdata/chacha20poly1305_kdf_known_vector.golden @@ -0,0 +1 @@ +"63799ab67f9e015ca29694e3df2d1ae66f5ac0aa886974378b9c424a9c7df885" \ No newline at end of file diff --git a/src/encrypted_sled/testdata/encrypt_with_nonce_known_vector.golden b/src/encrypted_sled/testdata/encrypt_with_nonce_known_vector.golden new file mode 100644 index 00000000..5f4c0193 --- /dev/null +++ b/src/encrypted_sled/testdata/encrypt_with_nonce_known_vector.golden @@ -0,0 +1,56 @@ +{ + "encrypted_value": [ + 98, + 227, + 247, + 125, + 18, + 128, + 210, + 249, + 235, + 248, + 0, + 112, + 6, + 3, + 156, + 239, + 40, + 46, + 208, + 108, + 246, + 75, + 59, + 68, + 48, + 2 + ], + "nonce": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ] +} \ No newline at end of file diff --git a/src/mnemonic/bip39_bindings.rs b/src/mnemonic/bip39_bindings.rs index f5a0ed20..23eaebc0 100644 --- a/src/mnemonic/bip39_bindings.rs +++ b/src/mnemonic/bip39_bindings.rs @@ -61,7 +61,7 @@ pub mod tests { #[traced_test] #[test] - fn test_create() { + fn create() { let entropy = bip39_new_w24(); let mnemonic = Mnemonic::from_entropy(&entropy.0, DEFAUT_LANG).unwrap(); let passphrase = mnemonic.phrase(); @@ -73,7 +73,7 @@ pub mod tests { #[traced_test] #[test] - fn test_from_entropy() { + fn from_entropy() { let ok_entropy = Entropy(vec![42; 16]); let err_entropy = Entropy(vec![42; 15]); @@ -83,17 +83,16 @@ pub mod tests { #[traced_test] #[test] - fn test_seed() { + fn seed_known_vector() { + // Expected output: https://github.com/maciejhirsz/tiny-bip39/blob/master/src/seed.rs#L102 let entropy = vec![ 0x33, 0xE4, 0x6B, 0xB1, 0x3A, 0x74, 0x6E, 0xA4, 0x1C, 0xDD, 0xE4, 0x5C, 0x90, 0x84, 0x6A, 0x79, ]; - // expected output as per https://github.com/maciejhirsz/tiny-bip39/blob/master/src/seed.rs#L102 - let expected_output = "0bde96f14c35a66235478e0c16c152fcaf6301e4d9a81d3febc50879fe7e5438e6a8dd3e39bdf3ab7b12d6b44218710e17d7a2844ee9633fab0e03d9a6c8569b"; - let actual_output = format!( - "{:x}", - bip39_seed(Entropy(entropy), Password("password".to_owned())).unwrap() - ); - assert_eq!(expected_output, &actual_output); + + let output = + hex::encode(bip39_seed(Entropy(entropy), Password("password".to_owned())).unwrap()); + + goldie::assert_json!(output); } } diff --git a/src/mnemonic/testdata/seed_known_vector.golden b/src/mnemonic/testdata/seed_known_vector.golden new file mode 100644 index 00000000..ceeddab7 --- /dev/null +++ b/src/mnemonic/testdata/seed_known_vector.golden @@ -0,0 +1 @@ +"0bde96f14c35a66235478e0c16c152fcaf6301e4d9a81d3febc50879fe7e5438e6a8dd3e39bdf3ab7b12d6b44218710e17d7a2844ee9633fab0e03d9a6c8569b" \ No newline at end of file diff --git a/src/multisig/key_presence.rs b/src/multisig/key_presence.rs index a614adde..f681bdbf 100644 --- a/src/multisig/key_presence.rs +++ b/src/multisig/key_presence.rs @@ -18,8 +18,8 @@ impl MultisigService { &self, request: proto::KeyPresenceRequest, ) -> TofndResult { - let algorithm = Algorithm::from_i32(request.algorithm) - .ok_or_else(|| anyhow!("Invalid algorithm: {}", request.algorithm))?; + let algorithm = Algorithm::try_from(request.algorithm) + .map_err(|_| anyhow!("Invalid algorithm: {}", request.algorithm))?; // check if mnemonic is available let _ = self diff --git a/src/multisig/keygen.rs b/src/multisig/keygen.rs index f1dac365..43d4a332 100644 --- a/src/multisig/keygen.rs +++ b/src/multisig/keygen.rs @@ -7,8 +7,8 @@ use anyhow::anyhow; impl MultisigService { pub(super) async fn handle_keygen(&self, request: &KeygenRequest) -> TofndResult> { - let algorithm = Algorithm::from_i32(request.algorithm) - .ok_or_else(|| anyhow!("Invalid algorithm: {}", request.algorithm))?; + let algorithm = Algorithm::try_from(request.algorithm) + .map_err(|_| anyhow!("Invalid algorithm: {}", request.algorithm))?; let secret_recovery_key = self.kv_manager.seed().await?; Ok( diff --git a/src/multisig/sign.rs b/src/multisig/sign.rs index 6a79446d..a79c0cea 100644 --- a/src/multisig/sign.rs +++ b/src/multisig/sign.rs @@ -9,8 +9,8 @@ use tofn::sdk::api::SecretRecoveryKey; impl MultisigService { pub(super) async fn handle_sign(&self, request: &SignRequest) -> TofndResult> { - let algorithm = Algorithm::from_i32(request.algorithm) - .ok_or_else(|| anyhow!("Invalid algorithm: {}", request.algorithm))?; + let algorithm = Algorithm::try_from(request.algorithm) + .map_err(|_| anyhow!("Invalid algorithm: {}", request.algorithm))?; // re-generate secret key from seed, then sign let secret_recovery_key = self