summaryrefslogtreecommitdiff
path: root/ext/node/ops/crypto/keys.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ext/node/ops/crypto/keys.rs')
-rw-r--r--ext/node/ops/crypto/keys.rs53
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,