What I am trying to achieve:
send a signed, unencrypted email using a smart card token through a Python script
What I've tried so far:
Have a look on an incoming email signed with same corporate smart card system. It is a multipart email with an attached signature headers like the following:
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"
Sign a text piece using PyKCS11, that is, for a text string and smart card pin code provided the function returns some bytecode.
Study a S/MIME example from M2Crypto though it's PCKS7 where I find code like the following:
s = SMIME.SMIME()
s.load_key('signer_key.pem', 'signer.pem')
p7 = s.sign(buf, SMIME.PKCS7_DETACHED)
..
s.write(out, p7, buf)
What I see so far is:
SMIME implementation I've found works with PKCS7 object (p7 is not a string as I thought initially);
Signed emails contain x-pkcs7-signature
Does this mean, the data I get from the PyKCS11 module in this case is not some sort of "pkcs11" signature and I have just to wrap it up as a PCKS7 object either override the SMIME.write() method?
Or, the whole setup might be a wrong way?
Related
Executive summary: I can construct a multipart message which contains HTML in two separate parts, and it displays correctly in multiple MUAs. However, outlook.com insists on putting any additional HTML after the first HTML part in a downloadable attachment, instead of displaying it. It also does this for plaintext parts.
In detail: I need to add a signature to an email message, where the structure of the original message is, in general, unknown. I do this by wrapping the original message in a multipart/mixed, and then adding a new multipart/alternative which contains text and html versions of the required signature.
If the original message was itself a multipart/alternative, then the new message now looks like:
multipart/mixed
multipart/alternative [the original message]
text/plain
text/html
multipart/alternative [the appended signature]
text/plain [plaintext signature]
text/html [html signature]
This displays well in various clients (Thunderbird, and webmail from gmail/Yahoo/AOL/gmx), showing the original message with the appended signature. However, it doesn't work for MS clients (I've only tried outlook.com). The two alternative signatures are presented to the user as attachments, and not inline, so the user only sees download boxes.
To get around this, I've historically done this for Microsoft:
multipart/mixed
multipart/alternative [the original message]
text/plain
text/html
text/html [html-only signature]
This worked for several years for Microsoft, but has now stopped working - the signature is again shown as an attachment.
I've spent some hours experimenting with this, and can't find any way to get outlook.com to show two different HMTL (or even plain) text parts in the same message. The second one always appears as an attachment. Some of the things I've tried are:
Replace the second multipart-alternative above with another multipart/mixed, which encloses the multipart-alternative signature
Trying to force Content-Disposition: inline for the signature: this never works, and MS appears to ignore Content-Disposition
Replace the outer multipart/mixed with multipart-related, with type=multipart/alternative
Any ideas on how I can get MS clients to actually show the signature, short of parsing the internals of the original message and re-writing it?
I fetched emails from gmail server using pop3 with enough_email package. Everything works as expected until I updated the flow like fetch emails which is encrypted by PGP encryption. I already achieved the decryption part of email using OpenPGP package which gives String in this form
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="000000000000da67ad05d5c5dfba"
--000000000000da67ad05d5c5dfba
Content-Type: text/plain; charset="UTF-8"
test 3
--000000000000da67ad05d5c5dfba
Content-Type: text/html; charset="UTF-8"
<div dir="ltr">test 3</div>
--000000000000da67ad05d5c5dfba--
now I am trying to create mimeMessage object from the string so I can parse it using decodeTextPlainPart function. Already tried to create mimeMessage object by using MimeMessage.parseFromText function but it's not working as expected, when ever I try to get plain text using decodeTextPlainPart function from my created mimeMessage object it returns the same thing which I provided to MimeMessage.parseFromText function.
Did I miss something or followed the wrong approach?
OpenPGP.decrypt function return string with \n as line separator but MimeMessage.parseFromText works with \r\n, when I replace all \n with \r\n in string then try to create mimeMessage object from the string I get the expected result.
When sending emails using the Gmail API, it places hard line breaks in the body at around 78 characters per line. A similar question about this can be found here.
How can I make this stop? I simply want to send plaintext emails through the API without line breaks. The current formatting looks terrible, especially on mobile clients (tested on Gmail and iOS Mail apps).
I've tried the following headers:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Am I missing anything?
EDIT: As per Mr.Rebot's suggestion, I've also tried this with no luck:
Content-Type: mixed/alternative
EDIT 2: Here's the exact format of the message I'm sending (attempted with and without the quoted-printable header:
From: Example Account <example1#example.com>
To: <example2#example.com>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Subject: This is a test!
Date: Tue, 18 Oct 2016 10:46:57 -GMT-07:00
Here is a long test message that will probably cause some words to wrap in strange places.
I take this full message and Base64-encode it, then POST it to /gmail/v1/users/{my_account}/drafts/send?fields=id with the following JSON body:
{
"id": MSG_ID,
"message": {
"raw": BASE64_DATA
}
}
Are you running the content through a quoted printable encoder and sending the encoded content value along with the header or expecting the API to encode it for you?
Per wikipedia it seems like if you add soft line breaks with = less than 76 characters apart as the last character on arbitrary lines, they should get decoded out of the result restoring your original text.
UPDATE
Try sending with this content whose message has been quoted-printable encoded (base64 it):
From: Example Account <example1#example.com>
To: <example2#example.com>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Subject: This is a test!
Date: Tue, 18 Oct 2016 10:46:57 -GMT-07:00
Here is a long test message that will probably cause some words to wrap in =
strange places.
I'm assuming you have a function similar to this:
1. def create_message(sender, to, cc, subject, message_body):
2. message = MIMEText(message_body, 'html')
3. message['to'] = to
4. message['from'] = sender
5. message['subject'] = subject
6. message['cc'] = cc
7. return {'raw': base64.urlsafe_b64encode(message.as_string())}
The one trick that finally worked for me, after all the attempts to modify the header values and payload dict (which is a member of the message object), was to set (line 2):
message = MIMEText(message_body, 'html') <-- add the 'html' as the second parameter of the MIMEText object constructor
The default code supplied by Google for their gmail API only tells you how to send plain text emails, but they hide how they're doing that.
ala...
message = MIMEText(message_body)
I had to look up the python class email.mime.text.MIMEText object.
That's where you'll see this definition of the constructor for the MIMEText object:
class email.mime.text.MIMEText(_text[, _subtype[, _charset]])
We want to explicitly pass it a value to the _subtype. In this case, we want to pass: 'html' as the _subtype.
Now, you won't have anymore unexpected word wrapping applied to your messages by Google, or the Python mime.text.MIMEText object
This exact issue made me crazy for a good couple of hours, and no solution I could find made any difference.
So if anyone else ends up frustrated here, I'd thought I'd just post my "solution".
Turn your text (what's going to be the body of the email) into simple HTML. I wrapped every paragraph in a simple <p>, and added line-breaks (<br>) where needed (e.g. my signature).
Then, per Andrew's answer, I attached the message body as MIMEText(message_text, _subtype="html"). The plain-text is still not correct AFAIK, but it works and I don't think there's a single actively used email-client out there that doesn't render HTML anymore.
I'm working on the soap client and have a problem with reading (and decryption) of the response attachment. The attachment is included into the the response using MTOM mechanism and encrypted via AES128-CBC algorithm (the secret key is included to the response xml header).
Here is the basic structure of the response:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope>
.. the xml data that includes the secret key for the attachment
decryption usign AES algorithm.
</soapenv:Envelope>
--MIMEBoundaryurn_uuid_174A74CB7221A5AF451426570004765
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-ID: <urn:uuid:174A74CB7221A5AF451426570004768#apache.org>
iQ�<]�+)B�ل�$O:���'�zT�F�x�����������}�t��݄��')#^��&�a�p}Q��¨גZ<G�%_"��|
Ps�<���'9��g](ǧ">�l��� ��XPrJ��jM�f�<$�)Q�*��
--MIMEBoundaryurn_uuid_174A74CB7221A5AF451426570004765--
MTOM mechanism implies that the attachment is sent as a binary string (without encoding to base64). As I suggest, this binary string is what must be decrypted via AES. But unfortunately it has the wrong length to apply the AES decryption - AES uses the 16 bytes blocks, so the cipher must be a multiple of 16. But it does not, for example in the example above the attachment length is 250.
Maybe I'm missing something and some kind of transformation must be applied to the attachment binary string before decrypting it?
P.S. The part of the response xml body is encrypted using the same algorithm (AES128-CBC), but is sent as a base64 cipher, which must be decoded to get the binary string and then decrypted. Which works fine. The decoded body cipher has the proper length - a multiple of 16 and it can be decrypted without any problems.
Thank you in advance for any thought or ideas!
Old, but from Oracle about half way down the page
Note: Streaming MTOM cannot be used in conjunction with message
encryption.
http://docs.oracle.com/cd/E14571_01/web.1111/e13734/mtom.htm#WSADV141
Just want a basic understand of what parts a email message may have.
I know there is a messageId, date, subject, from, cc, bcc, body, etc.
Specifically I want to know how attachments and images may be embedded in the email.
At this point I think there are 2, please correct me if I am wrong.
attachments
embedded attachments/images
is that correct?
The official answer for this question is contained in RFC5322 and some related RFC's. The Wikipedia entry for email does a pretty good job of referencing the RFC numbers. To get started with MIME see RFC2045.
Attachments are encoded as multipart similar to multipart file uploads. Basically the message has a header saying there is an attachment and sets a boundary ( random string of characters to announce the start of the attachment) The boundary says when the data of the attachment starts. I think the filename is set on the boundary as well (if i remember correctly). I am doing a bit of hand waving, but this is the basic idea.
so you get somthing like
To: ...
From: ...
Content-Type: Multpart...
Content-Boundry: ewafoiuasfjasdfoashiafhj
message here
--------- Content-boundry: ewafoiuasfjasdfoashiafhj
attachement here