mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
chore(ext/crypto): update webcrypto deps (#14452)
This commit is contained in:
parent
3d6fa64f19
commit
4cbb2567b5
10 changed files with 603 additions and 765 deletions
662
Cargo.lock
generated
662
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -14,26 +14,31 @@ description = "Web Cryptography API implementation for Deno"
|
|||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
aes = "0.7.5"
|
||||
aes-gcm = "0.9.4"
|
||||
aes-kw = { version = "0.1", features = ["alloc"] }
|
||||
aes = "0.8.1"
|
||||
# TODO(@littledivy): Move to stable release
|
||||
# https://github.com/RustCrypto/AEADs/issues/411
|
||||
aes-gcm = "0.10.0-pre"
|
||||
aes-kw = { version = "0.2.1", features = ["alloc"] }
|
||||
base64 = "0.13.0"
|
||||
block-modes = "0.8.1"
|
||||
ctr = "0.8.0"
|
||||
block-modes = "0.9.1"
|
||||
cbc = { version = "0.1.2", features = ["alloc"] }
|
||||
const-oid = "0.9.0"
|
||||
ctr = "0.9.1"
|
||||
deno_core = { version = "0.139.0", path = "../../core" }
|
||||
deno_web = { version = "0.88.0", path = "../web" }
|
||||
elliptic-curve = { version = "0.10.6", features = ["std", "pem"] }
|
||||
elliptic-curve = { version = "0.12.1", features = ["std", "pem"] }
|
||||
num-traits = "0.2.14"
|
||||
once_cell = "1.10.0"
|
||||
p256 = { version = "0.9.0", features = ["ecdh"] }
|
||||
p384 = "0.8.0"
|
||||
p256 = { version = "0.11.1", features = ["ecdh"] }
|
||||
p384 = "0.11.1"
|
||||
rand = "0.8.4"
|
||||
ring = { version = "0.16.20", features = ["std"] }
|
||||
rsa = { version = "0.5.0", default-features = false, features = ["std"] }
|
||||
rsa = { version = "0.7.0-pre", default-features = false, features = ["std"] }
|
||||
sec1 = "0.3.0"
|
||||
serde = { version = "1.0.129", features = ["derive"] }
|
||||
serde_bytes = "0.11"
|
||||
sha-1 = "0.9.7"
|
||||
sha2 = "0.9.5"
|
||||
spki = "0.4.1"
|
||||
sha-1 = "0.10.0"
|
||||
sha2 = "0.10.2"
|
||||
spki = "0.6.0"
|
||||
tokio = { version = "1.17", features = ["full"] }
|
||||
uuid = { version = "1.0.0", features = ["v4"] }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::shared::*;
|
||||
use aes::BlockEncrypt;
|
||||
use aes::NewBlockCipher;
|
||||
use aes::cipher::block_padding::Pkcs7;
|
||||
use aes::cipher::BlockDecryptMut;
|
||||
use aes::cipher::KeyIvInit;
|
||||
use aes_gcm::aead::generic_array::typenum::U12;
|
||||
use aes_gcm::aead::generic_array::typenum::U16;
|
||||
use aes_gcm::aead::generic_array::ArrayLength;
|
||||
|
@ -10,20 +11,16 @@ use aes_gcm::aes::Aes256;
|
|||
use aes_gcm::AeadInPlace;
|
||||
use aes_gcm::NewAead;
|
||||
use aes_gcm::Nonce;
|
||||
use block_modes::BlockMode;
|
||||
use ctr::cipher::NewCipher;
|
||||
use ctr::cipher::StreamCipher;
|
||||
use ctr::flavors::Ctr128BE;
|
||||
use ctr::flavors::Ctr32BE;
|
||||
use ctr::flavors::Ctr64BE;
|
||||
use ctr::flavors::CtrFlavor;
|
||||
use ctr::Ctr;
|
||||
use ctr::Ctr128BE;
|
||||
use ctr::Ctr32BE;
|
||||
use ctr::Ctr64BE;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use rsa::pkcs1::FromRsaPrivateKey;
|
||||
use rsa::pkcs1::DecodeRsaPrivateKey;
|
||||
use rsa::PaddingScheme;
|
||||
use serde::Deserialize;
|
||||
use sha1::Digest;
|
||||
|
@ -153,11 +150,15 @@ fn decrypt_aes_cbc(
|
|||
let plaintext = match length {
|
||||
128 => {
|
||||
// Section 10.3 Step 2 of RFC 2315 https://www.rfc-editor.org/rfc/rfc2315
|
||||
type Aes128Cbc =
|
||||
block_modes::Cbc<aes::Aes128, block_modes::block_padding::Pkcs7>;
|
||||
let cipher = Aes128Cbc::new_from_slices(key, &iv)?;
|
||||
type Aes128CbcDec = cbc::Decryptor<aes::Aes128>;
|
||||
let cipher = Aes128CbcDec::new_from_slices(key, &iv).map_err(|_| {
|
||||
custom_error(
|
||||
"DOMExceptionOperationError",
|
||||
"Invalid key or iv".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
cipher.decrypt_vec(data).map_err(|_| {
|
||||
cipher.decrypt_padded_vec_mut::<Pkcs7>(data).map_err(|_| {
|
||||
custom_error(
|
||||
"DOMExceptionOperationError",
|
||||
"Decryption failed".to_string(),
|
||||
|
@ -166,11 +167,15 @@ fn decrypt_aes_cbc(
|
|||
}
|
||||
192 => {
|
||||
// Section 10.3 Step 2 of RFC 2315 https://www.rfc-editor.org/rfc/rfc2315
|
||||
type Aes192Cbc =
|
||||
block_modes::Cbc<aes::Aes192, block_modes::block_padding::Pkcs7>;
|
||||
let cipher = Aes192Cbc::new_from_slices(key, &iv)?;
|
||||
type Aes192CbcDec = cbc::Decryptor<aes::Aes192>;
|
||||
let cipher = Aes192CbcDec::new_from_slices(key, &iv).map_err(|_| {
|
||||
custom_error(
|
||||
"DOMExceptionOperationError",
|
||||
"Invalid key or iv".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
cipher.decrypt_vec(data).map_err(|_| {
|
||||
cipher.decrypt_padded_vec_mut::<Pkcs7>(data).map_err(|_| {
|
||||
custom_error(
|
||||
"DOMExceptionOperationError",
|
||||
"Decryption failed".to_string(),
|
||||
|
@ -179,11 +184,15 @@ fn decrypt_aes_cbc(
|
|||
}
|
||||
256 => {
|
||||
// Section 10.3 Step 2 of RFC 2315 https://www.rfc-editor.org/rfc/rfc2315
|
||||
type Aes256Cbc =
|
||||
block_modes::Cbc<aes::Aes256, block_modes::block_padding::Pkcs7>;
|
||||
let cipher = Aes256Cbc::new_from_slices(key, &iv)?;
|
||||
type Aes256CbcDec = cbc::Decryptor<aes::Aes256>;
|
||||
let cipher = Aes256CbcDec::new_from_slices(key, &iv).map_err(|_| {
|
||||
custom_error(
|
||||
"DOMExceptionOperationError",
|
||||
"Invalid key or iv".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
cipher.decrypt_vec(data).map_err(|_| {
|
||||
cipher.decrypt_padded_vec_mut::<Pkcs7>(data).map_err(|_| {
|
||||
custom_error(
|
||||
"DOMExceptionOperationError",
|
||||
"Decryption failed".to_string(),
|
||||
|
@ -197,16 +206,15 @@ fn decrypt_aes_cbc(
|
|||
Ok(plaintext)
|
||||
}
|
||||
|
||||
fn decrypt_aes_ctr_gen<B, F>(
|
||||
fn decrypt_aes_ctr_gen<B>(
|
||||
key: &[u8],
|
||||
counter: &[u8],
|
||||
data: &[u8],
|
||||
) -> Result<Vec<u8>, AnyError>
|
||||
where
|
||||
B: BlockEncrypt + NewBlockCipher,
|
||||
F: CtrFlavor<B::BlockSize>,
|
||||
B: KeyIvInit + StreamCipher,
|
||||
{
|
||||
let mut cipher = Ctr::<B, F>::new(key.into(), counter.into());
|
||||
let mut cipher = B::new(key.into(), counter.into());
|
||||
|
||||
let mut plaintext = data.to_vec();
|
||||
cipher
|
||||
|
@ -279,21 +287,21 @@ fn decrypt_aes_ctr(
|
|||
|
||||
match ctr_length {
|
||||
32 => match key_length {
|
||||
128 => decrypt_aes_ctr_gen::<aes::Aes128, Ctr32BE>(key, counter, data),
|
||||
192 => decrypt_aes_ctr_gen::<aes::Aes192, Ctr32BE>(key, counter, data),
|
||||
256 => decrypt_aes_ctr_gen::<aes::Aes256, Ctr32BE>(key, counter, data),
|
||||
128 => decrypt_aes_ctr_gen::<Ctr32BE<aes::Aes128>>(key, counter, data),
|
||||
192 => decrypt_aes_ctr_gen::<Ctr32BE<aes::Aes192>>(key, counter, data),
|
||||
256 => decrypt_aes_ctr_gen::<Ctr32BE<aes::Aes256>>(key, counter, data),
|
||||
_ => Err(type_error("invalid length")),
|
||||
},
|
||||
64 => match key_length {
|
||||
128 => decrypt_aes_ctr_gen::<aes::Aes128, Ctr64BE>(key, counter, data),
|
||||
192 => decrypt_aes_ctr_gen::<aes::Aes192, Ctr64BE>(key, counter, data),
|
||||
256 => decrypt_aes_ctr_gen::<aes::Aes256, Ctr64BE>(key, counter, data),
|
||||
128 => decrypt_aes_ctr_gen::<Ctr64BE<aes::Aes128>>(key, counter, data),
|
||||
192 => decrypt_aes_ctr_gen::<Ctr64BE<aes::Aes192>>(key, counter, data),
|
||||
256 => decrypt_aes_ctr_gen::<Ctr64BE<aes::Aes256>>(key, counter, data),
|
||||
_ => Err(type_error("invalid length")),
|
||||
},
|
||||
128 => match key_length {
|
||||
128 => decrypt_aes_ctr_gen::<aes::Aes128, Ctr128BE>(key, counter, data),
|
||||
192 => decrypt_aes_ctr_gen::<aes::Aes192, Ctr128BE>(key, counter, data),
|
||||
256 => decrypt_aes_ctr_gen::<aes::Aes256, Ctr128BE>(key, counter, data),
|
||||
128 => decrypt_aes_ctr_gen::<Ctr128BE<aes::Aes128>>(key, counter, data),
|
||||
192 => decrypt_aes_ctr_gen::<Ctr128BE<aes::Aes192>>(key, counter, data),
|
||||
256 => decrypt_aes_ctr_gen::<Ctr128BE<aes::Aes256>>(key, counter, data),
|
||||
_ => Err(type_error("invalid length")),
|
||||
},
|
||||
_ => Err(type_error(
|
||||
|
|
|
@ -1,148 +0,0 @@
|
|||
use deno_core::error::AnyError;
|
||||
|
||||
use elliptic_curve::AlgorithmParameters;
|
||||
|
||||
use elliptic_curve::pkcs8;
|
||||
use elliptic_curve::pkcs8::der;
|
||||
use elliptic_curve::pkcs8::der::asn1::*;
|
||||
use elliptic_curve::pkcs8::der::Decodable as Pkcs8Decodable;
|
||||
use elliptic_curve::pkcs8::der::Encodable;
|
||||
use elliptic_curve::pkcs8::der::TagNumber;
|
||||
use elliptic_curve::pkcs8::AlgorithmIdentifier;
|
||||
use elliptic_curve::pkcs8::ObjectIdentifier;
|
||||
use elliptic_curve::pkcs8::PrivateKeyDocument;
|
||||
use elliptic_curve::pkcs8::PrivateKeyInfo;
|
||||
use elliptic_curve::zeroize::Zeroizing;
|
||||
|
||||
use crate::shared::*;
|
||||
|
||||
const VERSION: u8 = 1;
|
||||
|
||||
const PUBLIC_KEY_TAG: TagNumber = TagNumber::new(1);
|
||||
|
||||
pub struct ECPrivateKey<'a, C: elliptic_curve::Curve> {
|
||||
pub algorithm: AlgorithmIdentifier<'a>,
|
||||
|
||||
pub private_d: elliptic_curve::FieldBytes<C>,
|
||||
|
||||
pub encoded_point: &'a [u8],
|
||||
}
|
||||
|
||||
impl<'a, C> ECPrivateKey<'a, C>
|
||||
where
|
||||
C: elliptic_curve::Curve + AlgorithmParameters,
|
||||
{
|
||||
/// Create a new ECPrivateKey from a serialized private scalar and encoded public key
|
||||
pub fn from_private_and_public_bytes(
|
||||
private_d: elliptic_curve::FieldBytes<C>,
|
||||
encoded_point: &'a [u8],
|
||||
) -> Self {
|
||||
Self {
|
||||
private_d,
|
||||
encoded_point,
|
||||
algorithm: C::algorithm_identifier(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn named_curve_oid(&self) -> Result<ObjectIdentifier, AnyError> {
|
||||
let parameters = self
|
||||
.algorithm
|
||||
.parameters
|
||||
.ok_or_else(|| data_error("malformed parameters"))?;
|
||||
|
||||
Ok(parameters.oid().unwrap())
|
||||
}
|
||||
|
||||
fn internal_to_pkcs8_der(&self) -> der::Result<Vec<u8>> {
|
||||
// Shamelessly copied from pkcs8 crate and modified so as
|
||||
// to not require Arithmetic trait currently missing from p384
|
||||
let secret_key_field = OctetString::new(&self.private_d)?;
|
||||
let public_key_bytes = &self.encoded_point;
|
||||
let public_key_field = ContextSpecific {
|
||||
tag_number: PUBLIC_KEY_TAG,
|
||||
value: BitString::new(public_key_bytes)?.into(),
|
||||
};
|
||||
|
||||
let der_message_fields: &[&dyn Encodable] =
|
||||
&[&VERSION, &secret_key_field, &public_key_field];
|
||||
|
||||
let encoded_len =
|
||||
der::message::encoded_len(der_message_fields)?.try_into()?;
|
||||
let mut der_message = Zeroizing::new(vec![0u8; encoded_len]);
|
||||
let mut encoder = der::Encoder::new(&mut der_message);
|
||||
encoder.message(der_message_fields)?;
|
||||
encoder.finish()?;
|
||||
|
||||
Ok(der_message.to_vec())
|
||||
}
|
||||
|
||||
pub fn to_pkcs8_der(&self) -> Result<PrivateKeyDocument, AnyError> {
|
||||
let pkcs8_der = self
|
||||
.internal_to_pkcs8_der()
|
||||
.map_err(|_| data_error("expected valid PKCS#8 data"))?;
|
||||
|
||||
let pki =
|
||||
pkcs8::PrivateKeyInfo::new(C::algorithm_identifier(), pkcs8_der.as_ref());
|
||||
|
||||
Ok(pki.to_der())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, C: elliptic_curve::Curve> TryFrom<&'a [u8]> for ECPrivateKey<'a, C> {
|
||||
type Error = AnyError;
|
||||
|
||||
fn try_from(bytes: &'a [u8]) -> Result<ECPrivateKey<C>, AnyError> {
|
||||
let pk_info = PrivateKeyInfo::from_der(bytes)
|
||||
.map_err(|_| data_error("expected valid PKCS#8 data"))?;
|
||||
|
||||
Self::try_from(pk_info)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, C: elliptic_curve::Curve> TryFrom<PrivateKeyInfo<'a>>
|
||||
for ECPrivateKey<'a, C>
|
||||
{
|
||||
type Error = AnyError;
|
||||
|
||||
fn try_from(
|
||||
pk_info: PrivateKeyInfo<'a>,
|
||||
) -> Result<ECPrivateKey<'a, C>, AnyError> {
|
||||
let any = der::asn1::Any::from_der(pk_info.private_key).map_err(|_| {
|
||||
data_error("expected valid PrivateKeyInfo private_key der")
|
||||
})?;
|
||||
|
||||
if pk_info.algorithm.oid != elliptic_curve::ALGORITHM_OID {
|
||||
return Err(data_error("unsupported algorithm"));
|
||||
}
|
||||
|
||||
any
|
||||
.sequence(|decoder| {
|
||||
// ver
|
||||
if decoder.uint8()? != VERSION {
|
||||
return Err(der::Tag::Integer.value_error());
|
||||
}
|
||||
|
||||
// private_key
|
||||
let priv_key = decoder.octet_string()?.as_bytes();
|
||||
let mut private_d = elliptic_curve::FieldBytes::<C>::default();
|
||||
if priv_key.len() != private_d.len() {
|
||||
return Err(der::Tag::Sequence.value_error());
|
||||
};
|
||||
private_d.copy_from_slice(priv_key);
|
||||
|
||||
let public_key = decoder
|
||||
.context_specific(PUBLIC_KEY_TAG)?
|
||||
.ok_or_else(|| {
|
||||
der::Tag::ContextSpecific(PUBLIC_KEY_TAG).value_error()
|
||||
})?
|
||||
.bit_string()?;
|
||||
|
||||
Ok(Self {
|
||||
private_d,
|
||||
encoded_point: public_key.as_bytes(),
|
||||
algorithm: pk_info.algorithm,
|
||||
})
|
||||
})
|
||||
.map_err(|_| data_error("expected valid PrivateKeyInfo private_key der"))
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
use crate::shared::*;
|
||||
|
||||
use aes::cipher::NewCipher;
|
||||
use aes::BlockEncrypt;
|
||||
use aes::NewBlockCipher;
|
||||
use aes::cipher::block_padding::Pkcs7;
|
||||
use aes::cipher::BlockEncryptMut;
|
||||
use aes::cipher::KeyIvInit;
|
||||
use aes::cipher::StreamCipher;
|
||||
use aes_gcm::aead::generic_array::typenum::U12;
|
||||
use aes_gcm::aead::generic_array::typenum::U16;
|
||||
use aes_gcm::aead::generic_array::ArrayLength;
|
||||
|
@ -12,21 +13,15 @@ use aes_gcm::aes::Aes256;
|
|||
use aes_gcm::AeadInPlace;
|
||||
use aes_gcm::NewAead;
|
||||
use aes_gcm::Nonce;
|
||||
use ctr::Ctr;
|
||||
use deno_core::op;
|
||||
|
||||
use block_modes::BlockMode;
|
||||
use ctr::cipher::StreamCipher;
|
||||
use ctr::flavors::Ctr128BE;
|
||||
|
||||
use ctr::flavors::Ctr32BE;
|
||||
use ctr::flavors::Ctr64BE;
|
||||
use ctr::flavors::CtrFlavor;
|
||||
use ctr::Ctr128BE;
|
||||
use ctr::Ctr32BE;
|
||||
use ctr::Ctr64BE;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use rand::rngs::OsRng;
|
||||
use rsa::pkcs1::FromRsaPublicKey;
|
||||
use rsa::pkcs1::DecodeRsaPublicKey;
|
||||
use rsa::PaddingScheme;
|
||||
use rsa::PublicKey;
|
||||
use serde::Deserialize;
|
||||
|
@ -156,27 +151,27 @@ fn encrypt_aes_cbc(
|
|||
let ciphertext = match length {
|
||||
128 => {
|
||||
// Section 10.3 Step 2 of RFC 2315 https://www.rfc-editor.org/rfc/rfc2315
|
||||
type Aes128Cbc =
|
||||
block_modes::Cbc<aes::Aes128, block_modes::block_padding::Pkcs7>;
|
||||
type Aes128CbcEnc = cbc::Encryptor<aes::Aes128>;
|
||||
|
||||
let cipher = Aes128Cbc::new_from_slices(key, &iv)?;
|
||||
cipher.encrypt_vec(data)
|
||||
let cipher = Aes128CbcEnc::new_from_slices(key, &iv)
|
||||
.map_err(|_| operation_error("invalid key or iv".to_string()))?;
|
||||
cipher.encrypt_padded_vec_mut::<Pkcs7>(data)
|
||||
}
|
||||
192 => {
|
||||
// Section 10.3 Step 2 of RFC 2315 https://www.rfc-editor.org/rfc/rfc2315
|
||||
type Aes192Cbc =
|
||||
block_modes::Cbc<aes::Aes192, block_modes::block_padding::Pkcs7>;
|
||||
type Aes192CbcEnc = cbc::Encryptor<aes::Aes192>;
|
||||
|
||||
let cipher = Aes192Cbc::new_from_slices(key, &iv)?;
|
||||
cipher.encrypt_vec(data)
|
||||
let cipher = Aes192CbcEnc::new_from_slices(key, &iv)
|
||||
.map_err(|_| operation_error("invalid key or iv".to_string()))?;
|
||||
cipher.encrypt_padded_vec_mut::<Pkcs7>(data)
|
||||
}
|
||||
256 => {
|
||||
// Section 10.3 Step 2 of RFC 2315 https://www.rfc-editor.org/rfc/rfc2315
|
||||
type Aes256Cbc =
|
||||
block_modes::Cbc<aes::Aes256, block_modes::block_padding::Pkcs7>;
|
||||
type Aes256CbcEnc = cbc::Encryptor<aes::Aes256>;
|
||||
|
||||
let cipher = Aes256Cbc::new_from_slices(key, &iv)?;
|
||||
cipher.encrypt_vec(data)
|
||||
let cipher = Aes256CbcEnc::new_from_slices(key, &iv)
|
||||
.map_err(|_| operation_error("invalid key or iv".to_string()))?;
|
||||
cipher.encrypt_padded_vec_mut::<Pkcs7>(data)
|
||||
}
|
||||
_ => return Err(type_error("invalid length")),
|
||||
};
|
||||
|
@ -260,16 +255,15 @@ fn encrypt_aes_gcm(
|
|||
Ok(ciphertext)
|
||||
}
|
||||
|
||||
fn encrypt_aes_ctr_gen<B, F>(
|
||||
fn encrypt_aes_ctr_gen<B>(
|
||||
key: &[u8],
|
||||
counter: &[u8],
|
||||
data: &[u8],
|
||||
) -> Result<Vec<u8>, AnyError>
|
||||
where
|
||||
B: BlockEncrypt + NewBlockCipher,
|
||||
F: CtrFlavor<B::BlockSize>,
|
||||
B: KeyIvInit + StreamCipher,
|
||||
{
|
||||
let mut cipher = Ctr::<B, F>::new(key.into(), counter.into());
|
||||
let mut cipher = B::new(key.into(), counter.into());
|
||||
|
||||
let mut ciphertext = data.to_vec();
|
||||
cipher
|
||||
|
@ -290,21 +284,21 @@ fn encrypt_aes_ctr(
|
|||
|
||||
match ctr_length {
|
||||
32 => match key_length {
|
||||
128 => encrypt_aes_ctr_gen::<aes::Aes128, Ctr32BE>(key, counter, data),
|
||||
192 => encrypt_aes_ctr_gen::<aes::Aes192, Ctr32BE>(key, counter, data),
|
||||
256 => encrypt_aes_ctr_gen::<aes::Aes256, Ctr32BE>(key, counter, data),
|
||||
128 => encrypt_aes_ctr_gen::<Ctr32BE<aes::Aes128>>(key, counter, data),
|
||||
192 => encrypt_aes_ctr_gen::<Ctr32BE<aes::Aes192>>(key, counter, data),
|
||||
256 => encrypt_aes_ctr_gen::<Ctr32BE<aes::Aes256>>(key, counter, data),
|
||||
_ => Err(type_error("invalid length")),
|
||||
},
|
||||
64 => match key_length {
|
||||
128 => encrypt_aes_ctr_gen::<aes::Aes128, Ctr64BE>(key, counter, data),
|
||||
192 => encrypt_aes_ctr_gen::<aes::Aes192, Ctr64BE>(key, counter, data),
|
||||
256 => encrypt_aes_ctr_gen::<aes::Aes256, Ctr64BE>(key, counter, data),
|
||||
128 => encrypt_aes_ctr_gen::<Ctr64BE<aes::Aes128>>(key, counter, data),
|
||||
192 => encrypt_aes_ctr_gen::<Ctr64BE<aes::Aes192>>(key, counter, data),
|
||||
256 => encrypt_aes_ctr_gen::<Ctr64BE<aes::Aes256>>(key, counter, data),
|
||||
_ => Err(type_error("invalid length")),
|
||||
},
|
||||
128 => match key_length {
|
||||
128 => encrypt_aes_ctr_gen::<aes::Aes128, Ctr128BE>(key, counter, data),
|
||||
192 => encrypt_aes_ctr_gen::<aes::Aes192, Ctr128BE>(key, counter, data),
|
||||
256 => encrypt_aes_ctr_gen::<aes::Aes256, Ctr128BE>(key, counter, data),
|
||||
128 => encrypt_aes_ctr_gen::<Ctr128BE<aes::Aes128>>(key, counter, data),
|
||||
192 => encrypt_aes_ctr_gen::<Ctr128BE<aes::Aes192>>(key, counter, data),
|
||||
256 => encrypt_aes_ctr_gen::<Ctr128BE<aes::Aes256>>(key, counter, data),
|
||||
_ => Err(type_error("invalid length")),
|
||||
},
|
||||
_ => Err(type_error(
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
use crate::shared::*;
|
||||
use const_oid::AssociatedOid;
|
||||
use const_oid::ObjectIdentifier;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use rsa::pkcs1::UIntBytes;
|
||||
use elliptic_curve::sec1::ToEncodedPoint;
|
||||
use p256::pkcs8::DecodePrivateKey;
|
||||
use rsa::pkcs1::UIntRef;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use spki::der::asn1;
|
||||
use spki::der::Decodable;
|
||||
use spki::der::Encodable;
|
||||
use spki::der::Decode;
|
||||
use spki::der::Encode;
|
||||
use spki::AlgorithmIdentifier;
|
||||
use spki::ObjectIdentifier;
|
||||
|
||||
use crate::ec_key::ECPrivateKey;
|
||||
use crate::shared::*;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
@ -105,7 +106,7 @@ pub fn op_crypto_export_key(
|
|||
}
|
||||
}
|
||||
|
||||
fn uint_to_b64(bytes: UIntBytes) -> String {
|
||||
fn uint_to_b64(bytes: UIntRef) -> String {
|
||||
base64::encode_config(bytes.as_bytes(), base64::URL_SAFE_NO_PAD)
|
||||
}
|
||||
|
||||
|
@ -125,10 +126,10 @@ fn export_key_rsa(
|
|||
let key_info = spki::SubjectPublicKeyInfo {
|
||||
algorithm: spki::AlgorithmIdentifier {
|
||||
// rsaEncryption(1)
|
||||
oid: spki::ObjectIdentifier::new("1.2.840.113549.1.1.1"),
|
||||
oid: const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.1"),
|
||||
// parameters field should not be ommited (None).
|
||||
// It MUST have ASN.1 type NULL.
|
||||
parameters: Some(asn1::Any::from(asn1::Null)),
|
||||
parameters: Some(asn1::AnyRef::from(asn1::Null)),
|
||||
},
|
||||
subject_public_key,
|
||||
};
|
||||
|
@ -150,14 +151,13 @@ fn export_key_rsa(
|
|||
// version is 0 when publickey is None
|
||||
|
||||
let pk_info = rsa::pkcs8::PrivateKeyInfo {
|
||||
attributes: None,
|
||||
public_key: None,
|
||||
algorithm: rsa::pkcs8::AlgorithmIdentifier {
|
||||
// rsaEncryption(1)
|
||||
oid: rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.1"),
|
||||
oid: rsa::pkcs8::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.1"),
|
||||
// parameters field should not be ommited (None).
|
||||
// It MUST have ASN.1 type NULL as per defined in RFC 3279 Section 2.3.1
|
||||
parameters: Some(asn1::Any::from(asn1::Null)),
|
||||
parameters: Some(asn1::AnyRef::from(asn1::Null)),
|
||||
},
|
||||
private_key,
|
||||
};
|
||||
|
@ -266,14 +266,22 @@ fn export_key_ec(
|
|||
};
|
||||
|
||||
let alg_id = match named_curve {
|
||||
EcNamedCurve::P256 => <p256::NistP256 as p256::elliptic_curve::AlgorithmParameters>::algorithm_identifier(),
|
||||
EcNamedCurve::P384 => <p384::NistP384 as p384::elliptic_curve::AlgorithmParameters>::algorithm_identifier(),
|
||||
EcNamedCurve::P521 => return Err(data_error("Unsupported named curve"))
|
||||
EcNamedCurve::P256 => AlgorithmIdentifier {
|
||||
oid: elliptic_curve::ALGORITHM_OID,
|
||||
parameters: Some((&p256::NistP256::OID).into()),
|
||||
},
|
||||
EcNamedCurve::P384 => AlgorithmIdentifier {
|
||||
oid: elliptic_curve::ALGORITHM_OID,
|
||||
parameters: Some((&p384::NistP384::OID).into()),
|
||||
},
|
||||
EcNamedCurve::P521 => {
|
||||
return Err(data_error("Unsupported named curve"))
|
||||
}
|
||||
};
|
||||
|
||||
let alg_id = match algorithm {
|
||||
ExportKeyAlgorithm::Ecdh { .. } => AlgorithmIdentifier {
|
||||
oid: ObjectIdentifier::new("1.3.132.1.12"),
|
||||
oid: ObjectIdentifier::new_unwrap("1.3.132.1.12"),
|
||||
parameters: alg_id.parameters,
|
||||
},
|
||||
_ => alg_id,
|
||||
|
@ -339,24 +347,22 @@ fn export_key_ec(
|
|||
|
||||
match named_curve {
|
||||
EcNamedCurve::P256 => {
|
||||
let ec_key = ECPrivateKey::<p256::NistP256>::try_from(private_key)
|
||||
.map_err(|_| {
|
||||
let ec_key =
|
||||
p256::SecretKey::from_pkcs8_der(private_key).map_err(|_| {
|
||||
custom_error(
|
||||
"DOMExceptionOperationError",
|
||||
"failed to decode private key",
|
||||
)
|
||||
})?;
|
||||
|
||||
let point = p256::EncodedPoint::from_bytes(&ec_key.encoded_point)
|
||||
.map_err(|_| data_error("expected valid public EC key"))?;
|
||||
|
||||
let point = ec_key.public_key().to_encoded_point(false);
|
||||
if let elliptic_curve::sec1::Coordinates::Uncompressed { x, y } =
|
||||
point.coordinates()
|
||||
{
|
||||
Ok(ExportKeyResult::JwkPrivateEc {
|
||||
x: bytes_to_b64(x),
|
||||
y: bytes_to_b64(y),
|
||||
d: bytes_to_b64(&ec_key.private_d),
|
||||
d: bytes_to_b64(&ec_key.to_be_bytes()),
|
||||
})
|
||||
} else {
|
||||
Err(data_error("expected valid public EC key"))
|
||||
|
@ -364,24 +370,22 @@ fn export_key_ec(
|
|||
}
|
||||
|
||||
EcNamedCurve::P384 => {
|
||||
let ec_key = ECPrivateKey::<p384::NistP384>::try_from(private_key)
|
||||
.map_err(|_| {
|
||||
let ec_key =
|
||||
p384::SecretKey::from_pkcs8_der(private_key).map_err(|_| {
|
||||
custom_error(
|
||||
"DOMExceptionOperationError",
|
||||
"failed to decode private key",
|
||||
)
|
||||
})?;
|
||||
|
||||
let point = p384::EncodedPoint::from_bytes(&ec_key.encoded_point)
|
||||
.map_err(|_| data_error("expected valid public EC key"))?;
|
||||
|
||||
let point = ec_key.public_key().to_encoded_point(false);
|
||||
if let elliptic_curve::sec1::Coordinates::Uncompressed { x, y } =
|
||||
point.coordinates()
|
||||
{
|
||||
Ok(ExportKeyResult::JwkPrivateEc {
|
||||
x: bytes_to_b64(x),
|
||||
y: bytes_to_b64(y),
|
||||
d: bytes_to_b64(&ec_key.private_d),
|
||||
d: bytes_to_b64(&ec_key.to_be_bytes()),
|
||||
})
|
||||
} else {
|
||||
Err(data_error("expected valid public EC key"))
|
||||
|
|
|
@ -7,7 +7,7 @@ use num_traits::FromPrimitive;
|
|||
use once_cell::sync::Lazy;
|
||||
use ring::rand::SecureRandom;
|
||||
use ring::signature::EcdsaKeyPair;
|
||||
use rsa::pkcs1::ToRsaPrivateKey;
|
||||
use rsa::pkcs1::EncodeRsaPrivateKey;
|
||||
use rsa::BigUint;
|
||||
use rsa::RsaPrivateKey;
|
||||
use serde::Deserialize;
|
||||
|
@ -76,7 +76,7 @@ fn generate_key_rsa(
|
|||
.to_pkcs1_der()
|
||||
.map_err(|_| operation_error("Failed to serialize RSA key"))?;
|
||||
|
||||
Ok(private_key.as_ref().to_vec())
|
||||
Ok(private_key.as_bytes().to_vec())
|
||||
}
|
||||
|
||||
fn generate_key_ec(named_curve: EcNamedCurve) -> Result<Vec<u8>, AnyError> {
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use elliptic_curve::pkcs8::der::Decodable as Pkcs8Decodable;
|
||||
use elliptic_curve::pkcs8::PrivateKeyInfo;
|
||||
use ring::signature::EcdsaKeyPair;
|
||||
use rsa::pkcs1::UIntBytes;
|
||||
use rsa::pkcs8::AlgorithmIdentifier;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use spki::der::Encodable;
|
||||
|
||||
use crate::ec_key::ECPrivateKey;
|
||||
use crate::key::CryptoNamedCurve;
|
||||
use crate::shared::*;
|
||||
use crate::OaepPrivateKeyParameters;
|
||||
use crate::PssPrivateKeyParameters;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use elliptic_curve::pkcs8::PrivateKeyInfo;
|
||||
use p256::pkcs8::EncodePrivateKey;
|
||||
use ring::signature::EcdsaKeyPair;
|
||||
use rsa::pkcs1::UIntRef;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use spki::der::Decode;
|
||||
use spki::der::Encode;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
@ -114,7 +112,7 @@ macro_rules! jwt_b64_int_or_err {
|
|||
($name:ident, $b64:expr, $err:expr) => {
|
||||
let bytes = base64::decode_config($b64, URL_SAFE_FORGIVING)
|
||||
.map_err(|_| data_error($err))?;
|
||||
let $name = UIntBytes::new(&bytes).map_err(|_| data_error($err))?;
|
||||
let $name = UIntRef::new(&bytes).map_err(|_| data_error($err))?;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -164,7 +162,6 @@ fn import_key_rsa_jwk(
|
|||
jwt_b64_int_or_err!(coefficient, &qi, "invalid CRT coefficient");
|
||||
|
||||
let private_key = rsa::pkcs1::RsaPrivateKey {
|
||||
version: rsa::pkcs1::Version::TwoPrime,
|
||||
modulus,
|
||||
public_exponent,
|
||||
private_exponent,
|
||||
|
@ -173,6 +170,7 @@ fn import_key_rsa_jwk(
|
|||
exponent1,
|
||||
exponent2,
|
||||
coefficient,
|
||||
other_prime_infos: None,
|
||||
};
|
||||
|
||||
let data = private_key
|
||||
|
@ -193,28 +191,6 @@ fn import_key_rsa_jwk(
|
|||
}
|
||||
}
|
||||
|
||||
fn validate_mask_gen(
|
||||
mask_gen_algorithm: &AlgorithmIdentifier,
|
||||
hash_algorithm: &AlgorithmIdentifier,
|
||||
) -> Result<(), deno_core::anyhow::Error> {
|
||||
if mask_gen_algorithm.oid != ID_MFG1 {
|
||||
return Err(not_supported_error("unsupported mask gen algorithm"));
|
||||
}
|
||||
|
||||
let parameters = mask_gen_algorithm
|
||||
.parameters_any()
|
||||
.map_err(|_| not_supported_error("unsupported parameters"))?;
|
||||
let mgf1_hash_identifier = AlgorithmIdentifier::try_from(parameters)
|
||||
.map_err(|_| not_supported_error("unsupported parameters"))?;
|
||||
|
||||
// The hash function on which MGF1 is based.
|
||||
mgf1_hash_identifier
|
||||
.assert_algorithm_oid(hash_algorithm.oid)
|
||||
.map_err(|_| not_supported_error("unsupported parameters"))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn import_key_rsassa(
|
||||
key_data: KeyData,
|
||||
hash: ShaHash,
|
||||
|
@ -383,7 +359,6 @@ fn import_key_rsapss(
|
|||
return Err(not_supported_error("unsupported hash algorithm"));
|
||||
}
|
||||
|
||||
validate_mask_gen(¶ms.mask_gen_algorithm, &hash_alg)?;
|
||||
hash
|
||||
}
|
||||
_ => return Err(data_error("unsupported algorithm")),
|
||||
|
@ -446,7 +421,7 @@ fn import_key_rsapss(
|
|||
.map_err(|_| not_supported_error("malformed parameters"))?;
|
||||
|
||||
let hash_alg = params.hash_algorithm;
|
||||
let hash = match hash_alg.oid {
|
||||
match hash_alg.oid {
|
||||
// id-sha1
|
||||
ID_SHA1_OID => Some(ShaHash::Sha1),
|
||||
// id-sha256
|
||||
|
@ -456,10 +431,7 @@ fn import_key_rsapss(
|
|||
// id-sha256
|
||||
ID_SHA512_OID => Some(ShaHash::Sha512),
|
||||
_ => return Err(data_error("unsupported hash algorithm")),
|
||||
};
|
||||
|
||||
validate_mask_gen(¶ms.mask_gen_algorithm, &hash_alg)?;
|
||||
hash
|
||||
}
|
||||
}
|
||||
_ => return Err(data_error("unsupported algorithm")),
|
||||
};
|
||||
|
@ -532,7 +504,7 @@ fn import_key_rsaoaep(
|
|||
.map_err(|_| data_error("malformed parameters"))?;
|
||||
|
||||
let hash_alg = params.hash_algorithm;
|
||||
let hash = match hash_alg.oid {
|
||||
match hash_alg.oid {
|
||||
// id-sha1
|
||||
ID_SHA1_OID => Some(ShaHash::Sha1),
|
||||
// id-sha256
|
||||
|
@ -542,10 +514,7 @@ fn import_key_rsaoaep(
|
|||
// id-sha256
|
||||
ID_SHA512_OID => Some(ShaHash::Sha512),
|
||||
_ => return Err(data_error("unsupported hash algorithm")),
|
||||
};
|
||||
|
||||
validate_mask_gen(¶ms.mask_gen_algorithm, &hash_alg)?;
|
||||
hash
|
||||
}
|
||||
}
|
||||
_ => return Err(data_error("unsupported algorithm")),
|
||||
};
|
||||
|
@ -607,7 +576,7 @@ fn import_key_rsaoaep(
|
|||
.map_err(|_| not_supported_error("malformed parameters"))?;
|
||||
|
||||
let hash_alg = params.hash_algorithm;
|
||||
let hash = match hash_alg.oid {
|
||||
match hash_alg.oid {
|
||||
// id-sha1
|
||||
ID_SHA1_OID => Some(ShaHash::Sha1),
|
||||
// id-sha256
|
||||
|
@ -617,9 +586,7 @@ fn import_key_rsaoaep(
|
|||
// id-sha256
|
||||
ID_SHA512_OID => Some(ShaHash::Sha512),
|
||||
_ => return Err(data_error("unsupported hash algorithm")),
|
||||
};
|
||||
validate_mask_gen(¶ms.mask_gen_algorithm, &hash_alg)?;
|
||||
hash
|
||||
}
|
||||
}
|
||||
_ => return Err(data_error("unsupported algorithm")),
|
||||
};
|
||||
|
@ -716,30 +683,18 @@ fn import_key_ec_jwk(
|
|||
})
|
||||
}
|
||||
KeyData::JwkPrivateEc { d, x, y } => {
|
||||
let point_bytes = import_key_ec_jwk_to_point(x, y, named_curve)?;
|
||||
|
||||
jwt_b64_int_or_err!(private_d, &d, "invalid JWK private key");
|
||||
|
||||
let point_bytes = import_key_ec_jwk_to_point(x, y, named_curve)?;
|
||||
let pkcs8_der = match named_curve {
|
||||
EcNamedCurve::P256 => {
|
||||
let d = decode_b64url_to_field_bytes::<p256::NistP256>(&d)?;
|
||||
|
||||
let pk =
|
||||
ECPrivateKey::<p256::NistP256>::from_private_and_public_bytes(
|
||||
d,
|
||||
&point_bytes,
|
||||
);
|
||||
let pk = p256::SecretKey::from_be_bytes(&d)?;
|
||||
|
||||
pk.to_pkcs8_der()?
|
||||
}
|
||||
EcNamedCurve::P384 => {
|
||||
let d = decode_b64url_to_field_bytes::<p384::NistP384>(&d)?;
|
||||
|
||||
let pk =
|
||||
ECPrivateKey::<p384::NistP384>::from_private_and_public_bytes(
|
||||
d,
|
||||
&point_bytes,
|
||||
);
|
||||
let pk = p384::SecretKey::from_be_bytes(&d)?;
|
||||
|
||||
pk.to_pkcs8_der()?
|
||||
}
|
||||
|
@ -764,7 +719,7 @@ fn import_key_ec_jwk(
|
|||
);
|
||||
|
||||
Ok(ImportKeyResult::Ec {
|
||||
raw_data: RawKeyData::Private(pkcs8_der.as_ref().to_vec().into()),
|
||||
raw_data: RawKeyData::Private(pkcs8_der.as_bytes().to_vec().into()),
|
||||
})
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
@ -775,11 +730,11 @@ pub struct ECParametersSpki {
|
|||
pub named_curve_alg: spki::der::asn1::ObjectIdentifier,
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<spki::der::asn1::Any<'a>> for ECParametersSpki {
|
||||
impl<'a> TryFrom<spki::der::asn1::AnyRef<'a>> for ECParametersSpki {
|
||||
type Error = spki::der::Error;
|
||||
|
||||
fn try_from(
|
||||
any: spki::der::asn1::Any<'a>,
|
||||
any: spki::der::asn1::AnyRef<'a>,
|
||||
) -> spki::der::Result<ECParametersSpki> {
|
||||
let x = any.oid()?;
|
||||
|
||||
|
@ -824,15 +779,14 @@ fn import_key_ec(
|
|||
// 2-7
|
||||
// Deserialize PKCS8 - validate structure, extracts named_curve
|
||||
let named_curve_alg = match named_curve {
|
||||
EcNamedCurve::P256 => {
|
||||
let pk = ECPrivateKey::<p256::NistP256>::try_from(data.as_ref())?;
|
||||
|
||||
pk.named_curve_oid().unwrap()
|
||||
}
|
||||
EcNamedCurve::P384 => {
|
||||
let pk = ECPrivateKey::<p384::NistP384>::try_from(data.as_ref())?;
|
||||
|
||||
pk.named_curve_oid().unwrap()
|
||||
EcNamedCurve::P256 | EcNamedCurve::P384 => {
|
||||
let pk = PrivateKeyInfo::from_der(data.as_ref())
|
||||
.map_err(|_| data_error("expected valid PKCS#8 data"))?;
|
||||
pk.algorithm
|
||||
.parameters
|
||||
.ok_or_else(|| data_error("malformed parameters"))?
|
||||
.oid()
|
||||
.unwrap()
|
||||
}
|
||||
EcNamedCurve::P521 => {
|
||||
return Err(data_error("Unsupported named curve"))
|
||||
|
@ -922,7 +876,6 @@ fn import_key_ec(
|
|||
p256::EncodedPoint::from_bytes(&*encoded_key).map_err(|_| {
|
||||
data_error("invalid P-256 eliptic curve SPKI data")
|
||||
})?;
|
||||
|
||||
if point.is_identity() {
|
||||
return Err(data_error("invalid P-256 eliptic curve point"));
|
||||
}
|
||||
|
@ -957,7 +910,7 @@ fn import_key_ec(
|
|||
}
|
||||
|
||||
Ok(ImportKeyResult::Ec {
|
||||
raw_data: RawKeyData::Public(encoded_key.to_vec().into()),
|
||||
raw_data: RawKeyData::Public(encoded_key.into()),
|
||||
})
|
||||
}
|
||||
KeyData::JwkPublicEc { .. } | KeyData::JwkPrivateEc { .. } => {
|
||||
|
|
|
@ -17,10 +17,8 @@ use deno_core::ZeroCopyBuf;
|
|||
use serde::Deserialize;
|
||||
use shared::operation_error;
|
||||
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use p256::elliptic_curve::sec1::FromEncodedPoint;
|
||||
use p256::pkcs8::FromPrivateKey;
|
||||
use p256::pkcs8::DecodePrivateKey;
|
||||
use rand::rngs::OsRng;
|
||||
use rand::rngs::StdRng;
|
||||
use rand::thread_rng;
|
||||
|
@ -37,10 +35,10 @@ use ring::signature::EcdsaSigningAlgorithm;
|
|||
use ring::signature::EcdsaVerificationAlgorithm;
|
||||
use ring::signature::KeyPair;
|
||||
use rsa::padding::PaddingScheme;
|
||||
use rsa::pkcs1::der::Decodable;
|
||||
use rsa::pkcs1::der::Encodable;
|
||||
use rsa::pkcs1::FromRsaPrivateKey;
|
||||
use rsa::pkcs1::FromRsaPublicKey;
|
||||
use rsa::pkcs1::der::Decode;
|
||||
use rsa::pkcs1::der::Encode;
|
||||
use rsa::pkcs1::DecodeRsaPrivateKey;
|
||||
use rsa::pkcs1::DecodeRsaPublicKey;
|
||||
use rsa::pkcs8::der::asn1;
|
||||
use rsa::PublicKey;
|
||||
use rsa::RsaPrivateKey;
|
||||
|
@ -51,12 +49,12 @@ use sha2::Sha256;
|
|||
use sha2::Sha384;
|
||||
use sha2::Sha512;
|
||||
use std::convert::TryFrom;
|
||||
use std::num::NonZeroU32;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub use rand; // Re-export rand
|
||||
|
||||
mod decrypt;
|
||||
mod ec_key;
|
||||
mod encrypt;
|
||||
mod export_key;
|
||||
mod generate_key;
|
||||
|
@ -537,11 +535,10 @@ pub async fn op_crypto_derive_bits(
|
|||
type_error("Unexpected error decoding private key")
|
||||
})?;
|
||||
|
||||
let pk: Option<p256::PublicKey> =
|
||||
p256::PublicKey::from_encoded_point(&point);
|
||||
|
||||
if let Some(pk) = pk {
|
||||
pk
|
||||
let pk = p256::PublicKey::from_encoded_point(&point);
|
||||
// pk is a constant time Option.
|
||||
if pk.is_some().into() {
|
||||
pk.unwrap()
|
||||
} else {
|
||||
return Err(type_error(
|
||||
"Unexpected error decoding private key",
|
||||
|
@ -552,11 +549,12 @@ pub async fn op_crypto_derive_bits(
|
|||
};
|
||||
|
||||
let shared_secret = p256::elliptic_curve::ecdh::diffie_hellman(
|
||||
secret_key.to_secret_scalar(),
|
||||
secret_key.to_nonzero_scalar(),
|
||||
public_key.as_affine(),
|
||||
);
|
||||
|
||||
Ok(shared_secret.as_bytes().to_vec().into())
|
||||
// raw serialized x-coordinate of the computed point
|
||||
Ok(shared_secret.raw_secret_bytes().to_vec().into())
|
||||
}
|
||||
// TODO(@littledivy): support for P384
|
||||
// https://github.com/RustCrypto/elliptic-curves/issues/240
|
||||
|
@ -654,7 +652,7 @@ static SHA1_HASH_ALGORITHM: Lazy<rsa::pkcs8::AlgorithmIdentifier<'static>> =
|
|||
// id-sha1
|
||||
oid: ID_SHA1_OID,
|
||||
// NULL
|
||||
parameters: Some(asn1::Any::from(asn1::Null)),
|
||||
parameters: Some(asn1::AnyRef::from(asn1::Null)),
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -675,7 +673,7 @@ static MGF1_SHA1_MASK_ALGORITHM: Lazy<
|
|||
oid: ID_MFG1,
|
||||
// sha1
|
||||
parameters: Some(
|
||||
asn1::Any::from_der(&ENCODED_SHA1_HASH_ALGORITHM).unwrap(),
|
||||
asn1::AnyRef::from_der(&ENCODED_SHA1_HASH_ALGORITHM).unwrap(),
|
||||
),
|
||||
}
|
||||
});
|
||||
|
@ -695,33 +693,51 @@ static P_SPECIFIED_EMPTY: Lazy<rsa::pkcs8::AlgorithmIdentifier<'static>> =
|
|||
// id-pSpecified
|
||||
oid: ID_P_SPECIFIED,
|
||||
// EncodingParameters
|
||||
parameters: Some(asn1::Any::from(asn1::OctetString::new(b"").unwrap())),
|
||||
parameters: Some(asn1::AnyRef::from(
|
||||
asn1::OctetStringRef::new(b"").unwrap(),
|
||||
)),
|
||||
}
|
||||
});
|
||||
|
||||
impl<'a> TryFrom<rsa::pkcs8::der::asn1::Any<'a>>
|
||||
fn decode_content_tag<'a, T>(
|
||||
decoder: &mut rsa::pkcs8::der::SliceReader<'a>,
|
||||
tag: rsa::pkcs8::der::TagNumber,
|
||||
) -> rsa::pkcs8::der::Result<Option<T>>
|
||||
where
|
||||
T: rsa::pkcs8::der::Decode<'a>,
|
||||
{
|
||||
Ok(
|
||||
rsa::pkcs8::der::asn1::ContextSpecific::<T>::decode_explicit(decoder, tag)?
|
||||
.map(|field| field.value),
|
||||
)
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<rsa::pkcs8::der::asn1::AnyRef<'a>>
|
||||
for PssPrivateKeyParameters<'a>
|
||||
{
|
||||
type Error = rsa::pkcs8::der::Error;
|
||||
|
||||
fn try_from(
|
||||
any: rsa::pkcs8::der::asn1::Any<'a>,
|
||||
) -> rsa::pkcs8::der::Result<PssPrivateKeyParameters> {
|
||||
any: rsa::pkcs8::der::asn1::AnyRef<'a>,
|
||||
) -> rsa::pkcs8::der::Result<PssPrivateKeyParameters<'a>> {
|
||||
any.sequence(|decoder| {
|
||||
let hash_algorithm = decoder
|
||||
.context_specific(HASH_ALGORITHM_TAG)?
|
||||
let hash_algorithm =
|
||||
decode_content_tag::<rsa::pkcs8::AlgorithmIdentifier>(
|
||||
decoder,
|
||||
HASH_ALGORITHM_TAG,
|
||||
)?
|
||||
.map(TryInto::try_into)
|
||||
.transpose()?
|
||||
.unwrap_or(*SHA1_HASH_ALGORITHM);
|
||||
|
||||
let mask_gen_algorithm = decoder
|
||||
.context_specific(MASK_GEN_ALGORITHM_TAG)?
|
||||
let mask_gen_algorithm = decode_content_tag::<
|
||||
rsa::pkcs8::AlgorithmIdentifier,
|
||||
>(decoder, MASK_GEN_ALGORITHM_TAG)?
|
||||
.map(TryInto::try_into)
|
||||
.transpose()?
|
||||
.unwrap_or(*MGF1_SHA1_MASK_ALGORITHM);
|
||||
|
||||
let salt_length = decoder
|
||||
.context_specific(SALT_LENGTH_TAG)?
|
||||
let salt_length = decode_content_tag::<u32>(decoder, SALT_LENGTH_TAG)?
|
||||
.map(TryInto::try_into)
|
||||
.transpose()?
|
||||
.unwrap_or(20);
|
||||
|
@ -749,29 +765,34 @@ pub struct OaepPrivateKeyParameters<'a> {
|
|||
pub p_source_algorithm: rsa::pkcs8::AlgorithmIdentifier<'a>,
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<rsa::pkcs8::der::asn1::Any<'a>>
|
||||
impl<'a> TryFrom<rsa::pkcs8::der::asn1::AnyRef<'a>>
|
||||
for OaepPrivateKeyParameters<'a>
|
||||
{
|
||||
type Error = rsa::pkcs8::der::Error;
|
||||
|
||||
fn try_from(
|
||||
any: rsa::pkcs8::der::asn1::Any<'a>,
|
||||
) -> rsa::pkcs8::der::Result<OaepPrivateKeyParameters> {
|
||||
any: rsa::pkcs8::der::asn1::AnyRef<'a>,
|
||||
) -> rsa::pkcs8::der::Result<OaepPrivateKeyParameters<'a>> {
|
||||
any.sequence(|decoder| {
|
||||
let hash_algorithm = decoder
|
||||
.context_specific(HASH_ALGORITHM_TAG)?
|
||||
let hash_algorithm =
|
||||
decode_content_tag::<rsa::pkcs8::AlgorithmIdentifier>(
|
||||
decoder,
|
||||
HASH_ALGORITHM_TAG,
|
||||
)?
|
||||
.map(TryInto::try_into)
|
||||
.transpose()?
|
||||
.unwrap_or(*SHA1_HASH_ALGORITHM);
|
||||
|
||||
let mask_gen_algorithm = decoder
|
||||
.context_specific(MASK_GEN_ALGORITHM_TAG)?
|
||||
let mask_gen_algorithm = decode_content_tag::<
|
||||
rsa::pkcs8::AlgorithmIdentifier,
|
||||
>(decoder, MASK_GEN_ALGORITHM_TAG)?
|
||||
.map(TryInto::try_into)
|
||||
.transpose()?
|
||||
.unwrap_or(*MGF1_SHA1_MASK_ALGORITHM);
|
||||
|
||||
let p_source_algorithm = decoder
|
||||
.context_specific(P_SOURCE_ALGORITHM_TAG)?
|
||||
let p_source_algorithm = decode_content_tag::<
|
||||
rsa::pkcs8::AlgorithmIdentifier,
|
||||
>(decoder, P_SOURCE_ALGORITHM_TAG)?
|
||||
.map(TryInto::try_into)
|
||||
.transpose()?
|
||||
.unwrap_or(*P_SPECIFIED_EMPTY);
|
||||
|
|
|
@ -5,48 +5,46 @@ use deno_core::error::type_error;
|
|||
use deno_core::error::AnyError;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use elliptic_curve::sec1::ToEncodedPoint;
|
||||
use p256::pkcs8::FromPrivateKey;
|
||||
use rsa::pkcs1::FromRsaPrivateKey;
|
||||
use rsa::pkcs1::ToRsaPublicKey;
|
||||
use rsa::pkcs1::DecodeRsaPrivateKey;
|
||||
use rsa::pkcs1::EncodeRsaPublicKey;
|
||||
use rsa::pkcs8::DecodePrivateKey;
|
||||
use rsa::RsaPrivateKey;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::ec_key::ECPrivateKey;
|
||||
pub const RSA_ENCRYPTION_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.1");
|
||||
pub const SHA1_RSA_ENCRYPTION_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.5");
|
||||
pub const SHA256_RSA_ENCRYPTION_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.11");
|
||||
pub const SHA384_RSA_ENCRYPTION_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.12");
|
||||
pub const SHA512_RSA_ENCRYPTION_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.13");
|
||||
pub const RSASSA_PSS_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.10");
|
||||
pub const ID_SHA1_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("1.3.14.3.2.26");
|
||||
pub const ID_SHA256_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.1");
|
||||
pub const ID_SHA384_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.2");
|
||||
pub const ID_SHA512_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.3");
|
||||
pub const ID_MFG1: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.8");
|
||||
pub const RSAES_OAEP_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.7");
|
||||
pub const ID_P_SPECIFIED: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.9");
|
||||
|
||||
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");
|
||||
|
||||
pub const ID_SECP256R1_OID: rsa::pkcs8::ObjectIdentifier =
|
||||
rsa::pkcs8::ObjectIdentifier::new("1.2.840.10045.3.1.7");
|
||||
pub const ID_SECP384R1_OID: rsa::pkcs8::ObjectIdentifier =
|
||||
rsa::pkcs8::ObjectIdentifier::new("1.3.132.0.34");
|
||||
pub const ID_SECP521R1_OID: rsa::pkcs8::ObjectIdentifier =
|
||||
rsa::pkcs8::ObjectIdentifier::new("1.3.132.0.35");
|
||||
pub const ID_SECP256R1_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7");
|
||||
pub const ID_SECP384R1_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("1.3.132.0.34");
|
||||
pub const ID_SECP521R1_OID: const_oid::ObjectIdentifier =
|
||||
const_oid::ObjectIdentifier::new_unwrap("1.3.132.0.35");
|
||||
|
||||
#[derive(Serialize, Deserialize, Copy, Clone, PartialEq)]
|
||||
pub enum ShaHash {
|
||||
|
@ -91,7 +89,7 @@ impl RawKeyData {
|
|||
.to_pkcs1_der()
|
||||
.map_err(|_| type_error("expected valid public key"))?;
|
||||
|
||||
Ok(Cow::Owned(public_key_doc.as_der().into()))
|
||||
Ok(Cow::Owned(public_key_doc.as_bytes().into()))
|
||||
}
|
||||
_ => Err(type_error("expected public key")),
|
||||
}
|
||||
|
@ -136,16 +134,9 @@ impl RawKeyData {
|
|||
.map_err(|_| type_error("expected valid public EC key"))
|
||||
}
|
||||
RawKeyData::Private(data) => {
|
||||
let ec_key = ECPrivateKey::<p384::NistP384>::try_from(&**data)
|
||||
.map_err(|_| {
|
||||
custom_error(
|
||||
"DOMExceptionOperationError",
|
||||
"failed to decode private key",
|
||||
)
|
||||
})?;
|
||||
let point = p384::EncodedPoint::from_bytes(&ec_key.encoded_point)
|
||||
.map_err(|_| data_error("expected valid public EC key"))?;
|
||||
Ok(point)
|
||||
let signing_key = p384::SecretKey::from_pkcs8_der(data)
|
||||
.map_err(|_| type_error("expected valid private EC key"))?;
|
||||
Ok(signing_key.public_key().to_encoded_point(false))
|
||||
}
|
||||
// Should never reach here.
|
||||
RawKeyData::Secret(_) => unreachable!(),
|
||||
|
|
Loading…
Reference in a new issue