def create_app(test_config=None): app = Flask(__name__, instance_relative_config=True) ca_pub_key, _ = PGPKey.from_file( os.path.join(app.root_path, '..', 'key', 'pub.asc')) ca_sec_key, _ = PGPKey.from_file( os.path.join(app.root_path, '..', 'key', 'sec.asc')) assert ca_sec_key.is_protected assert ca_sec_key.is_unlocked is False app.config.from_mapping( SECRET_KEY='sooO0O0Oo0O0oo0OoOOo-s3cur3', CA_PUB_KEY=ca_pub_key, CA_SEC_KEY=ca_sec_key, CA_PASSPHRASE='is521xyz!', DB=os.path.join(app.instance_path, 'ca.db'), ) try: os.makedirs(app.instance_path) except OSError: pass app.register_blueprint(user.bp) app.register_blueprint(cert.bp) app.teardown_appcontext(db.close_db) if not os.path.isfile(app.config['DB']): with app.app_context(): db.init_db() return app
def test_save(self, kf): # load the key and export it back to binary key, _ = PGPKey.from_file(kf) pgpyblob = key.__bytes__() # try loading the exported key reloaded, _ = PGPKey.from_file(kf) assert pgpyblob == reloaded.__bytes__()
def main(): args = parseargs() # also print info messages logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s') # extract key material from firmware firmware = Firmware(args.fw, args.udid) # bruteforce firmware password if necessary if firmware.locked: if not args.dict: logging.critical("Firmware is password protected: please provide a dictionary with -d option") sys.exit(1) password = bruteforce(args.dict, firmware) if password is None: logging.critical("No valid password found in provided dictionary") sys.exit(1) logging.info("Firmware unlocked with password: {}".format(password)) pubkey, _ = PGPKey.from_file(args.key) privkey = firmware.extract_key(pubkey) if args.out == '-': # export ASCII armored version if writing to stdout sys.stdout.write(str(privkey)) else: with open(args.out, 'wb') as f: # export binary version when writing to file f.write(bytes(privkey))
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
def sign_security_txt(data: str) -> Dict[str, str]: """ Sign security.txt. :param data: data to sign :type data: str :return: templatetag context data :rtype: Dict[str, str] :raises ImproperlyConfigured: in case of bad signing config """ if (settings.SECURITY_TXT_SIGN and not settings.SECURITY_TXT_SIGNING_KEY ) or ( # type: ignore # noqa: E501 not Path(settings.SECURITY_TXT_SIGNING_KEY).exists( ) # type: ignore # noqa: E501 ): raise ImproperlyConfigured key, _ = PGPKey.from_file(filename=settings.SECURITY_TXT_SIGNING_KEY ) # type: ignore # noqa: E501 return { "DATA": data, "SIGNATURE": key.sign(subject=data), }
def test_spurious_dash_escapes(): from pgpy import PGPKey, PGPMessage message_data = r'''-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1,SHA256 - This is stored, literally\! -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.20 (Darwin) iJwEAQECAAYFAlQaCpEACgkQBM3VPIdAqKYrhwQAyQhwiqrR6oZ5fTBm4JyCOEND 72Kxbaz1i9Qh0jv7DmgRjb4udh95UQ8U0qVnmnhA8E2deKeDcWTS4fzUkU6J9OdH /GPHpL9QEtOJ7xifzJsnKaNJVynmNMtYOqHQ9gCmXx7jM2ngxbTKBT8YZlSLMUdO uoUFKrJGv0LWlSWHkeOJARwEAQECAAYFAlQaCpEACgkQKoNNjlkY6IYrhwf/ZnMN yKIVxGl+5/9oovvgz2MtGt9B09xRg4BqD+lUDshzQUvQIjBXZ7ZEGSWqerRymZDg ZzHpb1lv9oAOVU8f1qsMQJJkiz7Q+xu5FfgAp0WzMHJNy4QOmB4Kw/7UbTwdUXzw EzKwbJ8Eg97vJgYdfqUZLu949dwJvyYZzGDdkbrnsaZ8H29XkKXNMlMinDQjvFBR djgkILl3ZIdC3p+KechV3uYsqwje2qNEo69KukihPhzCe9o6/Yub5gdC+DSQDGl4 uPjk0zXjds4G5J5Jd5g4o7vhDWs8InxX4AcLfD6lH1XQ1VCZBpucun5CVsU3dUAv yvO7C7FubDu1GUxdbYheBAERCAAGBQJUGgqRAAoJEKXc3JZkUxQOZ+IA/3KI8Mnl k3jfpRQcvtSYFlU9WZk9SqZX6xirnV7Hloq6AP9ZlivPrJdWmjRyyShkMNgP/c63 cjMX82ahGPUVlyMP4A== =bcSu -----END PGP SIGNATURE----- ''' key = PGPKey.from_file('tests/testdata/keys/rsa.1.pub.asc')[0] message = PGPMessage.from_blob(message_data) assert key.verify(message)
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_verify_wrongkey(self, rsa_pub): wrongkey, _ = PGPKey.from_file( 'tests/testdata/signatures/aptapproval-test.key.asc') sig = PGPSignature.from_file( 'tests/testdata/signatures/debian-sid.sig.asc') with pytest.raises(PGPError): wrongkey.verify(_read('tests/testdata/signatures/debian-sid.subj'), sig)
def test_load_from_file(self, kf, gpg_keyid_file): key, _ = PGPKey.from_file(kf) # TODO: maybe store the fingerprint instead of relying on a particular version of GnuPG...? if 'ecc' in kf and gpg_ver < '2.1': assert key.fingerprint else: assert key.fingerprint.keyid in gpg_keyid_file( kf.replace('tests/testdata/', ''))
def test_sign_encrypted_message(self, sf, cipher): # test decrypting a message sec, _ = PGPKey.from_file(sf) if (sec.fingerprint, cipher) not in self.msgs: pytest.skip('Message not present; see test_encrypt_message skip or xfail reason') emsg = self.msgs[(sec.fingerprint, cipher)] emsg |= sec.sign(emsg) assert emsg.is_signed assert emsg.is_encrypted assert isinstance(next(iter(emsg)), PGPSignature)
def key_from_file(key_path='/tmp/pubkey.asc'): """Create PGPKey object from an armored key file (either public or private) :param key_path: path to the key :return: key :type key_path: string :rtype: PGPKey """ key, _ = PGPKey.from_file(key_path) logger.debug('Imported key with fingerprint %s', key.fingerprint) return key
def main(): parser = argparse.ArgumentParser( description='''Encrypting a relatively small message''') parser.add_argument('pubkey', help='PGP public key') parser.add_argument('file', help='File to encrypt') args = parser.parse_args() message = PGPMessage.new(args.file, file=True) key, _ = PGPKey.from_file(args.pubkey) enc = key.encrypt(message) sys.stdout.buffer.write(bytes(enc))
def test_load_key_instance(self, keyring, kf): key, _ = PGPKey.from_file(kf) keys = keyring.load(key) assert key.fingerprint in keyring for uid in key.userids: if uid.name != "": assert uid.name in keyring if uid.email != "": assert uid.email in keyring with keyring.key(key.fingerprint) as loaded_key: assert loaded_key.fingerprint == key.fingerprint
def test_sign_encrypted_message(self, sf, cipher): # test decrypting a message sec, _ = PGPKey.from_file(sf) if (sec.fingerprint, cipher) not in self.msgs: pytest.skip( 'Message not present; see test_encrypt_message skip or xfail reason' ) emsg = self.msgs[(sec.fingerprint, cipher)] emsg |= sec.sign(emsg) assert emsg.is_signed assert emsg.is_encrypted assert isinstance(next(iter(emsg)), PGPSignature)
def test_decrypt_message(self, sf, cipher): # test decrypting a message sec, _ = PGPKey.from_file(sf) if (sec.fingerprint, cipher) not in self.msgs: pytest.skip('Message not present; see test_encrypt_message skip or xfail reason') emsg = self.msgs[(sec.fingerprint, cipher)] dmsg = sec.decrypt(emsg) assert dmsg.message == "This message will have been encrypted" # now check with GnuPG, if possible if gpg_ver < '2.1' and sec.key_algorithm in {PubKeyAlgorithm.ECDSA, PubKeyAlgorithm.ECDH}: # GnuPG prior to 2.1.x does not support EC* keys, so skip this step return assert self.gpg_decrypt(emsg, sec).decode('utf-8') == dmsg.message
def get_private_key(self, fingerprint: str) -> Optional[PGPKey]: expected_fingerprint = Fingerprint(fingerprint) key_file = self._get_private_key_location(expected_fingerprint) try: key, _ = PGPKey.from_file(key_file) except FileNotFoundError: return None if not key.fingerprint == expected_fingerprint: raise CustomException("Actual fingerprint for stored private key does not match expected one. ({})".format( expected_fingerprint)) self._strip_signatures_uids_subkeys(key) pubkey = self.get_key(key.fingerprint.keyid, key.fingerprint) if pubkey is None: raise CustomException( "Missing public key for fingerprint {}, while private is available".format(expected_fingerprint)) return self._combine_key_parts([pubkey, key])
def test_decrypt_message(self, sf, cipher): # test decrypting a message sec, _ = PGPKey.from_file(sf) if (sec.fingerprint, cipher) not in self.msgs: pytest.skip( 'Message not present; see test_encrypt_message skip or xfail reason' ) emsg = self.msgs[(sec.fingerprint, cipher)] dmsg = sec.decrypt(emsg) assert dmsg.message == "This message will have been encrypted" # now check with GnuPG, if possible if gpg_ver < '2.1' and sec.key_algorithm in { PubKeyAlgorithm.ECDSA, PubKeyAlgorithm.ECDH }: # GnuPG prior to 2.1.x does not support EC* keys, so skip this step return assert self.gpg_decrypt(emsg, sec).decode('utf-8') == dmsg.message
def test_decrypt_message(self, sf, cipher, gpg_import, gpg_print): # test decrypting a message sec, _ = PGPKey.from_file(sf) if (sec.fingerprint, cipher) not in self.msgs: pytest.skip('Message not present; see test_encrypt_message skip or xfail reason') emsg = self.msgs[(sec.fingerprint, cipher)] dmsg = sec.decrypt(emsg) assert dmsg.message == "This message will have been encrypted" # now check with GnuPG, if possible if gpg_ver < '2.1' and sec.key_algorithm in {PubKeyAlgorithm.ECDSA, PubKeyAlgorithm.ECDH}: # GnuPG prior to 2.1.x does not support EC* keys, so skip this step return with tempfile.NamedTemporaryFile('w+') as emsgf: emsgf.write(str(emsg)) emsgf.flush() with gpg_import(os.path.realpath(sf)) as kf: assert gpg_print(emsgf.name) == dmsg.message
def key(fn): key, _ = PGPKey.from_file(fn) return key
usage={KeyFlags.EncryptCommunications, KeyFlags.EncryptStorage}) return key @pytest.fixture(scope='module') def targette_pub(): return PGPKey.from_file('tests/testdata/keys/targette.pub.rsa.asc')[0] @pytest.fixture(scope='module') def targette_sec(): return PGPKey.from_file('tests/testdata/keys/targette.sec.rsa.asc')[0] seckeys = [ PGPKey.from_file(f)[0] for f in sorted(glob.glob('tests/testdata/keys/*.sec.asc')) ] pubkeys = [ PGPKey.from_file(f)[0] for f in sorted(glob.glob('tests/testdata/keys/*.pub.asc')) ] class TestPGPKey_Actions(object): sigs = {} msgs = {} def gpg_verify(self, subject, sig=None, pubkey=None): # verify with GnuPG with gpg.Context(armor=True, offline=True) as c:
def rsa_enc(): return PGPKey.from_file('tests/testdata/keys/rsa.1.enc.asc')[0]
def rsa_pub(): return PGPKey.from_file('tests/testdata/keys/rsa.1.pub.asc')[0]
def test_load_from_file(self, gpg_keyid_file): key, _ = PGPKey.from_file(self.kf) assert key.fingerprint.keyid in gpg_keyid_file(self.kf.replace('tests/testdata/', ''))
def targette_sec(): return PGPKey.from_file('tests/testdata/keys/targette.sec.rsa.asc')[0]
def targette_pub(): return PGPKey.from_file('tests/testdata/keys/targette.pub.rsa.asc')[0]
key.add_uid(uphoto) key.add_subkey(subkey, usage={KeyFlags.EncryptCommunications, KeyFlags.EncryptStorage}) return key @pytest.fixture(scope='module') def targette_pub(): return PGPKey.from_file('tests/testdata/keys/targette.pub.rsa.asc')[0] @pytest.fixture(scope='module') def targette_sec(): return PGPKey.from_file('tests/testdata/keys/targette.sec.rsa.asc')[0] seckeys = [ PGPKey.from_file(f)[0] for f in sorted(glob.glob('tests/testdata/keys/*.sec.asc')) ] pubkeys = [ PGPKey.from_file(f)[0] for f in sorted(glob.glob('tests/testdata/keys/*.pub.asc')) ] class TestPGPKey_Actions(object): sigs = {} msgs = {} def gpg_verify(self, subject, sig=None, pubkey=None): # verify with GnuPG with gpg.Context(armor=True, offline=True) as c: c.set_engine_info(gpg.constants.PROTOCOL_OpenPGP, home_dir=gnupghome) # do we need to import the key? if pubkey: try:
sk = s2k.derive_key('sooper_sekret_passphrase') elapsed = rtime() - start # check that we're actually close to our target assert len(sk) == 32 try: assert 0.1 <= round(elapsed, 1) <= 0.2 except AssertionError: warnings.warn("tuned_count: {}; elapsed time: {:.5f}".format( pgpy.constants.HashAlgorithm.SHA256.tuned_count, elapsed)) _seckeys = { sk.key_algorithm.name: sk for sk in (PGPKey.from_file(f)[0] for f in sorted(glob.glob('tests/testdata/keys/*.sec.asc'))) } seckm = [ _seckeys['DSA']._key, # DSA private key packet _seckeys['DSA'].subkeys['1FD6D5D4DA0170C4']. _key, # ElGamal private key packet _seckeys['RSAEncryptOrSign']._key, # RSA private key packet _seckeys['ECDSA']._key, # ECDSA private key packet _seckeys['ECDSA'].subkeys['A81B93FD16BD9806']. _key, # ECDH private key packet ] @pytest.mark.regression(issue=172) @pytest.mark.parametrize('keypkt', seckm, ids=[sk.pkalg.name for sk in seckm])
def test_load_from_file(self, kf): key, _ = PGPKey.from_file(kf) assert key.fingerprint == _fingerprints[os.path.basename(kf)]
s2k.count = pgpy.constants.HashAlgorithm.SHA256.tuned_count start = rtime() sk = s2k.derive_key('sooper_sekret_passphrase') elapsed = rtime() - start # check that we're actually close to our target assert len(sk) == 32 try: assert 0.1 <= round(elapsed, 1) <= 0.2 except AssertionError: warnings.warn("tuned_count: {}; elapsed time: {:.5f}".format(pgpy.constants.HashAlgorithm.SHA256.tuned_count, elapsed)) _seckeys = {sk.key_algorithm.name: sk for sk in (PGPKey.from_file(f)[0] for f in sorted(glob.glob('tests/testdata/keys/*.sec.asc')))} seckm = [ _seckeys['DSA']._key, # DSA private key packet _seckeys['DSA'].subkeys['1FD6D5D4DA0170C4']._key, # ElGamal private key packet _seckeys['RSAEncryptOrSign']._key, # RSA private key packet _seckeys['ECDSA']._key, # ECDSA private key packet _seckeys['ECDSA'].subkeys['A81B93FD16BD9806']._key, # ECDH private key packet ] @pytest.mark.regression(issue=172) @pytest.mark.parametrize('keypkt', seckm, ids=[sk.pkalg.name for sk in seckm]) def test_check_checksum(keypkt): # this test is dirty and simple # take the key packet provided, and store the key material checksum # recompute the checksum, and ensure they match
def test_verify_wrongkey(self, rsa_pub): wrongkey, _ = PGPKey.from_file('tests/testdata/signatures/aptapproval-test.key.asc') sig = PGPSignature.from_file('tests/testdata/signatures/debian-sid.sig.asc') with pytest.raises(PGPError): wrongkey.verify(_read('tests/testdata/signatures/debian-sid.subj'), sig)
key.add_uid(uphoto) key.add_subkey(subkey, usage={KeyFlags.EncryptCommunications, KeyFlags.EncryptStorage}) return key @pytest.fixture(scope='module') def targette_pub(): return PGPKey.from_file('tests/testdata/keys/targette.pub.rsa.asc')[0] @pytest.fixture(scope='module') def targette_sec(): return PGPKey.from_file('tests/testdata/keys/targette.sec.rsa.asc')[0] seckeys = [ PGPKey.from_file(f)[0] for f in sorted(glob.glob('tests/testdata/keys/*.sec.asc')) ] pubkeys = [ PGPKey.from_file(f)[0] for f in sorted(glob.glob('tests/testdata/keys/*.pub.asc')) ] class TestPGPKey_Actions(object): sigs = {} msgs = {} def gpg_verify(self, subject, sig, pubkey): # verify with GnuPG from conftest import gpg_import as gpgi from conftest import gpg_verify as gpgv gpg_import = gpgi() gpg_verify = gpgv() with tempfile.NamedTemporaryFile('w+') as sigf, \
""" EggdraSyl - Bismuth Foundation Read a PGP public key and converts to X.509 format (Bismuth .der, b64 encoded) Also shows the matching BIS Address """ from Cryptodome.PublicKey import RSA from pgpy import PGPKey, PGPKeyring from hashlib import sha224 # Use either armored or binary key # key, _ = PGPKey.from_file('DA3B9CAB.pub.asc') key, _ = PGPKey.from_file('DA3B9CAB.pub.bin') # print(key.key_size, key.key_algorithm, key.pubkey, key._key.__dict__, key._key.keymaterial.__dict__) key_pub = RSA.construct((key._key.keymaterial.n, key._key.keymaterial.e), consistency_check=True) key_public_export = key_pub.exportKey('PEM') address = sha224(key_public_export).hexdigest() print("Address", address) with open('public.pem', 'wb') as f: f.write(key_public_export) print("Saved to public.pem")
def test_gpg_ed25519_verify(self, abe): # test verification of Ed25519 signature generated by GnuPG pubkey, _ = PGPKey.from_file('tests/testdata/keys/ecc.2.pub.asc') sig = PGPSignature.from_file('tests/testdata/signatures/ecc.2.sig.asc') assert pubkey.verify("This is a test signature message", sig)
def test_load_from_file(self, gpg_keyid_file): key, _ = PGPKey.from_file(self.kf) assert key.fingerprint.keyid in gpg_keyid_file( self.kf.replace('tests/testdata/', ''))