diff --git a/openssl/src/ec.rs b/openssl/src/ec.rs index ad3b0f54..c4800c73 100644 --- a/openssl/src/ec.rs +++ b/openssl/src/ec.rs @@ -729,6 +729,33 @@ impl EcKey { } } + /// Constructs an public/private key pair given a curve, a private key and a public key point. + pub fn from_private_components( + group: &EcGroupRef, + private_number: &BigNumRef, + public_key: &EcPointRef, + ) -> Result, ErrorStack> { + unsafe { + cvt_p(ffi::EC_KEY_new()) + .map(|p| EcKey::from_ptr(p)) + .and_then(|key| { + cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key) + }) + .and_then(|key| { + cvt(ffi::EC_KEY_set_private_key( + key.as_ptr(), + private_number.as_ptr(), + )).map(|_| key) + }) + .and_then(|key| { + cvt(ffi::EC_KEY_set_public_key( + key.as_ptr(), + public_key.as_ptr(), + )).map(|_| key) + }) + } + } + private_key_from_pem! { /// Deserializes a private key from a PEM-encoded ECPrivateKey structure. /// @@ -845,6 +872,18 @@ mod test { assert!(ec_key.check_key().is_ok()); } + #[test] + fn key_from_private_components() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let key = EcKey::generate(&group).unwrap(); + + let dup_key = EcKey::from_private_components(&group, key.private_key(), key.public_key()).unwrap(); + let res = dup_key.check_key().unwrap(); + + assert!(res == ()); + assert!(key.private_key() == dup_key.private_key()); + } + #[test] fn key_from_affine_coordinates() { let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();