Cleanup
This commit is contained in:
parent
8ae761063c
commit
04ada473d1
|
|
@ -1,15 +1,14 @@
|
||||||
use x509::{X509, X509Ref};
|
|
||||||
use x509::store::X509Store;
|
|
||||||
use ffi;
|
|
||||||
use bio::{MemBio, MemBioSlice};
|
use bio::{MemBio, MemBioSlice};
|
||||||
use error::ErrorStack;
|
use error::ErrorStack;
|
||||||
use stack::Stack;
|
use ffi;
|
||||||
use foreign_types::ForeignType;
|
|
||||||
use symm::Cipher;
|
|
||||||
use pkey::{HasPrivate, PKeyRef};
|
|
||||||
use libc::c_int;
|
|
||||||
use std::ptr::null_mut;
|
|
||||||
use foreign_types::ForeignTypeRef;
|
use foreign_types::ForeignTypeRef;
|
||||||
|
use libc::c_int;
|
||||||
|
use pkey::{HasPrivate, PKeyRef};
|
||||||
|
use stack::StackRef;
|
||||||
|
use std::ptr;
|
||||||
|
use symm::Cipher;
|
||||||
|
use x509::store::X509StoreRef;
|
||||||
|
use x509::{X509Ref, X509};
|
||||||
use {cvt, cvt_p};
|
use {cvt, cvt_p};
|
||||||
|
|
||||||
foreign_type_and_impl_send_sync! {
|
foreign_type_and_impl_send_sync! {
|
||||||
|
|
@ -70,20 +69,21 @@ impl Pkcs7 {
|
||||||
/// This corresponds to [`SMIME_read_PKCS7`].
|
/// This corresponds to [`SMIME_read_PKCS7`].
|
||||||
///
|
///
|
||||||
/// [`SMIME_read_PKCS7`]: https://www.openssl.org/docs/man1.1.0/crypto/SMIME_read_PKCS7.html
|
/// [`SMIME_read_PKCS7`]: https://www.openssl.org/docs/man1.1.0/crypto/SMIME_read_PKCS7.html
|
||||||
pub fn from_smime(input: &[u8]) -> Result<(Self, Option<Vec<u8>>), ErrorStack> {
|
pub fn from_smime(input: &[u8]) -> Result<(Pkcs7, Option<Vec<u8>>), ErrorStack> {
|
||||||
ffi::init();
|
ffi::init();
|
||||||
|
|
||||||
let input_bio = MemBioSlice::new(input)?;
|
let input_bio = MemBioSlice::new(input)?;
|
||||||
let mut bcont_bio = null_mut();
|
let mut bcont_bio = ptr::null_mut();
|
||||||
unsafe {
|
unsafe {
|
||||||
let pkcs7= cvt_p(ffi::SMIME_read_PKCS7(input_bio.as_ptr(), &mut bcont_bio))?;
|
let pkcs7 =
|
||||||
|
cvt_p(ffi::SMIME_read_PKCS7(input_bio.as_ptr(), &mut bcont_bio)).map(Pkcs7)?;
|
||||||
let out = if !bcont_bio.is_null() {
|
let out = if !bcont_bio.is_null() {
|
||||||
let bcont_bio = MemBio::from_ptr(bcont_bio);
|
let bcont_bio = MemBio::from_ptr(bcont_bio);
|
||||||
Some(bcont_bio.get_buf().to_vec())
|
Some(bcont_bio.get_buf().to_vec())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
Ok((Pkcs7::from_ptr(pkcs7), out))
|
Ok((pkcs7, out))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,9 +96,12 @@ impl Pkcs7 {
|
||||||
/// This corresponds to [`PKCS7_encrypt`].
|
/// This corresponds to [`PKCS7_encrypt`].
|
||||||
///
|
///
|
||||||
/// [`PKCS7_encrypt`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_encrypt.html
|
/// [`PKCS7_encrypt`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_encrypt.html
|
||||||
pub fn encrypt(certs: &Stack<X509>, input: &[u8], cipher: Cipher, flags: Pkcs7Flags) -> Result<Self, ErrorStack> {
|
pub fn encrypt(
|
||||||
ffi::init();
|
certs: &StackRef<X509>,
|
||||||
|
input: &[u8],
|
||||||
|
cipher: Cipher,
|
||||||
|
flags: Pkcs7Flags,
|
||||||
|
) -> Result<Pkcs7, ErrorStack> {
|
||||||
let input_bio = MemBioSlice::new(input)?;
|
let input_bio = MemBioSlice::new(input)?;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
@ -106,8 +109,8 @@ impl Pkcs7 {
|
||||||
certs.as_ptr(),
|
certs.as_ptr(),
|
||||||
input_bio.as_ptr(),
|
input_bio.as_ptr(),
|
||||||
cipher.as_ptr(),
|
cipher.as_ptr(),
|
||||||
flags.bits)
|
flags.bits,
|
||||||
).map(|p| Pkcs7::from_ptr(p))
|
)).map(Pkcs7)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,15 +127,13 @@ impl Pkcs7 {
|
||||||
pub fn sign<PT>(
|
pub fn sign<PT>(
|
||||||
signcert: &X509Ref,
|
signcert: &X509Ref,
|
||||||
pkey: &PKeyRef<PT>,
|
pkey: &PKeyRef<PT>,
|
||||||
certs: &Stack<X509>,
|
certs: &StackRef<X509>,
|
||||||
input: &[u8],
|
input: &[u8],
|
||||||
flags: Pkcs7Flags
|
flags: Pkcs7Flags,
|
||||||
) -> Result<Self, ErrorStack>
|
) -> Result<Pkcs7, ErrorStack>
|
||||||
where
|
where
|
||||||
PT: HasPrivate
|
PT: HasPrivate,
|
||||||
{
|
{
|
||||||
ffi::init();
|
|
||||||
|
|
||||||
let input_bio = MemBioSlice::new(input)?;
|
let input_bio = MemBioSlice::new(input)?;
|
||||||
unsafe {
|
unsafe {
|
||||||
cvt_p(ffi::PKCS7_sign(
|
cvt_p(ffi::PKCS7_sign(
|
||||||
|
|
@ -140,8 +141,8 @@ impl Pkcs7 {
|
||||||
pkey.as_ptr(),
|
pkey.as_ptr(),
|
||||||
certs.as_ptr(),
|
certs.as_ptr(),
|
||||||
input_bio.as_ptr(),
|
input_bio.as_ptr(),
|
||||||
flags.bits)
|
flags.bits,
|
||||||
).map(|p| Pkcs7::from_ptr(p))
|
)).map(Pkcs7)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -152,26 +153,16 @@ impl Pkcs7Ref {
|
||||||
/// This corresponds to [`SMIME_write_PKCS7`].
|
/// This corresponds to [`SMIME_write_PKCS7`].
|
||||||
///
|
///
|
||||||
/// [`SMIME_write_PKCS7`]: https://www.openssl.org/docs/man1.1.0/crypto/SMIME_write_PKCS7.html
|
/// [`SMIME_write_PKCS7`]: https://www.openssl.org/docs/man1.1.0/crypto/SMIME_write_PKCS7.html
|
||||||
pub fn to_smime(
|
pub fn to_smime(&self, input: &[u8], flags: Pkcs7Flags) -> Result<Vec<u8>, ErrorStack> {
|
||||||
&self,
|
|
||||||
input: &[u8],
|
|
||||||
flags: Pkcs7Flags
|
|
||||||
) -> Result<Vec<u8>, ErrorStack>
|
|
||||||
{
|
|
||||||
ffi::init();
|
|
||||||
|
|
||||||
let input_bio = MemBioSlice::new(input)?;
|
let input_bio = MemBioSlice::new(input)?;
|
||||||
let output = MemBio::new()?;
|
let output = MemBio::new()?;
|
||||||
unsafe {
|
unsafe {
|
||||||
cvt(
|
cvt(ffi::SMIME_write_PKCS7(
|
||||||
ffi::SMIME_write_PKCS7(
|
|
||||||
output.as_ptr(),
|
output.as_ptr(),
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
input_bio.as_ptr(),
|
input_bio.as_ptr(),
|
||||||
flags.bits)
|
flags.bits,
|
||||||
).and(
|
)).map(|_| output.get_buf().to_owned())
|
||||||
Ok(output.get_buf().to_owned())
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,17 +188,25 @@ impl Pkcs7Ref {
|
||||||
/// This corresponds to [`PKCS7_decrypt`].
|
/// This corresponds to [`PKCS7_decrypt`].
|
||||||
///
|
///
|
||||||
/// [`PKCS7_decrypt`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_decrypt.html
|
/// [`PKCS7_decrypt`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_decrypt.html
|
||||||
pub fn decrypt<PT>(&self, pkey: &PKeyRef<PT>, cert: &X509Ref) -> Result<Vec<u8>, ErrorStack>
|
pub fn decrypt<PT>(
|
||||||
|
&self,
|
||||||
|
pkey: &PKeyRef<PT>,
|
||||||
|
cert: &X509Ref,
|
||||||
|
flags: Pkcs7Flags,
|
||||||
|
) -> Result<Vec<u8>, ErrorStack>
|
||||||
where
|
where
|
||||||
PT: HasPrivate
|
PT: HasPrivate,
|
||||||
{
|
{
|
||||||
ffi::init();
|
|
||||||
|
|
||||||
let output = MemBio::new()?;
|
let output = MemBio::new()?;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
cvt(ffi::PKCS7_decrypt(self.as_ptr(), pkey.as_ptr(), cert.as_ptr(), output.as_ptr(), 0))
|
cvt(ffi::PKCS7_decrypt(
|
||||||
.and(Ok(output.get_buf().to_owned()))
|
self.as_ptr(),
|
||||||
|
pkey.as_ptr(),
|
||||||
|
cert.as_ptr(),
|
||||||
|
output.as_ptr(),
|
||||||
|
flags.bits,
|
||||||
|
)).map(|_| output.get_buf().to_owned())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,50 +222,48 @@ impl Pkcs7Ref {
|
||||||
/// [`PKCS7_verify`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_verify.html
|
/// [`PKCS7_verify`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_verify.html
|
||||||
pub fn verify(
|
pub fn verify(
|
||||||
&self,
|
&self,
|
||||||
certs: &Stack<X509>,
|
certs: &StackRef<X509>,
|
||||||
store: &X509Store,
|
store: &X509StoreRef,
|
||||||
indata: Option<&[u8]>,
|
indata: Option<&[u8]>,
|
||||||
out: Option<&mut Vec<u8>>,
|
out: Option<&mut Vec<u8>>,
|
||||||
flags: Pkcs7Flags
|
flags: Pkcs7Flags,
|
||||||
) -> Result<(), ErrorStack> {
|
) -> Result<(), ErrorStack> {
|
||||||
ffi::init();
|
|
||||||
|
|
||||||
let out_bio = MemBio::new()?;
|
let out_bio = MemBio::new()?;
|
||||||
|
|
||||||
let indata_bio = match indata {
|
let indata_bio = match indata {
|
||||||
Some(data) => Some(MemBioSlice::new(data)?),
|
Some(data) => Some(MemBioSlice::new(data)?),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
let indata_bio_ptr = indata_bio.as_ref().map_or(null_mut(), |p| p.as_ptr());
|
let indata_bio_ptr = indata_bio.as_ref().map_or(ptr::null_mut(), |p| p.as_ptr());
|
||||||
|
|
||||||
let result = unsafe {
|
unsafe {
|
||||||
cvt(ffi::PKCS7_verify(
|
cvt(ffi::PKCS7_verify(
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
certs.as_ptr(),
|
certs.as_ptr(),
|
||||||
store.as_ptr(),
|
store.as_ptr(),
|
||||||
indata_bio_ptr,
|
indata_bio_ptr,
|
||||||
out_bio.as_ptr(),
|
out_bio.as_ptr(),
|
||||||
flags.bits))
|
flags.bits,
|
||||||
.map(|_r| ())
|
)).map(|_| ())?
|
||||||
};
|
}
|
||||||
|
|
||||||
if let Some(data) = out {
|
if let Some(data) = out {
|
||||||
data.clear();
|
data.clear();
|
||||||
data.append(&mut out_bio.get_buf().to_vec());
|
data.extend_from_slice(out_bio.get_buf());
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use x509::X509;
|
|
||||||
use x509::store::X509StoreBuilder;
|
|
||||||
use symm::Cipher;
|
|
||||||
use pkcs7::{Pkcs7, Pkcs7Flags};
|
use pkcs7::{Pkcs7, Pkcs7Flags};
|
||||||
use pkey::PKey;
|
use pkey::PKey;
|
||||||
use stack::Stack;
|
use stack::Stack;
|
||||||
|
use symm::Cipher;
|
||||||
|
use x509::store::X509StoreBuilder;
|
||||||
|
use x509::X509;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn encrypt_decrypt_test() {
|
fn encrypt_decrypt_test() {
|
||||||
|
|
@ -280,13 +277,18 @@ mod tests {
|
||||||
let pkey = include_bytes!("../test/key.pem");
|
let pkey = include_bytes!("../test/key.pem");
|
||||||
let pkey = PKey::private_key_from_pem(pkey).unwrap();
|
let pkey = PKey::private_key_from_pem(pkey).unwrap();
|
||||||
|
|
||||||
let pkcs7 = Pkcs7::encrypt(&certs, message.as_bytes(), cypher, flags).expect("should succeed");
|
let pkcs7 =
|
||||||
|
Pkcs7::encrypt(&certs, message.as_bytes(), cypher, flags).expect("should succeed");
|
||||||
|
|
||||||
let encrypted = pkcs7.to_smime(message.as_bytes(), flags).expect("should succeed");
|
let encrypted = pkcs7
|
||||||
|
.to_smime(message.as_bytes(), flags)
|
||||||
|
.expect("should succeed");
|
||||||
|
|
||||||
let (pkcs7_decoded, _) = Pkcs7::from_smime(encrypted.as_slice()).expect("should succeed");
|
let (pkcs7_decoded, _) = Pkcs7::from_smime(encrypted.as_slice()).expect("should succeed");
|
||||||
|
|
||||||
let decoded = pkcs7_decoded.decrypt(&pkey, &cert).expect("should succeed");
|
let decoded = pkcs7_decoded
|
||||||
|
.decrypt(&pkey, &cert, Pkcs7Flags::empty())
|
||||||
|
.expect("should succeed");
|
||||||
|
|
||||||
assert_eq!(decoded, message.into_bytes());
|
assert_eq!(decoded, message.into_bytes());
|
||||||
}
|
}
|
||||||
|
|
@ -308,18 +310,31 @@ mod tests {
|
||||||
|
|
||||||
let store = store_builder.build();
|
let store = store_builder.build();
|
||||||
|
|
||||||
let pkcs7 = Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed");
|
let pkcs7 =
|
||||||
|
Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed");
|
||||||
|
|
||||||
let signed = pkcs7.to_smime(message.as_bytes(), flags).expect("should succeed");
|
let signed = pkcs7
|
||||||
|
.to_smime(message.as_bytes(), flags)
|
||||||
|
.expect("should succeed");
|
||||||
println!("{:?}", String::from_utf8(signed.clone()).unwrap());
|
println!("{:?}", String::from_utf8(signed.clone()).unwrap());
|
||||||
let (pkcs7_decoded, content) = Pkcs7::from_smime(signed.as_slice()).expect("should succeed");
|
let (pkcs7_decoded, content) =
|
||||||
|
Pkcs7::from_smime(signed.as_slice()).expect("should succeed");
|
||||||
|
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
pkcs7_decoded.verify(&certs, &store, Some(message.as_bytes()), Some(&mut output), flags)
|
pkcs7_decoded
|
||||||
.expect("should succeed");
|
.verify(
|
||||||
|
&certs,
|
||||||
|
&store,
|
||||||
|
Some(message.as_bytes()),
|
||||||
|
Some(&mut output),
|
||||||
|
flags,
|
||||||
|
).expect("should succeed");
|
||||||
|
|
||||||
assert_eq!(message.clone().into_bytes(), output);
|
assert_eq!(message.clone().into_bytes(), output);
|
||||||
assert_eq!(message.clone().into_bytes(), content.expect("should be non-empty"));
|
assert_eq!(
|
||||||
|
message.clone().into_bytes(),
|
||||||
|
content.expect("should be non-empty")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -339,14 +354,20 @@ mod tests {
|
||||||
|
|
||||||
let store = store_builder.build();
|
let store = store_builder.build();
|
||||||
|
|
||||||
let pkcs7 = Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed");
|
let pkcs7 =
|
||||||
|
Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed");
|
||||||
|
|
||||||
let signed = pkcs7.to_smime(message.as_bytes(), flags).expect("should succeed");
|
let signed = pkcs7
|
||||||
|
.to_smime(message.as_bytes(), flags)
|
||||||
|
.expect("should succeed");
|
||||||
|
|
||||||
let (pkcs7_decoded, content) = Pkcs7::from_smime(signed.as_slice()).expect("should succeed");
|
let (pkcs7_decoded, content) =
|
||||||
|
Pkcs7::from_smime(signed.as_slice()).expect("should succeed");
|
||||||
|
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
pkcs7_decoded.verify(&certs, &store, None, Some(&mut output), flags).expect("should succeed");
|
pkcs7_decoded
|
||||||
|
.verify(&certs, &store, None, Some(&mut output), flags)
|
||||||
|
.expect("should succeed");
|
||||||
|
|
||||||
assert_eq!(message.clone().into_bytes(), output);
|
assert_eq!(message.clone().into_bytes(), output);
|
||||||
assert!(content.is_none());
|
assert!(content.is_none());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue