def test_firmware_pass(algo):
    # test firmware decryption with wrong and correct password
    firmware = Firmware("firmwares/{}.pass.firmware.bin".format(algo), UDID)
    assert firmware.locked
    assert not firmware.unlock(WRONGPW)
    assert firmware.unlock(GOODPW)
    assert not firmware.locked

    # extract private key from firmware
    pubkey, _ = PGPKey.from_file("pubkeys/{}.pub.key.asc".format(algo))
    privkey = firmware.extract_key(pubkey)
    assert privkey is not None

    # test message decryption
    subk = get_key_with_flag(privkey, KeyFlags.EncryptCommunications)
    assert subk is not None
    enc = PGPMessage.from_file("messages/{}.enc.msg.gpg".format(algo))
    dec = subk.decrypt(enc)
    assert bytes(dec.message) == MESSAGE

    # test signature
    subk = get_key_with_flag(privkey, KeyFlags.Sign)
    assert subk is not None
    msg = PGPMessage.new(MESSAGE, compression=CompressionAlgorithm.Uncompressed)
    sig = subk.sign(msg)
    subk = get_key_with_flag(pubkey, KeyFlags.Sign)
    assert subk is not None
    assert subk.verify(MESSAGE, sig)
def test_firmware_nopass(algo):
    # extract private key from firmware
    firmware = Firmware("firmwares/{}.firmware.bin".format(algo), UDID)
    assert not firmware.locked
    pubkey, _ = PGPKey.from_file("pubkeys/{}.pub.key.asc".format(algo))
    privkey = firmware.extract_key(pubkey)
    assert privkey is not None

    # test message decryption
    subk = get_key_with_flag(privkey, KeyFlags.EncryptCommunications)
    assert subk is not None
    enc = PGPMessage.from_file("messages/{}.enc.msg.gpg".format(algo))
    dec = subk.decrypt(enc)
    assert bytes(dec.message) == MESSAGE

    # test signature: except Ed25519 which cannot be extracted
    subk = get_key_with_flag(privkey, KeyFlags.Sign)
    if algo != 'curve25519':
        assert subk is not None
        msg = PGPMessage.new(MESSAGE, compression=CompressionAlgorithm.Uncompressed)
        sig = subk.sign(msg)
        subk = get_key_with_flag(pubkey, KeyFlags.Sign)
        assert subk is not None
        assert subk.verify(MESSAGE, sig)
    else:
        assert subk is None
Exemple #3
0
 def test_gpg_cv25519_decrypt(self, abe):
     # test the decryption of X25519 generated by GnuPG
     seckey, _ = PGPKey.from_file('tests/testdata/keys/ecc.2.sec.asc')
     emsg = PGPMessage.from_file(
         'tests/testdata/messages/message.ecdh.cv25519.asc')
     with warnings.catch_warnings():
         warnings.simplefilter('ignore')
         dmsg = seckey.decrypt(emsg)
     assert bytes(dmsg.message) == b"This message will have been encrypted"
    def test_load_from_file(self, msgfile):
        # TODO: figure out a good way to verify that all went well here, because
        #       PGPy reorders signatures sometimes, and also unwraps compressed messages
        #       so comparing str(msg) to the contents of msgfile doesn't actually work
        msg = PGPMessage.from_file(msgfile)

        with open(msgfile, 'r') as mf:
            mt = mf.read()

            assert len(str(msg)) == len(mt)
    def test_load_from_file(self, msgfile):
        # TODO: figure out a good way to verify that all went well here, because
        #       PGPy reorders signatures sometimes, and also unwraps compressed messages
        #       so comparing str(msg) to the contents of msgfile doesn't actually work
        msg = PGPMessage.from_file(msgfile)

        with open(msgfile, 'r') as mf:
            mt = mf.read()

            assert len(str(msg)) == len(mt)
from pgpy.constants import CompressionAlgorithm
from pgpy.constants import EllipticCurveOID
from pgpy.constants import Features
from pgpy.constants import HashAlgorithm
from pgpy.constants import KeyFlags
from pgpy.constants import KeyServerPreferences
from pgpy.constants import PubKeyAlgorithm
from pgpy.constants import RevocationReason
from pgpy.constants import SignatureType
from pgpy.constants import SymmetricKeyAlgorithm
from pgpy.packet import Packet
from pgpy.packet.packets import PrivKeyV4
from pgpy.packet.packets import PrivSubKeyV4


enc_msgs = [ PGPMessage.from_file(f) for f in sorted(glob.glob('tests/testdata/messages/message*.pass*.asc')) ]


class TestPGPMessage(object):
    @staticmethod
    def gpg_message(msg):
        with gpg.Context(offline=True) as c:
            c.set_engine_info(gpg.constants.PROTOCOL_OpenPGP, home_dir=gnupghome)
            msg, _ = c.verify(gpg.Data(string=str(msg)))
        return msg

    @staticmethod
    def gpg_decrypt(msg, passphrase):
        try:
            with gpg.Context(armor=True, offline=True, pinentry_mode=gpg.constants.PINENTRY_MODE_LOOPBACK) as c:
                c.set_engine_info(gpg.constants.PROTOCOL_OpenPGP, file_name='/usr/bin/gpg', home_dir=gnupghome)
 def test_decrypt_unencrypted(self):
     msg = PGPMessage.from_file('tests/testdata/messages/message.signed.asc')
     with pytest.raises(PGPError):
         msg.decrypt("Password")
Exemple #8
0
class TestPGPMessage(object):
    params = {
        'comp_alg':
        comp_algs,
        'enc_msg': [
            PGPMessage.from_file(f)
            for f in glob.glob('tests/testdata/messages/message*.pass*.asc')
        ],
        'file':
        sorted(glob.glob('tests/testdata/files/literal*')),
    }
    ids = {
        'test_new': [str(ca).split('.')[-1] for ca in comp_algs],
        'test_new_from_file':
        [os.path.basename(fn).replace('.', '_') for fn in params['file']],
    }
    attrs = {
        'tests/testdata/files/literal.1.txt':
        [('filename', 'literal.1.txt'),
         ('message',
          os.linesep.join(['This is stored, literally\!', os.linesep]))],
        'tests/testdata/files/literal.2.txt': [
            ('filename', 'literal.2.txt'),
            ('message',
             os.linesep.join(['This is stored, literally!', os.linesep]))
        ],
        'tests/testdata/files/literal.dashesc.txt':
        [('filename', 'literal.dashesc.txt'),
         ('message',
          os.linesep.join([
              'The following items are stored, literally:', '- This one',
              '- Also this one', '- And finally, this one!', os.linesep
          ]))],
        'tests/testdata/files/literal.bin':
        [('filename', 'literal.bin'), ('message', bytearray(range(256)))],
    }

    def test_new(self, comp_alg, write_clean, gpg_print):
        msg = PGPMessage.new(u"This is a new message!", compression=comp_alg)

        assert msg.filename == ''
        assert msg.type == 'literal'
        assert msg.message == u"This is a new message!"
        assert msg._message.format == 'u'
        assert msg._message.filename == ''
        assert msg.is_compressed is bool(
            comp_alg != CompressionAlgorithm.Uncompressed)

        with write_clean('tests/testdata/cmsg.asc', 'w', str(msg)):
            assert gpg_print('cmsg.asc') == "This is a new message!"

    def test_new_sensitive(self, write_clean, gpg_print):
        msg = PGPMessage.new("This is a sensitive message!", sensitive=True)

        assert msg.type == 'literal'
        assert msg.message == "This is a sensitive message!"
        assert msg.is_sensitive
        assert msg.filename == '_CONSOLE'

        with write_clean('tests/testdata/csmsg.asc', 'w', str(msg)):
            assert gpg_print('csmsg.asc') == "This is a sensitive message!"

    @pytest.mark.regression(issue=154)
    def test_new_non_unicode(self, write_clean, gpg_print):
        # this message text comes from http://www.columbia.edu/~fdc/utf8/
        text = u'色は匂へど 散りぬるを\n' \
               u'我が世誰ぞ 常ならむ\n' \
               u'有為の奥山 今日越えて\n' \
               u'浅き夢見じ 酔ひもせず\n'
        msg = PGPMessage.new(text.encode('jisx0213'), encoding='jisx0213')

        assert msg.type == 'literal'
        assert msg.message == text.encode('jisx0213')

    @pytest.mark.regression(issue=154)
    def test_new_non_unicode_cleartext(self, write_clean, gpg_print):
        # this message text comes from http://www.columbia.edu/~fdc/utf8/
        text = u'色は匂へど 散りぬるを\n' \
               u'我が世誰ぞ 常ならむ\n' \
               u'有為の奥山 今日越えて\n' \
               u'浅き夢見じ 酔ひもせず\n'

        msg = PGPMessage.new(text.encode('jisx0213'),
                             cleartext=True,
                             encoding='jisx0213')

        assert msg.type == 'cleartext'
        assert msg.message == text

    def test_new_from_file(self, file, write_clean, gpg_print):
        msg = PGPMessage.new(file, file=True)

        assert isinstance(msg, PGPMessage)
        assert msg.type == 'literal'
        assert msg.is_sensitive is False

        assert file in self.attrs
        for attr, expected in self.attrs[file]:
            val = getattr(msg, attr)
            assert val == expected

        with write_clean('tests/testdata/cmsg.asc', 'w', str(msg)):
            out = gpg_print('cmsg.asc')
            if msg._message.format == 'b':
                out = out.encode('latin-1')
            assert out == msg.message

    def test_add_marker(self):
        msg = PGPMessage.new(u"This is a new message")
        marker = Packet(bytearray(b'\xa8\x03\x50\x47\x50'))
        msg |= marker

    def test_decrypt_passphrase_message(self, enc_msg):
        decmsg = enc_msg.decrypt("QwertyUiop")

        assert isinstance(decmsg, PGPMessage)
        assert decmsg.message == b"This is stored, literally\\!\n\n"

    def test_encrypt_passphrase(self, write_clean, gpg_decrypt):
        msg = PGPMessage.new("This message is to be encrypted")
        encmsg = msg.encrypt("QwertyUiop")

        # make sure lit was untouched
        assert not msg.is_encrypted

        # make sure encmsg is encrypted
        assert encmsg.is_encrypted
        assert encmsg.type == 'encrypted'

        # decrypt with PGPy
        decmsg = encmsg.decrypt("QwertyUiop")

        assert isinstance(decmsg, PGPMessage)
        assert decmsg.type == msg.type
        assert decmsg.is_compressed
        assert decmsg.message == msg.message

        # decrypt with GPG
        with write_clean('tests/testdata/semsg.asc', 'w', str(encmsg)):
            assert gpg_decrypt(
                './semsg.asc',
                "QwertyUiop") == "This message is to be encrypted"

    def test_encrypt_passphrase_2(self, write_clean, gpg_decrypt):
        msg = PGPMessage.new("This message is to be encrypted")
        sk = SymmetricKeyAlgorithm.AES256.gen_key()
        encmsg = msg.encrypt("QwertyUiop",
                             sessionkey=sk).encrypt("AsdfGhjkl", sessionkey=sk)

        # make sure lit was untouched
        assert not msg.is_encrypted

        # make sure encmsg is encrypted
        assert encmsg.is_encrypted
        assert encmsg.type == 'encrypted'
        assert len(encmsg._sessionkeys) == 2

        # decrypt with PGPy
        for passphrase in ["QwertyUiop", "AsdfGhjkl"]:
            decmsg = encmsg.decrypt(passphrase)
            assert isinstance(decmsg, PGPMessage)
            assert decmsg.type == msg.type
            assert decmsg.is_compressed
            assert decmsg.message == msg.message
