[wip] do a little validation of commit event blocks
This commit is contained in:
parent
34f09c8a3d
commit
e9bc95f98b
7 changed files with 484 additions and 16 deletions
299
Cargo.lock
generated
299
Cargo.lock
generated
|
@ -189,12 +189,24 @@ version = "0.2.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270"
|
||||
|
||||
[[package]]
|
||||
name = "base16ct"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.69.5"
|
||||
|
@ -288,17 +300,23 @@ dependencies = [
|
|||
"atrium-api",
|
||||
"bytes",
|
||||
"clap",
|
||||
"ecdsa",
|
||||
"fastwebsockets",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"ipld-core",
|
||||
"iroh-car",
|
||||
"k256",
|
||||
"multibase",
|
||||
"p256",
|
||||
"pin-project-lite",
|
||||
"qstring",
|
||||
"rustls",
|
||||
"serde",
|
||||
"serde_ipld_dagcbor",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"sled",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
|
@ -349,7 +367,7 @@ dependencies = [
|
|||
"multihash",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"unsigned-varint",
|
||||
"unsigned-varint 0.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -418,6 +436,12 @@ version = "1.0.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
|
@ -466,6 +490,18 @@ version = "0.8.20"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"rand_core",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
|
@ -502,6 +538,17 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.7.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"pem-rfc7468",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
|
@ -509,7 +556,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"const-oid",
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -518,12 +567,46 @@ version = "1.0.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[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.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[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",
|
||||
"group",
|
||||
"pem-rfc7468",
|
||||
"pkcs8",
|
||||
"rand_core",
|
||||
"sec1",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
|
@ -560,6 +643,16 @@ dependencies = [
|
|||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ff"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
|
@ -591,6 +684,21 @@ version = "1.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.31"
|
||||
|
@ -598,6 +706,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -606,6 +715,34 @@ version = "0.3.31"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.89",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.31"
|
||||
|
@ -624,10 +761,16 @@ version = "0.3.31"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -647,6 +790,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
|||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -672,6 +816,17 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[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 = "h2"
|
||||
version = "0.4.7"
|
||||
|
@ -709,6 +864,15 @@ version = "0.3.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.9"
|
||||
|
@ -856,6 +1020,22 @@ dependencies = [
|
|||
"serde_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iroh-car"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7f8cd4cb9aa083fba8b52e921764252d0b4dcb1cd6d120b809dbfe1106e81a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cid",
|
||||
"futures",
|
||||
"serde",
|
||||
"serde_ipld_dagcbor",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"unsigned-varint 0.7.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
|
@ -895,6 +1075,20 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "k256"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"ecdsa",
|
||||
"elliptic-curve",
|
||||
"once_cell",
|
||||
"sha2",
|
||||
"signature",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "langtag"
|
||||
version = "0.3.4"
|
||||
|
@ -1015,7 +1209,7 @@ checksum = "cc41f430805af9d1cf4adae4ed2149c759b877b01d909a1f40256188d09345d2"
|
|||
dependencies = [
|
||||
"core2",
|
||||
"serde",
|
||||
"unsigned-varint",
|
||||
"unsigned-varint 0.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1068,6 +1262,18 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[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_lot"
|
||||
version = "0.11.2"
|
||||
|
@ -1122,6 +1328,15 @@ version = "1.0.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "pem-rfc7468"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
|
@ -1160,6 +1375,16 @@ 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 = "ppv-lite86"
|
||||
version = "0.2.20"
|
||||
|
@ -1179,6 +1404,15 @@ dependencies = [
|
|||
"syn 2.0.89",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "primeorder"
|
||||
version = "0.13.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6"
|
||||
dependencies = [
|
||||
"elliptic-curve",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.92"
|
||||
|
@ -1298,6 +1532,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.8"
|
||||
|
@ -1383,6 +1627,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",
|
||||
"pkcs8",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.215"
|
||||
|
@ -1460,6 +1718,17 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
|
@ -1484,6 +1753,16 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simdutf8"
|
||||
version = "0.1.5"
|
||||
|
@ -1538,6 +1817,16 @@ version = "0.9.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
|
||||
[[package]]
|
||||
name = "spki"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"der",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
|
@ -1751,6 +2040,12 @@ version = "1.0.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||
|
||||
[[package]]
|
||||
name = "unsigned-varint"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105"
|
||||
|
||||
[[package]]
|
||||
name = "unsigned-varint"
|
||||
version = "0.8.0"
|
||||
|
|
|
@ -8,17 +8,23 @@ anyhow = "1.0.93"
|
|||
atrium-api = { version = "0.24.8", default-features = false, features = ["tokio"] }
|
||||
bytes = { version = "1.8.0", features = ["serde"] }
|
||||
clap = { version = "4.5.21", features = ["derive"] }
|
||||
ecdsa = { version = "0.16.9", features = ["verifying"] }
|
||||
fastwebsockets = { version = "0.8.0", features = ["hyper", "unstable-split", "upgrade"] }
|
||||
http-body-util = "0.1.2"
|
||||
hyper = { version = "1.5.1", features = ["client", "http1", "http2", "server"] }
|
||||
hyper-util = { version = "0.1.10", features = ["tokio", "server", "client", "http1", "http2"] }
|
||||
ipld-core = "0.4.1"
|
||||
iroh-car = "0.5.1"
|
||||
k256 = "0.13.4"
|
||||
multibase = "0.9.1"
|
||||
p256 = "0.13.2"
|
||||
pin-project-lite = "0.2.15"
|
||||
qstring = "0.7.2"
|
||||
rustls = "0.23.18"
|
||||
serde = { version = "1.0.215", features = ["derive"] }
|
||||
serde_ipld_dagcbor = "0.6.1"
|
||||
serde_json = "1.0.133"
|
||||
sha2 = "0.10.8"
|
||||
sled = { version = "0.34.7", features = ["compression"] }
|
||||
tokio = { version = "1.41.1", features = ["full"] }
|
||||
tokio-rustls = "0.26.0"
|
||||
|
|
|
@ -3,6 +3,7 @@ pub use app_state::*;
|
|||
|
||||
pub mod http;
|
||||
pub mod relay;
|
||||
pub mod repo;
|
||||
pub mod sequencer;
|
||||
pub mod tls;
|
||||
pub mod user;
|
||||
|
|
|
@ -25,6 +25,9 @@ struct Args {
|
|||
/// did:plc directory HTTPS host. defaults to plc.directory if unset
|
||||
#[arg(long)]
|
||||
plc_resolver: Option<String>,
|
||||
|
||||
#[arg(long)]
|
||||
drop_user_cache: bool,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -43,6 +46,10 @@ async fn main() -> Result<()> {
|
|||
.open()
|
||||
.expect("Failed to open database");
|
||||
|
||||
if args.drop_user_cache {
|
||||
let _ = db.drop_tree("users");
|
||||
}
|
||||
|
||||
let (event_tx, event_rx) = mpsc::channel(128);
|
||||
|
||||
let mut server = RelayServer::new(db, event_tx);
|
||||
|
|
|
@ -14,6 +14,7 @@ use tokio_rustls::rustls::pki_types::ServerName;
|
|||
|
||||
use crate::{
|
||||
http::{body_empty, HttpBody},
|
||||
repo::validate_commit,
|
||||
tls::open_tls_stream,
|
||||
user::{fetch_user, lookup_user},
|
||||
wire_proto::{StreamEvent, StreamEventHeader, StreamEventPayload},
|
||||
|
@ -116,6 +117,11 @@ impl DataServerSubscription {
|
|||
return Ok(None);
|
||||
}
|
||||
|
||||
if let Err(e) = validate_commit(&user, &event.data).await {
|
||||
tracing::warn!(did = %user.did, seq = %event.seq, err = ?e, "dropping commit that did not pass validation");
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
Ok(Some(StreamEventPayload::Commit(event)))
|
||||
}
|
||||
|
||||
|
|
119
src/repo/mod.rs
Normal file
119
src/repo/mod.rs
Normal file
|
@ -0,0 +1,119 @@
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use atrium_api::com::atproto::sync::subscribe_repos::CommitData;
|
||||
use bytes::Bytes;
|
||||
use ecdsa::signature::Verifier;
|
||||
use ipld_core::cid::Cid;
|
||||
use iroh_car::CarReader;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
use crate::user::User;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct UnsignedCommitNode {
|
||||
pub did: String,
|
||||
pub version: u8,
|
||||
pub prev: Option<Cid>,
|
||||
pub rev: String,
|
||||
pub data: Cid,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct SignedCommitNode {
|
||||
#[serde(flatten)]
|
||||
pub node: UnsignedCommitNode,
|
||||
pub sig: Bytes,
|
||||
}
|
||||
|
||||
pub async fn validate_commit(user: &User, commit: &CommitData) -> Result<()> {
|
||||
let mut car_reader = CarReader::new(commit.blocks.as_slice()).await?;
|
||||
let car_header = car_reader.header().clone();
|
||||
|
||||
let mut blocks = BTreeMap::new();
|
||||
while let Some((cid, cbor)) = car_reader.next_block().await? {
|
||||
let (hash_type, hash_digest, hash_len) = cid.hash().into_inner();
|
||||
if hash_type != 0x12 || hash_len != 32 {
|
||||
bail!(
|
||||
"unexpected cid type {:?} (expected sha-256 [id 18] with 32 bytes)",
|
||||
cid
|
||||
)
|
||||
}
|
||||
|
||||
let cid_display = cid.to_string_of_base(multibase::Base::Base32Lower)?;
|
||||
|
||||
let record_hash = Sha256::digest(&cbor);
|
||||
if &hash_digest[..32] != record_hash.as_slice() {
|
||||
bail!("cid doesn't match cbor hash: {}", &cid_display)
|
||||
}
|
||||
|
||||
blocks.insert(cid, cbor);
|
||||
}
|
||||
|
||||
/*
|
||||
let block_cids = blocks
|
||||
.keys()
|
||||
.filter_map(|cid| cid.to_string_of_base(multibase::Base::Base32Lower).ok())
|
||||
.collect::<Vec<_>>();
|
||||
dbg!(block_cids);
|
||||
let root_cids = car_header
|
||||
.roots()
|
||||
.iter()
|
||||
.filter_map(|cid| cid.to_string_of_base(multibase::Base::Base32Lower).ok())
|
||||
.collect::<Vec<_>>();
|
||||
dbg!(root_cids);
|
||||
*/
|
||||
|
||||
let signing_key = user
|
||||
.signing_key()
|
||||
.context("couldn't find signing key for user")?;
|
||||
let (_, signing_key) = multibase::decode(signing_key).unwrap();
|
||||
|
||||
for root in car_header.roots() {
|
||||
let cid_display = root.to_string_of_base(multibase::Base::Base32Lower)?;
|
||||
|
||||
let Some(block) = blocks.get(root) else {
|
||||
bail!("block did not exist: {}", &cid_display)
|
||||
};
|
||||
let commit: SignedCommitNode = serde_ipld_dagcbor::from_slice(block)
|
||||
.context("couldn't deserialize signed commit object")?;
|
||||
|
||||
if commit.node.did != user.did {
|
||||
bail!("did in car doesn't match repo did {}", &cid_display)
|
||||
}
|
||||
|
||||
let unsigned_data = serde_ipld_dagcbor::to_vec(&commit.node)?;
|
||||
if commit.sig.len() != 64 {
|
||||
bail!(
|
||||
"unexpected signature length {} (expected 64)",
|
||||
commit.sig.len()
|
||||
);
|
||||
}
|
||||
let r: [u8; 32] = commit.sig[..32].try_into().unwrap();
|
||||
let s: [u8; 32] = commit.sig[32..].try_into().unwrap();
|
||||
|
||||
match signing_key[..2] {
|
||||
[0xe7, 0x01] => {
|
||||
let key = k256::ecdsa::VerifyingKey::from_sec1_bytes(&signing_key[2..]).unwrap();
|
||||
let sig = k256::ecdsa::Signature::from_scalars(r, s).unwrap();
|
||||
key.verify(&unsigned_data, &sig)
|
||||
.context("failed to verify k256")
|
||||
}
|
||||
[0x80, 0x24] => {
|
||||
let key = p256::ecdsa::VerifyingKey::from_sec1_bytes(&signing_key[2..]).unwrap();
|
||||
let sig = p256::ecdsa::Signature::from_scalars(r, s).unwrap();
|
||||
key.verify(&unsigned_data, &sig)
|
||||
.context("failed to verify p256")
|
||||
}
|
||||
_ => Err(anyhow::anyhow!(
|
||||
"unknown signing key format {:?}",
|
||||
&signing_key[..2]
|
||||
)),
|
||||
}?;
|
||||
|
||||
// TODO: dfs for cid from commit.node.data, error if cid is not in any signed root
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
62
src/user.rs
62
src/user.rs
|
@ -1,4 +1,4 @@
|
|||
use anyhow::{bail, Context, Result};
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use atrium_api::did_doc::DidDocument;
|
||||
use bytes::Buf;
|
||||
use http_body_util::BodyExt;
|
||||
|
@ -20,6 +20,32 @@ pub struct User {
|
|||
pub pds: Option<String>,
|
||||
#[serde(default)]
|
||||
pub handle: Option<String>,
|
||||
#[serde(default)]
|
||||
pub did_document: Option<DidDocument>,
|
||||
}
|
||||
|
||||
impl User {
|
||||
pub fn signing_key(&self) -> Result<&str> {
|
||||
let did_doc = self
|
||||
.did_document
|
||||
.as_ref()
|
||||
.context("no did document stored for user")?;
|
||||
let verification_methods = did_doc
|
||||
.verification_method
|
||||
.as_ref()
|
||||
.context("no verification method in did document")?;
|
||||
|
||||
let target_id = format!("{}#atproto", &self.did);
|
||||
let method = verification_methods
|
||||
.iter()
|
||||
.find(|m| m.id == target_id)
|
||||
.context("couldn't find signing key")?;
|
||||
let key = method
|
||||
.public_key_multibase
|
||||
.as_ref()
|
||||
.context("publicKeyMultibase missing")?;
|
||||
Ok(key)
|
||||
}
|
||||
}
|
||||
|
||||
fn create_user_from_did_doc(did_doc: DidDocument) -> Result<User> {
|
||||
|
@ -33,19 +59,24 @@ fn create_user_from_did_doc(did_doc: DidDocument) -> Result<User> {
|
|||
|
||||
let handle = did_doc
|
||||
.also_known_as
|
||||
.and_then(|v| v.into_iter().next())
|
||||
.as_ref()
|
||||
.and_then(|v| v.iter().next())
|
||||
.and_then(|s| s.strip_prefix("at://").map(str::to_string));
|
||||
let did = did_doc.id;
|
||||
let did = did_doc.id.clone();
|
||||
|
||||
// TODO: check if handle resolves to did and fill none otherwise
|
||||
|
||||
let user = User { pds, did, handle };
|
||||
let user = User {
|
||||
pds,
|
||||
did,
|
||||
handle,
|
||||
did_document: Some(did_doc),
|
||||
};
|
||||
|
||||
Ok(user)
|
||||
}
|
||||
|
||||
pub async fn fetch_user(server: &RelayServer, did: &str) -> Result<User> {
|
||||
tracing::debug!(%did, "fetching user");
|
||||
pub async fn fetch_did_doc(server: &RelayServer, did: &str) -> Result<DidDocument> {
|
||||
if did.starts_with("did:plc:") {
|
||||
let domain: &str = &server.plc_resolver;
|
||||
|
||||
|
@ -79,10 +110,7 @@ pub async fn fetch_user(server: &RelayServer, did: &str) -> Result<User> {
|
|||
let did_doc = serde_json::from_reader::<_, DidDocument>(body.reader())
|
||||
.context("Failed to parse plc DID doc as JSON")?;
|
||||
|
||||
let user = create_user_from_did_doc(did_doc)?;
|
||||
store_user(server, &user)?;
|
||||
|
||||
Ok(user)
|
||||
Ok(did_doc)
|
||||
} else if let Some(domain) = did.strip_prefix("did:web:") {
|
||||
let tcp_stream = TcpStream::connect((domain, 443)).await?;
|
||||
let domain_tls: ServerName<'_> = ServerName::try_from(domain.to_string())?;
|
||||
|
@ -114,15 +142,21 @@ pub async fn fetch_user(server: &RelayServer, did: &str) -> Result<User> {
|
|||
let did_doc = serde_json::from_reader::<_, DidDocument>(body.reader())
|
||||
.context("Failed to parse did:web document as JSON")?;
|
||||
|
||||
let user = create_user_from_did_doc(did_doc)?;
|
||||
store_user(server, &user)?;
|
||||
|
||||
Ok(user)
|
||||
Ok(did_doc)
|
||||
} else {
|
||||
bail!("unknown did type {did}");
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn fetch_user(server: &RelayServer, did: &str) -> Result<User> {
|
||||
tracing::debug!(%did, "fetching user");
|
||||
let did_doc = fetch_did_doc(server, did).await?;
|
||||
let user = create_user_from_did_doc(did_doc)?;
|
||||
store_user(server, &user)?;
|
||||
|
||||
Ok(user)
|
||||
}
|
||||
|
||||
pub async fn lookup_user(server: &RelayServer, did: &str) -> Result<User> {
|
||||
if let Some(cached_user) = server.db_users.get(did)? {
|
||||
let cached_user = serde_ipld_dagcbor::from_slice::<User>(&cached_user)?;
|
||||
|
|
Loading…
Reference in a new issue