diff options
Diffstat (limited to 'openssl/src')
| -rw-r--r-- | openssl/src/derive.rs | 3 | ||||
| -rw-r--r-- | openssl/src/hash.rs | 6 | ||||
| -rw-r--r-- | openssl/src/pkey.rs | 37 | ||||
| -rw-r--r-- | openssl/src/rsa.rs | 1 | ||||
| -rw-r--r-- | openssl/src/sign.rs | 117 | ||||
| -rw-r--r-- | openssl/src/ssl/mod.rs | 3 | ||||
| -rw-r--r-- | openssl/src/symm.rs | 7 |
7 files changed, 172 insertions, 2 deletions
diff --git a/openssl/src/derive.rs b/openssl/src/derive.rs index fb7bbf14..30d7dc25 100644 --- a/openssl/src/derive.rs +++ b/openssl/src/derive.rs @@ -11,6 +11,9 @@ use pkey::{HasPrivate, HasPublic, PKeyRef}; /// A type used to derive a shared secret between two keys. pub struct Deriver<'a>(*mut ffi::EVP_PKEY_CTX, PhantomData<&'a ()>); +unsafe impl<'a> Sync for Deriver<'a> {} +unsafe impl<'a> Send for Deriver<'a> {} + impl<'a> Deriver<'a> { /// Creates a new `Deriver` using the provided private key. /// diff --git a/openssl/src/hash.rs b/openssl/src/hash.rs index 103a7ae3..c6d4c862 100644 --- a/openssl/src/hash.rs +++ b/openssl/src/hash.rs @@ -49,6 +49,9 @@ impl MessageDigest { } } +unsafe impl Sync for MessageDigest {} +unsafe impl Send for MessageDigest {} + #[derive(PartialEq, Copy, Clone)] enum State { Reset, @@ -99,6 +102,9 @@ pub struct Hasher { state: State, } +unsafe impl Sync for Hasher {} +unsafe impl Send for Hasher {} + impl Hasher { /// Creates a new `Hasher` with the specified hash type. pub fn new(ty: MessageDigest) -> Result<Hasher, ErrorStack> { diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index 8f7c4e4e..66ff33d6 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -70,6 +70,28 @@ pub enum Public {} /// A tag type indicating that a key has private components. pub enum Private {} +/// An identifier of a kind of key. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct Id(c_int); + +impl Id { + /// Creates a `Id` from an integer representation. + pub fn from_raw(value: c_int) -> Id { + Id(value) + } + + /// Returns the integer representation of the `Id`. + pub fn as_raw(&self) -> c_int { + self.0 + } + + pub const RSA: Id = Id(ffi::EVP_PKEY_RSA); + pub const HMAC: Id = Id(ffi::EVP_PKEY_HMAC); + pub const DSA: Id = Id(ffi::EVP_PKEY_DSA); + pub const DH: Id = Id(ffi::EVP_PKEY_DH); + pub const EC: Id = Id(ffi::EVP_PKEY_EC); +} + /// A trait indicating that a key has parameters. pub unsafe trait HasParams {} @@ -155,6 +177,17 @@ impl<T> PKeyRef<T> { Ok(EcKey::from_ptr(ec_key)) } } + + /// Returns the `Id` that represents the type of this key. + /// + /// This corresponds to [`EVP_PKEY_id`]. + /// + /// [`EVP_PKEY_id`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_id.html + pub fn id(&self) -> Id { + unsafe { + Id::from_raw(ffi::EVP_PKEY_id(self.as_ptr())) + } + } } impl<T> PKeyRef<T> @@ -531,6 +564,7 @@ mod tests { let rsa = Rsa::generate(2048).unwrap(); let pkey = PKey::from_rsa(rsa).unwrap(); pkey.rsa().unwrap(); + assert_eq!(pkey.id(), Id::RSA); assert!(pkey.dsa().is_err()); } @@ -539,6 +573,7 @@ mod tests { let dsa = Dsa::generate(2048).unwrap(); let pkey = PKey::from_dsa(dsa).unwrap(); pkey.dsa().unwrap(); + assert_eq!(pkey.id(), Id::DSA); assert!(pkey.rsa().is_err()); } @@ -548,6 +583,7 @@ mod tests { let dh = Dh::params_from_pem(dh).unwrap(); let pkey = PKey::from_dh(dh).unwrap(); pkey.dh().unwrap(); + assert_eq!(pkey.id(), Id::DH); assert!(pkey.rsa().is_err()); } @@ -556,6 +592,7 @@ mod tests { let ec_key = EcKey::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); let pkey = PKey::from_ec_key(ec_key).unwrap(); pkey.ec_key().unwrap(); + assert_eq!(pkey.id(), Id::EC); assert!(pkey.rsa().is_err()); } } diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs index 02240948..6a591b69 100644 --- a/openssl/src/rsa.rs +++ b/openssl/src/rsa.rs @@ -63,6 +63,7 @@ impl Padding { pub const NONE: Padding = Padding(ffi::RSA_NO_PADDING); pub const PKCS1: Padding = Padding(ffi::RSA_PKCS1_PADDING); pub const PKCS1_OAEP: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING); + pub const PKCS1_PSS: Padding = Padding(ffi::RSA_PKCS1_PSS_PADDING); } generic_foreign_type_and_impl_send_sync! { diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs index a61d883b..6a49cb49 100644 --- a/openssl/src/sign.rs +++ b/openssl/src/sign.rs @@ -66,6 +66,7 @@ use foreign_types::ForeignTypeRef; use std::io::{self, Write}; use std::marker::PhantomData; use std::ptr; +use libc::c_int; use {cvt, cvt_p}; use hash::MessageDigest; @@ -78,6 +79,28 @@ use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; #[cfg(any(ossl101, ossl102))] use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; +/// Salt lengths that must be used with `set_rsa_pss_saltlen`. +pub struct RsaPssSaltlen(c_int); + +impl RsaPssSaltlen { + /// Returns the integer representation of `RsaPssSaltlen`. + fn as_raw(&self) -> c_int { + self.0 + } + + /// Sets the salt length to the given value. + pub fn custom(val: c_int) -> RsaPssSaltlen { + RsaPssSaltlen(val) + } + + /// The salt length is set to the digest length. + /// Corresponds to the special value `-1`. + pub const DIGEST_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-1); + /// The salt length is set to the maximum permissible value. + /// Corresponds to the special value `-2`. + pub const MAXIMUM_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-2); +} + /// A type which computes cryptographic signatures of data. pub struct Signer<'a> { md_ctx: *mut ffi::EVP_MD_CTX, @@ -85,6 +108,9 @@ pub struct Signer<'a> { _p: PhantomData<&'a ()>, } +unsafe impl<'a> Sync for Signer<'a> {} +unsafe impl<'a> Send for Signer<'a> {} + 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. @@ -160,6 +186,38 @@ impl<'a> Signer<'a> { } } + /// Sets the RSA PSS salt length. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html + pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( + self.pctx, + len.as_raw(), + )).map(|_| ()) + } + } + + /// Sets the RSA MGF1 algorithm. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html + pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( + self.pctx, + md.as_ptr() as *mut _, + )).map(|_| ()) + } + } + /// Feeds more data into the `Signer`. /// /// OpenSSL documentation at [`EVP_DigestUpdate`]. @@ -244,6 +302,9 @@ pub struct Verifier<'a> { pkey_pd: PhantomData<&'a ()>, } +unsafe impl<'a> Sync for Verifier<'a> {} +unsafe impl<'a> Send for Verifier<'a> {} + 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. @@ -320,6 +381,38 @@ impl<'a> Verifier<'a> { } } + /// Sets the RSA PSS salt length. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html + pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( + self.pctx, + len.as_raw(), + )).map(|_| ()) + } + } + + /// Sets the RSA MGF1 algorithm. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html + pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( + self.pctx, + md.as_ptr() as *mut _, + )).map(|_| ()) + } + } + /// Feeds more data into the `Verifier`. /// /// OpenSSL documentation at [`EVP_DigestUpdate`]. @@ -386,7 +479,7 @@ mod test { use std::iter; use hash::MessageDigest; - use sign::{Signer, Verifier}; + use sign::{Signer, Verifier, RsaPssSaltlen}; use ec::{EcGroup, EcKey}; use nid::Nid; use rsa::{Padding, Rsa}; @@ -559,4 +652,26 @@ mod test { verifier.update(b"hello world").unwrap(); assert!(verifier.verify(&signature).unwrap()); } + + #[test] + fn rsa_sign_verify() { + let key = include_bytes!("../test/rsa.pem"); + let private_key = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(private_key).unwrap(); + + let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap(); + signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); + assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1_PSS); + signer.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH).unwrap(); + signer.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap(); + signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); + let signature = signer.sign_to_vec().unwrap(); + + let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap(); + verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); + verifier.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH).unwrap(); + verifier.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap(); + verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); + assert!(verifier.verify(&signature).unwrap()); + } } diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 5431df13..d7d98949 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -305,6 +305,9 @@ impl SslMethod { } } +unsafe impl Sync for SslMethod {} +unsafe impl Send for SslMethod {} + bitflags! { /// Options controling the behavior of certificate verification. pub struct SslVerifyMode: i32 { diff --git a/openssl/src/symm.rs b/openssl/src/symm.rs index 630f4ab6..1cb2ef81 100644 --- a/openssl/src/symm.rs +++ b/openssl/src/symm.rs @@ -223,6 +223,9 @@ impl Cipher { } } +unsafe impl Sync for Cipher {} +unsafe impl Send for Cipher {} + /// Represents a symmetric cipher context. /// /// Padding is enabled by default. @@ -288,6 +291,9 @@ pub struct Crypter { block_size: usize, } +unsafe impl Sync for Crypter {} +unsafe impl Send for Crypter {} + impl Crypter { /// Creates a new `Crypter`. The initialisation vector, `iv`, is not necesarry for certain /// types of `Cipher`. @@ -963,7 +969,6 @@ mod tests { #[test] fn test_des_ede3_cbc() { - let pt = "54686973206973206120746573742e"; let ct = "6f2867cfefda048a4046ef7e556c7132"; let key = "7cb66337f3d3c0fe7cb66337f3d3c0fe7cb66337f3d3c0fe"; |