From 8fd9ca15c3df8757b0268f9be49a952142fb333f Mon Sep 17 00:00:00 2001 From: Johann150 Date: Wed, 10 Feb 2021 23:34:40 +0100 Subject: [PATCH] better error message for missing keys (again) adresses comments from #33 Loading the certificate and key file is done at startup because: 1. We can detect the incorrect file faster and fail the whole server and not just a worker thread. All subsequent worker threads would fail for the same reason anyway. 2. We do not have to read the same unchanged files over and over again. This is good because file I/O is slower than in-memory cloning instead. --- CHANGELOG.md | 2 ++ src/main.rs | 34 +++++++++++++++++++++------------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce86e10..bdc51b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,9 +16,11 @@ Thank you to @gegeweb for contributing to this release. ### Changed * The changelog is now also kept in this file in addition to the GitHub releases. +* Certificate chain and key file are now only loaded once at startup, certificate changes need a restart to take effect. ### Fixed * The Syntax for the IPv6 address in the README has been corrected. +* Give a better error message when no keys are found in the key file instead of panicking with a range check. ## [2.4.1] - 2020-02-08 ### Fixed diff --git a/src/main.rs b/src/main.rs index db0746a..c997890 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use { percent_encoding::{percent_decode_str, percent_encode, AsciiSet, CONTROLS}, rustls::{ internal::pemfile::{certs, pkcs8_private_keys}, - NoClientAuth, ServerConfig, + Certificate, NoClientAuth, PrivateKey, ServerConfig, }, std::{ borrow::Cow, error::Error, ffi::OsStr, fmt::Write, fs::File, io::BufReader, @@ -68,8 +68,8 @@ static ARGS: Lazy = Lazy::new(|| { struct Args { addrs: Vec, content_dir: String, - cert_file: String, - key_file: String, + cert_chain: Vec, + key: PrivateKey, hostnames: Vec, language: Option, silent: bool, @@ -150,11 +150,26 @@ fn args() -> Result { "0.0.0.0:1965".parse().unwrap(), ]; } + + let cert_file = File::open(check_path( + matches.opt_get_default("cert", "cert.pem".into())?, + )?)?; + let cert_chain = certs(&mut BufReader::new(cert_file)).or(Err("bad cert"))?; + + let key_file = File::open(check_path( + matches.opt_get_default("key", "key.rsa".into())?, + )?)?; + let key = pkcs8_private_keys(&mut BufReader::new(key_file)) + .or(Err("bad key file"))? + .drain(..) + .next() + .ok_or("no keys found")?; + Ok(Args { addrs, content_dir: check_path(matches.opt_get_default("content", "content".into())?)?, - cert_file: check_path(matches.opt_get_default("cert", "cert.pem".into())?)?, - key_file: check_path(matches.opt_get_default("key", "key.rsa".into())?)?, + cert_chain, + key, hostnames, language: matches.opt_str("lang"), silent: matches.opt_present("s"), @@ -176,18 +191,11 @@ fn check_path(s: String) -> Result { static TLS: Lazy = Lazy::new(|| acceptor().unwrap()); fn acceptor() -> Result { - let cert_file = File::open(&ARGS.cert_file)?; - let certs = certs(&mut BufReader::new(cert_file)).or(Err("bad cert"))?; - - let key_file = File::open(&ARGS.key_file)?; - let mut keys = pkcs8_private_keys(&mut BufReader::new(key_file)).or(Err("bad key"))?; - let mut config = ServerConfig::new(NoClientAuth::new()); if ARGS.only_tls13 { config.versions = vec![rustls::ProtocolVersion::TLSv1_3]; } - assert!(!keys.is_empty(), "no valid keys"); - config.set_single_cert(certs, keys.remove(0))?; + config.set_single_cert(ARGS.cert_chain.clone(), ARGS.key.clone())?; Ok(TlsAcceptor::from(Arc::new(config))) }