diff options
author | Sean Michael Wykes <8363933+SeanWykes@users.noreply.github.com> | 2022-01-19 03:44:35 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-19 12:14:35 +0530 |
commit | 91399851809b2c1585b318d496e81f9683cd270b (patch) | |
tree | 65716b7831d41821e2058c72fec5cba2e80f28b2 /ext/crypto/import_key.rs | |
parent | 77e58fe7f9fc20dabf77424efbd25ce332f8f59c (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.rs | 159 |
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")); |