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

API for allowing signature validation given a SPKI/RPK #275

Merged
merged 3 commits into from
Aug 9, 2024

Conversation

holodorum
Copy link
Contributor

@holodorum holodorum commented Jul 31, 2024

This PR creates a new public API which allows for signature validation given a SPKI or a Raw Public Key. This aids the implementation of RFC 7250 (Raw Public Key support) in rustls.

Public API Changes

  • We have added a RawPublicKeyEntity, which creates a SubjectPublicKeyInfo from a `SubjectPublicKeyInfoDer.
  • RawPublicKeyEntity only has a verify_signature function, which verifies the signature with the spki.

API Changes

  • In the SubjectPublicKeyInfo type we've added the method subject_public_key_info. This method returns the DER of SubjectPublicKeyInfo.

Open Questions

  • To transform the SubjectPublicKeyInfo back into properly encoded ASN.1 we need to prepend the key_value and algorithm_value with the correct ASN.1 tag. For this we are using der::asn1_wrap, this function works as expected for the sequence algorithm_value, but not for the bitstring key_value. I assume the reason being that bit strings also need a byte for the number of unused bits. My current workaround is to manually add a 0 byte to the key_value and only then use asn1_wrap(). If this is not the expected behaviour for asn1_wrap() I can also open a PR for to update this.
  • The signed_data::verify_signature function expects a SPKI, but without the ASN.1 tag wrapping the algorithm value AND the key value.
    That's why I added a boolean for_verification to subject_public_key_info(). If for_verification is true the output DER can be used in signed_data::verify_signature, else it's a properly ASN.1 encoded SPKI. Is this a good way to go about this difference?
    EDIT: Instead of using the subject_public_key_info() function to get a key that can be used for verification, it might be better to add a der field to the SubjectPublicKeyInfo struct. In that way we don't need the subject_public_key_info() function anymore and are we not dependent on the alloc` feature.

Contributors:

This PR is made in collaboration with @aochagavia.

Copy link

codecov bot commented Aug 1, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.33%. Comparing base (c2ff93b) to head (c3d60bb).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #275      +/-   ##
==========================================
+ Coverage   97.30%   97.33%   +0.03%     
==========================================
  Files          19       20       +1     
  Lines        4234     4283      +49     
==========================================
+ Hits         4120     4169      +49     
  Misses        114      114              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

src/rpk_entity.rs Outdated Show resolved Hide resolved
src/rpk_entity.rs Outdated Show resolved Hide resolved
src/rpk_entity.rs Outdated Show resolved Hide resolved
src/rpk_entity.rs Outdated Show resolved Hide resolved
src/rpk_entity.rs Outdated Show resolved Hide resolved
src/signed_data.rs Outdated Show resolved Hide resolved
Copy link
Member

@cpu cpu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi there. Thanks for getting the ball rolling :-)

I think this would also benefit from the equivalent of a tests/signatures.rs integration test using the generate.py script to output tests/testdata for doing a signature verification using a raw public key entity across all the supported algorithms (e.g. ecdsa p256, p384, p521, ed25519, rsa 2048, 3072 and 4096). Right now there's just one ed25519 test being used from a unit test, and not an integration test.

src/signed_data.rs Outdated Show resolved Hide resolved
@holodorum holodorum force-pushed the rpk_entity branch 4 times, most recently from 57327fd to 8fc9ba9 Compare August 2, 2024 00:17
@cpu
Copy link
Member

cpu commented Aug 2, 2024

The way the generate.py script works isn't great for incremental updates. I think your CI failure will fix if you rm the existing signature test files and then run your updated generator script again. (we should make this less painful 😵‍💫)

Nevermind, looks like a different root cause.

tests/generate.py Outdated Show resolved Hide resolved
@holodorum
Copy link
Contributor Author

The way the generate.py script works isn't great for incremental updates. I think your CI failure will fix if you rm the existing signature test files and then run your updated generator script again.

@ctz seems you were right, this did seem to be the root cause. After removing the existing signature test files and rerunning generate.py the tests do pass!

@djc
Copy link
Member

djc commented Aug 3, 2024

The deny failure is addressed in #277.

@holodorum
Copy link
Contributor Author

@djc that solved the deny failure indeed. I've also added rpk_entity.rs to the cargo include so all tests should pass after #277 is merged!
Shall I bump the version so we can use the RawPublicKeyEntity in rustls/rustls#2062?

@djc
Copy link
Member

djc commented Aug 5, 2024

Shall I bump the version so we can use the RawPublicKeyEntity in rustls/rustls#2062?

Yes, in a separate commit please!

Copy link
Member

@ctz ctz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

personal terminology bugbear of mine :)

src/rpk_entity.rs Outdated Show resolved Hide resolved
src/rpk_entity.rs Outdated Show resolved Hide resolved
src/rpk_entity.rs Outdated Show resolved Hide resolved
src/rpk_entity.rs Outdated Show resolved Hide resolved
src/rpk_entity.rs Outdated Show resolved Hide resolved
@cpu
Copy link
Member

cpu commented Aug 5, 2024

ci / Cargo Deny (pull_request) Failing after 5s

Needs a rebase? 🤔

Copy link
Member

@cpu cpu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for applying our feedback!

src/rpk_entity.rs Outdated Show resolved Hide resolved
Comment on lines 58 to 59
//Try to read an end entity certificate into a RawPublicKeyEntity.
//It will fail to parse the key value since we expect no unused bits.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think these comments would benefit from a space between the // and the text (surprised cargo fmt isn't doing that automagically tbh...)

tests/generate.py Outdated Show resolved Hide resolved
Cargo.toml Show resolved Hide resolved
src/signed_data.rs Outdated Show resolved Hide resolved
tests/generate.py Outdated Show resolved Hide resolved
holodorum and others added 3 commits August 9, 2024 09:56
Co-authored-by: Adolfo Ochagavía <github@adolfo.ochagavia.nl>
Co-authored-by: Adolfo Ochagavía <github@adolfo.ochagavia.nl>
Co-authored-by: Adolfo Ochagavía <github@adolfo.ochagavia.nl>
@djc djc added this pull request to the merge queue Aug 9, 2024
@djc
Copy link
Member

djc commented Aug 9, 2024

Thanks!

Merged via the queue into rustls:main with commit b244be4 Aug 9, 2024
30 checks passed
@cpu cpu mentioned this pull request Aug 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants