aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openssl/src/ec.rs47
1 files changed, 47 insertions, 0 deletions
diff --git a/openssl/src/ec.rs b/openssl/src/ec.rs
index 607c30e0..94b11e93 100644
--- a/openssl/src/ec.rs
+++ b/openssl/src/ec.rs
@@ -289,6 +289,38 @@ impl EcKey {
}
}
+ /// Constructs an `EcKey` from the specified group with the associated `EcPoint`, public_key.
+ ///
+ /// This will only have the associated public_key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use openssl::bn::BigNumContext;
+ /// use openssl::ec::*;
+ /// use openssl::nid;
+ /// use openssl::pkey::PKey;
+ ///
+ /// // get bytes from somewhere, i.e. this will not produce a valid key
+ /// let public_key: Vec<u8> = vec![];
+ ///
+ /// // create a PKey from the binary form of a EcPoint
+ /// EcGroup::from_curve_name(nid::SECP256K1)
+ /// .and_then(|group| BigNumContext::new().map(|ctx| (group, ctx)))
+ /// .and_then(|(group, mut ctx)| EcPoint::from_bytes(&group, &public_key, &mut ctx)
+ /// .map(|point| (group, point) ))
+ /// .and_then(|(group, point)| EcKey::from_public_key(&group, &point))
+ /// .and_then(|ec_key| PKey::from_ec_key(ec_key));
+ /// ```
+ pub fn from_public_key(group: &EcGroupRef, public_key: &EcPointRef) -> Result<EcKey, ErrorStack> {
+ unsafe {
+ let key = EcKey(try!(cvt_p(ffi::EC_KEY_new())));
+ try!(cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())));
+ try!(cvt(ffi::EC_KEY_set_public_key(key.as_ptr(), public_key.as_ptr())));
+ Ok(key)
+ }
+ }
+
/// Generates a new public/private key pair on the specified curve.
pub fn generate(group: &EcGroupRef) -> Result<EcKey, ErrorStack> {
unsafe {
@@ -353,4 +385,19 @@ mod test {
public_key.mul_generator(&group, key.private_key().unwrap(), &mut ctx).unwrap();
assert!(public_key.eq(&group, key.public_key().unwrap(), &mut ctx).unwrap());
}
+
+ #[test]
+ fn key_from_public_key() {
+ let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
+ let key = EcKey::generate(&group).unwrap();
+ let mut ctx = BigNumContext::new().unwrap();
+ let bytes = key.public_key().unwrap().to_bytes(&group, POINT_CONVERSION_COMPRESSED, &mut ctx).unwrap();
+
+ drop(key);
+ let public_key = EcPoint::from_bytes(&group, &bytes, &mut ctx).unwrap();
+ let ec_key = EcKey::from_public_key(&group, &public_key).unwrap();
+ assert!(ec_key.check_key().is_ok());
+ assert!(ec_key.public_key().is_some());
+ assert!(ec_key.private_key().is_none());
+ }
}