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

Fix encoding of SSH certs with critical options #9208

Merged
merged 3 commits into from
Jul 10, 2023

Conversation

lkubb
Copy link
Contributor

@lkubb lkubb commented Jul 10, 2023

This corrects loading and serialization of SSH certificate critical options/extensions with non-empty values. Note that it does not add support for value types other than string since there is no official option that uses any.

Also breaks loading of certificates that were generated with previous versions of cryptography, I'm not sure if you want to keep backwards-compatibility with that custom format.

Thanks for your hard work on cryptography!

Fixes: #9207

@alex
Copy link
Member

alex commented Jul 10, 2023

Thanks for sending a PR. Can you please add an extra test case so that this has full coverage?

@lkubb
Copy link
Contributor Author

lkubb commented Jul 10, 2023

Thanks for sending a PR. Can you please add an extra test case so that this has full coverage?

Yup, on it already. Would it be sufficient to add a single new vector that tests unexpected data for critical options only or should I add one for extensions as well?

@alex
Copy link
Member

alex commented Jul 10, 2023

Only one is required, but having both is fine.

@reaperhulk
Copy link
Member

Thanks for catching this. That is a very confusing subtlety for a spec that is otherwise pretty well documented!

@reaperhulk
Copy link
Member

So when we encode an empty string for value should we expect to see UNKNOWN FLAG OPTION as part of the parsed output for ssh-keygen?

@lkubb
Copy link
Contributor Author

lkubb commented Jul 10, 2023

So when we encode an empty string for value should we expect to see UNKNOWN FLAG OPTION as part of the parsed output for ssh-keygen?

No, empty strings should behave as before. UNKNOWN FLAG OPTION indicates the option/extension name is not specified as an official one.

@reaperhulk
Copy link
Member

When I parse p256-ed25519-non-singular-ext-val.pub I get:

p256-ed25519-non-singular-ext-val.pub:
        Type: ecdsa-sha2-nistp256-cert-v01@openssh.com user certificate
        Public key: ECDSA-CERT SHA256:W6Wr6d8N5R5y1rzZl8L03NTgrxc8adxeET7GkXdJSvU
        Signing CA: ED25519 SHA256:knottK/0LBWlxvM2cDgzzCJdQ0ppFlY/hzlHWlZTOLk (using ssh-ed25519)
        Key ID: ""
        Serial: 0
        Valid: from 2022-12-31T18:00:00 to 2023-01-01T18:00:00
        Principals: (none)
        Critical Options: 
                verify-required UNKNOWN FLAG OPTION
        Extensions: 
                contains-extra-value UNKNOWN OPTION: 0000000568656c6c6f0000000620776f726c64 (len 19)

So we get the error in extensions that we expect, but I wouldn't have expected verify-required to display that message given that it is an official option.

@lkubb
Copy link
Contributor Author

lkubb commented Jul 10, 2023

That is indeed surprising, I will investigate when I have the time later. Note that I cannot reproduce this with ssh-keygen 9.3:

ssh-keygen -L -f vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-ed25519-non-singular-ext-val.pub
vectors/cryptography_vectors/asymmetric/OpenSSH/certs/p256-ed25519-non-singular-ext-val.pub:
        Type: ecdsa-sha2-nistp256-cert-v01@openssh.com user certificate
        Public key: ECDSA-CERT SHA256:W6Wr6d8N5R5y1rzZl8L03NTgrxc8adxeET7GkXdJSvU
        Signing CA: ED25519 SHA256:knottK/0LBWlxvM2cDgzzCJdQ0ppFlY/hzlHWlZTOLk (using ssh-ed25519)
        Key ID: ""
        Serial: 0
        Valid: from 2023-01-01T00:00:00 to 2023-01-02T00:00:00
        Principals: (none)
        Critical Options:
                verify-required
        Extensions:
                contains-extra-value UNKNOWN OPTION: 0000000568656c6c6f0000000620776f726c64 (len 19)

@lkubb
Copy link
Contributor Author

lkubb commented Jul 10, 2023

@reaperhulk

It seems verify-required was added to ssh-keygen in release 9.1, hence it's unknown below that version:

  • ssh-keygen(1): implement the "verify-required" certificate option.
    This was already documented when support for user-verified FIDO
    keys was added, but the ssh-keygen(1) code was missing.

https://www.openssh.com/txt/release-9.1

@reaperhulk
Copy link
Member

And I'm on 9.0, so alright then 😄

@reaperhulk reaperhulk merged commit 1ca7adc into pyca:main Jul 10, 2023
reaperhulk pushed a commit to reaperhulk/cryptography that referenced this pull request Jul 10, 2023
* Add tests for issue pyca#9207

* Fix encoding of SSH certs with critical options

* Test unexpected additional values for crit opts/exts
alex pushed a commit that referenced this pull request Jul 11, 2023
* Fix encoding of SSH certs with critical options (#9208)

* Add tests for issue #9207

* Fix encoding of SSH certs with critical options

* Test unexpected additional values for crit opts/exts

* temporarily allow invalid ssh cert encoding

---------

Co-authored-by: jeanluc <2163936+lkubb@users.noreply.github.com>
s0undt3ch added a commit to s0undt3ch/salt that referenced this pull request Jul 16, 2023
The cryptography package before 41.0.2 for Python mishandles SSH certificates that have critical options.
References:

    https://nvd.nist.gov/vuln/detail/CVE-2023-38325
    pyca/cryptography#9207
    pyca/cryptography#9208
    pyca/cryptography@41.0.1...41.0.2
    https://pypi.org/project/cryptography/#history
    pyca/cryptography@1ca7adc

Signed-off-by: Pedro Algarvio <palgarvio@vmware.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

SSH certificate encoding/parsing incompatibility with OpenSSH
3 participants