tcp_stream/
openssl_impl.rs1use crate::{
2 HandshakeError, HandshakeResult, Identity, MidHandshakeTlsStream, TLSConfig, TcpStream,
3};
4
5use openssl::x509::X509;
6use std::io;
7
8pub use openssl::ssl::{SslConnector as OpenSslConnector, SslMethod as OpenSslMethod};
10
11pub type OpenSslStream = openssl::ssl::SslStream<TcpStream>;
13
14pub type OpenSslMidHandshakeTlsStream = openssl::ssl::MidHandshakeSslStream<TcpStream>;
16
17pub type OpenSslHandshakeError = openssl::ssl::HandshakeError<TcpStream>;
19
20pub type OpenSslErrorStack = openssl::error::ErrorStack;
22
23pub(crate) fn into_openssl_impl(
24 s: TcpStream,
25 domain: &str,
26 config: TLSConfig<'_, '_, '_>,
27) -> HandshakeResult {
28 let mut builder = OpenSslConnector::builder(OpenSslMethod::tls())?;
29 if let Some(identity) = config.identity {
30 let (cert, pkey, chain) = match identity {
31 Identity::PKCS8 { pem, key } => {
32 let pkey = openssl::pkey::PKey::private_key_from_pem(key)?;
33 let mut chain = openssl::x509::X509::stack_from_pem(pem)?.into_iter();
34 let cert = chain.next();
35 (cert, Some(pkey), Some(chain.collect()))
36 }
37 Identity::PKCS12 { der, password } => {
38 let mut openssl_identity =
39 openssl::pkcs12::Pkcs12::from_der(der)?.parse2(password)?;
40 (
41 openssl_identity.cert,
42 openssl_identity.pkey,
43 openssl_identity
44 .ca
45 .take()
46 .map(|stack| stack.into_iter().collect::<Vec<_>>()),
47 )
48 }
49 };
50 if let Some(cert) = cert.as_ref() {
51 builder.set_certificate(cert)?;
52 }
53 if let Some(pkey) = pkey.as_ref() {
54 builder.set_private_key(pkey)?;
55 }
56 if let Some(chain) = chain.as_ref() {
57 for cert in chain.iter().rev() {
58 builder.add_extra_chain_cert(cert.to_owned())?;
59 }
60 }
61 }
62 if let Some(cert_chain) = config.cert_chain.as_ref() {
63 for cert in X509::stack_from_pem(cert_chain.as_bytes())?.drain(..).rev() {
64 builder.cert_store_mut().add_cert(cert)?;
65 }
66 }
67 s.into_openssl(&builder.build(), domain)
68}
69
70impl From<OpenSslStream> for TcpStream {
71 fn from(s: OpenSslStream) -> Self {
72 TcpStream::OpenSsl(Box::new(s))
73 }
74}
75
76impl From<OpenSslMidHandshakeTlsStream> for MidHandshakeTlsStream {
77 fn from(mid: OpenSslMidHandshakeTlsStream) -> Self {
78 MidHandshakeTlsStream::Openssl(mid)
79 }
80}
81
82impl From<OpenSslHandshakeError> for HandshakeError {
83 fn from(error: OpenSslHandshakeError) -> Self {
84 match error {
85 openssl::ssl::HandshakeError::WouldBlock(mid) => HandshakeError::WouldBlock(mid.into()),
86 openssl::ssl::HandshakeError::Failure(failure) => {
87 HandshakeError::Failure(io::Error::other(failure.into_error()))
88 }
89 openssl::ssl::HandshakeError::SetupFailure(failure) => failure.into(),
90 }
91 }
92}
93
94impl From<OpenSslErrorStack> for HandshakeError {
95 fn from(error: OpenSslErrorStack) -> Self {
96 Self::Failure(error.into())
97 }
98}