Compare commits

...

2 Commits

Author SHA1 Message Date
Alexey Proshutinskiy
b9ca3c0259 local-network: add builtins secret key 2021-09-30 18:21:53 +03:00
Alexey Proshutinskiy
51c4edd631 resolve merge issues 2021-09-30 17:53:29 +03:00
16 changed files with 1252 additions and 90 deletions

View File

@ -29,7 +29,7 @@ jobs:
paths:
- ~/.cargo
- ~/.rustup
key: trust-graph00-{{ checksum "./service/Cargo.lock" }}-{{ checksum "./Cargo.lock" }}-{{ checksum "./keypair/Cargo.lock" }}
key: trust-graph00-{{ checksum "./Cargo.lock" }-{{ checksum "./service/Cargo.lock" }}}-{{ checksum "./keypair/Cargo.lock" }}
workflows:

6
Cargo.lock generated
View File

@ -755,7 +755,7 @@ dependencies = [
[[package]]
name = "fluence-keypair"
version = "0.3.0"
version = "0.4.1"
dependencies = [
"asn1_der",
"bs58 0.3.1",
@ -2478,7 +2478,7 @@ dependencies = [
[[package]]
name = "trust-graph"
version = "0.2.7"
version = "0.2.9"
dependencies = [
"bs58 0.3.1",
"derivative",
@ -2498,7 +2498,7 @@ dependencies = [
[[package]]
name = "trust-graph-wasm"
version = "0.2.0"
version = "0.2.1"
dependencies = [
"anyhow",
"bincode",

View File

@ -1,6 +1,6 @@
[package]
name = "trust-graph"
version = "0.2.7"
version = "0.2.9"
authors = ["Fluence Labs"]
edition = "2018"
description = "trust graph"
@ -11,7 +11,7 @@ repository = "https://github.com/fluencelabs/trust-graph"
libp2p-core = { package = "fluence-fork-libp2p-core", version = "0.27.2", features = ["secp256k1"] }
serde = { version = "=1.0.118", features = ["derive"] }
fluence-keypair = { path = "./keypair", version = "0.3.0" }
fluence-keypair = { path = "./keypair", version = "0.4.1" }
serde_json = "1.0.58"
bs58 = "0.3.1"
failure = "0.1.6"

1112
example/generated/export.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@ let local: Node[] = [
];
async function main(environment: Node[]) {
let builtins_keypair = await KeyPair.fromBytes(bs58.decode("5CGiJio6m76GxJ2wLj46PzSu6V7SRa5agv6meR3SJBKtvTgethRCmgBJKXWDSpSEBpgNUPd7Re5cZjF8mWW4kBfs"));
let builtins_keypair = await KeyPair.fromBytes(bs58.decode("5CGiJio6m76GxJ2wLj46PzSu6V7SRa5agv6meR3SJBKtvTgethRCmgBJKXWDSpSEBpgNUPd7Re5cZjF8mWW4kBfs").slice(32));
await Fluence.start({ connectTo: environment[0], KeyPair: builtins_keypair});
console.log(
"📗 created a fluence peer %s with relay %s",

View File

@ -1,6 +1,6 @@
[package]
name = "fluence-keypair"
version = "0.3.0"
version = "0.4.1"
authors = ["Fluence Labs"]
edition = "2018"
description = "identity"

View File

@ -35,7 +35,7 @@ pub enum DecodingError {
Ed25519(
#[from]
#[source]
ed25519_dalek::ed25519::Error
ed25519_dalek::ed25519::Error,
),
#[error("Failed to decode with RSA")]
Rsa,
@ -49,6 +49,8 @@ pub enum DecodingError {
Base58DecodeError(#[source] bs58::decode::Error),
#[error("Raw signature decoding failed: type {0} not supported")]
RawSignatureUnsupportedType(String),
#[error("public key is not inlined in peer id: {0}")]
PublicKeyNotInlined(String),
}
/// An error during signing of a message.
@ -58,7 +60,7 @@ pub enum SigningError {
Ed25519(
#[from]
#[source]
ed25519_dalek::ed25519::Error
ed25519_dalek::ed25519::Error,
),
#[error("Failed to sign with RSA")]
Rsa,
@ -66,6 +68,6 @@ pub enum SigningError {
Secp256k1(
#[from]
#[source]
secp256k1::Error
secp256k1::Error,
),
}

View File

@ -20,15 +20,15 @@
//! A node's network identity keys.
use crate::ed25519;
use crate::error::{DecodingError, Error, SigningError};
use crate::public_key::PublicKey;
#[cfg(not(target_arch = "wasm32"))]
use crate::rsa;
use crate::secp256k1;
use crate::public_key::PublicKey;
use crate::signature::Signature;
use crate::error::{Error, DecodingError, SigningError};
use std::str::FromStr;
use std::convert::TryFrom;
use libp2p_core::PeerId;
use std::convert::TryFrom;
use std::str::FromStr;
/// Identity keypair of a node.
///
@ -48,7 +48,6 @@ use libp2p_core::PeerId;
/// ```
///
pub enum KeyFormat {
Ed25519,
#[cfg(not(target_arch = "wasm32"))]
@ -66,7 +65,7 @@ impl FromStr for KeyFormat {
"secp256k1" => Ok(KeyFormat::Secp256k1),
#[cfg(not(target_arch = "wasm32"))]
"rsa" => Ok(KeyFormat::Rsa),
_ => Err(Error::InvalidKeyFormat(s.to_string()))
_ => Err(Error::InvalidKeyFormat(s.to_string())),
}
}
}
@ -80,7 +79,7 @@ impl TryFrom<u8> for KeyFormat {
#[cfg(not(target_arch = "wasm32"))]
1 => Ok(KeyFormat::Rsa),
2 => Ok(KeyFormat::Secp256k1),
_ => Err(DecodingError::InvalidTypeByte)
_ => Err(DecodingError::InvalidTypeByte),
}
}
}
@ -96,6 +95,16 @@ impl From<KeyFormat> for u8 {
}
}
impl From<KeyFormat> for String {
fn from(kf: KeyFormat) -> Self {
match kf {
KeyFormat::Ed25519 => "ed25519".to_string(),
#[cfg(not(target_arch = "wasm32"))]
KeyFormat::Rsa => "rsa".to_string(),
KeyFormat::Secp256k1 => "secp256k1".to_string(),
}
}
}
#[derive(Clone)]
pub enum KeyPair {
/// An Ed25519 keypair.
@ -153,7 +162,9 @@ impl KeyPair {
Ed25519(ref pair) => Ok(Signature::Ed25519(ed25519::Signature(pair.sign(msg)?))),
#[cfg(not(target_arch = "wasm32"))]
Rsa(ref pair) => Ok(Signature::Rsa(rsa::Signature(pair.sign(msg)?))),
Secp256k1(ref pair) => Ok(Signature::Secp256k1(secp256k1::Signature(pair.secret().sign(msg)?)))
Secp256k1(ref pair) => Ok(Signature::Secp256k1(secp256k1::Signature(
pair.secret().sign(msg)?,
))),
}
}
@ -200,12 +211,12 @@ impl KeyPair {
KeyFormat::Ed25519 => Ok(Ed25519(ed25519::Keypair::decode(&mut bytes)?)),
KeyFormat::Secp256k1 => Ok(Secp256k1(secp256k1::SecretKey::from_bytes(bytes)?.into())),
#[cfg(not(target_arch = "wasm32"))]
KeyFormat::Rsa => Err(DecodingError::KeypairDecodingIsNotSupported)
KeyFormat::Rsa => Err(DecodingError::KeypairDecodingIsNotSupported),
}
}
pub fn get_peer_id(&self) -> PeerId {
self.public().to_peer_id()
self.public().to_peer_id()
}
}
@ -217,23 +228,33 @@ impl From<libp2p_core::identity::Keypair> for KeyPair {
Ed25519(kp) => KeyPair::Ed25519(ed25519::Keypair::decode(&mut kp.encode()).unwrap()),
#[cfg(not(target_arch = "wasm32"))]
// safety: these Keypair structures are identical
Rsa(kp) => KeyPair::Rsa(unsafe { std::mem::transmute::<libp2p_core::identity::rsa::Keypair, rsa::Keypair>(kp) }),
Secp256k1(kp) => KeyPair::Secp256k1(secp256k1::Keypair::from(secp256k1::SecretKey::from_bytes(kp.secret().to_bytes()).unwrap())),
Rsa(kp) => KeyPair::Rsa(unsafe {
std::mem::transmute::<libp2p_core::identity::rsa::Keypair, rsa::Keypair>(kp)
}),
Secp256k1(kp) => KeyPair::Secp256k1(secp256k1::Keypair::from(
secp256k1::SecretKey::from_bytes(kp.secret().to_bytes()).unwrap(),
)),
}
}
}
impl From<KeyPair> for libp2p_core::identity::Keypair {
fn from(key: KeyPair) -> Self {
use KeyPair::*;
use libp2p_core::identity::Keypair;
use libp2p_core::identity;
use libp2p_core::identity::Keypair;
use KeyPair::*;
match key {
Ed25519(kp) => Keypair::Ed25519(identity::ed25519::Keypair::decode(kp.encode().to_vec().as_mut_slice()).unwrap()),
Ed25519(kp) => Keypair::Ed25519(
identity::ed25519::Keypair::decode(kp.encode().to_vec().as_mut_slice()).unwrap(),
),
#[cfg(not(target_arch = "wasm32"))]
Rsa(kp) => Keypair::Rsa(unsafe { std::mem::transmute::<rsa::Keypair, libp2p_core::identity::rsa::Keypair>(kp) }),
Secp256k1(kp) => Keypair::Secp256k1(identity::secp256k1::Keypair::from(identity::secp256k1::SecretKey::from_bytes(kp.secret().to_bytes()).unwrap())),
Rsa(kp) => Keypair::Rsa(unsafe {
std::mem::transmute::<rsa::Keypair, libp2p_core::identity::rsa::Keypair>(kp)
}),
Secp256k1(kp) => Keypair::Secp256k1(identity::secp256k1::Keypair::from(
identity::secp256k1::SecretKey::from_bytes(kp.secret().to_bytes()).unwrap(),
)),
}
}
}

View File

@ -111,6 +111,17 @@ impl PublicKey {
pub fn to_peer_id(&self) -> PeerId {
PeerId::from_public_key(self.clone().into())
}
pub fn get_key_format(&self) -> KeyFormat {
use PublicKey::*;
match self {
Ed25519(_) => KeyFormat::Ed25519,
#[cfg(not(target_arch = "wasm32"))]
Rsa(_) => KeyFormat::Rsa,
Secp256k1(_) => KeyFormat::Secp256k1,
}
}
}
impl From<libp2p_core::identity::PublicKey> for PublicKey {
@ -149,14 +160,15 @@ impl From<PublicKey> for libp2p_core::identity::PublicKey {
}
}
pub fn peer_id_to_fluence_pk(peer_id: libp2p_core::PeerId) -> eyre::Result<PublicKey> {
Ok(peer_id
.as_public_key()
.ok_or(eyre::eyre!(
"public key is not inlined in peer id: {}",
peer_id
))?
.into())
impl TryFrom<libp2p_core::PeerId> for PublicKey {
type Error = DecodingError;
fn try_from(peer_id: libp2p_core::PeerId) -> Result<Self, Self::Error> {
Ok(peer_id
.as_public_key()
.ok_or(DecodingError::PublicKeyNotInlined(peer_id.to_base58()))?
.into())
}
}
#[cfg(test)]
@ -179,4 +191,15 @@ mod tests {
let encoded_pk = pk.encode();
assert_eq!(pk, PublicKey::decode(&encoded_pk).unwrap());
}
#[test]
fn public_key_peer_id_conversions() {
let kp = KeyPair::generate_secp256k1();
let fluence_pk = kp.public();
let libp2p_pk: libp2p_core::PublicKey = fluence_pk.clone().into();
let peer_id = PeerId::from_public_key(libp2p_pk);
let fluence_pk_converted = PublicKey::try_from(peer_id).unwrap();
assert_eq!(fluence_pk, fluence_pk_converted);
}
}

View File

@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use crate::{ed25519, PublicKey};
use crate::secp256k1;
use crate::ed25519;
use crate::error::DecodingError;
use crate::key_pair::KeyFormat;
#[cfg(not(target_arch = "wasm32"))]
use crate::rsa;
use crate::error::DecodingError;
use crate::secp256k1;
use serde::{Deserialize, Serialize};
use crate::key_pair::KeyFormat;
use std::convert::TryFrom;
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
@ -32,7 +32,7 @@ pub enum Signature {
pub struct RawSignature {
pub bytes: Vec<u8>,
pub sig_type: String,
pub sig_type: KeyFormat,
}
impl Signature {
@ -42,7 +42,7 @@ impl Signature {
Ed25519(_) => KeyFormat::Ed25519.into(),
#[cfg(not(target_arch = "wasm32"))]
Rsa(_) => KeyFormat::Rsa.into(),
Secp256k1(_) => KeyFormat::Secp256k1.into()
Secp256k1(_) => KeyFormat::Secp256k1.into(),
}
}
@ -68,7 +68,9 @@ impl Signature {
KeyFormat::Ed25519 => Ok(Signature::Ed25519(ed25519::Signature(bytes[1..].to_vec()))),
#[cfg(not(target_arch = "wasm32"))]
KeyFormat::Rsa => Ok(Signature::Rsa(rsa::Signature(bytes[1..].to_vec()))),
KeyFormat::Secp256k1 => Ok(Signature::Secp256k1(secp256k1::Signature(bytes[1..].to_vec()))),
KeyFormat::Secp256k1 => Ok(Signature::Secp256k1(secp256k1::Signature(
bytes[1..].to_vec(),
))),
}
}
@ -83,38 +85,30 @@ impl Signature {
}
}
pub fn get_signature_type(&self) -> String {
pub fn get_signature_type(&self) -> KeyFormat {
use Signature::*;
match self {
Ed25519(_) => "Ed25519".to_string(),
Ed25519(_) => KeyFormat::Ed25519,
#[cfg(not(target_arch = "wasm32"))]
Rsa(_) => "RSA".to_string(),
Secp256k1(_) => "Secp256k1".to_string(),
Rsa(_) => KeyFormat::Rsa,
Secp256k1(_) => KeyFormat::Secp256k1,
}
}
pub fn get_raw_signature(&self) -> RawSignature {
RawSignature { bytes: self.to_vec().clone().to_vec(), sig_type: self.get_signature_type() }
}
pub fn from_raw_signature(raw_signature: RawSignature) -> Result<Self, DecodingError> {
match raw_signature.sig_type.as_str() {
"Ed25519" => Ok(Signature::Ed25519(crate::ed25519::Signature(raw_signature.bytes))),
#[cfg(not(target_arch = "wasm32"))]
"RSA" => Ok(Signature::Rsa(crate::rsa::Signature(raw_signature.bytes))),
"Secp256k1" => Ok(Signature::Secp256k1(crate::secp256k1::Signature(raw_signature.bytes))),
_ => Err(DecodingError::RawSignatureUnsupportedType(raw_signature.sig_type)),
RawSignature {
bytes: self.to_vec().clone().to_vec(),
sig_type: self.get_signature_type(),
}
}
pub fn from_bytes_with_public_key(pk: &PublicKey, bytes: Vec<u8>) -> Self {
use PublicKey::*;
match pk {
Ed25519(_) => Signature::Ed25519(ed25519::Signature(bytes)),
pub fn from_bytes(key_format: KeyFormat, bytes: Vec<u8>) -> Self {
match key_format {
KeyFormat::Ed25519 => Signature::Ed25519(ed25519::Signature(bytes)),
#[cfg(not(target_arch = "wasm32"))]
Rsa(_) => Signature::Rsa(rsa::Signature(bytes)),
Secp256k1(_) => Signature::Secp256k1(secp256k1::Signature(bytes))
KeyFormat::Rsa => Signature::Rsa(rsa::Signature(bytes)),
KeyFormat::Secp256k1 => Signature::Secp256k1(secp256k1::Signature(bytes)),
}
}
}
@ -131,8 +125,14 @@ mod tests {
#[cfg(not(target_arch = "wasm32"))]
let rsa_sig = Signature::Rsa(crate::rsa::Signature(bytes.clone()));
assert_eq!(Signature::decode(ed25519_sig.encode()).unwrap(), ed25519_sig);
assert_eq!(Signature::decode(secp256k1_sig.encode()).unwrap(), secp256k1_sig);
assert_eq!(
Signature::decode(ed25519_sig.encode()).unwrap(),
ed25519_sig
);
assert_eq!(
Signature::decode(secp256k1_sig.encode()).unwrap(),
secp256k1_sig
);
#[cfg(not(target_arch = "wasm32"))]
assert_eq!(Signature::decode(rsa_sig.encode()).unwrap(), rsa_sig);
}

View File

@ -0,0 +1 @@
5FwE32bDcphFzuMca7Y2qW1gdR64fTBYoRNvD4MLE1hecDGhCMQGKn8aseMr5wRo4Xo2CRFdrEAawUNLYkgQD78K

View File

@ -18,6 +18,7 @@ services:
volumes:
- fluence-0:/.fluence
- data-0:/config
- ./builtins_secret_key.ed25519:/.fluence/v1/builtins_secret_key.ed25519
networks:
- fluence

View File

@ -1,6 +1,6 @@
[package]
name = "trust-graph-wasm"
version = "0.2.0"
version = "0.2.1"
authors = ["Fluence Labs"]
edition = "2018"
description = "trust graph wasm"
@ -12,7 +12,7 @@ path = "src/main.rs"
[dependencies]
trust-graph = { version = "0.2.6", path = "../." }
fluence-keypair = { version = "0.3.0", path = "../keypair" }
fluence-keypair = { version = "0.4.1", path = "../keypair" }
marine-rs-sdk = { version = "0.6.11", features = ["logger"] }
marine-sqlite-connector = "0.5.1"

View File

@ -1,8 +1,7 @@
use crate::dto::DtoConversionError::PeerIdDecodeError;
use fluence_keypair::error::DecodingError;
use fluence_keypair::public_key::peer_id_to_fluence_pk;
use fluence_keypair::signature::RawSignature;
use fluence_keypair::Signature;
use fluence_keypair::{KeyFormat, PublicKey, Signature};
use libp2p_core::PeerId;
use marine_rs_sdk::marine;
use std::convert::TryFrom;
@ -26,6 +25,12 @@ pub enum DtoConversionError {
),
#[error("Cannot decode peer id from string: {0}")]
PeerIdDecodeError(String),
#[error("{0}")]
InvalidKeyFormat(
#[from]
#[source]
fluence_keypair::error::Error,
),
}
#[marine]
@ -73,15 +78,12 @@ impl TryFrom<Trust> for trust_graph::Trust {
type Error = DtoConversionError;
fn try_from(t: Trust) -> Result<Self, Self::Error> {
let issued_for = peer_id_to_fluence_pk(
let issued_for = PublicKey::try_from(
PeerId::from_str(&t.issued_for).map_err(|e| PeerIdDecodeError(format!("{:?}", e)))?,
)
.map_err(|e| DtoConversionError::PeerIdDecodeError(e.to_string()))?;
let signature = bs58::decode(&t.signature).into_vec()?;
let signature = Signature::from_raw_signature(RawSignature {
bytes: signature,
sig_type: t.sig_type,
})?;
let signature = Signature::from_bytes(KeyFormat::from_str(&t.sig_type)?, signature);
let expires_at = Duration::from_secs(t.expires_at);
let issued_at = Duration::from_secs(t.issued_at);
return Ok(trust_graph::Trust {
@ -104,7 +106,7 @@ impl From<trust_graph::Trust> for Trust {
issued_for,
expires_at,
signature,
sig_type: raw_signature.sig_type,
sig_type: raw_signature.sig_type.into(),
issued_at,
};
}
@ -129,20 +131,17 @@ impl TryFrom<Revoke> for trust_graph::Revoke {
type Error = DtoConversionError;
fn try_from(r: Revoke) -> Result<Self, Self::Error> {
let revoked_pk = peer_id_to_fluence_pk(
let revoked_pk = PublicKey::try_from(
PeerId::from_str(&r.revoked_peer_id)
.map_err(|e| PeerIdDecodeError(format!("{:?}", e)))?,
)
.map_err(|e| DtoConversionError::PeerIdDecodeError(e.to_string()))?;
let revoked_by_pk = peer_id_to_fluence_pk(
let revoked_by_pk = PublicKey::try_from(
PeerId::from_str(&r.revoked_by).map_err(|e| PeerIdDecodeError(format!("{:?}", e)))?,
)
.map_err(|e| DtoConversionError::PeerIdDecodeError(e.to_string()))?;
let signature = bs58::decode(&r.signature).into_vec()?;
let signature = Signature::from_raw_signature(RawSignature {
bytes: signature,
sig_type: r.sig_type,
})?;
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 {
pk: revoked_pk,
@ -164,7 +163,7 @@ impl From<trust_graph::Revoke> for Revoke {
revoked_peer_id,
revoked_at,
signature,
sig_type: raw_signature.sig_type,
sig_type: raw_signature.sig_type.into(),
revoked_by,
};
}

View File

@ -2,12 +2,10 @@ use crate::dto::{Certificate, DtoConversionError, Revoke, Trust};
use crate::service_impl::ServiceError::InvalidTimestampTetraplet;
use crate::storage_impl::get_data;
use fluence_keypair::error::DecodingError;
use fluence_keypair::public_key::peer_id_to_fluence_pk;
use fluence_keypair::{PublicKey, Signature};
use libp2p_core::PeerId;
use marine_rs_sdk::CallParameters;
use std::convert::{Into, TryInto};
use std::iter::Rev;
use std::convert::{Into, TryFrom, TryInto};
use std::str::FromStr;
use std::time::Duration;
use thiserror::Error as ThisError;
@ -81,8 +79,11 @@ fn parse_peer_id(peer_id: String) -> Result<PeerId, ServiceError> {
}
fn extract_public_key(peer_id: String) -> Result<PublicKey, ServiceError> {
peer_id_to_fluence_pk(parse_peer_id(peer_id)?)
.map_err(|e| ServiceError::PublicKeyExtractionError(e.to_string()))
PublicKey::try_from(
parse_peer_id(peer_id)
.map_err(|e| ServiceError::PublicKeyExtractionError(e.to_string()))?,
)
.map_err(ServiceError::PublicKeyDecodeError)
}
pub fn get_weight_impl(peer_id: String, timestamp_sec: u64) -> Result<u32, ServiceError> {
@ -155,7 +156,7 @@ pub fn issue_trust_impl(
let public_key = extract_public_key(peer_id)?;
let expires_at_sec = Duration::from_secs(expires_at_sec);
let issued_at_sec = Duration::from_secs(issued_at_sec);
let signature = Signature::from_bytes_with_public_key(&public_key, trust_bytes);
let signature = Signature::from_bytes(public_key.get_key_format(), trust_bytes);
Ok(Trust::from(trust_graph::Trust::new(
public_key,
expires_at_sec,
@ -222,7 +223,7 @@ pub fn issue_revocation_impl(
let revoked_by_pk = extract_public_key(revoked_by_peer_id)?;
let revoked_at = Duration::from_secs(revoked_at_sec);
let signature = Signature::from_bytes_with_public_key(&revoked_by_pk, signature_bytes);
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())
}

View File

@ -14,7 +14,9 @@
* limitations under the License.
*/
use crate::trust::TrustError::{Base58DecodeError, DecodePublicKeyError, ParseError, SignatureError, DecodeErrorInvalidSize};
use crate::trust::TrustError::{
Base58DecodeError, DecodeErrorInvalidSize, DecodePublicKeyError, ParseError, SignatureError,
};
use derivative::Derivative;
use fluence_keypair::key_pair::KeyPair;
use fluence_keypair::public_key::PublicKey;