mirror of
https://github.com/denoland/deno.git
synced 2025-03-04 01:44:26 -05:00
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.
This commit is contained in:
parent
38f1630223
commit
2926827726
4 changed files with 689 additions and 748 deletions
|
@ -759,6 +759,7 @@
|
||||||
* @param {KeyUsages[]} keyUsages
|
* @param {KeyUsages[]} keyUsages
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
|
// deno-lint-ignore require-await
|
||||||
async importKey(format, keyData, algorithm, extractable, keyUsages) {
|
async importKey(format, keyData, algorithm, extractable, keyUsages) {
|
||||||
webidl.assertBranded(this, SubtleCrypto);
|
webidl.assertBranded(this, SubtleCrypto);
|
||||||
const prefix = "Failed to execute 'importKey' on 'SubtleCrypto'";
|
const prefix = "Failed to execute 'importKey' on 'SubtleCrypto'";
|
||||||
|
@ -812,7 +813,7 @@
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "ECDSA": {
|
case "ECDSA": {
|
||||||
return await importKeyECDSA(
|
return importKeyECDSA(
|
||||||
format,
|
format,
|
||||||
normalizedAlgorithm,
|
normalizedAlgorithm,
|
||||||
keyData,
|
keyData,
|
||||||
|
@ -823,7 +824,7 @@
|
||||||
case "RSASSA-PKCS1-v1_5":
|
case "RSASSA-PKCS1-v1_5":
|
||||||
case "RSA-PSS":
|
case "RSA-PSS":
|
||||||
case "RSA-OAEP": {
|
case "RSA-OAEP": {
|
||||||
return await importKeyRSA(
|
return importKeyRSA(
|
||||||
format,
|
format,
|
||||||
normalizedAlgorithm,
|
normalizedAlgorithm,
|
||||||
keyData,
|
keyData,
|
||||||
|
@ -850,7 +851,7 @@
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "AES-KW": {
|
case "AES-KW": {
|
||||||
return await importKeyAES(
|
return importKeyAES(
|
||||||
format,
|
format,
|
||||||
normalizedAlgorithm,
|
normalizedAlgorithm,
|
||||||
keyData,
|
keyData,
|
||||||
|
@ -2194,7 +2195,7 @@
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function importKeyECDSA(
|
function importKeyECDSA(
|
||||||
format,
|
format,
|
||||||
normalizedAlgorithm,
|
normalizedAlgorithm,
|
||||||
keyData,
|
keyData,
|
||||||
|
@ -2227,16 +2228,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3.
|
// 3.
|
||||||
const { data } = await core.opAsync("op_crypto_import_key", {
|
const { rawData } = core.opSync("op_crypto_import_key", {
|
||||||
algorithm: "ECDSA",
|
algorithm: "ECDSA",
|
||||||
namedCurve: normalizedAlgorithm.namedCurve,
|
namedCurve: normalizedAlgorithm.namedCurve,
|
||||||
}, keyData);
|
}, { raw: keyData });
|
||||||
|
|
||||||
const handle = {};
|
const handle = {};
|
||||||
WeakMapPrototypeSet(KEY_STORE, handle, {
|
WeakMapPrototypeSet(KEY_STORE, handle, rawData);
|
||||||
type: "public",
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 4-5.
|
// 4-5.
|
||||||
const algorithm = {
|
const algorithm = {
|
||||||
|
@ -2275,7 +2273,7 @@
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
async function importKeyRSA(
|
function importKeyRSA(
|
||||||
format,
|
format,
|
||||||
normalizedAlgorithm,
|
normalizedAlgorithm,
|
||||||
keyData,
|
keyData,
|
||||||
|
@ -2299,23 +2297,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2-9.
|
// 2-9.
|
||||||
const { modulusLength, publicExponent, data } = await core
|
const { modulusLength, publicExponent, rawData } = core.opSync(
|
||||||
.opAsync(
|
"op_crypto_import_key",
|
||||||
"op_crypto_import_key",
|
{
|
||||||
{
|
algorithm: normalizedAlgorithm.name,
|
||||||
algorithm: normalizedAlgorithm.name,
|
// Needed to perform step 7 without normalization.
|
||||||
format: "pkcs8",
|
hash: normalizedAlgorithm.hash.name,
|
||||||
// Needed to perform step 7 without normalization.
|
},
|
||||||
hash: normalizedAlgorithm.hash.name,
|
{ pkcs8: keyData },
|
||||||
},
|
);
|
||||||
keyData,
|
|
||||||
);
|
|
||||||
|
|
||||||
const handle = {};
|
const handle = {};
|
||||||
WeakMapPrototypeSet(KEY_STORE, handle, {
|
WeakMapPrototypeSet(KEY_STORE, handle, rawData);
|
||||||
type: "private",
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
|
|
||||||
const algorithm = {
|
const algorithm = {
|
||||||
name: normalizedAlgorithm.name,
|
name: normalizedAlgorithm.name,
|
||||||
|
@ -2350,23 +2343,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2-9.
|
// 2-9.
|
||||||
const { modulusLength, publicExponent, data } = await core
|
const { modulusLength, publicExponent, rawData } = core.opSync(
|
||||||
.opAsync(
|
"op_crypto_import_key",
|
||||||
"op_crypto_import_key",
|
{
|
||||||
{
|
algorithm: normalizedAlgorithm.name,
|
||||||
algorithm: normalizedAlgorithm.name,
|
// Needed to perform step 7 without normalization.
|
||||||
format: "spki",
|
hash: normalizedAlgorithm.hash.name,
|
||||||
// Needed to perform step 7 without normalization.
|
},
|
||||||
hash: normalizedAlgorithm.hash.name,
|
{ spki: keyData },
|
||||||
},
|
);
|
||||||
keyData,
|
|
||||||
);
|
|
||||||
|
|
||||||
const handle = {};
|
const handle = {};
|
||||||
WeakMapPrototypeSet(KEY_STORE, handle, {
|
WeakMapPrototypeSet(KEY_STORE, handle, rawData);
|
||||||
type: "public",
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
|
|
||||||
const algorithm = {
|
const algorithm = {
|
||||||
name: normalizedAlgorithm.name,
|
name: normalizedAlgorithm.name,
|
||||||
|
|
578
ext/crypto/import_key.rs
Normal file
578
ext/crypto/import_key.rs
Normal file
|
@ -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()),
|
||||||
|
})
|
||||||
|
}
|
|
@ -11,7 +11,6 @@ use deno_core::Extension;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
|
@ -57,46 +56,26 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
pub use rand; // Re-export rand
|
pub use rand; // Re-export rand
|
||||||
|
|
||||||
|
mod import_key;
|
||||||
mod key;
|
mod key;
|
||||||
|
mod shared;
|
||||||
|
|
||||||
use crate::key::Algorithm;
|
use crate::key::Algorithm;
|
||||||
use crate::key::CryptoHash;
|
use crate::key::CryptoHash;
|
||||||
use crate::key::CryptoNamedCurve;
|
use crate::key::CryptoNamedCurve;
|
||||||
use crate::key::HkdfOutput;
|
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.
|
// Allowlist for RSA public exponents.
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref PUB_EXPONENT_1: BigUint = BigUint::from_u64(3).unwrap();
|
static ref PUB_EXPONENT_1: BigUint = BigUint::from_u64(3).unwrap();
|
||||||
static ref PUB_EXPONENT_2: BigUint = BigUint::from_u64(65537).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 {
|
pub fn init(maybe_seed: Option<u64>) -> Extension {
|
||||||
Extension::builder()
|
Extension::builder()
|
||||||
.js(include_js_files!(
|
.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_sign_key", op_async(op_crypto_sign_key)),
|
||||||
("op_crypto_verify_key", op_async(op_crypto_verify_key)),
|
("op_crypto_verify_key", op_async(op_crypto_verify_key)),
|
||||||
("op_crypto_derive_bits", op_async(op_crypto_derive_bits)),
|
("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_export_key", op_async(op_crypto_export_key)),
|
||||||
("op_crypto_encrypt_key", op_async(op_crypto_encrypt_key)),
|
("op_crypto_encrypt_key", op_async(op_crypto_encrypt_key)),
|
||||||
("op_crypto_decrypt_key", op_async(op_crypto_decrypt_key)),
|
("op_crypto_decrypt_key", op_async(op_crypto_decrypt_key)),
|
||||||
|
@ -1176,684 +1155,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)]
|
#[derive(Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct DecryptArg {
|
pub struct DecryptArg {
|
||||||
|
|
74
ext/crypto/shared.rs
Normal file
74
ext/crypto/shared.rs
Normal file
|
@ -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")
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue