Esempio n. 1
0
    def test_encrypt(self):
        buf = BIO.MemoryBuffer(self.cleartext)
        s = SMIME.SMIME()

        x509 = X509.load_cert('tests/recipient.pem')
        sk = X509.X509_Stack()
        sk.push(x509)
        s.set_x509_stack(sk)

        with self.assertRaises(ValueError):
            SMIME.Cipher('nosuchcipher')

        s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
        p7 = s.encrypt(buf)

        self.assertEqual(len(buf), 0)
        self.assertEqual(p7.type(), SMIME.PKCS7_ENVELOPED, p7.type())
        self.assertIsInstance(p7, SMIME.PKCS7, p7)
        out = BIO.MemoryBuffer()
        p7.write(out)

        buf = out.read()

        self.assertTrue(buf.startswith(b'-----BEGIN PKCS7-----'))
        buf = buf.strip()
        self.assertTrue(buf.endswith(b'-----END PKCS7-----'))
        self.assertGreater(
            len(buf),
            len(b'-----END PKCS7-----') + len(b'-----BEGIN PKCS7-----'))

        s.write(out, p7)
        return out
Esempio n. 2
0
def encrypt_email_body(client: Client, args: Dict):
    """ generate an S/MIME-encrypted message

    Args:
        client: Client
        args: Dict

    """
    message_body = args.get('message', '').encode('utf-8')
    buf = makebuf(message_body)

    x509 = X509.load_cert(client.public_key_file)
    sk = X509.X509_Stack()
    sk.push(x509)
    client.smime.set_x509_stack(sk)
    client.smime.set_cipher(SMIME.Cipher('des_ede3_cbc'))
    p7 = client.smime.encrypt(buf)
    out = BIO.MemoryBuffer()

    client.smime.write(out, p7)
    encrypted_message = out.read().decode('utf-8')
    message = encrypted_message.split('\n\n')
    headers = message[0]
    new_headers = headers.replace(': ', '=').replace('\n', ',')

    entry_context = {
        'SMIME.Encrypted': {
            'Message': encrypted_message,
            'Headers': new_headers
        }
    }
    return encrypted_message, entry_context
Esempio n. 3
0
def encrypt(input_bio, cert, keyring_source, cypher):
    """
    Encrypts the input data with the public key in the certificate from keyring
    source with selected cypher.

    @type input_bio: M2Crypto.BIO
    @param input_bio: input data to encrypt.
    @type cert:  filepath or M2Crypto.BIO or M2Crypto.X509.X509
    @param cert: the recipient certificate reference from filepath, could be
        from file, from memory or from pkcs11 smartcard, based on
        keyring_soruce input parameter.
    @type keyring_source: str
    @keyword keyring_source: the type of the source for input certificate, used
        to recall the appropriate method for encrypter settings. Ammitted
        values are: file, memory, pkcs11.
    @type cypher: str
    @keyword cypher: the cypher to use for encryption of the data, run
        "openssl enc -help" for supported cyphers, you have to choose a public
        key cypher from availables.
    @rtype: M2Crypto.SMIME.PKCS7
    @return: the PKCS#7 encrypted data in PEM format.
    """
    encrypter = SMIME.SMIME()
    x509 = set_certificate(cert, keyring_source)
    sk = X509.X509_Stack()
    sk.push(x509)
    encrypter.set_x509_stack(sk)
    encrypter.set_cipher(SMIME.Cipher(cypher))
    Rand.load_file('randpool.dat', -1)
    try:
        p7 = encrypter.encrypt(input_bio)
    except SMIME.SMIME_Error, e:
        logging.error('smime error: ' + str(e))
        raise
Esempio n. 4
0
    def test_encrypt(self):
        buf = BIO.MemoryBuffer(self.cleartext)
        s = SMIME.SMIME()

        x509 = X509.load_cert('test/recipient.pem')
        sk = X509.X509_Stack()
        sk.push(x509)
        s.set_x509_stack(sk)

        self.assertRaises(ValueError, SMIME.Cipher, 'nosuchcipher')

        s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
        p7 = s.encrypt(buf)
        
        assert len(buf) == 0
        assert p7.type() == SMIME.PKCS7_ENVELOPED, p7.type()
        assert isinstance(p7, SMIME.PKCS7), p7
        out = BIO.MemoryBuffer()
        p7.write(out)
    
        buf = out.read()
        
        assert buf[:len('-----BEGIN PKCS7-----')] == '-----BEGIN PKCS7-----'
        buf = buf.strip()
        assert buf[-len('-----END PKCS7-----'):] == '-----END PKCS7-----'
        assert len(buf) > len('-----END PKCS7-----') + len('-----BEGIN PKCS7-----')
        
        s.write(out, p7)
        return out
Esempio n. 5
0
def encrypt_block(blob, pubkey):
    """
    Encrypt the given blob of data, given the public key provided.

    :return The encrypted blob.
    """
    # Make a MemoryBuffer of the message.
    inbuf = BIO.MemoryBuffer(blob)

    # Seed the PRNG.
    Rand.rand_seed(os.urandom(1024))

    # Instantiate an SMIME object.
    s = SMIME.SMIME()

    # Load target cert to encrypt to.
    x509 = X509.load_cert(pubkey)
    sk = X509.X509_Stack()
    sk.push(x509)
    s.set_x509_stack(sk)

    # Set cipher: AES 256 bit in CBC mode.
    s.set_cipher(SMIME.Cipher('aes_256_cbc'))

    # Encrypt the buffer.
    p7 = s.encrypt(inbuf)
    temp_buff = BIO.MemoryBuffer()
    s.write(temp_buff, p7)
    x = temp_buff.read()
    return x
Esempio n. 6
0
def encrypt(data,
            cert_path='/workspace/personal/python_test/keys/myCert.pem',
            compact=True):
    # Make a MemoryBuffer of the message.
    buf = BIO.MemoryBuffer(data)

    # Instantiate an SMIME object.
    s = SMIME.SMIME()

    # Load target cert to encrypt to.
    x509 = X509.load_cert(cert_path)
    sk = X509.X509_Stack()
    sk.push(x509)
    s.set_x509_stack(sk)

    # Set cipher: 3-key triple-DES in CBC mode.
    s.set_cipher(SMIME.Cipher('des_ede3_cbc'))

    # Encrypt the buffer.
    p7 = s.encrypt(buf)

    # Output p7 to a MemoryBuffer.
    out = BIO.MemoryBuffer()
    s.write(out, p7)

    # Read output as string
    output = out.read()
    if compact:
        # create a single line encrypted message
        output = ''.join(output.split('\n')[5:])

    return output
