У меня есть приложение для подписи PDF, которое работает на tomcat, используя SunPKCS11 и подключенный к сети HSM.Поставщик хранится в контексте приложения и извлекается из него при необходимости.Все работает нормально, за исключением того, что после потери связи между tomcat и HSM (например, после сбоя в сети) поставщик PKCS11 не восстанавливается, и tomcat необходимо перезапустить.Я ищу способ повторно инициализировать провайдера после сбоя (который я ловлю и на него реагирую).
public Provider loadProvider(Boolean forceReInit) {
ServletContext ctx = getServletContext();
Provider provider = null;
Provider cached = (Provider)ctx.getAttribute("cachedProvider");
if(cached == null || forceReInit) {
for(Provider p: Security.getProviders()) {
if(p.getName().contains("PKCS11")) {
Security.removeProvider(p.getName());
p.clear();
}
}
String configPath = "/path/to/pkcs11.cfg";
provider = new SunPKCS11(new FileInputStream(configPath)); // Exception here
Security.addProvider(provider);
ctx.setAttribute("cachedProvider", provider);
} else {
provider = cached;
}
return provider;
}
Используется так:
public class Signer {
...
for(int i=0; i<2; i++) {
Boolean forceReInit = (i>0);
try {
Provider p = loadProvider(forceReInit);
return signDocumentWithProvider(p);
} catch(Exception ex) {
if(forceReInit) {
// bail out after second failure
throw(ex);
}
continue;
}
}
}
Я всегда получаю java.security.ProviderException
при попытке загрузить новый SunPKCS11, если он уже был загружен ранее, даже если я его выгрузил.В зависимости от типа ошибки / сбоя, которые приводят к перезагрузке провайдера, исключение может отличаться, но впоследствии оно остается постоянным (ниже приведен один пример).
Caused by: java.security.ProviderException: Initialization failed
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:376)
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:107)
at my.package.loadProvider(Signer.java:102)
... 28 more
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_GENERAL_ERROR
at sun.security.pkcs11.wrapper.PKCS11.C_GetTokenInfo(Native Method)
at sun.security.pkcs11.Token.<init>(Token.java:135)
at sun.security.pkcs11.SunPKCS11.initToken(SunPKCS11.java:858)
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:367)
... 30 more
Кто-нибудь знает, как я могу повторно инициализировать провайдера SunPKCS11после сбоя драйвера?