Skip to content

Commit

Permalink
RepositorySimulator: Add new_signer()
Browse files Browse the repository at this point in the history
This wraps popping the next signing key from the pregenerated list
making it:
 * more user friendly if we run out of keys
 * better for the likely near future where we want to generate many more
   keytypes

This commit only supports rsa-pkcs1v15-sha256 but others should be
trivial to add now.

Signed-off-by: Jussi Kukkonen <[email protected]>
  • Loading branch information
jku committed Aug 19, 2024
1 parent 94a426f commit 7e9323d
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 12 deletions.
31 changes: 23 additions & 8 deletions tuf_conformance/repository_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@
SPEC_VER = ".".join(SPECIFICATION_VERSION)

# Generate some signers once (to avoid all tests generating them)
RSA_SIGNERS = [
CryptoSigner.generate_rsa(scheme="rsa-pkcs1v15-sha256") for _ in range(8)
NUM_SIGNERS = 8
RSA_PKCS_SIGNERS = [
CryptoSigner.generate_rsa(scheme="rsa-pkcs1v15-sha256") for _ in range(NUM_SIGNERS)
]


Expand Down Expand Up @@ -109,7 +110,7 @@ def __init__(self, dump_dir: str | None) -> None:
now = datetime.datetime.utcnow()
self.safe_expiry = now.replace(microsecond=0) + datetime.timedelta(days=30)

self._rsa_signers = RSA_SIGNERS.copy()
self._rsa_pkcs_signers = RSA_PKCS_SIGNERS.copy()

# initialize a basic repository structure
self._initialize()
Expand Down Expand Up @@ -147,6 +148,20 @@ def all_targets(self) -> Iterator[tuple[str, Targets]]:
if role not in [Root.type, Timestamp.type, Snapshot.type]:
yield role, md.signed

def new_signer(
self, keytype: str = "rsa", scheme: str = "rsa-pkcs1v15-sha256"
) -> CryptoSigner:
"""Return a Signer (from a set of pre-generated signers)."""
try:
if keytype == "rsa" and scheme == "rsa-pkcs1v15-sha256":
return self._rsa_pkcs_signers.pop()
except IndexError:
raise RuntimeError(
f"Test ran out of {keytype}/{scheme} keys (NUM_KEYS == {NUM_SIGNERS})"
)

raise ValueError("{keytype}/{scheme} not supported yet")

def add_signer(self, role: str, signer: CryptoSigner) -> None:
if role not in self.signers:
self.signers[role] = {}
Expand All @@ -158,7 +173,7 @@ def rotate_keys(self, role: str) -> None:
self.root.roles[role].keyids.clear()
self.signers[role].clear()
for _ in range(0, self.root.roles[role].threshold):
signer = self._rsa_signers.pop()
signer = self.new_signer()
self.root.add_key(signer.public_key, role)
self.add_signer(role, signer)

Expand All @@ -171,7 +186,7 @@ def _initialize(self) -> None:
self.mds[Root.type] = MetadataTest(RootTest(expires=self.safe_expiry))

for role in TOP_LEVEL_ROLE_NAMES:
signer = self._rsa_signers.pop()
signer = self.new_signer()
self.root.add_key(signer.public_key, role)
self.add_signer(role, signer)

Expand Down Expand Up @@ -345,7 +360,7 @@ def add_delegation(
delegator.delegations.roles[role.name] = role

# By default add one new key for the role
signer = self._rsa_signers.pop()
signer = self.new_signer()
delegator.add_key(signer.public_key, role.name)
self.add_signer(role.name, signer)

Expand All @@ -371,7 +386,7 @@ def add_succinct_roles(
):
raise ValueError("Can't add a succinct_roles when delegated roles are used")

signer = self._rsa_signers.pop()
signer = self.new_signer()
succinct_roles = SuccinctRoles([], 1, bit_length, name_prefix)
delegator.delegations = Delegations({}, None, succinct_roles)

Expand Down Expand Up @@ -411,7 +426,7 @@ def debug_dump(self) -> None:

def add_key(self, role: str, delegator_name: str = Root.type) -> None:
"""add new public key to delegating metadata and store the signer for role"""
signer = self._rsa_signers.pop()
signer = self.new_signer()

# Add key to delegating metadata
delegator = self.mds[delegator_name].signed
Expand Down
1 change: 0 additions & 1 deletion tuf_conformance/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ def test_basic_init_and_refresh(client: ClientRunner, server: SimulatorServer) -
Run a refresh, verify client trusted metadata and requests made by the client
"""
init_data, repo = server.new_test(client.test_name)
print(init_data.trusted_root)
# Run the test: step 1: initialize client
assert client.init_client(init_data) == 0

Expand Down
5 changes: 2 additions & 3 deletions tuf_conformance/test_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ def test_root_has_keys_but_not_snapshot(

# Add two keyids only to root and expect the client
# to fail updating
signer = repo._rsa_signers.pop()

signer = repo.new_signer()
repo.root.roles[Snapshot.type].keyids.append(signer.public_key.keyid)

# Sanity check
Expand Down Expand Up @@ -144,7 +143,7 @@ def test_duplicate_keys_root(client: ClientRunner, server: SimulatorServer) -> N

assert client.init_client(init_data) == 0

signer = repo._rsa_signers.pop()
signer = repo.new_signer()

# Add one key 9 times to root
for n in range(0, 9):
Expand Down

0 comments on commit 7e9323d

Please sign in to comment.