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                        Some(CommonError::InvalidCertificateForName)
92                    }
93                    ::rustls::CertificateError::Revoked => Some(CommonError::CertificateRevoked),
94                    ::rustls::CertificateError::Expired => Some(CommonError::CertificateExpired),
95                    ::rustls::CertificateError::UnknownIssuer => Some(CommonError::InvalidIssuer),
96                    _ => None,
97                }
98            }
99            #[cfg(feature = "rustls")]
100            SslError::RustlsError(::rustls::Error::InvalidMessage(_)) => {
101                Some(CommonError::InvalidTlsProtocolData)
102            }
103            #[cfg(feature = "openssl")]
104            SslError::OpenSslErrorVerify(e) => match e.as_raw() {
105                openssl_sys::X509_V_ERR_HOSTNAME_MISMATCH => {
106                    Some(CommonError::InvalidCertificateForName)
107                }
108                openssl_sys::X509_V_ERR_IP_ADDRESS_MISMATCH => {
109                    Some(CommonError::InvalidCertificateForName)
110                }
111                openssl_sys::X509_V_ERR_CERT_REVOKED => Some(CommonError::CertificateRevoked),
112                openssl_sys::X509_V_ERR_CERT_HAS_EXPIRED => Some(CommonError::CertificateExpired),
113                openssl_sys::X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
114                | openssl_sys::X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY => {
115                    Some(CommonError::InvalidIssuer)
116                }
117                _ => None,
118            },
119            #[cfg(feature = "openssl")]
120            SslError::OpenSslErrorStack(e) => match e.errors().first().map(|err| err.code()) {
121                // SSL_R_WRONG_VERSION_NUMBER
122                Some(0xa00010b) => Some(CommonError::InvalidTlsProtocolData),
123                // SSL_R_PACKET_LENGTH_TOO_LONG
124                Some(0xa0000c6) => Some(CommonError::InvalidTlsProtocolData),
125                _ => None,
126            },
127            #[cfg(feature = "openssl")]
128            SslError::OpenSslError(e) => match e.code().as_raw() {
129                // TODO: We should probably wrap up handshake errors differently.
130                openssl_sys::SSL_ERROR_SSL => {
131                    match e
132                        .ssl_error()
133                        .and_then(|e| e.errors().first())
134                        .map(|err| err.code())
135                    {
136                        // SSL_R_WRONG_VERSION_NUMBER
137                        Some(0xa00010b) => Some(CommonError::InvalidTlsProtocolData),
138                        // SSL_R_PACKET_LENGTH_TOO_LONG
139                        Some(0xa0000c6) => Some(CommonError::InvalidTlsProtocolData),
140                        _ => None,
141                    }
142                }
143                _ => None,
144            },
145            _ => None,
146        }
147    }
148}
149
150#[derive(Debug, thiserror::Error, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
151pub enum CommonError {
152    #[error("The certificate's subject name(s) do not match the name of the host")]
153    InvalidCertificateForName,
154    #[error("The certificate has been revoked")]
155    CertificateRevoked,
156    #[error("The certificate has expired")]
157    CertificateExpired,
158    #[error("The certificate was issued by an untrusted authority")]
159    InvalidIssuer,
160    #[error("TLS protocol error")]
161    InvalidTlsProtocolData,
162}