Package: opencryptoki Version: 2.2.8+dfsg-4 The TPM token code uses some global variables to track the storage root key, root public & private keys, and leaf public & private keys from the TPM. These variables are not properly reinitialized during unload and reload of the module. In the case of wpasupplicant, this results in PKCS#11 becoming unusable and one must kill the process to start a fresh reconfiguration.
How to reproduce, given a wpasupplicant configuration that uses opencryptoki to use the TPM for private key: - Connect to the network once, ensure a normal connection is possible. - Kill the opencryptoki pkcsslotd process (send SIGKILL; it ignores SIGTERM while in use). - Start a new opencryptoki pkcsslotd process. - Attempt to reconnect to the same network. Expected behavior: - wpasupplicant should unload the PKCS#11 openssl engine library and reload it for the reconnection attempt. - The connection should succeed. Observed behavior: - wpasupplicant unloads the PKCS#11 openssl engine library and reloads it for the reconnection attempt. - After wpasupplicant loads the PKCS#11 openssl engine library, it fails to load the private key. The failure to load the private key was debugged back to failure in the opencryptoki TPM library to load the private root key. The private key fails to load because the session object opencryptoki uses to load the key into the TPM is stale, left over from the first session. A patch for this is attached and the patch has been sent upstream. See http://sourceforge.net/tracker/?func=detail&atid=710344&aid=3073688&group_id=128009 and https://bugs.launchpad.net/ubuntu/+source/opencryptoki/+bug/645576.
Author: David Smith <d...@google.com> Description: Reset TPM datastructures on init, not just logout. Index: opencryptoki-2.2.8+dfsg/usr/lib/pkcs11/tpm_stdll/tpm_specific.c =================================================================== --- opencryptoki-2.2.8+dfsg.orig/usr/lib/pkcs11/tpm_stdll/tpm_specific.c 2010-10-28 12:56:36.000000000 -0700 +++ opencryptoki-2.2.8+dfsg/usr/lib/pkcs11/tpm_stdll/tpm_specific.c 2010-10-28 15:19:41.000000000 -0700 @@ -111,6 +111,22 @@ CK_BYTE current_so_pin_sha[SHA1_HASH_SIZE]; +static void +clear_internal_structures() +{ + hSRK = NULL_HKEY; + hPrivateLeafKey = NULL_HKEY; + hPublicLeafKey = NULL_HKEY; + hPrivateRootKey = NULL_HKEY; + hPublicRootKey = NULL_HKEY; + + memset(master_key_private, 0, MK_SIZE); + memset(current_so_pin_sha, 0, SHA1_HASH_SIZE); + memset(current_user_pin_sha, 0, SHA1_HASH_SIZE); + + object_mgr_purge_private_token_objects(); +} + CK_RV token_specific_session(CK_SLOT_ID slotid) { @@ -263,7 +279,7 @@ { TSS_RESULT result; TSS_HPOLICY hPolicy; - static TSS_BOOL get_srk_pub_key = TRUE; + TSS_BOOL get_srk_pub_key = TRUE; UINT32 key_size; key_size = util_get_keysize_flag(size_n * 8); @@ -1669,19 +1685,11 @@ { if (hPrivateLeafKey != NULL_HKEY) { Tspi_Key_UnloadKey(hPrivateLeafKey); - hPrivateLeafKey = NULL_HKEY; } else if (hPublicLeafKey != NULL_HKEY) { Tspi_Key_UnloadKey(hPublicLeafKey); - hPublicLeafKey = NULL_HKEY; } - memset(master_key_private, 0, MK_SIZE); - memset(current_so_pin_sha, 0, SHA1_HASH_SIZE); - memset(current_user_pin_sha, 0, SHA1_HASH_SIZE); - - /* pulled from new_host.c */ - object_mgr_purge_private_token_objects(); - + clear_internal_structures(); return CKR_OK; } @@ -2005,6 +2013,7 @@ return CKR_FUNCTION_FAILED; } + clear_internal_structures(); return CKR_OK; }