summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Casonato <hello@lcas.dev>2021-12-10 15:06:03 +0100
committerGitHub <noreply@github.com>2021-12-10 15:06:03 +0100
commit292682772691402bb3c1e4fee554d85746147621 (patch)
tree2df72a3edd51cf7bac39412a05f2c36cbf7de34a
parent38f163022373c9adb050f17140f7d29bb403abe2 (diff)
refactor(ext/crypto): clean up rust side importKey (#13036)
This commit cleans up the Rust side of `import_key` by using a bunch of enums instead of structs with "type" and "data" fields. This commit does add some duplicated code for the time being, because a lot of the other ops still need to get the same cleanup treatment.
-rw-r--r--ext/crypto/00_crypto.js70
-rw-r--r--ext/crypto/import_key.rs578
-rw-r--r--ext/crypto/lib.rs715
-rw-r--r--ext/crypto/shared.rs74
4 files changed, 689 insertions, 748 deletions
diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js
index ddc88bdcb..16c862829 100644
--- a/ext/crypto/00_crypto.js
+++ b/ext/crypto/00_crypto.js
@@ -759,6 +759,7 @@
* @param {KeyUsages[]} keyUsages
* @returns {Promise<any>}
*/
+ // deno-lint-ignore require-await
async importKey(format, keyData, algorithm, extractable, keyUsages) {
webidl.assertBranded(this, SubtleCrypto);
const prefix = "Failed to execute 'importKey' on 'SubtleCrypto'";
@@ -812,7 +813,7 @@
);
}
case "ECDSA": {
- return await importKeyECDSA(
+ return importKeyECDSA(
format,
normalizedAlgorithm,
keyData,
@@ -823,7 +824,7 @@
case "RSASSA-PKCS1-v1_5":
case "RSA-PSS":
case "RSA-OAEP": {
- return await importKeyRSA(
+ return importKeyRSA(
format,
normalizedAlgorithm,
keyData,
@@ -850,7 +851,7 @@
);
}
case "AES-KW": {
- return await importKeyAES(
+ return importKeyAES(
format,
normalizedAlgorithm,
keyData,
@@ -2194,7 +2195,7 @@
return key;
}
- async function importKeyECDSA(
+ function importKeyECDSA(
format,
normalizedAlgorithm,
keyData,
@@ -2227,16 +2228,13 @@
}
// 3.
- const { data } = await core.opAsync("op_crypto_import_key", {
+ const { rawData } = core.opSync("op_crypto_import_key", {
algorithm: "ECDSA",
namedCurve: normalizedAlgorithm.namedCurve,
- }, keyData);
+ }, { raw: keyData });
const handle = {};
- WeakMapPrototypeSet(KEY_STORE, handle, {
- type: "public",
- data,
- });
+ WeakMapPrototypeSet(KEY_STORE, handle, rawData);
// 4-5.
const algorithm = {
@@ -2275,7 +2273,7 @@
},
};
- async function importKeyRSA(
+ function importKeyRSA(
format,
normalizedAlgorithm,
keyData,
@@ -2299,23 +2297,18 @@
}
// 2-9.
- const { modulusLength, publicExponent, data } = await core
- .opAsync(
- "op_crypto_import_key",
- {
- algorithm: normalizedAlgorithm.name,
- format: "pkcs8",
- // Needed to perform step 7 without normalization.
- hash: normalizedAlgorithm.hash.name,
- },
- keyData,
- );
+ const { modulusLength, publicExponent, rawData } = core.opSync(
+ "op_crypto_import_key",
+ {
+ algorithm: normalizedAlgorithm.name,
+ // Needed to perform step 7 without normalization.
+ hash: normalizedAlgorithm.hash.name,
+ },
+ { pkcs8: keyData },
+ );
const handle = {};
- WeakMapPrototypeSet(KEY_STORE, handle, {
- type: "private",
- data,
- });
+ WeakMapPrototypeSet(KEY_STORE, handle, rawData);
const algorithm = {
name: normalizedAlgorithm.name,
@@ -2350,23 +2343,18 @@
}
// 2-9.
- const { modulusLength, publicExponent, data } = await core
- .opAsync(
- "op_crypto_import_key",
- {
- algorithm: normalizedAlgorithm.name,
- format: "spki",
- // Needed to perform step 7 without normalization.
- hash: normalizedAlgorithm.hash.name,
- },
- keyData,
- );
+ const { modulusLength, publicExponent, rawData } = core.opSync(
+ "op_crypto_import_key",
+ {
+ algorithm: normalizedAlgorithm.name,
+ // Needed to perform step 7 without normalization.
+ hash: normalizedAlgorithm.hash.name,
+ },
+ { spki: keyData },
+ );
const handle = {};
- WeakMapPrototypeSet(KEY_STORE, handle, {
- type: "public",
- data,
- });
+ WeakMapPrototypeSet(KEY_STORE, handle, rawData);
const algorithm = {
name: normalizedAlgorithm.name,
diff --git a/ext/crypto/import_key.rs b/ext/crypto/import_key.rs
new file mode 100644
index 000000000..16a8d155f
--- /dev/null
+++ b/ext/crypto/import_key.rs
@@ -0,0 +1,578 @@
+use deno_core::error::AnyError;
+use deno_core::OpState;
+use deno_core::ZeroCopyBuf;
+use serde::Deserialize;
+use serde::Serialize;
+use spki::der::Decodable;
+use spki::der::Encodable;
+
+use crate::shared::*;
+use crate::OaepPrivateKeyParameters;
+use crate::PssPrivateKeyParameters;
+
+#[derive(Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum KeyData {
+ Spki(ZeroCopyBuf),
+ Pkcs8(ZeroCopyBuf),
+ Raw(ZeroCopyBuf),
+ Jwk { k: String },
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase", tag = "algorithm")]
+pub enum ImportKeyOptions {
+ #[serde(rename = "RSASSA-PKCS1-v1_5")]
+ RsassaPkcs1v15 { hash: ShaHash },
+ #[serde(rename = "RSA-PSS")]
+ RsaPss { hash: ShaHash },
+ #[serde(rename = "RSA-OAEP")]
+ RsaOaep { hash: ShaHash },
+ #[serde(rename = "ECDSA", rename_all = "camelCase")]
+ Ecdsa { named_curve: EcNamedCurve },
+ #[serde(rename = "ECDH", rename_all = "camelCase")]
+ Ecdh { named_curve: EcNamedCurve },
+}
+
+#[derive(Serialize)]
+#[serde(untagged)]
+pub enum ImportKeyResult {
+ #[serde(rename_all = "camelCase")]
+ Rsa {
+ raw_data: RawKeyData,
+ modulus_length: usize,
+ public_exponent: ZeroCopyBuf,
+ },
+ #[serde(rename_all = "camelCase")]
+ Ec { raw_data: RawKeyData },
+}
+
+pub fn op_crypto_import_key(
+ _state: &mut OpState,
+ opts: ImportKeyOptions,
+ key_data: KeyData,
+) -> Result<ImportKeyResult, AnyError> {
+ match opts {
+ ImportKeyOptions::RsassaPkcs1v15 { hash } => {
+ import_key_rsassa(key_data, hash)
+ }
+ ImportKeyOptions::RsaPss { hash } => import_key_rsapss(key_data, hash),
+ ImportKeyOptions::RsaOaep { hash } => import_key_rsaoaep(key_data, hash),
+ ImportKeyOptions::Ecdsa { named_curve }
+ | ImportKeyOptions::Ecdh { named_curve } => {
+ import_key_ec(key_data, named_curve)
+ }
+ }
+}
+
+fn import_key_rsassa(
+ key_data: KeyData,
+ hash: ShaHash,
+) -> Result<ImportKeyResult, deno_core::anyhow::Error> {
+ match key_data {
+ KeyData::Spki(data) => {
+ // 2-3.
+ let pk_info = spki::SubjectPublicKeyInfo::from_der(&data)
+ .map_err(|e| data_error(e.to_string()))?;
+
+ // 4-5.
+ let alg = pk_info.algorithm.oid;
+
+ // 6.
+ let pk_hash = match alg {
+ // rsaEncryption
+ RSA_ENCRYPTION_OID => None,
+ // sha1WithRSAEncryption
+ SHA1_RSA_ENCRYPTION_OID => Some(ShaHash::Sha1),
+ // sha256WithRSAEncryption
+ SHA256_RSA_ENCRYPTION_OID => Some(ShaHash::Sha256),
+ // sha384WithRSAEncryption
+ SHA384_RSA_ENCRYPTION_OID => Some(ShaHash::Sha384),
+ // sha512WithRSAEncryption
+ SHA512_RSA_ENCRYPTION_OID => Some(ShaHash::Sha512),
+ _ => return Err(data_error("unsupported algorithm")),
+ };
+
+ // 7.
+ if let Some(pk_hash) = pk_hash {
+ if pk_hash != hash {
+ return Err(data_error("hash mismatch"));
+ }
+ }
+
+ // 8-9.
+ let public_key =
+ rsa::pkcs1::RsaPublicKey::from_der(pk_info.subject_public_key)
+ .map_err(|e| data_error(e.to_string()))?;
+
+ let bytes_consumed = public_key
+ .encoded_len()
+ .map_err(|e| data_error(e.to_string()))?;
+
+ if bytes_consumed
+ != spki::der::Length::new(pk_info.subject_public_key.len() as u16)
+ {
+ return Err(data_error("public key is invalid (too long)"));
+ }
+
+ let data = pk_info.subject_public_key.to_vec().into();
+ let public_exponent =
+ public_key.public_exponent.as_bytes().to_vec().into();
+ let modulus_length = public_key.modulus.as_bytes().len() * 8;
+
+ Ok(ImportKeyResult::Rsa {
+ raw_data: RawKeyData::Public(data),
+ modulus_length,
+ public_exponent,
+ })
+ }
+ KeyData::Pkcs8(data) => {
+ // 2-3.
+ let pk_info = rsa::pkcs8::PrivateKeyInfo::from_der(&data)
+ .map_err(|e| data_error(e.to_string()))?;
+
+ // 4-5.
+ let alg = pk_info.algorithm.oid;
+
+ // 6.
+ let pk_hash = match alg {
+ // rsaEncryption
+ RSA_ENCRYPTION_OID => None,
+ // sha1WithRSAEncryption
+ SHA1_RSA_ENCRYPTION_OID => Some(ShaHash::Sha1),
+ // sha256WithRSAEncryption
+ SHA256_RSA_ENCRYPTION_OID => Some(ShaHash::Sha256),
+ // sha384WithRSAEncryption
+ SHA384_RSA_ENCRYPTION_OID => Some(ShaHash::Sha384),
+ // sha512WithRSAEncryption
+ SHA512_RSA_ENCRYPTION_OID => Some(ShaHash::Sha512),
+ _ => return Err(data_error("unsupported algorithm")),
+ };
+
+ // 7.
+ if let Some(pk_hash) = pk_hash {
+ if pk_hash != hash {
+ return Err(data_error("hash mismatch"));
+ }
+ }
+
+ // 8-9.
+ let private_key =
+ rsa::pkcs1::RsaPrivateKey::from_der(pk_info.private_key)
+ .map_err(|e| data_error(e.to_string()))?;
+
+ let bytes_consumed = private_key
+ .encoded_len()
+ .map_err(|e| data_error(e.to_string()))?;
+
+ if bytes_consumed
+ != spki::der::Length::new(pk_info.private_key.len() as u16)
+ {
+ return Err(data_error("private key is invalid (too long)"));
+ }
+
+ let data = pk_info.private_key.to_vec().into();
+ let public_exponent =
+ private_key.public_exponent.as_bytes().to_vec().into();
+ let modulus_length = private_key.modulus.as_bytes().len() * 8;
+
+ Ok(ImportKeyResult::Rsa {
+ raw_data: RawKeyData::Private(data),
+ modulus_length,
+ public_exponent,
+ })
+ }
+ // TODO(lucacasonato): support JWK encoding
+ _ => Err(unsupported_format()),
+ }
+}
+
+fn import_key_rsapss(
+ key_data: KeyData,
+ hash: ShaHash,
+) -> Result<ImportKeyResult, deno_core::anyhow::Error> {
+ match key_data {
+ KeyData::Spki(data) => {
+ // 2-3.
+ let pk_info = spki::SubjectPublicKeyInfo::from_der(&data)
+ .map_err(|e| data_error(e.to_string()))?;
+
+ // 4-5.
+ let alg = pk_info.algorithm.oid;
+
+ // 6.
+ let pk_hash = match alg {
+ // rsaEncryption
+ RSA_ENCRYPTION_OID => None,
+ // id-RSASSA-PSS
+ RSASSA_PSS_OID => {
+ let params = PssPrivateKeyParameters::try_from(
+ pk_info
+ .algorithm
+ .parameters
+ .ok_or_else(|| data_error("malformed parameters"))?,
+ )
+ .map_err(|_| data_error("malformed parameters"))?;
+
+ let hash_alg = params.hash_algorithm;
+ let hash = match hash_alg.oid {
+ // id-sha1
+ ID_SHA1_OID => Some(ShaHash::Sha1),
+ // id-sha256
+ ID_SHA256_OID => Some(ShaHash::Sha256),
+ // id-sha384
+ ID_SHA384_OID => Some(ShaHash::Sha384),
+ // id-sha256
+ ID_SHA512_OID => Some(ShaHash::Sha512),
+ _ => return Err(data_error("unsupported hash algorithm")),
+ };
+
+ if params.mask_gen_algorithm.oid != ID_MFG1 {
+ return Err(not_supported_error("unsupported hash algorithm"));
+ }
+
+ // TODO(lucacasonato):
+ // If the parameters field of the maskGenAlgorithm field of params
+ // is not an instance of the HashAlgorithm ASN.1 type that is
+ // identical in content to the hashAlgorithm field of params,
+ // throw a NotSupportedError.
+
+ hash
+ }
+ _ => return Err(data_error("unsupported algorithm")),
+ };
+
+ // 7.
+ if let Some(pk_hash) = pk_hash {
+ if pk_hash != hash {
+ return Err(data_error("hash mismatch"));
+ }
+ }
+
+ // 8-9.
+ let public_key =
+ rsa::pkcs1::RsaPublicKey::from_der(pk_info.subject_public_key)
+ .map_err(|e| data_error(e.to_string()))?;
+
+ let bytes_consumed = public_key
+ .encoded_len()
+ .map_err(|e| data_error(e.to_string()))?;
+
+ if bytes_consumed
+ != spki::der::Length::new(pk_info.subject_public_key.len() as u16)
+ {
+ return Err(data_error("public key is invalid (too long)"));
+ }
+
+ let data = pk_info.subject_public_key.to_vec().into();
+ let public_exponent =
+ public_key.public_exponent.as_bytes().to_vec().into();
+ let modulus_length = public_key.modulus.as_bytes().len() * 8;
+
+ Ok(ImportKeyResult::Rsa {
+ raw_data: RawKeyData::Public(data),
+ modulus_length,
+ public_exponent,
+ })
+ }
+ KeyData::Pkcs8(data) => {
+ // 2-3.
+ let pk_info = rsa::pkcs8::PrivateKeyInfo::from_der(&data)
+ .map_err(|e| data_error(e.to_string()))?;
+
+ // 4-5.
+ let alg = pk_info.algorithm.oid;
+
+ // 6.
+ // 6.
+ let pk_hash = match alg {
+ // rsaEncryption
+ RSA_ENCRYPTION_OID => None,
+ // id-RSASSA-PSS
+ RSASSA_PSS_OID => {
+ let params = PssPrivateKeyParameters::try_from(
+ pk_info
+ .algorithm
+ .parameters
+ .ok_or_else(|| not_supported_error("malformed parameters"))?,
+ )
+ .map_err(|_| not_supported_error("malformed parameters"))?;
+
+ let hash_alg = params.hash_algorithm;
+ let hash = match hash_alg.oid {
+ // id-sha1
+ ID_SHA1_OID => Some(ShaHash::Sha1),
+ // id-sha256
+ ID_SHA256_OID => Some(ShaHash::Sha256),
+ // id-sha384
+ ID_SHA384_OID => Some(ShaHash::Sha384),
+ // id-sha256
+ ID_SHA512_OID => Some(ShaHash::Sha512),
+ _ => return Err(data_error("unsupported hash algorithm")),
+ };
+
+ if params.mask_gen_algorithm.oid != ID_MFG1 {
+ return Err(not_supported_error("unsupported mask gen algorithm"));
+ }
+
+ // TODO(lucacasonato):
+ // If the parameters field of the maskGenAlgorithm field of params
+ // is not an instance of the HashAlgorithm ASN.1 type that is
+ // identical in content to the hashAlgorithm field of params,
+ // throw a NotSupportedError.
+
+ hash
+ }
+ _ => return Err(data_error("unsupported algorithm")),
+ };
+
+ // 7.
+ if let Some(pk_hash) = pk_hash {
+ if pk_hash != hash {
+ return Err(data_error("hash mismatch"));
+ }
+ }
+
+ // 8-9.
+ let private_key =
+ rsa::pkcs1::RsaPrivateKey::from_der(pk_info.private_key)
+ .map_err(|e| data_error(e.to_string()))?;
+
+ let bytes_consumed = private_key
+ .encoded_len()
+ .map_err(|e| data_error(e.to_string()))?;
+
+ if bytes_consumed
+ != spki::der::Length::new(pk_info.private_key.len() as u16)
+ {
+ return Err(data_error("private key is invalid (too long)"));
+ }
+
+ let data = pk_info.private_key.to_vec().into();
+ let public_exponent =
+ private_key.public_exponent.as_bytes().to_vec().into();
+ let modulus_length = private_key.modulus.as_bytes().len() * 8;
+
+ Ok(ImportKeyResult::Rsa {
+ raw_data: RawKeyData::Private(data),
+ modulus_length,
+ public_exponent,
+ })
+ }
+ // TODO(lucacasonato): support JWK encoding
+ _ => Err(unsupported_format()),
+ }
+}
+
+fn import_key_rsaoaep(
+ key_data: KeyData,
+ hash: ShaHash,
+) -> Result<ImportKeyResult, deno_core::anyhow::Error> {
+ match key_data {
+ KeyData::Spki(data) => {
+ // 2-3.
+ let pk_info = spki::SubjectPublicKeyInfo::from_der(&data)
+ .map_err(|e| data_error(e.to_string()))?;
+
+ // 4-5.
+ let alg = pk_info.algorithm.oid;
+
+ // 6.
+ let pk_hash = match alg {
+ // rsaEncryption
+ RSA_ENCRYPTION_OID => None,
+ // id-RSAES-OAEP
+ RSAES_OAEP_OID => {
+ let params = OaepPrivateKeyParameters::try_from(
+ pk_info
+ .algorithm
+ .parameters
+ .ok_or_else(|| data_error("malformed parameters"))?,
+ )
+ .map_err(|_| data_error("malformed parameters"))?;
+
+ let hash_alg = params.hash_algorithm;
+ let hash = match hash_alg.oid {
+ // id-sha1
+ ID_SHA1_OID => Some(ShaHash::Sha1),
+ // id-sha256
+ ID_SHA256_OID => Some(ShaHash::Sha256),
+ // id-sha384
+ ID_SHA384_OID => Some(ShaHash::Sha384),
+ // id-sha256
+ ID_SHA512_OID => Some(ShaHash::Sha512),
+ _ => return Err(data_error("unsupported hash algorithm")),
+ };
+
+ if params.mask_gen_algorithm.oid != ID_MFG1 {
+ return Err(not_supported_error("unsupported hash algorithm"));
+ }
+
+ // TODO(lucacasonato):
+ // If the parameters field of the maskGenAlgorithm field of params
+ // is not an instance of the HashAlgorithm ASN.1 type that is
+ // identical in content to the hashAlgorithm field of params,
+ // throw a NotSupportedError.
+
+ hash
+ }
+ _ => return Err(data_error("unsupported algorithm")),
+ };
+
+ // 7.
+ if let Some(pk_hash) = pk_hash {
+ if pk_hash != hash {
+ return Err(data_error("hash mismatch"));
+ }
+ }
+
+ // 8-9.
+ let public_key =
+ rsa::pkcs1::RsaPublicKey::from_der(pk_info.subject_public_key)
+ .map_err(|e| data_error(e.to_string()))?;
+
+ let bytes_consumed = public_key
+ .encoded_len()
+ .map_err(|e| data_error(e.to_string()))?;
+
+ if bytes_consumed
+ != spki::der::Length::new(pk_info.subject_public_key.len() as u16)
+ {
+ return Err(data_error("public key is invalid (too long)"));
+ }
+
+ let data = pk_info.subject_public_key.to_vec().into();
+ let public_exponent =
+ public_key.public_exponent.as_bytes().to_vec().into();
+ let modulus_length = public_key.modulus.as_bytes().len() * 8;
+
+ Ok(ImportKeyResult::Rsa {
+ raw_data: RawKeyData::Public(data),
+ modulus_length,
+ public_exponent,
+ })
+ }
+ KeyData::Pkcs8(data) => {
+ // 2-3.
+ let pk_info = rsa::pkcs8::PrivateKeyInfo::from_der(&data)
+ .map_err(|e| data_error(e.to_string()))?;
+
+ // 4-5.
+ let alg = pk_info.algorithm.oid;
+
+ // 6.
+ // 6.
+ let pk_hash = match alg {
+ // rsaEncryption
+ RSA_ENCRYPTION_OID => None,
+ // id-RSAES-OAEP
+ RSAES_OAEP_OID => {
+ let params = OaepPrivateKeyParameters::try_from(
+ pk_info
+ .algorithm
+ .parameters
+ .ok_or_else(|| not_supported_error("malformed parameters"))?,
+ )
+ .map_err(|_| not_supported_error("malformed parameters"))?;
+
+ let hash_alg = params.hash_algorithm;
+ let hash = match hash_alg.oid {
+ // id-sha1
+ ID_SHA1_OID => Some(ShaHash::Sha1),
+ // id-sha256
+ ID_SHA256_OID => Some(ShaHash::Sha256),
+ // id-sha384
+ ID_SHA384_OID => Some(ShaHash::Sha384),
+ // id-sha256
+ ID_SHA512_OID => Some(ShaHash::Sha512),
+ _ => return Err(data_error("unsupported hash algorithm")),
+ };
+
+ if params.mask_gen_algorithm.oid != ID_MFG1 {
+ return Err(not_supported_error("unsupported mask gen algorithm"));
+ }
+
+ // TODO(lucacasonato):
+ // If the parameters field of the maskGenAlgorithm field of params
+ // is not an instance of the HashAlgorithm ASN.1 type that is
+ // identical in content to the hashAlgorithm field of params,
+ // throw a NotSupportedError.
+
+ hash
+ }
+ _ => return Err(data_error("unsupported algorithm")),
+ };
+
+ // 7.
+ if let Some(pk_hash) = pk_hash {
+ if pk_hash != hash {
+ return Err(data_error("hash mismatch"));
+ }
+ }
+
+ // 8-9.
+ let private_key =
+ rsa::pkcs1::RsaPrivateKey::from_der(pk_info.private_key)
+ .map_err(|e| data_error(e.to_string()))?;
+
+ let bytes_consumed = private_key
+ .encoded_len()
+ .map_err(|e| data_error(e.to_string()))?;
+
+ if bytes_consumed
+ != spki::der::Length::new(pk_info.private_key.len() as u16)
+ {
+ return Err(data_error("private key is invalid (too long)"));
+ }
+
+ let data = pk_info.private_key.to_vec().into();
+ let public_exponent =
+ private_key.public_exponent.as_bytes().to_vec().into();
+ let modulus_length = private_key.modulus.as_bytes().len() * 8;
+
+ Ok(ImportKeyResult::Rsa {
+ raw_data: RawKeyData::Private(data),
+ modulus_length,
+ public_exponent,
+ })
+ }
+ // TODO(lucacasonato): support JWK encoding
+ _ => Err(unsupported_format()),
+ }
+}
+
+fn import_key_ec(
+ key_data: KeyData,
+ named_curve: EcNamedCurve,
+) -> Result<ImportKeyResult, AnyError> {
+ Ok(match key_data {
+ KeyData::Raw(data) => {
+ // The point is parsed and validated, ultimately the original data is
+ // returned though.
+ match named_curve {
+ EcNamedCurve::P256 => {
+ // 1-2.
+ let point = p256::EncodedPoint::from_bytes(&data)
+ .map_err(|_| data_error("invalid P-256 eliptic curve point"))?;
+ // 3.
+ if point.is_identity() {
+ return Err(data_error("invalid P-256 eliptic curve point"));
+ }
+ }
+ EcNamedCurve::P384 => {
+ // 1-2.
+ let point = p384::EncodedPoint::from_bytes(&data)
+ .map_err(|_| data_error("invalid P-384 eliptic curve point"))?;
+ // 3.
+ if point.is_identity() {
+ return Err(data_error("invalid P-384 eliptic curve point"));
+ }
+ }
+ };
+ ImportKeyResult::Ec {
+ raw_data: RawKeyData::Public(data),
+ }
+ }
+ _ => return Err(unsupported_format()),
+ })
+}
diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs
index d811e504d..379b101a2 100644
--- a/ext/crypto/lib.rs
+++ b/ext/crypto/lib.rs
@@ -11,7 +11,6 @@ use deno_core::Extension;
use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use serde::Deserialize;
-use serde::Serialize;
use std::cell::RefCell;
use std::num::NonZeroU32;
@@ -57,46 +56,26 @@ use std::path::PathBuf;
pub use rand; // Re-export rand
+mod import_key;
mod key;
+mod shared;
use crate::key::Algorithm;
use crate::key::CryptoHash;
use crate::key::CryptoNamedCurve;
use crate::key::HkdfOutput;
+pub use crate::import_key::op_crypto_import_key;
+use crate::shared::ID_MFG1;
+use crate::shared::ID_P_SPECIFIED;
+use crate::shared::ID_SHA1_OID;
+
// Allowlist for RSA public exponents.
lazy_static! {
static ref PUB_EXPONENT_1: BigUint = BigUint::from_u64(3).unwrap();
static ref PUB_EXPONENT_2: BigUint = BigUint::from_u64(65537).unwrap();
}
-const RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
- rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.1");
-const SHA1_RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
- rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.5");
-const SHA256_RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
- rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.11");
-const SHA384_RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
- rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.12");
-const SHA512_RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
- rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.13");
-const RSASSA_PSS_OID: rsa::pkcs8::ObjectIdentifier =
- rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.10");
-const ID_SHA1_OID: rsa::pkcs8::ObjectIdentifier =
- rsa::pkcs8::ObjectIdentifier::new("1.3.14.3.2.26");
-const ID_SHA256_OID: rsa::pkcs8::ObjectIdentifier =
- rsa::pkcs8::ObjectIdentifier::new("2.16.840.1.101.3.4.2.1");
-const ID_SHA384_OID: rsa::pkcs8::ObjectIdentifier =
- rsa::pkcs8::ObjectIdentifier::new("2.16.840.1.101.3.4.2.2");
-const ID_SHA512_OID: rsa::pkcs8::ObjectIdentifier =
- rsa::pkcs8::ObjectIdentifier::new("2.16.840.1.101.3.4.2.3");
-const ID_MFG1: rsa::pkcs8::ObjectIdentifier =
- rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.8");
-const RSAES_OAEP_OID: rsa::pkcs8::ObjectIdentifier =
- rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.7");
-const ID_P_SPECIFIED: rsa::pkcs8::ObjectIdentifier =
- rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.9");
-
pub fn init(maybe_seed: Option<u64>) -> Extension {
Extension::builder()
.js(include_js_files!(
@@ -113,7 +92,7 @@ pub fn init(maybe_seed: Option<u64>) -> Extension {
("op_crypto_sign_key", op_async(op_crypto_sign_key)),
("op_crypto_verify_key", op_async(op_crypto_verify_key)),
("op_crypto_derive_bits", op_async(op_crypto_derive_bits)),
- ("op_crypto_import_key", op_async(op_crypto_import_key)),
+ ("op_crypto_import_key", op_sync(op_crypto_import_key)),
("op_crypto_export_key", op_async(op_crypto_export_key)),
("op_crypto_encrypt_key", op_async(op_crypto_encrypt_key)),
("op_crypto_decrypt_key", op_async(op_crypto_decrypt_key)),
@@ -1178,684 +1157,6 @@ impl<'a> TryFrom<rsa::pkcs8::der::asn1::Any<'a>>
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
-pub struct ImportKeyArg {
- algorithm: Algorithm,
- format: KeyFormat,
- // RSASSA-PKCS1-v1_5
- hash: Option<CryptoHash>,
- // ECDSA
- named_curve: Option<CryptoNamedCurve>,
-}
-
-#[derive(Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct ImportKeyResult {
- data: ZeroCopyBuf,
- // RSASSA-PKCS1-v1_5
- public_exponent: Option<ZeroCopyBuf>,
- modulus_length: Option<usize>,
-}
-
-pub async fn op_crypto_import_key(
- _state: Rc<RefCell<OpState>>,
- args: ImportKeyArg,
- zero_copy: ZeroCopyBuf,
-) -> Result<ImportKeyResult, AnyError> {
- let data = &*zero_copy;
- let algorithm = args.algorithm;
-
- match algorithm {
- Algorithm::Ecdsa => {
- let curve = args.named_curve.ok_or_else(|| {
- type_error("Missing argument named_curve".to_string())
- })?;
-
- match curve {
- CryptoNamedCurve::P256 => {
- // 1-2.
- let point = p256::EncodedPoint::from_bytes(data)?;
- // 3.
- if point.is_identity() {
- return Err(type_error("Invalid key data".to_string()));
- }
- }
- CryptoNamedCurve::P384 => {
- // 1-2.
- let point = p384::EncodedPoint::from_bytes(data)?;
- // 3.
- if point.is_identity() {
- return Err(type_error("Invalid key data".to_string()));
- }
- }
- };
-
- Ok(ImportKeyResult {
- data: zero_copy,
- modulus_length: None,
- public_exponent: None,
- })
- }
- Algorithm::RsassaPkcs1v15 => {
- match args.format {
- KeyFormat::Pkcs8 => {
- let hash = args
- .hash
- .ok_or_else(|| type_error("Missing argument hash".to_string()))?;
-
- // 2-3.
- let pk_info =
- rsa::pkcs8::PrivateKeyInfo::from_der(data).map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- // 4-5.
- let alg = pk_info.algorithm.oid;
-
- // 6.
- let pk_hash = match alg {
- // rsaEncryption
- RSA_ENCRYPTION_OID => None,
- // sha1WithRSAEncryption
- SHA1_RSA_ENCRYPTION_OID => Some(CryptoHash::Sha1),
- // sha256WithRSAEncryption
- SHA256_RSA_ENCRYPTION_OID => Some(CryptoHash::Sha256),
- // sha384WithRSAEncryption
- SHA384_RSA_ENCRYPTION_OID => Some(CryptoHash::Sha384),
- // sha512WithRSAEncryption
- SHA512_RSA_ENCRYPTION_OID => Some(CryptoHash::Sha512),
- _ => {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Unsupported algorithm".to_string(),
- ))
- }
- };
-
- // 7.
- if let Some(pk_hash) = pk_hash {
- if pk_hash != hash {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Hash mismatch".to_string(),
- ));
- }
- }
-
- // 8-9.
- let private_key = rsa::pkcs1::RsaPrivateKey::from_der(
- pk_info.private_key,
- )
- .map_err(|e| custom_error("DOMExceptionDataError", e.to_string()))?;
-
- let bytes_consumed = private_key.encoded_len().map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- if bytes_consumed
- != spki::der::Length::new(pk_info.private_key.len() as u16)
- {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Some bytes were not consumed".to_string(),
- ));
- }
-
- Ok(ImportKeyResult {
- data: pk_info.private_key.to_vec().into(),
- public_exponent: Some(
- private_key.public_exponent.as_bytes().to_vec().into(),
- ),
- modulus_length: Some(private_key.modulus.as_bytes().len() * 8),
- })
- }
- KeyFormat::Spki => {
- let hash = args
- .hash
- .ok_or_else(|| type_error("Missing argument hash".to_string()))?;
-
- // 2-3.
- let pk_info =
- spki::SubjectPublicKeyInfo::from_der(data).map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- // 4-5.
- let alg = pk_info.algorithm.oid;
-
- // 6.
- let pk_hash = match alg {
- // rsaEncryption
- RSA_ENCRYPTION_OID => None,
- // sha1WithRSAEncryption
- SHA1_RSA_ENCRYPTION_OID => Some(CryptoHash::Sha1),
- // sha256WithRSAEncryption
- SHA256_RSA_ENCRYPTION_OID => Some(CryptoHash::Sha256),
- // sha384WithRSAEncryption
- SHA384_RSA_ENCRYPTION_OID => Some(CryptoHash::Sha384),
- // sha512WithRSAEncryption
- SHA512_RSA_ENCRYPTION_OID => Some(CryptoHash::Sha512),
- _ => {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Unsupported algorithm".to_string(),
- ))
- }
- };
-
- // 7.
- if let Some(pk_hash) = pk_hash {
- if pk_hash != hash {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Hash mismatch".to_string(),
- ));
- }
- }
-
- // 8-9.
- let public_key =
- rsa::pkcs1::RsaPublicKey::from_der(pk_info.subject_public_key)
- .map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- let bytes_consumed = public_key.encoded_len().map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- if bytes_consumed
- != spki::der::Length::new(pk_info.subject_public_key.len() as u16)
- {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Some bytes were not consumed".to_string(),
- ));
- }
-
- Ok(ImportKeyResult {
- data: pk_info.subject_public_key.to_vec().into(),
- public_exponent: Some(
- public_key.public_exponent.as_bytes().to_vec().into(),
- ),
- modulus_length: Some(public_key.modulus.as_bytes().len() * 8),
- })
- }
- // TODO(@littledivy): jwk
- _ => Err(type_error("Unsupported format".to_string())),
- }
- }
- Algorithm::RsaPss => {
- match args.format {
- KeyFormat::Pkcs8 => {
- let hash = args
- .hash
- .ok_or_else(|| type_error("Missing argument hash".to_string()))?;
-
- // 2-3.
- let pk_info =
- rsa::pkcs8::PrivateKeyInfo::from_der(data).map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- // 4-5.
- let alg = pk_info.algorithm.oid;
-
- // 6.
- let pk_hash = match alg {
- // rsaEncryption
- RSA_ENCRYPTION_OID => None,
- // id-RSASSA-PSS
- RSASSA_PSS_OID => {
- let params = PssPrivateKeyParameters::try_from(
- pk_info.algorithm.parameters.ok_or_else(|| {
- custom_error(
- "DOMExceptionNotSupportedError",
- "Malformed parameters".to_string(),
- )
- })?,
- )
- .map_err(|_| {
- custom_error(
- "DOMExceptionNotSupportedError",
- "Malformed parameters".to_string(),
- )
- })?;
-
- let hash_alg = params.hash_algorithm;
- let hash = match hash_alg.oid {
- // id-sha1
- ID_SHA1_OID => Some(CryptoHash::Sha1),
- // id-sha256
- ID_SHA256_OID => Some(CryptoHash::Sha256),
- // id-sha384
- ID_SHA384_OID => Some(CryptoHash::Sha384),
- // id-sha256
- ID_SHA512_OID => Some(CryptoHash::Sha512),
- _ => {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Unsupported hash algorithm".to_string(),
- ))
- }
- };
-
- if params.mask_gen_algorithm.oid != ID_MFG1 {
- return Err(custom_error(
- "DOMExceptionNotSupportedError",
- "Unsupported hash algorithm".to_string(),
- ));
- }
-
- // TODO(lucacasonato):
- // If the parameters field of the maskGenAlgorithm field of params
- // is not an instance of the HashAlgorithm ASN.1 type that is
- // identical in content to the hashAlgorithm field of params,
- // throw a NotSupportedError.
-
- hash
- }
- _ => {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Unsupported algorithm".to_string(),
- ))
- }
- };
-
- // 7.
- if let Some(pk_hash) = pk_hash {
- if pk_hash != hash {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Hash mismatch".to_string(),
- ));
- }
- }
-
- // 8-9.
- let private_key = rsa::pkcs1::RsaPrivateKey::from_der(
- pk_info.private_key,
- )
- .map_err(|e| custom_error("DOMExceptionDataError", e.to_string()))?;
-
- let bytes_consumed = private_key.encoded_len().map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- if bytes_consumed
- != spki::der::Length::new(pk_info.private_key.len() as u16)
- {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Some bytes were not consumed".to_string(),
- ));
- }
-
- Ok(ImportKeyResult {
- data: pk_info.private_key.to_vec().into(),
- public_exponent: Some(
- private_key.public_exponent.as_bytes().to_vec().into(),
- ),
- modulus_length: Some(private_key.modulus.as_bytes().len() * 8),
- })
- }
- KeyFormat::Spki => {
- let hash = args
- .hash
- .ok_or_else(|| type_error("Missing argument hash".to_string()))?;
-
- // 2-3.
- let pk_info =
- spki::SubjectPublicKeyInfo::from_der(data).map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- // 4-5.
- let alg = pk_info.algorithm.oid;
-
- // 6.
- let pk_hash = match alg {
- // rsaEncryption
- RSA_ENCRYPTION_OID => None,
- // id-RSASSA-PSS
- RSASSA_PSS_OID => {
- let params = PssPrivateKeyParameters::try_from(
- pk_info.algorithm.parameters.ok_or_else(|| {
- custom_error(
- "DOMExceptionDataError",
- "Malformed parameters".to_string(),
- )
- })?,
- )
- .map_err(|_| {
- custom_error(
- "DOMExceptionDataError",
- "Malformed parameters".to_string(),
- )
- })?;
-
- let hash_alg = params.hash_algorithm;
- let hash = match hash_alg.oid {
- // id-sha1
- ID_SHA1_OID => Some(CryptoHash::Sha1),
- // id-sha256
- ID_SHA256_OID => Some(CryptoHash::Sha256),
- // id-sha384
- ID_SHA384_OID => Some(CryptoHash::Sha384),
- // id-sha256
- ID_SHA512_OID => Some(CryptoHash::Sha512),
- _ => {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Unsupported hash algorithm".to_string(),
- ))
- }
- };
-
- if params.mask_gen_algorithm.oid != ID_MFG1 {
- return Err(custom_error(
- "DOMExceptionNotSupportedError",
- "Unsupported hash algorithm".to_string(),
- ));
- }
-
- // TODO(lucacasonato):
- // If the parameters field of the maskGenAlgorithm field of params
- // is not an instance of the HashAlgorithm ASN.1 type that is
- // identical in content to the hashAlgorithm field of params,
- // throw a NotSupportedError.
-
- hash
- }
- _ => {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Unsupported algorithm".to_string(),
- ))
- }
- };
-
- // 7.
- if let Some(pk_hash) = pk_hash {
- if pk_hash != hash {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Hash mismatch".to_string(),
- ));
- }
- }
-
- // 8-9.
- let public_key =
- rsa::pkcs1::RsaPublicKey::from_der(pk_info.subject_public_key)
- .map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- let bytes_consumed = public_key.encoded_len().map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- if bytes_consumed
- != spki::der::Length::new(pk_info.subject_public_key.len() as u16)
- {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Some bytes were not consumed".to_string(),
- ));
- }
-
- Ok(ImportKeyResult {
- data: pk_info.subject_public_key.to_vec().into(),
- public_exponent: Some(
- public_key.public_exponent.as_bytes().to_vec().into(),
- ),
- modulus_length: Some(public_key.modulus.as_bytes().len() * 8),
- })
- }
- // TODO(@littledivy): jwk
- _ => Err(type_error("Unsupported format".to_string())),
- }
- }
- Algorithm::RsaOaep => {
- match args.format {
- KeyFormat::Pkcs8 => {
- let hash = args
- .hash
- .ok_or_else(|| type_error("Missing argument hash".to_string()))?;
-
- // 2-3.
- let pk_info =
- rsa::pkcs8::PrivateKeyInfo::from_der(data).map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- // 4-5.
- let alg = pk_info.algorithm.oid;
-
- // 6.
- let pk_hash = match alg {
- // rsaEncryption
- RSA_ENCRYPTION_OID => None,
- // id-RSAES-OAEP
- RSAES_OAEP_OID => {
- let params = OaepPrivateKeyParameters::try_from(
- pk_info.algorithm.parameters.ok_or_else(|| {
- custom_error(
- "DOMExceptionNotSupportedError",
- "Malformed parameters".to_string(),
- )
- })?,
- )
- .map_err(|_| {
- custom_error(
- "DOMExceptionNotSupportedError",
- "Malformed parameters".to_string(),
- )
- })?;
-
- let hash_alg = params.hash_algorithm;
- let hash = match hash_alg.oid {
- // id-sha1
- ID_SHA1_OID => Some(CryptoHash::Sha1),
- // id-sha256
- ID_SHA256_OID => Some(CryptoHash::Sha256),
- // id-sha384
- ID_SHA384_OID => Some(CryptoHash::Sha384),
- // id-sha256
- ID_SHA512_OID => Some(CryptoHash::Sha512),
- _ => {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Unsupported hash algorithm".to_string(),
- ))
- }
- };
-
- if params.mask_gen_algorithm.oid != ID_MFG1 {
- return Err(custom_error(
- "DOMExceptionNotSupportedError",
- "Unsupported hash algorithm".to_string(),
- ));
- }
-
- // TODO(lucacasonato):
- // If the parameters field of the maskGenAlgorithm field of params
- // is not an instance of the HashAlgorithm ASN.1 type that is
- // identical in content to the hashAlgorithm field of params,
- // throw a NotSupportedError.
-
- hash
- }
- _ => {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Unsupported algorithm".to_string(),
- ))
- }
- };
-
- // 7.
- if let Some(pk_hash) = pk_hash {
- if pk_hash != hash {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Hash mismatch".to_string(),
- ));
- }
- }
-
- // 8-9.
- let private_key = rsa::pkcs1::RsaPrivateKey::from_der(
- pk_info.private_key,
- )
- .map_err(|e| custom_error("DOMExceptionDataError", e.to_string()))?;
-
- let bytes_consumed = private_key.encoded_len().map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- if bytes_consumed
- != spki::der::Length::new(pk_info.private_key.len() as u16)
- {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Some bytes were not consumed".to_string(),
- ));
- }
-
- Ok(ImportKeyResult {
- data: pk_info.private_key.to_vec().into(),
- public_exponent: Some(
- private_key.public_exponent.as_bytes().to_vec().into(),
- ),
- modulus_length: Some(private_key.modulus.as_bytes().len() * 8),
- })
- }
- KeyFormat::Spki => {
- let hash = args
- .hash
- .ok_or_else(|| type_error("Missing argument hash".to_string()))?;
-
- // 2-3.
- let pk_info =
- spki::SubjectPublicKeyInfo::from_der(data).map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- // 4-5.
- let alg = pk_info.algorithm.oid;
-
- // 6.
- let pk_hash = match alg {
- // rsaEncryption
- RSA_ENCRYPTION_OID => None,
- // id-RSAES-OAEP
- RSAES_OAEP_OID => {
- let params = OaepPrivateKeyParameters::try_from(
- pk_info.algorithm.parameters.ok_or_else(|| {
- custom_error(
- "DOMExceptionDataError",
- "Malformed parameters".to_string(),
- )
- })?,
- )
- .map_err(|_| {
- custom_error(
- "DOMExceptionDataError",
- "Malformed parameters".to_string(),
- )
- })?;
-
- let hash_alg = params.hash_algorithm;
- let hash = match hash_alg.oid {
- // id-sha1
- ID_SHA1_OID => Some(CryptoHash::Sha1),
- // id-sha256
- ID_SHA256_OID => Some(CryptoHash::Sha256),
- // id-sha384
- ID_SHA384_OID => Some(CryptoHash::Sha384),
- // id-sha256
- ID_SHA512_OID => Some(CryptoHash::Sha512),
- _ => {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Unsupported hash algorithm".to_string(),
- ))
- }
- };
-
- if params.mask_gen_algorithm.oid != ID_MFG1 {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Unsupported hash algorithm".to_string(),
- ));
- }
-
- // TODO(lucacasonato):
- // If the parameters field of the maskGenAlgorithm field of params
- // is not an instance of the HashAlgorithm ASN.1 type that is
- // identical in content to the hashAlgorithm field of params,
- // throw a NotSupportedError.
-
- hash
- }
- _ => {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Unsupported algorithm".to_string(),
- ))
- }
- };
-
- // 7.
- if let Some(pk_hash) = pk_hash {
- if pk_hash != hash {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Hash mismatch".to_string(),
- ));
- }
- }
-
- // 8-9.
- let public_key =
- rsa::pkcs1::RsaPublicKey::from_der(pk_info.subject_public_key)
- .map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- let bytes_consumed = public_key.encoded_len().map_err(|e| {
- custom_error("DOMExceptionDataError", e.to_string())
- })?;
-
- if bytes_consumed
- != spki::der::Length::new(pk_info.subject_public_key.len() as u16)
- {
- return Err(custom_error(
- "DOMExceptionDataError",
- "Some bytes were not consumed".to_string(),
- ));
- }
-
- Ok(ImportKeyResult {
- data: pk_info.subject_public_key.to_vec().into(),
- public_exponent: Some(
- public_key.public_exponent.as_bytes().to_vec().into(),
- ),
- modulus_length: Some(public_key.modulus.as_bytes().len() * 8),
- })
- }
- // TODO(@littledivy): jwk
- _ => Err(type_error("Unsupported format".to_string())),
- }
- }
- _ => Err(type_error("Unsupported algorithm".to_string())),
- }
-}
-
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
pub struct DecryptArg {
key: KeyData,
algorithm: Algorithm,
diff --git a/ext/crypto/shared.rs b/ext/crypto/shared.rs
new file mode 100644
index 000000000..696b1c087
--- /dev/null
+++ b/ext/crypto/shared.rs
@@ -0,0 +1,74 @@
+use std::borrow::Cow;
+
+use deno_core::error::custom_error;
+use deno_core::error::AnyError;
+use deno_core::ZeroCopyBuf;
+use serde::Deserialize;
+use serde::Serialize;
+
+pub const RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
+ rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.1");
+pub const SHA1_RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
+ rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.5");
+pub const SHA256_RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
+ rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.11");
+pub const SHA384_RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
+ rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.12");
+pub const SHA512_RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
+ rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.13");
+pub const RSASSA_PSS_OID: rsa::pkcs8::ObjectIdentifier =
+ rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.10");
+pub const ID_SHA1_OID: rsa::pkcs8::ObjectIdentifier =
+ rsa::pkcs8::ObjectIdentifier::new("1.3.14.3.2.26");
+pub const ID_SHA256_OID: rsa::pkcs8::ObjectIdentifier =
+ rsa::pkcs8::ObjectIdentifier::new("2.16.840.1.101.3.4.2.1");
+pub const ID_SHA384_OID: rsa::pkcs8::ObjectIdentifier =
+ rsa::pkcs8::ObjectIdentifier::new("2.16.840.1.101.3.4.2.2");
+pub const ID_SHA512_OID: rsa::pkcs8::ObjectIdentifier =
+ rsa::pkcs8::ObjectIdentifier::new("2.16.840.1.101.3.4.2.3");
+pub const ID_MFG1: rsa::pkcs8::ObjectIdentifier =
+ rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.8");
+pub const RSAES_OAEP_OID: rsa::pkcs8::ObjectIdentifier =
+ rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.7");
+pub const ID_P_SPECIFIED: rsa::pkcs8::ObjectIdentifier =
+ rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.9");
+
+#[derive(Serialize, Deserialize, Copy, Clone, PartialEq)]
+pub enum ShaHash {
+ #[serde(rename = "SHA-1")]
+ Sha1,
+ #[serde(rename = "SHA-256")]
+ Sha256,
+ #[serde(rename = "SHA-384")]
+ Sha384,
+ #[serde(rename = "SHA-512")]
+ Sha512,
+}
+
+#[derive(Serialize, Deserialize, Copy, Clone, PartialEq)]
+pub enum EcNamedCurve {
+ #[serde(rename = "P-256")]
+ P256,
+ #[serde(rename = "P-384")]
+ P384,
+}
+
+#[derive(Serialize, Deserialize)]
+#[serde(rename_all = "lowercase", tag = "type", content = "data")]
+pub enum RawKeyData {
+ Secret(ZeroCopyBuf),
+ Private(ZeroCopyBuf),
+ Public(ZeroCopyBuf),
+}
+
+pub fn data_error(msg: impl Into<Cow<'static, str>>) -> AnyError {
+ custom_error("DOMExceptionDataError", msg)
+}
+
+pub fn not_supported_error(msg: impl Into<Cow<'static, str>>) -> AnyError {
+ custom_error("DOMExceptionNotSupportedError", msg)
+}
+
+pub fn unsupported_format() -> AnyError {
+ not_supported_error("unsupported format")
+}