I have asked this question on Stackoverflow but I am beginning to think that this may be a better forum to ask.
According to JEP 131, Java 8 should provide a PKCS#11 Crypto provider for 64 bit Windows: https://blogs.oracle.com/mullan/entry/jep_131_pkcs_11_crypto.
With that in mind, I downloaded and built both 32 and 64 bit versions of NSS with NSPR using these instructions: https://developer.mozilla.org/en-US/docs/NSS_Sources_Building_Testing
I downloaded Java 8 for Windows 64 build b118, configured the java.security file and created a nss.cfg file:
Excerpt from java.security file:
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=sun.security.ec.SunEC
security.provider.4=com.sun.net.ssl.internal.ssl.Provider SunPKCS11-NSS
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
security.provider.10=sun.security.pkcs11.SunPKCS11 /devel/nss.cfg
From my nss.cfg file:
# Use NSS as a FIPS-140 compliant cryptographic token
# SunPKCS11-NSS
name = NSS
#32 bit
#nssLibraryDirectory = C:\devel\nss\nss-3.15.3.1\dist\WINNT6.1_DBG.OBJ\lib
#64 bit
nssLibraryDirectory = C:\devel\nss\nss-3.15.3.1\dist\WINNT6.1_64_DBG.OBJ\lib
#non FIPS
#nssDbMode = noDb
#attributes = compatibility
#FIPS
nssSecmodDirectory = c:\devel\fipsdb
nssModule = fips
I ran the test suite that comes with NSS and it looks like all of the encryption/decryption tests passed (did have some issues with the tests that required hostname/domainname but that has to do with the Windows environment).
So here is the problem. I run my test encryption app on Java 7 32 bit with the 32 bit version of NSS and everything works great. When I attempt to run Java 8 64 bit with 64 bit NSS I get the following error:
java.security.ProviderException: Could not initialize NSS
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:212)
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:103)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at sun.security.jca.ProviderConfig$2.run(Unknown Source)
at sun.security.jca.ProviderConfig$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.jca.ProviderConfig.doLoadProvider(Unknown Source)
at sun.security.jca.ProviderConfig.getProvider(Unknown Source)
at sun.security.jca.ProviderList.getProvider(Unknown Source)
at sun.security.jca.ProviderList.getIndex(Unknown Source)
at sun.security.jca.ProviderList.getProviderConfig(Unknown Source)
at sun.security.jca.ProviderList.getProvider(Unknown Source)
at java.security.Security.getProvider(Unknown Source)
at sun.security.ssl.SunJSSE.<init>(Unknown Source)
at sun.security.ssl.SunJSSE.<init>(Unknown Source)
at com.sun.net.ssl.internal.ssl.Provider.<init>(Unknown Source)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at sun.security.jca.ProviderConfig$2.run(Unknown Source)
at sun.security.jca.ProviderConfig$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.jca.ProviderConfig.doLoadProvider(Unknown Source)
at sun.security.jca.ProviderConfig.getProvider(Unknown Source)
at sun.security.jca.ProviderList.getProvider(Unknown Source)
at sun.security.jca.ProviderList$ServiceList.tryGet(Unknown Source)
at sun.security.jca.ProviderList$ServiceList.access$200(Unknown Source)
at sun.security.jca.ProviderList$ServiceList$1.hasNext(Unknown Source)
at javax.crypto.KeyGenerator.nextSpi(KeyGenerator.java:323)
at javax.crypto.KeyGenerator.<init>(KeyGenerator.java:158)
at javax.crypto.KeyGenerator.getInstance(KeyGenerator.java:208)
at STSAESEncryption.generateKeyWithGenerator(STSAESEncryption.java:74)
at Main.main(Main.java:24)
Caused by: java.io.IOException: %1 is not a valid Win32 application.
at sun.security.pkcs11.Secmod.nssLoadLibrary(Native Method)
at sun.security.pkcs11.Secmod.initialize(Secmod.java:210)
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:207)
... 36 more
Has JEP 131 been implemented with Windows/Java 64 bit as of b119? If so has it been verified to work with NSS or should I submit a bug report? I did download the code and the error is occurring in the following block of code at the line in bold (also with the arrow by it):
public synchronized void initialize(DbMode dbMode, String configDir,
String nssLibDir, boolean nssOptimizeSpace) throws IOException {
if (isInitialized()) {
throw new IOException("NSS is already initialized");
}
if (dbMode == null) {
throw new NullPointerException();
}
if ((dbMode != DbMode.NO_DB) && (configDir == null)) {
throw new NullPointerException();
}
String platformLibName = System.mapLibraryName("nss3");
String platformPath;
if (nssLibDir == null) {
platformPath = platformLibName;
} else {
File base = new File(nssLibDir);
if (base.isDirectory() == false) {
throw new IOException("nssLibDir must be a directory:" + nssLibDir);
}
File platformFile = new File(base, platformLibName);
if (platformFile.isFile() == false) {
throw new FileNotFoundException(platformFile.getPath());
}
platformPath = platformFile.getPath();
}
if (configDir != null) {
File configBase = new File(configDir);
if (configBase.isDirectory() == false ) {
throw new IOException("configDir must be a directory: " + configDir);
}
File secmodFile = new File(configBase, "secmod.db");
if (secmodFile.isFile() == false) {
throw new FileNotFoundException(secmodFile.getPath());
}
}
if (DEBUG) System.out.println("lib: " + platformPath);
---> nssHandle = nssLoadLibrary(platformPath);
if (DEBUG) System.out.println("handle: " + nssHandle);
fetchVersions();
if (supported == false) {
throw new IOException
("The specified version of NSS is incompatible, "
+ "3.7 or later required");
}
if (DEBUG) System.out.println("dir: " + configDir);
boolean initok = nssInitialize(dbMode.functionName, nssHandle,
configDir, nssOptimizeSpace);
if (DEBUG) System.out.println("init: " + initok);
if (initok == false) {
throw new IOException("NSS initialization failed");
}
this.configDir = configDir;
this.nssLibDir = nssLibDir;
}
Any help or advise about filing a bug report would be appreciated.
Thanks,