diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2024-08-11 06:28:54 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-11 18:58:54 +0530 |
commit | b61fd622a5facc0ec29a8c3b04289ff5354ae03f (patch) | |
tree | ba6e5bf4c9e4fbb592f5dac719b22f2859ac5cbf /ext/node/ops/crypto/keys.rs | |
parent | d6f662ac8280511fb4ef0f81777a0a6c5c08c0fa (diff) |
fix(ext/node): rewrite X509Certificate resource and add `publicKey()` (#24988)
**Changes**:
- Remove unsafe usage, rewrite Rust representation with `yoke`.
- Implement `X509Certificate.prototype.publicKey()`
Fixes https://github.com/denoland/deno/issues/23307
Diffstat (limited to 'ext/node/ops/crypto/keys.rs')
-rw-r--r-- | ext/node/ops/crypto/keys.rs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/ext/node/ops/crypto/keys.rs b/ext/node/ops/crypto/keys.rs index cebafd584..45849cbd9 100644 --- a/ext/node/ops/crypto/keys.rs +++ b/ext/node/ops/crypto/keys.rs @@ -45,6 +45,7 @@ use spki::der::Reader as _; use spki::DecodePublicKey as _; use spki::EncodePublicKey as _; use spki::SubjectPublicKeyInfoRef; +use x509_parser::x509; use super::dh; use super::dh::DiffieHellmanGroup; @@ -518,6 +519,58 @@ impl KeyObjectHandle { Ok(KeyObjectHandle::AsymmetricPrivate(private_key)) } + pub fn new_x509_public_key( + spki: &x509::SubjectPublicKeyInfo, + ) -> Result<KeyObjectHandle, AnyError> { + use x509_parser::der_parser::asn1_rs::oid; + use x509_parser::public_key::PublicKey; + + let key = match spki.parsed()? { + PublicKey::RSA(key) => { + let public_key = RsaPublicKey::new( + rsa::BigUint::from_bytes_be(key.modulus), + rsa::BigUint::from_bytes_be(key.exponent), + )?; + AsymmetricPublicKey::Rsa(public_key) + } + PublicKey::EC(point) => { + let data = point.data(); + if let Some(params) = &spki.algorithm.parameters { + let curve_oid = params.as_oid()?; + const ID_SECP224R1: &[u8] = &oid!(raw 1.3.132.0.33); + const ID_SECP256R1: &[u8] = &oid!(raw 1.2.840.10045.3.1.7); + const ID_SECP384R1: &[u8] = &oid!(raw 1.3.132.0.34); + + match curve_oid.as_bytes() { + ID_SECP224R1 => { + let public_key = p224::PublicKey::from_sec1_bytes(data)?; + AsymmetricPublicKey::Ec(EcPublicKey::P224(public_key)) + } + ID_SECP256R1 => { + let public_key = p256::PublicKey::from_sec1_bytes(data)?; + AsymmetricPublicKey::Ec(EcPublicKey::P256(public_key)) + } + ID_SECP384R1 => { + let public_key = p384::PublicKey::from_sec1_bytes(data)?; + AsymmetricPublicKey::Ec(EcPublicKey::P384(public_key)) + } + _ => return Err(type_error("unsupported ec named curve")), + } + } else { + return Err(type_error("missing ec parameters")); + } + } + PublicKey::DSA(_) => { + let verifying_key = dsa::VerifyingKey::from_public_key_der(spki.raw) + .map_err(|_| type_error("malformed DSS public key"))?; + AsymmetricPublicKey::Dsa(verifying_key) + } + _ => return Err(type_error("unsupported x509 public key type")), + }; + + Ok(KeyObjectHandle::AsymmetricPublic(key)) + } + pub fn new_asymmetric_public_key_from_js( key: &[u8], format: &str, |