1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
use ffi; use std::io; use std::io::prelude::*; use ssl::error::{SslError, StreamError}; use bio::MemBio; use bn::BigNum; use std::mem; use std::ptr; pub struct DH(*mut ffi::DH); impl DH { pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<DH, SslError> { let dh = try_ssl_null!(unsafe { ffi::DH_new_from_params(p.raw(), g.raw(), q.raw()) }); mem::forget(p); mem::forget(g); mem::forget(q); Ok(DH(dh)) } pub fn from_pem<R>(reader: &mut R) -> Result<DH, SslError> where R: Read { let mut mem_bio = try!(MemBio::new()); try!(io::copy(reader, &mut mem_bio).map_err(StreamError)); let dh = unsafe { ffi::PEM_read_bio_DHparams(mem_bio.get_handle(), ptr::null_mut(), None, ptr::null_mut()) }; try_ssl_null!(dh); Ok(DH(dh)) } #[cfg(feature = "rfc5114")] pub fn get_1024_160() -> Result<DH, SslError> { let dh = try_ssl_null!(unsafe { ffi::DH_get_1024_160() }); Ok(DH(dh)) } #[cfg(feature = "rfc5114")] pub fn get_2048_224() -> Result<DH, SslError> { let dh = try_ssl_null!(unsafe { ffi::DH_get_2048_224() }); Ok(DH(dh)) } #[cfg(feature = "rfc5114")] pub fn get_2048_256() -> Result<DH, SslError> { let dh = try_ssl_null!(unsafe { ffi::DH_get_2048_256() }); Ok(DH(dh)) } pub unsafe fn raw(&self) -> *mut ffi::DH { let DH(n) = *self; n } pub unsafe fn raw_ptr(&self) -> *const *mut ffi::DH { let DH(ref n) = *self; n } } impl Drop for DH { fn drop(&mut self) { unsafe { if !self.raw().is_null() { ffi::DH_free(self.raw()) } } } } #[cfg(test)] mod tests { use std::fs::File; use std::path::Path; use super::DH; use bn::BigNum; use ssl::SslContext; use ssl::SslMethod::Sslv23; #[test] #[cfg(feature = "rfc5114")] fn test_dh_rfc5114() { let ctx = SslContext::new(Sslv23).unwrap(); let dh1 = DH::get_1024_160().unwrap(); ctx.set_tmp_dh(dh1).unwrap(); let dh2 = DH::get_2048_224().unwrap(); ctx.set_tmp_dh(dh2).unwrap(); let dh3 = DH::get_2048_256().unwrap(); ctx.set_tmp_dh(dh3).unwrap(); } #[test] fn test_dh() { let ctx = SslContext::new(Sslv23).unwrap(); let p = BigNum::from_hex_str("87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435\ E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF429\ 6D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C02\ 2E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF1230\ 7F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9\ A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251C\ CACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE\ 621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D227\ 6E11715F693877FAD7EF09CADB094AE91E1A1597") .unwrap(); let g = BigNum::from_hex_str("3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0\ BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773\ BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2D\ DF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428E\ BC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BF\ FE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7\ D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92\ B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148\ D47954515E2327CFEF98C582664B4C0F6CC41659") .unwrap(); let q = BigNum::from_hex_str("8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F\ 5FBD3") .unwrap(); let dh = DH::from_params(p, g, q).unwrap(); ctx.set_tmp_dh(dh).unwrap(); } #[test] fn test_dh_from_pem() { let ctx = SslContext::new(Sslv23).unwrap(); let pem_path = Path::new("test/dhparams.pem"); let mut file = File::open(&pem_path) .ok() .expect("Failed to open `test/dhparams.pem`"); let dh = DH::from_pem(&mut file).ok().expect("Failed to load PEM"); ctx.set_tmp_dh(dh).unwrap(); } }