diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fc4a86c..84d89dc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning][semver]. ### Added +- Removed 2048-bit key restriction [494] - Allow for the displaying of varied levels of log and debug information based on the verbosity level ([493]) - Added new tests to test out of sync repositories and manual updates ([488], [504]) - Added lazy loading to CLI ([481]) @@ -38,11 +39,12 @@ and this project adheres to [Semantic Versioning][semver]. ### Fixed [504]: https://github.com/openlawlibrary/taf/pull/504 +[494]: https://github.com/openlawlibrary/taf/pull/494 [493]: https://github.com/openlawlibrary/taf/pull/493 [489]: https://github.com/openlawlibrary/taf/pull/489 [488]: https://github.com/openlawlibrary/taf/pull/488 [487]: https://github.com/openlawlibrary/taf/pull/487 -[487]: https://github.com/openlawlibrary/taf/pull/485 +[485]: https://github.com/openlawlibrary/taf/pull/485 [481]: https://github.com/openlawlibrary/taf/pull/481 [479]: https://github.com/openlawlibrary/taf/pull/479 [473]: https://github.com/openlawlibrary/taf/pull/473 diff --git a/taf/api/roles.py b/taf/api/roles.py index c6ca289e..f1d3cbd1 100644 --- a/taf/api/roles.py +++ b/taf/api/roles.py @@ -498,12 +498,15 @@ def _enter_role_info( while click.confirm( f"Add {'another' if len(delegated_roles) else 'a'} delegated targets role of role {role}?" ): - role_name = _read_val(str, "role name", True) + role_name = _read_val(str, "role name", "role_name", True) delegated_paths: List[str] = [] while not len(delegated_paths) or click.confirm("Enter another path?"): delegated_paths.append( _read_val( - str, f"path or glob pattern delegated to {role_name}", True + str, + f"path or glob pattern delegated to {role_name}", + "delegated_paths", + True, ) ) delegated_roles[role_name]["paths"] = delegated_paths diff --git a/taf/api/yubikey.py b/taf/api/yubikey.py index 8addc88e..0d80a0a9 100644 --- a/taf/api/yubikey.py +++ b/taf/api/yubikey.py @@ -121,7 +121,9 @@ def get_yk_roles(path: str) -> Dict: on_exceptions=TAFError, reraise=True, ) -def setup_signing_yubikey(certs_dir: Optional[str] = None) -> None: +def setup_signing_yubikey( + certs_dir: Optional[str] = None, key_size: int = 2048 +) -> None: """ Delete everything from the inserted YubiKey, generate a new key and copy it to the YubiKey. Optionally export and save the certificate to a file. @@ -146,7 +148,7 @@ def setup_signing_yubikey(certs_dir: Optional[str] = None) -> None: pin_repeat=True, prompt_message="Please insert the new Yubikey and press ENTER", ) - key = yk.setup_new_yubikey(serial_num) + key = yk.setup_new_yubikey(serial_num, key_size=key_size) yk.export_yk_certificate(certs_dir, key) diff --git a/taf/keys.py b/taf/keys.py index e56cf4e7..27164930 100644 --- a/taf/keys.py +++ b/taf/keys.py @@ -330,6 +330,7 @@ def setup_roles_keys( yubikeys: Optional[Dict] = None, users_yubikeys_details: Optional[Dict[str, UserKeyData]] = None, skip_prompt: Optional[bool] = False, + key_size: int = 2048, ): if role.name is None: @@ -347,7 +348,7 @@ def setup_roles_keys( if is_yubikey: yubikey_keys = _setup_yubikey_roles_keys( - yubikey_ids, users_yubikeys_details, yubikeys, role, certs_dir + yubikey_ids, users_yubikeys_details, yubikeys, role, certs_dir, key_size ) else: if keystore is None: @@ -374,7 +375,7 @@ def setup_roles_keys( def _setup_yubikey_roles_keys( - yubikey_ids, users_yubikeys_details, yubikeys, role, certs_dir + yubikey_ids, users_yubikeys_details, yubikeys, role, certs_dir, key_size ): loaded_keys_num = 0 yk_with_public_key = {} @@ -397,7 +398,13 @@ def _setup_yubikey_roles_keys( key_scheme = users_yubikeys_details[key_id].scheme key_scheme = key_scheme or role.scheme public_key = _setup_yubikey( - yubikeys, role.name, key_id, yubikey_keys, key_scheme, certs_dir + yubikeys, + role.name, + key_id, + yubikey_keys, + key_scheme, + certs_dir, + key_size, ) loaded_keys_num += 1 yubikey_keys.append(public_key) @@ -526,6 +533,7 @@ def _setup_yubikey( loaded_keys: List[str], scheme: Optional[str] = DEFAULT_RSA_SIGNATURE_SCHEME, certs_dir: Optional[Union[Path, str]] = None, + key_size: int = 2048, ) -> Dict: print(f"Registering keys for {key_name}") while True: @@ -551,7 +559,7 @@ def _setup_yubikey( print("Key already loaded. Please insert a different YubiKey") else: if not use_existing: - key = yk.setup_new_yubikey(serial_num, scheme) + key = yk.setup_new_yubikey(serial_num, scheme, key_size=key_size) if certs_dir is not None: yk.export_yk_certificate(certs_dir, key) diff --git a/taf/tools/metadata/__init__.py b/taf/tools/metadata/__init__.py index ae3b1c2d..9db16f2b 100644 --- a/taf/tools/metadata/__init__.py +++ b/taf/tools/metadata/__init__.py @@ -77,9 +77,5 @@ def update_expiration_dates(path, role, interval, keystore, scheme, start_date, def attach_to_group(group): - metadata_group = click.Group(name='metadata') - - metadata_group.add_command(check_expiration_dates_command(), name='check-expiration-dates') - metadata_group.add_command(update_expiration_dates_command(), name='update-expiration-dates') - - group.add_command(metadata_group) + group.add_command(check_expiration_dates_command(), name='check-expiration-dates') + group.add_command(update_expiration_dates_command(), name='update-expiration-dates') diff --git a/taf/tools/yubikey/__init__.py b/taf/tools/yubikey/__init__.py index 68dd8848..90bc0e0d 100644 --- a/taf/tools/yubikey/__init__.py +++ b/taf/tools/yubikey/__init__.py @@ -62,7 +62,7 @@ def setup_signing_key_command(): WARNING - this will delete everything from the inserted key.""") @click.option("--certs-dir", help="Path of the directory where the exported certificate will be saved. Set to the user home directory by default") def setup_signing_key(certs_dir): - setup_signing_yubikey(certs_dir) + setup_signing_yubikey(certs_dir,key_size=2048) return setup_signing_key @@ -71,12 +71,11 @@ def setup_test_key_command(): WARNING - this will reset the inserted key.""") @click.argument("key-path") def setup_test_key(key_path): - setup_test_yubikey(key_path) + setup_test_yubikey(key_path,key_size=2048) return setup_test_key def attach_to_group(group): - group.add_command(check_pin_command(), name='check-pin') group.add_command(export_pub_key_command(), name='export-pub-key') group.add_command(get_roles_command(), name='get-roles') diff --git a/taf/yubikey.py b/taf/yubikey.py index 1f365009..1cac0212 100644 --- a/taf/yubikey.py +++ b/taf/yubikey.py @@ -230,11 +230,15 @@ def export_piv_pub_key(pub_key_format=serialization.Encoding.PEM, pub_key_pem=No - YubikeyError """ with _yk_piv_ctrl(pub_key_pem=pub_key_pem) as (ctrl, _): - x509 = ctrl.get_certificate(SLOT.SIGNATURE) - return x509.public_key().public_bytes( - encoding=pub_key_format, - format=serialization.PublicFormat.SubjectPublicKeyInfo, - ) + try: + x509_cert = ctrl.get_certificate(SLOT.SIGNATURE) + public_key = x509_cert.public_key() + return public_key.public_bytes( + encoding=pub_key_format, + format=serialization.PublicFormat.SubjectPublicKeyInfo, + ) + except Exception as e: + raise YubikeyError(f"Failed to export public key: {str(e)}") from e @raise_yubikey_err("Cannot export yk certificate.") @@ -302,6 +306,7 @@ def setup( pin_retries=10, private_key_pem=None, mgm_key=generate_random_management_key(MANAGEMENT_KEY_TYPE.TDES), + key_size=2048, ): """Use to setup inserted Yubikey, with following steps (order is important): - reset to factory settings @@ -326,6 +331,7 @@ def setup( Raises: - YubikeyError """ + with _yk_piv_ctrl() as (ctrl, _): # Factory reset and set PINs ctrl.reset() @@ -335,7 +341,7 @@ def setup( # Generate RSA2048 if private_key_pem is None: - private_key = rsa.generate_private_key(65537, 2048, default_backend()) + private_key = rsa.generate_private_key(65537, key_size, default_backend()) pub_key = private_key.public_key() else: try: @@ -382,11 +388,13 @@ def setup( ) -def setup_new_yubikey(serial_num, scheme=DEFAULT_RSA_SIGNATURE_SCHEME): +def setup_new_yubikey(serial_num, scheme=DEFAULT_RSA_SIGNATURE_SCHEME, key_size=2048): pin = get_key_pin(serial_num) cert_cn = input("Enter key holder's name: ") print("Generating key, please wait...") - pub_key_pem = setup(pin, cert_cn, cert_exp_days=EXPIRATION_INTERVAL).decode("utf-8") + pub_key_pem = setup( + pin, cert_cn, cert_exp_days=EXPIRATION_INTERVAL, key_size=key_size + ).decode("utf-8") scheme = DEFAULT_RSA_SIGNATURE_SCHEME key = import_rsakey_from_pem(pub_key_pem, scheme) return key