mirror of
https://github.com/fluencelabs/trust-graph-test
synced 2025-04-25 13:12:28 +00:00
change api to weight, use weight_factor internally
This commit is contained in:
parent
02406c6426
commit
0541946a1f
@ -23,7 +23,6 @@ impl From<Result<(), ServiceError>> for InsertResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add peer id to result
|
|
||||||
#[marine]
|
#[marine]
|
||||||
pub struct WeightResult {
|
pub struct WeightResult {
|
||||||
pub success: bool,
|
pub success: bool,
|
||||||
@ -32,17 +31,19 @@ pub struct WeightResult {
|
|||||||
pub error: String,
|
pub error: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Result<Option<u32>, ServiceError>> for WeightResult {
|
impl From<Result<(u32, String), ServiceError>> for WeightResult {
|
||||||
fn from(result: Result<Option<u32>, ServiceError>) -> Self {
|
fn from(result: Result<(u32, String), ServiceError>) -> Self {
|
||||||
match result {
|
match result {
|
||||||
Ok(wo) => WeightResult {
|
Ok((weight, peer_id)) => WeightResult {
|
||||||
success: true,
|
success: true,
|
||||||
weight: wo.map(|w| vec![w]).unwrap_or(vec![]),
|
weight,
|
||||||
|
peer_id,
|
||||||
error: "".to_string(),
|
error: "".to_string(),
|
||||||
},
|
},
|
||||||
Err(e) => WeightResult {
|
Err(e) => WeightResult {
|
||||||
success: false,
|
success: false,
|
||||||
weight: vec![],
|
weight: 0u32,
|
||||||
|
peer_id: "".to_string(),
|
||||||
error: format!("{}", e),
|
error: format!("{}", e),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
use crate::dto::{Certificate, Trust};
|
use crate::dto::{Certificate, Trust};
|
||||||
use crate::results::{
|
use crate::results::{
|
||||||
AddRootResult, AddTrustResult, AllCertsResult, GetTrustMetadataResult, InsertResult,
|
AddRootResult, AddTrustResult, AllCertsResult, GetTrustMetadataResult, InsertResult,
|
||||||
IssueCertificateResult, IssueTrustResult, VerifyTrustResult, WeightResult,
|
IssueTrustResult, VerifyTrustResult, WeightResult,
|
||||||
};
|
};
|
||||||
use crate::service_impl::{
|
use crate::service_impl::{
|
||||||
add_root_impl, add_trust_impl, get_all_certs_impl, get_trust_metadata_imp, get_weight_impl,
|
add_root_impl, add_trust_impl, get_all_certs_impl, get_trust_metadata_imp, get_weight_impl,
|
||||||
insert_cert_impl, insert_cert_impl_raw, issue_certificate_with_trust_checked_impl,
|
insert_cert_impl, insert_cert_impl_raw, issue_trust_impl, verify_trust_impl,
|
||||||
issue_root_certificate_checked_impl, issue_trust_impl, verify_trust_impl,
|
|
||||||
};
|
};
|
||||||
use marine_rs_sdk::{marine, CallParameters};
|
use marine_rs_sdk::{marine, CallParameters};
|
||||||
|
|
||||||
@ -28,7 +27,9 @@ fn insert_cert(certificate: Certificate, timestamp_sec: u64) -> InsertResult {
|
|||||||
// TODO: pass current timestamp, return only valid, delete expired, return max weight
|
// TODO: pass current timestamp, return only valid, delete expired, return max weight
|
||||||
#[marine]
|
#[marine]
|
||||||
fn get_weight(peer_id: String) -> WeightResult {
|
fn get_weight(peer_id: String) -> WeightResult {
|
||||||
get_weight_impl(peer_id).into()
|
get_weight_impl(peer_id.clone())
|
||||||
|
.map(|w| (w, peer_id))
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: pass current timestamp, return only valid, delete expired
|
// TODO: pass current timestamp, return only valid, delete expired
|
||||||
@ -37,8 +38,6 @@ fn get_all_certs(issued_for: String) -> AllCertsResult {
|
|||||||
get_all_certs_impl(issued_for).into()
|
get_all_certs_impl(issued_for).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: add trust method
|
|
||||||
|
|
||||||
#[marine]
|
#[marine]
|
||||||
/// could add only a host of a trust graph service
|
/// could add only a host of a trust graph service
|
||||||
fn add_root(peer_id: String, weight: u32) -> AddRootResult {
|
fn add_root(peer_id: String, weight: u32) -> AddRootResult {
|
||||||
@ -57,20 +56,26 @@ fn add_root(peer_id: String, weight: u32) -> AddRootResult {
|
|||||||
#[marine]
|
#[marine]
|
||||||
fn get_trust_metadata(
|
fn get_trust_metadata(
|
||||||
issued_for_peer_id: String,
|
issued_for_peer_id: String,
|
||||||
expires_at: u64,
|
expires_at_sec: u64,
|
||||||
issued_at: u64,
|
issued_at_sec: u64,
|
||||||
) -> GetTrustMetadataResult {
|
) -> GetTrustMetadataResult {
|
||||||
get_trust_metadata_imp(issued_for_peer_id, expires_at, issued_at).into()
|
get_trust_metadata_imp(issued_for_peer_id, expires_at_sec, issued_at_sec).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[marine]
|
#[marine]
|
||||||
fn issue_trust(
|
fn issue_trust(
|
||||||
issued_for_peer_id: String,
|
issued_for_peer_id: String,
|
||||||
expires_at: u64,
|
expires_at_sec: u64,
|
||||||
issued_at: u64,
|
issued_at_sec: u64,
|
||||||
signed_metadata: Vec<u8>,
|
signed_metadata: Vec<u8>,
|
||||||
) -> IssueTrustResult {
|
) -> IssueTrustResult {
|
||||||
issue_trust_impl(issued_for_peer_id, expires_at, issued_at, signed_metadata).into()
|
issue_trust_impl(
|
||||||
|
issued_for_peer_id,
|
||||||
|
expires_at_sec,
|
||||||
|
issued_at_sec,
|
||||||
|
signed_metadata,
|
||||||
|
)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[marine]
|
#[marine]
|
||||||
@ -78,47 +83,8 @@ fn verify_trust(trust: Trust, issuer_peer_id: String, timestamp_sec: u64) -> Ver
|
|||||||
verify_trust_impl(trust, issuer_peer_id, timestamp_sec).into()
|
verify_trust_impl(trust, issuer_peer_id, timestamp_sec).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: check issued_at earlier than timestamp_sec
|
||||||
#[marine]
|
#[marine]
|
||||||
fn add_trust(trust: Trust, issuer_peer_id: String, timestamp_sec: u64) -> AddTrustResult {
|
fn add_trust(trust: Trust, issuer_peer_id: String, timestamp_sec: u64) -> AddTrustResult {
|
||||||
add_trust_impl(trust, issuer_peer_id, timestamp_sec).into()
|
add_trust_impl(trust, issuer_peer_id, timestamp_sec).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
// service TrustGraph("trust-graph"):
|
|
||||||
// -- returns hash of metadata to sign
|
|
||||||
// get_trust_bytes(issued_for_peer_id: string, expires_at: u64, issued_at: u64) -> GetTrustMetadataResult
|
|
||||||
//
|
|
||||||
// -- issued_by needed to identify signature type (ed25519, rsa or secp256k1)
|
|
||||||
// issue_trust(issued_by_peer_id: string, issued_for_peer_id: string, expires_at: u64, issued_at: u64, signature: []u8) -> IssueTrustResult
|
|
||||||
//
|
|
||||||
// -- just verifying signatures, timestamp without inserting into local trust graph
|
|
||||||
// verify_trust(issued_by_peer_id: string, trust: Trust, timestamp_sec: u64) -> VerifyTrustResult
|
|
||||||
//
|
|
||||||
// -- checks signature, timestamp, try to find place to insert, returns max_weight if succeed
|
|
||||||
// add_trust(issued_by_peer_id: string, trust: Trust, timestamp_sec: u64) -> AddTrustResult
|
|
||||||
//
|
|
||||||
// -- add root trust with given weight
|
|
||||||
// add_root(peer_id: string, trust: Trust, weight: u32) -> AddRootResult
|
|
||||||
//
|
|
||||||
// -- return max weight if found, remove expired
|
|
||||||
// get_weight(issued_for: string, timestamp_sec: u32) -> WeightResult
|
|
||||||
//
|
|
||||||
// -- return all certs, remove expired
|
|
||||||
// get_all_certs(issued_for: string, timestamp_sec) -> AllCertsResult
|
|
||||||
//
|
|
||||||
// -- insert full certificate if possible
|
|
||||||
// insert_cert(certificate: Certificate, current_time: u64) -> InsertResult
|
|
||||||
// insert_cert_raw(certificate: string, current_time: u64) -> InsertResult
|
|
||||||
//
|
|
||||||
// -- returns hash of metadata to sign
|
|
||||||
// get_revoke_bytes(revoked_peer_id: string, revoked_at: u64, issued_at: u64) -> GetRevokeMetadataResult
|
|
||||||
//
|
|
||||||
// -- revoked_by needed to identify signature type (ed25519, rsa or secp256k1)
|
|
||||||
// issue_revoke(revoked_by_peer_id: string, revoked_peer_id: string, revoked_at: u64, signature: []u8) -> IssueRevokeResult
|
|
||||||
//
|
|
||||||
// -- checks signature, checks timestamp
|
|
||||||
// revoke(revoke: Revoke, timestamp_sec: u64) -> AddRevokeResult
|
|
||||||
//
|
|
||||||
// get_all_revocation(revoked_peer_id: string)
|
|
||||||
//
|
|
||||||
// -- TODO
|
|
||||||
// get_trust
|
|
||||||
|
@ -10,7 +10,7 @@ use std::convert::{Into, TryInto};
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use thiserror::Error as ThisError;
|
use thiserror::Error as ThisError;
|
||||||
use trust_graph::{current_time, CertificateError, TrustError, TrustGraphError};
|
use trust_graph::{CertificateError, TrustError, TrustGraphError};
|
||||||
|
|
||||||
pub static TRUSTED_TIMESTAMP_SERVICE_ID: &str = "peer";
|
pub static TRUSTED_TIMESTAMP_SERVICE_ID: &str = "peer";
|
||||||
pub static TRUSTED_TIMESTAMP_FUNCTION_NAME: &str = "timestamp_sec";
|
pub static TRUSTED_TIMESTAMP_FUNCTION_NAME: &str = "timestamp_sec";
|
||||||
@ -24,7 +24,7 @@ pub(crate) fn check_timestamp_tetraplets(
|
|||||||
.tetraplets
|
.tetraplets
|
||||||
.get(arg_number)
|
.get(arg_number)
|
||||||
.ok_or(InvalidTimestampTetraplet)?;
|
.ok_or(InvalidTimestampTetraplet)?;
|
||||||
let tetraplet = tetraplets.get(0).wrap_err(error_msg)?;
|
let tetraplet = tetraplets.get(0).ok_or(InvalidTimestampTetraplet)?;
|
||||||
(tetraplet.service_id == TRUSTED_TIMESTAMP_SERVICE_ID
|
(tetraplet.service_id == TRUSTED_TIMESTAMP_SERVICE_ID
|
||||||
&& tetraplet.function_name == TRUSTED_TIMESTAMP_FUNCTION_NAME
|
&& tetraplet.function_name == TRUSTED_TIMESTAMP_FUNCTION_NAME
|
||||||
&& tetraplet.peer_pk == call_parameters.host_id)
|
&& tetraplet.peer_pk == call_parameters.host_id)
|
||||||
@ -82,7 +82,7 @@ fn extract_public_key(peer_id: String) -> Result<PublicKey, ServiceError> {
|
|||||||
.map_err(|e| ServiceError::PublicKeyExtractionError(e.to_string()))
|
.map_err(|e| ServiceError::PublicKeyExtractionError(e.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_weight_impl(peer_id: String) -> Result<Option<u32>, ServiceError> {
|
pub fn get_weight_impl(peer_id: String) -> Result<u32, ServiceError> {
|
||||||
let tg = get_data().lock();
|
let tg = get_data().lock();
|
||||||
let public_key = extract_public_key(peer_id)?;
|
let public_key = extract_public_key(peer_id)?;
|
||||||
let weight = tg.weight(public_key)?;
|
let weight = tg.weight(public_key)?;
|
||||||
@ -127,35 +127,38 @@ pub fn insert_cert_impl(certificate: Certificate, timestamp_sec: u64) -> Result<
|
|||||||
pub fn add_root_impl(peer_id: String, weight: u32) -> Result<(), ServiceError> {
|
pub fn add_root_impl(peer_id: String, weight: u32) -> Result<(), ServiceError> {
|
||||||
let mut tg = get_data().lock();
|
let mut tg = get_data().lock();
|
||||||
let public_key = extract_public_key(peer_id)?;
|
let public_key = extract_public_key(peer_id)?;
|
||||||
tg.add_root_weight(public_key, weight)?;
|
tg.add_root_weight_factor(public_key, weight)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_trust_metadata_imp(
|
pub fn get_trust_metadata_imp(
|
||||||
peer_id: String,
|
peer_id: String,
|
||||||
expires_at: u64,
|
expires_at_sec: u64,
|
||||||
issued_at: u64,
|
issued_at_sec: u64,
|
||||||
) -> Result<Vec<u8>, ServiceError> {
|
) -> Result<Vec<u8>, ServiceError> {
|
||||||
let public_key = extract_public_key(peer_id)?;
|
let public_key = extract_public_key(peer_id)?;
|
||||||
Ok(trust_graph::Trust::metadata_bytes(
|
Ok(trust_graph::Trust::metadata_bytes(
|
||||||
&public_key,
|
&public_key,
|
||||||
Duration::from_secs(expires_at),
|
Duration::from_secs(expires_at_sec),
|
||||||
Duration::from_secs(issued_at),
|
Duration::from_secs(issued_at_sec),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn issue_trust_impl(
|
pub fn issue_trust_impl(
|
||||||
peer_id: String,
|
peer_id: String,
|
||||||
expires_at: u64,
|
expires_at_sec: u64,
|
||||||
issued_at: u64,
|
issued_at_sec: u64,
|
||||||
signed_metadata: Vec<u8>,
|
signed_metadata: Vec<u8>,
|
||||||
) -> Result<Trust, ServiceError> {
|
) -> Result<Trust, ServiceError> {
|
||||||
let public_key = extract_public_key(peer_id)?;
|
let public_key = extract_public_key(peer_id)?;
|
||||||
let expires_at = Duration::from_secs(expires_at);
|
let expires_at_sec = Duration::from_secs(expires_at_sec);
|
||||||
let issued_at = Duration::from_secs(issued_at);
|
let issued_at_sec = Duration::from_secs(issued_at_sec);
|
||||||
let signature = Signature::from_bytes_with_public_key(&public_key, signed_metadata);
|
let signature = Signature::from_bytes_with_public_key(&public_key, signed_metadata);
|
||||||
Ok(Trust::from(trust_graph::Trust::new(
|
Ok(Trust::from(trust_graph::Trust::new(
|
||||||
public_key, expires_at, issued_at, signature,
|
public_key,
|
||||||
|
expires_at_sec,
|
||||||
|
issued_at_sec,
|
||||||
|
signature,
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,15 +182,14 @@ pub fn add_trust_impl(
|
|||||||
trust: Trust,
|
trust: Trust,
|
||||||
issuer_peer_id: String,
|
issuer_peer_id: String,
|
||||||
timestamp_sec: u64,
|
timestamp_sec: u64,
|
||||||
) -> Result<(), ServiceError> {
|
) -> Result<u32, ServiceError> {
|
||||||
let public_key = extract_public_key(issuer_peer_id)?;
|
let public_key = extract_public_key(issuer_peer_id)?;
|
||||||
check_timestamp_tetraplets(&marine_rs_sdk::get_call_parameters(), 2)?;
|
check_timestamp_tetraplets(&marine_rs_sdk::get_call_parameters(), 2)?;
|
||||||
let mut tg = get_data().lock();
|
let mut tg = get_data().lock();
|
||||||
tg.add_trust(
|
tg.add_trust(
|
||||||
trust.try_into()?,
|
&trust.try_into()?,
|
||||||
public_key,
|
public_key,
|
||||||
Duration::from_secs(timestamp_sec),
|
Duration::from_secs(timestamp_sec),
|
||||||
)?;
|
)
|
||||||
|
.map_err(ServiceError::TGError)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ use crate::storage_impl::SQLiteStorageError::{
|
|||||||
WeightConversionDB,
|
WeightConversionDB,
|
||||||
};
|
};
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
use fluence_keypair::public_key::PublicKey;
|
|
||||||
use marine_sqlite_connector;
|
use marine_sqlite_connector;
|
||||||
use marine_sqlite_connector::Connection;
|
use marine_sqlite_connector::Connection;
|
||||||
use marine_sqlite_connector::Error as InternalSqliteError;
|
use marine_sqlite_connector::Error as InternalSqliteError;
|
||||||
@ -21,7 +20,8 @@ use std::str::FromStr;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use thiserror::Error as ThisError;
|
use thiserror::Error as ThisError;
|
||||||
use trust_graph::{
|
use trust_graph::{
|
||||||
Auth, PublicKeyHashable as PK, Revoke, Storage, StorageError, TrustGraph, TrustNode, Weight,
|
Auth, PublicKeyHashable as PK, Revoke, Storage, StorageError, TrustGraph, TrustNode,
|
||||||
|
WeightFactor,
|
||||||
};
|
};
|
||||||
|
|
||||||
static INSTANCE: OnceCell<Mutex<TrustGraph<SQLiteStorage>>> = OnceCell::new();
|
static INSTANCE: OnceCell<Mutex<TrustGraph<SQLiteStorage>>> = OnceCell::new();
|
||||||
@ -140,7 +140,7 @@ impl Storage for SQLiteStorage {
|
|||||||
Ok({})
|
Ok({})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_root_weight(&self, pk: &PK) -> Result<Option<Weight>, Self::Error> {
|
fn get_root_weight_factor(&self, pk: &PK) -> Result<Option<WeightFactor>, Self::Error> {
|
||||||
let mut cursor = self
|
let mut cursor = self
|
||||||
.connection
|
.connection
|
||||||
.prepare("SELECT public_key,weight FROM roots WHERE public_key = ?")?
|
.prepare("SELECT public_key,weight FROM roots WHERE public_key = ?")?
|
||||||
@ -160,7 +160,7 @@ impl Storage for SQLiteStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_root_weight(&mut self, pk: PK, weight: Weight) -> Result<(), Self::Error> {
|
fn add_root_weight_factor(&mut self, pk: PK, weight: WeightFactor) -> Result<(), Self::Error> {
|
||||||
log::info!("add root: {} weight: {}", pk, weight);
|
log::info!("add root: {} weight: {}", pk, weight);
|
||||||
let mut cursor = self
|
let mut cursor = self
|
||||||
.connection
|
.connection
|
||||||
@ -208,20 +208,19 @@ impl Storage for SQLiteStorage {
|
|||||||
|
|
||||||
fn update_auth(
|
fn update_auth(
|
||||||
&mut self,
|
&mut self,
|
||||||
pk: &PK,
|
issued_for_pk: &PK,
|
||||||
auth: Auth,
|
auth: Auth,
|
||||||
issued_for: &PublicKey,
|
|
||||||
cur_time: Duration,
|
cur_time: Duration,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
match self.get(&pk)? {
|
match self.get(&issued_for_pk)? {
|
||||||
Some(mut trust_node) => {
|
Some(mut trust_node) => {
|
||||||
trust_node.update_auth(auth);
|
trust_node.update_auth(auth);
|
||||||
self.insert(pk.clone(), trust_node)
|
self.insert(issued_for_pk.clone(), trust_node)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let mut trust_node = TrustNode::new(issued_for.clone(), cur_time);
|
let mut trust_node = TrustNode::new(auth.trust.issued_for.clone(), cur_time);
|
||||||
trust_node.update_auth(auth);
|
trust_node.update_auth(auth);
|
||||||
self.insert(pk.clone(), trust_node)
|
self.insert(issued_for_pk.clone(), trust_node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,30 @@
|
|||||||
// TODO: clear DB before every test, run in 1 thread
|
// TODO: clear DB before every test, run in 1 thread
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use crate::service_impl::{TRUSTED_TIMESTAMP_FUNCTION_NAME, TRUSTED_TIMESTAMP_SERVICE_ID};
|
||||||
use fluence_keypair;
|
use fluence_keypair;
|
||||||
use fluence_keypair::KeyPair;
|
use fluence_keypair::KeyPair;
|
||||||
use marine_rs_sdk_test::marine_test;
|
use marine_rs_sdk_test::{marine_test, CallParameters, SecurityTetraplet};
|
||||||
use std::time::Duration;
|
|
||||||
|
pub static HOST_ID: &str = "host_id";
|
||||||
|
|
||||||
|
fn get_correct_timestamp_cp(arg_number: usize) -> CallParameters {
|
||||||
|
let mut cp = CallParameters::default();
|
||||||
|
cp.host_id = HOST_ID.to_string();
|
||||||
|
|
||||||
|
for _ in 0..arg_number {
|
||||||
|
cp.tetraplets.push(vec![]);
|
||||||
|
}
|
||||||
|
|
||||||
|
cp.tetraplets.push(vec![SecurityTetraplet {
|
||||||
|
peer_pk: HOST_ID.to_string(),
|
||||||
|
service_id: TRUSTED_TIMESTAMP_SERVICE_ID.to_string(),
|
||||||
|
function_name: TRUSTED_TIMESTAMP_FUNCTION_NAME.to_string(),
|
||||||
|
json_path: "".to_string(),
|
||||||
|
}]);
|
||||||
|
|
||||||
|
cp
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! issue_trust {
|
macro_rules! issue_trust {
|
||||||
($trust_graph:expr, $issuer_kp:expr, $issued_peer_id: expr, $expires_at:expr, $issued_at: expr) => {{
|
($trust_graph:expr, $issuer_kp:expr, $issued_peer_id: expr, $expires_at:expr, $issued_at: expr) => {{
|
||||||
@ -64,67 +84,12 @@ mod tests {
|
|||||||
expires_at,
|
expires_at,
|
||||||
issued_at
|
issued_at
|
||||||
);
|
);
|
||||||
let verify_result = trust_graph.verify_trust(trust, issuer_kp.get_peer_id().to_base58(), 0);
|
let verify_result = trust_graph.verify_trust_cp(
|
||||||
|
trust,
|
||||||
|
issuer_kp.get_peer_id().to_base58(),
|
||||||
|
0,
|
||||||
|
get_correct_timestamp_cp(2),
|
||||||
|
);
|
||||||
assert_result!(verify_result);
|
assert_result!(verify_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[marine_test(config_path = "../Config.toml", modules_dir = "../artifacts/")]
|
|
||||||
fn issue_cert_test() {
|
|
||||||
let issuer_kp = KeyPair::generate_ed25519();
|
|
||||||
let issued_peer_id = KeyPair::generate_ed25519().get_peer_id();
|
|
||||||
let issued_at = 0u64;
|
|
||||||
let expires_at = 10u64;
|
|
||||||
let root_trust = issue_trust!(
|
|
||||||
trust_graph,
|
|
||||||
issuer_kp,
|
|
||||||
issuer_kp.get_peer_id(),
|
|
||||||
expires_at,
|
|
||||||
issued_at
|
|
||||||
);
|
|
||||||
let trust = issue_trust!(
|
|
||||||
trust_graph,
|
|
||||||
issuer_kp,
|
|
||||||
issued_peer_id,
|
|
||||||
expires_at,
|
|
||||||
issued_at
|
|
||||||
);
|
|
||||||
|
|
||||||
let cert_result = trust_graph.issue_root_certificate_checked(root_trust, trust, 0u64);
|
|
||||||
assert_result!(cert_result);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[marine_test(config_path = "../Config.toml", modules_dir = "../artifacts/")]
|
|
||||||
fn extend_cert_test() {
|
|
||||||
let issuer_kp = KeyPair::generate_ed25519();
|
|
||||||
let issued_peer_id = KeyPair::generate_ed25519().get_peer_id();
|
|
||||||
let issued_at = 0u64;
|
|
||||||
let expires_at = 10u64;
|
|
||||||
let root_trust = issue_trust!(
|
|
||||||
trust_graph,
|
|
||||||
issuer_kp,
|
|
||||||
issuer_kp.get_peer_id(),
|
|
||||||
expires_at,
|
|
||||||
issued_at
|
|
||||||
);
|
|
||||||
let trust = issue_trust!(
|
|
||||||
trust_graph,
|
|
||||||
issuer_kp,
|
|
||||||
issued_peer_id,
|
|
||||||
expires_at,
|
|
||||||
issued_at
|
|
||||||
);
|
|
||||||
|
|
||||||
let cert_result = trust_graph.issue_root_certificate_checked(root_trust, trust, 0u64);
|
|
||||||
assert_result!(cert_result);
|
|
||||||
println!("{:?}", cert_result.cert);
|
|
||||||
|
|
||||||
assert_result!(trust_graph.add_root(issuer_kp.get_peer_id().to_base58(), 300));
|
|
||||||
|
|
||||||
let insert_res = trust_graph.insert_cert(cert_result.cert, 0u64);
|
|
||||||
assert_result!(insert_res);
|
|
||||||
let all_certs_res = trust_graph.get_all_certs(issued_peer_id.to_base58());
|
|
||||||
assert_result!(all_certs_res);
|
|
||||||
assert_eq!(all_certs_res.certificates.len(), 1);
|
|
||||||
println!("{:?}", all_certs_res.certificates);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,11 @@ data AddRootResult:
|
|||||||
success: bool
|
success: bool
|
||||||
error: string
|
error: string
|
||||||
|
|
||||||
|
data AddTrustResult:
|
||||||
|
success: bool
|
||||||
|
error: string
|
||||||
|
weight: u32
|
||||||
|
|
||||||
data Trust:
|
data Trust:
|
||||||
issued_for: string
|
issued_for: string
|
||||||
expires_at: u64
|
expires_at: u64
|
||||||
@ -26,11 +31,6 @@ data InsertResult:
|
|||||||
success: bool
|
success: bool
|
||||||
error: string
|
error: string
|
||||||
|
|
||||||
data IssueCertificateResult:
|
|
||||||
success: bool
|
|
||||||
error: string
|
|
||||||
cert: Certificate
|
|
||||||
|
|
||||||
data IssueTrustResult:
|
data IssueTrustResult:
|
||||||
success: bool
|
success: bool
|
||||||
error: string
|
error: string
|
||||||
@ -40,12 +40,6 @@ data VerifyTrustResult:
|
|||||||
success: bool
|
success: bool
|
||||||
error: string
|
error: string
|
||||||
|
|
||||||
data AddTrustResult:
|
|
||||||
success: bool
|
|
||||||
error: string
|
|
||||||
weight: u32
|
|
||||||
peer_id: u32
|
|
||||||
|
|
||||||
data WeightResult:
|
data WeightResult:
|
||||||
success: bool
|
success: bool
|
||||||
weight: u32
|
weight: u32
|
||||||
@ -53,41 +47,12 @@ data WeightResult:
|
|||||||
error: string
|
error: string
|
||||||
|
|
||||||
service TrustGraph("trust-graph"):
|
service TrustGraph("trust-graph"):
|
||||||
-- returns hash of metadata to sign
|
add_root(peer_id: string, weight: u32) -> AddRootResult
|
||||||
get_trust_bytes(issued_for_peer_id: string, expires_at: u64, issued_at: u64) -> GetTrustMetadataResult
|
add_trust(trust: Trust, issuer_peer_id: string, timestamp_sec: u64) -> AddTrustResult
|
||||||
|
get_all_certs(issued_for: string) -> AllCertsResult
|
||||||
-- issued_by needed to identify signature type (ed25519, rsa or secp256k1)
|
get_trust_metadata(issued_for_peer_id: string, expires_at: u64, issued_at: u64) -> GetTrustMetadataResult
|
||||||
issue_trust(issued_by_peer_id: string, issued_for_peer_id: string, expires_at: u64, issued_at: u64, signature: []u8) -> IssueTrustResult
|
get_weight(peer_id: string) -> WeightResult
|
||||||
|
insert_cert(certificate: Certificate, timestamp_sec: u64) -> InsertResult
|
||||||
-- just verifying signatures, timestamp without inserting into local trust graph
|
insert_cert_raw(certificate: string, timestamp_sec: u64) -> InsertResult
|
||||||
verify_trust(issued_by_peer_id: string, trust: Trust, timestamp_sec: u64) -> VerifyTrustResult
|
issue_trust(issued_for_peer_id: string, expires_at: u64, issued_at: u64, signed_metadata: []u8) -> IssueTrustResult
|
||||||
|
verify_trust(trust: Trust, issuer_peer_id: string, timestamp_sec: u64) -> VerifyTrustResult
|
||||||
-- checks signature, timestamp, try to find place to insert, returns max_weight if succeed
|
|
||||||
add_trust(issued_by_peer_id: string, trust: Trust, timestamp_sec: u64) -> AddTrustResult
|
|
||||||
|
|
||||||
-- add root trust with given weight
|
|
||||||
add_root(peer_id: string, trust: Trust, weight: u32) -> AddRootResult
|
|
||||||
|
|
||||||
-- return max weight if found, remove expired
|
|
||||||
get_weight(issued_for: string, timestamp_sec: u32) -> WeightResult
|
|
||||||
|
|
||||||
-- return all certs, remove expired
|
|
||||||
get_all_certs(issued_for: string, timestamp_sec) -> AllCertsResult
|
|
||||||
|
|
||||||
-- insert full certificate if possible
|
|
||||||
insert_cert(certificate: Certificate, current_time: u64) -> InsertResult
|
|
||||||
insert_cert_raw(certificate: string, current_time: u64) -> InsertResult
|
|
||||||
|
|
||||||
-- returns hash of metadata to sign
|
|
||||||
get_revoke_bytes(revoked_peer_id: string, revoked_at: u64, issued_at: u64) -> GetRevokeMetadataResult
|
|
||||||
|
|
||||||
-- revoked_by needed to identify signature type (ed25519, rsa or secp256k1)
|
|
||||||
issue_revoke(revoked_by_peer_id: string, revoked_peer_id: string, revoked_at: u64, signature: []u8) -> IssueRevokeResult
|
|
||||||
|
|
||||||
-- checks signature, checks timestamp
|
|
||||||
revoke(revoke: Revoke, timestamp_sec: u64) -> AddRevokeResult
|
|
||||||
|
|
||||||
get_all_revocation(revoked_peer_id: string)
|
|
||||||
|
|
||||||
-- TODO
|
|
||||||
get_trust
|
|
||||||
|
@ -41,6 +41,8 @@ pub use crate::misc::current_time;
|
|||||||
pub use crate::public_key_hashable::PublicKeyHashable;
|
pub use crate::public_key_hashable::PublicKeyHashable;
|
||||||
pub use crate::revoke::Revoke;
|
pub use crate::revoke::Revoke;
|
||||||
pub use crate::trust::{Trust, TrustError};
|
pub use crate::trust::{Trust, TrustError};
|
||||||
pub use crate::trust_graph::{TrustGraph, TrustGraphError, Weight};
|
pub use crate::trust_graph::{TrustGraph, TrustGraphError, WeightFactor};
|
||||||
pub use crate::trust_graph_storage::{Storage, StorageError, InMemoryStorage, InMemoryStorageError};
|
pub use crate::trust_graph_storage::{
|
||||||
|
InMemoryStorage, InMemoryStorageError, Storage, StorageError,
|
||||||
|
};
|
||||||
pub use crate::trust_node::{Auth, TrustNode};
|
pub use crate::trust_node::{Auth, TrustNode};
|
||||||
|
@ -25,7 +25,7 @@ use crate::trust_graph::TrustGraphError::{
|
|||||||
};
|
};
|
||||||
use crate::trust_graph_storage::Storage;
|
use crate::trust_graph_storage::Storage;
|
||||||
use crate::trust_node::{Auth, TrustNode};
|
use crate::trust_node::{Auth, TrustNode};
|
||||||
use crate::StorageError;
|
use crate::{StorageError, TrustError};
|
||||||
use fluence_keypair::public_key::PublicKey;
|
use fluence_keypair::public_key::PublicKey;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::collections::{HashSet, VecDeque};
|
use std::collections::{HashSet, VecDeque};
|
||||||
@ -35,7 +35,9 @@ use std::time::Duration;
|
|||||||
use thiserror::Error as ThisError;
|
use thiserror::Error as ThisError;
|
||||||
|
|
||||||
/// for simplicity, we store `n` where Weight = 1/n^2
|
/// for simplicity, we store `n` where Weight = 1/n^2
|
||||||
pub type Weight = u32;
|
pub type WeightFactor = u32;
|
||||||
|
|
||||||
|
pub static MAX_WEIGHT_FACTOR: u32 = 16;
|
||||||
|
|
||||||
/// Graph to efficiently calculate weights of certificates and get chains of certificates.
|
/// Graph to efficiently calculate weights of certificates and get chains of certificates.
|
||||||
/// TODO serialization/deserialization
|
/// TODO serialization/deserialization
|
||||||
@ -70,6 +72,12 @@ pub enum TrustGraphError {
|
|||||||
),
|
),
|
||||||
#[error("Path to {0} not found")]
|
#[error("Path to {0} not found")]
|
||||||
AddTrustError(String),
|
AddTrustError(String),
|
||||||
|
#[error("Trust verification error: {0}")]
|
||||||
|
TrustVerificationError(
|
||||||
|
#[from]
|
||||||
|
#[source]
|
||||||
|
TrustError,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: StorageError + 'static> From<T> for TrustGraphError {
|
impl<T: StorageError + 'static> From<T> for TrustGraphError {
|
||||||
@ -84,6 +92,10 @@ impl From<TrustGraphError> for String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_weight_from_factor(wf: WeightFactor) -> u32 {
|
||||||
|
2u32.pow(MAX_WEIGHT_FACTOR - wf)
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl<S> TrustGraph<S>
|
impl<S> TrustGraph<S>
|
||||||
where
|
where
|
||||||
@ -94,12 +106,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Insert new root weight
|
/// Insert new root weight
|
||||||
pub fn add_root_weight(
|
pub fn add_root_weight_factor(
|
||||||
&mut self,
|
&mut self,
|
||||||
pk: PublicKey,
|
pk: PublicKey,
|
||||||
weight: Weight,
|
weight: WeightFactor,
|
||||||
) -> Result<(), TrustGraphError> {
|
) -> Result<(), TrustGraphError> {
|
||||||
Ok(self.storage.add_root_weight(pk.into(), weight)?)
|
Ok(self.storage.add_root_weight_factor(pk.into(), weight)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get trust by public key
|
/// Get trust by public key
|
||||||
@ -112,28 +124,29 @@ where
|
|||||||
trust: T,
|
trust: T,
|
||||||
issued_by: P,
|
issued_by: P,
|
||||||
cur_time: Duration,
|
cur_time: Duration,
|
||||||
) -> Result<(), TrustGraphError>
|
) -> Result<u32, TrustGraphError>
|
||||||
where
|
where
|
||||||
T: Borrow<Trust>,
|
T: Borrow<Trust>,
|
||||||
P: Borrow<PublicKey>,
|
P: Borrow<PublicKey>,
|
||||||
{
|
{
|
||||||
Trust::verify(trust, issued_by.borrow(), cur_time)?;
|
Trust::verify(trust.borrow(), issued_by.borrow(), cur_time)?;
|
||||||
|
|
||||||
let _parent_trust_node =
|
let issued_by_weight = self.weight(issued_by.borrow().clone().borrow())?;
|
||||||
self.get(issued_by.clone().borrow())?
|
|
||||||
.ok_or(TrustGraphError::AddTrustError(
|
|
||||||
issued_by.borrow().to_peer_id().to_base58(),
|
|
||||||
))?;
|
|
||||||
|
|
||||||
let pk = trust.issued_for.clone().into();
|
if issued_by_weight == 0u32 {
|
||||||
|
return Ok(0u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
let pk = trust.borrow().issued_for.clone().into();
|
||||||
|
|
||||||
let auth = Auth {
|
let auth = Auth {
|
||||||
trust: trust.clone(),
|
trust: trust.borrow().clone(),
|
||||||
issued_by,
|
issued_by: issued_by.borrow().clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.storage
|
self.storage.update_auth(&pk, auth, cur_time)?;
|
||||||
.update_auth(&pk, auth, &root_trust.issued_for, cur_time)
|
|
||||||
|
Ok(issued_by_weight / 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Certificate is a chain of trusts, add this chain to graph
|
/// Certificate is a chain of trusts, add this chain to graph
|
||||||
@ -148,36 +161,25 @@ where
|
|||||||
.cloned()
|
.cloned()
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
// TODO: add possibility to add certs with root not in trusted_roots (if path to cert root exists)
|
||||||
// Check that certificate is valid and converges to one of the known roots
|
// Check that certificate is valid and converges to one of the known roots
|
||||||
Certificate::verify(cert.borrow(), roots.as_slice(), cur_time)?;
|
Certificate::verify(cert.borrow(), roots.as_slice(), cur_time)?;
|
||||||
|
|
||||||
let mut chain = cert.borrow().chain.iter();
|
let chain = &cert.borrow().chain;
|
||||||
let root_trust = chain.next().ok_or(EmptyChain)?;
|
let root_trust = chain.get(0).ok_or(EmptyChain)?;
|
||||||
let root_pk: PK = root_trust.issued_for.clone().into();
|
|
||||||
|
|
||||||
// Insert new TrustNode for this root_pk if there wasn't one
|
|
||||||
if self.storage.get(&root_pk)?.is_none() {
|
|
||||||
let root_auth = Auth {
|
|
||||||
trust: root_trust.clone(),
|
|
||||||
issued_by: root_trust.issued_for.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.storage
|
|
||||||
.update_auth(&root_pk, root_auth, &root_trust.issued_for, cur_time)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert remaining trusts to the graph
|
// Insert remaining trusts to the graph
|
||||||
let mut previous_trust = root_trust;
|
let mut previous_trust = root_trust;
|
||||||
for trust in chain {
|
for trust in chain {
|
||||||
let pk = trust.issued_for.clone().into();
|
let issued_for_pk = trust.issued_for.clone().into();
|
||||||
|
|
||||||
let auth = Auth {
|
let auth = Auth {
|
||||||
trust: trust.clone(),
|
trust: trust.clone(),
|
||||||
issued_by: previous_trust.issued_for.clone(),
|
issued_by: previous_trust.issued_for.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.storage
|
self.storage.update_auth(&issued_for_pk, auth, cur_time)?;
|
||||||
.update_auth(&pk, auth, &root_trust.issued_for, cur_time)?;
|
|
||||||
|
|
||||||
previous_trust = trust;
|
previous_trust = trust;
|
||||||
}
|
}
|
||||||
@ -186,12 +188,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the maximum weight of trust for one public key.
|
/// Get the maximum weight of trust for one public key.
|
||||||
pub fn weight<P>(&self, pk: P) -> Result<Option<Weight>, TrustGraphError>
|
pub fn weight<P>(&self, pk: P) -> Result<u32, TrustGraphError>
|
||||||
where
|
where
|
||||||
P: Borrow<PublicKey>,
|
P: Borrow<PublicKey>,
|
||||||
{
|
{
|
||||||
if let Some(weight) = self.storage.get_root_weight(pk.borrow().as_ref())? {
|
if let Some(weight_factor) = self.storage.get_root_weight_factor(pk.borrow().as_ref())? {
|
||||||
return Ok(Some(weight));
|
return Ok(get_weight_from_factor(weight_factor));
|
||||||
}
|
}
|
||||||
|
|
||||||
let roots: Vec<PublicKey> = self
|
let roots: Vec<PublicKey> = self
|
||||||
@ -203,14 +205,18 @@ where
|
|||||||
|
|
||||||
// get all possible certificates from the given public key to all roots in the graph
|
// get all possible certificates from the given public key to all roots in the graph
|
||||||
let certs = self.get_all_certs(pk, roots.as_slice())?;
|
let certs = self.get_all_certs(pk, roots.as_slice())?;
|
||||||
self.certificates_weight(certs)
|
self.certificates_weight_factor(certs)
|
||||||
|
.map(get_weight_from_factor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate weight from given certificates
|
/// Calculate weight from given certificates
|
||||||
/// Returns None if there is no such public key
|
/// Returns None if there is no such public key
|
||||||
/// or some trust between this key and a root key is revoked.
|
/// or some trust between this key and a root key is revoked.
|
||||||
/// TODO handle non-direct revocations
|
/// TODO handle non-direct revocations
|
||||||
pub fn certificates_weight<C, I>(&self, certs: I) -> Result<Option<Weight>, TrustGraphError>
|
pub fn certificates_weight_factor<C, I>(
|
||||||
|
&self,
|
||||||
|
certs: I,
|
||||||
|
) -> Result<WeightFactor, TrustGraphError>
|
||||||
where
|
where
|
||||||
C: Borrow<Certificate>,
|
C: Borrow<Certificate>,
|
||||||
I: IntoIterator<Item = C>,
|
I: IntoIterator<Item = C>,
|
||||||
@ -219,10 +225,10 @@ where
|
|||||||
// if there are no certificates for the given public key, there is no info about this public key
|
// if there are no certificates for the given public key, there is no info about this public key
|
||||||
// or some elements of possible certificate chains was revoked
|
// or some elements of possible certificate chains was revoked
|
||||||
if certs.peek().is_none() {
|
if certs.peek().is_none() {
|
||||||
return Ok(None);
|
return Ok(0u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut weight = u32::MAX;
|
let mut weight_factor = u32::MAX;
|
||||||
|
|
||||||
for cert in certs {
|
for cert in certs {
|
||||||
let c = cert.borrow();
|
let c = cert.borrow();
|
||||||
@ -234,15 +240,15 @@ where
|
|||||||
|
|
||||||
let root_weight = self
|
let root_weight = self
|
||||||
.storage
|
.storage
|
||||||
.get_root_weight(first.issued_for.as_ref())?
|
.get_root_weight_factor(first.issued_for.as_ref())?
|
||||||
.ok_or(NoRoot)?;
|
.ok_or(NoRoot)?;
|
||||||
|
|
||||||
// certificate weight = root weight + 1 * every other element in the chain
|
// certificate weight = root weight + 1 * every other element in the chain
|
||||||
// (except root, so the formula is `root weight + chain length - 1`)
|
// (except root, so the formula is `root weight + chain length - 1`)
|
||||||
weight = std::cmp::min(weight, root_weight + c.chain.len() as u32 - 1)
|
weight_factor = std::cmp::min(weight_factor, root_weight + c.chain.len() as u32 - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(weight))
|
Ok(weight_factor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// BF search for all converging paths (chains) in the graph
|
/// BF search for all converging paths (chains) in the graph
|
||||||
@ -463,7 +469,9 @@ mod tests {
|
|||||||
|
|
||||||
let st = InMemoryStorage::new();
|
let st = InMemoryStorage::new();
|
||||||
let mut graph = TrustGraph::new(st);
|
let mut graph = TrustGraph::new(st);
|
||||||
graph.add_root_weight(root.public().into(), 0).unwrap();
|
graph
|
||||||
|
.add_root_weight_factor(root.public().into(), 0)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let addition = graph.add(cert, current_time());
|
let addition = graph.add(cert, current_time());
|
||||||
assert_eq!(addition.is_ok(), true);
|
assert_eq!(addition.is_ok(), true);
|
||||||
@ -497,8 +505,8 @@ mod tests {
|
|||||||
let mut graph = TrustGraph::new(st);
|
let mut graph = TrustGraph::new(st);
|
||||||
let root1_pk = key_pairs1[0].public();
|
let root1_pk = key_pairs1[0].public();
|
||||||
let root2_pk = key_pairs2[0].public();
|
let root2_pk = key_pairs2[0].public();
|
||||||
graph.add_root_weight(root1_pk.into(), 1).unwrap();
|
graph.add_root_weight_factor(root1_pk.into(), 1).unwrap();
|
||||||
graph.add_root_weight(root2_pk.into(), 0).unwrap();
|
graph.add_root_weight_factor(root2_pk.into(), 0).unwrap();
|
||||||
graph.add(cert1, cur_time).unwrap();
|
graph.add(cert1, cur_time).unwrap();
|
||||||
|
|
||||||
let node2 = graph.get(key_pair2.public()).unwrap().unwrap();
|
let node2 = graph.get(key_pair2.public()).unwrap().unwrap();
|
||||||
@ -529,18 +537,19 @@ mod tests {
|
|||||||
let mut graph = TrustGraph::new(st);
|
let mut graph = TrustGraph::new(st);
|
||||||
|
|
||||||
let root_pk = key_pairs[0].public();
|
let root_pk = key_pairs[0].public();
|
||||||
graph.add_root_weight(root_pk.into(), 1).unwrap();
|
graph.add_root_weight_factor(root_pk.into(), 1).unwrap();
|
||||||
|
|
||||||
graph.add(cert1, current_time()).unwrap();
|
graph.add(cert1, current_time()).unwrap();
|
||||||
|
|
||||||
let w1 = graph.weight(key_pairs[0].public()).unwrap().unwrap();
|
let root_weight = get_weight_from_factor(1);
|
||||||
assert_eq!(w1, 1);
|
let w1 = graph.weight(key_pairs[0].public()).unwrap();
|
||||||
|
assert_eq!(w1, root_weight * 2u32.pow(0));
|
||||||
|
|
||||||
let w2 = graph.weight(key_pairs[1].public()).unwrap().unwrap();
|
let w2 = graph.weight(key_pairs[1].public()).unwrap();
|
||||||
assert_eq!(w2, 2);
|
assert_eq!(w2, root_weight / 2u32.pow(1));
|
||||||
|
|
||||||
let w3 = graph.weight(key_pairs[9].public()).unwrap().unwrap();
|
let w3 = graph.weight(key_pairs[9].public()).unwrap();
|
||||||
assert_eq!(w3, 10);
|
assert_eq!(w3, root_weight / 2u32.pow(9));
|
||||||
|
|
||||||
let node = graph.get(key_pairs[9].public()).unwrap().unwrap();
|
let node = graph.get(key_pairs[9].public()).unwrap().unwrap();
|
||||||
let auths: Vec<&Auth> = node.authorizations().collect();
|
let auths: Vec<&Auth> = node.authorizations().collect();
|
||||||
@ -573,8 +582,8 @@ mod tests {
|
|||||||
let mut graph = TrustGraph::new(st);
|
let mut graph = TrustGraph::new(st);
|
||||||
let root1_pk = key_pairs1[0].public();
|
let root1_pk = key_pairs1[0].public();
|
||||||
let root2_pk = key_pairs2[0].public();
|
let root2_pk = key_pairs2[0].public();
|
||||||
graph.add_root_weight(root1_pk.into(), 1).unwrap();
|
graph.add_root_weight_factor(root1_pk.into(), 1).unwrap();
|
||||||
graph.add_root_weight(root2_pk.into(), 0).unwrap();
|
graph.add_root_weight_factor(root2_pk.into(), 0).unwrap();
|
||||||
|
|
||||||
let last_pk1 = cert1.chain[9].issued_for.clone();
|
let last_pk1 = cert1.chain[9].issued_for.clone();
|
||||||
let last_pk2 = cert2.chain[9].issued_for.clone();
|
let last_pk2 = cert2.chain[9].issued_for.clone();
|
||||||
@ -587,15 +596,15 @@ mod tests {
|
|||||||
let revoke2 = Revoke::create(&key_pairs2[5], key_pairs2[6].public(), current_time());
|
let revoke2 = Revoke::create(&key_pairs2[5], key_pairs2[6].public(), current_time());
|
||||||
graph.revoke(revoke2).unwrap();
|
graph.revoke(revoke2).unwrap();
|
||||||
|
|
||||||
let w1 = graph.weight(key_pair1.public()).unwrap().unwrap();
|
let w1 = graph.weight(key_pair1.public()).unwrap();
|
||||||
// all upper trusts are revoked for this public key
|
// all upper trusts are revoked for this public key
|
||||||
let w2 = graph.weight(key_pair2.public()).unwrap();
|
let w2 = graph.weight(key_pair2.public()).unwrap();
|
||||||
let w3 = graph.weight(key_pair3.public()).unwrap().unwrap();
|
let w3 = graph.weight(key_pair3.public()).unwrap();
|
||||||
let w_last1 = graph.weight(last_pk1).unwrap().unwrap();
|
let w_last1 = graph.weight(last_pk1).unwrap();
|
||||||
let w_last2 = graph.weight(last_pk2).unwrap().unwrap();
|
let w_last2 = graph.weight(last_pk2).unwrap();
|
||||||
|
|
||||||
assert_eq!(w1, 4);
|
assert_eq!(w1, 4);
|
||||||
assert_eq!(w2.is_none(), true);
|
assert_eq!(w2, 0);
|
||||||
assert_eq!(w3, 5);
|
assert_eq!(w3, 5);
|
||||||
assert_eq!(w_last1, 7);
|
assert_eq!(w_last1, 7);
|
||||||
assert_eq!(w_last2, 6);
|
assert_eq!(w_last2, 6);
|
||||||
@ -608,7 +617,9 @@ mod tests {
|
|||||||
let st = InMemoryStorage::new();
|
let st = InMemoryStorage::new();
|
||||||
let mut graph = TrustGraph::new(st);
|
let mut graph = TrustGraph::new(st);
|
||||||
let root1_pk = key_pairs[0].public();
|
let root1_pk = key_pairs[0].public();
|
||||||
graph.add_root_weight(root1_pk.clone().into(), 1).unwrap();
|
graph
|
||||||
|
.add_root_weight_factor(root1_pk.clone().into(), 1)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
graph.add(cert.clone(), current_time()).unwrap();
|
graph.add(cert.clone(), current_time()).unwrap();
|
||||||
|
|
||||||
@ -628,13 +639,13 @@ mod tests {
|
|||||||
let mut graph = TrustGraph::new(st);
|
let mut graph = TrustGraph::new(st);
|
||||||
// add first and last trusts as roots
|
// add first and last trusts as roots
|
||||||
graph
|
graph
|
||||||
.add_root_weight(cert.chain[0].clone().issued_for.into(), 1)
|
.add_root_weight_factor(cert.chain[0].clone().issued_for.into(), 1)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
graph
|
graph
|
||||||
.add_root_weight(cert.chain[3].clone().issued_for.into(), 1)
|
.add_root_weight_factor(cert.chain[3].clone().issued_for.into(), 1)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
graph
|
graph
|
||||||
.add_root_weight(cert.chain[5].clone().issued_for.into(), 1)
|
.add_root_weight_factor(cert.chain[5].clone().issued_for.into(), 1)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
graph.add(cert.clone(), current_time()).unwrap();
|
graph.add(cert.clone(), current_time()).unwrap();
|
||||||
@ -677,9 +688,15 @@ mod tests {
|
|||||||
let root1_pk = key_pairs1[0].public();
|
let root1_pk = key_pairs1[0].public();
|
||||||
let root2_pk = key_pairs2[0].public();
|
let root2_pk = key_pairs2[0].public();
|
||||||
let root3_pk = key_pairs3[0].public();
|
let root3_pk = key_pairs3[0].public();
|
||||||
graph.add_root_weight(root1_pk.clone().into(), 1).unwrap();
|
graph
|
||||||
graph.add_root_weight(root2_pk.clone().into(), 0).unwrap();
|
.add_root_weight_factor(root1_pk.clone().into(), 1)
|
||||||
graph.add_root_weight(root3_pk.clone().into(), 0).unwrap();
|
.unwrap();
|
||||||
|
graph
|
||||||
|
.add_root_weight_factor(root2_pk.clone().into(), 0)
|
||||||
|
.unwrap();
|
||||||
|
graph
|
||||||
|
.add_root_weight_factor(root3_pk.clone().into(), 0)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
graph.add(cert1, current_time()).unwrap();
|
graph.add(cert1, current_time()).unwrap();
|
||||||
graph.add(cert2, current_time()).unwrap();
|
graph.add(cert2, current_time()).unwrap();
|
||||||
@ -708,4 +725,74 @@ mod tests {
|
|||||||
let check_lenghts3: Vec<usize> = vec![3, 3, 5];
|
let check_lenghts3: Vec<usize> = vec![3, 3, 5];
|
||||||
assert_eq!(lenghts3, check_lenghts3);
|
assert_eq!(lenghts3, check_lenghts3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_add_one_trust_to_cert_last() {
|
||||||
|
let (key_pairs, mut cert) = generate_cert_with_len(5, HashMap::new()).unwrap();
|
||||||
|
let cur_time = current_time();
|
||||||
|
|
||||||
|
let st = InMemoryStorage::new();
|
||||||
|
let mut graph = TrustGraph::new(st);
|
||||||
|
let root_pk = key_pairs[0].public();
|
||||||
|
graph
|
||||||
|
.add_root_weight_factor(root_pk.clone().into(), 2)
|
||||||
|
.unwrap();
|
||||||
|
graph.add(cert.clone(), cur_time).unwrap();
|
||||||
|
|
||||||
|
let issued_by = key_pairs.last().unwrap();
|
||||||
|
let trust_kp = KeyPair::generate_ed25519();
|
||||||
|
let trust = Trust::create(
|
||||||
|
issued_by,
|
||||||
|
trust_kp.public(),
|
||||||
|
cur_time.checked_add(one_minute()).unwrap(),
|
||||||
|
cur_time,
|
||||||
|
);
|
||||||
|
|
||||||
|
let weight = graph
|
||||||
|
.add_trust(trust.clone(), issued_by.public(), cur_time)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(weight, graph.weight(issued_by.public()).unwrap() / 2);
|
||||||
|
|
||||||
|
cert.chain.push(trust);
|
||||||
|
|
||||||
|
let certs = graph.get_all_certs(trust_kp.public(), &[]).unwrap();
|
||||||
|
assert_eq!(certs.len(), 1);
|
||||||
|
assert_eq!(certs[0], cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_add_one_trust_to_cert_after_root() {
|
||||||
|
let (key_pairs, cert) = generate_cert_with_len(5, HashMap::new()).unwrap();
|
||||||
|
let cur_time = current_time();
|
||||||
|
|
||||||
|
let st = InMemoryStorage::new();
|
||||||
|
let mut graph = TrustGraph::new(st);
|
||||||
|
let root1_pk = key_pairs[0].public();
|
||||||
|
graph
|
||||||
|
.add_root_weight_factor(root1_pk.clone().into(), 2)
|
||||||
|
.unwrap();
|
||||||
|
graph.add(cert.clone(), cur_time).unwrap();
|
||||||
|
|
||||||
|
let issued_by = key_pairs.first().unwrap();
|
||||||
|
let trust_kp = KeyPair::generate_ed25519();
|
||||||
|
let trust = Trust::create(
|
||||||
|
issued_by,
|
||||||
|
trust_kp.public(),
|
||||||
|
cur_time.checked_add(one_minute()).unwrap(),
|
||||||
|
cur_time,
|
||||||
|
);
|
||||||
|
|
||||||
|
let weight = graph
|
||||||
|
.add_trust(trust.clone(), issued_by.public(), cur_time)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(weight, graph.weight(issued_by.public()).unwrap() / 2);
|
||||||
|
|
||||||
|
let target_cert = Certificate {
|
||||||
|
chain: vec![cert.chain[0].clone(), trust],
|
||||||
|
};
|
||||||
|
|
||||||
|
let certs = graph.get_all_certs(trust_kp.public(), &[root1_pk]).unwrap();
|
||||||
|
assert_eq!(certs.len(), 1);
|
||||||
|
assert_eq!(certs[0], target_cert);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::public_key_hashable::PublicKeyHashable as PK;
|
use crate::public_key_hashable::PublicKeyHashable as PK;
|
||||||
use crate::revoke::Revoke;
|
use crate::revoke::Revoke;
|
||||||
use crate::trust_graph::Weight;
|
use crate::trust_graph::WeightFactor;
|
||||||
use crate::trust_graph_storage::InMemoryStorageError::RevokeError;
|
use crate::trust_graph_storage::InMemoryStorageError::RevokeError;
|
||||||
use crate::trust_node::{Auth, TrustNode};
|
use crate::trust_node::{Auth, TrustNode};
|
||||||
use fluence_keypair::public_key::PublicKey;
|
use fluence_keypair::public_key::PublicKey;
|
||||||
@ -17,28 +17,22 @@ pub trait Storage {
|
|||||||
fn get(&self, pk: &PK) -> Result<Option<TrustNode>, Self::Error>;
|
fn get(&self, pk: &PK) -> Result<Option<TrustNode>, Self::Error>;
|
||||||
fn insert(&mut self, pk: PK, node: TrustNode) -> Result<(), Self::Error>;
|
fn insert(&mut self, pk: PK, node: TrustNode) -> Result<(), Self::Error>;
|
||||||
|
|
||||||
fn get_root_weight(&self, pk: &PK) -> Result<Option<Weight>, Self::Error>;
|
fn get_root_weight_factor(&self, pk: &PK) -> Result<Option<WeightFactor>, Self::Error>;
|
||||||
fn add_root_weight(&mut self, pk: PK, weight: Weight) -> Result<(), 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 root_keys(&self) -> Result<Vec<PK>, Self::Error>;
|
||||||
fn revoke(&mut self, pk: &PK, revoke: Revoke) -> Result<(), Self::Error>;
|
fn revoke(&mut self, pk: &PK, revoke: Revoke) -> Result<(), Self::Error>;
|
||||||
fn update_auth(
|
fn update_auth(&mut self, pk: &PK, auth: Auth, cur_time: Duration) -> Result<(), Self::Error>;
|
||||||
&mut self,
|
|
||||||
pk: &PK,
|
|
||||||
auth: Auth,
|
|
||||||
issued_for: &PublicKey,
|
|
||||||
cur_time: Duration,
|
|
||||||
) -> Result<(), Self::Error>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct InMemoryStorage {
|
pub struct InMemoryStorage {
|
||||||
nodes: HashMap<PK, TrustNode>,
|
nodes: HashMap<PK, TrustNode>,
|
||||||
root_weights: HashMap<PK, Weight>,
|
root_weights: HashMap<PK, WeightFactor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InMemoryStorage {
|
impl InMemoryStorage {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn new_in_memory(root_weights: Vec<(PublicKey, Weight)>) -> Self {
|
pub fn new_in_memory(root_weights: Vec<(PublicKey, WeightFactor)>) -> Self {
|
||||||
let root_weights = root_weights
|
let root_weights = root_weights
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(k, w)| (k.into(), w))
|
.map(|(k, w)| (k.into(), w))
|
||||||
@ -78,11 +72,11 @@ impl Storage for InMemoryStorage {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_root_weight(&self, pk: &PK) -> Result<Option<Weight>, Self::Error> {
|
fn get_root_weight_factor(&self, pk: &PK) -> Result<Option<WeightFactor>, Self::Error> {
|
||||||
Ok(self.root_weights.get(pk).cloned())
|
Ok(self.root_weights.get(pk).cloned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_root_weight(&mut self, pk: PK, weight: Weight) -> Result<(), Self::Error> {
|
fn add_root_weight_factor(&mut self, pk: PK, weight: WeightFactor) -> Result<(), Self::Error> {
|
||||||
self.root_weights.insert(pk, weight);
|
self.root_weights.insert(pk, weight);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -105,20 +99,19 @@ impl Storage for InMemoryStorage {
|
|||||||
|
|
||||||
fn update_auth(
|
fn update_auth(
|
||||||
&mut self,
|
&mut self,
|
||||||
pk: &PK,
|
issued_for_pk: &PK,
|
||||||
auth: Auth,
|
auth: Auth,
|
||||||
issued_for: &PublicKey,
|
|
||||||
cur_time: Duration,
|
cur_time: Duration,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
match self.nodes.get_mut(&pk) {
|
match self.nodes.get_mut(&issued_for_pk) {
|
||||||
Some(trust_node) => {
|
Some(trust_node) => {
|
||||||
trust_node.update_auth(auth);
|
trust_node.update_auth(auth);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let mut trust_node = TrustNode::new(issued_for.clone(), cur_time);
|
let mut trust_node = TrustNode::new(auth.trust.issued_for.clone(), cur_time);
|
||||||
trust_node.update_auth(auth);
|
trust_node.update_auth(auth);
|
||||||
self.insert(pk.clone(), trust_node)
|
self.insert(issued_for_pk.clone(), trust_node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user