gel_stream/
lib.rs

1// We don't want to warn about unused code when 1) either client or server is not
2// enabled, or 2) no crypto backend is enabled.
3#![cfg_attr(
4    not(all(
5        all(feature = "client", feature = "server"),
6        any(feature = "rustls", feature = "openssl")
7    )),
8    allow(unused)
9)]
10
11#[cfg(feature = "client")]
12mod client;
13#[cfg(feature = "server")]
14mod server;
15
16#[cfg(feature = "client")]
17pub use client::Connector;
18
19#[cfg(feature = "server")]
20pub use server::Acceptor;
21
22mod common;
23#[cfg(feature = "openssl")]
24pub use common::openssl::OpensslDriver;
25#[cfg(feature = "rustls")]
26pub use common::rustls::RustlsDriver;
27pub use common::{stream::*, target::*, tls::*, BaseStream};
28pub use rustls_pki_types as pki_types;
29
30pub type RawStream = UpgradableStream<BaseStream>;
31
32#[derive(Debug, thiserror::Error)]
33pub enum ConnectionError {
34    /// I/O error encountered during connection operations.
35    #[error("I/O error: {0}")]
36    Io(#[from] std::io::Error),
37
38    /// UTF-8 decoding error.
39    #[error("UTF8 error: {0}")]
40    Utf8Error(#[from] std::str::Utf8Error),
41
42    /// SSL-related error.
43    #[error("SSL error: {0}")]
44    SslError(#[from] SslError),
45}
46
47#[derive(Debug, thiserror::Error)]
48pub enum SslError {
49    #[error("SSL is not supported by this client transport")]
50    SslUnsupportedByClient,
51    #[error("SSL is already upgraded or is in the process of upgrading")]
52    SslAlreadyUpgraded,
53
54    #[cfg(feature = "openssl")]
55    #[error("OpenSSL error: {0}")]
56    OpenSslError(#[from] ::openssl::ssl::Error),
57    #[cfg(feature = "openssl")]
58    #[error("OpenSSL error: {0}")]
59    OpenSslErrorStack(#[from] ::openssl::error::ErrorStack),
60    #[cfg(feature = "openssl")]
61    #[error("OpenSSL certificate verification error: {0}")]
62    OpenSslErrorVerify(#[from] ::openssl::x509::X509VerifyResult),
63
64    #[cfg(feature = "rustls")]
65    #[error("Rustls error: {0}")]
66    RustlsError(#[from] ::rustls::Error),
67
68    #[cfg(feature = "rustls")]
69    #[error("Webpki error: {0}")]
70    WebpkiError(::webpki::Error),
71
72    #[cfg(feature = "rustls")]
73    #[error("Verifier builder error: {0}")]
74    VerifierBuilderError(#[from] ::rustls::server::VerifierBuilderError),
75
76    #[error("Invalid DNS name: {0}")]
77    InvalidDnsNameError(#[from] ::rustls_pki_types::InvalidDnsNameError),
78
79    #[error("SSL I/O error: {0}")]
80    SslIoError(#[from] std::io::Error),
81}
82
83impl SslError {
84    /// Returns a common error for any time of crypto backend.
85    pub fn common_error(&self) -> Option<CommonError> {
86        match self {
87            #[cfg(feature = "rustls")]
88            SslError::RustlsError(::rustls::Error::InvalidCertificate(cert_err)) => {
89                match cert_err {
90                    ::rustls::CertificateError::NotValidForName
91                    | ::rustls::CertificateError::NotValidForNameContext { .. } => {
92                        Some(CommonError::InvalidCertificateForName)
93                    }
94                    ::rustls::CertificateError::Revoked => Some(CommonError::CertificateRevoked),
95                    ::rustls::CertificateError::Expired => Some(CommonError::CertificateExpired),
96                    ::rustls::CertificateError::UnknownIssuer => Some(CommonError::InvalidIssuer),
97                    _ => None,
98                }
99            }
100            #[cfg(feature = "rustls")]
101            SslError::RustlsError(::rustls::Error::InvalidMessage(_)) => {
102                Some(CommonError::InvalidTlsProtocolData)
103            }
104            #[cfg(feature = "openssl")]
105            SslError::OpenSslErrorVerify(e) => match e.as_raw() {
106                openssl_sys::X509_V_ERR_HOSTNAME_MISMATCH => {
107                    Some(CommonError::InvalidCertificateForName)
108                }
109                openssl_sys::X509_V_ERR_IP_ADDRESS_MISMATCH => {
110                    Some(CommonError::InvalidCertificateForName)
111                }
112                openssl_sys::X509_V_ERR_CERT_REVOKED => Some(CommonError::CertificateRevoked),
113                openssl_sys::X509_V_ERR_CERT_HAS_EXPIRED => Some(CommonError::CertificateExpired),
114                openssl_sys::X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
115                | openssl_sys::X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY => {
116                    Some(CommonError::InvalidIssuer)
117                }
118                _ => None,
119            },
120            #[cfg(feature = "openssl")]
121            SslError::OpenSslErrorStack(e) => match e.errors().first().map(|err| err.code()) {
122                // SSL_R_WRONG_VERSION_NUMBER
123                Some(0xa00010b) => Some(CommonError::InvalidTlsProtocolData),
124                // SSL_R_PACKET_LENGTH_TOO_LONG
125                Some(0xa0000c6) => Some(CommonError::InvalidTlsProtocolData),
126                _ => None,
127            },
128            #[cfg(feature = "openssl")]
129            SslError::OpenSslError(e) => match e.code().as_raw() {
130                // TODO: We should probably wrap up handshake errors differently.
131                openssl_sys::SSL_ERROR_SSL => {
132                    match e
133                        .ssl_error()
134                        .and_then(|e| e.errors().first())
135                        .map(|err| err.code())
136                    {
137                        // SSL_R_WRONG_VERSION_NUMBER
138                        Some(0xa00010b) => Some(CommonError::InvalidTlsProtocolData),
139                        // SSL_R_PACKET_LENGTH_TOO_LONG
140                        Some(0xa0000c6) => Some(CommonError::InvalidTlsProtocolData),
141                        _ => None,
142                    }
143                }
144                _ => None,
145            },
146            _ => None,
147        }
148    }
149}
150
151#[derive(Debug, thiserror::Error, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
152pub enum CommonError {
153    #[error("The certificate's subject name(s) do not match the name of the host")]
154    InvalidCertificateForName,
155    #[error("The certificate has been revoked")]
156    CertificateRevoked,
157    #[error("The certificate has expired")]
158    CertificateExpired,
159    #[error("The certificate was issued by an untrusted authority")]
160    InvalidIssuer,
161    #[error("TLS protocol error")]
162    InvalidTlsProtocolData,
163}