Beispiel #1
0
     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
Beispiel #2
0
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)
Beispiel #3
0
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)