(certs_path: &PathBuf, wss_host: &[String])
| 12 | use crate::options::WssproxyOptions; |
| 13 | |
| 14 | pub fn generate_certificates(certs_path: &PathBuf, wss_host: &[String]) -> Result<(), Error> { |
| 15 | /* Generate the CA certificate */ |
| 16 | let mut ca_params = CertificateParams::new(vec![ |
| 17 | "cln Root wss-proxy CA".to_string(), |
| 18 | "cln".to_string(), |
| 19 | "localhost".to_string(), |
| 20 | ])?; |
| 21 | ca_params.is_ca = rcgen::IsCa::Ca(rcgen::BasicConstraints::Unconstrained); |
| 22 | ca_params |
| 23 | .key_usages |
| 24 | .push(rcgen::KeyUsagePurpose::KeyCertSign); |
| 25 | ca_params.use_authority_key_identifier_extension = true; |
| 26 | let ca_key = KeyPair::generate()?; |
| 27 | let ca_cert = ca_params.self_signed(&ca_key)?; |
| 28 | let ca_issuer = Issuer::from_params(&ca_params, &ca_key); |
| 29 | |
| 30 | fs::create_dir_all(certs_path)?; |
| 31 | |
| 32 | fs::write(certs_path.join("ca.pem"), ca_cert.pem())?; |
| 33 | fs::write( |
| 34 | certs_path.join("ca-key.pem"), |
| 35 | ca_key.serialize_pem().as_bytes(), |
| 36 | )?; |
| 37 | |
| 38 | /* Generate the server certificate signed by the CA */ |
| 39 | let mut server_params = CertificateParams::new(vec![ |
| 40 | format!("cln wss-proxy server"), |
| 41 | "cln".to_string(), |
| 42 | "localhost".to_string(), |
| 43 | ])?; |
| 44 | server_params.is_ca = rcgen::IsCa::NoCa; |
| 45 | server_params |
| 46 | .key_usages |
| 47 | .push(rcgen::KeyUsagePurpose::DigitalSignature); |
| 48 | server_params |
| 49 | .key_usages |
| 50 | .push(rcgen::KeyUsagePurpose::KeyEncipherment); |
| 51 | server_params |
| 52 | .key_usages |
| 53 | .push(rcgen::KeyUsagePurpose::KeyAgreement); |
| 54 | server_params.use_authority_key_identifier_extension = true; |
| 55 | server_params.distinguished_name = DistinguishedName::new(); |
| 56 | server_params |
| 57 | .distinguished_name |
| 58 | .push(rcgen::DnType::CommonName, "cln wss-proxy server"); |
| 59 | |
| 60 | /* It is convention to not include [] for ipv6 addresses in certificate SAN's */ |
| 61 | for host in wss_host.iter() { |
| 62 | let host_stripped = if host.starts_with('[') && host.ends_with(']') { |
| 63 | host[1..host.len() - 1].to_string() |
| 64 | } else { |
| 65 | host.to_owned() |
| 66 | }; |
| 67 | if let Ok(ip) = host_stripped.parse::<IpAddr>() { |
| 68 | server_params |
| 69 | .subject_alt_names |
| 70 | .push(rcgen::SanType::IpAddress(ip)); |
| 71 | } else if let Ok(dns) = Ia5String::try_from(host.to_owned()) { |
no test coverage detected