mirror of
https://github.com/fluencelabs/trust-graph
synced 2024-12-04 23:30:19 +00:00
Fix revocations logic (#34)
This commit is contained in:
parent
c4019127e8
commit
8214b1cc5c
130
Cargo.lock
generated
130
Cargo.lock
generated
@ -39,9 +39,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.45"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7"
|
||||
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
@ -529,9 +529,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ed25519"
|
||||
version = "1.2.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc"
|
||||
checksum = "74e1069e39f1454367eb2de793ed062fac4c35c2934b76a81d90dd9abcd28816"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"signature",
|
||||
@ -656,9 +656,9 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
|
||||
|
||||
[[package]]
|
||||
name = "fluence-app-service"
|
||||
version = "0.9.0"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58d92fd37b7673513efafb0d1e0c366b8d6f297b74e9bfcda27c452f400af70a"
|
||||
checksum = "01c66660de99826038c5ec4ad0f5dccf10b1c8a15924aeaa5315ab49d718bfc9"
|
||||
dependencies = [
|
||||
"fluence-faas",
|
||||
"log",
|
||||
@ -819,9 +819,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca"
|
||||
checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@ -834,9 +834,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888"
|
||||
checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@ -844,15 +844,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
|
||||
checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c"
|
||||
checksum = "7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@ -862,18 +862,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
|
||||
checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb"
|
||||
checksum = "a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
@ -881,15 +879,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11"
|
||||
checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99"
|
||||
checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12"
|
||||
|
||||
[[package]]
|
||||
name = "futures-timer"
|
||||
@ -899,11 +897,10 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481"
|
||||
checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
@ -913,8 +910,6 @@ dependencies = [
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"proc-macro-hack",
|
||||
"proc-macro-nested",
|
||||
"slab",
|
||||
]
|
||||
|
||||
@ -1147,9 +1142,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.1"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
|
||||
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
@ -1196,9 +1191,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.107"
|
||||
version = "0.2.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219"
|
||||
checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01"
|
||||
|
||||
[[package]]
|
||||
name = "libsecp256k1"
|
||||
@ -1261,9 +1256,9 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
||||
|
||||
[[package]]
|
||||
name = "marine-build-rs-generator"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c81d725ea49f554e23d3a0eb9464fcdad0bc190e42bb5a5a27699fb56557177c"
|
||||
checksum = "0108407ef0528984cd5b226e6d69552b1658b205f60c83305ca33179d6e9eee1"
|
||||
dependencies = [
|
||||
"marine-test-macro-impl",
|
||||
]
|
||||
@ -1303,7 +1298,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edd97bd85072fc540763769be153a7c8ee83391e668b37ef96d6c48decec2cd5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.10.1",
|
||||
"itertools 0.10.3",
|
||||
"marine-it-interfaces",
|
||||
"marine-module-interface",
|
||||
"nom",
|
||||
@ -1362,7 +1357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06bc36ef268bf7436916f1fa9b0c84104692a717ea5eef3c90b9f25c3407f6b7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.10.1",
|
||||
"itertools 0.10.3",
|
||||
"marine-it-interfaces",
|
||||
"nom",
|
||||
"semver 0.11.0",
|
||||
@ -1398,9 +1393,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "marine-rs-sdk-test"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe77591c893dcfda3acd02b89ad42102a6739ead8200717e4cf325c52ba7001e"
|
||||
checksum = "03e286a347527936cf97456b928bd6271e0d39fc1c6b78e99461f00e6d74f018"
|
||||
dependencies = [
|
||||
"fluence-app-service",
|
||||
"marine-build-rs-generator",
|
||||
@ -1451,9 +1446,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "marine-test-macro"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c73a012946439eb619375cc825f008ac74489092f826fe596e465d355542cf"
|
||||
checksum = "bf4d0463358f6c2459089ef8f130983dc911fd0c2aa4cb7c6b59de206f4a816e"
|
||||
dependencies = [
|
||||
"marine-test-macro-impl",
|
||||
"proc-macro-error",
|
||||
@ -1464,13 +1459,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "marine-test-macro-impl"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa833b78d05abb43ca46c2c85cce1e664bde4b8b1926ae2bd420aba426a9b22a"
|
||||
checksum = "b8f4f1ae0ba20e9241e8882e6eb1b2302daa479d67eee5badb54b1520e17c0cb"
|
||||
dependencies = [
|
||||
"darling 0.12.4",
|
||||
"fluence-app-service",
|
||||
"itertools 0.10.1",
|
||||
"itertools 0.10.3",
|
||||
"marine-it-parser",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
@ -1520,9 +1515,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.4"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
@ -1597,6 +1592,12 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nonempty"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
@ -1803,9 +1804,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.22"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
|
||||
checksum = "d1a3ea4f0dd7f1f3e512cf97bf100819aa547f36a6eccac8dbaae839eb92363e"
|
||||
|
||||
[[package]]
|
||||
name = "polyplets"
|
||||
@ -1858,23 +1859,11 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-nested"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.32"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
|
||||
checksum = "fb37d2df5df740e582f28f8560cf425f52bb267d872fe58358eadb554909f07a"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
@ -2219,9 +2208,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568"
|
||||
|
||||
[[package]]
|
||||
name = "safe-transmute"
|
||||
@ -2319,9 +2308,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.69"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8"
|
||||
checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@ -2425,9 +2414,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.81"
|
||||
version = "1.0.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
|
||||
checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -2531,6 +2520,7 @@ dependencies = [
|
||||
"fluence-fork-libp2p-core",
|
||||
"fluence-keypair",
|
||||
"log",
|
||||
"nonempty",
|
||||
"rand 0.7.3",
|
||||
"ref-cast",
|
||||
"serde",
|
||||
@ -2543,7 +2533,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "trust-graph-wasm"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -2848,7 +2838,7 @@ dependencies = [
|
||||
"fluence-it-types",
|
||||
"it-lilo",
|
||||
"it-to-bytes",
|
||||
"itertools 0.10.1",
|
||||
"itertools 0.10.3",
|
||||
"log",
|
||||
"nom",
|
||||
"safe-transmute",
|
||||
|
@ -23,6 +23,7 @@ serde_with = "1.6.0"
|
||||
thiserror = "1.0.23"
|
||||
sha2 = "0.9.5"
|
||||
rand = "0.7.0"
|
||||
nonempty = "0.7.0"
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fluencelabs/trust-graph",
|
||||
"version": "0.1.12",
|
||||
"version": "0.2.0",
|
||||
"description": "Aqua Trust Graph API library",
|
||||
"files": [
|
||||
"*.aqua"
|
||||
|
@ -67,10 +67,10 @@ func issue_revocation(node: string, revoked_peer_id: string, revoked_by_peer_id:
|
||||
result <- TrustGraph.issue_revocation(revoked_peer_id, revoked_by_peer_id, revoked_at_sec, signature_bytes)
|
||||
<- result
|
||||
|
||||
func revoke(node: string, revoke: Revoke) -> RevokeResult:
|
||||
func revoke(node: string, revocation: Revocation) -> RevokeResult:
|
||||
on node:
|
||||
timestamp_sec <- Peer.timestamp_sec()
|
||||
result <- TrustGraph.revoke(revoke, timestamp_sec)
|
||||
result <- TrustGraph.revoke(revocation, timestamp_sec)
|
||||
<- result
|
||||
|
||||
service TrustOp("op"):
|
||||
|
@ -38,7 +38,7 @@ data InsertResult:
|
||||
success: bool
|
||||
error: string
|
||||
|
||||
data Revoke:
|
||||
data Revocation:
|
||||
revoked_peer_id: string
|
||||
revoked_at: u64
|
||||
signature: string
|
||||
@ -48,7 +48,7 @@ data Revoke:
|
||||
data IssueRevocationResult:
|
||||
success: bool
|
||||
error: string
|
||||
revoke: Revoke
|
||||
revocation: Revocation
|
||||
|
||||
data IssueTrustResult:
|
||||
success: bool
|
||||
@ -83,5 +83,5 @@ service TrustGraph("trust-graph"):
|
||||
insert_cert_raw(certificate: string, timestamp_sec: u64) -> InsertResult
|
||||
issue_revocation(revoked_peer_id: string, revoked_by_peer_id: string, revoked_at_sec: u64, signature_bytes: []u8) -> IssueRevocationResult
|
||||
issue_trust(issued_for_peer_id: string, expires_at_sec: u64, issued_at_sec: u64, trust_bytes: []u8) -> IssueTrustResult
|
||||
revoke(revoke: Revoke, timestamp_sec: u64) -> RevokeResult
|
||||
revoke(revoke: Revocation, timestamp_sec: u64) -> RevokeResult
|
||||
verify_trust(trust: Trust, issuer_peer_id: string, timestamp_sec: u64) -> VerifyTrustResult
|
||||
|
@ -65,7 +65,7 @@ async function revoke_helper(node: string, issuer_kp: KeyPair, revoked_by_peer_i
|
||||
let revocation = await tg.issue_revocation(node, revoked_peer_id, revoked_by_peer_id, revoked_at_sec, Array.from(signed_metadata));
|
||||
assert(revocation.success)
|
||||
|
||||
let result_add = await tg.revoke(node, revocation.revoke);
|
||||
let result_add = await tg.revoke(node, revocation.revocation);
|
||||
assert(result_add.success)
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ impl Keypair {
|
||||
///
|
||||
/// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5
|
||||
pub fn from_pkcs8(der: &mut [u8]) -> Result<Self, DecodingError> {
|
||||
let kp = RsaKeyPair::from_pkcs8(&der).map_err(|_| DecodingError::Rsa)?;
|
||||
let kp = RsaKeyPair::from_pkcs8(der).map_err(|_| DecodingError::Rsa)?;
|
||||
der.zeroize();
|
||||
Ok(Keypair(Arc::new(kp)))
|
||||
}
|
||||
@ -57,7 +57,7 @@ impl Keypair {
|
||||
pub fn sign(&self, data: &[u8]) -> Result<Vec<u8>, SigningError> {
|
||||
let mut signature = vec![0; self.0.public_modulus_len()];
|
||||
let rng = SystemRandom::new();
|
||||
match self.0.sign(&RSA_PKCS1_SHA256, &rng, &data, &mut signature) {
|
||||
match self.0.sign(&RSA_PKCS1_SHA256, &rng, data, &mut signature) {
|
||||
Ok(()) => Ok(signature),
|
||||
Err(_) => Err(SigningError::Rsa),
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ impl Signature {
|
||||
|
||||
pub fn get_raw_signature(&self) -> RawSignature {
|
||||
RawSignature {
|
||||
bytes: self.to_vec().clone().to_vec(),
|
||||
bytes: self.to_vec().to_vec(),
|
||||
sig_type: self.get_signature_type(),
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "trust-graph-wasm"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
authors = ["Fluence Labs"]
|
||||
edition = "2018"
|
||||
description = "trust graph wasm"
|
||||
|
@ -113,7 +113,7 @@ impl From<trust_graph::Trust> for Trust {
|
||||
|
||||
#[marine]
|
||||
#[derive(Default)]
|
||||
pub struct Revoke {
|
||||
pub struct Revocation {
|
||||
/// who is revoked
|
||||
pub revoked_peer_id: String,
|
||||
/// date when revocation was created
|
||||
@ -126,10 +126,10 @@ pub struct Revoke {
|
||||
pub revoked_by: String,
|
||||
}
|
||||
|
||||
impl TryFrom<Revoke> for trust_graph::Revoke {
|
||||
impl TryFrom<Revocation> for trust_graph::Revocation {
|
||||
type Error = DtoConversionError;
|
||||
|
||||
fn try_from(r: Revoke) -> Result<Self, Self::Error> {
|
||||
fn try_from(r: Revocation) -> Result<Self, Self::Error> {
|
||||
let revoked_pk = PublicKey::try_from(
|
||||
PeerId::from_str(&r.revoked_peer_id)
|
||||
.map_err(|e| PeerIdDecodeError(format!("{:?}", e)))?,
|
||||
@ -142,7 +142,7 @@ impl TryFrom<Revoke> for trust_graph::Revoke {
|
||||
let signature = bs58::decode(&r.signature).into_vec()?;
|
||||
let signature = Signature::from_bytes(KeyFormat::from_str(&r.sig_type)?, signature);
|
||||
let revoked_at = Duration::from_secs(r.revoked_at);
|
||||
return Ok(trust_graph::Revoke {
|
||||
return Ok(trust_graph::Revocation {
|
||||
pk: revoked_pk,
|
||||
revoked_at,
|
||||
revoked_by: revoked_by_pk,
|
||||
@ -151,14 +151,14 @@ impl TryFrom<Revoke> for trust_graph::Revoke {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<trust_graph::Revoke> for Revoke {
|
||||
fn from(r: trust_graph::Revoke) -> Self {
|
||||
impl From<trust_graph::Revocation> for Revocation {
|
||||
fn from(r: trust_graph::Revocation) -> Self {
|
||||
let revoked_by = r.revoked_by.to_peer_id().to_base58();
|
||||
let revoked_peer_id = r.pk.to_peer_id().to_base58();
|
||||
let raw_signature = r.signature.get_raw_signature();
|
||||
let signature = bs58::encode(raw_signature.bytes).into_string();
|
||||
let revoked_at = r.revoked_at.as_secs();
|
||||
return Revoke {
|
||||
return Revocation {
|
||||
revoked_peer_id,
|
||||
revoked_at,
|
||||
signature,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::dto::{Certificate, Revoke, Trust};
|
||||
use crate::dto::{Certificate, Revocation, Trust};
|
||||
use crate::error::ServiceError;
|
||||
use marine_rs_sdk::marine;
|
||||
|
||||
@ -216,21 +216,21 @@ impl From<Result<Vec<u8>, ServiceError>> for GetRevokeBytesResult {
|
||||
pub struct IssueRevocationResult {
|
||||
pub success: bool,
|
||||
pub error: String,
|
||||
pub revoke: Revoke,
|
||||
pub revocation: Revocation,
|
||||
}
|
||||
|
||||
impl From<Result<Revoke, ServiceError>> for IssueRevocationResult {
|
||||
fn from(result: Result<Revoke, ServiceError>) -> Self {
|
||||
impl From<Result<Revocation, ServiceError>> for IssueRevocationResult {
|
||||
fn from(result: Result<Revocation, ServiceError>) -> Self {
|
||||
match result {
|
||||
Ok(revoke) => IssueRevocationResult {
|
||||
Ok(revocation) => IssueRevocationResult {
|
||||
success: true,
|
||||
error: "".to_string(),
|
||||
revoke,
|
||||
revocation,
|
||||
},
|
||||
Err(e) => IssueRevocationResult {
|
||||
success: false,
|
||||
error: format!("{}", e),
|
||||
revoke: Revoke::default(),
|
||||
revocation: Revocation::default(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::dto::{Certificate, Revoke, Trust};
|
||||
use crate::dto::{Certificate, Revocation, Trust};
|
||||
use crate::error::ServiceError;
|
||||
use crate::misc::{check_timestamp_tetraplets, extract_public_key, with_tg, wrapped_try};
|
||||
use crate::results::{
|
||||
@ -201,7 +201,7 @@ fn add_trust(trust: Trust, issuer_peer_id: String, timestamp_sec: u64) -> AddTru
|
||||
fn get_revoke_bytes(revoked_peer_id: String, revoked_at: u64) -> GetRevokeBytesResult {
|
||||
wrapped_try(|| {
|
||||
let public_key = extract_public_key(revoked_peer_id)?;
|
||||
Ok(trust_graph::Revoke::signature_bytes(
|
||||
Ok(trust_graph::Revocation::signature_bytes(
|
||||
&public_key,
|
||||
Duration::from_secs(revoked_at),
|
||||
))
|
||||
@ -222,13 +222,13 @@ fn issue_revocation(
|
||||
|
||||
let revoked_at = Duration::from_secs(revoked_at_sec);
|
||||
let signature = Signature::from_bytes(revoked_by_pk.get_key_format(), signature_bytes);
|
||||
Ok(trust_graph::Revoke::new(revoked_pk, revoked_by_pk, revoked_at, signature).into())
|
||||
Ok(trust_graph::Revocation::new(revoked_pk, revoked_by_pk, revoked_at, signature).into())
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
#[marine]
|
||||
fn revoke(revoke: Revoke, timestamp_sec: u64) -> RevokeResult {
|
||||
fn revoke(revoke: Revocation, timestamp_sec: u64) -> RevokeResult {
|
||||
with_tg(|tg| {
|
||||
check_timestamp_tetraplets(&marine_rs_sdk::get_call_parameters(), 1)?;
|
||||
|
||||
|
@ -17,12 +17,12 @@ use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use thiserror::Error as ThisError;
|
||||
use trust_graph::{
|
||||
Auth, PublicKeyHashable as PK, PublicKeyHashable, Revoke, Storage, StorageError, Trust,
|
||||
Auth, PublicKeyHashable as PK, PublicKeyHashable, Revocation, Storage, StorageError, Trust,
|
||||
TrustRelation, WeightFactor,
|
||||
};
|
||||
|
||||
static AUTH_TYPE: i64 = 0;
|
||||
static REVOKE_TYPE: i64 = 1;
|
||||
static REVOCATION_TYPE: i64 = 1;
|
||||
pub static DB_PATH: &str = "/tmp/trust-graph.sqlite";
|
||||
|
||||
pub fn create_tables() {
|
||||
@ -72,7 +72,7 @@ impl SQLiteStorage {
|
||||
}
|
||||
}
|
||||
|
||||
Some(TrustRelation::Revoke(revoke)) => {
|
||||
Some(TrustRelation::Revocation(revoke)) => {
|
||||
if revoke.revoked_at < relation.issued_at() {
|
||||
self.insert(relation)?;
|
||||
}
|
||||
@ -85,6 +85,35 @@ impl SQLiteStorage {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_relations(
|
||||
&self,
|
||||
issued_for: &PublicKeyHashable,
|
||||
relation_type: i64,
|
||||
) -> Result<Vec<TrustRelation>, SQLiteStorageError> {
|
||||
let mut cursor = self
|
||||
.connection
|
||||
.prepare(
|
||||
"SELECT relation_type, issued_for, issued_by, issued_at, expires_at, signature \
|
||||
FROM trust_relations WHERE issued_for = ? and relation_type = ?",
|
||||
)?
|
||||
.cursor();
|
||||
|
||||
cursor.bind(&[
|
||||
Value::String(format!("{}", issued_for)),
|
||||
Value::Integer(relation_type),
|
||||
])?;
|
||||
let mut relations: Vec<TrustRelation> = vec![];
|
||||
|
||||
while let Some(row) = cursor.next()? {
|
||||
match parse_relation(row) {
|
||||
Ok(r) => relations.push(r),
|
||||
Err(e) => log::error!("parse_relation: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(relations)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ThisError, Debug)]
|
||||
@ -143,7 +172,7 @@ fn parse_relation(row: &[Value]) -> Result<TrustRelation, SQLiteStorageError> {
|
||||
issued_by: issued_by.into(),
|
||||
}))
|
||||
} else {
|
||||
Ok(TrustRelation::Revoke(Revoke {
|
||||
Ok(TrustRelation::Revocation(Revocation {
|
||||
pk: issued_for.into(),
|
||||
revoked_at: issued_at,
|
||||
revoked_by: issued_by.into(),
|
||||
@ -189,25 +218,34 @@ impl Storage for SQLiteStorage {
|
||||
}
|
||||
|
||||
/// return all auths issued for pk
|
||||
fn get_authorizations(&self, pk: &PublicKeyHashable) -> Result<Vec<Auth>, Self::Error> {
|
||||
let mut cursor = self
|
||||
.connection
|
||||
.prepare(
|
||||
"SELECT relation_type, issued_for, issued_by, issued_at, expires_at, signature \
|
||||
FROM trust_relations WHERE issued_for = ? and relation_type = ?",
|
||||
)?
|
||||
.cursor();
|
||||
fn get_authorizations(&self, issued_for: &PublicKeyHashable) -> Result<Vec<Auth>, Self::Error> {
|
||||
Ok(self
|
||||
.get_relations(issued_for, AUTH_TYPE)?
|
||||
.into_iter()
|
||||
.fold(vec![], |mut acc, r| {
|
||||
if let TrustRelation::Auth(a) = r {
|
||||
acc.push(a);
|
||||
}
|
||||
|
||||
cursor.bind(&[Value::String(format!("{}", pk)), Value::Integer(AUTH_TYPE)])?;
|
||||
let mut auths: Vec<Auth> = vec![];
|
||||
acc
|
||||
}))
|
||||
}
|
||||
|
||||
while let Some(row) = cursor.next()? {
|
||||
if let TrustRelation::Auth(auth) = parse_relation(row)? {
|
||||
auths.push(auth);
|
||||
}
|
||||
}
|
||||
/// return all revocations issued for pk
|
||||
fn get_revocations(
|
||||
&self,
|
||||
issued_for: &PublicKeyHashable,
|
||||
) -> Result<Vec<Revocation>, Self::Error> {
|
||||
Ok(self
|
||||
.get_relations(issued_for, REVOCATION_TYPE)?
|
||||
.into_iter()
|
||||
.fold(vec![], |mut acc, r| {
|
||||
if let TrustRelation::Revocation(revocation) = r {
|
||||
acc.push(revocation);
|
||||
}
|
||||
|
||||
Ok(auths)
|
||||
acc
|
||||
}))
|
||||
}
|
||||
|
||||
fn insert(&mut self, relation: TrustRelation) -> Result<(), Self::Error> {
|
||||
@ -217,7 +255,7 @@ impl Storage for SQLiteStorage {
|
||||
|
||||
let relation_type = match relation {
|
||||
TrustRelation::Auth(_) => AUTH_TYPE,
|
||||
TrustRelation::Revoke(_) => REVOKE_TYPE,
|
||||
TrustRelation::Revocation(_) => REVOCATION_TYPE,
|
||||
};
|
||||
|
||||
statement.bind(1, &Value::Integer(relation_type))?;
|
||||
@ -293,8 +331,8 @@ impl Storage for SQLiteStorage {
|
||||
Ok(roots)
|
||||
}
|
||||
|
||||
fn revoke(&mut self, revoke: Revoke) -> Result<(), Self::Error> {
|
||||
self.update_relation(TrustRelation::Revoke(revoke))
|
||||
fn revoke(&mut self, revoke: Revocation) -> Result<(), Self::Error> {
|
||||
self.update_relation(TrustRelation::Revocation(revoke))
|
||||
}
|
||||
|
||||
fn update_auth(&mut self, auth: Auth, _cur_time: Duration) -> Result<(), Self::Error> {
|
||||
|
@ -23,7 +23,7 @@ mod service_tests {
|
||||
use fluence_keypair::KeyPair;
|
||||
use libp2p_core::PeerId;
|
||||
use marine_rs_sdk::{CallParameters, SecurityTetraplet};
|
||||
use marine_test_env::trust_graph::{Certificate, Revoke, ServiceInterface, Trust};
|
||||
use marine_test_env::trust_graph::{Certificate, Revocation, ServiceInterface, Trust};
|
||||
use rusqlite::Connection;
|
||||
use std::collections::HashMap;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
@ -200,7 +200,7 @@ mod service_tests {
|
||||
issuer_kp: &KeyPair,
|
||||
revoked_peer_id: &PeerId,
|
||||
revoked_at_sec: u64,
|
||||
) -> Revoke {
|
||||
) -> Revocation {
|
||||
let result = trust_graph.get_revoke_bytes(revoked_peer_id.to_base58(), revoked_at_sec);
|
||||
assert!(result.success, "{}", result.error);
|
||||
|
||||
@ -214,14 +214,14 @@ mod service_tests {
|
||||
assert!(issue_result.success, "{}", issue_result.error);
|
||||
|
||||
let revoke_result = trust_graph.revoke_cp(
|
||||
issue_result.revoke.clone(),
|
||||
issue_result.revocation.clone(),
|
||||
revoked_at_sec,
|
||||
get_correct_timestamp_cp(1),
|
||||
);
|
||||
|
||||
assert!(revoke_result.success, "{}", revoke_result.error);
|
||||
|
||||
issue_result.revoke
|
||||
issue_result.revocation
|
||||
}
|
||||
|
||||
fn generate_trust_chain_with(
|
||||
@ -436,39 +436,98 @@ mod service_tests {
|
||||
assert_eq!(certs.len(), 0);
|
||||
}
|
||||
|
||||
/// 1. peer `A` gives trusts to `B`
|
||||
/// 2. weight of `B` is not 0
|
||||
/// 3. peer `A` revokes `B`
|
||||
/// 4. there is no path from `A` to `B`, weight of `A` is 0
|
||||
#[test]
|
||||
fn revoke_test() {
|
||||
fn trust_direct_revoke_test() {
|
||||
let mut trust_graph = marine_test_env::trust_graph::ServiceInterface::new();
|
||||
clear_env();
|
||||
|
||||
let root_kp = KeyPair::generate_ed25519();
|
||||
let peerA_kp = KeyPair::generate_ed25519();
|
||||
let mut cur_time = 100u64;
|
||||
add_root_with_trust(&mut trust_graph, &root_kp, cur_time, cur_time + 9999, 4u32);
|
||||
add_root_with_trust(&mut trust_graph, &peerA_kp, cur_time, cur_time + 9999, 4u32);
|
||||
|
||||
let trust_kp = KeyPair::generate_ed25519();
|
||||
let peerB_kp = KeyPair::generate_ed25519();
|
||||
add_trust(
|
||||
&mut trust_graph,
|
||||
&root_kp,
|
||||
&trust_kp.get_peer_id(),
|
||||
&peerA_kp,
|
||||
&peerB_kp.get_peer_id(),
|
||||
cur_time,
|
||||
cur_time + 99999,
|
||||
);
|
||||
|
||||
let weight = get_weight(&mut trust_graph, trust_kp.get_peer_id(), cur_time);
|
||||
let weight = get_weight(&mut trust_graph, peerB_kp.get_peer_id(), cur_time);
|
||||
assert_ne!(weight, 0u32);
|
||||
|
||||
cur_time += 1;
|
||||
// A revokes B and cancels trust
|
||||
revoke(
|
||||
&mut trust_graph,
|
||||
&root_kp,
|
||||
&trust_kp.get_peer_id(),
|
||||
&peerA_kp,
|
||||
&peerB_kp.get_peer_id(),
|
||||
cur_time,
|
||||
);
|
||||
|
||||
let weight = get_weight(&mut trust_graph, trust_kp.get_peer_id(), cur_time);
|
||||
let weight = get_weight(&mut trust_graph, peerB_kp.get_peer_id(), cur_time);
|
||||
assert_eq!(weight, 0u32);
|
||||
}
|
||||
|
||||
/// There is chain of trusts [0] -> [1] -> [2] -> [3] -> [4]
|
||||
/// 1. [1] revokes [4]
|
||||
/// 2. there is no path from [0] to [4], weight of [4] is 0
|
||||
/// 3. [0] gives trust to [2]
|
||||
/// 4. now there is path [0] -> [2] -> [3] -> [4]
|
||||
/// 5. weight of [4] is not 0
|
||||
#[test]
|
||||
fn indirect_revoke_test() {
|
||||
let mut trust_graph = marine_test_env::trust_graph::ServiceInterface::new();
|
||||
clear_env();
|
||||
|
||||
let (key_pairs, trusts) =
|
||||
generate_trust_chain_with_len(&mut trust_graph, 5, HashMap::new());
|
||||
let mut cur_time = current_time();
|
||||
|
||||
let root_peer_id = key_pairs[0].get_peer_id();
|
||||
add_root_peer_id(&mut trust_graph, root_peer_id, 2);
|
||||
add_trusts(&mut trust_graph, &trusts, cur_time);
|
||||
|
||||
let target_peer_id = key_pairs[4].get_peer_id();
|
||||
let revoked_by = &key_pairs[1];
|
||||
let weight = get_weight(&mut trust_graph, target_peer_id, cur_time);
|
||||
assert_ne!(weight, 0u32);
|
||||
|
||||
cur_time += 1;
|
||||
// [1] revokes [4]
|
||||
revoke(&mut trust_graph, &revoked_by, &target_peer_id, cur_time);
|
||||
|
||||
// now there are no path from root to [4]
|
||||
let weight = get_weight(&mut trust_graph, target_peer_id, cur_time);
|
||||
assert_eq!(weight, 0u32);
|
||||
|
||||
// [0] trusts [2]
|
||||
add_trust(
|
||||
&mut trust_graph,
|
||||
&key_pairs[0],
|
||||
&key_pairs[2].get_peer_id(),
|
||||
cur_time,
|
||||
cur_time + 99999,
|
||||
);
|
||||
// [2] trusts [4]
|
||||
add_trust(
|
||||
&mut trust_graph,
|
||||
&key_pairs[2],
|
||||
&target_peer_id,
|
||||
cur_time,
|
||||
cur_time + 99999,
|
||||
);
|
||||
|
||||
// now we have [0] -> [2] -> [4] path
|
||||
let weight = get_weight(&mut trust_graph, target_peer_id, cur_time);
|
||||
assert_ne!(weight, 0u32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_one_trust_to_cert_last() {
|
||||
let mut trust_graph = ServiceInterface::new();
|
||||
|
47
src/chain.rs
Normal file
47
src/chain.rs
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2021 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::{Auth, PublicKeyHashable, Revocation};
|
||||
use fluence_keypair::PublicKey;
|
||||
use nonempty::NonEmpty;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Chain {
|
||||
pub(crate) auths: NonEmpty<Auth>,
|
||||
revoked_by: HashSet<PublicKeyHashable>,
|
||||
}
|
||||
impl Chain {
|
||||
pub(crate) fn new(auths: NonEmpty<Auth>, revocations: Vec<Revocation>) -> Self {
|
||||
let mut chain = Self {
|
||||
auths,
|
||||
revoked_by: Default::default(),
|
||||
};
|
||||
chain.add_revocations(revocations);
|
||||
|
||||
chain
|
||||
}
|
||||
pub(crate) fn can_be_extended_by(&self, pk: &PublicKey) -> bool {
|
||||
!self.revoked_by.contains(pk.as_ref())
|
||||
&& !self.auths.iter().any(|a| a.trust.issued_for.eq(pk))
|
||||
}
|
||||
|
||||
pub(crate) fn add_revocations(&mut self, revocations: Vec<Revocation>) {
|
||||
revocations.into_iter().for_each(move |r| {
|
||||
self.revoked_by.insert(r.revoked_by.into());
|
||||
});
|
||||
}
|
||||
}
|
@ -29,6 +29,7 @@
|
||||
|
||||
mod certificate;
|
||||
pub mod certificate_serde;
|
||||
mod chain;
|
||||
mod misc;
|
||||
mod public_key_hashable;
|
||||
mod revoke;
|
||||
@ -40,7 +41,7 @@ mod trust_relation;
|
||||
pub use crate::certificate::{Certificate, CertificateError};
|
||||
pub use crate::misc::current_time;
|
||||
pub use crate::public_key_hashable::PublicKeyHashable;
|
||||
pub use crate::revoke::Revoke;
|
||||
pub use crate::revoke::Revocation;
|
||||
pub use crate::trust::{Trust, TrustError};
|
||||
pub use crate::trust_graph::{TrustGraph, TrustGraphError, WeightFactor, MAX_WEIGHT_FACTOR};
|
||||
pub use crate::trust_graph_storage::{Storage, StorageError};
|
||||
|
@ -36,7 +36,7 @@ pub enum RevokeError {
|
||||
/// "A document" that cancels trust created before.
|
||||
/// TODO delete pk from Revoke (it is already in a trust node)
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Revoke {
|
||||
pub struct Revocation {
|
||||
/// who is revoked
|
||||
pub pk: PublicKey,
|
||||
/// date when revocation was created
|
||||
@ -47,7 +47,7 @@ pub struct Revoke {
|
||||
pub signature: Signature,
|
||||
}
|
||||
|
||||
impl Revoke {
|
||||
impl Revocation {
|
||||
#[allow(dead_code)]
|
||||
pub fn new(
|
||||
pk: PublicKey,
|
||||
@ -66,10 +66,10 @@ impl Revoke {
|
||||
/// Creates new revocation signed by a revoker.
|
||||
#[allow(dead_code)]
|
||||
pub fn create(revoker: &KeyPair, to_revoke: PublicKey, revoked_at: Duration) -> Self {
|
||||
let msg = Revoke::signature_bytes(&to_revoke, revoked_at);
|
||||
let msg = Revocation::signature_bytes(&to_revoke, revoked_at);
|
||||
let signature = revoker.sign(&msg).unwrap();
|
||||
|
||||
Revoke::new(to_revoke, revoker.public(), revoked_at, signature)
|
||||
Revocation::new(to_revoke, revoker.public(), revoked_at, signature)
|
||||
}
|
||||
|
||||
pub fn signature_bytes(pk: &PublicKey, revoked_at: Duration) -> Vec<u8> {
|
||||
@ -83,8 +83,8 @@ impl Revoke {
|
||||
}
|
||||
|
||||
/// Verifies that revocation is cryptographically correct.
|
||||
pub fn verify(revoke: &Revoke) -> Result<(), RevokeError> {
|
||||
let msg = Revoke::signature_bytes(&revoke.pk, revoke.revoked_at);
|
||||
pub fn verify(revoke: &Revocation) -> Result<(), RevokeError> {
|
||||
let msg = Revocation::signature_bytes(&revoke.pk, revoke.revoked_at);
|
||||
|
||||
revoke
|
||||
.revoked_by
|
||||
@ -104,9 +104,9 @@ mod tests {
|
||||
|
||||
let duration = Duration::new(100, 0);
|
||||
|
||||
let revoke = Revoke::create(&revoker, to_revoke.public(), duration);
|
||||
let revoke = Revocation::create(&revoker, to_revoke.public(), duration);
|
||||
|
||||
assert_eq!(Revoke::verify(&revoke).is_ok(), true);
|
||||
assert_eq!(Revocation::verify(&revoke).is_ok(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -116,16 +116,16 @@ mod tests {
|
||||
|
||||
let duration = Duration::new(100, 0);
|
||||
|
||||
let revoke = Revoke::create(&revoker, to_revoke.public(), duration);
|
||||
let revoke = Revocation::create(&revoker, to_revoke.public(), duration);
|
||||
|
||||
let duration2 = Duration::new(95, 0);
|
||||
let corrupted_revoke = Revoke::new(
|
||||
let corrupted_revoke = Revocation::new(
|
||||
to_revoke.public(),
|
||||
revoker.public(),
|
||||
duration2,
|
||||
revoke.signature,
|
||||
);
|
||||
|
||||
assert_eq!(Revoke::verify(&corrupted_revoke).is_ok(), false);
|
||||
assert_eq!(Revocation::verify(&corrupted_revoke).is_ok(), false);
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,9 @@
|
||||
|
||||
use crate::certificate::CertificateError::CertificateLengthError;
|
||||
use crate::certificate::{Certificate, CertificateError};
|
||||
use crate::chain::Chain;
|
||||
use crate::public_key_hashable::PublicKeyHashable as PK;
|
||||
use crate::revoke::Revoke;
|
||||
use crate::revoke::Revocation;
|
||||
use crate::revoke::RevokeError;
|
||||
use crate::trust::Trust;
|
||||
use crate::trust_graph::TrustGraphError::{
|
||||
@ -27,6 +28,7 @@ use crate::trust_graph_storage::Storage;
|
||||
use crate::trust_relation::Auth;
|
||||
use crate::{StorageError, TrustError};
|
||||
use fluence_keypair::public_key::PublicKey;
|
||||
use nonempty::NonEmpty;
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::{HashSet, VecDeque};
|
||||
use std::convert::{From, Into};
|
||||
@ -93,7 +95,7 @@ impl From<TrustGraphError> for String {
|
||||
}
|
||||
|
||||
pub fn get_weight_from_factor(wf: WeightFactor) -> u32 {
|
||||
2u32.pow(MAX_WEIGHT_FACTOR.checked_sub(wf).unwrap_or(0u32))
|
||||
2u32.pow(MAX_WEIGHT_FACTOR.saturating_sub(wf))
|
||||
}
|
||||
|
||||
impl<S> TrustGraph<S>
|
||||
@ -245,12 +247,14 @@ where
|
||||
roots: HashSet<&PK>,
|
||||
) -> Result<Vec<Vec<Auth>>, TrustGraphError> {
|
||||
// queue to collect all chains in the trust graph (each chain is a path in the trust graph)
|
||||
let mut chains_queue: VecDeque<Vec<Auth>> = VecDeque::new();
|
||||
let mut chains_queue: VecDeque<Chain> = VecDeque::new();
|
||||
|
||||
let node_auths: Vec<Auth> = self.storage.get_authorizations(pk)?;
|
||||
let node_revocations = self.storage.get_revocations(pk)?;
|
||||
|
||||
// put all auth in the queue as the first possible paths through the graph
|
||||
for auth in node_auths {
|
||||
chains_queue.push_back(vec![auth]);
|
||||
chains_queue.push_back(Chain::new(NonEmpty::new(auth), node_revocations.clone()));
|
||||
}
|
||||
|
||||
// List of all chains that converge (terminate) to known roots
|
||||
@ -261,22 +265,21 @@ where
|
||||
.pop_front()
|
||||
.expect("`chains_queue` always has at least one element");
|
||||
|
||||
let last = cur_chain
|
||||
.last()
|
||||
.expect("`cur_chain` always has at least one element");
|
||||
let last = cur_chain.auths.last();
|
||||
|
||||
let auths = self
|
||||
.storage
|
||||
.get_authorizations(&last.issued_by.clone().into())?;
|
||||
|
||||
for auth in auths {
|
||||
// if there is auth, that we not visited in the current chain, copy chain and append this auth
|
||||
if !cur_chain
|
||||
.iter()
|
||||
.any(|a| a.trust.issued_for == auth.issued_by)
|
||||
{
|
||||
// if there is auth, that we not visited in the current chain and no revocations to any chain member -- copy chain and append this auth
|
||||
if cur_chain.can_be_extended_by(&auth.issued_by) {
|
||||
let mut new_chain = cur_chain.clone();
|
||||
new_chain.push(auth);
|
||||
new_chain.add_revocations(
|
||||
self.storage
|
||||
.get_revocations(&auth.issued_by.clone().into())?,
|
||||
);
|
||||
new_chain.auths.push(auth);
|
||||
chains_queue.push_back(new_chain);
|
||||
}
|
||||
}
|
||||
@ -289,8 +292,8 @@ where
|
||||
let issued_by: &PK = last.issued_by.as_ref();
|
||||
let converges_to_root = roots.contains(issued_by);
|
||||
|
||||
if self_signed && converges_to_root && cur_chain.len() > 1 {
|
||||
terminated_chains.push(cur_chain);
|
||||
if self_signed && converges_to_root && cur_chain.auths.len() > 1 {
|
||||
terminated_chains.push(cur_chain.auths.into());
|
||||
}
|
||||
}
|
||||
|
||||
@ -334,9 +337,11 @@ where
|
||||
}
|
||||
|
||||
/// Mark public key as revoked.
|
||||
pub fn revoke(&mut self, revoke: Revoke) -> Result<(), TrustGraphError> {
|
||||
Revoke::verify(&revoke)?;
|
||||
/// Every chain that contains path from `revoked_by` to revoked `pk`
|
||||
/// will be excluded from valid certificates until revocation canceled by giving trust
|
||||
pub fn revoke(&mut self, revocation: Revocation) -> Result<(), TrustGraphError> {
|
||||
Revocation::verify(&revocation)?;
|
||||
|
||||
Ok(self.storage.revoke(revoke)?)
|
||||
Ok(self.storage.revoke(revocation)?)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::public_key_hashable::PublicKeyHashable as PK;
|
||||
use crate::revoke::Revoke;
|
||||
use crate::revoke::Revocation;
|
||||
use crate::trust_graph::WeightFactor;
|
||||
use crate::trust_relation::{Auth, TrustRelation};
|
||||
use std::fmt::Display;
|
||||
@ -16,13 +16,15 @@ pub trait Storage {
|
||||
issued_by: &PK,
|
||||
) -> Result<Option<TrustRelation>, Self::Error>;
|
||||
|
||||
fn get_authorizations(&self, pk: &PK) -> Result<Vec<Auth>, Self::Error>;
|
||||
fn get_authorizations(&self, issued_for: &PK) -> Result<Vec<Auth>, Self::Error>;
|
||||
fn get_revocations(&self, issued_for: &PK) -> Result<Vec<Revocation>, Self::Error>;
|
||||
|
||||
fn insert(&mut self, node: TrustRelation) -> Result<(), Self::Error>;
|
||||
|
||||
fn get_root_weight_factor(&self, pk: &PK) -> Result<Option<WeightFactor>, Self::Error>;
|
||||
fn add_root_weight_factor(&mut self, pk: PK, weight: WeightFactor) -> Result<(), Self::Error>;
|
||||
fn root_keys(&self) -> Result<Vec<PK>, Self::Error>;
|
||||
fn revoke(&mut self, revoke: Revoke) -> Result<(), Self::Error>;
|
||||
fn revoke(&mut self, revocation: Revocation) -> Result<(), Self::Error>;
|
||||
fn update_auth(&mut self, auth: Auth, cur_time: Duration) -> Result<(), Self::Error>;
|
||||
fn remove_expired(&mut self, current_time: Duration) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
@ -1,206 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::public_key_hashable::PublicKeyHashable;
|
||||
use crate::revoke::Revoke;
|
||||
use crate::trust::Trust;
|
||||
use failure::_core::time::Duration;
|
||||
use fluence_keypair::public_key::PublicKey;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::serde_as;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
enum TrustRelation {
|
||||
Auth(Auth),
|
||||
Revoke(Revoke),
|
||||
}
|
||||
|
||||
impl TrustRelation {
|
||||
/// Returns timestamp of when this relation was created
|
||||
pub fn issued_at(&self) -> Duration {
|
||||
match self {
|
||||
TrustRelation::Auth(auth) => auth.trust.issued_at,
|
||||
TrustRelation::Revoke(revoke) => revoke.revoked_at,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns public key of the creator of this relation
|
||||
pub fn issued_by(&self) -> &PublicKey {
|
||||
match self {
|
||||
TrustRelation::Auth(auth) => &auth.issued_by,
|
||||
TrustRelation::Revoke(revoke) => &revoke.revoked_by,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents who give a certificate
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Auth {
|
||||
/// proof of this authorization
|
||||
pub trust: Trust,
|
||||
/// the issuer of this authorization
|
||||
pub issued_by: PublicKey,
|
||||
}
|
||||
|
||||
/// An element of trust graph that store relations (trust or revoke)
|
||||
/// that given by some owners of public keys.
|
||||
#[serde_as]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct TrustNode {
|
||||
/// identity key of this element
|
||||
pub pk: PublicKey,
|
||||
|
||||
/// one public key could be authorized or revoked by multiple certificates
|
||||
#[serde_as(as = "Vec<(_, _)>")]
|
||||
trust_relations: HashMap<PublicKeyHashable, TrustRelation>,
|
||||
|
||||
/// for maintain
|
||||
pub verified_at: Duration,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl TrustNode {
|
||||
pub fn new(pk: PublicKey, verified_at: Duration) -> Self {
|
||||
Self {
|
||||
pk,
|
||||
trust_relations: HashMap::new(),
|
||||
verified_at,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_auth(&self, pk: PublicKey) -> Option<Auth> {
|
||||
match self.trust_relations.get(&pk.into()) {
|
||||
Some(TrustRelation::Auth(auth)) => Some(auth.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_revoke(&self, pk: PublicKey) -> Option<Revoke> {
|
||||
match self.trust_relations.get(&pk.into()) {
|
||||
Some(TrustRelation::Revoke(rev)) => Some(rev.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn authorizations(&self) -> impl Iterator<Item = &Auth> + '_ {
|
||||
self.trust_relations.values().filter_map(|tr| {
|
||||
if let TrustRelation::Auth(auth) = tr {
|
||||
Some(auth)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn revocations(&self) -> impl Iterator<Item = &Revoke> + '_ {
|
||||
self.trust_relations.values().filter_map(|tr| {
|
||||
if let TrustRelation::Revoke(revoke) = tr {
|
||||
Some(revoke)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Adds authorization. If the trust node already has this authorization,
|
||||
/// add auth with later expiration date.
|
||||
pub fn update_auth(&mut self, auth: Auth) {
|
||||
self.update_relation(TrustRelation::Auth(auth));
|
||||
}
|
||||
|
||||
// insert new trust relation, ignore if there is another one with same public key
|
||||
fn insert(&mut self, pk: PublicKeyHashable, tr: TrustRelation) {
|
||||
self.trust_relations.insert(pk, tr);
|
||||
}
|
||||
|
||||
fn update_relation(&mut self, relation: TrustRelation) {
|
||||
let issued_by = relation.issued_by().as_ref();
|
||||
|
||||
match self.trust_relations.get(issued_by) {
|
||||
Some(TrustRelation::Auth(auth)) => {
|
||||
if auth.trust.issued_at < relation.issued_at() {
|
||||
self.insert(issued_by.clone(), relation)
|
||||
}
|
||||
}
|
||||
Some(TrustRelation::Revoke(existed_revoke)) => {
|
||||
if existed_revoke.revoked_at < relation.issued_at() {
|
||||
self.insert(issued_by.clone(), relation)
|
||||
}
|
||||
}
|
||||
None => self.insert(issued_by.clone(), relation),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn update_revoke(&mut self, revoke: Revoke) {
|
||||
self.update_relation(TrustRelation::Revoke(revoke));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::time::Duration;
|
||||
|
||||
use fluence_keypair::key_pair::KeyPair;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_auth_and_revoke_trust_node() {
|
||||
let kp = KeyPair::generate_ed25519();
|
||||
|
||||
let now = Duration::new(50, 0);
|
||||
let past = Duration::new(5, 0);
|
||||
let future = Duration::new(500, 0);
|
||||
|
||||
let mut trust_node = TrustNode {
|
||||
pk: kp.public(),
|
||||
trust_relations: HashMap::new(),
|
||||
verified_at: now,
|
||||
};
|
||||
|
||||
let truster = KeyPair::generate_ed25519();
|
||||
|
||||
let revoke = Revoke::create(&truster, kp.public(), now);
|
||||
|
||||
trust_node.update_revoke(revoke);
|
||||
|
||||
assert!(trust_node.get_revoke(truster.public()).is_some());
|
||||
|
||||
let old_trust = Trust::create(&truster, kp.public(), Duration::new(60, 0), past);
|
||||
|
||||
let old_auth = Auth {
|
||||
trust: old_trust,
|
||||
issued_by: truster.public(),
|
||||
};
|
||||
|
||||
trust_node.update_auth(old_auth);
|
||||
|
||||
assert!(trust_node.get_revoke(truster.public()).is_some());
|
||||
assert!(trust_node.get_auth(truster.public()).is_none());
|
||||
|
||||
let trust = Trust::create(&truster, kp.public(), Duration::new(60, 0), future);
|
||||
let auth = Auth {
|
||||
trust,
|
||||
issued_by: truster.public(),
|
||||
};
|
||||
|
||||
trust_node.update_auth(auth);
|
||||
|
||||
assert!(trust_node.get_auth(truster.public()).is_some());
|
||||
assert!(trust_node.get_revoke(truster.public()).is_none());
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::revoke::Revoke;
|
||||
use crate::revoke::Revocation;
|
||||
use crate::trust::Trust;
|
||||
use failure::_core::time::Duration;
|
||||
use fluence_keypair::public_key::PublicKey;
|
||||
@ -33,7 +33,7 @@ pub struct Auth {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum TrustRelation {
|
||||
Auth(Auth),
|
||||
Revoke(Revoke),
|
||||
Revocation(Revocation),
|
||||
}
|
||||
|
||||
impl TrustRelation {
|
||||
@ -41,7 +41,7 @@ impl TrustRelation {
|
||||
pub fn issued_at(&self) -> Duration {
|
||||
match self {
|
||||
TrustRelation::Auth(auth) => auth.trust.issued_at,
|
||||
TrustRelation::Revoke(revoke) => revoke.revoked_at,
|
||||
TrustRelation::Revocation(r) => r.revoked_at,
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,28 +49,29 @@ impl TrustRelation {
|
||||
pub fn issued_by(&self) -> &PublicKey {
|
||||
match self {
|
||||
TrustRelation::Auth(auth) => &auth.issued_by,
|
||||
TrustRelation::Revoke(revoke) => &revoke.revoked_by,
|
||||
TrustRelation::Revocation(r) => &r.revoked_by,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn issued_for(&self) -> &PublicKey {
|
||||
match self {
|
||||
TrustRelation::Auth(auth) => &auth.trust.issued_for,
|
||||
TrustRelation::Revoke(revoke) => &revoke.pk,
|
||||
TrustRelation::Revocation(r) => &r.pk,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expires_at(&self) -> Duration {
|
||||
match self {
|
||||
TrustRelation::Auth(auth) => auth.trust.expires_at,
|
||||
TrustRelation::Revoke(_) => Duration::from_secs(0),
|
||||
// revocations never expire
|
||||
TrustRelation::Revocation(_) => Duration::from_secs(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn signature(&self) -> &Signature {
|
||||
match self {
|
||||
TrustRelation::Auth(auth) => &auth.trust.signature,
|
||||
TrustRelation::Revoke(revoke) => &revoke.signature,
|
||||
TrustRelation::Revocation(r) => &r.signature,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user