--- old/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java 2018-06-04 19:27:17.718659724 -0300 +++ new/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java 2018-06-04 19:27:17.452657833 -0300 @@ -394,25 +394,40 @@ this.iv = iv; p11Key = P11SecretKeyFactory.convertKey(token, key, keyAlgorithm); try { - initialize(); + ensureInitialized(); } catch (PKCS11Exception e) { throw new InvalidKeyException("Could not initialize cipher", e); } } - private void cancelOperation() { - if (initialized == false) { - return; - } - - if ((session == null) || (token.explicitCancel == false)) { + // reset the states to the pre-initialized values + private void reset(boolean doCancel) { + if (!initialized) { return; } + initialized = false; try { - if (session.hasObjects() == false) { - session = token.killSession(session); + if (session == null) { return; - } else { + } + if (doCancel && token.explicitCancel) { + cancelOperation(); + } + } finally { + p11Key.decNativeKeyRef(); + session = token.releaseSession(session); + bytesBuffered = 0; + padBufferLen = 0; + } + } + + private void cancelOperation() { + token.ensureValid(); + if (session.hasObjects() == false) { + session = token.killSession(session); + return; + } else { + try { // cancel operation by finishing it int bufLen = doFinalLength(0); byte[] buffer = new byte[bufLen]; @@ -421,40 +436,42 @@ } else { token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen); } + } catch (PKCS11Exception e) { + throw new ProviderException("Cancel failed", e); } - } catch (PKCS11Exception e) { - throw new ProviderException("Cancel failed", e); } } private void ensureInitialized() throws PKCS11Exception { - if (initialized == false) { - initialize(); + if (initialized) { + return; } - } - - private void initialize() throws PKCS11Exception { - if (session == null) { - session = token.getOpSession(); + if (p11Key == null) { + throw new ProviderException( + "Operation cannot be performed without calling engineInit first"); } - CK_MECHANISM mechParams = (blockMode == MODE_CTR? - new CK_MECHANISM(mechanism, new CK_AES_CTR_PARAMS(iv)) : - new CK_MECHANISM(mechanism, iv)); - + token.ensureValid(); + p11Key.incNativeKeyRef(); try { + if (session == null) { + session = token.getOpSession(); + } + CK_MECHANISM mechParams = (blockMode == MODE_CTR? + new CK_MECHANISM(mechanism, new CK_AES_CTR_PARAMS(iv)) : + new CK_MECHANISM(mechanism, iv)); if (encrypt) { token.p11.C_EncryptInit(session.id(), mechParams, p11Key.keyID); } else { token.p11.C_DecryptInit(session.id(), mechParams, p11Key.keyID); } - } catch (PKCS11Exception ex) { - // release session when initialization failed + } catch (Throwable t) { + p11Key.decNativeKeyRef(); session = token.releaseSession(session); - throw ex; + throw t; } + initialized = true; bytesBuffered = 0; padBufferLen = 0; - initialized = true; } // if update(inLen) is called, how big does the output buffer have to be? @@ -485,18 +502,6 @@ return result; } - // reset the states to the pre-initialized values - private void reset(boolean doCancel) { - if (doCancel) cancelOperation(); - - initialized = false; - bytesBuffered = 0; - padBufferLen = 0; - if (session != null) { - session = token.releaseSession(session); - } - } - // see JCE spec protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) { try {