Loading openssl-sys/src/lib.rs +18 −0 Original line number Diff line number Diff line Loading @@ -151,6 +151,12 @@ pub const EVP_PKEY_DSA: c_int = NID_dsa; pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement; pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey; pub const EVP_PKEY_ALG_CTRL: c_int = 0x1000; pub const EVP_PKEY_CTRL_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 1; pub const EVP_PKEY_CTRL_GET_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 6; pub const EVP_CTRL_GCM_SET_IVLEN: c_int = 0x9; pub const EVP_CTRL_GCM_GET_TAG: c_int = 0x10; pub const EVP_CTRL_GCM_SET_TAG: c_int = 0x11; Loading Loading @@ -1304,6 +1310,15 @@ pub unsafe fn BIO_set_retry_write(b: *mut BIO) { BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY) } // EVP_PKEY_CTX_ctrl macros pub unsafe fn EVP_PKEY_CTX_set_rsa_padding(ctx: *mut EVP_PKEY_CTX, pad: c_int) -> c_int { EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, ptr::null_mut()) } pub unsafe fn EVP_PKEY_CTX_get_rsa_padding(ctx: *mut EVP_PKEY_CTX, ppad: *mut c_int) -> c_int { EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad as *mut c_void) } pub unsafe fn SSL_CTX_set_mode(ctx: *mut SSL_CTX, op: c_long) -> c_long { SSL_CTX_ctrl(ctx, SSL_CTRL_MODE, op, ptr::null_mut()) } Loading Loading @@ -1632,6 +1647,9 @@ extern { key: *const c_uchar, keylen: c_int) -> *mut EVP_PKEY; pub fn EVP_PKEY_CTX_ctrl(ctx: *mut EVP_PKEY_CTX, keytype: c_int, optype: c_int, cmd: c_int, p1: c_int, p2: *mut c_void) -> c_int; pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *mut HMAC_CTX) -> c_int; pub fn OCSP_BASICRESP_new() -> *mut OCSP_BASICRESP; Loading openssl/src/pkey.rs +24 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ use bio::MemBioSlice; use dh::Dh; use dsa::Dsa; use ec::EcKey; use rsa::Rsa; use rsa::{Rsa, Padding}; use error::ErrorStack; use util::{CallbackState, invoke_passwd_cb_old}; use types::{OpenSslType, OpenSslTypeRef}; Loading Loading @@ -151,6 +151,29 @@ impl PKey { } } pub struct PKeyCtxRef(::util::Opaque); impl PKeyCtxRef { pub fn set_rsa_padding(&mut self, pad: Padding) -> Result<(), ErrorStack> { unsafe { try!(cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(self.as_ptr(), pad.as_raw()))); } Ok(()) } pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> { let mut pad: c_int = 0; unsafe { try!(cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad))); }; Ok(Padding::from_raw(pad)) } } impl ::types::OpenSslTypeRef for PKeyCtxRef { type CType = ffi::EVP_PKEY_CTX; } #[cfg(test)] mod tests { use symm::Cipher; Loading openssl/src/rsa.rs +11 −2 Original line number Diff line number Diff line Loading @@ -12,9 +12,19 @@ use util::{CallbackState, invoke_passwd_cb_old}; use types::OpenSslTypeRef; /// Type of encryption padding to use. #[derive(Copy, Clone)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct Padding(c_int); impl Padding { pub fn from_raw(value: c_int) -> Padding { Padding(value) } pub fn as_raw(&self) -> c_int { self.0 } } pub const NO_PADDING: Padding = Padding(ffi::RSA_NO_PADDING); pub const PKCS1_PADDING: Padding = Padding(ffi::RSA_PKCS1_PADDING); pub const PKCS1_OAEP_PADDING: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING); Loading Loading @@ -343,7 +353,6 @@ mod compat { } } #[cfg(test)] mod test { use symm::Cipher; Loading openssl/src/sign.rs +59 −15 Original line number Diff line number Diff line Loading @@ -68,7 +68,7 @@ use std::ptr; use {cvt, cvt_p}; use hash::MessageDigest; use pkey::PKeyRef; use pkey::{PKeyRef, PKeyCtxRef}; use error::ErrorStack; use types::OpenSslTypeRef; Loading @@ -77,12 +77,17 @@ use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free}; #[cfg(any(ossl101, ossl102))] use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; pub struct Signer<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a PKeyRef>); pub struct Signer<'a> { md_ctx: *mut ffi::EVP_MD_CTX, pkey_ctx: *mut ffi::EVP_PKEY_CTX, pkey_pd: PhantomData<&'a PKeyRef>, } impl<'a> Drop for Signer<'a> { fn drop(&mut self) { // pkey_ctx is owned by the md_ctx, so no need to explicitly free it. unsafe { EVP_MD_CTX_free(self.0); EVP_MD_CTX_free(self.md_ctx); } } } Loading @@ -93,8 +98,9 @@ impl<'a> Signer<'a> { ffi::init(); let ctx = try!(cvt_p(EVP_MD_CTX_new())); let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut(); let r = ffi::EVP_DigestSignInit(ctx, ptr::null_mut(), &mut pctx, type_.as_ptr(), ptr::null_mut(), pkey.as_ptr()); Loading @@ -102,22 +108,37 @@ impl<'a> Signer<'a> { EVP_MD_CTX_free(ctx); return Err(ErrorStack::get()); } Ok(Signer(ctx, PhantomData)) assert!(!pctx.is_null()); Ok(Signer { md_ctx: ctx, pkey_ctx: pctx, pkey_pd: PhantomData, }) } } pub fn pkey_ctx(&self) -> &PKeyCtxRef { unsafe { ::types::OpenSslTypeRef::from_ptr(self.pkey_ctx) } } pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef { unsafe { ::types::OpenSslTypeRef::from_ptr_mut(self.pkey_ctx) } } pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_DigestUpdate(self.0, buf.as_ptr() as *const _, buf.len())).map(|_| ()) cvt(ffi::EVP_DigestUpdate(self.md_ctx, buf.as_ptr() as *const _, buf.len())).map(|_| ()) } } pub fn finish(&self) -> Result<Vec<u8>, ErrorStack> { unsafe { let mut len = 0; try!(cvt(ffi::EVP_DigestSignFinal(self.0, ptr::null_mut(), &mut len))); try!(cvt(ffi::EVP_DigestSignFinal(self.md_ctx, ptr::null_mut(), &mut len))); let mut buf = vec![0; len]; try!(cvt(ffi::EVP_DigestSignFinal(self.0, buf.as_mut_ptr() as *mut _, &mut len))); try!(cvt(ffi::EVP_DigestSignFinal(self.md_ctx, buf.as_mut_ptr() as *mut _, &mut len))); // The advertised length is not always equal to the real length for things like DSA buf.truncate(len); Ok(buf) Loading @@ -136,12 +157,17 @@ impl<'a> Write for Signer<'a> { } } pub struct Verifier<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a PKeyRef>); pub struct Verifier<'a> { md_ctx: *mut ffi::EVP_MD_CTX, pkey_ctx: *mut ffi::EVP_PKEY_CTX, pkey_pd: PhantomData<&'a PKeyRef>, } impl<'a> Drop for Verifier<'a> { fn drop(&mut self) { // pkey_ctx is owned by the md_ctx, so no need to explicitly free it. unsafe { EVP_MD_CTX_free(self.0); EVP_MD_CTX_free(self.md_ctx); } } } Loading @@ -152,8 +178,9 @@ impl<'a> Verifier<'a> { ffi::init(); let ctx = try!(cvt_p(EVP_MD_CTX_new())); let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut(); let r = ffi::EVP_DigestVerifyInit(ctx, ptr::null_mut(), &mut pctx, type_.as_ptr(), ptr::null_mut(), pkey.as_ptr()); Loading @@ -162,19 +189,33 @@ impl<'a> Verifier<'a> { return Err(ErrorStack::get()); } Ok(Verifier(ctx, PhantomData)) assert!(!pctx.is_null()); Ok(Verifier { md_ctx: ctx, pkey_ctx: pctx, pkey_pd: PhantomData, }) } } pub fn pkey_ctx(&self) -> &PKeyCtxRef { unsafe { ::types::OpenSslTypeRef::from_ptr(self.pkey_ctx) } } pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef { unsafe { ::types::OpenSslTypeRef::from_ptr_mut(self.pkey_ctx) } } pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_DigestUpdate(self.0, buf.as_ptr() as *const _, buf.len())).map(|_| ()) cvt(ffi::EVP_DigestUpdate(self.md_ctx, buf.as_ptr() as *const _, buf.len())).map(|_| ()) } } pub fn finish(&self, signature: &[u8]) -> Result<bool, ErrorStack> { unsafe { let r = EVP_DigestVerifyFinal(self.0, signature.as_ptr() as *const _, signature.len()); let r = EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *const _, signature.len()); match r { 1 => Ok(true), 0 => { Loading Loading @@ -219,7 +260,7 @@ mod test { use sign::{Signer, Verifier}; use ec::{EcGroup, EcKey}; use nid; use rsa::Rsa; use rsa::{Rsa, PKCS1_PADDING}; use dsa::Dsa; use pkey::PKey; Loading Loading @@ -254,6 +295,8 @@ mod test { let pkey = PKey::from_rsa(private_key).unwrap(); let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap(); assert_eq!(signer.pkey_ctx_mut().rsa_padding().unwrap(), PKCS1_PADDING); signer.pkey_ctx_mut().set_rsa_padding(PKCS1_PADDING).unwrap(); signer.update(INPUT).unwrap(); let result = signer.finish().unwrap(); Loading @@ -267,6 +310,7 @@ mod test { let pkey = PKey::from_rsa(private_key).unwrap(); let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap(); assert_eq!(verifier.pkey_ctx_mut().rsa_padding().unwrap(), PKCS1_PADDING); verifier.update(INPUT).unwrap(); assert!(verifier.finish(SIGNATURE).unwrap()); } Loading Loading
openssl-sys/src/lib.rs +18 −0 Original line number Diff line number Diff line Loading @@ -151,6 +151,12 @@ pub const EVP_PKEY_DSA: c_int = NID_dsa; pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement; pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey; pub const EVP_PKEY_ALG_CTRL: c_int = 0x1000; pub const EVP_PKEY_CTRL_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 1; pub const EVP_PKEY_CTRL_GET_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 6; pub const EVP_CTRL_GCM_SET_IVLEN: c_int = 0x9; pub const EVP_CTRL_GCM_GET_TAG: c_int = 0x10; pub const EVP_CTRL_GCM_SET_TAG: c_int = 0x11; Loading Loading @@ -1304,6 +1310,15 @@ pub unsafe fn BIO_set_retry_write(b: *mut BIO) { BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY) } // EVP_PKEY_CTX_ctrl macros pub unsafe fn EVP_PKEY_CTX_set_rsa_padding(ctx: *mut EVP_PKEY_CTX, pad: c_int) -> c_int { EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, ptr::null_mut()) } pub unsafe fn EVP_PKEY_CTX_get_rsa_padding(ctx: *mut EVP_PKEY_CTX, ppad: *mut c_int) -> c_int { EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad as *mut c_void) } pub unsafe fn SSL_CTX_set_mode(ctx: *mut SSL_CTX, op: c_long) -> c_long { SSL_CTX_ctrl(ctx, SSL_CTRL_MODE, op, ptr::null_mut()) } Loading Loading @@ -1632,6 +1647,9 @@ extern { key: *const c_uchar, keylen: c_int) -> *mut EVP_PKEY; pub fn EVP_PKEY_CTX_ctrl(ctx: *mut EVP_PKEY_CTX, keytype: c_int, optype: c_int, cmd: c_int, p1: c_int, p2: *mut c_void) -> c_int; pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *mut HMAC_CTX) -> c_int; pub fn OCSP_BASICRESP_new() -> *mut OCSP_BASICRESP; Loading
openssl/src/pkey.rs +24 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ use bio::MemBioSlice; use dh::Dh; use dsa::Dsa; use ec::EcKey; use rsa::Rsa; use rsa::{Rsa, Padding}; use error::ErrorStack; use util::{CallbackState, invoke_passwd_cb_old}; use types::{OpenSslType, OpenSslTypeRef}; Loading Loading @@ -151,6 +151,29 @@ impl PKey { } } pub struct PKeyCtxRef(::util::Opaque); impl PKeyCtxRef { pub fn set_rsa_padding(&mut self, pad: Padding) -> Result<(), ErrorStack> { unsafe { try!(cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(self.as_ptr(), pad.as_raw()))); } Ok(()) } pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> { let mut pad: c_int = 0; unsafe { try!(cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad))); }; Ok(Padding::from_raw(pad)) } } impl ::types::OpenSslTypeRef for PKeyCtxRef { type CType = ffi::EVP_PKEY_CTX; } #[cfg(test)] mod tests { use symm::Cipher; Loading
openssl/src/rsa.rs +11 −2 Original line number Diff line number Diff line Loading @@ -12,9 +12,19 @@ use util::{CallbackState, invoke_passwd_cb_old}; use types::OpenSslTypeRef; /// Type of encryption padding to use. #[derive(Copy, Clone)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct Padding(c_int); impl Padding { pub fn from_raw(value: c_int) -> Padding { Padding(value) } pub fn as_raw(&self) -> c_int { self.0 } } pub const NO_PADDING: Padding = Padding(ffi::RSA_NO_PADDING); pub const PKCS1_PADDING: Padding = Padding(ffi::RSA_PKCS1_PADDING); pub const PKCS1_OAEP_PADDING: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING); Loading Loading @@ -343,7 +353,6 @@ mod compat { } } #[cfg(test)] mod test { use symm::Cipher; Loading
openssl/src/sign.rs +59 −15 Original line number Diff line number Diff line Loading @@ -68,7 +68,7 @@ use std::ptr; use {cvt, cvt_p}; use hash::MessageDigest; use pkey::PKeyRef; use pkey::{PKeyRef, PKeyCtxRef}; use error::ErrorStack; use types::OpenSslTypeRef; Loading @@ -77,12 +77,17 @@ use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free}; #[cfg(any(ossl101, ossl102))] use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; pub struct Signer<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a PKeyRef>); pub struct Signer<'a> { md_ctx: *mut ffi::EVP_MD_CTX, pkey_ctx: *mut ffi::EVP_PKEY_CTX, pkey_pd: PhantomData<&'a PKeyRef>, } impl<'a> Drop for Signer<'a> { fn drop(&mut self) { // pkey_ctx is owned by the md_ctx, so no need to explicitly free it. unsafe { EVP_MD_CTX_free(self.0); EVP_MD_CTX_free(self.md_ctx); } } } Loading @@ -93,8 +98,9 @@ impl<'a> Signer<'a> { ffi::init(); let ctx = try!(cvt_p(EVP_MD_CTX_new())); let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut(); let r = ffi::EVP_DigestSignInit(ctx, ptr::null_mut(), &mut pctx, type_.as_ptr(), ptr::null_mut(), pkey.as_ptr()); Loading @@ -102,22 +108,37 @@ impl<'a> Signer<'a> { EVP_MD_CTX_free(ctx); return Err(ErrorStack::get()); } Ok(Signer(ctx, PhantomData)) assert!(!pctx.is_null()); Ok(Signer { md_ctx: ctx, pkey_ctx: pctx, pkey_pd: PhantomData, }) } } pub fn pkey_ctx(&self) -> &PKeyCtxRef { unsafe { ::types::OpenSslTypeRef::from_ptr(self.pkey_ctx) } } pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef { unsafe { ::types::OpenSslTypeRef::from_ptr_mut(self.pkey_ctx) } } pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_DigestUpdate(self.0, buf.as_ptr() as *const _, buf.len())).map(|_| ()) cvt(ffi::EVP_DigestUpdate(self.md_ctx, buf.as_ptr() as *const _, buf.len())).map(|_| ()) } } pub fn finish(&self) -> Result<Vec<u8>, ErrorStack> { unsafe { let mut len = 0; try!(cvt(ffi::EVP_DigestSignFinal(self.0, ptr::null_mut(), &mut len))); try!(cvt(ffi::EVP_DigestSignFinal(self.md_ctx, ptr::null_mut(), &mut len))); let mut buf = vec![0; len]; try!(cvt(ffi::EVP_DigestSignFinal(self.0, buf.as_mut_ptr() as *mut _, &mut len))); try!(cvt(ffi::EVP_DigestSignFinal(self.md_ctx, buf.as_mut_ptr() as *mut _, &mut len))); // The advertised length is not always equal to the real length for things like DSA buf.truncate(len); Ok(buf) Loading @@ -136,12 +157,17 @@ impl<'a> Write for Signer<'a> { } } pub struct Verifier<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a PKeyRef>); pub struct Verifier<'a> { md_ctx: *mut ffi::EVP_MD_CTX, pkey_ctx: *mut ffi::EVP_PKEY_CTX, pkey_pd: PhantomData<&'a PKeyRef>, } impl<'a> Drop for Verifier<'a> { fn drop(&mut self) { // pkey_ctx is owned by the md_ctx, so no need to explicitly free it. unsafe { EVP_MD_CTX_free(self.0); EVP_MD_CTX_free(self.md_ctx); } } } Loading @@ -152,8 +178,9 @@ impl<'a> Verifier<'a> { ffi::init(); let ctx = try!(cvt_p(EVP_MD_CTX_new())); let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut(); let r = ffi::EVP_DigestVerifyInit(ctx, ptr::null_mut(), &mut pctx, type_.as_ptr(), ptr::null_mut(), pkey.as_ptr()); Loading @@ -162,19 +189,33 @@ impl<'a> Verifier<'a> { return Err(ErrorStack::get()); } Ok(Verifier(ctx, PhantomData)) assert!(!pctx.is_null()); Ok(Verifier { md_ctx: ctx, pkey_ctx: pctx, pkey_pd: PhantomData, }) } } pub fn pkey_ctx(&self) -> &PKeyCtxRef { unsafe { ::types::OpenSslTypeRef::from_ptr(self.pkey_ctx) } } pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef { unsafe { ::types::OpenSslTypeRef::from_ptr_mut(self.pkey_ctx) } } pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_DigestUpdate(self.0, buf.as_ptr() as *const _, buf.len())).map(|_| ()) cvt(ffi::EVP_DigestUpdate(self.md_ctx, buf.as_ptr() as *const _, buf.len())).map(|_| ()) } } pub fn finish(&self, signature: &[u8]) -> Result<bool, ErrorStack> { unsafe { let r = EVP_DigestVerifyFinal(self.0, signature.as_ptr() as *const _, signature.len()); let r = EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *const _, signature.len()); match r { 1 => Ok(true), 0 => { Loading Loading @@ -219,7 +260,7 @@ mod test { use sign::{Signer, Verifier}; use ec::{EcGroup, EcKey}; use nid; use rsa::Rsa; use rsa::{Rsa, PKCS1_PADDING}; use dsa::Dsa; use pkey::PKey; Loading Loading @@ -254,6 +295,8 @@ mod test { let pkey = PKey::from_rsa(private_key).unwrap(); let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap(); assert_eq!(signer.pkey_ctx_mut().rsa_padding().unwrap(), PKCS1_PADDING); signer.pkey_ctx_mut().set_rsa_padding(PKCS1_PADDING).unwrap(); signer.update(INPUT).unwrap(); let result = signer.finish().unwrap(); Loading @@ -267,6 +310,7 @@ mod test { let pkey = PKey::from_rsa(private_key).unwrap(); let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap(); assert_eq!(verifier.pkey_ctx_mut().rsa_padding().unwrap(), PKCS1_PADDING); verifier.update(INPUT).unwrap(); assert!(verifier.finish(SIGNATURE).unwrap()); } Loading