Exemple #9
0
from pgpy.constants import CompressionAlgorithm
from pgpy.constants import EllipticCurveOID
from pgpy.constants import Features
from pgpy.constants import HashAlgorithm
from pgpy.constants import KeyFlags
from pgpy.constants import KeyServerPreferences
from pgpy.constants import PubKeyAlgorithm
from pgpy.constants import RevocationReason
from pgpy.constants import SignatureType
from pgpy.constants import SymmetricKeyAlgorithm
from pgpy.packet import Packet
from pgpy.packet.packets import PrivKeyV4
from pgpy.packet.packets import PrivSubKeyV4

enc_msgs = [
    PGPMessage.from_file(f)
    for f in sorted(glob.glob('tests/testdata/messages/message*.pass*.asc'))
]


class TestPGPMessage(object):
    @staticmethod
    def gpg_message(msg):
        with gpg.Context(offline=True) as c:
            c.set_engine_info(gpg.constants.PROTOCOL_OpenPGP,
                              home_dir=gnupghome)
            msg, _ = c.verify(gpg.Data(string=str(msg)))
        return msg

    @staticmethod
    def gpg_decrypt(msg, passphrase):
Exemple #10
0
 def test_decrypt_wrongpass(self):
     msg = PGPMessage.from_file(
         next(f for f in glob.glob(
             'tests/testdata/messages/message*.pass*.asc')))
     with pytest.raises(PGPDecryptionError):
         msg.decrypt("TheWrongPassword")
Exemple #11
0
from pgpy.constants import CompressionAlgorithm
from pgpy.constants import EllipticCurveOID
from pgpy.constants import Features
from pgpy.constants import HashAlgorithm
from pgpy.constants import KeyFlags
from pgpy.constants import KeyServerPreferences
from pgpy.constants import PubKeyAlgorithm
from pgpy.constants import RevocationReason
from pgpy.constants import SignatureType
from pgpy.constants import SymmetricKeyAlgorithm
from pgpy.packet import Packet
from pgpy.packet.packets import PrivKeyV4
from pgpy.packet.packets import PrivSubKeyV4


enc_msgs = [ PGPMessage.from_file(f) for f in sorted(glob.glob('tests/testdata/messages/message*.pass*.asc')) ]


class TestPGPMessage(object):
    @pytest.mark.parametrize('comp_alg,sensitive',
                             itertools.product(CompressionAlgorithm, [False, True]))
    def test_new(self, comp_alg, sensitive, gpg_print):
        mtxt = u"This is a new message!"
        msg = PGPMessage.new(mtxt, compression=comp_alg, sensitive=sensitive)

        assert isinstance(msg, PGPMessage)
        assert msg.filename == ('_CONSOLE' if sensitive else '')
        assert msg.is_sensitive is sensitive
        assert msg.type == 'literal'
        assert msg.message == mtxt
        assert msg._compression == comp_alg
    # integers are kind of a special case.
    #   ints that do not exceed sys.maxsize are singletons, and in either case are immutable
    #   this shouldn't apply to MPIs, though, which are subclasses of int
    if isinstance(obj, int) and not isinstance(obj, pgpy.packet.types.MPI):
        return False

    return True


def ksort(key):
    # return a tuple of key, key.count('.') so we get a descending alphabetical, ascending depth ordering
    return key, key.count('.')


objs = [sig(), uid(),] + [PGPMessage.from_file(m) for m in _msgs] + [key(f) for f in _keys]
cids = ['sig', 'uid',] + [os.path.basename(m) for m in _msgs] + [os.path.basename(f) for f in _keys]


@pytest.mark.parametrize('obj', objs, ids=cids)
def test_copy_obj(request, obj):
    obj2 = copy.copy(obj)

    objflat = {name: val for name, val in walk_obj(obj, '{}.'.format(request.node.callspec.id))}
    obj2flat = {name: val for name, val in walk_obj(obj2, '{}.'.format(request.node.callspec.id))}

    for k in sorted(objflat, key=ksort):
        print("checking attribute: {} ".format(k), end="")
        if isinstance(objflat[k], pgpy.types.SorteDeque):
            print("[SorteDeque] ", end="")
            assert len(objflat[k]) == len(obj2flat[k])
Exemple #13
0
    #   this shouldn't apply to MPIs, though, which are subclasses of int
    if isinstance(obj, int) and not isinstance(obj, pgpy.packet.types.MPI):
        return False

    return True


def ksort(key):
    # return a tuple of key, key.count('.') so we get a descending alphabetical, ascending depth ordering
    return key, key.count('.')


objs = [
    sig(),
    uid(),
] + [PGPMessage.from_file(m) for m in _msgs] + [key(f) for f in _keys]
cids = [
    'sig',
    'uid',
] + [os.path.basename(m)
     for m in _msgs] + [os.path.basename(f) for f in _keys]


@pytest.mark.parametrize('obj', objs, ids=cids)
def test_copy_obj(request, obj):
    obj2 = copy.copy(obj)

    objflat = {
        name: val
        for name, val in walk_obj(obj, '{}.'.format(request.node.callspec.id))
    }
