| Index: chrome/browser/chromeos/login/owner_key_utils.cc
|
| diff --git a/chrome/browser/chromeos/login/owner_key_utils.cc b/chrome/browser/chromeos/login/owner_key_utils.cc
|
| index 916d9c70445866f736fcc078792c0b32c5584eeb..7831d995573a7f30fa55d31325520ca3bb52c8ba 100644
|
| --- a/chrome/browser/chromeos/login/owner_key_utils.cc
|
| +++ b/chrome/browser/chromeos/login/owner_key_utils.cc
|
| @@ -20,9 +20,21 @@
|
| #include "base/scoped_ptr.h"
|
| #include "base/string_util.h"
|
|
|
| +namespace chromeos {
|
| +
|
| +///////////////////////////////////////////////////////////////////////////
|
| +// OwnerKeyUtils
|
| +
|
| // static
|
| OwnerKeyUtils::Factory* OwnerKeyUtils::factory_ = NULL;
|
|
|
| +OwnerKeyUtils::OwnerKeyUtils() {}
|
| +
|
| +OwnerKeyUtils::~OwnerKeyUtils() {}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////
|
| +// OwnerKeyUtilsImpl
|
| +
|
| class OwnerKeyUtilsImpl : public OwnerKeyUtils {
|
| public:
|
| OwnerKeyUtilsImpl();
|
| @@ -31,10 +43,18 @@ class OwnerKeyUtilsImpl : public OwnerKeyUtils {
|
| bool GenerateKeyPair(SECKEYPrivateKey** private_key_out,
|
| SECKEYPublicKey** public_key_out);
|
|
|
| - bool ExportPublicKey(SECKEYPublicKey* key, const FilePath& key_file);
|
| + bool ExportPublicKeyViaDbus(SECKEYPublicKey* key);
|
| +
|
| + bool ExportPublicKeyToFile(SECKEYPublicKey* key, const FilePath& key_file);
|
|
|
| SECKEYPublicKey* ImportPublicKey(const FilePath& key_file);
|
|
|
| + SECKEYPrivateKey* FindPrivateKey(SECKEYPublicKey* key);
|
| +
|
| + void DestroyKeys(SECKEYPrivateKey* private_key, SECKEYPublicKey* public_key);
|
| +
|
| + FilePath GetOwnerKeyFilePath();
|
| +
|
| private:
|
| // Fills in fields of |key_der| with DER encoded data from a file at
|
| // |key_file|. The caller must pass in a pointer to an actual SECItem
|
| @@ -48,7 +68,9 @@ class OwnerKeyUtilsImpl : public OwnerKeyUtils {
|
| // SECITEM_FreeItem(key_der, PR_FALSE);
|
| static bool ReadDERFromFile(const FilePath& key_file, SECItem* key_der);
|
|
|
| - // The place outside the owner's encrypted home directory where her
|
| + static bool EncodePublicKey(SECKEYPublicKey* key, std::string* out);
|
| +
|
| + // The file outside the owner's encrypted home directory where her
|
| // key will live.
|
| static const char kOwnerKeyFile[];
|
|
|
| @@ -60,10 +82,7 @@ class OwnerKeyUtilsImpl : public OwnerKeyUtils {
|
| DISALLOW_COPY_AND_ASSIGN(OwnerKeyUtilsImpl);
|
| };
|
|
|
| -OwnerKeyUtils::OwnerKeyUtils() {}
|
| -
|
| -OwnerKeyUtils::~OwnerKeyUtils() {}
|
| -
|
| +// Defined here, instead of up above, because we need OwnerKeyUtilsImpl.
|
| OwnerKeyUtils* OwnerKeyUtils::Create() {
|
| if (!factory_)
|
| return new OwnerKeyUtilsImpl();
|
| @@ -147,18 +166,9 @@ bool OwnerKeyUtilsImpl::GenerateKeyPair(SECKEYPrivateKey** private_key_out,
|
| if (!is_success) {
|
| LOG(ERROR) << "Owner key generation failed! (NSS error code "
|
| << PR_GetError() << ")";
|
| - // Do cleanups
|
| - base::AutoNSSWriteLock lock;
|
| - if (*private_key_out) {
|
| - PK11_DestroyTokenObject((*private_key_out)->pkcs11Slot,
|
| - (*private_key_out)->pkcs11ID);
|
| - SECKEY_DestroyPrivateKey(*private_key_out);
|
| - }
|
| - if (*public_key_out) {
|
| - PK11_DestroyTokenObject((*public_key_out)->pkcs11Slot,
|
| - (*public_key_out)->pkcs11ID);
|
| - SECKEY_DestroyPublicKey(*public_key_out);
|
| - }
|
| + DestroyKeys(*private_key_out, *public_key_out);
|
| + *private_key_out = NULL;
|
| + *public_key_out = NULL;
|
| } else {
|
| LOG(INFO) << "Owner key generation succeeded!";
|
| }
|
| @@ -169,39 +179,48 @@ bool OwnerKeyUtilsImpl::GenerateKeyPair(SECKEYPrivateKey** private_key_out,
|
| return is_success;
|
| }
|
|
|
| -bool OwnerKeyUtilsImpl::ExportPublicKey(SECKEYPublicKey* key,
|
| - const FilePath& key_file) {
|
| +bool OwnerKeyUtilsImpl::ExportPublicKeyViaDbus(SECKEYPublicKey* key) {
|
| + DCHECK(key);
|
| + bool ok = false;
|
| +
|
| + std::string to_export;
|
| + if (!EncodePublicKey(key, &to_export)) {
|
| + LOG(ERROR) << "Formatting key for export failed!";
|
| + return ok;
|
| + }
|
| +
|
| + // TODO(cmasone): send the data over dbus.
|
| + return ok;
|
| +}
|
| +
|
| +bool OwnerKeyUtilsImpl::ExportPublicKeyToFile(SECKEYPublicKey* key,
|
| + const FilePath& key_file) {
|
| DCHECK(key);
|
| - SECItem* der;
|
| bool ok = false;
|
| int safe_file_size = 0;
|
|
|
| - // Instead of exporting/importing the key directly, I'm actually
|
| - // going to use a SubjectPublicKeyInfo. The reason is because NSS
|
| - // exports functions that encode/decode these kinds of structures, while
|
| - // it does not export the ones that deal directly with public keys.
|
| - der = SECKEY_EncodeDERSubjectPublicKeyInfo(key);
|
| - if (!der) {
|
| - LOG(ERROR) << "Could not encode public key for export!";
|
| - return false;
|
| + std::string to_export;
|
| + if (!EncodePublicKey(key, &to_export)) {
|
| + LOG(ERROR) << "Formatting key for export failed!";
|
| + return ok;
|
| }
|
|
|
| - if (der->len > static_cast<uint>(INT_MAX)) {
|
| - LOG(ERROR) << "key is too big! " << der->len;
|
| + if (to_export.length() > static_cast<uint>(INT_MAX)) {
|
| + LOG(ERROR) << "key is too big! " << to_export.length();
|
| } else {
|
| - safe_file_size = static_cast<int>(der->len);
|
| + safe_file_size = static_cast<int>(to_export.length());
|
|
|
| - ok = (safe_file_size ==
|
| - file_util::WriteFile(key_file,
|
| - reinterpret_cast<char*>(der->data),
|
| - der->len));
|
| + ok = (safe_file_size == file_util::WriteFile(key_file,
|
| + to_export.c_str(),
|
| + safe_file_size));
|
| }
|
| - SECITEM_FreeItem(der, PR_TRUE);
|
| return ok;
|
| }
|
|
|
| SECKEYPublicKey* OwnerKeyUtilsImpl::ImportPublicKey(const FilePath& key_file) {
|
| SECItem key_der;
|
| + key_der.data = NULL;
|
| + key_der.len = 0;
|
|
|
| if (!ReadDERFromFile(key_file, &key_der)) {
|
| PLOG(ERROR) << "Could not read in key from " << key_file.value() << ":";
|
| @@ -231,6 +250,8 @@ bool OwnerKeyUtilsImpl::ReadDERFromFile(const FilePath& key_file,
|
| // considered internal to the NSS command line utils.
|
| // This code is lifted, in spirit, from the implementation of that function.
|
| DCHECK(key_der) << "Don't pass NULL for |key_der|";
|
| + DCHECK(key_der->data == NULL);
|
| + DCHECK(key_der->len == 0);
|
|
|
| // Get the file size (must fit in a 32 bit int for NSS).
|
| int64 file_size;
|
| @@ -265,3 +286,68 @@ bool OwnerKeyUtilsImpl::ReadDERFromFile(const FilePath& key_file,
|
| }
|
| return true;
|
| }
|
| +
|
| +bool OwnerKeyUtilsImpl::EncodePublicKey(SECKEYPublicKey* key,
|
| + std::string* out) {
|
| + SECItem* der;
|
| +
|
| + // Instead of exporting/importing the key directly, I'm actually
|
| + // going to use a SubjectPublicKeyInfo. The reason is because NSS
|
| + // exports functions that encode/decode these kinds of structures, while
|
| + // it does not export the ones that deal directly with public keys.
|
| + der = SECKEY_EncodeDERSubjectPublicKeyInfo(key);
|
| + if (!der) {
|
| + LOG(ERROR) << "Could not encode public key for export!";
|
| + return false;
|
| + }
|
| +
|
| + out->assign(reinterpret_cast<char*>(der->data), der->len);
|
| +
|
| + SECITEM_FreeItem(der, PR_TRUE);
|
| + return true;
|
| +}
|
| +
|
| +SECKEYPrivateKey* OwnerKeyUtilsImpl::FindPrivateKey(SECKEYPublicKey* key) {
|
| + DCHECK(key);
|
| +
|
| + PK11SlotInfo* slot = NULL;
|
| + SECItem* ck_id = NULL;
|
| + SECKEYPrivateKey* found = NULL;
|
| +
|
| + slot = base::GetDefaultNSSKeySlot();
|
| + if (!slot)
|
| + goto cleanup;
|
| +
|
| + ck_id = PK11_MakeIDFromPubKey(&(key->u.rsa.modulus));
|
| + if (!ck_id)
|
| + goto cleanup;
|
| +
|
| + found = PK11_FindKeyByKeyID(slot, ck_id, NULL);
|
| +
|
| + cleanup:
|
| + if (slot)
|
| + PK11_FreeSlot(slot);
|
| + if (ck_id)
|
| + SECITEM_FreeItem(ck_id, PR_TRUE);
|
| +
|
| + return found;
|
| +}
|
| +
|
| +void OwnerKeyUtilsImpl::DestroyKeys(SECKEYPrivateKey* private_key,
|
| + SECKEYPublicKey* public_key) {
|
| + base::AutoNSSWriteLock lock;
|
| + if (private_key) {
|
| + PK11_DestroyTokenObject(private_key->pkcs11Slot, private_key->pkcs11ID);
|
| + SECKEY_DestroyPrivateKey(private_key);
|
| + }
|
| + if (public_key) {
|
| + PK11_DestroyTokenObject(public_key->pkcs11Slot, public_key->pkcs11ID);
|
| + SECKEY_DestroyPublicKey(public_key);
|
| + }
|
| +}
|
| +
|
| +FilePath OwnerKeyUtilsImpl::GetOwnerKeyFilePath() {
|
| + return FilePath(OwnerKeyUtilsImpl::kOwnerKeyFile);
|
| +}
|
| +
|
| +} // namespace chromeos
|
|
|