Esempio n. 7
0
    def _encrypt(self):
        """Use your key thing to encrypt things."""
        from M2Crypto import BIO, SMIME, X509
        CERT = self.settings.private_cert
        PUB_CERT = self.settings.public_cert
        PAYPAL_CERT = self.settings.paypal_cert
        CERT_ID = self.settings.cert_id

        # Iterate through the fields and pull out the ones that have a value.
        plaintext = 'cert_id=%s' % CERT_ID
        for name, value in self.items.iteritems():
            plaintext += '\n%s=%s' % (name, value)
        #plaintext = plaintext.encode('utf-8')

        # Begin crypto weirdness.
        s = SMIME.SMIME()    
        s.load_key_bio(BIO.openfile(CERT), BIO.openfile(PUB_CERT))
        p7 = s.sign(BIO.MemoryBuffer(plaintext), flags=SMIME.PKCS7_BINARY)
        x509 = X509.load_cert_bio(BIO.openfile(PAYPAL_CERT))
        sk = X509.X509_Stack()
        sk.push(x509)
        s.set_x509_stack(sk)
        s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
        tmp = BIO.MemoryBuffer()
        p7.write_der(tmp)
        p7 = s.encrypt(tmp, flags=SMIME.PKCS7_BINARY)
        out = BIO.MemoryBuffer()
        p7.write(out)
        return out.read()
Esempio n. 8
0
def ed():
    print 'test encrypt/decrypt...',
    buf = makebuf()
    s = SMIME.SMIME()

    # Load target cert to encrypt to.
    x509 = X509.load_cert('client.pem')
    sk = X509.X509_Stack()
    sk.push(x509)
    s.set_x509_stack(sk)

    # Add a cipher.
    s.set_cipher(SMIME.Cipher('bf_cbc'))

    # Encrypt.
    p7 = s.encrypt(buf)

    # Load target's private key.
    s.load_key('client.pem')

    # Decrypt.
    data = s.decrypt(p7)

    if data:
        print 'ok'
    else:
        print 'not ok'
Esempio n. 9
0
    def _encrypt(self):
        """Use your key thing to encrypt things."""
        from M2Crypto import BIO, SMIME, X509

        # Iterate through the fields and pull out the ones that have a value.
        plaintext = 'cert_id=%s\n' % self.cert_id
        for name, field in self.fields.items():
            value = None
            if name in self.initial:
                value = self.initial[name]
            elif field.initial is not None:
                value = field.initial
            if value is not None:
                plaintext += u'%s=%s\n' % (name, value)
        plaintext = plaintext.encode('utf-8')

        # Begin crypto weirdness.
        s = SMIME.SMIME()
        s.load_key_bio(BIO.openfile(self.private_cert), BIO.openfile(self.public_cert))
        p7 = s.sign(BIO.MemoryBuffer(plaintext), flags=SMIME.PKCS7_BINARY)
        x509 = X509.load_cert_bio(BIO.openfile(self.paypal_cert))
        sk = X509.X509_Stack()
        sk.push(x509)
        s.set_x509_stack(sk)
        s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
        tmp = BIO.MemoryBuffer()
        p7.write_der(tmp)
        p7 = s.encrypt(tmp, flags=SMIME.PKCS7_BINARY)
        out = BIO.MemoryBuffer()
        p7.write(out)
        return out.read().decode()
Esempio n. 10
0
def smime_encrypt(raw_message, recipients):

    if not get_bool_from_cfg('smime', 'cert_path'):
        log("No valid path for S/MIME certs found in config file. S/MIME encryption aborted."
            )
        return recipients

    cert_path = cfg['smime']['cert_path'] + "/"
    s = SMIME.SMIME()
    sk = X509.X509_Stack()
    smime_to = list()
    unsmime_to = list()

    for addr in recipients:
        cert_and_email = get_cert_for_email(addr, cert_path)

        if not (cert_and_email is None):
            (to_cert, normal_email) = cert_and_email
            if verbose:
                log("Found cert " + to_cert + " for " + addr + ": " +
                    normal_email)
            smime_to.append(addr)
            x509 = X509.load_cert(to_cert, format=X509.FORMAT_PEM)
            sk.push(x509)
        else:
            unsmime_to.append(addr)

    if smime_to != list():
        s.set_x509_stack(sk)
        s.set_cipher(SMIME.Cipher('aes_192_cbc'))
        p7 = s.encrypt(BIO.MemoryBuffer(raw_message.as_string()))
        # Output p7 in mail-friendly format.
        out = BIO.MemoryBuffer()
        out.write('From: ' + from_addr + '\n')
        out.write('To: ' + raw_message['To'] + '\n')
        if raw_message['Cc']:
            out.write('Cc: ' + raw_message['Cc'] + '\n')
        if raw_message['Bcc']:
            out.write('Bcc: ' + raw_message['Bcc'] + '\n')
        if raw_message['Subject']:
            out.write('Subject: ' + raw_message['Subject'] + '\n')

        if get_bool_from_cfg('default', 'add_header', 'yes'):
            out.write('X-GPG-Mailgate: Encrypted by GPG Mailgate\n')

        s.write(out, p7)

        if verbose:
            log("Sending message from " + from_addr + " to " + str(smime_to))

        send_msg(out.read(), smime_to)
    if unsmime_to != list():
        if verbose:
            log("Unable to find valid S/MIME certificates for " +
                str(unsmime_to))

    return unsmime_to
Esempio n. 11
0
def encrypt_payload(payload, key, cipher):
    encrypter = SMIME.SMIME()
    certificate = X509.X509_Stack()
    certificate.push(X509.load_cert(key))
    encrypter.set_x509_stack(certificate)
    encrypter.set_cipher(SMIME.Cipher(cipher))
    encrypted_content = encrypter.encrypt(BIO.MemoryBuffer(payload), SMIME.PKCS7_BINARY)
    out = BIO.MemoryBuffer()
    encrypter.write(out, encrypted_content)
    return email.message_from_string(out.read())
Esempio n. 12
0
def to_smime(message,
             sender_key,
             sender_cert,
             recipient_cert,
             cipher='aes_128_cbc'):
    try:
        message = RFC822 % message
        smime = SMIME.SMIME()
        #smime.pkey = sender_key
        #smime.x509 = sender_cert
        signature = ''
        logging.debug('Signing outgoing message')
        command = ('/usr/bin/env', 'openssl', 'cms', '-sign', '-signer',
                   sender_cert, '-inkey', sender_key, '-md', 'sha256')
        proc = subprocess.Popen(command,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                bufsize=-1)
        #proc.stdin.write(message)
        #signature, stderr = proc.communicate()
        thread = threading.Thread(target=writer, args=(
            proc,
            message,
        ))
        thread.start()
        for line in proc.stdout:
            signature += line
        thread.join()
        logging.debug('Message signed')

        logging.debug('Encrypting message')

        #signature = smime.sign(BIO.MemoryBuffer(message), flags=SMIME.PKCS7_DETACHED)
        #init buffer
        message_signed = BIO.MemoryBuffer(signature)
        #smime.write(message_signed, signature, BIO.MemoryBuffer(message))
        cert_stack = X509.X509_Stack()
        #for cert in recipient_certs:
        cert_stack.push(X509.load_cert_der_string(recipient_cert))

        smime.set_x509_stack(cert_stack)
        smime.set_cipher(SMIME.Cipher(cipher))

        message_encrypted = smime.encrypt(message_signed)

        out = BIO.MemoryBuffer()
        smime.write(out, message_encrypted)
        out.close()

        logging.debug('Message encrypted')
        return out.read().replace('x-pkcs7-mime', 'pkcs7-mime')
    except SMIME.SMIME_Error, e:
        logging.error('smime error: %s', e)
        raise
