ca_cert = cert if message.partner.signature_key.ca_cert: ca_cert = str(message.partner.signature_key.ca_cert.path) verify_cert = message.partner.signature_key.verify_cert ### Extract the base64 encoded signature for part in payload.walk(): if part.get_content_type() == "application/pkcs7-signature": try: raw_sig = part.get_payload().encode('ascii').strip() except Exception,e: raw_sig = part.get_payload().encode('base64').strip() else: payload = part ### Verify message using complete raw payload received from partner try: as2utils.verify_payload(as2utils.canonicalize2(payload),raw_sig,cert,ca_cert,verify_cert) except Exception, e: ### Verify message using extracted signature and stripped message try: as2utils.verify_payload(as2utils.extractpayload_fromstring1(raw_payload,main_boundary),raw_sig,cert,ca_cert,verify_cert) except Exception, e: ### Verify message using extracted signature and message without extra trailing new line try: as2utils.verify_payload(as2utils.extractpayload_fromstring2(raw_payload,main_boundary),raw_sig,cert,ca_cert,verify_cert) except Exception, e: raise as2utils.as2invalidsignature('Signature Verification Failed, exception message is %s'%str(e)) micContent = as2utils.canonicalize2(payload) #micContent = as2utils.extractpayload_fromstring2(raw_payload,main_boundary) if payload.get_content_type() == 'application/pkcs7-mime' and payload.get_param('smime-type') == 'compressed-data': models.Log.objects.create(message=message, status='S', text=_(u'Decompressing the payload')) message.compressed = True
def save_message(message, payload, raw_payload): """ Function decompresses, decrypts and verifies the received AS2 message Takes an AS2 message as input and returns the actual payload ex. X12 message """ try: # Initialize variables mic_content = None mic_alg = None filename = payload.get_filename() # Search for the organization adn partner, raise error if none exists. models.Log.objects.create( message=message, status='S', text=_(u'Begin Processing of received AS2 message')) if not models.Organization.objects.filter( as2_name=as2utils.unescape_as2name(payload.get( 'as2-to'))).exists(): raise as2utils.As2PartnerNotFound( 'Unknown AS2 organization with id %s' % payload.get('as2-to')) message.organization = models.Organization.objects.get( as2_name=as2utils.unescape_as2name(payload.get('as2-to'))) if not models.Partner.objects.filter( as2_name=as2utils.unescape_as2name(payload.get( 'as2-from'))).exists(): raise as2utils.As2PartnerNotFound( 'Unknown AS2 Trading partner with id %s' % payload.get('as2-from')) message.partner = models.Partner.objects.get( as2_name=as2utils.unescape_as2name(payload.get('as2-from'))) models.Log.objects.create( message=message, status='S', text=_(u'Message is for Organization "%s" from partner "%s"' % (message.organization, message.partner))) # Check if message from this partner are expected to be encrypted if message.partner.encryption and payload.get_content_type( ) != 'application/pkcs7-mime': raise as2utils.As2InsufficientSecurity( u'Incoming messages from AS2 partner {0:s} are defined to be encrypted' .format(message.partner.as2_name)) # Check if payload is encrypted and if so decrypt it if payload.get_content_type() == 'application/pkcs7-mime' \ and payload.get_param('smime-type') == 'enveloped-data': models.Log.objects.create( message=message, status='S', text=_( u'Decrypting the payload using private key {0:s}'.format( message.organization.encryption_key))) message.encrypted = True # Check if encrypted data is base64 encoded, if not then encode try: payload.get_payload().encode('ascii') except UnicodeDecodeError: payload.set_payload(payload.get_payload().encode('base64')) # Decrypt the base64 encoded data using the partners public key pyas2init.logger.debug(u'Decrypting the payload :\n{0:s}'.format( payload.get_payload())) try: decrypted_content = as2utils.decrypt_payload( as2utils.mimetostring(payload, 78), str(message.organization.encryption_key.certificate.path), str(message.organization.encryption_key. certificate_passphrase)) raw_payload = decrypted_content payload = email.message_from_string(decrypted_content) # Check if decrypted content is the actual content i.e. no compression and no signatures if payload.get_content_type() == 'text/plain': payload = email.Message.Message() payload.set_payload(decrypted_content) payload.set_type('application/edi-consent') if filename: payload.add_header('Content-Disposition', 'attachment', filename=filename) except Exception, msg: raise as2utils.As2DecryptionFailed( 'Failed to decrypt message, exception message is %s' % msg) # Check if message from this partner are expected to be signed if message.partner.signature and payload.get_content_type( ) != 'multipart/signed': raise as2utils.As2InsufficientSecurity( u'Incoming messages from AS2 partner {0:s} are defined to be signed' .format(message.partner.as2_name)) # Check if message is signed and if so verify it if payload.get_content_type() == 'multipart/signed': if not message.partner.signature_key: raise as2utils.As2InsufficientSecurity( 'Partner has no signature verification key defined') models.Log.objects.create( message=message, status='S', text=_( u'Message is signed, Verifying it using public key {0:s}'. format(message.partner.signature_key))) pyas2init.logger.debug( 'Verifying the signed payload:\n{0:s}'.format( payload.as_string())) message.signed = True mic_alg = payload.get_param('micalg').lower() or 'sha1' # Get the partners public and ca certificates cert = str(message.partner.signature_key.certificate.path) ca_cert = cert if message.partner.signature_key.ca_cert: ca_cert = str(message.partner.signature_key.ca_cert.path) verify_cert = message.partner.signature_key.verify_cert # Extract the signature and signed content from the mime message main_boundary = '--' + payload.get_boundary() for part in payload.walk(): if part.get_content_type() in [ "application/pkcs7-signature", "application/x-pkcs7-signature" ]: __, raw_sig = as2utils.check_binary_sig( part, main_boundary, raw_payload) else: payload = part # Verify message using raw payload received from partner try: as2utils.verify_payload(raw_payload, None, cert, ca_cert, verify_cert) except Exception: # Verify message using extracted signature and canonicalzed message try: as2utils.verify_payload(as2utils.canonicalize2(payload), raw_sig, cert, ca_cert, verify_cert) except Exception, e: raise as2utils.As2InvalidSignature( 'Signature Verification Failed, exception message is {0:s}' .format(e)) mic_content = as2utils.canonicalize2(payload)
def save_message(message, payload, raw_payload): """ Function decompresses, decrypts and verifies the received AS2 message Takes an AS2 message as input and returns the actual payload ex. X12 message """ try: # Initialize variables mic_content = None mic_alg = None filename = payload.get_filename() # Search for the organization adn partner, raise error if none exists. models.Log.objects.create(message=message, status='S', text=_(u'Begin Processing of received AS2 message')) if not models.Organization.objects.filter(as2_name=as2utils.unescape_as2name(payload.get('as2-to'))).exists(): raise as2utils.As2PartnerNotFound('Unknown AS2 organization with id %s' % payload.get('as2-to')) message.organization = models.Organization.objects.get( as2_name=as2utils.unescape_as2name(payload.get('as2-to'))) if not models.Partner.objects.filter(as2_name=as2utils.unescape_as2name(payload.get('as2-from'))).exists(): raise as2utils.As2PartnerNotFound('Unknown AS2 Trading partner with id %s' % payload.get('as2-from')) message.partner = models.Partner.objects.get(as2_name=as2utils.unescape_as2name(payload.get('as2-from'))) models.Log.objects.create( message=message, status='S', text=_(u'Message is for Organization "%s" from partner "%s"' % (message.organization, message.partner)) ) # Check if message from this partner are expected to be encrypted if message.partner.encryption and payload.get_content_type() != 'application/pkcs7-mime': raise as2utils.As2InsufficientSecurity( u'Incoming messages from AS2 partner {0:s} are defined to be encrypted'.format( message.partner.as2_name)) # Check if payload is encrypted and if so decrypt it if payload.get_content_type() == 'application/pkcs7-mime' \ and payload.get_param('smime-type') == 'enveloped-data': models.Log.objects.create(message=message, status='S', text=_( u'Decrypting the payload using private key {0:s}'.format(message.organization.encryption_key))) message.encrypted = True # Check if encrypted data is base64 encoded, if not then encode try: payload.get_payload().encode('ascii') except UnicodeDecodeError: payload.set_payload(payload.get_payload().encode('base64')) # Decrypt the base64 encoded data using the partners public key pyas2init.logger.debug(u'Decrypting the payload :\n{0:s}'.format(payload.get_payload())) try: decrypted_content = as2utils.decrypt_payload( as2utils.mimetostring(payload, 78), str(message.organization.encryption_key.certificate.path), str(message.organization.encryption_key.certificate_passphrase) ) raw_payload = decrypted_content payload = email.message_from_string(decrypted_content) # Check if decrypted content is the actual content i.e. no compression and no signatures if payload.get_content_type() == 'text/plain': payload = email.Message.Message() payload.set_payload(decrypted_content) payload.set_type('application/edi-consent') if filename: payload.add_header('Content-Disposition', 'attachment', filename=filename) except Exception, msg: raise as2utils.As2DecryptionFailed('Failed to decrypt message, exception message is %s' % msg) # Check if message from this partner are expected to be signed if message.partner.signature and payload.get_content_type() != 'multipart/signed': raise as2utils.As2InsufficientSecurity( u'Incoming messages from AS2 partner {0:s} are defined to be signed'.format(message.partner.as2_name)) # Check if message is signed and if so verify it if payload.get_content_type() == 'multipart/signed': if not message.partner.signature_key: raise as2utils.As2InsufficientSecurity('Partner has no signature verification key defined') models.Log.objects.create(message=message, status='S', text=_( u'Message is signed, Verifying it using public key {0:s}'.format(message.partner.signature_key))) pyas2init.logger.debug('Verifying the signed payload:\n{0:s}'.format(payload.as_string())) message.signed = True mic_alg = payload.get_param('micalg').lower() or 'sha1' # Get the partners public and ca certificates cert = str(message.partner.signature_key.certificate.path) ca_cert = cert if message.partner.signature_key.ca_cert: ca_cert = str(message.partner.signature_key.ca_cert.path) verify_cert = message.partner.signature_key.verify_cert # Extract the signature and signed content from the mime message main_boundary = '--' + payload.get_boundary() for part in payload.walk(): if part.get_content_type() == "application/pkcs7-signature": __, raw_sig = as2utils.check_binary_sig(part, main_boundary, raw_payload) else: payload = part # Verify message using raw payload received from partner try: as2utils.verify_payload(raw_payload, None, cert, ca_cert, verify_cert) except Exception: # Verify message using extracted signature and canonicalzed message try: as2utils.verify_payload(as2utils.canonicalize2(payload), raw_sig, cert, ca_cert, verify_cert) except Exception, e: raise as2utils.As2InvalidSignature( 'Signature Verification Failed, exception message is {0:s}'.format(e)) mic_content = as2utils.canonicalize2(payload)