Implement CertFP

resolves #131
This commit is contained in:
Alex S. Glomsaas 2018-03-31 21:09:42 +02:00
parent f2e10001c0
commit e80a0f3a89
3 changed files with 28 additions and 1 deletions

View file

@ -145,6 +145,8 @@ port = 6697
password = "" password = ""
use_ssl = true use_ssl = true
cert_path = "cert.der" cert_path = "cert.der"
client_cert_path = "client.der"
client_cert_pass = "password"
encoding = "UTF-8" encoding = "UTF-8"
channels = ["#rust", "#haskell", "#fake"] channels = ["#rust", "#haskell", "#fake"]
umodes = "+RB-x" umodes = "+RB-x"

View file

@ -6,7 +6,7 @@ use std::io::Read;
use encoding::EncoderTrap; use encoding::EncoderTrap;
use encoding::label::encoding_from_whatwg_label; use encoding::label::encoding_from_whatwg_label;
use futures::{Async, Poll, Future, Sink, StartSend, Stream}; use futures::{Async, Poll, Future, Sink, StartSend, Stream};
use native_tls::{Certificate, TlsConnector}; use native_tls::{Certificate, TlsConnector, Pkcs12};
use tokio_core::reactor::Handle; use tokio_core::reactor::Handle;
use tokio_core::net::{TcpStream, TcpStreamNew}; use tokio_core::net::{TcpStream, TcpStreamNew};
use tokio_io::AsyncRead; use tokio_io::AsyncRead;
@ -135,6 +135,15 @@ impl Connection {
builder.add_root_certificate(cert)?; builder.add_root_certificate(cert)?;
info!("Added {} to trusted certificates.", cert_path); info!("Added {} to trusted certificates.", cert_path);
} }
if let Some(client_cert_path) = config.client_cert_path() {
let client_cert_pass = config.client_cert_pass();
let mut file = File::open(client_cert_path)?;
let mut client_cert_data = vec![];
file.read_to_end(&mut client_cert_data)?;
let pkcs12_archive = Pkcs12::from_der(&client_cert_data, &client_cert_pass)?;
builder.identity(pkcs12_archive)?;
info!("Using {} for client certificate authentication.", client_cert_path);
}
let connector = builder.build()?; let connector = builder.build()?;
let stream = Box::new(TcpStream::connect(&config.socket_addr()?, handle).map_err(|e| { let stream = Box::new(TcpStream::connect(&config.socket_addr()?, handle).map_err(|e| {
let res: error::IrcError = e.into(); let res: error::IrcError = e.into();

View file

@ -88,6 +88,10 @@ pub struct Config {
pub use_ssl: Option<bool>, pub use_ssl: Option<bool>,
/// The path to the SSL certificate for this server in DER format. /// The path to the SSL certificate for this server in DER format.
pub cert_path: Option<String>, pub cert_path: Option<String>,
/// The path to a SSL certificate to use for CertFP client authentication in DER format.
pub client_cert_path: Option<String>,
/// The password for the certificate to use in CertFP authentication.
pub client_cert_pass: Option<String>,
/// The encoding type used for this connection. /// The encoding type used for this connection.
/// This is typically UTF-8, but could be something else. /// This is typically UTF-8, but could be something else.
pub encoding: Option<String>, pub encoding: Option<String>,
@ -419,6 +423,16 @@ impl Config {
self.cert_path.as_ref().map(|s| &s[..]) self.cert_path.as_ref().map(|s| &s[..])
} }
/// Gets the path to the client authentication certificate in DER format if specified.
pub fn client_cert_path(&self) -> Option<&str> {
self.client_cert_path.as_ref().map(|s| &s[..])
}
/// Gets the password to the client authentication certificate.
pub fn client_cert_pass(&self) -> &str {
self.client_cert_pass.as_ref().map_or("", |s| &s[..])
}
/// Gets the encoding to use for this connection. This requires the encode feature to work. /// Gets the encoding to use for this connection. This requires the encode feature to work.
/// This defaults to UTF-8 when not specified. /// This defaults to UTF-8 when not specified.
pub fn encoding(&self) -> &str { pub fn encoding(&self) -> &str {
@ -557,6 +571,8 @@ mod test {
port: Some(6667), port: Some(6667),
use_ssl: Some(false), use_ssl: Some(false),
cert_path: None, cert_path: None,
client_cert_path: None,
client_cert_pass: None,
encoding: Some(format!("UTF-8")), encoding: Some(format!("UTF-8")),
channels: Some(vec![format!("#test"), format!("#test2")]), channels: Some(vec![format!("#test"), format!("#test2")]),
channel_keys: None, channel_keys: None,