From 2213b055dcf3978da3f8f81d7ec500611be23bf8 Mon Sep 17 00:00:00 2001 From: Johann150 Date: Sat, 27 Mar 2021 00:52:50 +0100 Subject: [PATCH] add automatic certificate generation --- Cargo.lock | 85 ++++++++++++++- Cargo.toml | 1 + src/certificates.rs | 55 ++++------ src/main.rs | 79 ++++++++++++-- tests/data/.certificates/cert.der | Bin 0 -> 1293 bytes tests/data/.certificates/cert.pem | 29 ----- tests/data/.certificates/key.der | Bin 0 -> 2348 bytes tests/data/.certificates/key.rsa | 52 --------- tests/data/cert_missing/key.der | Bin 0 -> 2348 bytes tests/data/cert_missing/key.rsa | 52 --------- tests/data/key_missing/cert.der | Bin 0 -> 1293 bytes tests/data/key_missing/cert.pem | 29 ----- tests/data/multicert/create_certs.sh | 8 +- tests/data/multicert/example.com/cert.der | Bin 0 -> 1240 bytes tests/data/multicert/example.com/cert.pem | 28 ----- tests/data/multicert/example.com/key.der | Bin 0 -> 2347 bytes tests/data/multicert/example.com/key.rsa | 52 --------- tests/data/multicert/example.org/cert.der | Bin 0 -> 1240 bytes tests/data/multicert/example.org/cert.pem | 28 ----- tests/data/multicert/example.org/key.der | Bin 0 -> 2349 bytes tests/data/multicert/example.org/key.rsa | 52 --------- tests/tests.rs | 123 ++++++++++++---------- 22 files changed, 251 insertions(+), 422 deletions(-) create mode 100644 tests/data/.certificates/cert.der delete mode 100644 tests/data/.certificates/cert.pem create mode 100644 tests/data/.certificates/key.der delete mode 100644 tests/data/.certificates/key.rsa create mode 100644 tests/data/cert_missing/key.der delete mode 100644 tests/data/cert_missing/key.rsa create mode 100644 tests/data/key_missing/cert.der delete mode 100644 tests/data/key_missing/cert.pem create mode 100644 tests/data/multicert/example.com/cert.der delete mode 100644 tests/data/multicert/example.com/cert.pem create mode 100644 tests/data/multicert/example.com/key.der delete mode 100644 tests/data/multicert/example.com/key.rsa create mode 100644 tests/data/multicert/example.org/cert.der delete mode 100644 tests/data/multicert/example.org/cert.pem create mode 100644 tests/data/multicert/example.org/key.der delete mode 100644 tests/data/multicert/example.org/key.rsa diff --git a/Cargo.lock b/Cargo.lock index a4b4042..c2d6e49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,7 @@ dependencies = [ "mime_guess", "once_cell", "percent-encoding", + "rcgen", "rustls", "tokio", "tokio-rustls", @@ -23,9 +24,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.39" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cddc5f91628367664cc7c69714ff08deee8a3efc54623011c772544d7b2767" +checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" [[package]] name = "atty" @@ -74,6 +75,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "configparser" version = "2.0.0" @@ -250,6 +261,25 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.13.0" @@ -266,6 +296,17 @@ version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +[[package]] +name = "pem" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" +dependencies = [ + "base64", + "once_cell", + "regex", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -296,6 +337,33 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rcgen" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cb7a2dc0e5307189b6933a61290ff06b65b35bdcaae2b2c50a0c3e355cb118e" +dependencies = [ + "chrono", + "pem", + "ring", + "yasna", +] + +[[package]] +name = "regex" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" + [[package]] name = "ring" version = "0.16.20" @@ -342,9 +410,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "syn" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f" +checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663" dependencies = [ "proc-macro2", "quote", @@ -619,3 +687,12 @@ dependencies = [ "ring", "untrusted", ] + +[[package]] +name = "yasna" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de7bff972b4f2a06c85f6d8454b09df153af7e3a4ec2aac81db1b105b684ddb" +dependencies = [ + "chrono", +] diff --git a/Cargo.toml b/Cargo.toml index dfe112a..7e4981b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ log = "0.4" mime_guess = "2.0" once_cell = "1.5" percent-encoding = "2.1" +rcgen = { version = "0.8.9", features = ["pem"] } rustls = "0.19.0" tokio-rustls = "0.22.0" tokio = { version = "1.2", features = ["fs", "io-util", "net", "rt-multi-thread", "sync"] } diff --git a/src/certificates.rs b/src/certificates.rs index 73a6687..70d2d38 100644 --- a/src/certificates.rs +++ b/src/certificates.rs @@ -1,14 +1,11 @@ use { rustls::{ - internal::pemfile::{certs, pkcs8_private_keys}, - sign::{CertifiedKey, RSASigningKey}, + sign::{any_supported_type, CertifiedKey}, ResolvesServerCert, }, std::{ ffi::OsStr, fmt::{Display, Formatter}, - fs::File, - io::BufReader, path::Path, sync::Arc, }, @@ -23,17 +20,17 @@ pub(crate) struct CertStore { certs: Vec<(String, CertifiedKey)>, } -static CERT_FILE_NAME: &str = "cert.pem"; -static KEY_FILE_NAME: &str = "key.rsa"; +pub static CERT_FILE_NAME: &str = "cert.der"; +pub static KEY_FILE_NAME: &str = "key.der"; #[derive(Debug)] pub enum CertLoadError { /// could not access the certificate root directory NoReadCertDir, + /// no certificates or keys were found + Empty, /// the specified domain name cannot be processed correctly BadDomain(String), - /// The key file for the given domain does not contain any suitable keys. - NoKeys(String), /// the key file for the specified domain is bad (e.g. does not contain a /// key or is invalid) BadKey(String), @@ -55,17 +52,13 @@ impl Display for CertLoadError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { Self::NoReadCertDir => write!(f, "Could not read from certificate directory."), + Self::Empty => write!(f, "No keys or certificates were found in the given directory.\nSpecify the --hostname option to generate these automatically."), Self::BadDomain(domain) if !domain.is_ascii() => write!( f, "The domain name {} cannot be processed, it must be punycoded.", domain ), Self::BadDomain(domain) => write!(f, "The domain name {} cannot be processed.", domain), - Self::NoKeys(domain) => write!( - f, - "The key file for {} does not contain any suitable key.", - domain - ), Self::BadKey(domain) => write!(f, "The key file for {} is malformed.", domain), Self::BadCert(domain, e) => { write!(f, "The certificate file for {} is malformed: {}", domain, e) @@ -97,29 +90,25 @@ fn load_domain(certs_dir: &Path, domain: String) -> Result cert, - Err(()) => return Err(CertLoadError::BadCert(domain, String::new())), - }; + let cert = rustls::Certificate( + std::fs::read(&path).map_err(|_| CertLoadError::MissingCert(domain.clone()))?, + ); // load key from file path.set_file_name(KEY_FILE_NAME); if !path.is_file() { return Err(CertLoadError::MissingKey(domain)); } - let key = match pkcs8_private_keys(&mut BufReader::new(File::open(&path).unwrap())) { - Ok(mut keys) if !keys.is_empty() => keys.remove(0), - Ok(_) => return Err(CertLoadError::NoKeys(domain)), - Err(()) => return Err(CertLoadError::BadKey(domain)), - }; + let key = rustls::PrivateKey( + std::fs::read(&path).map_err(|_| CertLoadError::MissingKey(domain.clone()))?, + ); // transform key to correct format - let key = match RSASigningKey::new(&key) { + let key = match any_supported_type(&key) { Ok(key) => key, Err(()) => return Err(CertLoadError::BadKey(domain)), }; - Ok(CertifiedKey::new(cert_chain, Arc::new(Box::new(key)))) + Ok(CertifiedKey::new(vec![cert], Arc::new(key))) } impl CertStore { @@ -135,14 +124,12 @@ impl CertStore { let mut certs = vec![]; // Try to load fallback certificate and key directly from the top level - // certificate directory. It will be loaded as the `.` domain. - match load_domain(certs_dir, ".".to_string()) { + // certificate directory. + match load_domain(certs_dir, String::new()) { Err(CertLoadError::EmptyDomain(_)) => { /* there are no fallback keys */ } - Err(CertLoadError::NoReadCertDir) => unreachable!(), - Err(CertLoadError::BadDomain(_)) => unreachable!(), - Err(CertLoadError::NoKeys(_)) => { - return Err(CertLoadError::NoKeys("fallback".to_string())) - } + Err(CertLoadError::Empty) + | Err(CertLoadError::NoReadCertDir) + | Err(CertLoadError::BadDomain(_)) => unreachable!(), Err(CertLoadError::BadKey(_)) => { return Err(CertLoadError::BadKey("fallback".to_string())) } @@ -188,6 +175,10 @@ impl CertStore { certs.push((filename, key)); } + if certs.is_empty() { + return Err(CertLoadError::Empty); + } + certs.sort_unstable_by(|(a, _), (b, _)| { // Try to match as many domain segments as possible. If one is a // substring of the other, the `zip` will only compare the smaller diff --git a/src/main.rs b/src/main.rs index 7144b35..31a69bd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,12 +7,15 @@ use metadata::{FileOptions, PresetMeta}; use { once_cell::sync::Lazy, percent_encoding::{percent_decode_str, percent_encode, AsciiSet, CONTROLS}, + rcgen::{Certificate, CertificateParams, DnType}, rustls::{NoClientAuth, ServerConfig}, std::{ borrow::Cow, error::Error, ffi::OsStr, fmt::Write, + fs::{self, File}, + io::Write as _, net::SocketAddr, path::{Path, PathBuf}, sync::Arc, @@ -132,20 +135,88 @@ fn args() -> Result { "central-conf", "Use a central .meta file in the content root directory. Decentral config files will be ignored.", ); + opts.optflag( + "", + "ecdsa", + "Generate keys using the ecdsa signature algorithm instead of the default ed25519.", + ); let matches = opts.parse(&args[1..]).map_err(|f| f.to_string())?; + if matches.opt_present("h") { eprintln!("{}", opts.usage(&format!("Usage: {} [options]", &args[0]))); std::process::exit(0); } + if matches.opt_present("V") { eprintln!("agate {}", env!("CARGO_PKG_VERSION")); std::process::exit(0); } + + let certs_path = check_path(matches.opt_get_default("certs", ".certificates".into())?)?; + let certs = match certificates::CertStore::load_from(&certs_path) { + Ok(certs) => Some(certs), + Err(certificates::CertLoadError::Empty) if matches.opt_present("hostname") => { + // we will generate certificates in the next step + None + } + Err(e) => return Err(e.into()), + }; + + let mut reload_certs = false; let mut hostnames = vec![]; for s in matches.opt_strs("hostname") { - hostnames.push(Host::parse(&s)?); + let hostname = Host::parse(&s)?; + + // check if we have a certificate for that domain + if let Host::Domain(ref domain) = hostname { + if !matches!(certs, Some(ref certs) if certs.has_domain(domain)) { + eprintln!("no certificate or key found for {:?}, generating...", s); + + let mut cert_params = CertificateParams::new(vec![domain.clone()]); + cert_params + .distinguished_name + .push(DnType::CommonName, domain); + + // ::default() already implements a + // date in the far future from the time of writing: 4096-01-01 + + if !matches.opt_present("ecdsa") { + cert_params.alg = &rcgen::PKCS_ED25519; + } + + // generate the certificate with the configuration + let cert = Certificate::from_params(cert_params)?; + + fs::create_dir(certs_path.join(domain))?; + // write certificate data to disk + let mut cert_file = File::create(certs_path.join(format!( + "{}/{}", + domain, + certificates::CERT_FILE_NAME + )))?; + cert_file.write_all(&cert.serialize_der()?)?; + let mut key_file = File::create(certs_path.join(format!( + "{}/{}", + domain, + certificates::KEY_FILE_NAME + )))?; + key_file.write_all(&cert.serialize_private_key_der())?; + + reload_certs = true; + } + } + + hostnames.push(hostname); } + + // if new certificates were generated, reload the certificate store + let certs = if reload_certs { + certificates::CertStore::load_from(&certs_path)? + } else { + certs.unwrap() + }; + let mut addrs = vec![]; for i in matches.opt_strs("addr") { addrs.push(i.parse()?); @@ -157,14 +228,10 @@ fn args() -> Result { ]; } - let certs = Arc::new(certificates::CertStore::load_from(&check_path( - matches.opt_get_default("certs", ".certificates".into())?, - )?)?); - Ok(Args { addrs, content_dir: check_path(matches.opt_get_default("content", "content".into())?)?, - certs, + certs: Arc::new(certs), hostnames, language: matches.opt_str("lang"), serve_secret: matches.opt_present("serve-secret"), diff --git a/tests/data/.certificates/cert.der b/tests/data/.certificates/cert.der new file mode 100644 index 0000000000000000000000000000000000000000..951cff73064a0bb3cbed3023a61ef49e58217359 GIT binary patch literal 1293 zcmXqLV&ybwV*0p%nTe5!NyL7wfn9p!*}&N1>!z*`qt6~)@W{e7|?YEX#KRCMJ(l&p;h;+_*&h&s=C)!_}scw@N=hv`D2qC zTc&rfJCJA98Jpg@`OO6Vb%LRn&5L6%Eaq!rTghjunxv?lyWHPR>-nk1$JbuXj{f-5 zY;jD(JIxE72d2MmiT}H?V)d-W7E*`%&M?a#-D*BH{bQ+bcFbH|wy+@iZ{M%Zd}pGd z$Hdw(KT!YH!fo-cQ?<|DSD!eqW;(w%UtN@zr9x%G@qoVSum&*|_wx~-)~N~c&&yJ&pAvY^sx7->`9AIE$p+ul%C@*1 z<*ng8)EgDM{kz5g`6-&dH$V65ot^ahaJpLjqnXS8d+*S^AGCP6(8&#LJ=v+tvhvU9 ziSK;&cJT-6b3t)R9I3Z5XD=@GX$!V^R3bOw-PRdhn{VFKYRHg(=QTl7`~BiC$N3(M3)8}%h=JP8(R5@%Q50X}9kuVTzz^;HFq(GRF@jnZz z0W*+7PIkal4NP{73|BaRW>5I&mNWU>+IJ?GzO3zN(k{EvIlc9IEKlKWwrzKHt9YB6 z#JlX(1ZK^**P7XCXX~ANdr`;2J(D-J+FxuGsM6_w$o8~!uMLA+l3;M_!W52@BR!&A zDt1(G4tzgTvu3)#HOEGQ`&%dG&-HoAy>Qdc zPmg9v z;Pr3u-{QI50;+BMBvoBDOscY0+3j;=g~-fMv6FsBxBH*DDO<2_@v*6A*}V>}(M|AO zVl-dm+(N!8^JCQy;|muS$6lNx<;5sg``GSh^QOsF3+jGkV z)zmjM3ZMpe|fLPUMuSFdGHav7$cQ16&d+BXPT6Xz20Di$uYybcN literal 0 HcmV?d00001 diff --git a/tests/data/.certificates/cert.pem b/tests/data/.certificates/cert.pem deleted file mode 100644 index df3fbd8..0000000 --- a/tests/data/.certificates/cert.pem +++ /dev/null @@ -1,29 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFCTCCAvGgAwIBAgIUP60wPmdZzVFdc9c1ReFbzcWk9CwwDQYJKoZIhvcNAQEL -BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIwMTEwODE0MzE1NloXDTMwMTEw -NjE0MzE1NlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA+3+qGCFlrKMqyCl7uO7QJ+ILZx94swlcxaO1Vo2plau/ -rLFksNTm9EeT5kfovgE8UIXyuwQWZOoxOouaX30t3SUt1qhM2tJw+bkgN+M02LSX -i67AbjqJXWeJs+yQL64RVdM3c13Qow6EBqkOPSViISNtp09GKufKgePW6ptb8fk2 -o1yA7inQicCX7YRf/bF4q5qjOBrDjswDH8W1N5Vn8XVNa1ydLQZWUh/299WZ7jQg -LgIFiJ9RL9qhtl9FlSvN3yeRnny3AX4bk+I666vmleqAB8579QCT7wcGIVatPX71 -b0xZxayCZHNzcWTI4nZI2CO5b4T88F9qztM8NzBC/OvNKVPAiTrFwMnlxg3oqbe9 -Evqep2Ut/n5aKjkgeWDHUI57VoAWJEfPWPKuJhIPnmokf5RRzjqGa3invivnYzD2 -Jna0RMUNfA3CjVpdt/c4/59kKU3Z848uzZLrw2cmX+KZpv9LuCnfUqOnEsmwhoxr -ZaZqb8wuF7nm7aPwO85SXiIIZdppm6N1TIZTOOJ0HpDutZiKs9nZKoBoH+5KkCkr -76P0Y+bvA+DdxZ0V0Jvyar5QskJac3hbpO7xSc9cgNXytwsX7iusbnJTIY6Nr4DQ -sGogRY2/3gJ6zPv27VHykxlyMeJ3nRK5bE7k6rpCUQjrpVXb9GVbFZ1uv9LeIfkC -AwEAAaNTMFEwHQYDVR0OBBYEFI7IjwaA0gwpeZXl5x7Knw8i4STDMB8GA1UdIwQY -MBaAFI7IjwaA0gwpeZXl5x7Knw8i4STDMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI -hvcNAQELBQADggIBANQJ+WuQ8UZsk86t7jTS9K2Igit22ImXhdddDHHbBrbdLXoN -g4IXij8mEJqfPyqZhT49S23booihvJOyhT/RgRB6LI/hBuV1vTwARmIRU4WhZAh0 -xIwVCqniDp6Rgf6OEOYgLGk11CEv7vMfPZYbLddDY1HvmSl8l087CLEQ37WRb51M -5Quhsrny441s6aTn8I7c9WY2H/CUmlF8byoLuIl2MpR5bQN17binfsJZPYkKaMyJ -5URM0nCVUEr+o/1znYsQJYa+GSVEsJJ6OyS7TMSoFJlVFslOxbdPzNkdcL6jxpXN -B0rCrC1gTaQynxTOoQ56N8Z74V9xoXNd0ZwaSgEWfeM++YOyk3qgfvhobd0F8rTD -8+dvMN7eI+N8P+S+VCnX9YzrQIZyTwEhHK9fXLlcqoiAhpizgGhlGctiZ1MmpzT2 -aqFmLOCKpcQLyofsSLSFbhV2/w8rJbS1kTlrzwQLzaJvtLVy+ZZdQFP49Vj8Lb7n -3Oos/YeNoGhJoTWX7S2nQBChYMsSUA15+IS7RN0b+cJroHESsqCkbp07M20zhztz -fDWdYFh+o4V2lF9ecnqV7MwTvz9WxpchcUfQgENrJ3dgTn35hsZOMM2anwFWrmG+ -KVyFMhWNnZB1E530Nsu9cNHntqc3sFBdJebrFED9gOFErt5Vou8btjIqPm/Y ------END CERTIFICATE----- diff --git a/tests/data/.certificates/key.der b/tests/data/.certificates/key.der new file mode 100644 index 0000000000000000000000000000000000000000..745784f2341210c492094ad2fb7498940bafb801 GIT binary patch literal 2348 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 literal 0 HcmV?d00001 diff --git a/tests/data/.certificates/key.rsa b/tests/data/.certificates/key.rsa deleted file mode 100644 index a713c8e..0000000 --- a/tests/data/.certificates/key.rsa +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQD7f6oYIWWsoyrI -KXu47tAn4gtnH3izCVzFo7VWjamVq7+ssWSw1Ob0R5PmR+i+ATxQhfK7BBZk6jE6 -i5pffS3dJS3WqEza0nD5uSA34zTYtJeLrsBuOoldZ4mz7JAvrhFV0zdzXdCjDoQG -qQ49JWIhI22nT0Yq58qB49bqm1vx+TajXIDuKdCJwJfthF/9sXirmqM4GsOOzAMf -xbU3lWfxdU1rXJ0tBlZSH/b31ZnuNCAuAgWIn1Ev2qG2X0WVK83fJ5GefLcBfhuT -4jrrq+aV6oAHznv1AJPvBwYhVq09fvVvTFnFrIJkc3NxZMjidkjYI7lvhPzwX2rO -0zw3MEL8680pU8CJOsXAyeXGDeipt70S+p6nZS3+floqOSB5YMdQjntWgBYkR89Y -8q4mEg+eaiR/lFHOOoZreKe+K+djMPYmdrRExQ18DcKNWl239zj/n2QpTdnzjy7N -kuvDZyZf4pmm/0u4Kd9So6cSybCGjGtlpmpvzC4Xuebto/A7zlJeIghl2mmbo3VM -hlM44nQekO61mIqz2dkqgGgf7kqQKSvvo/Rj5u8D4N3FnRXQm/JqvlCyQlpzeFuk -7vFJz1yA1fK3CxfuK6xuclMhjo2vgNCwaiBFjb/eAnrM+/btUfKTGXIx4nedErls -TuTqukJRCOulVdv0ZVsVnW6/0t4h+QIDAQABAoICAF7c+LvBXSiRI0H8474N1lY0 -3Tg4lr5xeZzS80OCi8T404PAJcrNg5AAr7jcxt1keeulmrkQAaJu88Kxhbke7n3L -2E5vjQ288wA+4/gwq25SMBdwAwWQ7t9cfoRvZrOVZNSKpw/NAzV99C7O9Z/6ydjW -FDZXoI/ufmQgHKDBmRzcc8+KxNcQzqgnDSd6FvsKRgn0ejxfXAQwz7zcRk6A/IQH -SvyEIoUpLsYraGxzFWzUHI8+E/hEn8r9HKI9rXFm5HCX7EVrpVvaxWwymSbr4D4M -Bd7r87WmUiaG77kDiLT5fnpMwk/dkhFxusm6ykshcriUQQ3fi8jfNNpusvfeLGWa -4IcwkWPGd5EWNjM1eqeCfh79FAdJe8sEYf2pAkT8LVNT23J/jsL5dsLy3VFQ6svV -NReDnaWBxw92Xh/zqmo7L7/zGaLKXJPSQYHlnDUuYBOxoKhnzDY7P1XWk3STKDan -1rwSelBb/9Z/KGgeg92YlHrYOspw7JaCaYbzpsi8vCS+ZrTrbQ0UoHUAVKgRkTsG -pgUvlbX+RL1+nweGmjenDYEGn5MsPhoKgJFhJLgqqdo3ZTruEazU9Q5xLZDhWz82 -hxJKm3WFAqIL8Q5Wd22z7+DjS9YLuHYB+o9dSbqR0UOiyvYb+eL8gkvPtlvnE0yC -iWl1SDg25iWmbQz1X7EBAoIBAQD+AImpGYgRhIglB2MSz9LPLEC9lGZX6ZznfS91 -1tc5iPcqqKQ3VBCJWnCNOTh5RXlau0s/+vE6zKytSiWrzgkTBMkd18xPTy6c5O4J -XUCArZHx+GoXooOkSPxcLM1IGElTpHT/4Ua4KrGzMpdI8khHLDfiXeUL9mlgYrho -rLjArOo/1pBURYfNSay+bmTB/CzoS+0EXYc6fCNhNvE8fOkCCdPiwrpUjuZyYzmR -pkU1XVOzgqLEqBadywXfp6NeyRBVWO9OxWcJ63smwWCJz/KcTYhBAG5TH/959O6z -115Q7tst+amhBZLgOvHnYJ1S/dK1fU4PDRAm6dEW7kqeFd11AoIBAQD9ehX2SVdo -RHT69H4ItMpYWiBUtAwOEE5d5RPVrjtFtSh/V1pZ+jjGTyqTL5+885o1A6q2Nkrc -d8kYG5VVaGkjJEibCk6px0TWN2Lt73Q0ixNbBmcjxsjRp4EfHvMR/5IqvSZNuUjy -8j3dFHgeB6/PFY283Z9XbMrcFZeEsL4rljF+/XCX2ZeMIUBU93cbZr80o1LgcwpI -Qw61g6Kfjwm6jJEws3doxcmAGSkbR4PzZyRI8lLlIEWWccRG1k34J7s2eDfk8O6F -awv/pgcyFQQwl3zMXmCDNvdHkHV7EDu0gZc8WEuKBTA9tOfokkQmp4rbvMGqtJJm -OfYFZZR/YU31AoIBAHUulFPiRocmaJUEum1kWbJgjSGpRCoMyel2NJ4d1r9hc/5H -PTOVYeesRL6yhl5Uce8s90N2JzJkWMm9qnF/pWoTzCErfMOeGTgi2bqSPf7flLRY -UcHDpQ326g4wUSiQo8ul1KB0MucmM0Mj9O2fcT78pG+Xt+Lz9JuWD9Oi0714SL3Y -5E8soMFR2xMj5PIlwCYPWTKpX4jY2o2wBk1Mp0bcd9dm1QXLw39ETbvnRIihHMt1 -Wlh137E+h+At+83v3swxMn5Zzfain/c6QapyuE/p6RFr/Hn3Cisel716f7XA7Hdi -diKmaqNuLkn7pbkzBrHaNFf3Q9tgBamZl+0k0z0CggEAAuOgWnVNjL+zAaVFxn2h -DM7CLZT7yjE/Y2yYBEh/HnVJJ+JsAjiK6x+94X2aeYHhURdgm8EUq1ymKyMtWZLe -F+ty9Glyqha+Xx60fvfKwEqRhukUxeCfK1yYaS1mId9i4B/Vzu78uOAv+lQgZl86 -Dsc1HWD9TvbLfSS13GpTUJXerI7g+KofQxah8BX+Ao7yQPxXln1ZMaeqBEGi2eS8 -fKbbhM2W39fZSx9+S3ROObkEPdydO0VZ5bQYQ6JvsxNo298U7AQfA+BLe7d9v4Fj -0dX4MzAkM3qt6N/ppuRxecY8XhC3k7Qpb5qfRhRcuIASYhzNrE9wl7+zYS5eOfF2 -/QKCAQEAyOKjglWIpOul3EIOF2D0O6fkulxLfUya6URok00p3CxFXlFdDXwTzC9R -TNYMVE0WrxnXk1KT7ave4PJRFKMNk/PxbMQbtji9m3mWlZsM2vNNQ9nuWnrfOAha -plI7XBPJ4NNapl/RAFVhu3WVHG4CaYiqWPR3dMBi1/2Uk7EhZjhuJ8/AsJz5v7iO -Nv0ydQX7ZisNwf1eksL7odZjGcm/PNOxdAnFI67DuXo4YvyMjzovhTgm0s4yrecC -OMkrvwvefnzUQKV8m9na8pPG+ZJd518oK8nuk9UMgwsJnCWEVgzVjzRIxv7AElrO -tPwNvAOh6tUMmDlbRt+xdpFmU238jA== ------END PRIVATE KEY----- diff --git a/tests/data/cert_missing/key.der b/tests/data/cert_missing/key.der new file mode 100644 index 0000000000000000000000000000000000000000..745784f2341210c492094ad2fb7498940bafb801 GIT binary patch literal 2348 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 literal 0 HcmV?d00001 diff --git a/tests/data/cert_missing/key.rsa b/tests/data/cert_missing/key.rsa deleted file mode 100644 index a713c8e..0000000 --- a/tests/data/cert_missing/key.rsa +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -tPwNvAOh6tUMmDlbRt+xdpFmU238jA== ------END PRIVATE KEY----- diff --git a/tests/data/key_missing/cert.der b/tests/data/key_missing/cert.der new file mode 100644 index 0000000000000000000000000000000000000000..951cff73064a0bb3cbed3023a61ef49e58217359 GIT binary patch literal 1293 zcmXqLV&ybwV*0p%nTe5!NyL7wfn9p!*}&N1>!z*`qt6~)@W{e7|?YEX#KRCMJ(l&p;h;+_*&h&s=C)!_}scw@N=hv`D2qC zTc&rfJCJA98Jpg@`OO6Vb%LRn&5L6%Eaq!rTghjunxv?lyWHPR>-nk1$JbuXj{f-5 zY;jD(JIxE72d2MmiT}H?V)d-W7E*`%&M?a#-D*BH{bQ+bcFbH|wy+@iZ{M%Zd}pGd z$Hdw(KT!YH!fo-cQ?<|DSD!eqW;(w%UtN@zr9x%G@qoVSum&*|_wx~-)~N~c&&yJ&pAvY^sx7->`9AIE$p+ul%C@*1 z<*ng8)EgDM{kz5g`6-&dH$V65ot^ahaJpLjqnXS8d+*S^AGCP6(8&#LJ=v+tvhvU9 ziSK;&cJT-6b3t)R9I3Z5XD=@GX$!V^R3bOw-PRdhn{VFKYRHg(=QTl7`~BiC$N3(M3)8}%h=JP8(R5@%Q50X}9kuVTzz^;HFq(GRF@jnZz z0W*+7PIkal4NP{73|BaRW>5I&mNWU>+IJ?GzO3zN(k{EvIlc9IEKlKWwrzKHt9YB6 z#JlX(1ZK^**P7XCXX~ANdr`;2J(D-J+FxuGsM6_w$o8~!uMLA+l3;M_!W52@BR!&A zDt1(G4tzgTvu3)#HOEGQ`&%dG&-HoAy>Qdc zPmg9v z;Pr3u-{QI50;+BMBvoBDOscY0+3j;=g~-fMv6FsBxBH*DDO<2_@v*6A*}V>}(M|AO zVl-dm+(N!8^JCQy;|muS$6lNx<;5sg``GSh^QOsF3+jGkV z)zmjM3ZMpe|fLPUMuSFdGHav7$cQ16&d+BXPT6Xz20Di$uYybcN literal 0 HcmV?d00001 diff --git a/tests/data/key_missing/cert.pem b/tests/data/key_missing/cert.pem deleted file mode 100644 index df3fbd8..0000000 --- a/tests/data/key_missing/cert.pem +++ /dev/null @@ -1,29 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFCTCCAvGgAwIBAgIUP60wPmdZzVFdc9c1ReFbzcWk9CwwDQYJKoZIhvcNAQEL -BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIwMTEwODE0MzE1NloXDTMwMTEw -NjE0MzE1NlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA+3+qGCFlrKMqyCl7uO7QJ+ILZx94swlcxaO1Vo2plau/ -rLFksNTm9EeT5kfovgE8UIXyuwQWZOoxOouaX30t3SUt1qhM2tJw+bkgN+M02LSX -i67AbjqJXWeJs+yQL64RVdM3c13Qow6EBqkOPSViISNtp09GKufKgePW6ptb8fk2 -o1yA7inQicCX7YRf/bF4q5qjOBrDjswDH8W1N5Vn8XVNa1ydLQZWUh/299WZ7jQg -LgIFiJ9RL9qhtl9FlSvN3yeRnny3AX4bk+I666vmleqAB8579QCT7wcGIVatPX71 -b0xZxayCZHNzcWTI4nZI2CO5b4T88F9qztM8NzBC/OvNKVPAiTrFwMnlxg3oqbe9 -Evqep2Ut/n5aKjkgeWDHUI57VoAWJEfPWPKuJhIPnmokf5RRzjqGa3invivnYzD2 -Jna0RMUNfA3CjVpdt/c4/59kKU3Z848uzZLrw2cmX+KZpv9LuCnfUqOnEsmwhoxr -ZaZqb8wuF7nm7aPwO85SXiIIZdppm6N1TIZTOOJ0HpDutZiKs9nZKoBoH+5KkCkr -76P0Y+bvA+DdxZ0V0Jvyar5QskJac3hbpO7xSc9cgNXytwsX7iusbnJTIY6Nr4DQ -sGogRY2/3gJ6zPv27VHykxlyMeJ3nRK5bE7k6rpCUQjrpVXb9GVbFZ1uv9LeIfkC -AwEAAaNTMFEwHQYDVR0OBBYEFI7IjwaA0gwpeZXl5x7Knw8i4STDMB8GA1UdIwQY -MBaAFI7IjwaA0gwpeZXl5x7Knw8i4STDMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI -hvcNAQELBQADggIBANQJ+WuQ8UZsk86t7jTS9K2Igit22ImXhdddDHHbBrbdLXoN -g4IXij8mEJqfPyqZhT49S23booihvJOyhT/RgRB6LI/hBuV1vTwARmIRU4WhZAh0 -xIwVCqniDp6Rgf6OEOYgLGk11CEv7vMfPZYbLddDY1HvmSl8l087CLEQ37WRb51M -5Quhsrny441s6aTn8I7c9WY2H/CUmlF8byoLuIl2MpR5bQN17binfsJZPYkKaMyJ -5URM0nCVUEr+o/1znYsQJYa+GSVEsJJ6OyS7TMSoFJlVFslOxbdPzNkdcL6jxpXN -B0rCrC1gTaQynxTOoQ56N8Z74V9xoXNd0ZwaSgEWfeM++YOyk3qgfvhobd0F8rTD -8+dvMN7eI+N8P+S+VCnX9YzrQIZyTwEhHK9fXLlcqoiAhpizgGhlGctiZ1MmpzT2 -aqFmLOCKpcQLyofsSLSFbhV2/w8rJbS1kTlrzwQLzaJvtLVy+ZZdQFP49Vj8Lb7n -3Oos/YeNoGhJoTWX7S2nQBChYMsSUA15+IS7RN0b+cJroHESsqCkbp07M20zhztz -fDWdYFh+o4V2lF9ecnqV7MwTvz9WxpchcUfQgENrJ3dgTn35hsZOMM2anwFWrmG+ -KVyFMhWNnZB1E530Nsu9cNHntqc3sFBdJebrFED9gOFErt5Vou8btjIqPm/Y ------END CERTIFICATE----- diff --git a/tests/data/multicert/create_certs.sh b/tests/data/multicert/create_certs.sh index 02f58b4..af5369c 100755 --- a/tests/data/multicert/create_certs.sh +++ b/tests/data/multicert/create_certs.sh @@ -5,7 +5,7 @@ mkdir -p example.com example.org for domain in "example.com" "example.org" do # create private key -openssl genpkey -out $domain/key.rsa -algorithm RSA -pkeyopt rsa_keygen_bits:4096 +openssl genpkey -outform DER -out $domain/key.der -algorithm RSA -pkeyopt rsa_keygen_bits:4096 # create config file: # the generated certificates must not be CA-capable, otherwise rustls complains @@ -26,10 +26,10 @@ commonName = $domain subjectAltName = DNS:$domain EOT -openssl req -new -sha256 -out request.csr -key $domain/key.rsa -config openssl.conf +openssl req -new -sha256 -out request.csr -key $domain/key.der -keyform DER -config openssl.conf -openssl x509 -req -sha256 -days 3650 -in request.csr -out $domain/cert.pem \ - -extensions req_ext -extfile openssl.conf -signkey $domain/key.rsa +openssl x509 -req -sha256 -days 3650 -in request.csr -outform DER -out $domain/cert.der \ + -extensions req_ext -extfile openssl.conf -signkey $domain/key.der -keyform DER done # clean up diff --git a/tests/data/multicert/example.com/cert.der b/tests/data/multicert/example.com/cert.der new file mode 100644 index 0000000000000000000000000000000000000000..1e062775b69e658ed7dee7ee8fec5fec5856c686 GIT binary patch literal 1240 zcmXqLV!2|_#I$DtGZP~dlSqY$O#ovi-k`WtDF8pS|%f_kI=F#?@mywa1 zmBB#FP{crpjX9KsnTI>IA~ClhCsi*wKi5D`oY%_wCUY%5IdBVD7IpG;diyA$MlnsrJe08yL%O zPinejI5BPErJDSu1wU3UxP621d92j*u!-EO7db6hSmB!(bXT!$)*()%C)I_z_2pjL zs`1W0mhQUs<@QCP7@n;@?G81XIwzVJY+(KWujkdr?ropy5@vtb6~5gQ+UKTyu~N%^ zwT&GA`l|3V@iUU#zS+)RtdYIDS$^U996yb@CTI5+@NM7T(&wBybE=u3?_zjz%U751g;2Hl?dE?cWZ`<-YoGp=YQ(dm)*6{Sx zI z_UoMBE2U*66U&SvJ8!jaH`sP%MNvh(4D4V zz1K2s-8s22Xvc@|J6Nmjn=?cyF7r!}XZ{6}`c~ZAGAIow# z;|*IjE<7G&#WKxz>dlEqcU0e-J!N8c;EZ$kCG5R-+SGBL<9xqNdar~x@4JG|6~4SN z4OSa|$6A)L`+lD`OGDiFl!1$8-2cFx<+~3bc1xZl5?DA_>tRx%V95O%o@tkp{+C8w zi#|0wK~p0{W5-!RUCldXTS60KBzB7Yej%2l6qO%+vGvf+`>F@5#MCs(=%b4Kjk1hNz$a&i{-Dg-)<>I8~|F}bbllDoS z{T`m|j>{H(j+WnfvhbQ<$<>#ay;Y^Jxc)yD9+BSnz-Jn>s?)b^!J%%77ia0W2)G?{ zOnLeIf#O!~zn1FkY@1aN?bh3~I=oHxR*J(+rKK*dZ%_K2IrI5+OHKT|;>xbK+*7W* z=8M1C7+aIeeAYW+cDvFSZQ+=MR{J>EY97ov7j)hFLDqG9{>$5=qqa5_S>9|qd(%0b rag+T#5$?0WihUkB<;mN&yItely+rd=*k=$7XR_ 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 RVmldRQt5{Qk&6kv#pZLYc+3C* literal 0 HcmV?d00001 diff --git a/tests/data/multicert/example.com/key.rsa b/tests/data/multicert/example.com/key.rsa deleted file mode 100644 index c960ff1..0000000 --- a/tests/data/multicert/example.com/key.rsa +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -q+T6LY6tbtpB+11HBnD4I79WCYf4DA== ------END PRIVATE KEY----- diff --git a/tests/data/multicert/example.org/cert.der b/tests/data/multicert/example.org/cert.der new file mode 100644 index 0000000000000000000000000000000000000000..ba3f35b16b0695abf5f6da78735ea34ec4a158db GIT binary patch literal 1240 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 SocketAddr { use std::net::{IpAddr, Ipv4Addr}; @@ -19,7 +19,6 @@ fn addr(port: u16) -> SocketAddr { struct Server { server: std::process::Child, - buf: u8, // is set when output is collected by stop() output: Option>, } @@ -31,47 +30,67 @@ impl Server { .stderr(Stdio::piped()) .current_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/data")) .args(args) + .env("RUST_LOG", "debug") .spawn() .expect("failed to start binary"); - // the first output is when Agate is listening, so we only have to wait - // until the first byte is output - let mut buffer = [0; 1]; - server - .stderr - .as_mut() - .unwrap() - .read_exact(&mut buffer) - .unwrap(); + // We can be sure that agate is listening because it logs a message saying so. + let mut reader = BufReader::new(server.stderr.as_mut().unwrap()); + let mut buffer = String::new(); + while matches!(reader.read_line(&mut buffer), Ok(i) if i>0) { + print!("log: {}", buffer); + if buffer.contains("Listening") { + break; + } + + buffer.clear(); + } + + if matches!(server.try_wait(), Ok(Some(_)) | Err(_)) { + panic!("Server did not start properly"); + } Self { server, - buf: buffer[0], output: None, } } pub fn stop(&mut self) -> Result<(), String> { // try to stop the server - if let Some(output) = self.output.clone() { - return output; + if let Some(output) = self.output.as_ref() { + return output.clone(); } self.output = Some(match self.server.try_wait() { Err(e) => Err(format!("cannot access orchestrated program: {:?}", e)), - // everything fine, still running as expected, kill it now - Ok(None) => Ok(self.server.kill().unwrap()), - Ok(Some(_)) => { - // forward stderr so we have a chance to understand the problem - let buffer = std::iter::once(Ok(self.buf)) - .chain(self.server.stderr.take().unwrap().bytes()) - .collect::, _>>() - .unwrap(); + Ok(None) => { + // everything fine, still running as expected, kill it now + self.server.kill().unwrap(); - Err(String::from_utf8_lossy(&buffer).into_owned()) + let mut reader = BufReader::new(self.server.stderr.as_mut().unwrap()); + let mut buffer = String::new(); + while matches!(reader.read_line(&mut buffer), Ok(i) if i>0) { + print!("log: {}", buffer); + if buffer.contains("Listening") { + break; + } + } + Ok(()) + } + Ok(Some(_)) => { + let mut reader = BufReader::new(self.server.stderr.as_mut().unwrap()); + let mut buffer = String::new(); + while matches!(reader.read_line(&mut buffer), Ok(i) if i>0) { + print!("log: {}", buffer); + if buffer.contains("Listening") { + break; + } + } + Err(buffer) } }); - return self.output.clone().unwrap(); + self.output.clone().unwrap() } } @@ -84,7 +103,7 @@ impl Drop for Server { // server was already stopped } else { // we are panicking and a potential error was not handled - self.stop().unwrap_or_else(|e| eprintln!("{:?}", e)); + self.stop().unwrap_or_else(|e| eprintln!("{}", e)); } } } @@ -395,37 +414,27 @@ mod multicert { use super::*; #[test] + #[should_panic] fn cert_missing() { let mut server = Server::new(&["--addr", "[::]:1979", "--certs", "cert_missing"]); // wait for the server to stop, it should crash let _ = server.server.wait(); - - assert!(server - .stop() - .unwrap_err() - .to_string() - .contains("certificate file for fallback is missing")); } #[test] + #[should_panic] fn key_missing() { let mut server = Server::new(&["--addr", "[::]:1980", "--certs", "key_missing"]); // wait for the server to stop, it should crash let _ = server.server.wait(); - - assert!(server - .stop() - .unwrap_err() - .to_string() - .contains("key file for fallback is missing")); } #[test] fn example_com() { - use rustls::ClientSession; - use std::io::{Cursor, Write}; + use rustls::{Certificate, ClientSession}; + use std::io::Write; use std::net::TcpStream; let mut server = Server::new(&["--addr", "[::]:1981", "--certs", "multicert"]); @@ -433,10 +442,13 @@ mod multicert { let mut config = rustls::ClientConfig::new(); config .root_store - .add_pem_file(&mut Cursor::new(include_bytes!(concat!( - env!("CARGO_MANIFEST_DIR"), - "/tests/data/multicert/example.com/cert.pem" - )))) + .add(&Certificate( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/data/multicert/example.com/cert.der" + )) + .to_vec(), + )) .unwrap(); let dns_name = webpki::DNSNameRef::try_from_ascii_str("example.com").unwrap(); @@ -447,15 +459,15 @@ mod multicert { write!(tls, "gemini://example.com/\r\n").unwrap(); let mut buf = [0; 10]; - tls.read(&mut buf).unwrap(); + let _ = tls.read(&mut buf); - server.stop().unwrap() + server.stop().unwrap(); } #[test] fn example_org() { - use rustls::ClientSession; - use std::io::{Cursor, Write}; + use rustls::{Certificate, ClientSession}; + use std::io::Write; use std::net::TcpStream; let mut server = Server::new(&["--addr", "[::]:1982", "--certs", "multicert"]); @@ -463,10 +475,13 @@ mod multicert { let mut config = rustls::ClientConfig::new(); config .root_store - .add_pem_file(&mut Cursor::new(include_bytes!(concat!( - env!("CARGO_MANIFEST_DIR"), - "/tests/data/multicert/example.org/cert.pem" - )))) + .add(&Certificate( + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/data/multicert/example.org/cert.der" + )) + .to_vec(), + )) .unwrap(); let dns_name = webpki::DNSNameRef::try_from_ascii_str("example.org").unwrap(); @@ -477,8 +492,8 @@ mod multicert { write!(tls, "gemini://example.org/\r\n").unwrap(); let mut buf = [0; 10]; - tls.read(&mut buf).unwrap(); + let _ = tls.read(&mut buf); - server.stop().unwrap() + server.stop().unwrap(); } }