Enable system NSS key slot.

This only affects users of domains that the device is registered to for policy.
All other users are unaffected (EnableNSSSystemKeySlotForResourceContext is only called for USER_AFFILIATION_MANAGED)

For the affected users, this enables and uses the slot for
- client authentication for TSL (see ClientCertStoreChromeOS)
- client authentication for 802.1x networks
- listing/removing certificates on the settings page (see CertificateManager)

In a follow up, also the enterprise.platformKeys API will be updated.

Depends on:
https://codereview.chromium.org/426983002/
https://codereview.chromium.org/428933002/

BUG=210525
[email protected], [email protected], [email protected], [email protected]

Review URL: https://codereview.chromium.org/424523002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@287175 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/crypto/nss_util.cc b/crypto/nss_util.cc
index 29a0b66..062bcb5 100644
--- a/crypto/nss_util.cc
+++ b/crypto/nss_util.cc
@@ -394,19 +394,22 @@
     }
     initializing_tpm_token_ = false;
 
-    if (tpm_slot_) {
-      TPMReadyCallbackList callback_list;
-      callback_list.swap(tpm_ready_callback_list_);
-      for (TPMReadyCallbackList::iterator i = callback_list.begin();
-           i != callback_list.end();
-           ++i) {
-        (*i).Run();
-      }
-    }
+    if (tpm_slot_)
+      RunAndClearTPMReadyCallbackList();
 
     callback.Run(!!tpm_slot_);
   }
 
+  void RunAndClearTPMReadyCallbackList() {
+    TPMReadyCallbackList callback_list;
+    callback_list.swap(tpm_ready_callback_list_);
+    for (TPMReadyCallbackList::iterator i = callback_list.begin();
+         i != callback_list.end();
+         ++i) {
+      i->Run();
+    }
+  }
+
   bool IsTPMTokenReady(const base::Closure& callback) {
     if (!callback.is_null()) {
       // Cannot DCHECK in the general case yet, but since the callback is
@@ -579,6 +582,12 @@
     // Unsetting, i.e. setting a NULL, however is allowed.
     DCHECK(!slot || !test_system_slot_);
     test_system_slot_ = slot.Pass();
+    if (test_system_slot_) {
+      tpm_slot_.reset(PK11_ReferenceSlot(test_system_slot_.get()));
+      RunAndClearTPMReadyCallbackList();
+    } else {
+      tpm_slot_.reset();
+    }
   }
 #endif  // defined(OS_CHROMEOS)
 
@@ -1014,7 +1023,7 @@
 }
 
 void SetSystemKeySlotForTesting(ScopedPK11Slot slot) {
-  g_nss_singleton.Get().SetSystemKeySlotForTesting(ScopedPK11Slot());
+  g_nss_singleton.Get().SetSystemKeySlotForTesting(slot.Pass());
 }
 
 void EnableTPMTokenForNSS() {