11/*
2- * Copyright (c) 2003, 2020 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2003, 2021 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
@@ -439,6 +439,13 @@ private void cancelOperation() {
439439 token .p11 .C_DecryptFinal (session .id (), 0 , buffer , 0 , bufLen );
440440 }
441441 } catch (PKCS11Exception e ) {
442+ if (e .getErrorCode () == CKR_OPERATION_NOT_INITIALIZED ) {
443+ // Cancel Operation may be invoked after an error on a PKCS#11
444+ // call. If the operation inside the token was already cancelled,
445+ // do not fail here. This is part of a defensive mechanism for
446+ // PKCS#11 libraries that do not strictly follow the standard.
447+ return ;
448+ }
442449 if (encrypt ) {
443450 throw new ProviderException ("Cancel failed" , e );
444451 }
@@ -628,7 +635,11 @@ private int implUpdate(byte[] in, int inOfs, int inLen,
628635 throw (ShortBufferException )
629636 (new ShortBufferException ().initCause (e ));
630637 }
631- reset (false );
638+ // Some implementations such as the NSS Software Token do not
639+ // cancel the operation upon a C_EncryptUpdate/C_DecryptUpdate
640+ // failure (as required by the PKCS#11 standard). See JDK-8258833
641+ // for further information.
642+ reset (true );
632643 throw new ProviderException ("update() failed" , e );
633644 }
634645 }
@@ -746,7 +757,11 @@ private int implUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
746757 throw (ShortBufferException )
747758 (new ShortBufferException ().initCause (e ));
748759 }
749- reset (false );
760+ // Some implementations such as the NSS Software Token do not
761+ // cancel the operation upon a C_EncryptUpdate/C_DecryptUpdate
762+ // failure (as required by the PKCS#11 standard). See JDK-8258833
763+ // for further information.
764+ reset (true );
750765 throw new ProviderException ("update() failed" , e );
751766 }
752767 }
@@ -770,9 +785,14 @@ private int implDoFinal(byte[] out, int outOfs, int outLen)
770785 0 , padBuffer , 0 , actualPadLen ,
771786 0 , out , outOfs , outLen );
772787 }
788+ // Some implementations such as the NSS Software Token do not
789+ // cancel the operation upon a C_EncryptUpdate failure (as
790+ // required by the PKCS#11 standard). Cancel is not needed
791+ // only after this point. See JDK-8258833 for further
792+ // information.
793+ doCancel = false ;
773794 k += token .p11 .C_EncryptFinal (session .id (),
774795 0 , out , (outOfs + k ), (outLen - k ));
775- doCancel = false ;
776796 } else {
777797 // Special handling to match SunJCE provider behavior
778798 if (bytesBuffered == 0 && padBufferLen == 0 ) {
@@ -784,22 +804,26 @@ private int implDoFinal(byte[] out, int outOfs, int outLen)
784804 padBuffer , 0 , padBufferLen , 0 , padBuffer , 0 ,
785805 padBuffer .length );
786806 }
807+ // Some implementations such as the NSS Software Token do not
808+ // cancel the operation upon a C_DecryptUpdate failure (as
809+ // required by the PKCS#11 standard). Cancel is not needed
810+ // only after this point. See JDK-8258833 for further
811+ // information.
812+ doCancel = false ;
787813 k += token .p11 .C_DecryptFinal (session .id (), 0 , padBuffer , k ,
788814 padBuffer .length - k );
789- doCancel = false ;
790815
791816 int actualPadLen = paddingObj .unpad (padBuffer , k );
792817 k -= actualPadLen ;
793818 System .arraycopy (padBuffer , 0 , out , outOfs , k );
794819 } else {
820+ doCancel = false ;
795821 k = token .p11 .C_DecryptFinal (session .id (), 0 , out , outOfs ,
796822 outLen );
797- doCancel = false ;
798823 }
799824 }
800825 return k ;
801826 } catch (PKCS11Exception e ) {
802- doCancel = false ;
803827 handleException (e );
804828 throw new ProviderException ("doFinal() failed" , e );
805829 } finally {
@@ -845,9 +869,14 @@ private int implDoFinal(ByteBuffer outBuffer)
845869 0 , padBuffer , 0 , actualPadLen ,
846870 outAddr , outArray , outOfs , outLen );
847871 }
872+ // Some implementations such as the NSS Software Token do not
873+ // cancel the operation upon a C_EncryptUpdate failure (as
874+ // required by the PKCS#11 standard). Cancel is not needed
875+ // only after this point. See JDK-8258833 for further
876+ // information.
877+ doCancel = false ;
848878 k += token .p11 .C_EncryptFinal (session .id (),
849879 outAddr , outArray , (outOfs + k ), (outLen - k ));
850- doCancel = false ;
851880 } else {
852881 // Special handling to match SunJCE provider behavior
853882 if (bytesBuffered == 0 && padBufferLen == 0 ) {
@@ -861,18 +890,23 @@ private int implDoFinal(ByteBuffer outBuffer)
861890 0 , padBuffer , 0 , padBuffer .length );
862891 padBufferLen = 0 ;
863892 }
893+ // Some implementations such as the NSS Software Token do not
894+ // cancel the operation upon a C_DecryptUpdate failure (as
895+ // required by the PKCS#11 standard). Cancel is not needed
896+ // only after this point. See JDK-8258833 for further
897+ // information.
898+ doCancel = false ;
864899 k += token .p11 .C_DecryptFinal (session .id (),
865900 0 , padBuffer , k , padBuffer .length - k );
866- doCancel = false ;
867901
868902 int actualPadLen = paddingObj .unpad (padBuffer , k );
869903 k -= actualPadLen ;
870904 outArray = padBuffer ;
871905 outOfs = 0 ;
872906 } else {
907+ doCancel = false ;
873908 k = token .p11 .C_DecryptFinal (session .id (),
874909 outAddr , outArray , outOfs , outLen );
875- doCancel = false ;
876910 }
877911 }
878912 if ((!encrypt && paddingObj != null ) ||
@@ -884,7 +918,6 @@ private int implDoFinal(ByteBuffer outBuffer)
884918 }
885919 return k ;
886920 } catch (PKCS11Exception e ) {
887- doCancel = false ;
888921 handleException (e );
889922 throw new ProviderException ("doFinal() failed" , e );
890923 } finally {
0 commit comments