polymorph_webcrypto_guest/rsa_oaep.rs
1//! `rsa-oaep-encrypt` key creation (RFC 8017 §7.1) — the public half of
2//! key transport — plus, behind the `rsa-oaep-decrypt` cargo feature,
3//! `rsa-oaep-decrypt`.
4//!
5//! The declared variant binds the digest at mint; the MGF1 digest is the
6//! same digest. Admission tightens the RSA family contract on both ends:
7//! the modulus must be 2048–8192 bits (see the WIT `rsa-oaep-encrypt`
8//! interface). The plaintext bound follows from the mint: modulus bytes
9//! minus twice the digest length minus 2.
10
11use crate::{bindings, EncryptionKey, Error};
12#[cfg(feature = "rsa-oaep-decrypt")]
13use crate::{DecryptionKey, DecryptionKeyOptions};
14
15pub use crate::bindings::rsa_oaep_encrypt::RsaVariant;
16
17#[cfg(feature = "rsa-oaep-decrypt")]
18pub use crate::bindings::rsa_oaep_decrypt::RsaModulus;
19
20/// Import a public key as an X.509 SubjectPublicKeyInfo (DER). Admission
21/// follows the RSA family contract (see the WIT `rsa` interface) plus the
22/// 2048–8192-bit window.
23pub async fn import_encryption_key_spki(
24 variant: RsaVariant,
25 spki: impl Into<Vec<u8>>,
26) -> Result<EncryptionKey, Error> {
27 Ok(EncryptionKey::from_raw(
28 bindings::rsa_oaep_encrypt::import_encryption_key_spki(variant, spki.into()).await?,
29 ))
30}
31
32/// Import a public key as an RSA public JWK (`kty: "RSA"`, with `n` and
33/// `e`, as JSON text). An `alg` member, when present, must be the
34/// variant's JOSE alg (`"RSA-OAEP-256"`, `"RSA-OAEP-384"`, or
35/// `"RSA-OAEP-512"`). See the WIT `mac-key.export-key-jwk` doc for the
36/// package-wide JWK contract.
37pub async fn import_encryption_key_jwk(
38 variant: RsaVariant,
39 jwk: impl Into<String>,
40) -> Result<EncryptionKey, Error> {
41 Ok(EncryptionKey::from_raw(
42 bindings::rsa_oaep_encrypt::import_encryption_key_jwk(variant, jwk.into()).await?,
43 ))
44}
45
46/// Generate a fresh key pair of the declared variant and modulus length,
47/// returning both halves. The public exponent is 65537; it is not a
48/// parameter.
49#[cfg(feature = "rsa-oaep-decrypt")]
50pub async fn generate_key(
51 variant: RsaVariant,
52 modulus: RsaModulus,
53 options: DecryptionKeyOptions,
54) -> Result<(DecryptionKey, EncryptionKey), Error> {
55 let (decryption, encryption) =
56 bindings::rsa_oaep_decrypt::generate_key(variant, modulus, options.lower()).await?;
57 Ok((
58 DecryptionKey::from_raw(decryption),
59 EncryptionKey::from_raw(encryption),
60 ))
61}
62
63/// Import a decryption key as a PKCS#8 PrivateKeyInfo (DER, with the CRT
64/// parameters). Admission follows the RSA family contract plus the
65/// 2048–8192-bit window (see the WIT `rsa-oaep-decrypt` interface).
66/// Returns only the decryption key; supply the public half to
67/// [`import_encryption_key_spki`] if you need it.
68#[cfg(feature = "rsa-oaep-decrypt")]
69pub async fn import_decryption_key_pkcs8(
70 variant: RsaVariant,
71 pkcs8: impl Into<Vec<u8>>,
72 options: DecryptionKeyOptions,
73) -> Result<DecryptionKey, Error> {
74 Ok(DecryptionKey::from_raw(
75 bindings::rsa_oaep_decrypt::import_decryption_key_pkcs8(
76 variant,
77 pkcs8.into(),
78 options.lower(),
79 )
80 .await?,
81 ))
82}
83
84/// Import a decryption key as a full-CRT RSA private JWK (`kty: "RSA"`,
85/// with `n`, `e`, `d`, and the CRT members, as JSON text), subject to
86/// [`import_decryption_key_pkcs8`]'s admission. An `alg` member, when
87/// present, must be the variant's JOSE alg (`"RSA-OAEP-256"`,
88/// `"RSA-OAEP-384"`, or `"RSA-OAEP-512"`).
89#[cfg(feature = "rsa-oaep-decrypt")]
90pub async fn import_decryption_key_jwk(
91 variant: RsaVariant,
92 jwk: impl Into<String>,
93 options: DecryptionKeyOptions,
94) -> Result<DecryptionKey, Error> {
95 Ok(DecryptionKey::from_raw(
96 bindings::rsa_oaep_decrypt::import_decryption_key_jwk(variant, jwk.into(), options.lower())
97 .await?,
98 ))
99}