aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2017-01-31 14:55:11 -0800
committerGitHub <[email protected]>2017-01-31 14:55:11 -0800
commit7bd90dcb18ac9dccbbd68d7b5d0ace704dcc8447 (patch)
treea6614602603c645617e15286f9fc92385e651735 /openssl/src
parentMerge pull request #569 from sfackler/expando (diff)
parentFixed constant names from openssl/rsa.h (diff)
downloadrust-openssl-7bd90dcb18ac9dccbbd68d7b5d0ace704dcc8447.tar.xz
rust-openssl-7bd90dcb18ac9dccbbd68d7b5d0ace704dcc8447.zip
Merge pull request #570 from brianchin/add_evp_pkey_ctx_ctrl
Add PKey context options
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/pkey.rs25
-rw-r--r--openssl/src/rsa.rs13
-rw-r--r--openssl/src/sign.rs74
3 files changed, 94 insertions, 18 deletions
diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs
index 7a32692b..c9f5ec1b 100644
--- a/openssl/src/pkey.rs
+++ b/openssl/src/pkey.rs
@@ -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};
@@ -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;
diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs
index 8c3507f4..dc760f7a 100644
--- a/openssl/src/rsa.rs
+++ b/openssl/src/rsa.rs
@@ -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);
@@ -343,7 +353,6 @@ mod compat {
}
}
-
#[cfg(test)]
mod test {
use symm::Cipher;
diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs
index ec37c885..ac33bd07 100644
--- a/openssl/src/sign.rs
+++ b/openssl/src/sign.rs
@@ -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;
@@ -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);
}
}
}
@@ -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());
@@ -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)
@@ -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);
}
}
}
@@ -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());
@@ -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 => {
@@ -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;
@@ -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();
@@ -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());
}