Coverage Report

Created: 2025-07-14 07:05

/rust/registry/src/index.crates.io-6f17d22bba15001f/rustls-webpki-0.103.4/src/ring_algs.rs
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2015 Brian Smith.
2
//
3
// Permission to use, copy, modify, and/or distribute this software for any
4
// purpose with or without fee is hereby granted, provided that the above
5
// copyright notice and this permission notice appear in all copies.
6
//
7
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
10
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15
use pki_types::{AlgorithmIdentifier, InvalidSignature, SignatureVerificationAlgorithm, alg_id};
16
use ring::signature;
17
18
/// A `SignatureVerificationAlgorithm` implemented using *ring*.
19
#[derive(Debug)]
20
struct RingAlgorithm {
21
    public_key_alg_id: AlgorithmIdentifier,
22
    signature_alg_id: AlgorithmIdentifier,
23
    verification_alg: &'static dyn signature::VerificationAlgorithm,
24
}
25
26
impl SignatureVerificationAlgorithm for RingAlgorithm {
27
0
    fn public_key_alg_id(&self) -> AlgorithmIdentifier {
28
0
        self.public_key_alg_id
29
0
    }
Unexecuted instantiation: <webpki::ring_algs::RingAlgorithm as rustls_pki_types::SignatureVerificationAlgorithm>::public_key_alg_id
Unexecuted instantiation: <webpki::ring_algs::RingAlgorithm as rustls_pki_types::SignatureVerificationAlgorithm>::public_key_alg_id
30
31
0
    fn signature_alg_id(&self) -> AlgorithmIdentifier {
32
0
        self.signature_alg_id
33
0
    }
Unexecuted instantiation: <webpki::ring_algs::RingAlgorithm as rustls_pki_types::SignatureVerificationAlgorithm>::signature_alg_id
Unexecuted instantiation: <webpki::ring_algs::RingAlgorithm as rustls_pki_types::SignatureVerificationAlgorithm>::signature_alg_id
34
35
0
    fn verify_signature(
36
0
        &self,
37
0
        public_key: &[u8],
38
0
        message: &[u8],
39
0
        signature: &[u8],
40
0
    ) -> Result<(), InvalidSignature> {
41
0
        signature::UnparsedPublicKey::new(self.verification_alg, public_key)
42
0
            .verify(message, signature)
43
0
            .map_err(|_| InvalidSignature)
Unexecuted instantiation: <webpki::ring_algs::RingAlgorithm as rustls_pki_types::SignatureVerificationAlgorithm>::verify_signature::{closure#0}
Unexecuted instantiation: <webpki::ring_algs::RingAlgorithm as rustls_pki_types::SignatureVerificationAlgorithm>::verify_signature::{closure#0}
44
0
    }
Unexecuted instantiation: <webpki::ring_algs::RingAlgorithm as rustls_pki_types::SignatureVerificationAlgorithm>::verify_signature
Unexecuted instantiation: <webpki::ring_algs::RingAlgorithm as rustls_pki_types::SignatureVerificationAlgorithm>::verify_signature
45
}
46
47
/// ECDSA signatures using the P-256 curve and SHA-256.
48
pub static ECDSA_P256_SHA256: &dyn SignatureVerificationAlgorithm = &RingAlgorithm {
49
    public_key_alg_id: alg_id::ECDSA_P256,
50
    signature_alg_id: alg_id::ECDSA_SHA256,
51
    verification_alg: &signature::ECDSA_P256_SHA256_ASN1,
52
};
53
54
/// ECDSA signatures using the P-256 curve and SHA-384. Deprecated.
55
pub static ECDSA_P256_SHA384: &dyn SignatureVerificationAlgorithm = &RingAlgorithm {
56
    public_key_alg_id: alg_id::ECDSA_P256,
57
    signature_alg_id: alg_id::ECDSA_SHA384,
58
    verification_alg: &signature::ECDSA_P256_SHA384_ASN1,
59
};
60
61
/// ECDSA signatures using the P-384 curve and SHA-256. Deprecated.
62
pub static ECDSA_P384_SHA256: &dyn SignatureVerificationAlgorithm = &RingAlgorithm {
63
    public_key_alg_id: alg_id::ECDSA_P384,
64
    signature_alg_id: alg_id::ECDSA_SHA256,
65
    verification_alg: &signature::ECDSA_P384_SHA256_ASN1,
66
};
67
68
/// ECDSA signatures using the P-384 curve and SHA-384.
69
pub static ECDSA_P384_SHA384: &dyn SignatureVerificationAlgorithm = &RingAlgorithm {
70
    public_key_alg_id: alg_id::ECDSA_P384,
71
    signature_alg_id: alg_id::ECDSA_SHA384,
72
    verification_alg: &signature::ECDSA_P384_SHA384_ASN1,
73
};
74
75
/// RSA PKCS#1 1.5 signatures using SHA-256 for keys of 2048-8192 bits.
76
#[cfg(feature = "alloc")]
77
pub static RSA_PKCS1_2048_8192_SHA256: &dyn SignatureVerificationAlgorithm = &RingAlgorithm {
78
    public_key_alg_id: alg_id::RSA_ENCRYPTION,
79
    signature_alg_id: alg_id::RSA_PKCS1_SHA256,
80
    verification_alg: &signature::RSA_PKCS1_2048_8192_SHA256,
81
};
82
83
/// RSA PKCS#1 1.5 signatures using SHA-384 for keys of 2048-8192 bits.
84
#[cfg(feature = "alloc")]
85
pub static RSA_PKCS1_2048_8192_SHA384: &dyn SignatureVerificationAlgorithm = &RingAlgorithm {
86
    public_key_alg_id: alg_id::RSA_ENCRYPTION,
87
    signature_alg_id: alg_id::RSA_PKCS1_SHA384,
88
    verification_alg: &signature::RSA_PKCS1_2048_8192_SHA384,
89
};
90
91
/// RSA PKCS#1 1.5 signatures using SHA-512 for keys of 2048-8192 bits.
92
#[cfg(feature = "alloc")]
93
pub static RSA_PKCS1_2048_8192_SHA512: &dyn SignatureVerificationAlgorithm = &RingAlgorithm {
94
    public_key_alg_id: alg_id::RSA_ENCRYPTION,
95
    signature_alg_id: alg_id::RSA_PKCS1_SHA512,
96
    verification_alg: &signature::RSA_PKCS1_2048_8192_SHA512,
97
};
98
99
/// RSA PKCS#1 1.5 signatures using SHA-256 for keys of 2048-8192 bits,
100
/// with illegally absent AlgorithmIdentifier parameters.
101
///
102
/// RFC4055 says on sha256WithRSAEncryption and company:
103
///
104
/// >   When any of these four object identifiers appears within an
105
/// >   AlgorithmIdentifier, the parameters MUST be NULL.  Implementations
106
/// >   MUST accept the parameters being absent as well as present.
107
///
108
/// This algorithm covers the absent case, [`RSA_PKCS1_2048_8192_SHA256`] covers
109
/// the present case.
110
#[cfg(feature = "alloc")]
111
pub static RSA_PKCS1_2048_8192_SHA256_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
112
    &RingAlgorithm {
113
        public_key_alg_id: alg_id::RSA_ENCRYPTION,
114
        signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
115
            "data/alg-rsa-pkcs1-sha256-absent-params.der"
116
        )),
117
        verification_alg: &signature::RSA_PKCS1_2048_8192_SHA256,
118
    };
