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 key hashing for v5 / v6 signatures #2261

Merged
merged 1 commit into from
Oct 29, 2024
Merged

Conversation

TJ-91
Copy link
Contributor

@TJ-91 TJ-91 commented Aug 15, 2024

Justus pointed out that the hashing of keys is implemented incorrectly for RNP and some other implementations, see https://mailarchive.ietf.org/arch/msg/openpgp/PyP-XDv0VM5bYPX1Iq41-Oyytds/
This concerns computing v5 and v6 signatures over keys.

This PR fixes that. I separated signature and fingerprint computation logically, but the same code is used in the background. I also added a check that we don't accidently hash too large a key.

Copy link

codecov bot commented Aug 15, 2024

Codecov Report

Attention: Patch coverage is 88.88889% with 1 line in your changes missing coverage. Please review.

Project coverage is 84.27%. Comparing base (92adfd7) to head (c13ce03).
Report is 28 commits behind head on main.

Files with missing lines Patch % Lines
src/librepgp/stream-sig.cpp 87.50% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2261   +/-   ##
=======================================
  Coverage   84.27%   84.27%           
=======================================
  Files         114      114           
  Lines       23324    23324           
=======================================
  Hits        19656    19656           
  Misses       3668     3668           

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

@TJ-91 TJ-91 force-pushed the fix-v6-key-sig-justus branch 2 times, most recently from f3e99bb to c74315c Compare September 23, 2024 09:04
@TJ-91
Copy link
Contributor Author

TJ-91 commented Sep 23, 2024

@ni4 I'm not sure why a windows and Cirrus CI test fails. Does the problem still exists that tests need to be restarted occasionally?

Also codecov complains about some code that is not tested. Are we required to provide full test coverage for new code? It's not always trivial. For example, one failure case I added tests whether the length of a key is longer than what can be encoded in 4 length octets, i.e., 4 gigabyte.

@ni4
Copy link
Contributor

ni4 commented Sep 23, 2024

@ni4 I'm not sure why a windows and Cirrus CI test fails. Does the problem still exists that tests need to be restarted occasionally?

Yeah, that could be caused by two reason: GnuPG is not designed to run in batch/multiple threads and it seem to fail occasionally in tests. Also there is issue with encryption to multiple password which in some cases not well handled by GnuPG (cannot find now, but we should have issue for that).

Also codecov complains about some code that is not tested. Are we required to provide full test coverage for new code? It's not always trivial. For example, one failure case I added tests whether the length of a key is longer than what can be encoded in 4 length octets, i.e., 4 gigabyte.

Codecov requires the patch coverage to be not smaller than overall project coverage, and sometimes that get tricky. In some cases which should never happen, like checks for memory failures, you may use LCOV_EXCL_LINE or LCOV_EXCL_START/LCOV_EXCL_END to disable check for certain code lines.

@TJ-91
Copy link
Contributor Author

TJ-91 commented Sep 25, 2024

So what would you suggest how can I best satisfy codecov here? I agree with the general idea to ideally test every line but for most of the changes it'll be a bit tricky and I suppose a typical test case would fail somewhere earlier already.

Let's look for example at the codecov finding src/librepgp/stream-sig.cpp#L87-L89. I test for key version, and for this I use a switch-case statement. The default case will abort with some error message. If the switch-case statement is deep enough in the library, some earlier switch-case statement's default case will be triggered before I get to this code. For example, I can't see how a version "123" certificate would be getting that deep into the library code.

In summary, I'm not sure if it's reasonable to make the effort here and some more sophisticated testing utility framework to help write the specific test cases might be needed if that level of testing is desired.

Would you be fine with just using LCOV_EXCL_LINE for all reported lines?

Copy link
Contributor

@ni4 ni4 left a comment

Choose a reason for hiding this comment

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

Please see the review comments.

* Throws exception on error.
* @param key key packet, must be populated
* @param hash initialized hash context
*/
void signature_hash_key(const pgp_key_pkt_t &key, rnp::Hash &hash);
void fingerprint_hash_key(const pgp_key_pkt_t &key, rnp::Hash &hash);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we should introduce new functions, adding and describing just version field to already existing signature_hash_key() would be pretty enough.

case PGP_V3:
FALLTHROUGH_STATEMENT;
case PGP_V4:
if (key.hashed_len > ((size_t) 1 << 16) - 1) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Given that we cannot have key artifacts with length >65535 at the moment (we will not parse it nor generate) we could add just an assert() here and below. The price of mistake would be just an incorrect signature.

@ni4
Copy link
Contributor

ni4 commented Sep 26, 2024

@TJ-91 Please see the review comments. Let's just keep things simpler :)

@TJ-91 TJ-91 force-pushed the fix-v6-key-sig-justus branch from c74315c to 17845b3 Compare September 27, 2024 08:41
@TJ-91
Copy link
Contributor Author

TJ-91 commented Sep 27, 2024

@ni4 I hope now it's simple enough :) I think I need to restart tests for the macos test (fails cli_tests-Encryption) but I'm not sure for the codecov test again. Do I need to wait on your PRs here as well?

@ni4 ni4 self-requested a review October 1, 2024 10:55
Copy link
Contributor

@ni4 ni4 left a comment

Choose a reason for hiding this comment

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

LGTM, thanks! Yeah, let's first wait till PR #2277 is merged and then rebase to mace codecov happy.

@ni4
Copy link
Contributor

ni4 commented Oct 9, 2024

@TJ-91 PRs which fix CI are finally merged, so could you please rebase this on main to get it merged? Thanks!

@TJ-91 TJ-91 force-pushed the fix-v6-key-sig-justus branch from 17845b3 to c13ce03 Compare October 14, 2024 08:12
@TJ-91
Copy link
Contributor Author

TJ-91 commented Oct 14, 2024

@ni4 Passes all checks now, thanks!

Copy link
Member

@maxirmx maxirmx left a comment

Choose a reason for hiding this comment

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

LGTM

@ni4
Copy link
Contributor

ni4 commented Oct 29, 2024

Merging with two approvals. Thanks all!

@ni4 ni4 merged commit 4c1ef3d into rnpgp:main Oct 29, 2024
124 checks passed
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.

3 participants