summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/crypto/Cargo.toml1
-rw-r--r--ext/crypto/export_key.rs34
-rw-r--r--ext/crypto/import_key.rs77
-rw-r--r--ext/crypto/shared.rs17
-rw-r--r--ext/node/Cargo.toml2
5 files changed, 64 insertions, 67 deletions
diff --git a/ext/crypto/Cargo.toml b/ext/crypto/Cargo.toml
index beea81d1e..3f2a8d703 100644
--- a/ext/crypto/Cargo.toml
+++ b/ext/crypto/Cargo.toml
@@ -33,6 +33,7 @@ p521 = "0.13.3"
rand.workspace = true
ring = { workspace = true, features = ["std"] }
rsa.workspace = true
+sec1.workspace = true
serde.workspace = true
serde_bytes.workspace = true
sha1.workspace = true
diff --git a/ext/crypto/export_key.rs b/ext/crypto/export_key.rs
index 588e9978b..00ce7e11c 100644
--- a/ext/crypto/export_key.rs
+++ b/ext/crypto/export_key.rs
@@ -254,7 +254,9 @@ fn export_key_ec(
point.as_ref().to_vec()
}
EcNamedCurve::P521 => {
- return Err(data_error("Unsupported named curve"))
+ let point = key_data.as_ec_public_key_p521()?;
+
+ point.as_ref().to_vec()
}
};
Ok(ExportKeyResult::Raw(subject_public_key.into()))
@@ -272,7 +274,9 @@ fn export_key_ec(
point.as_ref().to_vec()
}
EcNamedCurve::P521 => {
- return Err(data_error("Unsupported named curve"))
+ let point = key_data.as_ec_public_key_p521()?;
+
+ point.as_ref().to_vec()
}
};
@@ -285,9 +289,10 @@ fn export_key_ec(
oid: elliptic_curve::ALGORITHM_OID,
parameters: Some((&p384::NistP384::OID).into()),
},
- EcNamedCurve::P521 => {
- return Err(data_error("Unsupported named curve"))
- }
+ EcNamedCurve::P521 => AlgorithmIdentifierOwned {
+ oid: elliptic_curve::ALGORITHM_OID,
+ parameters: Some((&p521::NistP521::OID).into()),
+ },
};
let alg_id = match algorithm {
@@ -351,7 +356,24 @@ fn export_key_ec(
))
}
}
- EcNamedCurve::P521 => Err(data_error("Unsupported named curve")),
+ EcNamedCurve::P521 => {
+ let point = key_data.as_ec_public_key_p521()?;
+ let coords = point.coordinates();
+
+ if let p521::elliptic_curve::sec1::Coordinates::Uncompressed { x, y } =
+ coords
+ {
+ Ok(ExportKeyResult::JwkPublicEc {
+ x: bytes_to_b64(x),
+ y: bytes_to_b64(y),
+ })
+ } else {
+ Err(custom_error(
+ "DOMExceptionOperationError",
+ "failed to decode public key",
+ ))
+ }
+ }
},
ExportKeyFormat::JwkPrivate => {
let private_key = key_data.as_ec_private_key()?;
diff --git a/ext/crypto/import_key.rs b/ext/crypto/import_key.rs
index 88265a2cd..e30baea03 100644
--- a/ext/crypto/import_key.rs
+++ b/ext/crypto/import_key.rs
@@ -7,14 +7,12 @@ use deno_core::JsBuffer;
use deno_core::ToJsBuffer;
use elliptic_curve::pkcs8::PrivateKeyInfo;
use p256::pkcs8::EncodePrivateKey;
-use ring::signature::EcdsaKeyPair;
use rsa::pkcs1::UintRef;
use rsa::pkcs8::der::Encode;
use serde::Deserialize;
use serde::Serialize;
use spki::der::Decode;
-use crate::key::CryptoNamedCurve;
use crate::shared::*;
#[derive(Deserialize)]
@@ -45,7 +43,9 @@ pub enum KeyData {
y: String,
},
JwkPrivateEc {
+ #[allow(dead_code)]
x: String,
+ #[allow(dead_code)]
y: String,
d: String,
},
@@ -543,9 +543,7 @@ fn import_key_ec_jwk(
raw_data: RustRawKeyData::Public(point_bytes.into()),
})
}
- KeyData::JwkPrivateEc { d, x, y } => {
- 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)?;
+ KeyData::JwkPrivateEc { d, .. } => {
let pkcs8_der = match named_curve {
EcNamedCurve::P256 => {
let d = decode_b64url_to_field_bytes::<p256::NistP256>(&d)?;
@@ -562,27 +560,14 @@ fn import_key_ec_jwk(
.map_err(|_| data_error("invalid JWK private key"))?
}
EcNamedCurve::P521 => {
- return Err(data_error("Unsupported named curve"))
- }
- };
+ let d = decode_b64url_to_field_bytes::<p521::NistP521>(&d)?;
+ let pk = p521::SecretKey::from_bytes(&d)?;
- // Import using ring, to validate key
- let key_alg = match named_curve {
- EcNamedCurve::P256 => CryptoNamedCurve::P256.into(),
- EcNamedCurve::P384 => CryptoNamedCurve::P256.into(),
- EcNamedCurve::P521 => {
- return Err(data_error("Unsupported named curve"))
+ pk.to_pkcs8_der()
+ .map_err(|_| data_error("invalid JWK private key"))?
}
};
- let rng = ring::rand::SystemRandom::new();
- let _key_pair = EcdsaKeyPair::from_private_key_and_public_key(
- key_alg,
- private_d.as_bytes(),
- point_bytes.as_ref(),
- &rng,
- );
-
Ok(ImportKeyResult::Ec {
raw_data: RustRawKeyData::Private(pkcs8_der.as_bytes().to_vec().into()),
})
@@ -649,24 +634,15 @@ fn import_key_ec(
})
}
KeyData::Pkcs8(data) => {
- // 2-7
- // Deserialize PKCS8 - validate structure, extracts named_curve
- let named_curve_alg = match named_curve {
- 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"))?
- .try_into()
- .unwrap()
- }
- EcNamedCurve::P521 => {
- return Err(data_error("Unsupported named curve"))
- }
- };
+ let pk = PrivateKeyInfo::from_der(data.as_ref())
+ .map_err(|_| data_error("expected valid PKCS#8 data"))?;
+ let named_curve_alg = pk
+ .algorithm
+ .parameters
+ .ok_or_else(|| data_error("malformed parameters"))?
+ .try_into()
+ .unwrap();
- // 8-9.
let pk_named_curve = match named_curve_alg {
// id-secp256r1
ID_SECP256R1_OID => Some(EcNamedCurve::P256),
@@ -677,27 +653,8 @@ fn import_key_ec(
_ => None,
};
- // 10.
- if let Some(pk_named_curve) = pk_named_curve {
- let signing_alg = match pk_named_curve {
- EcNamedCurve::P256 => CryptoNamedCurve::P256.into(),
- EcNamedCurve::P384 => CryptoNamedCurve::P384.into(),
- EcNamedCurve::P521 => {
- return Err(data_error("Unsupported named curve"))
- }
- };
-
- let rng = ring::rand::SystemRandom::new();
- // deserialize pkcs8 using ring crate, to VALIDATE public key
- let _private_key = EcdsaKeyPair::from_pkcs8(signing_alg, &data, &rng)
- .map_err(|_| data_error("invalid key"))?;
-
- // 11.
- if named_curve != pk_named_curve {
- return Err(data_error("curve mismatch"));
- }
- } else {
- return Err(data_error("Unsupported named curve"));
+ if pk_named_curve != Some(named_curve) {
+ return Err(data_error("curve mismatch"));
}
Ok(ImportKeyResult::Ec {
diff --git a/ext/crypto/shared.rs b/ext/crypto/shared.rs
index d5b2d6593..d06a268cd 100644
--- a/ext/crypto/shared.rs
+++ b/ext/crypto/shared.rs
@@ -126,6 +126,23 @@ impl V8RawKeyData {
}
}
+ pub fn as_ec_public_key_p521(&self) -> Result<p521::EncodedPoint, AnyError> {
+ match self {
+ V8RawKeyData::Public(data) => {
+ // public_key is a serialized EncodedPoint
+ p521::EncodedPoint::from_bytes(data)
+ .map_err(|_| type_error("expected valid public EC key"))
+ }
+ V8RawKeyData::Private(data) => {
+ let signing_key = p521::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.
+ V8RawKeyData::Secret(_) => unreachable!(),
+ }
+ }
+
pub fn as_ec_private_key(&self) -> Result<&[u8], AnyError> {
match self {
V8RawKeyData::Private(data) => Ok(data),
diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml
index 24e7ecf2e..1cd97e3e8 100644
--- a/ext/node/Cargo.toml
+++ b/ext/node/Cargo.toml
@@ -81,7 +81,7 @@ ring.workspace = true
ripemd = { version = "0.1.3", features = ["oid"] }
rsa.workspace = true
scrypt = "0.11.0"
-sec1 = "0.7"
+sec1.workspace = true
serde = "1.0.149"
sha1.workspace = true
sha2.workspace = true