Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ public static boolean signedBy(X509Certificate end, X509Certificate ca) {
public static boolean isWindowsKeyStore(String storetype) {
return storetype != null
&& (storetype.equalsIgnoreCase("Windows-MY")
|| storetype.equalsIgnoreCase("Windows-ROOT"));
|| storetype.equalsIgnoreCase("Windows-ROOT")
|| storetype.equalsIgnoreCase("Windows-MY-CURRENTUSER")
|| storetype.equalsIgnoreCase("Windows-ROOT-CURRENTUSER")
|| storetype.equalsIgnoreCase("Windows-MY-LOCALMACHINE")
|| storetype.equalsIgnoreCase("Windows-ROOT-LOCALMACHINE"));
}

/**
Expand All @@ -102,6 +106,14 @@ public static String niceStoreTypeName(String storetype) {
return "Windows-MY";
} else if(storetype.equalsIgnoreCase("Windows-ROOT")) {
return "Windows-ROOT";
} else if(storetype.equalsIgnoreCase("Windows-MY-CURRENTUSER")) {
return "Windows-MY-CURRENTUSER";
} else if(storetype.equalsIgnoreCase("Windows-ROOT-CURRENTUSER")) {
return "Windows-ROOT-CURRENTUSER";
} else if(storetype.equalsIgnoreCase("Windows-MY-LOCALMACHINE")) {
return "Windows-MY-LOCALMACHINE";
} else if(storetype.equalsIgnoreCase("Windows-ROOT-LOCALMACHINE")) {
return "Windows-ROOT-LOCALMACHINE";
} else {
return storetype.toUpperCase(Locale.ENGLISH);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,30 @@
*/
abstract class CKeyStore extends KeyStoreSpi {

private static final int LOCATION_CURRENTUSER = 0;
private static final int LOCATION_LOCALMACHINE = 1;

public static final class MY extends CKeyStore {
public MY() {
super("MY");
super("MY", LOCATION_CURRENTUSER);
}
}

public static final class ROOT extends CKeyStore {
public ROOT() {
super("ROOT");
super("ROOT", LOCATION_CURRENTUSER);
}
}

public static final class MYLocalMachine extends CKeyStore {
public MYLocalMachine() {
super("MY", LOCATION_LOCALMACHINE);
}
}

public static final class ROOTLocalMachine extends CKeyStore {
public ROOTLocalMachine() {
super("ROOT", LOCATION_LOCALMACHINE);
}
}

Expand Down Expand Up @@ -220,7 +235,12 @@ public void delete() throws KeyStoreException {
*/
private final String storeName;

CKeyStore(String storeName) {
/*
* The keystore location.
*/
private final int storeLocation;

CKeyStore(String storeName, int storeLocation) {
// Get the compatibility mode
@SuppressWarnings("removal")
String prop = AccessController.doPrivileged(
Expand All @@ -233,6 +253,7 @@ public void delete() throws KeyStoreException {
}

this.storeName = storeName;
this.storeLocation = storeLocation;
}

/**
Expand All @@ -259,7 +280,7 @@ public void delete() throws KeyStoreException {
* @exception UnrecoverableKeyException if the key cannot be recovered.
*/
public java.security.Key engineGetKey(String alias, char[] password)
throws NoSuchAlgorithmException, UnrecoverableKeyException {
throws NoSuchAlgorithmException, UnrecoverableKeyException {
if (alias == null) {
return null;
}
Expand Down Expand Up @@ -705,7 +726,7 @@ public void engineLoad(InputStream stream, char[] password)
try {

// Load keys and/or certificate chains
loadKeysOrCertificateChains(getName());
loadKeysOrCertificateChains(getName(), getLocation());

} catch (KeyStoreException e) {
throw new IOException(e);
Expand Down Expand Up @@ -801,7 +822,7 @@ private void generateKeyAndCertificateChain(boolean isRSA, String alias,
* @param certCollection Collection of certificates.
*/
private void generateCertificate(byte[] data,
Collection<Certificate> certCollection) {
Collection<Certificate> certCollection) {
try {
ByteArrayInputStream bis = new ByteArrayInputStream(data);

Expand Down Expand Up @@ -829,12 +850,20 @@ private String getName() {
}

/**
* Load keys and/or certificates from keystore into Collection.
* Returns the location of the keystore.
*/
private int getLocation() {
return storeLocation;
}

/**
* Loads keys and/or certificates from keystore into Collection.
*
* @param name Name of keystore.
* @param location Location of keystore.
*/
private native void loadKeysOrCertificateChains(String name)
throws KeyStoreException;
private native void loadKeysOrCertificateChains(String name,
int location) throws KeyStoreException;

/**
* Stores a DER-encoded certificate into the certificate store
Expand All @@ -844,8 +873,8 @@ private native void loadKeysOrCertificateChains(String name)
* @param encoding DER-encoded certificate.
*/
private native void storeCertificate(String name, String alias,
byte[] encoding, int encodingLength, long hCryptProvider,
long hCryptKey) throws CertificateException, KeyStoreException;
byte[] encoding, int encodingLength, long hCryptProvider,
long hCryptKey) throws CertificateException, KeyStoreException;

/**
* Removes the certificate from the certificate store
Expand All @@ -855,7 +884,7 @@ private native void storeCertificate(String name, String alias,
* @param encoding DER-encoded certificate.
*/
private native void removeCertificate(String name, String alias,
byte[] encoding, int encodingLength)
byte[] encoding, int encodingLength)
throws CertificateException, KeyStoreException;

/**
Expand All @@ -864,7 +893,7 @@ private native void removeCertificate(String name, String alias,
* @param keyContainerName The name of the key container.
*/
private native void destroyKeyContainer(String keyContainerName)
throws KeyStoreException;
throws KeyStoreException;

/**
* Removes a CNG key.
Expand All @@ -877,16 +906,16 @@ private native void destroyKeyContainer(String keyContainerName)
* Generates a private-key BLOB from a key's components.
*/
private native byte[] generateRSAPrivateKeyBlob(
int keyBitLength,
byte[] modulus,
byte[] publicExponent,
byte[] privateExponent,
byte[] primeP,
byte[] primeQ,
byte[] exponentP,
byte[] exponentQ,
byte[] crtCoefficient) throws InvalidKeyException;
int keyBitLength,
byte[] modulus,
byte[] publicExponent,
byte[] privateExponent,
byte[] primeP,
byte[] primeQ,
byte[] exponentP,
byte[] exponentQ,
byte[] crtCoefficient) throws InvalidKeyException;

private native CPrivateKey storePrivateKey(String alg, byte[] keyBlob,
String keyContainerName, int keySize) throws KeyStoreException;
String keyContainerName, int keySize) throws KeyStoreException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,14 @@ public Object newInstance(Object ctrParamObj)
return new PRNG();
}
} else if (type.equals("KeyStore")) {
if (algo.equals("Windows-MY")) {
if (algo.equals("Windows-MY") || algo.equals("Windows-MY-CURRENTUSER")) {
return new CKeyStore.MY();
} else if (algo.equals("Windows-ROOT")) {
} else if (algo.equals("Windows-ROOT") || algo.equals("Windows-ROOT-CURRENTUSER")) {
return new CKeyStore.ROOT();
} else if (algo.equals("Windows-MY-LOCALMACHINE")) {
return new CKeyStore.MYLocalMachine();
} else if (algo.equals("Windows-ROOT-LOCALMACHINE")) {
return new CKeyStore.ROOTLocalMachine();
}
} else if (type.equals("Signature")) {
if (algo.equals("NONEwithRSA")) {
Expand Down Expand Up @@ -165,8 +169,16 @@ public Void run() {
*/
putService(new ProviderService(p, "KeyStore",
"Windows-MY", "sun.security.mscapi.CKeyStore$MY"));
putService(new ProviderService(p, "KeyStore",
"Windows-MY-CURRENTUSER", "sun.security.mscapi.CKeyStore$MY"));
putService(new ProviderService(p, "KeyStore",
"Windows-ROOT", "sun.security.mscapi.CKeyStore$ROOT"));
putService(new ProviderService(p, "KeyStore",
"Windows-ROOT-CURRENTUSER", "sun.security.mscapi.CKeyStore$ROOT"));
putService(new ProviderService(p, "KeyStore",
"Windows-MY-LOCALMACHINE", "sun.security.mscapi.CKeyStore$MYLocalMachine"));
putService(new ProviderService(p, "KeyStore",
"Windows-ROOT-LOCALMACHINE", "sun.security.mscapi.CKeyStore$ROOTLocalMachine"));

/*
* Signature engines
Expand Down
26 changes: 20 additions & 6 deletions src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
#define SIGNATURE_EXCEPTION "java/security/SignatureException"
#define OUT_OF_MEMORY_ERROR "java/lang/OutOfMemoryError"

#define KEYSTORE_LOCATION_CURRENTUSER 0
#define KEYSTORE_LOCATION_LOCALMACHINE 1

#define SS_CHECK(Status) \
if (Status != ERROR_SUCCESS) { \
ThrowException(env, SIGNATURE_EXCEPTION, Status); \
Expand Down Expand Up @@ -386,10 +389,10 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_PRNG_generateSeed
/*
* Class: sun_security_mscapi_CKeyStore
* Method: loadKeysOrCertificateChains
* Signature: (Ljava/lang/String;)V
* Signature: (Ljava/lang/String;I)V
*/
JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateChains
(JNIEnv *env, jobject obj, jstring jCertStoreName)
(JNIEnv *env, jobject obj, jstring jCertStoreName, jint jCertStoreLocation)
{
/**
* Certificate in cert store has enhanced key usage extension
Expand All @@ -407,16 +410,27 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC
char* pszNameString = NULL; // certificate's friendly name
DWORD cchNameString = 0;


__try
{
// Open a system certificate store.
if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
== NULL) {
__leave;
}
if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName))
== NULL) {

if (jCertStoreLocation == KEYSTORE_LOCATION_CURRENTUSER) {
hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName);
}
else if (jCertStoreLocation == KEYSTORE_LOCATION_LOCALMACHINE) {
hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, NULL,
CERT_SYSTEM_STORE_LOCAL_MACHINE, pszCertStoreName);
}
else {
PP("jCertStoreLocation is not a valid value");
__leave;
}

if (hCertStore == NULL) {

ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
__leave;
Expand Down Expand Up @@ -469,7 +483,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC
PP("--------------------------");
// Check if private key available - client authentication certificate
// must have private key available.
HCRYPTPROV hCryptProv = NULL;
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv = NULL;
DWORD dwKeySpec = 0;
HCRYPTKEY hUserKey = NULL;
BOOL bCallerFreeProv = FALSE;
Expand Down
87 changes: 87 additions & 0 deletions test/jdk/sun/security/mscapi/AllTypes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

import jdk.test.lib.Asserts;
import jdk.test.lib.SecurityTools;

import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

/*
* @test
* @bug 6782021
* @requires os.family == "windows"
* @library /test/lib
* @summary More keystore types
*/
public class AllTypes {

public static void main(String[] args) throws Exception {
var nm = test("windows-my");
var nr = test("windows-root");
var nmu = test("windows-my-currentuser");
var nru = test("windows-root-currentuser");
var hasAdminPrivileges = detectIfRunningWithAdminPrivileges();
var nmm = adminTest("windows-my-localmachine", hasAdminPrivileges);
var nrm = adminTest("windows-root-localmachine", hasAdminPrivileges);
Asserts.assertEQ(nm, nmu);
Asserts.assertEQ(nr, nru);
}

private static boolean detectIfRunningWithAdminPrivileges() {
try {
Process p = Runtime.getRuntime().exec("reg query \"HKU\\S-1-5-19\"");
p.waitFor();
return (p.exitValue() == 0);
}
catch (Exception ex) {
System.out.println("Warning: unable to detect admin privileges, assuming none");
return false;
}
}

private static List<String> adminTest(String type, boolean hasAdminPrivileges) throws Exception {
if (hasAdminPrivileges) {
return test(type);
}
System.out.println("Ignoring: " + type + " as it requires admin privileges");
return null;
}

private static List<String> test(String type) throws Exception {
var stdType = "Windows-" + type.substring(8).toUpperCase(Locale.ROOT);
SecurityTools.keytool("-storetype " + type + " -list")
.shouldHaveExitValue(0)
.shouldContain("Keystore provider: SunMSCAPI")
.shouldContain("Keystore type: " + stdType);
KeyStore ks = KeyStore.getInstance(type);
ks.load(null, null);
var content = Collections.list(ks.aliases());
Collections.sort(content);
return content;
}
}