--- old/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java 2018-06-04 19:27:26.467721920 -0300 +++ new/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java 2018-06-04 19:27:26.269720513 -0300 @@ -263,31 +263,35 @@ } } - private void ensureInitialized() { - token.ensureValid(); - if (initialized == false) { - initialize(); + // reset the states to the pre-initialized values + private void reset(boolean doCancel) { + if (!initialized) { + return; + } + initialized = false; + try { + if (session == null) { + return; + } + if (doCancel && token.explicitCancel) { + cancelOperation(); + } + } finally { + p11Key.decNativeKeyRef(); + session = token.releaseSession(session); } } private void cancelOperation() { token.ensureValid(); - if (initialized == false) { - return; - } - initialized = false; - if ((session == null) || (token.explicitCancel == false)) { - return; - } if (session.hasObjects() == false) { session = token.killSession(session); return; - } - try { + } else { // "cancel" operation by finishing it // XXX make sure all this always works correctly - if (mode == M_SIGN) { - try { + try { + if (mode == M_SIGN) { if (type == T_UPDATE) { token.p11.C_SignFinal(session.id(), 0); } else { @@ -299,11 +303,7 @@ } token.p11.C_Sign(session.id(), digest); } - } catch (PKCS11Exception e) { - throw new ProviderException("cancel failed", e); - } - } else { // M_VERIFY - try { + } else { // M_VERIFY byte[] signature; if (keyAlgorithm.equals("DSA")) { signature = new byte[40]; @@ -321,40 +321,48 @@ } token.p11.C_Verify(session.id(), digest, signature); } - } catch (PKCS11Exception e) { - // will fail since the signature is incorrect - // XXX check error code } + } catch (PKCS11Exception e) { + throw new ProviderException("cancel failed", e); } - } finally { - session = token.releaseSession(session); } } // assumes current state is initialized == false - private void initialize() { + private void ensureInitialized() { + if (initialized) { + return; + } + if (p11Key == null) { + throw new ProviderException( + "Operation cannot be performed without calling engineInit first"); + } try { - if (session == null) { - session = token.getOpSession(); - } - if (mode == M_SIGN) { - token.p11.C_SignInit(session.id(), - new CK_MECHANISM(mechanism), p11Key.keyID); - } else { - token.p11.C_VerifyInit(session.id(), - new CK_MECHANISM(mechanism), p11Key.keyID); + token.ensureValid(); + p11Key.incNativeKeyRef(); + try { + if (session == null) { + session = token.getOpSession(); + } + if (mode == M_SIGN) { + token.p11.C_SignInit(session.id(), + new CK_MECHANISM(mechanism), p11Key.keyID); + } else { + token.p11.C_VerifyInit(session.id(), + new CK_MECHANISM(mechanism), p11Key.keyID); + } + } catch (Throwable t) { + p11Key.decNativeKeyRef(); + session = token.releaseSession(session); + throw t; } initialized = true; - } catch (PKCS11Exception e) { - // release session when initialization failed - session = token.releaseSession(session); - throw new ProviderException("Initialization failed", e); - } - if (bytesProcessed != 0) { - bytesProcessed = 0; - if (md != null) { + if (bytesProcessed != 0 && md != null) { md.reset(); } + bytesProcessed = 0; + } catch (PKCS11Exception e) { + throw new ProviderException("Initialization failed", e); } } @@ -451,10 +459,10 @@ if (publicKey != p11Key) { checkKeySize(keyAlgorithm, publicKey); } - cancelOperation(); + reset(true); mode = M_VERIFY; p11Key = P11KeyFactory.convertKey(token, publicKey, keyAlgorithm); - initialize(); + ensureInitialized(); } // see JCA spec @@ -468,10 +476,10 @@ if (privateKey != p11Key) { checkKeySize(keyAlgorithm, privateKey); } - cancelOperation(); + reset(true); mode = M_SIGN; p11Key = P11KeyFactory.convertKey(token, privateKey, keyAlgorithm); - initialize(); + ensureInitialized(); } // see JCA spec @@ -517,8 +525,7 @@ } bytesProcessed += len; } catch (PKCS11Exception e) { - initialized = false; - session = token.releaseSession(session); + reset(true); throw new ProviderException(e); } break; @@ -641,11 +648,10 @@ } catch (PKCS11Exception pe) { throw new ProviderException(pe); } catch (SignatureException | ProviderException e) { - cancelOperation(); + reset(true); throw e; } finally { - initialized = false; - session = token.releaseSession(session); + reset(false); } } @@ -710,11 +716,10 @@ } throw new ProviderException(pe); } catch (SignatureException | ProviderException e) { - cancelOperation(); + reset(true); throw e; } finally { - initialized = false; - session = token.releaseSession(session); + reset(false); } }