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
use super::*;
pub trait TextSignable: Debug + Clone {
fn as_signable_text(&self) -> String;
fn issuer_pubkey(&self) -> PubKey;
fn signature(&self) -> Option<Sig>;
fn set_signature(&mut self, _signature: Sig);
fn sign(&mut self, priv_key: PrivKey) -> Result<String, SignError> {
if self.signature().is_some() {
return Err(SignError::AlreadySign());
}
let text = self.as_signable_text();
match self.issuer_pubkey() {
PubKey::Ed25519(_) => match priv_key {
PrivKey::Ed25519(priv_key) => {
let sig = priv_key.sign(&text.as_bytes());
self.set_signature(Sig::Ed25519(sig));
let str_sig = sig.to_base64();
Ok(format!("{}{}", text, str_sig))
}
_ => Err(SignError::WrongAlgo()),
},
_ => Err(SignError::WrongAlgo()),
}
}
fn verify(&self) -> Result<(), SigError> {
if let Some(signature) = self.signature() {
match self.issuer_pubkey() {
PubKey::Ed25519(pubkey) => match signature {
Sig::Ed25519(sig) => {
if pubkey.verify(&self.as_signable_text().as_bytes(), &sig) {
Ok(())
} else {
Err(SigError::InvalidSig())
}
}
_ => Err(SigError::NotSameAlgo()),
},
_ => Err(SigError::NotSameAlgo()),
}
} else {
Err(SigError::NotSig())
}
}
}