2021-08-26 17:27:05 +03:00
|
|
|
use crate::dto::{Certificate, DtoConversionError, Trust};
|
2021-09-14 14:21:26 +03:00
|
|
|
use crate::service_impl::ServiceError::InvalidTimestampTetraplet;
|
2021-02-12 14:42:51 +03:00
|
|
|
use crate::storage_impl::get_data;
|
2021-08-12 15:49:03 +03:00
|
|
|
use fluence_keypair::error::DecodingError;
|
2021-09-06 18:13:08 +03:00
|
|
|
use fluence_keypair::public_key::peer_id_to_fluence_pk;
|
|
|
|
use fluence_keypair::{PublicKey, Signature};
|
|
|
|
use libp2p_core::PeerId;
|
2021-09-14 14:21:26 +03:00
|
|
|
use marine_rs_sdk::CallParameters;
|
2021-02-12 14:42:51 +03:00
|
|
|
use std::convert::{Into, TryInto};
|
|
|
|
use std::str::FromStr;
|
|
|
|
use std::time::Duration;
|
|
|
|
use thiserror::Error as ThisError;
|
2021-09-06 18:13:08 +03:00
|
|
|
use trust_graph::{current_time, CertificateError, TrustError, TrustGraphError};
|
2021-02-12 14:42:51 +03:00
|
|
|
|
2021-09-14 14:21:26 +03:00
|
|
|
pub static TRUSTED_TIMESTAMP_SERVICE_ID: &str = "peer";
|
|
|
|
pub static TRUSTED_TIMESTAMP_FUNCTION_NAME: &str = "timestamp_sec";
|
|
|
|
|
|
|
|
/// Check timestamps are generated on the current host with builtin ("peer" "timestamp_sec")
|
|
|
|
pub(crate) fn check_timestamp_tetraplets(
|
|
|
|
call_parameters: &CallParameters,
|
|
|
|
arg_number: usize,
|
|
|
|
) -> Result<(), ServiceError> {
|
|
|
|
let tetraplets = call_parameters
|
|
|
|
.tetraplets
|
|
|
|
.get(arg_number)
|
|
|
|
.ok_or(InvalidTimestampTetraplet)?;
|
|
|
|
let tetraplet = tetraplets.get(0).wrap_err(error_msg)?;
|
|
|
|
(tetraplet.service_id == TRUSTED_TIMESTAMP_SERVICE_ID
|
|
|
|
&& tetraplet.function_name == TRUSTED_TIMESTAMP_FUNCTION_NAME
|
|
|
|
&& tetraplet.peer_pk == call_parameters.host_id)
|
|
|
|
.then(|| ())
|
|
|
|
.ok_or(InvalidTimestampTetraplet)
|
|
|
|
}
|
|
|
|
|
2021-02-12 14:42:51 +03:00
|
|
|
#[derive(ThisError, Debug)]
|
|
|
|
pub enum ServiceError {
|
2021-08-12 16:16:58 +03:00
|
|
|
#[error("peer id parse error: {0}")]
|
|
|
|
PeerIdParseError(String),
|
|
|
|
#[error("public key extraction from peer id failed: {0}")]
|
|
|
|
PublicKeyExtractionError(String),
|
2021-02-15 13:01:22 +03:00
|
|
|
#[error("{0}")]
|
|
|
|
PublicKeyDecodeError(
|
|
|
|
#[from]
|
|
|
|
#[source]
|
2021-08-01 16:31:13 +03:00
|
|
|
DecodingError,
|
2021-02-15 13:01:22 +03:00
|
|
|
),
|
|
|
|
#[error("{0}")]
|
|
|
|
TGError(
|
|
|
|
#[from]
|
|
|
|
#[source]
|
|
|
|
TrustGraphError,
|
|
|
|
),
|
|
|
|
#[error("{0}")]
|
|
|
|
CertError(
|
|
|
|
#[from]
|
|
|
|
#[source]
|
|
|
|
CertificateError,
|
|
|
|
),
|
|
|
|
#[error("{0}")]
|
|
|
|
DtoError(
|
|
|
|
#[from]
|
|
|
|
#[source]
|
|
|
|
DtoConversionError,
|
|
|
|
),
|
2021-09-06 18:13:08 +03:00
|
|
|
#[error("{0}")]
|
|
|
|
TrustError(
|
|
|
|
#[from]
|
|
|
|
#[source]
|
|
|
|
TrustError,
|
|
|
|
),
|
2021-09-14 14:21:26 +03:00
|
|
|
#[error("you should use host peer.timestamp_sec to pass timestamp")]
|
|
|
|
InvalidTimestampTetraplet,
|
2021-02-12 14:42:51 +03:00
|
|
|
}
|
|
|
|
|
2021-08-12 16:16:58 +03:00
|
|
|
fn parse_peer_id(peer_id: String) -> Result<PeerId, ServiceError> {
|
2021-09-06 18:13:08 +03:00
|
|
|
libp2p_core::PeerId::from_str(&peer_id)
|
|
|
|
.map_err(|e| ServiceError::PeerIdParseError(format!("{:?}", e)))
|
2021-08-12 16:16:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn extract_public_key(peer_id: String) -> Result<PublicKey, ServiceError> {
|
2021-09-06 18:13:08 +03:00
|
|
|
peer_id_to_fluence_pk(parse_peer_id(peer_id)?)
|
|
|
|
.map_err(|e| ServiceError::PublicKeyExtractionError(e.to_string()))
|
2021-08-12 16:16:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_weight_impl(peer_id: String) -> Result<Option<u32>, ServiceError> {
|
2021-02-12 14:42:51 +03:00
|
|
|
let tg = get_data().lock();
|
2021-08-12 16:16:58 +03:00
|
|
|
let public_key = extract_public_key(peer_id)?;
|
2021-02-12 14:42:51 +03:00
|
|
|
let weight = tg.weight(public_key)?;
|
|
|
|
Ok(weight)
|
|
|
|
}
|
|
|
|
|
2021-09-14 14:21:26 +03:00
|
|
|
fn add_cert(certificate: trust_graph::Certificate, timestamp_sec: u64) -> Result<(), ServiceError> {
|
|
|
|
let timestamp_sec = Duration::from_secs(timestamp_sec);
|
2021-02-12 14:42:51 +03:00
|
|
|
let mut tg = get_data().lock();
|
2021-09-14 14:21:26 +03:00
|
|
|
tg.add(certificate, timestamp_sec)?;
|
2021-02-12 14:42:51 +03:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2021-09-14 14:21:26 +03:00
|
|
|
pub fn insert_cert_impl_raw(certificate: String, timestamp_sec: u64) -> Result<(), ServiceError> {
|
2021-02-12 14:42:51 +03:00
|
|
|
let certificate = trust_graph::Certificate::from_str(&certificate)?;
|
|
|
|
|
2021-09-14 14:21:26 +03:00
|
|
|
add_cert(certificate, timestamp_sec)?;
|
2021-02-12 14:42:51 +03:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn string_to_public_key(public_key: String) -> Result<PublicKey, ServiceError> {
|
|
|
|
let public_key = PublicKey::from_base58(&public_key)?;
|
|
|
|
|
|
|
|
Ok(public_key)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_all_certs_impl(issued_for: String) -> Result<Vec<Certificate>, ServiceError> {
|
|
|
|
let tg = get_data().lock();
|
|
|
|
|
2021-08-12 16:16:58 +03:00
|
|
|
let public_key = extract_public_key(issued_for)?;
|
2021-02-12 14:42:51 +03:00
|
|
|
let certs = tg.get_all_certs(public_key, &[])?;
|
|
|
|
Ok(certs.into_iter().map(|c| c.into()).collect())
|
|
|
|
}
|
|
|
|
|
2021-09-14 14:21:26 +03:00
|
|
|
pub fn insert_cert_impl(certificate: Certificate, timestamp_sec: u64) -> Result<(), ServiceError> {
|
2021-02-12 14:42:51 +03:00
|
|
|
let certificate: trust_graph::Certificate = certificate.try_into()?;
|
|
|
|
|
2021-09-14 14:21:26 +03:00
|
|
|
add_cert(certificate, timestamp_sec)?;
|
2021-02-12 14:42:51 +03:00
|
|
|
Ok(())
|
|
|
|
}
|
2021-02-12 14:54:08 +03:00
|
|
|
|
2021-08-12 16:16:58 +03:00
|
|
|
pub fn add_root_impl(peer_id: String, weight: u32) -> Result<(), ServiceError> {
|
2021-02-12 14:54:08 +03:00
|
|
|
let mut tg = get_data().lock();
|
2021-08-12 16:16:58 +03:00
|
|
|
let public_key = extract_public_key(peer_id)?;
|
|
|
|
tg.add_root_weight(public_key, weight)?;
|
2021-02-12 14:54:08 +03:00
|
|
|
Ok(())
|
|
|
|
}
|
2021-08-26 17:27:05 +03:00
|
|
|
|
2021-09-06 18:13:08 +03:00
|
|
|
pub fn get_trust_metadata_imp(
|
|
|
|
peer_id: String,
|
|
|
|
expires_at: u64,
|
|
|
|
issued_at: u64,
|
|
|
|
) -> Result<Vec<u8>, ServiceError> {
|
|
|
|
let public_key = extract_public_key(peer_id)?;
|
|
|
|
Ok(trust_graph::Trust::metadata_bytes(
|
|
|
|
&public_key,
|
|
|
|
Duration::from_secs(expires_at),
|
|
|
|
Duration::from_secs(issued_at),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn issue_trust_impl(
|
|
|
|
peer_id: String,
|
|
|
|
expires_at: u64,
|
|
|
|
issued_at: u64,
|
|
|
|
signed_metadata: Vec<u8>,
|
|
|
|
) -> Result<Trust, ServiceError> {
|
2021-08-26 17:27:05 +03:00
|
|
|
let public_key = extract_public_key(peer_id)?;
|
2021-09-06 18:13:08 +03:00
|
|
|
let expires_at = Duration::from_secs(expires_at);
|
|
|
|
let issued_at = Duration::from_secs(issued_at);
|
|
|
|
let signature = Signature::from_bytes_with_public_key(&public_key, signed_metadata);
|
|
|
|
Ok(Trust::from(trust_graph::Trust::new(
|
|
|
|
public_key, expires_at, issued_at, signature,
|
|
|
|
)))
|
2021-08-26 17:27:05 +03:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:13:08 +03:00
|
|
|
pub fn verify_trust_impl(
|
|
|
|
trust: Trust,
|
|
|
|
issuer_peer_id: String,
|
2021-09-14 14:21:26 +03:00
|
|
|
timestamp_sec: u64,
|
2021-09-06 18:13:08 +03:00
|
|
|
) -> Result<(), ServiceError> {
|
2021-09-14 14:21:26 +03:00
|
|
|
check_timestamp_tetraplets(&marine_rs_sdk::get_call_parameters(), 2)?;
|
2021-09-06 18:13:08 +03:00
|
|
|
let public_key = extract_public_key(issuer_peer_id)?;
|
|
|
|
trust_graph::Trust::verify(
|
|
|
|
&trust.try_into()?,
|
|
|
|
&public_key,
|
2021-09-14 14:21:26 +03:00
|
|
|
Duration::from_secs(timestamp_sec),
|
2021-09-06 18:13:08 +03:00
|
|
|
)?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2021-09-14 14:21:26 +03:00
|
|
|
pub fn add_trust_impl(
|
2021-09-06 18:13:08 +03:00
|
|
|
trust: Trust,
|
2021-09-14 14:21:26 +03:00
|
|
|
issuer_peer_id: String,
|
|
|
|
timestamp_sec: u64,
|
|
|
|
) -> Result<(), ServiceError> {
|
|
|
|
let public_key = extract_public_key(issuer_peer_id)?;
|
|
|
|
check_timestamp_tetraplets(&marine_rs_sdk::get_call_parameters(), 2)?;
|
|
|
|
let mut tg = get_data().lock();
|
|
|
|
tg.add_trust(
|
2021-09-06 18:13:08 +03:00
|
|
|
trust.try_into()?,
|
2021-09-14 14:21:26 +03:00
|
|
|
public_key,
|
|
|
|
Duration::from_secs(timestamp_sec),
|
|
|
|
)?;
|
|
|
|
|
|
|
|
Ok(())
|
2021-09-06 18:13:08 +03:00
|
|
|
}
|