summaryrefslogtreecommitdiff
path: root/ext/crypto/import_key.rs
diff options
context:
space:
mode:
authorSean Michael Wykes <8363933+SeanWykes@users.noreply.github.com>2022-01-19 03:44:35 -0300
committerGitHub <noreply@github.com>2022-01-19 12:14:35 +0530
commit91399851809b2c1585b318d496e81f9683cd270b (patch)
tree65716b7831d41821e2058c72fec5cba2e80f28b2 /ext/crypto/import_key.rs
parent77e58fe7f9fc20dabf77424efbd25ce332f8f59c (diff)
feat(ext/crypto): implement pkcs8/JWK for P-384 curves (#13154)
Diffstat (limited to 'ext/crypto/import_key.rs')
-rw-r--r--ext/crypto/import_key.rs159
1 files changed, 67 insertions, 92 deletions
diff --git a/ext/crypto/import_key.rs b/ext/crypto/import_key.rs
index 56fbfa111..6d6b11c52 100644
--- a/ext/crypto/import_key.rs
+++ b/ext/crypto/import_key.rs
@@ -3,14 +3,14 @@ use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use elliptic_curve::pkcs8::der::Decodable as Pkcs8Decodable;
use elliptic_curve::pkcs8::PrivateKeyInfo;
-use elliptic_curve::sec1::ToEncodedPoint;
-use p256::pkcs8::FromPrivateKey;
-use p256::pkcs8::ToPrivateKey;
+use ring::signature::EcdsaKeyPair;
use rsa::pkcs1::UIntBytes;
use serde::Deserialize;
use serde::Serialize;
use spki::der::Encodable;
+use crate::ec_key::ECPrivateKey;
+use crate::key::CryptoNamedCurve;
use crate::shared::*;
use crate::OaepPrivateKeyParameters;
use crate::PssPrivateKeyParameters;
@@ -721,68 +721,65 @@ fn import_key_ec_jwk(
let point_bytes = import_key_ec_jwk_to_point(x, y, named_curve)?;
Ok(ImportKeyResult::Ec {
- raw_data: RawKeyData::Public(point_bytes.to_vec().into()),
+ raw_data: RawKeyData::Public(point_bytes.into()),
})
}
KeyData::JwkPrivateEc { d, x, y } => {
let point_bytes = import_key_ec_jwk_to_point(x, y, named_curve)?;
- let secret_key_der = match named_curve {
+ jwt_b64_int_or_err!(private_d, &d, "invalid JWK private key");
+
+ let pkcs8_der = match named_curve {
EcNamedCurve::P256 => {
let d = decode_b64url_to_field_bytes::<p256::NistP256>(&d)?;
- let secret_key = p256::SecretKey::from_bytes(&d)?;
- ToPrivateKey::to_pkcs8_der(&secret_key).unwrap()
+
+ let pk =
+ ECPrivateKey::<p256::NistP256>::from_private_and_public_bytes(
+ d,
+ &point_bytes,
+ );
+
+ pk.to_pkcs8_der()?
}
- //@todo(sean) - build p384 secret key from jwk, when crate implements to_pkcs8_der
- //Problem: p384 crate does not implement ProjectiveArithmetic
- /*EcNamedCurve::P384 => {
- let secret_key = p384::SecretKey::from_be_bytes(&d)?;
+ EcNamedCurve::P384 => {
+ let d = decode_b64url_to_field_bytes::<p384::NistP384>(&d)?;
- secret_key.to_pkcs8_der().unwrap()
- }*/
- _ => return Err(not_supported_error("Unsupported named curve")),
+ let pk =
+ ECPrivateKey::<p384::NistP384>::from_private_and_public_bytes(
+ d,
+ &point_bytes,
+ );
+
+ pk.to_pkcs8_der()?
+ }
+ EcNamedCurve::P521 => {
+ return Err(data_error("Unsupported named curve"))
+ }
};
- let oid =
- <p256::NistP256 as p256::elliptic_curve::AlgorithmParameters>::OID;
+ // Import using ring, to validate key
+ let key_alg = match named_curve {
+ EcNamedCurve::P256 => CryptoNamedCurve::P256.try_into()?,
+ EcNamedCurve::P384 => CryptoNamedCurve::P256.try_into()?,
+ EcNamedCurve::P521 => {
+ return Err(data_error("Unsupported named curve"))
+ }
+ };
- let pki = p256::pkcs8::PrivateKeyInfo::new(
- p256::pkcs8::AlgorithmIdentifier {
- oid,
- parameters: None,
- },
- secret_key_der.as_ref(),
+ let _key_pair = EcdsaKeyPair::from_private_key_and_public_key(
+ key_alg,
+ private_d.as_bytes(),
+ point_bytes.as_ref(),
);
- let pki = p256::pkcs8::PrivateKeyInfo {
- public_key: Some(&point_bytes),
- ..pki
- };
-
Ok(ImportKeyResult::Ec {
- raw_data: RawKeyData::Private(pki.private_key.to_vec().into()),
+ raw_data: RawKeyData::Private(pkcs8_der.as_ref().to_vec().into()),
})
}
_ => unreachable!(),
}
}
-pub struct ECParametersPkcs8 {
- pub named_curve_alg: p256::pkcs8::der::asn1::ObjectIdentifier,
-}
-
-impl<'a> TryFrom<p256::pkcs8::der::asn1::Any<'a>> for ECParametersPkcs8 {
- type Error = p256::pkcs8::der::Error;
-
- fn try_from(
- any: p256::pkcs8::der::asn1::Any<'a>,
- ) -> p256::pkcs8::der::Result<ECParametersPkcs8> {
- let x = any.oid()?;
-
- Ok(Self { named_curve_alg: x })
- }
-}
-
pub struct ECParametersSpki {
pub named_curve_alg: spki::der::asn1::ObjectIdentifier,
}
@@ -833,70 +830,48 @@ fn import_key_ec(
})
}
KeyData::Pkcs8(data) => {
- // 2-3.
- let pk_info = PrivateKeyInfo::from_der(&data)
- .map_err(|e| data_error(e.to_string()))?;
+ // 2-7
+ // Deserialize PKCS8 - validate structure, extracts named_curve
+ let named_curve_alg = match named_curve {
+ EcNamedCurve::P256 => {
+ let pk = ECPrivateKey::<p256::NistP256>::try_from(data.as_ref())?;
- // 4-5.
- let alg = pk_info.algorithm.oid;
- // id-ecPublicKey
- if alg != elliptic_curve::ALGORITHM_OID {
- return Err(data_error("unsupported algorithm"));
- }
+ pk.named_curve_oid().unwrap()
+ }
+ EcNamedCurve::P384 => {
+ let pk = ECPrivateKey::<p384::NistP384>::try_from(data.as_ref())?;
- // 5-7.
- let params = ECParametersPkcs8::try_from(
- pk_info
- .algorithm
- .parameters
- .ok_or_else(|| data_error("malformed parameters"))?,
- )
- .map_err(|_| data_error("malformed parameters"))?;
+ pk.named_curve_oid().unwrap()
+ }
+ EcNamedCurve::P521 => {
+ return Err(data_error("Unsupported named curve"))
+ }
+ };
// 8-9.
- let pk_named_curve = match params.named_curve_alg {
+ let pk_named_curve = match named_curve_alg {
// id-secp256r1
ID_SECP256R1_OID => Some(EcNamedCurve::P256),
// id-secp384r1
ID_SECP384R1_OID => Some(EcNamedCurve::P384),
- // id-secp384r1
+ // id-secp521r1
ID_SECP521R1_OID => Some(EcNamedCurve::P521),
_ => None,
};
// 10.
if let Some(pk_named_curve) = pk_named_curve {
- match pk_named_curve {
- EcNamedCurve::P256 => {
- let secret_key =
- p256::SecretKey::from_pkcs8_der(&data).map_err(|_| {
- data_error("invalid P-256 elliptic curve PKCS8 data")
- })?;
-
- let point =
- secret_key.public_key().as_affine().to_encoded_point(false);
-
- // 12 - not sure if this is correct.
- if point.is_identity() {
- return Err(data_error("Invalid key data"));
- }
+ let signing_alg = match pk_named_curve {
+ EcNamedCurve::P256 => CryptoNamedCurve::P256.try_into()?,
+ EcNamedCurve::P384 => CryptoNamedCurve::P384.try_into()?,
+ EcNamedCurve::P521 => {
+ return Err(data_error("Unsupported named curve"))
}
- //@todo(sean) Validate P384 secret-key on import(pkcs8)
- //Problem: Nist384 Curve from p384 crate does not implement ProjectiveArithmetic
- //so cannot extract PublicKey from SecretKey.
- /*EcNamedCurve::P384 => {
- let secret_key =
- p384::SecretKey::from_pkcs8_der(&data).unwrap();
+ };
+
+ // deserialize pkcs8 using ring crate, to VALIDATE public key
+ let _private_key = EcdsaKeyPair::from_pkcs8(signing_alg, &data)?;
- let point =
- secret_key.public_key().as_affine().to_encoded_point(false);
- // 3.
- if point.is_identity() {
- return Err(type_error("Invalid key data".to_string()));
- }
- }*/
- _ => return Err(data_error("Unsupported named curve")),
- }
// 11.
if named_curve != pk_named_curve {
return Err(data_error("curve mismatch"));