Skip to content

Commit

Permalink
look for all signature types
Browse files Browse the repository at this point in the history
  • Loading branch information
abhishekram committed Apr 30, 2019
1 parent 0fcf070 commit 21e0f21
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Handle cases where compression is done before signing.
* Add support for additional encryption algorithms.
* Use binary encoding for encryption and signatures.
* Look for `application/x-pkcs7-signature` when verifying signatures.
* Remove support for Python 2.

## 1.0.3 - 2018-05-01
Expand Down
52 changes: 27 additions & 25 deletions pyas2lib/as2.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,11 +542,11 @@ def parse(self, raw_content, find_org_cb, find_partner_cb,

if self.payload.get_content_type() == 'application/pkcs7-mime' \
and self.payload.get_param('smime-type') == 'enveloped-data':
encrypted_data = self.payload.get_payload(decode=True)
# logger.debug(
# 'Decrypting the payload :\n%s' % self.payload.as_string())
logger.debug('Decrypting message %s payload :\n%s' % (
self.message_id, self.payload.as_string()))

self.encrypted = True
encrypted_data = self.payload.get_payload(decode=True)
self.enc_alg, decrypted_content = decrypt_message(
encrypted_data, self.receiver.decrypt_key)

Expand All @@ -568,14 +568,16 @@ def parse(self, raw_content, find_org_cb, find_partner_cb,
'but signed message not found.'.format(partner_id))

if self.payload.get_content_type() == 'multipart/signed':
# logger.debug(b'Verifying the signed payload:\n{0:s}'.format(
# self.payload.as_string()))
logger.debug('Verifying signed message %s payload: \n%s' % (
self.message_id, self.payload.as_string()))
self.signed = True

# Split the message into signature and signed message
signature = None
message_boundary = ('--' + self.payload.get_boundary()).\
encode('utf-8')
signature_types = ['application/pkcs7-signature',
'application/x-pkcs7-signature']
for part in self.payload.walk():
if part.get_content_type() == "application/pkcs7-signature":
if part.get_content_type() in signature_types:
signature = part.get_payload(decode=True)
else:
self.payload = part
Expand All @@ -584,14 +586,8 @@ def parse(self, raw_content, find_org_cb, find_partner_cb,
# then convert to canonical form and try again
mic_content = canonicalize(self.payload)
verify_cert = self.sender.load_verify_cert()
try:
self.digest_alg = verify_message(
mic_content, signature, verify_cert)
except IntegrityError:
mic_content = raw_content.split(message_boundary)[1].\
replace(b'\n', b'\r\n')
self.digest_alg = verify_message(
mic_content, signature, verify_cert)
self.digest_alg = verify_message(
mic_content, signature, verify_cert)

# Calculate the MIC Hash of the message to be verified
digest_func = hashlib.new(self.digest_alg)
Expand Down Expand Up @@ -753,8 +749,8 @@ def build(self, message, status, detailed_status=None):
encoders.encode_7or8bit(mdn_base)
self.payload.attach(mdn_base)

# logger.debug('MDN for message %s created:\n%s' % (
# message.message_id, mdn_base.as_string()))
logger.debug('MDN for message %s created:\n%s' % (
message.message_id, mdn_base.as_string()))

# Sign the MDN if it is requested by the sender
if message.headers.get('disposition-notification-options') and \
Expand All @@ -775,18 +771,20 @@ def build(self, message, status, detailed_status=None):
signature.add_header(
'Content-Disposition', 'attachment', filename='smime.p7s')
del signature['MIME-Version']

signature.set_payload(sign_message(
canonicalize(self.payload),
self.digest_alg,
message.receiver.sign_key
))
encoders.encode_base64(signature)
# logger.debug(
# 'Signature for MDN created:\n%s' % signature.as_string())

signed_mdn.set_param('micalg', self.digest_alg)
signed_mdn.attach(signature)

self.payload = signed_mdn
logger.debug('Signature for MDN %s created:\n%s' % (
message.message_id, signature.as_string()))

# Update the headers of the final payload and set message boundary
for k, v in mdn_headers.items():
Expand Down Expand Up @@ -838,11 +836,15 @@ def parse(self, raw_content, find_message_cb):
return status, detailed_status

if self.payload.get_content_type() == 'multipart/signed':
message_boundary = ('--' + self.payload.get_boundary()).\
encode('utf-8')

# Extract the signature and the signed payload
signature = None
message_boundary = (
'--' + self.payload.get_boundary()).encode('utf-8')
signature_types = ['application/pkcs7-signature',
'application/x-pkcs7-signature']
for part in self.payload.walk():
if part.get_content_type() == 'application/pkcs7-signature':
if part.get_content_type() in signature_types:
signature = part.get_payload(decode=True)
elif part.get_content_type() == 'multipart/report':
self.payload = part
Expand All @@ -861,8 +863,8 @@ def parse(self, raw_content, find_message_cb):

for part in self.payload.walk():
if part.get_content_type() == 'message/disposition-notification':
# logger.debug('Found MDN report for message %s:\n%s' % (
# orig_message.message_id, part.as_string()))
logger.debug('Found MDN report for message %s:\n%s' % (
orig_message.message_id, part.as_string()))

mdn = part.get_payload()[-1]
mdn_status = mdn['Disposition'].split(';').\
Expand Down

0 comments on commit 21e0f21

Please sign in to comment.