entd: wait for cryptohomed to initialize opencryptoki tpm token

Also blow away the old pkcs11.cc since it's old enough now and we
don't want to it to initialize early.

BUG=chromium-os:14462 chromium-os:9982
TEST=below: (requires pending 15495 fix)
Do these both with secure_certs on and off
1) blow away user's .tpm directory
2) log in as user
3) verify that eventually enterprise daemon shows an initialized
TPM token (or in non-secure certs, that you can click the initialize
button and initialize the token)
4) install a certificate

Change-Id: If364261e15b312963bcb45da527c6f72f9d0bde7
Reviewed-on: http://gerrit.chromium.org/gerrit/1224
Reviewed-by: Robert Ginda <rginda@chromium.org>
Tested-by: Ken Mixter <kmixter@chromium.org>
diff --git a/SConstruct b/SConstruct
index 2a28328..bb7a904 100644
--- a/SConstruct
+++ b/SConstruct
@@ -45,7 +45,6 @@
         "flimflam.cc",
         "http.cc",
         "main.cc",
-        "pkcs11.cc",
         "crypto_openssl.cc",
         "crypto_pkcs11.cc",
         "syslog.cc",
diff --git a/base_policy/policy-utils.js b/base_policy/policy-utils.js
index 85b5587..11b7415 100644
--- a/base_policy/policy-utils.js
+++ b/base_policy/policy-utils.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -343,14 +343,25 @@
 
   ++this.pkcs11.initCount;
 
