diff options
author | Luca Casonato <hello@lcas.dev> | 2021-12-14 17:02:14 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-14 17:02:14 +0100 |
commit | b220a58d1a678ffd46a42567909d0b0d59731d99 (patch) | |
tree | 423a9c086696e77b58a71317e005a713903fb7f5 /ext/crypto/export_key.rs | |
parent | 5fe4d5c818d598abfdfc9ef1db0b00f56cf03c20 (diff) |
feat(ext/crypto): support exporting RSA JWKs (#13081)
This commit adds support for exporting RSA JWKs in the Web Crypto API.
It also does some minor fixes for RSA JWK imports.
Co-authored-by: Sean Michael Wykes <sean.wykes@nascent.com.br>
Diffstat (limited to 'ext/crypto/export_key.rs')
-rw-r--r-- | ext/crypto/export_key.rs | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/ext/crypto/export_key.rs b/ext/crypto/export_key.rs index 22a4b55ca..2e74d61f2 100644 --- a/ext/crypto/export_key.rs +++ b/ext/crypto/export_key.rs @@ -1,9 +1,12 @@ +use deno_core::error::custom_error; use deno_core::error::AnyError; use deno_core::OpState; use deno_core::ZeroCopyBuf; +use rsa::pkcs1::UIntBytes; use serde::Deserialize; use serde::Serialize; use spki::der::asn1; +use spki::der::Decodable; use spki::der::Encodable; use crate::shared::*; @@ -21,7 +24,8 @@ pub struct ExportKeyOptions { pub enum ExportKeyFormat { Pkcs8, Spki, - Jwk, + JwkPublic, + JwkPrivate, } #[derive(Deserialize)] @@ -40,6 +44,20 @@ pub enum ExportKeyAlgorithm { pub enum ExportKeyResult { Pkcs8(ZeroCopyBuf), Spki(ZeroCopyBuf), + JwkPublicRsa { + n: String, + e: String, + }, + JwkPrivateRsa { + n: String, + e: String, + d: String, + p: String, + q: String, + dp: String, + dq: String, + qi: String, + }, } pub fn op_crypto_export_key( @@ -54,6 +72,10 @@ pub fn op_crypto_export_key( } } +fn uint_to_b64(bytes: UIntBytes) -> String { + base64::encode_config(bytes.as_bytes(), base64::URL_SAFE_NO_PAD) +} + fn export_key_rsa( format: ExportKeyFormat, key_data: RawKeyData, @@ -108,6 +130,41 @@ fn export_key_rsa( Ok(ExportKeyResult::Pkcs8(pkcs8_der.into())) } - _ => Err(unsupported_format()), + ExportKeyFormat::JwkPublic => { + let public_key = key_data.as_rsa_public_key()?; + let public_key = rsa::pkcs1::RsaPublicKey::from_der(&public_key) + .map_err(|_| { + custom_error( + "DOMExceptionOperationError", + "failed to decode public key", + ) + })?; + + Ok(ExportKeyResult::JwkPublicRsa { + n: uint_to_b64(public_key.modulus), + e: uint_to_b64(public_key.public_exponent), + }) + } + ExportKeyFormat::JwkPrivate => { + let private_key = key_data.as_rsa_private_key()?; + let private_key = rsa::pkcs1::RsaPrivateKey::from_der(private_key) + .map_err(|_| { + custom_error( + "DOMExceptionOperationError", + "failed to decode private key", + ) + })?; + + Ok(ExportKeyResult::JwkPrivateRsa { + n: uint_to_b64(private_key.modulus), + e: uint_to_b64(private_key.public_exponent), + d: uint_to_b64(private_key.private_exponent), + p: uint_to_b64(private_key.prime1), + q: uint_to_b64(private_key.prime2), + dp: uint_to_b64(private_key.exponent1), + dq: uint_to_b64(private_key.exponent2), + qi: uint_to_b64(private_key.coefficient), + }) + } } } |