1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use core::marker::PhantomData;
use identity_iota_core::did::IotaDID;
use serde::Serialize;
use identity_core::convert::ToJson;
use identity_core::crypto::Named;
use identity_core::crypto::Proof;
use identity_core::crypto::ProofOptions;
use identity_core::crypto::ProofValue;
use identity_core::crypto::SetSignature;
use identity_core::error::Error;
use identity_core::error::Result;
use identity_core::utils::BaseEncoding;
use crate::storage::Storage;
use crate::types::KeyLocation;
use crate::types::Signature as StorageSignature;
pub struct RemoteEd25519;
impl Named for RemoteEd25519 {
const NAME: &'static str = "JcsEd25519Signature2020";
}
impl RemoteEd25519 {
pub async fn create_signature<U>(
data: &mut U,
method: impl Into<String>,
secret: &RemoteKey<'_>,
options: ProofOptions,
) -> Result<()>
where
U: Serialize + SetSignature,
{
let signature: Proof = Proof::new_with_options(Self::NAME, method, options);
data.set_signature(signature);
let value: ProofValue = Self::sign(&data, secret).await?;
let write: &mut Proof = data.signature_mut().ok_or(Error::MissingSignature)?;
write.set_value(value);
Ok(())
}
pub async fn sign<X>(data: &X, remote_key: &RemoteKey<'_>) -> Result<ProofValue>
where
X: Serialize,
{
let message: Vec<u8> = data.to_jcs()?;
let signature: Vec<u8> = RemoteSign::sign(&message, remote_key).await?.into();
let encoded: String = BaseEncoding::encode_base58(&signature);
Ok(ProofValue::Signature(encoded))
}
}
#[derive(Debug)]
pub struct RemoteKey<'a> {
did: &'a IotaDID,
location: &'a KeyLocation,
store: &'a dyn Storage,
}
impl<'a> RemoteKey<'a> {
pub fn new(did: &'a IotaDID, location: &'a KeyLocation, store: &'a dyn Storage) -> Self {
Self { did, location, store }
}
}
#[derive(Clone, Copy, Debug)]
pub struct RemoteSign<'a> {
marker: PhantomData<RemoteKey<'a>>,
}
impl<'a> RemoteSign<'a> {
pub async fn sign(message: &[u8], key: &RemoteKey<'a>) -> Result<StorageSignature> {
key
.store
.key_sign(key.did, key.location, message.to_vec())
.await
.map_err(|_| Error::InvalidProofValue("remote sign"))
}
}