Esempio n. 13
0
    def form_encrypted(self, data):
        """Return an s/mime encrypted form.  Refer to 
        http://sandbox.rulemaker.net/ngps/m2/howto.smime.html for instructions."""
        from M2Crypto import BIO, SMIME, X509
        certid = self.settings["PUBLIC_CERT_ID"]
        ret = ['CERT_ID=%s' % certid]
        ret.extend([u'%s=%s' % (key, val) for key, val in data.items() if val])
        raw = "\n".join(ret)
        raw = raw.encode('utf-8')

        self.log_extra('Plaintext form: %s', raw)

        # encrypt the plaintext

        # make an smime object
        s = SMIME.SMIME()

        # load our public and private keys
        s.load_key_bio(BIO.openfile(self.localprikey),
                       BIO.openfile(self.localpubkey))

        # put the data in the buffer
        buf = BIO.MemoryBuffer(raw)

        # sign the text
        p7 = s.sign(buf, flags=SMIME.PKCS7_BINARY)

        # Load target cert to encrypt to.
        x509 = X509.load_cert_bio(BIO.openfile(self.paypalpubkey))
        sk = X509.X509_Stack()
        sk.push(x509)
        s.set_x509_stack(sk)

        # Set cipher: 3-key triple-DES in CBC mode.
        s.set_cipher(SMIME.Cipher('des_ede3_cbc'))

        # save data to buffer
        tmp = BIO.MemoryBuffer()
        p7.write_der(tmp)

        # encrypt
        p7 = s.encrypt(tmp, flags=SMIME.PKCS7_BINARY)
        out = BIO.MemoryBuffer()

        # write into a new buffer
        p7.write(out)

        # read the result
        form = out.read()
        self.log_extra('Encrypted form: %s', form)
        return mark_safe(
            u"""<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="encrypted" value="%s" />
        """ % form)
Esempio n. 14
0
def sendsmime(from_addr,
              to_addrs,
              subject,
              msg,
              from_key,
              from_cert=None,
              to_certs=None,
              smtpd='localhost'):

    msg_bio = BIO.MemoryBuffer(msg)
    sign = from_key
    encrypt = to_certs

    s = SMIME.SMIME()
    if sign:
        s.load_key(from_key, from_cert)
        if encrypt:
            p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT)
        else:
            p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT | SMIME.PKCS7_DETACHED)
        msg_bio = BIO.MemoryBuffer(msg)  # Recreate coz sign() has consumed it.

    if encrypt:
        sk = X509.X509_Stack()
        for x in to_certs:
            sk.push(X509.load_cert(x))
        s.set_x509_stack(sk)
        s.set_cipher(SMIME.Cipher('rc2_40_cbc'))
        tmp_bio = BIO.MemoryBuffer()
        if sign:
            s.write(tmp_bio, p7)
        else:
            tmp_bio.write(msg)
        p7 = s.encrypt(tmp_bio)

    out = BIO.MemoryBuffer()
    out.write('From: %s\r\n' % from_addr)
    out.write('To: %s\r\n' % string.join(to_addrs, ", "))
    out.write('Subject: %s\r\n' % subject)
    if encrypt:
        s.write(out, p7)
    else:
        if sign:
            s.write(out, p7, msg_bio, SMIME.PKCS7_TEXT)
        else:
            out.write('\r\n')
            out.write(msg)
    out.close()

    smtp = smtplib.SMTP()
    smtp.connect(smtpd)
    smtp.sendmail(from_addr, to_addrs, out.read())
    smtp.quit()
Esempio n. 15
0
    def set_message(self, message, certificates=[]):
        """Sign and encrypt the email and prepare it to send"""
        self.message = message
        # Seed the PRNG.
        Rand.load_file('randpool.dat', -1)
    
        smime = SMIME.SMIME()
        
        # put message with attachments into into SSL" I/O buffer
        msg_str = self.message.msg.as_string()
        msg_bio = BIO.MemoryBuffer(bytes(msg_str, 'utf-8'))
        
        if self.sign:
            smime.load_key(self.key, self.cert)
            p7 = smime.sign(msg_bio, SMIME.PKCS7_DETACHED)
            # Recreate the message because sign function has consumed it
            msg_bio = BIO.MemoryBuffer(bytes(msg_str, 'utf-8')) 

        if self.encrypt:
            sk = X509.X509_Stack()
            for cert in certificates:
                sk.push(X509.load_cert(cert))
            smime.set_x509_stack(sk)
            smime.set_cipher(SMIME.Cipher(self.cipher))
            tmp_bio = BIO.MemoryBuffer()
            if self.sign:
                smime.write(tmp_bio, p7, msg_bio)
            else:
                tmp_bio.write(msg_str)
            p7 = smime.encrypt(tmp_bio)

        out = BIO.MemoryBuffer()
        out.write('From: %s\r\n' % self.message.sender)
        out.write('To: %s\r\n' % ", ".join(self.message.recipients))
        out.write('Subject: %s\r\n' % self.message.subject) 
        
        if self.encrypt:
            smime.write(out, p7)
        elif self.sign:
            smime.write(out, p7, msg_bio)
        else:
            out.write(msg_str)
                
        out.close()
        
        # Save the PRNG's state.
        Rand.save_file('randpool.dat')
        
        return out.read().decode("utf-8")
Esempio n. 16
0
    def encrypt(self, sender_address, encrypting_identities, message):
        """
        Encrypts the given message for all the supplied recipients.
        """

        if not encrypting_identities:
            raise ValueError("Encrypting recipient identities not supplied.")

        if not message:
            raise ValueError("Valid Message not supplied.")

        s = SMIME.SMIME()

        cipher = getattr(settings, "DJEMBE_CIPHER", "aes_256_cbc")
        s.set_cipher(SMIME.Cipher(cipher))

        self.logger.debug("Encrypting message for %s" % encrypting_identities)

        # Gather all the recipient certificates
        sk = X509.X509_Stack()
        for identity in encrypting_identities:
            sk.push(identity.x509)
        s.set_x509_stack(sk)

        # prepare the payload for encryption
        payload_msg = self.extract_payload(message)

        # encrypt the payload
        payload = BIO.MemoryBuffer(payload_msg.as_bytes())
        pkcs7_encrypted_data = s.encrypt(payload)
        payload.close()

        # get the PKCS7 object into a string
        payload = BIO.MemoryBuffer()
        s.write(payload, pkcs7_encrypted_data)
        pkcs7_string = payload.read()
        payload.close()

        encrypted_message = email.message_from_string(pkcs7_string.decode("UTF-8"))

        message.set_payload(encrypted_message.get_payload())

        for header, value in encrypted_message.items():
            del message[header]
            message[header] = value
        del message["Message-ID"]
        message["Message-ID"] = make_msgid()

        return message
