-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8278851: Correct signer logic for jars signed with multiple digestalgs #7056
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
Conversation
|
👋 Welcome back mullan! A progress list of the required criteria for merging this PR into |
|
@seanjmullan The following labels will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
| JarConstraintsParameters params = | ||
| getParams(verifiedSigners, sigFileSigners); | ||
| CodeSigner[] entrySigners = sigFileSigners.get(name); | ||
| Map<String, Boolean> permittedAlgs = |
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.
maybe permittedAlgsChecker as variable name ? the Map contains both permitted and non-permitted algs.
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.
Checker sounds like it going to do something. But I agree the name could be better. I was mostly being consistent with the permittedAlgs variable in SignatureFileVerifier. Maybe algsPermittedStatus?
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.
yes, algsPermittedStatus sounds better. Thanks.
| } | ||
|
|
||
| // A non-disabled algorithm was used. | ||
| disabledAlgs = false; |
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 usage doesn't seem right. I think it's always set to false no matter what algs are detected.
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.
If all algs are disabled, it will never get here, because it will either continue on line 231 or 234.
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.
Ah yes - I was reading the scope of for loop incorrectly. Thanks for clarifying!
| } | ||
|
|
||
| // A non-disabled algorithm was used. | ||
| disabledAlgs = false; |
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.
Ah yes - I was reading the scope of for loop incorrectly. Thanks for clarifying!
| JarConstraintsParameters params = | ||
| getParams(verifiedSigners, sigFileSigners); | ||
| CodeSigner[] entrySigners = sigFileSigners.get(name); | ||
| Map<String, Boolean> permittedAlgs = |
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.
yes, algsPermittedStatus sounds better. Thanks.
|
@seanjmullan This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be: You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 19 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
| params = new JarConstraintsParameters(entrySigners); | ||
| } | ||
| return null; | ||
| if (!checkConstraints(digestAlg, permittedAlgs, params)) { |
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.
Can we move the permittedAlgs::put call from inside the checkConstraints method to here? You can even call computeIfAbsent to make the intention clearer.
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.
Yes, I can do that. However, I'm a bit wary of using lambdas in this code which may get exercised early in app startup. WDYT?
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.
Maybe, I don't know how problematic if lambda is used this early.
Anyway, I still prefer moving the update of permittedAlgs here. Updating it inside the method seems too faraway.
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.
Changed as suggested in latest revision.
| } else { | ||
| return new JarConstraintsParameters( | ||
| verifiedSigners.get(manifestFileName)); | ||
| // Gets the permitted algs for the signers of this entry. |
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 can probably be another computeIfAbsent.
|
|
||
| JarConstraintsParameters params = | ||
| getParams(verifiedSigners, sigFileSigners); | ||
| CodeSigner[] entrySigners = sigFileSigners.get(name); |
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.
What if we return here if entrySigners == null? It seems the hash comparison will be skipped, but at the end there is no difference in verifiedSigners.
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.
The algorithm constraints check will be skipped (because permittedAlgs will be null) but the hash check will not be skipped.
I don't think null would be returned in a normal case. The only case I can think of is if there was an entry in the Manifest, but no corresponding entry in the SF file. I suppose we could still do a constraints check as if there were no signers. However, it doesn't seem that useful since technically the entry is not protected by the signature and the hash check is still done, unless I am missing something.
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.
Or maybe the key/signature algorithm is weak and ignored. I was only thinking it's not worth calculating the hash anymore. Of course there will be a behavior change. If there's a hash mismatch, it used to be a security exception, but if ignored, it's just a plain unsigned entry.
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.
It will never get here if all of the signers are using disabled algorithms (or for some other reason cannot be parsed/verified) as JarVerifier.nothingToVerify() will return true. But I think it's possible if one of the signers is ok. But I'd prefer not to make that change because of the change in behavior. And I think in most cases, JARs will have a single signer.
Move put methods out of checkConstraints().
wangweij
left a comment
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.
No more comment. Approved.
src/java.base/share/classes/sun/security/util/ManifestEntryVerifier.java
Show resolved
Hide resolved
|
/integrate |
|
Going to push as commit 61b8944.
Your commit was automatically rebased without conflicts. |
|
@seanjmullan Pushed as commit 61b8944. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
If a JAR is signed with multiple digest algorithms and one of the digest algorithms is disabled,
ManifestEntryVerifier.verify()was incorrectly returning null indicating that the jar entry has no signers.This fixes the issue such that an entry is considered signed if at least one of the digest algorithms is not disabled and the digest match passes. This makes the fix consistent with how multiple digest algorithms are handled in the Signature File. This also fixes an issue in the
ManifestEntryVerifier.getParams()method in which it was incorrectly checking the algorithm constraints against all signers of a JAR when it should check them only against the signers of the entry that is being verified.An additional cache has also been added to avoid checking if the digest algorithm is disabled more than once for entries signed by the same set of signers.
Progress
Issue
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/7056/head:pull/7056$ git checkout pull/7056Update a local copy of the PR:
$ git checkout pull/7056$ git pull https://git.openjdk.java.net/jdk pull/7056/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 7056View PR using the GUI difftool:
$ git pr show -t 7056Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/7056.diff