summaryrefslogtreecommitdiff
path: root/openssl/src/dh.rs
diff options
context:
space:
mode:
authorSteven Fackler <sfackler@palantir.com>2016-11-11 19:49:00 +0000
committerSteven Fackler <sfackler@palantir.com>2016-11-11 20:10:10 +0000
commit6b7279eb5224a422860d0adb38becd5bca19763f (patch)
treeb74aab6be99b603ff763263439733354e92f1b4b /openssl/src/dh.rs
parent15490a43e399ce0f6e3838c96c609abf08b1c5db (diff)
downloadrust-openssl-6b7279eb5224a422860d0adb38becd5bca19763f.zip
Consistently support both PEM and DER encodings
Closes #500
Diffstat (limited to 'openssl/src/dh.rs')
-rw-r--r--openssl/src/dh.rs48
1 files changed, 39 insertions, 9 deletions
diff --git a/openssl/src/dh.rs b/openssl/src/dh.rs
index 5a07e50f..ad1ebf9f 100644
--- a/openssl/src/dh.rs
+++ b/openssl/src/dh.rs
@@ -1,11 +1,12 @@
-use ffi;
use error::ErrorStack;
-use bio::MemBioSlice;
-use std::ptr;
+use ffi;
+use libc::c_long;
+use std::cmp;
use std::mem;
+use std::ptr;
-use {cvt, cvt_p};
-use bio::MemBio;
+use {cvt, cvt_p, init};
+use bio::{MemBio, MemBioSlice};
use bn::BigNum;
use types::OpenSslTypeRef;
@@ -15,18 +16,27 @@ impl DhRef {
/// Encodes the parameters to PEM.
pub fn to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
let mem_bio = try!(MemBio::new());
-
unsafe {
try!(cvt(ffi::PEM_write_bio_DHparams(mem_bio.as_ptr(), self.as_ptr())));
}
-
Ok(mem_bio.get_buf().to_owned())
}
+
+ /// Encodes the parameters to DER.
+ pub fn to_der(&self) -> Result<Vec<u8>, ErrorStack> {
+ unsafe {
+ let len = try!(cvt(ffi::i2d_DHparams(self.as_ptr(), ptr::null_mut())));
+ let mut buf = vec![0; len as usize];
+ try!(cvt(ffi::i2d_DHparams(self.as_ptr(), &mut buf.as_mut_ptr())));
+ Ok(buf)
+ }
+ }
}
impl Dh {
pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<Dh, ErrorStack> {
unsafe {
+ init();
let dh = Dh(try!(cvt_p(ffi::DH_new())));
try!(cvt(compat::DH_set0_pqg(dh.0, p.as_ptr(), q.as_ptr(), g.as_ptr())));
mem::forget((p, g, q));
@@ -34,9 +44,11 @@ impl Dh {
}
}
+ /// Reads Diffie-Hellman parameters from PEM.
pub fn from_pem(buf: &[u8]) -> Result<Dh, ErrorStack> {
- let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
+ init();
+ let mem_bio = try!(MemBioSlice::new(buf));
cvt_p(ffi::PEM_read_bio_DHparams(mem_bio.as_ptr(),
ptr::null_mut(),
None,
@@ -45,6 +57,16 @@ impl Dh {
}
}
+ /// Reads Diffie-Hellman parameters from DER.
+ pub fn from_der(buf: &[u8]) -> Result<Dh, ErrorStack> {
+ unsafe {
+ init();
+ let len = cmp::min(buf.len(), c_long::max_value() as usize) as c_long;
+ let dh = try!(cvt_p(ffi::d2i_DHparams(ptr::null_mut(), &mut buf.as_ptr(), len)));
+ Ok(Dh(dh))
+ }
+ }
+
/// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0.
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
pub fn get_1024_160() -> Result<Dh, ErrorStack> {
@@ -139,7 +161,15 @@ mod tests {
fn test_dh_from_pem() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
let params = include_bytes!("../test/dhparams.pem");
- let dh = Dh::from_pem(params).ok().expect("Failed to load PEM");
+ let dh = Dh::from_pem(params).unwrap();
ctx.set_tmp_dh(&dh).unwrap();
}
+
+ #[test]
+ fn test_dh_from_der() {
+ let params = include_bytes!("../test/dhparams.pem");
+ let dh = Dh::from_pem(params).unwrap();
+ let der = dh.to_der().unwrap();
+ Dh::from_der(&der).unwrap();
+ }
}