Esempio n. 17
0
    def render(self, md):
        # Render the dtml block.
        data = render_blocks(self.section.blocks, md)
        data_bio = BIO.MemoryBuffer(data)

        # Prepare to S/MIME.
        s = SMIME.SMIME()

        # Render the signer key, load into BIO. 
        try:
            signer = Var(self.signer).render(md)
        except ParseError:
            raise SmimeError, ('Invalid parameter "signer".')
        signer_key_bio = BIO.MemoryBuffer(signer)
        signer_cert_bio = BIO.MemoryBuffer(signer) # XXX Kludge.
        
        # Sign the data.
        s.load_key_bio(signer_key_bio, signer_cert_bio)
        p7 = s.sign(data_bio, flags=SMIME.PKCS7_TEXT)

        # Recreate coz sign() has consumed the MemoryBuffer.
        # May be cheaper to seek to start.
        data_bio = BIO.MemoryBuffer(data)

        # Render recipients, load into BIO.
        try:
            recip = Var(self.recipients).render(md)
        except ParseError:
            raise SmimeError, ('Invalid parameter "recipients".')
        recip_bio = BIO.MemoryBuffer(recip)

        # Load recipient certificates.
        sk = X509.X509_Stack()
        sk.push(X509.load_cert_bio(recip_bio))
        s.set_x509_stack(sk)

        # Set a cipher.
        s.set_cipher(SMIME.Cipher('des_ede3_cbc'))

        # Encrypt.
        tmp_bio = BIO.MemoryBuffer()
        s.write(tmp_bio, p7)
        p7 = s.encrypt(tmp_bio)

        # Finally, return the now signed/encrypted PKCS7.
        out = BIO.MemoryBuffer()
        s.write(out, p7)
        return out.getvalue()
Esempio n. 18
0
    def paypalencrypt(self):

        plaintext = ''

        for key, value in self.attributes.items():
            plaintext += u'%s=%s\n' % (key, value)

        plaintext = plaintext.encode('utf-8')

        # Instantiate an SMIME object.
        s = SMIME.SMIME()

        # Load signer's key and cert. Sign the buffer.
        s.pkey = EVP.load_key(
            os.path.join(current.request.folder, 'private/paypal',
                         'priv_paypalgextiendas.pem'))
        s.x509 = X509.load_cert(
            os.path.join(current.request.folder, 'private/paypal',
                         'pub_paypalgextiendas.pem'))

        p7 = s.sign(BIO.MemoryBuffer(plaintext), flags=SMIME.PKCS7_BINARY)

        x509 = X509.load_cert(
            os.path.join(current.request.folder, 'private/paypal',
                         'paypal_cert_pem.txt'))

        sk = X509.X509_Stack()
        sk.push(x509)
        s.set_x509_stack(sk)

        # Set cipher: 3-key triple-DES in CBC mode.
        s.set_cipher(SMIME.Cipher('des_ede3_cbc'))

        # Create a temporary buffer.
        tmp = BIO.MemoryBuffer()

        # Write the signed message into the temporary buffer.
        p7.write_der(tmp)

        # Encrypt the temporary buffer.
        p7 = s.encrypt(tmp, flags=SMIME.PKCS7_BINARY)

        # Output p7 in mail-friendly format.
        out = BIO.MemoryBuffer()
        p7.write(out)

        return out.read()
def encrypt(filename, outfilename):
    from M2Crypto import BIO, Rand, SMIME, X509

    PUBLIC_KEY = '''-----BEGIN CERTIFICATE-----
MIIEUTCCAzmgAwIBAgIJAK1MSC7OcXXEMA0GCSqGSIb3DQEBBQUAMIG+MQswCQYD
VQQGEwJVUzENMAsGA1UECAwEVXRhaDEPMA0GA1UEBwwGRHJhcGVyMR0wGwYDVQQK
DBRDb250cm9sNCBDb3Jwb3JhdGlvbjEiMCAGA1UECwwZRHJpdmVyV29ya3MgRW5j
cnlwdGlvbiBWMjEiMCAGA1UEAwwZRHJpdmVyV29ya3MgRW5jcnlwdGlvbiBWMjEo
MCYGCSqGSIb3DQEJARYZY2VydC1zdXBwb3J0QGNvbnRyb2w0LmNvbTAeFw0xMzA5
MTcxOTUwMTlaFw0zMzA5MTIxOTUwMTlaMIG+MQswCQYDVQQGEwJVUzENMAsGA1UE
CAwEVXRhaDEPMA0GA1UEBwwGRHJhcGVyMR0wGwYDVQQKDBRDb250cm9sNCBDb3Jw
b3JhdGlvbjEiMCAGA1UECwwZRHJpdmVyV29ya3MgRW5jcnlwdGlvbiBWMjEiMCAG
A1UEAwwZRHJpdmVyV29ya3MgRW5jcnlwdGlvbiBWMjEoMCYGCSqGSIb3DQEJARYZ
Y2VydC1zdXBwb3J0QGNvbnRyb2w0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBANpapgg8oU3FIhzDYEVM14lPKVbsuqm/+9CJKYSPVPjEvdm17IMI
O4axqFDj1BH8qdbSwhPugC+j0q5O2jlfA19u5aL2vHpr04MSZF0OHWYN20g+pWXe
gaq3LQsjBLiQPQKewS5v5Ff4GydJD63rJz8pO18ztYlPYNrABOBcEM7MiVvzJK6e
NMTOOEZqf2FIjtXQhyclkzcBz7j/TC2jqvYa96DmfpYoPAajf+ypzxezSZ6G4GRa
6jlNtBg40QjHtHxWa3PsZ86PiLMnZ2z4SryMpcecm7Jj/iA9Hh76wLglv4TtjXxk
gtqkv7RzOHlmOeB4nH8lsqTyRBmnn39fDuMCAwEAAaNQME4wHQYDVR0OBBYEFHCV
PSWmatjY5ixd4azS6+GxDIpwMB8GA1UdIwQYMBaAFHCVPSWmatjY5ixd4azS6+Gx
DIpwMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHl58yYI7IMWkkxI
vu5kff/MKTSt4SXN365o3opc8FBuo/d3v2IKkIlo8BWbuCp4MwqV8L/0UYupFs49
RI5N0ETTapdg1uoVUd8NGHx7FgZ5MU9+caMEI8PoaRcFPdrxL1S7nOyl0ceFWwIz
1V2Hc9hZQEcv586El+/xXq/jd/oydN+j+knaL/dwvcK88TvQjl3AS974QuedvGIh
pq8tXfMiu1iPpc29tOMgfJzO0V6T92Fn5XbAY4u5p9Rvs/h8x7Ono++zRh66JOXQ
T++pYjmRUr+BSgZfoZzvs9mdMqtFpeWIx6nW4vXjDwAILVP3Bgh9MwrEzJtIQ/qy
Zwi18AY=
-----END CERTIFICATE-----'''

    with open(filename, 'rb') as file:
        str = file.read()
        buf = BIO.MemoryBuffer(str)

        smime = SMIME.SMIME()
        x509 = X509.load_cert_string(PUBLIC_KEY)
        x509_stack = X509.X509_Stack()
        x509_stack.push(x509)
        smime.set_x509_stack(x509_stack)
        smime.set_cipher(SMIME.Cipher('aes_256_cbc'))

        pkcs7 = smime.encrypt(buf, flags=SMIME.PKCS7_BINARY)
        outbuf = BIO.MemoryBuffer()
        pkcs7.write_der(outbuf)

        with open(outfilename, 'wb') as outfile:
            outfile.write(outbuf.read())
