Commit 8ce5dee0 authored by Umang Raghuvanshi's avatar Umang Raghuvanshi
Browse files

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.
parent 6b1edf56
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -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;
+49 −1
Original line number Diff line number Diff line
@@ -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)
        }
    }
}