Exemple #14
0
class TestCopy(object):
    params = {
        'obj': [sig(), uid()] + [PGPMessage.from_file(m)
                                 for m in _msgs] + [key(fn) for fn in _keys],
    }
    ids = {
        'test_copy_obj': ['sig', 'uid'] +
        ['-'.join(os.path.basename(fn).split('.')[:3]) for fn in _msgs] +
        ['-'.join(os.path.basename(fn).split('.')[:3]) for fn in _keys],
    }

    @staticmethod
    def check_id(obj):
        from datetime import datetime
        from enum import Enum

        # do some type checking to determine if we should check the identity of an object member
        # these types are singletons
        if isinstance(obj, (Enum, bool, type(None))):
            return False

        # these types are immutable
        if isinstance(obj, (six.string_types, datetime)):
            return False

        # integers are kind of a special case.
        #   ints that do not exceed sys.maxsize are singletons, and in either case are immutable
        #   this shouldn't apply to MPIs, though, which are subclasses of int
        if isinstance(obj, int) and not isinstance(obj, pgpy.packet.types.MPI):
            return False

        return True

    @staticmethod
    def ksort(key):
        # return a tuple of key, key.count('.') so we get a descending alphabetical, ascending depth ordering
        return key, key.count('.')

    def test_copy_obj(self, request, obj):
        obj2 = copy.copy(obj)

        objflat = {
            name: val
            for name, val in walk_obj(obj, '{}.'.format(
                request.node.callspec.id))
        }
        obj2flat = {
            name: val
            for name, val in walk_obj(obj2, '{}.'.format(
                request.node.callspec.id))
        }

        for k in sorted(objflat, key=self.ksort):
            print("checking attribute: {} ".format(k), end="")
            if isinstance(objflat[k], pgpy.types.SorteDeque):
                print("[SorteDeque] ", end="")
                assert len(objflat[k]) == len(obj2flat[k])

            if not isinstance(objflat[k],
                              (pgpy.types.PGPObject, pgpy.types.SorteDeque)):
                print("[{} ]".format(type(objflat[k])), end="")
                assert objflat[k] == objflat[k], k

            # check identity, but only types that should definitely be copied
            if self.check_id(objflat[k]):
                print("[id] {}".format(type(objflat[k])))
                assert objflat[k] is not obj2flat[k], "{}: {}".format(
                    type(objflat[k]), k)

            else:
                print()
Exemple #15
0
 def test_decrypt_wrongkey(self, targette_sec):
     msg = PGPMessage.from_file(
         'tests/testdata/messages/message.rsa.cast5.asc')
     with pytest.raises(PGPError):
         targette_sec.decrypt(msg)
Exemple #16
0
 def test_decrypt_unsupported_algorithm(self):
     msg = PGPMessage.from_file('tests/testdata/message.enc.twofish.asc')
     with pytest.raises(PGPDecryptionError):
         msg.decrypt("QwertyUiop")
 def test_decrypt_wrongkey(self, targette_sec):
     msg = PGPMessage.from_file('tests/testdata/messages/message.rsa.cast5.asc')
     with pytest.raises(PGPError):
         targette_sec.decrypt(msg)
Exemple #18
0
 def test_decrypt_unencrypted(self):
     msg = PGPMessage.from_file(
         'tests/testdata/messages/message.signed.asc')
     with pytest.raises(PGPError):
         msg.decrypt("Password")
 def test_decrypt_unsupported_algorithm(self):
     msg = PGPMessage.from_file('tests/testdata/message.enc.twofish.asc')
     with pytest.raises(PGPDecryptionError):
         msg.decrypt("QwertyUiop")
 def test_decrypt_wrongpass(self):
     msg = PGPMessage.from_file(next(f for f in glob.glob('tests/testdata/messages/message*.pass*.asc')))
     with pytest.raises(PGPDecryptionError):
         msg.decrypt("TheWrongPassword")
Exemple #21
0
from pgpy import PGPKey, PGPMessage, constants
from pyspark.sql.types import StructType, StructField, StringType, IntegerType
from pyspark.sql.functions import percent_rank, col
from pyspark.sql.window import Window

if 'PYSPARK_DRIVER_PYTHON' not in os.environ.keys(
) and 'PYSPARK_DRIVER_PYTHON' not in os.environ.keys():
    os.environ['PYSPARK_DRIVER_PYTHON'] = 'python3.6'
    os.environ['PYSPARK_PYTHON'] = 'python3.6'

# Decrypt CSV file
# https://pgpy.readthedocs.io/en/latest/examples.html
titanic = open('titanic.csv', 'w')
key, _ = PGPKey.from_file('slim.shady.sec.asc')

message_from_blob = PGPMessage.from_file('titanic.csv.gpg')
dec_mess = key.decrypt(message_from_blob)
csv_result = dec_mess.message
titanic.write(csv_result.decode('UTF-8'))

# Setting up our DataFrame
sc = pyspark.SparkContext()
sql_ctx = pyspark.SQLContext(sc)

# Explicitly setting the schema type - may be unnecessary
# Notes: https://stackoverflow.com/questions/44706398/spark-csv-reader-quoted-numerics
schema = StructType([
    StructField("RecId", IntegerType(), True),
    StructField("Name", StringType(), True),
    StructField("PassengerClass", StringType(), True),
    StructField("Age", IntegerType(), True),