Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: remove 2048-bit restriction for yubikey sizes #494

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning][semver].

### Added


- Removed 2048-bit key restriction [494]
- Added lazy loading to CLI [481]
- Testing repositories with dependencies ([479], [487])
- Hid plaintext when users are prompted to insert YubiKey and press ENTER [473]
Expand All @@ -36,6 +36,7 @@ and this project adheres to [Semantic Versioning][semver].

### Fixed

[494]: https://github.com/openlawlibrary/taf/pull/494
[487]: https://github.com/openlawlibrary/taf/pull/489
[487]: https://github.com/openlawlibrary/taf/pull/487
[487]: https://github.com/openlawlibrary/taf/pull/485
Expand Down
11 changes: 9 additions & 2 deletions taf/api/roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -521,6 +524,10 @@ def _read_val(input_type, name, param=None, required=False):
default_value_msg = ""
default_value = None
if param is not None:
if not isinstance(param, str):
raise TypeError(
ronantakizawa marked this conversation as resolved.
Show resolved Hide resolved
f"Parameter 'param' must be a string, got {type(param).__name__}"
)
default_value = DEFAULT_ROLE_SETUP_PARAMS[param]
if default_value is not None:
default_value_msg = f"(default {default_value}) "
Expand Down
6 changes: 4 additions & 2 deletions taf/api/yubikey.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)


Expand Down
16 changes: 12 additions & 4 deletions taf/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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 = {}
Expand All @@ -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)
Expand Down Expand Up @@ -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:
Expand All @@ -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)
Expand Down
8 changes: 2 additions & 6 deletions taf/tools/metadata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
5 changes: 2 additions & 3 deletions taf/tools/yubikey/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand All @@ -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')
Expand Down
24 changes: 16 additions & 8 deletions taf/yubikey.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.")
Expand Down Expand Up @@ -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
Expand All @@ -326,6 +331,7 @@ def setup(
Raises:
- YubikeyError
"""

with _yk_piv_ctrl() as (ctrl, _):
# Factory reset and set PINs
ctrl.reset()
Expand All @@ -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:
Expand Down Expand Up @@ -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
Expand Down