didbot_tls/
test_support.rs1use std::sync::Arc;
16
17use rcgen::{
18 BasicConstraints, CertificateParams, DistinguishedName, DnType, ExtendedKeyUsagePurpose, IsCa,
19 Issuer, KeyPair, KeyUsagePurpose,
20};
21use time::{Duration, OffsetDateTime};
22
23pub struct TestCertificate {
25 pub chain_pem: String,
27 pub key_pem: String,
29 pub ca_pem: String,
31}
32
33pub fn issue_for(names: &[&str]) -> TestCertificate {
40 let ca_key = KeyPair::generate().expect("a key pair");
41 let mut ca = CertificateParams::new(Vec::<String>::new()).expect("no names is valid");
42 ca.is_ca = IsCa::Ca(BasicConstraints::Constrained(0));
43 ca.distinguished_name = DistinguishedName::new();
44 ca.distinguished_name
45 .push(DnType::CommonName, "didbot test authority");
46 ca.key_usages = vec![KeyUsagePurpose::KeyCertSign, KeyUsagePurpose::CrlSign];
47 let ca_pem = ca.self_signed(&ca_key).expect("a self-signed ca").pem();
48 let issuer = Issuer::new(ca, ca_key);
49
50 let mut leaf =
51 CertificateParams::new(names.iter().map(|n| (*n).to_owned()).collect::<Vec<_>>())
52 .expect("valid names");
53 let now = OffsetDateTime::now_utc();
54 leaf.not_before = now - Duration::hours(1);
55 leaf.not_after = now + Duration::days(1);
56 leaf.distinguished_name = DistinguishedName::new();
57 leaf.distinguished_name
58 .push(DnType::CommonName, names.first().copied().unwrap_or("test"));
59 leaf.use_authority_key_identifier_extension = true;
60 leaf.key_usages = vec![
61 KeyUsagePurpose::DigitalSignature,
62 KeyUsagePurpose::KeyEncipherment,
63 ];
64 leaf.extended_key_usages = vec![ExtendedKeyUsagePurpose::ServerAuth];
65 let leaf_key = KeyPair::generate().expect("a key pair");
66 let signed = leaf.signed_by(&leaf_key, &issuer).expect("a signed leaf");
67
68 TestCertificate {
69 chain_pem: format!("{}{ca_pem}", signed.pem()),
70 key_pem: leaf_key.serialize_pem(),
71 ca_pem,
72 }
73}
74
75pub fn server_config(names: &[&str]) -> (Arc<rustls::ServerConfig>, String) {
78 let _ = rustls::crypto::ring::default_provider().install_default();
79 let provider = rustls::crypto::ring::default_provider();
80 let issued = issue_for(names);
81 let certified =
82 crate::cert::certified_key_from_pem(&issued.chain_pem, &issued.key_pem, &provider)
83 .expect("the pair this module just signed loads");
84 let mut config = rustls::ServerConfig::builder()
85 .with_no_client_auth()
86 .with_cert_resolver(crate::resolver::SwappableCert::new(certified));
87 config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
88 (Arc::new(config), issued.ca_pem)
89}
90
91pub fn self_signed_pem(name: &str) -> (String, String) {
98 let rcgen::CertifiedKey { cert, signing_key } =
99 rcgen::generate_simple_self_signed(vec![name.to_owned()])
100 .expect("self-signed generation for a valid DNS name does not fail");
101 (cert.pem(), signing_key.serialize_pem())
102}