119
120
/// RSA PKCS#1 1.5 signatures using SHA-384 for keys of 2048-8192 bits,
121
/// with illegally absent AlgorithmIdentifier parameters.
122
///
123
/// RFC4055 says on sha256WithRSAEncryption and company:
124
///
125
/// >   When any of these four object identifiers appears within an
126
/// >   AlgorithmIdentifier, the parameters MUST be NULL.  Implementations
127
/// >   MUST accept the parameters being absent as well as present.
128
///
129
/// This algorithm covers the absent case, [`RSA_PKCS1_2048_8192_SHA384`] covers
130
/// the present case.
131
#[cfg(feature = "alloc")]
132
pub static RSA_PKCS1_2048_8192_SHA384_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
133
    &RingAlgorithm {
134
        public_key_alg_id: alg_id::RSA_ENCRYPTION,
135
        signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
136
            "data/alg-rsa-pkcs1-sha384-absent-params.der"
137
        )),
138
        verification_alg: &signature::RSA_PKCS1_2048_8192_SHA384,
139
    };
140
141
/// RSA PKCS#1 1.5 signatures using SHA-512 for keys of 2048-8192 bits,
142
/// with illegally absent AlgorithmIdentifier parameters.
143
///
144
/// RFC4055 says on sha256WithRSAEncryption and company:
145
///
146
/// >   When any of these four object identifiers appears within an
147
/// >   AlgorithmIdentifier, the parameters MUST be NULL.  Implementations
148
/// >   MUST accept the parameters being absent as well as present.
149
///
150
/// This algorithm covers the absent case, [`RSA_PKCS1_2048_8192_SHA512`] covers
151
/// the present case.
152
#[cfg(feature = "alloc")]
153
pub static RSA_PKCS1_2048_8192_SHA512_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm =
154
    &RingAlgorithm {
155
        public_key_alg_id: alg_id::RSA_ENCRYPTION,
156
        signature_alg_id: alg_id::AlgorithmIdentifier::from_slice(include_bytes!(
157
            "data/alg-rsa-pkcs1-sha512-absent-params.der"
158
        )),
159
        verification_alg: &signature::RSA_PKCS1_2048_8192_SHA512,
160
    };
