Skip to content

Commit

Permalink
Fixing FindFromPublicKeyInfo so that it searches the "Public" NSS dat…
Browse files Browse the repository at this point in the history
…abase

if it doesn't find the requested key in the "Private" NSS database.

This fixes the ownership process because the ownership key is created
in the public database because that needs to happen before the TPM is
owned and available (and it's not really all that sensitive to begin
with).

BUG=chromium-os:15645
TEST=Built a new recovery image, wiped a device with it and verified
that I was able to sign in as a new user and add users and forget
networks.  It also showed me as the owner of the device.

Review URL: http://codereview.chromium.org/7066032

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86654 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
gspencer@google.com committed May 25, 2011
1 parent 4195cfc commit cfa46c0
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 30 deletions.
2 changes: 1 addition & 1 deletion crypto/nss_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ bool CheckNSSVersion(const char* version);
// GetPublicNSSKeySlot().
void OpenPersistentNSSDB();

// A delegate class that we can use it to access the cros API for
// A delegate class that we can use to access the cros API for
// communication with cryptohomed and the TPM.
class TPMTokenInfoDelegate {
public:
Expand Down
64 changes: 35 additions & 29 deletions crypto/rsa_private_key_nss.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "base/string_util.h"
#include "crypto/nss_util.h"
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_nss_types.h"

// TODO(rafaelw): Consider refactoring common functions and definitions from
// rsa_private_key_win.cc or using NSS's ASN.1 encoder.
Expand Down Expand Up @@ -91,7 +92,7 @@ RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo(
key_der.data = const_cast<unsigned char*>(&input[0]);
key_der.len = input.size();

CERTSubjectPublicKeyInfo *spki =
CERTSubjectPublicKeyInfo* spki =
SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der);
if (!spki) {
NOTREACHED();
Expand All @@ -105,35 +106,38 @@ RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo(
return NULL;
}

// Now, look for the associated private key in the user's
// hardware-backed NSS DB. If it's not there, consider that an
// error.
PK11SlotInfo *slot = GetPrivateNSSKeySlot();
if (!slot) {
// Make sure the key is an RSA key. If not, that's an error
if (result->public_key_->keyType != rsaKey) {
NOTREACHED();
return NULL;
}

// Make sure the key is an RSA key. If not, that's an error
if (result->public_key_->keyType != rsaKey) {
PK11_FreeSlot(slot);
ScopedSECItem ck_id(
PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus)));
if (!ck_id.get()) {
NOTREACHED();
return NULL;
}

SECItem *ck_id = PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus));
if (!ck_id) {
PK11_FreeSlot(slot);
ScopedPK11Slot slot(GetPrivateNSSKeySlot());
if (!slot.get()) {
NOTREACHED();
return NULL;
}

// Finally...Look for the key!
result->key_ = PK11_FindKeyByKeyID(slot, ck_id, NULL);

// Cleanup...
PK11_FreeSlot(slot);
SECITEM_FreeItem(ck_id, PR_TRUE);
result->key_ = PK11_FindKeyByKeyID(slot.get(), ck_id.get(), NULL);

// If we don't find the matching key in the private slot, then we
// look in the public slot.
if (!result->key_) {
slot.reset(GetPublicNSSKeySlot());
if (!slot.get()) {
NOTREACHED();
return NULL;
}
result->key_ = PK11_FindKeyByKeyID(slot.get(), ck_id.get(), NULL);
}

// If we didn't find it, that's ok.
if (!result->key_)
Expand Down Expand Up @@ -166,16 +170,15 @@ bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) {
}

bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) {
SECItem* der_pubkey = SECKEY_EncodeDERSubjectPublicKeyInfo(public_key_);
if (!der_pubkey) {
ScopedSECItem der_pubkey(SECKEY_EncodeDERSubjectPublicKeyInfo(public_key_));
if (!der_pubkey.get()) {
NOTREACHED();
return false;
}

for (size_t i = 0; i < der_pubkey->len; ++i)
output->push_back(der_pubkey->data[i]);

SECITEM_FreeItem(der_pubkey, PR_TRUE);
return true;
}

Expand All @@ -191,16 +194,20 @@ RSAPrivateKey* RSAPrivateKey::CreateWithParams(uint16 num_bits,

scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);

PK11SlotInfo *slot = GetPrivateNSSKeySlot();
if (!slot)
ScopedPK11Slot slot(GetPrivateNSSKeySlot());
if (!slot.get())
return NULL;

PK11RSAGenParams param;
param.keySizeInBits = num_bits;
param.pe = 65537L;
result->key_ = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &param,
&result->public_key_, permanent, sensitive, NULL);
PK11_FreeSlot(slot);
result->key_ = PK11_GenerateKeyPair(slot.get(),
CKM_RSA_PKCS_KEY_PAIR_GEN,
&param,
&result->public_key_,
permanent,
sensitive,
NULL);
if (!result->key_)
return NULL;

Expand All @@ -217,8 +224,8 @@ RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams(

scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);

PK11SlotInfo *slot = GetPrivateNSSKeySlot();
if (!slot)
ScopedPK11Slot slot(GetPrivateNSSKeySlot());
if (!slot.get())
return NULL;

SECItem der_private_key_info;
Expand All @@ -229,9 +236,8 @@ RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams(
const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT |
KU_DIGITAL_SIGNATURE;
SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
slot, &der_private_key_info, NULL, NULL, permanent, sensitive,
slot.get(), &der_private_key_info, NULL, NULL, permanent, sensitive,
key_usage, &result->key_, NULL);
PK11_FreeSlot(slot);
if (rv != SECSuccess) {
NOTREACHED();
return NULL;
Expand Down

0 comments on commit cfa46c0

Please sign in to comment.