def _verify_signed_message(self, content_type): if content_type != 'multipart/signed': raise AS2MdnException('content-type invalid when signed required') mdn_signature_thumbprint = self.context.agreement.outbound_agreement.message_encryption_certificate.thumbprint mdn_signature_cert_path = self.context.agreement.outbound_agreement.message_encryption_certificate.local_file_path mdn_signature_cert_ca_path = self.context.agreement.outbound_agreement.message_encryption_certificate.local_ca_file_path mdn_signature_cert_verify = self.context.agreement.outbound_agreement.message_encryption_certificate.is_need_verify try: if is_none_or_whitespace(mdn_signature_cert_ca_path): mdn_signature_cert_ca_path = mdn_signature_cert_path f_mime_string = SMIMEHelper.format_with_cr_lf( SMIMEHelper.mime_to_string(self.mime_message)) SMIMEHelper.verify_signed_text(f_mime_string, mdn_signature_cert_path, mdn_signature_cert_ca_path, mdn_signature_cert_verify) self.context.trace( "mdn signature verify finished; thumbprint: {thumbprint}, verify certificate: {verify}", thumbprint=mdn_signature_thumbprint, verify=mdn_signature_cert_verify) except: logger.exception( "mdn signature verify failed; mdn-message-id: {id}".format( id=self.mdn_message_id)) raise AS2MdnException( "mdn signature verify failed; thumbprint: {thumbprint}, verify certificate: {verify}, due to: {message}", thumbprint=mdn_signature_thumbprint, verify=mdn_signature_cert_verify, message=sys.exc_info()[1])
def _verify_signature(self): if not self.is_signed: self.context.trace("verify signature ignored") return content_type = self.mime_message.get_content_type().lower() if content_type != 'multipart/signed': raise AS2VerifySignatureException('verify signature failed; content-type:{type} invalid', type=content_type) cert_thumbprint = self.context.agreement.inbound_agreement.message_verify_certificate.thumbprint cert_local_file_path = self.context.agreement.inbound_agreement.message_verify_certificate.local_file_path cert_ca_local_file_path = self.context.agreement.inbound_agreement.message_verify_certificate.local_ca_file_path cert_verify = self.context.agreement.inbound_agreement.message_verify_certificate.is_need_verify try: if is_none_or_whitespace(cert_ca_local_file_path): cert_ca_local_file_path = cert_local_file_path for part in self.mime_message.get_payload(): if not isinstance(part, email.message.Message): continue part_type = part.get_content_type().lower() part_encoding = part.get('Content-Transfer-Encoding', '').lower() if 'application/pkcs7-signature' == part_type and 'base64' != part_encoding: del part['Content-Transfer-Encoding'] email.encoders.encode_base64(part) self.context.trace('signature content transfer encoding to base64') f_mime_string = SMIMEHelper.format_with_cr_lf( SMIMEHelper.mime_to_string(self.mime_message)) SMIMEHelper.verify_signed_text( f_mime_string, cert_local_file_path, cert_ca_local_file_path, cert_verify) self.mic_algorithm = self.mime_message.get_param('micalg').lower() parts = [part for part in self.mime_message.walk() if part.get_content_type() not in ['multipart/signed', 'application/pkcs7-signature']] if len(parts) != 1: raise AS2VerifySignatureException( "verify signature failed; due to multiple part content in mime message") self.mime_message = parts[0] self.context.trace("verify signature finished; thumbprint: {thumbprint}, verify certificate: {verify}", thumbprint=cert_thumbprint, verify=cert_verify) except: logger.exception("verify signature failed; message-id: {id}".format(id=self.message_id)) raise AS2VerifySignatureException( "verify signature failed; thumbprint: {thumbprint}, verify certificate: {verify}, due to: {message}", thumbprint=cert_thumbprint, verify=cert_verify, message=sys.exc_info()[1])
def test_mime_to_string_public_cert_without_ca_des_ede3_cbc(self): crt_path = self.__get_cert_path('P1_public.cer') alg = "des_ede3_cbc" rst = SMIMEHelper.encrypt_to_mime(self.clearText, crt_path, alg) msg = SMIMEHelper.mime_to_string(rst, 0) assert_not_equal(None, msg) assert_equal(True, "MIME-Version" in msg)
def test_format_with_cr_lf_public_cert_without_ca_des_ede3_cbc(self): crt_path = self.__get_cert_path('P1_public.cer') alg = "des_ede3_cbc" rst = SMIMEHelper.encrypt_to_mime(self.clearText, crt_path, alg) msg = SMIMEHelper.mime_to_string(rst) f_msg = SMIMEHelper.format_with_cr_lf(msg) assert_not_equal(msg, f_msg) assert_equal(True, "\r\n" in f_msg)
def _signature(self): if not self.is_signed: self.context.trace("signature ignored") return cert_thumbprint = self.context.agreement.outbound_agreement.message_signature_certificate.thumbprint cert_local_file_path = self.context.agreement.outbound_agreement.message_signature_certificate.local_file_path cert_pass_phrase = self.context.agreement.outbound_agreement.message_signature_certificate.pass_phrase cert_signature_algorithm = self.context.agreement.outbound_agreement.message_signature_algorithm try: f_mime_string = SMIMEHelper.format_with_cr_lf( SMIMEHelper.mime_to_string(self.mime_message)) self.mic_content = f_mime_string self.mic_algorithm = self.context.agreement.outbound_agreement.message_signature_algorithm detached_signed_message = SMIMEHelper.sign_to_mime_detached( f_mime_string, cert_local_file_path, cert_pass_phrase, cert_signature_algorithm) signature = SMIMEHelper.get_signature_from_mime(detached_signed_message) if signature is None: raise Exception("signature is none from detached signed mime message") signed_mime_message = MIMEMultipart('signed', boundary=SMIMEHelper.get_random_boundary(), protocol="application/pkcs7-signature") del signed_mime_message['MIME-Version'] signed_mime_message.set_param('micalg', self.mic_algorithm) signed_mime_message.attach(self.mime_message) signed_mime_message.attach(signature) self.body = SMIMEHelper.format_with_cr_lf(SMIMEHelper.extract_payload(signed_mime_message)) self.mime_message = signed_mime_message self.context.trace("signature finished; thumbprint: {thumbprint}, algorithm: {algorithm}", thumbprint=cert_thumbprint, algorithm=cert_signature_algorithm) except: logger.exception("signature failed; message-id: {id}".format(id=self.message_id)) raise AS2SignatureException( "signature failed; thumbprint: {thumbprint}, algorithm: {algorithm}, due to: {message}", thumbprint=cert_thumbprint, algorithm=cert_signature_algorithm, message=sys.exc_info()[1])
def _decrypt(self): if not self.is_encrypted: self.context.trace("decrypt ignored") return content_type = self.mime_message.get_content_type().lower() s_mime_type = self.mime_message.get_param('smime-type') if content_type != 'application/pkcs7-mime': raise AS2DecryptException('decrypt failed; content-type:{type} invalid', type=content_type) if s_mime_type != 'enveloped-data': raise AS2DecryptException('decrypt failed; s/mime-type:{type} invalid', type=s_mime_type) cert_thumbprint = self.context.agreement.inbound_agreement.message_decrypt_certificate.thumbprint cert_local_file_path = self.context.agreement.inbound_agreement.message_decrypt_certificate.local_file_path cert_pass_phrase = self.context.agreement.inbound_agreement.message_decrypt_certificate.pass_phrase try: content_transfer_encoding = self.mime_message.get('Content-Transfer-Encoding', '').lower() if 'base64' != content_transfer_encoding: del self.mime_message['Content-Transfer-Encoding'] email.encoders.encode_base64(self.mime_message) self.context.trace('content transfer encoding to base64') f_mime_string = SMIMEHelper.format_with_cr_lf( SMIMEHelper.mime_to_string(self.mime_message, 78) ) decrypted_content = SMIMEHelper.decrypt_from_text( f_mime_string, cert_local_file_path, cert_pass_phrase ) self.mime_message = email.message_from_string(decrypted_content) self.context.trace("decrypt finished; thumbprint: {thumbprint}", thumbprint=cert_thumbprint) except: logger.exception("decrypt failed; message-id: {id}".format(id=self.message_id)) raise AS2DecryptException("decrypt failed; thumbprint: {thumbprint}, due to: {message}", thumbprint=cert_thumbprint, message=sys.exc_info()[1])
def _compress(self): if not self.is_compressed: self.context.trace("compress ignored") return try: f_mime_string = SMIMEHelper.format_with_cr_lf( SMIMEHelper.mime_to_string(self.mime_message)) self.mic_content = f_mime_string self.mime_message = SMIMEHelper.compress_to_mime(f_mime_string) del self.mime_message['MIME-Version'] self.body = self.mime_message.get_payload() self.context.trace("compress finished") except: logger.exception("compress failed; message-id: {id}".format(id=self.message_id)) raise AS2CompressException("compress failed; due to: {message}", message=sys.exc_info()[1])
def _signature_mdn_mime(self, mdn_report): signed_mdn_report = MIMEMultipart( 'signed', boundary=SMIMEHelper.get_random_boundary(), protocol="application/pkcs7-signature") signed_mdn_report.attach(mdn_report) cert_thumbprint = self.context.agreement.outbound_agreement.message_signature_certificate.thumbprint cert_local_file_path = self.context.agreement.outbound_agreement.message_signature_certificate.local_file_path cert_pass_phrase = self.context.agreement.outbound_agreement.message_signature_certificate.pass_phrase cert_signature_algorithm = self.context.agreement.inbound_agreement.mdn_signature_algorithm try: mime_message = SMIMEHelper.sign_to_mime_detached( SMIMEHelper.format_with_cr_lf( SMIMEHelper.mime_to_string(mdn_report)), cert_local_file_path, cert_pass_phrase, cert_signature_algorithm) signature = SMIMEHelper.get_signature_from_mime(mime_message) del signature['MIME-Version'] signed_mdn_report.set_param('micalg', cert_signature_algorithm) signed_mdn_report.attach(signature) self.context.trace( "mdn signature finished; thumbprint: {thumbprint}, algorithm: {algorithm}", thumbprint=cert_thumbprint, algorithm=cert_signature_algorithm) except: logger.exception('sign mdn failed') raise AS2MdnException( "mdn signature failed; thumbprint: {thumbprint}, algorithm: {algorithm}, due to: {message}", thumbprint=cert_thumbprint, algorithm=cert_signature_algorithm, message=sys.exc_info()[1]) return signed_mdn_report
def _encryption(self): if not self.is_encrypted: self.context.trace("encryption ignored") return cert_thumbprint = self.context.agreement.outbound_agreement.message_encryption_certificate.thumbprint cert_local_file_path = self.context.agreement.outbound_agreement.message_encryption_certificate.local_file_path cert_encrypt_algorithm = self.context.agreement.outbound_agreement.message_encryption_algorithm try: f_mime_string = SMIMEHelper.format_with_cr_lf( SMIMEHelper.mime_to_string(self.mime_message)) # encrypt without sign and compress if not self.is_signed and not self.is_compressed: self.mic_content = f_mime_string encrypted_mime_message = SMIMEHelper.encrypt_to_mime( f_mime_string, cert_local_file_path, cert_encrypt_algorithm) encrypted_mime_message.set_type('application/pkcs7-mime') self.body = encrypted_mime_message.get_payload() self.mime_message = encrypted_mime_message self.context.trace("encryption finished; thumbprint: {thumbprint}, algorithm: {algorithm}", thumbprint=cert_thumbprint, algorithm=cert_encrypt_algorithm) except: logger.exception("encryption failed; message-id: {id}".format(id=self.message_id)) raise AS2EncryptException( "encryption failed; thumbprint: {thumbprint}, algorithm: {algorithm}, due to: {message}", thumbprint=cert_thumbprint, algorithm=cert_encrypt_algorithm, message=sys.exc_info()[1])