1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use alloc::{format, sync::Arc};
use rustls::OtherError;

/// Converts an `mbedtls::Error` into a `rustls::Error`
pub fn mbedtls_err_into_rustls_err(err: mbedtls::Error) -> rustls::Error {
    mbedtls_err_into_rustls_err_with_error_msg(err, "")
}

/// Converts an `mbedtls::Error` into a `rustls::Error`; may include the provided `msg` in the
/// returned error (e.g., if returning a `rustls::Error::General` error).
pub fn mbedtls_err_into_rustls_err_with_error_msg(err: mbedtls::Error, msg: &str) -> rustls::Error {
    match err {
        mbedtls::Error::X509InvalidSignature |
        mbedtls::Error::RsaVerifyFailed => rustls::Error::InvalidCertificate(rustls::CertificateError::BadSignature),

        mbedtls::Error::X509CertUnknownFormat |
        mbedtls::Error::X509BadInputData => rustls::Error::InvalidCertificate(rustls::CertificateError::BadEncoding),

        // mbedtls::Error::X509AllocFailed |
        mbedtls::Error::X509BufferTooSmall |
        mbedtls::Error::X509CertVerifyFailed |
        mbedtls::Error::X509FatalError |
        mbedtls::Error::X509FeatureUnavailable |
        // mbedtls::Error::X509FileIoError |
        mbedtls::Error::X509InvalidAlg |
        mbedtls::Error::X509InvalidDate |
        mbedtls::Error::X509InvalidExtensions |
        mbedtls::Error::X509InvalidFormat |
        mbedtls::Error::X509InvalidSerial |
        mbedtls::Error::X509InvalidVersion |
        mbedtls::Error::X509SigMismatch |
        mbedtls::Error::X509UnknownOid |
        mbedtls::Error::X509UnknownSigAlg |
        mbedtls::Error::X509UnknownVersion => rustls::Error::InvalidCertificate(rustls::CertificateError::Other(OtherError(Arc::new(err)))),

        mbedtls::Error::X509InvalidName => rustls::Error::InvalidCertificate(rustls::CertificateError::NotValidForName),

        _ => rustls::Error::General(format!("{err}{sep}{msg}", sep = if msg.is_empty() {""} else {"\n"})),
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use rustls::CertificateError;

    #[test]
    fn test_mbedtls_err_into_rustls_err() {
        assert_eq!(
            mbedtls_err_into_rustls_err(mbedtls::Error::X509InvalidSignature),
            rustls::Error::InvalidCertificate(CertificateError::BadSignature)
        );
        assert_eq!(
            mbedtls_err_into_rustls_err(mbedtls::Error::RsaVerifyFailed),
            rustls::Error::InvalidCertificate(CertificateError::BadSignature)
        );
        assert_eq!(
            mbedtls_err_into_rustls_err(mbedtls::Error::X509BadInputData),
            rustls::Error::InvalidCertificate(CertificateError::BadEncoding)
        );
        assert_eq!(
            mbedtls_err_into_rustls_err(mbedtls::Error::X509CertUnknownFormat),
            rustls::Error::InvalidCertificate(CertificateError::BadEncoding)
        );
        assert_eq!(
            mbedtls_err_into_rustls_err(mbedtls::Error::X509InvalidName),
            rustls::Error::InvalidCertificate(CertificateError::NotValidForName)
        );
    }

    #[test]
    fn test_mbedtls_err_into_rustls_err_with_error_msg() {
        assert_eq!(
            mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::X509InvalidSignature, ""),
            rustls::Error::InvalidCertificate(CertificateError::BadSignature)
        );
        assert_eq!(
            mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::CipherAuthFailed, ""),
            rustls::Error::General(String::from("mbedTLS error CipherAuthFailed"))
        );
        assert_eq!(
            mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::RsaVerifyFailed, ""),
            rustls::Error::InvalidCertificate(CertificateError::BadSignature)
        );
        assert_eq!(
            mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::X509InvalidName, ""),
            rustls::Error::InvalidCertificate(CertificateError::NotValidForName)
        );
        assert_eq!(
            format!(
                "{:?}",
                mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::X509UnknownVersion, "")
            ),
            format!(
                "{:?}",
                rustls::Error::InvalidCertificate(CertificateError::Other(OtherError(Arc::new(
                    mbedtls::Error::X509UnknownVersion
                ))))
            )
        );
        assert_eq!(
            format!(
                "{:?}",
                mbedtls_err_into_rustls_err_with_error_msg(mbedtls::Error::X509InvalidSerial, "Invalid serial number")
            ),
            format!(
                "{:?}",
                rustls::Error::InvalidCertificate(CertificateError::Other(OtherError(Arc::new(
                    mbedtls::Error::X509InvalidSerial
                ))))
            )
        );
    }
}