Sealing: Encryption of Secrets #1
10 changed files with 691 additions and 132 deletions
455
Cargo.lock
generated
455
Cargo.lock
generated
|
|
@ -24,7 +24,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"generic-array",
|
||||
"generic-array 0.14.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -53,6 +53,18 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
|
|
@ -135,9 +147,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
|||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.8.1"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d6fd624c75e18b3b4c6b9caf42b1afe24437daaee904069137d8bab077be8b8"
|
||||
checksum = "de45108900e1f9b9242f7f2e254aa3e2c029c921c258fe9e6b4217eeebd54288"
|
||||
dependencies = [
|
||||
"axum-core",
|
||||
"bytes",
|
||||
|
|
@ -169,12 +181,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.5.0"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df1362f362fd16024ae199c1970ce98f9661bf5ef94b9808fee734bc3698b733"
|
||||
checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"futures-core",
|
||||
"http",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
|
|
@ -202,6 +214,12 @@ dependencies = [
|
|||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base16ct"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
|
|
@ -223,13 +241,25 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
"tap",
|
||||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"generic-array 0.14.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -329,13 +359,26 @@ version = "0.8.21"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
|
||||
dependencies = [
|
||||
"generic-array 0.14.7",
|
||||
"rand_core",
|
||||
"serdect",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"generic-array 0.14.7",
|
||||
"rand_core",
|
||||
"typenum",
|
||||
]
|
||||
|
|
@ -399,6 +442,20 @@ version = "0.15.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
||||
|
||||
[[package]]
|
||||
name = "ecdsa"
|
||||
version = "0.16.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
|
||||
dependencies = [
|
||||
"der",
|
||||
"digest",
|
||||
"elliptic-curve",
|
||||
"rfc6979",
|
||||
"signature",
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
|
|
@ -408,6 +465,41 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "elliptic-curve"
|
||||
version = "0.13.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"crypto-bigint",
|
||||
"digest",
|
||||
"ff",
|
||||
"generic-array 0.14.7",
|
||||
"group",
|
||||
"hkdf",
|
||||
"pkcs8",
|
||||
"rand_core",
|
||||
"sec1",
|
||||
"subtle",
|
||||
"tap",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "elliptic-curve-tools"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e48843edfbd0a370b3dd14cdbb4e446e9a8855311e6b2b57bf9a1fd1367bc317"
|
||||
dependencies = [
|
||||
"elliptic-curve",
|
||||
"heapless",
|
||||
"hex",
|
||||
"multiexp",
|
||||
"serde",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.3"
|
||||
|
|
@ -475,6 +567,17 @@ version = "2.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||
|
||||
[[package]]
|
||||
name = "ff"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"rand_core",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flume"
|
||||
version = "0.11.1"
|
||||
|
|
@ -507,6 +610,12 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.31"
|
||||
|
|
@ -587,6 +696,16 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
|||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8c8444bc9d71b935156cc0ccab7f622180808af7867b1daae6547d773591703"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -618,6 +737,36 @@ version = "0.31.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "group"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
|
||||
dependencies = [
|
||||
"ff",
|
||||
"rand_core",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hash32"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.2"
|
||||
|
|
@ -635,7 +784,17 @@ version = "0.10.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"hashbrown 0.15.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
|
||||
dependencies = [
|
||||
"hash32",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -799,9 +958,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "icu_locid_transform_data"
|
||||
version = "1.5.0"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
|
||||
checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d"
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer"
|
||||
|
|
@ -823,9 +982,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "icu_normalizer_data"
|
||||
version = "1.5.0"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
|
||||
checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7"
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties"
|
||||
|
|
@ -844,9 +1003,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "icu_properties_data"
|
||||
version = "1.5.0"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
|
||||
checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2"
|
||||
|
||||
[[package]]
|
||||
name = "icu_provider"
|
||||
|
|
@ -904,7 +1063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
"hashbrown 0.15.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -913,7 +1072,7 @@ version = "0.1.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"generic-array 0.14.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -953,25 +1112,12 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "json-patch"
|
||||
version = "4.0.0"
|
||||
name = "keccak"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "159294d661a039f7644cea7e4d844e6b25aaf71c1ffe9d73a96d768c24b0faf4"
|
||||
checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654"
|
||||
dependencies = [
|
||||
"jsonptr",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonptr"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5a3cc660ba5d72bce0b3bb295bf20847ccbb40fd423f3f05b61273672e561fe"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1082,6 +1228,44 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multiexp"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25a383da1ae933078ddb1e4141f1dd617b512b4183779d6977e6451b0e644806"
|
||||
dependencies = [
|
||||
"ff",
|
||||
"group",
|
||||
"rustversion",
|
||||
"std-shims",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint-dig"
|
||||
version = "0.8.4"
|
||||
|
|
@ -1099,6 +1283,16 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
|
|
@ -1125,6 +1319,17 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
|
|
@ -1146,9 +1351,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.1"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
|
|
@ -1156,6 +1361,18 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||
|
||||
[[package]]
|
||||
name = "p256"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b"
|
||||
dependencies = [
|
||||
"ecdsa",
|
||||
"elliptic-curve",
|
||||
"primeorder",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.2.1"
|
||||
|
|
@ -1278,7 +1495,16 @@ version = "0.2.21"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
"zerocopy 0.8.24",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "primeorder"
|
||||
version = "0.13.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6"
|
||||
dependencies = [
|
||||
"elliptic-curve",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1305,6 +1531,12 @@ version = "5.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
||||
|
||||
[[package]]
|
||||
name = "radium"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
|
|
@ -1373,6 +1605,16 @@ version = "0.8.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "rfc6979"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
|
||||
dependencies = [
|
||||
"hmac",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.14"
|
||||
|
|
@ -1457,9 +1699,9 @@ checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
|
|||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.0"
|
||||
version = "0.103.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f"
|
||||
checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
|
|
@ -1481,14 +1723,15 @@ dependencies = [
|
|||
"base64",
|
||||
"dotenvy",
|
||||
"env_logger",
|
||||
"json-patch",
|
||||
"log",
|
||||
"p256",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"time",
|
||||
"tokio",
|
||||
"tower",
|
||||
"vsss-rs",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
|
|
@ -1504,6 +1747,20 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "sec1"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"der",
|
||||
"generic-array 0.14.7",
|
||||
"pkcs8",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
|
|
@ -1558,6 +1815,16 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serdect"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.6"
|
||||
|
|
@ -1580,6 +1847,16 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha3"
|
||||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
|
|
@ -1680,7 +1957,7 @@ dependencies = [
|
|||
"futures-intrusive",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"hashbrown",
|
||||
"hashbrown 0.15.2",
|
||||
"hashlink",
|
||||
"indexmap",
|
||||
"log",
|
||||
|
|
@ -1693,7 +1970,7 @@ dependencies = [
|
|||
"serde_json",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
"thiserror 2.0.12",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
|
|
@ -1760,7 +2037,7 @@ dependencies = [
|
|||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"generic-array",
|
||||
"generic-array 0.14.7",
|
||||
"hex",
|
||||
"hkdf",
|
||||
"hmac",
|
||||
|
|
@ -1778,7 +2055,7 @@ dependencies = [
|
|||
"smallvec",
|
||||
"sqlx-core",
|
||||
"stringprep",
|
||||
"thiserror 2.0.12",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tracing",
|
||||
"whoami",
|
||||
|
|
@ -1816,7 +2093,7 @@ dependencies = [
|
|||
"smallvec",
|
||||
"sqlx-core",
|
||||
"stringprep",
|
||||
"thiserror 2.0.12",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tracing",
|
||||
"whoami",
|
||||
|
|
@ -1852,6 +2129,16 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "std-shims"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90e49360f31b0b75a6a82a5205c6103ea07a79a60808d44f5cc879d303337926"
|
||||
dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stringprep"
|
||||
version = "0.1.5"
|
||||
|
|
@ -1897,6 +2184,12 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.19.1"
|
||||
|
|
@ -1910,33 +2203,13 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||
dependencies = [
|
||||
"thiserror-impl 2.0.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2196,6 +2469,25 @@ version = "0.9.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "vsss-rs"
|
||||
version = "5.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fec4ebcc5594130c31b49594d55c0583fe80621f252f570b222ca4845cafd3cf"
|
||||
dependencies = [
|
||||
"crypto-bigint",
|
||||
"elliptic-curve",
|
||||
"elliptic-curve-tools",
|
||||
"generic-array 1.2.0",
|
||||
"hex",
|
||||
"num",
|
||||
"rand_core",
|
||||
"serde",
|
||||
"sha3",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
|
|
@ -2405,6 +2697,15 @@ version = "0.5.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
|
||||
dependencies = [
|
||||
"tap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.7.5"
|
||||
|
|
@ -2429,13 +2730,33 @@ dependencies = [
|
|||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"zerocopy-derive 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
"zerocopy-derive 0.8.24",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
23
Cargo.toml
23
Cargo.toml
|
|
@ -4,19 +4,16 @@ version = "0.1.0"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.21"
|
||||
env_logger = "0.11.3"
|
||||
zeroize = { version = "1.7.0", features = ["zeroize_derive"] }
|
||||
time = { version = "0.3.39", features = ["serde", "formatting"]}
|
||||
tokio = { version = "1.37.0", features = ["full"] }
|
||||
log = "0.4.27"
|
||||
env_logger = "0.11.7"
|
||||
zeroize = { version = "1.8.1", features = ["zeroize_derive"] }
|
||||
time = { version = "0.3.41", features = ["serde", "formatting"]}
|
||||
tokio = { version = "1.44.1", features = ["full"] }
|
||||
tower = { version = "0.5.2", features = [] }
|
||||
axum = "0.8.1"
|
||||
serde = "1.0.201"
|
||||
serde_json = "1.0.117"
|
||||
json-patch = "4.0.0"
|
||||
# serde_with = "3.8.1"
|
||||
axum = "0.8.3"
|
||||
serde = "1.0.219"
|
||||
serde_json = "1.0.140"
|
||||
dotenvy = "0.15.7"
|
||||
aes-gcm-siv = "0.11.1"
|
||||
base64 = "0.22.1"
|
||||
|
||||
# utoipa = { version = "4.2.0", features = ["axum_extras"] }
|
||||
|
|
@ -30,6 +27,10 @@ sqlx = { version = "0.8.3", features = [
|
|||
"time"
|
||||
] }
|
||||
|
||||
aes-gcm-siv = "0.11.1"
|
||||
vsss-rs = { version = "5.1.0", default-features = false, features = ["zeroize", "std"] }
|
||||
p256 = { version = "0.13.2", default-features = false, features = ["std", "ecdsa"] }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import (
|
|||
// vault "github.com/openbao/openbao/api/v2"
|
||||
)
|
||||
|
||||
var client *vault.Client
|
||||
var Client *vault.Client
|
||||
var ctx context.Context
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
|
|
@ -23,35 +23,49 @@ func TestMain(m *testing.M) {
|
|||
|
||||
config := vault.DefaultConfig()
|
||||
config.Address = "http://localhost:8200"
|
||||
config.Timeout = 30*time.Second
|
||||
config.Timeout = 30 * time.Second
|
||||
|
||||
// prepare a client with the given base address
|
||||
client, err = vault.NewClient(config)
|
||||
Client, err = vault.NewClient(config)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to initialize Vault client: %v", err)
|
||||
}
|
||||
log.Println("client prepared")
|
||||
|
||||
// authenticate with a root token (insecure)
|
||||
client.SetToken("my-token")
|
||||
Client.SetToken("my-token")
|
||||
|
||||
exitCode := m.Run() // run all tests and get code
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
// Requires in-code portions
|
||||
func TestUnseal(t *testing.T) {
|
||||
abc := []string{
|
||||
"eyJpIjpbMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwxXSwidiI6WzE4OCw2NiwxMTksMTQ0LDE1OSw3MCw4NiwxMTUsMTIwLDI1MywxMjQsOTYsMTM5LDk0LDQ1LDE2NiwyMTMsMzYsMTE1LDU4LDg5LDE0OCw2MCwyOCwxNTAsMTE2LDU3LDg5LDIwMCw5NywxNDYsMjEzXX0=",
|
||||
"eyJpIjpbMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwyXSwidiI6WzE1OCwyNDQsNzEsOTUsMTIyLDEzOCwyNDEsMjEzLDQ1LDE1NiwxMTgsNCwxNzYsNiwxNTcsMTkyLDE2MSwxNjEsNDMsMTc1LDE5NSw4NywxODAsMTAwLDE1NiwxNCwxNDgsMTUsMTc4LDkwLDY3LDExOF19",
|
||||
}
|
||||
for i := range abc {
|
||||
if _, err := Client.Sys().Unseal(abc[i]); err != nil {
|
||||
t.Fatal("Error unsealing", err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func kv2Write(t *testing.T, mount string, path string) {
|
||||
data := map[string]any{
|
||||
"password1": "123abc",
|
||||
"password2": "horse horse horse battery staple correct",
|
||||
}
|
||||
t.Logf("Attempting to write to KV2 %s path %s:\t", mount, path)
|
||||
v, err := client.KVv2(mount).Put(ctx, path, data)
|
||||
v, err := Client.KVv2(mount).Put(ctx, path, data)
|
||||
if err != nil {
|
||||
t.Fatal("ERROR writing secret:\n\t", err)
|
||||
}
|
||||
t.Log("Success (unchecked)\n\t", v)
|
||||
|
||||
res, err := client.KVv2(mount).Get(ctx, path)
|
||||
res, err := Client.KVv2(mount).Get(ctx, path)
|
||||
if err != nil {
|
||||
t.Fatal("ERROR checking/reading secret (request failed)\n\t", err)
|
||||
}
|
||||
|
|
@ -65,11 +79,11 @@ func kv2Write(t *testing.T, mount string, path string) {
|
|||
}
|
||||
|
||||
func kv2Delete(t *testing.T, mount string, path string) {
|
||||
err := client.KVv2(mount).Delete(ctx, path) // currently disregarding modifier options
|
||||
err := Client.KVv2(mount).Delete(ctx, path) // currently disregarding modifier options
|
||||
if err != nil {
|
||||
log.Fatal("ERROR deleting secret:\n\t", err)
|
||||
}
|
||||
res, err := client.KVv2(mount).Get(ctx, path)
|
||||
res, err := Client.KVv2(mount).Get(ctx, path)
|
||||
if res != nil || err == nil {
|
||||
t.Fatal("ERROR checking/reading secret (request failed)\n\t", res, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ CREATE TABLE root_key (
|
|||
version INTEGER PRIMARY KEY CHECK ( version = 1 ),
|
||||
encrypted_key BLOB NOT NULL,
|
||||
nonce BLOB,
|
||||
type TEXT NOT NULL CHECK ( type IN ('dev_only', 'simple') )
|
||||
type TEXT NOT NULL CHECK ( type IN ('dev_only', 'simple', 'shamir') )
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#![forbid(unsafe_code)]
|
||||
|
||||
use axum::{
|
||||
extract::Request,
|
||||
http::StatusCode,
|
||||
|
|
@ -50,8 +52,10 @@ async fn main() {
|
|||
|
||||
if !storage::sealing::prepare_unseal(&pool).await {
|
||||
// storage::sealing::init_insecure_in_db(&pool).await;
|
||||
let user_key = storage::sealing::simple::init_simple(&pool).await;
|
||||
warn!("New sealing password generated: {user_key}");
|
||||
let user_key = storage::sealing::shamir::init_shamir(&pool, 2, 5).await;
|
||||
let success = storage::sealing::prepare_unseal(&pool).await;
|
||||
warn!("New sealing password generated: ");
|
||||
assert!(success, "Vault ought to have been initialized just now but it is not.");
|
||||
}
|
||||
|
||||
warn!("Listening on {}", listen_addr.to_string());
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
pub mod simple;
|
||||
pub mod shamir;
|
||||
|
||||
use aes_gcm_siv::{
|
||||
AeadCore, Aes256GcmSiv, KeyInit,
|
||||
|
|
@ -15,9 +16,10 @@ enum KeyEnum {
|
|||
MainKey(Vec<u8>),
|
||||
/// Encrypted with single secret (protected_rk, nonce)
|
||||
Simple(Vec<u8>, Vec<u8>),
|
||||
// Shamir's Secret Sharing
|
||||
Shamir(Vec<u8>, Vec<u8>),
|
||||
/// Unknown or not initialized
|
||||
Uninitialized,
|
||||
// ShamirPortion(Vec<String>),
|
||||
}
|
||||
|
||||
static ROOT_KEY_MAYBE: RwLock<KeyEnum> = RwLock::const_new(KeyEnum::Uninitialized);
|
||||
|
|
@ -75,6 +77,12 @@ pub async fn prepare_unseal(pool: &DbPool) -> bool {
|
|||
v.nonce.expect("Simple encryption but the nonce is missing"),
|
||||
);
|
||||
}
|
||||
"shamir" => {
|
||||
*lock = KeyEnum::Shamir(
|
||||
v.encrypted_key,
|
||||
v.nonce.expect("Simple encryption but the nonce is missing"),
|
||||
);
|
||||
}
|
||||
_ => panic!("Unknown root key type in database"),
|
||||
}
|
||||
true
|
||||
|
|
@ -130,6 +138,7 @@ pub async fn sealing_status() {
|
|||
KeyEnum::MainKey(_) => todo!(),
|
||||
KeyEnum::Simple(_, _) => todo!(),
|
||||
KeyEnum::Uninitialized => todo!(),
|
||||
KeyEnum::Shamir(_, _) => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -148,6 +157,35 @@ pub async fn provide_key(key: String) {
|
|||
error!("Cannot process provided key when the vault is uninitialized");
|
||||
return;
|
||||
}
|
||||
KeyEnum::Shamir(protected_rk, nonce) => {
|
||||
let rk = shamir::unseal(protected_rk, key, nonce).await;
|
||||
match rk {
|
||||
Ok(rk) => KeyEnum::MainKey(rk),
|
||||
Err(e) => {
|
||||
match e {
|
||||
vsss_rs::Error::SharingMinThreshold => {
|
||||
info!("Shamir portion provided. Sharing threshold not reached.")
|
||||
},
|
||||
vsss_rs::Error::SharingLimitLessThanThreshold => unreachable!(),
|
||||
vsss_rs::Error::InvalidSizeRequest => todo!(),
|
||||
vsss_rs::Error::SharingInvalidIdentifier => todo!(),
|
||||
vsss_rs::Error::SharingDuplicateIdentifier => {
|
||||
warn!("The supplied Shamir portion is already known. Duplication ignored.")
|
||||
},
|
||||
vsss_rs::Error::SharingMaxRequest => todo!(),
|
||||
vsss_rs::Error::InvalidShare => todo!(),
|
||||
vsss_rs::Error::InvalidGenerator(_) => todo!(),
|
||||
vsss_rs::Error::InvalidSecret => todo!(),
|
||||
vsss_rs::Error::InvalidShareConversion => todo!(),
|
||||
vsss_rs::Error::NotImplemented => todo!(),
|
||||
vsss_rs::Error::InvalidShareElement => todo!(),
|
||||
vsss_rs::Error::NotEnoughShareIdentifiers => todo!(),
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
// todo!()
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
152
src/storage/sealing/shamir.rs
Normal file
152
src/storage/sealing/shamir.rs
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
use aes_gcm_siv::{
|
||||
AeadCore, Aes256GcmSiv, KeyInit,
|
||||
aead::{Aead, OsRng, generic_array::GenericArray},
|
||||
};
|
||||
use base64::{Engine, prelude::BASE64_STANDARD};
|
||||
use log::warn;
|
||||
use p256::{NonZeroScalar, Scalar, SecretKey};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use tokio::sync::RwLock;
|
||||
use vsss_rs::{
|
||||
DefaultShare, Error as VsssErr, IdentifierPrimeField, ReadableShareSet, ShareElement, ValuePrimeField
|
||||
};
|
||||
use zeroize::ZeroizeOnDrop;
|
||||
|
||||
use crate::DbPool;
|
||||
|
||||
use super::write_new_root_key;
|
||||
|
||||
type P256Share = DefaultShare<IdentifierPrimeField<Scalar>, IdentifierPrimeField<Scalar>>;
|
||||
|
||||
static PORTIONS: RwLock<Vec<ShamirPortion>> = RwLock::const_new(Vec::new());
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize, ZeroizeOnDrop)]
|
||||
/// Differs from [P256Share] by containing Strings
|
||||
pub struct ShamirPortion {
|
||||
#[serde(rename = "i")]
|
||||
pub identifier: Vec<u8>,
|
||||
#[serde(rename = "v")]
|
||||
pub value: Vec<u8>,
|
||||
}
|
||||
|
||||
/// Shamir Secret Sharing does not verify a portion for validity,
|
||||
/// unlike Feldman Verified Secret Sharing, which is built on Shamir.
|
||||
/// "Validation" happens by attempting to decrypt the root key.
|
||||
///
|
||||
/// # Returns
|
||||
/// List of key portions
|
||||
pub async fn init_shamir(pool: &DbPool, threshold: usize, limit: usize) -> Vec<String> {
|
||||
let root_key = Aes256GcmSiv::generate_key(&mut OsRng);
|
||||
let nonce: GenericArray<u8, <Aes256GcmSiv as AeadCore>::NonceSize> =
|
||||
Aes256GcmSiv::generate_nonce(&mut OsRng); // 96-bits; unique per message
|
||||
let root_key = root_key.as_slice().to_owned();
|
||||
|
||||
let (user_key, protected_rk) = {
|
||||
let key = Aes256GcmSiv::generate_key(&mut OsRng);
|
||||
let cipher = Aes256GcmSiv::new(&key);
|
||||
let nonce: &[u8] = nonce.as_slice();
|
||||
debug_assert_eq!(nonce.len(), 12);
|
||||
let nonce = aes_gcm_siv::aead::generic_array::GenericArray::from_slice(nonce);
|
||||
let enc = cipher.encrypt(nonce, root_key.as_slice()).unwrap();
|
||||
(key, enc)
|
||||
};
|
||||
|
||||
let portions = share_keys(&mut OsRng, threshold, limit, &user_key);
|
||||
|
||||
log::debug!("Shared Keys: {portions:?}");
|
||||
|
||||
write_new_root_key(pool, protected_rk, "shamir", Some(nonce.as_slice())).await;
|
||||
portions
|
||||
}
|
||||
|
||||
pub async fn unseal(protected_rk: &Vec<u8>, key: String, nonce: &[u8]) -> Result<Vec<u8>, VsssErr> {
|
||||
let key = BASE64_STANDARD.decode(key).unwrap();
|
||||
let key_portion: ShamirPortion = serde_json::from_slice(&key).unwrap();
|
||||
|
||||
let mut portions = PORTIONS.write().await;
|
||||
if portions.contains(&key_portion) {
|
||||
return Err(VsssErr::SharingDuplicateIdentifier);
|
||||
}
|
||||
portions.push(key_portion);
|
||||
|
||||
let abc = match join_keys(&*portions) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
.to_bytes();
|
||||
|
||||
let cipher = Aes256GcmSiv::new_from_slice(&abc).unwrap();
|
||||
debug_assert_eq!(nonce.len(), 12);
|
||||
let nonce = aes_gcm_siv::aead::generic_array::GenericArray::from_slice(nonce);
|
||||
let root_key = cipher.decrypt(nonce, protected_rk.as_ref());
|
||||
match root_key {
|
||||
Ok(v) => return Ok(v),
|
||||
Err(_) => {
|
||||
// Err is opaque on purpose
|
||||
todo!("Error: While the threshold is reached, at least one portion is invalid. TODO: reset advised")
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a Vec of Base64 encoded JSON-wrapped identifier-value pairs
|
||||
fn share_keys(
|
||||
mut osrng: &mut OsRng,
|
||||
threshold: usize,
|
||||
limit: usize,
|
||||
root_key: &[u8],
|
||||
) -> Vec<String> {
|
||||
log::debug!("RK: {root_key:?}");
|
||||
assert!(
|
||||
threshold <= limit,
|
||||
"Threshold cannot be higher than the number of shares (limit)"
|
||||
);
|
||||
|
||||
let rk_array = GenericArray::from_slice(root_key);
|
||||
let rk_scalar = NonZeroScalar::from_repr(*rk_array).unwrap();
|
||||
let shared_secret = IdentifierPrimeField(*rk_scalar.as_ref());
|
||||
let res =
|
||||
vsss_rs::shamir::split_secret::<P256Share>(threshold, limit, &shared_secret, &mut osrng);
|
||||
|
||||
res.unwrap()
|
||||
.iter()
|
||||
.map(|f| {
|
||||
BASE64_STANDARD.encode(
|
||||
json!(ShamirPortion {
|
||||
identifier: f.identifier.to_vec(),
|
||||
value: f.value.to_vec(),
|
||||
})
|
||||
.to_string(),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn join_keys(shares: &Vec<ShamirPortion>) -> Result<SecretKey, vsss_rs::Error> {
|
||||
let shares: Vec<P256Share> = shares
|
||||
.iter()
|
||||
.map(|portion| P256Share {
|
||||
identifier: IdentifierPrimeField::<Scalar>::from_slice(&portion.identifier).unwrap(),
|
||||
value: ValuePrimeField::<Scalar>::from_slice(&portion.value).unwrap(),
|
||||
})
|
||||
.collect();
|
||||
let scalar = shares.combine()?;
|
||||
let nzs_dup = NonZeroScalar::from_repr(scalar.0.into()).unwrap();
|
||||
let sk_dup = SecretKey::from(nzs_dup);
|
||||
Ok(sk_dup)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn split_and_join() {
|
||||
let root_key = Aes256GcmSiv::generate_key(&mut OsRng);
|
||||
let root_key = root_key.as_slice().to_owned();
|
||||
let kps = share_keys(&mut OsRng, 2, 5, &root_key);
|
||||
|
||||
let kps: Vec<_> = kps.iter().map(|f| {
|
||||
let b = BASE64_STANDARD.decode(f).unwrap();
|
||||
serde_json::from_slice(&b).unwrap()
|
||||
}).collect();
|
||||
let k = join_keys(&kps).unwrap();
|
||||
|
||||
assert_eq!(root_key, k.to_bytes().as_slice());
|
||||
}
|
||||
51
src/sys.rs
51
src/sys.rs
|
|
@ -1,49 +1,16 @@
|
|||
use axum::{
|
||||
extract::State, routing::{get, post}, Json, Router
|
||||
};
|
||||
use serde::Deserialize;
|
||||
mod root_generation;
|
||||
mod sealing;
|
||||
|
||||
use crate::storage::{DbPool, sealing};
|
||||
use axum::Router;
|
||||
use root_generation::root_generation;
|
||||
use sealing::sealing_routes;
|
||||
|
||||
use crate::storage::DbPool;
|
||||
|
||||
/// System routes
|
||||
pub fn sys_router(pool: DbPool) -> Router<DbPool> {
|
||||
Router::new()
|
||||
.route("/seal", post(seal_post))
|
||||
.route("/seal-status", get(seal_status_get))
|
||||
.route("/unseal", post(unseal_post))
|
||||
.merge(sealing_routes())
|
||||
.merge(root_generation())
|
||||
.with_state(pool)
|
||||
}
|
||||
|
||||
async fn seal_post(State(pool): State<DbPool>) {
|
||||
sealing::reseal(&pool).await;
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct UnsealRequest {
|
||||
/// Required, unless `reset` is true
|
||||
pub key: Option<String>,
|
||||
#[serde(default)]
|
||||
/// Specifies if previously-provided unseal keys are discarded and the unseal process is reset.
|
||||
pub reset: bool,
|
||||
|
||||
// #[serde(default)]
|
||||
// /// Used to migrate the seal from shamir to autoseal or autoseal to shamir. Must be provided on all unseal key calls.
|
||||
// pub migrate: bool,
|
||||
}
|
||||
|
||||
async fn unseal_post(State(pool): State<DbPool>, Json(req): Json<UnsealRequest>) -> Result<(), ()> {
|
||||
if req.reset {
|
||||
sealing::reseal(&pool).await;
|
||||
}
|
||||
|
||||
if let Some(key) = req.key {
|
||||
sealing::provide_key(key).await;
|
||||
} else if !req.reset {
|
||||
// No request key nor reset = bad request
|
||||
return Err(());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn seal_status_get(State(pool): State<DbPool>) {}
|
||||
|
|
|
|||
12
src/sys/root_generation.rs
Normal file
12
src/sys/root_generation.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
use axum::{Router, routing::post};
|
||||
|
||||
use crate::DbPool;
|
||||
|
||||
pub fn root_generation() -> Router<DbPool> {
|
||||
Router::new()
|
||||
// .route("/generate-root", get(get_root_generation_attempt))
|
||||
.route("/generate-root", post(generate_new_root))
|
||||
// .route("/generate-root", delete(cancel_generate_root))
|
||||
}
|
||||
|
||||
async fn generate_new_root() {}
|
||||
50
src/sys/sealing.rs
Normal file
50
src/sys/sealing.rs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
use axum::{
|
||||
extract::State, routing::{get, post, put}, Json, Router
|
||||
};
|
||||
use log::warn;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::storage::{DbPool, sealing};
|
||||
|
||||
pub fn sealing_routes() -> Router<DbPool> {
|
||||
Router::new()
|
||||
.route("/seal", post(seal_post))
|
||||
.route("/seal-status", get(seal_status_get))
|
||||
.route("/unseal", post(unseal_post))
|
||||
// WTF? Again? Its supposed to be POST but actually a PUT
|
||||
.route("/unseal", put(unseal_post))
|
||||
}
|
||||
|
||||
async fn seal_post(State(pool): State<DbPool>) {
|
||||
sealing::reseal(&pool).await;
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct UnsealRequest {
|
||||
/// Required, unless `reset` is true
|
||||
pub key: Option<String>,
|
||||
#[serde(default)]
|
||||
/// Specifies if previously-provided unseal keys are discarded and the unseal process is reset.
|
||||
pub reset: bool,
|
||||
// #[serde(default)]
|
||||
// /// Used to migrate the seal from shamir to autoseal or autoseal to shamir. Must be provided on all unseal key calls.
|
||||
// pub migrate: bool,
|
||||
}
|
||||
|
||||
async fn unseal_post(State(pool): State<DbPool>, Json(req): Json<UnsealRequest>) -> Result<(), ()> {
|
||||
if req.reset {
|
||||
warn!("Unsealing progress has been reset on unseal request");
|
||||
sealing::reseal(&pool).await;
|
||||
}
|
||||
|
||||
if let Some(key) = req.key {
|
||||
sealing::provide_key(key).await;
|
||||
} else if !req.reset {
|
||||
// No request key nor reset = bad request
|
||||
return Err(());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn seal_status_get(State(pool): State<DbPool>) {}
|
||||
Loading…
Reference in a new issue