161
162
/// RSA PKCS#1 1.5 signatures using SHA-384 for keys of 3072-8192 bits.
163
#[cfg(feature = "alloc")]
164
pub static RSA_PKCS1_3072_8192_SHA384: &dyn SignatureVerificationAlgorithm = &RingAlgorithm {
165
    public_key_alg_id: alg_id::RSA_ENCRYPTION,
166
    signature_alg_id: alg_id::RSA_PKCS1_SHA384,
167
    verification_alg: &signature::RSA_PKCS1_3072_8192_SHA384,
168
};
169
170
/// RSA PSS signatures using SHA-256 for keys of 2048-8192 bits and of
171
/// type rsaEncryption; see [RFC 4055 Section 1.2].
172
///
173
/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
174
#[cfg(feature = "alloc")]
175
pub static RSA_PSS_2048_8192_SHA256_LEGACY_KEY: &dyn SignatureVerificationAlgorithm =
176
    &RingAlgorithm {
177
        public_key_alg_id: alg_id::RSA_ENCRYPTION,
178
        signature_alg_id: alg_id::RSA_PSS_SHA256,
179
        verification_alg: &signature::RSA_PSS_2048_8192_SHA256,
180
    };
181
182
/// RSA PSS signatures using SHA-384 for keys of 2048-8192 bits and of
183
/// type rsaEncryption; see [RFC 4055 Section 1.2].
184
///
185
/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
186
#[cfg(feature = "alloc")]
187
pub static RSA_PSS_2048_8192_SHA384_LEGACY_KEY: &dyn SignatureVerificationAlgorithm =
188
    &RingAlgorithm {
189
        public_key_alg_id: alg_id::RSA_ENCRYPTION,
190
        signature_alg_id: alg_id::RSA_PSS_SHA384,
191
        verification_alg: &signature::RSA_PSS_2048_8192_SHA384,
192
    };
193
194
/// RSA PSS signatures using SHA-512 for keys of 2048-8192 bits and of
195
/// type rsaEncryption; see [RFC 4055 Section 1.2].
196
///
197
/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
198
#[cfg(feature = "alloc")]
199
pub static RSA_PSS_2048_8192_SHA512_LEGACY_KEY: &dyn SignatureVerificationAlgorithm =
200
    &RingAlgorithm {
201
        public_key_alg_id: alg_id::RSA_ENCRYPTION,
202
        signature_alg_id: alg_id::RSA_PSS_SHA512,
203
        verification_alg: &signature::RSA_PSS_2048_8192_SHA512,
204
    };
