-
Notifications
You must be signed in to change notification settings - Fork 5.8k
8313367: SunMSCAPI cannot read Local Computer certs w/o Windows elevation #16687
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
8313367: SunMSCAPI cannot read Local Computer certs w/o Windows elevation #16687
Conversation
Hi @rebarbora-mckvak, welcome to this OpenJDK project and thanks for contributing! We do not recognize you as Contributor and need to ensure you have signed the Oracle Contributor Agreement (OCA). If you have not signed the OCA, please follow the instructions. Please fill in your GitHub username in the "Username" field of the application. Once you have signed the OCA, please let us know by writing If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please use "Add GitHub user rebarbora-mckvak" as summary for the issue. If you are contributing this work on behalf of your employer and your employer has signed the OCA, please let us know by writing |
@rebarbora-mckvak The following label 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 list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
@rebarbora-mckvak This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
This is a very trivial change fixing rather annoying bug. Can someone review it and let it merge? |
@macarte, can you take a look at this fix? Thanks. |
Apologies I wasn't aware of the JBS issue until I saw this github notification. At a glance the fix seems trivial, but I'll need to test it. We were planning on looking at supporting the ability to open a keystore with READONLY access and I emailed security-dev to this effect in May Considering this change, I'd suggest that when the store is opened with read-only permissions that some warning is output (if this can't be detected then we may have to attempt to open with write-privileges and the fall back to read-only (CERT_STORE_READONLY_FLAG). @rebarbora-mckvak - what testing was done with a NON-elevated user opening a keystore with (CERT_STORE_MAXIMUM_ALLOWED_FLAG) and then attempting write-operations on the keystore? |
Also, when a keystore is read-only. What happens when one tries to write into it? Ideally a |
@rebarbora-mckvak This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
I have not tested any write operations yet. My use case has always been: administrators put private keys in the store and give a service (my java app) permissions to use it e.g. to sign data.
I guess you get the same "Access denied" error now as before. |
Oh, I re-read the bug report. It looks like a |
Please enable github actions so that minimal tier1 jtreg tests are run; as you're changing the behavior of KeyStore.load (for SunMSCAPI) you should really test that all available write operations fail as expected (as they did before this change). |
I enabled gh actions and started build of windows platforms (all other options left empty/default). Hopefully github lets you to look at the results - https://github.com/rebarbora-mckvak/jdk/actions/runs/7658564889 |
@rebarbora-mckvak This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
@macarte : In your comment on JDK-8313367, you suggest that perhaps "this is a feature request". What do you mean by that? JDK-6782021 provides the Microsoft CNG interface for an OpenJDK application, such as jarsigner.exe, to function as a native Windows application when integrated with something like Azure Key Vault. On a secure system, by the principle of least privilege, the following accesses would inhibit a bad actor from committing code signing forgery:
These accesses provide complete, unambiguous separation of roles. A user with dual roles must remain vigilant to accurately simulate a production environment when verifying this fix. Code signing authorization would be assigned, for example, by a key vault admin. A system admin privilege is not also needed. So, for this test, an elevation prompt should be seen as a red flag. |
For "this is a feature request", I think Mat means the type of this JBS issue should be an "Enhancement" instead of a "Bug". |
For clarification I've edited the comment in the JBS issue, replacing "feature request" with "enhancement" so that it properly matches the terminology used in JBS. |
@macarte : Thank you for the clarification. But why do you think this issue should be an Enhancement? It appears to be a minor scope, high impact defect that would block an application from production deployment. Omission of a secure environment test for security Enhancement JDK-6782021 could not have been intentional. Its underlying requirement, like a lock on a car door, is implicit. And, even if the fix is broader than the elegant change proposed by @rebarbora-mckvak, a documentation change should be unnecessary. Given the threat of forgery, security around code signing is not optional. Windows can be part of a secure platform for activities such as this, but not when applications leave issues like this unresolved. |
I have encountered a related problem on my customer's system. Depending on how private keys are imported in the store, either |
@stepan-atypon-com : This looks like a helpful comment. But as your first comment on Github,
no one can see it until you return to that page and check the box indicated
you agree to the terms of use. Then everyone can view your posting. :-)
…On Tue, Mar 5, 2024 at 2:54 AM Stepan Schejbal ***@***.***> wrote:
I have encountered another related problem on one of my customer systems -
signing with some private keys fails when non-administrator account is
used. I will add another patch after some more testing.
—
Reply to this email directly, view it on GitHub
<#16687 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/BFUF6UIAATCKRDBLNIR3LK3YWWB3JAVCNFSM6AAAAAA7OBIQAKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNZYGI2DQOBSGI>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
I welcome your contribution and feel that it will be a worthwhile improvement; and I'm happy to give feedback (and have done already), but as an author I'm not able to sponsor this change. The original enhancement has gone through a review process and has not had any security related bugs raised against it. The scenario this change targets is a valid one, but is not a security vulnerability as the original enhancement does not circumvent security. The choice to deploy to a less-secure environment to use the feature is a user choice. While the change in this PR is trivial, it is still classed as an enhancement as it's not addressing a bug; ie. the original change functions as expected. That you have identified a scenario and supplied a patch is much appreciated; however the change will need to go through review as it changes functionality; again we'll need to consider informing the user as the change could lead to unexpected deployment issues (it may also require documentation changes [CSR]). |
@macarte If you find the change ok, you can always add yourself as a reviewer even if the OpenJDK bot might not count you as a Reviewer. |
A CSR is needed if there will be a spec or doc change, and I don't see we need it anywhere. It is also needed if there is a non-trivial compatibility issue. While there is some behavior change here I don't think it's a compatibility issue. Those worked still work and those didn't work now somehow work. To inform the user this behavior change it looks like a release note is enough. See https://openjdk.org/guide/#release-notes. |
@wangweij, please see the release note above. |
@rebarbora-mckvak I've added the release note as https://bugs.openjdk.org/browse/JDK-8340661 last month. I didn't approve because of Mat's Aug 14 comment:
@macarte Is this still your current opinion? |
@rebarbora-mckvak BTW, I have a small comment on the test. |
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. | |||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. |
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.
Do not remove the old year. This should be "Copyright (c) 2022, 2024, Oracle..."
Any news on this issue? I would like to use certificates from the windows cert store for our tomcat servers, because these will get automatically renewed by AD cert templates. The problem is: it currently works only when the tomcat server is running as LocalSystem. I need a solution which works with a gMSA - without admin rights. |
Yes I believe these are two potential issues that should at least be reviewed (the issues are outlined in the comments); IIRC they should be trivial to address |
@macarte that's a lot to read. could you give a short summary of the issues?
That's by design. When the user needs access to the private key, assign the proper permissions. |
![]() ![]() |
Wierd, I do not see those comments in github. Anyway it is fixed now. |
@rebarbora-mckvak - change looks good to me @wangweij - this commit addresses the two issues I highlighted, I don't have any other concerns |
Thanks for the new commit. I'll run some tests and probably approve it tomorrow. @macarte, the screenshot you posted shows the comments in "Pending" mode which sounds like you added them to a review session but has never submitted it. |
@@ -798,20 +798,16 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_signHash | |||
::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, //deprecated | |||
(BYTE *)pbData, &cbData, 0); | |||
|
|||
DWORD keysetType; | |||
::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_KEYSET_TYPE, //deprecated | |||
(BYTE*)&keysetType, &cbData, 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.
I think this is a bug, cbData starts of initialized to 256 (for the length of pbData), however a sideeffect of the previous call can change that (going in to the call, informs the method of the number of bytes that can be stored in pbData, and coming out indicates the number of bytes actually store)
for this second call to CryptGetProvParam cbData should be the number of bytes in the DWORD keysetType.
@@ -798,20 +798,16 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_signHash | |||
::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, //deprecated | |||
(BYTE *)pbData, &cbData, 0); | |||
|
|||
DWORD keysetType; |
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 should be initialized explicitly to zero (0) in case the method returns an error, we want 0 (through failure or because the CRYPT_KEYMACHINE_KEYSET flag was not used when the key was created), or we want this set by the CryptGetProvParam to CRYPT_KEYMACHINE_KEYSET
@@ -798,11 +798,15 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_signHash | |||
::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, //deprecated | |||
(BYTE *)pbData, &cbData, 0); | |||
|
|||
DWORD keysetType = 0; | |||
DWORD keysetTypeLen = sizeof(keysetType); | |||
::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_KEYSET_TYPE, //deprecated |
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 addresses the previous concerns
@rebarbora-mckvak If you are ready to integrate this fix, please issue the |
/integrate |
@rebarbora-mckvak |
/sponsor |
Going to push as commit db535c8.
Your commit was automatically rebased without conflicts. |
@wangweij @rebarbora-mckvak Pushed as commit db535c8. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
could you please backport the fix to Java 17 LTS or at least 21 LTS? |
This fixes the defect described at https://bugs.openjdk.org/browse/JDK-8313367
If the process does not have write permissions, the store is opened as read-only (instead of failing).
Please note that permissions to use a certificate in a local machine store must be granted - in a management console, select a certificate, right-click -> All tasks... -> Manage Private Keys... -> add Full control to user.
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/16687/head:pull/16687
$ git checkout pull/16687
Update a local copy of the PR:
$ git checkout pull/16687
$ git pull https://git.openjdk.org/jdk.git pull/16687/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 16687
View PR using the GUI difftool:
$ git pr show -t 16687
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/16687.diff
Using Webrev
Link to Webrev Comment