Hello,
I would like to be able to verify evolution's mutltipart/signed messages via scripts on my server. I'm having trouble figuring out the details though. I've read RFC 2015, which covers this the format of pgp-signatures and I have the source for evolution 0.99.2. Has someone else done this already? Illustrative of my area of ignorence is the fact that I can't verify the evolution's signatures "by hand"---that is, by slicing the mail message file by hand, saving the seperate parts and running gpg --verify on them. I've tried converting linefeeds from <LF> to <CR><LF> as mentioned in the RFC. Also, I can create and verify my own signed files using gpg and verify them without problem. I've included a short python script that I'm working on to do the job in case someone can see from it what I'm doing wrong when splitting the body from the signature. Thanks in advance, -chris
#!/usr/bin/env python
# A script to verify the email of type multipart signed
# passed in from stdin
# Want to handle pgp signatures attached to messages from evolution
# (cf. RFC 2015, application/pgp-signature)
from pprint import pprint
import sys, re, mimetools, cStringIO, multifile
# (1) read in entire message for safekeeping and then turn back into
# file object with cStringIO
inputbuf =sys.stdin.read()
strfp = cStringIO.StringIO(inputbuf)
# use mimetools to parse mime headers
msg = mimetools.Message(strfp)
email_type = msg.getmaintype()
if email_type == 'multipart' and msg.getsubtype()=='signed':
sys.stdout.write("This is a multipart/signed message. Let get busy\n")
# plist = msg.getplist()
# pprint(plist)
# assume that it's protocol is correct for now
boundary = msg.getparam('boundary')
# print "boundary is %s" % boundary
# now split message at boundaries
mfile = multifile.MultiFile(strfp)
mfile.push(msg.getparam("boundary"))
while mfile.next():
submsg = mimetools.Message(mfile)
try:
data = cStringIO.StringIO()
mimetools.decode(mfile, data, submsg.getencoding())
except ValueError:
continue
if submsg.gettype() == 'application/pgp-signature':
print "This is the signature: "
sys.stdout.write(data.getvalue() )
open("/tmp/body.asc", "wb").write(data.getvalue())
else:
print "This is part of the body"
sys.stdout.write(data.getvalue() )
open("/tmp/body.decoded", "wb").write(data.getvalue() )
mfile.seek(0)
open("/home/clee/body", "wb").write(mfile.read())
mfile.pop()
else:
sys.stdout.write("Not a multipart/signed message\n")
sys.stdout.write("The actual mime type is:\n")
sys.stdout.write("getmaintype(): %s\n" % msg.getmaintype())
sys.stdout.write("getsubtype(): %s\n" % msg.getsubtype())
sys.stdout.write("getplist(): %s\n" % msg.getplist())
# [From RFC 2015]
#
# When the PGP digital signature is generated:
# (1) The data to be signed must first be converted to its type/subtype
# specific canonical form. For text/plain, this means conversion to an
# appropriate character set and conversion of line endings to the
# canonical <CR><LF> sequence.
# (2) An appropriate Content-Transfer-Encoding is then applied. Each line of
# the encoded data MUST end with the canonical <CR><LF> sequence.
# (3) MIME content headers are then added to the body, each ending with the
# canonical <CR><LF> sequence.
# (4) As described in [1], the digital signature MUST be calculated over both
# the data to be signed and its set of content headers.
# (5) The signature MUST be generated detached from the signed data so that
# the process does not alter the signed data in any way.
msg03548/pgp00000.pgp
Description: PGP signature
