Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

remove and insert smartcard using sunpkcs#11 and tomcat

I have a web application running on Tomcat. My application uses a web service which signs (via smartcard) and sends email. The web service itself adds the sunpkcs#11 provider automatically during the first call and before sending email, then can sign in and send emails if smartcard is not removed and inserted. If removed and inserted, in order to send email I must restart the tomcat server or it will give several errors depending on my code:

result= api.signAndSend(to, cc, bcc, subject, content, smartCardPin); 

After removing and inserting smart card this code gives below exception message:

Token has been removed

These are my tryings:

  1. I tried removing the sunpkcs#11 provider just after sending email and creating a new sunpkcs#11 provider and adding it.it gives and error like:

java.security.InvalidKeyException: No installed provider supports this key: sun.security.pkcs11.P11Key$P11PrivateKey or java.security.InvalidKeyException: No installed provider supports this key: null

  1. I did not remove sunpkcs#11 provider after each api.signAndSend(...) call,

rather :

  result= api.signAndSend(to, cc, bcc, subject, content, smartCardPin);  
  SunPKCS11 sunPKCS11=(SunPKCS11)getLastProvider();  
  sunPKCS11.logout();  
  sunPKCS11.setCallbackHandler(new MyCallbackHandler());  
  KeyStore.CallbackHandlerProtection cpprotection = new KeyStore.CallbackHandlerProtection(  
  new MyCallbackHandler());  
  KeyStore.Builder builder = KeyStore.Builder.newInstance(  
  "PKCS11", sunPKCS11, cpprotection);  
  KeyStore ks = builder.getKeyStore();  

//finalize PKCS#11  
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(i expect this code to load pkcs#11 again but i am not sure)  
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 = (PKCS11) getInstanceMethod.invoke(null, pkcs11Path,  
  "C_GetFunctionList", ck_c_initialize_args, false);  

this code gives:

java.security.ProviderException: Initialization failed at sun.security.pkcs11.P11Signature.initialize(P11Signature.java:319) at sun.security.pkcs11.P11Signature.engineInitSign(P11Signature.java:432) at java.security.Signature$Delegate.init(Signature.java:1127) at java.security.Signature$Delegate.chooseProvider(Signature.java:1087) at java.security.Signature$Delegate.engineInitSign(Signature.java:1151) at java.security.Signature.initSign(Signature.java:512) at org.esign.bouncycastle.operator.jcajce.JcaContentSignerBuilder.build(Unknown Source) . . . Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_KEY_HANDLE_INVALID at sun.security.pkcs11.wrapper.PKCS11.C_SignInit(Native Method) at sun.security.pkcs11.wrapper.PKCS11$SynchronizedPKCS11.C_SignInit(PKCS11.java:1721) at sun.security.pkcs11.P11Signature.initialize(P11Signature.java:311)

java: 1.8.0.31

edit: i remove and add SunPkcs#11 like this:

//the code below adds sunpkcss provider automatically after first call
result= api.signAndSend(to, cc, bcc, subject, content, smartCardPin);

//after each signAndSend i remove sunpkcs and add a new one
String sunpkcs11Name=getLastProvider().getName();
Security.removeProvider(sunpkcs11Name);

String cfg = MessageFormat.format(
                "name = Starcos-SunPkcs11  library = c:/windows/system32/aetpkss1.dll slot = 52481 ");
        InputStream is=new ByteArrayInputStream(cfg.getBytes());

SunPKCS11 newSunPkcs11Provider = new SunPKCS11(is);
Security.addProvider(newSunPkcs11Provider);

after i add a new SunPkcs11, while api.signAndSend(...) it gives:

java.security.InvalidKeyException: No installed provider supports this key: >sun.security.pkcs11.P11Key$P11PrivateKey

This exception is not because of absence of SunPkcs11 because i see the SunPkcs11 that i added, in the providers list.

like image 458
ihsan kocak Avatar asked Oct 19 '22 17:10

ihsan kocak


1 Answers

It is hard to find exact solution in this kind of problem because it is hard to reproduce it so according to my reading PKCS#11 is already cover this Smartcards being inserted and removed scenario according to its documentation,

This is fine for an application that treats PKCS#11 tokens as static keystores. For an application that wants to accommodate PKCS#11 tokens more dynamically, such as Smartcards being inserted and removed, you can use the new KeyStore.Builder class. Here is an example of how to initialize the builder for a PKCS#11 keystore with a callback handler.

You already mention that remove and add provider is not working for you but according to this post they solve it via this way.

like image 180
erhun Avatar answered Oct 29 '22 15:10

erhun