pub trait DecryptionKey {
// Required methods
fn decrypt_cek(
&self,
encrypted_key: &[u8],
algorithm: &KeyEncryptionAlgorithm,
) -> Result<Vec<u8>, SmimeError>;
fn matches_recipient(&self, id: &RecipientIdentifier) -> bool;
// Provided methods
fn agree_ecdh(
&self,
ephemeral_public_key_bytes: &[u8],
ukm: Option<&[u8]>,
enc_cek: &[u8],
alg: &KariAlgorithm,
) -> Result<Vec<u8>, SmimeError> { ... }
fn supported_key_enc_algorithm(&self) -> Option<KeyEncryptionAlgorithm> { ... }
}Expand description
Abstraction over a private key capable of decrypting an S/MIME message.
Implementors provide the key-unwrap step: given an encrypted CEK and the algorithm that was used to wrap it, return the raw CEK bytes.
Required Methods§
Sourcefn decrypt_cek(
&self,
encrypted_key: &[u8],
algorithm: &KeyEncryptionAlgorithm,
) -> Result<Vec<u8>, SmimeError>
fn decrypt_cek( &self, encrypted_key: &[u8], algorithm: &KeyEncryptionAlgorithm, ) -> Result<Vec<u8>, SmimeError>
Decrypt an encrypted content-encryption key.
Sourcefn matches_recipient(&self, id: &RecipientIdentifier) -> bool
fn matches_recipient(&self, id: &RecipientIdentifier) -> bool
Returns true if this key matches the given RecipientIdentifier.
§Example
RecipientIdentifier is #[non_exhaustive], so your implementation
must include a catch-all arm (_ => false) to remain forward-compatible
with future identifier variants.
fn matches_recipient(&self, id: &RecipientIdentifier) -> bool {
match id {
RecipientIdentifier::IssuerAndSerialNumber { issuer_der, serial } => {
// issuer_der: DER-encoded Name — compare against
// cert.tbs_certificate().issuer().to_der().unwrap_or_default()
// serial: big-endian bytes — compare against
// cert.tbs_certificate().serial_number().as_bytes()
self.cert_issuer_der() == issuer_der
&& self.cert_serial() == serial
}
RecipientIdentifier::SubjectKeyIdentifier(ski) => {
// ski: raw bytes of the Subject Key Identifier extension value —
// obtain via cert.tbs_certificate()
// .get_extension::<SubjectKeyIdentifier>()
self.cert_ski() == ski
}
_ => false, // required: RecipientIdentifier is #[non_exhaustive]
}
}Provided Methods§
Sourcefn agree_ecdh(
&self,
ephemeral_public_key_bytes: &[u8],
ukm: Option<&[u8]>,
enc_cek: &[u8],
alg: &KariAlgorithm,
) -> Result<Vec<u8>, SmimeError>
fn agree_ecdh( &self, ephemeral_public_key_bytes: &[u8], ukm: Option<&[u8]>, enc_cek: &[u8], alg: &KariAlgorithm, ) -> Result<Vec<u8>, SmimeError>
Perform ECDH key agreement and unwrap the content-encryption key.
Called when the EnvelopedData contains a KARI (KeyAgreeRecipientInfo)
entry that matches this key (as determined by matches_recipient).
The implementor must:
- Perform ECDH using the recipient’s private key and
ephemeral_public_key_bytes(SEC1 uncompressed EC point) to obtain the shared secret Z. - Apply the X9.63 KDF (RFC 5753 §3.6.1): hash Z concatenated with a
counter and the
EccCmsSharedInfostructure to derive the key-encryption key (KEK).SharedInfoencodesalg.key_wrapOID inkeyInfoand, whenukmisSome, the UKM bytes inentityUInfo [0] EXPLICIT. WhenukmisNone(which is always the case when this crate’sencrypt()produced the message, as this crate never generates UKM), omitentityUInfo. - Unwrap
enc_cekwith AES-128-KW or AES-256-KW (peralg.key_wrap) using the derived KEK. - Return the raw CEK bytes.
§Default — IMPORTANT for EC key implementors
Returns Err(SmimeError::UnsupportedAlgorithm(...)). EC key
implementors MUST override this method or KARI-encrypted messages
will silently fail to decrypt (the error is caught per-recipient
and the next RecipientInfo is tried; if no other recipient matches,
NoMatchingRecipient is returned with no indication that ECDH was
attempted). RSA-only keys can leave the default.
Sourcefn supported_key_enc_algorithm(&self) -> Option<KeyEncryptionAlgorithm>
fn supported_key_enc_algorithm(&self) -> Option<KeyEncryptionAlgorithm>
Returns a hint about which key encryption algorithms this key supports.
This crate does not consult this hint internally — decrypt() always
tries all recipients and lets decrypt_cek() / agree_ecdh() reject
unsupported algorithms. This method is provided as an extension point for
callers that want to pre-screen or log algorithm capabilities.
Default: returns None (no hint; let decrypt_cek() reject unsupported ones).
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".