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
use crate::export::Principal;
use crate::{Identity, Signature};
use ring::signature::{Ed25519KeyPair, KeyPair};
use thiserror::Error;
#[derive(Error, Debug)]
pub enum PemError {
#[error(transparent)]
Io(#[from] std::io::Error),
#[cfg(feature = "pem")]
#[error("An error occurred while reading the file: {0}")]
PemError(#[from] pem::PemError),
#[error("A key was rejected by Ring: {0}")]
KeyRejected(#[from] ring::error::KeyRejected),
}
pub struct BasicIdentity {
key_pair: Ed25519KeyPair,
}
impl BasicIdentity {
#[cfg(feature = "pem")]
pub fn from_pem_file<P: AsRef<std::path::Path>>(file_path: P) -> Result<Self, PemError> {
Self::from_pem(std::fs::File::open(file_path)?)
}
#[cfg(feature = "pem")]
pub fn from_pem<R: std::io::Read>(pem_reader: R) -> Result<Self, PemError> {
let bytes: Vec<u8> = pem_reader
.bytes()
.collect::<Result<Vec<u8>, std::io::Error>>()?;
Ok(Self {
key_pair: Ed25519KeyPair::from_pkcs8(pem::parse(&bytes)?.contents.as_slice())?,
})
}
pub fn from_key_pair(key_pair: Ed25519KeyPair) -> Self {
Self { key_pair }
}
}
impl Identity for BasicIdentity {
fn sender(&self) -> Result<Principal, String> {
Ok(Principal::self_authenticating(&self.key_pair.public_key()))
}
fn sign(&self, msg: &[u8], _principal: &Principal) -> Result<Signature, String> {
let signature = self.key_pair.sign(msg.as_ref());
let public_key_bytes = self.key_pair.public_key();
Ok(Signature {
signature: signature.as_ref().to_vec(),
public_key: public_key_bytes.as_ref().to_vec(),
})
}
}