Thanks for the input, Bernd and Sean! I'm afraid submitting a patch for
this directly is a bit beyond my ability, but I'll happily discuss the
design of such a patch.

Nelson D'Costa proposed a couple of possible solutions in JDK-6782021:

> Either define a new store type like Windows-LOCALCOMPUTER,
> or also list the computer local certificates when using the Windows-MY
store type.

My rudimentary understanding of the Windows certificate store architecture
after reading [1] is that Windows comes with a predefined set of
"collection stores" that can be opened with the WinCrypt function
CertOpenStore() using identifier tuples such as
CERT_SYSTEM_STORE_CURRENT_USER+MY, CERT_SYSTEM_STORE_LOCAL_MACHINE+CA etc.
and that these collection stores aggregate a set of "physical stores",
typically in the Windows registry. This model is thoroughly documented in
[1] (although complex), but mapping this identifier scheme to something
that can be used by JCA and KeyStore.getInstance(<identifier>) is slightly
tricky because of at least two concerns:

1) The SunMSCAPI JCA provider is widely used and although its "Windows-MY"
certificate store identifier scheme is flawed (it should have been
something like "Windows-CurrentUser-MY") we can't easily change it without
breaking things.
2) Opening any certificate stores involving the
CERT_SYSTEM_STORE_LOCAL_MACHINE identifier (and most likely other
identifiers) requires administrator privileges or specifically opening the
store as read-only by passing CERT_STORE_READONLY_FLAG to CertOpenStore [2].

To offer the full flexibility of CertOpenStore() through
KeyStore.getInstance() seems like a grand undertaking involving an almost
infinite number of magic string identifiers, so my suggestion is as follows:

1) Introduce the new identifiers Windows-CurrentUser-MY,
Windows-CurrentUser-ROOT, Windows-LocalMachine-MY and
Windows-LocalMachine-ROOT. These seem to be the most requested, but the
identifier scheme allows for more esoteric additions such as
Windows-Services-<ServiceName>-MY down the line.
2) Make Windows-MY and Windows-ROOT be aliases for Windows-CurrentUser-MY
and Windows-CurrentUser-ROOT to maintain backward compatibility.
3) Attempt to open Windows-LocalMachine-MY and Windows-LocalMachine-ROOT in
the default read-write mode, but fallback to read-only if read-write mode
fails. This will transparently enable write operations for privileged
users, while unprivileged users will get an exception when attempting to
write to the store.

References:
[1]
https://docs.microsoft.com/en-us/windows/desktop/seccrypto/system-store-locations
[2]
https://docs.microsoft.com/en-us/windows/desktop/api/wincrypt/nf-wincrypt-certopenstore

Best regards,
Oddbjørn Kvalsund

ons. 8. aug. 2018 kl. 14:04 skrev Bernd Eckenfels <e...@zusammenkunft.net>:

> Hello,
>
> What also should be mentioned is that the old CAPI clients cannot access
> CNG Keys. Which is especially a pity since only the new keys benefit from
> the cryptographic process isolation (not to mention the confusion that it’s
> hard to see which provide hosts them)
>
> Gruss
> Bernd
>
> Gruss
> Bernd
> --
> http://bernd.eckenfels.net
>
> ------------------------------
> *Von:* -980814368m Auftrag von
> *Gesendet:* Mittwoch, August 8, 2018 12:35 PM
> *An:* Oddbjørn Kvalsund; security-dev@openjdk.java.net
> *Betreff:* Re: JDK-6782021
>
> Vinnie is not working on security-libs any more and I think the JBS report
> should be marked as unassigned.  If any contributors want to suggest a
> patch, then I think it can be reviewed on this list!
>
> regards,
> Sean.
>
> On 07/08/2018 06:36, Oddbjørn Kvalsund wrote:
>
> Hi,
>
> I was just bit by this issue [JDK-6782021] It is not possible to read
> local computer certificates with the SunMSCAPI provider
> <https://bugs.openjdk.java.net/browse/JDK-6782021> and from StackOverflow
> I notice that several other people (see [1][2][3]) have come across the
> same problem. Coming up on the 10th anniversary for this issue; any chance
> we'll see some love for it? Or at least a comment on the issue on what
> timeline to expect and a list of workaround/alternative solutions for the
> meantime?
>
> Background: I'm working with a company having primarily Microsoft
> infrastructure and they have a routine where all Windows servers
> automatically receive new certificates/keys when the old ones expire. These
> certificates are installed in the "Local Computer → Private" certificate
> store. They're quite fond of this system and hesitant to diverge from it,
> so my preferred option is to just "get with the program". To temporarily
> get around JDK-6782021 I created a small utility [5] that intercepts the
> JDKs call to 'CertOpenSystemStore' [4] and presents a read-only virtual
> certificate store combining all certificates and keys from the "Current
> User" and "Local Computer" certificate stores, but this may have unexpected
> implications that I've not yet uncovered, so I'd much prefer not having to
> do this. A more thorough solution would be to use the commercial Pheox
> JCAPI [6] product, but this is rather expensive and way overkill for what I
> (and most others, it seems) need.
>
> References:
> [1]
> https://stackoverflow.com/questions/3612962/access-local-machine-certificate-store-in-java/51708360
> [2]
> https://stackoverflow.com/questions/51205158/access-windows-local-machine-personal-keystore-with-java-sunmscapi
> [3]
> https://stackoverflow.com/questions/51193143/use-jna-to-get-local-machine-certificate
> [4]
> http://hg.openjdk.java.net/jdk/jdk/file/tip/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp
> [5] https://github.com/oddbjornkvalsund/wcsa
> [6] https://pheox.com/products/jcapi/
>
> Best regards,
> Oddbjørn Kvalsund
>
>
>

Reply via email to