-
Notifications
You must be signed in to change notification settings - Fork 89
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
Add support for SSH certificates using ecdsa-sk or ed25519-sk public keys #813
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for your contribution! I've taken a first look and added some first comments.
Please also add a changelog fragment, and note that the sanity tests are currently failing.
@@ -145,7 +151,8 @@ def format_datetime(dt, date_format): | |||
elif dt == _FOREVER: | |||
result = 'forever' | |||
else: | |||
result = dt.isoformat().replace('+00:00', '') if date_format == 'human_readable' else dt.strftime("%Y%m%d%H%M%S") | |||
result = dt.isoformat().replace('+00:00', '') if date_format == 'human_readable' else dt.strftime( | |||
"%Y%m%d%H%M%S") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind undoing reformatting changes to unrelated code?
return fingerprint(writer.bytes()) | ||
|
||
@abc.abstractmethod | ||
def write_public_key_params(self, writer): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a breaking API change. You need to remove @abc.abstractmethod
and add in a docstring that in community.crypto 3.0.0 this will become an abstract method.
Also you should add a docstring here explaining what this function is expected to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jnohlgard I think it would be better to just introduce the feature in this PR and move the refactor to a follow up if necessary. As @felixfontein is indicating you would force this feature to wait until the next major release if it includes breaking changes.
def public_key_fingerprint(self): | ||
if self.public_key_type_string is None: | ||
return b'' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning b''
instead of None
is also an API breakage, I would add a docstring that specifies that None
will change to b''
in community.crypto 3.0.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
b''
is actually consistent with the existing behavior.self.public_key_type_string
is a new property added with this refactor which is why there is a None
check now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good, but as mentioned in the review comments putting the breaking changes into a separate PR is probably best.
def public_key_fingerprint(self): | ||
if self.public_key_type_string is None: | ||
return b'' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
b''
is actually consistent with the existing behavior.self.public_key_type_string
is a new property added with this refactor which is why there is a None
check now.
return fingerprint(writer.bytes()) | ||
|
||
@abc.abstractmethod | ||
def write_public_key_params(self, writer): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jnohlgard I think it would be better to just introduce the feature in this PR and move the refactor to a follow up if necessary. As @felixfontein is indicating you would force this feature to wait until the next major release if it includes breaking changes.
if any([self.e is None, self.n is None]): | ||
return b'' | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning early here without throwing an exception or any indication of missing data will result in an invalid fingerprint now instead of b''
. So if you really want this refactor I would throw an exception and catch it in public_key_fingerprint
to handle the error properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same goes for the other concrete implementations.
@jnohlgard ping |
SUMMARY
Fixes #796
ISSUE TYPE
COMPONENT NAME
module_utils.openssh.certificate
ADDITIONAL INFORMATION
The openssh.certificate module can both sign using FIDO2 SSH keys and create signatures for FIDO2 SSH keys, but the overall task results in a failure status because it can not understand the certificate it has created.
This PR adds two new types of public keys and certificates to the load function which match the
ssh-keygen
key typesecdsa-sk
anded25519-sk
.Steps to reproduce
This requires a hardware FIDO2 key, e.g. Yubikey.
Create FIDO2 keys using
ssh-keygen -t ecdsa-sk -f /tmp/id_ecdsa_sk -N ''
andssh-keygen -t ecdsa-sk -f /tmp/id_ed25519_sk -N ''
, then use the example below to sign the ECDSA key using the Ed25519 key.sign-key.yml
$ ansible-playbook -c local -i /dev/null -v sign-key.yml
Without this PR:
The full traceback is:
With this PR applied: