Coverage Report

Created: 2024-12-17 06:15

/rust/registry/src/index.crates.io-6f17d22bba15001f/rustls-0.23.20/src/webpki/mod.rs
Line
Count
Source (jump to first uncovered line)
1
#[cfg(feature = "std")]
2
use alloc::sync::Arc;
3
use alloc::vec::Vec;
4
use core::fmt;
5
6
use pki_types::CertificateRevocationListDer;
7
use webpki::{CertRevocationList, OwnedCertRevocationList};
8
9
use crate::error::{CertRevocationListError, CertificateError, Error, OtherError};
10
11
mod anchors;
12
mod client_verifier;
13
mod server_verifier;
14
mod verify;
15
16
pub use anchors::RootCertStore;
17
pub use client_verifier::{ClientCertVerifierBuilder, WebPkiClientVerifier};
18
pub use server_verifier::{ServerCertVerifierBuilder, WebPkiServerVerifier};
19
// Conditionally exported from crate.
20
#[allow(unreachable_pub)]
21
pub use verify::{
22
    verify_server_cert_signed_by_trust_anchor, verify_server_name, ParsedCertificate,
23
};
24
pub use verify::{
25
    verify_tls12_signature, verify_tls13_signature, verify_tls13_signature_with_raw_key,
26
    WebPkiSupportedAlgorithms,
27
};
28
29
/// An error that can occur when building a certificate verifier.
30
#[derive(Debug, Clone)]
31
#[non_exhaustive]
32
pub enum VerifierBuilderError {
33
    /// No root trust anchors were provided.
34
    NoRootAnchors,
35
    /// A provided CRL could not be parsed.
36
    InvalidCrl(CertRevocationListError),
37
}
38
39
impl From<CertRevocationListError> for VerifierBuilderError {
40
0
    fn from(value: CertRevocationListError) -> Self {
41
0
        Self::InvalidCrl(value)
42
0
    }
43
}
44
45
impl fmt::Display for VerifierBuilderError {
46
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47
0
        match self {
48
0
            Self::NoRootAnchors => write!(f, "no root trust anchors were provided"),
49
0
            Self::InvalidCrl(e) => write!(f, "provided CRL could not be parsed: {:?}", e),
50
        }
51
0
    }
52
}
53
54
#[cfg(feature = "std")]
55
impl std::error::Error for VerifierBuilderError {}
56
57
0
fn pki_error(error: webpki::Error) -> Error {
58
    use webpki::Error::*;
59
0
    match error {
60
0
        BadDer | BadDerTime | TrailingData(_) => CertificateError::BadEncoding.into(),
61
0
        CertNotValidYet => CertificateError::NotValidYet.into(),
62
0
        CertExpired | InvalidCertValidity => CertificateError::Expired.into(),
63
0
        UnknownIssuer => CertificateError::UnknownIssuer.into(),
64
0
        CertNotValidForName => CertificateError::NotValidForName.into(),
65
0
        CertRevoked => CertificateError::Revoked.into(),
66
0
        UnknownRevocationStatus => CertificateError::UnknownRevocationStatus.into(),
67
0
        CrlExpired => CertificateError::ExpiredRevocationList.into(),
68
0
        IssuerNotCrlSigner => CertRevocationListError::IssuerInvalidForCrl.into(),
69
70
        InvalidSignatureForPublicKey
71
        | UnsupportedSignatureAlgorithm
72
0
        | UnsupportedSignatureAlgorithmForPublicKey => CertificateError::BadSignature.into(),
73
74
        InvalidCrlSignatureForPublicKey
75
        | UnsupportedCrlSignatureAlgorithm
76
        | UnsupportedCrlSignatureAlgorithmForPublicKey => {
77
0
            CertRevocationListError::BadSignature.into()
78
        }
79
80
0
        _ => CertificateError::Other(OtherError(
81
0
            #[cfg(feature = "std")]
82
0
            Arc::new(error),
83
0
        ))
84
0
        .into(),
85
    }
86
0
}
87
88
0
fn crl_error(e: webpki::Error) -> CertRevocationListError {
89
    use webpki::Error::*;
90
0
    match e {
91
        InvalidCrlSignatureForPublicKey
92
        | UnsupportedCrlSignatureAlgorithm
93
0
        | UnsupportedCrlSignatureAlgorithmForPublicKey => CertRevocationListError::BadSignature,
94
0
        InvalidCrlNumber => CertRevocationListError::InvalidCrlNumber,
95
0
        InvalidSerialNumber => CertRevocationListError::InvalidRevokedCertSerialNumber,
96
0
        IssuerNotCrlSigner => CertRevocationListError::IssuerInvalidForCrl,
97
0
        MalformedExtensions | BadDer | BadDerTime => CertRevocationListError::ParseError,
98
0
        UnsupportedCriticalExtension => CertRevocationListError::UnsupportedCriticalExtension,
99
0
        UnsupportedCrlVersion => CertRevocationListError::UnsupportedCrlVersion,
100
0
        UnsupportedDeltaCrl => CertRevocationListError::UnsupportedDeltaCrl,
101
0
        UnsupportedIndirectCrl => CertRevocationListError::UnsupportedIndirectCrl,
102
0
        UnsupportedRevocationReason => CertRevocationListError::UnsupportedRevocationReason,
103
104
0
        _ => CertRevocationListError::Other(OtherError(
105
0
            #[cfg(feature = "std")]
106
0
            Arc::new(e),
107
0
        )),
108
    }
109
0
}
110
111
8.18k
fn parse_crls(
112
8.18k
    crls: Vec<CertificateRevocationListDer<'_>>,
113
8.18k
) -> Result<Vec<CertRevocationList<'_>>, CertRevocationListError> {
114
8.18k
    crls.iter()
115
8.18k
        .map(|der| OwnedCertRevocationList::from_der(der.as_ref()).map(Into::into))
116
8.18k
        .collect::<Result<Vec<_>, _>>()
117
8.18k
        .map_err(crl_error)
118
8.18k
}
119
120
mod tests {
121
    #[test]
122
    fn pki_crl_errors() {
123
        use super::{pki_error, CertRevocationListError, CertificateError, Error};
124
125
        // CRL signature errors should be turned into BadSignature.
126
        assert_eq!(
127
            pki_error(webpki::Error::InvalidCrlSignatureForPublicKey),
128
            Error::InvalidCertRevocationList(CertRevocationListError::BadSignature),
129
        );
130
        assert_eq!(
131
            pki_error(webpki::Error::UnsupportedCrlSignatureAlgorithm),
132
            Error::InvalidCertRevocationList(CertRevocationListError::BadSignature),
133
        );
134
        assert_eq!(
135
            pki_error(webpki::Error::UnsupportedCrlSignatureAlgorithmForPublicKey),
136
            Error::InvalidCertRevocationList(CertRevocationListError::BadSignature),
137
        );
138
139
        // Revoked cert errors should be turned into Revoked.
140
        assert_eq!(
141
            pki_error(webpki::Error::CertRevoked),
142
            Error::InvalidCertificate(CertificateError::Revoked),
143
        );
144
145
        // Issuer not CRL signer errors should be turned into IssuerInvalidForCrl
146
        assert_eq!(
147
            pki_error(webpki::Error::IssuerNotCrlSigner),
148
            Error::InvalidCertRevocationList(CertRevocationListError::IssuerInvalidForCrl)
149
        );
150
    }
151
152
    #[test]
153
    fn crl_error_from_webpki() {
154
        use super::crl_error;
155
        use super::CertRevocationListError::*;
156
157
        let testcases = &[
158
            (webpki::Error::InvalidCrlSignatureForPublicKey, BadSignature),
159
            (
160
                webpki::Error::UnsupportedCrlSignatureAlgorithm,
161
                BadSignature,
162
            ),
163
            (
164
                webpki::Error::UnsupportedCrlSignatureAlgorithmForPublicKey,
165
                BadSignature,
166
            ),
167
            (webpki::Error::InvalidCrlNumber, InvalidCrlNumber),
168
            (
169
                webpki::Error::InvalidSerialNumber,
170
                InvalidRevokedCertSerialNumber,
171
            ),
172
            (webpki::Error::IssuerNotCrlSigner, IssuerInvalidForCrl),
173
            (webpki::Error::MalformedExtensions, ParseError),
174
            (webpki::Error::BadDer, ParseError),
175
            (webpki::Error::BadDerTime, ParseError),
176
            (
177
                webpki::Error::UnsupportedCriticalExtension,
178
                UnsupportedCriticalExtension,
179
            ),
180
            (webpki::Error::UnsupportedCrlVersion, UnsupportedCrlVersion),
181
            (webpki::Error::UnsupportedDeltaCrl, UnsupportedDeltaCrl),
182
            (
183
                webpki::Error::UnsupportedIndirectCrl,
184
                UnsupportedIndirectCrl,
185
            ),
186
            (
187
                webpki::Error::UnsupportedRevocationReason,
188
                UnsupportedRevocationReason,
189
            ),
190
        ];
191
        for t in testcases {
192
            assert_eq!(crl_error(t.0), t.1);
193
        }
194
195
        assert!(matches!(
196
            crl_error(webpki::Error::NameConstraintViolation),
197
            Other(..)
198
        ));
199
    }
200
}