tokio_rustls_acme/caches/
test.rs1use crate::{AccountCache, CertCache};
2use async_trait::async_trait;
3use rcgen::{
4 date_time_ymd, BasicConstraints, CertificateParams, DistinguishedName, DnType, IsCa,
5 KeyUsagePurpose, PKCS_ECDSA_P256_SHA256,
6};
7use std::fmt::Debug;
8use std::marker::PhantomData;
9use std::sync::atomic::AtomicPtr;
10use std::sync::Arc;
11
12#[derive(Clone)]
24pub struct TestCache<EC: Debug = std::io::Error, EA: Debug = std::io::Error> {
25 ca_cert: Arc<rcgen::Certificate>,
26 ca_pem: Arc<String>,
27 ca_key_pair: Arc<rcgen::KeyPair>,
28 _cert_error: PhantomData<AtomicPtr<Box<EC>>>,
29 _account_error: PhantomData<AtomicPtr<Box<EA>>>,
30}
31
32impl<EC: Debug, EA: Debug> Default for TestCache<EC, EA> {
33 fn default() -> Self {
34 let mut params = CertificateParams::default();
35 let mut distinguished_name = DistinguishedName::new();
36 distinguished_name.push(DnType::CountryName, "US");
37 distinguished_name.push(DnType::OrganizationName, "Test CA");
38 distinguished_name.push(DnType::CommonName, "Test CA");
39 params.distinguished_name = distinguished_name;
40
41 params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
42 params.key_usages = vec![KeyUsagePurpose::KeyCertSign, KeyUsagePurpose::CrlSign];
43 params.not_before = date_time_ymd(2000, 1, 1);
44 params.not_after = date_time_ymd(3000, 1, 1);
45
46 let key_pair = rcgen::KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256).unwrap();
47 let ca_cert = params.self_signed(&key_pair).unwrap();
48 let ca_pem = ca_cert.pem();
49 Self {
50 ca_cert: ca_cert.into(),
51 ca_key_pair: key_pair.into(),
52 ca_pem: ca_pem.into(),
53 _cert_error: Default::default(),
54 _account_error: Default::default(),
55 }
56 }
57}
58
59impl<EC: Debug, EA: Debug> TestCache<EC, EA> {
60 pub fn new() -> Self {
61 Self::default()
62 }
63
64 pub fn ca_pem(&self) -> &str {
65 &self.ca_pem
66 }
67}
68
69#[async_trait]
70impl<EC: Debug, EA: Debug> CertCache for TestCache<EC, EA> {
71 type EC = EC;
72 async fn load_cert(
73 &self,
74 domains: &[String],
75 _directory_url: &str,
76 ) -> Result<Option<Vec<u8>>, Self::EC> {
77 let key_pair = rcgen::KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256).unwrap();
78 let mut params = CertificateParams::new(domains).unwrap();
79 let mut distinguished_name = DistinguishedName::new();
80 distinguished_name.push(DnType::CommonName, "Test Cert");
81 params.distinguished_name = distinguished_name;
82 params.not_before = date_time_ymd(2000, 1, 1);
83 params.not_after = date_time_ymd(3000, 1, 1);
84
85 let cert = match params.signed_by(&key_pair, &self.ca_cert, &self.ca_key_pair) {
86 Ok(cert) => cert,
87 Err(err) => {
88 log::error!("test cache: generation error: {:?}", err);
89 return Ok(None);
90 }
91 };
92
93 let cert_pem = cert.pem();
94
95 let pem = [
96 &key_pair.serialize_pem(),
97 "\n",
98 &cert_pem,
99 "\n",
100 &self.ca_pem,
101 ]
102 .concat();
103 Ok(Some(pem.into_bytes()))
104 }
105 async fn store_cert(
106 &self,
107 _domains: &[String],
108 _directory_url: &str,
109 _cert: &[u8],
110 ) -> Result<(), Self::EC> {
111 log::info!("test cache configured, could not store certificate");
112 Ok(())
113 }
114}
115
116#[async_trait]
117impl<EC: Debug, EA: Debug> AccountCache for TestCache<EC, EA> {
118 type EA = EA;
119 async fn load_account(
120 &self,
121 _contact: &[String],
122 _directory_url: &str,
123 ) -> Result<Option<Vec<u8>>, Self::EA> {
124 log::info!("test cache configured, could not load account");
125 Ok(None)
126 }
127 async fn store_account(
128 &self,
129 _contact: &[String],
130 _directory_url: &str,
131 _account: &[u8],
132 ) -> Result<(), Self::EA> {
133 log::info!("test cache configured, could not store account");
134 Ok(())
135 }
136}