summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/base.gyp1
-rw-r--r--base/base.gypi8
-rw-r--r--base/crypto/pbkdf2.h22
-rw-r--r--base/crypto/pbkdf2_mac.cc17
-rw-r--r--base/crypto/pbkdf2_nss.cc56
-rw-r--r--base/crypto/pbkdf2_unittest.cc79
-rw-r--r--base/crypto/pbkdf2_win.cc17
-rw-r--r--base/crypto/scoped_nss_types.h47
-rw-r--r--base/crypto/symmetric_key.h46
-rw-r--r--base/crypto/symmetric_key_mac.cc14
-rw-r--r--base/crypto/symmetric_key_nss.cc27
-rw-r--r--base/crypto/symmetric_key_win.cc14
-rw-r--r--base/hmac_nss.cc37
-rw-r--r--base/nss_util.h3
14 files changed, 358 insertions, 30 deletions
diff --git a/base/base.gyp b/base/base.gyp
index 581b38b..74a22f5 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -58,6 +58,7 @@
'cancellation_flag_unittest.cc',
'command_line_unittest.cc',
'condition_variable_unittest.cc',
+ 'crypto/pbkdf2_unittest.cc',
'crypto/rsa_private_key_unittest.cc',
'crypto/signature_creator_unittest.cc',
'crypto/signature_verifier_unittest.cc',
diff --git a/base/base.gypi b/base/base.gypi
index 9ba6ca3..3325b63 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -457,6 +457,10 @@
'sources': [
'crypto/cssm_init.cc',
'crypto/cssm_init.h',
+ 'crypto/pbkdf2.h',
+ 'crypto/pbkdf2_mac.cc',
+ 'crypto/pbkdf2_nss.cc',
+ 'crypto/pbkdf2_win.cc',
'crypto/rsa_private_key.h',
'crypto/rsa_private_key.cc',
'crypto/rsa_private_key_mac.cc',
@@ -470,6 +474,10 @@
'crypto/signature_verifier_mac.cc',
'crypto/signature_verifier_nss.cc',
'crypto/signature_verifier_win.cc',
+ 'crypto/symmetric_key.h',
+ 'crypto/symmetric_key_mac.cc',
+ 'crypto/symmetric_key_nss.cc',
+ 'crypto/symmetric_key_win.cc',
'third_party/nspr/prcpucfg.h',
'third_party/nspr/prcpucfg_win.h',
'third_party/nspr/prtypes.h',
diff --git a/base/crypto/pbkdf2.h b/base/crypto/pbkdf2.h
new file mode 100644
index 0000000..e5c0821
--- /dev/null
+++ b/base/crypto/pbkdf2.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2010 The Chromium 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 BASE_CRYPTO_PBKDF2_H_
+#define BASE_CRYPTO_PBKDF2_H_
+
+#include <string>
+
+#include "base/crypto/symmetric_key.h"
+
+namespace base {
+
+// Derives a key from the supplied password and salt using PBKDF2.
+SymmetricKey* DeriveKeyFromPassword(const std::string& password,
+ const std::string& salt,
+ unsigned int iterations,
+ unsigned int key_size);
+
+} // namespace base
+
+#endif // BASE_CRYPTO_PBKDF2_H_
diff --git a/base/crypto/pbkdf2_mac.cc b/base/crypto/pbkdf2_mac.cc
new file mode 100644
index 0000000..64e661e
--- /dev/null
+++ b/base/crypto/pbkdf2_mac.cc
@@ -0,0 +1,17 @@
+// Copyright (c) 2010 The Chromium 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 "base/crypto/pbkdf2.h"
+
+namespace base {
+
+SymmetricKey* DeriveKeyFromPassword(const std::string& password,
+ const std::string& salt,
+ unsigned int iterations,
+ unsigned int key_size) {
+ // TODO(albertb): Implement this on Mac.
+ return NULL;
+}
+
+} // namespace base
diff --git a/base/crypto/pbkdf2_nss.cc b/base/crypto/pbkdf2_nss.cc
new file mode 100644
index 0000000..df1d898
--- /dev/null
+++ b/base/crypto/pbkdf2_nss.cc
@@ -0,0 +1,56 @@
+// Copyright (c) 2010 The Chromium 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 "base/crypto/pbkdf2.h"
+
+#include <nss.h>
+#include <pk11pub.h>
+
+#include "base/crypto/scoped_nss_types.h"
+#include "base/nss_util.h"
+
+namespace base {
+
+SymmetricKey* DeriveKeyFromPassword(const std::string& password,
+ const std::string& salt,
+ unsigned int iterations,
+ unsigned int key_size) {
+ EnsureNSSInit();
+ if (salt.empty() || iterations == 0 || key_size == 0)
+ return NULL;
+
+ SECItem password_item;
+ password_item.type = siBuffer;
+ password_item.data = reinterpret_cast<unsigned char*>(
+ const_cast<char *>(password.data()));
+ password_item.len = password.size();
+
+ SECItem salt_item;
+ salt_item.type = siBuffer;
+ salt_item.data = reinterpret_cast<unsigned char*>(
+ const_cast<char *>(salt.data()));
+ salt_item.len = salt.size();
+
+ ScopedSECAlgorithmID alg_id(PK11_CreatePBEV2AlgorithmID(SEC_OID_PKCS5_PBKDF2,
+ SEC_OID_PKCS5_PBKDF2,
+ SEC_OID_HMAC_SHA1,
+ key_size,
+ iterations,
+ &salt_item));
+ if (!alg_id.get())
+ return NULL;
+
+ ScopedPK11Slot slot(PK11_GetBestSlot(SEC_OID_PKCS5_PBKDF2, NULL));
+ if (!slot.get())
+ return NULL;
+
+ PK11SymKey* sym_key = PK11_PBEKeyGen(slot.get(), alg_id.get(), &password_item,
+ PR_FALSE, NULL);
+ if (!sym_key)
+ return NULL;
+
+ return new SymmetricKey(sym_key);
+}
+
+} // namespace base
diff --git a/base/crypto/pbkdf2_unittest.cc b/base/crypto/pbkdf2_unittest.cc
new file mode 100644
index 0000000..377bd61
--- /dev/null
+++ b/base/crypto/pbkdf2_unittest.cc
@@ -0,0 +1,79 @@
+// Copyright (c) 2010 The Chromium 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 "base/crypto/pbkdf2.h"
+
+#include <string>
+
+#include "base/scoped_ptr.h"
+#include "base/string_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+struct TestVector {
+ const char* password;
+ const char* salt;
+ unsigned int rounds;
+ unsigned int key_size;
+ const char* expected;
+};
+
+// These are the test vectors suggested in:
+// http://www.ietf.org/id/draft-josefsson-pbkdf2-test-vectors-00.txt
+static const TestVector test_vectors[] = {
+ {
+ "password",
+ "salt",
+ 1,
+ 20,
+ "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9"
+ "\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6",
+ },
+ {
+ "password",
+ "salt",
+ 2,
+ 20,
+ "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e"
+ "\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57",
+ },
+ {
+ "password",
+ "salt",
+ 4096,
+ 20,
+ "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad"
+ "\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1",
+ },
+ // This test takes over 30s to run on the trybots.
+#if 0
+ {
+ "password",
+ "salt",
+ 16777216,
+ 20,
+ "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94"
+ "\x5b\x3d\x6b\xa2\x15\x8c\x26\x34\xe9\x84",
+ },
+#endif
+};
+
+#if defined(USE_NSS)
+#define MAYBE_TestVectors TestVectors
+#else
+#define MAYBE_TestVectors DISABLED_TestVectors
+#endif
+TEST(PBKDF2Test, MAYBE_TestVectors) {
+ for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(test_vectors); ++i) {
+ SCOPED_TRACE(StringPrintf("Test[%u]", i));
+ scoped_ptr<base::SymmetricKey> key(base::DeriveKeyFromPassword(
+ test_vectors[i].password, test_vectors[i].salt, test_vectors[i].rounds,
+ test_vectors[i].key_size));
+ EXPECT_TRUE(NULL != key.get());
+
+ std::string raw_key;
+ key->GetRawKey(&raw_key);
+ EXPECT_EQ(test_vectors[i].key_size, raw_key.size());
+ EXPECT_STREQ(test_vectors[i].expected, raw_key.c_str());
+ }
+}
diff --git a/base/crypto/pbkdf2_win.cc b/base/crypto/pbkdf2_win.cc
new file mode 100644
index 0000000..172199b
--- /dev/null
+++ b/base/crypto/pbkdf2_win.cc
@@ -0,0 +1,17 @@
+// Copyright (c) 2010 The Chromium 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 "base/crypto/pbkdf2.h"
+
+namespace base {
+
+SymmetricKey* DeriveKeyFromPassword(const std::string& password,
+ const std::string& salt,
+ unsigned int iterations,
+ unsigned int key_size) {
+ // TODO(albertb): Implement this on Windows.
+ return NULL;
+}
+
+} // namespace base
diff --git a/base/crypto/scoped_nss_types.h b/base/crypto/scoped_nss_types.h
new file mode 100644
index 0000000..5d67ba1
--- /dev/null
+++ b/base/crypto/scoped_nss_types.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2010 The Chromium 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 BASE_SCOPED_NSS_TYPES_H_
+#define BASE_SCOPED_NSS_TYPES_H_
+
+#include <nss.h>
+#include <pk11pub.h>
+
+#include "base/scoped_ptr.h"
+
+namespace base {
+
+template <typename Type, void (*Destroyer)(Type*)>
+struct NSSDestroyer {
+ void operator()(Type* ptr) const {
+ if (ptr)
+ Destroyer(ptr);
+ }
+};
+
+template <typename Type, void (*Destroyer)(Type*, PRBool), PRBool freeit>
+struct NSSDestroyer1 {
+ void operator()(Type* ptr) const {
+ if (ptr)
+ Destroyer(ptr, freeit);
+ }
+};
+
+// Define some convenient scopers around NSS pointers.
+typedef scoped_ptr_malloc<
+ SECAlgorithmID, NSSDestroyer1<SECAlgorithmID,
+ SECOID_DestroyAlgorithmID,
+ PR_TRUE> > ScopedSECAlgorithmID;
+typedef scoped_ptr_malloc<
+ PK11Context, NSSDestroyer1<PK11Context,
+ PK11_DestroyContext,
+ PR_TRUE> > ScopedPK11Context;
+typedef scoped_ptr_malloc<
+ PK11SlotInfo, NSSDestroyer<PK11SlotInfo, PK11_FreeSlot> > ScopedPK11Slot;
+typedef scoped_ptr_malloc<
+ PK11SymKey, NSSDestroyer<PK11SymKey, PK11_FreeSymKey> > ScopedPK11SymKey;
+
+} // namespace base
+
+#endif // BASE_SCOPED_NSS_TYPES_H_
diff --git a/base/crypto/symmetric_key.h b/base/crypto/symmetric_key.h
new file mode 100644
index 0000000..c298048
--- /dev/null
+++ b/base/crypto/symmetric_key.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2010 The Chromium 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 BASE_CRYPTO_SYMMETRIC_KEY_H_
+#define BASE_CRYPTO_SYMMETRIC_KEY_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+
+#if defined(USE_NSS)
+#include "base/crypto/scoped_nss_types.h"
+#endif // USE_NSS
+
+namespace base {
+
+// Wraps a platform-specific symmetric key and allows it to be held in a
+// scoped_ptr.
+class SymmetricKey {
+ public:
+#if defined(USE_NSS)
+ explicit SymmetricKey(PK11SymKey* key) : key_(key) {}
+#endif // USE_NSS
+
+ virtual ~SymmetricKey() {}
+
+#if defined(USE_NSS)
+ PK11SymKey* key() const { return key_.get(); }
+#endif // USE_NSS
+
+ // Extracts the raw key from the platform specific data. This should only be
+ // done in unit tests to verify that keys are generated correctly.
+ bool GetRawKey(std::string* raw_key);
+
+ private:
+#if defined(USE_NSS)
+ ScopedPK11SymKey key_;
+#endif // USE_NSS
+
+ DISALLOW_COPY_AND_ASSIGN(SymmetricKey);
+};
+
+} // namespace base
+
+#endif // BASE_CRYPTO_SYMMETRIC_KEY_H_
diff --git a/base/crypto/symmetric_key_mac.cc b/base/crypto/symmetric_key_mac.cc
new file mode 100644
index 0000000..b24b434
--- /dev/null
+++ b/base/crypto/symmetric_key_mac.cc
@@ -0,0 +1,14 @@
+// Copyright (c) 2010 The Chromium 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 "base/crypto/symmetric_key.h"
+
+namespace base {
+
+bool SymmetricKey::GetRawKey(std::string* raw_key) {
+ // TODO(albertb): Implement on Mac.
+ return false;
+}
+
+} // namespace base
diff --git a/base/crypto/symmetric_key_nss.cc b/base/crypto/symmetric_key_nss.cc
new file mode 100644
index 0000000..2c6c1ac
--- /dev/null
+++ b/base/crypto/symmetric_key_nss.cc
@@ -0,0 +1,27 @@
+// Copyright (c) 2010 The Chromium 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 "base/crypto/symmetric_key.h"
+
+#include <nss.h>
+#include <pk11pub.h>
+
+#include "base/logging.h"
+
+namespace base {
+
+bool SymmetricKey::GetRawKey(std::string* raw_key) {
+ SECStatus rv = PK11_ExtractKeyValue(key_.get());
+ if (SECSuccess != rv)
+ return false;
+
+ SECItem* key_item = PK11_GetKeyData(key_.get());
+ if (!key_item)
+ return false;
+
+ raw_key->assign(reinterpret_cast<char*>(key_item->data), key_item->len);
+ return true;
+}
+
+} // namespace base
diff --git a/base/crypto/symmetric_key_win.cc b/base/crypto/symmetric_key_win.cc
new file mode 100644
index 0000000..5a302aa
--- /dev/null
+++ b/base/crypto/symmetric_key_win.cc
@@ -0,0 +1,14 @@
+// Copyright (c) 2010 The Chromium 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 "base/crypto/symmetric_key.h"
+
+namespace base {
+
+bool SymmetricKey::GetRawKey(std::string* raw_key) {
+ // TODO(albertb): Implement on Windows.
+ return false;
+}
+
+} // namespace base
diff --git a/base/hmac_nss.cc b/base/hmac_nss.cc
index d55bc64..8f63d04 100644
--- a/base/hmac_nss.cc
+++ b/base/hmac_nss.cc
@@ -7,39 +7,16 @@
#include <nss.h>
#include <pk11pub.h>
+#include "base/crypto/scoped_nss_types.h"
#include "base/logging.h"
#include "base/nss_util.h"
#include "base/scoped_ptr.h"
-namespace {
-
-template <typename Type, void (*Destroyer)(Type*)>
-struct NSSDestroyer {
- void operator()(Type* ptr) const {
- if (ptr)
- Destroyer(ptr);
- }
-};
-
-void DestroyContext(PK11Context* context) {
- PK11_DestroyContext(context, PR_TRUE);
-}
-
-// Define some convenient scopers around NSS pointers.
-typedef scoped_ptr_malloc<
- PK11SlotInfo, NSSDestroyer<PK11SlotInfo, PK11_FreeSlot> > ScopedNSSSlot;
-typedef scoped_ptr_malloc<
- PK11SymKey, NSSDestroyer<PK11SymKey, PK11_FreeSymKey> > ScopedNSSSymKey;
-typedef scoped_ptr_malloc<
- PK11Context, NSSDestroyer<PK11Context, DestroyContext> > ScopedNSSContext;
-
-} // namespace
-
namespace base {
struct HMACPlatformData {
- ScopedNSSSlot slot_;
- ScopedNSSSymKey sym_key_;
+ ScopedPK11Slot slot_;
+ ScopedPK11SymKey sym_key_;
};
HMAC::HMAC(HashAlgorithm hash_alg)
@@ -100,10 +77,10 @@ bool HMAC::Sign(const std::string& data,
}
SECItem param = { siBuffer, NULL, 0 };
- ScopedNSSContext context(PK11_CreateContextBySymKey(CKM_SHA_1_HMAC,
- CKA_SIGN,
- plat_->sym_key_.get(),
- &param));
+ ScopedPK11Context context(PK11_CreateContextBySymKey(CKM_SHA_1_HMAC,
+ CKA_SIGN,
+ plat_->sym_key_.get(),
+ &param));
if (!context.get()) {
NOTREACHED();
return false;
diff --git a/base/nss_util.h b/base/nss_util.h
index f766228..5c8e0f6 100644
--- a/base/nss_util.h
+++ b/base/nss_util.h
@@ -7,6 +7,9 @@
#include "base/basictypes.h"
+// This file specifically doesn't depend on any NSS or NSPR headers because it
+// is included by various (non-crypto) parts of chrome to call the
+// initialization functions.
namespace base {
class Time;