def get_encrypted_message(self, message): """Get the encrypted message from the passed payload message. Parameters ---------- message : MIMEBase The message to encrypt (e.g. as created by :py:func:`get_octed_stream`. """ control = self.get_control_message() msg = MIMEMultipart(_subtype='encrypted', _subparts=[control, message]) msg.set_param('protocol', 'application/pgp-encrypted') return msg
def get_signed_message(self, message, signature): """Get a signed MIME message from the passed message and signature messages. Parameters ---------- message : MIMEBase MIME message that is signed by the signature. signature : MIMEBase MIME message containing the signature. """ msg = MIMEMultipart(_subtype='signed', _subparts=[message, signature]) msg.set_param('protocol', 'application/pgp-signature') msg.set_param('micalg', 'pgp-sha256') # TODO: Just the current default return msg
def rfc3156(message, recipients=None, signers=None, context=None, always_trust=False): """ Parameters ---------- message : :py:class:`email.mime.base.MIMEBase` or str context : :py:class:`pygpgme.Context`, optional If not set, a new object with default parameters will be created. always_trust : bool, optional If ``True``, always trust recipient keys. """ if (not signers and not recipients) or context and context.signers: raise ValueError("No signers or recipients given.") if isinstance(message, six.string_types): message = MIMEText(message + '\n\n') del message['MIME-Version'] if recipients is None: recipients = [] elif isinstance(recipients, six.string_types): recipients = [recipients] if signers is None: signers = [] elif isinstance(signers, six.string_types): signers = [signers] if context is None: context = gpgme.Context() context.armor = True # signers/recpiients may either be a string or a key from the context signers = [(context.get_key(k) if isinstance(k, six.string_types) else k) for k in signers] recipients = [context.get_key(k) if isinstance(k, six.string_types) else k for k in recipients] if signers: context.signers = signers input_bytes = six.BytesIO(message.as_bytes()) output_bytes = six.BytesIO() if recipients: # we have recipients, so we encrypt # compute flags passed to encrypt/encrypt_sign flags = 0 if always_trust is True: flags |= gpgme.ENCRYPT_ALWAYS_TRUST # sign message if context.signers: context.encrypt_sign(recipients, flags, input_bytes, output_bytes) else: context.encrypt(recipients, flags, input_bytes, output_bytes) output_bytes.seek(0) # the control message control_msg = MIMEApplication(_data='Version: 1\n', _subtype='pgp-encrypted', _encoder=encode_noop) control_msg.add_header('Content-Description', 'PGP/MIME version identification') del control_msg['MIME-Version'] encrypted = MIMEApplication(_data=output_bytes.getvalue(), _subtype='octed-stream', name='encrypted.asc', _encoder=encode_noop) encrypted.add_header('Content-Description', 'OpenPGP encrypted message') encrypted.add_header('Content-Disposition', 'inline; filename="encrypted.asc"') del encrypted['MIME-Version'] msg = MIMEMultipart(_subtype='pgp-encrypted', _subparts=[control_msg, encrypted]) msg.set_param('protocol', 'application/pgp-encrypted') return msg else: # just signing del message['MIME-Version'] for payload in message.get_payload(): if isinstance(payload, MIMEBase): del payload['MIME-Version'] message.policy = message.policy.clone(max_line_length=0) to_sign = message.as_bytes().replace(b'\n', b'\r\n') context.sign(six.BytesIO(to_sign), output_bytes, gpgme.SIG_MODE_DETACH) output_bytes.seek(0) signature = output_bytes.getvalue() sig = MIMEBase(_maintype='application', _subtype='pgp-signature', name='signature.asc') sig.set_payload(signature.decode('utf-8')) sig.add_header('Content-Description', 'OpenPGP digital signature') sig.add_header('Content-Disposition', 'attachment; filename="signature.asc"') del sig['MIME-Version'] del sig['Content-Transfer-Encoding'] msg = MIMEMultipart(_subtype='signed', _subparts=[message, sig]) msg.set_param('protocol', 'application/pgp-signature') del msg['MIME-Version'] return msg