Background information Which might help in alaysis :
From a web application i am trying to connect to smart card and read certificates from a java program which runs on client machine to perform some signing operation. I am using Opensc-PKCS11.dll with java sunpkcs11 provider class to access certificate on the smart card (FIPS PIV compliance smart card).
My problem is as long as smart card is connected i am able access keystore on smart card and perform crypto operations, but when we remove smart card and insert again, program not able to fetch slot id due to which loading of provider fails.
Since i cannot hard code my slot id i am leaving it as either 0/-1
Config file content
Name="Opensc"
Library="OpenSC-PKCS11.dll"
slot=-1
showinfo=true
byte[] pkcs11configBytes = configName.getBytes();
ByteArrayInputStream confStream = new ByteArrayInputStream(pkcs11configBytes);
bc = new org.bouncycastle.jce.provider.BouncyCastleProvider();
Security.addProvider(bc);
sun = new sun.security.pkcs11.SunPKCS11(confStream);
Security.addProvider(sun);
This question does provide enough information though related. Java - how to detect smartcard hotplug
Update: I could fix the issue. In finally block I invoked C_Finalize from provider after my job with provider is finished. For the next run in the same java instance i did some thing like below clearing PKCS11 map and initialize provider again
Field moduleMapField = PKCS11.class.getDeclaredField("moduleMap");
moduleMapField.setAccessible(true);
Map<?, ?> moduleMap = (Map<?, ?>) moduleMapField.get(null);
moduleMap.clear(); // force re-execution of C_Initialize next time
//load PKCS#11
Method getInstanceMethod = PKCS11.class.getMethod("getInstance",
String.class, String.class, CK_C_INITIALIZE_ARGS.class,
Boolean.TYPE);
CK_C_INITIALIZE_ARGS ck_c_initialize_args = new CK_C_INITIALIZE_ARGS();
pkcs11 = (PKCS11) getInstanceMethod.invoke(null, libFile,
"C_GetFunctionList", ck_c_initialize_args, false);