Loading openssl-sys/src/lib.rs +3 −0 Original line number Diff line number Diff line Loading @@ -1109,6 +1109,8 @@ pub const OCSP_RESPONSE_STATUS_TRYLATER: c_int = 3; pub const OCSP_RESPONSE_STATUS_SIGREQUIRED: c_int = 5; pub const OCSP_RESPONSE_STATUS_UNAUTHORIZED: c_int = 6; pub const OPENSSL_EC_NAMED_CURVE: c_int = 1; pub const PKCS5_SALT_LEN: c_int = 8; pub const RSA_F4: c_long = 0x10001; Loading Loading @@ -1510,6 +1512,7 @@ extern { pub fn EC_GROUP_get_curve_GF2m(group: *const EC_GROUP, p: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; pub fn EC_GROUP_get_degree(group: *const EC_GROUP) -> c_int; pub fn EC_GROUP_get_order(group: *const EC_GROUP, order: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; pub fn EC_GROUP_set_asn1_flag(key: *mut EC_GROUP, flag: c_int); pub fn EC_GROUP_free(group: *mut EC_GROUP); Loading openssl/src/ec.rs +71 −13 Original line number Diff line number Diff line use ffi; use std::ptr; use std::mem; use libc::c_int; use {cvt, cvt_n, cvt_p, init}; use bn::{BigNumRef, BigNumContextRef}; use error::ErrorStack; use nid::Nid; use types::OpenSslTypeRef; use types::{OpenSslType, OpenSslTypeRef}; pub const POINT_CONVERSION_COMPRESSED: PointConversionForm = PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_COMPRESSED); Loading @@ -16,9 +18,17 @@ pub const POINT_CONVERSION_UNCOMPRESSED: PointConversionForm = pub const POINT_CONVERSION_HYBRID: PointConversionForm = PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_HYBRID); // OPENSSL_EC_EXPLICIT_CURVE, but that was only added in 1.1. // Man page documents that 0 can be used in older versions. pub const EXPLICIT_CURVE: Asn1Flag = Asn1Flag(0); pub const NAMED_CURVE: Asn1Flag = Asn1Flag(ffi::OPENSSL_EC_NAMED_CURVE); #[derive(Copy, Clone)] pub struct PointConversionForm(ffi::point_conversion_form_t); #[derive(Copy, Clone)] pub struct Asn1Flag(c_int); type_!(EcGroup, EcGroupRef, ffi::EC_GROUP, ffi::EC_GROUP_free); impl EcGroup { Loading Loading @@ -80,6 +90,17 @@ impl EcGroupRef { cvt(ffi::EC_GROUP_get_order(self.as_ptr(), order.as_ptr(), ctx.as_ptr())).map(|_| ()) } } /// Sets the flag determining if the group corresponds to a named curve or must be explicitly /// parameterized. /// /// This defaults to `EXPLICIT_CURVE` in OpenSSL 1.0.1 and 1.0.2, but `NAMED_CURVE` in OpenSSL /// 1.1.0. pub fn set_asn1_flag(&mut self, flag: Asn1Flag) { unsafe { ffi::EC_GROUP_set_asn1_flag(self.as_ptr(), flag.0); } } } type_!(EcPoint, EcPointRef, ffi::EC_POINT, ffi::EC_POINT_free); Loading Loading @@ -311,22 +332,18 @@ impl EcKey { /// let key = EcKey::from_public_key(&group, &point); /// ``` 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) } let mut builder = try!(EcKeyBuilder::new()); try!(builder.set_group(group)); try!(builder.set_public_key(public_key)); Ok(builder.build()) } /// Generates a new public/private key pair on the specified curve. pub fn generate(group: &EcGroupRef) -> 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_generate_key(key.as_ptr()))); Ok(key) } let mut builder = try!(EcKeyBuilder::new()); try!(builder.set_group(group)); try!(builder.generate_key()); Ok(builder.build()) } #[deprecated(since = "0.9.2", note = "use from_curve_name")] Loading @@ -338,6 +355,47 @@ impl EcKey { private_key_from_der!(EcKey, ffi::d2i_ECPrivateKey); } type_!(EcKeyBuilder, EcKeyBuilderRef, ffi::EC_KEY, ffi::EC_KEY_free); impl EcKeyBuilder { pub fn new() -> Result<EcKeyBuilder, ErrorStack> { unsafe { init(); cvt_p(ffi::EC_KEY_new()).map(EcKeyBuilder) } } pub fn build(self) -> EcKey { unsafe { let key = EcKey::from_ptr(self.as_ptr()); mem::forget(self); key } } } impl EcKeyBuilderRef { pub fn set_group(&mut self, group: &EcGroupRef) -> Result<&mut EcKeyBuilderRef, ErrorStack> { unsafe { cvt(ffi::EC_KEY_set_group(self.as_ptr(), group.as_ptr())).map(|_| self) } } pub fn set_public_key(&mut self, public_key: &EcPointRef) -> Result<&mut EcKeyBuilderRef, ErrorStack> { unsafe { cvt(ffi::EC_KEY_set_public_key(self.as_ptr(), public_key.as_ptr())).map(|_| self) } } pub fn generate_key(&mut self) -> Result<&mut EcKeyBuilderRef, ErrorStack> { unsafe { cvt(ffi::EC_KEY_generate_key(self.as_ptr())).map(|_| self) } } } #[cfg(test)] mod test { use bn::BigNumContext; Loading openssl/src/x509/tests.rs +23 −0 Original line number Diff line number Diff line use hex::{FromHex, ToHex}; use ec::{NAMED_CURVE, EcGroup, EcKey}; use hash::MessageDigest; use nid::X9_62_PRIME256V1; use pkey::PKey; use rsa::Rsa; use ssl::{SslMethod, SslContextBuilder}; use x509::{X509, X509Generator}; use x509::extension::Extension::{KeyUsage, ExtKeyUsage, SubjectAltName, OtherNid, OtherStr}; use x509::extension::AltNameOption as SAN; Loading Loading @@ -197,3 +200,23 @@ fn issued() { ca.issued(&cert).unwrap(); cert.issued(&cert).err().unwrap(); } #[test] fn ecdsa_cert() { let mut group = EcGroup::from_curve_name(X9_62_PRIME256V1).unwrap(); group.set_asn1_flag(NAMED_CURVE); let key = EcKey::generate(&group).unwrap(); let key = PKey::from_ec_key(key).unwrap(); let cert = X509Generator::new() .set_valid_period(365) .add_name("CN".to_owned(), "TestServer".to_owned()) .set_sign_hash(MessageDigest::sha256()) .sign(&key) .unwrap(); let mut ctx = SslContextBuilder::new(SslMethod::tls()).unwrap(); ctx.set_certificate(&cert).unwrap(); ctx.set_private_key(&key).unwrap(); ctx.check_private_key().unwrap(); } Loading
openssl-sys/src/lib.rs +3 −0 Original line number Diff line number Diff line Loading @@ -1109,6 +1109,8 @@ pub const OCSP_RESPONSE_STATUS_TRYLATER: c_int = 3; pub const OCSP_RESPONSE_STATUS_SIGREQUIRED: c_int = 5; pub const OCSP_RESPONSE_STATUS_UNAUTHORIZED: c_int = 6; pub const OPENSSL_EC_NAMED_CURVE: c_int = 1; pub const PKCS5_SALT_LEN: c_int = 8; pub const RSA_F4: c_long = 0x10001; Loading Loading @@ -1510,6 +1512,7 @@ extern { pub fn EC_GROUP_get_curve_GF2m(group: *const EC_GROUP, p: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; pub fn EC_GROUP_get_degree(group: *const EC_GROUP) -> c_int; pub fn EC_GROUP_get_order(group: *const EC_GROUP, order: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; pub fn EC_GROUP_set_asn1_flag(key: *mut EC_GROUP, flag: c_int); pub fn EC_GROUP_free(group: *mut EC_GROUP); Loading
openssl/src/ec.rs +71 −13 Original line number Diff line number Diff line use ffi; use std::ptr; use std::mem; use libc::c_int; use {cvt, cvt_n, cvt_p, init}; use bn::{BigNumRef, BigNumContextRef}; use error::ErrorStack; use nid::Nid; use types::OpenSslTypeRef; use types::{OpenSslType, OpenSslTypeRef}; pub const POINT_CONVERSION_COMPRESSED: PointConversionForm = PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_COMPRESSED); Loading @@ -16,9 +18,17 @@ pub const POINT_CONVERSION_UNCOMPRESSED: PointConversionForm = pub const POINT_CONVERSION_HYBRID: PointConversionForm = PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_HYBRID); // OPENSSL_EC_EXPLICIT_CURVE, but that was only added in 1.1. // Man page documents that 0 can be used in older versions. pub const EXPLICIT_CURVE: Asn1Flag = Asn1Flag(0); pub const NAMED_CURVE: Asn1Flag = Asn1Flag(ffi::OPENSSL_EC_NAMED_CURVE); #[derive(Copy, Clone)] pub struct PointConversionForm(ffi::point_conversion_form_t); #[derive(Copy, Clone)] pub struct Asn1Flag(c_int); type_!(EcGroup, EcGroupRef, ffi::EC_GROUP, ffi::EC_GROUP_free); impl EcGroup { Loading Loading @@ -80,6 +90,17 @@ impl EcGroupRef { cvt(ffi::EC_GROUP_get_order(self.as_ptr(), order.as_ptr(), ctx.as_ptr())).map(|_| ()) } } /// Sets the flag determining if the group corresponds to a named curve or must be explicitly /// parameterized. /// /// This defaults to `EXPLICIT_CURVE` in OpenSSL 1.0.1 and 1.0.2, but `NAMED_CURVE` in OpenSSL /// 1.1.0. pub fn set_asn1_flag(&mut self, flag: Asn1Flag) { unsafe { ffi::EC_GROUP_set_asn1_flag(self.as_ptr(), flag.0); } } } type_!(EcPoint, EcPointRef, ffi::EC_POINT, ffi::EC_POINT_free); Loading Loading @@ -311,22 +332,18 @@ impl EcKey { /// let key = EcKey::from_public_key(&group, &point); /// ``` 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) } let mut builder = try!(EcKeyBuilder::new()); try!(builder.set_group(group)); try!(builder.set_public_key(public_key)); Ok(builder.build()) } /// Generates a new public/private key pair on the specified curve. pub fn generate(group: &EcGroupRef) -> 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_generate_key(key.as_ptr()))); Ok(key) } let mut builder = try!(EcKeyBuilder::new()); try!(builder.set_group(group)); try!(builder.generate_key()); Ok(builder.build()) } #[deprecated(since = "0.9.2", note = "use from_curve_name")] Loading @@ -338,6 +355,47 @@ impl EcKey { private_key_from_der!(EcKey, ffi::d2i_ECPrivateKey); } type_!(EcKeyBuilder, EcKeyBuilderRef, ffi::EC_KEY, ffi::EC_KEY_free); impl EcKeyBuilder { pub fn new() -> Result<EcKeyBuilder, ErrorStack> { unsafe { init(); cvt_p(ffi::EC_KEY_new()).map(EcKeyBuilder) } } pub fn build(self) -> EcKey { unsafe { let key = EcKey::from_ptr(self.as_ptr()); mem::forget(self); key } } } impl EcKeyBuilderRef { pub fn set_group(&mut self, group: &EcGroupRef) -> Result<&mut EcKeyBuilderRef, ErrorStack> { unsafe { cvt(ffi::EC_KEY_set_group(self.as_ptr(), group.as_ptr())).map(|_| self) } } pub fn set_public_key(&mut self, public_key: &EcPointRef) -> Result<&mut EcKeyBuilderRef, ErrorStack> { unsafe { cvt(ffi::EC_KEY_set_public_key(self.as_ptr(), public_key.as_ptr())).map(|_| self) } } pub fn generate_key(&mut self) -> Result<&mut EcKeyBuilderRef, ErrorStack> { unsafe { cvt(ffi::EC_KEY_generate_key(self.as_ptr())).map(|_| self) } } } #[cfg(test)] mod test { use bn::BigNumContext; Loading
openssl/src/x509/tests.rs +23 −0 Original line number Diff line number Diff line use hex::{FromHex, ToHex}; use ec::{NAMED_CURVE, EcGroup, EcKey}; use hash::MessageDigest; use nid::X9_62_PRIME256V1; use pkey::PKey; use rsa::Rsa; use ssl::{SslMethod, SslContextBuilder}; use x509::{X509, X509Generator}; use x509::extension::Extension::{KeyUsage, ExtKeyUsage, SubjectAltName, OtherNid, OtherStr}; use x509::extension::AltNameOption as SAN; Loading Loading @@ -197,3 +200,23 @@ fn issued() { ca.issued(&cert).unwrap(); cert.issued(&cert).err().unwrap(); } #[test] fn ecdsa_cert() { let mut group = EcGroup::from_curve_name(X9_62_PRIME256V1).unwrap(); group.set_asn1_flag(NAMED_CURVE); let key = EcKey::generate(&group).unwrap(); let key = PKey::from_ec_key(key).unwrap(); let cert = X509Generator::new() .set_valid_period(365) .add_name("CN".to_owned(), "TestServer".to_owned()) .set_sign_hash(MessageDigest::sha256()) .sign(&key) .unwrap(); let mut ctx = SslContextBuilder::new(SslMethod::tls()).unwrap(); ctx.set_certificate(&cert).unwrap(); ctx.set_private_key(&key).unwrap(); ctx.check_private_key().unwrap(); }