Esempio n. 20
0
    def test_signEncryptDecryptVerify(self):
        # sign
        buf = BIO.MemoryBuffer(self.cleartext)
        s = SMIME.SMIME()
        s.load_key('tests/signer_key.pem', 'tests/signer.pem')
        p7 = s.sign(buf)

        # encrypt
        x509 = X509.load_cert('tests/recipient.pem')
        sk = X509.X509_Stack()
        sk.push(x509)
        s.set_x509_stack(sk)

        s.set_cipher(SMIME.Cipher('des_ede3_cbc'))

        tmp = BIO.MemoryBuffer()
        s.write(tmp, p7)

        p7 = s.encrypt(tmp)

        signedEncrypted = BIO.MemoryBuffer()
        s.write(signedEncrypted, p7)

        # decrypt
        s = SMIME.SMIME()

        s.load_key('tests/recipient_key.pem', 'tests/recipient.pem')

        p7, data = SMIME.smime_load_pkcs7_bio(signedEncrypted)

        out = s.decrypt(p7)

        # verify
        x509 = X509.load_cert('tests/signer.pem')
        sk = X509.X509_Stack()
        sk.push(x509)
        s.set_x509_stack(sk)

        st = X509.X509_Store()
        st.load_info('tests/ca.pem')
        s.set_x509_store(st)

        p7_bio = BIO.MemoryBuffer(out)
        p7, data = SMIME.smime_load_pkcs7_bio(p7_bio)
        v = s.verify(p7)
        self.assertEqual(v, self.cleartext)
Esempio n. 21
0
    def sign_and_encrypt(self):

        # Make a MemoryBuffer of the message.
        buf = makebuf('a sign of our times')

        # Seed the PRNG.
        Rand.load_file(randpool, -1)

        # Instantiate an SMIME object.
        s = SMIME.SMIME()

        # Load signer's key and cert. Sign the buffer.
        s.load_key(signer_key, signer_cert)
        p7 = s.sign(buf, SMIME.PKCS7_DETACHED)

        # Load target cert to encrypt the signed message to.
        x509 = X509.load_cert(recipient_cert)
        sk = X509.X509_Stack()
        sk.push(x509)
        s.set_x509_stack(sk)

        # Set cipher: 3-key triple-DES in CBC mode.
        s.set_cipher(SMIME.Cipher('des_ede3_cbc'))

        # Create a temporary buffer.
        tmp = BIO.MemoryBuffer()

        # Write the signed message into the temporary buffer.
        s.write(tmp, p7, buf)

        # Encrypt the temporary buffer.
        p7 = s.encrypt(tmp)

        # Output p7 in mail-friendly format.
        out = BIO.MemoryBuffer()
        out.write('From: [email protected]\n')
        out.write('To: [email protected]\n')
        out.write('Subject: M2Crypto S/MIME testing\n')
        s.write(out, p7)

        result = out.read()

        # Save the PRNG's state.
        Rand.save_file(randpool)

        open('smime-m2-sign-encrypt.txt', 'wt').write(result)
Esempio n. 22
0
def sign_and_encrypt(client: Client, args: Dict):

    message = args.get('message', '').encode('utf-8')
    msg_bio = BIO.MemoryBuffer(message)
    sign = client.private_key_file
    encrypt = client.public_key_file

    if sign:
        client.smime.load_key(client.private_key_file, client.public_key_file)
        if encrypt:
            p7 = client.smime.sign(msg_bio, flags=SMIME.PKCS7_TEXT)
        else:
            p7 = client.smime.sign(msg_bio,
                                   flags=SMIME.PKCS7_TEXT
                                   | SMIME.PKCS7_DETACHED)
        msg_bio = BIO.MemoryBuffer(
            message)  # Recreate coz sign() has consumed it.

    if encrypt:
        x509 = X509.load_cert(client.public_key_file)
        sk = X509.X509_Stack()
        sk.push(x509)
        client.smime.set_x509_stack(sk)

        client.smime.set_cipher(SMIME.Cipher('des_ede3_cbc'))
        tmp_bio = BIO.MemoryBuffer()
        if sign:
            client.smime.write(tmp_bio, p7)
        else:
            tmp_bio.write(message)
        p7 = client.smime.encrypt(tmp_bio)

    out = BIO.MemoryBuffer()
    if encrypt:
        client.smime.write(out, p7)
    else:
        if sign:
            client.smime.write(out, p7, msg_bio, SMIME.PKCS7_TEXT)
        else:
            out.write('\r\n')
            out.write(message)

    msg = out.read().decode('utf-8')
    entry_context = {'SMIME.SignedAndEncrypted': {'Message': msg}}

    return msg, entry_context
Esempio n. 23
0
    def __init__(self, d):
        self.plaindict = d
        plaintext = dumps(dict(d))

        self.key_hashes = set([self.hash_key(k) for k in d.keys()])

        s = SMIME.SMIME()

        x509 = X509.load_cert(settings.RSA_CERTIFICATE)
        sk = X509.X509_Stack()
        sk.push(x509)
        s.set_x509_stack(sk)
        s.set_cipher(SMIME.Cipher('des_ede3_cbc'))

        p7 = s.encrypt(BIO.MemoryBuffer(plaintext), flags=SMIME.PKCS7_BINARY)

        out = BIO.MemoryBuffer()
        p7.write(out)
        self.ciphertext = out.read()
Esempio n. 24
0
    def _encrypt(self):
        """Use your key thing to encrypt things."""
        from M2Crypto import BIO, SMIME, X509
        # @@@ Could we move this to conf.py?
        CERT = settings.PAYPAL_PRIVATE_CERT
        PUB_CERT = settings.PAYPAL_PUBLIC_CERT
        PAYPAL_CERT = settings.PAYPAL_CERT
        CERT_ID = self.cert_id

        # Iterate through the fields and pull out the ones that have a value.
        plaintext = 'cert_id=%s\n' % CERT_ID
        for name, field in self.fields.items():
            value = None
            if name in self.initial:
                value = self.initial[name]
            elif field.initial is not None:
                value = field.initial
            if value is not None:
                # @@@ Make this less hackish and put it in the widget.
                if name == "return_url":
                    name = "return"
                plaintext += u'%s=%s\n' % (name, value)
        plaintext = plaintext.encode('utf-8')

        with BIO.openfile(CERT) as cert_f, \
                BIO.openfile(PUB_CERT) as pub_cert_f, \
                BIO.openfile(settings.PAYPAL_CERT) as pp_cert_f:
            # Begin crypto weirdness.
            s = SMIME.SMIME()
            s.load_key_bio(cert_f, pub_cert_f)
            p7 = s.sign(BIO.MemoryBuffer(plaintext), flags=SMIME.PKCS7_BINARY)
            x509 = X509.load_cert_bio(pp_cert_f)
            sk = X509.X509_Stack()
            sk.push(x509)
            s.set_x509_stack(sk)
            s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
            tmp = BIO.MemoryBuffer()
            p7.write_der(tmp)
            p7 = s.encrypt(tmp, flags=SMIME.PKCS7_BINARY)
            out = BIO.MemoryBuffer()
            p7.write(out)
            return out.read()
Esempio n. 25
0
    def get_encrypt_ctx(self, receiver_name):
        """Return SMIME context for encryption."""

        ck = ('E', receiver_name)
        if ck in self.cache:
            return self.cache[ck]

        # here we could add several certs
        crt = self.ks.load_cert_obj(receiver_name)
        x = X509.X509_Stack()
        x.push(crt)

        # SMIME setup
        sm = SMIME.SMIME()
        sm.set_x509_stack(x)
        sm.set_cipher(SMIME.Cipher('aes_128_cbc'))

        if CACHE_KEYS:
            self.cache[ck] = sm
        return sm
Esempio n. 26
0
    def encrypt(self, attributes):
        plaintext = ''

        for key, value in attributes.items():
            plaintext += u'%s=%s\n' % (key, value)

        plaintext = plaintext.encode('utf-8')

        # Instantiate an SMIME object.
        s = SMIME.SMIME()

        # Load signer's key and cert. Sign the buffer.
        s.load_key_bio(BIO.openfile(PAYPAL_PRIVATE_KEY),
                       BIO.openfile(PAYPAL_PUBLIC_KEY))

        p7 = s.sign(BIO.MemoryBuffer(plaintext), flags=SMIME.PKCS7_BINARY)

        # Load target cert to encrypt the signed message to.
        x509 = X509.load_cert_bio(BIO.openfile(PAYPAL_PAYPAL_CERT))
        sk = X509.X509_Stack()
        sk.push(x509)
        s.set_x509_stack(sk)

        # Set cipher: 3-key triple-DES in CBC mode.
        s.set_cipher(SMIME.Cipher('des_ede3_cbc'))

        # Create a temporary buffer.
        tmp = BIO.MemoryBuffer()

        # Write the signed message into the temporary buffer.
        p7.write_der(tmp)

        # Encrypt the temporary buffer.
        p7 = s.encrypt(tmp, flags=SMIME.PKCS7_BINARY)

        # Output p7 in mail-friendly format.
        out = BIO.MemoryBuffer()
        p7.write(out)

        return out.read()
Esempio n. 27
0
    def _encrypt_data(self, data):
        """
        Encrypt the form data.

        Refer to http://sandbox.rulemaker.net/ngps/m2/howto.smime.html
        """
        # Don't import at top because these are only required if user wants encryption
        from M2Crypto import BIO, SMIME, X509
        certid = self.settings["PUBLIC_CERT_ID"]
        # Assemble form data and encode in utf-8
        raw = ["cert_id=%s" % certid]
        raw.extend([u"%s=%s" % (key, val) for key, val in data.items() if val])
        raw = "\n".join(raw)
        raw = raw.encode("utf-8")
        self.log.debug('Encrypted Paypal data: %s' % raw)
        # make an smime object
        s = SMIME.SMIME()
        # load our public and private keys
        s.load_key_bio(BIO.openfile(self.localprikey),
                       BIO.openfile(self.localpubkey))
        # put the data in the buffer
        buf = BIO.MemoryBuffer(raw)
        # sign the text
        p7 = s.sign(buf, flags=SMIME.PKCS7_BINARY)
        # Load target cert to encrypt to.
        x509 = X509.load_cert_bio(BIO.openfile(self.paypalpubkey))
        sk = X509.X509_Stack()
        sk.push(x509)
        s.set_x509_stack(sk)
        # Set cipher: 3-key triple-DES in CBC mode.
        s.set_cipher(SMIME.Cipher("des_ede3_cbc"))
        # save data to buffer
        tmp = BIO.MemoryBuffer()
        p7.write_der(tmp)
        # encrypt
        p7 = s.encrypt(tmp, flags=SMIME.PKCS7_BINARY)
        out = BIO.MemoryBuffer()
        # write into a new buffer
        p7.write(out)
        return out.read()
Esempio n. 28
0
def to_smime_handler(raw_message, recipients=None):
    if recipients == None:
        recipients = to_addrs
    s = SMIME.SMIME()
    sk = X509.X509_Stack()
    normalized_recipient = []
    for addr in recipients:
        addr_addr = email.utils.parseaddr(addr)[1].lower()
        cert_and_email = get_cert_for_email(addr_addr)
        if cert_and_email:
            (to_cert, normal_email) = cert_and_email
            log("Found cert " + to_cert + " for " + addr + ": " + normal_email)
            normalized_recipient.append(
                (email.utils.parseaddr(addr)[0], normal_email))
            x509 = X509.load_cert(to_cert, format=X509.FORMAT_PEM)
            sk.push(x509)
    if len(normalized_recipient):
        s.set_x509_stack(sk)
        s.set_cipher(SMIME.Cipher('aes_192_cbc'))
        p7 = s.encrypt(BIO.MemoryBuffer(raw_message.as_string()))
        # Output p7 in mail-friendly format.
        out = BIO.MemoryBuffer()
        out.write('From: ' + from_addr + '\n')
        to_list = ",".join(
            [email.utils.formataddr(x) for x in normalized_recipient])
        out.write('To: ' + to_list + '\n')
        if raw_message['Subject']:
            out.write('Subject: ' + raw_message['Subject'] + '\n')
        if cfg['default'].has_key(
                'add_header') and cfg['default']['add_header'] == 'yes':
            out.write('X-GPG-Mailgate: Encrypted by GPG Mailgate\n')
        s.write(out, p7)
        log("Sending message from " + from_addr + " to " + str(recipients))
        raw_msg = out.read()
        send_msg(raw_msg, recipients)
    else:
        log("Unable to find valid S/MIME recipient")
        send_msg(raw_message.as_string(), recipients)
    return None
Esempio n. 29
0
    def send(self,
             to,
             subject='None',
             message='None',
             attachments=None,
             cc=None,
             bcc=None,
             reply_to=None,
             encoding='utf-8',
             raw=False,
             headers={}):
        """
        Sends an email using data specified in constructor

        Arguments:

            to: list or tuple of receiver addresses; will also accept single
                object
            subject: subject of the email
            message: email body text; depends on type of passed object:
                     if 2-list or 2-tuple is passed: first element will be
                     source of plain text while second of html text;
                     otherwise: object will be the only source of plain text
                     and html source will be set to None;
                     If text or html source is:
                     None: content part will be ignored,
                     string: content part will be set to it,
                     file-like object: content part will be fetched from
                                       it using it's read() method
            attachments: list or tuple of Mail.Attachment objects; will also
                         accept single object
            cc: list or tuple of carbon copy receiver addresses; will also
                accept single object
            bcc: list or tuple of blind carbon copy receiver addresses; will
                also accept single object
            reply_to: address to which reply should be composed
            encoding: encoding of all strings passed to this method (including
                      message bodies)
            headers: dictionary of headers to refine the headers just before
                     sending mail, e.g. {'Return-Path' : '*****@*****.**'}

        Examples:

            #Send plain text message to single address:
            mail.send('*****@*****.**',
                      'Message subject',
                      'Plain text body of the message')

            #Send html message to single address:
            mail.send('*****@*****.**',
                      'Message subject',
                      '<html>Plain text body of the message</html>')

            #Send text and html message to three addresses (two in cc):
            mail.send('*****@*****.**',
                      'Message subject',
                      ('Plain text body', '<html>html body</html>'),
                      cc=['*****@*****.**', '*****@*****.**'])

            #Send html only message with image attachment available from
            the message by 'photo' content id:
            mail.send('*****@*****.**',
                      'Message subject',
                      (None, '<html><img src="cid:photo" /></html>'),
                      Mail.Attachment('/path/to/photo.jpg'
                                      content_id='photo'))

            #Send email with two attachments and no body text
            mail.send('[email protected],
                      'Message subject',
                      None,
                      [Mail.Attachment('/path/to/fist.file'),
                       Mail.Attachment('/path/to/second.file')])

        Returns True on success, False on failure.

        Before return, method updates two object's fields:
        self.result: return value of smtplib.SMTP.sendmail() or GAE's
                     mail.send_mail() method
        self.error: Exception message or None if above was successful
        """
        def encode_header(key):
            if [c for c in key if 32 > ord(c) or ord(c) > 127]:
                return Header.Header(key.encode('utf-8'), 'utf-8')
            else:
                return key

        # encoded or raw text
        def encoded_or_raw(text):
            if raw:
                text = encode_header(text)
            return text

        if not isinstance(self.server, str):
            raise Exception('Server address not specified')
        if not isinstance(self.sender, str):
            raise Exception('Sender address not specified')

        if not raw:
            payload_in = MIMEMultipart.MIMEMultipart('mixed')
        else:
            # no encoding configuration for raw messages
            if isinstance(message, basestring):
                text = message.decode(encoding).encode('utf-8')
            else:
                text = message.read().decode(encoding).encode('utf-8')
            # No charset passed to avoid transport encoding
            # NOTE: some unicode encoded strings will produce
            # unreadable mail contents.
            payload_in = MIMEText.MIMEText(text)
        if to:
            if not isinstance(to, (list, tuple)):
                to = [to]
        else:
            raise Exception('Target receiver address not specified')
        if cc:
            if not isinstance(cc, (list, tuple)):
                cc = [cc]
        if bcc:
            if not isinstance(bcc, (list, tuple)):
                bcc = [bcc]
        if message is None:
            text = html = None
        elif isinstance(message, (list, tuple)):
            text, html = message
        elif message.strip().startswith('<html') and message.strip().endswith(
                '</html>'):
            text = self.server == 'gae' and message or None
            html = message
        else:
            text = message
            html = None

        if (not text is None or not html is None) and (not raw):
            attachment = MIMEMultipart.MIMEMultipart('alternative')
            if not text is None:
                if isinstance(text, basestring):
                    text = text.decode(encoding).encode('utf-8')
                else:
                    text = text.read().decode(encoding).encode('utf-8')
                attachment.attach(MIMEText.MIMEText(text, _charset='utf-8'))
            if not html is None:
                if isinstance(html, basestring):
                    html = html.decode(encoding).encode('utf-8')
                else:
                    html = html.read().decode(encoding).encode('utf-8')
                attachment.attach(
                    MIMEText.MIMEText(html, 'html', _charset='utf-8'))
            payload_in.attach(attachment)
        if (attachments is None) or raw:
            pass
        elif isinstance(attachments, (list, tuple)):
            for attachment in attachments:
                payload_in.attach(attachment)
        else:
            payload_in.attach(attachments)

        #######################################################
        #                      CIPHER                         #
        #######################################################
        cipher_type = self.cipher_type
        sign = self.sign
        sign_passphrase = self.sign_passphrase
        encrypt = self.encrypt
        #######################################################
        #                       GPGME                         #
        #######################################################
        if cipher_type == 'gpg':
            if self.gpg_home:
                # Set GNUPGHOME environment variable to set home of gnupg
                import os
                os.environ['GNUPGHOME'] = self.gpg_home
            if not sign and not encrypt:
                self.error = "No sign and no encrypt is set but cipher type to gpg"
                return False

            # need a python-pyme package and gpgme lib
            from pyme import core, errors
            from pyme.constants.sig import mode
            ############################################
            #                   sign                   #
            ############################################
            if sign:
                import string
                core.check_version(None)
                pin = string.replace(payload_in.as_string(), '\n', '\r\n')
                plain = core.Data(pin)
                sig = core.Data()
                c = core.Context()
                c.set_armor(1)
                c.signers_clear()
                # search for signing key for From:
                for sigkey in c.op_keylist_all(self.sender, 1):
                    if sigkey.can_sign:
                        c.signers_add(sigkey)
                if not c.signers_enum(0):
                    self.error = 'No key for signing [%s]' % self.sender
                    return False
                c.set_passphrase_cb(lambda x, y, z: sign_passphrase)
                try:
                    # make a signature
                    c.op_sign(plain, sig, mode.DETACH)
                    sig.seek(0, 0)
                    # make it part of the email
                    payload = MIMEMultipart.MIMEMultipart(
                        'signed',
                        boundary=None,
                        _subparts=None,
                        **dict(micalg="pgp-sha1",
                               protocol="application/pgp-signature"))
                    # insert the origin payload
                    payload.attach(payload_in)
                    # insert the detached signature
                    p = MIMEBase.MIMEBase("application", 'pgp-signature')
                    p.set_payload(sig.read())
                    payload.attach(p)
                    # it's just a trick to handle the no encryption case
                    payload_in = payload
                except errors.GPGMEError:
                    self.error = "GPG error: %s"
                    return False
            ############################################
            #                  encrypt                 #
            ############################################
            if encrypt:
                core.check_version(None)
                plain = core.Data(payload_in.as_string())
                cipher = core.Data()
                c = core.Context()
                c.set_armor(1)
                # collect the public keys for encryption
                recipients = []
                rec = to[:]
                if cc:
                    rec.extend(cc)
                if bcc:
                    rec.extend(bcc)
                for addr in rec:
                    c.op_keylist_start(addr, 0)
                    r = c.op_keylist_next()
                    if r is None:
                        self.error = 'No key for [%s]' % addr
                        return False
                    recipients.append(r)
                try:
                    # make the encryption
                    c.op_encrypt(recipients, 1, plain, cipher)
                    cipher.seek(0, 0)
                    # make it a part of the email
                    payload = MIMEMultipart.MIMEMultipart(
                        'encrypted',
                        boundary=None,
                        _subparts=None,
                        **dict(protocol="application/pgp-encrypted"))
                    p = MIMEBase.MIMEBase("application", 'pgp-encrypted')
                    p.set_payload("Version: 1\r\n")
                    payload.attach(p)
                    p = MIMEBase.MIMEBase("application", 'octet-stream')
                    p.set_payload(cipher.read())
                    payload.attach(p)
                except errors.GPGMEError:
                    self.error = "GPG error: %s"
                    return False
        #######################################################
        #                       X.509                         #
        #######################################################
        elif cipher_type == 'x509':
            if not sign and not encrypt:
                self.error = "No sign and no encrypt is set but cipher type to x509"
                return False
            x509_sign_keyfile = self.x509_sign_keyfile
            if self.x509_sign_certfile:
                x509_sign_certfile = self.x509_sign_certfile
            else:
                # if there is no sign certfile we'll assume the
                # cert is in keyfile
                x509_sign_certfile = self.x509_sign_keyfile
            # crypt certfiles could be a string or a list
            x509_crypt_certfiles = self.x509_crypt_certfiles
            x509_nocerts = self.x509_nocerts

            # need m2crypto
            try:
                from M2Crypto import BIO, SMIME, X509
            except Exception:
                self.error = "Can't load M2Crypto module"
                return False
            msg_bio = BIO.MemoryBuffer(payload_in.as_string())
            s = SMIME.SMIME()

            #                   SIGN
            if sign:
                #key for signing
                try:
                    s.load_key(x509_sign_keyfile,
                               x509_sign_certfile,
                               callback=lambda x: sign_passphrase)
                except Exception:
                    self.error = "Something went wrong on certificate / private key loading: <%s>" % str(
                        e)
                    return False
                try:
                    if x509_nocerts:
                        flags = SMIME.PKCS7_NOCERTS
                    else:
                        flags = 0
                    if not encrypt:
                        flags += SMIME.PKCS7_DETACHED
                    p7 = s.sign(msg_bio, flags=flags)
                    msg_bio = BIO.MemoryBuffer(payload_in.as_string(
                    ))  # Recreate coz sign() has consumed it.
                except Exception:
                    self.error = "Something went wrong on signing: <%s> %s"
                    return False

            #                   ENCRYPT
            if encrypt:
                try:
                    sk = X509.X509_Stack()
                    if not isinstance(x509_crypt_certfiles, (list, tuple)):
                        x509_crypt_certfiles = [x509_crypt_certfiles]

                    # make an encryption cert's stack
                    for x in x509_crypt_certfiles:
                        sk.push(X509.load_cert(x))
                    s.set_x509_stack(sk)

                    s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
                    tmp_bio = BIO.MemoryBuffer()
                    if sign:
                        s.write(tmp_bio, p7)
                    else:
                        tmp_bio.write(payload_in.as_string())
                    p7 = s.encrypt(tmp_bio)
                except Exception:
                    self.error = "Something went wrong on encrypting: <%s>"
                    return False

            #                 Final stage in sign and encryption
            out = BIO.MemoryBuffer()
            if encrypt:
                s.write(out, p7)
            else:
                if sign:
                    s.write(out, p7, msg_bio, SMIME.PKCS7_DETACHED)
                else:
                    out.write('\r\n')
                    out.write(payload_in.as_string())
            out.close()
            st = str(out.read())
            payload = message_from_string(st)
        else:
            # no cryptography process as usual
            payload = payload_in

        payload['From'] = encoded_or_raw(self.sender.decode(encoding))
        origTo = to[:]
        if to:
            payload['To'] = encoded_or_raw(', '.join(to).decode(encoding))
        if reply_to:
            payload['Reply-To'] = encoded_or_raw(reply_to.decode(encoding))
        if cc:
            payload['Cc'] = encoded_or_raw(', '.join(cc).decode(encoding))
            to.extend(cc)
        if bcc:
            to.extend(bcc)
        payload['Subject'] = encoded_or_raw(subject.decode(encoding))
        payload['Date'] = time.strftime("%a, %d %b %Y %H:%M:%S +0000",
                                        time.gmtime())
        for k, v in headers.iteritems():
            payload[k] = encoded_or_raw(v.decode(encoding))
        result = {}
        try:
            if self.server == 'logging':
                logger.warn('email not sent\n%s\nFrom: %s\nTo: %s\nSubject: %s\n\n%s\n%s\n' % \
                                ('-'*40,self.sender,
                                 ', '.join(to),subject,
                                 text or html,'-'*40))
            elif self.server == 'gae':
                xcc = dict()
                if cc:
                    xcc['cc'] = cc
                if bcc:
                    xcc['bcc'] = bcc
                if reply_to:
                    xcc['reply_to'] = reply_to
                from google.appengine.api import mail
                attachments = attachments and [(a.my_filename, a.my_payload)
                                               for a in attachments if not raw]
                if attachments:
                    result = mail.send_mail(sender=self.sender,
                                            to=origTo,
                                            subject=subject,
                                            body=text,
                                            html=html,
                                            attachments=attachments,
                                            **xcc)
                elif html and (not raw):
                    result = mail.send_mail(sender=self.sender,
                                            to=origTo,
                                            subject=subject,
                                            body=text,
                                            html=html,
                                            **xcc)
                else:
                    result = mail.send_mail(sender=self.sender,
                                            to=origTo,
                                            subject=subject,
                                            body=text,
                                            **xcc)
            else:
                smtp_args = self.server.split(':')
                if self.ssl:
                    server = smtplib.SMTP_SSL(*smtp_args)
                else:
                    server = smtplib.SMTP(*smtp_args)
                if self.tls and not self.ssl:
                    server.ehlo()
                    server.starttls()
                    server.ehlo()
                if self.login:
                    server.login(*self.login.split(':', 1))
                result = server.sendmail(self.sender, to, payload.as_string())
                server.quit()
        except Exception:

            self.result = result
            self.error = None
            return False
        self.result = result
        self.error = None
        return True
Esempio n. 30
0
buf = makebuf(message)

# Seed the PRNG.
Rand.load_file('randpool.dat', -1)

# Instantiate an SMIME object.
s = SMIME.SMIME()

# Load target cert to encrypt to.
x509 = X509.load_cert('sample_keys/recipient.pem')
sk = X509.X509_Stack()
sk.push(x509)
s.set_x509_stack(sk)

# Set cipher: 3-key triple-DES in CBC mode.
s.set_cipher(SMIME.Cipher('des_ede3_cbc'))

# Encrypt the buffer.
p7 = s.encrypt(buf)

# Output p7 in mail-friendly format.
out = BIO.MemoryBuffer()
out.write('From: [email protected]\n')
out.write('To: [email protected]\n')
out.write('Subject: M2Crypto S/MIME testing\n')
s.write(out, p7)

stringEncrypted = str(out.read(), 'utf-8')
print(stringEncrypted)

with open('encrypt.p7', 'w') as outf: