1#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
9use getrandom::rand_core::TryCryptoRng;
10use getrandom::{SysRng, rand_core::TryRng};
11
12#[cfg(feature = "xmldsig")]
13use crate::xmldsig::DigestAlgorithm;
14#[cfg(feature = "xmlenc")]
15use crate::xmlenc::RsaOaepParameters;
16#[cfg(feature = "xmlenc")]
17use crate::xmlenc::{DataEncryptionAlgorithm, KeyWrapAlgorithm};
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21#[non_exhaustive]
22pub enum ProviderOperation {
23 Digest,
25 Sign,
27 Verify,
29 VerifyCertificate,
31 Encrypt,
33 Decrypt,
35 KeyWrap,
37 KeyUnwrap,
39 KeyTransport,
41 KeyAgreement,
43 Kdf,
45 Random,
47}
48
49#[derive(Debug, Clone, Copy)]
51pub struct CapabilityQuery<'a> {
52 pub operation: ProviderOperation,
54 pub algorithm: Option<&'a str>,
56}
57
58#[cfg(feature = "xmldsig")]
60#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61#[non_exhaustive]
62pub enum X509SignatureAlgorithm {
63 Dsa(DigestAlgorithm),
65 RsaPkcs1v15(DigestAlgorithm),
67 RsaPss {
69 digest: DigestAlgorithm,
71 mgf_digest: DigestAlgorithm,
73 salt_len: usize,
75 },
76 Ecdsa(DigestAlgorithm),
78 Ed25519,
80}
81
82#[cfg(feature = "xmldsig")]
83impl X509SignatureAlgorithm {
84 #[must_use]
86 pub const fn oid(self) -> &'static str {
87 match self {
88 Self::Dsa(DigestAlgorithm::Sha1) => "1.2.840.10040.4.3",
89 Self::Dsa(DigestAlgorithm::Sha256) => "2.16.840.1.101.3.4.3.2",
90 Self::Dsa(DigestAlgorithm::Sha384) => "2.16.840.1.101.3.4.3.3",
91 Self::Dsa(DigestAlgorithm::Sha512) => "2.16.840.1.101.3.4.3.4",
92 Self::RsaPkcs1v15(DigestAlgorithm::Sha1) => "1.2.840.113549.1.1.5",
93 Self::RsaPkcs1v15(DigestAlgorithm::Sha256) => "1.2.840.113549.1.1.11",
94 Self::RsaPkcs1v15(DigestAlgorithm::Sha384) => "1.2.840.113549.1.1.12",
95 Self::RsaPkcs1v15(DigestAlgorithm::Sha512) => "1.2.840.113549.1.1.13",
96 Self::RsaPss { .. } => "1.2.840.113549.1.1.10",
97 Self::Ecdsa(DigestAlgorithm::Sha1) => "1.2.840.10045.4.1",
98 Self::Ecdsa(DigestAlgorithm::Sha256) => "1.2.840.10045.4.3.2",
99 Self::Ecdsa(DigestAlgorithm::Sha384) => "1.2.840.10045.4.3.3",
100 Self::Ecdsa(DigestAlgorithm::Sha512) => "1.2.840.10045.4.3.4",
101 Self::Ed25519 => "1.3.101.112",
102 }
103 }
104}
105
106#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
108#[non_exhaustive]
109pub enum ProviderInputError {
110 #[error("failed to initialize {0}")]
112 PrimitiveInitialization(&'static str),
113 #[error("invalid AES-CBC framing")]
115 AesCbcFraming,
116 #[error("invalid AES-CBC ciphertext")]
118 AesCbcCiphertext,
119 #[error("invalid AES-GCM framing")]
121 AesGcmFraming,
122 #[error("invalid AES key-wrap framing")]
124 AesKeyWrapFraming,
125 #[error("legacy RSA-OAEP requires MGF1-SHA1")]
127 LegacyRsaOaepMgf,
128}
129
130#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
132#[non_exhaustive]
133pub enum ProviderError {
134 #[error("provider does not support {operation:?} with algorithm {algorithm:?}")]
136 Unsupported {
137 operation: ProviderOperation,
139 algorithm: Option<String>,
141 },
142 #[error("invalid key size: expected {expected} bytes, got {actual}")]
144 InvalidKeySize {
145 expected: usize,
147 actual: usize,
149 },
150 #[error(
153 "invalid provider output size for {operation:?}: expected {expected} bytes, got {actual}"
154 )]
155 InvalidOutputSize {
156 operation: ProviderOperation,
158 expected: usize,
160 actual: usize,
162 },
163 #[error(
166 "invalid provider output size for {operation:?}: expected {minimum}..={maximum} bytes, got {actual}"
167 )]
168 InvalidOutputSizeRange {
169 operation: ProviderOperation,
171 minimum: usize,
173 maximum: usize,
175 actual: usize,
177 },
178 #[error("invalid cryptographic input: {0}")]
180 InvalidInput(ProviderInputError),
181 #[error("cryptographic authentication failed")]
183 AuthenticationFailed,
184 #[error("operating-system random number generation failed: {0}")]
186 Random(String),
187}
188
189pub trait CryptoProvider: Send + Sync {
191 fn name(&self) -> &'static str;
193
194 fn supports(&self, query: CapabilityQuery<'_>) -> bool;
196
197 fn fill_random(&self, output: &mut [u8]) -> Result<(), ProviderError>;
199
200 #[cfg(feature = "xmldsig")]
202 fn digest(&self, algorithm: DigestAlgorithm, data: &[u8]) -> Result<Vec<u8>, ProviderError>;
203
204 #[cfg(feature = "xmldsig")]
210 fn sign(
211 &self,
212 key: &dyn crate::xmldsig::SigningKey,
213 algorithm: crate::xmldsig::SignatureAlgorithm,
214 data: &[u8],
215 ) -> Result<Vec<u8>, crate::xmldsig::SigningKeyError>;
216
217 #[cfg(feature = "xmldsig")]
222 fn verify(
223 &self,
224 key: &dyn crate::xmldsig::VerifyingKey,
225 algorithm: crate::xmldsig::SignatureAlgorithm,
226 data: &[u8],
227 signature: &[u8],
228 ) -> Result<bool, crate::xmldsig::DsigError>;
229
230 #[cfg(feature = "xmldsig")]
232 fn verify_x509_signature(
233 &self,
234 algorithm: X509SignatureAlgorithm,
235 signed_data: &[u8],
236 signature: &[u8],
237 issuer_spki_der: &[u8],
238 ) -> Result<bool, ProviderError> {
239 let _ = (signed_data, signature, issuer_spki_der);
240 Err(ProviderError::Unsupported {
241 operation: ProviderOperation::VerifyCertificate,
242 algorithm: Some(algorithm.oid().to_owned()),
243 })
244 }
245
246 #[cfg(feature = "xmlenc")]
248 fn encrypt_data(
249 &self,
250 algorithm: DataEncryptionAlgorithm,
251 key: &[u8],
252 plaintext: &[u8],
253 ) -> Result<Vec<u8>, ProviderError>;
254
255 #[cfg(feature = "xmlenc")]
257 fn decrypt_data(
258 &self,
259 algorithm: DataEncryptionAlgorithm,
260 key: &[u8],
261 ciphertext: &[u8],
262 ) -> Result<Vec<u8>, ProviderError>;
263
264 #[cfg(feature = "xmlenc")]
270 fn wrap_key(
271 &self,
272 algorithm: KeyWrapAlgorithm,
273 kek: &[u8],
274 key: &[u8],
275 ) -> Result<Vec<u8>, ProviderError>;
276
277 #[cfg(feature = "xmlenc")]
279 fn unwrap_key(
280 &self,
281 algorithm: KeyWrapAlgorithm,
282 kek: &[u8],
283 wrapped: &[u8],
284 ) -> Result<Vec<u8>, ProviderError>;
285
286 #[cfg(feature = "xmlenc")]
288 fn transport_key(
289 &self,
290 key: &rsa::RsaPublicKey,
291 parameters: &RsaOaepParameters,
292 plaintext: &[u8],
293 ) -> Result<Vec<u8>, ProviderError>;
294
295 #[cfg(feature = "xmlenc")]
297 fn recover_key(
298 &self,
299 key: &rsa::RsaPrivateKey,
300 parameters: &RsaOaepParameters,
301 ciphertext: &[u8],
302 ) -> Result<Vec<u8>, ProviderError>;
303}
304
305#[derive(Debug, Clone, Copy, Default)]
307pub struct RustCryptoProvider;
308
309pub static RUST_CRYPTO_PROVIDER: RustCryptoProvider = RustCryptoProvider;
311
312#[must_use]
314pub fn default_provider() -> &'static dyn CryptoProvider {
315 &RUST_CRYPTO_PROVIDER
316}
317
318#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
320pub(crate) struct ProviderRng<'a>(pub(crate) &'a dyn CryptoProvider);
321
322#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
323impl TryRng for ProviderRng<'_> {
324 type Error = ProviderError;
325
326 fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
327 let mut bytes = [0_u8; 4];
328 self.try_fill_bytes(&mut bytes)?;
329 Ok(u32::from_le_bytes(bytes))
330 }
331
332 fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
333 let mut bytes = [0_u8; 8];
334 self.try_fill_bytes(&mut bytes)?;
335 Ok(u64::from_le_bytes(bytes))
336 }
337
338 fn try_fill_bytes(&mut self, output: &mut [u8]) -> Result<(), Self::Error> {
339 self.0.fill_random(output)
340 }
341}
342
343#[cfg(any(feature = "xmldsig", feature = "xmlenc"))]
344impl TryCryptoRng for ProviderRng<'_> {}
345
346impl CryptoProvider for RustCryptoProvider {
347 fn name(&self) -> &'static str {
348 "rustcrypto"
349 }
350
351 fn supports(&self, query: CapabilityQuery<'_>) -> bool {
352 match query.operation {
353 ProviderOperation::Digest => {
354 #[cfg(feature = "xmldsig")]
355 {
356 query.algorithm.is_none_or(|algorithm| {
357 matches!(
358 algorithm,
359 "http://www.w3.org/2000/09/xmldsig#sha1"
360 | "http://www.w3.org/2001/04/xmlenc#sha256"
361 | "http://www.w3.org/2001/04/xmldsig-more#sha384"
362 | "http://www.w3.org/2001/04/xmlenc#sha512"
363 )
364 })
365 }
366 #[cfg(not(feature = "xmldsig"))]
367 {
368 false
369 }
370 }
371 ProviderOperation::Sign => {
372 #[cfg(feature = "xmldsig")]
373 {
374 query.algorithm.is_none_or(is_supported_signing_uri)
375 }
376 #[cfg(not(feature = "xmldsig"))]
377 {
378 false
379 }
380 }
381 ProviderOperation::Verify => {
382 #[cfg(feature = "xmldsig")]
383 {
384 query.algorithm.is_none_or(is_supported_signature_uri)
385 }
386 #[cfg(not(feature = "xmldsig"))]
387 {
388 false
389 }
390 }
391 ProviderOperation::VerifyCertificate => {
392 #[cfg(feature = "xmldsig")]
393 {
394 query.algorithm.is_none_or(is_supported_x509_signature_oid)
395 }
396 #[cfg(not(feature = "xmldsig"))]
397 {
398 false
399 }
400 }
401 ProviderOperation::Encrypt | ProviderOperation::Decrypt => {
402 #[cfg(feature = "xmlenc")]
403 {
404 query.algorithm.is_none_or(is_supported_data_encryption_uri)
405 }
406 #[cfg(not(feature = "xmlenc"))]
407 {
408 false
409 }
410 }
411 ProviderOperation::KeyWrap | ProviderOperation::KeyUnwrap => {
412 #[cfg(feature = "xmlenc")]
413 {
414 query.algorithm.is_none_or(is_supported_key_wrap_uri)
415 }
416 #[cfg(not(feature = "xmlenc"))]
417 {
418 false
419 }
420 }
421 ProviderOperation::KeyTransport => {
422 #[cfg(feature = "xmlenc")]
423 {
424 query.algorithm.is_none_or(|algorithm| {
425 matches!(
426 algorithm,
427 "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"
428 | "http://www.w3.org/2009/xmlenc11#rsa-oaep"
429 )
430 })
431 }
432 #[cfg(not(feature = "xmlenc"))]
433 {
434 false
435 }
436 }
437 ProviderOperation::Random => true,
438 ProviderOperation::KeyAgreement | ProviderOperation::Kdf => false,
439 }
440 }
441
442 fn fill_random(&self, output: &mut [u8]) -> Result<(), ProviderError> {
443 SysRng
444 .try_fill_bytes(output)
445 .map_err(|error| ProviderError::Random(error.to_string()))
446 }
447
448 #[cfg(feature = "xmldsig")]
449 fn digest(&self, algorithm: DigestAlgorithm, data: &[u8]) -> Result<Vec<u8>, ProviderError> {
450 use sha1::Sha1;
451 use sha2::{Digest, Sha256, Sha384, Sha512};
452 Ok(match algorithm {
453 DigestAlgorithm::Sha1 => Sha1::digest(data).to_vec(),
454 DigestAlgorithm::Sha256 => Sha256::digest(data).to_vec(),
455 DigestAlgorithm::Sha384 => Sha384::digest(data).to_vec(),
456 DigestAlgorithm::Sha512 => Sha512::digest(data).to_vec(),
457 })
458 }
459
460 #[cfg(feature = "xmldsig")]
461 fn sign(
462 &self,
463 key: &dyn crate::xmldsig::SigningKey,
464 algorithm: crate::xmldsig::SignatureAlgorithm,
465 data: &[u8],
466 ) -> Result<Vec<u8>, crate::xmldsig::SigningKeyError> {
467 self.require(ProviderOperation::Sign, Some(algorithm.uri()))?;
468 key.sign_with_provider(self, algorithm, data)
469 }
470
471 #[cfg(feature = "xmldsig")]
472 fn verify(
473 &self,
474 key: &dyn crate::xmldsig::VerifyingKey,
475 algorithm: crate::xmldsig::SignatureAlgorithm,
476 data: &[u8],
477 signature: &[u8],
478 ) -> Result<bool, crate::xmldsig::DsigError> {
479 self.require(ProviderOperation::Verify, Some(algorithm.uri()))?;
480 key.verify(algorithm, data, signature)
481 }
482
483 #[cfg(feature = "xmldsig")]
484 fn verify_x509_signature(
485 &self,
486 algorithm: X509SignatureAlgorithm,
487 signed_data: &[u8],
488 signature: &[u8],
489 issuer_spki_der: &[u8],
490 ) -> Result<bool, ProviderError> {
491 self.require(ProviderOperation::VerifyCertificate, Some(algorithm.oid()))?;
492 rustcrypto_x509::verify_signature(algorithm, signed_data, signature, issuer_spki_der)
493 }
494
495 #[cfg(feature = "xmlenc")]
496 fn encrypt_data(
497 &self,
498 algorithm: DataEncryptionAlgorithm,
499 key: &[u8],
500 plaintext: &[u8],
501 ) -> Result<Vec<u8>, ProviderError> {
502 rustcrypto::encrypt_data(self, algorithm, key, plaintext)
503 }
504
505 #[cfg(feature = "xmlenc")]
506 fn decrypt_data(
507 &self,
508 algorithm: DataEncryptionAlgorithm,
509 key: &[u8],
510 ciphertext: &[u8],
511 ) -> Result<Vec<u8>, ProviderError> {
512 rustcrypto::decrypt_data(algorithm, key, ciphertext)
513 }
514
515 #[cfg(feature = "xmlenc")]
516 fn wrap_key(
517 &self,
518 algorithm: KeyWrapAlgorithm,
519 kek: &[u8],
520 key: &[u8],
521 ) -> Result<Vec<u8>, ProviderError> {
522 rustcrypto::wrap_key(algorithm, kek, key)
523 }
524
525 #[cfg(feature = "xmlenc")]
526 fn unwrap_key(
527 &self,
528 algorithm: KeyWrapAlgorithm,
529 kek: &[u8],
530 wrapped: &[u8],
531 ) -> Result<Vec<u8>, ProviderError> {
532 rustcrypto::unwrap_key(algorithm, kek, wrapped)
533 }
534
535 #[cfg(feature = "xmlenc")]
536 fn transport_key(
537 &self,
538 key: &rsa::RsaPublicKey,
539 parameters: &RsaOaepParameters,
540 plaintext: &[u8],
541 ) -> Result<Vec<u8>, ProviderError> {
542 self.require(
543 ProviderOperation::KeyTransport,
544 Some(parameters.algorithm.uri()),
545 )?;
546 rustcrypto::transport_key(self, key, parameters, plaintext)
547 }
548
549 #[cfg(feature = "xmlenc")]
550 fn recover_key(
551 &self,
552 key: &rsa::RsaPrivateKey,
553 parameters: &RsaOaepParameters,
554 ciphertext: &[u8],
555 ) -> Result<Vec<u8>, ProviderError> {
556 self.require(
557 ProviderOperation::KeyTransport,
558 Some(parameters.algorithm.uri()),
559 )?;
560 rustcrypto::recover_key(self, key, parameters, ciphertext)
561 }
562}
563
564impl RustCryptoProvider {
565 fn require(
566 &self,
567 operation: ProviderOperation,
568 algorithm: Option<&str>,
569 ) -> Result<(), ProviderError> {
570 if self.supports(CapabilityQuery {
571 operation,
572 algorithm,
573 }) {
574 Ok(())
575 } else {
576 Err(ProviderError::Unsupported {
577 operation,
578 algorithm: algorithm.map(str::to_owned),
579 })
580 }
581 }
582}
583
584#[cfg(feature = "xmldsig")]
585fn is_supported_signature_uri(algorithm: &str) -> bool {
586 matches!(
587 algorithm,
588 "http://www.w3.org/2000/09/xmldsig#dsa-sha1"
589 | "http://www.w3.org/2000/09/xmldsig#hmac-sha1"
590 | "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
591 | "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
592 | "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"
593 | "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
594 | "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"
595 | "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"
596 )
597}
598
599#[cfg(feature = "xmldsig")]
600fn is_supported_signing_uri(algorithm: &str) -> bool {
601 matches!(
602 algorithm,
603 "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
604 | "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"
605 | "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
606 | "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"
607 | "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"
608 )
609}
610
611#[cfg(feature = "xmldsig")]
612fn is_supported_x509_signature_oid(algorithm: &str) -> bool {
613 matches!(
614 algorithm,
615 "1.2.840.10040.4.3"
616 | "1.2.840.113549.1.1.5"
617 | "1.3.14.3.2.29"
618 | "1.2.840.113549.1.1.10"
619 | "1.2.840.113549.1.1.11"
620 | "1.2.840.113549.1.1.12"
621 | "1.2.840.113549.1.1.13"
622 | "1.2.840.10045.4.3.2"
623 | "1.2.840.10045.4.3.3"
624 | "1.3.101.112"
625 )
626}
627
628#[cfg(feature = "xmldsig")]
629mod rustcrypto_x509 {
630 use der::Decode as _;
631 use dsa::pkcs8::DecodePublicKey as _;
632 use rsa::{
633 RsaPublicKey,
634 pkcs1::DecodeRsaPublicKey as _,
635 pss::{Signature as RsaPssSignature, VerifyingKey as RsaPssVerifyingKey},
636 };
637 use sha1::Digest as _;
638 use sha2::{Sha256, Sha384, Sha512};
639 use signature::{Verifier as _, hazmat::PrehashVerifier as _};
640 use x509_parser::prelude::FromDer as _;
641
642 use super::{ProviderError, X509SignatureAlgorithm};
643 use crate::xmldsig::{
644 DigestAlgorithm, DsigError, SignatureAlgorithm, VerificationKey, VerifyingKey as _,
645 };
646
647 pub(super) fn verify_signature(
648 algorithm: X509SignatureAlgorithm,
649 signed_data: &[u8],
650 signature: &[u8],
651 issuer_spki_der: &[u8],
652 ) -> Result<bool, ProviderError> {
653 match algorithm {
654 X509SignatureAlgorithm::Dsa(DigestAlgorithm::Sha1) => {
655 let Ok(key) = dsa::VerifyingKey::from_public_key_der(issuer_spki_der) else {
659 return Ok(false);
660 };
661 let Ok(signature) = dsa::Signature::from_der(signature) else {
662 return Ok(false);
663 };
664 let digest = sha1::Sha1::digest(signed_data);
665 Ok(key.verify_prehash(&digest, &signature).is_ok())
666 }
667 X509SignatureAlgorithm::RsaPkcs1v15(digest) => {
668 let Some(algorithm) = rsa_pkcs1_algorithm(digest) else {
669 return unsupported(X509SignatureAlgorithm::RsaPkcs1v15(digest));
670 };
671 verify_xml_signature(algorithm, signed_data, signature, issuer_spki_der)
672 }
673 X509SignatureAlgorithm::Ecdsa(digest) => {
674 let Some(algorithm) = ecdsa_algorithm(digest) else {
675 return unsupported(X509SignatureAlgorithm::Ecdsa(digest));
676 };
677 verify_xml_signature(algorithm, signed_data, signature, issuer_spki_der)
678 }
679 X509SignatureAlgorithm::RsaPss {
680 digest,
681 mgf_digest,
682 salt_len,
683 } => {
684 let Some(key) = compatible_rsa_pss_public_key_from_spki(issuer_spki_der, algorithm)
688 else {
689 return Ok(false);
690 };
691 if digest != mgf_digest {
692 return unsupported(algorithm);
693 }
694 verify_rsa_pss(digest, salt_len, signed_data, signature, key)
695 }
696 X509SignatureAlgorithm::Ed25519 => {
697 let Ok(key) = ed25519_dalek::VerifyingKey::from_public_key_der(issuer_spki_der)
698 else {
699 return Ok(false);
700 };
701 let Ok(signature) = ed25519_dalek::Signature::try_from(signature) else {
702 return Ok(false);
703 };
704 Ok(key.verify_strict(signed_data, &signature).is_ok())
705 }
706 _ => unsupported(algorithm),
707 }
708 }
709
710 fn verify_xml_signature(
711 algorithm: SignatureAlgorithm,
712 signed_data: &[u8],
713 signature: &[u8],
714 issuer_spki_der: &[u8],
715 ) -> Result<bool, ProviderError> {
716 let key = VerificationKey {
717 algorithm,
718 public_key_bytes: issuer_spki_der.to_vec(),
719 certificate_der: None,
720 name: None,
721 };
722 match key.verify(algorithm, signed_data, signature) {
723 Ok(verified) => Ok(verified),
724 Err(DsigError::Provider(error)) => Err(error),
725 Err(_) => Ok(false),
726 }
727 }
728
729 fn verify_rsa_pss(
730 digest: DigestAlgorithm,
731 salt_len: usize,
732 signed_data: &[u8],
733 signature: &[u8],
734 key: RsaPublicKey,
735 ) -> Result<bool, ProviderError> {
736 let Ok(signature) = RsaPssSignature::try_from(signature) else {
737 return Ok(false);
738 };
739 let verified = match digest {
740 DigestAlgorithm::Sha256 => {
741 RsaPssVerifyingKey::<Sha256>::new_with_salt_len(key, salt_len)
742 .verify(signed_data, &signature)
743 }
744 DigestAlgorithm::Sha384 => {
745 RsaPssVerifyingKey::<Sha384>::new_with_salt_len(key, salt_len)
746 .verify(signed_data, &signature)
747 }
748 DigestAlgorithm::Sha512 => {
749 RsaPssVerifyingKey::<Sha512>::new_with_salt_len(key, salt_len)
750 .verify(signed_data, &signature)
751 }
752 DigestAlgorithm::Sha1 => {
753 return unsupported(X509SignatureAlgorithm::RsaPss {
754 digest,
755 mgf_digest: digest,
756 salt_len,
757 });
758 }
759 };
760 Ok(verified.is_ok())
761 }
762
763 fn compatible_rsa_pss_public_key_from_spki(
764 spki_der: &[u8],
765 signature_algorithm: X509SignatureAlgorithm,
766 ) -> Option<RsaPublicKey> {
767 let (_, spki) = x509_parser::x509::SubjectPublicKeyInfo::from_der(spki_der).ok()?;
768 match spki.algorithm.algorithm.to_id_string().as_str() {
769 "1.2.840.113549.1.1.1" => RsaPublicKey::from_public_key_der(spki_der).ok(),
770 "1.2.840.113549.1.1.10" => {
771 if spki
774 .algorithm
775 .parameters
776 .as_ref()
777 .is_some_and(|parameters| {
778 !rsa_pss_key_parameters_allow(parameters, signature_algorithm)
779 })
780 {
781 return None;
782 }
783 RsaPublicKey::from_pkcs1_der(&spki.subject_public_key.data).ok()
784 }
785 _ => None,
786 }
787 }
788
789 fn rsa_pss_key_parameters_allow(
790 parameters: &x509_parser::asn1_rs::Any<'_>,
791 signature_algorithm: X509SignatureAlgorithm,
792 ) -> bool {
793 let X509SignatureAlgorithm::RsaPss {
794 digest,
795 mgf_digest,
796 salt_len,
797 } = signature_algorithm
798 else {
799 return false;
800 };
801 let Ok(parameters) =
802 x509_parser::signature_algorithm::RsaSsaPssParams::try_from(parameters)
803 else {
804 return false;
805 };
806 let Ok(mask) = parameters.mask_gen_algorithm() else {
807 return false;
808 };
809 parameters.trailer_field() == 1
810 && x509_digest_from_oid(¶meters.hash_algorithm_oid().to_id_string()) == Some(digest)
811 && mask.mgf.to_id_string() == "1.2.840.113549.1.1.8"
812 && x509_digest_from_oid(&mask.hash.to_id_string()) == Some(mgf_digest)
813 && usize::try_from(parameters.salt_length()).is_ok_and(|minimum| salt_len >= minimum)
814 }
815
816 fn x509_digest_from_oid(oid: &str) -> Option<DigestAlgorithm> {
817 match oid {
818 "1.3.14.3.2.26" => Some(DigestAlgorithm::Sha1),
819 "2.16.840.1.101.3.4.2.1" => Some(DigestAlgorithm::Sha256),
820 "2.16.840.1.101.3.4.2.2" => Some(DigestAlgorithm::Sha384),
821 "2.16.840.1.101.3.4.2.3" => Some(DigestAlgorithm::Sha512),
822 _ => None,
823 }
824 }
825
826 const fn rsa_pkcs1_algorithm(digest: DigestAlgorithm) -> Option<SignatureAlgorithm> {
827 match digest {
828 DigestAlgorithm::Sha1 => Some(SignatureAlgorithm::RsaSha1),
829 DigestAlgorithm::Sha256 => Some(SignatureAlgorithm::RsaSha256),
830 DigestAlgorithm::Sha384 => Some(SignatureAlgorithm::RsaSha384),
831 DigestAlgorithm::Sha512 => Some(SignatureAlgorithm::RsaSha512),
832 }
833 }
834
835 const fn ecdsa_algorithm(digest: DigestAlgorithm) -> Option<SignatureAlgorithm> {
836 match digest {
837 DigestAlgorithm::Sha256 => Some(SignatureAlgorithm::EcdsaSha256),
838 DigestAlgorithm::Sha384 => Some(SignatureAlgorithm::EcdsaSha384),
839 DigestAlgorithm::Sha1 | DigestAlgorithm::Sha512 => None,
840 }
841 }
842
843 fn unsupported<T>(algorithm: X509SignatureAlgorithm) -> Result<T, ProviderError> {
844 Err(ProviderError::Unsupported {
845 operation: super::ProviderOperation::VerifyCertificate,
846 algorithm: Some(algorithm.oid().to_owned()),
847 })
848 }
849}
850
851#[cfg(feature = "xmlenc")]
852fn is_supported_data_encryption_uri(algorithm: &str) -> bool {
853 matches!(
854 algorithm,
855 "http://www.w3.org/2001/04/xmlenc#aes128-cbc"
856 | "http://www.w3.org/2001/04/xmlenc#aes256-cbc"
857 | "http://www.w3.org/2009/xmlenc11#aes128-gcm"
858 | "http://www.w3.org/2009/xmlenc11#aes256-gcm"
859 )
860}
861
862#[cfg(feature = "xmlenc")]
863fn is_supported_key_wrap_uri(algorithm: &str) -> bool {
864 matches!(
865 algorithm,
866 "http://www.w3.org/2001/04/xmlenc#kw-aes128" | "http://www.w3.org/2001/04/xmlenc#kw-aes256"
867 )
868}
869
870#[cfg(feature = "xmlenc")]
871mod rustcrypto {
872 use aes::{
873 Aes128, Aes256,
874 cipher::{BlockModeDecrypt, BlockModeEncrypt, KeyIvInit, block_padding::NoPadding},
875 };
876 use aes_gcm::{
877 Aes128Gcm, Aes256Gcm, Nonce,
878 aead::{AeadInOut, KeyInit},
879 };
880 use aes_kw::{KwAes128, KwAes256};
881 use cbc::{Decryptor, Encryptor};
882 use rsa::{Oaep, traits::PaddingScheme};
883 use sha1::Sha1;
884 use sha2::{Sha256, Sha384, Sha512};
885
886 use super::{CryptoProvider, ProviderError, ProviderInputError};
887 use crate::xmlenc::{
888 DataEncryptionAlgorithm, KeyTransportAlgorithm, KeyWrapAlgorithm, OaepDigestAlgorithm,
889 RsaOaepParameters,
890 };
891
892 pub(super) fn encrypt_data(
893 provider: &dyn CryptoProvider,
894 algorithm: DataEncryptionAlgorithm,
895 key: &[u8],
896 plaintext: &[u8],
897 ) -> Result<Vec<u8>, ProviderError> {
898 check_key(algorithm.key_len(), key)?;
899 match algorithm {
900 DataEncryptionAlgorithm::Aes128Cbc => encrypt_cbc::<Aes128>(provider, key, plaintext),
901 DataEncryptionAlgorithm::Aes256Cbc => encrypt_cbc::<Aes256>(provider, key, plaintext),
902 DataEncryptionAlgorithm::Aes128Gcm => {
903 encrypt_gcm::<Aes128Gcm>(provider, key, plaintext)
904 }
905 DataEncryptionAlgorithm::Aes256Gcm => {
906 encrypt_gcm::<Aes256Gcm>(provider, key, plaintext)
907 }
908 }
909 }
910
911 pub(super) fn decrypt_data(
912 algorithm: DataEncryptionAlgorithm,
913 key: &[u8],
914 ciphertext: &[u8],
915 ) -> Result<Vec<u8>, ProviderError> {
916 check_key(algorithm.key_len(), key)?;
917 match algorithm {
918 DataEncryptionAlgorithm::Aes128Cbc => decrypt_cbc::<Aes128>(key, ciphertext),
919 DataEncryptionAlgorithm::Aes256Cbc => decrypt_cbc::<Aes256>(key, ciphertext),
920 DataEncryptionAlgorithm::Aes128Gcm => decrypt_gcm::<Aes128Gcm>(key, ciphertext),
921 DataEncryptionAlgorithm::Aes256Gcm => decrypt_gcm::<Aes256Gcm>(key, ciphertext),
922 }
923 }
924
925 fn check_key(expected: usize, key: &[u8]) -> Result<(), ProviderError> {
926 if key.len() == expected {
927 Ok(())
928 } else {
929 Err(ProviderError::InvalidKeySize {
930 expected,
931 actual: key.len(),
932 })
933 }
934 }
935
936 fn encrypt_cbc<C>(
937 provider: &dyn CryptoProvider,
938 key: &[u8],
939 plaintext: &[u8],
940 ) -> Result<Vec<u8>, ProviderError>
941 where
942 C: aes::cipher::BlockCipherEncrypt + aes::cipher::KeyInit,
943 {
944 let mut iv = [0_u8; 16];
945 provider.fill_random(&mut iv)?;
946 let pad_len = 16 - (plaintext.len() % 16);
947 let mut padded = vec![0_u8; plaintext.len() + pad_len];
948 padded[..plaintext.len()].copy_from_slice(plaintext);
949 if pad_len > 1 {
950 let last = padded.len() - 1;
951 provider.fill_random(&mut padded[plaintext.len()..last])?;
952 }
953 *padded.last_mut().expect("padding is non-empty") = pad_len as u8;
954 Encryptor::<C>::new_from_slices(key, &iv)
955 .map_err(|_| {
956 ProviderError::InvalidInput(ProviderInputError::PrimitiveInitialization("AES-CBC"))
957 })?
958 .encrypt_padded::<NoPadding>(&mut padded, plaintext.len() + pad_len)
959 .map_err(|_| {
960 ProviderError::InvalidInput(ProviderInputError::PrimitiveInitialization(
961 "AES-CBC padding",
962 ))
963 })?;
964 let mut output = Vec::with_capacity(16 + padded.len());
965 output.extend_from_slice(&iv);
966 output.extend_from_slice(&padded);
967 Ok(output)
968 }
969
970 fn decrypt_cbc<C>(key: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, ProviderError>
971 where
972 C: aes::cipher::BlockCipherDecrypt + aes::cipher::KeyInit,
973 {
974 if ciphertext.len() < 32 || !(ciphertext.len() - 16).is_multiple_of(16) {
975 return Err(ProviderError::InvalidInput(
976 ProviderInputError::AesCbcFraming,
977 ));
978 }
979 let (iv, body) = ciphertext.split_at(16);
980 let mut plaintext = body.to_vec();
981 Decryptor::<C>::new_from_slices(key, iv)
982 .map_err(|_| {
983 ProviderError::InvalidInput(ProviderInputError::PrimitiveInitialization("AES-CBC"))
984 })?
985 .decrypt_padded::<NoPadding>(&mut plaintext)
986 .map_err(|_| ProviderError::InvalidInput(ProviderInputError::AesCbcCiphertext))?;
987 let pad_len = *plaintext.last().ok_or(ProviderError::InvalidInput(
988 ProviderInputError::AesCbcCiphertext,
989 ))?;
990 let padding_bytes = usize::from(pad_len);
991 if !(1..=16).contains(&padding_bytes) || padding_bytes > plaintext.len() {
992 return Err(ProviderError::InvalidInput(
993 ProviderInputError::AesCbcCiphertext,
994 ));
995 }
996 plaintext.truncate(plaintext.len() - padding_bytes);
997 Ok(plaintext)
998 }
999
1000 fn encrypt_gcm<C>(
1001 provider: &dyn CryptoProvider,
1002 key: &[u8],
1003 plaintext: &[u8],
1004 ) -> Result<Vec<u8>, ProviderError>
1005 where
1006 C: AeadInOut + KeyInit,
1007 {
1008 let mut nonce = [0_u8; 12];
1009 provider.fill_random(&mut nonce)?;
1010 let cipher = C::new_from_slice(key).map_err(|_| {
1011 ProviderError::InvalidInput(ProviderInputError::PrimitiveInitialization("AES-GCM"))
1012 })?;
1013 let mut output = plaintext.to_vec();
1014 let nonce = Nonce::try_from(nonce.as_slice()).map_err(|_| {
1015 ProviderError::InvalidInput(ProviderInputError::PrimitiveInitialization(
1016 "AES-GCM nonce",
1017 ))
1018 })?;
1019 cipher
1020 .encrypt_in_place(&nonce, &[], &mut output)
1021 .map_err(|_| ProviderError::AuthenticationFailed)?;
1022 let mut framed = Vec::with_capacity(12 + output.len());
1023 framed.extend_from_slice(&nonce);
1024 framed.extend_from_slice(&output);
1025 Ok(framed)
1026 }
1027
1028 fn decrypt_gcm<C>(key: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, ProviderError>
1029 where
1030 C: AeadInOut + KeyInit,
1031 {
1032 if ciphertext.len() < 28 {
1033 return Err(ProviderError::InvalidInput(
1034 ProviderInputError::AesGcmFraming,
1035 ));
1036 }
1037 let (nonce, body) = ciphertext.split_at(12);
1038 let cipher = C::new_from_slice(key).map_err(|_| {
1039 ProviderError::InvalidInput(ProviderInputError::PrimitiveInitialization("AES-GCM"))
1040 })?;
1041 let mut plaintext = body.to_vec();
1042 let nonce = Nonce::try_from(nonce).map_err(|_| {
1043 ProviderError::InvalidInput(ProviderInputError::PrimitiveInitialization(
1044 "AES-GCM nonce",
1045 ))
1046 })?;
1047 cipher
1048 .decrypt_in_place(&nonce, &[], &mut plaintext)
1049 .map_err(|_| ProviderError::AuthenticationFailed)?;
1050 Ok(plaintext)
1051 }
1052
1053 pub(super) fn wrap_key(
1054 algorithm: KeyWrapAlgorithm,
1055 kek: &[u8],
1056 key: &[u8],
1057 ) -> Result<Vec<u8>, ProviderError> {
1058 check_key(algorithm.key_len(), kek)?;
1059 let mut output = vec![0_u8; key.len() + 8];
1060 match algorithm {
1061 KeyWrapAlgorithm::AesKw128 => KwAes128::new_from_slice(kek)
1062 .map_err(|_| ProviderError::InvalidKeySize {
1063 expected: 16,
1064 actual: kek.len(),
1065 })?
1066 .wrap_key(key, &mut output),
1067 KeyWrapAlgorithm::AesKw256 => KwAes256::new_from_slice(kek)
1068 .map_err(|_| ProviderError::InvalidKeySize {
1069 expected: 32,
1070 actual: kek.len(),
1071 })?
1072 .wrap_key(key, &mut output),
1073 }
1074 .map_err(|_| ProviderError::InvalidInput(ProviderInputError::AesKeyWrapFraming))?;
1075 Ok(output)
1076 }
1077
1078 pub(super) fn unwrap_key(
1079 algorithm: KeyWrapAlgorithm,
1080 kek: &[u8],
1081 wrapped: &[u8],
1082 ) -> Result<Vec<u8>, ProviderError> {
1083 check_key(algorithm.key_len(), kek)?;
1084 if wrapped.len() < 16 || !wrapped.len().is_multiple_of(8) {
1085 return Err(ProviderError::InvalidInput(
1086 ProviderInputError::AesKeyWrapFraming,
1087 ));
1088 }
1089 let mut output = vec![0_u8; wrapped.len() - 8];
1090 let key = match algorithm {
1091 KeyWrapAlgorithm::AesKw128 => KwAes128::new_from_slice(kek)
1092 .map_err(|_| ProviderError::InvalidKeySize {
1093 expected: 16,
1094 actual: kek.len(),
1095 })?
1096 .unwrap_key(wrapped, &mut output),
1097 KeyWrapAlgorithm::AesKw256 => KwAes256::new_from_slice(kek)
1098 .map_err(|_| ProviderError::InvalidKeySize {
1099 expected: 32,
1100 actual: kek.len(),
1101 })?
1102 .unwrap_key(wrapped, &mut output),
1103 }
1104 .map_err(|_| ProviderError::AuthenticationFailed)?;
1105 Ok(key.to_vec())
1106 }
1107
1108 pub(super) fn transport_key(
1109 provider: &dyn CryptoProvider,
1110 key: &rsa::RsaPublicKey,
1111 parameters: &RsaOaepParameters,
1112 plaintext: &[u8],
1113 ) -> Result<Vec<u8>, ProviderError> {
1114 if parameters.algorithm == KeyTransportAlgorithm::RsaOaepMgf1p
1115 && parameters.mgf_digest != OaepDigestAlgorithm::Sha1
1116 {
1117 return Err(ProviderError::InvalidInput(
1118 ProviderInputError::LegacyRsaOaepMgf,
1119 ));
1120 }
1121 let mut rng = super::ProviderRng(provider);
1122 macro_rules! encrypt_with {
1123 ($digest:ty, $mgf:ty) => {
1124 Oaep::<$digest, $mgf>::new_with_mgf_hash_and_label(parameters.label.clone())
1125 .encrypt(&mut rng, key, plaintext)
1126 };
1127 }
1128 let result = match (parameters.digest, parameters.mgf_digest) {
1129 (OaepDigestAlgorithm::Sha1, OaepDigestAlgorithm::Sha1) => {
1130 encrypt_with!(Sha1, Sha1)
1131 }
1132 (OaepDigestAlgorithm::Sha1, OaepDigestAlgorithm::Sha256) => {
1133 encrypt_with!(Sha1, Sha256)
1134 }
1135 (OaepDigestAlgorithm::Sha1, OaepDigestAlgorithm::Sha384) => {
1136 encrypt_with!(Sha1, Sha384)
1137 }
1138 (OaepDigestAlgorithm::Sha1, OaepDigestAlgorithm::Sha512) => {
1139 encrypt_with!(Sha1, Sha512)
1140 }
1141 (OaepDigestAlgorithm::Sha256, OaepDigestAlgorithm::Sha1) => {
1142 encrypt_with!(Sha256, Sha1)
1143 }
1144 (OaepDigestAlgorithm::Sha256, OaepDigestAlgorithm::Sha256) => {
1145 encrypt_with!(Sha256, Sha256)
1146 }
1147 (OaepDigestAlgorithm::Sha256, OaepDigestAlgorithm::Sha384) => {
1148 encrypt_with!(Sha256, Sha384)
1149 }
1150 (OaepDigestAlgorithm::Sha256, OaepDigestAlgorithm::Sha512) => {
1151 encrypt_with!(Sha256, Sha512)
1152 }
1153 (OaepDigestAlgorithm::Sha384, OaepDigestAlgorithm::Sha1) => {
1154 encrypt_with!(Sha384, Sha1)
1155 }
1156 (OaepDigestAlgorithm::Sha384, OaepDigestAlgorithm::Sha256) => {
1157 encrypt_with!(Sha384, Sha256)
1158 }
1159 (OaepDigestAlgorithm::Sha384, OaepDigestAlgorithm::Sha384) => {
1160 encrypt_with!(Sha384, Sha384)
1161 }
1162 (OaepDigestAlgorithm::Sha384, OaepDigestAlgorithm::Sha512) => {
1163 encrypt_with!(Sha384, Sha512)
1164 }
1165 (OaepDigestAlgorithm::Sha512, OaepDigestAlgorithm::Sha1) => {
1166 encrypt_with!(Sha512, Sha1)
1167 }
1168 (OaepDigestAlgorithm::Sha512, OaepDigestAlgorithm::Sha256) => {
1169 encrypt_with!(Sha512, Sha256)
1170 }
1171 (OaepDigestAlgorithm::Sha512, OaepDigestAlgorithm::Sha384) => {
1172 encrypt_with!(Sha512, Sha384)
1173 }
1174 (OaepDigestAlgorithm::Sha512, OaepDigestAlgorithm::Sha512) => {
1175 encrypt_with!(Sha512, Sha512)
1176 }
1177 };
1178 result.map_err(map_rsa_error)
1179 }
1180
1181 pub(super) fn recover_key(
1182 provider: &dyn CryptoProvider,
1183 key: &rsa::RsaPrivateKey,
1184 parameters: &RsaOaepParameters,
1185 ciphertext: &[u8],
1186 ) -> Result<Vec<u8>, ProviderError> {
1187 if parameters.algorithm == KeyTransportAlgorithm::RsaOaepMgf1p
1188 && parameters.mgf_digest != OaepDigestAlgorithm::Sha1
1189 {
1190 return Err(ProviderError::InvalidInput(
1191 ProviderInputError::LegacyRsaOaepMgf,
1192 ));
1193 }
1194 let mut rng = super::ProviderRng(provider);
1195 macro_rules! decrypt_with {
1196 ($digest:ty, $mgf:ty) => {
1197 Oaep::<$digest, $mgf>::new_with_mgf_hash_and_label(parameters.label.clone())
1198 .decrypt(Some(&mut rng), key, ciphertext)
1199 };
1200 }
1201 let result = match (parameters.digest, parameters.mgf_digest) {
1202 (OaepDigestAlgorithm::Sha1, OaepDigestAlgorithm::Sha1) => {
1203 decrypt_with!(Sha1, Sha1)
1204 }
1205 (OaepDigestAlgorithm::Sha1, OaepDigestAlgorithm::Sha256) => {
1206 decrypt_with!(Sha1, Sha256)
1207 }
1208 (OaepDigestAlgorithm::Sha1, OaepDigestAlgorithm::Sha384) => {
1209 decrypt_with!(Sha1, Sha384)
1210 }
1211 (OaepDigestAlgorithm::Sha1, OaepDigestAlgorithm::Sha512) => {
1212 decrypt_with!(Sha1, Sha512)
1213 }
1214 (OaepDigestAlgorithm::Sha256, OaepDigestAlgorithm::Sha1) => {
1215 decrypt_with!(Sha256, Sha1)
1216 }
1217 (OaepDigestAlgorithm::Sha256, OaepDigestAlgorithm::Sha256) => {
1218 decrypt_with!(Sha256, Sha256)
1219 }
1220 (OaepDigestAlgorithm::Sha256, OaepDigestAlgorithm::Sha384) => {
1221 decrypt_with!(Sha256, Sha384)
1222 }
1223 (OaepDigestAlgorithm::Sha256, OaepDigestAlgorithm::Sha512) => {
1224 decrypt_with!(Sha256, Sha512)
1225 }
1226 (OaepDigestAlgorithm::Sha384, OaepDigestAlgorithm::Sha1) => {
1227 decrypt_with!(Sha384, Sha1)
1228 }
1229 (OaepDigestAlgorithm::Sha384, OaepDigestAlgorithm::Sha256) => {
1230 decrypt_with!(Sha384, Sha256)
1231 }
1232 (OaepDigestAlgorithm::Sha384, OaepDigestAlgorithm::Sha384) => {
1233 decrypt_with!(Sha384, Sha384)
1234 }
1235 (OaepDigestAlgorithm::Sha384, OaepDigestAlgorithm::Sha512) => {
1236 decrypt_with!(Sha384, Sha512)
1237 }
1238 (OaepDigestAlgorithm::Sha512, OaepDigestAlgorithm::Sha1) => {
1239 decrypt_with!(Sha512, Sha1)
1240 }
1241 (OaepDigestAlgorithm::Sha512, OaepDigestAlgorithm::Sha256) => {
1242 decrypt_with!(Sha512, Sha256)
1243 }
1244 (OaepDigestAlgorithm::Sha512, OaepDigestAlgorithm::Sha384) => {
1245 decrypt_with!(Sha512, Sha384)
1246 }
1247 (OaepDigestAlgorithm::Sha512, OaepDigestAlgorithm::Sha512) => {
1248 decrypt_with!(Sha512, Sha512)
1249 }
1250 };
1251 result.map_err(map_rsa_error)
1252 }
1253
1254 fn map_rsa_error(error: rsa::Error) -> ProviderError {
1255 match error {
1256 rsa::Error::Rng => ProviderError::Random("RSA-OAEP randomness failed".into()),
1257 _ => ProviderError::AuthenticationFailed,
1258 }
1259 }
1260}
1261
1262#[cfg(test)]
1263mod tests {
1264 #[cfg(feature = "xmldsig")]
1265 use std::sync::atomic::{AtomicUsize, Ordering};
1266
1267 use super::*;
1268
1269 #[cfg(feature = "xmldsig")]
1270 struct CountingRandomProvider {
1271 random_calls: AtomicUsize,
1272 reject_digest: Option<DigestAlgorithm>,
1273 extra_digest_byte: bool,
1274 accept_signatures: bool,
1275 }
1276
1277 #[cfg(feature = "xmldsig")]
1278 impl CryptoProvider for CountingRandomProvider {
1279 fn name(&self) -> &'static str {
1280 "counting-random"
1281 }
1282
1283 fn supports(&self, query: CapabilityQuery<'_>) -> bool {
1284 RUST_CRYPTO_PROVIDER.supports(query)
1285 }
1286
1287 fn fill_random(&self, output: &mut [u8]) -> Result<(), ProviderError> {
1288 self.random_calls.fetch_add(1, Ordering::Relaxed);
1289 RUST_CRYPTO_PROVIDER.fill_random(output)
1290 }
1291
1292 fn digest(
1293 &self,
1294 algorithm: DigestAlgorithm,
1295 data: &[u8],
1296 ) -> Result<Vec<u8>, ProviderError> {
1297 if self.reject_digest == Some(algorithm) {
1298 return Err(ProviderError::Unsupported {
1299 operation: ProviderOperation::Digest,
1300 algorithm: Some(algorithm.uri().to_owned()),
1301 });
1302 }
1303 let mut digest = RUST_CRYPTO_PROVIDER.digest(algorithm, data)?;
1304 if self.extra_digest_byte {
1305 digest.push(0);
1306 }
1307 Ok(digest)
1308 }
1309
1310 fn sign(
1311 &self,
1312 key: &dyn crate::xmldsig::SigningKey,
1313 algorithm: crate::xmldsig::SignatureAlgorithm,
1314 data: &[u8],
1315 ) -> Result<Vec<u8>, crate::xmldsig::SigningKeyError> {
1316 key.sign_with_provider(self, algorithm, data)
1317 }
1318
1319 fn verify(
1320 &self,
1321 key: &dyn crate::xmldsig::VerifyingKey,
1322 algorithm: crate::xmldsig::SignatureAlgorithm,
1323 data: &[u8],
1324 signature: &[u8],
1325 ) -> Result<bool, crate::xmldsig::DsigError> {
1326 if self.accept_signatures {
1327 return Ok(true);
1328 }
1329 RUST_CRYPTO_PROVIDER.verify(key, algorithm, data, signature)
1330 }
1331
1332 #[cfg(feature = "xmlenc")]
1333 fn encrypt_data(
1334 &self,
1335 algorithm: DataEncryptionAlgorithm,
1336 key: &[u8],
1337 plaintext: &[u8],
1338 ) -> Result<Vec<u8>, ProviderError> {
1339 RUST_CRYPTO_PROVIDER.encrypt_data(algorithm, key, plaintext)
1340 }
1341
1342 #[cfg(feature = "xmlenc")]
1343 fn decrypt_data(
1344 &self,
1345 algorithm: DataEncryptionAlgorithm,
1346 key: &[u8],
1347 ciphertext: &[u8],
1348 ) -> Result<Vec<u8>, ProviderError> {
1349 RUST_CRYPTO_PROVIDER.decrypt_data(algorithm, key, ciphertext)
1350 }
1351
1352 #[cfg(feature = "xmlenc")]
1353 fn wrap_key(
1354 &self,
1355 algorithm: KeyWrapAlgorithm,
1356 kek: &[u8],
1357 key: &[u8],
1358 ) -> Result<Vec<u8>, ProviderError> {
1359 RUST_CRYPTO_PROVIDER.wrap_key(algorithm, kek, key)
1360 }
1361
1362 #[cfg(feature = "xmlenc")]
1363 fn unwrap_key(
1364 &self,
1365 algorithm: KeyWrapAlgorithm,
1366 kek: &[u8],
1367 wrapped: &[u8],
1368 ) -> Result<Vec<u8>, ProviderError> {
1369 RUST_CRYPTO_PROVIDER.unwrap_key(algorithm, kek, wrapped)
1370 }
1371
1372 #[cfg(feature = "xmlenc")]
1373 fn transport_key(
1374 &self,
1375 key: &rsa::RsaPublicKey,
1376 parameters: &RsaOaepParameters,
1377 plaintext: &[u8],
1378 ) -> Result<Vec<u8>, ProviderError> {
1379 RUST_CRYPTO_PROVIDER.transport_key(key, parameters, plaintext)
1380 }
1381
1382 #[cfg(feature = "xmlenc")]
1383 fn recover_key(
1384 &self,
1385 key: &rsa::RsaPrivateKey,
1386 parameters: &RsaOaepParameters,
1387 ciphertext: &[u8],
1388 ) -> Result<Vec<u8>, ProviderError> {
1389 RUST_CRYPTO_PROVIDER.recover_key(key, parameters, ciphertext)
1390 }
1391 }
1392
1393 #[test]
1394 fn capability_query_is_explicit_about_unimplemented_operations() {
1395 assert!(RUST_CRYPTO_PROVIDER.supports(CapabilityQuery {
1396 operation: ProviderOperation::Digest,
1397 algorithm: None
1398 }));
1399 assert!(!RUST_CRYPTO_PROVIDER.supports(CapabilityQuery {
1400 operation: ProviderOperation::KeyAgreement,
1401 algorithm: None
1402 }));
1403 assert!(!RUST_CRYPTO_PROVIDER.supports(CapabilityQuery {
1404 operation: ProviderOperation::Sign,
1405 algorithm: Some("http://www.w3.org/2000/09/xmldsig#rsa-sha1")
1406 }));
1407 assert!(RUST_CRYPTO_PROVIDER.supports(CapabilityQuery {
1408 operation: ProviderOperation::Verify,
1409 algorithm: Some("http://www.w3.org/2000/09/xmldsig#rsa-sha1")
1410 }));
1411 assert!(!RUST_CRYPTO_PROVIDER.supports(CapabilityQuery {
1412 operation: ProviderOperation::Verify,
1413 algorithm: Some("urn:unsupported:signature"),
1414 }));
1415 }
1416
1417 #[cfg(not(feature = "xmlenc"))]
1418 #[test]
1419 fn capability_query_hides_xmlenc_operations_when_feature_is_disabled() {
1420 for operation in [
1423 ProviderOperation::Encrypt,
1424 ProviderOperation::Decrypt,
1425 ProviderOperation::KeyWrap,
1426 ProviderOperation::KeyUnwrap,
1427 ProviderOperation::KeyTransport,
1428 ] {
1429 assert!(!RUST_CRYPTO_PROVIDER.supports(CapabilityQuery {
1430 operation,
1431 algorithm: None,
1432 }));
1433 }
1434 }
1435
1436 #[cfg(not(feature = "xmldsig"))]
1437 #[test]
1438 fn capability_query_hides_xmldsig_operations_when_feature_is_disabled() {
1439 for operation in [
1441 ProviderOperation::Digest,
1442 ProviderOperation::Sign,
1443 ProviderOperation::Verify,
1444 ] {
1445 assert!(!RUST_CRYPTO_PROVIDER.supports(CapabilityQuery {
1446 operation,
1447 algorithm: None,
1448 }));
1449 }
1450 }
1451
1452 #[cfg(feature = "xmldsig")]
1453 #[test]
1454 fn rsa_signing_uses_the_selected_providers_randomness() {
1455 use crate::xmldsig::{RsaSigningKey, SignatureAlgorithm};
1456
1457 let key = RsaSigningKey::from_pkcs8_pem(include_str!(
1460 "../tests/fixtures/keys/rsa/rsa-2048-key.pem"
1461 ))
1462 .expect("RSA fixture must parse");
1463 let provider = CountingRandomProvider {
1464 random_calls: AtomicUsize::new(0),
1465 reject_digest: None,
1466 extra_digest_byte: false,
1467 accept_signatures: false,
1468 };
1469
1470 let signature = provider
1471 .sign(&key, SignatureAlgorithm::RsaSha256, b"signed info")
1472 .expect("RSA signing must succeed");
1473
1474 assert!(!signature.is_empty());
1475 assert!(provider.random_calls.load(Ordering::Relaxed) > 0);
1476 }
1477
1478 #[cfg(feature = "xmldsig")]
1479 #[test]
1480 fn ecdsa_signing_uses_the_selected_providers_digest() {
1481 use crate::xmldsig::{
1482 EcdsaP256SigningKey, EcdsaP384SigningKey, SignatureAlgorithm, SigningKeyError,
1483 };
1484
1485 let cases: [(
1489 Box<dyn crate::xmldsig::SigningKey>,
1490 SignatureAlgorithm,
1491 DigestAlgorithm,
1492 ); 2] = [
1493 (
1494 Box::new(
1495 EcdsaP256SigningKey::from_pkcs8_pem(include_str!(
1496 "../tests/fixtures/keys/ec/ec-prime256v1-key.pem"
1497 ))
1498 .expect("P-256 fixture must parse"),
1499 ),
1500 SignatureAlgorithm::EcdsaSha384,
1501 DigestAlgorithm::Sha384,
1502 ),
1503 (
1504 Box::new(
1505 EcdsaP384SigningKey::from_pkcs8_pem(include_str!(
1506 "../tests/fixtures/keys/ec/ec-prime384v1-key.pem"
1507 ))
1508 .expect("P-384 fixture must parse"),
1509 ),
1510 SignatureAlgorithm::EcdsaSha256,
1511 DigestAlgorithm::Sha256,
1512 ),
1513 ];
1514
1515 for (key, signature_algorithm, digest_algorithm) in cases {
1516 let provider = CountingRandomProvider {
1517 random_calls: AtomicUsize::new(0),
1518 reject_digest: Some(digest_algorithm),
1519 extra_digest_byte: false,
1520 accept_signatures: false,
1521 };
1522 let error = provider
1523 .sign(key.as_ref(), signature_algorithm, b"signed info")
1524 .expect_err("provider digest rejection must stop ECDSA signing");
1525
1526 assert!(matches!(
1527 error,
1528 SigningKeyError::Provider(ProviderError::Unsupported {
1529 operation: ProviderOperation::Digest,
1530 algorithm: Some(ref uri),
1531 }) if uri == digest_algorithm.uri()
1532 ));
1533 }
1534 }
1535
1536 #[cfg(feature = "xmldsig")]
1537 #[test]
1538 fn ecdsa_signing_rejects_provider_digests_with_the_wrong_length() {
1539 use crate::xmldsig::{
1540 EcdsaP256SigningKey, EcdsaP384SigningKey, SignatureAlgorithm, SigningKeyError,
1541 };
1542
1543 let cases: [(
1546 Box<dyn crate::xmldsig::SigningKey>,
1547 SignatureAlgorithm,
1548 usize,
1549 ); 2] = [
1550 (
1551 Box::new(
1552 EcdsaP256SigningKey::from_pkcs8_pem(include_str!(
1553 "../tests/fixtures/keys/ec/ec-prime256v1-key.pem"
1554 ))
1555 .expect("P-256 fixture must parse"),
1556 ),
1557 SignatureAlgorithm::EcdsaSha256,
1558 32,
1559 ),
1560 (
1561 Box::new(
1562 EcdsaP384SigningKey::from_pkcs8_pem(include_str!(
1563 "../tests/fixtures/keys/ec/ec-prime384v1-key.pem"
1564 ))
1565 .expect("P-384 fixture must parse"),
1566 ),
1567 SignatureAlgorithm::EcdsaSha384,
1568 48,
1569 ),
1570 ];
1571
1572 for (key, algorithm, expected) in cases {
1573 let provider = CountingRandomProvider {
1574 random_calls: AtomicUsize::new(0),
1575 reject_digest: None,
1576 extra_digest_byte: true,
1577 accept_signatures: false,
1578 };
1579 let error = provider
1580 .sign(key.as_ref(), algorithm, b"signed info")
1581 .expect_err("an oversized provider digest must not reach ECDSA prehash signing");
1582
1583 assert!(matches!(
1584 error,
1585 SigningKeyError::Provider(ProviderError::InvalidOutputSize {
1586 operation: ProviderOperation::Digest,
1587 expected: actual_expected,
1588 actual,
1589 }) if actual_expected == expected && actual == expected + 1
1590 ));
1591 }
1592 }
1593
1594 #[cfg(feature = "xmldsig")]
1595 #[test]
1596 fn verification_facade_rejects_malformed_dsa_before_provider_dispatch() {
1597 use crate::xmldsig::{
1598 DefaultKeyResolver, DsigStatus, FailureReason, SignatureAlgorithm, VerifyContext,
1599 };
1600
1601 let original = include_str!(
1602 "../tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-dsa.xml"
1603 );
1604 let value_start = original
1605 .find("<SignatureValue>")
1606 .expect("Merlin fixture must contain SignatureValue")
1607 + "<SignatureValue>".len();
1608 let value_end = original[value_start..]
1609 .find("</SignatureValue>")
1610 .map(|offset| value_start + offset)
1611 .expect("Merlin fixture must close SignatureValue");
1612 let mut malformed = original.to_owned();
1613 malformed.replace_range(value_start..value_end, "AQ==");
1614 let provider = CountingRandomProvider {
1615 random_calls: AtomicUsize::new(0),
1616 reject_digest: None,
1617 extra_digest_byte: false,
1618 accept_signatures: true,
1619 };
1620
1621 let mut policy = crate::policy::VerificationPolicy::default();
1622 policy
1623 .key_trust
1624 .allowed_legacy_signature_algorithms
1625 .insert(SignatureAlgorithm::DsaSha1);
1626 policy.key_trust.dsa_keys.minimum_modulus_bits = 1024;
1627 let result = VerifyContext::new()
1628 .policy(policy)
1629 .provider(&provider)
1630 .key_resolver(&DefaultKeyResolver::default())
1631 .verify(&malformed)
1632 .expect("malformed framing must be a verification miss");
1633
1634 assert_eq!(
1635 result.status,
1636 DsigStatus::Invalid(FailureReason::SignatureMismatch)
1637 );
1638 }
1639
1640 #[cfg(feature = "xmldsig")]
1641 #[test]
1642 fn rustcrypto_provider_verifies_parameterized_rsa_pss_certificates() {
1643 use der::{Decode as _, Encode as _};
1644 use rand_chacha::{ChaCha20Rng, rand_core::SeedableRng};
1645 use rsa::{RsaPrivateKey, pkcs8::EncodePublicKey, pss::SigningKey as RsaPssSigningKey};
1646 use sha2::Sha256;
1647 use signature::{RandomizedSigner, SignatureEncoding};
1648 use x509_cert::spki::{AlgorithmIdentifierOwned, ObjectIdentifier};
1649
1650 let mut rng = ChaCha20Rng::from_seed([0x5a; 32]);
1653 let private_key =
1654 RsaPrivateKey::new(&mut rng, 2048).expect("deterministic RSA key generation");
1655 let public_key = private_key
1656 .to_public_key()
1657 .to_public_key_der()
1658 .expect("RSA public key must encode as SPKI");
1659 let signing_key = RsaPssSigningKey::<Sha256>::new_with_salt_len(private_key, 32);
1660 let signed_data = b"certificate tbs bytes";
1661 let signature = signing_key
1662 .try_sign_with_rng(&mut rng, signed_data)
1663 .expect("RSA-PSS signing must succeed")
1664 .to_vec();
1665
1666 assert!(
1667 RUST_CRYPTO_PROVIDER
1668 .verify_x509_signature(
1669 X509SignatureAlgorithm::RsaPss {
1670 digest: DigestAlgorithm::Sha256,
1671 mgf_digest: DigestAlgorithm::Sha256,
1672 salt_len: 32,
1673 },
1674 signed_data,
1675 &signature,
1676 public_key.as_bytes(),
1677 )
1678 .expect("standard RSA-PSS parameters must be supported")
1679 );
1680
1681 let mut parameterless_pss_spki =
1682 x509_cert::SubjectPublicKeyInfo::from_der(public_key.as_bytes())
1683 .expect("RSA SPKI must decode");
1684 parameterless_pss_spki.algorithm = AlgorithmIdentifierOwned {
1685 oid: ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.10"),
1686 parameters: None,
1687 };
1688 let parameterless_pss_spki = parameterless_pss_spki
1689 .to_der()
1690 .expect("parameterless PSS SPKI must encode");
1691 assert!(
1692 RUST_CRYPTO_PROVIDER
1693 .verify_x509_signature(
1694 X509SignatureAlgorithm::RsaPss {
1695 digest: DigestAlgorithm::Sha256,
1696 mgf_digest: DigestAlgorithm::Sha256,
1697 salt_len: 32,
1698 },
1699 signed_data,
1700 &signature,
1701 ¶meterless_pss_spki,
1702 )
1703 .expect("parameterless PSS keys impose no signature restrictions")
1704 );
1705
1706 let mut pss_spki = x509_cert::SubjectPublicKeyInfo::from_der(public_key.as_bytes())
1707 .expect("RSA SPKI must decode");
1708 let pss_parameters = der::asn1::Any::from_der(&[
1709 0x30, 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
1710 0x04, 0x02, 0x01, 0x05, 0x00, 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48,
1711 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
1712 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x20,
1713 ])
1714 .expect("standard SHA-256 PSS parameters must decode");
1715 pss_spki.algorithm = AlgorithmIdentifierOwned {
1716 oid: ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.10"),
1717 parameters: Some(pss_parameters),
1718 };
1719 let pss_spki = pss_spki.to_der().expect("PSS SPKI must encode");
1720
1721 assert!(
1722 RUST_CRYPTO_PROVIDER
1723 .verify_x509_signature(
1724 X509SignatureAlgorithm::RsaPss {
1725 digest: DigestAlgorithm::Sha256,
1726 mgf_digest: DigestAlgorithm::Sha256,
1727 salt_len: 32,
1728 },
1729 signed_data,
1730 &signature,
1731 &pss_spki,
1732 )
1733 .expect("RFC 4055 PSS SubjectPublicKeyInfo must be supported")
1734 );
1735
1736 for incompatible in [
1737 X509SignatureAlgorithm::RsaPss {
1738 digest: DigestAlgorithm::Sha384,
1739 mgf_digest: DigestAlgorithm::Sha256,
1740 salt_len: 32,
1741 },
1742 X509SignatureAlgorithm::RsaPss {
1743 digest: DigestAlgorithm::Sha256,
1744 mgf_digest: DigestAlgorithm::Sha384,
1745 salt_len: 32,
1746 },
1747 X509SignatureAlgorithm::RsaPss {
1748 digest: DigestAlgorithm::Sha256,
1749 mgf_digest: DigestAlgorithm::Sha256,
1750 salt_len: 16,
1751 },
1752 ] {
1753 assert!(
1754 !RUST_CRYPTO_PROVIDER
1755 .verify_x509_signature(incompatible, signed_data, &signature, &pss_spki,)
1756 .expect("incompatible PSS key restrictions are invalid, not unsupported")
1757 );
1758 }
1759 }
1760
1761 #[cfg(feature = "xmldsig")]
1762 #[test]
1763 fn rustcrypto_provider_verifies_dsa_certificate_signature_at_q_width() {
1764 use base64::Engine as _;
1765
1766 let spki = base64::engine::general_purpose::STANDARD
1769 .decode("MIIDQzCCAjYGByqGSM44BAEwggIpAoIBAQDEkm7mUEj1dizQRRrcU6ehyhpQ1NAkcKi9XyNcBJDZlyTdVH09XZ04UZNuXAWRL1hEDvDAvFimuwmW7k099j0PRM+WypsfOOgZPJhIVNZu9poTPGINKpbMTXFmR+qhrYM4z+NSKxuUBWZwX5HibBIG5INbx8IDHWAxZqxgHQsebDej1+yZyCTTpmDS9nKGkBRVaxsJgZt958UPNlIz1ECf4n4P4mPLAl7W5xV8VSWMqlXdkOAPbLC/mChjFoCj0jmCQpbcOvd7a6cWhcyhw/yikoVoKEPNWr9xLtdJV37f1/4q/xTvoPKWhMmgMQ/DigUnYgPzmexyS82m5HLZ/vOJAh0A/ckrg9g9PsZesUsH/4bEijeNwWGXB5e+/LCt0QKCAQEAuBGFzyjZEmvbDKbb+8tz+zqw4lK7RGwOjVM3v9xPS6LuG5L1OwCNQcUcVIsU9VxBnEx9oMnl8eVX1nq3kfdiZB2F9ESxwX5FzBt+KLjMOzBa8rPlzVcyCZ3sT3orAQ2D/q7ffDhTCUt+v8UNiAhVbaNnR/vI7AkVoP9crRjpOSV/7b5MGa0BcjIyEzTtqM58wppfSQt8jkj7WT3+Bww/Y9rOtshDE2QosaX/7xoDnzyeZ3amLjTe3/MjBcsKlbK2z4QuaI6xoQBVd/QjP8FjXpZBhXWFIAsOL/sz6uR2Er0ovdX8DBA0EJpuzlTX94Lvf+Eh+5/83ESAm97fk4pnhQOCAQUAAoIBAEwSwKuLFPeR7UJGXkWM9egyYewhqHpIXPBEWOVPqwTw3xLc3EkufpYY9wkhJS08KD+J92jMjm//0bYeVf7fXisc6PHtGY4wx5XBm1g9HKw9lwRjbk7nH495dlZdl0BXHa14TJ8myE2zOM1jsaFyz6jAFTaRnKYIj6WlKOj59d2iAXtLZRme9r+7U4G6zDUkphyIEcIGH4vhb6gm3URr1zAV5kJjTlsPAiqgeH/PgxU52tmvLphJgv/xPxsuX5W0/s7iKbphIb2YWh/gtTWXvRQHiQQ2fCncI3TAMnZ75dBY0gPOVLQJhUyffeRbk9UULux/jc8QBPgKBS7GM5DnNSw=")
1770 .expect("DSA SPKI fixture must decode");
1771 let signature = base64::engine::general_purpose::STANDARD
1772 .decode("MD0CHQChtB1c+f5BmTJCtT7Gi4cyQiR2igj0znRQYCJ3Ahw4NGg4pL5jgA8Ri07ESV9Yr90WfUmRrbRcnjsY")
1773 .expect("DSA signature fixture must decode");
1774 let message = b"certificate tbs bytes for dsa q-width regression";
1775
1776 assert!(
1777 rustcrypto_x509::verify_signature(
1778 X509SignatureAlgorithm::Dsa(DigestAlgorithm::Sha1),
1779 message,
1780 &signature,
1781 &spki,
1782 )
1783 .expect("supported DSA-SHA1 certificate signature")
1784 );
1785
1786 let mut tampered = signature;
1787 *tampered.last_mut().expect("DER signature is non-empty") ^= 1;
1788 assert!(
1789 !rustcrypto_x509::verify_signature(
1790 X509SignatureAlgorithm::Dsa(DigestAlgorithm::Sha1),
1791 message,
1792 &tampered,
1793 &spki,
1794 )
1795 .expect("tampered DSA-SHA1 certificate signature is a verification miss")
1796 );
1797 }
1798
1799 #[cfg(feature = "xmldsig")]
1800 #[test]
1801 fn primitive_provider_does_not_embed_rsa_strength_policy() {
1802 use rand_chacha::{ChaCha20Rng, rand_core::SeedableRng};
1803 use rsa::{RsaPrivateKey, pkcs8::EncodePublicKey, pss::SigningKey as RsaPssSigningKey};
1804 use sha2::Sha256;
1805 use signature::{RandomizedSigner, SignatureEncoding};
1806
1807 let mut rng = ChaCha20Rng::from_seed([0x3c; 32]);
1808 let private_key =
1809 RsaPrivateKey::new(&mut rng, 1024).expect("deterministic weak RSA key generation");
1810 let public_key = private_key
1811 .to_public_key()
1812 .to_public_key_der()
1813 .expect("weak RSA public key must encode as SPKI");
1814 let signed_data = b"certificate tbs bytes";
1815 let signature = RsaPssSigningKey::<Sha256>::new_with_salt_len(private_key, 32)
1816 .try_sign_with_rng(&mut rng, signed_data)
1817 .expect("weak RSA-PSS key can still produce a cryptographic signature")
1818 .to_vec();
1819
1820 assert!(
1821 RUST_CRYPTO_PROVIDER
1822 .verify_x509_signature(
1823 X509SignatureAlgorithm::RsaPss {
1824 digest: DigestAlgorithm::Sha256,
1825 mgf_digest: DigestAlgorithm::Sha256,
1826 salt_len: 32,
1827 },
1828 signed_data,
1829 &signature,
1830 public_key.as_bytes(),
1831 )
1832 .expect(
1833 "provider must evaluate structurally valid RSA-PSS independently of policy"
1834 )
1835 );
1836 }
1837
1838 #[cfg(feature = "xmlenc")]
1839 #[test]
1840 fn legacy_oaep_mgf_constraint_is_symmetric() {
1841 use rsa::pkcs8::DecodePrivateKey;
1842
1843 let key = rsa::RsaPrivateKey::from_pkcs8_pem(include_str!(
1846 "../tests/fixtures/keys/rsa/rsa-2048-key.pem"
1847 ))
1848 .expect("RSA fixture must parse");
1849 let parameters = crate::xmlenc::RsaOaepParameters {
1850 algorithm: crate::xmlenc::KeyTransportAlgorithm::RsaOaepMgf1p,
1851 digest: crate::xmlenc::OaepDigestAlgorithm::Sha256,
1852 mgf_digest: crate::xmlenc::OaepDigestAlgorithm::Sha256,
1853 label: Vec::new(),
1854 };
1855
1856 assert!(matches!(
1857 RUST_CRYPTO_PROVIDER.recover_key(&key, ¶meters, &[0_u8; 256]),
1858 Err(ProviderError::InvalidInput(
1859 ProviderInputError::LegacyRsaOaepMgf
1860 ))
1861 ));
1862 assert!(matches!(
1863 RUST_CRYPTO_PROVIDER.transport_key(&key.to_public_key(), ¶meters, &[0_u8; 16]),
1864 Err(ProviderError::InvalidInput(
1865 ProviderInputError::LegacyRsaOaepMgf
1866 ))
1867 ));
1868 }
1869}