CMS: add encrypt, from_der
This commit is contained in:
parent
7602aed0dc
commit
546eb4d391
|
|
@ -1,4 +1,5 @@
|
|||
use libc::*;
|
||||
use *;
|
||||
|
||||
pub enum CMS_ContentInfo {}
|
||||
|
||||
|
|
@ -7,6 +8,9 @@ extern "C" {
|
|||
pub fn CMS_ContentInfo_free(cms: *mut ::CMS_ContentInfo);
|
||||
#[cfg(ossl101)]
|
||||
pub fn i2d_CMS_ContentInfo(a: *mut ::CMS_ContentInfo, pp: *mut *mut c_uchar) -> c_int;
|
||||
|
||||
#[cfg(ossl101)]
|
||||
pub fn d2i_CMS_ContentInfo(a: *mut *mut ::CMS_ContentInfo, pp: *mut *const c_uchar, length: c_long) -> *mut ::CMS_ContentInfo;
|
||||
}
|
||||
|
||||
#[cfg(ossl101)]
|
||||
|
|
@ -67,6 +71,14 @@ extern "C" {
|
|||
flags: c_uint,
|
||||
) -> *mut ::CMS_ContentInfo;
|
||||
|
||||
#[cfg(ossl101)]
|
||||
pub fn CMS_encrypt(
|
||||
certs: *mut stack_st_X509,
|
||||
data: *mut ::BIO,
|
||||
cipher: *const EVP_CIPHER,
|
||||
flags: c_uint
|
||||
) -> *mut ::CMS_ContentInfo;
|
||||
|
||||
#[cfg(ossl101)]
|
||||
pub fn CMS_decrypt(
|
||||
cms: *mut ::CMS_ContentInfo,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use libc::c_uint;
|
|||
use pkey::{HasPrivate, PKeyRef};
|
||||
use stack::StackRef;
|
||||
use x509::{X509Ref, X509};
|
||||
use symm::Cipher;
|
||||
use {cvt, cvt_p};
|
||||
|
||||
bitflags! {
|
||||
|
|
@ -122,6 +123,17 @@ impl CmsContentInfo {
|
|||
}
|
||||
}
|
||||
|
||||
from_der! {
|
||||
/// Deserializes a DER-encoded ContentInfo structure.
|
||||
///
|
||||
/// This corresponds to [`d2i_CMS_ContentInfo`].
|
||||
///
|
||||
/// [`d2i_CMS_ContentInfo`]: https://www.openssl.org/docs/manmaster/man3/d2i_X509.html
|
||||
from_der,
|
||||
CmsContentInfo,
|
||||
ffi::d2i_CMS_ContentInfo
|
||||
}
|
||||
|
||||
/// Given a signing cert `signcert`, private key `pkey`, a certificate stack `certs`,
|
||||
/// data `data` and flags `flags`, create a CmsContentInfo struct.
|
||||
///
|
||||
|
|
@ -161,4 +173,67 @@ impl CmsContentInfo {
|
|||
Ok(CmsContentInfo::from_ptr(cms))
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a certificate stack `certs`, data `data`, cipher `cipher` and flags `flags`,
|
||||
/// create a CmsContentInfo struct.
|
||||
///
|
||||
/// OpenSSL documentation at [`CMS_encrypt`]
|
||||
///
|
||||
/// [`CMS_encrypt`]: https://www.openssl.org/docs/manmaster/man3/CMS_encrypt.html
|
||||
pub fn encrypt(
|
||||
certs: &StackRef<X509>,
|
||||
data: &[u8],
|
||||
cipher: Cipher,
|
||||
flags: CMSOptions,
|
||||
) -> Result<CmsContentInfo, ErrorStack>
|
||||
{
|
||||
unsafe {
|
||||
let data_bio = MemBioSlice::new(data)?;
|
||||
|
||||
let cms = cvt_p(ffi::CMS_encrypt(
|
||||
certs.as_ptr(),
|
||||
data_bio.as_ptr(),
|
||||
cipher.as_ptr(),
|
||||
flags.bits(),
|
||||
))?;
|
||||
|
||||
Ok(CmsContentInfo::from_ptr(cms))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use stack::Stack;
|
||||
use x509::X509;
|
||||
use pkcs12::Pkcs12;
|
||||
|
||||
#[test]
|
||||
fn cms_encrypt_decrypt() {
|
||||
// load cert with public key only
|
||||
let pub_cert_bytes = include_bytes!("../test/cms_pubkey.der");
|
||||
let pub_cert = X509::from_der(pub_cert_bytes).expect("failed to load pub cert");
|
||||
|
||||
// load cert with private key
|
||||
let priv_cert_bytes = include_bytes!("../test/cms.p12");
|
||||
let priv_cert = Pkcs12::from_der(priv_cert_bytes).expect("failed to load priv cert");
|
||||
let priv_cert = priv_cert.parse("mypass").expect("failed to parse priv cert");
|
||||
|
||||
// encrypt cms message using public key cert
|
||||
let input = String::from("My Message");
|
||||
let mut cert_stack = Stack::new().expect("failed to create stack");
|
||||
cert_stack.push(pub_cert).expect("failed to add pub cert to stack");
|
||||
|
||||
let encrypt = CmsContentInfo::encrypt(&cert_stack, &input.as_bytes(), Cipher::des_ede3_cbc(), CMSOptions::empty())
|
||||
.expect("failed create encrypted cms");
|
||||
let encrypt = encrypt.to_der().expect("failed to create der from cms");
|
||||
|
||||
// decrypt cms message using private key cert
|
||||
let decrypt = CmsContentInfo::from_der(&encrypt).expect("failed read cms from der");
|
||||
let decrypt = decrypt.decrypt(&priv_cert.pkey, &priv_cert.cert).expect("failed to decrypt cms");
|
||||
let decrypt = String::from_utf8(decrypt).expect("failed to create string from cms content");
|
||||
|
||||
assert_eq!(input, decrypt);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue