Exemple #1
0
 def testEncryptSymmetric(self):
     data = OpenPGP.LiteralDataPacket('This is text.', 'u', 'stuff.txt')
     encrypted = OpenPGP.cryptography.Wrapper(OpenPGP.Message(
         [data])).encrypt('secret')
     decrypted = OpenPGP.cryptography.Wrapper(encrypted).decrypt_symmetric(
         'secret')
     nose.tools.assert_equal(decrypted[0].data, b'This is text.')
Exemple #2
0
    def sign(self, packet, hash='SHA256', keyid=None):
        if self._key and not isinstance(packet, OpenPGP.Packet) and not isinstance(packet, OpenPGP.Message):
            packet = OpenPGP.LiteralDataPacket(packet)
        else:
            packet = self._parse_packet(packet)

        if isinstance(packet, OpenPGP.SecretKeyPacket) or isinstance(packet, Crypto.PublicKey.RSA._RSAobj) or isinstance(packet, Crypto.PublicKey.DSA._DSAobj) or (hasattr(packet, '__getitem__') and isinstance(packet[0], OpenPGP.SecretKeyPacket)):
            key = packet
            message = self._message
        else:
            key = self._key
            message = packet

        if not key or not message:
            return None # Missing some data

        if isinstance(message, OpenPGP.Message):
            message = message.signature_and_data()[1]

        if not (isinstance(key, Crypto.PublicKey.RSA._RSAobj) or isinstance(packet, Crypto.PublicKey.DSA._DSAobj)):
            key = self.__class__(key)
            if not keyid:
                keyid = key.key().fingerprint()[-16:]
            key = key.private_key(keyid)

        key_algorithm = None
        if isinstance(key, Crypto.PublicKey.RSA._RSAobj):
            key_algorithm = 'RSA'
        elif isinstance(key, Crypto.PublicKey.DSA._DSAobj):
            key_algorithm = 'DSA'

        sig = OpenPGP.SignaturePacket(message, key_algorithm, hash.upper())

        if keyid:
            sig.hashed_subpackets.append(OpenPGP.SignaturePacket.IssuerPacket(keyid))

        def doDSA(h, m):
            return list(key.sign(h.new(m).digest()[0:int(Crypto.Util.number.size(key.q) / 8)],
                Crypto.Random.random.StrongRandom().randint(1,key.q-1)))

        sig.sign_data({'RSA': {
                'MD5':       lambda m: [Crypto.Signature.PKCS1_v1_5.new(key).sign(Crypto.Hash.MD5.new(m))],
                'RIPEMD160': lambda m: [Crypto.Signature.PKCS1_v1_5.new(key).sign(Crypto.Hash.RIPEMD.new(m))],
                'SHA1':      lambda m: [Crypto.Signature.PKCS1_v1_5.new(key).sign(Crypto.Hash.SHA.new(m))],
                'SHA224':    lambda m: [Crypto.Signature.PKCS1_v1_5.new(key).sign(Crypto.Hash.SHA224.new(m))],
                'SHA256':    lambda m: [Crypto.Signature.PKCS1_v1_5.new(key).sign(Crypto.Hash.SHA256.new(m))],
                'SHA384':    lambda m: [Crypto.Signature.PKCS1_v1_5.new(key).sign(Crypto.Hash.SHA384.new(m))],
                'SHA512':    lambda m: [Crypto.Signature.PKCS1_v1_5.new(key).sign(Crypto.Hash.SHA512.new(m))],
            }, 'DSA': {
                'MD5':       lambda m: doDSA(Crypto.Hash.MD5, m),
                'RIPEMD160': lambda m: doDSA(Crypto.Hash.RIPEMD, m),
                'SHA1':      lambda m: doDSA(Crypto.Hash.SHA, m),
                'SHA224':    lambda m: doDSA(Crypto.Hash.SHA224, m),
                'SHA256':    lambda m: doDSA(Crypto.Hash.SHA256, m),
                'SHA384':    lambda m: doDSA(Crypto.Hash.SHA384, m),
                'SHA512':    lambda m: doDSA(Crypto.Hash.SHA512, m),
            }})

        return OpenPGP.Message([sig, message])
Exemple #3
0
    def encrypt(self, passphrases_and_keys, symmetric_algorithm=9):
        cipher, key_bytes, key_block_bytes = self.get_cipher(
            symmetric_algorithm)
        if not cipher:
            raise Exception("Unsupported cipher")
        prefix = Crypto.Random.new().read(key_block_bytes)
        prefix += prefix[-2:]

        key = Crypto.Random.new().read(key_bytes)
        session_cipher = cipher(key)(None)

        to_encrypt = prefix + self._message.to_bytes()
        mdc = OpenPGP.ModificationDetectionCodePacket(
            Crypto.Hash.SHA.new(to_encrypt + b'\xD3\x14').digest())
        to_encrypt += mdc.to_bytes()

        def doEncrypt(cipher):
            ctx = cipher.encryptor()
            return lambda x: ctx.update(x) + ctx.finalize()

        encrypted = [
            OpenPGP.IntegrityProtectedDataPacket(
                self._block_pad_unpad(key_block_bytes, to_encrypt,
                                      doEncrypt(session_cipher)))
        ]

        if not isinstance(passphrases_and_keys,
                          collections.Iterable) or hasattr(
                              passphrases_and_keys, 'encode'):
            passphrases_and_keys = [passphrases_and_keys]

        for psswd in passphrases_and_keys:
            if isinstance(psswd, OpenPGP.PublicKeyPacket):
                if not psswd.key_algorithm in [1, 2, 3]:
                    raise Exception("Only RSA keys are supported.")
                rsa = self.__class__(psswd).public_key()
                pkcs1 = Crypto.Cipher.PKCS1_v1_5.new(rsa)
                esk = pkcs1.encrypt(
                    pack('!B', symmetric_algorithm) + key +
                    pack('!H', OpenPGP.checksum(key)))
                esk = pack('!H', OpenPGP.bitlength(esk)) + esk
                encrypted = [
                    OpenPGP.AsymmetricSessionKeyPacket(
                        psswd.key_algorithm, psswd.fingerprint(), esk)
                ] + encrypted
            elif hasattr(psswd, 'encode'):
                psswd = psswd.encode('utf-8')
                s2k = OpenPGP.S2K(Crypto.Random.new().read(10))
                packet_cipher = cipher(s2k.make_key(psswd, key_bytes))(None)
                esk = self._block_pad_unpad(
                    key_block_bytes,
                    pack('!B', symmetric_algorithm) + key,
                    doEncrypt(packet_cipher))
                encrypted = [
                    OpenPGP.SymmetricSessionKeyPacket(s2k, esk,
                                                      symmetric_algorithm)
                ] + encrypted

        return OpenPGP.Message(encrypted)
Exemple #4
0
 def test_partial_results(self):
     m = OpenPGP.Message.parse(
         OpenPGP.Message([
             OpenPGP.UserIDPacket('My name <*****@*****.**>'),
             OpenPGP.UserIDPacket('Your name <*****@*****.**>')
         ]).to_bytes())
     m[0]  # Just the first one
     nose.tools.assert_equal(len(m.force()), 2)
Exemple #5
0
 def testEncryptAsymmetric(self):
     key = OpenPGP.Message.parse(
         open(os.path.dirname(__file__) + '/data/helloKey.gpg',
              'rb').read())
     data = OpenPGP.LiteralDataPacket('This is text.', 'u', 'stuff.txt')
     encrypted = OpenPGP.Crypto.Wrapper(OpenPGP.Message([data
                                                         ])).encrypt(key)
     decryptor = OpenPGP.Crypto.Wrapper(key)
     decrypted = decryptor.decrypt(encrypted)
     nose.tools.assert_equal(decrypted[0].data, b'This is text.')
Exemple #6
0
    def sign_key_userid(self, packet, hash='SHA256', keyid=None):
        if isinstance(packet, list):
            packet = OpenPGP.Message(packet)
        elif not isinstance(packet, OpenPGP.Message):
            packet = OpenPGP.Message.parse(packet)

        key = self.key(keyid)
        if not key or not packet: # Missing some data
            return None

        if not keyid:
            keyid = key.fingerprint()[-16:]

        key = self.private_key(keyid)

        sig = None
        for p in packet:
            if isinstance(p, OpenPGP.SignaturePacket):
                sig = p
        if not sig:
            sig = OpenPGP.SignaturePacket(packet, 'RSA', hash.upper())
            sig.signature_type = 0x13
            sig.hashed_subpackets.append(OpenPGP.SignaturePacket.KeyFlagsPacket([0x01]))
            sig.hashed_subpackets.append(OpenPGP.SignaturePacket.IssuerPacket(keyid))
            packet.append(sig)

        def doDSA(h, m):
            return list(key.sign(h.new(m).digest()[0:int(Crypto.Util.number.size(key.q) / 8)],
                Crypto.Random.random.StrongRandom().randint(1,key.q-1)))

        def doRSA(h, m):
            ctx = key.signer(padding.PKCS1v15(), h())
            ctx.update(m)
            return [ctx.finalize()]

        sig.sign_data({'RSA': {
                'MD5':       lambda m: doRSA(hashes.MD5, m),
                'RIPEMD160': lambda m: doRSA(hashes.RIPEMD160, m),
                'SHA1':      lambda m: doRSA(hashes.SHA1, m),
                'SHA224':    lambda m: doRSA(hashes.SHA224, m),
                'SHA256':    lambda m: doRSA(hashes.SHA256, m),
                'SHA384':    lambda m: doRSA(hashes.SHA384, m),
                'SHA512':    lambda m: doRSA(hashes.SHA512, m)
            }, 'DSA': {
                'MD5':       lambda m: doDSA(Crypto.Hash.MD5, m),
                'RIPEMD160': lambda m: doDSA(Crypto.Hash.RIPEMD, m),
                'SHA1':      lambda m: doDSA(Crypto.Hash.SHA, m),
                'SHA224':    lambda m: doDSA(Crypto.Hash.SHA224, m),
                'SHA256':    lambda m: doDSA(Crypto.Hash.SHA256, m),
                'SHA384':    lambda m: doDSA(Crypto.Hash.SHA384, m),
                'SHA512':    lambda m: doDSA(Crypto.Hash.SHA512, m),
            }})

        return packet
