summaryrefslogtreecommitdiff
path: root/ext/crypto
diff options
context:
space:
mode:
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() {