mirror of
https://github.com/fluencelabs/trust-graph
synced 2025-03-15 12:50:48 +00:00
structurize errors
This commit is contained in:
parent
feac5dadf6
commit
1e9b8ba33b
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -406,6 +406,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
"signature",
|
"signature",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
1
identity/Cargo.lock
generated
1
identity/Cargo.lock
generated
@ -344,6 +344,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
"signature",
|
"signature",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -16,3 +16,4 @@ rand = "0.7.0"
|
|||||||
signature = "1.3.0"
|
signature = "1.3.0"
|
||||||
ed25519 = "1.0.3"
|
ed25519 = "1.0.3"
|
||||||
serde_with = "1.6.0"
|
serde_with = "1.6.0"
|
||||||
|
thiserror = "1.0.23"
|
||||||
|
@ -79,11 +79,10 @@ impl KeyPair {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Verify the Ed25519 signature on a message using the public key.
|
/// Verify the Ed25519 signature on a message using the public key.
|
||||||
pub fn verify(pk: &PublicKey, msg: &[u8], signature: &Signature) -> Result<(), String> {
|
pub fn verify(pk: &PublicKey, msg: &[u8], signature: &Signature) -> Result<(), SignatureError> {
|
||||||
// let signature = ed25519_dalek::Signature::from_bytes(signature)
|
// let signature = ed25519_dalek::Signature::from_bytes(signature)
|
||||||
// .map_err(|err| format!("Cannot convert bytes to a signature: {:?}", err))?;
|
// .map_err(|err| format!("Cannot convert bytes to a signature: {:?}", err))?;
|
||||||
pk.verify_strict(msg, signature)
|
pk.verify_strict(msg, signature)
|
||||||
.map_err(|err| format!("Signature verification failed: {:?}", err))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,10 +14,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use crate::public_key::PKError::{FromBase58Error, FromBytesError};
|
||||||
use crate::signature::Signature;
|
use crate::signature::Signature;
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use ed25519_dalek::SignatureError;
|
use ed25519_dalek::SignatureError;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use thiserror::Error as ThisError;
|
||||||
|
|
||||||
|
#[derive(ThisError, Debug)]
|
||||||
|
pub enum PKError {
|
||||||
|
#[error("Cannot decode public key from bytes: {0}")]
|
||||||
|
FromBytesError(SignatureError),
|
||||||
|
#[error("Cannot decode public key from base58 format: {0}")]
|
||||||
|
FromBase58Error(bs58::decode::Error),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Default, Eq, PartialEq, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct PublicKey(pub(crate) ed25519_dalek::PublicKey);
|
pub struct PublicKey(pub(crate) ed25519_dalek::PublicKey);
|
||||||
@ -37,9 +47,13 @@ impl PublicKey {
|
|||||||
self.0.verify_strict(message, &signature.0)
|
self.0.verify_strict(message, &signature.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Result<PublicKey, SignatureError> {
|
pub fn from_base58(str: &str) -> Result<PublicKey, PKError> {
|
||||||
let pk = ed25519_dalek::PublicKey::from_bytes(bytes)?;
|
let bytes = bs58::decode(str).into_vec().map_err(FromBase58Error)?;
|
||||||
|
Self::from_bytes(&bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_bytes(bytes: &[u8]) -> Result<PublicKey, PKError> {
|
||||||
|
let pk = ed25519_dalek::PublicKey::from_bytes(bytes).map_err(FromBytesError)?;
|
||||||
Ok(PublicKey(pk))
|
Ok(PublicKey(pk))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use signature::Error as SigError;
|
||||||
use signature::Signature as SigSignature;
|
use signature::Signature as SigSignature;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
@ -33,8 +34,8 @@ impl Signature {
|
|||||||
self.0.to_bytes()
|
self.0.to_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, String> {
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self, SigError> {
|
||||||
let sig = ed25519_dalek::Signature::from_bytes(bytes).map_err(|err| err.to_string())?;
|
let sig = ed25519_dalek::Signature::from_bytes(bytes)?;
|
||||||
Ok(Signature(sig))
|
Ok(Signature(sig))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,11 +36,11 @@ mod trust_graph;
|
|||||||
mod trust_graph_storage;
|
mod trust_graph_storage;
|
||||||
mod trust_node;
|
mod trust_node;
|
||||||
|
|
||||||
pub use crate::certificate::Certificate;
|
pub use crate::certificate::{Certificate, CertificateError};
|
||||||
pub use crate::misc::current_time;
|
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;
|
pub use crate::trust::Trust;
|
||||||
pub use crate::trust_graph::{TrustGraph, Weight};
|
pub use crate::trust_graph::{TrustGraph, TrustGraphError, Weight};
|
||||||
pub use crate::trust_graph_storage::{Storage, StorageError};
|
pub use crate::trust_graph_storage::{Storage, StorageError};
|
||||||
pub use crate::trust_node::{Auth, TrustNode};
|
pub use crate::trust_node::{Auth, TrustNode};
|
||||||
|
@ -14,11 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use fluence_identity::public_key::PublicKey;
|
use fluence_identity::public_key::{PKError, PublicKey};
|
||||||
|
|
||||||
use crate::public_key_hashable::PkError::{Base58DecodeError, BytesDecodeError};
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use ed25519_dalek::SignatureError;
|
|
||||||
use ref_cast::RefCast;
|
use ref_cast::RefCast;
|
||||||
use serde::ser::Serializer;
|
use serde::ser::Serializer;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
@ -26,7 +24,6 @@ use std::{
|
|||||||
fmt::{Display, Formatter},
|
fmt::{Display, Formatter},
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
};
|
};
|
||||||
use thiserror::Error as ThisError;
|
|
||||||
|
|
||||||
/// Wrapper to use PublicKey in HashMap
|
/// Wrapper to use PublicKey in HashMap
|
||||||
#[derive(PartialEq, Eq, Debug, Clone, RefCast)]
|
#[derive(PartialEq, Eq, Debug, Clone, RefCast)]
|
||||||
@ -84,23 +81,11 @@ impl Display for PublicKeyHashable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(ThisError, Debug)]
|
|
||||||
pub enum PkError {
|
|
||||||
#[error("Invalid string '{0}': {1}")]
|
|
||||||
Base58DecodeError(String, bs58::decode::Error),
|
|
||||||
#[error("Invalid bytes {0:?}: {1}")]
|
|
||||||
BytesDecodeError(Vec<u8>, SignatureError),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for PublicKeyHashable {
|
impl FromStr for PublicKeyHashable {
|
||||||
type Err = PkError;
|
type Err = PKError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
let bytes = bs58::decode(s)
|
let pk = PublicKey::from_base58(s)?;
|
||||||
.into_vec()
|
|
||||||
.map_err(|err| Base58DecodeError(s.to_string(), err))?;
|
|
||||||
|
|
||||||
let pk = PublicKey::from_bytes(&bytes).map_err(|err| BytesDecodeError(bytes, err))?;
|
|
||||||
Ok(PublicKeyHashable::from(pk))
|
Ok(PublicKeyHashable::from(pk))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
33
src/trust.rs
33
src/trust.rs
@ -14,10 +14,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::trust::TrustError::{DecodeError, SignatureError};
|
use crate::trust::TrustError::{
|
||||||
|
DecodeError, IncorrectTrustLength, PublicKeyError, SignatureError, SignatureFromBytesError,
|
||||||
|
};
|
||||||
use derivative::Derivative;
|
use derivative::Derivative;
|
||||||
use fluence_identity::key_pair::KeyPair;
|
use fluence_identity::key_pair::KeyPair;
|
||||||
use fluence_identity::public_key::PublicKey;
|
use fluence_identity::public_key::{PKError, PublicKey};
|
||||||
use fluence_identity::signature::Signature;
|
use fluence_identity::signature::Signature;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
@ -65,11 +67,22 @@ pub enum TrustError {
|
|||||||
|
|
||||||
/// Errors occured on signature verification
|
/// Errors occured on signature verification
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
SignatureError(String),
|
SignatureError(ed25519_dalek::SignatureError),
|
||||||
|
|
||||||
/// Errors occured on trust decoding from differrent formats
|
/// Errors occured on trust decoding from differrent formats
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
DecodeError(String),
|
DecodeError(String),
|
||||||
|
|
||||||
|
#[error("Cannot decode a signature from bytes: {0}")]
|
||||||
|
SignatureFromBytesError(signature::Error),
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
PublicKeyError(PKError),
|
||||||
|
|
||||||
|
#[error(
|
||||||
|
"Trust length should be 104: public key(32) + signature(64) + expiration date(8), was: {0}"
|
||||||
|
)]
|
||||||
|
IncorrectTrustLength(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Trust {
|
impl Trust {
|
||||||
@ -155,19 +168,13 @@ impl Trust {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn decode(arr: &[u8]) -> Result<Self, TrustError> {
|
pub fn decode(arr: &[u8]) -> Result<Self, TrustError> {
|
||||||
if arr.len() != TRUST_LEN {
|
if arr.len() != TRUST_LEN {
|
||||||
return Err(DecodeError(
|
return Err(IncorrectTrustLength(arr.len()));
|
||||||
format!("Trust length should be 104: public key(32) + signature(64) + expiration date(8), was: {}",
|
|
||||||
arr.len())
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let pk = PublicKey::from_bytes(&arr[0..PK_LEN]).map_err(|err| {
|
let pk = PublicKey::from_bytes(&arr[0..PK_LEN]).map_err(PublicKeyError)?;
|
||||||
DecodeError(format!("Cannot decode a public key: {}", err.to_string()))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let signature = &arr[PK_LEN..PK_LEN + SIG_LEN];
|
let signature = &arr[PK_LEN..PK_LEN + SIG_LEN];
|
||||||
let signature = Signature::from_bytes(signature)
|
let signature = Signature::from_bytes(signature).map_err(SignatureFromBytesError)?;
|
||||||
.map_err(|err| DecodeError(format!("Cannot decode a signature: {}", err)))?;
|
|
||||||
|
|
||||||
let expiration_bytes = &arr[PK_LEN + SIG_LEN..PK_LEN + SIG_LEN + EXPIRATION_LEN];
|
let expiration_bytes = &arr[PK_LEN + SIG_LEN..PK_LEN + SIG_LEN + EXPIRATION_LEN];
|
||||||
let expiration_date = u64::from_le_bytes(expiration_bytes.try_into().unwrap());
|
let expiration_date = u64::from_le_bytes(expiration_bytes.try_into().unwrap());
|
||||||
@ -221,7 +228,7 @@ impl Trust {
|
|||||||
|
|
||||||
// 64 bytes signature
|
// 64 bytes signature
|
||||||
let signature = Self::bs58_str_to_vec(signature, "signature")?;
|
let signature = Self::bs58_str_to_vec(signature, "signature")?;
|
||||||
let signature = Signature::from_bytes(&signature).map_err(DecodeError)?;
|
let signature = Signature::from_bytes(&signature).map_err(SignatureFromBytesError)?;
|
||||||
|
|
||||||
// Duration
|
// Duration
|
||||||
let expires_at = Self::str_to_duration(expires_at, "expires_at")?;
|
let expires_at = Self::str_to_duration(expires_at, "expires_at")?;
|
||||||
|
1
wasm/Cargo.lock
generated
1
wasm/Cargo.lock
generated
@ -441,6 +441,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
"signature",
|
"signature",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::dto::Certificate;
|
use crate::dto::Certificate;
|
||||||
|
use crate::service_api::ServiceError;
|
||||||
use fluence::fce;
|
use fluence::fce;
|
||||||
|
|
||||||
#[fce]
|
#[fce]
|
||||||
@ -7,8 +8,8 @@ pub struct InsertResult {
|
|||||||
pub error: String,
|
pub error: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Result<(), String>> for InsertResult {
|
impl From<Result<(), ServiceError>> for InsertResult {
|
||||||
fn from(result: Result<(), String>) -> Self {
|
fn from(result: Result<(), ServiceError>) -> Self {
|
||||||
match result {
|
match result {
|
||||||
Ok(()) => InsertResult {
|
Ok(()) => InsertResult {
|
||||||
ret_code: 0,
|
ret_code: 0,
|
||||||
@ -16,7 +17,7 @@ impl From<Result<(), String>> for InsertResult {
|
|||||||
},
|
},
|
||||||
Err(e) => InsertResult {
|
Err(e) => InsertResult {
|
||||||
ret_code: 1,
|
ret_code: 1,
|
||||||
error: e,
|
error: format!("{}", e),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,8 +30,8 @@ pub struct WeightResult {
|
|||||||
pub error: String,
|
pub error: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Result<Option<u32>, String>> for WeightResult {
|
impl From<Result<Option<u32>, ServiceError>> for WeightResult {
|
||||||
fn from(result: Result<Option<u32>, String>) -> Self {
|
fn from(result: Result<Option<u32>, ServiceError>) -> Self {
|
||||||
match result {
|
match result {
|
||||||
Ok(wo) => WeightResult {
|
Ok(wo) => WeightResult {
|
||||||
ret_code: 0,
|
ret_code: 0,
|
||||||
@ -40,7 +41,7 @@ impl From<Result<Option<u32>, String>> for WeightResult {
|
|||||||
Err(e) => WeightResult {
|
Err(e) => WeightResult {
|
||||||
ret_code: 1,
|
ret_code: 1,
|
||||||
weight: vec![],
|
weight: vec![],
|
||||||
error: e,
|
error: format!("{}", e),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,8 +54,8 @@ pub struct AllCertsResult {
|
|||||||
pub error: String,
|
pub error: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Result<Vec<Certificate>, String>> for AllCertsResult {
|
impl From<Result<Vec<Certificate>, ServiceError>> for AllCertsResult {
|
||||||
fn from(result: Result<Vec<Certificate>, String>) -> Self {
|
fn from(result: Result<Vec<Certificate>, ServiceError>) -> Self {
|
||||||
match result {
|
match result {
|
||||||
Ok(certs) => AllCertsResult {
|
Ok(certs) => AllCertsResult {
|
||||||
ret_code: 0,
|
ret_code: 0,
|
||||||
@ -64,7 +65,7 @@ impl From<Result<Vec<Certificate>, String>> for AllCertsResult {
|
|||||||
Err(e) => AllCertsResult {
|
Err(e) => AllCertsResult {
|
||||||
ret_code: 1,
|
ret_code: 1,
|
||||||
certificates: vec![],
|
certificates: vec![],
|
||||||
error: e,
|
error: format!("{}", e),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,33 @@
|
|||||||
use crate::dto::Certificate;
|
use crate::dto::Certificate;
|
||||||
use crate::results::{AllCertsResult, InsertResult, WeightResult};
|
use crate::results::{AllCertsResult, InsertResult, WeightResult};
|
||||||
|
use crate::service_api::ServiceError::{CertError, PublicKeyDecodeError, TGError};
|
||||||
use crate::storage_impl::get_data;
|
use crate::storage_impl::get_data;
|
||||||
use fluence::fce;
|
use fluence::fce;
|
||||||
|
use fluence_identity::public_key::PKError;
|
||||||
use fluence_identity::{KeyPair, PublicKey};
|
use fluence_identity::{KeyPair, PublicKey};
|
||||||
use std::convert::Into;
|
use std::convert::Into;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use thiserror::Error as ThisError;
|
||||||
|
use trust_graph::{CertificateError, TrustGraphError};
|
||||||
|
|
||||||
fn insert_cert_impl(certificate: String, duration: u64) -> Result<(), String> {
|
#[derive(ThisError, Debug)]
|
||||||
|
pub enum ServiceError {
|
||||||
|
#[error("{0}")]
|
||||||
|
PublicKeyDecodeError(PKError),
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
TGError(TrustGraphError),
|
||||||
|
#[error("{0}")]
|
||||||
|
CertError(CertificateError),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_cert_impl(certificate: String, duration: u64) -> Result<(), ServiceError> {
|
||||||
let duration = Duration::from_millis(duration);
|
let duration = Duration::from_millis(duration);
|
||||||
let certificate =
|
let certificate = trust_graph::Certificate::from_str(&certificate).map_err(CertError)?;
|
||||||
trust_graph::Certificate::from_str(&certificate).map_err(|e| format!("{}", e))?;
|
|
||||||
|
|
||||||
let mut tg = get_data().lock();
|
let mut tg = get_data().lock();
|
||||||
tg.add(certificate, duration)?;
|
tg.add(certificate, duration).map_err(TGError)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,12 +37,12 @@ fn insert_cert(certificate: String, duration: u64) -> InsertResult {
|
|||||||
insert_cert_impl(certificate, duration).into()
|
insert_cert_impl(certificate, duration).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_weight_impl(public_key: String) -> Result<Option<u32>, String> {
|
fn get_weight_impl(public_key: String) -> Result<Option<u32>, ServiceError> {
|
||||||
let tg = get_data().lock();
|
let tg = get_data().lock();
|
||||||
|
|
||||||
let public_key = string_to_public_key(public_key)?;
|
let public_key = string_to_public_key(public_key)?;
|
||||||
|
|
||||||
let weight = tg.weight(public_key)?;
|
let weight = tg.weight(public_key).map_err(TGError)?;
|
||||||
|
|
||||||
Ok(weight)
|
Ok(weight)
|
||||||
}
|
}
|
||||||
@ -38,12 +52,8 @@ fn get_weight(public_key: String) -> WeightResult {
|
|||||||
get_weight_impl(public_key).into()
|
get_weight_impl(public_key).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn string_to_public_key(public_key: String) -> Result<PublicKey, String> {
|
fn string_to_public_key(public_key: String) -> Result<PublicKey, ServiceError> {
|
||||||
let public_key = bs58::decode(public_key)
|
let public_key = PublicKey::from_base58(&public_key).map_err(PublicKeyDecodeError)?;
|
||||||
.into_vec()
|
|
||||||
.map_err(|e| format!("Couldn't decode public_key from base58: {}", e))?;
|
|
||||||
let public_key = PublicKey::from_bytes(&public_key)
|
|
||||||
.map_err(|e| format!("Couldn't decode public_key: {}", e))?;
|
|
||||||
|
|
||||||
Ok(public_key)
|
Ok(public_key)
|
||||||
}
|
}
|
||||||
@ -53,11 +63,11 @@ fn get_all_certs(issued_for: String) -> AllCertsResult {
|
|||||||
get_all_certs_impl(issued_for).into()
|
get_all_certs_impl(issued_for).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_all_certs_impl(issued_for: String) -> Result<Vec<Certificate>, String> {
|
fn get_all_certs_impl(issued_for: String) -> Result<Vec<Certificate>, ServiceError> {
|
||||||
let tg = get_data().lock();
|
let tg = get_data().lock();
|
||||||
|
|
||||||
let public_key = string_to_public_key(issued_for)?;
|
let public_key = string_to_public_key(issued_for)?;
|
||||||
let certs = tg.get_all_certs(public_key, &[])?;
|
let certs = tg.get_all_certs(public_key, &[]).map_err(TGError)?;
|
||||||
Ok(certs.into_iter().map(|c| c.into()).collect())
|
Ok(certs.into_iter().map(|c| c.into()).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user