The Wrapper Key may get deleted when closing sessions in the SunPKCS11 crypto provider. In particular, when closing the session used to create it in NativeKeyHolder class constructor [1]. After deleting the native Wrapper Key, following wrapping and unwrapping operations use an invalid handle and fail -returned error is CKR_OBJECT_HANDLE_INVALID-.
This is a call-stack example of the Wrapper Key being deleted on the NSS software token side:
(gdb) bt
#0 sftk_DeleteObject (session=session@entry=0x7ff9388a8a80, object=0x7ff9386dc960) at pkcs11u.c:1188
#1 0x00007ff9402f9ac6 in sftk_DestroySession (session=0x7ff9388a8a80) at pkcs11u.c:1812
#2 sftk_FreeSession (session=0x7ff9388a8a80) at pkcs11u.c:1871
#3 0x00007ff9402e60ff in NSC_CloseSession (hSession=<optimized out>) at pkcs11.c:3935
#4 0x00007ff8fa846211 in Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseSession (env=0x7ff93801bb90, obj=0x7ff9415348c8, jSessionHandle=2147483651)
#5 0x00007ff9209a503c in ?? ()
#6 0x00007ff91091f818 in ?? ()
#7 0x00007ff9415348c8 in ?? ()
#8 0x00007ff91096a270 in ?? ()
#9 0x0000000000000000 in ?? ()
The reason why this happens is because the object count in the session is not incremented when creating the Wrapper Key. Once the object count is incremented, and considering the Wrapper Key lifetime, the session will never be closed.
In addition to this bug, there is a potential race-condition bug affecting the same Wrapper Key creation code. Before creating the Wrapper Key, there is a check to decide if the Wrapper Key exists [2]. However, this check is not synchronized so 2 or more threads can then enter the synchronized block -one after each other- without checking if a Wrapper Key was created.
--
[1] - http://hg.openjdk.java.net/jdk/jdk/file/daec95ed6795/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java#l1180
[2] - http://hg.openjdk.java.net/jdk/jdk/file/daec95ed6795/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java#l1169