Exemple #7
0
    def decrypt(self, packet):
        if isinstance(packet, list):
            packet = OpenPGP.Message(packet)
        elif not isinstance(packet, OpenPGP.Message):
            packet = OpenPGP.Message.parse(packet)

        if isinstance(packet, OpenPGP.SecretKeyPacket) or isinstance(
                packet, rsa.RSAPrivateKey) or (
                    hasattr(packet, '__getitem__')
                    and isinstance(packet[0], OpenPGP.SecretKeyPacket)):
            keys = packet
        else:
            keys = self._key
            self._message = packet

        if not keys or not self._message:
            return None  # Missing some data

        if not isinstance(keys, rsa.RSAPrivateKey):
            keys = self.__class__(keys)

        for p in self._message:
            if isinstance(p, OpenPGP.AsymmetricSessionKeyPacket):
                if isinstance(keys, rsa.RSAPrivateKey):
                    sk = self.try_decrypt_session(keys, p.encrypted_data[2:])
                elif len(p.keyid.replace('0', '')) < 1:
                    for k in keys.key:
                        sk = self.try_decrypt_session(
                            self.convert_private_key(k), p.encyrpted_data[2:])
                        if sk:
                            break
                else:
                    key = keys.private_key(p.keyid)
                    sk = self.try_decrypt_session(key, p.encrypted_data[2:])

                if not sk:
                    continue

                r = self.decrypt_packet(self.encrypted_data(), sk[0], sk[1])
                if r:
                    return r

        return None  # Failed
Exemple #8
0
    def sign(self, packet, hash='SHA256', keyid=None):
        if self._key and not isinstance(packet, OpenPGP.Packet) and not isinstance(packet, OpenPGP.Message):
            packet = OpenPGP.LiteralDataPacket(packet)
        else:
            packet = self._parse_packet(packet)

        if isinstance(packet, OpenPGP.SecretKeyPacket) or isinstance(packet, RSAPrivateKey) or isinstance(packet, DSAPrivateKey) or (hasattr(packet, '__getitem__') and isinstance(packet[0], OpenPGP.SecretKeyPacket)):
            key = packet
            message = self._message
        else:
            key = self._key
            message = packet

        if not key or not message:
            return None # Missing some data

        if isinstance(message, OpenPGP.Message):
            message = message.signature_and_data()[1]

        if not (isinstance(key, RSAPrivateKey) or isinstance(key, DSAPrivateKey)):
            key = self.__class__(key)
            if not keyid:
                keyid = key.key().fingerprint()[-16:]
            key = key.private_key(keyid)

        key_algorithm = None
        if isinstance(key, RSAPrivateKey):
            key_algorithm = 'RSA'
        elif isinstance(key, DSAPrivateKey):
            key_algorithm = 'DSA'

        sig = OpenPGP.SignaturePacket(message, key_algorithm, hash.upper())

        if keyid:
            sig.hashed_subpackets.append(OpenPGP.SignaturePacket.IssuerPacket(keyid))

        def doDSA(h, m):
            ctx = key.signer(h())
            ctx.update(m)
            return list(self._decode_dsa_der(ctx.finalize()))

        def doRSA(h, m):
            ctx = key.signer(padding.PKCS1v15(), h())
            ctx.update(m)
            return [ctx.finalize()]

        sig.sign_data({'RSA': {
                'MD5':       lambda m: doRSA(hashes.MD5, m),
                'RIPEMD160': lambda m: doRSA(hashes.RIPEMD160, m),
                'SHA1':      lambda m: doRSA(hashes.SHA1, m),
                'SHA224':    lambda m: doRSA(hashes.SHA224, m),
                'SHA256':    lambda m: doRSA(hashes.SHA256, m),
                'SHA384':    lambda m: doRSA(hashes.SHA384, m),
                'SHA512':    lambda m: doRSA(hashes.SHA512, m)
            }, 'DSA': {
                'MD5':       lambda m: doDSA(hashes.MD5, m),
                'RIPEMD160': lambda m: doDSA(hashes.RIPME160, m),
                'SHA1':      lambda m: doDSA(hashes.SHA1, m),
                'SHA224':    lambda m: doDSA(hashes.SHA224, m),
                'SHA256':    lambda m: doDSA(hashes.SHA256, m),
                'SHA384':    lambda m: doDSA(hashes.SHA384, m),
                'SHA512':    lambda m: doDSA(hashes.SHA512, m)
            }})

        return OpenPGP.Message([sig, message])