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
use crate::{export::Principal, Identity, Signature};
#[cfg(feature = "pem")]
use crate::identity::error::PemError;
use ring::signature::{Ed25519KeyPair, KeyPair};
use simple_asn1::{
oid, to_der,
ASN1Block::{BitString, ObjectIdentifier, Sequence},
};
pub struct BasicIdentity {
key_pair: Ed25519KeyPair,
der_encoded_public_key: Vec<u8>,
}
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(BasicIdentity::from_key_pair(Ed25519KeyPair::from_pkcs8(
pem::parse(&bytes)?.contents.as_slice(),
)?))
}
pub fn from_key_pair(key_pair: Ed25519KeyPair) -> Self {
let der_encoded_public_key = der_encode_public_key(key_pair.public_key().as_ref().to_vec());
Self {
key_pair,
der_encoded_public_key,
}
}
}
impl Identity for BasicIdentity {
fn sender(&self) -> Result<Principal, String> {
Ok(Principal::self_authenticating(&self.der_encoded_public_key))
}
fn sign(&self, msg: &[u8]) -> Result<Signature, String> {
let signature = self.key_pair.sign(msg.as_ref());
Ok(Signature {
signature: Some(signature.as_ref().to_vec()),
public_key: Some(self.der_encoded_public_key.clone()),
})
}
}
fn der_encode_public_key(public_key: Vec<u8>) -> Vec<u8> {
let id_ed25519 = oid!(1, 3, 101, 112);
let algorithm = Sequence(0, vec![ObjectIdentifier(0, id_ed25519)]);
let subject_public_key = BitString(0, public_key.len() * 8, public_key);
let subject_public_key_info = Sequence(0, vec![algorithm, subject_public_key]);
to_der(&subject_public_key_info).unwrap()
}