We have created a new site for our web where we let the users to sign a pdf document using an applet we have designed. The issue is that this applet works fine only in Windows OS and we would like to extend it to linux OS.
When we run the applet in linux we get this error message:
[opensc-pkcs11] reader-pcsc.c:896:pcsc_detect_readers: SCardListReaders failed: 0x8010002e [opensc-pkcs11] reader-pcsc.c:1015:pcsc_detect_readers: returning with: No readers found [opensc-pkcs11] reader-pcsc.c:896:pcsc_detect_readers: SCardListReaders failed: 0x8010002e [opensc-pkcs11] reader-pcsc.c:1015:pcsc_detect_readers: returning with: No readers found java.security.NoSuchProviderException: no such provider: SunMSCAPI at sun.security.jca.GetInstance.getService(Unknown Source) at sun.security.jca.GetInstance.getInstance(Unknown Source)
I think the problem comes when we try to read the certificated stored in the Windows OS with this call in our code:
KeyStore keystore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
keystore.load(null, null);
return keystore;
This is te function we use to obtain the list of certificates.
public KeyStore obtenerCertificados() throws Exception {
String osNombre = System.getProperty("os.name");
String osArquitectura = System.getProperty("os.arch");
String providerConfig = null;
String configuracionPKCS11 = null;
// LINUX
if(osNombre.contains(new StringBuffer("Linux")))
providerConfig = "name = OpenSC\nlibrary = /usr/lib/opensc-pkcs11.so\n";
// WINDOWS
else if(osNombre.contains(new StringBuffer("Windows")))
if(!osArquitectura.toLowerCase().contains("x86")){
System.out.println("Estamos en toLowerCase().contains x86");
providerConfig = "name = NSS"+"\n"+
"nssLibraryDirectory = "+"C:/Archivos de programa/Mozilla Firefox"+"\n"+
"nssSecmodDirectory = "+"C:/Users/SM/AppData/Local/Mozilla/Firefox/Profiles/plmk3eh9.default"+"\n"+
"nssDbMode = readOnly" + "\n" +
"nssModule = keystore" + "\n" +
"\r";
}
else{
System.out.println("Estamos en NO toLowerCase().contains x86");
providerConfig = "name = NSS"+"\n"+
"nssLibraryDirectory = "+"C:/Program Files (x86)/Mozilla Firefox"+"\n"+
"nssLibrary = "+"C:/Program Files (x86)/Mozilla Firefox/softokn3.dll"+"\n"+
"nssSecmodDirectory = "+"C:/Users/SM/AppData/Roaming/Mozilla/Firefox/Profiles/plmk3eh9.default"+"\n"+
"nssDbMode = readOnly" + "\n" +
"nssModule = keystore" + "\n" +
"\r";
}
// MAC OS
else {providerConfig = "name = OpenSC\nlibrary = /Library/OpenSC/lib/opensc-pkcs11.so\n";}
ByteArrayInputStream localByteArrayInputStream = new ByteArrayInputStream(providerConfig.getBytes());
SunPKCS11 _pk11provider = null;
try {
_pk11provider = new SunPKCS11(localByteArrayInputStream);
Security.addProvider(_pk11provider);
// _pk11provider.login(new Subject(), new DialogCallbackHandler());
}catch(Throwable e){
System.out.println(e.getMessage());
}
KeyStore keystore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
keystore.load(null, null);
return keystore;
}
Any ideas about how to extend this use to linux and MAC???
Thanks a lot for your help!!
You can not use
SunMSCAPI
provider in Linux or MAC OS X, this provider is Windows specific which deals with Windows keystore. If you want to use a Smart Card or Firefox keystore in Linux or MAC OS X throughSunPKCS11
provider you must get an instance ofjava.security.KeyStore
passingSunPKCS11
as provider, like you are doing withSunMSCAPI
i.e:With this code you load on the
Keystore ks
the keys from your configured PKCS11.There is another way to do it if you want that your PKCS11 pin will be introduced by a third party later. To do so you can initialize your keystore with a
java.security.KeyStore.CallbackHandlerProtection
parameter like follows:Note that
PinInputHandler
in this second sample must implements:javax.security.auth.callback.CallbackHandler
.Additionally in your code seems that you never loads the PKCS11 keys through
SunPKCS11
provider (even in Windows case) because you are not instantiating a keystore withSunPKCS11
you are only adding it as a provider withSecurity.addProvider
method and always you are instantiating only a keystore withSunMSCAPI
, however probably in Windows you are getting some of your Smart cards keys because if you install Windows drivers for you smart card you can get their keys through Windows keystore.Hope this helps,