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