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, 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(note = "please use `VerificationAlgorithm::verify_sig` instead")]
397 fn verify(
398 &self,
399 public_key: Input<'_>,
400 msg: Input<'_>,
401 signature: Input<'_>,
402 ) -> Result<(), error::Unspecified>;
403
404 /// Verify the signature `signature` of message `msg` with the public key
405 /// `public_key`.
406 ///
407 // # FIPS
408 // The following conditions must be met:
409 // * RSA Key Sizes: 1024, 2048, 3072, 4096
410 // * NIST Elliptic Curves: P256, P384, P521
411 // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
412 //
413 /// # Errors
414 /// `error::Unspecified` if inputs not verified.
415 fn verify_sig(
416 &self,
417 public_key: &[u8],
418 msg: &[u8],
419 signature: &[u8],
420 ) -> Result<(), error::Unspecified>;
421
422 /// Verify the signature `signature` of `digest` with the `public_key`.
423 ///
424 // # FIPS
425 // Not approved.
426 //
427 /// # Errors
428 /// `error::Unspecified` if inputs not verified.
429 fn verify_digest_sig(
430 &self,
431 public_key: &[u8],
432 digest: &Digest,
433 signature: &[u8],
434 ) -> Result<(), error::Unspecified>;
435}
436
437/// An unparsed, possibly malformed, public key for signature verification.
438#[derive(Clone)]
439pub struct UnparsedPublicKey<B: AsRef<[u8]>> {
440 algorithm: &'static dyn VerificationAlgorithm,
441 bytes: B,
442}
443/// A parsed public key for signature verification.
444///
445/// A `ParsedPublicKey` can be created in two ways:
446/// - Directly from public key bytes using [`ParsedPublicKey::new`]
447/// - By parsing an `UnparsedPublicKey` using [`UnparsedPublicKey::parse`]
448///
449/// This pre-validates the public key format and stores the parsed key material,
450/// allowing for more efficient signature verification operations compared to
451/// parsing the key on each verification.
452///
453/// See the [`crate::signature`] module-level documentation for examples.
454#[derive(Clone)]
455pub struct ParsedPublicKey {
456 algorithm: &'static dyn VerificationAlgorithm,
457 parsed_algorithm: &'static dyn ParsedVerificationAlgorithm,
458 key: LcPtr<EVP_PKEY>,
459 bytes: Box<[u8]>,
460}
461
462// See EVP_PKEY documentation here:
463// https://github.com/aws/aws-lc/blob/125af14c57451565b875fbf1282a38a6ecf83782/include/openssl/evp.h#L83-L89
464// An |EVP_PKEY| object represents a public or private key. A given object may
465// be used concurrently on multiple threads by non-mutating functions, provided
466// no other thread is concurrently calling a mutating function. Unless otherwise
467// documented, functions which take a |const| pointer are non-mutating and
468// functions which take a non-|const| pointer are mutating.
469unsafe impl Send for ParsedPublicKey {}
470unsafe impl Sync for ParsedPublicKey {}
471
472impl ParsedPublicKey {
473 /// Creates a new `ParsedPublicKey` directly from public key bytes.
474 ///
475 /// This method validates the public key format and creates a `ParsedPublicKey`
476 /// that can be used for efficient signature verification operations.
477 ///
478 /// # Errors
479 /// `KeyRejected` if the public key bytes are malformed or incompatible
480 /// with the specified algorithm.
481 ///
482 /// # Examples
483 ///
484 /// ```
485 /// use aws_lc_rs::signature::{self, ParsedPublicKey};
486 ///
487 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
488 /// let parsed_key = ParsedPublicKey::new(&signature::ED25519, include_bytes!("../tests/data/ed25519_test_public_key.bin"))?;
489 /// let signature = [
490 /// 0xED, 0xDB, 0x67, 0xE9, 0xF7, 0x8C, 0x9A, 0x0, 0xFD, 0xEE, 0x2D, 0x22, 0x21, 0xA3, 0x9A,
491 /// 0x8A, 0x79, 0xF2, 0x53, 0x88, 0x78, 0xF0, 0xA0, 0x1, 0x80, 0xA, 0x49, 0xA4, 0x17, 0x88,
492 /// 0xAB, 0x44, 0x4B, 0xD2, 0x58, 0xB0, 0x3B, 0x51, 0x8A, 0x1B, 0x61, 0x24, 0x52, 0x78, 0x48,
493 /// 0x58, 0x40, 0x5, 0xB5, 0x45, 0x22, 0xB6, 0x40, 0xBD, 0x14, 0x47, 0xB1, 0xF0, 0xDC, 0x13,
494 /// 0xB3, 0xE9, 0xD0, 0x6,
495 /// ];
496 /// assert!(parsed_key.verify_sig(b"hello world!", &signature).is_ok());
497 /// assert!(parsed_key.verify_sig(b"hello world.", &signature).is_err());
498 /// # Ok(())
499 /// # }
500 /// ```
501 pub fn new<B: AsRef<[u8]>>(
502 algorithm: &'static dyn VerificationAlgorithm,
503 bytes: B,
504 ) -> Result<Self, KeyRejected> {
505 parse_public_key(bytes.as_ref(), algorithm)
506 }
507
508 /// Returns the algorithm used by this public key.
509 #[must_use]
510 pub fn algorithm(&self) -> &'static dyn VerificationAlgorithm {
511 self.algorithm
512 }
513
514 pub(crate) fn key(&self) -> &LcPtr<EVP_PKEY> {
515 &self.key
516 }
517
518 /// Constructs a `ParsedPublicKey` directly from an already-built RSA
519 /// `EVP_PKEY`, skipping the DER-encode / DER-decode round-trip that
520 /// [`parse_public_key`] would otherwise perform. The SubjectPublicKeyInfo
521 /// DER is still marshalled once so that [`AsRef<[u8]>`] on the resulting
522 /// `ParsedPublicKey` continues to return a canonical encoding.
523 ///
524 /// `params` is used as both the public [`VerificationAlgorithm`] and the
525 /// internal `ParsedVerificationAlgorithm`, matching what
526 /// [`parse_public_key`] would assign for RSA inputs.
527 pub(crate) fn from_rsa_evp_pkey(
528 params: &'static RsaParameters,
529 key: LcPtr<EVP_PKEY>,
530 ) -> Result<Self, Unspecified> {
531 let bytes = key
532 .as_const()
533 .marshal_rfc5280_public_key()?
534 .into_boxed_slice();
535 Ok(ParsedPublicKey {
536 algorithm: params,
537 parsed_algorithm: params,
538 key,
539 bytes,
540 })
541 }
542
543 /// Uses the public key to verify that `signature` is a valid signature of
544 /// `message`.
545 ///
546 /// This method is more efficient than [`UnparsedPublicKey::verify`] when
547 /// performing multiple signature verifications with the same public key,
548 /// as the key parsing overhead is avoided.
549 ///
550 /// See the [`crate::signature`] module-level documentation for examples.
551 ///
552 // # FIPS
553 // The following conditions must be met:
554 // * RSA Key Sizes: 1024, 2048, 3072, 4096
555 // * NIST Elliptic Curves: P256, P384, P521
556 // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
557 //
558 /// # Errors
559 /// `error::Unspecified` if the signature is invalid or verification fails.
560 #[inline]
561 pub fn verify_sig(&self, message: &[u8], signature: &[u8]) -> Result<(), error::Unspecified> {
562 self.parsed_algorithm
563 .parsed_verify_sig(self, message, signature)
564 }
565
566 /// Uses the public key to verify that `signature` is a valid signature of
567 /// `digest`.
568 ///
569 /// This method is more efficient than [`UnparsedPublicKey::verify_digest`] when
570 /// performing multiple signature verifications with the same public key,
571 /// as the key parsing overhead is avoided.
572 ///
573 /// See the [`crate::signature`] module-level documentation for examples.
574 ///
575 // # FIPS
576 // Not allowed
577 //
578 /// # Errors
579 /// `error::Unspecified` if the signature is invalid or verification fails.
580 #[inline]
581 pub fn verify_digest_sig(
582 &self,
583 digest: &Digest,
584 signature: &[u8],
585 ) -> Result<(), error::Unspecified> {
586 self.parsed_algorithm
587 .parsed_verify_digest_sig(self, digest, signature)
588 }
589}
590
591impl AsDer<PublicKeyX509Der<'static>> for ParsedPublicKey {
592 fn as_der(&self) -> Result<PublicKeyX509Der<'static>, Unspecified> {
593 Ok(PublicKeyX509Der::new(
594 self.key.as_const().marshal_rfc5280_public_key()?,
595 ))
596 }
597}
598
599/// Provides the original bytes from which this key was parsed
600impl AsRef<[u8]> for ParsedPublicKey {
601 fn as_ref(&self) -> &[u8] {
602 &self.bytes
603 }
604}
605
606impl Debug for ParsedPublicKey {
607 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
608 f.write_str(&format!(
609 "ParsedPublicKey {{ algorithm: {:?}, bytes: \"{}\" }}",
610 self.algorithm,
611 hex::encode(self.bytes.as_ref())
612 ))
613 }
614}
615
616impl<B: AsRef<[u8]>> AsRef<[u8]> for UnparsedPublicKey<B> {
617 #[inline]
618 fn as_ref(&self) -> &[u8] {
619 self.bytes.as_ref()
620 }
621}
622
623impl<B: Copy + AsRef<[u8]>> Copy for UnparsedPublicKey<B> {}
624
625impl<B: AsRef<[u8]>> Debug for UnparsedPublicKey<B> {
626 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
627 f.write_str(&format!(
628 "UnparsedPublicKey {{ algorithm: {:?}, bytes: \"{}\" }}",
629 self.algorithm,
630 hex::encode(self.bytes.as_ref())
631 ))
632 }
633}
634
635impl<B: AsRef<[u8]>> UnparsedPublicKey<B> {
636 /// Construct a new `UnparsedPublicKey`.
637 ///
638 /// No validation of `bytes` is done until `verify()` is called.
639 #[inline]
640 pub fn new(algorithm: &'static dyn VerificationAlgorithm, bytes: B) -> Self {
641 Self { algorithm, bytes }
642 }
643
644 /// Parses the public key and verifies `signature` is a valid signature of
645 /// `message` using it.
646 ///
647 /// See the [`crate::signature`] module-level documentation for examples.
648 ///
649 // # FIPS
650 // The following conditions must be met:
651 // * RSA Key Sizes: 1024, 2048, 3072, 4096
652 // * NIST Elliptic Curves: P256, P384, P521
653 // * Digest Algorithms: SHA1, SHA256, SHA384, SHA512
654 //
655 /// # Errors
656 /// `error::Unspecified` if inputs not verified.
657 #[inline]
658 pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), error::Unspecified> {
659 self.algorithm
660 .verify_sig(self.bytes.as_ref(), message, signature)
661 }
662
663 /// Parses the public key and verifies `signature` is a valid signature of
664 /// `digest` using it.
665 ///
666 /// See the [`crate::signature`] module-level documentation for examples.
667 ///
668 // # FIPS
669 // Not allowed
670 //
671 /// # Errors
672 /// `error::Unspecified` if inputs not verified.
673 #[inline]
674 pub fn verify_digest(
675 &self,
676 digest: &Digest,
677 signature: &[u8],
678 ) -> Result<(), error::Unspecified> {
679 self.algorithm
680 .verify_digest_sig(self.bytes.as_ref(), digest, signature)
681 }
682
683 /// Parses the public key bytes and returns a `ParsedPublicKey`.
684 ///
685 /// This method validates the public key format and creates a `ParsedPublicKey`
686 /// that can be used for more efficient signature verification operations.
687 /// The parsing overhead is incurred once, making subsequent verifications
688 /// faster compared to using `UnparsedPublicKey::verify` directly.
689 ///
690 /// This is equivalent to calling [`ParsedPublicKey::new`] with the same
691 /// algorithm and bytes.
692 ///
693 /// # Errors
694 /// `KeyRejected` if the public key bytes are malformed or incompatible
695 /// with the specified algorithm.
696 pub fn parse(&self) -> Result<ParsedPublicKey, KeyRejected> {
697 parse_public_key(self.bytes.as_ref(), self.algorithm)
698 }
699}
700
701pub(crate) fn parse_public_key(
702 bytes: &[u8],
703 algorithm: &'static dyn VerificationAlgorithm,
704) -> Result<ParsedPublicKey, KeyRejected> {
705 let parsed_algorithm: &'static dyn ParsedVerificationAlgorithm;
706
707 let key = if algorithm.type_id() == TypeId::of::<EcdsaVerificationAlgorithm>() {
708 #[allow(clippy::cast_ptr_alignment)]
709 let ec_alg = unsafe {
710 &*(algorithm as *const dyn VerificationAlgorithm).cast::<EcdsaVerificationAlgorithm>()
711 };
712 parsed_algorithm = ec_alg;
713 parse_ec_public_key(bytes, ec_alg.id.nid())?
714 } else if algorithm.type_id() == TypeId::of::<EdDSAParameters>() {
715 #[allow(clippy::cast_ptr_alignment)]
716 let ed_alg =
717 unsafe { &*(algorithm as *const dyn VerificationAlgorithm).cast::<EdDSAParameters>() };
718 parsed_algorithm = ed_alg;
719 parse_ed25519_public_key(bytes)?
720 } else if algorithm.type_id() == TypeId::of::<RsaParameters>() {
721 #[allow(clippy::cast_ptr_alignment)]
722 let rsa_alg =
723 unsafe { &*(algorithm as *const dyn VerificationAlgorithm).cast::<RsaParameters>() };
724 parsed_algorithm = rsa_alg;
725 parse_rsa_public_key(bytes)?
726 } else if algorithm.type_id() == TypeId::of::<PqdsaVerificationAlgorithm>() {
727 #[allow(clippy::cast_ptr_alignment)]
728 let pqdsa_alg = unsafe {
729 &*(algorithm as *const dyn VerificationAlgorithm).cast::<PqdsaVerificationAlgorithm>()
730 };
731 parsed_algorithm = pqdsa_alg;
732 parse_pqdsa_public_key(bytes, pqdsa_alg.id)?
733 } else {
734 unreachable!()
735 };
736
737 let bytes = bytes.to_vec().into_boxed_slice();
738 Ok(ParsedPublicKey {
739 algorithm,
740 parsed_algorithm,
741 key,
742 bytes,
743 })
744}
745
746/// Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-1.
747pub const RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
748 &digest::SHA1_FOR_LEGACY_USE_ONLY,
749 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
750 1024..=8192,
751 &RsaVerificationAlgorithmId::RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY,
752);
753
754/// Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-256.
755pub const RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
756 &digest::SHA256,
757 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
758 1024..=8192,
759 &RsaVerificationAlgorithmId::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY,
760);
761
762/// Verification of signatures using RSA keys of 1024-8192 bits, PKCS#1.5 padding, and SHA-512.
763pub const RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
764 &digest::SHA512,
765 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
766 1024..=8192,
767 &RsaVerificationAlgorithmId::RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY,
768);
769
770/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-1.
771pub const RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY: RsaParameters = RsaParameters::new(
772 &digest::SHA1_FOR_LEGACY_USE_ONLY,
773 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
774 2048..=8192,
775 &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY,
776);
777
778/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-256.
779pub const RSA_PKCS1_2048_8192_SHA256: RsaParameters = RsaParameters::new(
780 &digest::SHA256,
781 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
782 2048..=8192,
783 &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA256,
784);
785
786/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-384.
787pub const RSA_PKCS1_2048_8192_SHA384: RsaParameters = RsaParameters::new(
788 &digest::SHA384,
789 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
790 2048..=8192,
791 &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA384,
792);
793
794/// Verification of signatures using RSA keys of 2048-8192 bits, PKCS#1.5 padding, and SHA-512.
795pub const RSA_PKCS1_2048_8192_SHA512: RsaParameters = RsaParameters::new(
796 &digest::SHA512,
797 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
798 2048..=8192,
799 &RsaVerificationAlgorithmId::RSA_PKCS1_2048_8192_SHA512,
800);
801
802/// Verification of signatures using RSA keys of 3072-8192 bits, PKCS#1.5 padding, and SHA-384.
803pub const RSA_PKCS1_3072_8192_SHA384: RsaParameters = RsaParameters::new(
804 &digest::SHA384,
805 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
806 3072..=8192,
807 &RsaVerificationAlgorithmId::RSA_PKCS1_3072_8192_SHA384,
808);
809
810/// Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-256.
811pub const RSA_PSS_2048_8192_SHA256: RsaParameters = RsaParameters::new(
812 &digest::SHA256,
813 &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
814 2048..=8192,
815 &RsaVerificationAlgorithmId::RSA_PSS_2048_8192_SHA256,
816);
817
818/// Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-384.
819pub const RSA_PSS_2048_8192_SHA384: RsaParameters = RsaParameters::new(
820 &digest::SHA384,
821 &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
822 2048..=8192,
823 &RsaVerificationAlgorithmId::RSA_PSS_2048_8192_SHA384,
824);
825
826/// Verification of signatures using RSA keys of 2048-8192 bits, PSS padding, and SHA-512.
827pub const RSA_PSS_2048_8192_SHA512: RsaParameters = RsaParameters::new(
828 &digest::SHA512,
829 &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
830 2048..=8192,
831 &RsaVerificationAlgorithmId::RSA_PSS_2048_8192_SHA512,
832);
833
834/// RSA PSS padding using SHA-256 for RSA signatures.
835pub const RSA_PSS_SHA256: RsaSignatureEncoding = RsaSignatureEncoding::new(
836 &digest::SHA256,
837 &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
838 &RsaSigningAlgorithmId::RSA_PSS_SHA256,
839);
840
841/// RSA PSS padding using SHA-384 for RSA signatures.
842pub const RSA_PSS_SHA384: RsaSignatureEncoding = RsaSignatureEncoding::new(
843 &digest::SHA384,
844 &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
845 &RsaSigningAlgorithmId::RSA_PSS_SHA384,
846);
847
848/// RSA PSS padding using SHA-512 for RSA signatures.
849pub const RSA_PSS_SHA512: RsaSignatureEncoding = RsaSignatureEncoding::new(
850 &digest::SHA512,
851 &rsa::signature::RsaPadding::RSA_PKCS1_PSS_PADDING,
852 &RsaSigningAlgorithmId::RSA_PSS_SHA512,
853);
854
855/// PKCS#1 1.5 padding using SHA-256 for RSA signatures.
856pub const RSA_PKCS1_SHA256: RsaSignatureEncoding = RsaSignatureEncoding::new(
857 &digest::SHA256,
858 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
859 &RsaSigningAlgorithmId::RSA_PKCS1_SHA256,
860);
861
862/// PKCS#1 1.5 padding using SHA-384 for RSA signatures.
863pub const RSA_PKCS1_SHA384: RsaSignatureEncoding = RsaSignatureEncoding::new(
864 &digest::SHA384,
865 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
866 &RsaSigningAlgorithmId::RSA_PKCS1_SHA384,
867);
868
869/// PKCS#1 1.5 padding using SHA-512 for RSA signatures.
870pub const RSA_PKCS1_SHA512: RsaSignatureEncoding = RsaSignatureEncoding::new(
871 &digest::SHA512,
872 &rsa::signature::RsaPadding::RSA_PKCS1_PADDING,
873 &RsaSigningAlgorithmId::RSA_PKCS1_SHA512,
874);
875
876/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-256 curve and SHA-256.
877pub const ECDSA_P256_SHA256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
878 id: &ec::signature::AlgorithmID::ECDSA_P256,
879 digest: &digest::SHA256,
880 sig_format: EcdsaSignatureFormat::Fixed,
881};
882
883/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA-384.
884pub const ECDSA_P384_SHA384_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
885 id: &ec::signature::AlgorithmID::ECDSA_P384,
886 digest: &digest::SHA384,
887 sig_format: EcdsaSignatureFormat::Fixed,
888};
889
890/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA3-384.
891pub const ECDSA_P384_SHA3_384_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
892 id: &ec::signature::AlgorithmID::ECDSA_P384,
893 digest: &digest::SHA3_384,
894 sig_format: EcdsaSignatureFormat::Fixed,
895};
896
897/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-1.
898pub const ECDSA_P521_SHA1_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
899 id: &ec::signature::AlgorithmID::ECDSA_P521,
900 digest: &digest::SHA1_FOR_LEGACY_USE_ONLY,
901 sig_format: EcdsaSignatureFormat::Fixed,
902};
903
904/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-224.
905pub const ECDSA_P521_SHA224_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
906 id: &ec::signature::AlgorithmID::ECDSA_P521,
907 digest: &digest::SHA224,
908 sig_format: EcdsaSignatureFormat::Fixed,
909};
910
911/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-256.
912pub const ECDSA_P521_SHA256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
913 id: &ec::signature::AlgorithmID::ECDSA_P521,
914 digest: &digest::SHA256,
915 sig_format: EcdsaSignatureFormat::Fixed,
916};
917
918/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-384.
919pub const ECDSA_P521_SHA384_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
920 id: &ec::signature::AlgorithmID::ECDSA_P521,
921 digest: &digest::SHA384,
922 sig_format: EcdsaSignatureFormat::Fixed,
923};
924
925/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-512.
926pub const ECDSA_P521_SHA512_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
927 id: &ec::signature::AlgorithmID::ECDSA_P521,
928 digest: &digest::SHA512,
929 sig_format: EcdsaSignatureFormat::Fixed,
930};
931
932/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA3-512.
933pub const ECDSA_P521_SHA3_512_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
934 id: &ec::signature::AlgorithmID::ECDSA_P521,
935 digest: &digest::SHA3_512,
936 sig_format: EcdsaSignatureFormat::Fixed,
937};
938
939/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA-256.
940pub const ECDSA_P256K1_SHA256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
941 id: &ec::signature::AlgorithmID::ECDSA_P256K1,
942 digest: &digest::SHA256,
943 sig_format: EcdsaSignatureFormat::Fixed,
944};
945
946/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA3-256.
947pub const ECDSA_P256K1_SHA3_256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
948 id: &ec::signature::AlgorithmID::ECDSA_P256K1,
949 digest: &digest::SHA3_256,
950 sig_format: EcdsaSignatureFormat::Fixed,
951};
952
953/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-256.
954pub const ECDSA_P256_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
955 id: &ec::signature::AlgorithmID::ECDSA_P256,
956 digest: &digest::SHA256,
957 sig_format: EcdsaSignatureFormat::ASN1,
958};
959
960/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-384.
961pub const ECDSA_P256_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
962 id: &ec::signature::AlgorithmID::ECDSA_P256,
963 digest: &digest::SHA384,
964 sig_format: EcdsaSignatureFormat::ASN1,
965};
966
967/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-512.
968pub const ECDSA_P256_SHA512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
969 id: &ec::signature::AlgorithmID::ECDSA_P256,
970 digest: &digest::SHA512,
971 sig_format: EcdsaSignatureFormat::ASN1,
972};
973
974/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-256.
975pub const ECDSA_P384_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
976 id: &ec::signature::AlgorithmID::ECDSA_P384,
977 digest: &digest::SHA256,
978 sig_format: EcdsaSignatureFormat::ASN1,
979};
980
981/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-384.
982pub const ECDSA_P384_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
983 id: &ec::signature::AlgorithmID::ECDSA_P384,
984 digest: &digest::SHA384,
985 sig_format: EcdsaSignatureFormat::ASN1,
986};
987
988/// *Not recommended.* Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-512.
989pub const ECDSA_P384_SHA512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
990 id: &ec::signature::AlgorithmID::ECDSA_P384,
991 digest: &digest::SHA512,
992 sig_format: EcdsaSignatureFormat::ASN1,
993};
994
995/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA3-384.
996pub const ECDSA_P384_SHA3_384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
997 id: &ec::signature::AlgorithmID::ECDSA_P384,
998 digest: &digest::SHA3_384,
999 sig_format: EcdsaSignatureFormat::ASN1,
1000};
1001
1002/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-1.
1003pub const ECDSA_P521_SHA1_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
1004 id: &ec::signature::AlgorithmID::ECDSA_P521,
1005 digest: &digest::SHA1_FOR_LEGACY_USE_ONLY,
1006 sig_format: EcdsaSignatureFormat::ASN1,
1007};
1008
1009/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-224.
1010pub const ECDSA_P521_SHA224_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
1011 id: &ec::signature::AlgorithmID::ECDSA_P521,
1012 digest: &digest::SHA224,
1013 sig_format: EcdsaSignatureFormat::ASN1,
1014};
1015
1016/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-256.
1017pub const ECDSA_P521_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
1018 id: &ec::signature::AlgorithmID::ECDSA_P521,
1019 digest: &digest::SHA256,
1020 sig_format: EcdsaSignatureFormat::ASN1,
1021};
1022
1023/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-384.
1024pub const ECDSA_P521_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
1025 id: &ec::signature::AlgorithmID::ECDSA_P521,
1026 digest: &digest::SHA384,
1027 sig_format: EcdsaSignatureFormat::ASN1,
1028};
1029
1030/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-512.
1031pub const ECDSA_P521_SHA512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
1032 id: &ec::signature::AlgorithmID::ECDSA_P521,
1033 digest: &digest::SHA512,
1034 sig_format: EcdsaSignatureFormat::ASN1,
1035};
1036
1037/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA3-512.
1038pub const ECDSA_P521_SHA3_512_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
1039 id: &ec::signature::AlgorithmID::ECDSA_P521,
1040 digest: &digest::SHA3_512,
1041 sig_format: EcdsaSignatureFormat::ASN1,
1042};
1043
1044/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA-256.
1045pub const ECDSA_P256K1_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
1046 id: &ec::signature::AlgorithmID::ECDSA_P256K1,
1047 digest: &digest::SHA256,
1048 sig_format: EcdsaSignatureFormat::ASN1,
1049};
1050
1051/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA3-256.
1052pub const ECDSA_P256K1_SHA3_256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
1053 id: &ec::signature::AlgorithmID::ECDSA_P256K1,
1054 digest: &digest::SHA3_256,
1055 sig_format: EcdsaSignatureFormat::ASN1,
1056};
1057
1058/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-256 curve and SHA-256.
1059pub const ECDSA_P256_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm =
1060 EcdsaSigningAlgorithm(&ECDSA_P256_SHA256_FIXED);
1061
1062/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA-384.
1063pub const ECDSA_P384_SHA384_FIXED_SIGNING: EcdsaSigningAlgorithm =
1064 EcdsaSigningAlgorithm(&ECDSA_P384_SHA384_FIXED);
1065
1066/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-384 curve and SHA3-384.
1067pub const ECDSA_P384_SHA3_384_FIXED_SIGNING: EcdsaSigningAlgorithm =
1068 EcdsaSigningAlgorithm(&ECDSA_P384_SHA3_384_FIXED);
1069
1070/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-224.
1071/// # ⚠️ Warning
1072/// The security design strength of SHA-224 digests is less then security strength of P-521.
1073/// This scheme should only be used for backwards compatibility purposes.
1074pub const ECDSA_P521_SHA224_FIXED_SIGNING: EcdsaSigningAlgorithm =
1075 EcdsaSigningAlgorithm(&ECDSA_P521_SHA224_FIXED);
1076
1077/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-256.
1078/// # ⚠️ Warning
1079/// The security design strength of SHA-256 digests is less then security strength of P-521.
1080/// This scheme should only be used for backwards compatibility purposes.
1081pub const ECDSA_P521_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm =
1082 EcdsaSigningAlgorithm(&ECDSA_P521_SHA256_FIXED);
1083
1084/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-384.
1085/// # ⚠️ Warning
1086/// The security design strength of SHA-384 digests is less then security strength of P-521.
1087/// This scheme should only be used for backwards compatibility purposes.
1088pub const ECDSA_P521_SHA384_FIXED_SIGNING: EcdsaSigningAlgorithm =
1089 EcdsaSigningAlgorithm(&ECDSA_P521_SHA384_FIXED);
1090
1091/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA-512.
1092pub const ECDSA_P521_SHA512_FIXED_SIGNING: EcdsaSigningAlgorithm =
1093 EcdsaSigningAlgorithm(&ECDSA_P521_SHA512_FIXED);
1094
1095/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-521 curve and SHA3-512.
1096pub const ECDSA_P521_SHA3_512_FIXED_SIGNING: EcdsaSigningAlgorithm =
1097 EcdsaSigningAlgorithm(&ECDSA_P521_SHA3_512_FIXED);
1098
1099/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA-256.
1100pub const ECDSA_P256K1_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm =
1101 EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA256_FIXED);
1102
1103/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the P-256K1 curve and SHA3-256.
1104pub const ECDSA_P256K1_SHA3_256_FIXED_SIGNING: EcdsaSigningAlgorithm =
1105 EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA3_256_FIXED);
1106
1107/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and SHA-256.
1108pub const ECDSA_P256_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm =
1109 EcdsaSigningAlgorithm(&ECDSA_P256_SHA256_ASN1);
1110
1111/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA-384.
1112pub const ECDSA_P384_SHA384_ASN1_SIGNING: EcdsaSigningAlgorithm =
1113 EcdsaSigningAlgorithm(&ECDSA_P384_SHA384_ASN1);
1114
1115/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and SHA3-384.
1116pub const ECDSA_P384_SHA3_384_ASN1_SIGNING: EcdsaSigningAlgorithm =
1117 EcdsaSigningAlgorithm(&ECDSA_P384_SHA3_384_ASN1);
1118
1119/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-224.
1120/// # ⚠️ Warning
1121/// The security design strength of SHA-224 digests is less then security strength of P-521.
1122/// This scheme should only be used for backwards compatibility purposes.
1123pub const ECDSA_P521_SHA224_ASN1_SIGNING: EcdsaSigningAlgorithm =
1124 EcdsaSigningAlgorithm(&ECDSA_P521_SHA224_ASN1);
1125
1126/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-256.
1127/// # ⚠️ Warning
1128/// The security design strength of SHA-256 digests is less then security strength of P-521.
1129/// This scheme should only be used for backwards compatibility purposes.
1130pub const ECDSA_P521_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm =
1131 EcdsaSigningAlgorithm(&ECDSA_P521_SHA256_ASN1);
1132
1133/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-384.
1134/// # ⚠️ Warning
1135/// The security design strength of SHA-384 digests is less then security strength of P-521.
1136/// This scheme should only be used for backwards compatibility purposes.
1137pub const ECDSA_P521_SHA384_ASN1_SIGNING: EcdsaSigningAlgorithm =
1138 EcdsaSigningAlgorithm(&ECDSA_P521_SHA384_ASN1);
1139
1140/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA-512.
1141pub const ECDSA_P521_SHA512_ASN1_SIGNING: EcdsaSigningAlgorithm =
1142 EcdsaSigningAlgorithm(&ECDSA_P521_SHA512_ASN1);
1143
1144/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-521 curve and SHA3-512.
1145pub const ECDSA_P521_SHA3_512_ASN1_SIGNING: EcdsaSigningAlgorithm =
1146 EcdsaSigningAlgorithm(&ECDSA_P521_SHA3_512_ASN1);
1147
1148/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA-256.
1149pub const ECDSA_P256K1_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm =
1150 EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA256_ASN1);
1151
1152/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-256K1 curve and SHA3-256.
1153pub const ECDSA_P256K1_SHA3_256_ASN1_SIGNING: EcdsaSigningAlgorithm =
1154 EcdsaSigningAlgorithm(&ECDSA_P256K1_SHA3_256_ASN1);
1155
1156/// Verification of Ed25519 signatures.
1157pub const ED25519: EdDSAParameters = EdDSAParameters {};
1158
1159/// Verification of ML-DSA-44 signatures.
1160pub const ML_DSA_44: PqdsaVerificationAlgorithm = PqdsaVerificationAlgorithm {
1161 id: &PqdsaAlgorithmID::ML_DSA_44,
1162};
1163
1164/// Verification of ML-DSA-65 signatures.
1165pub const ML_DSA_65: PqdsaVerificationAlgorithm = PqdsaVerificationAlgorithm {
1166 id: &PqdsaAlgorithmID::ML_DSA_65,
1167};
1168
1169/// Verification of ML-DSA-87 signatures.
1170pub const ML_DSA_87: PqdsaVerificationAlgorithm = PqdsaVerificationAlgorithm {
1171 id: &PqdsaAlgorithmID::ML_DSA_87,
1172};
1173
1174/// Signing using ML-DSA-44.
1175pub const ML_DSA_44_SIGNING: PqdsaSigningAlgorithm = PqdsaSigningAlgorithm(&ML_DSA_44);
1176
1177/// Signing using ML-DSA-65.
1178pub const ML_DSA_65_SIGNING: PqdsaSigningAlgorithm = PqdsaSigningAlgorithm(&ML_DSA_65);
1179
1180/// Signing using ML-DSA-87.
1181pub const ML_DSA_87_SIGNING: PqdsaSigningAlgorithm = PqdsaSigningAlgorithm(&ML_DSA_87);
1182
1183#[cfg(test)]
1184mod parsed_public_key_tests;
1185
1186#[cfg(test)]
1187mod tests {
1188 use crate::rand::{generate, SystemRandom};
1189 use crate::signature::{ParsedPublicKey, UnparsedPublicKey, ED25519};
1190 use crate::test;
1191 use regex::Regex;
1192
1193 #[cfg(feature = "fips")]
1194 mod fips;
1195
1196 #[test]
1197 fn test_unparsed_public_key() {
1198 let random_pubkey: [u8; 32] = generate(&SystemRandom::new()).unwrap().expose();
1199 let unparsed_pubkey = UnparsedPublicKey::new(&ED25519, random_pubkey);
1200 let unparsed_pubkey_debug = format!("{unparsed_pubkey:?}");
1201
1202 #[allow(clippy::clone_on_copy)]
1203 let unparsed_pubkey_clone = unparsed_pubkey.clone();
1204 assert_eq!(unparsed_pubkey_debug, format!("{unparsed_pubkey_clone:?}"));
1205 let pubkey_re = Regex::new(
1206 "UnparsedPublicKey \\{ algorithm: EdDSAParameters, bytes: \"[0-9a-f]{64}\" \\}",
1207 )
1208 .unwrap();
1209
1210 assert!(pubkey_re.is_match(&unparsed_pubkey_debug));
1211 }
1212 #[test]
1213 fn test_types() {
1214 test::compile_time_assert_send::<UnparsedPublicKey<&[u8]>>();
1215 test::compile_time_assert_sync::<UnparsedPublicKey<&[u8]>>();
1216 test::compile_time_assert_send::<UnparsedPublicKey<Vec<u8>>>();
1217 test::compile_time_assert_sync::<UnparsedPublicKey<Vec<u8>>>();
1218 test::compile_time_assert_clone::<UnparsedPublicKey<&[u8]>>();
1219 test::compile_time_assert_clone::<UnparsedPublicKey<Vec<u8>>>();
1220 test::compile_time_assert_send::<ParsedPublicKey>();
1221 test::compile_time_assert_sync::<ParsedPublicKey>();
1222 test::compile_time_assert_clone::<ParsedPublicKey>();
1223 }
1224}