The SunMSCAPI Cryptographic provider does only support two keystores: Windows-MY
(personal certificate store) and Windows-ROOT
(trusted authorities certificate store), thus I don't thinks it is possible to directly access to other windows certificate stores. However it may not be necessart since it seems that the Windows-MY
keystore is able to build certificate chains with the certificates from other stores.
Here is a code snippet I use to test it:
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null) ;
Enumeration en = ks.aliases() ;
while (en.hasMoreElements()) {
String aliasKey = (String)en.nextElement() ;
Certificate c = ks.getCertificate(aliasKey) ;
System.out.println("---> alias : " + aliasKey) ;
if (ks.isKeyEntry(aliasKey)) {
Certificate[] chain = ks.getCertificateChain(aliasKey);
System.out.println("---> chain length: " + chain.length);
for (Certificate cert: chain) {
System.out.println(cert);
}
}
If I add a single certificate with private key in the personal certificate store the chain length is 1. After adding the CA in the intermediate CA certificate store the I launch the program a second time and the chain length is now 2.
UPDATE (April, 2nd)
It is possible to programmatically add certificates in the Windows-MY
and Windows-ROOT
keystore with some limitations:
- when adding a certificate in the
Windows-ROOT
the user is prompted for confirmation
- all certificate added in the
Windows-MY
keystore is a TrustedCertificateEntry
(from the keystore point of view, not the Windows point of view). The keystore seems to build the longest possible chain with all available certificates.
- the certifcates with no associated private key are not visible in the Windows certificate store browser but it is possible to programmatically delete them.
Adding a certificate in a keystore is straightforward:
Certificate c = CertificateFactory.getInstance("X.509").generateCertificate(new FileInputStream("C:/Users/me/Downloads/myca.crt"));
KeyStore.TrustedCertificateEntry entry = new KeyStore.TrustedCertificateEntry(c);
ks.setEntry("CA1", entry , null);