entd: move opencryptoki initialization out of entd
Look for a file /home/chronos/.cryptohome-init-pkcs11 and expect cryptohome to initialize the PKCS#11 token, disabling that interface in newer extensions.
Change-Id: I363ec0ef093d58d793a3d75e22dee96b58bdacd3
R=rginda@chromium.org
BUG=chromium-os:12304
TEST=
old extension / new entd (w/ and w/o flag)
new extension / old entd:
new extension / new entd (w/ and w/o flag):
When flag is set with new entd, Initialize button disappears and we wait for cryptohomed to signal the TPM token is ready.
Review URL: http://codereview.chromium.org/6821025
diff --git a/base_policy/policy-utils.js b/base_policy/policy-utils.js
index 03d9964..85b5587 100644
--- a/base_policy/policy-utils.js
+++ b/base_policy/policy-utils.js
@@ -1241,7 +1241,7 @@
*/
Policy.Callbacks.prototype['cb:info'] =
function cb_info() {
- return Policy.CallbackSuccess({
+ var callback_data = {
description: this.policy.manifest.description,
version: this.policy.manifest.version,
username: entd.username,
@@ -1253,13 +1253,19 @@
isOwned: (entd.isLibcrosLoaded ? entd.tpm.isOwned : true),
isBeingOwned: (entd.isLibcrosLoaded ? entd.tpm.isBeingOwned : false),
statusString: (entd.isLibcrosLoaded ? entd.tpm.statusString :
- "libcros not loaded"),
+ "libcros not loaded")
},
pkcs11: {
state: this.policy.pkcs11.state,
log: this.policy.getLog(this.policy.pkcs11)
}
- });
+ }
+ if ('isTokenReady' in entd.tpm) {
+ callback_data.pkcs11.isTokenReady =
+ (entd.isLibcrosLoaded ? entd.tpm.isTokenReady : false);
+ }
+
+ return Policy.CallbackSuccess(callback_data);
};
/**
@@ -1281,6 +1287,7 @@
* if the operation completes successfully but the token is not ready due to
* some unexpected condition, it will become 'stop:user-pin'. On error it will
* become 'stop:error'.
+ * TODO(crosbug.com/14277): Remove SetPIN functions.
*/
Policy.Callbacks.prototype['cb:setUserPin'] =
function cb_setUserPin(arg) {
@@ -1413,6 +1420,7 @@
* initialization is in progress the token state will be 'start:init'. If the
* operation completes successfully the token state will become 'stop:init'.
* On error it will become 'stop:error'.
+ * TODO(crosbug.com/14277): Remove initToken function.
*/
Policy.Callbacks.prototype['cb:initToken'] =
function cb_initToken(arg) {
@@ -1668,6 +1676,8 @@
*/
Policy.CallbackError =
function CallbackError(data) {
+ // Log the error to syslogs for further diagnosis.
+ entd.syslog.error(data);
return { status: 'error', data: data };
};
diff --git a/bin/entdwife.sh b/bin/entdwife.sh
index b602e5a..dad3a05 100755
--- a/bin/entdwife.sh
+++ b/bin/entdwife.sh
@@ -292,12 +292,16 @@
local extid="$(basename $(dirname "$extension"))"
+ local cryptohome_flag=""
+ if [ -r "/home/chronos/.cryptohome-init-pkcs11" ]; then
+ cryptohome_flag="--cryptohome-init-pkcs11"
+ fi
# Run entd in the background and wait on it - this allows the
# shell interpreter to catch TERM signal and clean up session_path.
"$FLAGS_entd" --utility="$FLAGS_utility" "$root_ca_option" \
--policy="$extension/policy.js" --manifest="$extension/manifest.json" \
--username="$FLAGS_username" --callback-origin=chrome-extension://"$extid" \
- --session-id="$session_id" &
+ --session-id="$session_id" $cryptohome_flag &
local pid=$!
wait $pid
}
diff --git a/main.cc b/main.cc
index 299ece7..caa1784 100644
--- a/main.cc
+++ b/main.cc
@@ -15,6 +15,7 @@
#include "entd/callback_server.h"
#include "entd/http.h"
#include "entd/pkcs11.h"
+#include "entd/tpm.h"
#include "entd/utils.h"
namespace switches {
@@ -58,6 +59,10 @@
static const char *kSessionId = "session-id";
+// TODO(crosbug.com/14277): Remove option and assume it is true.
+static const char *kCryptohomeInitPkcs11 =
+ "cryptohome-init-pkcs11";
+
} // namespace switches
// Return values:
@@ -139,6 +144,11 @@
LOG(INFO) << "Setting libcros location: " << entd::Entd::libcros_location;
}
+ if (cl->HasSwitch(switches::kCryptohomeInitPkcs11)) {
+ LOG(INFO) << "Expecting cryptohome to initialize the TPM token";
+ entd::Tpm::cryptohome_init_pkcs11 = true;
+ }
+
if (cl->HasSwitch(switches::kAllowFileIO)) {
LOG(INFO) << "Allowing File IO.";
entd::Entd::allow_file_io = true;
diff --git a/reference_extension/client.js b/reference_extension/client.js
index 8bfdd17..80b677c 100644
--- a/reference_extension/client.js
+++ b/reference_extension/client.js
@@ -12,6 +12,8 @@
*/
client.policyCallbackPort = 5199;
+client.cryptohome_init_pkcs11 = false;
+
/**
* Initialize the client.
*/
@@ -172,6 +174,12 @@
text('Ready').
attr('status', 'green');
+ // Use presence of isTokenReady to determine if
+ // cryptohome_init_pkcs11 is true.
+ // TODO(crosbug.com/14277): Remove this conditional and code
+ // to recognize if TPM has been initialized (only check token).
+ client.cryptohome_init_pkcs11 = 'isTokenReady' in pkcs11;
+
if (retval.data.isLibcrosLoaded && !retval.data.tpm.isEnabled) {
if (!tpmError) {
client.showError("Your TPM is not enabled. Please enable " +
@@ -202,6 +210,19 @@
attr('status', 'red');
tpmError = true;
}
+ } else if (retval.data.isLibcrosLoaded &&
+ client.cryptohome_init_pkcs11 &&
+ !pkcs11.isTokenReady) {
+ if (!tpmError) {
+ client.showAlert('Please wait while your TPM Token is being ' +
+ 'created. This dialog should go away on its ' +
+ 'own when the process completes.', 'Alert',
+ options);
+ $('#entd-message').
+ text('Waiting for TPM Token.').
+ attr('status', 'red');
+ tpmError = true;
+ }
} else {
ready = true;
}
@@ -387,6 +408,7 @@
*
* This causes the token initialization progress dialog to be shown, and manages
* the asynchronous initialization of a token.
+ * TODO(crosbug.com/14277): Remove token initialization UI.
*/
client.initToken =
function initToken(token, force) {
@@ -957,8 +979,8 @@
$(li).html(
'<table width="100%">' +
'<tr><td><span class="desc"></span> (<span class="label"></span>)</td>' +
- '<td rowspan="2" width="1%"><button>Initialize</button></td></tr>' +
- '<tr><td class="status"></td></tr></table>');
+ '<td rowspan="2" width="1%"><button class="init-button">Initialize' +
+ '</button></td></tr><tr><td class="status"></td></tr></table>');
$(li).find('button').click(function () {
client.onTokenClick_(client.tokens[token.slotId]);
@@ -1000,7 +1022,13 @@
$('.label', li).text(token.label || 'Unlabeled');
$('.status', li).attr('status', color);
$('.status', li).text(status);
- $('button', li).text(color == 'red' ? 'Initialize' : 'Reinitialize');
+ if (client.cryptohome_init_pkcs11) {
+ // If automatic initialization is enabled, do not give the user
+ // the option to initialize.
+ $('.init-button', li).css('display', 'none');
+ } else {
+ $('button', li).text(color == 'red' ? 'Initialize' : 'Reinitialize');
+ }
}
/**
diff --git a/reference_extension/options.html b/reference_extension/options.html
index f4a6d50..868eb20 100644
--- a/reference_extension/options.html
+++ b/reference_extension/options.html
@@ -210,6 +210,7 @@
</form>
</div>
+ <!-- TODO(crosbug.com/14277): Remove initialization UI. -->
<div class="modal-dialog" id="token-status">
<b>Initializing PKCS#11 Token</b>
<hr>
diff --git a/tpm.cc b/tpm.cc
index 95b7e8a..04d3f5a 100644
--- a/tpm.cc
+++ b/tpm.cc
@@ -9,6 +9,8 @@
namespace entd {
+bool Tpm::cryptohome_init_pkcs11 = false;
+
bool Tpm::Initialize() {
return true;
}
@@ -52,6 +54,14 @@
v8::Handle<v8::Value>(), // Don't need any data.
v8::DEFAULT, // DEFAULT AccessControl
v8::DontDelete);
+ if (cryptohome_init_pkcs11) {
+ instance_t->SetAccessor(v8::String::New("isTokenReady"),
+ Tpm::IsTokenReady,
+ 0, // readonly, so setter is NULL
+ v8::Handle<v8::Value>(), // Don't need any data.
+ v8::DEFAULT, // DEFAULT AccessControl
+ v8::DontDelete);
+ }
return true;
}
@@ -103,4 +113,10 @@
return v8::String::New(status.c_str());
}
+// static
+v8::Handle<v8::Value> Tpm::IsTokenReady(v8::Local<v8::String> property,
+ const v8::AccessorInfo& info) {
+ return v8::Boolean::New(chromeos::CryptohomePkcs11IsTpmTokenReady());
+}
+
} // namespace entd
diff --git a/tpm.h b/tpm.h
index 3c5ef51..31b9eae 100644
--- a/tpm.h
+++ b/tpm.h
@@ -30,6 +30,10 @@
const v8::AccessorInfo& info);
static v8::Handle<v8::Value> GetStatusString(v8::Local<v8::String> property,
const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> IsTokenReady(v8::Local<v8::String> property,
+ const v8::AccessorInfo& info);
+
+ static bool cryptohome_init_pkcs11;
};
} // namespace entd