aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUmang Raghuvanshi <[email protected]>2018-04-20 17:15:04 +0530
committerUmang Raghuvanshi <[email protected]>2018-04-20 17:15:04 +0530
commit8ce5dee00d1f7658e0790b60dfcb86d4b2f81621 (patch)
tree604a482d3ca9f69e0d9f2c7425e135da5f7635a2
parentMerge pull request #899 from rohit-lshift/master (diff)
downloadrust-openssl-8ce5dee00d1f7658e0790b60dfcb86d4b2f81621.tar.xz
rust-openssl-8ce5dee00d1f7658e0790b60dfcb86d4b2f81621.zip
Add the CMS_sign and i2d_CMS_ContentInfo function bindings
This adds the CMS_sign and i2d_CMS_ContentInfo bindings in the openssl-sys crate and Rusty wrappers in the openssl crate.
-rw-r--r--openssl-sys/src/lib.rs12
-rw-r--r--openssl/src/cms.rs50
2 files changed, 60 insertions, 2 deletions
diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs
index 85527f8f..42bd8268 100644
--- a/openssl-sys/src/lib.rs
+++ b/openssl-sys/src/lib.rs
@@ -5,8 +5,8 @@
extern crate libc;
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t, FILE};
-use std::ptr;
use std::mem;
+use std::ptr;
#[cfg(any(ossl101, ossl102))]
mod ossl10x;
@@ -2846,6 +2846,16 @@ extern "C" {
pub fn SMIME_read_CMS(bio: *mut BIO, bcont: *mut *mut BIO) -> *mut CMS_ContentInfo;
#[cfg(not(libressl))]
pub fn CMS_ContentInfo_free(cms: *mut CMS_ContentInfo);
+ #[cfg(not(libressl))]
+ pub fn CMS_sign(
+ signcert: *const X509,
+ pkey: *const EVP_PKEY,
+ certs: *const stack_st_X509,
+ data: *mut BIO,
+ flags: c_uint,
+ ) -> *mut CMS_ContentInfo;
+ #[cfg(not(libressl))]
+ pub fn i2d_CMS_ContentInfo(a: *mut CMS_ContentInfo, pp: *mut *mut c_uchar) -> c_int;
#[cfg(not(libressl))]
pub fn FIPS_mode_set(onoff: c_int) -> c_int;
diff --git a/openssl/src/cms.rs b/openssl/src/cms.rs
index 8c60455c..b549e066 100644
--- a/openssl/src/cms.rs
+++ b/openssl/src/cms.rs
@@ -9,11 +9,12 @@ use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use std::ptr;
-use {cvt, cvt_p};
use bio::{MemBio, MemBioSlice};
use error::ErrorStack;
use pkey::{HasPrivate, PKeyRef};
+use stack::Stack;
use x509::X509;
+use {cvt, cvt_p};
foreign_type_and_impl_send_sync! {
type CType = ffi::CMS_ContentInfo;
@@ -80,4 +81,51 @@ impl CmsContentInfo {
Ok(CmsContentInfo::from_ptr(cms))
}
}
+
+ /// Given a signing cert `signcert`, private key `pkey`, an optional certificate stack `certs`,
+ /// data `data` and flags `flags`, create a CmsContentInfo struct.
+ ///
+ /// OpenSSL documentation at [`CMS_sign`]
+ ///
+ /// [`CMS_sign`]: https://www.openssl.org/docs/manmaster/man3/CMS_sign.html
+ pub fn sign<T: HasPrivate>(
+ signcert: &X509,
+ pkey: &PKeyRef<T>,
+ certs: Option<&Stack<X509>>,
+ data: &[u8],
+ flags: u32,
+ ) -> Result<CmsContentInfo, ErrorStack> {
+ unsafe {
+ let signcert = signcert.as_ptr();
+ let pkey = pkey.as_ptr();
+ let data_bio = MemBioSlice::new(data)?;
+ let cms = cvt_p(ffi::CMS_sign(
+ signcert,
+ pkey,
+ certs.unwrap_or(&Stack::<X509>::new()?).as_ptr(),
+ data_bio.as_ptr(),
+ flags,
+ ))?;
+
+ Ok(CmsContentInfo::from_ptr(cms))
+ }
+ }
+
+ /// Serializes this CmsContentInfo using DER.
+ ///
+ /// OpenSSL documentation at [`i2d_CMS_ContentInfo`]
+ ///
+ /// [`i2d_CMS_ContentInfo`]: https://www.openssl.org/docs/man1.0.2/crypto/i2d_CMS_ContentInfo.html
+ pub fn to_der(&mut self) -> Result<Vec<u8>, ErrorStack> {
+ unsafe {
+ let size = ffi::i2d_CMS_ContentInfo(self.as_ptr(), ptr::null_mut());
+ let mut der = vec![0u8; size as usize];
+
+ let raw_ptr = Box::into_raw(Box::new(der.as_mut_ptr()));
+ ffi::i2d_CMS_ContentInfo(self.as_ptr(), raw_ptr);
+
+ Box::from_raw(raw_ptr);
+ Ok(der)
+ }
+ }
}