summaryrefslogtreecommitdiff
path: root/ext/crypto
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2024-01-06 16:48:31 +0530
committerGitHub <noreply@github.com>2024-01-06 16:48:31 +0530
commitbfd5f1598cc462b460791fdfca9bb6c2c69fec9b (patch)
tree93dfa9f650d07351d76e2202b7a4f7930727271b /ext/crypto
parent1d46ee5129dc5c674a7a4b6ad3a40243de4de2a0 (diff)
feat(ext/crypto): initial support for p521 in `generateKey` and `importKey` (#21815)
Part 1 of a potential 3 part series. Ref #13449 The current implementation passes key material back and forth RustCrypto group of crates and ring. ring does not implement p521 yet. This PR adds support for P521 named curve in `generateKey` and `importKey` where we use RustCrypto. Other parts should be moved over to the RustGroup group of crates for consistency.
Diffstat (limited to 'ext/crypto')
-rw-r--r--ext/crypto/00_crypto.js3
-rw-r--r--ext/crypto/Cargo.toml1
-rw-r--r--ext/crypto/generate_key.rs8
-rw-r--r--ext/crypto/import_key.rs30
4 files changed, 36 insertions, 6 deletions
diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js
index 06dd0f41a..d2949eb62 100644
--- a/ext/crypto/00_crypto.js
+++ b/ext/crypto/00_crypto.js
@@ -63,8 +63,7 @@ const {
isDataView,
} = core;
-// P-521 is not yet supported.
-const supportedNamedCurves = ["P-256", "P-384"];
+const supportedNamedCurves = ["P-256", "P-384", "P-521"];
const recognisedUsages = [
"encrypt",
"decrypt",
diff --git a/ext/crypto/Cargo.toml b/ext/crypto/Cargo.toml
index 2ac35c4e0..9896bde0b 100644
--- a/ext/crypto/Cargo.toml
+++ b/ext/crypto/Cargo.toml
@@ -30,6 +30,7 @@ num-traits = "0.2.14"
once_cell.workspace = true
p256 = { version = "0.13.2", features = ["ecdh"] }
p384 = "0.13.0"
+p521 = "0.13.3"
rand.workspace = true
ring = { workspace = true, features = ["std"] }
rsa.workspace = true
diff --git a/ext/crypto/generate_key.rs b/ext/crypto/generate_key.rs
index 074558532..43aea2c70 100644
--- a/ext/crypto/generate_key.rs
+++ b/ext/crypto/generate_key.rs
@@ -84,11 +84,17 @@ fn generate_key_rsa(
Ok(private_key.as_bytes().to_vec())
}
+fn generate_key_ec_p521() -> Vec<u8> {
+ let mut rng = OsRng;
+ let key = p521::SecretKey::random(&mut rng);
+ key.to_nonzero_scalar().to_bytes().to_vec()
+}
+
fn generate_key_ec(named_curve: EcNamedCurve) -> Result<Vec<u8>, AnyError> {
let curve = match named_curve {
EcNamedCurve::P256 => &ring::signature::ECDSA_P256_SHA256_FIXED_SIGNING,
EcNamedCurve::P384 => &ring::signature::ECDSA_P384_SHA384_FIXED_SIGNING,
- _ => return Err(not_supported_error("Unsupported named curve")),
+ EcNamedCurve::P521 => return Ok(generate_key_ec_p521()),
};
let rng = ring::rand::SystemRandom::new();
diff --git a/ext/crypto/import_key.rs b/ext/crypto/import_key.rs
index 409ffe7be..7b06cae99 100644
--- a/ext/crypto/import_key.rs
+++ b/ext/crypto/import_key.rs
@@ -520,7 +520,12 @@ fn import_key_ec_jwk_to_point(
p384::EncodedPoint::from_affine_coordinates(&x, &y, false).to_bytes()
}
- _ => return Err(not_supported_error("Unsupported named curve")),
+ EcNamedCurve::P521 => {
+ let x = decode_b64url_to_field_bytes::<p521::NistP521>(&x)?;
+ let y = decode_b64url_to_field_bytes::<p521::NistP521>(&y)?;
+
+ p521::EncodedPoint::from_affine_coordinates(&x, &y, false).to_bytes()
+ }
};
Ok(point_bytes.to_vec())
@@ -629,7 +634,15 @@ fn import_key_ec(
return Err(data_error("invalid P-384 elliptic curve point"));
}
}
- _ => return Err(not_supported_error("Unsupported named curve")),
+ EcNamedCurve::P521 => {
+ // 1-2.
+ let point = p521::EncodedPoint::from_bytes(&data)
+ .map_err(|_| data_error("invalid P-521 elliptic curve point"))?;
+ // 3.
+ if point.is_identity() {
+ return Err(data_error("invalid P-521 elliptic curve point"));
+ }
+ }
};
Ok(ImportKeyResult::Ec {
raw_data: RustRawKeyData::Public(data.to_vec().into()),
@@ -755,7 +768,18 @@ fn import_key_ec(
point.as_bytes().len()
}
- _ => return Err(not_supported_error("Unsupported named curve")),
+ EcNamedCurve::P521 => {
+ let point =
+ p521::EncodedPoint::from_bytes(&*encoded_key).map_err(|_| {
+ data_error("invalid P-521 elliptic curve SPKI data")
+ })?;
+
+ if point.is_identity() {
+ return Err(data_error("invalid P-521 elliptic curve point"));
+ }
+
+ point.as_bytes().len()
+ }
};
if bytes_consumed != pk_info.subject_public_key.raw_bytes().len() {