webpki/
ring_algs.rs

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
15use pki_types::{AlgorithmIdentifier, InvalidSignature, SignatureVerificationAlgorithm, alg_id};
16use ring::signature;
17
18/// A `SignatureVerificationAlgorithm` implemented using *ring*.
19#[derive(Debug)]
20struct RingAlgorithm {
21    public_key_alg_id: AlgorithmIdentifier,
22    signature_alg_id: AlgorithmIdentifier,
23    verification_alg: &'static dyn signature::VerificationAlgorithm,
24}
25
26impl SignatureVerificationAlgorithm for RingAlgorithm {
27    fn public_key_alg_id(&self) -> AlgorithmIdentifier {
28        self.public_key_alg_id
29    }
30
31    fn signature_alg_id(&self) -> AlgorithmIdentifier {
32        self.signature_alg_id
33    }
34
35    fn verify_signature(
36        &self,
37        public_key: &[u8],
38        message: &[u8],
39        signature: &[u8],
40    ) -> Result<(), InvalidSignature> {
41        signature::UnparsedPublicKey::new(self.verification_alg, public_key)
42            .verify(message, signature)
43            .map_err(|_| InvalidSignature)
44    }
45}
46
47/// ECDSA signatures using the P-256 curve and SHA-256.
48pub 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.
55pub 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.
62pub 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.
69pub 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")]
77pub 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")]
85pub 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")]
93pub 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-384 for keys of 3072-8192 bits.
100#[cfg(feature = "alloc")]
101pub static RSA_PKCS1_3072_8192_SHA384: &dyn SignatureVerificationAlgorithm = &RingAlgorithm {
102    public_key_alg_id: alg_id::RSA_ENCRYPTION,
103    signature_alg_id: alg_id::RSA_PKCS1_SHA384,
104    verification_alg: &signature::RSA_PKCS1_3072_8192_SHA384,
105};
106
107/// RSA PSS signatures using SHA-256 for keys of 2048-8192 bits and of
108/// type rsaEncryption; see [RFC 4055 Section 1.2].
109///
110/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
111#[cfg(feature = "alloc")]
112pub static RSA_PSS_2048_8192_SHA256_LEGACY_KEY: &dyn SignatureVerificationAlgorithm =
113    &RingAlgorithm {
114        public_key_alg_id: alg_id::RSA_ENCRYPTION,
115        signature_alg_id: alg_id::RSA_PSS_SHA256,
116        verification_alg: &signature::RSA_PSS_2048_8192_SHA256,
117    };
118
119/// RSA PSS signatures using SHA-384 for keys of 2048-8192 bits and of
120/// type rsaEncryption; see [RFC 4055 Section 1.2].
121///
122/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
123#[cfg(feature = "alloc")]
124pub static RSA_PSS_2048_8192_SHA384_LEGACY_KEY: &dyn SignatureVerificationAlgorithm =
125    &RingAlgorithm {
126        public_key_alg_id: alg_id::RSA_ENCRYPTION,
127        signature_alg_id: alg_id::RSA_PSS_SHA384,
128        verification_alg: &signature::RSA_PSS_2048_8192_SHA384,
129    };
130
131/// RSA PSS signatures using SHA-512 for keys of 2048-8192 bits and of
132/// type rsaEncryption; see [RFC 4055 Section 1.2].
133///
134/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
135#[cfg(feature = "alloc")]
136pub static RSA_PSS_2048_8192_SHA512_LEGACY_KEY: &dyn SignatureVerificationAlgorithm =
137    &RingAlgorithm {
138        public_key_alg_id: alg_id::RSA_ENCRYPTION,
139        signature_alg_id: alg_id::RSA_PSS_SHA512,
140        verification_alg: &signature::RSA_PSS_2048_8192_SHA512,
141    };
142
143/// ED25519 signatures according to RFC 8410
144pub static ED25519: &dyn SignatureVerificationAlgorithm = &RingAlgorithm {
145    public_key_alg_id: alg_id::ED25519,
146    signature_alg_id: alg_id::ED25519,
147    verification_alg: &signature::ED25519,
148};
149
150#[cfg(test)]
151#[path = "."]
152mod tests {
153    use crate::Error;
154
155    static SUPPORTED_ALGORITHMS_IN_TESTS: &[&dyn super::SignatureVerificationAlgorithm] = &[
156        // Reasonable algorithms.
157        super::ECDSA_P256_SHA256,
158        super::ECDSA_P384_SHA384,
159        super::ED25519,
160        #[cfg(feature = "alloc")]
161        super::RSA_PKCS1_2048_8192_SHA256,
162        #[cfg(feature = "alloc")]
163        super::RSA_PKCS1_2048_8192_SHA384,
164        #[cfg(feature = "alloc")]
165        super::RSA_PKCS1_2048_8192_SHA512,
166        #[cfg(feature = "alloc")]
167        super::RSA_PKCS1_3072_8192_SHA384,
168        #[cfg(feature = "alloc")]
169        super::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
170        #[cfg(feature = "alloc")]
171        super::RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
172        #[cfg(feature = "alloc")]
173        super::RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
174        // Algorithms deprecated because they are nonsensical combinations.
175        super::ECDSA_P256_SHA384, // Truncates digest.
176        super::ECDSA_P384_SHA256, // Digest is unnecessarily short.
177    ];
178
179    const UNSUPPORTED_SIGNATURE_ALGORITHM_FOR_RSA_KEY: Error = if cfg!(feature = "alloc") {
180        Error::UnsupportedSignatureAlgorithmForPublicKey
181    } else {
182        Error::UnsupportedSignatureAlgorithm
183    };
184
185    const UNSUPPORTED_ECDSA_SHA512_SIGNATURE: Error = Error::UnsupportedSignatureAlgorithm;
186
187    const INVALID_SIGNATURE_FOR_RSA_KEY: Error = if cfg!(feature = "alloc") {
188        Error::InvalidSignatureForPublicKey
189    } else {
190        Error::UnsupportedSignatureAlgorithm
191    };
192
193    const OK_IF_RSA_AVAILABLE: Result<(), Error> = if cfg!(feature = "alloc") {
194        Ok(())
195    } else {
196        Err(Error::UnsupportedSignatureAlgorithm)
197    };
198
199    const OK_IF_POINT_COMPRESSION_SUPPORTED: Result<(), Error> =
200        Err(Error::InvalidSignatureForPublicKey);
201
202    #[path = "alg_tests.rs"]
203    mod alg_tests;
204}