I'm trying to write an HTTPS server that uses a legacy format of PFX (pkcs#12 aka .p12
) identity files for TLS.
From attempting to with the native_tls example structure (see code below), I find that it doesn't support this.
In a situation where I'm forced to use this format of a certificate for a client that cannot be modified, how would one go about this? I'm doing this for a learning experience, but seeing that this is a totally reasonable situation to find yourself at an odd job, what do you do?
use native_tls::{Identity, TlsAcceptor, TlsStream};
use std::fs::File;
use std::io::Read;
use std::io::{prelude::*, BufReader};
use std::net::{TcpListener, TcpStream};
use std::sync::Arc;
use std::thread;
fn handle_connection(mut stream: TlsStream<TcpStream>) {
let buf_reader = BufReader::new(&mut stream);
let http_request: Vec<_> = buf_reader.lines().map(|result| result.unwrap()).take_while(|line| !line.is_empty()).collect();
println!("Request: {:#?}", http_request);
}
fn main() {
let mut file = File::open("root.pfx").unwrap();
let mut identity = vec![];
file.read_to_end(&mut identity).unwrap();
let identity = Identity::from_pkcs12(&identity, "").unwrap();
let listener = TcpListener::bind("0.0.0.0:8443").unwrap();
let acceptor = TlsAcceptor::new(identity).unwrap();
let acceptor = Arc::new(acceptor);
for stream in listener.incoming() {
match stream {
Ok(stream) => {
let acceptor = acceptor.clone();
thread::spawn(move || {
let stream = acceptor.accept(stream).unwrap();
handle_connection(stream);
});
}
Err(e) => { /* connection failed */ }
}
}
}
Error:
Trying to compile this.
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Normal(ErrorStack([Error { code: 621174887, library: "DSO support routines", function: "dlfcn_load", reason: "could not l
oad the shared library", file: "crypto/dso/dso_dlfcn.c", line: 118, data: "filename(libproviders.so): libproviders.so: cannot open shared object file: No such file or directory" }, Error { code
: 621215847, library: "DSO support routines", function: "DSO_load", reason: "could not load the shared library", file: "crypto/dso/dso_lib.c", line: 162 }, Error { code: 235360366, library: "co
nfiguration file routines", function: "module_load_dso", reason: "error loading dso", file: "crypto/conf/conf_mod.c", line: 224, data: "module=providers, path=providers" }, Error { code: 235364
465, library: "configuration file routines", function: "module_run", reason: "unknown module name", file: "crypto/conf/conf_mod.c", line: 165, data: "module=providers" }, Error { code: 58771876
4, library: "PKCS12 routines", function: "PKCS12_verify_mac", reason: "mac absent", file: "crypto/pkcs12/p12_mutl.c", line: 157 }, Error { code: 587718764, library: "PKCS12 routines", function:
"PKCS12_verify_mac", reason: "mac absent", file: "crypto/pkcs12/p12_mutl.c", line: 157 }, Error { code: 587686001, library: "PKCS12 routines", function: "PKCS12_parse", reason: "mac verify fai
lure", file: "crypto/pkcs12/p12_kiss.c", line: 66 }]))', src/main.rs:20:57
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
(I'm guessing this means it's not supported, but maybe I'm doing something else wrong)
The certificate is generated like this:
# Generate certificate
openssl req -newkey rsa:2048 -nodes -keyout root.key -x509 -days 3650 -out root.crt -subj "/CN=Root Cert"
# Put into legacy PFX format for client
openssl pkcs12 -export -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES -nomac -inkey root.key -in root.crt -out root.pfx
For more detail on why I'm doing this, read my previous post.