pgp: perform gpgme's sign+encrypt manually

gpgme's sign and encrypt API doesn't seem to work properly; it only
encrypts for some reason. Do it manually which according to RFC 3156 -
MIME Security with OpenPGP is to sign first then encrypt the whole
thing.

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/494/head
Manos Pitsidianakis 4 weeks ago
parent e032acfab7
commit 593ed22ba1
No known key found for this signature in database
GPG Key ID: 7729C7707F7E09D0

@ -33,7 +33,6 @@ use melib::{
},
error::*,
gpgme::*,
log,
parser::BytesExt,
};
@ -199,13 +198,33 @@ pub fn encrypt_filter(
}
}
}
let a: Attachment = a.into();
log::trace!(
"main attachment is {:?} sign_keys = {:?} encrypt_keys = {:?}",
&a,
&sign_keys,
&encrypt_keys
);
let a: Attachment = if let Some(sign_keys) = sign_keys {
let a: Attachment = a.into();
let mut ctx = Context::new()?;
let data = ctx.new_data_mem(&melib_pgp::convert_attachment_to_rfc_spec(
a.into_raw().as_bytes(),
))?;
let sig_attachment = Attachment::new(
ContentType::PGPSignature,
Default::default(),
ctx.sign(sign_keys, data)?.await?,
);
let a: AttachmentBuilder = a.into();
let parts = vec![a, sig_attachment.into()];
let boundary = ContentType::make_boundary(&parts);
Attachment::new(
ContentType::Multipart {
boundary: boundary.into_bytes(),
kind: MultipartType::Signed,
parts: parts.into_iter().map(|a| a.into()).collect::<Vec<_>>(),
parameters: vec![],
},
Default::default(),
vec![],
)
} else {
a.into()
};
let mut ctx = Context::new()?;
let data = ctx.new_data_mem(a.into_raw().as_bytes())?;
@ -216,7 +235,7 @@ pub fn encrypt_filter(
parameters: vec![],
},
Default::default(),
ctx.encrypt(sign_keys, encrypt_keys, data)?.await?,
ctx.encrypt(encrypt_keys, data)?.await?,
);
a.content_disposition =
ContentDisposition::from(br#"attachment; filename="msg.asc""#);

@ -961,7 +961,6 @@ impl Context {
pub fn encrypt(
&mut self,
sign_keys: Option<Vec<Key>>,
encrypt_keys: Vec<Key>,
mut plain: Data,
) -> Result<impl Future<Output = Result<Vec<u8>>> + Send> {
@ -974,26 +973,6 @@ impl Context {
call!(&self.inner.lib, gpgme_signers_clear)(self.inner.ptr.as_ptr());
}
let also_sign: bool = if let Some(keys) = sign_keys {
if keys.is_empty() {
false
} else {
for k in keys {
unsafe {
gpgme_error_try(
&self.inner.lib,
call!(&self.inner.lib, gpgme_signers_add)(
self.inner.ptr.as_ptr(),
k.inner.ptr.as_ptr(),
),
)?;
}
}
true
}
} else {
false
};
let mut cipher: gpgme_data_t = std::ptr::null_mut();
let mut raw_keys: Vec<gpgme_key_t> = Vec::with_capacity(encrypt_keys.len() + 1);
raw_keys.extend(encrypt_keys.iter().map(|k| k.inner.ptr.as_ptr()));
@ -1006,27 +985,15 @@ impl Context {
)?;
if let Err(mut err) = gpgme_error_try(
&self.inner.lib,
if also_sign {
call!(&self.inner.lib, gpgme_op_encrypt_sign_start)(
self.inner.ptr.as_ptr(),
raw_keys.as_mut_slice().as_mut_ptr(),
gpgme_encrypt_flags_t_GPGME_ENCRYPT_NO_ENCRYPT_TO
| gpgme_encrypt_flags_t_GPGME_ENCRYPT_NO_COMPRESS
| gpgme_encrypt_flags_t_GPGME_ENCRYPT_ALWAYS_TRUST,
plain.inner.as_mut(),
cipher,
)
} else {
call!(&self.inner.lib, gpgme_op_encrypt_start)(
self.inner.ptr.as_ptr(),
raw_keys.as_mut_slice().as_mut_ptr(),
gpgme_encrypt_flags_t_GPGME_ENCRYPT_NO_ENCRYPT_TO
| gpgme_encrypt_flags_t_GPGME_ENCRYPT_NO_COMPRESS
| gpgme_encrypt_flags_t_GPGME_ENCRYPT_ALWAYS_TRUST,
plain.inner.as_mut(),
cipher,
)
},
call!(&self.inner.lib, gpgme_op_encrypt_start)(
self.inner.ptr.as_ptr(),
raw_keys.as_mut_slice().as_mut_ptr(),
gpgme_encrypt_flags_t_GPGME_ENCRYPT_NO_ENCRYPT_TO
| gpgme_encrypt_flags_t_GPGME_ENCRYPT_NO_COMPRESS
| gpgme_encrypt_flags_t_GPGME_ENCRYPT_ALWAYS_TRUST,
plain.inner.as_mut(),
cipher,
),
) {
let result =
call!(&self.inner.lib, gpgme_op_encrypt_result)(self.inner.ptr.as_ptr());

Loading…
Cancel
Save