205
206
/// ED25519 signatures according to RFC 8410
207
pub static ED25519: &dyn SignatureVerificationAlgorithm = &RingAlgorithm {
208
    public_key_alg_id: alg_id::ED25519,
209
    signature_alg_id: alg_id::ED25519,
210
    verification_alg: &signature::ED25519,
211
};
212
213
#[cfg(test)]
214
#[path = "."]
215
mod tests {
216
    #[cfg(feature = "alloc")]
217
    use crate::error::UnsupportedSignatureAlgorithmForPublicKeyContext;
218
    use crate::error::{Error, UnsupportedSignatureAlgorithmContext};
219
220
    static SUPPORTED_ALGORITHMS_IN_TESTS: &[&dyn super::SignatureVerificationAlgorithm] = &[
221
        // Reasonable algorithms.
222
        super::ECDSA_P256_SHA256,
223
        super::ECDSA_P384_SHA384,
224
        super::ED25519,
225
        #[cfg(feature = "alloc")]
226
        super::RSA_PKCS1_2048_8192_SHA256,
227
        #[cfg(feature = "alloc")]
228
        super::RSA_PKCS1_2048_8192_SHA384,
229
        #[cfg(feature = "alloc")]
230
        super::RSA_PKCS1_2048_8192_SHA512,
231
        #[cfg(feature = "alloc")]
232
        super::RSA_PKCS1_3072_8192_SHA384,
233
        #[cfg(feature = "alloc")]
234
        super::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
235
        #[cfg(feature = "alloc")]
236
        super::RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
237
        #[cfg(feature = "alloc")]
238
        super::RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
239
        // Algorithms deprecated because they are nonsensical combinations.
240
        super::ECDSA_P256_SHA384, // Truncates digest.
241
        super::ECDSA_P384_SHA256, // Digest is unnecessarily short.
242
    ];
243
244
    const OK_IF_POINT_COMPRESSION_SUPPORTED: Result<(), Error> =
245
        Err(Error::InvalidSignatureForPublicKey);
246
247
    #[path = "alg_tests.rs"]
248
    mod alg_tests;
249
250
    fn maybe_rsa() -> Result<(), Error> {
251
        #[cfg(feature = "alloc")]
252
        {
253
            Ok(())
254
        }
255
        #[cfg(not(feature = "alloc"))]
256
        {
257
            Err(unsupported(&[]))
258
        }
259
    }
260
261
    fn unsupported_for_rsa(sig_alg_id: &[u8], _public_key_alg_id: &[u8]) -> Error {
262
        #[cfg(feature = "alloc")]
263
        {
264
            Error::UnsupportedSignatureAlgorithmForPublicKeyContext(
265
                UnsupportedSignatureAlgorithmForPublicKeyContext {
266
                    signature_algorithm_id: sig_alg_id.to_vec(),
267
                    public_key_algorithm_id: _public_key_alg_id.to_vec(),
268
                },
269
            )
270
        }
271
        #[cfg(not(feature = "alloc"))]
272
        {
273
            unsupported(sig_alg_id)
274
        }
275
    }
276
277
    fn invalid_rsa_signature() -> Error {
278
        #[cfg(feature = "alloc")]
279
        {
280
            Error::InvalidSignatureForPublicKey
281
        }
282
        #[cfg(not(feature = "alloc"))]
283
        {
284
            unsupported(&[])
285
        }
286
    }
287
288
    fn unsupported_for_ecdsa(sig_alg_id: &[u8], _public_key_alg_id: &[u8]) -> Error {
289
        unsupported(sig_alg_id)
290
    }
291
292
    fn unsupported(_sig_alg_id: &[u8]) -> Error {
293
        Error::UnsupportedSignatureAlgorithmContext(UnsupportedSignatureAlgorithmContext {
294
            #[cfg(feature = "alloc")]
295
            signature_algorithm_id: _sig_alg_id.to_vec(),
296
            #[cfg(feature = "alloc")]
297
            supported_algorithms: SUPPORTED_ALGORITHMS_IN_TESTS
298
                .iter()
299
                .map(|&alg| alg.signature_alg_id())
300
                .collect(),
301
        })
302
    }
303
}