forked from secure-systems-lab/securesystemslib
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is in preparation for the removal of legacy key modules and formats, in favor of the new Signer API. It allows users to convert their old rsa, ed25519 and ecdsa key files, generated with the `interface` or `keys` module, and using an outdated standard or sslib proprietary format (see secure-systems-lab#309), to a consistent new standard format, which can be used with the file-based signer (`CryptoSigner`) of the new Signer API. NOTE: The script uses legacy code and should thus be removed with them, from the repo tree, while remaining available to users of securesystemslib for some time. We could keep pointing to it in docs after its removal (users would need to check-out the repo at a specified tag), or move it to a different place. *Change details* * Add cli script to convert key files. * Add private/private encrypted/public test key files for each supported algorithm in the legacy format. **The key pairs were generated with `interface`, minimally modified to allow writing an encrypted and non-encrypted version of the same private key. * Add comprehensive tests, includes backwards/forward compatibility of signatures. Signed-off-by: Lukas Puehringer <[email protected]>
- Loading branch information
Showing
11 changed files
with
353 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
#!/usr/bin/env python | ||
"""CLI script to migrate legacy keys to standard format | ||
Convert legacy key files created via `securesystemslib.interface` or | ||
`securesystemslib.keys` to a standard format, e.g. for use with `CryptoSigner` | ||
of the Signer API (see CRYPTO_SIGNER.md). | ||
Standard format for all algorithms | ||
---------------------------------- | ||
* private: PEM/PKCS8 | ||
* public: PEM/subjectPublicKeyInfo | ||
NOTE: Auto-generated keyids are likely to change after migration. Make sure to | ||
set keyids of new signers explicitly, by passing a public key with the desired | ||
keyid, or adopt changes in any delegations in TUF or in-toto. | ||
""" | ||
import argparse | ||
|
||
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey | ||
from cryptography.hazmat.primitives.serialization import ( | ||
BestAvailableEncryption, | ||
Encoding, | ||
NoEncryption, | ||
PrivateFormat, | ||
PublicFormat, | ||
load_pem_public_key, | ||
) | ||
|
||
from securesystemslib import interface as legacy | ||
from securesystemslib.signer import CryptoSigner | ||
|
||
|
||
def migrate_private(path_in, algo, password): | ||
"""Migrate private key""" | ||
legacy_key = legacy.import_privatekey_from_file(path_in, algo, password) | ||
crypto_signer = CryptoSigner.from_securesystemslib_key(legacy_key) | ||
|
||
if password: | ||
encryption_algorithm = BestAvailableEncryption(password.encode()) | ||
else: | ||
encryption_algorithm = NoEncryption() | ||
|
||
private_key = crypto_signer._private_key # pylint: disable=protected-access | ||
|
||
return private_key.private_bytes( | ||
encoding=Encoding.PEM, | ||
format=PrivateFormat.PKCS8, | ||
encryption_algorithm=encryption_algorithm, | ||
) | ||
|
||
|
||
def migrate_public(path_in, algo): | ||
"""Migrate public key""" | ||
legacy_keys = legacy.import_publickeys_from_file([path_in], [algo]) | ||
legacy_key = list(legacy_keys.values())[0] | ||
|
||
if algo in ["rsa", "ecdsa"]: | ||
public_key = load_pem_public_key( | ||
legacy_key["keyval"]["public"].encode() | ||
) | ||
else: # ed25519 | ||
public_bytes = bytes.fromhex(legacy_key["keyval"]["public"]) | ||
public_key = Ed25519PublicKey.from_public_bytes(public_bytes) | ||
|
||
return public_key.public_bytes( | ||
encoding=Encoding.PEM, | ||
format=PublicFormat.SubjectPublicKeyInfo, | ||
) | ||
|
||
|
||
def main(): | ||
parser = argparse.ArgumentParser( | ||
description=( | ||
"Migrate legacy keys to standard format " | ||
"(PEM/PKCS8/subjectPublicKeyInfo)." | ||
) | ||
) | ||
|
||
parser.add_argument( | ||
"--type", | ||
choices=["private", "public"], | ||
required=True, | ||
help="key type", | ||
) | ||
parser.add_argument( | ||
"--password", | ||
help="password to decrypt legacy and encrypt new private key", | ||
) | ||
parser.add_argument( | ||
"--algo", | ||
choices=["rsa", "ecdsa", "ed25519"], | ||
required=True, | ||
help="key algorithm", | ||
) | ||
parser.add_argument( | ||
"--in", | ||
dest="path_in", | ||
metavar="PATH", | ||
required=True, | ||
help="file path to legacy key", | ||
) | ||
parser.add_argument( | ||
"--out", | ||
dest="path_out", | ||
metavar="PATH", | ||
required=True, | ||
help="file path to new key", | ||
) | ||
|
||
args = parser.parse_args() | ||
|
||
if args.type == "private": | ||
new_key_bytes = migrate_private(args.path_in, args.algo, args.password) | ||
|
||
else: # public | ||
if args.password: | ||
parser.print_usage() | ||
parser.error("use password with --type private only") | ||
new_key_bytes = migrate_public(args.path_in, args.algo) | ||
|
||
with open(args.path_out, "wb+") as output_file: | ||
output_file.write(new_key_bytes) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
8fbf611c59332aebc82bdcf026fe4119@@@@100000@@@@307a043b7e82a3bf4421f6971e3c5af13570d6824e52e096ab653b877fc52e9f@@@@835eccefffb6b5492c53027a5a92e445@@@@c6513cceb8cb00fd117787a4a8e0331b55b24f7467e7ed881910954deecd23611fd09238a425052ee0fe5647cedaf42ee31e04a9233d368616f8f0668ebd2cc63bf8aa466f438d2aa671ebab9dc4fdacdd5600672480161f43318dd76410145fea99eaa4eb4ef36a4d903007461ac1f123beb72fbb2793ea1d0f7bf9199894d8af43dc880968e882ff5cc342bdebfb827e4158e74aa93b70164324c510aef94389ee4bac90c39277da0ff6a56d41d28e2f019ac90d7008a58e792064ad8e8800925a10bdf161159cc8169bc6bde07bce5b57ffbdaae3f90c825b2f4af9f8a58617f4fcd020922d5b1f6d8b6fe273e59627698acc80ccac5574a5254b1d4e2faae67daeee9dc36c673724d1663ada890a9176d2754eb75c6245f429df773b19b80ef0e18c076f159572acff26a51b15f302473638e08230d137246ab6cada40b26717dda3bd295d9df675f5d025230f9d67d79e70f94cd766abae8afff13f11bb2137e28bb0ed2b4e3675b6a3df707fd89a780ebf6c3c93834eecf7d2ff80240abf7d04957feb613554afb1fd5517320b422ef228608b87740ac2801bd4f9907ac018a9aeb51f36317736c54cc593712219dcf00af3a009ac5a0c762c69cc4d579c425f642f0053668bec77d65bb3f046ed090ebdc502c09fe83e68cc94355be96ec22bd3019043dc6a9e0a3acbb245e710caebc5df7b9ed1c81ec983b6b828f84f8487ac1b068ee8c2cbd91c411041a7a48a4fe59d10e55a7ee0bb276ddde9a3bbfe21bedfd50c094dc161034e3100dfa0309cca8bbe8178a8d5504741e1953075cc25922bca7f19284c51e85669be52687c9c005892c3331057964733b4d5c5b85bfb7bc31bc4a75fcd1f9cd121b19dd48cf5dc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"keytype": "ecdsa", "scheme": "ecdsa-sha2-nistp256", "keyid": "57b7afab61dfd16b96619bb8af6c55483eeade3aa68cf20ff8f0aa69a8bcc8d8", "keyval": {"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEx+6/aDen+X60RXLETPYz/H4U4qAY\neD/faCdpHBBmyip7xRiyWIrWljDmqcwLfv5wswrqdLF8M6hAdgYjIQZU/A==\n-----END PUBLIC KEY-----", "private": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIEm0tgzxA8OHiudMGqscqR4QpaJfxwwREqAD3rlSfXGJoAoGCCqGSM49\nAwEHoUQDQgAEx+6/aDen+X60RXLETPYz/H4U4qAYeD/faCdpHBBmyip7xRiyWIrW\nljDmqcwLfv5wswrqdLF8M6hAdgYjIQZU/A==\n-----END EC PRIVATE KEY-----"}, "keyid_hash_algorithms": ["sha256", "sha512"]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"keytype": "ecdsa", "scheme": "ecdsa-sha2-nistp256", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEx+6/aDen+X60RXLETPYz/H4U4qAY\neD/faCdpHBBmyip7xRiyWIrWljDmqcwLfv5wswrqdLF8M6hAdgYjIQZU/A==\n-----END PUBLIC KEY-----"}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
9ad267c7c10c74fb754b2d0811cadb6a@@@@100000@@@@06e3a7f38f26fc7c08d28e112fb6b53ab56b84c6214ac040bfcfdafb2fd7d221@@@@52d11d61e2e4ce57f39b3db799e72d24@@@@a5dc0ef8f4c7b1a87ab91c71eac39453004b36fea1284526bc109ae97f179bed1efd5d2a39f69c4a9f246b5ca6cc2e53366f830c11e5d2032c792dfd7f64bc87562b791ca1c1af1cedd245d438033d81688414c1ceaf0883f5cd604311978a60a5239b96fe2ff64ca1cc96becb8aefafe8600dda3b268249bc265cdbd086edbaaf53fd016109125e1dec784390cb8eb1501ccfcdbc4a4608ed8ffbbffd56ec7c97badea762b4a37f00dc7998da8c22c13b0125ffa91465262004a6ed1747a22074a3b32aac64e773f104538fa5032b7667a76f6963bd86d1ec7d3e83e2d59a070d3f558e27e6c8228080f0cc81d07dff2907ef617571ba1b18836743327579285844b1cc6e8ce809a092af8f6e1f7c8d27621348cc35698dec7e1dd82d9d5f07e89bc6d3e192fb1f7822d057265a30f36f18fe376c3c729335605e7d0e0fdbc3f30352f3a2ed94cba2f01f4df015957d |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"keytype": "ed25519", "scheme": "ed25519", "keyid": "cb2eea1134dac06c1ca2e94b1ffbd15c0bf9f0f541458f0a1df6968a900392f9", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "167ced64cc9908b0bebb92df124d8d7fbe4298d41407524e8d238d0bcdd76c79", "private": "71fe1138357bf15b08723fd01af86deb5b58e4f469eb0acc9892e3c4cf9f4504"}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"keytype": "ed25519", "scheme": "ed25519", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "167ced64cc9908b0bebb92df124d8d7fbe4298d41407524e8d238d0bcdd76c79"}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
-----BEGIN RSA PRIVATE KEY----- | ||
Proc-Type: 4,ENCRYPTED | ||
DEK-Info: AES-256-CBC,5196BEDDC2BA3ECB973C1B15CF8BA8F0 | ||
|
||
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 | ||
-----END RSA PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
-----BEGIN RSA PRIVATE KEY----- | ||
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 | ||
-----END RSA PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
-----BEGIN PUBLIC KEY----- | ||
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwYSU3rVOgJV1uXPdkBK+ | ||
Wkx09xMMEQE/xTQG0wX4tLOSeHSK+/MwXeYw83DGYAsHEtEb57j/iNrVSESMEJfB | ||
9CT6YBLh6DfnZQnG5GS5f997t8c3zyGM1fYzoBWaVakMVO2DoM8vxst/c2MU1BJX | ||
aG7hW+Tu5Kuz856YGmX8fV6eGvetWaQM9iN6jRmSS6Wmt/2WXcnvzjV5OyetpkH2 | ||
s8kT60x1zElKiZtmGvz2lnxBZWK3uMBiBL8I52KZF+s9G65+shPJScYFKJ/NLVcM | ||
EaVDCghPay5bZ9pv6vqhylisLIs+alJoxWriz8a7Pc1tW0pBsWrk53adtBaxscFe | ||
3kjiJblQWE19xDwjEVCGA1MmslY0LFi2+R6SVcDDnNK7m0wcaqy1OG1bQXSpZLn/ | ||
bNKE0NvT1SzrlRUojkcneiH6sJSWucXmoo5tL2+uzjEFM/xppW/leo72Umtgahlq | ||
jhvFboJB0slG7ppwcrkuWYg1SejTHBt51jdvzsq6tVtdAgMBAAE= | ||
-----END PUBLIC KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
"""Test key migration script""" | ||
|
||
import shutil | ||
import sys | ||
import tempfile | ||
import unittest | ||
from pathlib import Path | ||
from unittest.mock import patch | ||
|
||
from securesystemslib.exceptions import UnverifiedSignatureError | ||
from securesystemslib.interface import ( | ||
import_privatekey_from_file, | ||
import_publickeys_from_file, | ||
) | ||
from securesystemslib.migrate_key import main as migrate_key_cli | ||
from securesystemslib.signer import CryptoSigner, SSlibKey, SSlibSigner | ||
|
||
|
||
class TestMigrateKey(unittest.TestCase): | ||
"""Test key migration and backwards compatibility of signatures.""" | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
cls.old_keys = Path(__file__).parent / "data" / "legacy" | ||
cls.new_keys = Path(tempfile.mkdtemp()) | ||
|
||
# Migrate private, private encrypted and public keys for each algo | ||
for algo in ["rsa", "ecdsa", "ed25519"]: | ||
for type_, name_suffix, has_password in [ | ||
("private", "_encrypted", True), | ||
("private", "_unencrypted", False), | ||
("public", "", False), | ||
]: | ||
args = [ | ||
"migrate_key.py", | ||
"--type", | ||
type_, | ||
"--algo", | ||
algo, | ||
"--in", | ||
str(cls.old_keys / f"{algo}_{type_}{name_suffix}"), | ||
"--out", | ||
str(cls.new_keys / f"{algo}_{type_}{name_suffix}"), | ||
] | ||
|
||
if has_password: | ||
args += ["--password", "password"] | ||
|
||
with patch.object(sys, "argv", args): | ||
migrate_key_cli() | ||
|
||
@classmethod | ||
def tearDownClass(cls): | ||
shutil.rmtree(cls.new_keys) | ||
|
||
def test_migrated_keys(self): | ||
for algo in ["rsa", "ecdsa", "ed25519"]: | ||
# Load public key | ||
with open(self.new_keys / f"{algo}_public", "rb") as f: | ||
public_key = SSlibKey.from_pem(f.read()) | ||
|
||
# Load unencrypted private key | ||
path = self.new_keys / f"{algo}_private_unencrypted" | ||
uri = f"file:{path}?encrypted=false" | ||
signer_unenc = CryptoSigner.from_priv_key_uri(uri, public_key) | ||
|
||
# Load encrypted private key | ||
path = self.new_keys / f"{algo}_private_encrypted" | ||
uri = f"file:{path}?encrypted=true" | ||
signer_enc = CryptoSigner.from_priv_key_uri( | ||
uri, public_key, lambda sec: "password" | ||
) | ||
|
||
# Sign and test signatures | ||
for signer in [signer_unenc, signer_enc]: | ||
sig = signer.sign(b"data") | ||
self.assertIsNone(public_key.verify_signature(sig, b"data")) | ||
with self.assertRaises(UnverifiedSignatureError): | ||
public_key.verify_signature(sig, b"not data") | ||
|
||
def test_new_signature_verifies_with_old_key(self): | ||
for algo in ["rsa", "ecdsa", "ed25519"]: | ||
# Load old public key | ||
key_dicts = import_publickeys_from_file( | ||
[str(self.old_keys / f"{algo}_public")], [algo] | ||
) | ||
key_dict = list(key_dicts.values())[0] | ||
public_key = SSlibKey.from_securesystemslib_key(key_dict) | ||
|
||
# Load new private key | ||
# NOTE: The signer is loaded with the old public key, thus the old | ||
# keyid will be assigned to any new signatures. | ||
path = self.new_keys / f"{algo}_private_unencrypted" | ||
uri = f"file:{path}?encrypted=false" | ||
signer = CryptoSigner.from_priv_key_uri(uri, public_key) | ||
|
||
# Sign and test signatures | ||
sig = signer.sign(b"data") | ||
self.assertIsNone(public_key.verify_signature(sig, b"data")) | ||
with self.assertRaises(UnverifiedSignatureError): | ||
public_key.verify_signature(sig, b"not data") | ||
|
||
def test_old_signature_verifies_with_new_key(self): | ||
for algo in ["rsa", "ecdsa", "ed25519"]: | ||
# Load old private key | ||
private_key = import_privatekey_from_file( | ||
str(self.old_keys / f"{algo}_private_unencrypted"), algo | ||
) | ||
signer = SSlibSigner(private_key) | ||
|
||
# Load new public key | ||
with open(self.new_keys / f"{algo}_public", "rb") as f: | ||
# NOTE: The new auto-keyid would differ from the old keyid. | ||
# Set it explicitly, to verify signatures with old keyid below | ||
public_key = SSlibKey.from_pem( | ||
f.read(), keyid=private_key["keyid"] | ||
) | ||
|
||
# Sign and test signature | ||
sig = signer.sign(b"data") | ||
self.assertIsNone(public_key.verify_signature(sig, b"data")) | ||
with self.assertRaises(UnverifiedSignatureError): | ||
public_key.verify_signature(sig, b"not data") | ||
|
||
|
||
# Run the unit tests. | ||
if __name__ == "__main__": | ||
unittest.main() |