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
use crate::*;
use ghost_actor::dependencies::futures::future::FutureExt;
use lair_keystore_api_0_0::actor::{
Cert, CertDigest, CertPrivKey, LairClientApiSender, LairEntryType, TlsCertOptions,
};
pub type KeystoreSender = ghost_actor::GhostSender<lair_keystore_api_0_0::actor::LairClientApi>;
pub type KeystoreApiResult<T> = Result<T, KeystoreError>;
pub type KeystoreApiFuture<T> =
ghost_actor::dependencies::must_future::MustBoxFuture<'static, KeystoreApiResult<T>>;
pub trait KeystoreSenderExt {
fn get_first_tls_cert(&self) -> KeystoreApiFuture<(CertDigest, Cert, CertPrivKey)>;
fn get_or_create_first_tls_cert(&self) -> KeystoreApiFuture<(CertDigest, Cert, CertPrivKey)>;
}
impl KeystoreSenderExt for KeystoreSender {
fn get_first_tls_cert(&self) -> KeystoreApiFuture<(CertDigest, Cert, CertPrivKey)> {
let this = self.clone();
async move {
let last_index = this.lair_get_last_entry_index().await?;
for i in 1..=*last_index {
if let Ok(LairEntryType::TlsCert) = this.lair_get_entry_type(i.into()).await {
let (_, digest) = this.tls_cert_get(i.into()).await?;
let cert = this.tls_cert_get_cert_by_index(i.into()).await?;
let cert_priv = this.tls_cert_get_priv_key_by_index(i.into()).await?;
return Ok((digest, cert, cert_priv));
}
}
Err("no tls cert registered".into())
}
.boxed()
.into()
}
fn get_or_create_first_tls_cert(&self) -> KeystoreApiFuture<(CertDigest, Cert, CertPrivKey)> {
let this = self.clone();
async move {
if let Ok(r) = this.get_first_tls_cert().await {
return Ok(r);
}
let mut tls_opt = TlsCertOptions::default();
tls_opt.alg = lair_keystore_api_0_0::actor::TlsCertAlg::PkcsEcdsaP256Sha256;
let _ = this.tls_cert_new_self_signed_from_entropy(tls_opt).await?;
this.get_first_tls_cert().await
}
.boxed()
.into()
}
}
#[cfg(test)]
mod tests {
use crate::test_keystore::*;
#[tokio::test(flavor = "multi_thread")]
async fn test_tls_cert_get_or_create() {
let keystore = spawn_test_keystore().await.unwrap();
let (dig1, cert1, priv1) = keystore.get_or_create_first_tls_cert().await.unwrap();
let (dig2, cert2, priv2) = keystore.get_or_create_first_tls_cert().await.unwrap();
assert_eq!(dig1, dig2);
assert_eq!(cert1, cert2);
assert_eq!(priv1, priv2);
}
}