-  this.info('Initializing PKCS11 library, attempt: ' +
+  this.info('Initializing PKCS#11 library, attempt: ' +
             this.pkcs11.initCount);
 
+  if ('isTokenReady' in entd.tpm) {
+    if (!entd.tpm.isTokenReady) {
+      // The TPM token is not yet initialized by cryptohomed and we
+      // must not load PKCS11 until it has finished.  Re-check again
+      // in a second.
+      this.info('TPM token not yet initialized, delaying library load.');
+      entd.setTimeout(util.bindp(this, "initPkcs11"), 1000);
+      return false;
+    }
+  }
+
   try {
     this.pkcs11.api = new entd.crypto.Pkcs11();
     this.info('entd.cryto.Pkcs11 initialized.');
   } catch (ex) {
-    this.error('PKCS11 library failed to initialize: ' + ex);
+    this.error('PKCS#11 library failed to initialize: ' + ex);
     this.pkcs11.error = ex;
   }
 
diff --git a/entd.cc b/entd.cc
index d74bd17..6750ffd 100644
--- a/entd.cc
+++ b/entd.cc
@@ -18,7 +18,6 @@
 #include "entd/callback_server.h"
 #include "entd/flimflam.h"
 #include "entd/http.h"
-#include "entd/pkcs11.h"
 #include "entd/crypto_openssl.h"
 #include "entd/crypto_pkcs11.h"
 #include "entd/scriptable.h"
@@ -431,16 +430,6 @@
   crypto_obj->Set(v8::String::NewSymbol("OpenSSL"),
                   crypto::OpenSSL::constructor_template()->GetFunction());
 
-  // Build the (soon-to-be-deprecated) entd.pkcs11 object
-  pkcs11_.reset(new Pkcs11());
-  if (!pkcs11_->Initialize()) {
-    LOG(ERROR) << "Error initializing entd.pkcs11";
-    exit(1);
-  }
-
-  entd->Set(v8::String::New("pkcs11"),
-            pkcs11_->obj(), v8::ReadOnly);
-
   Browser::Reference browser = Browser::New();
   if (!browser->Initialize(this)) {
     LOG(ERROR) << "Error initializing entd.browser";
diff --git a/entd.h b/entd.h
index f98b0b3..1b6ecbb 100644
--- a/entd.h
+++ b/entd.h
@@ -25,7 +25,6 @@
 class NativeTimeout;
 class Syslog;
 class Timeout;
-class Pkcs11;
 
 class Entd : public JSObjectWrapper<Entd> {
  public:
@@ -219,7 +218,6 @@
   scoped_ptr<CallbackServer> callback_server_;
   scoped_ptr<Flimflam> flimflam_;
   scoped_ptr<Syslog> syslog_;
-  scoped_ptr<Pkcs11> pkcs11_;
   v8::Persistent<v8::Context> context_;
 
   DISALLOW_COPY_AND_ASSIGN(Entd);
diff --git a/main.cc b/main.cc
index caa1784..2e73c51 100644
--- a/main.cc
+++ b/main.cc
@@ -14,7 +14,6 @@
 #include "entd/extensions.h"
 #include "entd/callback_server.h"
 #include "entd/http.h"
-#include "entd/pkcs11.h"
 #include "entd/tpm.h"
 #include "entd/utils.h"
 
@@ -30,10 +29,6 @@
 static const char *kPolicy =   "policy";
 static const char *kUtility =  "utility";
 
-// Opencryptoki support is enabled by default.  Turn it off if you want to be
-// able to generate Certificates even if opencryptoki isn't available.
-static const char *kDisableOpencryptoki = "disable-opencryptoki";
-
 // Root CA for HTTPS requests.
 static const char *kRootCAFile = "root-ca-file";
 
@@ -164,11 +159,6 @@
     entd::Entd::allow_dirty_exit = true;
   }
 
-  if (cl->HasSwitch(switches::kDisableOpencryptoki)) {
-    LOG(INFO) << "Disabling opencryptoki.";
-    entd::Pkcs11::enable_opencryptoki = false;
-  }
-
   if (cl->HasSwitch(switches::kCallbackOrigin)) {
     entd::CallbackServer::required_origin = cl->GetSwitchValueASCII(
         switches::kCallbackOrigin);
diff --git a/pkcs11.cc b/pkcs11.cc
deleted file mode 100644
index 6d18b80..0000000
--- a/pkcs11.cc
+++ /dev/null
@@ -1,1866 +0,0 @@
-// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "entd/pkcs11.h"
-
-#include <algorithm>
-#include <iostream>
-#include <map>
-#include <string>
-#include <tr1/memory>
-
-#include <base/basictypes.h>
-#include <base/file_util.h>
-#include <base/logging.h>
-#include <base/memory/scoped_ptr.h>
-#include <chromeos/utility.h>
-#include <curl/curl.h>
-#include <opencryptoki/pkcs11.h>
-#include <openssl/bio.h>
-#include <openssl/bn.h>
-#include <openssl/pem.h>
-#include <openssl/rand.h>
-#include <openssl/rsa.h>
-#include <openssl/x509.h>
-
-#include "entd/utils.h"
-
-namespace entd {
-
-// Class SlotObject declaration (implementation below)
-// SlotObject JavaScript interface wrapper around SlotHandler.
-class SlotObject : public JSObjectWrapper<SlotObject> {
- public:
-  SlotObject() : slot_handler_(NULL) {}
-  SlotObject(const std::string& label, const std::string& key_id)
-      : label_(label), key_identifier_(key_id), slot_handler_(NULL) {}
-  virtual ~SlotObject() {}
-
-  virtual bool Initialize();
-
-  // JSObjectWrapper Interface
-  virtual bool ParseConstructorArgs(
-      v8::Handle<v8::Object> obj, const v8::Arguments& args);
-  static void SetTemplateBindings(
-      v8::Handle<v8::ObjectTemplate> template_object);
-  static const char* GetClassName() { return "SlotObject"; }
-
-  // Accessors
-  const std::string& label() const { return label_; }
-  const std::string& key_identifier() const { return key_identifier_; }
-  const std::string& passphrase() const { return passphrase_; }
-  std::string GetPublicKey() const {
-    return slot_handler()->GetPublicKey(label_);
-  }
-  SlotHandler* slot_handler() const { return slot_handler_; }
-
-  // Setters
-
-  // Stores the key identifier and passes it to the slot handler.
-  bool SetKeyIdentifier(const std::string& id) {
-    key_identifier_ = id;
-    return slot_handler_->SetKeyIdentifier(label_, id);
-  }
-  const void SetPassphrase(const std::string& passphrase) {
-    passphrase_ = passphrase;
-  }
-  void SetSlotHandler(SlotHandler* slot_handler) {
-    slot_handler_ = slot_handler;
-  }
-
- private:
-  std::string label_;
-  std::string key_identifier_;
-  std::string passphrase_;
-  SlotHandler* slot_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(SlotObject);
-};
-
-// Class Certificate declaration (implementation below)
-// Certificate JavaScript interface wrapper around CertificateHandler.
-class Certificate : public JSObjectWrapper<Certificate> {
- public:
-  Certificate() {}
-  virtual ~Certificate() {}
-
-  // JSObjectWrapper Interface
-  virtual bool ParseConstructorArgs(
-      v8::Handle<v8::Object> obj, const v8::Arguments& args);
-  static void SetTemplateBindings(
-      v8::Handle<v8::ObjectTemplate> template_object);
-  static const char* GetClassName() { return "Certificate"; }
-
-  // Accessors
-  const chromeos::Blob& certificate() const { return certificate_; }
-  const std::string& subject() const { return subject_; }
-
-  // Certificate handler management
-  static void InitCertificateHandler(CertificateHandler* handler) {
-    certificate_handler_ = handler;
-  }
-
-  static CertificateHandler* certificate_handler() {
-    return certificate_handler_;
-  }
-
- private:
-  // The certificate may contain binary data, so store it as an array of bytes
-  // instead of a string.
-  chromeos::Blob certificate_;
-  std::string subject_;
-  static CertificateHandler* certificate_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(Certificate);
-};
-
-// Class CertificateHandlerOpenSsl
-// Implements CSR generation using the openssl crypto library
-//
-// TODO(rginda): Refactor most of the implementation of this class out
-// into an openssl_utils module.
-class CertificateHandlerOpenSsl : public CertificateHandler {
- public:
-  CertificateHandlerOpenSsl() {}
-
-  virtual ~CertificateHandlerOpenSsl() {}
-
-  virtual bool Initialize() { return true; }
-
-  virtual bool BuildCSR(const std::string& label,
-                        const std::string& subject,
-                        std::string* csr) {
-    LOG(INFO) << "Generating CSR.";
-
-    // Equivalent to:
-    // openssl req -new -batch -newkey rsa:2048 -subj {subject}
-    // -keyout {private_key} -pubkey -out {csr}
-    // -passout pass:{passphrase}
-
-    // Generate a private key in DER format and pass it to the slot handler
-    EVP_PKEY* pkey = EVP_PKEY_new();
-    RSA* rsa = NULL;  // NOTE: This gets freed with pkey
-    bool res = pkey && GeneratePrivateKey(pkey, &rsa) &&
-        PrivateKeyToDER(rsa, &private_key_der_);
-
-    if (!res) {
-      LOG(ERROR) << "Error generating RSA key.";
-      EVP_PKEY_free(pkey);
-      return false;
-    }
-
-    // Generate a CSR request using the private key
-    X509_REQ* req = X509_REQ_new();
-    res = req && SetX509Req(pkey, subject, req);
-
-    EVP_PKEY_free(pkey);
-
-    if (!res) {
-      LOG(ERROR) << "Error generating X509 Request.";
-      X509_REQ_free(req);
-      return false;
-    }
-
-    // Extract the CSR and Public Key components in PEM format
-    res = X509ReqPublicKeyToPEM(req, &public_key_) &&
-        X509ReqToPEM(req, &csr_);
-
-    X509_REQ_free(req);
-
-    if (!res) {
-      LOG(ERROR) << "Error extracting data from X509 Request.";
-      return false;
-    }
-
-    // Store the private key in the slot handler (e.g. TPM device)
-    if (!slot_handler()->AddPrivateKey(label, subject, private_key_der_))
-      return false;
-
-    *csr = csr_;
-
-    return true;
-  }
-
-  virtual bool BuildCertificate(const std::string& content,
-                                chromeos::Blob* certificate,
-                                std::string* subject) {
-    LOG(INFO) << "Building Certificate.";
-
-    // Equivalent to:
-    // openssl x509 -inform PEM -in content -outform DER -subject subject
-    if (content.empty()) {
-      LOG(ERROR) << "BuildCertificate called with empty content";
-      return false;
-    }
-
-    // Convert 'content' to a DER Blob and extract the subject
-    X509* cert = NULL;
-    bool res = X509CertificateToDER(content, &cert, certificate)
-        && X509CertificateToSubject(cert, subject);
-    X509_free(cert);
-
-    if (!res) {
-      LOG(ERROR) << "Error in X509 Certificate parsing.";
-      return false;
-    }
-
-    return true;
-  }
-
- private:
-  // Utility class and functions for interfacing with the openssl BIO interface
-
-  // BioMem allocates an in-memory BIO instance and frees it on destruction.
-  //
-  // TODO(rginda): Remove static "Create" in favor of a per-instance
-  // "Initialize" returning a boolean, so callers can dump the scoped_pointers
-  // in favor of stack allocated objects.
-  class BioMem {
-   public:
-    static BioMem* Create() {
-      BioMem* biomem = new BioMem();
-      if (!biomem || !biomem->InitBio()) {
-        LOG(ERROR) << "Error initializing BIO";
-        delete biomem;
-        return NULL;
-      }
-      return biomem;
-    }
-    static BioMem* CreateFromString(const std::string& data) {
-      BioMem* biomem = new BioMem();
-      if (!biomem || !biomem->InitBioFromString(data)) {
-        LOG(ERROR) << "Error initializing BIO from string";
-        delete biomem;
-        return NULL;
-      }
-      return biomem;
-    }
-    ~BioMem() {
-      BIO_free(bio_);
-    }
-    // Extract a std::string from the BIO instance
-    bool GetBIOString(std::string* str) {
-      char* mem = 0;
-      long bytes = BIO_get_mem_data(bio(), &mem);
-      if (bytes == 0 || !mem) {
-        return false;
-      }
-      *str = std::string(mem, mem + bytes);
-      return true;
-    }
-
-    // Extract a Blob from the BIO instance
-    bool GetBIOBlob(chromeos::Blob* der) {
-      char* mem = 0;
-      long bytes = BIO_get_mem_data(bio(), &mem);
-      if (bytes == 0 || !mem) {
-        return false;
-      }
-      unsigned char* umem = reinterpret_cast<unsigned char*>(mem);
-      *der = chromeos::Blob(umem, umem + bytes);
-      return true;
-    }
-    BIO* bio() const { return bio_; }
-   private:
-    BioMem() : bio_(NULL) {};
-    // The default init is typically used to receive then extract data
-    bool InitBio() {
-      bio_ = BIO_new(BIO_s_mem());
-      return (bio_ != NULL);
-    }
-    // The string init creates a BIO instance with the string contents
-    // to pass to openssl functions
-    bool InitBioFromString(const std::string& data) {
-      char* bytes = const_cast<char*>(data.c_str());
-      bio_ = BIO_new_mem_buf(bytes, data.size());
-      return (bio_ != NULL);
-    }
-    BIO* bio_;
-  };
-
-  // Private key related functions.
-
-  bool GeneratePrivateKey(EVP_PKEY* pkey, RSA** rsap) {
-    // Get the default RAND file name from the crypto library (~/.rnd)
-    char rand_file_name[kMaxFilePath];
-    if (RAND_file_name(rand_file_name, kMaxFilePath) == NULL)
-      return false;
-    // Expand the filename ($USERNAME -> user)
-    std::string rand_file_name_exp = utils::ExpandFilePath(rand_file_name);
-
-    // Try to load the filename returned.  The RAND file is a nice way
-    // of stirring the RNG, but it's not necessary - OpenSSL knows how
-    // to use /dev/random and has already used it for seeding. If the
-    // RNG truly doesn't have enough entropy, the RSA_generate_key()
-    // call will fail.
-    if (RAND_load_file(rand_file_name_exp.c_str(), -1) == 0)
-      LOG(WARNING) << "Unable to load RAND file: " << rand_file_name_exp;
-
-    // Generate the RSA key and an EVP_PKEY wrapper
-    RSA* rsa = RSA_generate_key(kRsaKeyLength, kRsaKeyExponent, NULL, NULL);
-    if (!rsa)
-      return false;
-    if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
-      RSA_free(rsa);  // rsa won't be freed with pkey if assign failed.
-      return false;
-    }
-
-    // Write to the RAND file
-    if (RAND_write_file(rand_file_name_exp.c_str()) == 0)
-      LOG(WARNING) << "Unable to write to RAND file: " << rand_file_name_exp;
-
-    *rsap = rsa;
-
-    return true;
-  }
-
-  bool PrivateKeyToDER(RSA* rsa, chromeos::Blob* der) {
-    scoped_ptr<BioMem> bio_mem(BioMem::Create());
-    if (!bio_mem.get())
-      return false;
-    bool res = i2d_RSAPrivateKey_bio(bio_mem->bio(), rsa)
-        && bio_mem->GetBIOBlob(der);
-    return res;
-  }
-
-  // X509 Request generation helper functions
-
-  // Find the first instance of 'c' in string 's', skipping over escape
-  // sequences (e.g if c == '/' skip '\/')
-  std::string::size_type FindUnescaped(const std::string& s,
-                                       char c,
-                                       std::string::size_type start) {
-    if (start >= s.length())
-      return std::string::npos;
-    for (std::string::const_iterator iter = s.begin() + start;
-         iter != s.end(); ++iter) {
-      char c1 = *iter;
-      if (c1 == '\\') {
-        ++iter;  // skip the '\', the loop will skip the next char
-        if (iter == s.end())
-          break;
-      } else {
-        if (c1 == c)
-          return iter - s.begin();
-      }
-    }
-    return std::string::npos;
-  }
-
-  // Parse the subject and add the name/type pairs to an X509_NAME.
-  bool ParseSubject(const std::string& subject, X509_NAME* name) {
-    if (subject.empty())
-      return false;
-
-    std::string::size_type start = 0;
-    while (start != std::string::npos) {
-      if (subject[start] != '/') {
-        LOG(ERROR) << "Subject must start with '/'";
-        return false;
-      }
-      ++start;  // skip leading '/'
-
-      // Find the next '/' (or npos to indicate the end of the string)
-      std::string::size_type end = FindUnescaped(subject, '/', start);
-
-      // Build the token amd split it at '=' into type/value
-      std::string token;
-      if (end == std::string::npos)
-        token = subject.substr(start);
-      else
-        token = subject.substr(start, end - start);
-      if (token.empty()) {
-        LOG(ERROR) << "Subject contains an invalid entry at: " << start;
-        return false;
-      }
-      std::string::size_type eq = FindUnescaped(token, '=', 0);
-      if (eq == std::string::npos) {
-        LOG(ERROR) << "Subject entry is missing '=': '" << token << "'";
-        return false;
-      }
-      std::string type = token.substr(0, eq);
-      std::string value = token.substr(eq+1);
-
-      if (type.length() == 0) {
-        LOG(ERROR) << "Subject entry has no type: '" << token << "'";
-        return false;
-      }
-
-      // Add the type/value pair to the X509_NAME
-      const unsigned char* bytes =
-          reinterpret_cast<const unsigned char*>(value.c_str());
-      if (!X509_NAME_add_entry_by_txt(name, type.c_str(), MBSTRING_ASC,
-                                      bytes, value.size(), -1, 0)) {
-        return false;
-      }
-
-      start = end;  // start at next '/' (or npos)
-    }
-
-    return true;
-  }
-
-  // X509 Request functions
-
-  bool SetX509Req(EVP_PKEY* pkey, const std::string& subject,
-                  X509_REQ* req) {
-    if (!X509_REQ_set_version(req, 0L))  // version 1
-      return false;
-    X509_NAME* name = X509_NAME_new();
-    if (!name)
-      return false;
-    bool res = ParseSubject(subject, name)
-        && X509_REQ_set_subject_name(req, name)
-        && X509_REQ_set_pubkey(req, pkey)
-        && X509_REQ_sign(req, pkey, EVP_sha1());
-    X509_NAME_free(name);
-    return res;
-  }
-
-  bool X509ReqPublicKeyToPEM(X509_REQ* req, std::string* pub_key_str) {
-    scoped_ptr<BioMem> bio_mem(BioMem::Create());
-    if (!bio_mem.get())
-      return false;
-    EVP_PKEY* pub_key = X509_REQ_get_pubkey(req);
-    if (!pub_key)
-      return false;
-    bool res = PEM_write_bio_PUBKEY(bio_mem->bio(), pub_key)
-        &&  bio_mem->GetBIOString(pub_key_str);
-    EVP_PKEY_free(pub_key);
-    return res;
-  }
-
-  bool X509ReqToPEM(X509_REQ* req, std::string* req_str) {
-    scoped_ptr<BioMem> bio_mem (BioMem::Create());
-    if (!bio_mem.get())
-      return false;
-    bool res = PEM_write_bio_X509_REQ(bio_mem->bio(), req)
-        && bio_mem->GetBIOString(req_str);
-    return res;
-  }
-
-  // X509 Certificte functions
-
-  bool X509CertificateToDER(const std::string& content,
-                            X509** cert, chromeos::Blob* der) {
-    scoped_ptr<BioMem> bio_content(BioMem::CreateFromString(content));
-    if (!bio_content.get())
-      return false;
-    bool res = PEM_read_bio_X509(bio_content->bio(), cert, NULL, NULL);
-    if (!res)
-      return false;
-    scoped_ptr<BioMem> bio_cert(BioMem::Create());
-    if (!bio_cert.get())
-      return false;
-    res = i2d_X509_bio(bio_cert->bio(), *cert)
-        && bio_cert->GetBIOBlob(der);
-    return res;
-  }
-
-  bool X509CertificateToSubject(X509* cert, std::string* subject) {
-    X509_NAME* name = X509_get_subject_name(cert);
-    const int NAME_BUF_LEN = 1024;
-    char name_buf[NAME_BUF_LEN];
-    if (!X509_NAME_oneline(name, name_buf, NAME_BUF_LEN))
-      return false;
-    subject->assign(name_buf);
-    return true;
-  }
-
-  static const long kRsaKeyLength;
-  static const long kRsaKeyExponent;
-  static const long kMaxFilePath;
-
-  std::string csr_;
-  std::string certificate_;
-  std::string public_key_;
-  chromeos::Blob private_key_der_;
-
-  DISALLOW_COPY_AND_ASSIGN(CertificateHandlerOpenSsl);
-};
-
-// Use 2048 bits for the key length, and an exponent of 0x10001.
-const long CertificateHandlerOpenSsl::kRsaKeyLength = 2048;
-const long CertificateHandlerOpenSsl::kRsaKeyExponent = 0x10001;
-// Max number of chars for local array allocation for file paths.
-const long CertificateHandlerOpenSsl::kMaxFilePath = 1024;
-
-// Class SlotHandlerInMemory
-// Stores the contents of slots in memory, used for testing the interface.
-class SlotHandlerInMemory : public SlotHandler {
- protected:
-  // Forward declarations and typedefs.
-  struct Object;
-  typedef std::map<std::string, std::tr1::shared_ptr<Object> > ObjectMap;
-
- public:
-  SlotHandlerInMemory() { }
-  virtual bool Initialize() { return true; }
-
-  virtual bool SetUserPin(const std::string& pin) { return true; }
-
-  virtual bool SetKeyIdentifier(const std::string& label,
-                                const std::string& keyid) {
-    Object* obj = GetObject(label);
-    if (!obj) {
-      LOG(WARNING) << "BuildSlotObject must be called before SetKeyIdentifier";
-      return false;
-    }
-    obj->key_identifier_ = keyid;
-    return true;
-  }
-
-  virtual bool BuildSlotObject(const std::string& label) {
-    if (label.empty()) {
-      LOG(ERROR) << "BuildSlotObject called with empty label.";
-      return false;
-    }
-    if (GetObject(label) != NULL) {
-      LOG(ERROR) << "BuildSlotObject called on existing object: " << label;
-      return false;
-    } else {
-      AddObject(label);
-      return true;
-    }
-  }
-
-  // No-op (just save the key identifier and passphrase.)
-  virtual bool GenerateKeyPair(const std::string& label,
-                               const std::string& passphrase) {
-    Object* obj = GetObject(label);
-    if (!obj) {
-      LOG(WARNING) << "BuildSlotObject must be called before GenerateKeyPair";
-      return false;
-    }
-    obj->passphrase_ = passphrase;
-    obj->public_key_ = "<This is a public key>";
-    return true;
-  }
-
-  virtual bool AddCertificate(const std::string& label,
-                              const chromeos::Blob& cert,
-                              const std::string& subject) {
-    Object* obj = GetObject(label);
-    if (!obj) {
-      LOG(WARNING) << "BuildSlotObject must be called before AddCertificate";
-      return false;
-    }
-    obj->subject_ = subject;
-    obj->cert_ = cert;
-    return true;
-  }
-
-  virtual bool AddPrivateKey(const std::string& label,
-                             const std::string& subject,
-                             const chromeos::Blob& key) {
-    // Don't store the private key in memory.
-    return true;
-  }
-
-  virtual bool ReadObjectsFromSlot(Pkcs11* pkcs11) {
-    // In memory slot handler does not persist data anywhere, so there is
-    // no data to read.
-    return true;
-  }
-
-  virtual bool RemoveObjects(const std::string& label) {
-    DeleteObject(label);
-    return true;
-  }
-
-  virtual std::string GetKeyIdentifier(const std::string& label) const {
-    const Object* obj = GetObject(label);
-    if (!obj) {
-      LOG(WARNING) << "GetKeyIdentifier called on nonexistant object";
-      return NULL;
-    }
-    return obj->key_identifier_;
-  }
-
-  virtual std::string GetPassphrase(const std::string& label) const {
-    const Object* obj = GetObject(label);
-    if (!obj) {
-      LOG(WARNING) << "GetPassphrase called on nonexistant object";
-      return NULL;
-    }
-    return obj->passphrase_;
-  }
-
-  virtual std::string GetPublicKey(const std::string& label) const {
-    const Object* obj = GetObject(label);
-    if (!obj) {
-      LOG(WARNING) << "GetPublicKey called on nonexistant object";
-      return NULL;
-    }
-    return obj->public_key_;
-  }
-
-  virtual std::vector<std::string> GetObjectNames() const {
-    std::vector<std::string> objnames;
-    for (ObjectMap::const_iterator iter = objects_.begin();
-         iter != objects_.end(); ++iter) {
-      objnames.push_back(iter->first);
-    }
-    return objnames;
-  }
-
- protected:
-  struct Object {
-    Object(const std::string& label) : label_(label) {}
-    std::string label_;
-    std::string key_identifier_;
-    std::string passphrase_;
-    std::string subject_;
-    std::string public_key_;
-    chromeos::Blob cert_;
-  };
-
-  const Object* GetObject(const std::string& label) const {
-    ObjectMap::const_iterator iter = objects_.find(label);
-    if (iter == objects_.end())
-      return NULL;
-    else
-      return iter->second.get();
-  }
-
-  Object* GetObject(const std::string& label) {
-    ObjectMap::iterator iter = objects_.find(label);
-    if (iter == objects_.end())
-      return NULL;
-    else
-      return iter->second.get();
-  }
-
-  Object* AddObject(const std::string& label) {
-    ObjectMap::iterator iter = objects_.find(label);
-    if (iter != objects_.end()) {
-      return iter->second.get();
-    } else {
-      Object* obj = new Object(label);
-      objects_.insert(std::make_pair(label, obj));
-      return obj;
-    }
-  }
-
-  bool DeleteObject(const std::string& label) {
-    ObjectMap::iterator iter = objects_.find(label);
-    if (iter == objects_.end()) {
-      return false;
-    } else {
-      objects_.erase(iter);  // Will delete Object
-      return true;
-    }
-  }
-
-  ObjectMap objects_;
-
-  DISALLOW_COPY_AND_ASSIGN(SlotHandlerInMemory);
-};
-
-// Class SlotHandlerOpenCryptoki
-// Inherits from SlotHandlerInMemory to share memory mapping of objects
-class SlotHandlerOpenCryptoki : public SlotHandlerInMemory {
- public:
-  SlotHandlerOpenCryptoki()
-      : user_pin_(""), slot_index_(0), slot_id_(0) { }
-
-  ~SlotHandlerOpenCryptoki() {
-    C_Finalize(NULL);
-  }
-
-  virtual bool Initialize() {
-    CK_RV rv;
-
-    // Initialize opencryptoki
-    rv = C_Initialize(NULL);
-    if (rv != CKR_OK) {
-      // Note: This will happen if opencryptoki isn't properly set up.
-      LOG(ERROR) << "C_Initialize failed: " << rv;
-      return false;
-    }
-
-    CK_ULONG num_slots = 0;
-    CK_SLOT_ID_PTR slot_list = NULL;
-
-    // Get the list of slots
-    // The first call to C_GetSlotList fills in the number of slots.
-    rv = C_GetSlotList(0, NULL, &num_slots);
-    if (rv != CKR_OK) {
-      LOG(ERROR) << "C_GetSlotList(&num_slots) failed: " << rv;
-      return false;
-    }
-
-    if (num_slots == 0) {
-      LOG(ERROR) << "C_GetSlotList: 0 slots.";
-      return false;
-    }
-
-    slot_list = static_cast<CK_SLOT_ID_PTR>(
-        malloc(num_slots * sizeof (CK_SLOT_ID)));
-    if (slot_list == NULL) {
-      LOG(ERROR) << "Unable to allocate slots: " << num_slots;
-      return false;
-    }
-
-    // The second call to C_GetSlotList fills in the actual slot info.
-    rv = C_GetSlotList(0, slot_list, &num_slots);
-    if (rv != CKR_OK) {
-      LOG(ERROR) << "C_GetSlotList(&slot_list) failed. rv=" << rv
-                 << " num_slots=" << num_slots;
-      free(slot_list);
-      return false;
-    }
-
-    // Find a valid slot
-    slot_index_ = num_slots;
-    CK_MECHANISM_TYPE x509_mech_type = CKM_RSA_X_509;
-    CK_MECHANISM_INFO mech_info;
-    for (CK_ULONG i = 0; i < num_slots; ++i) {
-      CK_SLOT_ID slot_id = slot_list[i];
-      CK_TOKEN_INFO info;
-
-      rv = C_GetTokenInfo(i, &info);
-      if (rv != CKR_OK) {
-        LOG(INFO) << "Slot " << i << ": C_GetTokenInfo failed: " << rv;
-        continue;
-      }
-      // Skip any slots that can't handle RSA X.509 certificates.
-      if (C_GetMechanismInfo(slot_id, x509_mech_type, &mech_info) != CKR_OK) {
-        LOG(INFO) << "Slot " << i << ": C_GetMechanismInfo failed: " << rv;
-        continue;
-      }
-      // TODO(stevenjb):
-      // Here is where we would check any criteria other than support for x509.
-      // if ((mech_info.flags & CKF_HW) == 0) {
-      //   LOG(INFO) << "Slot " << i << ": is not a hardware device, skipping.";
-      //   continue;
-      // }
-
-      std::string label = std::string(reinterpret_cast<char*>(info.label));
-      std::string::size_type labeln = label.find_last_not_of(' ');
-      if (labeln != std::string::npos) ++labeln;
-      label = label.substr(0, labeln);
-      if (slot_index_ == num_slots) {
-        slot_index_ = i;
-        slot_id_ = slot_id;
-        LOG(INFO) << "*Slot " << i << ": '" << label << "'";
-      } else {
-        break;  // Use the first valid slot we find
-      }
-    }
-
-    bool res;
-    if (slot_index_ == num_slots) {
-      LOG(ERROR) << "SlotHandlerOpenCryptoki Faied to find a valid slot.";
-      res = false;
-    } else {
-      LOG(INFO) << "SlotHandlerOpenCryptoki Initialized. Using slot: "
-                << slot_index_;
-      res = true;
-    }
-
-    free(slot_list);
-    if (res) {
-      res = SlotHandlerInMemory::Initialize();
-    }
-
-    return res;
-  }
-
-  bool ReadObjectsFromSlot(Pkcs11* pkcs11) {
-    CK_SESSION_HANDLE session_handle = NULL;
-    CK_RV rv = C_OpenSession(slot_id_,
-                             CKF_SERIAL_SESSION|CKF_RW_SESSION, NULL, NULL,
-                             &session_handle);
-    if (rv != CKR_OK) {
-      LOG(ERROR) << "C_OpenSession failed, error: " << rv
-                 << ", slot: " << slot_index_;
-      return false;
-    }
-
-    // Gather a list of objects in the slot
-    int num_objects = 0;
-
-    rv = C_FindObjectsInit(session_handle, NULL, 0);
-    if (rv != CKR_OK) {
-      LOG(ERROR) << "C_FindObjectsInit failed: " << rv;
-      C_CloseSession(session_handle);
-      return false;
-    }
-
-    while (1) {
-      CK_ULONG count;
-      CK_OBJECT_HANDLE object;
-      rv = C_FindObjects(session_handle, &object, 1, &count);
-      if (rv != CKR_OK) {
-        LOG(ERROR) << "C_FindObjects failed: " << rv;
-        C_CloseSession(session_handle);
-        return false;
-      }
-      if (count == 0) {
-        // No more objects to read, exit loop.
-        break;
-      }
-      ++num_objects;
-
-      const size_t LABEL_MAX_LENGTH = 256;
-      const size_t IDSTR_MAX_LENGTH = 8;
-      const size_t SUBJECT_MAX_LENGTH = 1024;
-
-      // Define a template with the values we are interested in
-      CK_OBJECT_CLASS obj_class;
-      char obj_label[LABEL_MAX_LENGTH];
-      CK_BYTE idstr[IDSTR_MAX_LENGTH];
-      CK_BYTE subject[SUBJECT_MAX_LENGTH];
-
-      CK_ATTRIBUTE obj_template[] = {
-        { CKA_CLASS, &obj_class, sizeof(obj_class) },
-        { CKA_LABEL, obj_label, LABEL_MAX_LENGTH },
-        { CKA_ID, idstr, IDSTR_MAX_LENGTH },
-        { CKA_SUBJECT, subject, SUBJECT_MAX_LENGTH },
-      };
-      int n_attr = sizeof(obj_template) / sizeof(CK_ATTRIBUTE);
-
-      // Read values into obj_template
-      rv = C_GetAttributeValue(session_handle, object, obj_template, n_attr);
-      if (rv != CKR_OK) {
-        LOG(ERROR) << "C_GetAttributeValue failed: " << rv
-                   << " obj: " << num_objects;
-      }
-      obj_class = *(static_cast<CK_OBJECT_CLASS*>(obj_template[0].pValue));
-      if (obj_class == CKO_CERTIFICATE ||
-          obj_class == CKO_PUBLIC_KEY ||
-          obj_class == CKO_PRIVATE_KEY) {
-        if (obj_template[1].ulValueLen > 0) {
-          // Only parse certificate and key objects with a valid label
-          std::string label = TemplateToString(obj_template[1]);
-          std::string idstr = GetKeyFromId(
-              static_cast<CK_BYTE*>(obj_template[2].pValue),
-              obj_template[2].ulValueLen);
-          std::string subject = TemplateToString(obj_template[3]);
-          Object* obj = AddObject(label);
-          if (!obj->key_identifier_.empty() && obj->key_identifier_ != idstr) {
-            LOG(WARNING) << "Object '" << label << "' "
-                         << "with mismatched key identifers: "
-                         << "'" << obj->key_identifier_ << "'"
-                         << " != '" << idstr << "'";
-          } else {
-            obj->key_identifier_ = idstr;
-            obj->subject_ = subject;
-          }
-        }
-      }
-    }
-
-    C_FindObjectsFinal(session_handle);
-
-    LOG(INFO) << "Found " << num_objects << " distinct objects in slot.";
-
-    // Iterate through the list of objects and generate
-    // SlotObject objects and insert them into pkcs11.slots.
-    for (ObjectMap::iterator iter = objects_.begin();
-         iter != objects_.end(); ++iter) {
-      Object* object = iter->second.get();
-
-      // Build a slot object
-      SlotObject* slot_object = new SlotObject(object->label_,
-                                               object->key_identifier_);
-      slot_object->Initialize();
-      slot_object->SetSlotHandler(pkcs11->slot_handler());
-      slot_object->obj()->Set(v8::String::NewSymbol("label"),
-                              v8::String::New(object->label_.c_str()),
-                              v8::ReadOnly);
-      slot_object->obj()->Set(v8::String::NewSymbol("keyIdentifier"),
-                              v8::String::New(object->key_identifier_.c_str()));
-
-      // Build a certificate
-      Certificate* certificate = new Certificate();
-      certificate->Initialize();
-      certificate->obj()->Set(v8::String::NewSymbol("subject"),
-                              v8::String::New(object->subject_.c_str()));
-
-      // Add the certificate to the slot object
-      slot_object->obj()->Set(v8::String::NewSymbol("certificate"),
-                              certificate->obj());
-
-      // Add the object to pkcs11.slots ("slots[label] = obj")
-      pkcs11->AddJSSlotObject(slot_object);
-    }
-    C_CloseSession(session_handle);
-    return true;
-  }
-
-  // Returns false if the key is longer than a reasonable maximum length.
-  virtual bool SetKeyIdentifier(const std::string& label,
-                                const std::string& keyid) {
-    const std::size_t MAX_KEY_LENGTH = 16;
-    if (keyid.length() > MAX_KEY_LENGTH)
-        return false;
-    return SlotHandlerInMemory::SetKeyIdentifier(label, keyid);
-  }
-
-  virtual bool SetUserPin(const std::string& pin) {
-    user_pin_ = pin;
-    return true;
-  }
-
-  virtual bool BuildSlotObject(const std::string& label) {
-    if (label.empty()) {
-      LOG(ERROR) << "BuildSlotObject called with empty label.";
-      return false;
-    }
-    if (GetObject(label) != NULL) {
-      LOG(INFO) << "Using existing SlotObject label: " << label;
-      return true;
-    } else {
-      AddObject(label);
-      LOG(INFO) << "New SlotObject label: " << label;
-      return true;
-    }
-  }
-
-  virtual bool AddCertificate(const std::string& label,
-                              const chromeos::Blob& cert,
-                              const std::string& subject) {
-    LOG(INFO) << "Adding Certificate.";
-
-    Object* object = GetObject(label);
-    if (!object) {
-      LOG(ERROR) << "BuildSlotObject must be called before AddCertificate.";
-      return false;
-    }
-    SessionHandle session(OpenSession(label));
-    if (!session.handle())
-      return false;
-
-    object->cert_ = cert;
-    object->subject_ = subject;
-
-    const size_t IDSTR_MAX_LENGTH = 8;
-    CK_BYTE idstr[IDSTR_MAX_LENGTH];
-    CK_ULONG idstrlen;
-    if (!GetKeyIdStr(object->key_identifier_,
-                     &idstr[0], &idstrlen, IDSTR_MAX_LENGTH)) {
-      return false;
-    }
-
-    // Add the certifiacte object
-    CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
-    CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
-    CK_BBOOL is_token = TRUE;
-
-    CK_ATTRIBUTE cert_template[16];
-    int n_attr = 0;
-    FillAttr(&cert_template[n_attr++], CKA_CLASS,
-             &cert_class, sizeof(cert_class));
-    FillAttr(&cert_template[n_attr++], CKA_CERTIFICATE_TYPE,
-             &cert_type, sizeof(cert_type));
-    FillAttr(&cert_template[n_attr++], CKA_TOKEN,
-             &is_token, sizeof(is_token));
-    FillStringAttr(&cert_template[n_attr++], CKA_LABEL, label);
-    FillStringAttr(&cert_template[n_attr++], CKA_SUBJECT, subject);
-    FillAttr(&cert_template[n_attr++], CKA_ID,
-             idstr, idstrlen);
-    FillAttr(&cert_template[n_attr++], CKA_VALUE,
-             (CK_VOID_PTR)(&(cert.front())), cert.size());
-
-    CK_OBJECT_HANDLE cert_obj;
-    CK_RV rv = C_CreateObject(session.handle(),
-                              cert_template, n_attr, &cert_obj);
-    if (rv != CKR_OK) {
-      LOG(ERROR) << "C_CreateObject error: " << rv;
-      return false;
-    }
-
-    return true;
-  }
-
-  virtual bool AddPrivateKey(const std::string& label,
-                             const std::string& subject,
-                             const chromeos::Blob& key) {
-    LOG(INFO) << "Adding Private Key.";
-
-    Object* object = GetObject(label);
-    if (!object){
-      LOG(ERROR) << "BuildSlotObject must be called before AddPrivateKey.";
-      return false;
-    }
-
-    SessionHandle session(OpenSession(label));
-    if (!session.handle())
-      return false;
-
-    const size_t IDSTR_MAX_LENGTH = 8;
-    CK_BYTE idstr[IDSTR_MAX_LENGTH];
-    CK_ULONG idstrlen;
-    if (!GetKeyIdStr(object->key_identifier_,
-                     &idstr[0], &idstrlen, IDSTR_MAX_LENGTH)) {
-      return false;
-    }
-
-    // Add the private key object
-    CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
-    CK_CERTIFICATE_TYPE key_type = CKK_RSA;
-    CK_BBOOL is_token = TRUE;
-    CK_BBOOL is_private = TRUE;
-    CK_BBOOL is_sensitive = TRUE;
-
-    RsaKeyInfo rsa;
-    if (!ParseRSAPrivateKey(key, &rsa)) {
-      return false;
-    }
-
-    CK_ATTRIBUTE key_template[32];
-    int n_attr = 0;
-    FillAttr(&key_template[n_attr++], CKA_CLASS,
-             &key_class, sizeof(key_class));
-    FillAttr(&key_template[n_attr++], CKA_KEY_TYPE,
-             &key_type, sizeof(key_type));
-    FillAttr(&key_template[n_attr++], CKA_TOKEN,
-             &is_token, sizeof(is_token));
-    FillAttr(&key_template[n_attr++], CKA_PRIVATE,
-             &is_token, sizeof(is_private));
-    FillAttr(&key_template[n_attr++], CKA_SENSITIVE,
-             &is_token, sizeof(is_sensitive));
-    FillStringAttr(&key_template[n_attr++], CKA_LABEL, label);
-    FillAttr(&key_template[n_attr++], CKA_ID,
-             idstr, idstrlen);
-    FillStringAttr(&key_template[n_attr++], CKA_SUBJECT, subject);
-    FillAttr(&key_template[n_attr++], CKA_MODULUS,
-             rsa.modulus, rsa.modulus_len);
-    FillAttr(&key_template[n_attr++], CKA_PUBLIC_EXPONENT,
-             rsa.public_exp, rsa.public_exp_len);
-    FillAttr(&key_template[n_attr++], CKA_PRIVATE_EXPONENT,
-             rsa.private_exp, rsa.private_exp_len);
-    FillAttr(&key_template[n_attr++], CKA_PRIME_1,
-             rsa.prime_1, rsa.prime_1_len);
-    FillAttr(&key_template[n_attr++], CKA_PRIME_2,
-             rsa.prime_2, rsa.prime_2_len);
-    FillAttr(&key_template[n_attr++], CKA_EXPONENT_1,
-             rsa.exp_1, rsa.exp_1_len);
-    FillAttr(&key_template[n_attr++], CKA_EXPONENT_2,
-             rsa.exp_2, rsa.exp_2_len);
-    FillAttr(&key_template[n_attr++], CKA_COEFFICIENT,
-             rsa.coefficient, rsa.coefficient_len);
-
-    CK_OBJECT_HANDLE key_obj;
-    CK_RV rv = C_CreateObject(session.handle(),
-                              key_template, n_attr, &key_obj);
-    if (rv != CKR_OK) {
-      LOG(ERROR) << "C_CreateObject error: " << rv;
-      return false;
-    }
-
-    return true;
-  }
-
-  // TODO(rginda): Refactor so that the SSL based keypair generation actually
-  // happens here, rather than in the certificate object.
-  //
-  // See the NOTE at the bottom of this file for a
-  // close-but-still-broken implementation pkcs11-only keypair generation.
-  virtual bool GenerateKeyPair(const std::string& label,
-                               const std::string& passphrase) {
-    Object* obj = GetObject(label);
-    if (!obj) {
-      LOG(WARNING) << "BuildSlotObject must be called before GenerateKeyPair";
-      return false;
-    }
-    obj->passphrase_ = passphrase;
-    return true;
-  }
-
-  // Removes all objects in the slot matching 'label'
-  // Note: may be called before BuildSlotObject(), but we still need to
-  // be logged in so that we can remove matching private keys.
-  virtual bool RemoveObjects(const std::string& label) {
-    LOG(INFO) << "Removing Objects matching: " << label;
-
-    SessionHandle session(OpenSession(label));
-    if (!session.handle())
-      return false;
-
-    CK_ATTRIBUTE object_template[4];
-    int n_attr = 0;
-    FillStringAttr(&object_template[n_attr++], CKA_LABEL, label);
-    CK_RV rv = C_FindObjectsInit(session.handle(), object_template, n_attr);
-    if (rv != CKR_OK) {
-      LOG(ERROR) << "C_FindObjectsInit failed: " << rv;
-      return false;
-    }
-
-    bool res = true;
-    int num_objects = 0;
-    while (1) {
-      CK_ULONG count;
-      CK_OBJECT_HANDLE object;
-      rv = C_FindObjects(session.handle(), &object, 1, &count);
-      if (rv != CKR_OK) {
-        LOG(ERROR) << "C_FindObjects failed: " << rv;
-        res = false;
-        break;
-      }
-      if (count == 0) {
-        break;
-      }
-      ++num_objects;
-      rv = C_DestroyObject(session.handle(), object);
-      if (rv != CKR_OK) {
-        LOG(ERROR) << "C_DestroyObject failed: " << rv
-                   << " obj: " << num_objects;
-        res = false;
-        break;
-      }
-    }
-    LOG(INFO) << " Removed " << num_objects << " objects.";
-
-    C_FindObjectsFinal(session.handle());
-
-    return res;
-  }
-
- private:
-  // Class to close sessions we have opened on destruction
-  class SessionHandle {
-   public:
-    SessionHandle(CK_SESSION_HANDLE handle) : handle_(handle) {}
-    ~SessionHandle() {
-      if (handle_)
-        C_CloseSession(handle_);
-    }
-    CK_SESSION_HANDLE handle() { return handle_; }
-   private:
-    CK_SESSION_HANDLE handle_;
-  };
-
-  CK_SESSION_HANDLE OpenSession(const std::string& label) {
-    CK_SESSION_HANDLE handle = NULL;
-    CK_RV rv = C_OpenSession(slot_id_,
-                             CKF_SERIAL_SESSION|CKF_RW_SESSION, NULL, NULL,
-                             &handle);
-    if (rv != CKR_OK) {
-      LOG(ERROR) << "C_OpenSession failed, error: " << rv
-                 << " label: " << label << " slot: " << slot_index_;
-      return NULL;
-    }
-    CK_UTF8CHAR* pin_ptr =
-        reinterpret_cast<unsigned char*>(const_cast<char*>(user_pin_.c_str()));
-    rv = C_Login(handle, CKU_USER,
-                 pin_ptr, user_pin_.length());
-    if (rv != CKR_OK) {
-      LOG(ERROR) << "C_Login failed, error: " << rv
-                 << " label: " << label << " pin: " << user_pin_;
-      return NULL;
-    }
-
-    return handle;
-  }
-
-  std::string TemplateToString(const CK_ATTRIBUTE& attr) {
-    const char* value = static_cast<const char*>(attr.pValue);
-    return std::string(value, attr.ulValueLen);
-  }
-
-  // openssl crypto library interface
-
-  struct RsaKeyInfo {
-    unsigned char *modulus;
-    int modulus_len;
-    unsigned char *public_exp;
-    int public_exp_len;
-    unsigned char *private_exp;
-    int private_exp_len;
-    unsigned char *prime_1;
-    int prime_1_len;
-    unsigned char *prime_2;
-    int prime_2_len;
-    unsigned char *exp_1;
-    int exp_1_len;
-    unsigned char *exp_2;
-    int exp_2_len;
-    unsigned char *coefficient;
-    int coefficient_len;
-  };
-
-  bool RSAGetBN(const BIGNUM* component , unsigned char** dest, int* len) {
-    unsigned char* vec = NULL;
-    int bytes = BN_num_bytes(component);
-    if (bytes) {
-      vec = static_cast<unsigned char*>(malloc(bytes));
-    }
-    if (!vec) {
-      LOG(ERROR) << "Error allocating memory while parsing RSA key.";
-      return false;
-    }
-    int length = BN_bn2bin(component, vec);
-    if (!length) {
-      LOG(ERROR) << "Error parsing component in RSA key.";
-      return false;
-    }
-    *len = length;
-    *dest = vec;
-    return true;
-  }
-
-  bool ParseRSAPrivateKey(const chromeos::Blob& data, RsaKeyInfo* info) {
-    const unsigned char *p = &(data.front());
-    RSA* key = d2i_RSAPrivateKey(NULL, &p, data.size());
-    if (!key) {
-      LOG(ERROR) << "OpenSSL error during RSA private key parsing.";
-      return false;
-    }
-    bool res =
-        RSAGetBN(key->n, &info->modulus, &info->modulus_len) &&
-        RSAGetBN(key->e, &info->public_exp, &info->public_exp_len) &&
-        RSAGetBN(key->d, &info->private_exp, &info->private_exp_len) &&
-        RSAGetBN(key->p, &info->prime_1, &info->prime_1_len) &&
-        RSAGetBN(key->q, &info->prime_2, &info->prime_2_len) &&
-        RSAGetBN(key->dmp1, &info->exp_1, &info->exp_1_len) &&
-        RSAGetBN(key->dmq1, &info->exp_2, &info->exp_2_len) &&
-        RSAGetBN(key->iqmp, &info->coefficient, &info->coefficient_len);
-    return res;
-  }
-
-  // Note: use casting to store const values as non const.
-  // This avoids using lots of casts or needlessly copying the contents
-  // of strings, but be careful not to use this to receive data
-  // into a string or other const array.
-  void FillStringAttr(CK_ATTRIBUTE* attr, CK_ATTRIBUTE_TYPE type,
-                      const std::string& str) {
-    attr->type = type;
-    attr->pValue = const_cast<char*>(str.c_str());
-    attr->ulValueLen = str.length();
-  }
-
-  void FillAttr(CK_ATTRIBUTE* attr, CK_ATTRIBUTE_TYPE type,
-                void* value, CK_ULONG length) {
-    attr->type = type;
-    attr->pValue = value;
-    attr->ulValueLen = length;
-  }
-
-  // Converts the string "0123abcd" to CK_BYTE[] { 01,23,ab,cd }
-  // If the string is too long, *idstrlenp is set to 0 and false is returned.
-  // Invalid characters are clamped to [a,f]. "123abz@" -> { 01,23,ab,ff }
-  bool GetKeyIdStr(const std::string& keyid_in,
-                   CK_BYTE* idstrp, CK_ULONG *idstrlenp, size_t max_length) {
-    std::string keyid;
-    if (keyid_in.size() & 1) {
-      keyid.push_back('0');
-      keyid.append(keyid_in);
-    } else {
-      keyid = keyid_in;
-    }
-    chromeos::Blob bytes = chromeos::AsciiDecode(keyid);
-    if (bytes.size() > max_length) {
-      LOG(ERROR) << "Too many characters in key: " << keyid;
-      *idstrlenp = 0;
-      return false;
-    }
-    memcpy(idstrp, &bytes.front(), bytes.size());
-    *idstrlenp = bytes.size();
-    return true;
-  }
-
-  // Inverse of GetKeyIdStr
-  std::string GetKeyFromId(CK_BYTE* idstrp, CK_ULONG idstrlen) {
-    chromeos::Blob bytes = chromeos::Blob(idstrp, idstrp+idstrlen);
-    return chromeos::AsciiEncode(bytes);
-  }
-
-  std::string user_pin_;
-  CK_ULONG slot_index_;
-  CK_SLOT_ID slot_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(SlotHandlerOpenCryptoki);
-};
-
-// Class CSR
-// CSR JavaScript interface wrapper around CertificateHandler.
-class CSR : public JSObjectWrapper<CSR> {
- public:
-  CSR() { }
-  virtual ~CSR() {}
-
-  // JSObjectWrapper Interface
-  virtual bool ParseConstructorArgs(
-      v8::Handle<v8::Object> obj, const v8::Arguments& args);
-  static void SetTemplateBindings(
-      v8::Handle<v8::ObjectTemplate> template_object);
-  static const char* GetClassName() { return "CSR"; }
-
-  // Accessor
-  const std::string& request() const { return request_; }
-
-  // Certificate handler management
-  static void InitCertificateHandler(CertificateHandler* cert_handler) {
-    certificate_handler_ = cert_handler;
-  }
-  static CertificateHandler* certificate_handler() {
-    return certificate_handler_;
-  }
-
- private:
-  std::string request_;
-
-  static CertificateHandler* certificate_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(CSR);
-};
-
-// static
-CertificateHandler* CSR::certificate_handler_ = NULL;
-
-// Base64 encoded version of the CSR
-static v8::Handle<v8::Value> dispatch_CSRToString(const v8::Arguments& args) {
-  CSR* csr = CSR::Unwrap(args.This());
-  if (csr == NULL)
-    return utils::ThrowV8Exception("Method called on incorrect object type.");
-
-  v8::Local<v8::String> res = v8::String::New(csr->request().c_str());
-  return res;
-}
-
-// static
-void CSR::SetTemplateBindings(
-    v8::Handle<v8::ObjectTemplate> template_object) {
-  template_object->Set(v8::String::NewSymbol("toString"),
-                       v8::FunctionTemplate::New(dispatch_CSRToString),
-                       v8::ReadOnly);
-}
-
-// virtual
-bool CSR::ParseConstructorArgs(
-    v8::Handle<v8::Object> obj, const v8::Arguments& args) {
-  if (args.Length() < 1) {
-    utils::ThrowV8Exception("Not enough parameters.");
-    return false;
-  }
-
-  // Extract the SlotObject
-  SlotObject* slot_object =
-      reinterpret_cast<SlotObject*>(v8::External::Unwrap(args.Data()));
-  if (!slot_object) {
-    utils::ThrowV8Exception("Data argument is not a SlotObject.");
-    return false;
-  }
-
-  // Argument 0 is the subject
-  v8::Handle<v8::Value> subject = args[0];
-  obj->Set(v8::String::NewSymbol("subject"), subject->ToString());
-
-  // Build the CSR request
-  if (!certificate_handler()->BuildCSR(slot_object->label(),
-                                       utils::ValueAsUtf8String(subject),
-                                       &request_)) {
-    utils::ThrowV8Exception("Error building CSR.");
-    return false;
-  }
-
-  return true;
-}
-
-// Class Certificate Implementation
-
-// static
-CertificateHandler* Certificate::certificate_handler_ = NULL;
-
-// Returns the contents of the Certificate as a string.
-// Note: if this is binary and not Base64, results may be unexpected.
-// (i.e. don't call this unles you expect the contents to be a string)
-static v8::Handle<v8::Value> dispatch_CertificateToString(
-    const v8::Arguments& args) {
-  Certificate* cert = Certificate::Unwrap(args.This());
-  const chromeos::Blob& certdata = cert->certificate();
-  const char* certstrptr = reinterpret_cast<const char*>(&(certdata.front()));
-  v8::Local<v8::String> res = v8::String::New(certstrptr);
-  return res;
-}
-
-// static
-void Certificate::SetTemplateBindings(
-    v8::Handle<v8::ObjectTemplate> template_object){
-  template_object->Set(v8::String::NewSymbol("toString"),
-                       v8::FunctionTemplate::New(dispatch_CertificateToString),
-                       v8::ReadOnly);
-}
-
-// virtual
-bool Certificate::ParseConstructorArgs(v8::Handle<v8::Object> obj,
-                                       const v8::Arguments& args) {
-  // Extract the pkcs11 object
-  Pkcs11* pkcs11 = reinterpret_cast<Pkcs11*>(v8::External::Unwrap(args.Data()));
-  if (!pkcs11) {
-    utils::ThrowV8Exception("Data argument is not a Pkcs11 object.");
-    return false;
-  }
-
-  if (!pkcs11->IsReady()) {
-    utils::ThrowV8Exception("Pkcs11 object is not ready.");
-    return false;
-  }
-
-  if (args.Length() < 1) {
-    utils::ThrowV8Exception("Not enough parameters.");
-    return false;
-  }
-
-  // Argument is the contents (passed to BuildCertificate)
-  v8::Handle<v8::Value> content = args[0];
-
-  // Generate the Certificate data
-  bool res = certificate_handler()->BuildCertificate(
-      utils::ValueAsUtf8String(content), &certificate_, &subject_);
-  if (!res) {
-    utils::ThrowV8Exception("Unable to build certificate.");
-    return false;
-  }
-
-  // Set the 'subject' property to the certificate subject
-  obj->Set(v8::String::NewSymbol("subject"),
-           v8::String::New(subject_.c_str()));
-
-  return true;
-}
-
-// Class SlotObject Implementation
-
-bool SlotObject::Initialize() {
-  // Bind "CSR" here so we can associate this with it
-  v8::Handle<v8::FunctionTemplate> t = GetTemplate();
-  v8::Handle<v8::ObjectTemplate> t_obj = t->InstanceTemplate();
-  t_obj->Set(v8::String::NewSymbol("CSR"),
-             v8::FunctionTemplate::New(CSR::Construct,
-                                       v8::External::Wrap(this)),
-             v8::ReadOnly);
-
-  // Build and initialize the V8 object.
-  return JSObjectWrapper<SlotObject>::Initialize();
-}
-
-static v8::Handle<v8::Value> dispatch_generateKeyPair(
-    const v8::Arguments& args) {
-  // Get the arguments.
-  SlotObject* slot = SlotObject::Unwrap(args.This());
-  if (slot == NULL)
-    return utils::ThrowV8Exception("Method called on incorrect object type.");
-
-  if (args.Length() < 1)
-    return utils::ThrowV8Exception("Not enough parameters.");
-
-  // Argument 0 is the key identifier
-  v8::Handle<v8::String> v8keyid = args[0]->ToString();
-  std::string keyid = std::string(*v8::String::Utf8Value(v8keyid));
-  bool res = slot->SetKeyIdentifier(keyid);
-  if (!res)
-    return utils::ThrowV8Exception(std::string("Invalid key id: ") + keyid);
-
-  // Set the JS keyIdentifier property
-  slot->obj()->Set(v8::String::NewSymbol("keyIdentifier"), v8keyid);
-
-  // Argumnet 1 is the passphrase (optional)
-  std::string passphrase;  // defaults to empty
-  if (!args[1]->IsUndefined()) {
-    passphrase = utils::ValueAsUtf8String(args[1]);
-    slot->SetPassphrase(passphrase);
-  }
-
-  // Access the slot handler and generate the public/private key pair
-  if (!slot->slot_handler()->GenerateKeyPair(slot->label(),
-                                             slot->passphrase())) {
-    return utils::ThrowV8Exception("Unable to build key pair");
-  }
-
-  return v8::True();
-}
-
-static v8::Handle<v8::Value> dispatch_addCertificate(
-    const v8::Arguments& args) {
-  // Get the arguments.
-  SlotObject* slot = SlotObject::Unwrap(args.This());
-  if (slot == NULL)
-    return utils::ThrowV8Exception("Method called on incorrect object type.");
-
-  if (args.Length() < 1)
-    return utils::ThrowV8Exception("Not enough parameters.");
-
-  // Argument is the Certificate object.
-  Certificate* cert = Certificate::GetFromArg(args, 0);
-  if (cert == NULL)
-    return utils::ThrowV8Exception("Invalid Certificate object");
-
-  // Access the slot handler and add the Certificate
-  if (!slot->slot_handler()->AddCertificate(slot->label(),
-                                            cert->certificate(),
-                                            cert->subject())) {
-    return utils::ThrowV8Exception("PKCS11 device error.");
-  }
-
-  // Add the certificate to the JS object
-  slot->obj()->Set(v8::String::NewSymbol("certificate"), cert->obj());
-
-  return v8::True();
-}
-
-// static
-void SlotObject::SetTemplateBindings(
-    v8::Handle<v8::ObjectTemplate> template_object) {
-  // "CSR" is set in Initialize so it can include
-  // a pointer back to the SlotObject.
-  template_object->Set(v8::String::NewSymbol("generateKeyPair"),
-                       v8::FunctionTemplate::New(dispatch_generateKeyPair),
-                       v8::ReadOnly);
-  template_object->Set(v8::String::NewSymbol("addCertificate"),
-                       v8::FunctionTemplate::New(dispatch_addCertificate),
-                       v8::ReadOnly);
-}
-
-// virtual
-bool SlotObject::ParseConstructorArgs(
-    v8::Handle<v8::Object> obj, const v8::Arguments& args) {
-  // Extract the pkcs11 object
-  Pkcs11* pkcs11 = reinterpret_cast<Pkcs11*>(v8::External::Unwrap(args.Data()));
-  if (!pkcs11) {
-    utils::ThrowV8Exception("Data argument is not a Pkcs11 object.");
-    return false;
-  }
-
-  if (!pkcs11->IsReady()) {
-    utils::ThrowV8Exception("Pkcs11 object is not ready.");
-    return false;
-  }
-
-  if (args.Length() < 1) {
-    utils::ThrowV8Exception("Not enough parameters.");
-    return false;
-  }
-
-  SetSlotHandler(pkcs11->slot_handler());
-
-  // Argument is the label; make it ReadOnly so it can not be changed later.
-  v8::Handle<v8::String> v8label = args[0]->ToString();
-  obj->Set(v8::String::NewSymbol("label"), v8label, v8::ReadOnly);
-  label_ = std::string(*v8::String::Utf8Value(v8label));
-
-  // Build the SlotObject
-  if (!pkcs11->slot_handler()->BuildSlotObject(label_)) {
-    utils::ThrowV8Exception("Unable to build SlotObject");
-    return false;
-  }
-
-  // Add this to pkcs11.slots ("slots[label] = obj")
-  pkcs11->AddJSSlotObject(this);
-  return true;
-}
-
-
-// Class Pkcs11
-Pkcs11::Pkcs11()
-    : JSObjectWrapper<Pkcs11>(),
-      certificate_handler_(NULL),
-      slot_handler_(NULL),
-      handlers_ready_(false) {
-}
-
-bool Pkcs11::enable_opencryptoki = true;
-
-Pkcs11::~Pkcs11() {
-  CleanupTemplate();  // We only have one Pkcs11 instance.
-}
-
-bool Pkcs11::Initialize() {
-  // Initialize the SlotObject template here so that we can embed 'this'.
-  v8::Handle<v8::FunctionTemplate> t = GetTemplate();
-  v8::Handle<v8::ObjectTemplate> t_obj = t->InstanceTemplate();
-
-  // These properties are set here because they need a reference to "this",
-  // which isn't available in the static SetTemplateBindings method.
-  t_obj->Set(v8::String::NewSymbol("SlotObject"),
-             v8::FunctionTemplate::New(SlotObject::Construct,
-                                       v8::External::Wrap(this)),
-             v8::ReadOnly);
-  t_obj->Set(v8::String::NewSymbol("Certificate"),
-             v8::FunctionTemplate::New(Certificate::Construct,
-                                       v8::External::Wrap(this)),
-             v8::ReadOnly);
-
-  // Build and initialize the V8 object.
-  if (!JSObjectWrapper<Pkcs11>::Initialize())
-    return false;
-
-  // InitializeCrypto may fail if the requisite crypto daemons aren't running.
-  // We try to setup here to save the caller the trouble, but if it fails
-  // we don't want to claim the whole initialization failed, so we ignore
-  // the return vale.
-  InitializeCrypto();
-
-  return true;
-}
-
-// Called to initialize the certificate and slot handlers.  This may fail if
-// the pkcs11 prerequisites aren't yet available (for example, the TPM hasn't
-// been owned, or the token hasn't been initialized.)  If it fails, you should
-// be free to try again later.
-bool Pkcs11::InitializeCrypto() {
-  if (handlers_ready_)
-    return true;
-
-  certificate_handler_.reset(new CertificateHandlerOpenSsl());
-  if (!certificate_handler_.get() || !certificate_handler_->Initialize()) {
-    LOG(WARNING) << "Certificate Handler failed to initialize.";
-    certificate_handler_.reset();
-    slot_handler_.reset();
-    return false;
-  }
-
-  if (Pkcs11::enable_opencryptoki) {
-    LOG(INFO) << "Initializing opencryptoki slot handler.";
-    slot_handler_.reset(new SlotHandlerOpenCryptoki());
-  } else {
-    LOG(INFO) << "Initializing in-memory slot handler.";
-    slot_handler_.reset(new SlotHandlerInMemory());
-  }
-
-  if (!slot_handler_.get() || !slot_handler_->Initialize()) {
-    LOG(WARNING) << "Slot Handler failed to initialize.";
-    certificate_handler_.reset();
-    slot_handler_.reset();
-    return false;
-  }
-
-  slot_handler_->ReadObjectsFromSlot(this);
-
-  // The certificate handler may need access to the slot handler.
-  certificate_handler_->SetSlotHandler(slot_handler());
-
-  // Set up the CSR and Certificate sub-classes with the certificate handler.
-  CSR::InitCertificateHandler(certificate_handler_.get());
-  Certificate::InitCertificateHandler(certificate_handler_.get());
-
-  handlers_ready_ = true;
-
-  return true;
-}
-
-// pkcs11[slot_object->label()] = slot_object->obj()
-bool Pkcs11::AddJSSlotObject(const SlotObject* slot_object) {
-  v8::Local<v8::Value> slotsvalue = obj()->Get(v8::String::NewSymbol("slots"));
-  if (slotsvalue.IsEmpty() || !slotsvalue->IsObject()) {
-    LOG(ERROR) << "'slots' is not an object in pkcs11";
-    return false;
-  }
-  v8::Local<v8::Object> slots = v8::Local<v8::Object>::Cast(slotsvalue);
-  v8::Local<v8::String> v8label = v8::String::New(slot_object->label().c_str());
-  slots->Set(v8label, slot_object->obj());
-  return true;
-}
-
-// delete pkcs11.slots[label]")
-bool Pkcs11::RemoveJSSlotObject(const std::string& label) {
-  v8::Local<v8::Value> slotsvalue = obj()->Get(v8::String::NewSymbol("slots"));
-  if (slotsvalue.IsEmpty() || !slotsvalue->IsObject()) {
-    LOG(ERROR) << "'slots' is not an object in pkcs11";
-    return false;
-  }
-  v8::Local<v8::Object> slots = v8::Local<v8::Object>::Cast(slotsvalue);
-  v8::Local<v8::String> v8label = v8::String::New(label.c_str());
-  slots->Delete(v8label);
-  return true;
-}
-
-static v8::Handle<v8::Value> dispatch_setUserPin(
-    const v8::Arguments& args) {
-  // Get the arguments.
-  Pkcs11* pkcs11 = Pkcs11::Unwrap(args.This());
-  if (!pkcs11)
-    return utils::ThrowV8Exception("Method called on incorrect object");
-
-  if (!pkcs11->IsReady())
-    return utils::ThrowV8Exception("Pkcs11 object is not ready");
-
-  if (args.Length() < 1)
-    return utils::ThrowV8Exception("Not enough parameters.");
-
-  // Argument is the pin
-  std::string pin = utils::ValueAsUtf8String(args[0]);
-  if (!pkcs11->slot_handler()->SetUserPin(pin))
-    return utils::ThrowV8Exception("PKCS11 device error");
-
-  return v8::True();
-}
-
-static v8::Handle<v8::Value> dispatch_removeSlotObject(
-    const v8::Arguments& args) {
-  // Get the pkcs11 object.
-  Pkcs11* pkcs11 = Pkcs11::Unwrap(args.This());
-  if (!pkcs11)
-    return utils::ThrowV8Exception("Method called on incorrect object");
-
-  if (!pkcs11->IsReady())
-    return utils::ThrowV8Exception("Pkcs11 object is not ready");
-
-  if (args.Length() < 1)
-    return utils::ThrowV8Exception("Not enough parameters");
-
-  // Argument 0 is a label.
-  std::string label = utils::ValueAsUtf8String(args[0]);
-
-  // Remove the contents of the slot in the slot handler.
-  if (!pkcs11->slot_handler()->RemoveObjects(label))
-    return utils::ThrowV8Exception("PKCS11 device error");
-
-  // Remove entry from pkcs11.slots
-  pkcs11->RemoveJSSlotObject(label);
-
-  return v8::True();
-}
-
-// Called by v8 when someone trys to read pkcs11.isReady.
-v8::Handle<v8::Value> dispatch_GetIsReady(v8::Local<v8::String> name,
-                                        const v8::AccessorInfo& info) {
-  Pkcs11* pkcs11 = Pkcs11::Unwrap(info.Holder());
-  if (!pkcs11)
-    return utils::ThrowV8Exception("Method called on incorrect object");
-
-  if (pkcs11->IsReady() || pkcs11->InitializeCrypto())
-    return v8::True();
-
-  return v8::False();
-}
-
-// Called by v8 when someone trys write to pkcs11.isReady.
-void dispatch_SetReadOnly(v8::Local<v8::String> name,
-                          v8::Local<v8::Value> value,
-                          const v8::AccessorInfo& info) {
-  utils::ThrowV8Exception("Attempt to set read-only property");
-}
-
-// static
-void Pkcs11::SetTemplateBindings(
-    v8::Handle<v8::ObjectTemplate> template_object) {
-  // "SlotObject" gets setup specially in Initialize();
-  template_object->Set(v8::String::NewSymbol("setUserPin"),
-                       v8::FunctionTemplate::New(dispatch_setUserPin),
-                       v8::ReadOnly);
-  template_object->Set(v8::String::NewSymbol("remove"),
-                       v8::FunctionTemplate::New(dispatch_removeSlotObject),
-                       v8::ReadOnly);
-  template_object->Set(v8::String::NewSymbol("slots"),
-                       v8::Object::New(),
-                       v8::ReadOnly);
-
-  template_object->SetAccessor(v8::String::NewSymbol("isReady"),
-                               dispatch_GetIsReady,
-                               dispatch_SetReadOnly);
-}
-
-#if 0
-// NOTE(rginda): This could potentially be
-// SlotHandlerOpencryptoki::GenerateKeyPair, except it's known to not
-// work.  The symptom is that it generates broken keys with a "0" exponent.
-// The guess is that this is due to a bug in opencryptoki, though it could
-// also be a bug in this chunk of code.  For now, we just generate keypairs
-// with the vanilla OpenSSL libraries, store them under opencryptoki,
-// and toss out the plaintext keypair.
-
-  virtual bool GenerateKeyPair(const std::string& label,
-                               const std::string& passphrase) {
-    LOG(INFO) << "Generating Key Pair.";
-
-    Object* object = GetObject(label);
-    if (!object) {
-      LOG(ERROR) << "BuildSlotObject must be called before GenerateKeyPair.";
-      return false;
-    }
-    SessionHandle session(OpenSession(label));
-    if (!session.handle())
-      return false;
-
-    CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY;
-    CK_BBOOL is_token = TRUE;
-    CK_BBOOL can_encrypt = TRUE;
-    CK_BBOOL can_verify = TRUE;
-    CK_BBOOL can_wrap = TRUE;
-    CK_ULONG modulusBits = 2048;
-    CK_BYTE publicExponent[] = { 0x01, 0x00, 0x01 };  // 65537 in bytes
-
-    const size_t IDSTR_MAX_LENGTH = 8;
-    CK_BYTE idstr[IDSTR_MAX_LENGTH];
-    CK_ULONG idstrlen;
-    if (!GetKeyIdStr(object->key_identifier_,
-                     &idstr[0], &idstrlen, IDSTR_MAX_LENGTH)) {
-      return false;
-    }
-
-    int public_key_n_attr = 0;
-    CK_ATTRIBUTE public_key_template[16];
-    FillAttr(&public_key_template[public_key_n_attr++], CKA_CLASS,
-             &pubkey_class, sizeof(pubkey_class));
-    FillAttr(&public_key_template[public_key_n_attr++], CKA_TOKEN,
-             &is_token, sizeof(is_token));
-    FillAttr(&public_key_template[public_key_n_attr++], CKA_ENCRYPT,
-             &can_encrypt, sizeof(can_encrypt));
-    FillAttr(&public_key_template[public_key_n_attr++], CKA_VERIFY,
-             &can_verify, sizeof(can_verify));
-    FillAttr(&public_key_template[public_key_n_attr++], CKA_WRAP,
-             &can_wrap, sizeof(can_wrap));
-    FillAttr(&public_key_template[public_key_n_attr++], CKA_MODULUS_BITS,
-             &modulusBits, sizeof(modulusBits));
-    FillAttr(&public_key_template[public_key_n_attr++], CKA_PUBLIC_EXPONENT,
-             publicExponent, sizeof(publicExponent));
-    FillStringAttr(&public_key_template[public_key_n_attr++], CKA_LABEL,
-                   label);
-    FillAttr(&public_key_template[public_key_n_attr++], CKA_ID,
-             idstr, idstrlen);
-
-
-    CK_OBJECT_CLASS privkey_class = CKO_PRIVATE_KEY;
-    CK_BBOOL is_private = TRUE;
-    CK_BBOOL is_sensitive = TRUE;
-    CK_BBOOL can_decrypt = TRUE;
-    CK_BBOOL can_sign = TRUE;
-    CK_BBOOL can_unwrap = TRUE;
-
-    int private_key_n_attr = 0;
-    CK_ATTRIBUTE private_key_template[16];
-    FillAttr(&private_key_template[private_key_n_attr++], CKA_CLASS,
-             &privkey_class, sizeof(privkey_class));
-    FillAttr(&private_key_template[private_key_n_attr++], CKA_TOKEN,
-             &is_token, sizeof(is_token));
-    FillAttr(&private_key_template[private_key_n_attr++], CKA_PRIVATE,
-             &is_private, sizeof(is_private));
-    FillAttr(&private_key_template[private_key_n_attr++], CKA_SENSITIVE,
-             &is_sensitive, sizeof(is_sensitive));
-    FillAttr(&private_key_template[private_key_n_attr++], CKA_DECRYPT,
-             &can_decrypt, sizeof(can_decrypt));
-    FillAttr(&private_key_template[private_key_n_attr++], CKA_SIGN,
-             &can_sign, sizeof(can_sign));
-    FillAttr(&private_key_template[private_key_n_attr++], CKA_UNWRAP,
-             &can_unwrap, sizeof(can_unwrap));
-    FillStringAttr(&private_key_template[private_key_n_attr++], CKA_LABEL,
-                   label);
-    FillAttr(&private_key_template[private_key_n_attr++], CKA_ID,
-             idstr, idstrlen);
-
-
-    CK_MECHANISM mechanism = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
-    CK_OBJECT_HANDLE public_key_handle;
-    CK_OBJECT_HANDLE private_key_handle;
-
-    CK_RV rv = C_GenerateKeyPair(session.handle(), &mechanism,
-                                 public_key_template, public_key_n_attr,
-                                 private_key_template, private_key_n_attr,
-                                 &public_key_handle, &private_key_handle);
-
-    if (rv != CKR_OK) {
-      LOG(ERROR) << "C_GenerateKeyPair() failed. rv=" << rv;
-      return false;
-    }
-
-    return true;
-  }
-
-#endif
-
-} // namespace entd
diff --git a/pkcs11.h b/pkcs11.h
deleted file mode 100644
index 230fb21..0000000
--- a/pkcs11.h
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ENTD_PKCS11_H_
-#define ENTD_PKCS11_H_
-
-#include <string>
-#include <vector>
-
-#include <base/basictypes.h>
-#include <base/memory/scoped_ptr.h>
-#include <chromeos/utility.h>
-#include <v8.h>
-
-#include "entd/js_object_wrapper.h"
-
-namespace entd {
-
-class Certificate;
-class CSR;
-class CertificateHandler;
-class SlotHandler;
-class SlotObject;
-class Pkcs11;
-
-// Implementation class for interfacing with pkcs11 devices,
-// including generation of Certificate Service Requests (CSR)
-// with a hidden private key (e.g. stored in a TPM), and
-// storage of encrypted Certificates in a device associated
-// with a public/private key pair.
-
-
-// Pure Interface class for defining PKCS11 slot handlers
-class SlotHandler {
- public:
-  virtual ~SlotHandler() {}
-  virtual bool Initialize() = 0;
-  virtual bool SetUserPin(const std::string& pin) = 0;
-  virtual bool SetKeyIdentifier(const std::string& label,
-                                const std::string& keyid) = 0;
-  virtual bool BuildSlotObject(const std::string& label) = 0;
-  virtual bool GenerateKeyPair(const std::string& label,
-                               const std::string& passphrase) = 0;
-  virtual bool AddPrivateKey(const std::string& label,
-                             const std::string& subject,
-                             const chromeos::Blob& key) = 0;
-  virtual bool AddCertificate(const std::string& label,
-                              const chromeos::Blob& cert,
-                              const std::string& subject) = 0;
-  virtual bool ReadObjectsFromSlot(Pkcs11* pkcs11) = 0;
-  virtual bool RemoveObjects(const std::string& label) = 0;
-  virtual std::string GetKeyIdentifier(const std::string& label) const = 0;
-  virtual std::string GetPassphrase(const std::string& label) const = 0;
-  virtual std::string GetPublicKey(const std::string& label) const = 0;
-  virtual std::vector<std::string> GetObjectNames() const = 0;
-};
-
-// Pure Interface class for defining certificate handlers.
-class CertificateHandler {
- public:
-  CertificateHandler() : slot_handler_(NULL) {}
-  virtual ~CertificateHandler() {}
-  virtual bool Initialize() = 0;
-  virtual bool BuildCSR(const std::string& label,
-                        const std::string& subject,
-                        std::string* csr) = 0;
-  virtual bool BuildCertificate(const std::string& content,
-                                chromeos::Blob* certificate,
-                                std::string* subject) = 0;
-  // SetSlotHandler() is called from Pkcs11::Initialize with its
-  // SlotHandler implementation for the benefit of certificate handlers
-  // that need access to the slot handler (e.g. for encryption).
-  void SetSlotHandler(SlotHandler* slot_handler) {
-    slot_handler_ = slot_handler;
-  }
-  SlotHandler* slot_handler() { return slot_handler_; }
- private:
-  SlotHandler* slot_handler_;
-};
-
-// Pkcs11 JavaScript Interface class.
-//
-// This class wraps a V8 singleton object to handle the PKCS11 interface.
-class Pkcs11 : public JSObjectWrapper<Pkcs11> {
- public:
-  Pkcs11();
-
-  virtual ~Pkcs11();
-
-  // Initialize the instance (Must be called before using other methods.)
-  //
-  // Returns false if initialization fails fatally, in which case you should
-  // discard the object.  May return true without fully initializing the
-  // object in the case that the requisite crypto libraries fail to
-  // initialize.
-  //
-  // If that happens IsReady() will return false.  You should then
-  // invoke InitializeCrypto() later, before invoking any other functions.
-  virtual bool Initialize();
-
-  // Initialize the chosen crypto mode.  Returns true if it is able to
-  // initialize crypto, false otherwise.  You may call this multiple times.
-  // It's a no-op if crypto is already loaded, but will retry initialization
-  // if not.
-  bool InitializeCrypto();
-
-  // True if the crypto has been properly set up and the object is ready to
-  // use.
-  bool IsReady() { return handlers_ready_; }
-
-  // Adds slot_object to "pkcs11.slots"
-  bool AddJSSlotObject(const SlotObject* slot_object);
-  bool RemoveJSSlotObject(const std::string& label);
-
-  // JSObjectWrapper functions
-  static const char* GetClassName() { return "pkcs11"; }
-  static void SetTemplateBindings(
-      v8::Handle<v8::ObjectTemplate> template_object);
-
-  // Accessors for V8 callbacks
-  CertificateHandler* certificate_handler() {
-    return certificate_handler_.get();
-  }
-
-  SlotHandler* slot_handler() {
-    return slot_handler_.get();
-  }
-
-  // globals
-  static bool enable_opencryptoki;
-
- private:
-  scoped_ptr<CertificateHandler> certificate_handler_;
-  scoped_ptr<SlotHandler> slot_handler_;
-
-  bool handlers_ready_;
-
-  DISALLOW_COPY_AND_ASSIGN(Pkcs11);
-};
-
-} // namespace entd
-
-#endif // ENTD_PKCS11_H_