Skip to main content

aws_lc_rs/
signature.rs

1// Copyright 2015-2017 Brian Smith.
2// SPDX-License-Identifier: ISC
3// Modifications copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4// SPDX-License-Identifier: Apache-2.0 OR ISC
5
6//! Public key signatures: signing and verification.
7//!
8//! Use the `verify` function to verify signatures, passing a reference to the
9//! algorithm that identifies the algorithm. See the documentation for `verify`
10//! for examples.
11//!
12//! For signature verification, this API treats each combination of parameters
13//! as a separate algorithm. For example, instead of having a single "RSA"
14//! algorithm with a verification function that takes a bunch of parameters,
15//! there are `RSA_PKCS1_2048_8192_SHA256`, `RSA_PKCS1_2048_8192_SHA384`, etc.,
16//! which encode sets of parameter choices into objects. This is designed to
17//! reduce the risks of algorithm agility and to provide consistency with ECDSA
18//! and `EdDSA`.
19//!
20//! Currently this module does not support digesting the message to be signed
21//! separately from the public key operation, as it is currently being
22//! optimized for Ed25519 and for the implementation of protocols that do not
23//! requiring signing large messages. An interface for efficiently supporting
24//! larger messages may be added later.
25//!
26//!
27//! # Algorithm Details
28//!
29//! ## `ECDSA_*_ASN1` Details: ASN.1-encoded ECDSA Signatures
30//!
31//! The signature is a ASN.1 DER-encoded `Ecdsa-Sig-Value` as described in
32//! [RFC 3279 Section 2.2.3]. This is the form of ECDSA signature used in
33//! X.509-related structures and in TLS's `ServerKeyExchange` messages.
34//!
35//! The public key is encoding in uncompressed form using the
36//! Octet-String-to-Elliptic-Curve-Point algorithm in
37//! [SEC 1: Elliptic Curve Cryptography, Version 2.0].
38//!
39//! During verification, the public key is validated using the ECC Partial
40//! Public-Key Validation Routine from Section 5.6.2.3.3 of
41//! [NIST Special Publication 800-56A, revision 2] and Appendix A.3 of the
42//! NSA's [Suite B implementer's guide to FIPS 186-3]. Note that, as explained
43//! in the NSA guide, ECC Partial Public-Key Validation is equivalent to ECC
44//! Full Public-Key Validation for prime-order curves like this one.
45//!
46//! ## `ECDSA_*_FIXED` Details: Fixed-length (PKCS#11-style) ECDSA Signatures
47//!
48//! The signature is *r*||*s*, where || denotes concatenation, and where both
49//! *r* and *s* are both big-endian-encoded values that are left-padded to the
50//! maximum length. A P-256 signature will be 64 bytes long (two 32-byte
51//! components) and a P-384 signature will be 96 bytes long (two 48-byte
52//! components). This is the form of ECDSA signature used PKCS#11 and DNSSEC.
53//!
54//! The public key is encoding in uncompressed form using the
55//! Octet-String-to-Elliptic-Curve-Point algorithm in
56//! [SEC 1: Elliptic Curve Cryptography, Version 2.0].
57//!
58//! During verification, the public key is validated using the ECC Partial
59//! Public-Key Validation Routine from Section 5.6.2.3.3 of
60//! [NIST Special Publication 800-56A, revision 2] and Appendix A.3 of the
61//! NSA's [Suite B implementer's guide to FIPS 186-3]. Note that, as explained
62//! in the NSA guide, ECC Partial Public-Key Validation is equivalent to ECC
63//! Full Public-Key Validation for prime-order curves like this one.
64//!
65//! ## `RSA_PKCS1_*` Details: RSA PKCS#1 1.5 Signatures
66//!
67//! The signature is an RSASSA-PKCS1-v1_5 signature as described in
68//! [RFC 3447 Section 8.2].
69//!
70//! The public key is encoded as an ASN.1 `RSAPublicKey` as described in
71//! [RFC 3447 Appendix-A.1.1]. The public key modulus length, rounded *up* to
72//! the nearest (larger) multiple of 8 bits, must be in the range given in the
73//! name of the algorithm. The public exponent must be an odd integer of 2-33
74//! bits, inclusive.
75//!
76//!
77//! ## `RSA_PSS_*` Details: RSA PSS Signatures
78//!
79//! The signature is an RSASSA-PSS signature as described in
80//! [RFC 3447 Section 8.1].
81//!
82//! The public key is encoded as an ASN.1 `RSAPublicKey` as described in
83//! [RFC 3447 Appendix-A.1.1]. The public key modulus length, rounded *up* to
84//! the nearest (larger) multiple of 8 bits, must be in the range given in the
85//! name of the algorithm. The public exponent must be an odd integer of 2-33
86//! bits, inclusive.
87//!
88//! During verification, signatures will only be accepted if the MGF1 digest
89//! algorithm is the same as the message digest algorithm and if the salt
90//! length is the same length as the message digest. This matches the
91//! requirements in TLS 1.3 and other recent specifications.
92//!
93//! During signing, the message digest algorithm will be used as the MGF1
94//! digest algorithm. The salt will be the same length as the message digest.
95//! This matches the requirements in TLS 1.3 and other recent specifications.
96//! Additionally, the entire salt is randomly generated separately for each
97//! signature using the secure random number generator passed to `sign()`.
98//!
99//!
100//! [SEC 1: Elliptic Curve Cryptography, Version 2.0]:
101//!     http://www.secg.org/sec1-v2.pdf
102//! [NIST Special Publication 800-56A, revision 2]:
103//!     http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf
104//! [Suite B implementer's guide to FIPS 186-3]:
105//!     https://github.com/briansmith/ring/blob/main/doc/ecdsa.pdf
106//! [RFC 3279 Section 2.2.3]:
107//!     https://tools.ietf.org/html/rfc3279#section-2.2.3
108//! [RFC 3447 Section 8.2]:
109//!     https://tools.ietf.org/html/rfc3447#section-7.2
110//! [RFC 3447 Section 8.1]:
111//!     https://tools.ietf.org/html/rfc3447#section-8.1
112//! [RFC 3447 Appendix-A.1.1]:
113//!     https://tools.ietf.org/html/rfc3447#appendix-A.1.1
114//!
115//!
116//! # Examples
117//!
118//! ## Signing and verifying with Ed25519
119//!
120//! ```
121//! use aws_lc_rs::{
122//!     rand,
123//!     signature::{self, KeyPair},
124//! };
125//!
126//! fn main() -> Result<(), aws_lc_rs::error::Unspecified> {
127//!     // Generate a new key pair for Ed25519.
128//!     let key_pair = signature::Ed25519KeyPair::generate()?;
129//!
130//!     // Sign the message "hello, world".
131//!     const MESSAGE: &[u8] = b"hello, world";
132//!     let sig = key_pair.sign(MESSAGE);
133//!
134//!     // Normally an application would extract the bytes of the signature and
135//!     // send them in a protocol message to the peer(s). Here we just get the
136//!     // public key key directly from the key pair.
137//!     let peer_public_key_bytes = key_pair.public_key().as_ref();
138//!
139//!     // Verify the signature of the message using the public key. Normally the
140//!     // verifier of the message would parse the inputs to this code out of the
141//!     // protocol message(s) sent by the signer.
142//!     let peer_public_key =
143//!         signature::UnparsedPublicKey::new(&signature::ED25519, peer_public_key_bytes);
144//!     peer_public_key.verify(MESSAGE, sig.as_ref())?;
145//!
146//!     Ok(())
147//! }
148//! ```
149//!
150//! ## Signing and verifying with RSA (PKCS#1 1.5 padding)
151//!
152//! By default OpenSSL writes RSA public keys in `SubjectPublicKeyInfo` format,
153//! not `RSAPublicKey` format, and Base64-encodes them (“PEM” format).
154//!
155//! To convert the PEM `SubjectPublicKeyInfo` format (“BEGIN PUBLIC KEY”) to the
156//! binary `RSAPublicKey` format needed by `verify()`, use:
157//!
158//! ```sh
159//! openssl rsa -pubin \
160//!             -in public_key.pem \
161//!             -inform PEM \
162//!             -RSAPublicKey_out \
163//!             -outform DER \
164//!             -out public_key.der
165//! ```
166//!
167//! To extract the RSAPublicKey-formatted public key from an ASN.1 (binary)
168//! DER-encoded `RSAPrivateKey` format private key file, use:
169//!
170//! ```sh
171//! openssl rsa -in private_key.der \
172//!             -inform DER \
173//!             -RSAPublicKey_out \
174//!             -outform DER \
175//!             -out public_key.der
176//! ```
177//!
178//! ```
179//! use aws_lc_rs::{rand, signature};
180//!
181//! fn sign_and_verify_rsa(
182//!     private_key_path: &std::path::Path,
183//!     public_key_path: &std::path::Path,
184//! ) -> Result<(), MyError> {
185//!     // Create an `RsaKeyPair` from the DER-encoded bytes. This example uses
186//!     // a 2048-bit key, but larger keys are also supported.
187//!     let private_key_der = read_file(private_key_path)?;
188//!     let key_pair = signature::RsaKeyPair::from_der(&private_key_der)
189//!         .map_err(|_| MyError::BadPrivateKey)?;
190//!
191//!     // Sign the message "hello, world", using PKCS#1 v1.5 padding and the
192//!     // SHA256 digest algorithm.
193//!     const MESSAGE: &'static [u8] = b"hello, world";
194//!     let rng = rand::SystemRandom::new();
195//!     let mut signature = vec![0; key_pair.public_modulus_len()];
196//!     key_pair
197//!         .sign(&signature::RSA_PKCS1_SHA256, &rng, MESSAGE, &mut signature)
198//!         .map_err(|_| MyError::OOM)?;
199//!
200//!     // Verify the signature.
201//!     let public_key = signature::UnparsedPublicKey::new(
202//!         &signature::RSA_PKCS1_2048_8192_SHA256,
203//!         read_file(public_key_path)?,
204//!     );
205//!     public_key
206//!         .verify(MESSAGE, &signature)
207//!         .map_err(|_| MyError::BadSignature)
208//! }
209//!
210//! #[derive(Debug)]
211//! enum MyError {
212//!     IO(std::io::Error),
213//!     BadPrivateKey,
214//!     OOM,
215//!     BadSignature,
216//! }
217//!
218//! fn read_file(path: &std::path::Path) -> Result<Vec<u8>, MyError> {
219//!     use std::io::Read;
220//!
221//!     let mut file = std::fs::File::open(path).map_err(|e| MyError::IO(e))?;
222//!     let mut contents: Vec<u8> = Vec::new();
223//!     file.read_to_end(&mut contents)
224//!         .map_err(|e| MyError::IO(e))?;
225//!     Ok(contents)
226//! }
227//!
228//! fn main() {
229//! #   if !cfg!(target_arch = "wasm32") {
230//!     let private_key_path =
231//!         std::path::Path::new("tests/data/signature_rsa_example_private_key.der");
232//!     let public_key_path =
233//!         std::path::Path::new("tests/data/signature_rsa_example_public_key.der");
234//!     sign_and_verify_rsa(&private_key_path, &public_key_path).unwrap()
235//! #   }
236//! }
237//! ```
238use crate::aws_lc::EVP_PKEY;
239pub use crate::rsa::signature::{RsaEncoding, RsaSignatureEncoding};
240pub use crate::rsa::{
241    KeyPair as RsaKeyPair, PublicKey as RsaSubjectPublicKey,
242    PublicKeyComponents as RsaPublicKeyComponents, RsaParameters,
243};
244use core::fmt::{Debug, Formatter};
245use std::any::{Any, TypeId};
246#[cfg(feature = "ring-sig-verify")]
247use untrusted::Input;
248
249use crate::rsa::signature::RsaSigningAlgorithmId;
250use crate::rsa::RsaVerificationAlgorithmId;
251
252pub use crate::ec::key_pair::{EcdsaKeyPair, PrivateKey as EcdsaPrivateKey};
253use crate::ec::signature::EcdsaSignatureFormat;
254pub use crate::ec::signature::{
255    EcdsaSigningAlgorithm, EcdsaVerificationAlgorithm, PublicKey as EcdsaPublicKey,
256};
257pub use crate::ed25519::{
258    Ed25519KeyPair, EdDSAParameters, PublicKey as Ed25519PublicKey, Seed as Ed25519Seed,
259    ED25519_PUBLIC_KEY_LEN,
260};
261
262use crate::digest::Digest;
263use crate::ec::encoding::parse_ec_public_key;
264use crate::ed25519::parse_ed25519_public_key;
265use crate::encoding::{AsDer, PublicKeyX509Der};
266use crate::error::{KeyRejected, Unspecified};
267#[cfg(all(feature = "unstable", not(feature = "fips")))]
268use crate::pqdsa::{parse_pqdsa_public_key, signature::PqdsaVerificationAlgorithm};
269use crate::ptr::LcPtr;
270use crate::rsa::key::parse_rsa_public_key;
271use crate::{digest, ec, error, hex, rsa, sealed};
272
273/// The longest signature is for ML-DSA-87
274pub(crate) const MAX_LEN: usize = 4627;
275
276/// A public key signature returned from a signing operation.
277#[derive(Clone, Copy)]
278pub struct Signature {
279    value: [u8; MAX_LEN],
280    len: usize,
281}
282
283impl Signature {
284    // Panics if `value` is too long.
285    pub(crate) fn new<F>(fill: F) -> Self
286    where
287        F: FnOnce(&mut [u8; MAX_LEN]) -> usize,
288    {
289        let mut r = Self {
290            value: [0; MAX_LEN],
291            len: 0,
292        };
293        r.len = fill(&mut r.value);
294        r
295    }
296}
297
298impl AsRef<[u8]> for Signature {
299    #[inline]
300    fn as_ref(&self) -> &[u8] {
301        &self.value[..self.len]
302    }
303}
304
305/// Key pairs for signing messages (private key and public key).
306pub trait KeyPair: Debug + Send + Sized + Sync {
307    /// The type of the public key.
308    type PublicKey: AsRef<[u8]> + Debug + Clone + Send + Sized + Sync;
309
310    /// The public key for the key pair.
311    fn public_key(&self) -> &Self::PublicKey;
312}
313
314// Private trait
315pub(crate) trait ParsedVerificationAlgorithm: Debug + Sync {
316    fn parsed_verify_sig(
317        &self,
318        public_key: &ParsedPublicKey,
319        msg: &[u8],
320        signature: &[u8],
321    ) -> Result<(), error::Unspecified>;
322
323    fn parsed_verify_digest_sig(
324        &self,
325        public_key: &ParsedPublicKey,
326        digest: &Digest,
327        signature: &[u8],
328    ) -> Result<(), error::Unspecified>;
329}
330
331/// A signature verification algorithm.
332pub trait VerificationAlgorithm: Debug + Sync + Any + sealed::Sealed {
333    /// Verify the signature `signature` of message `msg` with the public key
334    /// `public_key`.
335    ///
336    // # FIPS
337    // The following conditions must be met:
338    // * RSA Key Sizes: 1024, 2048, 3072, 4096
339    // * NIST Elliptic Curves: P256, P384, P521
340    // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
341    //
342    /// # Errors
343    /// `error::Unspecified` if inputs not verified.
344    #[cfg(feature = "ring-sig-verify")]
345    #[deprecated(note = "please use `VerificationAlgorithm::verify_sig` instead")]
346    fn verify(
347        &self,
348        public_key: Input<'_>,
349        msg: Input<'_>,
350        signature: Input<'_>,
351    ) -> Result<(), error::Unspecified>;
352
353    /// Verify the signature `signature` of message `msg` with the public key
354    /// `public_key`.
355    ///
356    // # FIPS
357    // The following conditions must be met:
358    // * RSA Key Sizes: 1024, 2048, 3072, 4096
359    // * NIST Elliptic Curves: P256, P384, P521
360    // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
361    //
362    /// # Errors
363    /// `error::Unspecified` if inputs not verified.
364    fn verify_sig(
365        &self,
366        public_key: &[u8],
367        msg: &[u8],
368        signature: &[u8],
369    ) -> Result<(), error::Unspecified>;
370
371    /// Verify the signature `signature` of `digest` with the `public_key`.
372    ///
373    // # FIPS
374    // Not approved.
375    //
376    /// # Errors
377    /// `error::Unspecified` if inputs not verified.
378    fn verify_digest_sig(
379        &self,
380        public_key: &[u8],
381        digest: &Digest,
382        signature: &[u8],
383    ) -> Result<(), error::Unspecified>;
384}
385
386/// An unparsed, possibly malformed, public key for signature verification.
387#[derive(Clone)]
388pub struct UnparsedPublicKey<B: AsRef<[u8]>> {
389    algorithm: &'static dyn VerificationAlgorithm,
390    bytes: B,
391}
392/// A parsed public key for signature verification.
393///
394/// A `ParsedPublicKey` can be created in two ways:
395/// - Directly from public key bytes using [`ParsedPublicKey::new`]
396/// - By parsing an `UnparsedPublicKey` using [`UnparsedPublicKey::parse`]
397///
398/// This pre-validates the public key format and stores the parsed key material,
399/// allowing for more efficient signature verification operations compared to
400/// parsing the key on each verification.
401///
402/// See the [`crate::signature`] module-level documentation for examples.
403#[derive(Clone)]
404pub struct ParsedPublicKey {
405    algorithm: &'static dyn VerificationAlgorithm,
406    parsed_algorithm: &'static dyn ParsedVerificationAlgorithm,
407    key: LcPtr<EVP_PKEY>,
408    bytes: Box<[u8]>,
409}
410
411// See EVP_PKEY documentation here:
412// https://github.com/aws/aws-lc/blob/125af14c57451565b875fbf1282a38a6ecf83782/include/openssl/evp.h#L83-L89
413// An |EVP_PKEY| object represents a public or private key. A given object may
414// be used concurrently on multiple threads by non-mutating functions, provided
415// no other thread is concurrently calling a mutating function. Unless otherwise
416// documented, functions which take a |const| pointer are non-mutating and
417// functions which take a non-|const| pointer are mutating.
418unsafe impl Send for ParsedPublicKey {}
419unsafe impl Sync for ParsedPublicKey {}
420
421impl ParsedPublicKey {
422    /// Creates a new `ParsedPublicKey` directly from public key bytes.
423    ///
424    /// This method validates the public key format and creates a `ParsedPublicKey`
425    /// that can be used for efficient signature verification operations.
426    ///
427    /// # Errors
428    /// `KeyRejected` if the public key bytes are malformed or incompatible
429    /// with the specified algorithm.
430    ///
431    /// # Examples
432    ///
433    /// ```
434    /// use aws_lc_rs::signature::{self, ParsedPublicKey};
435    ///
436    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
437    ///     let parsed_key = ParsedPublicKey::new(&signature::ED25519, include_bytes!("../tests/data/ed25519_test_public_key.bin"))?;
438    ///     let signature = [
439    ///         0xED, 0xDB, 0x67, 0xE9, 0xF7, 0x8C, 0x9A, 0x0, 0xFD, 0xEE, 0x2D, 0x22, 0x21, 0xA3, 0x9A,
440    ///         0x8A, 0x79, 0xF2, 0x53, 0x88, 0x78, 0xF0, 0xA0, 0x1, 0x80, 0xA, 0x49, 0xA4, 0x17, 0x88,
441    ///         0xAB, 0x44, 0x4B, 0xD2, 0x58, 0xB0, 0x3B, 0x51, 0x8A, 0x1B, 0x61, 0x24, 0x52, 0x78, 0x48,
442    ///         0x58, 0x40, 0x5, 0xB5, 0x45, 0x22, 0xB6, 0x40, 0xBD, 0x14, 0x47, 0xB1, 0xF0, 0xDC, 0x13,
443    ///         0xB3, 0xE9, 0xD0, 0x6,
444    ///     ];
445    ///     assert!(parsed_key.verify_sig(b"hello world!", &signature).is_ok());
446    ///     assert!(parsed_key.verify_sig(b"hello world.", &signature).is_err());
447    /// # Ok(())
448    /// # }
449    /// ```
450    pub fn new<B: AsRef<[u8]>>(
451        algorithm: &'static dyn VerificationAlgorithm,
452        bytes: B,
453    ) -> Result<Self, KeyRejected> {
454        parse_public_key(bytes.as_ref(), algorithm)
455    }
456
457    /// Returns the algorithm used by this public key.
458    #[must_use]
459    pub fn algorithm(&self) -> &'static dyn VerificationAlgorithm {
460        self.algorithm
461    }
462
463    pub(crate) fn key(&self) -> &LcPtr<EVP_PKEY> {
464        &self.key
465    }
466
467    /// Constructs a `ParsedPublicKey` directly from an already-built RSA
468    /// `EVP_PKEY`, skipping the DER-encode / DER-decode round-trip that
469    /// [`parse_public_key`] would otherwise perform. The SubjectPublicKeyInfo
470    /// DER is still marshalled once so that [`AsRef<[u8]>`] on the resulting
471    /// `ParsedPublicKey` continues to return a canonical encoding.
472    ///
473    /// `params` is used as both the public [`VerificationAlgorithm`] and the
474    /// internal `ParsedVerificationAlgorithm`, matching what
475    /// [`parse_public_key`] would assign for RSA inputs.
476    pub(crate) fn from_rsa_evp_pkey(
477        params: &'static RsaParameters,
478        key: LcPtr<EVP_PKEY>,
479    ) -> Result<Self, Unspecified> {
480        let bytes = key
481            .as_const()
482            .marshal_rfc5280_public_key()?
483            .into_boxed_slice();
484        Ok(ParsedPublicKey {
485            algorithm: params,
486            parsed_algorithm: params,
487            key,
488            bytes,
489        })
490    }
491
492    /// Uses the public key to verify that `signature` is a valid signature of
493    /// `message`.
494    ///
495    /// This method is more efficient than [`UnparsedPublicKey::verify`] when
496    /// performing multiple signature verifications with the same public key,
497    /// as the key parsing overhead is avoided.
498    ///
499    /// See the [`crate::signature`] module-level documentation for examples.
500    ///
501    // # FIPS
502    // The following conditions must be met:
503    // * RSA Key Sizes: 1024, 2048, 3072, 4096
504    // * NIST Elliptic Curves: P256, P384, P521
505    // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
506    //
507    /// # Errors
508    /// `error::Unspecified` if the signature is invalid or verification fails.
509    #[inline]
510    pub fn verify_sig(&self, message: &[u8], signature: &[u8]) -> Result<(), error::Unspecified> {
511        self.parsed_algorithm
512            .parsed_verify_sig(self, message, signature)
513    }
514
515    /// Uses the public key to verify that `signature` is a valid signature of
516    /// `digest`.
517    ///
518    /// This method is more efficient than [`UnparsedPublicKey::verify_digest`] when
519    /// performing multiple signature verifications with the same public key,
520    /// as the key parsing overhead is avoided.
521    ///
522    /// See the [`crate::signature`] module-level documentation for examples.
523    ///
524    // # FIPS
525    // Not allowed
526    //
527    /// # Errors
528    /// `error::Unspecified` if the signature is invalid or verification fails.
529    #[inline]
530    pub fn verify_digest_sig(
531        &self,
532        digest: &Digest,
533        signature: &[u8],
534    ) -> Result<(), error::Unspecified> {
535        self.parsed_algorithm
536            .parsed_verify_digest_sig(self, digest, signature)
537    }
538}
539
540impl AsDer<PublicKeyX509Der<'static>> for ParsedPublicKey {
541    fn as_der(&self) -> Result<PublicKeyX509Der<'static>, Unspecified> {
542        Ok(PublicKeyX509Der::new(
543            self.key.as_const().marshal_rfc5280_public_key()?,
544        ))
545    }
546}
547
548/// Provides the original bytes from which this key was parsed
549impl AsRef<[u8]> for ParsedPublicKey {
550    fn as_ref(&self) -> &[u8] {
551        &self.bytes
552    }
553}
554
555impl Debug for ParsedPublicKey {
556    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
557        f.write_str(&format!(
558            "ParsedPublicKey {{ algorithm: {:?}, bytes: \"{}\" }}",
559            self.algorithm,
560            hex::encode(self.bytes.as_ref())
561        ))
562    }
563}
564
565impl<B: AsRef<[u8]>> AsRef<[u8]> for UnparsedPublicKey<B> {
566    #[inline]
567    fn as_ref(&self) -> &[u8] {
568        self.bytes.as_ref()
569    }
570}
571
572impl<B: Copy + AsRef<[u8]>> Copy for UnparsedPublicKey<B> {}
573
574impl<B: AsRef<[u8]>> Debug for UnparsedPublicKey<B> {
575    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
576        f.write_str(&format!(
577            "UnparsedPublicKey {{ algorithm: {:?}, bytes: \"{}\" }}",
578            self.algorithm,
579            hex::encode(self.bytes.as_ref())
580        ))
581    }
582}
583
584impl<B: AsRef<[u8]>> UnparsedPublicKey<B> {
585    /// Construct a new `UnparsedPublicKey`.
586    ///
587    /// No validation of `bytes` is done until `verify()` is called.
588    #[inline]
589    pub fn new(algorithm: &'static dyn VerificationAlgorithm, bytes: B) -> Self {
590        Self { algorithm, bytes }
591    }
592
593    /// Parses the public key and verifies `signature` is a valid signature of
594    /// `message` using it.
595    ///
596    /// See the [`crate::signature`] module-level documentation for examples.
597    ///
598    // # FIPS
599    // The following conditions must be met:
600    // * RSA Key Sizes: 1024, 2048, 3072, 4096
601    // * NIST Elliptic Curves: P256, P384, P521
602    // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
603    //
604    /// # Errors
605    /// `error::Unspecified` if inputs not verified.
606    #[inline]
607    pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), error::Unspecified> {
608        self.algorithm
609            .verify_sig(self.bytes.as_ref(), message, signature)
610    }
611
612    /// Parses the public key and verifies `signature` is a valid signature of
613    /// `digest` using it.
614    ///
615    /// See the [`crate::signature`] module-level documentation for examples.
616    ///
617    // # FIPS
618    // Not allowed
619    //
620    /// # Errors
621    /// `error::Unspecified` if inputs not verified.
622    #[inline]
623    pub fn verify_digest(
624        &self,
625        digest: &Digest,
626        signature: &[u8],
627    ) -> Result<(), error::Unspecified> {
628        self.algorithm
629            .verify_digest_sig(self.bytes.as_ref(), digest, signature)
630    }
631
632    /// Parses the public key bytes and returns a `ParsedPublicKey`.
633    ///
634    /// This method validates the public key format and creates a `ParsedPublicKey`
635    /// that can be used for more efficient signature verification operations.
636    /// The parsing overhead is incurred once, making subsequent verifications
637    /// faster compared to using `UnparsedPublicKey::verify` directly.
638    ///
639    /// This is equivalent to calling [`ParsedPublicKey::new`] with the same
640    /// algorithm and bytes.
641    ///
642    /// # Errors
643    /// `KeyRejected` if the public key bytes are malformed or incompatible
644    /// with the specified algorithm.
645    pub fn parse(&self) -> Result<ParsedPublicKey, KeyRejected> {
646        parse_public_key(self.bytes.as_ref(), self.algorithm)
647    }
648}
649
650pub(crate) fn parse_public_key(
651    bytes: &[u8],
652    algorithm: &'static dyn VerificationAlgorithm,
653) -> Result<ParsedPublicKey, KeyRejected> {
654    let parsed_algorithm: &'static dyn ParsedVerificationAlgorithm;
655
656    let key = if algorithm.type_id() == TypeId::of::<EcdsaVerificationAlgorithm>() {
657        #[allow(clippy::cast_ptr_alignment)]
658        let ec_alg = unsafe {
659            &*(algorithm as *const dyn VerificationAlgorithm).cast::<EcdsaVerificationAlgorithm>()
660        };
661        parsed_algorithm = ec_alg;
662        parse_ec_public_key(bytes, ec_alg.id.nid())?
663    } else if algorithm.type_id() == TypeId::of::<EdDSAParameters>() {
664        #[allow(clippy::cast_ptr_alignment)]
665        let ed_alg =
666            unsafe { &*(algorithm as *const dyn VerificationAlgorithm).cast::<EdDSAParameters>() };
667        parsed_algorithm = ed_alg;
668        parse_ed25519_public_key(bytes)?
669    } else if algorithm.type_id() == TypeId::of::<RsaParameters>() {
670        #[allow(clippy::cast_ptr_alignment)]
671        let rsa_alg =
672            unsafe { &*(algorithm as *const dyn VerificationAlgorithm).cast::<RsaParameters>() };
673        parsed_algorithm = rsa_alg;
674        parse_rsa_public_key(bytes)?
675    } else {
676        #[cfg(all(feature = "unstable", not(feature = "fips")))]
677        if algorithm.type_id() == TypeId::of::<PqdsaVerificationAlgorithm>() {
678            #[allow(clippy::cast_ptr_alignment)]
679            let pqdsa_alg = unsafe {
680                &*(algorithm as *const dyn VerificationAlgorithm)
681                    .cast::<PqdsaVerificationAlgorithm>()
682            };
683            parsed_algorithm = pqdsa_alg;
684            parse_pqdsa_public_key(bytes, pqdsa_alg.id)?
685        } else {
686            unreachable!()
687        }
688        #[cfg(any(not(feature = "unstable"), feature = "fips"))]
689        unreachable!()
690    };
691
692    let bytes = bytes.to_vec().into_boxed_slice();
693    Ok(ParsedPublicKey {
694        algorithm,
695        parsed_algorithm,
696        key,
697        bytes,
698    })
699}
700
701/// Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-1.
702pub const RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
703    &digest::SHA1_FOR_LEGACY_USE_ONLY,
704    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
705    1024..=8192,
706    &RsaVerificationAlgorithmId::RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY,
707);
708
709/// Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-256.
710pub const RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
711    &digest::SHA256,
712    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
713    1024..=8192,
714    &RsaVerificationAlgorithmId::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY,
715);
716
717/// Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-512.
718pub const RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
719    &digest::SHA512,
720    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
721    1024..=8192,
722    &RsaVerificationAlgorithmId::RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY,
723);
724
725/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-1.
726pub const RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
727    &digest::SHA1_FOR_LEGACY_USE_ONLY,
728    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
729    2048..=8192,
730    &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY,
731);
732
733/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-256.
734pub const RSA_PKCS1_2048_8192_SHA256: RsaParameters = RsaParameters::new(
735    &digest::SHA256,
736    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
737    2048..=8192,
738    &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA256,
739);
740
741/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-384.
742pub const RSA_PKCS1_2048_8192_SHA384: RsaParameters = RsaParameters::new(
743    &digest::SHA384,
744    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
745    2048..=8192,
746    &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA384,
747);
748
749/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-512.
750pub const RSA_PKCS1_2048_8192_SHA512: RsaParameters = RsaParameters::new(
751    &digest::SHA512,
752    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
753    2048..=8192,
754    &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA512,
755);
756
757/// Verification of signatures using RSA keys of 3072-8192 bits, PKCS#1.5 padding, and SHA-384.
758pub const RSA_PKCS1_3072_8192_SHA384: RsaParameters = RsaParameters::new(
759    &digest::SHA384,
760    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
761    3072..=8192,
762    &RsaVerificationAlgorithmId::RSA_PKCS1_3072_8192_SHA384,
763);
764
765/// Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-256.
766pub const RSA_PSS_2048_8192_SHA256: RsaParameters = RsaParameters::new(
767    &digest::SHA256,
768    &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
769    2048..=8192,
770    &RsaVerificationAlgorithmId::RSA_PSS_2048_8192_SHA256,
771);
772
773/// Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-384.
774pub const RSA_PSS_2048_8192_SHA384: RsaParameters = RsaParameters::new(
775    &digest::SHA384,
776    &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
777    2048..=8192,
778    &RsaVerificationAlgorithmId::RSA_PSS_2048_8192_SHA384,
779);
780
781/// Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-512.
782pub const RSA_PSS_2048_8192_SHA512: RsaParameters = RsaParameters::new(
783    &digest::SHA512,
784    &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
785    2048..=8192,
786    &RsaVerificationAlgorithmId::RSA_PSS_2048_8192_SHA512,
787);
788
789/// RSA PSS padding using SHA-256 for RSA signatures.
790pub const RSA_PSS_SHA256: RsaSignatureEncoding = RsaSignatureEncoding::new(
791    &digest::SHA256,
792    &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
793    &RsaSigningAlgorithmId::RSA_PSS_SHA256,
794);
795
796/// RSA PSS padding using SHA-384 for RSA signatures.
797pub const RSA_PSS_SHA384: RsaSignatureEncoding = RsaSignatureEncoding::new(
798    &digest::SHA384,
799    &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
800    &RsaSigningAlgorithmId::RSA_PSS_SHA384,
801);
802
803/// RSA PSS padding using SHA-512 for RSA signatures.
804pub const RSA_PSS_SHA512: RsaSignatureEncoding = RsaSignatureEncoding::new(
805    &digest::SHA512,
806    &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
807    &RsaSigningAlgorithmId::RSA_PSS_SHA512,
808);
809
810/// PKCS#1 1.5 padding using SHA-256 for RSA signatures.
811pub const RSA_PKCS1_SHA256: RsaSignatureEncoding = RsaSignatureEncoding::new(
812    &digest::SHA256,
813    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
814    &RsaSigningAlgorithmId::RSA_PKCS1_SHA256,
815);
816
817/// PKCS#1 1.5 padding using SHA-384 for RSA signatures.
818pub const RSA_PKCS1_SHA384: RsaSignatureEncoding = RsaSignatureEncoding::new(
819    &digest::SHA384,
820    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
821    &RsaSigningAlgorithmId::RSA_PKCS1_SHA384,
822);
823
824/// PKCS#1 1.5 padding using SHA-512 for RSA signatures.
825pub const RSA_PKCS1_SHA512: RsaSignatureEncoding = RsaSignatureEncoding::new(
826    &digest::SHA512,
827    &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
828    &RsaSigningAlgorithmId::RSA_PKCS1_SHA512,
829);
830
831/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-256 curve and SHA-256.
832pub const ECDSA_P256_SHA256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
833    id: &ec::signature::AlgorithmID::ECDSA_P256,
834    digest: &digest::SHA256,
835    sig_format: EcdsaSignatureFormat::Fixed,
836};
837
838/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA-384.
839pub const ECDSA_P384_SHA384_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
840    id: &ec::signature::AlgorithmID::ECDSA_P384,
841    digest: &digest::SHA384,
842    sig_format: EcdsaSignatureFormat::Fixed,
843};
844
845/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA3-384.
846pub const ECDSA_P384_SHA3_384_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
847    id: &ec::signature::AlgorithmID::ECDSA_P384,
848    digest: &digest::SHA3_384,
849    sig_format: EcdsaSignatureFormat::Fixed,
850};
851
852/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-1.
853pub const ECDSA_P521_SHA1_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
854    id: &ec::signature::AlgorithmID::ECDSA_P521,
855    digest: &digest::SHA1_FOR_LEGACY_USE_ONLY,
856    sig_format: EcdsaSignatureFormat::Fixed,
857};
858
859/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-224.
860pub const ECDSA_P521_SHA224_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
861    id: &ec::signature::AlgorithmID::ECDSA_P521,
862    digest: &digest::SHA224,
863    sig_format: EcdsaSignatureFormat::Fixed,
864};
865
866/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-256.
867pub const ECDSA_P521_SHA256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
868    id: &ec::signature::AlgorithmID::ECDSA_P521,
869    digest: &digest::SHA256,
870    sig_format: EcdsaSignatureFormat::Fixed,
871};
872
873/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-384.
874pub const ECDSA_P521_SHA384_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
875    id: &ec::signature::AlgorithmID::ECDSA_P521,
876    digest: &digest::SHA384,
877    sig_format: EcdsaSignatureFormat::Fixed,
878};
879
880/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-512.
881pub const ECDSA_P521_SHA512_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
882    id: &ec::signature::AlgorithmID::ECDSA_P521,
883    digest: &digest::SHA512,
884    sig_format: EcdsaSignatureFormat::Fixed,
885};
886
887/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA3-512.
888pub const ECDSA_P521_SHA3_512_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
889    id: &ec::signature::AlgorithmID::ECDSA_P521,
890    digest: &digest::SHA3_512,
891    sig_format: EcdsaSignatureFormat::Fixed,
892};
893
894/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA-256.
895pub const ECDSA_P256K1_SHA256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
896    id: &ec::signature::AlgorithmID::ECDSA_P256K1,
897    digest: &digest::SHA256,
898    sig_format: EcdsaSignatureFormat::Fixed,
899};
900
901/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA3-256.
902pub const ECDSA_P256K1_SHA3_256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
903    id: &ec::signature::AlgorithmID::ECDSA_P256K1,
904    digest: &digest::SHA3_256,
905    sig_format: EcdsaSignatureFormat::Fixed,
906};
907
908/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-256.
909pub const ECDSA_P256_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
910    id: &ec::signature::AlgorithmID::ECDSA_P256,
911    digest: &digest::SHA256,
912    sig_format: EcdsaSignatureFormat::ASN1,
913};
914
915/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-384.
916pub const ECDSA_P256_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
917    id: &ec::signature::AlgorithmID::ECDSA_P256,
918    digest: &digest::SHA384,
919    sig_format: EcdsaSignatureFormat::ASN1,
920};
921
922/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-512.
923pub const ECDSA_P256_SHA512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
924    id: &ec::signature::AlgorithmID::ECDSA_P256,
925    digest: &digest::SHA512,
926    sig_format: EcdsaSignatureFormat::ASN1,
927};
928
929/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-256.
930pub const ECDSA_P384_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
931    id: &ec::signature::AlgorithmID::ECDSA_P384,
932    digest: &digest::SHA256,
933    sig_format: EcdsaSignatureFormat::ASN1,
934};
935
936/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-384.
937pub const ECDSA_P384_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
938    id: &ec::signature::AlgorithmID::ECDSA_P384,
939    digest: &digest::SHA384,
940    sig_format: EcdsaSignatureFormat::ASN1,
941};
942
943/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-512.
944pub const ECDSA_P384_SHA512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
945    id: &ec::signature::AlgorithmID::ECDSA_P384,
946    digest: &digest::SHA512,
947    sig_format: EcdsaSignatureFormat::ASN1,
948};
949
950/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA3-384.
951pub const ECDSA_P384_SHA3_384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
952    id: &ec::signature::AlgorithmID::ECDSA_P384,
953    digest: &digest::SHA3_384,
954    sig_format: EcdsaSignatureFormat::ASN1,
955};
956
957/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-1.
958pub const ECDSA_P521_SHA1_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
959    id: &ec::signature::AlgorithmID::ECDSA_P521,
960    digest: &digest::SHA1_FOR_LEGACY_USE_ONLY,
961    sig_format: EcdsaSignatureFormat::ASN1,
962};
963
964/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-224.
965pub const ECDSA_P521_SHA224_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
966    id: &ec::signature::AlgorithmID::ECDSA_P521,
967    digest: &digest::SHA224,
968    sig_format: EcdsaSignatureFormat::ASN1,
969};
970
971/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-256.
972pub const ECDSA_P521_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
973    id: &ec::signature::AlgorithmID::ECDSA_P521,
974    digest: &digest::SHA256,
975    sig_format: EcdsaSignatureFormat::ASN1,
976};
977
978/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-384.
979pub const ECDSA_P521_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
980    id: &ec::signature::AlgorithmID::ECDSA_P521,
981    digest: &digest::SHA384,
982    sig_format: EcdsaSignatureFormat::ASN1,
983};
984
985/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-512.
986pub const ECDSA_P521_SHA512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
987    id: &ec::signature::AlgorithmID::ECDSA_P521,
988    digest: &digest::SHA512,
989    sig_format: EcdsaSignatureFormat::ASN1,
990};
991
992/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA3-512.
993pub const ECDSA_P521_SHA3_512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
994    id: &ec::signature::AlgorithmID::ECDSA_P521,
995    digest: &digest::SHA3_512,
996    sig_format: EcdsaSignatureFormat::ASN1,
997};
998
999/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA-256.
1000pub const ECDSA_P256K1_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
1001    id: &ec::signature::AlgorithmID::ECDSA_P256K1,
1002    digest: &digest::SHA256,
1003    sig_format: EcdsaSignatureFormat::ASN1,
1004};
1005
1006/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA3-256.
1007pub const ECDSA_P256K1_SHA3_256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
1008    id: &ec::signature::AlgorithmID::ECDSA_P256K1,
1009    digest: &digest::SHA3_256,
1010    sig_format: EcdsaSignatureFormat::ASN1,
1011};
1012
1013/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-256 curve and SHA-256.
1014pub const ECDSA_P256_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm =
1015    EcdsaSigningAlgorithm(&ECDSA_P256_SHA256_FIXED);
1016
1017/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA-384.
1018pub const ECDSA_P384_SHA384_FIXED_SIGNING: EcdsaSigningAlgorithm =
1019    EcdsaSigningAlgorithm(&ECDSA_P384_SHA384_FIXED);
1020
1021/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA3-384.
1022pub const ECDSA_P384_SHA3_384_FIXED_SIGNING: EcdsaSigningAlgorithm =
1023    EcdsaSigningAlgorithm(&ECDSA_P384_SHA3_384_FIXED);
1024
1025/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-224.
1026/// # ⚠️ Warning
1027/// The security design strength of SHA-224 digests is less then security strength of P-521.
1028/// This scheme should only be used for backwards compatibility purposes.
1029pub const ECDSA_P521_SHA224_FIXED_SIGNING: EcdsaSigningAlgorithm =
1030    EcdsaSigningAlgorithm(&ECDSA_P521_SHA224_FIXED);
1031
1032/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-256.
1033/// # ⚠️ Warning
1034/// The security design strength of SHA-256 digests is less then security strength of P-521.
1035/// This scheme should only be used for backwards compatibility purposes.
1036pub const ECDSA_P521_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm =
1037    EcdsaSigningAlgorithm(&ECDSA_P521_SHA256_FIXED);
1038
1039/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-384.
1040/// # ⚠️ Warning
1041/// The security design strength of SHA-384 digests is less then security strength of P-521.
1042/// This scheme should only be used for backwards compatibility purposes.
1043pub const ECDSA_P521_SHA384_FIXED_SIGNING: EcdsaSigningAlgorithm =
1044    EcdsaSigningAlgorithm(&ECDSA_P521_SHA384_FIXED);
1045
1046/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-512.
1047pub const ECDSA_P521_SHA512_FIXED_SIGNING: EcdsaSigningAlgorithm =
1048    EcdsaSigningAlgorithm(&ECDSA_P521_SHA512_FIXED);
1049
1050/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA3-512.
1051pub const ECDSA_P521_SHA3_512_FIXED_SIGNING: EcdsaSigningAlgorithm =
1052    EcdsaSigningAlgorithm(&ECDSA_P521_SHA3_512_FIXED);
1053
1054/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA-256.
1055pub const ECDSA_P256K1_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm =
1056    EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA256_FIXED);
1057
1058/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA3-256.
1059pub const ECDSA_P256K1_SHA3_256_FIXED_SIGNING: EcdsaSigningAlgorithm =
1060    EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA3_256_FIXED);
1061
1062/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-256.
1063pub const ECDSA_P256_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm =
1064    EcdsaSigningAlgorithm(&ECDSA_P256_SHA256_ASN1);
1065
1066/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-384.
1067pub const ECDSA_P384_SHA384_ASN1_SIGNING: EcdsaSigningAlgorithm =
1068    EcdsaSigningAlgorithm(&ECDSA_P384_SHA384_ASN1);
1069
1070/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA3-384.
1071pub const ECDSA_P384_SHA3_384_ASN1_SIGNING: EcdsaSigningAlgorithm =
1072    EcdsaSigningAlgorithm(&ECDSA_P384_SHA3_384_ASN1);
1073
1074/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-224.
1075/// # ⚠️ Warning
1076/// The security design strength of SHA-224 digests is less then security strength of P-521.
1077/// This scheme should only be used for backwards compatibility purposes.
1078pub const ECDSA_P521_SHA224_ASN1_SIGNING: EcdsaSigningAlgorithm =
1079    EcdsaSigningAlgorithm(&ECDSA_P521_SHA224_ASN1);
1080
1081/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-256.
1082/// # ⚠️ Warning
1083/// The security design strength of SHA-256 digests is less then security strength of P-521.
1084/// This scheme should only be used for backwards compatibility purposes.
1085pub const ECDSA_P521_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm =
1086    EcdsaSigningAlgorithm(&ECDSA_P521_SHA256_ASN1);
1087
1088/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-384.
1089/// # ⚠️ Warning
1090/// The security design strength of SHA-384 digests is less then security strength of P-521.
1091/// This scheme should only be used for backwards compatibility purposes.
1092pub const ECDSA_P521_SHA384_ASN1_SIGNING: EcdsaSigningAlgorithm =
1093    EcdsaSigningAlgorithm(&ECDSA_P521_SHA384_ASN1);
1094
1095/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-512.
1096pub const ECDSA_P521_SHA512_ASN1_SIGNING: EcdsaSigningAlgorithm =
1097    EcdsaSigningAlgorithm(&ECDSA_P521_SHA512_ASN1);
1098
1099/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA3-512.
1100pub const ECDSA_P521_SHA3_512_ASN1_SIGNING: EcdsaSigningAlgorithm =
1101    EcdsaSigningAlgorithm(&ECDSA_P521_SHA3_512_ASN1);
1102
1103/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA-256.
1104pub const ECDSA_P256K1_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm =
1105    EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA256_ASN1);
1106
1107/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA3-256.
1108pub const ECDSA_P256K1_SHA3_256_ASN1_SIGNING: EcdsaSigningAlgorithm =
1109    EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA3_256_ASN1);
1110
1111/// Verification of Ed25519 signatures.
1112pub const ED25519: EdDSAParameters = EdDSAParameters {};
1113
1114#[cfg(test)]
1115mod tests {
1116    use crate::rand::{generate, SystemRandom};
1117    use crate::signature::{ParsedPublicKey, UnparsedPublicKey, ED25519};
1118    use crate::test;
1119    use regex::Regex;
1120
1121    #[cfg(feature = "fips")]
1122    mod fips;
1123
1124    #[test]
1125    fn test_unparsed_public_key() {
1126        let random_pubkey: [u8; 32] = generate(&SystemRandom::new()).unwrap().expose();
1127        let unparsed_pubkey = UnparsedPublicKey::new(&ED25519, random_pubkey);
1128        let unparsed_pubkey_debug = format!("{unparsed_pubkey:?}");
1129
1130        #[allow(clippy::clone_on_copy)]
1131        let unparsed_pubkey_clone = unparsed_pubkey.clone();
1132        assert_eq!(unparsed_pubkey_debug, format!("{unparsed_pubkey_clone:?}"));
1133        let pubkey_re = Regex::new(
1134            "UnparsedPublicKey \\{ algorithm: EdDSAParameters, bytes: \"[0-9a-f]{64}\" \\}",
1135        )
1136        .unwrap();
1137
1138        assert!(pubkey_re.is_match(&unparsed_pubkey_debug));
1139    }
1140    #[test]
1141    fn test_types() {
1142        test::compile_time_assert_send::<UnparsedPublicKey<&[u8]>>();
1143        test::compile_time_assert_sync::<UnparsedPublicKey<&[u8]>>();
1144        test::compile_time_assert_send::<UnparsedPublicKey<Vec<u8>>>();
1145        test::compile_time_assert_sync::<UnparsedPublicKey<Vec<u8>>>();
1146        test::compile_time_assert_clone::<UnparsedPublicKey<&[u8]>>();
1147        test::compile_time_assert_clone::<UnparsedPublicKey<Vec<u8>>>();
1148        test::compile_time_assert_send::<ParsedPublicKey>();
1149        test::compile_time_assert_sync::<ParsedPublicKey>();
1150        test::compile_time_assert_clone::<ParsedPublicKey>();
1151    }
1152}