diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-14 17:37:14 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-14 17:37:14 +0000 |
commit | 4b559b4ddffc0b7f688019bcb80658f05e063af7 (patch) | |
tree | 0be21d8914de707f5125d2cb66733cbcf088606c /base | |
parent | 056dd45d610de34312344445d7b078a31f4a1e20 (diff) | |
download | chromium_src-4b559b4ddffc0b7f688019bcb80658f05e063af7.zip chromium_src-4b559b4ddffc0b7f688019bcb80658f05e063af7.tar.gz chromium_src-4b559b4ddffc0b7f688019bcb80658f05e063af7.tar.bz2 |
Move crypto files out of base, to a top level directory.
src/crypto is now an independent project that contains our
cryptographic primitives (except md5 and sha1).
This removes the base dependency from nss, openssl and sqlite.
BUG=76996
TEST=none
Review URL: http://codereview.chromium.org/6805019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81611 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
69 files changed, 4 insertions, 9711 deletions
diff --git a/base/base.gyp b/base/base.gyp index 183749e..37b197d 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -112,13 +112,6 @@ 'callback_unittest.cc', 'command_line_unittest.cc', 'cpu_unittest.cc', - 'crypto/encryptor_unittest.cc', - 'crypto/rsa_private_key_unittest.cc', - 'crypto/rsa_private_key_nss_unittest.cc', - 'crypto/secure_hash_unittest.cc', - 'crypto/signature_creator_unittest.cc', - 'crypto/signature_verifier_unittest.cc', - 'crypto/symmetric_key_unittest.cc', 'debug/leak_tracker_unittest.cc', 'debug/stack_trace_unittest.cc', 'debug/trace_event_win_unittest.cc', @@ -129,7 +122,6 @@ 'file_util_unittest.cc', 'file_version_info_unittest.cc', 'gmock_unittest.cc', - 'hmac_unittest.cc', 'id_map_unittest.cc', 'i18n/break_iterator_unittest.cc', 'i18n/char_iterator_unittest.cc', @@ -167,7 +159,6 @@ 'process_util_unittest_mac.mm', 'rand_util_unittest.cc', 'sha1_unittest.cc', - 'sha2_unittest.cc', 'shared_memory_unittest.cc', 'stack_container_unittest.cc', 'string16_unittest.cc', @@ -256,7 +247,6 @@ }, { # OS != "linux" and OS != "freebsd" and OS != "openbsd" and OS != "solaris" 'sources!': [ 'message_pump_glib_unittest.cc', - 'crypto/rsa_private_key_nss_unittest.cc', ] }], # This is needed to trigger the dll copy step on windows. @@ -281,11 +271,6 @@ 'win_util_unittest.cc', ], }], - [ 'use_openssl==1', { - 'sources!': [ - 'crypto/rsa_private_key_nss_unittest.cc', - ], - }], ], }, { diff --git a/base/base.gypi b/base/base.gypi index 4f409ab..8e49dd5 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -456,22 +456,6 @@ }, }, ], - [ 'use_openssl==1', { - 'dependencies': [ - '../third_party/openssl/openssl.gyp:openssl', - ], - }, { # use_openssl==0 - 'sources': [ - 'base/crypto/scoped_nss_types.h', - ], - 'dependencies': [ - '../build/linux/system.gyp:nss', - ], - 'export_dependent_settings': [ - '../build/linux/system.gyp:nss', - ], - } - ], ], 'dependencies': [ 'symbolize', @@ -525,27 +509,13 @@ '$(SDKROOT)/System/Library/Frameworks/Security.framework', ], }, - }, { # OS != "mac" - 'sources!': [ - 'crypto/cssm_init.cc', - 'crypto/cssm_init.h', - 'crypto/mac_security_services_lock.cc', - 'crypto/mac_security_services_lock.h', - ], }], - [ 'OS == "mac" or OS == "win"', { - 'dependencies': [ - '../third_party/nss/nss.gyp:nss', - ], - },], [ 'OS != "win"', { 'dependencies': ['../third_party/libevent/libevent.gyp:libevent'], 'sources!': [ 'third_party/purify/pure_api.c', 'base_drag_source.cc', 'base_drop_target.cc', - 'crypto/capi_util.h', - 'crypto/capi_util.cc', 'event_recorder.cc', 'file_version_info.cc', 'registry.cc', @@ -553,82 +523,11 @@ 'win_util.cc', ], },], - [ 'use_openssl==1', { - # TODO(joth): Use a glob to match exclude patterns once the - # OpenSSL file set is complete. - 'sources!': [ - 'crypto/encryptor_nss.cc', - 'crypto/rsa_private_key_nss.cc', - 'crypto/secure_hash_default.cc', - 'crypto/signature_creator_nss.cc', - 'crypto/signature_verifier_nss.cc', - 'crypto/symmetric_key_nss.cc', - 'hmac_nss.cc', - 'nss_util.cc', - 'nss_util.h', - 'third_party/nss/blapi.h', - 'third_party/nss/blapit.h', - 'third_party/nss/sha256.h', - 'third_party/nss/sha512.cc', - ], - }, { - 'sources!': [ - 'crypto/encryptor_openssl.cc', - 'crypto/rsa_private_key_openssl.cc', - 'crypto/secure_hash_openssl.cc', - 'crypto/signature_creator_openssl.cc', - 'crypto/signature_verifier_openssl.cc', - 'crypto/symmetric_key_openssl.cc', - 'hmac_openssl.cc', - 'openssl_util.cc', - 'openssl_util.h', - ], - },], ], 'sources': [ - 'crypto/capi_util.cc', - 'crypto/capi_util.h', - 'crypto/crypto_module_blocking_password_delegate.h', - 'crypto/cssm_init.cc', - 'crypto/cssm_init.h', - 'crypto/encryptor.h', - 'crypto/encryptor_mac.cc', - 'crypto/encryptor_nss.cc', - 'crypto/encryptor_openssl.cc', - 'crypto/encryptor_win.cc', - 'crypto/mac_security_services_lock.cc', - 'crypto/mac_security_services_lock.h', - 'crypto/rsa_private_key.h', - 'crypto/rsa_private_key.cc', - 'crypto/rsa_private_key_mac.cc', - 'crypto/rsa_private_key_nss.cc', - 'crypto/rsa_private_key_openssl.cc', - 'crypto/rsa_private_key_win.cc', - 'crypto/secure_hash.h', - 'crypto/secure_hash_default.cc', - 'crypto/secure_hash_openssl.cc', - 'crypto/signature_creator.h', - 'crypto/signature_creator_mac.cc', - 'crypto/signature_creator_nss.cc', - 'crypto/signature_creator_openssl.cc', - 'crypto/signature_creator_win.cc', - 'crypto/signature_verifier.h', - 'crypto/signature_verifier_mac.cc', - 'crypto/signature_verifier_nss.cc', - 'crypto/signature_verifier_openssl.cc', - 'crypto/signature_verifier_win.cc', - 'crypto/symmetric_key.h', - 'crypto/symmetric_key_mac.cc', - 'crypto/symmetric_key_nss.cc', - 'crypto/symmetric_key_openssl.cc', - 'crypto/symmetric_key_win.cc', 'third_party/nspr/prcpucfg.h', 'third_party/nspr/prcpucfg_win.h', 'third_party/nspr/prtypes.h', - 'third_party/nss/blapi.h', - 'third_party/nss/blapit.h', - 'third_party/nss/sha256.h', - 'third_party/nss/sha512.cc', 'third_party/purify/pure.h', 'third_party/purify/pure_api.c', 'third_party/xdg_user_dirs/xdg_user_dir_lookup.cc', @@ -641,11 +540,6 @@ 'event_recorder_stubs.cc', 'file_descriptor_shuffle.cc', 'file_descriptor_shuffle.h', - 'hmac.h', - 'hmac_mac.cc', - 'hmac_nss.cc', - 'hmac_openssl.cc', - 'hmac_win.cc', 'linux_util.cc', 'linux_util.h', 'md5.cc', @@ -661,12 +555,6 @@ 'message_pump_mac.mm', 'metrics/field_trial.cc', 'metrics/field_trial.h', - 'nss_util.cc', - 'nss_util.h', - 'openssl_util.cc', - 'openssl_util.h', - 'sha2.cc', - 'sha2.h', 'string16.cc', 'string16.h', 'sync_socket.h', diff --git a/base/crypto/capi_util.cc b/base/crypto/capi_util.cc deleted file mode 100644 index 1828afd..0000000 --- a/base/crypto/capi_util.cc +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2011 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/capi_util.h" - -#include "base/basictypes.h" -#include "base/memory/singleton.h" -#include "base/synchronization/lock.h" - -namespace { - -class CAPIUtilSingleton { - public: - static CAPIUtilSingleton* GetInstance() { - return Singleton<CAPIUtilSingleton>::get(); - } - - // Returns a lock to guard calls to CryptAcquireContext with - // CRYPT_DELETEKEYSET or CRYPT_NEWKEYSET. - base::Lock& acquire_context_lock() { - return acquire_context_lock_; - } - - private: - friend class Singleton<CAPIUtilSingleton>; - friend struct DefaultSingletonTraits<CAPIUtilSingleton>; - - CAPIUtilSingleton() {} - - base::Lock acquire_context_lock_; - - DISALLOW_COPY_AND_ASSIGN(CAPIUtilSingleton); -}; - -} // namespace - -namespace base { - -BOOL CryptAcquireContextLocked(HCRYPTPROV* prov, - LPCWSTR container, - LPCWSTR provider, - DWORD prov_type, - DWORD flags) -{ - base::AutoLock lock(CAPIUtilSingleton::GetInstance()->acquire_context_lock()); - return CryptAcquireContext(prov, container, provider, prov_type, flags); -} - -} // namespace base diff --git a/base/crypto/capi_util.h b/base/crypto/capi_util.h deleted file mode 100644 index f4b7e68..0000000 --- a/base/crypto/capi_util.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2011 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_CAPI_UTIL_H_ -#define BASE_CRYPTO_CAPI_UTIL_H_ -#pragma once - -#include <windows.h> -#include <wincrypt.h> - -#include "base/base_api.h" - -namespace base { - -// CryptAcquireContext when passed CRYPT_NEWKEYSET or CRYPT_DELETEKEYSET in -// flags is not thread-safe. For such calls, we create a global lock to -// synchronize it. -// -// From "Threading Issues with Cryptographic Service Providers", -// <http://msdn.microsoft.com/en-us/library/aa388149(v=VS.85).aspx>: -// -// "The CryptAcquireContext function is generally thread safe unless -// CRYPT_NEWKEYSET or CRYPT_DELETEKEYSET is specified in the dwFlags -// parameter." -BASE_API BOOL CryptAcquireContextLocked(HCRYPTPROV* prov, - LPCWSTR container, - LPCWSTR provider, - DWORD prov_type, - DWORD flags); - -} // namespace base - -#endif // BASE_CRYPTO_CAPI_UTIL_H_ diff --git a/base/crypto/crypto_module_blocking_password_delegate.h b/base/crypto/crypto_module_blocking_password_delegate.h deleted file mode 100644 index ae962a8..0000000 --- a/base/crypto/crypto_module_blocking_password_delegate.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2011 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_CRYPTO_MODULE_BLOCKING_PASSWORD_DELEGATE_H_ -#define BASE_CRYPTO_CRYPTO_MODULE_BLOCKING_PASSWORD_DELEGATE_H_ -#pragma once - -#include <string> - -namespace base { - -// PK11_SetPasswordFunc is a global setting. An implementation of -// CryptoModuleBlockingPasswordDelegate should be passed as the user data -// argument (|wincx|) to relevant NSS functions, which the global password -// handler will call to do the actual work. -class CryptoModuleBlockingPasswordDelegate { - public: - virtual ~CryptoModuleBlockingPasswordDelegate() {} - - // Requests a password to unlock |slot_name|. The interface is - // synchronous because NSS cannot issue an asynchronous - // request. |retry| is true if this is a request for the retry - // and we previously returned the wrong password. - // The implementation should set |*cancelled| to true if the user cancelled - // instead of entering a password, otherwise it should return the password the - // user entered. - virtual std::string RequestPassword(const std::string& slot_name, bool retry, - bool* cancelled) = 0; -}; - -} - -#endif // BASE_CRYPTO_CRYPTO_MODULE_BLOCKING_PASSWORD_DELEGATE_H_ diff --git a/base/crypto/cssm_init.cc b/base/crypto/cssm_init.cc deleted file mode 100644 index ccd6993..0000000 --- a/base/crypto/cssm_init.cc +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright (c) 2011 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/cssm_init.h" - -#include <Security/SecBase.h> - -#include "base/logging.h" -#include "base/mac/scoped_cftyperef.h" -#include "base/memory/singleton.h" -#include "base/sys_string_conversions.h" - -// When writing crypto code for Mac OS X, you may find the following -// documentation useful: -// - Common Security: CDSA and CSSM, Version 2 (with corrigenda) -// http://www.opengroup.org/security/cdsa.htm -// - Apple Cryptographic Service Provider Functional Specification -// - CryptoSample: http://developer.apple.com/SampleCode/CryptoSample/ - -namespace { - -void* CSSMMalloc(CSSM_SIZE size, void* alloc_ref) { - return malloc(size); -} - -void CSSMFree(void* mem_ptr, void* alloc_ref) { - free(mem_ptr); -} - -void* CSSMRealloc(void* ptr, CSSM_SIZE size, void* alloc_ref) { - return realloc(ptr, size); -} - -void* CSSMCalloc(uint32 num, CSSM_SIZE size, void* alloc_ref) { - return calloc(num, size); -} - -class CSSMInitSingleton { - public: - static CSSMInitSingleton* GetInstance() { - return Singleton<CSSMInitSingleton, - LeakySingletonTraits<CSSMInitSingleton> >::get(); - } - - CSSM_CSP_HANDLE csp_handle() const { return csp_handle_; } - CSSM_CL_HANDLE cl_handle() const { return cl_handle_; } - CSSM_TP_HANDLE tp_handle() const { return tp_handle_; } - - private: - CSSMInitSingleton() - : inited_(false), csp_loaded_(false), cl_loaded_(false), - tp_loaded_(false), csp_handle_(NULL), cl_handle_(NULL), - tp_handle_(NULL) { - static CSSM_VERSION version = {2, 0}; - // TODO(wtc): what should our caller GUID be? - static const CSSM_GUID test_guid = { - 0xFADE, 0, 0, { 1, 2, 3, 4, 5, 6, 7, 0 } - }; - CSSM_RETURN crtn; - CSSM_PVC_MODE pvc_policy = CSSM_PVC_NONE; - crtn = CSSM_Init(&version, CSSM_PRIVILEGE_SCOPE_NONE, &test_guid, - CSSM_KEY_HIERARCHY_NONE, &pvc_policy, NULL); - if (crtn) { - NOTREACHED(); - return; - } - inited_ = true; - - crtn = CSSM_ModuleLoad(&gGuidAppleCSP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); - if (crtn) { - NOTREACHED(); - return; - } - csp_loaded_ = true; - crtn = CSSM_ModuleLoad( - &gGuidAppleX509CL, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); - if (crtn) { - NOTREACHED(); - return; - } - cl_loaded_ = true; - crtn = CSSM_ModuleLoad( - &gGuidAppleX509TP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); - if (crtn) { - NOTREACHED(); - return; - } - tp_loaded_ = true; - - const CSSM_API_MEMORY_FUNCS cssmMemoryFunctions = { - CSSMMalloc, - CSSMFree, - CSSMRealloc, - CSSMCalloc, - NULL - }; - - crtn = CSSM_ModuleAttach(&gGuidAppleCSP, &version, &cssmMemoryFunctions, 0, - CSSM_SERVICE_CSP, 0, CSSM_KEY_HIERARCHY_NONE, - NULL, 0, NULL, &csp_handle_); - DCHECK(crtn == CSSM_OK); - crtn = CSSM_ModuleAttach(&gGuidAppleX509CL, &version, &cssmMemoryFunctions, - 0, CSSM_SERVICE_CL, 0, CSSM_KEY_HIERARCHY_NONE, - NULL, 0, NULL, &cl_handle_); - DCHECK(crtn == CSSM_OK); - crtn = CSSM_ModuleAttach(&gGuidAppleX509TP, &version, &cssmMemoryFunctions, - 0, CSSM_SERVICE_TP, 0, CSSM_KEY_HIERARCHY_NONE, - NULL, 0, NULL, &tp_handle_); - DCHECK(crtn == CSSM_OK); - } - - ~CSSMInitSingleton() { - CSSM_RETURN crtn; - if (csp_handle_) { - CSSM_RETURN crtn = CSSM_ModuleDetach(csp_handle_); - DCHECK(crtn == CSSM_OK); - } - if (cl_handle_) { - CSSM_RETURN crtn = CSSM_ModuleDetach(cl_handle_); - DCHECK(crtn == CSSM_OK); - } - if (tp_handle_) { - CSSM_RETURN crtn = CSSM_ModuleDetach(tp_handle_); - DCHECK(crtn == CSSM_OK); - } - if (csp_loaded_) { - crtn = CSSM_ModuleUnload(&gGuidAppleCSP, NULL, NULL); - DCHECK(crtn == CSSM_OK); - } - if (cl_loaded_) { - crtn = CSSM_ModuleUnload(&gGuidAppleX509CL, NULL, NULL); - DCHECK(crtn == CSSM_OK); - } - if (tp_loaded_) { - crtn = CSSM_ModuleUnload(&gGuidAppleX509TP, NULL, NULL); - DCHECK(crtn == CSSM_OK); - } - if (inited_) { - crtn = CSSM_Terminate(); - DCHECK(crtn == CSSM_OK); - } - } - - bool inited_; // True if CSSM_Init has been called successfully. - bool csp_loaded_; // True if gGuidAppleCSP has been loaded - bool cl_loaded_; // True if gGuidAppleX509CL has been loaded. - bool tp_loaded_; // True if gGuidAppleX509TP has been loaded. - CSSM_CSP_HANDLE csp_handle_; - CSSM_CL_HANDLE cl_handle_; - CSSM_TP_HANDLE tp_handle_; - - friend struct DefaultSingletonTraits<CSSMInitSingleton>; -}; - -} // namespace - -namespace base { - -void EnsureCSSMInit() { - CSSMInitSingleton::GetInstance(); -} - -CSSM_CSP_HANDLE GetSharedCSPHandle() { - return CSSMInitSingleton::GetInstance()->csp_handle(); -} - -CSSM_CL_HANDLE GetSharedCLHandle() { - return CSSMInitSingleton::GetInstance()->cl_handle(); -} - -CSSM_TP_HANDLE GetSharedTPHandle() { - return CSSMInitSingleton::GetInstance()->tp_handle(); -} - -void* CSSMMalloc(CSSM_SIZE size) { - return ::CSSMMalloc(size, NULL); -} - -void CSSMFree(void* ptr) { - ::CSSMFree(ptr, NULL); -} - -void LogCSSMError(const char* fn_name, CSSM_RETURN err) { - if (!err) - return; - base::mac::ScopedCFTypeRef<CFStringRef> cfstr( - SecCopyErrorMessageString(err, NULL)); - LOG(ERROR) << fn_name << " returned " << err - << " (" << SysCFStringRefToUTF8(cfstr) << ")"; -} - -ScopedCSSMData::ScopedCSSMData() { - memset(&data_, 0, sizeof(data_)); -} - -ScopedCSSMData::~ScopedCSSMData() { - if (data_.Data) { - CSSMFree(data_.Data); - data_.Data = NULL; - } -} - -} // namespace base diff --git a/base/crypto/cssm_init.h b/base/crypto/cssm_init.h deleted file mode 100644 index bce5954..0000000 --- a/base/crypto/cssm_init.h +++ /dev/null @@ -1,60 +0,0 @@ -// 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_CSSM_INIT_H_ -#define BASE_CRYPTO_CSSM_INIT_H_ -#pragma once - -#include <Security/cssm.h> - -#include "base/basictypes.h" - -namespace base { - -// Initialize CSSM if it isn't already initialized. This must be called before -// any other CSSM functions. This function is thread-safe, and CSSM will only -// ever be initialized once. CSSM will be properly shut down on program exit. -void EnsureCSSMInit(); - -// Returns the shared CSP handle used by CSSM functions. -CSSM_CSP_HANDLE GetSharedCSPHandle(); - -// Returns the shared CL handle used by CSSM functions. -CSSM_CL_HANDLE GetSharedCLHandle(); - -// Returns the shared TP handle used by CSSM functions. -CSSM_TP_HANDLE GetSharedTPHandle(); - -// Set of pointers to memory function wrappers that are required for CSSM -extern const CSSM_API_MEMORY_FUNCS kCssmMemoryFunctions; - -// Utility function to log an error message including the error name. -void LogCSSMError(const char *function_name, CSSM_RETURN err); - -// Utility functions to allocate and release CSSM memory. -void* CSSMMalloc(CSSM_SIZE size); -void CSSMFree(void* ptr); - -// Wrapper class for CSSM_DATA type. This should only be used when using the -// CL/TP/CSP handles from above, since that's the only time we're guaranteed (or -// supposed to be guaranteed) that our memory management functions will be used. -// Apple's Sec* APIs manage their own memory so it shouldn't be used for those. -// The constructor initializes data_ to zero and the destructor releases the -// data properly. -class ScopedCSSMData { - public: - ScopedCSSMData(); - ~ScopedCSSMData(); - operator CSSM_DATA*() { return &data_; } - CSSM_DATA* operator ->() { return &data_; } - - private: - CSSM_DATA data_; - - DISALLOW_COPY_AND_ASSIGN(ScopedCSSMData); -}; - -} // namespace base - -#endif // BASE_CRYPTO_CSSM_INIT_H_ diff --git a/base/crypto/encryptor.h b/base/crypto/encryptor.h deleted file mode 100644 index 360a333..0000000 --- a/base/crypto/encryptor.h +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2011 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_ENCRYPTOR_H_ -#define BASE_CRYPTO_ENCRYPTOR_H_ -#pragma once - -#include <string> - -#include "base/base_api.h" -#include "build/build_config.h" - -#if defined(USE_NSS) -#include "base/crypto/scoped_nss_types.h" -#elif defined(OS_WIN) -#include "base/crypto/scoped_capi_types.h" -#endif - -namespace base { - -class SymmetricKey; - -class BASE_API Encryptor { - public: - enum Mode { - CBC - }; - Encryptor(); - virtual ~Encryptor(); - - // Initializes the encryptor using |key| and |iv|. Returns false if either the - // key or the initialization vector cannot be used. - bool Init(SymmetricKey* key, Mode mode, const std::string& iv); - - // Encrypts |plaintext| into |ciphertext|. - bool Encrypt(const std::string& plaintext, std::string* ciphertext); - - // Decrypts |ciphertext| into |plaintext|. - bool Decrypt(const std::string& ciphertext, std::string* plaintext); - - // TODO(albertb): Support streaming encryption. - - private: - SymmetricKey* key_; - Mode mode_; - -#if defined(USE_OPENSSL) - bool Crypt(bool encrypt, // Pass true to encrypt, false to decrypt. - const std::string& input, - std::string* output); - std::string iv_; -#elif defined(USE_NSS) - ScopedPK11Slot slot_; - ScopedSECItem param_; -#elif defined(OS_MACOSX) - bool Crypt(int /*CCOperation*/ op, - const std::string& input, - std::string* output); - - std::string iv_; -#elif defined(OS_WIN) - ScopedHCRYPTKEY capi_key_; - DWORD block_size_; -#endif -}; - -} // namespace base - -#endif // BASE_CRYPTO_ENCRYPTOR_H_ diff --git a/base/crypto/encryptor_mac.cc b/base/crypto/encryptor_mac.cc deleted file mode 100644 index e26c6bd7..0000000 --- a/base/crypto/encryptor_mac.cc +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2011 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/encryptor.h" - -#include <CommonCrypto/CommonCryptor.h> - -#include "base/crypto/symmetric_key.h" -#include "base/logging.h" -#include "base/string_util.h" - -namespace base { - -Encryptor::Encryptor() - : key_(NULL), - mode_(CBC) { -} - -Encryptor::~Encryptor() { -} - -bool Encryptor::Init(SymmetricKey* key, Mode mode, const std::string& iv) { - DCHECK(key); - DCHECK_EQ(CBC, mode) << "Unsupported mode of operation"; - CSSM_DATA raw_key = key->cssm_data(); - if (raw_key.Length != kCCKeySizeAES128 && - raw_key.Length != kCCKeySizeAES192 && - raw_key.Length != kCCKeySizeAES256) - return false; - if (iv.size() != kCCBlockSizeAES128) - return false; - - key_ = key; - mode_ = mode; - iv_ = iv; - return true; -} - -bool Encryptor::Crypt(int /*CCOperation*/ op, - const std::string& input, - std::string* output) { - DCHECK(key_); - CSSM_DATA raw_key = key_->cssm_data(); - // CommonCryptor.h: "A general rule for the size of the output buffer which - // must be provided by the caller is that for block ciphers, the output - // length is never larger than the input length plus the block size." - - size_t output_size = input.size() + iv_.size(); - CCCryptorStatus err = CCCrypt(op, - kCCAlgorithmAES128, - kCCOptionPKCS7Padding, - raw_key.Data, raw_key.Length, - iv_.data(), - input.data(), input.size(), - WriteInto(output, output_size+1), - output_size, - &output_size); - if (err) { - output->resize(0); - LOG(ERROR) << "CCCrypt returned " << err; - return false; - } - output->resize(output_size); - return true; -} - -bool Encryptor::Encrypt(const std::string& plaintext, std::string* ciphertext) { - return Crypt(kCCEncrypt, plaintext, ciphertext); -} - -bool Encryptor::Decrypt(const std::string& ciphertext, std::string* plaintext) { - return Crypt(kCCDecrypt, ciphertext, plaintext); -} - -} // namespace base diff --git a/base/crypto/encryptor_nss.cc b/base/crypto/encryptor_nss.cc deleted file mode 100644 index 3b9f7f3..0000000 --- a/base/crypto/encryptor_nss.cc +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2011 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/encryptor.h" - -#include <cryptohi.h> -#include <vector> - -#include "base/crypto/symmetric_key.h" -#include "base/logging.h" -#include "base/nss_util.h" - -namespace base { - -Encryptor::Encryptor() - : key_(NULL), - mode_(CBC) { - EnsureNSSInit(); -} - -Encryptor::~Encryptor() { -} - -bool Encryptor::Init(SymmetricKey* key, Mode mode, const std::string& iv) { - DCHECK(key); - DCHECK_EQ(CBC, mode); - - key_ = key; - mode_ = mode; - - if (iv.size() != AES_BLOCK_SIZE) - return false; - - slot_.reset(PK11_GetBestSlot(CKM_AES_CBC_PAD, NULL)); - if (!slot_.get()) - return false; - - SECItem iv_item; - iv_item.type = siBuffer; - iv_item.data = reinterpret_cast<unsigned char*>( - const_cast<char *>(iv.data())); - iv_item.len = iv.size(); - - param_.reset(PK11_ParamFromIV(CKM_AES_CBC_PAD, &iv_item)); - if (!param_.get()) - return false; - - return true; -} - -bool Encryptor::Encrypt(const std::string& plaintext, std::string* ciphertext) { - ScopedPK11Context context(PK11_CreateContextBySymKey(CKM_AES_CBC_PAD, - CKA_ENCRYPT, - key_->key(), - param_.get())); - if (!context.get()) - return false; - - size_t ciphertext_len = plaintext.size() + AES_BLOCK_SIZE; - std::vector<unsigned char> buffer(ciphertext_len); - - int op_len; - SECStatus rv = PK11_CipherOp(context.get(), - &buffer[0], - &op_len, - ciphertext_len, - reinterpret_cast<unsigned char*>( - const_cast<char*>(plaintext.data())), - plaintext.size()); - if (SECSuccess != rv) - return false; - - unsigned int digest_len; - rv = PK11_DigestFinal(context.get(), - &buffer[op_len], - &digest_len, - ciphertext_len - op_len); - if (SECSuccess != rv) - return false; - - ciphertext->assign(reinterpret_cast<char *>(&buffer[0]), - op_len + digest_len); - return true; -} - -bool Encryptor::Decrypt(const std::string& ciphertext, std::string* plaintext) { - if (ciphertext.empty()) - return false; - - ScopedPK11Context context(PK11_CreateContextBySymKey(CKM_AES_CBC_PAD, - CKA_DECRYPT, - key_->key(), - param_.get())); - if (!context.get()) - return false; - - size_t plaintext_len = ciphertext.size(); - std::vector<unsigned char> buffer(plaintext_len); - - int op_len; - SECStatus rv = PK11_CipherOp(context.get(), - &buffer[0], - &op_len, - plaintext_len, - reinterpret_cast<unsigned char*>( - const_cast<char*>(ciphertext.data())), - ciphertext.size()); - if (SECSuccess != rv) - return false; - - unsigned int digest_len; - rv = PK11_DigestFinal(context.get(), - &buffer[op_len], - &digest_len, - plaintext_len - op_len); - if (SECSuccess != rv) - return false; - - plaintext->assign(reinterpret_cast<char *>(&buffer[0]), - op_len + digest_len); - return true; -} - -} // namespace base diff --git a/base/crypto/encryptor_openssl.cc b/base/crypto/encryptor_openssl.cc deleted file mode 100644 index 0e101a0..0000000 --- a/base/crypto/encryptor_openssl.cc +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 2011 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/encryptor.h" - -#include <openssl/aes.h> -#include <openssl/evp.h> - -#include "base/crypto/symmetric_key.h" -#include "base/logging.h" -#include "base/openssl_util.h" -#include "base/string_util.h" - -namespace base { - -namespace { - -const EVP_CIPHER* GetCipherForKey(SymmetricKey* key) { - switch (key->key().length()) { - case 16: return EVP_aes_128_cbc(); - case 24: return EVP_aes_192_cbc(); - case 32: return EVP_aes_256_cbc(); - default: return NULL; - } -} - -// On destruction this class will cleanup the ctx, and also clear the OpenSSL -// ERR stack as a convenience. -class ScopedCipherCTX { - public: - explicit ScopedCipherCTX() { - EVP_CIPHER_CTX_init(&ctx_); - } - ~ScopedCipherCTX() { - EVP_CIPHER_CTX_cleanup(&ctx_); - ClearOpenSSLERRStack(FROM_HERE); - } - EVP_CIPHER_CTX* get() { return &ctx_; } - - private: - EVP_CIPHER_CTX ctx_; -}; - -} // namespace - -Encryptor::Encryptor() - : key_(NULL), - mode_(CBC) { -} - -Encryptor::~Encryptor() { -} - -bool Encryptor::Init(SymmetricKey* key, Mode mode, const std::string& iv) { - DCHECK(key); - DCHECK_EQ(CBC, mode); - - EnsureOpenSSLInit(); - if (iv.size() != AES_BLOCK_SIZE) - return false; - - if (GetCipherForKey(key) == NULL) - return false; - - key_ = key; - mode_ = mode; - iv_ = iv; - return true; -} - -bool Encryptor::Encrypt(const std::string& plaintext, std::string* ciphertext) { - return Crypt(true, plaintext, ciphertext); -} - -bool Encryptor::Decrypt(const std::string& ciphertext, std::string* plaintext) { - return Crypt(false, ciphertext, plaintext); -} - -bool Encryptor::Crypt(bool do_encrypt, - const std::string& input, - std::string* output) { - DCHECK(key_); // Must call Init() before En/De-crypt. - // Work on the result in a local variable, and then only transfer it to - // |output| on success to ensure no partial data is returned. - std::string result; - output->swap(result); - - const EVP_CIPHER* cipher = GetCipherForKey(key_); - DCHECK(cipher); // Already handled in Init(); - - const std::string& key = key_->key(); - DCHECK_EQ(EVP_CIPHER_iv_length(cipher), static_cast<int>(iv_.length())); - DCHECK_EQ(EVP_CIPHER_key_length(cipher), static_cast<int>(key.length())); - - ScopedCipherCTX ctx; - if (!EVP_CipherInit_ex(ctx.get(), cipher, NULL, - reinterpret_cast<const uint8*>(key.data()), - reinterpret_cast<const uint8*>(iv_.data()), - do_encrypt)) - return false; - - // When encrypting, add another block size of space to allow for any padding. - const size_t output_size = input.size() + (do_encrypt ? iv_.size() : 0); - uint8* out_ptr = reinterpret_cast<uint8*>(WriteInto(&result, - output_size + 1)); - int out_len; - if (!EVP_CipherUpdate(ctx.get(), out_ptr, &out_len, - reinterpret_cast<const uint8*>(input.data()), - input.length())) - return false; - - // Write out the final block plus padding (if any) to the end of the data - // just written. - int tail_len; - if (!EVP_CipherFinal_ex(ctx.get(), out_ptr + out_len, &tail_len)) - return false; - - out_len += tail_len; - DCHECK_LE(out_len, static_cast<int>(output_size)); - result.resize(out_len); - - output->swap(result); - return true; -} - -} // namespace base diff --git a/base/crypto/encryptor_unittest.cc b/base/crypto/encryptor_unittest.cc deleted file mode 100644 index 5060b2a..0000000 --- a/base/crypto/encryptor_unittest.cc +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) 2011 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/encryptor.h" - -#include <string> - -#include "base/crypto/symmetric_key.h" -#include "base/memory/scoped_ptr.h" -#include "base/string_number_conversions.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(EncryptorTest, EncryptDecrypt) { - scoped_ptr<base::SymmetricKey> key(base::SymmetricKey::DeriveKeyFromPassword( - base::SymmetricKey::AES, "password", "saltiest", 1000, 256)); - EXPECT_TRUE(NULL != key.get()); - - base::Encryptor encryptor; - // The IV must be exactly as long as the cipher block size. - std::string iv("the iv: 16 bytes"); - EXPECT_EQ(16U, iv.size()); - EXPECT_TRUE(encryptor.Init(key.get(), base::Encryptor::CBC, iv)); - - std::string plaintext("this is the plaintext"); - std::string ciphertext; - EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext)); - - EXPECT_LT(0U, ciphertext.size()); - - std::string decypted; - EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted)); - - EXPECT_EQ(plaintext, decypted); -} - -// TODO(wtc): add more known-answer tests. Test vectors are available from -// http://www.ietf.org/rfc/rfc3602 -// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf -// http://gladman.plushost.co.uk/oldsite/AES/index.php -// http://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip - -// NIST SP 800-38A test vector F.2.5 CBC-AES256.Encrypt. -TEST(EncryptorTest, EncryptAES256CBC) { - // From NIST SP 800-38a test cast F.2.5 CBC-AES256.Encrypt. - static const unsigned char raw_key[] = { - 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, - 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, - 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, - 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 - }; - static const unsigned char raw_iv[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f - }; - static const unsigned char raw_plaintext[] = { - // Block #1 - 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, - 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - // Block #2 - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, - 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - // Block #3 - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, - 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, - // Block #4 - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, - 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, - }; - static const unsigned char raw_ciphertext[] = { - // Block #1 - 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, - 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6, - // Block #2 - 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d, - 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d, - // Block #3 - 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf, - 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61, - // Block #4 - 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc, - 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b, - // PKCS #5 padding, encrypted. - 0x3f, 0x46, 0x17, 0x96, 0xd6, 0xb0, 0xd6, 0xb2, - 0xe0, 0xc2, 0xa7, 0x2b, 0x4d, 0x80, 0xe6, 0x44 - }; - - std::string key(reinterpret_cast<const char*>(raw_key), sizeof(raw_key)); - scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import( - base::SymmetricKey::AES, key)); - ASSERT_TRUE(NULL != sym_key.get()); - - base::Encryptor encryptor; - // The IV must be exactly as long a the cipher block size. - std::string iv(reinterpret_cast<const char*>(raw_iv), sizeof(raw_iv)); - EXPECT_EQ(16U, iv.size()); - EXPECT_TRUE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv)); - - std::string plaintext(reinterpret_cast<const char*>(raw_plaintext), - sizeof(raw_plaintext)); - std::string ciphertext; - EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext)); - - EXPECT_EQ(sizeof(raw_ciphertext), ciphertext.size()); - EXPECT_EQ(0, memcmp(ciphertext.data(), raw_ciphertext, ciphertext.size())); - - std::string decypted; - EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted)); - - EXPECT_EQ(plaintext, decypted); -} - -// Expected output derived from the NSS implementation. -TEST(EncryptorTest, EncryptAES128CBCRegression) { - std::string key = "128=SixteenBytes"; - std::string iv = "Sweet Sixteen IV"; - std::string plaintext = "Plain text with a g-clef U+1D11E \360\235\204\236"; - std::string expected_ciphertext_hex = - "D4A67A0BA33C30F207344D81D1E944BBE65587C3D7D9939A" - "C070C62B9C15A3EA312EA4AD1BC7929F4D3C16B03AD5ADA8"; - - scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import( - base::SymmetricKey::AES, key)); - ASSERT_TRUE(NULL != sym_key.get()); - - base::Encryptor encryptor; - // The IV must be exactly as long a the cipher block size. - EXPECT_EQ(16U, iv.size()); - EXPECT_TRUE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv)); - - std::string ciphertext; - EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext)); - EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(), - ciphertext.size())); - - std::string decypted; - EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted)); - EXPECT_EQ(plaintext, decypted); -} - -// Expected output derived from the NSS implementation. -TEST(EncryptorTest, EncryptAES192CBCRegression) { - std::string key = "192bitsIsTwentyFourByte!"; - std::string iv = "Sweet Sixteen IV"; - std::string plaintext = "Small text"; - std::string expected_ciphertext_hex = "78DE5D7C2714FC5C61346C5416F6C89A"; - - scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import( - base::SymmetricKey::AES, key)); - ASSERT_TRUE(NULL != sym_key.get()); - - base::Encryptor encryptor; - // The IV must be exactly as long a the cipher block size. - EXPECT_EQ(16U, iv.size()); - EXPECT_TRUE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv)); - - std::string ciphertext; - EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext)); - EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(), - ciphertext.size())); - - std::string decypted; - EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted)); - EXPECT_EQ(plaintext, decypted); -} - -// Not all platforms allow import/generation of symmetric keys with an -// unsupported size. -#if !defined(OS_WIN) && !defined(USE_NSS) -TEST(EncryptorTest, UnsupportedKeySize) { - std::string key = "7 = bad"; - std::string iv = "Sweet Sixteen IV"; - scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import( - base::SymmetricKey::AES, key)); - ASSERT_TRUE(NULL != sym_key.get()); - - base::Encryptor encryptor; - // The IV must be exactly as long a the cipher block size. - EXPECT_EQ(16U, iv.size()); - EXPECT_FALSE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv)); -} -#endif // unsupported platforms. - -TEST(EncryptorTest, UnsupportedIV) { - std::string key = "128=SixteenBytes"; - std::string iv = "OnlyForteen :("; - scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import( - base::SymmetricKey::AES, key)); - ASSERT_TRUE(NULL != sym_key.get()); - - base::Encryptor encryptor; - EXPECT_FALSE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv)); -} - -TEST(EncryptorTest, EmptyEncrypt) { - std::string key = "128=SixteenBytes"; - std::string iv = "Sweet Sixteen IV"; - std::string plaintext; - std::string expected_ciphertext_hex = "8518B8878D34E7185E300D0FCC426396"; - - scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import( - base::SymmetricKey::AES, key)); - ASSERT_TRUE(NULL != sym_key.get()); - - base::Encryptor encryptor; - // The IV must be exactly as long a the cipher block size. - EXPECT_EQ(16U, iv.size()); - EXPECT_TRUE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv)); - - std::string ciphertext; - EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext)); - EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(), - ciphertext.size())); -} - -TEST(EncryptorTest, EmptyDecrypt) { - std::string key = "128=SixteenBytes"; - std::string iv = "Sweet Sixteen IV"; - - scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import( - base::SymmetricKey::AES, key)); - ASSERT_TRUE(NULL != sym_key.get()); - - base::Encryptor encryptor; - // The IV must be exactly as long a the cipher block size. - EXPECT_EQ(16U, iv.size()); - EXPECT_TRUE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv)); - - std::string decrypted; - EXPECT_FALSE(encryptor.Decrypt("", &decrypted)); - EXPECT_EQ("", decrypted); -} diff --git a/base/crypto/encryptor_win.cc b/base/crypto/encryptor_win.cc deleted file mode 100644 index 1d732b5..0000000 --- a/base/crypto/encryptor_win.cc +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) 2011 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/encryptor.h" - -#include <vector> - -#include "base/crypto/symmetric_key.h" - -namespace base { - -namespace { - -// On success, returns the block size (in bytes) for the algorithm that |key| -// is for. On failure, returns 0. -DWORD GetCipherBlockSize(HCRYPTKEY key) { - DWORD block_size_in_bits = 0; - DWORD param_size = sizeof(block_size_in_bits); - BOOL ok = CryptGetKeyParam(key, KP_BLOCKLEN, - reinterpret_cast<BYTE*>(&block_size_in_bits), - ¶m_size, 0); - if (!ok) - return 0; - - return block_size_in_bits / 8; -} - -} // namespace - -Encryptor::Encryptor() - : key_(NULL), - mode_(CBC), - block_size_(0) { -} - -Encryptor::~Encryptor() { -} - -bool Encryptor::Init(SymmetricKey* key, Mode mode, const std::string& iv) { - DCHECK(key); - DCHECK_EQ(CBC, mode) << "Unsupported mode of operation"; - - // In CryptoAPI, the IV, padding mode, and feedback register (for a chaining - // mode) are properties of a key, so we have to create a copy of the key for - // the Encryptor. See the Remarks section of the CryptEncrypt MSDN page. - BOOL ok = CryptDuplicateKey(key->key(), NULL, 0, capi_key_.receive()); - if (!ok) - return false; - - // CRYPT_MODE_CBC is the default for Microsoft Base Cryptographic Provider, - // but we set it anyway to be safe. - DWORD cipher_mode = CRYPT_MODE_CBC; - ok = CryptSetKeyParam(capi_key_.get(), KP_MODE, - reinterpret_cast<BYTE*>(&cipher_mode), 0); - if (!ok) - return false; - - block_size_ = GetCipherBlockSize(capi_key_.get()); - if (block_size_ == 0) - return false; - - if (iv.size() != block_size_) - return false; - - ok = CryptSetKeyParam(capi_key_.get(), KP_IV, - reinterpret_cast<const BYTE*>(iv.data()), 0); - if (!ok) - return false; - - DWORD padding_method = PKCS5_PADDING; - ok = CryptSetKeyParam(capi_key_.get(), KP_PADDING, - reinterpret_cast<BYTE*>(&padding_method), 0); - if (!ok) - return false; - - return true; -} - -bool Encryptor::Encrypt(const std::string& plaintext, std::string* ciphertext) { - DWORD data_len = plaintext.size(); - DWORD total_len = data_len + block_size_; - - // CryptoAPI encrypts/decrypts in place. - std::vector<BYTE> tmp(total_len); - memcpy(&tmp[0], plaintext.data(), data_len); - - BOOL ok = CryptEncrypt(capi_key_.get(), NULL, TRUE, 0, &tmp[0], - &data_len, total_len); - if (!ok) - return false; - - ciphertext->assign(reinterpret_cast<char*>(&tmp[0]), data_len); - return true; -} - -bool Encryptor::Decrypt(const std::string& ciphertext, std::string* plaintext) { - DWORD data_len = ciphertext.size(); - if (data_len == 0) - return false; - - std::vector<BYTE> tmp(data_len); - memcpy(&tmp[0], ciphertext.data(), data_len); - - BOOL ok = CryptDecrypt(capi_key_.get(), NULL, TRUE, 0, &tmp[0], &data_len); - if (!ok) - return false; - - DCHECK_GT(tmp.size(), data_len); - - plaintext->assign(reinterpret_cast<char*>(&tmp[0]), data_len); - return true; -} - -} // namespace base diff --git a/base/crypto/mac_security_services_lock.cc b/base/crypto/mac_security_services_lock.cc deleted file mode 100644 index d68d757..0000000 --- a/base/crypto/mac_security_services_lock.cc +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2011 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/mac_security_services_lock.h" - -#include "base/memory/singleton.h" -#include "base/synchronization/lock.h" - -namespace { - -// This singleton pertains to Apple's wrappers over their own CSSM handles, -// as opposed to our own CSSM_CSP_HANDLE in cssm_init.cc. -class SecurityServicesSingleton { - public: - static SecurityServicesSingleton* GetInstance() { - return Singleton<SecurityServicesSingleton, - LeakySingletonTraits<SecurityServicesSingleton> >::get(); - } - - base::Lock& lock() { return lock_; } - - private: - friend struct DefaultSingletonTraits<SecurityServicesSingleton>; - - SecurityServicesSingleton() {} - ~SecurityServicesSingleton() {} - - base::Lock lock_; - - DISALLOW_COPY_AND_ASSIGN(SecurityServicesSingleton); -}; - -} // namespace - -namespace base { - -base::Lock& GetMacSecurityServicesLock() { - return SecurityServicesSingleton::GetInstance()->lock(); -} - -} // namespace base diff --git a/base/crypto/mac_security_services_lock.h b/base/crypto/mac_security_services_lock.h deleted file mode 100644 index 42c2bff..0000000 --- a/base/crypto/mac_security_services_lock.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2011 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_MAC_SECURITY_SERVICES_LOCK_H_ -#define BASE_CRYPTO_MAC_SECURITY_SERVICES_LOCK_H_ -#pragma once - -namespace base { - -class Lock; - -// The Mac OS X certificate and key management wrappers over CSSM are not -// thread-safe. In particular, code that accesses the CSSM database is -// problematic. -// -// http://developer.apple.com/mac/library/documentation/Security/Reference/certifkeytrustservices/Reference/reference.html -Lock& GetMacSecurityServicesLock(); - -} // namespace base - -#endif // BASE_CRYPTO_MAC_SECURITY_SERVICES_LOCK_H_ diff --git a/base/crypto/rsa_private_key.cc b/base/crypto/rsa_private_key.cc deleted file mode 100644 index c4464f1..0000000 --- a/base/crypto/rsa_private_key.cc +++ /dev/null @@ -1,390 +0,0 @@ -// Copyright (c) 2011 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/rsa_private_key.h" - -#include <algorithm> -#include <list> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/string_util.h" - -// This file manually encodes and decodes RSA private keys using PrivateKeyInfo -// from PKCS #8 and RSAPrivateKey from PKCS #1. These structures are: -// -// PrivateKeyInfo ::= SEQUENCE { -// version Version, -// privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, -// privateKey PrivateKey, -// attributes [0] IMPLICIT Attributes OPTIONAL -// } -// -// RSAPrivateKey ::= SEQUENCE { -// version Version, -// modulus INTEGER, -// publicExponent INTEGER, -// privateExponent INTEGER, -// prime1 INTEGER, -// prime2 INTEGER, -// exponent1 INTEGER, -// exponent2 INTEGER, -// coefficient INTEGER -// } - -namespace { -// Helper for error handling during key import. -#define READ_ASSERT(truth) \ - if (!(truth)) { \ - NOTREACHED(); \ - return false; \ - } -} // namespace - -namespace base { - -const uint8 PrivateKeyInfoCodec::kRsaAlgorithmIdentifier[] = { - 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, - 0x05, 0x00 -}; - -PrivateKeyInfoCodec::PrivateKeyInfoCodec(bool big_endian) - : big_endian_(big_endian) {} - -PrivateKeyInfoCodec::~PrivateKeyInfoCodec() {} - -bool PrivateKeyInfoCodec::Export(std::vector<uint8>* output) { - std::list<uint8> content; - - // Version (always zero) - uint8 version = 0; - - PrependInteger(coefficient_, &content); - PrependInteger(exponent2_, &content); - PrependInteger(exponent1_, &content); - PrependInteger(prime2_, &content); - PrependInteger(prime1_, &content); - PrependInteger(private_exponent_, &content); - PrependInteger(public_exponent_, &content); - PrependInteger(modulus_, &content); - PrependInteger(&version, 1, &content); - PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); - PrependTypeHeaderAndLength(kOctetStringTag, content.size(), &content); - - // RSA algorithm OID - for (size_t i = sizeof(kRsaAlgorithmIdentifier); i > 0; --i) - content.push_front(kRsaAlgorithmIdentifier[i - 1]); - - PrependInteger(&version, 1, &content); - PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); - - // Copy everying into the output. - output->reserve(content.size()); - for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i) - output->push_back(*i); - - return true; -} - -bool PrivateKeyInfoCodec::ExportPublicKeyInfo(std::vector<uint8>* output) { - // Create a sequence with the modulus (n) and public exponent (e). - std::vector<uint8> bit_string; - if (!ExportPublicKey(&bit_string)) - return false; - - // Add the sequence as the contents of a bit string. - std::list<uint8> content; - PrependBitString(&bit_string[0], static_cast<int>(bit_string.size()), - &content); - - // Add the RSA algorithm OID. - for (size_t i = sizeof(kRsaAlgorithmIdentifier); i > 0; --i) - content.push_front(kRsaAlgorithmIdentifier[i - 1]); - - // Finally, wrap everything in a sequence. - PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); - - // Copy everything into the output. - output->reserve(content.size()); - for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i) - output->push_back(*i); - - return true; -} - -bool PrivateKeyInfoCodec::ExportPublicKey(std::vector<uint8>* output) { - // Create a sequence with the modulus (n) and public exponent (e). - std::list<uint8> content; - PrependInteger(&public_exponent_[0], - static_cast<int>(public_exponent_.size()), - &content); - PrependInteger(&modulus_[0], static_cast<int>(modulus_.size()), &content); - PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content); - - // Copy everything into the output. - output->reserve(content.size()); - for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i) - output->push_back(*i); - - return true; -} - -bool PrivateKeyInfoCodec::Import(const std::vector<uint8>& input) { - if (input.empty()) { - return false; - } - - // Parse the private key info up to the public key values, ignoring - // the subsequent private key values. - uint8* src = const_cast<uint8*>(&input.front()); - uint8* end = src + input.size(); - if (!ReadSequence(&src, end) || - !ReadVersion(&src, end) || - !ReadAlgorithmIdentifier(&src, end) || - !ReadTypeHeaderAndLength(&src, end, kOctetStringTag, NULL) || - !ReadSequence(&src, end) || - !ReadVersion(&src, end) || - !ReadInteger(&src, end, &modulus_)) - return false; - - int mod_size = modulus_.size(); - READ_ASSERT(mod_size % 2 == 0); - int primes_size = mod_size / 2; - - if (!ReadIntegerWithExpectedSize(&src, end, 4, &public_exponent_) || - !ReadIntegerWithExpectedSize(&src, end, mod_size, &private_exponent_) || - !ReadIntegerWithExpectedSize(&src, end, primes_size, &prime1_) || - !ReadIntegerWithExpectedSize(&src, end, primes_size, &prime2_) || - !ReadIntegerWithExpectedSize(&src, end, primes_size, &exponent1_) || - !ReadIntegerWithExpectedSize(&src, end, primes_size, &exponent2_) || - !ReadIntegerWithExpectedSize(&src, end, primes_size, &coefficient_)) - return false; - - READ_ASSERT(src == end); - - - return true; -} - -void PrivateKeyInfoCodec::PrependInteger(const std::vector<uint8>& in, - std::list<uint8>* out) { - uint8* ptr = const_cast<uint8*>(&in.front()); - PrependIntegerImpl(ptr, in.size(), out, big_endian_); -} - -// Helper to prepend an ASN.1 integer. -void PrivateKeyInfoCodec::PrependInteger(uint8* val, - int num_bytes, - std::list<uint8>* data) { - PrependIntegerImpl(val, num_bytes, data, big_endian_); -} - -void PrivateKeyInfoCodec::PrependIntegerImpl(uint8* val, - int num_bytes, - std::list<uint8>* data, - bool big_endian) { - // Reverse input if little-endian. - std::vector<uint8> tmp; - if (!big_endian) { - tmp.assign(val, val + num_bytes); - reverse(tmp.begin(), tmp.end()); - val = &tmp.front(); - } - - // ASN.1 integers are unpadded byte arrays, so skip any null padding bytes - // from the most-significant end of the integer. - int start = 0; - while (start < (num_bytes - 1) && val[start] == 0x00) { - start++; - num_bytes--; - } - PrependBytes(val, start, num_bytes, data); - - // ASN.1 integers are signed. To encode a positive integer whose sign bit - // (the most significant bit) would otherwise be set and make the number - // negative, ASN.1 requires a leading null byte to force the integer to be - // positive. - uint8 front = data->front(); - if ((front & 0x80) != 0) { - data->push_front(0x00); - num_bytes++; - } - - PrependTypeHeaderAndLength(kIntegerTag, num_bytes, data); -} - -bool PrivateKeyInfoCodec::ReadInteger(uint8** pos, - uint8* end, - std::vector<uint8>* out) { - return ReadIntegerImpl(pos, end, out, big_endian_); -} - -bool PrivateKeyInfoCodec::ReadIntegerWithExpectedSize(uint8** pos, - uint8* end, - size_t expected_size, - std::vector<uint8>* out) { - std::vector<uint8> temp; - if (!ReadIntegerImpl(pos, end, &temp, true)) // Big-Endian - return false; - - int pad = expected_size - temp.size(); - int index = 0; - if (out->size() == expected_size + 1) { - READ_ASSERT(out->front() == 0x00); - pad++; - index++; - } else { - READ_ASSERT(out->size() <= expected_size); - } - - while (pad) { - out->push_back(0x00); - pad--; - } - out->insert(out->end(), temp.begin(), temp.end()); - - // Reverse output if little-endian. - if (!big_endian_) - reverse(out->begin(), out->end()); - return true; -} - -bool PrivateKeyInfoCodec::ReadIntegerImpl(uint8** pos, - uint8* end, - std::vector<uint8>* out, - bool big_endian) { - uint32 length = 0; - if (!ReadTypeHeaderAndLength(pos, end, kIntegerTag, &length) || !length) - return false; - - // The first byte can be zero to force positiveness. We can ignore this. - if (**pos == 0x00) { - ++(*pos); - --length; - } - - if (length) - out->insert(out->end(), *pos, (*pos) + length); - - (*pos) += length; - - // Reverse output if little-endian. - if (!big_endian) - reverse(out->begin(), out->end()); - return true; -} - -void PrivateKeyInfoCodec::PrependBytes(uint8* val, - int start, - int num_bytes, - std::list<uint8>* data) { - while (num_bytes > 0) { - --num_bytes; - data->push_front(val[start + num_bytes]); - } -} - -void PrivateKeyInfoCodec::PrependLength(size_t size, std::list<uint8>* data) { - // The high bit is used to indicate whether additional octets are needed to - // represent the length. - if (size < 0x80) { - data->push_front(static_cast<uint8>(size)); - } else { - uint8 num_bytes = 0; - while (size > 0) { - data->push_front(static_cast<uint8>(size & 0xFF)); - size >>= 8; - num_bytes++; - } - CHECK_LE(num_bytes, 4); - data->push_front(0x80 | num_bytes); - } -} - -void PrivateKeyInfoCodec::PrependTypeHeaderAndLength(uint8 type, - uint32 length, - std::list<uint8>* output) { - PrependLength(length, output); - output->push_front(type); -} - -void PrivateKeyInfoCodec::PrependBitString(uint8* val, - int num_bytes, - std::list<uint8>* output) { - // Start with the data. - PrependBytes(val, 0, num_bytes, output); - // Zero unused bits. - output->push_front(0); - // Add the length. - PrependLength(num_bytes + 1, output); - // Finally, add the bit string tag. - output->push_front((uint8) kBitStringTag); -} - -bool PrivateKeyInfoCodec::ReadLength(uint8** pos, uint8* end, uint32* result) { - READ_ASSERT(*pos < end); - int length = 0; - - // If the MSB is not set, the length is just the byte itself. - if (!(**pos & 0x80)) { - length = **pos; - (*pos)++; - } else { - // Otherwise, the lower 7 indicate the length of the length. - int length_of_length = **pos & 0x7F; - READ_ASSERT(length_of_length <= 4); - (*pos)++; - READ_ASSERT(*pos + length_of_length < end); - - length = 0; - for (int i = 0; i < length_of_length; ++i) { - length <<= 8; - length |= **pos; - (*pos)++; - } - } - - READ_ASSERT(*pos + length <= end); - if (result) *result = length; - return true; -} - -bool PrivateKeyInfoCodec::ReadTypeHeaderAndLength(uint8** pos, - uint8* end, - uint8 expected_tag, - uint32* length) { - READ_ASSERT(*pos < end); - READ_ASSERT(**pos == expected_tag); - (*pos)++; - - return ReadLength(pos, end, length); -} - -bool PrivateKeyInfoCodec::ReadSequence(uint8** pos, uint8* end) { - return ReadTypeHeaderAndLength(pos, end, kSequenceTag, NULL); -} - -bool PrivateKeyInfoCodec::ReadAlgorithmIdentifier(uint8** pos, uint8* end) { - READ_ASSERT(*pos + sizeof(kRsaAlgorithmIdentifier) < end); - READ_ASSERT(memcmp(*pos, kRsaAlgorithmIdentifier, - sizeof(kRsaAlgorithmIdentifier)) == 0); - (*pos) += sizeof(kRsaAlgorithmIdentifier); - return true; -} - -bool PrivateKeyInfoCodec::ReadVersion(uint8** pos, uint8* end) { - uint32 length = 0; - if (!ReadTypeHeaderAndLength(pos, end, kIntegerTag, &length)) - return false; - - // The version should be zero. - for (uint32 i = 0; i < length; ++i) { - READ_ASSERT(**pos == 0x00); - (*pos)++; - } - - return true; -} - -} // namespace base diff --git a/base/crypto/rsa_private_key.h b/base/crypto/rsa_private_key.h deleted file mode 100644 index 1f32982..0000000 --- a/base/crypto/rsa_private_key.h +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright (c) 2011 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_RSA_PRIVATE_KEY_H_ -#define BASE_CRYPTO_RSA_PRIVATE_KEY_H_ -#pragma once - -#include "build/build_config.h" - -#if defined(USE_OPENSSL) -// Forward declaration for openssl/*.h -typedef struct evp_pkey_st EVP_PKEY; -#elif defined(USE_NSS) -// Forward declaration. -struct SECKEYPrivateKeyStr; -struct SECKEYPublicKeyStr; -#elif defined(OS_MACOSX) -#include <Security/cssm.h> -#endif - -#include <list> -#include <vector> - -#include "base/base_api.h" -#include "base/basictypes.h" - -#if defined(OS_WIN) -#include "base/crypto/scoped_capi_types.h" -#endif -#if defined(USE_NSS) -#include "base/gtest_prod_util.h" -#endif - -namespace base { - -// Used internally by RSAPrivateKey for serializing and deserializing -// PKCS #8 PrivateKeyInfo and PublicKeyInfo. -class BASE_API PrivateKeyInfoCodec { - public: - - // ASN.1 encoding of the AlgorithmIdentifier from PKCS #8. - static const uint8 kRsaAlgorithmIdentifier[]; - - // ASN.1 tags for some types we use. - static const uint8 kBitStringTag = 0x03; - static const uint8 kIntegerTag = 0x02; - static const uint8 kNullTag = 0x05; - static const uint8 kOctetStringTag = 0x04; - static const uint8 kSequenceTag = 0x30; - - // |big_endian| here specifies the byte-significance of the integer components - // that will be parsed & serialized (modulus(), etc...) during Import(), - // Export() and ExportPublicKeyInfo() -- not the ASN.1 DER encoding of the - // PrivateKeyInfo/PublicKeyInfo (which is always big-endian). - explicit PrivateKeyInfoCodec(bool big_endian); - - ~PrivateKeyInfoCodec(); - - // Exports the contents of the integer components to the ASN.1 DER encoding - // of the PrivateKeyInfo structure to |output|. - bool Export(std::vector<uint8>* output); - - // Exports the contents of the integer components to the ASN.1 DER encoding - // of the PublicKeyInfo structure to |output|. - bool ExportPublicKeyInfo(std::vector<uint8>* output); - - // Exports the contents of the integer components to the ASN.1 DER encoding - // of the RSAPublicKey structure to |output|. - bool ExportPublicKey(std::vector<uint8>* output); - - // Parses the ASN.1 DER encoding of the PrivateKeyInfo structure in |input| - // and populates the integer components with |big_endian_| byte-significance. - // IMPORTANT NOTE: This is currently *not* security-approved for importing - // keys from unstrusted sources. - bool Import(const std::vector<uint8>& input); - - // Accessors to the contents of the integer components of the PrivateKeyInfo - // structure. - std::vector<uint8>* modulus() { return &modulus_; }; - std::vector<uint8>* public_exponent() { return &public_exponent_; }; - std::vector<uint8>* private_exponent() { return &private_exponent_; }; - std::vector<uint8>* prime1() { return &prime1_; }; - std::vector<uint8>* prime2() { return &prime2_; }; - std::vector<uint8>* exponent1() { return &exponent1_; }; - std::vector<uint8>* exponent2() { return &exponent2_; }; - std::vector<uint8>* coefficient() { return &coefficient_; }; - - private: - // Utility wrappers for PrependIntegerImpl that use the class's |big_endian_| - // value. - void PrependInteger(const std::vector<uint8>& in, std::list<uint8>* out); - void PrependInteger(uint8* val, int num_bytes, std::list<uint8>* data); - - // Prepends the integer stored in |val| - |val + num_bytes| with |big_endian| - // byte-significance into |data| as an ASN.1 integer. - void PrependIntegerImpl(uint8* val, - int num_bytes, - std::list<uint8>* data, - bool big_endian); - - // Utility wrappers for ReadIntegerImpl that use the class's |big_endian_| - // value. - bool ReadInteger(uint8** pos, uint8* end, std::vector<uint8>* out); - bool ReadIntegerWithExpectedSize(uint8** pos, - uint8* end, - size_t expected_size, - std::vector<uint8>* out); - - // Reads an ASN.1 integer from |pos|, and stores the result into |out| with - // |big_endian| byte-significance. - bool ReadIntegerImpl(uint8** pos, - uint8* end, - std::vector<uint8>* out, - bool big_endian); - - // Prepends the integer stored in |val|, starting a index |start|, for - // |num_bytes| bytes onto |data|. - void PrependBytes(uint8* val, - int start, - int num_bytes, - std::list<uint8>* data); - - // Helper to prepend an ASN.1 length field. - void PrependLength(size_t size, std::list<uint8>* data); - - // Helper to prepend an ASN.1 type header. - void PrependTypeHeaderAndLength(uint8 type, - uint32 length, - std::list<uint8>* output); - - // Helper to prepend an ASN.1 bit string - void PrependBitString(uint8* val, int num_bytes, std::list<uint8>* output); - - // Read an ASN.1 length field. This also checks that the length does not - // extend beyond |end|. - bool ReadLength(uint8** pos, uint8* end, uint32* result); - - // Read an ASN.1 type header and its length. - bool ReadTypeHeaderAndLength(uint8** pos, - uint8* end, - uint8 expected_tag, - uint32* length); - - // Read an ASN.1 sequence declaration. This consumes the type header and - // length field, but not the contents of the sequence. - bool ReadSequence(uint8** pos, uint8* end); - - // Read the RSA AlgorithmIdentifier. - bool ReadAlgorithmIdentifier(uint8** pos, uint8* end); - - // Read one of the two version fields in PrivateKeyInfo. - bool ReadVersion(uint8** pos, uint8* end); - - // The byte-significance of the stored components (modulus, etc..). - bool big_endian_; - - // Component integers of the PrivateKeyInfo - std::vector<uint8> modulus_; - std::vector<uint8> public_exponent_; - std::vector<uint8> private_exponent_; - std::vector<uint8> prime1_; - std::vector<uint8> prime2_; - std::vector<uint8> exponent1_; - std::vector<uint8> exponent2_; - std::vector<uint8> coefficient_; - - DISALLOW_COPY_AND_ASSIGN(PrivateKeyInfoCodec); -}; - -// Encapsulates an RSA private key. Can be used to generate new keys, export -// keys to other formats, or to extract a public key. -// TODO(hclam): This class should be ref-counted so it can be reused easily. -class BASE_API RSAPrivateKey { - public: - ~RSAPrivateKey(); - - // Create a new random instance. Can return NULL if initialization fails. - static RSAPrivateKey* Create(uint16 num_bits); - - // Create a new random instance. Can return NULL if initialization fails. - // The created key is permanent and is not exportable in plaintext form. - // - // NOTE: Currently only available if USE_NSS is defined. - static RSAPrivateKey* CreateSensitive(uint16 num_bits); - - // Create a new instance by importing an existing private key. The format is - // an ASN.1-encoded PrivateKeyInfo block from PKCS #8. This can return NULL if - // initialization fails. - static RSAPrivateKey* CreateFromPrivateKeyInfo( - const std::vector<uint8>& input); - - // Create a new instance by importing an existing private key. The format is - // an ASN.1-encoded PrivateKeyInfo block from PKCS #8. This can return NULL if - // initialization fails. - // The created key is permanent and is not exportable in plaintext form. - // - // NOTE: Currently only available if USE_NSS is defined. - static RSAPrivateKey* CreateSensitiveFromPrivateKeyInfo( - const std::vector<uint8>& input); - - // Import an existing public key, and then search for the private - // half in the key database. The format of the public key blob is is - // an X509 SubjectPublicKeyInfo block. This can return NULL if - // initialization fails or the private key cannot be found. The - // caller takes ownership of the returned object, but nothing new is - // created in the key database. - // - // NOTE: Currently only available if USE_NSS is defined. - static RSAPrivateKey* FindFromPublicKeyInfo( - const std::vector<uint8>& input); - -#if defined(USE_OPENSSL) - EVP_PKEY* key() { return key_; } -#elif defined(USE_NSS) - SECKEYPrivateKeyStr* key() { return key_; } - SECKEYPublicKeyStr* public_key() { return public_key_; } -#elif defined(OS_WIN) - HCRYPTPROV provider() { return provider_; } - HCRYPTKEY key() { return key_; } -#elif defined(OS_MACOSX) - CSSM_KEY_PTR key() { return &key_; } - CSSM_KEY_PTR public_key() { return &public_key_; } -#endif - - // Exports the private key to a PKCS #1 PrivateKey block. - bool ExportPrivateKey(std::vector<uint8>* output); - - // Exports the public key to an X509 SubjectPublicKeyInfo block. - bool ExportPublicKey(std::vector<uint8>* output); - - private: -#if defined(USE_NSS) - FRIEND_TEST_ALL_PREFIXES(RSAPrivateKeyNSSTest, FindFromPublicKey); - FRIEND_TEST_ALL_PREFIXES(RSAPrivateKeyNSSTest, FailedFindFromPublicKey); -#endif - - // Constructor is private. Use one of the Create*() or Find*() - // methods above instead. - RSAPrivateKey(); - - // Shared helper for Create() and CreateSensitive(). - // TODO(cmasone): consider replacing |permanent| and |sensitive| with a - // flags arg created by ORing together some enumerated values. - static RSAPrivateKey* CreateWithParams(uint16 num_bits, - bool permanent, - bool sensitive); - - // Shared helper for CreateFromPrivateKeyInfo() and - // CreateSensitiveFromPrivateKeyInfo(). - static RSAPrivateKey* CreateFromPrivateKeyInfoWithParams( - const std::vector<uint8>& input, bool permanent, bool sensitive); - -#if defined(USE_OPENSSL) - EVP_PKEY* key_; -#elif defined(USE_NSS) - SECKEYPrivateKeyStr* key_; - SECKEYPublicKeyStr* public_key_; -#elif defined(OS_WIN) - bool InitProvider(); - - ScopedHCRYPTPROV provider_; - ScopedHCRYPTKEY key_; -#elif defined(OS_MACOSX) - CSSM_KEY key_; - CSSM_KEY public_key_; -#endif - - DISALLOW_COPY_AND_ASSIGN(RSAPrivateKey); -}; - -} // namespace base - -#endif // BASE_CRYPTO_RSA_PRIVATE_KEY_H_ diff --git a/base/crypto/rsa_private_key_mac.cc b/base/crypto/rsa_private_key_mac.cc deleted file mode 100644 index 35f9104..0000000 --- a/base/crypto/rsa_private_key_mac.cc +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (c) 2011 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/rsa_private_key.h" - -#include <list> - -#include "base/crypto/cssm_init.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" - -namespace base { - -// static -RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { - scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); - - CSSM_CC_HANDLE cc_handle; - CSSM_RETURN crtn; - crtn = CSSM_CSP_CreateKeyGenContext(GetSharedCSPHandle(), CSSM_ALGID_RSA, - num_bits, NULL, NULL, NULL, NULL, NULL, - &cc_handle); - if (crtn) { - NOTREACHED() << "CSSM_CSP_CreateKeyGenContext failed: " << crtn; - return NULL; - } - - CSSM_DATA label = { 9, - const_cast<uint8*>(reinterpret_cast<const uint8*>("temp_key")) }; - crtn = CSSM_GenerateKeyPair(cc_handle, - CSSM_KEYUSE_VERIFY, - CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label, - result->public_key(), CSSM_KEYUSE_SIGN, - CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label, NULL, - result->key()); - CSSM_DeleteContext(cc_handle); - if (crtn) { - NOTREACHED() << "CSSM_CSP_CreateKeyGenContext failed: " << crtn; - return NULL; - } - - return result.release(); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( - const std::vector<uint8>& input) { - if (input.empty()) - return NULL; - - scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); - - CSSM_KEY key; - memset(&key, 0, sizeof(key)); - key.KeyData.Data = const_cast<uint8*>(&input.front()); - key.KeyData.Length = input.size(); - key.KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8; - key.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; - key.KeyHeader.BlobType = CSSM_KEYBLOB_RAW; - key.KeyHeader.AlgorithmId = CSSM_ALGID_RSA; - key.KeyHeader.KeyClass = CSSM_KEYCLASS_PRIVATE_KEY; - key.KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE; - key.KeyHeader.KeyUsage = CSSM_KEYUSE_ANY; - - CSSM_KEY_SIZE key_size; - CSSM_RETURN crtn; - crtn = CSSM_QueryKeySizeInBits(GetSharedCSPHandle(), NULL, &key, &key_size); - if (crtn) { - NOTREACHED() << "CSSM_QueryKeySizeInBits failed: " << crtn; - return NULL; - } - key.KeyHeader.LogicalKeySizeInBits = key_size.LogicalKeySizeInBits; - - // Perform a NULL unwrap operation on the key so that result's key_ - // instance variable points to a key that can be released via CSSM_FreeKey(). - CSSM_ACCESS_CREDENTIALS creds; - memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS)); - CSSM_CC_HANDLE cc_handle; - crtn = CSSM_CSP_CreateSymmetricContext(GetSharedCSPHandle(), CSSM_ALGID_NONE, - CSSM_ALGMODE_NONE, &creds, NULL, NULL, CSSM_PADDING_NONE, 0, &cc_handle); - if (crtn) { - NOTREACHED() << "CSSM_CSP_CreateSymmetricContext failed: " << crtn; - return NULL; - } - CSSM_DATA label_data, desc_data = { 0, NULL }; - label_data.Data = - const_cast<uint8*>(reinterpret_cast<const uint8*>("unwrapped")); - label_data.Length = 9; - crtn = CSSM_UnwrapKey(cc_handle, NULL, &key, CSSM_KEYUSE_ANY, - CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label_data, - NULL, result->key(), &desc_data); - if (crtn) { - NOTREACHED() << "CSSM_UnwrapKey failed: " << crtn; - return NULL; - } - - // Extract a public key from the private key. - // Apple doesn't accept CSSM_KEYBLOB_RAW_FORMAT_X509 as a valid key - // format when attempting to generate certs, so use PKCS1 instead. - PrivateKeyInfoCodec codec(true); - std::vector<uint8> private_key_data; - private_key_data.assign(key.KeyData.Data, - key.KeyData.Data + key.KeyData.Length); - if (!codec.Import(private_key_data)) { - return NULL; - } - std::vector<uint8> public_key_data; - if (!codec.ExportPublicKey(&public_key_data)) { - return NULL; - } - - CSSM_KEY* public_key = result->public_key(); - size_t size = public_key_data.size(); - public_key->KeyData.Data = reinterpret_cast<uint8*>(CSSMMalloc(size)); - if (!public_key->KeyData.Data) { - NOTREACHED() << "CSSMMalloc failed"; - return NULL; - } - memcpy(public_key->KeyData.Data, &public_key_data.front(), size); - public_key->KeyData.Length = size; - public_key->KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; - public_key->KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; - public_key->KeyHeader.BlobType = CSSM_KEYBLOB_RAW; - public_key->KeyHeader.AlgorithmId = CSSM_ALGID_RSA; - public_key->KeyHeader.KeyClass = CSSM_KEYCLASS_PUBLIC_KEY; - public_key->KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE; - public_key->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY; - - crtn = CSSM_QueryKeySizeInBits( - base::GetSharedCSPHandle(), NULL, public_key, &key_size); - if (crtn) { - DLOG(ERROR) << "CSSM_QueryKeySizeInBits failed " << crtn; - return NULL; - } - public_key->KeyHeader.LogicalKeySizeInBits = key_size.LogicalKeySizeInBits; - - return result.release(); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -RSAPrivateKey::RSAPrivateKey() { - memset(&key_, 0, sizeof(key_)); - memset(&public_key_, 0, sizeof(public_key_)); - - EnsureCSSMInit(); -} - -RSAPrivateKey::~RSAPrivateKey() { - if (key_.KeyData.Data) { - CSSM_FreeKey(GetSharedCSPHandle(), NULL, &key_, CSSM_FALSE); - } - if (public_key_.KeyData.Data) { - CSSM_FreeKey(GetSharedCSPHandle(), NULL, &public_key_, CSSM_FALSE); - } -} - -bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { - if (!key_.KeyData.Data || !key_.KeyData.Length) { - return false; - } - output->clear(); - output->insert(output->end(), key_.KeyData.Data, - key_.KeyData.Data + key_.KeyData.Length); - return true; -} - -bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { - PrivateKeyInfoCodec private_key_info(true); - std::vector<uint8> private_key_data; - private_key_data.assign(key_.KeyData.Data, - key_.KeyData.Data + key_.KeyData.Length); - return (private_key_info.Import(private_key_data) && - private_key_info.ExportPublicKeyInfo(output)); -} - -} // namespace base diff --git a/base/crypto/rsa_private_key_nss.cc b/base/crypto/rsa_private_key_nss.cc deleted file mode 100644 index 9c474ff..0000000 --- a/base/crypto/rsa_private_key_nss.cc +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright (c) 2011 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/rsa_private_key.h" - -#include <cryptohi.h> -#include <keyhi.h> -#include <pk11pub.h> - -#include <list> - -#include "base/debug/leak_annotations.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/nss_util.h" -#include "base/nss_util_internal.h" -#include "base/string_util.h" - -// TODO(rafaelw): Consider refactoring common functions and definitions from -// rsa_private_key_win.cc or using NSS's ASN.1 encoder. -namespace { - -static bool ReadAttribute(SECKEYPrivateKey* key, - CK_ATTRIBUTE_TYPE type, - std::vector<uint8>* output) { - SECItem item; - SECStatus rv; - rv = PK11_ReadRawAttribute(PK11_TypePrivKey, key, type, &item); - if (rv != SECSuccess) { - NOTREACHED(); - return false; - } - - output->assign(item.data, item.data + item.len); - SECITEM_FreeItem(&item, PR_FALSE); - return true; -} - -} // namespace - -namespace base { - -RSAPrivateKey::~RSAPrivateKey() { - if (key_) - SECKEY_DestroyPrivateKey(key_); - if (public_key_) - SECKEY_DestroyPublicKey(public_key_); -} - -// static -RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { - return CreateWithParams(num_bits, - PR_FALSE /* not permanent */, - PR_FALSE /* not sensitive */); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { - return CreateWithParams(num_bits, - PR_TRUE /* permanent */, - PR_TRUE /* sensitive */); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( - const std::vector<uint8>& input) { - return CreateFromPrivateKeyInfoWithParams(input, - PR_FALSE /* not permanent */, - PR_FALSE /* not sensitive */); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( - const std::vector<uint8>& input) { - return CreateFromPrivateKeyInfoWithParams(input, - PR_TRUE /* permanent */, - PR_TRUE /* seneitive */); -} - -// static -RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( - const std::vector<uint8>& input) { - base::EnsureNSSInit(); - - scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); - - // First, decode and save the public key. - SECItem key_der; - key_der.type = siBuffer; - key_der.data = const_cast<unsigned char*>(&input[0]); - key_der.len = input.size(); - - CERTSubjectPublicKeyInfo *spki = - SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der); - if (!spki) { - NOTREACHED(); - return NULL; - } - - result->public_key_ = SECKEY_ExtractPublicKey(spki); - SECKEY_DestroySubjectPublicKeyInfo(spki); - if (!result->public_key_) { - NOTREACHED(); - return NULL; - } - - // Now, look for the associated private key in the user's NSS DB. If it's - // not there, consider that an error. - PK11SlotInfo *slot = GetPrivateNSSKeySlot(); - if (!slot) { - 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); - NOTREACHED(); - return NULL; - } - - SECItem *ck_id = PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus)); - if (!ck_id) { - PK11_FreeSlot(slot); - 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); - - // If we didn't find it, that's ok. - if (!result->key_) - return NULL; - - return result.release(); -} - - -bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { - PrivateKeyInfoCodec private_key_info(true); - - // Manually read the component attributes of the private key and build up - // the PrivateKeyInfo. - if (!ReadAttribute(key_, CKA_MODULUS, private_key_info.modulus()) || - !ReadAttribute(key_, CKA_PUBLIC_EXPONENT, - private_key_info.public_exponent()) || - !ReadAttribute(key_, CKA_PRIVATE_EXPONENT, - private_key_info.private_exponent()) || - !ReadAttribute(key_, CKA_PRIME_1, private_key_info.prime1()) || - !ReadAttribute(key_, CKA_PRIME_2, private_key_info.prime2()) || - !ReadAttribute(key_, CKA_EXPONENT_1, private_key_info.exponent1()) || - !ReadAttribute(key_, CKA_EXPONENT_2, private_key_info.exponent2()) || - !ReadAttribute(key_, CKA_COEFFICIENT, private_key_info.coefficient())) { - NOTREACHED(); - return false; - } - - return private_key_info.Export(output); -} - -bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { - SECItem* der_pubkey = SECKEY_EncodeDERSubjectPublicKeyInfo(public_key_); - if (!der_pubkey) { - 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; -} - -RSAPrivateKey::RSAPrivateKey() : key_(NULL), public_key_(NULL) { - EnsureNSSInit(); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateWithParams(uint16 num_bits, - bool permanent, - bool sensitive) { - base::EnsureNSSInit(); - - scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); - - PK11SlotInfo *slot = GetPrivateNSSKeySlot(); - if (!slot) - return NULL; - - PK11RSAGenParams param; - param.keySizeInBits = num_bits; - param.pe = 65537L; - result->key_ = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, ¶m, - &result->public_key_, permanent, sensitive, NULL); - PK11_FreeSlot(slot); - if (!result->key_) - return NULL; - - return result.release(); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams( - const std::vector<uint8>& input, bool permanent, bool sensitive) { - // This method currently leaks some memory. - // See http://crbug.com/34742. - ANNOTATE_SCOPED_MEMORY_LEAK; - base::EnsureNSSInit(); - - scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); - - PK11SlotInfo *slot = GetPrivateNSSKeySlot(); - if (!slot) - return NULL; - - SECItem der_private_key_info; - der_private_key_info.data = const_cast<unsigned char*>(&input.front()); - der_private_key_info.len = input.size(); - // Allow the private key to be used for key unwrapping, data decryption, - // and signature generation. - 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, - key_usage, &result->key_, NULL); - PK11_FreeSlot(slot); - if (rv != SECSuccess) { - NOTREACHED(); - return NULL; - } - - result->public_key_ = SECKEY_ConvertToPublicKey(result->key_); - if (!result->public_key_) { - NOTREACHED(); - return NULL; - } - - return result.release(); -} - -} // namespace base diff --git a/base/crypto/rsa_private_key_nss_unittest.cc b/base/crypto/rsa_private_key_nss_unittest.cc deleted file mode 100644 index f132d37..0000000 --- a/base/crypto/rsa_private_key_nss_unittest.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2011 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/rsa_private_key.h" - -#include <keyhi.h> -#include <pk11pub.h> - -#include "base/memory/scoped_ptr.h" -#include "base/nss_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace base { - -class RSAPrivateKeyNSSTest : public testing::Test { - public: - RSAPrivateKeyNSSTest() {} - virtual ~RSAPrivateKeyNSSTest() {} - - virtual void SetUp() { -#if defined(OS_CHROMEOS) - base::OpenPersistentNSSDB(); -#endif - } - - private: - DISALLOW_COPY_AND_ASSIGN(RSAPrivateKeyNSSTest); -}; - -TEST_F(RSAPrivateKeyNSSTest, FindFromPublicKey) { - // Create a keypair, which will put the keys in the user's NSSDB. - scoped_ptr<base::RSAPrivateKey> key_pair(base::RSAPrivateKey::Create(256)); - - std::vector<uint8> public_key; - ASSERT_TRUE(key_pair->ExportPublicKey(&public_key)); - - scoped_ptr<base::RSAPrivateKey> key_pair_2( - base::RSAPrivateKey::FindFromPublicKeyInfo(public_key)); - - EXPECT_EQ(key_pair->key_->pkcs11ID, key_pair_2->key_->pkcs11ID); -} - -TEST_F(RSAPrivateKeyNSSTest, FailedFindFromPublicKey) { - // Create a keypair, which will put the keys in the user's NSSDB. - scoped_ptr<base::RSAPrivateKey> key_pair(base::RSAPrivateKey::Create(256)); - - std::vector<uint8> public_key; - ASSERT_TRUE(key_pair->ExportPublicKey(&public_key)); - - // Remove the keys from the DB, and make sure we can't find them again. - if (key_pair->key_) { - PK11_DestroyTokenObject(key_pair->key_->pkcs11Slot, - key_pair->key_->pkcs11ID); - } - if (key_pair->public_key_) { - PK11_DestroyTokenObject(key_pair->public_key_->pkcs11Slot, - key_pair->public_key_->pkcs11ID); - } - - EXPECT_EQ(NULL, base::RSAPrivateKey::FindFromPublicKeyInfo(public_key)); -} - -} // namespace base diff --git a/base/crypto/rsa_private_key_openssl.cc b/base/crypto/rsa_private_key_openssl.cc deleted file mode 100644 index 3dc6223..0000000 --- a/base/crypto/rsa_private_key_openssl.cc +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) 2011 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/rsa_private_key.h" - -#include <openssl/evp.h> -#include <openssl/pkcs12.h> -#include <openssl/rsa.h> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/openssl_util.h" -#include "base/stl_util-inl.h" - -namespace base { - -namespace { - -// Function pointer definition, for injecting the required key export function -// into ExportKey, below. The supplied function should export EVP_PKEY into -// the supplied BIO, returning 1 on success or 0 on failure. -typedef int (ExportFunction)(BIO*, EVP_PKEY*); - -// Helper to export |key| into |output| via the specified ExportFunction. -bool ExportKey(EVP_PKEY* key, - ExportFunction export_fn, - std::vector<uint8>* output) { - if (!key) - return false; - - OpenSSLErrStackTracer err_tracer(FROM_HERE); - ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new(BIO_s_mem())); - - int res = export_fn(bio.get(), key); - if (!res) - return false; - - char* data = NULL; - long len = BIO_get_mem_data(bio.get(), &data); - if (!data || len < 0) - return false; - - STLAssignToVector(output, reinterpret_cast<const uint8*>(data), len); - return true; -} - -} // namespace - -// static -RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { - OpenSSLErrStackTracer err_tracer(FROM_HERE); - - ScopedOpenSSL<RSA, RSA_free> rsa_key(RSA_new()); - ScopedOpenSSL<BIGNUM, BN_free> bn(BN_new()); - if (!rsa_key.get() || !bn.get() || !BN_set_word(bn.get(), 65537L)) - return NULL; - - if (!RSA_generate_key_ex(rsa_key.get(), num_bits, bn.get(), NULL)) - return NULL; - - scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); - result->key_ = EVP_PKEY_new(); - if (!result->key_ || !EVP_PKEY_set1_RSA(result->key_, rsa_key.get())) - return NULL; - - return result.release(); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( - const std::vector<uint8>& input) { - OpenSSLErrStackTracer err_tracer(FROM_HERE); - - // BIO_new_mem_buf is not const aware, but it does not modify the buffer. - char* data = reinterpret_cast<char*>(const_cast<uint8*>( - vector_as_array(&input))); - ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new_mem_buf(data, input.size())); - if (!bio.get()) - return NULL; - - // Importing is a little more involved than exporting, as we must first - // PKCS#8 decode the input, and then import the EVP_PKEY from Private Key - // Info structure returned. - ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> p8inf( - d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), NULL)); - if (!p8inf.get()) - return NULL; - - scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); - result->key_ = EVP_PKCS82PKEY(p8inf.get()); - if (!result->key_) - return NULL; - - return result.release(); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -RSAPrivateKey::RSAPrivateKey() - : key_(NULL) { -} - -RSAPrivateKey::~RSAPrivateKey() { - if (key_) - EVP_PKEY_free(key_); -} - -bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { - return ExportKey(key_, i2d_PKCS8PrivateKeyInfo_bio, output); -} - -bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { - return ExportKey(key_, i2d_PUBKEY_bio, output); -} - -} // namespace base diff --git a/base/crypto/rsa_private_key_unittest.cc b/base/crypto/rsa_private_key_unittest.cc deleted file mode 100644 index 1d9a249..0000000 --- a/base/crypto/rsa_private_key_unittest.cc +++ /dev/null @@ -1,383 +0,0 @@ -// Copyright (c) 2011 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/rsa_private_key.h" -#include "base/memory/scoped_ptr.h" -#include "testing/gtest/include/gtest/gtest.h" - -// Generate random private keys with two different sizes. Reimport, then -// export them again. We should get back the same exact bytes. -TEST(RSAPrivateKeyUnitTest, InitRandomTest) { - scoped_ptr<base::RSAPrivateKey> keypair1(base::RSAPrivateKey::Create(1024)); - scoped_ptr<base::RSAPrivateKey> keypair2(base::RSAPrivateKey::Create(2048)); - ASSERT_TRUE(keypair1.get()); - ASSERT_TRUE(keypair2.get()); - - std::vector<uint8> privkey1; - std::vector<uint8> privkey2; - std::vector<uint8> pubkey1; - std::vector<uint8> pubkey2; - - ASSERT_TRUE(keypair1->ExportPrivateKey(&privkey1)); - ASSERT_TRUE(keypair2->ExportPrivateKey(&privkey2)); - ASSERT_TRUE(keypair1->ExportPublicKey(&pubkey1)); - ASSERT_TRUE(keypair2->ExportPublicKey(&pubkey2)); - - scoped_ptr<base::RSAPrivateKey> keypair3( - base::RSAPrivateKey::CreateFromPrivateKeyInfo(privkey1)); - scoped_ptr<base::RSAPrivateKey> keypair4( - base::RSAPrivateKey::CreateFromPrivateKeyInfo(privkey2)); - ASSERT_TRUE(keypair3.get()); - ASSERT_TRUE(keypair4.get()); - - std::vector<uint8> privkey3; - std::vector<uint8> privkey4; - ASSERT_TRUE(keypair3->ExportPrivateKey(&privkey3)); - ASSERT_TRUE(keypair4->ExportPrivateKey(&privkey4)); - - ASSERT_EQ(privkey1.size(), privkey3.size()); - ASSERT_EQ(privkey2.size(), privkey4.size()); - ASSERT_TRUE(0 == memcmp(&privkey1.front(), &privkey3.front(), - privkey1.size())); - ASSERT_TRUE(0 == memcmp(&privkey2.front(), &privkey4.front(), - privkey2.size())); -} - - -// Verify that generated public keys look good. This test data was generated -// with the openssl command line tool. -TEST(RSAPrivateKeyUnitTest, PublicKeyTest) { - const uint8 private_key_info[] = { - 0x30, 0x82, 0x02, 0x78, 0x02, 0x01, 0x00, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, - 0x02, 0x62, 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, - 0x00, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x7f, 0x2b, - 0x20, 0xdc, 0x7c, 0x9b, 0x0c, 0xdc, 0x51, 0x61, - 0x99, 0x0d, 0x36, 0x0f, 0xd4, 0x66, 0x88, 0x08, - 0x55, 0x84, 0xd5, 0x3a, 0xbf, 0x2b, 0xa4, 0x64, - 0x85, 0x7b, 0x0c, 0x04, 0x13, 0x3f, 0x8d, 0xf4, - 0xbc, 0x38, 0x0d, 0x49, 0xfe, 0x6b, 0xc4, 0x5a, - 0xb0, 0x40, 0x53, 0x3a, 0xd7, 0x66, 0x09, 0x0f, - 0x9e, 0x36, 0x74, 0x30, 0xda, 0x8a, 0x31, 0x4f, - 0x1f, 0x14, 0x50, 0xd7, 0xc7, 0x20, 0x94, 0x17, - 0xde, 0x4e, 0xb9, 0x57, 0x5e, 0x7e, 0x0a, 0xe5, - 0xb2, 0x65, 0x7a, 0x89, 0x4e, 0xb6, 0x47, 0xff, - 0x1c, 0xbd, 0xb7, 0x38, 0x13, 0xaf, 0x47, 0x85, - 0x84, 0x32, 0x33, 0xf3, 0x17, 0x49, 0xbf, 0xe9, - 0x96, 0xd0, 0xd6, 0x14, 0x6f, 0x13, 0x8d, 0xc5, - 0xfc, 0x2c, 0x72, 0xba, 0xac, 0xea, 0x7e, 0x18, - 0x53, 0x56, 0xa6, 0x83, 0xa2, 0xce, 0x93, 0x93, - 0xe7, 0x1f, 0x0f, 0xe6, 0x0f, 0x02, 0x03, 0x01, - 0x00, 0x01, 0x02, 0x81, 0x80, 0x03, 0x61, 0x89, - 0x37, 0xcb, 0xf2, 0x98, 0xa0, 0xce, 0xb4, 0xcb, - 0x16, 0x13, 0xf0, 0xe6, 0xaf, 0x5c, 0xc5, 0xa7, - 0x69, 0x71, 0xca, 0xba, 0x8d, 0xe0, 0x4d, 0xdd, - 0xed, 0xb8, 0x48, 0x8b, 0x16, 0x93, 0x36, 0x95, - 0xc2, 0x91, 0x40, 0x65, 0x17, 0xbd, 0x7f, 0xd6, - 0xad, 0x9e, 0x30, 0x28, 0x46, 0xe4, 0x3e, 0xcc, - 0x43, 0x78, 0xf9, 0xfe, 0x1f, 0x33, 0x23, 0x1e, - 0x31, 0x12, 0x9d, 0x3c, 0xa7, 0x08, 0x82, 0x7b, - 0x7d, 0x25, 0x4e, 0x5e, 0x19, 0xa8, 0x9b, 0xed, - 0x86, 0xb2, 0xcb, 0x3c, 0xfe, 0x4e, 0xa1, 0xfa, - 0x62, 0x87, 0x3a, 0x17, 0xf7, 0x60, 0xec, 0x38, - 0x29, 0xe8, 0x4f, 0x34, 0x9f, 0x76, 0x9d, 0xee, - 0xa3, 0xf6, 0x85, 0x6b, 0x84, 0x43, 0xc9, 0x1e, - 0x01, 0xff, 0xfd, 0xd0, 0x29, 0x4c, 0xfa, 0x8e, - 0x57, 0x0c, 0xc0, 0x71, 0xa5, 0xbb, 0x88, 0x46, - 0x29, 0x5c, 0xc0, 0x4f, 0x01, 0x02, 0x41, 0x00, - 0xf5, 0x83, 0xa4, 0x64, 0x4a, 0xf2, 0xdd, 0x8c, - 0x2c, 0xed, 0xa8, 0xd5, 0x60, 0x5a, 0xe4, 0xc7, - 0xcc, 0x61, 0xcd, 0x38, 0x42, 0x20, 0xd3, 0x82, - 0x18, 0xf2, 0x35, 0x00, 0x72, 0x2d, 0xf7, 0x89, - 0x80, 0x67, 0xb5, 0x93, 0x05, 0x5f, 0xdd, 0x42, - 0xba, 0x16, 0x1a, 0xea, 0x15, 0xc6, 0xf0, 0xb8, - 0x8c, 0xbc, 0xbf, 0x54, 0x9e, 0xf1, 0xc1, 0xb2, - 0xb3, 0x8b, 0xb6, 0x26, 0x02, 0x30, 0xc4, 0x81, - 0x02, 0x41, 0x00, 0xc0, 0x60, 0x62, 0x80, 0xe1, - 0x22, 0x78, 0xf6, 0x9d, 0x83, 0x18, 0xeb, 0x72, - 0x45, 0xd7, 0xc8, 0x01, 0x7f, 0xa9, 0xca, 0x8f, - 0x7d, 0xd6, 0xb8, 0x31, 0x2b, 0x84, 0x7f, 0x62, - 0xd9, 0xa9, 0x22, 0x17, 0x7d, 0x06, 0x35, 0x6c, - 0xf3, 0xc1, 0x94, 0x17, 0x85, 0x5a, 0xaf, 0x9c, - 0x5c, 0x09, 0x3c, 0xcf, 0x2f, 0x44, 0x9d, 0xb6, - 0x52, 0x68, 0x5f, 0xf9, 0x59, 0xc8, 0x84, 0x2b, - 0x39, 0x22, 0x8f, 0x02, 0x41, 0x00, 0xb2, 0x04, - 0xe2, 0x0e, 0x56, 0xca, 0x03, 0x1a, 0xc0, 0xf9, - 0x12, 0x92, 0xa5, 0x6b, 0x42, 0xb8, 0x1c, 0xda, - 0x4d, 0x93, 0x9d, 0x5f, 0x6f, 0xfd, 0xc5, 0x58, - 0xda, 0x55, 0x98, 0x74, 0xfc, 0x28, 0x17, 0x93, - 0x1b, 0x75, 0x9f, 0x50, 0x03, 0x7f, 0x7e, 0xae, - 0xc8, 0x95, 0x33, 0x75, 0x2c, 0xd6, 0xa4, 0x35, - 0xb8, 0x06, 0x03, 0xba, 0x08, 0x59, 0x2b, 0x17, - 0x02, 0xdc, 0x4c, 0x7a, 0x50, 0x01, 0x02, 0x41, - 0x00, 0x9d, 0xdb, 0x39, 0x59, 0x09, 0xe4, 0x30, - 0xa0, 0x24, 0xf5, 0xdb, 0x2f, 0xf0, 0x2f, 0xf1, - 0x75, 0x74, 0x0d, 0x5e, 0xb5, 0x11, 0x73, 0xb0, - 0x0a, 0xaa, 0x86, 0x4c, 0x0d, 0xff, 0x7e, 0x1d, - 0xb4, 0x14, 0xd4, 0x09, 0x91, 0x33, 0x5a, 0xfd, - 0xa0, 0x58, 0x80, 0x9b, 0xbe, 0x78, 0x2e, 0x69, - 0x82, 0x15, 0x7c, 0x72, 0xf0, 0x7b, 0x18, 0x39, - 0xff, 0x6e, 0xeb, 0xc6, 0x86, 0xf5, 0xb4, 0xc7, - 0x6f, 0x02, 0x41, 0x00, 0x8d, 0x1a, 0x37, 0x0f, - 0x76, 0xc4, 0x82, 0xfa, 0x5c, 0xc3, 0x79, 0x35, - 0x3e, 0x70, 0x8a, 0xbf, 0x27, 0x49, 0xb0, 0x99, - 0x63, 0xcb, 0x77, 0x5f, 0xa8, 0x82, 0x65, 0xf6, - 0x03, 0x52, 0x51, 0xf1, 0xae, 0x2e, 0x05, 0xb3, - 0xc6, 0xa4, 0x92, 0xd1, 0xce, 0x6c, 0x72, 0xfb, - 0x21, 0xb3, 0x02, 0x87, 0xe4, 0xfd, 0x61, 0xca, - 0x00, 0x42, 0x19, 0xf0, 0xda, 0x5a, 0x53, 0xe3, - 0xb1, 0xc5, 0x15, 0xf3 - }; - - const uint8 expected_public_key_info[] = { - 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, - 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, - 0x89, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x7f, 0x2b, - 0x20, 0xdc, 0x7c, 0x9b, 0x0c, 0xdc, 0x51, 0x61, - 0x99, 0x0d, 0x36, 0x0f, 0xd4, 0x66, 0x88, 0x08, - 0x55, 0x84, 0xd5, 0x3a, 0xbf, 0x2b, 0xa4, 0x64, - 0x85, 0x7b, 0x0c, 0x04, 0x13, 0x3f, 0x8d, 0xf4, - 0xbc, 0x38, 0x0d, 0x49, 0xfe, 0x6b, 0xc4, 0x5a, - 0xb0, 0x40, 0x53, 0x3a, 0xd7, 0x66, 0x09, 0x0f, - 0x9e, 0x36, 0x74, 0x30, 0xda, 0x8a, 0x31, 0x4f, - 0x1f, 0x14, 0x50, 0xd7, 0xc7, 0x20, 0x94, 0x17, - 0xde, 0x4e, 0xb9, 0x57, 0x5e, 0x7e, 0x0a, 0xe5, - 0xb2, 0x65, 0x7a, 0x89, 0x4e, 0xb6, 0x47, 0xff, - 0x1c, 0xbd, 0xb7, 0x38, 0x13, 0xaf, 0x47, 0x85, - 0x84, 0x32, 0x33, 0xf3, 0x17, 0x49, 0xbf, 0xe9, - 0x96, 0xd0, 0xd6, 0x14, 0x6f, 0x13, 0x8d, 0xc5, - 0xfc, 0x2c, 0x72, 0xba, 0xac, 0xea, 0x7e, 0x18, - 0x53, 0x56, 0xa6, 0x83, 0xa2, 0xce, 0x93, 0x93, - 0xe7, 0x1f, 0x0f, 0xe6, 0x0f, 0x02, 0x03, 0x01, - 0x00, 0x01 - }; - - std::vector<uint8> input; - input.resize(sizeof(private_key_info)); - memcpy(&input.front(), private_key_info, sizeof(private_key_info)); - - scoped_ptr<base::RSAPrivateKey> key( - base::RSAPrivateKey::CreateFromPrivateKeyInfo(input)); - ASSERT_TRUE(key.get()); - - std::vector<uint8> output; - ASSERT_TRUE(key->ExportPublicKey(&output)); - - ASSERT_TRUE( - memcmp(expected_public_key_info, &output.front(), output.size()) == 0); -} - -// These two test keys each contain an integer that has 0x00 for its most -// significant byte. When encoded as ASN.1, this byte is dropped and there are -// two interesting sub-cases. When the sign bit of the integer is set, an extra -// null byte is added back to force the encoded value to be positive. When the -// sign bit is not set, the encoded integer is just left shorter than usual. -// See also: http://code.google.com/p/chromium/issues/detail?id=14877. -// -// Before we were handling this correctly, we would see one of two failures: -// * RSAPrivateKey::CreateFromPrivateKeyInfo would return null because the -// underlying windows API failed to import the key. -// * The import would succeed, but incorrectly interpret the data. On export, -// the key would contain different values. -// -// This test case verifies these two failures modes don't occur. -TEST(RSAPrivateKeyUnitTest, ShortIntegers) { - const uint8 short_integer_with_high_bit[] = { - 0x30, 0x82, 0x02, 0x77, 0x02, 0x01, 0x00, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, - 0x02, 0x61, 0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, - 0x00, 0x02, 0x81, 0x81, 0x00, 0x92, 0x59, 0x32, - 0x7d, 0x8e, 0xaf, 0x2e, 0xd5, 0xb2, 0x5c, 0x67, - 0xc8, 0x7d, 0x48, 0xb7, 0x84, 0x12, 0xd0, 0x76, - 0xda, 0xe1, 0xa3, 0x1e, 0x40, 0x01, 0x14, 0x5c, - 0xef, 0x26, 0x6e, 0x28, 0xa2, 0xf7, 0xa5, 0xb4, - 0x02, 0x37, 0xd0, 0x53, 0x10, 0xcb, 0x7c, 0x6a, - 0xf4, 0x53, 0x9f, 0xb8, 0xe0, 0x83, 0x93, 0xd1, - 0x19, 0xd8, 0x28, 0xd1, 0xd1, 0xd8, 0x87, 0x8f, - 0x92, 0xfd, 0x73, 0xc0, 0x4d, 0x3e, 0x07, 0x22, - 0x1f, 0xc1, 0x20, 0xb0, 0x70, 0xb2, 0x3b, 0xea, - 0xb1, 0xe5, 0x0a, 0xfd, 0x56, 0x49, 0x5e, 0x39, - 0x90, 0x91, 0xce, 0x04, 0x83, 0x29, 0xaa, 0xfd, - 0x12, 0xa4, 0x42, 0x26, 0x6c, 0x6e, 0x79, 0x70, - 0x77, 0x03, 0xb2, 0x07, 0x01, 0x3d, 0x85, 0x81, - 0x95, 0x9e, 0xda, 0x5a, 0xa3, 0xf4, 0x2d, 0x38, - 0x04, 0x58, 0xf5, 0x6b, 0xc9, 0xf1, 0xb5, 0x65, - 0xfe, 0x66, 0x0d, 0xa2, 0xd5, 0x02, 0x03, 0x01, - 0x00, 0x01, 0x02, 0x81, 0x80, 0x5e, 0x01, 0x5f, - 0xb6, 0x59, 0x1d, 0xdc, 0x36, 0xb6, 0x60, 0x36, - 0xe6, 0x08, 0xdb, 0xd9, 0xcd, 0xc3, 0x8c, 0x16, - 0x9c, 0x98, 0x8d, 0x7f, 0xd3, 0xdb, 0x1d, 0xaa, - 0x68, 0x8f, 0xc5, 0xf8, 0xe2, 0x5d, 0xb3, 0x19, - 0xc2, 0xc6, 0xf9, 0x51, 0x32, 0x1b, 0x93, 0x6a, - 0xdc, 0x50, 0x8e, 0xeb, 0x61, 0x84, 0x03, 0x42, - 0x30, 0x98, 0xb1, 0xf7, 0xbd, 0x14, 0x9a, 0x57, - 0x36, 0x33, 0x09, 0xd4, 0x3e, 0x90, 0xda, 0xef, - 0x09, 0x6e, 0xef, 0x49, 0xb6, 0x60, 0x68, 0x5e, - 0x54, 0x17, 0x25, 0x5b, 0x37, 0xe3, 0x35, 0x63, - 0x5b, 0x60, 0x3c, 0xbd, 0x50, 0xdf, 0x46, 0x43, - 0x08, 0xa4, 0x71, 0x21, 0xf1, 0x30, 0x71, 0xdc, - 0xda, 0xd7, 0x6f, 0xd2, 0x18, 0xbd, 0x39, 0xf1, - 0xe1, 0xbe, 0xa8, 0x8d, 0x62, 0xdf, 0xa2, 0x3e, - 0xb6, 0x15, 0x26, 0xb6, 0x57, 0xbd, 0x63, 0xdb, - 0xc1, 0x91, 0xec, 0xb8, 0x01, 0x02, 0x41, 0x00, - 0xc6, 0x1a, 0x06, 0x48, 0xf2, 0x12, 0x1c, 0x9f, - 0x74, 0x20, 0x5c, 0x85, 0xa2, 0xda, 0xe5, 0x62, - 0x96, 0x8d, 0x22, 0x7b, 0x78, 0x73, 0xea, 0xbb, - 0x9f, 0x59, 0x42, 0x13, 0x15, 0xc8, 0x11, 0x50, - 0x6c, 0x55, 0xf6, 0xdf, 0x8b, 0xfe, 0xc7, 0xdd, - 0xa8, 0xca, 0x54, 0x41, 0xe8, 0xce, 0xbe, 0x7d, - 0xbd, 0xe2, 0x13, 0x4b, 0x5b, 0x61, 0xeb, 0x69, - 0x6c, 0xb1, 0x9b, 0x28, 0x68, 0x5b, 0xd6, 0x01, - 0x02, 0x41, 0x00, 0xbd, 0x1e, 0xfe, 0x51, 0x99, - 0xb6, 0xe3, 0x84, 0xfe, 0xf1, 0x9e, 0xfd, 0x9c, - 0xe7, 0x86, 0x43, 0x68, 0x7f, 0x2f, 0x6a, 0x2a, - 0x4c, 0xae, 0xa6, 0x41, 0x1c, 0xf0, 0x10, 0x37, - 0x54, 0x23, 0xba, 0x05, 0x0d, 0x18, 0x27, 0x8d, - 0xb8, 0xe4, 0x8f, 0xf2, 0x25, 0x73, 0x8a, 0xd7, - 0x05, 0x98, 0x6b, 0x3d, 0x55, 0xb7, 0x6f, 0x7c, - 0xec, 0x77, 0x61, 0x54, 0x7b, 0xb6, 0x6b, 0x31, - 0xec, 0x94, 0xd5, 0x02, 0x41, 0x00, 0x90, 0xa2, - 0xa5, 0x9e, 0x12, 0xa7, 0x68, 0xa0, 0x7e, 0xdf, - 0xb5, 0xcd, 0x98, 0x26, 0xab, 0xbd, 0xbc, 0x5f, - 0xd5, 0x22, 0x42, 0xc2, 0x97, 0x4a, 0x5f, 0x40, - 0x82, 0xfe, 0x7e, 0x33, 0xb1, 0x78, 0x7f, 0x70, - 0x90, 0x2b, 0x8d, 0x01, 0xfb, 0x18, 0xfa, 0x48, - 0xa7, 0x15, 0xec, 0x0d, 0x2e, 0x85, 0x8d, 0xe2, - 0x86, 0xe5, 0xc9, 0x15, 0x88, 0x14, 0x53, 0xd8, - 0xa4, 0x88, 0xef, 0x10, 0xc6, 0x01, 0x02, 0x41, - 0x00, 0xba, 0xe4, 0xaf, 0x14, 0xfa, 0xdf, 0xf6, - 0xd5, 0xce, 0x8f, 0xfe, 0xbb, 0xc8, 0x5c, 0x30, - 0x9d, 0xda, 0xdd, 0x9d, 0x80, 0xc0, 0x0e, 0x89, - 0xa5, 0xb8, 0xc1, 0x1d, 0x28, 0x19, 0x55, 0x67, - 0xfd, 0x03, 0xd2, 0xdd, 0xe4, 0xf0, 0xb4, 0x20, - 0x03, 0x74, 0x9b, 0xb8, 0x24, 0x23, 0xbb, 0xde, - 0xd5, 0x53, 0x86, 0xaa, 0xc1, 0x5d, 0x65, 0xdd, - 0xcf, 0xec, 0x8a, 0x59, 0x4a, 0x73, 0xca, 0xc5, - 0x85, 0x02, 0x40, 0x00, 0xc4, 0x5e, 0x8d, 0xa4, - 0xea, 0xbb, 0x6a, 0x9b, 0xe6, 0x3a, 0x4d, 0xc1, - 0xdb, 0xe5, 0x52, 0x38, 0xf9, 0x59, 0x91, 0x2d, - 0x90, 0x82, 0xe3, 0x31, 0x1b, 0x48, 0xb7, 0x42, - 0xfa, 0x1d, 0x83, 0xd5, 0x3d, 0x02, 0xc2, 0x12, - 0x71, 0x10, 0x3a, 0xbd, 0x92, 0x8f, 0x9b, 0xa2, - 0x6b, 0x2d, 0x21, 0xa4, 0x65, 0xe9, 0xfa, 0x8c, - 0x30, 0x2a, 0x89, 0xce, 0xd0, 0xa7, 0x67, 0xd8, - 0x45, 0x84, 0xb0 - }; - - const uint8 short_integer_without_high_bit[] = { - 0x30, 0x82, 0x02, 0x76, 0x02, 0x01, 0x00, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, - 0x02, 0x60, 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, - 0x00, 0x02, 0x81, 0x81, 0x00, 0xc3, 0x9e, 0x8d, - 0xc4, 0x6d, 0x38, 0xe8, 0x0e, 0x9f, 0x84, 0x03, - 0x40, 0x8e, 0x81, 0x2e, 0x56, 0x67, 0x78, 0x11, - 0x85, 0x27, 0x81, 0x52, 0xf2, 0x1b, 0x3e, 0x5b, - 0xf8, 0xab, 0xfc, 0xaf, 0xca, 0x5c, 0x26, 0xd5, - 0xfa, 0xd4, 0x55, 0x50, 0x38, 0xb9, 0x9d, 0x89, - 0x92, 0x7e, 0x34, 0xcf, 0x37, 0x82, 0x48, 0x2d, - 0xaa, 0xc4, 0x6a, 0x0e, 0x93, 0xea, 0xad, 0x8a, - 0x33, 0xf0, 0x42, 0x23, 0xe0, 0x4c, 0x98, 0xbf, - 0x01, 0x00, 0x1b, 0xfe, 0x06, 0x15, 0xc6, 0xe3, - 0x80, 0x79, 0x6d, 0xfe, 0x48, 0xcd, 0x40, 0xbb, - 0xf9, 0x58, 0xe6, 0xbf, 0xd5, 0x4c, 0x29, 0x48, - 0x53, 0x78, 0x06, 0x03, 0x0d, 0x59, 0xf5, 0x20, - 0xe0, 0xe6, 0x8c, 0xb2, 0xf5, 0xd8, 0x61, 0x52, - 0x7e, 0x40, 0x83, 0xd7, 0x69, 0xae, 0xd7, 0x75, - 0x02, 0x2d, 0x49, 0xd5, 0x15, 0x5b, 0xf1, 0xd9, - 0x4d, 0x60, 0x7d, 0x62, 0xa5, 0x02, 0x03, 0x01, - 0x00, 0x01, 0x02, 0x7f, 0x6d, 0x45, 0x23, 0xeb, - 0x95, 0x17, 0x34, 0x88, 0xf6, 0x91, 0xc7, 0x3f, - 0x48, 0x5a, 0xe0, 0x87, 0x63, 0x44, 0xae, 0x84, - 0xb2, 0x8c, 0x8a, 0xc8, 0xb2, 0x6f, 0x22, 0xf0, - 0xc5, 0x21, 0x61, 0x10, 0xa8, 0x69, 0x09, 0x1e, - 0x13, 0x7d, 0x94, 0x52, 0x1b, 0x5c, 0xe4, 0x7b, - 0xf0, 0x03, 0x8f, 0xbc, 0x72, 0x09, 0xdf, 0x78, - 0x84, 0x3e, 0xb9, 0xe5, 0xe6, 0x31, 0x0a, 0x01, - 0xf9, 0x32, 0xf8, 0xd6, 0x57, 0xa3, 0x87, 0xe6, - 0xf5, 0x98, 0xbc, 0x8e, 0x41, 0xb9, 0x50, 0x17, - 0x7b, 0xd3, 0x97, 0x5a, 0x44, 0x3a, 0xee, 0xff, - 0x6b, 0xb3, 0x3a, 0x52, 0xe7, 0xa4, 0x96, 0x9a, - 0xf6, 0x83, 0xc8, 0x97, 0x1c, 0x63, 0xa1, 0xd6, - 0xb3, 0xa8, 0xb2, 0xc7, 0x73, 0x25, 0x0f, 0x58, - 0x36, 0xb9, 0x7a, 0x47, 0xa7, 0x4d, 0x30, 0xfe, - 0x4d, 0x74, 0x56, 0xe8, 0xfb, 0xd6, 0x50, 0xe5, - 0xe0, 0x28, 0x15, 0x02, 0x41, 0x00, 0xeb, 0x15, - 0x62, 0xb6, 0x37, 0x41, 0x7c, 0xc5, 0x00, 0x22, - 0x2c, 0x5a, 0x5e, 0xe4, 0xb2, 0x11, 0x87, 0x89, - 0xad, 0xf4, 0x57, 0x68, 0x90, 0xb7, 0x9f, 0xe2, - 0x79, 0x20, 0x6b, 0x98, 0x00, 0x0d, 0x3a, 0x3b, - 0xc1, 0xcd, 0x36, 0xf9, 0x27, 0xda, 0x40, 0x36, - 0x1d, 0xb8, 0x5c, 0x96, 0xeb, 0x04, 0x08, 0xe1, - 0x3f, 0xfa, 0x94, 0x8b, 0x0f, 0xa0, 0xff, 0xc1, - 0x51, 0xea, 0x90, 0xad, 0x15, 0xc7, 0x02, 0x41, - 0x00, 0xd5, 0x06, 0x45, 0xd7, 0x55, 0x63, 0x1a, - 0xf0, 0x89, 0x81, 0xae, 0x87, 0x23, 0xa2, 0x39, - 0xfe, 0x3d, 0x82, 0xc7, 0xcb, 0x15, 0xb9, 0xe3, - 0xe2, 0x5b, 0xc6, 0xd2, 0x55, 0xdd, 0xab, 0x55, - 0x29, 0x7c, 0xda, 0x0e, 0x1c, 0x09, 0xfc, 0x73, - 0x0d, 0x01, 0xed, 0x6d, 0x2f, 0x05, 0xd0, 0xd5, - 0x1d, 0xce, 0x18, 0x7f, 0xb0, 0xc8, 0x47, 0x77, - 0xd2, 0xa9, 0x9e, 0xfc, 0x39, 0x4b, 0x3d, 0x94, - 0x33, 0x02, 0x41, 0x00, 0x8f, 0x94, 0x09, 0x2d, - 0x17, 0x44, 0x75, 0x0a, 0xf1, 0x10, 0xee, 0x1b, - 0xe7, 0xd7, 0x2f, 0xf6, 0xca, 0xdc, 0x49, 0x15, - 0x72, 0x09, 0x58, 0x51, 0xfe, 0x61, 0xd8, 0xee, - 0xf7, 0x27, 0xe7, 0xe8, 0x2c, 0x47, 0xf1, 0x0f, - 0x00, 0x63, 0x5e, 0x76, 0xcb, 0x3f, 0x02, 0x19, - 0xe6, 0xda, 0xfa, 0x01, 0x05, 0xd7, 0x65, 0x37, - 0x0b, 0x60, 0x7f, 0x94, 0x2a, 0x80, 0x8d, 0x22, - 0x81, 0x68, 0x65, 0x63, 0x02, 0x41, 0x00, 0xc2, - 0xd4, 0x18, 0xde, 0x47, 0x9e, 0xfb, 0x8d, 0x91, - 0x05, 0xc5, 0x3c, 0x9d, 0xcf, 0x8a, 0x60, 0xc7, - 0x9b, 0x2b, 0xe5, 0xc6, 0xba, 0x1b, 0xfc, 0xf3, - 0xd9, 0x54, 0x97, 0xe9, 0xc4, 0x00, 0x80, 0x90, - 0x4a, 0xd2, 0x6a, 0xbc, 0x8b, 0x62, 0x22, 0x3c, - 0x68, 0x0c, 0xda, 0xdb, 0xe3, 0xd2, 0x76, 0x8e, - 0xff, 0x03, 0x12, 0x09, 0x2a, 0xac, 0x21, 0x44, - 0xb7, 0x3e, 0x91, 0x9c, 0x09, 0xf6, 0xd7, 0x02, - 0x41, 0x00, 0xc0, 0xa1, 0xbb, 0x70, 0xdc, 0xf8, - 0xeb, 0x17, 0x61, 0xd4, 0x8c, 0x7c, 0x3b, 0x82, - 0x91, 0x58, 0xff, 0xf9, 0x19, 0xac, 0x3a, 0x73, - 0xa7, 0x20, 0xe5, 0x22, 0x02, 0xc4, 0xf6, 0xb9, - 0xb9, 0x43, 0x53, 0x35, 0x88, 0xe1, 0x05, 0xb6, - 0x43, 0x9b, 0x39, 0xc8, 0x04, 0x4d, 0x2b, 0x01, - 0xf7, 0xe6, 0x1b, 0x8d, 0x7e, 0x89, 0xe3, 0x43, - 0xd4, 0xf3, 0xab, 0x28, 0xd4, 0x5a, 0x1f, 0x20, - 0xea, 0xbe - }; - - std::vector<uint8> input1; - std::vector<uint8> input2; - - input1.resize(sizeof(short_integer_with_high_bit)); - input2.resize(sizeof(short_integer_without_high_bit)); - - memcpy(&input1.front(), short_integer_with_high_bit, - sizeof(short_integer_with_high_bit)); - memcpy(&input2.front(), short_integer_without_high_bit, - sizeof(short_integer_without_high_bit)); - - scoped_ptr<base::RSAPrivateKey> keypair1( - base::RSAPrivateKey::CreateFromPrivateKeyInfo(input1)); - scoped_ptr<base::RSAPrivateKey> keypair2( - base::RSAPrivateKey::CreateFromPrivateKeyInfo(input2)); - ASSERT_TRUE(keypair1.get()); - ASSERT_TRUE(keypair2.get()); - - std::vector<uint8> output1; - std::vector<uint8> output2; - ASSERT_TRUE(keypair1->ExportPrivateKey(&output1)); - ASSERT_TRUE(keypair2->ExportPrivateKey(&output2)); - - ASSERT_EQ(input1.size(), output1.size()); - ASSERT_EQ(input2.size(), output2.size()); - ASSERT_TRUE(0 == memcmp(&output1.front(), &input1.front(), - input1.size())); - ASSERT_TRUE(0 == memcmp(&output2.front(), &input2.front(), - input2.size())); -} diff --git a/base/crypto/rsa_private_key_win.cc b/base/crypto/rsa_private_key_win.cc deleted file mode 100644 index 20e91a9..0000000 --- a/base/crypto/rsa_private_key_win.cc +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright (c) 2011 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/rsa_private_key.h" - -#include <list> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/string_util.h" - -namespace { - // Helper for error handling during key import. -#define READ_ASSERT(truth) \ - if (!(truth)) { \ - NOTREACHED(); \ - return false; \ - } -} // namespace - -namespace base { - -// static -RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { - scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); - if (!result->InitProvider()) - return NULL; - - DWORD flags = CRYPT_EXPORTABLE; - - // The size is encoded as the upper 16 bits of the flags. :: sigh ::. - flags |= (num_bits << 16); - if (!CryptGenKey(result->provider_, CALG_RSA_SIGN, flags, - result->key_.receive())) - return NULL; - - return result.release(); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( - const std::vector<uint8>& input) { - scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); - if (!result->InitProvider()) - return NULL; - - PrivateKeyInfoCodec pki(false); // Little-Endian - pki.Import(input); - - int blob_size = sizeof(PUBLICKEYSTRUC) + - sizeof(RSAPUBKEY) + - pki.modulus()->size() + - pki.prime1()->size() + - pki.prime2()->size() + - pki.exponent1()->size() + - pki.exponent2()->size() + - pki.coefficient()->size() + - pki.private_exponent()->size(); - scoped_array<BYTE> blob(new BYTE[blob_size]); - - uint8* dest = blob.get(); - PUBLICKEYSTRUC* public_key_struc = reinterpret_cast<PUBLICKEYSTRUC*>(dest); - public_key_struc->bType = PRIVATEKEYBLOB; - public_key_struc->bVersion = 0x02; - public_key_struc->reserved = 0; - public_key_struc->aiKeyAlg = CALG_RSA_SIGN; - dest += sizeof(PUBLICKEYSTRUC); - - RSAPUBKEY* rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(dest); - rsa_pub_key->magic = 0x32415352; - rsa_pub_key->bitlen = pki.modulus()->size() * 8; - int public_exponent_int = 0; - for (size_t i = pki.public_exponent()->size(); i > 0; --i) { - public_exponent_int <<= 8; - public_exponent_int |= (*pki.public_exponent())[i - 1]; - } - rsa_pub_key->pubexp = public_exponent_int; - dest += sizeof(RSAPUBKEY); - - memcpy(dest, &pki.modulus()->front(), pki.modulus()->size()); - dest += pki.modulus()->size(); - memcpy(dest, &pki.prime1()->front(), pki.prime1()->size()); - dest += pki.prime1()->size(); - memcpy(dest, &pki.prime2()->front(), pki.prime2()->size()); - dest += pki.prime2()->size(); - memcpy(dest, &pki.exponent1()->front(), pki.exponent1()->size()); - dest += pki.exponent1()->size(); - memcpy(dest, &pki.exponent2()->front(), pki.exponent2()->size()); - dest += pki.exponent2()->size(); - memcpy(dest, &pki.coefficient()->front(), pki.coefficient()->size()); - dest += pki.coefficient()->size(); - memcpy(dest, &pki.private_exponent()->front(), - pki.private_exponent()->size()); - dest += pki.private_exponent()->size(); - - READ_ASSERT(dest == blob.get() + blob_size); - if (!CryptImportKey(result->provider_, - reinterpret_cast<uint8*>(public_key_struc), blob_size, 0, - CRYPT_EXPORTABLE, result->key_.receive())) - return NULL; - - return result.release(); -} - -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -// static -RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( - const std::vector<uint8>& input) { - NOTIMPLEMENTED(); - return NULL; -} - -RSAPrivateKey::RSAPrivateKey() : provider_(NULL), key_(NULL) {} - -RSAPrivateKey::~RSAPrivateKey() {} - -bool RSAPrivateKey::InitProvider() { - return FALSE != CryptAcquireContext(provider_.receive(), NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); -} - -bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { - // Export the key - DWORD blob_length = 0; - if (!CryptExportKey(key_, 0, PRIVATEKEYBLOB, 0, NULL, &blob_length)) { - NOTREACHED(); - return false; - } - - scoped_array<uint8> blob(new uint8[blob_length]); - if (!CryptExportKey(key_, 0, PRIVATEKEYBLOB, 0, blob.get(), &blob_length)) { - NOTREACHED(); - return false; - } - - uint8* pos = blob.get(); - PUBLICKEYSTRUC *publickey_struct = reinterpret_cast<PUBLICKEYSTRUC*>(pos); - pos += sizeof(PUBLICKEYSTRUC); - - RSAPUBKEY *rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(pos); - pos += sizeof(RSAPUBKEY); - - int mod_size = rsa_pub_key->bitlen / 8; - int primes_size = rsa_pub_key->bitlen / 16; - - PrivateKeyInfoCodec pki(false); // Little-Endian - - pki.modulus()->assign(pos, pos + mod_size); - pos += mod_size; - - pki.prime1()->assign(pos, pos + primes_size); - pos += primes_size; - pki.prime2()->assign(pos, pos + primes_size); - pos += primes_size; - - pki.exponent1()->assign(pos, pos + primes_size); - pos += primes_size; - pki.exponent2()->assign(pos, pos + primes_size); - pos += primes_size; - - pki.coefficient()->assign(pos, pos + primes_size); - pos += primes_size; - - pki.private_exponent()->assign(pos, pos + mod_size); - pos += mod_size; - - pki.public_exponent()->assign(reinterpret_cast<uint8*>(&rsa_pub_key->pubexp), - reinterpret_cast<uint8*>(&rsa_pub_key->pubexp) + 4); - - CHECK_EQ(pos - blob_length, reinterpret_cast<BYTE*>(publickey_struct)); - - return pki.Export(output); -} - -bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { - DWORD key_info_len; - if (!CryptExportPublicKeyInfo( - provider_, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - NULL, &key_info_len)) { - NOTREACHED(); - return false; - } - - scoped_array<uint8> key_info(new uint8[key_info_len]); - if (!CryptExportPublicKeyInfo( - provider_, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), &key_info_len)) { - NOTREACHED(); - return false; - } - - DWORD encoded_length; - if (!CryptEncodeObject( - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, - reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), NULL, - &encoded_length)) { - NOTREACHED(); - return false; - } - - scoped_array<BYTE> encoded(new BYTE[encoded_length]); - if (!CryptEncodeObject( - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, - reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), encoded.get(), - &encoded_length)) { - NOTREACHED(); - return false; - } - - for (size_t i = 0; i < encoded_length; ++i) - output->push_back(encoded[i]); - - return true; -} - -} // namespace base diff --git a/base/crypto/scoped_capi_types.h b/base/crypto/scoped_capi_types.h deleted file mode 100644 index d6582a7b..0000000 --- a/base/crypto/scoped_capi_types.h +++ /dev/null @@ -1,125 +0,0 @@ -// 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_SCOPED_CAPI_TYPES_H_ -#define BASE_CRYPTO_SCOPED_CAPI_TYPES_H_ -#pragma once - -#include <windows.h> -#include <wincrypt.h> - -#include <algorithm> - -#include "base/logging.h" - -namespace base { - -// Simple destructor for the Free family of CryptoAPI functions, such as -// CryptDestroyHash, which take only a single argument to release. -template <typename CAPIHandle, BOOL (WINAPI *Destroyer)(CAPIHandle)> -struct CAPIDestroyer { - void operator()(CAPIHandle handle) const { - if (handle) { - BOOL ok = Destroyer(handle); - DCHECK(ok); - } - } -}; - -// Destructor for the Close/Release family of CryptoAPI functions, which take -// a second DWORD parameter indicating flags to use when closing or releasing. -// This includes functions like CertCloseStore or CryptReleaseContext. -template <typename CAPIHandle, BOOL (WINAPI *Destroyer)(CAPIHandle, DWORD), - DWORD flags> -struct CAPIDestroyerWithFlags { - void operator()(CAPIHandle handle) const { - if (handle) { - BOOL ok = Destroyer(handle, flags); - DCHECK(ok); - } - } -}; - -// scoped_ptr-like class for the CryptoAPI cryptography and certificate -// handles. Because these handles are defined as integer types, and not -// pointers, the existing scoped classes, such as scoped_ptr_malloc, are -// insufficient. The semantics are the same as scoped_ptr. -template <class CAPIHandle, typename FreeProc> -class ScopedCAPIHandle { - public: - explicit ScopedCAPIHandle(CAPIHandle handle = NULL) : handle_(handle) {} - - ~ScopedCAPIHandle() { - free_(handle_); - } - - void reset(CAPIHandle handle = NULL) { - if (handle_ != handle) { - free_(handle_); - handle_ = handle; - } - } - - operator CAPIHandle() const { return handle_; } - CAPIHandle get() const { return handle_; } - - CAPIHandle* receive() { - CHECK(handle_ == NULL); - return &handle_; - } - - bool operator==(CAPIHandle handle) const { - return handle_ == handle; - } - - bool operator!=(CAPIHandle handle) const { - return handle_ != handle; - } - - void swap(ScopedCAPIHandle& b) { - CAPIHandle tmp = b.handle_; - b.handle_ = handle_; - handle_ = tmp; - } - - CAPIHandle release() { - CAPIHandle tmp = handle_; - handle_ = NULL; - return tmp; - } - - private: - CAPIHandle handle_; - static const FreeProc free_; - - DISALLOW_COPY_AND_ASSIGN(ScopedCAPIHandle); -}; - -template<class CH, typename FP> -const FP ScopedCAPIHandle<CH, FP>::free_ = FP(); - -template<class CH, typename FP> inline -bool operator==(CH h, const ScopedCAPIHandle<CH, FP>& b) { - return h == b.get(); -} - -template<class CH, typename FP> inline -bool operator!=(CH h, const ScopedCAPIHandle<CH, FP>& b) { - return h != b.get(); -} - -typedef ScopedCAPIHandle< - HCRYPTPROV, - CAPIDestroyerWithFlags<HCRYPTPROV, - CryptReleaseContext, 0> > ScopedHCRYPTPROV; - -typedef ScopedCAPIHandle< - HCRYPTKEY, CAPIDestroyer<HCRYPTKEY, CryptDestroyKey> > ScopedHCRYPTKEY; - -typedef ScopedCAPIHandle< - HCRYPTHASH, CAPIDestroyer<HCRYPTHASH, CryptDestroyHash> > ScopedHCRYPTHASH; - -} // namespace base - -#endif // BASE_CRYPTO_SCOPED_CAPI_TYPES_H_ diff --git a/base/crypto/scoped_nss_types.h b/base/crypto/scoped_nss_types.h deleted file mode 100644 index 4a77f88..0000000 --- a/base/crypto/scoped_nss_types.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2011 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_ -#pragma once - -#include <nss.h> -#include <pk11pub.h> - -#include "base/memory/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< - 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; -typedef scoped_ptr_malloc< - SECAlgorithmID, NSSDestroyer1<SECAlgorithmID, - SECOID_DestroyAlgorithmID, - PR_TRUE> > ScopedSECAlgorithmID; -typedef scoped_ptr_malloc< - SECItem, NSSDestroyer1<SECItem, - SECITEM_FreeItem, - PR_TRUE> > ScopedSECItem; - -} // namespace base - -#endif // BASE_SCOPED_NSS_TYPES_H_ diff --git a/base/crypto/secure_hash.h b/base/crypto/secure_hash.h deleted file mode 100644 index 904d163..0000000 --- a/base/crypto/secure_hash.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2011 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_SECURE_HASH_H_ -#define BASE_CRYPTO_SECURE_HASH_H_ -#pragma once - -#include "base/base_api.h" -#include "base/basictypes.h" - -namespace base { - -// A wrapper to calculate secure hashes incrementally, allowing to -// be used when the full input is not known in advance. -class BASE_API SecureHash { - public: - enum Algorithm { - SHA256, - }; - virtual ~SecureHash() {} - - static SecureHash* Create(Algorithm type); - - virtual void Update(const void* input, size_t len) = 0; - virtual void Finish(void* output, size_t len) = 0; - - protected: - SecureHash() {} - - private: - DISALLOW_COPY_AND_ASSIGN(SecureHash); -}; - -} // namespace base - -#endif // BASE_CRYPTO_SECURE_HASH_H_ diff --git a/base/crypto/secure_hash_default.cc b/base/crypto/secure_hash_default.cc deleted file mode 100644 index 436867e..0000000 --- a/base/crypto/secure_hash_default.cc +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2011 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/secure_hash.h" - -#include "base/logging.h" -#include "base/third_party/nss/blapi.h" -#include "base/third_party/nss/sha256.h" - -namespace base { - -namespace { - -class SecureHashSHA256NSS : public SecureHash { - public: - SecureHashSHA256NSS() { - SHA256_Begin(&ctx_); - } - - virtual ~SecureHashSHA256NSS() { - } - - virtual void Update(const void* input, size_t len) { - SHA256_Update(&ctx_, static_cast<const unsigned char*>(input), len); - } - - virtual void Finish(void* output, size_t len) { - SHA256_End(&ctx_, static_cast<unsigned char*>(output), NULL, - static_cast<unsigned int>(len)); - } - - private: - SHA256Context ctx_; -}; - -} // namespace - -SecureHash* SecureHash::Create(Algorithm algorithm) { - switch (algorithm) { - case SHA256: - return new SecureHashSHA256NSS(); - default: - NOTIMPLEMENTED(); - return NULL; - } -} - -} // namespace base diff --git a/base/crypto/secure_hash_openssl.cc b/base/crypto/secure_hash_openssl.cc deleted file mode 100644 index 8087279..0000000 --- a/base/crypto/secure_hash_openssl.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2011 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/secure_hash.h" - -#include <openssl/ssl.h> - -#include "base/basictypes.h" -#include "base/logging.h" -#include "base/openssl_util.h" - -namespace base { - -namespace { - -class SecureHashSHA256OpenSSL : public SecureHash { - public: - SecureHashSHA256OpenSSL() { - SHA256_Init(&ctx_); - } - - virtual ~SecureHashSHA256OpenSSL() { - OPENSSL_cleanse(&ctx_, sizeof(ctx_)); - } - - virtual void Update(const void* input, size_t len) { - SHA256_Update(&ctx_, static_cast<const unsigned char*>(input), len); - } - - virtual void Finish(void* output, size_t len) { - ScopedOpenSSLSafeSizeBuffer<SHA256_DIGEST_LENGTH> result( - static_cast<unsigned char*>(output), len); - SHA256_Final(result.safe_buffer(), &ctx_); - } - - private: - SHA256_CTX ctx_; -}; - -} // namespace - -SecureHash* SecureHash::Create(Algorithm algorithm) { - switch (algorithm) { - case SHA256: - return new SecureHashSHA256OpenSSL(); - default: - NOTIMPLEMENTED(); - return NULL; - } -} - -} // namespace base diff --git a/base/crypto/secure_hash_unittest.cc b/base/crypto/secure_hash_unittest.cc deleted file mode 100644 index ca46dac..0000000 --- a/base/crypto/secure_hash_unittest.cc +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2011 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/secure_hash.h" - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "base/sha2.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(SecureHashTest, TestUpdate) { - // Example B.3 from FIPS 180-2: long message. - std::string input3(500000, 'a'); // 'a' repeated half a million times - int expected3[] = { 0xcd, 0xc7, 0x6e, 0x5c, - 0x99, 0x14, 0xfb, 0x92, - 0x81, 0xa1, 0xc7, 0xe2, - 0x84, 0xd7, 0x3e, 0x67, - 0xf1, 0x80, 0x9a, 0x48, - 0xa4, 0x97, 0x20, 0x0e, - 0x04, 0x6d, 0x39, 0xcc, - 0xc7, 0x11, 0x2c, 0xd0 }; - - uint8 output3[base::SHA256_LENGTH]; - - scoped_ptr<base::SecureHash> ctx(base::SecureHash::Create( - base::SecureHash::SHA256)); - ctx->Update(input3.data(), input3.size()); - ctx->Update(input3.data(), input3.size()); - - ctx->Finish(output3, sizeof(output3)); - for (size_t i = 0; i < base::SHA256_LENGTH; i++) - EXPECT_EQ(expected3[i], static_cast<int>(output3[i])); -} diff --git a/base/crypto/signature_creator.h b/base/crypto/signature_creator.h deleted file mode 100644 index 93cf83c..0000000 --- a/base/crypto/signature_creator.h +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2011 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_SIGNATURE_CREATOR_H_ -#define BASE_CRYPTO_SIGNATURE_CREATOR_H_ -#pragma once - -#include "build/build_config.h" - -#if defined(USE_OPENSSL) -// Forward declaration for openssl/*.h -typedef struct env_md_ctx_st EVP_MD_CTX; -#elif defined(USE_NSS) -// Forward declaration. -struct SGNContextStr; -#elif defined(OS_MACOSX) -#include <Security/cssm.h> -#endif - -#include <vector> - -#include "base/base_api.h" -#include "base/basictypes.h" -#include "base/crypto/rsa_private_key.h" - -#if defined(OS_WIN) -#include "base/crypto/scoped_capi_types.h" -#endif - -namespace base { - -// Signs data using a bare private key (as opposed to a full certificate). -// Currently can only sign data using SHA-1 with RSA encryption. -class BASE_API SignatureCreator { - public: - ~SignatureCreator(); - - // Create an instance. The caller must ensure that the provided PrivateKey - // instance outlives the created SignatureCreator. - static SignatureCreator* Create(RSAPrivateKey* key); - - // Update the signature with more data. - bool Update(const uint8* data_part, int data_part_len); - - // Finalize the signature. - bool Final(std::vector<uint8>* signature); - - private: - // Private constructor. Use the Create() method instead. - SignatureCreator(); - - RSAPrivateKey* key_; - -#if defined(USE_OPENSSL) - EVP_MD_CTX* sign_context_; -#elif defined(USE_NSS) - SGNContextStr* sign_context_; -#elif defined(OS_MACOSX) - CSSM_CC_HANDLE sig_handle_; -#elif defined(OS_WIN) - ScopedHCRYPTHASH hash_object_; -#endif - - DISALLOW_COPY_AND_ASSIGN(SignatureCreator); -}; - -} // namespace base - -#endif // BASE_CRYPTO_SIGNATURE_CREATOR_H_ diff --git a/base/crypto/signature_creator_mac.cc b/base/crypto/signature_creator_mac.cc deleted file mode 100644 index 5c2d477..0000000 --- a/base/crypto/signature_creator_mac.cc +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2011 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/signature_creator.h" - -#include <stdlib.h> - -#include "base/crypto/cssm_init.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" - -namespace base { - -// static -SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) { - scoped_ptr<SignatureCreator> result(new SignatureCreator); - result->key_ = key; - - CSSM_RETURN crtn; - crtn = CSSM_CSP_CreateSignatureContext(GetSharedCSPHandle(), - CSSM_ALGID_SHA1WithRSA, - NULL, - key->key(), - &result->sig_handle_); - if (crtn) { - NOTREACHED(); - return NULL; - } - - crtn = CSSM_SignDataInit(result->sig_handle_); - if (crtn) { - NOTREACHED(); - return NULL; - } - - return result.release(); -} - -SignatureCreator::SignatureCreator() : sig_handle_(0) { - EnsureCSSMInit(); -} - -SignatureCreator::~SignatureCreator() { - CSSM_RETURN crtn; - if (sig_handle_) { - crtn = CSSM_DeleteContext(sig_handle_); - DCHECK(crtn == CSSM_OK); - } -} - -bool SignatureCreator::Update(const uint8* data_part, int data_part_len) { - CSSM_DATA data; - data.Data = const_cast<uint8*>(data_part); - data.Length = data_part_len; - CSSM_RETURN crtn = CSSM_SignDataUpdate(sig_handle_, &data, 1); - DCHECK(crtn == CSSM_OK); - return true; -} - -bool SignatureCreator::Final(std::vector<uint8>* signature) { - ScopedCSSMData sig; - CSSM_RETURN crtn = CSSM_SignDataFinal(sig_handle_, sig); - - if (crtn) { - NOTREACHED(); - return false; - } - - signature->assign(sig->Data, sig->Data + sig->Length); - return true; -} - -} // namespace base diff --git a/base/crypto/signature_creator_nss.cc b/base/crypto/signature_creator_nss.cc deleted file mode 100644 index 92bf4d7..0000000 --- a/base/crypto/signature_creator_nss.cc +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2011 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/signature_creator.h" - -#include <cryptohi.h> -#include <keyhi.h> -#include <stdlib.h> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/nss_util.h" - -namespace base { - -SignatureCreator::~SignatureCreator() { - if (sign_context_) { - SGN_DestroyContext(sign_context_, PR_TRUE); - sign_context_ = NULL; - } -} - -// static -SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) { - scoped_ptr<SignatureCreator> result(new SignatureCreator); - result->key_ = key; - - result->sign_context_ = SGN_NewContext(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, - key->key()); - if (!result->sign_context_) { - NOTREACHED(); - return NULL; - } - - SECStatus rv = SGN_Begin(result->sign_context_); - if (rv != SECSuccess) { - NOTREACHED(); - return NULL; - } - - return result.release(); -} - -bool SignatureCreator::Update(const uint8* data_part, int data_part_len) { - // TODO(wtc): Remove this const_cast when we require NSS 3.12.5. - // See NSS bug https://bugzilla.mozilla.org/show_bug.cgi?id=518255 - SECStatus rv = SGN_Update(sign_context_, - const_cast<unsigned char*>(data_part), - data_part_len); - if (rv != SECSuccess) { - NOTREACHED(); - return false; - } - - return true; -} - -bool SignatureCreator::Final(std::vector<uint8>* signature) { - SECItem signature_item; - SECStatus rv = SGN_End(sign_context_, &signature_item); - if (rv != SECSuccess) { - NOTREACHED(); - return false; - } - signature->assign(signature_item.data, - signature_item.data + signature_item.len); - SECITEM_FreeItem(&signature_item, PR_FALSE); - return true; -} - -SignatureCreator::SignatureCreator() : sign_context_(NULL) { - EnsureNSSInit(); -} - -} // namespace base diff --git a/base/crypto/signature_creator_openssl.cc b/base/crypto/signature_creator_openssl.cc deleted file mode 100644 index cdf351f..0000000 --- a/base/crypto/signature_creator_openssl.cc +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2011 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/signature_creator.h" - -#include <openssl/evp.h> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/openssl_util.h" -#include "base/stl_util-inl.h" - -namespace base { - -// static -SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) { - OpenSSLErrStackTracer err_tracer(FROM_HERE); - scoped_ptr<SignatureCreator> result(new SignatureCreator); - result->key_ = key; - if (!EVP_SignInit_ex(result->sign_context_, EVP_sha1(), NULL)) - return NULL; - return result.release(); -} - -SignatureCreator::SignatureCreator() - : sign_context_(EVP_MD_CTX_create()) { -} - -SignatureCreator::~SignatureCreator() { - EVP_MD_CTX_destroy(sign_context_); -} - -bool SignatureCreator::Update(const uint8* data_part, int data_part_len) { - OpenSSLErrStackTracer err_tracer(FROM_HERE); - return EVP_SignUpdate(sign_context_, data_part, data_part_len) == 1; -} - -bool SignatureCreator::Final(std::vector<uint8>* signature) { - OpenSSLErrStackTracer err_tracer(FROM_HERE); - EVP_PKEY* key = key_->key(); - signature->resize(EVP_PKEY_size(key)); - - unsigned int len = 0; - int rv = EVP_SignFinal(sign_context_, vector_as_array(signature), &len, key); - if (!rv) { - signature->clear(); - return false; - } - signature->resize(len); - return true; -} - -} // namespace base diff --git a/base/crypto/signature_creator_unittest.cc b/base/crypto/signature_creator_unittest.cc deleted file mode 100644 index 644ab7f..0000000 --- a/base/crypto/signature_creator_unittest.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2011 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 <vector> - -#include "base/crypto/signature_creator.h" -#include "base/crypto/signature_verifier.h" -#include "base/memory/scoped_ptr.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(SignatureCreatorTest, BasicTest) { - // Do a verify round trip. - scoped_ptr<base::RSAPrivateKey> key_original( - base::RSAPrivateKey::Create(1024)); - ASSERT_TRUE(key_original.get()); - - std::vector<uint8> key_info; - key_original->ExportPrivateKey(&key_info); - scoped_ptr<base::RSAPrivateKey> key( - base::RSAPrivateKey::CreateFromPrivateKeyInfo(key_info)); - ASSERT_TRUE(key.get()); - - scoped_ptr<base::SignatureCreator> signer( - base::SignatureCreator::Create(key.get())); - ASSERT_TRUE(signer.get()); - - std::string data("Hello, World!"); - ASSERT_TRUE(signer->Update(reinterpret_cast<const uint8*>(data.c_str()), - data.size())); - - std::vector<uint8> signature; - ASSERT_TRUE(signer->Final(&signature)); - - std::vector<uint8> public_key_info; - ASSERT_TRUE(key_original->ExportPublicKey(&public_key_info)); - - // This is the algorithm ID for SHA-1 with RSA encryption. - // TODO(aa): Factor this out into some shared location. - const uint8 kSHA1WithRSAAlgorithmID[] = { - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00 - }; - base::SignatureVerifier verifier; - ASSERT_TRUE(verifier.VerifyInit( - kSHA1WithRSAAlgorithmID, sizeof(kSHA1WithRSAAlgorithmID), - &signature.front(), signature.size(), - &public_key_info.front(), public_key_info.size())); - - verifier.VerifyUpdate(reinterpret_cast<const uint8*>(data.c_str()), - data.size()); - ASSERT_TRUE(verifier.VerifyFinal()); -} diff --git a/base/crypto/signature_creator_win.cc b/base/crypto/signature_creator_win.cc deleted file mode 100644 index 7102007..0000000 --- a/base/crypto/signature_creator_win.cc +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2011 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/signature_creator.h" - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" - -namespace base { - -// static -SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) { - scoped_ptr<SignatureCreator> result(new SignatureCreator); - result->key_ = key; - - if (!CryptCreateHash(key->provider(), CALG_SHA1, 0, 0, - result->hash_object_.receive())) { - NOTREACHED(); - return NULL; - } - - return result.release(); -} - -SignatureCreator::SignatureCreator() : hash_object_(0) {} - -SignatureCreator::~SignatureCreator() {} - -bool SignatureCreator::Update(const uint8* data_part, int data_part_len) { - if (!CryptHashData(hash_object_, data_part, data_part_len, 0)) { - NOTREACHED(); - return false; - } - - return true; -} - -bool SignatureCreator::Final(std::vector<uint8>* signature) { - DWORD signature_length = 0; - if (!CryptSignHash(hash_object_, AT_SIGNATURE, NULL, 0, NULL, - &signature_length)) { - return false; - } - - std::vector<uint8> temp; - temp.resize(signature_length); - if (!CryptSignHash(hash_object_, AT_SIGNATURE, NULL, 0, &temp.front(), - &signature_length)) { - return false; - } - - temp.resize(signature_length); - for (size_t i = temp.size(); i > 0; --i) - signature->push_back(temp[i - 1]); - - return true; -} - -} // namespace base diff --git a/base/crypto/signature_verifier.h b/base/crypto/signature_verifier.h deleted file mode 100644 index 1a2c3e7..0000000 --- a/base/crypto/signature_verifier.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2011 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_SIGNATURE_VERIFIER_H_ -#define BASE_CRYPTO_SIGNATURE_VERIFIER_H_ -#pragma once - -#include "build/build_config.h" - -#if defined(USE_NSS) -#include <cryptoht.h> -#elif defined(OS_MACOSX) -#include <Security/cssm.h> -#endif - -#include <vector> - -#include "base/base_api.h" -#include "base/basictypes.h" - -#if defined(OS_WIN) -#include "base/crypto/scoped_capi_types.h" -#endif - -namespace base { - -// The SignatureVerifier class verifies a signature using a bare public key -// (as opposed to a certificate). -class BASE_API SignatureVerifier { - public: - SignatureVerifier(); - ~SignatureVerifier(); - - // Streaming interface: - - // Initiates a signature verification operation. This should be followed - // by one or more VerifyUpdate calls and a VerifyFinal call. - // - // The signature algorithm is specified as a DER encoded ASN.1 - // AlgorithmIdentifier structure: - // AlgorithmIdentifier ::= SEQUENCE { - // algorithm OBJECT IDENTIFIER, - // parameters ANY DEFINED BY algorithm OPTIONAL } - // - // The signature is encoded according to the signature algorithm, but it - // must not be further encoded in an ASN.1 BIT STRING. - // Note: An RSA signatures is actually a big integer. It must be in the - // big-endian byte order. - // - // The public key is specified as a DER encoded ASN.1 SubjectPublicKeyInfo - // structure, which contains not only the public key but also its type - // (algorithm): - // SubjectPublicKeyInfo ::= SEQUENCE { - // algorithm AlgorithmIdentifier, - // subjectPublicKey BIT STRING } - bool VerifyInit(const uint8* signature_algorithm, - int signature_algorithm_len, - const uint8* signature, - int signature_len, - const uint8* public_key_info, - int public_key_info_len); - - // Feeds a piece of the data to the signature verifier. - void VerifyUpdate(const uint8* data_part, int data_part_len); - - // Concludes a signature verification operation. Returns true if the - // signature is valid. Returns false if the signature is invalid or an - // error occurred. - bool VerifyFinal(); - - // Note: we can provide a one-shot interface if there is interest: - // bool Verify(const uint8* data, - // int data_len, - // const uint8* signature_algorithm, - // int signature_algorithm_len, - // const uint8* signature, - // int signature_len, - // const uint8* public_key_info, - // int public_key_info_len); - - private: - void Reset(); - - std::vector<uint8> signature_; - -#if defined(USE_OPENSSL) - struct VerifyContext; - VerifyContext* verify_context_; -#elif defined(USE_NSS) - VFYContext* vfy_context_; -#elif defined(OS_MACOSX) - std::vector<uint8> public_key_info_; - - CSSM_CC_HANDLE sig_handle_; - - CSSM_KEY public_key_; -#elif defined(OS_WIN) - ScopedHCRYPTPROV provider_; - - ScopedHCRYPTHASH hash_object_; - - ScopedHCRYPTKEY public_key_; -#endif -}; - -} // namespace base - -#endif // BASE_CRYPTO_SIGNATURE_VERIFIER_H_ diff --git a/base/crypto/signature_verifier_mac.cc b/base/crypto/signature_verifier_mac.cc deleted file mode 100644 index c8bfa8b..0000000 --- a/base/crypto/signature_verifier_mac.cc +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2009 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/signature_verifier.h" - -#include <stdlib.h> - -#include "base/crypto/cssm_init.h" -#include "base/logging.h" - -namespace base { - -SignatureVerifier::SignatureVerifier() : sig_handle_(0) { - EnsureCSSMInit(); -} - -SignatureVerifier::~SignatureVerifier() { - Reset(); -} - -bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm, - int signature_algorithm_len, - const uint8* signature, - int signature_len, - const uint8* public_key_info, - int public_key_info_len) { - signature_.assign(signature, signature + signature_len); - public_key_info_.assign(public_key_info, - public_key_info + public_key_info_len); - - CSSM_ALGORITHMS key_alg = CSSM_ALGID_RSA; // TODO(wtc): hardcoded. - - memset(&public_key_, 0, sizeof(public_key_)); - public_key_.KeyData.Data = const_cast<uint8*>(&public_key_info_[0]); - public_key_.KeyData.Length = public_key_info_.size(); - public_key_.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; - public_key_.KeyHeader.BlobType = CSSM_KEYBLOB_RAW; - public_key_.KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_X509; - public_key_.KeyHeader.AlgorithmId = key_alg; - public_key_.KeyHeader.KeyClass = CSSM_KEYCLASS_PUBLIC_KEY; - public_key_.KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE; - public_key_.KeyHeader.KeyUsage = CSSM_KEYUSE_VERIFY; - CSSM_KEY_SIZE key_size; - CSSM_RETURN crtn; - crtn = CSSM_QueryKeySizeInBits(GetSharedCSPHandle(), NULL, - &public_key_, &key_size); - if (crtn) { - NOTREACHED() << "CSSM_QueryKeySizeInBits failed: " << crtn; - return false; - } - public_key_.KeyHeader.LogicalKeySizeInBits = key_size.LogicalKeySizeInBits; - - // TODO(wtc): decode signature_algorithm... - CSSM_ALGORITHMS sig_alg = CSSM_ALGID_SHA1WithRSA; - - crtn = CSSM_CSP_CreateSignatureContext(GetSharedCSPHandle(), sig_alg, NULL, - &public_key_, &sig_handle_); - if (crtn) { - NOTREACHED(); - return false; - } - crtn = CSSM_VerifyDataInit(sig_handle_); - if (crtn) { - NOTREACHED(); - return false; - } - return true; -} - -void SignatureVerifier::VerifyUpdate(const uint8* data_part, - int data_part_len) { - CSSM_DATA data; - data.Data = const_cast<uint8*>(data_part); - data.Length = data_part_len; - CSSM_RETURN crtn = CSSM_VerifyDataUpdate(sig_handle_, &data, 1); - DCHECK(crtn == CSSM_OK); -} - -bool SignatureVerifier::VerifyFinal() { - CSSM_DATA sig; - sig.Data = const_cast<uint8*>(&signature_[0]); - sig.Length = signature_.size(); - CSSM_RETURN crtn = CSSM_VerifyDataFinal(sig_handle_, &sig); - Reset(); - - // crtn is CSSMERR_CSP_VERIFY_FAILED if signature verification fails. - return (crtn == CSSM_OK); -} - -void SignatureVerifier::Reset() { - CSSM_RETURN crtn; - if (sig_handle_) { - crtn = CSSM_DeleteContext(sig_handle_); - DCHECK(crtn == CSSM_OK); - sig_handle_ = 0; - } - signature_.clear(); - - // Can't call CSSM_FreeKey on public_key_ because we constructed - // public_key_ manually. -} - -} // namespace base - diff --git a/base/crypto/signature_verifier_nss.cc b/base/crypto/signature_verifier_nss.cc deleted file mode 100644 index 369f275..0000000 --- a/base/crypto/signature_verifier_nss.cc +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2009 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/signature_verifier.h" - -#include <cryptohi.h> -#include <keyhi.h> -#include <stdlib.h> - -#include "base/logging.h" -#include "base/nss_util.h" - -namespace base { - -SignatureVerifier::SignatureVerifier() : vfy_context_(NULL) { - EnsureNSSInit(); -} - -SignatureVerifier::~SignatureVerifier() { - Reset(); -} - -bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm, - int signature_algorithm_len, - const uint8* signature, - int signature_len, - const uint8* public_key_info, - int public_key_info_len) { - signature_.assign(signature, signature + signature_len); - - CERTSubjectPublicKeyInfo* spki = NULL; - SECItem spki_der; - spki_der.type = siBuffer; - spki_der.data = const_cast<uint8*>(public_key_info); - spki_der.len = public_key_info_len; - spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_der); - if (!spki) - return false; - SECKEYPublicKey* public_key = SECKEY_ExtractPublicKey(spki); - SECKEY_DestroySubjectPublicKeyInfo(spki); // Done with spki. - if (!public_key) - return false; - - PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (!arena) { - SECKEY_DestroyPublicKey(public_key); - return false; - } - - SECItem sig_alg_der; - sig_alg_der.type = siBuffer; - sig_alg_der.data = const_cast<uint8*>(signature_algorithm); - sig_alg_der.len = signature_algorithm_len; - SECAlgorithmID sig_alg_id; - SECStatus rv; - rv = SEC_QuickDERDecodeItem(arena, &sig_alg_id, SECOID_AlgorithmIDTemplate, - &sig_alg_der); - if (rv != SECSuccess) { - SECKEY_DestroyPublicKey(public_key); - PORT_FreeArena(arena, PR_TRUE); - return false; - } - - SECItem sig; - sig.type = siBuffer; - sig.data = const_cast<uint8*>(signature); - sig.len = signature_len; - SECOidTag hash_alg_tag; - vfy_context_ = VFY_CreateContextWithAlgorithmID(public_key, &sig, - &sig_alg_id, &hash_alg_tag, - NULL); - SECKEY_DestroyPublicKey(public_key); // Done with public_key. - PORT_FreeArena(arena, PR_TRUE); // Done with sig_alg_id. - if (!vfy_context_) { - // A corrupted RSA signature could be detected without the data, so - // VFY_CreateContextWithAlgorithmID may fail with SEC_ERROR_BAD_SIGNATURE - // (-8182). - return false; - } - - rv = VFY_Begin(vfy_context_); - if (rv != SECSuccess) { - NOTREACHED(); - return false; - } - return true; -} - -void SignatureVerifier::VerifyUpdate(const uint8* data_part, - int data_part_len) { - SECStatus rv = VFY_Update(vfy_context_, data_part, data_part_len); - DCHECK(rv == SECSuccess); -} - -bool SignatureVerifier::VerifyFinal() { - SECStatus rv = VFY_End(vfy_context_); - Reset(); - - // If signature verification fails, the error code is - // SEC_ERROR_BAD_SIGNATURE (-8182). - return (rv == SECSuccess); -} - -void SignatureVerifier::Reset() { - if (vfy_context_) { - VFY_DestroyContext(vfy_context_, PR_TRUE); - vfy_context_ = NULL; - } - signature_.clear(); -} - -} // namespace base diff --git a/base/crypto/signature_verifier_openssl.cc b/base/crypto/signature_verifier_openssl.cc deleted file mode 100644 index abfb553..0000000 --- a/base/crypto/signature_verifier_openssl.cc +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2011 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/signature_verifier.h" - -#include <openssl/evp.h> -#include <openssl/x509.h> - -#include <vector> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/openssl_util.h" -#include "base/stl_util-inl.h" - -namespace base { - -struct SignatureVerifier::VerifyContext { - ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> public_key; - ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy> ctx; -}; - -SignatureVerifier::SignatureVerifier() - : verify_context_(NULL) { -} - -SignatureVerifier::~SignatureVerifier() { - Reset(); -} - -bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm, - int signature_algorithm_len, - const uint8* signature, - int signature_len, - const uint8* public_key_info, - int public_key_info_len) { - DCHECK(!verify_context_); - verify_context_ = new VerifyContext; - OpenSSLErrStackTracer err_tracer(FROM_HERE); - - ScopedOpenSSL<X509_ALGOR, X509_ALGOR_free> algorithm( - d2i_X509_ALGOR(NULL, &signature_algorithm, signature_algorithm_len)); - if (!algorithm.get()) - return false; - - const EVP_MD* digest = EVP_get_digestbyobj(algorithm.get()->algorithm); - DCHECK(digest); - - signature_.assign(signature, signature + signature_len); - - // BIO_new_mem_buf is not const aware, but it does not modify the buffer. - char* data = reinterpret_cast<char*>(const_cast<uint8*>(public_key_info)); - ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new_mem_buf(data, - public_key_info_len)); - if (!bio.get()) - return false; - - verify_context_->public_key.reset(d2i_PUBKEY_bio(bio.get(), NULL)); - if (!verify_context_->public_key.get()) - return false; - - verify_context_->ctx.reset(EVP_MD_CTX_create()); - int rv = EVP_VerifyInit_ex(verify_context_->ctx.get(), digest, NULL); - return rv == 1; -} - -void SignatureVerifier::VerifyUpdate(const uint8* data_part, - int data_part_len) { - DCHECK(verify_context_); - OpenSSLErrStackTracer err_tracer(FROM_HERE); - int rv = EVP_VerifyUpdate(verify_context_->ctx.get(), - data_part, data_part_len); - DCHECK_EQ(rv, 1); -} - -bool SignatureVerifier::VerifyFinal() { - DCHECK(verify_context_); - OpenSSLErrStackTracer err_tracer(FROM_HERE); - int rv = EVP_VerifyFinal(verify_context_->ctx.get(), - vector_as_array(&signature_), signature_.size(), - verify_context_->public_key.get()); - DCHECK_GE(rv, 0); - Reset(); - return rv == 1; -} - -void SignatureVerifier::Reset() { - delete verify_context_; - verify_context_ = NULL; - signature_.clear(); -} - -} // namespace base diff --git a/base/crypto/signature_verifier_unittest.cc b/base/crypto/signature_verifier_unittest.cc deleted file mode 100644 index e28395f..0000000 --- a/base/crypto/signature_verifier_unittest.cc +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright (c) 2009 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/signature_verifier.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(SignatureVerifierTest, BasicTest) { - // The input data in this test comes from real certificates. - // - // tbs_certificate ("to-be-signed certificate", the part of a certificate - // that is signed), signature_algorithm, and algorithm come from the - // certificate of bugs.webkit.org. - // - // public_key_info comes from the certificate of the issuer, Go Daddy Secure - // Certification Authority. - // - // The bytes in the array initializers are formatted to expose the DER - // encoding of the ASN.1 structures. - - // The data that is signed is the following ASN.1 structure: - // TBSCertificate ::= SEQUENCE { - // ... -- omitted, not important - // } - const uint8 tbs_certificate[1017] = { - 0x30, 0x82, 0x03, 0xf5, // a SEQUENCE of length 1013 (0x3f5) - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x43, 0xdd, 0x63, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x30, 0x81, 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, - 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, - 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, - 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, - 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x27, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, - 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, - 0x03, 0x55, 0x04, 0x05, 0x13, 0x08, 0x30, 0x37, 0x39, 0x36, 0x39, 0x32, - 0x38, 0x37, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x33, 0x31, 0x38, - 0x32, 0x33, 0x33, 0x35, 0x31, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, - 0x33, 0x31, 0x38, 0x32, 0x33, 0x33, 0x35, 0x31, 0x39, 0x5a, 0x30, 0x79, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, - 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, - 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, - 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x0c, 0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x46, 0x6f, 0x72, - 0x67, 0x65, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x0c, 0x2a, 0x2e, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2e, 0x6f, 0x72, - 0x67, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, - 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xa7, 0x62, 0x79, 0x41, 0xda, 0x28, - 0xf2, 0xc0, 0x4f, 0xe0, 0x25, 0xaa, 0xa1, 0x2e, 0x3b, 0x30, 0x94, 0xb5, - 0xc9, 0x26, 0x3a, 0x1b, 0xe2, 0xd0, 0xcc, 0xa2, 0x95, 0xe2, 0x91, 0xc0, - 0xf0, 0x40, 0x9e, 0x27, 0x6e, 0xbd, 0x6e, 0xde, 0x7c, 0xb6, 0x30, 0x5c, - 0xb8, 0x9b, 0x01, 0x2f, 0x92, 0x04, 0xa1, 0xef, 0x4a, 0xb1, 0x6c, 0xb1, - 0x7e, 0x8e, 0xcd, 0xa6, 0xf4, 0x40, 0x73, 0x1f, 0x2c, 0x96, 0xad, 0xff, - 0x2a, 0x6d, 0x0e, 0xba, 0x52, 0x84, 0x83, 0xb0, 0x39, 0xee, 0xc9, 0x39, - 0xdc, 0x1e, 0x34, 0xd0, 0xd8, 0x5d, 0x7a, 0x09, 0xac, 0xa9, 0xee, 0xca, - 0x65, 0xf6, 0x85, 0x3a, 0x6b, 0xee, 0xe4, 0x5c, 0x5e, 0xf8, 0xda, 0xd1, - 0xce, 0x88, 0x47, 0xcd, 0x06, 0x21, 0xe0, 0xb9, 0x4b, 0xe4, 0x07, 0xcb, - 0x57, 0xdc, 0xca, 0x99, 0x54, 0xf7, 0x0e, 0xd5, 0x17, 0x95, 0x05, 0x2e, - 0xe9, 0xb1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xce, 0x30, - 0x82, 0x01, 0xca, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, - 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, - 0x02, 0x05, 0xa0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, - 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x57, - 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x50, 0x30, 0x4e, 0x30, 0x4c, 0xa0, - 0x4a, 0xa0, 0x48, 0x86, 0x46, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, - 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, - 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x65, 0x78, 0x74, 0x65, 0x6e, - 0x64, 0x65, 0x64, 0x69, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x33, 0x2e, - 0x63, 0x72, 0x6c, 0x30, 0x52, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4b, - 0x30, 0x49, 0x30, 0x47, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, - 0x6d, 0x01, 0x07, 0x17, 0x02, 0x30, 0x38, 0x30, 0x36, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2a, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x30, 0x7f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x01, 0x01, 0x04, 0x73, 0x30, 0x71, 0x30, 0x23, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x17, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, - 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4a, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, - 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x2e, 0x63, 0x72, 0x74, - 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x48, - 0xdf, 0x60, 0x32, 0xcc, 0x89, 0x01, 0xb6, 0xdc, 0x2f, 0xe3, 0x73, 0xb5, - 0x9c, 0x16, 0x58, 0x32, 0x68, 0xa9, 0xc3, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xfd, 0xac, 0x61, 0x32, - 0x93, 0x6c, 0x45, 0xd6, 0xe2, 0xee, 0x85, 0x5f, 0x9a, 0xba, 0xe7, 0x76, - 0x99, 0x68, 0xcc, 0xe7, 0x30, 0x23, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, - 0x1c, 0x30, 0x1a, 0x82, 0x0c, 0x2a, 0x2e, 0x77, 0x65, 0x62, 0x6b, 0x69, - 0x74, 0x2e, 0x6f, 0x72, 0x67, 0x82, 0x0a, 0x77, 0x65, 0x62, 0x6b, 0x69, - 0x74, 0x2e, 0x6f, 0x72, 0x67 - }; - - // The signature algorithm is specified as the following ASN.1 structure: - // AlgorithmIdentifier ::= SEQUENCE { - // algorithm OBJECT IDENTIFIER, - // parameters ANY DEFINED BY algorithm OPTIONAL } - // - const uint8 signature_algorithm[15] = { - 0x30, 0x0d, // a SEQUENCE of length 13 (0xd) - 0x06, 0x09, // an OBJECT IDENTIFIER of length 9 - // 1.2.840.113549.1.1.5 - sha1WithRSAEncryption - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, // a NULL of length 0 - }; - - // RSA signature, a big integer in the big-endian byte order. - const uint8 signature[256] = { - 0x1e, 0x6a, 0xe7, 0xe0, 0x4f, 0xe7, 0x4d, 0xd0, 0x69, 0x7c, 0xf8, 0x8f, - 0x99, 0xb4, 0x18, 0x95, 0x36, 0x24, 0x0f, 0x0e, 0xa3, 0xea, 0x34, 0x37, - 0xf4, 0x7d, 0xd5, 0x92, 0x35, 0x53, 0x72, 0x76, 0x3f, 0x69, 0xf0, 0x82, - 0x56, 0xe3, 0x94, 0x7a, 0x1d, 0x1a, 0x81, 0xaf, 0x9f, 0xc7, 0x43, 0x01, - 0x64, 0xd3, 0x7c, 0x0d, 0xc8, 0x11, 0x4e, 0x4a, 0xe6, 0x1a, 0xc3, 0x01, - 0x74, 0xe8, 0x35, 0x87, 0x5c, 0x61, 0xaa, 0x8a, 0x46, 0x06, 0xbe, 0x98, - 0x95, 0x24, 0x9e, 0x01, 0xe3, 0xe6, 0xa0, 0x98, 0xee, 0x36, 0x44, 0x56, - 0x8d, 0x23, 0x9c, 0x65, 0xea, 0x55, 0x6a, 0xdf, 0x66, 0xee, 0x45, 0xe8, - 0xa0, 0xe9, 0x7d, 0x9a, 0xba, 0x94, 0xc5, 0xc8, 0xc4, 0x4b, 0x98, 0xff, - 0x9a, 0x01, 0x31, 0x6d, 0xf9, 0x2b, 0x58, 0xe7, 0xe7, 0x2a, 0xc5, 0x4d, - 0xbb, 0xbb, 0xcd, 0x0d, 0x70, 0xe1, 0xad, 0x03, 0xf5, 0xfe, 0xf4, 0x84, - 0x71, 0x08, 0xd2, 0xbc, 0x04, 0x7b, 0x26, 0x1c, 0xa8, 0x0f, 0x9c, 0xd8, - 0x12, 0x6a, 0x6f, 0x2b, 0x67, 0xa1, 0x03, 0x80, 0x9a, 0x11, 0x0b, 0xe9, - 0xe0, 0xb5, 0xb3, 0xb8, 0x19, 0x4e, 0x0c, 0xa4, 0xd9, 0x2b, 0x3b, 0xc2, - 0xca, 0x20, 0xd3, 0x0c, 0xa4, 0xff, 0x93, 0x13, 0x1f, 0xfc, 0xba, 0x94, - 0x93, 0x8c, 0x64, 0x15, 0x2e, 0x28, 0xa9, 0x55, 0x8c, 0x2c, 0x48, 0xd3, - 0xd3, 0xc1, 0x50, 0x69, 0x19, 0xe8, 0x34, 0xd3, 0xf1, 0x04, 0x9f, 0x0a, - 0x7a, 0x21, 0x87, 0xbf, 0xb9, 0x59, 0x37, 0x2e, 0xf4, 0x71, 0xa5, 0x3e, - 0xbe, 0xcd, 0x70, 0x83, 0x18, 0xf8, 0x8a, 0x72, 0x85, 0x45, 0x1f, 0x08, - 0x01, 0x6f, 0x37, 0xf5, 0x2b, 0x7b, 0xea, 0xb9, 0x8b, 0xa3, 0xcc, 0xfd, - 0x35, 0x52, 0xdd, 0x66, 0xde, 0x4f, 0x30, 0xc5, 0x73, 0x81, 0xb6, 0xe8, - 0x3c, 0xd8, 0x48, 0x8a - }; - - // The public key is specified as the following ASN.1 structure: - // SubjectPublicKeyInfo ::= SEQUENCE { - // algorithm AlgorithmIdentifier, - // subjectPublicKey BIT STRING } - const uint8 public_key_info[294] = { - 0x30, 0x82, 0x01, 0x22, // a SEQUENCE of length 290 (0x122) - // algorithm - 0x30, 0x0d, // a SEQUENCE of length 13 - 0x06, 0x09, // an OBJECT IDENTIFIER of length 9 - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, - 0x05, 0x00, // a NULL of length 0 - // subjectPublicKey - 0x03, 0x82, 0x01, 0x0f, // a BIT STRING of length 271 (0x10f) - 0x00, // number of unused bits - 0x30, 0x82, 0x01, 0x0a, // a SEQUENCE of length 266 (0x10a) - // modulus - 0x02, 0x82, 0x01, 0x01, // an INTEGER of length 257 (0x101) - 0x00, 0xc4, 0x2d, 0xd5, 0x15, 0x8c, 0x9c, 0x26, 0x4c, 0xec, - 0x32, 0x35, 0xeb, 0x5f, 0xb8, 0x59, 0x01, 0x5a, 0xa6, 0x61, - 0x81, 0x59, 0x3b, 0x70, 0x63, 0xab, 0xe3, 0xdc, 0x3d, 0xc7, - 0x2a, 0xb8, 0xc9, 0x33, 0xd3, 0x79, 0xe4, 0x3a, 0xed, 0x3c, - 0x30, 0x23, 0x84, 0x8e, 0xb3, 0x30, 0x14, 0xb6, 0xb2, 0x87, - 0xc3, 0x3d, 0x95, 0x54, 0x04, 0x9e, 0xdf, 0x99, 0xdd, 0x0b, - 0x25, 0x1e, 0x21, 0xde, 0x65, 0x29, 0x7e, 0x35, 0xa8, 0xa9, - 0x54, 0xeb, 0xf6, 0xf7, 0x32, 0x39, 0xd4, 0x26, 0x55, 0x95, - 0xad, 0xef, 0xfb, 0xfe, 0x58, 0x86, 0xd7, 0x9e, 0xf4, 0x00, - 0x8d, 0x8c, 0x2a, 0x0c, 0xbd, 0x42, 0x04, 0xce, 0xa7, 0x3f, - 0x04, 0xf6, 0xee, 0x80, 0xf2, 0xaa, 0xef, 0x52, 0xa1, 0x69, - 0x66, 0xda, 0xbe, 0x1a, 0xad, 0x5d, 0xda, 0x2c, 0x66, 0xea, - 0x1a, 0x6b, 0xbb, 0xe5, 0x1a, 0x51, 0x4a, 0x00, 0x2f, 0x48, - 0xc7, 0x98, 0x75, 0xd8, 0xb9, 0x29, 0xc8, 0xee, 0xf8, 0x66, - 0x6d, 0x0a, 0x9c, 0xb3, 0xf3, 0xfc, 0x78, 0x7c, 0xa2, 0xf8, - 0xa3, 0xf2, 0xb5, 0xc3, 0xf3, 0xb9, 0x7a, 0x91, 0xc1, 0xa7, - 0xe6, 0x25, 0x2e, 0x9c, 0xa8, 0xed, 0x12, 0x65, 0x6e, 0x6a, - 0xf6, 0x12, 0x44, 0x53, 0x70, 0x30, 0x95, 0xc3, 0x9c, 0x2b, - 0x58, 0x2b, 0x3d, 0x08, 0x74, 0x4a, 0xf2, 0xbe, 0x51, 0xb0, - 0xbf, 0x87, 0xd0, 0x4c, 0x27, 0x58, 0x6b, 0xb5, 0x35, 0xc5, - 0x9d, 0xaf, 0x17, 0x31, 0xf8, 0x0b, 0x8f, 0xee, 0xad, 0x81, - 0x36, 0x05, 0x89, 0x08, 0x98, 0xcf, 0x3a, 0xaf, 0x25, 0x87, - 0xc0, 0x49, 0xea, 0xa7, 0xfd, 0x67, 0xf7, 0x45, 0x8e, 0x97, - 0xcc, 0x14, 0x39, 0xe2, 0x36, 0x85, 0xb5, 0x7e, 0x1a, 0x37, - 0xfd, 0x16, 0xf6, 0x71, 0x11, 0x9a, 0x74, 0x30, 0x16, 0xfe, - 0x13, 0x94, 0xa3, 0x3f, 0x84, 0x0d, 0x4f, - // public exponent - 0x02, 0x03, // an INTEGER of length 3 - 0x01, 0x00, 0x01 - }; - - // We use the signature verifier to perform four signature verification - // tests. - base::SignatureVerifier verifier; - bool ok; - - // Test 1: feed all of the data to the verifier at once (a single - // VerifyUpdate call). - ok = verifier.VerifyInit(signature_algorithm, - sizeof(signature_algorithm), - signature, sizeof(signature), - public_key_info, sizeof(public_key_info)); - EXPECT_TRUE(ok); - verifier.VerifyUpdate(tbs_certificate, sizeof(tbs_certificate)); - ok = verifier.VerifyFinal(); - EXPECT_TRUE(ok); - - // Test 2: feed the data to the verifier in three parts (three VerifyUpdate - // calls). - ok = verifier.VerifyInit(signature_algorithm, - sizeof(signature_algorithm), - signature, sizeof(signature), - public_key_info, sizeof(public_key_info)); - EXPECT_TRUE(ok); - verifier.VerifyUpdate(tbs_certificate, 256); - verifier.VerifyUpdate(tbs_certificate + 256, 256); - verifier.VerifyUpdate(tbs_certificate + 512, sizeof(tbs_certificate) - 512); - ok = verifier.VerifyFinal(); - EXPECT_TRUE(ok); - - // Test 3: verify the signature with incorrect data. - uint8 bad_tbs_certificate[sizeof(tbs_certificate)]; - memcpy(bad_tbs_certificate, tbs_certificate, sizeof(tbs_certificate)); - bad_tbs_certificate[10] += 1; // Corrupt one byte of the data. - ok = verifier.VerifyInit(signature_algorithm, - sizeof(signature_algorithm), - signature, sizeof(signature), - public_key_info, sizeof(public_key_info)); - EXPECT_TRUE(ok); - verifier.VerifyUpdate(bad_tbs_certificate, sizeof(bad_tbs_certificate)); - ok = verifier.VerifyFinal(); - - // Purify disables digital signature verification, causing the Windows - // CryptoAPI function CryptVerifySignature to always succeed. So we can't - // check the signature verification results of the negative tests when - // running inside Purify. See http://crbug.com/10031. -#ifndef PURIFY - EXPECT_FALSE(ok); -#endif - - // Test 4: verify a bad signature. - uint8 bad_signature[sizeof(signature)]; - memcpy(bad_signature, signature, sizeof(signature)); - bad_signature[10] += 1; // Corrupt one byte of the signature. - ok = verifier.VerifyInit(signature_algorithm, - sizeof(signature_algorithm), - bad_signature, sizeof(bad_signature), - public_key_info, sizeof(public_key_info)); - - // A crypto library (e.g., NSS) may detect that the signature is corrupted - // and cause VerifyInit to return false, so it is fine for 'ok' to be false. - if (ok) { - verifier.VerifyUpdate(tbs_certificate, sizeof(tbs_certificate)); - ok = verifier.VerifyFinal(); -#ifndef PURIFY - EXPECT_FALSE(ok); -#endif - } -} diff --git a/base/crypto/signature_verifier_win.cc b/base/crypto/signature_verifier_win.cc deleted file mode 100644 index c040d05..0000000 --- a/base/crypto/signature_verifier_win.cc +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) 2009 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/signature_verifier.h" - -#include "base/logging.h" - -#pragma comment(lib, "crypt32.lib") - -namespace { - -// Wrappers of malloc and free for CRYPT_DECODE_PARA, which requires the -// WINAPI calling convention. -void* WINAPI MyCryptAlloc(size_t size) { - return malloc(size); -} - -void WINAPI MyCryptFree(void* p) { - free(p); -} - -} // namespace - -namespace base { - -SignatureVerifier::SignatureVerifier() : hash_object_(0), public_key_(0) { - if (!CryptAcquireContext(provider_.receive(), NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - provider_.reset(); -} - -SignatureVerifier::~SignatureVerifier() { -} - -bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm, - int signature_algorithm_len, - const uint8* signature, - int signature_len, - const uint8* public_key_info, - int public_key_info_len) { - signature_.reserve(signature_len); - // CryptoAPI uses big integers in the little-endian byte order, so we need - // to first swap the order of signature bytes. - for (int i = signature_len - 1; i >= 0; --i) - signature_.push_back(signature[i]); - - CRYPT_DECODE_PARA decode_para; - decode_para.cbSize = sizeof(decode_para); - decode_para.pfnAlloc = MyCryptAlloc; - decode_para.pfnFree = MyCryptFree; - CERT_PUBLIC_KEY_INFO* cert_public_key_info = NULL; - DWORD struct_len = 0; - BOOL ok; - ok = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - X509_PUBLIC_KEY_INFO, - public_key_info, - public_key_info_len, - CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, - &decode_para, - &cert_public_key_info, - &struct_len); - if (!ok) - return false; - - ok = CryptImportPublicKeyInfo(provider_, - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - cert_public_key_info, public_key_.receive()); - free(cert_public_key_info); - if (!ok) - return false; - - CRYPT_ALGORITHM_IDENTIFIER* signature_algorithm_id; - struct_len = 0; - ok = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - X509_ALGORITHM_IDENTIFIER, - signature_algorithm, - signature_algorithm_len, - CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, - &decode_para, - &signature_algorithm_id, - &struct_len); - DCHECK(ok || GetLastError() == ERROR_FILE_NOT_FOUND); - ALG_ID hash_alg_id; - if (ok) { - hash_alg_id = CALG_MD4; // Initialize to a weak hash algorithm that we - // don't support. - if (!strcmp(signature_algorithm_id->pszObjId, szOID_RSA_SHA1RSA)) - hash_alg_id = CALG_SHA1; - else if (!strcmp(signature_algorithm_id->pszObjId, szOID_RSA_MD5RSA)) - hash_alg_id = CALG_MD5; - free(signature_algorithm_id); - DCHECK(hash_alg_id != CALG_MD4); - if (hash_alg_id == CALG_MD4) - return false; // Unsupported hash algorithm. - } else if (GetLastError() == ERROR_FILE_NOT_FOUND) { - // TODO(wtc): X509_ALGORITHM_IDENTIFIER isn't supported on XP SP2. We - // may be able to encapsulate signature_algorithm in a dummy SignedContent - // and decode it with X509_CERT into a CERT_SIGNED_CONTENT_INFO. For now, - // just hardcode the hash algorithm to be SHA-1. - hash_alg_id = CALG_SHA1; - } else { - return false; - } - - ok = CryptCreateHash(provider_, hash_alg_id, 0, 0, hash_object_.receive()); - if (!ok) - return false; - return true; -} - -void SignatureVerifier::VerifyUpdate(const uint8* data_part, - int data_part_len) { - BOOL ok = CryptHashData(hash_object_, data_part, data_part_len, 0); - DCHECK(ok) << "CryptHashData failed: " << GetLastError(); -} - -bool SignatureVerifier::VerifyFinal() { - BOOL ok = CryptVerifySignature(hash_object_, &signature_[0], - signature_.size(), public_key_, NULL, 0); - Reset(); - if (!ok) - return false; - return true; -} - -void SignatureVerifier::Reset() { - hash_object_.reset(); - public_key_.reset(); - signature_.clear(); -} - -} // namespace base - diff --git a/base/crypto/symmetric_key.h b/base/crypto/symmetric_key.h deleted file mode 100644 index b72c840..0000000 --- a/base/crypto/symmetric_key.h +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2011 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_ -#pragma once - -#include <string> - -#include "base/base_api.h" -#include "base/basictypes.h" - -#if defined(USE_NSS) -#include "base/crypto/scoped_nss_types.h" -#elif defined(OS_MACOSX) -#include <Security/cssmtype.h> -#elif defined(OS_WIN) -#include "base/crypto/scoped_capi_types.h" -#endif - -namespace base { - -// Wraps a platform-specific symmetric key and allows it to be held in a -// scoped_ptr. -class BASE_API SymmetricKey { - public: - // Defines the algorithm that a key will be used with. See also - // classs Encrptor. - enum Algorithm { - AES, - HMAC_SHA1, - }; - - virtual ~SymmetricKey(); - - // Generates a random key suitable to be used with |algorithm| and of - // |key_size_in_bits| bits. - // The caller is responsible for deleting the returned SymmetricKey. - static SymmetricKey* GenerateRandomKey(Algorithm algorithm, - size_t key_size_in_bits); - - // Derives a key from the supplied password and salt using PBKDF2, suitable - // for use with specified |algorithm|. Note |algorithm| is not the algorithm - // used to derive the key from the password. The caller is responsible for - // deleting the returned SymmetricKey. - static SymmetricKey* DeriveKeyFromPassword(Algorithm algorithm, - const std::string& password, - const std::string& salt, - size_t iterations, - size_t key_size_in_bits); - - // Imports an array of key bytes in |raw_key|. This key may have been - // generated by GenerateRandomKey or DeriveKeyFromPassword and exported with - // GetRawKey, or via another compatible method. The key must be of suitable - // size for use with |algorithm|. The caller owns the returned SymmetricKey. - static SymmetricKey* Import(Algorithm algorithm, const std::string& raw_key); - -#if defined(USE_OPENSSL) - const std::string& key() { return key_; } -#elif defined(USE_NSS) - PK11SymKey* key() const { return key_.get(); } -#elif defined(OS_MACOSX) - CSSM_DATA cssm_data() const; -#elif defined(OS_WIN) - HCRYPTKEY key() const { return key_.get(); } -#endif - - // Extracts the raw key from the platform specific data. - // Warning: |raw_key| holds the raw key as bytes and thus must be handled - // carefully. - bool GetRawKey(std::string* raw_key); - - private: -#if defined(USE_OPENSSL) - SymmetricKey() {} - std::string key_; -#elif defined(USE_NSS) - explicit SymmetricKey(PK11SymKey* key); - ScopedPK11SymKey key_; -#elif defined(OS_MACOSX) - SymmetricKey(const void* key_data, size_t key_size_in_bits); - std::string key_; -#elif defined(OS_WIN) - SymmetricKey(HCRYPTPROV provider, HCRYPTKEY key, - const void* key_data, size_t key_size_in_bytes); - - ScopedHCRYPTPROV provider_; - ScopedHCRYPTKEY key_; - - // Contains the raw key, if it is known during initialization and when it - // is likely that the associated |provider_| will be unable to export the - // |key_|. This is the case of HMAC keys when the key size exceeds 16 bytes - // when using the default RSA provider. - // TODO(rsleevi): See if KP_EFFECTIVE_KEYLEN is the reason why CryptExportKey - // fails with NTE_BAD_KEY/NTE_BAD_LEN - std::string raw_key_; -#endif - - 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 deleted file mode 100644 index 574f9d2..0000000 --- a/base/crypto/symmetric_key_mac.cc +++ /dev/null @@ -1,155 +0,0 @@ -// 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 <CommonCrypto/CommonCryptor.h> -#include <CoreFoundation/CFString.h> -#include <Security/cssm.h> - -#include "base/crypto/cssm_init.h" -#include "base/logging.h" - -namespace { - -CSSM_KEY_TYPE CheckKeyParams(base::SymmetricKey::Algorithm algorithm, - size_t key_size_in_bits) { - if (algorithm == base::SymmetricKey::AES) { - CHECK(key_size_in_bits == 128 || - key_size_in_bits == 192 || - key_size_in_bits == 256) - << "Invalid key size " << key_size_in_bits << " bits"; - return CSSM_ALGID_AES; - } else { - // FIPS 198 Section 3 requires a HMAC-SHA-1 derived keys to be at least - // (HMAC-SHA-1 output size / 2) to be compliant. Since the ouput size of - // HMAC-SHA-1 is 160 bits, we require at least 80 bits here. - CHECK(algorithm == base::SymmetricKey::HMAC_SHA1); - CHECK(key_size_in_bits >= 80 && (key_size_in_bits % 8) == 0) - << "Invalid key size " << key_size_in_bits << " bits"; - return CSSM_ALGID_SHA1HMAC_LEGACY; - } -} - -void* CreateRandomBytes(size_t size) { - CSSM_RETURN err; - CSSM_CC_HANDLE ctx; - err = CSSM_CSP_CreateRandomGenContext(base::GetSharedCSPHandle(), - CSSM_ALGID_APPLE_YARROW, - NULL, - size, &ctx); - if (err) { - base::LogCSSMError("CSSM_CSP_CreateRandomGenContext", err); - return NULL; - } - CSSM_DATA random_data = {}; - err = CSSM_GenerateRandom(ctx, &random_data); - if (err) { - base::LogCSSMError("CSSM_GenerateRandom", err); - random_data.Data = NULL; - } - CSSM_DeleteContext(ctx); - return random_data.Data; // Caller responsible for freeing this -} - -inline CSSM_DATA StringToData(const std::string& str) { - CSSM_DATA data = { - str.size(), - reinterpret_cast<uint8_t*>(const_cast<char*>(str.data())) - }; - return data; -} - -} // namespace - -namespace base { - -SymmetricKey::~SymmetricKey() {} - -// static -SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm, - size_t key_size_in_bits) { - CheckKeyParams(algorithm, key_size_in_bits); - void* random_bytes = CreateRandomBytes((key_size_in_bits + 7) / 8); - if (!random_bytes) - return NULL; - SymmetricKey *key = new SymmetricKey(random_bytes, key_size_in_bits); - free(random_bytes); - return key; -} - -// static -SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm, - const std::string& password, - const std::string& salt, - size_t iterations, - size_t key_size_in_bits) { - // Derived (haha) from cdsaDeriveKey() in Apple's CryptoSample. - CSSM_KEY_TYPE key_type = CheckKeyParams(algorithm, key_size_in_bits); - SymmetricKey* derived_key = NULL; - CSSM_KEY cssm_key = {}; - - CSSM_CC_HANDLE ctx = 0; - CSSM_ACCESS_CREDENTIALS credentials = {}; - CSSM_RETURN err; - CSSM_DATA salt_data = StringToData(salt); - err = CSSM_CSP_CreateDeriveKeyContext(GetSharedCSPHandle(), - CSSM_ALGID_PKCS5_PBKDF2, - key_type, key_size_in_bits, - &credentials, - NULL, - iterations, - &salt_data, - NULL, - &ctx); - if (err) { - LogCSSMError("CSSM_CSP_CreateDeriveKeyContext", err); - return NULL; - } - - CSSM_PKCS5_PBKDF2_PARAMS params = {}; - params.Passphrase = StringToData(password); - params.PseudoRandomFunction = CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1; - CSSM_DATA param_data = {sizeof(params), reinterpret_cast<uint8_t*>(¶ms)}; - err = CSSM_DeriveKey(ctx, - ¶m_data, - CSSM_KEYUSE_ANY, - CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, - NULL, - NULL, - &cssm_key); - if (err) { - LogCSSMError("CSSM_DeriveKey", err); - goto exit; - } - - DCHECK_EQ(cssm_key.KeyData.Length, key_size_in_bits / 8); - derived_key = new SymmetricKey(cssm_key.KeyData.Data, key_size_in_bits); - - exit: - CSSM_DeleteContext(ctx); - CSSM_FreeKey(GetSharedCSPHandle(), &credentials, &cssm_key, false); - return derived_key; -} - -// static -SymmetricKey* SymmetricKey::Import(Algorithm algorithm, - const std::string& raw_key) { - return new SymmetricKey(raw_key.data(), raw_key.size() * 8); -} - -SymmetricKey::SymmetricKey(const void *key_data, size_t key_size_in_bits) - : key_(reinterpret_cast<const char*>(key_data), - key_size_in_bits / 8) {} - -bool SymmetricKey::GetRawKey(std::string* raw_key) { - *raw_key = key_; - return true; -} - -CSSM_DATA SymmetricKey::cssm_data() const { - return StringToData(key_); -} - -} // namespace base diff --git a/base/crypto/symmetric_key_nss.cc b/base/crypto/symmetric_key_nss.cc deleted file mode 100644 index 1e3551d..0000000 --- a/base/crypto/symmetric_key_nss.cc +++ /dev/null @@ -1,127 +0,0 @@ -// 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/nss_util.h" -#include "base/logging.h" - -namespace base { - -SymmetricKey::~SymmetricKey() {} - -// static -SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm, - size_t key_size_in_bits) { - DCHECK_EQ(AES, algorithm); - - EnsureNSSInit(); - if (key_size_in_bits == 0) - return NULL; - - ScopedPK11Slot slot(PK11_GetBestSlot(CKM_AES_KEY_GEN, NULL)); - if (!slot.get()) - return NULL; - - PK11SymKey* sym_key = PK11_KeyGen(slot.get(), CKM_AES_KEY_GEN, NULL, - key_size_in_bits / 8, NULL); - if (!sym_key) - return NULL; - - return new SymmetricKey(sym_key); -} - -// static -SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm, - const std::string& password, - const std::string& salt, - size_t iterations, - size_t key_size_in_bits) { - EnsureNSSInit(); - if (salt.empty() || iterations == 0 || key_size_in_bits == 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(); - - SECOidTag cipher_algorithm = - algorithm == AES ? SEC_OID_AES_256_CBC : SEC_OID_HMAC_SHA1; - ScopedSECAlgorithmID alg_id(PK11_CreatePBEV2AlgorithmID(SEC_OID_PKCS5_PBKDF2, - cipher_algorithm, - SEC_OID_HMAC_SHA1, - key_size_in_bits / 8, - 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); -} - -// static -SymmetricKey* SymmetricKey::Import(Algorithm algorithm, - const std::string& raw_key) { - CK_MECHANISM_TYPE cipher = - algorithm == AES ? CKM_AES_CBC : CKM_SHA_1_HMAC; - - SECItem key_item; - key_item.type = siBuffer; - key_item.data = reinterpret_cast<unsigned char*>( - const_cast<char *>(raw_key.data())); - key_item.len = raw_key.size(); - - ScopedPK11Slot slot(PK11_GetBestSlot(cipher, NULL)); - if (!slot.get()) - return NULL; - - // The exact value of the |origin| argument doesn't matter to NSS as long as - // it's not PK11_OriginFortezzaHack, so we pass PK11_OriginUnwrap as a - // placeholder. - PK11SymKey* sym_key = PK11_ImportSymKey(slot.get(), cipher, PK11_OriginUnwrap, - CKA_ENCRYPT, &key_item, NULL); - if (!sym_key) - return NULL; - - return new SymmetricKey(sym_key); -} - -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; -} - -SymmetricKey::SymmetricKey(PK11SymKey* key) : key_(key) { - DCHECK(key); -} - -} // namespace base diff --git a/base/crypto/symmetric_key_openssl.cc b/base/crypto/symmetric_key_openssl.cc deleted file mode 100644 index d055b61..0000000 --- a/base/crypto/symmetric_key_openssl.cc +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2011 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 <openssl/evp.h> -#include <openssl/rand.h> - -#include <algorithm> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/openssl_util.h" -#include "base/string_util.h" - -namespace base { - -SymmetricKey::~SymmetricKey() { - std::fill(key_.begin(), key_.end(), '\0'); // Zero out the confidential key. -} - -// static -SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm, - size_t key_size_in_bits) { - DCHECK_EQ(AES, algorithm); - int key_size_in_bytes = key_size_in_bits / 8; - DCHECK_EQ(static_cast<int>(key_size_in_bits), key_size_in_bytes * 8); - - if (key_size_in_bits == 0) - return NULL; - - OpenSSLErrStackTracer err_tracer(FROM_HERE); - scoped_ptr<SymmetricKey> key(new SymmetricKey); - uint8* key_data = - reinterpret_cast<uint8*>(WriteInto(&key->key_, key_size_in_bytes + 1)); - - int rv = RAND_bytes(key_data, key_size_in_bytes); - return rv == 1 ? key.release() : NULL; -} - -// static -SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm, - const std::string& password, - const std::string& salt, - size_t iterations, - size_t key_size_in_bits) { - DCHECK(algorithm == AES || algorithm == HMAC_SHA1); - int key_size_in_bytes = key_size_in_bits / 8; - DCHECK_EQ(static_cast<int>(key_size_in_bits), key_size_in_bytes * 8); - - OpenSSLErrStackTracer err_tracer(FROM_HERE); - scoped_ptr<SymmetricKey> key(new SymmetricKey); - uint8* key_data = - reinterpret_cast<uint8*>(WriteInto(&key->key_, key_size_in_bytes + 1)); - int rv = PKCS5_PBKDF2_HMAC_SHA1(password.data(), password.length(), - reinterpret_cast<const uint8*>(salt.data()), - salt.length(), iterations, - key_size_in_bytes, key_data); - return rv == 1 ? key.release() : NULL; -} - -// static -SymmetricKey* SymmetricKey::Import(Algorithm algorithm, - const std::string& raw_key) { - scoped_ptr<SymmetricKey> key(new SymmetricKey); - key->key_ = raw_key; - return key.release(); -} - -bool SymmetricKey::GetRawKey(std::string* raw_key) { - *raw_key = key_; - return true; -} - -} // namespace base diff --git a/base/crypto/symmetric_key_unittest.cc b/base/crypto/symmetric_key_unittest.cc deleted file mode 100644 index f9e9419..0000000 --- a/base/crypto/symmetric_key_unittest.cc +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright (c) 2011 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 <string> - -#include "base/memory/scoped_ptr.h" -#include "base/string_number_conversions.h" -#include "base/string_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(SymmetricKeyTest, GenerateRandomKey) { - scoped_ptr<base::SymmetricKey> key( - base::SymmetricKey::GenerateRandomKey(base::SymmetricKey::AES, 256)); - ASSERT_TRUE(NULL != key.get()); - std::string raw_key; - EXPECT_TRUE(key->GetRawKey(&raw_key)); - EXPECT_EQ(32U, raw_key.size()); - - // Do it again and check that the keys are different. - // (Note: this has a one-in-10^77 chance of failure!) - scoped_ptr<base::SymmetricKey> key2( - base::SymmetricKey::GenerateRandomKey(base::SymmetricKey::AES, 256)); - ASSERT_TRUE(NULL != key2.get()); - std::string raw_key2; - EXPECT_TRUE(key2->GetRawKey(&raw_key2)); - EXPECT_EQ(32U, raw_key2.size()); - EXPECT_NE(raw_key, raw_key2); -} - -TEST(SymmetricKeyTest, ImportGeneratedKey) { - scoped_ptr<base::SymmetricKey> key1( - base::SymmetricKey::GenerateRandomKey(base::SymmetricKey::AES, 256)); - ASSERT_TRUE(NULL != key1.get()); - std::string raw_key1; - EXPECT_TRUE(key1->GetRawKey(&raw_key1)); - - scoped_ptr<base::SymmetricKey> key2( - base::SymmetricKey::Import(base::SymmetricKey::AES, raw_key1)); - ASSERT_TRUE(NULL != key2.get()); - - std::string raw_key2; - EXPECT_TRUE(key2->GetRawKey(&raw_key2)); - - EXPECT_EQ(raw_key1, raw_key2); -} - -TEST(SymmetricKeyTest, ImportDerivedKey) { - scoped_ptr<base::SymmetricKey> key1( - base::SymmetricKey::DeriveKeyFromPassword(base::SymmetricKey::HMAC_SHA1, - "password", "somesalt", 1024, - 160)); - ASSERT_TRUE(NULL != key1.get()); - std::string raw_key1; - EXPECT_TRUE(key1->GetRawKey(&raw_key1)); - - scoped_ptr<base::SymmetricKey> key2( - base::SymmetricKey::Import(base::SymmetricKey::HMAC_SHA1, raw_key1)); - ASSERT_TRUE(NULL != key2.get()); - - std::string raw_key2; - EXPECT_TRUE(key2->GetRawKey(&raw_key2)); - - EXPECT_EQ(raw_key1, raw_key2); -} - -struct PBKDF2TestVector { - base::SymmetricKey::Algorithm algorithm; - const char* password; - const char* salt; - unsigned int rounds; - unsigned int key_size_in_bits; - const char* expected; // ASCII encoded hex bytes -}; - -class SymmetricKeyDeriveKeyFromPasswordTest - : public testing::TestWithParam<PBKDF2TestVector> { -}; - -TEST_P(SymmetricKeyDeriveKeyFromPasswordTest, DeriveKeyFromPassword) { - PBKDF2TestVector test_data(GetParam()); -#if defined(OS_MACOSX) - // The OS X crypto libraries have minimum salt and iteration requirements - // so some of the tests below will cause them to barf. Skip these. - if (strlen(test_data.salt) < 8 || test_data.rounds < 1000) { - VLOG(1) << "Skipped test vector for " << test_data.expected; - return; - } -#endif // OS_MACOSX - - scoped_ptr<base::SymmetricKey> key( - base::SymmetricKey::DeriveKeyFromPassword( - test_data.algorithm, - test_data.password, test_data.salt, - test_data.rounds, test_data.key_size_in_bits)); - ASSERT_TRUE(NULL != key.get()); - - std::string raw_key; - key->GetRawKey(&raw_key); - EXPECT_EQ(test_data.key_size_in_bits / 8, raw_key.size()); - EXPECT_EQ(test_data.expected, - StringToLowerASCII(base::HexEncode(raw_key.data(), - raw_key.size()))); -} - -static const PBKDF2TestVector kTestVectors[] = { - // These tests come from - // http://www.ietf.org/id/draft-josefsson-pbkdf2-test-vectors-00.txt - { - base::SymmetricKey::HMAC_SHA1, - "password", - "salt", - 1, - 160, - "0c60c80f961f0e71f3a9b524af6012062fe037a6", - }, - { - base::SymmetricKey::HMAC_SHA1, - "password", - "salt", - 2, - 160, - "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", - }, - { - base::SymmetricKey::HMAC_SHA1, - "password", - "salt", - 4096, - 160, - "4b007901b765489abead49d926f721d065a429c1", - }, - // This test takes over 30s to run on the trybots. -#if 0 - { - base::SymmetricKey::HMAC_SHA1, - "password", - "salt", - 16777216, - 160, - "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984", - }, -#endif - - // These tests come from RFC 3962, via BSD source code at - // http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/bioctl/pbkdf2.c?rev=HEAD&content-type=text/plain - { - base::SymmetricKey::HMAC_SHA1, - "password", - "ATHENA.MIT.EDUraeburn", - 1, - 160, - "cdedb5281bb2f801565a1122b25635150ad1f7a0", - }, - { - base::SymmetricKey::HMAC_SHA1, - "password", - "ATHENA.MIT.EDUraeburn", - 2, - 160, - "01dbee7f4a9e243e988b62c73cda935da05378b9", - }, - { - base::SymmetricKey::HMAC_SHA1, - "password", - "ATHENA.MIT.EDUraeburn", - 1200, - 160, - "5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddb", - }, - { - base::SymmetricKey::HMAC_SHA1, - "password", - "\0224VxxV4\022", /* 0x1234567878563412 */ - 5, - 160, - "d1daa78615f287e6a1c8b120d7062a493f98d203", - }, - { - base::SymmetricKey::HMAC_SHA1, - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", - "pass phrase equals block size", - 1200, - 160, - "139c30c0966bc32ba55fdbf212530ac9c5ec59f1", - }, - { - base::SymmetricKey::HMAC_SHA1, - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", - "pass phrase exceeds block size", - 1200, - 160, - "9ccad6d468770cd51b10e6a68721be611a8b4d28", - }, - { - base::SymmetricKey::HMAC_SHA1, - "\360\235\204\236", /* g-clef (0xf09d849e) */ - "EXAMPLE.COMpianist", - 50, - 160, - "6b9cf26d45455a43a5b8bb276a403b39e7fe37a0", - }, - - // Regression tests for AES keys, derived from the Linux NSS implementation. - { - base::SymmetricKey::AES, - "A test password", - "saltsalt", - 1, - 256, - "44899a7777f0e6e8b752f875f02044b8ac593de146de896f2e8a816e315a36de", - }, - { - base::SymmetricKey::AES, - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", - "pass phrase exceeds block size", - 20, - 256, - "e0739745dc28b8721ba402e05214d2ac1eab54cf72bee1fba388297a09eb493c", - }, -}; - -INSTANTIATE_TEST_CASE_P(, SymmetricKeyDeriveKeyFromPasswordTest, - testing::ValuesIn(kTestVectors)); diff --git a/base/crypto/symmetric_key_win.cc b/base/crypto/symmetric_key_win.cc deleted file mode 100644 index 0a1c234..0000000 --- a/base/crypto/symmetric_key_win.cc +++ /dev/null @@ -1,536 +0,0 @@ -// Copyright (c) 2011 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 <winsock2.h> // For htonl. - -#include <vector> - -// TODO(wtc): replace scoped_array by std::vector. -#include "base/memory/scoped_ptr.h" - -namespace base { - -namespace { - -// The following is a non-public Microsoft header documented in MSDN under -// CryptImportKey / CryptExportKey. Following the header is the byte array of -// the actual plaintext key. -struct PlaintextBlobHeader { - BLOBHEADER hdr; - DWORD cbKeySize; -}; - -// CryptoAPI makes use of three distinct ALG_IDs for AES, rather than just -// CALG_AES (which exists, but depending on the functions you are calling, may -// result in function failure, whereas the subtype would succeed). -ALG_ID GetAESAlgIDForKeySize(size_t key_size_in_bits) { - // Only AES-128/-192/-256 is supported in CryptoAPI. - switch (key_size_in_bits) { - case 128: - return CALG_AES_128; - case 192: - return CALG_AES_192; - case 256: - return CALG_AES_256; - default: - NOTREACHED(); - return 0; - } -}; - -// Imports a raw/plaintext key of |key_size| stored in |*key_data| into a new -// key created for the specified |provider|. |alg| contains the algorithm of -// the key being imported. -// If |key_data| is intended to be used as an HMAC key, then |alg| should be -// CALG_HMAC. -// If successful, returns true and stores the imported key in |*key|. -// TODO(wtc): use this function in hmac_win.cc. -bool ImportRawKey(HCRYPTPROV provider, - ALG_ID alg, - const void* key_data, DWORD key_size, - ScopedHCRYPTKEY* key) { - DCHECK_GT(key_size, 0); - - DWORD actual_size = sizeof(PlaintextBlobHeader) + key_size; - std::vector<BYTE> tmp_data(actual_size); - BYTE* actual_key = &tmp_data[0]; - memcpy(actual_key + sizeof(PlaintextBlobHeader), key_data, key_size); - PlaintextBlobHeader* key_header = - reinterpret_cast<PlaintextBlobHeader*>(actual_key); - memset(key_header, 0, sizeof(PlaintextBlobHeader)); - - key_header->hdr.bType = PLAINTEXTKEYBLOB; - key_header->hdr.bVersion = CUR_BLOB_VERSION; - key_header->hdr.aiKeyAlg = alg; - - key_header->cbKeySize = key_size; - - HCRYPTKEY unsafe_key = NULL; - DWORD flags = CRYPT_EXPORTABLE; - if (alg == CALG_HMAC) { - // Though it may appear odd that IPSEC and RC2 are being used, this is - // done in accordance with Microsoft's FIPS 140-2 Security Policy for the - // RSA Enhanced Provider, as the approved means of using arbitrary HMAC - // key material. - key_header->hdr.aiKeyAlg = CALG_RC2; - flags |= CRYPT_IPSEC_HMAC_KEY; - } - - BOOL ok = - CryptImportKey(provider, actual_key, actual_size, 0, flags, &unsafe_key); - - // Clean up the temporary copy of key, regardless of whether it was imported - // sucessfully or not. - SecureZeroMemory(actual_key, actual_size); - - if (!ok) - return false; - - key->reset(unsafe_key); - return true; -} - -// Attempts to generate a random AES key of |key_size_in_bits|. Returns true -// if generation is successful, storing the generated key in |*key| and the -// key provider (CSP) in |*provider|. -bool GenerateAESKey(size_t key_size_in_bits, - ScopedHCRYPTPROV* provider, - ScopedHCRYPTKEY* key) { - DCHECK(provider); - DCHECK(key); - - ALG_ID alg = GetAESAlgIDForKeySize(key_size_in_bits); - if (alg == 0) - return false; - - ScopedHCRYPTPROV safe_provider; - // Note: The only time NULL is safe to be passed as pszContainer is when - // dwFlags contains CRYPT_VERIFYCONTEXT, as all keys generated and/or used - // will be treated as ephemeral keys and not persisted. - BOOL ok = CryptAcquireContext(safe_provider.receive(), NULL, NULL, - PROV_RSA_AES, CRYPT_VERIFYCONTEXT); - if (!ok) - return false; - - ScopedHCRYPTKEY safe_key; - // In the FIPS 140-2 Security Policy for CAPI on XP/Vista+, Microsoft notes - // that CryptGenKey makes use of the same functionality exposed via - // CryptGenRandom. The reason this is being used, as opposed to - // CryptGenRandom and CryptImportKey is for compliance with the security - // policy - ok = CryptGenKey(safe_provider.get(), alg, CRYPT_EXPORTABLE, - safe_key.receive()); - if (!ok) - return false; - - key->swap(safe_key); - provider->swap(safe_provider); - - return true; -} - -// Returns true if the HMAC key size meets the requirement of FIPS 198 -// Section 3. |alg| is the hash function used in the HMAC. -bool CheckHMACKeySize(size_t key_size_in_bits, ALG_ID alg) { - DWORD hash_size = 0; - switch (alg) { - case CALG_SHA1: - hash_size = 20; - break; - case CALG_SHA_256: - hash_size = 32; - break; - case CALG_SHA_384: - hash_size = 48; - break; - case CALG_SHA_512: - hash_size = 64; - break; - } - if (hash_size == 0) - return false; - - // An HMAC key must be >= L/2, where L is the output size of the hash - // function being used. - return (key_size_in_bits >= (hash_size / 2 * 8) && - (key_size_in_bits % 8) == 0); -} - -// Attempts to generate a random, |key_size_in_bits|-long HMAC key, for use -// with the hash function |alg|. -// |key_size_in_bits| must be >= 1/2 the hash size of |alg| for security. -// Returns true if generation is successful, storing the generated key in -// |*key| and the key provider (CSP) in |*provider|. -bool GenerateHMACKey(size_t key_size_in_bits, - ALG_ID alg, - ScopedHCRYPTPROV* provider, - ScopedHCRYPTKEY* key, - scoped_array<BYTE>* raw_key) { - DCHECK(provider); - DCHECK(key); - DCHECK(raw_key); - - if (!CheckHMACKeySize(key_size_in_bits, alg)) - return false; - - ScopedHCRYPTPROV safe_provider; - // See comment in GenerateAESKey as to why NULL is acceptable for the - // container name. - BOOL ok = CryptAcquireContext(safe_provider.receive(), NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - if (!ok) - return false; - - DWORD key_size_in_bytes = key_size_in_bits / 8; - scoped_array<BYTE> random(new BYTE[key_size_in_bytes]); - ok = CryptGenRandom(safe_provider, key_size_in_bytes, random.get()); - if (!ok) - return false; - - ScopedHCRYPTKEY safe_key; - bool rv = ImportRawKey(safe_provider, CALG_HMAC, random.get(), - key_size_in_bytes, &safe_key); - if (rv) { - key->swap(safe_key); - provider->swap(safe_provider); - raw_key->swap(random); - } - - SecureZeroMemory(random.get(), key_size_in_bytes); - return rv; -} - -// Attempts to create an HMAC hash instance using the specified |provider| -// and |key|. The inner hash function will be |hash_alg|. If successful, -// returns true and stores the hash in |*hash|. -// TODO(wtc): use this function in hmac_win.cc. -bool CreateHMACHash(HCRYPTPROV provider, - HCRYPTKEY key, - ALG_ID hash_alg, - ScopedHCRYPTHASH* hash) { - ScopedHCRYPTHASH safe_hash; - BOOL ok = CryptCreateHash(provider, CALG_HMAC, key, 0, safe_hash.receive()); - if (!ok) - return false; - - HMAC_INFO hmac_info; - memset(&hmac_info, 0, sizeof(hmac_info)); - hmac_info.HashAlgid = hash_alg; - - ok = CryptSetHashParam(safe_hash, HP_HMAC_INFO, - reinterpret_cast<const BYTE*>(&hmac_info), 0); - if (!ok) - return false; - - hash->swap(safe_hash); - return true; -} - -// Computes a block of the derived key using the PBKDF2 function F for the -// specified |block_index| using the PRF |hash|, writing the output to -// |output_buf|. -// |output_buf| must have enough space to accomodate the output of the PRF -// specified by |hash|. -// Returns true if the block was successfully computed. -bool ComputePBKDF2Block(HCRYPTHASH hash, - DWORD hash_size, - const std::string& salt, - size_t iterations, - uint32 block_index, - BYTE* output_buf) { - // From RFC 2898: - // 3. <snip> The function F is defined as the exclusive-or sum of the first - // c iterates of the underlying pseudorandom function PRF applied to the - // password P and the concatenation of the salt S and the block index i: - // F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c - // where - // U_1 = PRF(P, S || INT (i)) - // U_2 = PRF(P, U_1) - // ... - // U_c = PRF(P, U_{c-1}) - ScopedHCRYPTHASH safe_hash; - BOOL ok = CryptDuplicateHash(hash, NULL, 0, safe_hash.receive()); - if (!ok) - return false; - - // Iteration U_1: Compute PRF for S. - ok = CryptHashData(safe_hash, reinterpret_cast<const BYTE*>(salt.data()), - salt.size(), 0); - if (!ok) - return false; - - // Iteration U_1: and append (big-endian) INT (i). - uint32 big_endian_block_index = htonl(block_index); - ok = CryptHashData(safe_hash, - reinterpret_cast<BYTE*>(&big_endian_block_index), - sizeof(big_endian_block_index), 0); - - std::vector<BYTE> hash_value(hash_size); - - DWORD size = hash_size; - ok = CryptGetHashParam(safe_hash, HP_HASHVAL, &hash_value[0], &size, 0); - if (!ok || size != hash_size) - return false; - - memcpy(output_buf, &hash_value[0], hash_size); - - // Iteration 2 - c: Compute U_{iteration} by applying the PRF to - // U_{iteration - 1}, then xor the resultant hash with |output|, which - // contains U_1 ^ U_2 ^ ... ^ U_{iteration - 1}. - for (size_t iteration = 2; iteration <= iterations; ++iteration) { - safe_hash.reset(); - ok = CryptDuplicateHash(hash, NULL, 0, safe_hash.receive()); - if (!ok) - return false; - - ok = CryptHashData(safe_hash, &hash_value[0], hash_size, 0); - if (!ok) - return false; - - size = hash_size; - ok = CryptGetHashParam(safe_hash, HP_HASHVAL, &hash_value[0], &size, 0); - if (!ok || size != hash_size) - return false; - - for (int i = 0; i < hash_size; ++i) - output_buf[i] ^= hash_value[i]; - } - - return true; -} - -} // namespace - -SymmetricKey::~SymmetricKey() { - // TODO(wtc): create a "secure" string type that zeroes itself in the - // destructor. - if (!raw_key_.empty()) - SecureZeroMemory(const_cast<char *>(raw_key_.data()), raw_key_.size()); -} - -// static -SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm, - size_t key_size_in_bits) { - DCHECK_GE(key_size_in_bits, 8); - - ScopedHCRYPTPROV provider; - ScopedHCRYPTKEY key; - - bool ok = false; - scoped_array<BYTE> raw_key; - - switch (algorithm) { - case AES: - ok = GenerateAESKey(key_size_in_bits, &provider, &key); - break; - case HMAC_SHA1: - ok = GenerateHMACKey(key_size_in_bits, CALG_SHA1, &provider, - &key, &raw_key); - break; - } - - if (!ok) { - NOTREACHED(); - return NULL; - } - - size_t key_size_in_bytes = key_size_in_bits / 8; - if (raw_key == NULL) - key_size_in_bytes = 0; - - SymmetricKey* result = new SymmetricKey(provider.release(), - key.release(), - raw_key.get(), - key_size_in_bytes); - if (raw_key != NULL) - SecureZeroMemory(raw_key.get(), key_size_in_bytes); - - return result; -} - -// static -SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm, - const std::string& password, - const std::string& salt, - size_t iterations, - size_t key_size_in_bits) { - // CryptoAPI lacks routines to perform PBKDF2 derivation as specified - // in RFC 2898, so it must be manually implemented. Only HMAC-SHA1 is - // supported as the PRF. - - // While not used until the end, sanity-check the input before proceeding - // with the expensive computation. - DWORD provider_type = 0; - ALG_ID alg = 0; - switch (algorithm) { - case AES: - provider_type = PROV_RSA_AES; - alg = GetAESAlgIDForKeySize(key_size_in_bits); - break; - case HMAC_SHA1: - provider_type = PROV_RSA_FULL; - alg = CALG_HMAC; - break; - default: - NOTREACHED(); - break; - } - if (provider_type == 0 || alg == 0) - return NULL; - - ScopedHCRYPTPROV provider; - BOOL ok = CryptAcquireContext(provider.receive(), NULL, NULL, provider_type, - CRYPT_VERIFYCONTEXT); - if (!ok) - return NULL; - - // Convert the user password into a key suitable to be fed into the PRF - // function. - ScopedHCRYPTKEY password_as_key; - BYTE* password_as_bytes = - const_cast<BYTE*>(reinterpret_cast<const BYTE*>(password.data())); - if (!ImportRawKey(provider, CALG_HMAC, password_as_bytes, - password.size(), &password_as_key)) - return NULL; - - // Configure the PRF function. Only HMAC variants are supported, with the - // only hash function supported being SHA1. - // TODO(rsleevi): Support SHA-256 on XP SP3+. - ScopedHCRYPTHASH prf; - if (!CreateHMACHash(provider, password_as_key, CALG_SHA1, &prf)) - return NULL; - - DWORD hLen = 0; - DWORD param_size = sizeof(hLen); - ok = CryptGetHashParam(prf, HP_HASHSIZE, - reinterpret_cast<BYTE*>(&hLen), ¶m_size, 0); - if (!ok || hLen == 0) - return NULL; - - // 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and stop. - size_t dkLen = key_size_in_bits / 8; - DCHECK_GT(dkLen, 0); - - if ((dkLen / hLen) > 0xFFFFFFFF) { - DLOG(ERROR) << "Derived key too long."; - return NULL; - } - - // 2. Let l be the number of hLen-octet blocks in the derived key, - // rounding up, and let r be the number of octets in the last - // block: - size_t L = (dkLen + hLen - 1) / hLen; - DCHECK_GT(L, 0); - - size_t total_generated_size = L * hLen; - std::vector<BYTE> generated_key(total_generated_size); - BYTE* block_offset = &generated_key[0]; - - // 3. For each block of the derived key apply the function F defined below - // to the password P, the salt S, the iteration count c, and the block - // index to compute the block: - // T_1 = F (P, S, c, 1) - // T_2 = F (P, S, c, 2) - // ... - // T_l = F (P, S, c, l) - // <snip> - // 4. Concatenate the blocks and extract the first dkLen octets to produce - // a derived key DK: - // DK = T_1 || T_2 || ... || T_l<0..r-1> - for (uint32 block_index = 1; block_index <= L; ++block_index) { - if (!ComputePBKDF2Block(prf, hLen, salt, iterations, block_index, - block_offset)) - return NULL; - block_offset += hLen; - } - - // Convert the derived key bytes into a key handle for the desired algorithm. - ScopedHCRYPTKEY key; - if (!ImportRawKey(provider, alg, &generated_key[0], dkLen, &key)) - return NULL; - - SymmetricKey* result = new SymmetricKey(provider.release(), key.release(), - &generated_key[0], dkLen); - - SecureZeroMemory(&generated_key[0], total_generated_size); - - return result; -} - -// static -SymmetricKey* SymmetricKey::Import(Algorithm algorithm, - const std::string& raw_key) { - DWORD provider_type = 0; - ALG_ID alg = 0; - switch (algorithm) { - case AES: - provider_type = PROV_RSA_AES; - alg = GetAESAlgIDForKeySize(raw_key.size() * 8); - break; - case HMAC_SHA1: - provider_type = PROV_RSA_FULL; - alg = CALG_HMAC; - break; - default: - NOTREACHED(); - break; - } - if (provider_type == 0 || alg == 0) - return NULL; - - ScopedHCRYPTPROV provider; - BOOL ok = CryptAcquireContext(provider.receive(), NULL, NULL, provider_type, - CRYPT_VERIFYCONTEXT); - if (!ok) - return NULL; - - ScopedHCRYPTKEY key; - if (!ImportRawKey(provider, alg, raw_key.data(), raw_key.size(), &key)) - return NULL; - - return new SymmetricKey(provider.release(), key.release(), - raw_key.data(), raw_key.size()); -} - -bool SymmetricKey::GetRawKey(std::string* raw_key) { - // Short circuit for when the key was supplied to the constructor. - if (!raw_key_.empty()) { - *raw_key = raw_key_; - return true; - } - - DWORD size = 0; - BOOL ok = CryptExportKey(key_, 0, PLAINTEXTKEYBLOB, 0, NULL, &size); - if (!ok) - return false; - - std::vector<BYTE> result(size); - - ok = CryptExportKey(key_, 0, PLAINTEXTKEYBLOB, 0, &result[0], &size); - if (!ok) - return false; - - PlaintextBlobHeader* header = - reinterpret_cast<PlaintextBlobHeader*>(&result[0]); - raw_key->assign(reinterpret_cast<char*>(&result[sizeof(*header)]), - header->cbKeySize); - - SecureZeroMemory(&result[0], size); - - return true; -} - -SymmetricKey::SymmetricKey(HCRYPTPROV provider, - HCRYPTKEY key, - const void* key_data, size_t key_size_in_bytes) - : provider_(provider), key_(key) { - if (key_data) { - raw_key_.assign(reinterpret_cast<const char*>(key_data), - key_size_in_bytes); - } -} - -} // namespace base diff --git a/base/hmac.h b/base/hmac.h deleted file mode 100644 index 2593307..0000000 --- a/base/hmac.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2011 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. - -// Utility class for calculating the HMAC for a given message. We currently -// only support SHA1 for the hash algorithm, but this can be extended easily. - -#ifndef BASE_HMAC_H_ -#define BASE_HMAC_H_ -#pragma once - -#include <string> - -#include "base/base_api.h" -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" - -namespace base { - -// Simplify the interface and reduce includes by abstracting out the internals. -struct HMACPlatformData; - -class BASE_API HMAC { - public: - // The set of supported hash functions. Extend as required. - enum HashAlgorithm { - SHA1, - SHA256, - }; - - explicit HMAC(HashAlgorithm hash_alg); - ~HMAC(); - - // Initializes this instance using |key| of the length |key_length|. Call Init - // only once. It returns false on the second or later calls. - bool Init(const unsigned char* key, int key_length); - - // Initializes this instance using |key|. Call Init only once. It returns - // false on the second or later calls. - bool Init(const std::string& key) { - return Init(reinterpret_cast<const unsigned char*>(key.data()), - static_cast<int>(key.size())); - } - - // Calculates the HMAC for the message in |data| using the algorithm supplied - // to the constructor and the key supplied to the Init method. The HMAC is - // returned in |digest|, which has |digest_length| bytes of storage available. - bool Sign(const std::string& data, unsigned char* digest, int digest_length); - - // TODO(albertb): Add a Verify method. - - private: - HashAlgorithm hash_alg_; - scoped_ptr<HMACPlatformData> plat_; - - DISALLOW_COPY_AND_ASSIGN(HMAC); -}; - -} // namespace base - -#endif // BASE_HMAC_H_ diff --git a/base/hmac_mac.cc b/base/hmac_mac.cc deleted file mode 100644 index 97dcbf5..0000000 --- a/base/hmac_mac.cc +++ /dev/null @@ -1,73 +0,0 @@ -// 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/hmac.h" - -#include <CommonCrypto/CommonHMAC.h> - -#include "base/logging.h" - -namespace base { - -struct HMACPlatformData { - std::string key_; -}; - -HMAC::HMAC(HashAlgorithm hash_alg) - : hash_alg_(hash_alg), plat_(new HMACPlatformData()) { - // Only SHA-1 and SHA-256 hash algorithms are supported now. - DCHECK(hash_alg_ == SHA1 || hash_alg_ == SHA256); -} - -bool HMAC::Init(const unsigned char *key, int key_length) { - if (!plat_->key_.empty()) { - // Init must not be called more than once on the same HMAC object. - NOTREACHED(); - return false; - } - - plat_->key_.assign(reinterpret_cast<const char*>(key), key_length); - - return true; -} - -HMAC::~HMAC() { - // Zero out key copy. - plat_->key_.assign(plat_->key_.length(), std::string::value_type()); - plat_->key_.clear(); - plat_->key_.reserve(0); -} - -bool HMAC::Sign(const std::string& data, - unsigned char* digest, - int digest_length) { - CCHmacAlgorithm algorithm; - int algorithm_digest_length; - switch (hash_alg_) { - case SHA1: - algorithm = kCCHmacAlgSHA1; - algorithm_digest_length = CC_SHA1_DIGEST_LENGTH; - break; - case SHA256: - algorithm = kCCHmacAlgSHA256; - algorithm_digest_length = CC_SHA256_DIGEST_LENGTH; - break; - default: - NOTREACHED(); - return false; - } - - if (digest_length < algorithm_digest_length) { - NOTREACHED(); - return false; - } - - CCHmac(algorithm, - plat_->key_.data(), plat_->key_.length(), data.data(), data.length(), - digest); - - return true; -} - -} // namespace base diff --git a/base/hmac_nss.cc b/base/hmac_nss.cc deleted file mode 100644 index 658616b..0000000 --- a/base/hmac_nss.cc +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2011 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/hmac.h" - -#include <nss.h> -#include <pk11pub.h> - -#include "base/crypto/scoped_nss_types.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/nss_util.h" - -namespace base { - -struct HMACPlatformData { - CK_MECHANISM_TYPE mechanism_; - ScopedPK11Slot slot_; - ScopedPK11SymKey sym_key_; -}; - -HMAC::HMAC(HashAlgorithm hash_alg) - : hash_alg_(hash_alg), plat_(new HMACPlatformData()) { - // Only SHA-1 and SHA-256 hash algorithms are supported. - switch (hash_alg_) { - case SHA1: - plat_->mechanism_ = CKM_SHA_1_HMAC; - break; - case SHA256: - plat_->mechanism_ = CKM_SHA256_HMAC; - break; - default: - NOTREACHED() << "Unsupported hash algorithm"; - break; - } -} - -HMAC::~HMAC() { -} - -bool HMAC::Init(const unsigned char *key, int key_length) { - base::EnsureNSSInit(); - - if (plat_->slot_.get()) { - // Init must not be called more than twice on the same HMAC object. - NOTREACHED(); - return false; - } - - plat_->slot_.reset(PK11_GetBestSlot(plat_->mechanism_, NULL)); - if (!plat_->slot_.get()) { - NOTREACHED(); - return false; - } - - SECItem key_item; - key_item.type = siBuffer; - key_item.data = const_cast<unsigned char*>(key); // NSS API isn't const. - key_item.len = key_length; - - plat_->sym_key_.reset(PK11_ImportSymKey(plat_->slot_.get(), - plat_->mechanism_, - PK11_OriginUnwrap, - CKA_SIGN, - &key_item, - NULL)); - if (!plat_->sym_key_.get()) { - NOTREACHED(); - return false; - } - - return true; -} - -bool HMAC::Sign(const std::string& data, - unsigned char* digest, - int digest_length) { - if (!plat_->sym_key_.get()) { - // Init has not been called before Sign. - NOTREACHED(); - return false; - } - - SECItem param = { siBuffer, NULL, 0 }; - ScopedPK11Context context(PK11_CreateContextBySymKey(plat_->mechanism_, - CKA_SIGN, - plat_->sym_key_.get(), - ¶m)); - if (!context.get()) { - NOTREACHED(); - return false; - } - - if (PK11_DigestBegin(context.get()) != SECSuccess) { - NOTREACHED(); - return false; - } - - if (PK11_DigestOp(context.get(), - reinterpret_cast<const unsigned char*>(data.data()), - data.length()) != SECSuccess) { - NOTREACHED(); - return false; - } - - unsigned int len = 0; - if (PK11_DigestFinal(context.get(), - digest, &len, digest_length) != SECSuccess) { - NOTREACHED(); - return false; - } - - return true; -} - -} // namespace base diff --git a/base/hmac_openssl.cc b/base/hmac_openssl.cc deleted file mode 100644 index 64ce177..0000000 --- a/base/hmac_openssl.cc +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2011 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/hmac.h" - -#include <openssl/hmac.h> - -#include <algorithm> -#include <vector> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/openssl_util.h" -#include "base/stl_util-inl.h" - -namespace base { - -struct HMACPlatformData { - std::vector<unsigned char> key; -}; - -HMAC::HMAC(HashAlgorithm hash_alg) - : hash_alg_(hash_alg), plat_(new HMACPlatformData()) { - // Only SHA-1 and SHA-256 hash algorithms are supported now. - DCHECK(hash_alg_ == SHA1 || hash_alg_ == SHA256); -} - -bool HMAC::Init(const unsigned char* key, int key_length) { - // Init must not be called more than once on the same HMAC object. - DCHECK(plat_->key.empty()); - - plat_->key.assign(key, key + key_length); - return true; -} - -HMAC::~HMAC() { - // Zero out key copy. - plat_->key.assign(plat_->key.size(), 0); - STLClearObject(&plat_->key); -} - -bool HMAC::Sign(const std::string& data, - unsigned char* digest, - int digest_length) { - DCHECK_GE(digest_length, 0); - DCHECK(!plat_->key.empty()); // Init must be called before Sign. - - ScopedOpenSSLSafeSizeBuffer<EVP_MAX_MD_SIZE> result(digest, digest_length); - return ::HMAC(hash_alg_ == SHA1 ? EVP_sha1() : EVP_sha256(), - &plat_->key[0], plat_->key.size(), - reinterpret_cast<const unsigned char*>(data.data()), - data.size(), - result.safe_buffer(), NULL); -} - -} // namespace base diff --git a/base/hmac_unittest.cc b/base/hmac_unittest.cc deleted file mode 100644 index 480c771..0000000 --- a/base/hmac_unittest.cc +++ /dev/null @@ -1,236 +0,0 @@ -// 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 <string> - -#include "base/hmac.h" -#include "testing/gtest/include/gtest/gtest.h" - -static const int kSHA1DigestSize = 20; -static const int kSHA256DigestSize = 32; - -TEST(HMACTest, HmacSafeBrowsingResponseTest) { - const int kKeySize = 16; - - // Client key. - const unsigned char kClientKey[kKeySize] = - { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd, - 0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 }; - - // Expected HMAC result using kMessage and kClientKey. - const unsigned char kReceivedHmac[kSHA1DigestSize] = - { 0xb9, 0x3c, 0xd6, 0xf0, 0x49, 0x47, 0xe2, 0x52, - 0x59, 0x7a, 0xbd, 0x1f, 0x2b, 0x4c, 0x83, 0xad, - 0x86, 0xd2, 0x48, 0x85 }; - - const char kMessage[] = -"n:1896\ni:goog-malware-shavar\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shav" -"ar_s_445-450\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_439-444\nu:s" -".ytimg.com/safebrowsing/rd/goog-malware-shavar_s_437\nu:s.ytimg.com/safebrowsi" -"ng/rd/goog-malware-shavar_s_436\nu:s.ytimg.com/safebrowsing/rd/goog-malware-sh" -"avar_s_433-435\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_431\nu:s.y" -"timg.com/safebrowsing/rd/goog-malware-shavar_s_430\nu:s.ytimg.com/safebrowsing" -"/rd/goog-malware-shavar_s_429\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shav" -"ar_s_428\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_426\nu:s.ytimg.c" -"om/safebrowsing/rd/goog-malware-shavar_s_424\nu:s.ytimg.com/safebrowsing/rd/go" -"og-malware-shavar_s_423\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_4" -"22\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_420\nu:s.ytimg.com/saf" -"ebrowsing/rd/goog-malware-shavar_s_419\nu:s.ytimg.com/safebrowsing/rd/goog-mal" -"ware-shavar_s_414\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_409-411" -"\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_405\nu:s.ytimg.com/safeb" -"rowsing/rd/goog-malware-shavar_s_404\nu:s.ytimg.com/safebrowsing/rd/goog-malwa" -"re-shavar_s_402\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_401\nu:s." -"ytimg.com/safebrowsing/rd/goog-malware-shavar_a_973-978\nu:s.ytimg.com/safebro" -"wsing/rd/goog-malware-shavar_a_937-972\nu:s.ytimg.com/safebrowsing/rd/goog-mal" -"ware-shavar_a_931-936\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_a_925" -"-930\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_a_919-924\ni:goog-phis" -"h-shavar\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2633\nu:s.ytimg.co" -"m/safebrowsing/rd/goog-phish-shavar_a_2632\nu:s.ytimg.com/safebrowsing/rd/goog" -"-phish-shavar_a_2629-2631\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2" -"626-2628\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2625\n"; - - std::string message_data(kMessage); - - base::HMAC hmac(base::HMAC::SHA1); - ASSERT_TRUE(hmac.Init(kClientKey, kKeySize)); - unsigned char calculated_hmac[kSHA1DigestSize]; - - EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kSHA1DigestSize)); - EXPECT_EQ(0, memcmp(kReceivedHmac, calculated_hmac, kSHA1DigestSize)); -} - -// Test cases from RFC 2202 section 3 -TEST(HMACTest, RFC2202TestCases) { - const struct { - const char *key; - const int key_len; - const char *data; - const int data_len; - const char *digest; - } cases[] = { - { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" - "\x0B\x0B\x0B\x0B", 20, - "Hi There", 8, - "\xB6\x17\x31\x86\x55\x05\x72\x64\xE2\x8B\xC0\xB6\xFB\x37\x8C\x8E" - "\xF1\x46\xBE\x00" }, - { "Jefe", 4, - "what do ya want for nothing?", 28, - "\xEF\xFC\xDF\x6A\xE5\xEB\x2F\xA2\xD2\x74\x16\xD5\xF1\x84\xDF\x9C" - "\x25\x9A\x7C\x79" }, - { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA", 20, - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD", 50, - "\x12\x5D\x73\x42\xB9\xAC\x11\xCD\x91\xA3\x9A\xF4\x8A\xA1\x7B\x4F" - "\x63\xF1\x75\xD3" }, - { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" - "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25, - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD", 50, - "\x4C\x90\x07\xF4\x02\x62\x50\xC6\xBC\x84\x14\xF9\xBF\x50\xC8\x6C" - "\x2D\x72\x35\xDA" }, - { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" - "\x0C\x0C\x0C\x0C", 20, - "Test With Truncation", 20, - "\x4C\x1A\x03\x42\x4B\x55\xE0\x7F\xE7\xF2\x7B\xE1\xD5\x8B\xB9\x32" - "\x4A\x9A\x5A\x04" }, - { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA", - 80, - "Test Using Larger Than Block-Size Key - Hash Key First", 54, - "\xAA\x4A\xE5\xE1\x52\x72\xD0\x0E\x95\x70\x56\x37\xCE\x8A\x3B\x55" - "\xED\x40\x21\x12" }, - { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA", - 80, - "Test Using Larger Than Block-Size Key and Larger " - "Than One Block-Size Data", 73, - "\xE8\xE9\x9D\x0F\x45\x23\x7D\x78\x6D\x6B\xBA\xA7\x96\x5C\x78\x08" - "\xBB\xFF\x1A\x91" } - }; - - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { - base::HMAC hmac(base::HMAC::SHA1); - ASSERT_TRUE(hmac.Init(reinterpret_cast<const unsigned char*>(cases[i].key), - cases[i].key_len)); - std::string data_string(cases[i].data, cases[i].data_len); - unsigned char digest[kSHA1DigestSize]; - EXPECT_TRUE(hmac.Sign(data_string, digest, kSHA1DigestSize)); - EXPECT_EQ(0, memcmp(cases[i].digest, digest, kSHA1DigestSize)); - } -} - -// TODO(wtc): add other test vectors from RFC 4231. -TEST(HMACTest, RFC4231TestCase6) { - unsigned char key[131]; - for (size_t i = 0; i < sizeof(key); ++i) - key[i] = 0xaa; - - std::string data = "Test Using Larger Than Block-Size Key - Hash Key First"; - ASSERT_EQ(54U, data.size()); - - static unsigned char kKnownHMACSHA256[] = { - 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, - 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, - 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, - 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 - }; - - base::HMAC hmac(base::HMAC::SHA256); - ASSERT_TRUE(hmac.Init(key, sizeof(key))); - unsigned char calculated_hmac[kSHA256DigestSize]; - - EXPECT_TRUE(hmac.Sign(data, calculated_hmac, kSHA256DigestSize)); - EXPECT_EQ(0, memcmp(kKnownHMACSHA256, calculated_hmac, kSHA256DigestSize)); -} - -// Based on NSS's FIPS HMAC power-up self-test. -TEST(HMACTest, NSSFIPSPowerUpSelfTest) { - static const char kKnownMessage[] = - "The test message for the MD2, MD5, and SHA-1 hashing algorithms."; - - static const unsigned char kKnownSecretKey[] = { - 0x46, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x54, 0x68, 0x75, 0x6e, - 0x64, 0x65, 0x72, 0x42, 0x69, 0x72, 0x64, 0x20, - 0x61, 0x72, 0x65, 0x20, 0x61, 0x77, 0x65, 0x73, - 0x6f, 0x6d, 0x65, 0x21, 0x00 - }; - - static const size_t kKnownSecretKeySize = sizeof(kKnownSecretKey); - - // HMAC-SHA-1 known answer (20 bytes). - static const unsigned char kKnownHMACSHA1[] = { - 0xd5, 0x85, 0xf6, 0x5b, 0x39, 0xfa, 0xb9, 0x05, - 0x3b, 0x57, 0x1d, 0x61, 0xe7, 0xb8, 0x84, 0x1e, - 0x5d, 0x0e, 0x1e, 0x11 - }; - - // HMAC-SHA-256 known answer (32 bytes). - static const unsigned char kKnownHMACSHA256[] = { - 0x05, 0x75, 0x9a, 0x9e, 0x70, 0x5e, 0xe7, 0x44, - 0xe2, 0x46, 0x4b, 0x92, 0x22, 0x14, 0x22, 0xe0, - 0x1b, 0x92, 0x8a, 0x0c, 0xfe, 0xf5, 0x49, 0xe9, - 0xa7, 0x1b, 0x56, 0x7d, 0x1d, 0x29, 0x40, 0x48 - }; - - std::string message_data(kKnownMessage); - - base::HMAC hmac(base::HMAC::SHA1); - ASSERT_TRUE(hmac.Init(kKnownSecretKey, kKnownSecretKeySize)); - unsigned char calculated_hmac[kSHA1DigestSize]; - - EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kSHA1DigestSize)); - EXPECT_EQ(0, memcmp(kKnownHMACSHA1, calculated_hmac, kSHA1DigestSize)); - - base::HMAC hmac2(base::HMAC::SHA256); - ASSERT_TRUE(hmac2.Init(kKnownSecretKey, kKnownSecretKeySize)); - unsigned char calculated_hmac2[kSHA256DigestSize]; - - EXPECT_TRUE(hmac2.Sign(message_data, calculated_hmac2, kSHA256DigestSize)); - EXPECT_EQ(0, memcmp(kKnownHMACSHA256, calculated_hmac2, kSHA256DigestSize)); -} - -TEST(HMACTest, HMACObjectReuse) { - const char *key = - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"; - const int key_len = 80; - - const struct { - const char *data; - const int data_len; - const char *digest; - } cases[] = { - { "Test Using Larger Than Block-Size Key - Hash Key First", 54, - "\xAA\x4A\xE5\xE1\x52\x72\xD0\x0E\x95\x70\x56\x37\xCE\x8A\x3B\x55" - "\xED\x40\x21\x12" }, - { "Test Using Larger Than Block-Size Key and Larger " - "Than One Block-Size Data", 73, - "\xE8\xE9\x9D\x0F\x45\x23\x7D\x78\x6D\x6B\xBA\xA7\x96\x5C\x78\x08" - "\xBB\xFF\x1A\x91" } - }; - - base::HMAC hmac(base::HMAC::SHA1); - ASSERT_TRUE(hmac.Init(reinterpret_cast<const unsigned char*>(key), key_len)); - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { - std::string data_string(cases[i].data, cases[i].data_len); - unsigned char digest[kSHA1DigestSize]; - EXPECT_TRUE(hmac.Sign(data_string, digest, kSHA1DigestSize)); - EXPECT_EQ(0, memcmp(cases[i].digest, digest, kSHA1DigestSize)); - } -} diff --git a/base/hmac_win.cc b/base/hmac_win.cc deleted file mode 100644 index a1c8225..0000000 --- a/base/hmac_win.cc +++ /dev/null @@ -1,197 +0,0 @@ -// 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/hmac.h" - -#include <windows.h> -#include <wincrypt.h> - -#include <algorithm> -#include <vector> - -#include "base/crypto/scoped_capi_types.h" -#include "base/logging.h" -#include "base/third_party/nss/blapi.h" -#include "base/third_party/nss/sha256.h" - -namespace base { - -namespace { - -// Implementation of HMAC-SHA-256: -// -// SHA-256 is supported in Windows XP SP3 or later. We still need to support -// Windows XP SP2, so unfortunately we have to implement HMAC-SHA-256 here. - -enum { - SHA256_BLOCK_SIZE = 64 // Block size (in bytes) of the input to SHA-256. -}; - -// See FIPS 198: The Keyed-Hash Message Authentication Code (HMAC). -void ComputeHMACSHA256(const unsigned char* key, size_t key_len, - const unsigned char* text, size_t text_len, - unsigned char* output, size_t output_len) { - SHA256Context ctx; - - // Pre-process the key, if necessary. - unsigned char key0[SHA256_BLOCK_SIZE]; - if (key_len > SHA256_BLOCK_SIZE) { - SHA256_Begin(&ctx); - SHA256_Update(&ctx, key, key_len); - SHA256_End(&ctx, key0, NULL, SHA256_LENGTH); - memset(key0 + SHA256_LENGTH, 0, SHA256_BLOCK_SIZE - SHA256_LENGTH); - } else { - memcpy(key0, key, key_len); - memset(key0 + key_len, 0, SHA256_BLOCK_SIZE - key_len); - } - - unsigned char padded_key[SHA256_BLOCK_SIZE]; - unsigned char inner_hash[SHA256_LENGTH]; - - // XOR key0 with ipad. - for (int i = 0; i < SHA256_BLOCK_SIZE; ++i) - padded_key[i] = key0[i] ^ 0x36; - - // Compute the inner hash. - SHA256_Begin(&ctx); - SHA256_Update(&ctx, padded_key, SHA256_BLOCK_SIZE); - SHA256_Update(&ctx, text, text_len); - SHA256_End(&ctx, inner_hash, NULL, SHA256_LENGTH); - - // XOR key0 with opad. - for (int i = 0; i < SHA256_BLOCK_SIZE; ++i) - padded_key[i] = key0[i] ^ 0x5c; - - // Compute the outer hash. - SHA256_Begin(&ctx); - SHA256_Update(&ctx, padded_key, SHA256_BLOCK_SIZE); - SHA256_Update(&ctx, inner_hash, SHA256_LENGTH); - SHA256_End(&ctx, output, NULL, output_len); -} - -} // namespace - -struct HMACPlatformData { - ~HMACPlatformData() { - if (!raw_key_.empty()) { - SecureZeroMemory(&raw_key_[0], raw_key_.size()); - } - - // Destroy the key before releasing the provider. - key_.reset(); - } - - ScopedHCRYPTPROV provider_; - ScopedHCRYPTKEY key_; - - // For HMAC-SHA-256 only. - std::vector<unsigned char> raw_key_; -}; - -HMAC::HMAC(HashAlgorithm hash_alg) - : hash_alg_(hash_alg), plat_(new HMACPlatformData()) { - // Only SHA-1 and SHA-256 hash algorithms are supported now. - DCHECK(hash_alg_ == SHA1 || hash_alg_ == SHA256); -} - -bool HMAC::Init(const unsigned char* key, int key_length) { - if (plat_->provider_ || plat_->key_ || !plat_->raw_key_.empty()) { - // Init must not be called more than once on the same HMAC object. - NOTREACHED(); - return false; - } - - if (hash_alg_ == SHA256) { - if (key_length < SHA256_LENGTH / 2) - return false; // Key is too short. - plat_->raw_key_.assign(key, key + key_length); - return true; - } - - if (!CryptAcquireContext(plat_->provider_.receive(), NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { - NOTREACHED(); - return false; - } - - // This code doesn't work on Win2k because PLAINTEXTKEYBLOB and - // CRYPT_IPSEC_HMAC_KEY are not supported on Windows 2000. PLAINTEXTKEYBLOB - // allows the import of an unencrypted key. For Win2k support, a cubmbersome - // exponent-of-one key procedure must be used: - // http://support.microsoft.com/kb/228786/en-us - // CRYPT_IPSEC_HMAC_KEY allows keys longer than 16 bytes. - - struct KeyBlob { - BLOBHEADER header; - DWORD key_size; - BYTE key_data[1]; - }; - size_t key_blob_size = std::max(offsetof(KeyBlob, key_data) + key_length, - sizeof(KeyBlob)); - std::vector<BYTE> key_blob_storage = std::vector<BYTE>(key_blob_size); - KeyBlob* key_blob = reinterpret_cast<KeyBlob*>(&key_blob_storage[0]); - key_blob->header.bType = PLAINTEXTKEYBLOB; - key_blob->header.bVersion = CUR_BLOB_VERSION; - key_blob->header.reserved = 0; - key_blob->header.aiKeyAlg = CALG_RC2; - key_blob->key_size = key_length; - memcpy(key_blob->key_data, key, key_length); - - if (!CryptImportKey(plat_->provider_, &key_blob_storage[0], - key_blob_storage.size(), 0, CRYPT_IPSEC_HMAC_KEY, - plat_->key_.receive())) { - NOTREACHED(); - return false; - } - - // Destroy the copy of the key. - SecureZeroMemory(key_blob->key_data, key_length); - - return true; -} - -HMAC::~HMAC() { -} - -bool HMAC::Sign(const std::string& data, - unsigned char* digest, - int digest_length) { - if (hash_alg_ == SHA256) { - if (plat_->raw_key_.empty()) - return false; - ComputeHMACSHA256(&plat_->raw_key_[0], plat_->raw_key_.size(), - reinterpret_cast<const unsigned char*>(data.data()), - data.size(), digest, digest_length); - return true; - } - - if (!plat_->provider_ || !plat_->key_) - return false; - - if (hash_alg_ != SHA1) { - NOTREACHED(); - return false; - } - - ScopedHCRYPTHASH hash; - if (!CryptCreateHash(plat_->provider_, CALG_HMAC, plat_->key_, 0, - hash.receive())) - return false; - - HMAC_INFO hmac_info; - memset(&hmac_info, 0, sizeof(hmac_info)); - hmac_info.HashAlgid = CALG_SHA1; - if (!CryptSetHashParam(hash, HP_HMAC_INFO, - reinterpret_cast<BYTE*>(&hmac_info), 0)) - return false; - - if (!CryptHashData(hash, reinterpret_cast<const BYTE*>(data.data()), - static_cast<DWORD>(data.size()), 0)) - return false; - - DWORD sha1_size = digest_length; - return !!CryptGetHashParam(hash, HP_HASHVAL, digest, &sha1_size, 0); -} - -} // namespace base diff --git a/base/nss_util.cc b/base/nss_util.cc deleted file mode 100644 index a074ab5..0000000 --- a/base/nss_util.cc +++ /dev/null @@ -1,704 +0,0 @@ -// Copyright (c) 2011 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/nss_util.h" -#include "base/nss_util_internal.h" - -#include <nss.h> -#include <pk11pub.h> -#include <plarena.h> -#include <prerror.h> -#include <prinit.h> -#include <prtime.h> -#include <secmod.h> - -#if defined(OS_LINUX) -#include <linux/nfs_fs.h> -#include <sys/vfs.h> -#endif - -#include <vector> - -#include "base/crypto/scoped_nss_types.h" -#include "base/environment.h" -#include "base/file_path.h" -#include "base/file_util.h" -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/native_library.h" -#include "base/stringprintf.h" -#include "base/threading/thread_restrictions.h" - -// USE_NSS means we use NSS for everything crypto-related. If USE_NSS is not -// defined, such as on Mac and Windows, we use NSS for SSL only -- we don't -// use NSS for crypto or certificate verification, and we don't use the NSS -// certificate and key databases. -#if defined(USE_NSS) -#include "base/crypto/crypto_module_blocking_password_delegate.h" -#include "base/synchronization/lock.h" -#endif // defined(USE_NSS) - -namespace base { - -namespace { - -#if defined(OS_CHROMEOS) -const char kNSSDatabaseName[] = "Real NSS database"; - -// Constants for loading opencryptoki. -const char kOpencryptokiModuleName[] = "opencryptoki"; -const char kOpencryptokiPath[] = "/usr/lib/opencryptoki/libopencryptoki.so"; - -// TODO(gspencer): Get these values from cryptohomed's dbus API when -// we ask if it has initialized the TPM yet. These should not be -// hard-coded here. -const char kTPMTokenName[] = "Initialized by CrOS"; -const char kTPMUserPIN[] = "111111"; -const char kTPMSecurityOfficerPIN[] = "000000"; - -// Fake certificate authority database used for testing. -static const FilePath::CharType kReadOnlyCertDB[] = - FILE_PATH_LITERAL("/etc/fake_root_ca/nssdb"); -#endif // defined(OS_CHROMEOS) - -std::string GetNSSErrorMessage() { - std::string result; - if (PR_GetErrorTextLength()) { - scoped_array<char> error_text(new char[PR_GetErrorTextLength() + 1]); - PRInt32 copied = PR_GetErrorText(error_text.get()); - result = std::string(error_text.get(), copied); - } else { - result = StringPrintf("NSS error code: %d", PR_GetError()); - } - return result; -} - -#if defined(USE_NSS) -FilePath GetDefaultConfigDirectory() { - FilePath dir = file_util::GetHomeDir(); - if (dir.empty()) { - LOG(ERROR) << "Failed to get home directory."; - return dir; - } - dir = dir.AppendASCII(".pki").AppendASCII("nssdb"); - if (!file_util::CreateDirectory(dir)) { - LOG(ERROR) << "Failed to create ~/.pki/nssdb directory."; - dir.clear(); - } - return dir; -} - -// On non-chromeos platforms, return the default config directory. -// On chromeos, return a read-only directory with fake root CA certs for testing -// (which will not exist on non-testing images). These root CA certs are used -// by the local Google Accounts server mock we use when testing our login code. -// If this directory is not present, NSS_Init() will fail. It is up to the -// caller to failover to NSS_NoDB_Init() at that point. -FilePath GetInitialConfigDirectory() { -#if defined(OS_CHROMEOS) - return FilePath(kReadOnlyCertDB); -#else - return GetDefaultConfigDirectory(); -#endif // defined(OS_CHROMEOS) -} - -// This callback for NSS forwards all requests to a caller-specified -// CryptoModuleBlockingPasswordDelegate object. -char* PKCS11PasswordFunc(PK11SlotInfo* slot, PRBool retry, void* arg) { -#if defined(OS_CHROMEOS) - // If we get asked for a password for the TPM, then return the - // static password we use. - if (PK11_GetTokenName(slot) == base::GetTPMTokenName()) - return PORT_Strdup(GetTPMUserPIN().c_str()); -#endif - base::CryptoModuleBlockingPasswordDelegate* delegate = - reinterpret_cast<base::CryptoModuleBlockingPasswordDelegate*>(arg); - if (delegate) { - bool cancelled = false; - std::string password = delegate->RequestPassword(PK11_GetTokenName(slot), - retry != PR_FALSE, - &cancelled); - if (cancelled) - return NULL; - char* result = PORT_Strdup(password.c_str()); - password.replace(0, password.size(), password.size(), 0); - return result; - } - DLOG(ERROR) << "PK11 password requested with NULL arg"; - return NULL; -} - -// NSS creates a local cache of the sqlite database if it detects that the -// filesystem the database is on is much slower than the local disk. The -// detection doesn't work with the latest versions of sqlite, such as 3.6.22 -// (NSS bug https://bugzilla.mozilla.org/show_bug.cgi?id=578561). So we set -// the NSS environment variable NSS_SDB_USE_CACHE to "yes" to override NSS's -// detection when database_dir is on NFS. See http://crbug.com/48585. -// -// TODO(wtc): port this function to other USE_NSS platforms. It is defined -// only for OS_LINUX simply because the statfs structure is OS-specific. -// -// Because this function sets an environment variable it must be run before we -// go multi-threaded. -void UseLocalCacheOfNSSDatabaseIfNFS(const FilePath& database_dir) { -#if defined(OS_LINUX) - struct statfs buf; - if (statfs(database_dir.value().c_str(), &buf) == 0) { - if (buf.f_type == NFS_SUPER_MAGIC) { - scoped_ptr<Environment> env(Environment::Create()); - const char* use_cache_env_var = "NSS_SDB_USE_CACHE"; - if (!env->HasVar(use_cache_env_var)) - env->SetVar(use_cache_env_var, "yes"); - } - } -#endif // defined(OS_LINUX) -} - -// A helper class that acquires the SECMOD list read lock while the -// AutoSECMODListReadLock is in scope. -class AutoSECMODListReadLock { - public: - AutoSECMODListReadLock() - : lock_(SECMOD_GetDefaultModuleListLock()) { - SECMOD_GetReadLock(lock_); - } - - ~AutoSECMODListReadLock() { - SECMOD_ReleaseReadLock(lock_); - } - - private: - SECMODListLock* lock_; - DISALLOW_COPY_AND_ASSIGN(AutoSECMODListReadLock); -}; - -PK11SlotInfo* FindSlotWithTokenName(const std::string& token_name) { - AutoSECMODListReadLock auto_lock; - SECMODModuleList* head = SECMOD_GetDefaultModuleList(); - for (SECMODModuleList* item = head; item != NULL; item = item->next) { - int slot_count = item->module->loaded ? item->module->slotCount : 0; - for (int i = 0; i < slot_count; i++) { - PK11SlotInfo* slot = item->module->slots[i]; - if (PK11_GetTokenName(slot) == token_name) - return PK11_ReferenceSlot(slot); - } - } - return NULL; -} - -#endif // defined(USE_NSS) - -// A singleton to initialize/deinitialize NSPR. -// Separate from the NSS singleton because we initialize NSPR on the UI thread. -// Now that we're leaking the singleton, we could merge back with the NSS -// singleton. -class NSPRInitSingleton { - private: - friend struct DefaultLazyInstanceTraits<NSPRInitSingleton>; - - NSPRInitSingleton() { - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - } - - // NOTE(willchan): We don't actually execute this code since we leak NSS to - // prevent non-joinable threads from using NSS after it's already been shut - // down. - ~NSPRInitSingleton() { - PL_ArenaFinish(); - PRStatus prstatus = PR_Cleanup(); - if (prstatus != PR_SUCCESS) { - LOG(ERROR) << "PR_Cleanup failed; was NSPR initialized on wrong thread?"; - } - } -}; - -LazyInstance<NSPRInitSingleton, LeakyLazyInstanceTraits<NSPRInitSingleton> > - g_nspr_singleton(LINKER_INITIALIZED); - -class NSSInitSingleton { - public: -#if defined(OS_CHROMEOS) - void OpenPersistentNSSDB() { - if (!chromeos_user_logged_in_) { - // GetDefaultConfigDirectory causes us to do blocking IO on UI thread. - // Temporarily allow it until we fix http://crbug.com/70119 - ThreadRestrictions::ScopedAllowIO allow_io; - chromeos_user_logged_in_ = true; - - // This creates another DB slot in NSS that is read/write, unlike - // the fake root CA cert DB and the "default" crypto key - // provider, which are still read-only (because we initialized - // NSS before we had a cryptohome mounted). - software_slot_ = OpenUserDB(GetDefaultConfigDirectory(), - kNSSDatabaseName); - } - } - - bool EnableTPMForNSS() { - if (!opencryptoki_module_) { - // This loads the opencryptoki module so we can talk to the - // hardware TPM. - opencryptoki_module_ = LoadModule( - kOpencryptokiModuleName, - kOpencryptokiPath, - // trustOrder=100 -- means it'll select this as the most - // trusted slot for the mechanisms it provides. - // slotParams=... -- selects RSA as the only mechanism, and only - // asks for the password when necessary (instead of every - // time, or after a timeout). - "trustOrder=100 slotParams=(1={slotFlags=[RSA] askpw=only})"); - if (opencryptoki_module_) { - // We shouldn't need to initialize the TPM PIN here because - // it'll be taken care of by cryptohomed, but we have to make - // sure that it is initialized. - - // TODO(gspencer): replace this with a dbus call that will - // check to see that cryptohomed has initialized the PINs, and - // will fetch the token name and PINs for accessing the TPM. - EnsureTPMInit(); - - // If this is set, then we'll use the TPM by default. - tpm_slot_ = GetTPMSlot(); - return true; - } - } - return false; - } - - std::string GetTPMTokenName() { - // TODO(gspencer): This should come from the dbus interchange with - // cryptohomed instead of being hard-coded. - return std::string(kTPMTokenName); - } - - std::string GetTPMUserPIN() { - // TODO(gspencer): This should come from the dbus interchange with - // cryptohomed instead of being hard-coded. - return std::string(kTPMUserPIN); - } - - PK11SlotInfo* GetTPMSlot() { - return FindSlotWithTokenName(GetTPMTokenName()); - } -#endif // defined(OS_CHROMEOS) - - - bool OpenTestNSSDB(const FilePath& path, const char* description) { - test_slot_ = OpenUserDB(path, description); - return !!test_slot_; - } - - void CloseTestNSSDB() { - if (test_slot_) { - SECStatus status = SECMOD_CloseUserDB(test_slot_); - if (status != SECSuccess) - LOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError(); - PK11_FreeSlot(test_slot_); - test_slot_ = NULL; - } - } - - PK11SlotInfo* GetPublicNSSKeySlot() { - if (test_slot_) - return PK11_ReferenceSlot(test_slot_); - if (software_slot_) - return PK11_ReferenceSlot(software_slot_); - return PK11_GetInternalKeySlot(); - } - - PK11SlotInfo* GetPrivateNSSKeySlot() { - if (test_slot_) - return PK11_ReferenceSlot(test_slot_); - // If the TPM slot has been opened, then return that one. - if (tpm_slot_) - return PK11_ReferenceSlot(tpm_slot_); - // If it hasn't, then return the software slot. - if (software_slot_) - return PK11_ReferenceSlot(software_slot_); - return PK11_GetInternalKeySlot(); - } - -#if defined(USE_NSS) - Lock* write_lock() { - return &write_lock_; - } -#endif // defined(USE_NSS) - - // This method is used to force NSS to be initialized without a DB. - // Call this method before NSSInitSingleton() is constructed. - static void ForceNoDBInit() { - force_nodb_init_ = true; - } - - private: - friend struct DefaultLazyInstanceTraits<NSSInitSingleton>; - - NSSInitSingleton() - : opencryptoki_module_(NULL), - software_slot_(NULL), - test_slot_(NULL), - tpm_slot_(NULL), - root_(NULL), - chromeos_user_logged_in_(false) { - EnsureNSPRInit(); - - // We *must* have NSS >= 3.12.3. See bug 26448. - COMPILE_ASSERT( - (NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH >= 3) || - (NSS_VMAJOR == 3 && NSS_VMINOR > 12) || - (NSS_VMAJOR > 3), - nss_version_check_failed); - // Also check the run-time NSS version. - // NSS_VersionCheck is a >= check, not strict equality. - if (!NSS_VersionCheck("3.12.3")) { - // It turns out many people have misconfigured NSS setups, where - // their run-time NSPR doesn't match the one their NSS was compiled - // against. So rather than aborting, complain loudly. - LOG(ERROR) << "NSS_VersionCheck(\"3.12.3\") failed. " - "We depend on NSS >= 3.12.3, and this error is not fatal " - "only because many people have busted NSS setups (for " - "example, using the wrong version of NSPR). " - "Please upgrade to the latest NSS and NSPR, and if you " - "still get this error, contact your distribution " - "maintainer."; - } - - SECStatus status = SECFailure; - bool nodb_init = force_nodb_init_; - -#if !defined(USE_NSS) - // Use the system certificate store, so initialize NSS without database. - nodb_init = true; -#endif - - if (nodb_init) { - status = NSS_NoDB_Init(NULL); - if (status != SECSuccess) { - LOG(ERROR) << "Error initializing NSS without a persistent " - "database: " << GetNSSErrorMessage(); - } - } else { -#if defined(USE_NSS) - FilePath database_dir = GetInitialConfigDirectory(); - if (!database_dir.empty()) { - // This duplicates the work which should have been done in - // EarlySetupForNSSInit. However, this function is idempotent so - // there's no harm done. - UseLocalCacheOfNSSDatabaseIfNFS(database_dir); - - // Initialize with a persistent database (likely, ~/.pki/nssdb). - // Use "sql:" which can be shared by multiple processes safely. - std::string nss_config_dir = - StringPrintf("sql:%s", database_dir.value().c_str()); -#if defined(OS_CHROMEOS) - status = NSS_Init(nss_config_dir.c_str()); -#else - status = NSS_InitReadWrite(nss_config_dir.c_str()); -#endif - if (status != SECSuccess) { - LOG(ERROR) << "Error initializing NSS with a persistent " - "database (" << nss_config_dir - << "): " << GetNSSErrorMessage(); - } - } - if (status != SECSuccess) { - VLOG(1) << "Initializing NSS without a persistent database."; - status = NSS_NoDB_Init(NULL); - if (status != SECSuccess) { - LOG(ERROR) << "Error initializing NSS without a persistent " - "database: " << GetNSSErrorMessage(); - return; - } - } - - PK11_SetPasswordFunc(PKCS11PasswordFunc); - - // If we haven't initialized the password for the NSS databases, - // initialize an empty-string password so that we don't need to - // log in. - PK11SlotInfo* slot = PK11_GetInternalKeySlot(); - if (slot) { - // PK11_InitPin may write to the keyDB, but no other thread can use NSS - // yet, so we don't need to lock. - if (PK11_NeedUserInit(slot)) - PK11_InitPin(slot, NULL, NULL); - PK11_FreeSlot(slot); - } - - root_ = InitDefaultRootCerts(); -#endif // defined(USE_NSS) - } - } - - // NOTE(willchan): We don't actually execute this code since we leak NSS to - // prevent non-joinable threads from using NSS after it's already been shut - // down. - ~NSSInitSingleton() { - if (tpm_slot_) { - PK11_FreeSlot(tpm_slot_); - tpm_slot_ = NULL; - } - if (software_slot_) { - SECMOD_CloseUserDB(software_slot_); - PK11_FreeSlot(software_slot_); - software_slot_ = NULL; - } - CloseTestNSSDB(); - if (root_) { - SECMOD_UnloadUserModule(root_); - SECMOD_DestroyModule(root_); - root_ = NULL; - } - if (opencryptoki_module_) { - SECMOD_UnloadUserModule(opencryptoki_module_); - SECMOD_DestroyModule(opencryptoki_module_); - opencryptoki_module_ = NULL; - } - - SECStatus status = NSS_Shutdown(); - if (status != SECSuccess) { - // We VLOG(1) because this failure is relatively harmless (leaking, but - // we're shutting down anyway). - VLOG(1) << "NSS_Shutdown failed; see http://crbug.com/4609"; - } - } - -#if defined(USE_NSS) - // Load nss's built-in root certs. - SECMODModule* InitDefaultRootCerts() { - SECMODModule* root = LoadModule("Root Certs", "libnssckbi.so", NULL); - if (root) - return root; - - // Aw, snap. Can't find/load root cert shared library. - // This will make it hard to talk to anybody via https. - NOTREACHED(); - return NULL; - } - - // Load the given module for this NSS session. - SECMODModule* LoadModule(const char* name, - const char* library_path, - const char* params) { - std::string modparams = StringPrintf( - "name=\"%s\" library=\"%s\" %s", - name, library_path, params ? params : ""); - - // Shouldn't need to const_cast here, but SECMOD doesn't properly - // declare input string arguments as const. Bug - // https://bugzilla.mozilla.org/show_bug.cgi?id=642546 was filed - // on NSS codebase to address this. - SECMODModule* module = SECMOD_LoadUserModule( - const_cast<char*>(modparams.c_str()), NULL, PR_FALSE); - if (!module) { - LOG(ERROR) << "Error loading " << name << " module into NSS: " - << GetNSSErrorMessage(); - return NULL; - } - return module; - } -#endif - -#if defined(OS_CHROMEOS) - void EnsureTPMInit() { - base::ScopedPK11Slot tpm_slot(GetTPMSlot()); - if (tpm_slot.get()) { - // TODO(gspencer): Remove this in favor of the dbus API for - // cryptohomed when that is available. - if (PK11_NeedUserInit(tpm_slot.get())) { - PK11_InitPin(tpm_slot.get(), - kTPMSecurityOfficerPIN, - kTPMUserPIN); - } - } - } -#endif - - static PK11SlotInfo* OpenUserDB(const FilePath& path, - const char* description) { - const std::string modspec = - StringPrintf("configDir='sql:%s' tokenDescription='%s'", - path.value().c_str(), description); - PK11SlotInfo* db_slot = SECMOD_OpenUserDB(modspec.c_str()); - if (db_slot) { - if (PK11_NeedUserInit(db_slot)) - PK11_InitPin(db_slot, NULL, NULL); - } - else { - LOG(ERROR) << "Error opening persistent database (" << modspec - << "): " << GetNSSErrorMessage(); - } - return db_slot; - } - - // If this is set to true NSS is forced to be initialized without a DB. - static bool force_nodb_init_; - - SECMODModule* opencryptoki_module_; - PK11SlotInfo* software_slot_; - PK11SlotInfo* test_slot_; - PK11SlotInfo* tpm_slot_; - SECMODModule* root_; - bool chromeos_user_logged_in_; -#if defined(USE_NSS) - // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011 - // is fixed, we will no longer need the lock. - Lock write_lock_; -#endif // defined(USE_NSS) -}; - -// static -bool NSSInitSingleton::force_nodb_init_ = false; - -LazyInstance<NSSInitSingleton, LeakyLazyInstanceTraits<NSSInitSingleton> > - g_nss_singleton(LINKER_INITIALIZED); - -} // namespace - -#if defined(USE_NSS) -void EarlySetupForNSSInit() { - FilePath database_dir = GetInitialConfigDirectory(); - if (!database_dir.empty()) - UseLocalCacheOfNSSDatabaseIfNFS(database_dir); -} -#endif - -void EnsureNSPRInit() { - g_nspr_singleton.Get(); -} - -void EnsureNSSInit() { - // Initializing SSL causes us to do blocking IO. - // Temporarily allow it until we fix - // http://code.google.com/p/chromium/issues/detail?id=59847 - ThreadRestrictions::ScopedAllowIO allow_io; - g_nss_singleton.Get(); -} - -void ForceNSSNoDBInit() { - NSSInitSingleton::ForceNoDBInit(); -} - -void DisableNSSForkCheck() { - scoped_ptr<Environment> env(Environment::Create()); - env->SetVar("NSS_STRICT_NOFORK", "DISABLED"); -} - -void LoadNSSLibraries() { - // Some NSS libraries are linked dynamically so load them here. -#if defined(USE_NSS) - // Try to search for multiple directories to load the libraries. - std::vector<FilePath> paths; - - // Use relative path to Search PATH for the library files. - paths.push_back(FilePath()); - - // For Debian derivaties NSS libraries are located here. - paths.push_back(FilePath("/usr/lib/nss")); - - // A list of library files to load. - std::vector<std::string> libs; - libs.push_back("libsoftokn3.so"); - libs.push_back("libfreebl3.so"); - - // For each combination of library file and path, check for existence and - // then load. - size_t loaded = 0; - for (size_t i = 0; i < libs.size(); ++i) { - for (size_t j = 0; j < paths.size(); ++j) { - FilePath path = paths[j].Append(libs[i]); - NativeLibrary lib = base::LoadNativeLibrary(path); - if (lib) { - ++loaded; - break; - } - } - } - - if (loaded == libs.size()) { - VLOG(3) << "NSS libraries loaded."; - } else { - LOG(WARNING) << "Failed to load NSS libraries."; - } -#endif -} - -bool CheckNSSVersion(const char* version) { - return !!NSS_VersionCheck(version); -} - -#if defined(USE_NSS) -bool OpenTestNSSDB(const FilePath& path, const char* description) { - return g_nss_singleton.Get().OpenTestNSSDB(path, description); -} - -void CloseTestNSSDB() { - g_nss_singleton.Get().CloseTestNSSDB(); -} - -Lock* GetNSSWriteLock() { - return g_nss_singleton.Get().write_lock(); -} - -AutoNSSWriteLock::AutoNSSWriteLock() : lock_(GetNSSWriteLock()) { - // May be NULL if the lock is not needed in our version of NSS. - if (lock_) - lock_->Acquire(); -} - -AutoNSSWriteLock::~AutoNSSWriteLock() { - if (lock_) { - lock_->AssertAcquired(); - lock_->Release(); - } -} -#endif // defined(USE_NSS) - -#if defined(OS_CHROMEOS) -void OpenPersistentNSSDB() { - g_nss_singleton.Get().OpenPersistentNSSDB(); -} - -bool EnableTPMForNSS() { - return g_nss_singleton.Get().EnableTPMForNSS(); -} - -std::string GetTPMTokenName() { - return g_nss_singleton.Get().GetTPMTokenName(); -} - -std::string GetTPMUserPIN() { - return g_nss_singleton.Get().GetTPMUserPIN(); -} -#endif // defined(OS_CHROMEOS) - -// TODO(port): Implement this more simply. We can convert by subtracting an -// offset (the difference between NSPR's and base::Time's epochs). -Time PRTimeToBaseTime(PRTime prtime) { - PRExplodedTime prxtime; - PR_ExplodeTime(prtime, PR_GMTParameters, &prxtime); - - Time::Exploded exploded; - exploded.year = prxtime.tm_year; - exploded.month = prxtime.tm_month + 1; - exploded.day_of_week = prxtime.tm_wday; - exploded.day_of_month = prxtime.tm_mday; - exploded.hour = prxtime.tm_hour; - exploded.minute = prxtime.tm_min; - exploded.second = prxtime.tm_sec; - exploded.millisecond = prxtime.tm_usec / 1000; - - return Time::FromUTCExploded(exploded); -} - -PK11SlotInfo* GetPublicNSSKeySlot() { - return g_nss_singleton.Get().GetPublicNSSKeySlot(); -} - -PK11SlotInfo* GetPrivateNSSKeySlot() { - return g_nss_singleton.Get().GetPrivateNSSKeySlot(); -} - -} // namespace base diff --git a/base/nss_util.h b/base/nss_util.h deleted file mode 100644 index adc514a..0000000 --- a/base/nss_util.h +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (c) 2011 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_NSS_UTIL_H_ -#define BASE_NSS_UTIL_H_ -#pragma once - -#include <string> -#include "base/basictypes.h" - -#if defined(USE_NSS) -class FilePath; -#endif // defined(USE_NSS) - -// 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 Lock; -class Time; - -#if defined(USE_NSS) -// EarlySetupForNSSInit performs lightweight setup which must occur before the -// process goes multithreaded. This does not initialise NSS. For test, see -// EnsureNSSInit. -void EarlySetupForNSSInit(); -#endif - -// Initialize NRPR if it isn't already initialized. This function is -// thread-safe, and NSPR will only ever be initialized once. NSPR will be -// properly shut down on program exit. -void EnsureNSPRInit(); - -// Initialize NSS if it isn't already initialized. This must be called before -// any other NSS functions. This function is thread-safe, and NSS will only -// ever be initialized once. NSS will be properly shut down on program exit. -void EnsureNSSInit(); - -// Call this before calling EnsureNSSInit() will force NSS to initialize -// without a persistent DB. This is used for the special case where access of -// persistent DB is prohibited. -// -// TODO(hclam): Isolate loading default root certs. -// -// NSS will be initialized without loading any user security modules, including -// the built-in root certificates module. User security modules need to be -// loaded manually after NSS initialization. -// -// If EnsureNSSInit() is called before then this function has no effect. -// -// Calling this method only has effect on Linux. -// -// WARNING: Use this with caution. -void ForceNSSNoDBInit(); - -// This methods is used to disable checks in NSS when used in a forked process. -// NSS checks whether it is running a forked process to avoid problems when -// using user security modules in a forked process. However if we are sure -// there are no modules loaded before the process is forked then there is no -// harm disabling the check. -// -// This method must be called before EnsureNSSInit() to take effect. -// -// WARNING: Use this with caution. -void DisableNSSForkCheck(); - -// Load NSS library files. This function has no effect on Mac and Windows. -// This loads the necessary NSS library files so that NSS can be initialized -// after loading additional library files is disallowed, for example when the -// sandbox is active. -// -// Note that this does not load libnssckbi.so which contains the root -// certificates. -void LoadNSSLibraries(); - -// Check if the current NSS version is greater than or equals to |version|. -// A sample version string is "3.12.3". -bool CheckNSSVersion(const char* version); - -#if defined(OS_CHROMEOS) -// Open the r/w nssdb that's stored inside the user's encrypted home -// directory. This is the default slot returned by -// GetPublicNSSKeySlot(). -void OpenPersistentNSSDB(); - -// Load the opencryptoki library into NSS so that we can access the -// TPM through NSS. Once this is called, GetPrivateNSSKeySlot() will -// return the TPM slot if one was found. Returns false if it was -// unable to load opencryptoki or open the TPM slot. -bool EnableTPMForNSS(); - -// Get name for the built-in TPM token on ChromeOS. -std::string GetTPMTokenName(); - -// Get the user PIN for the built-in TPM token on ChromeOS. -std::string GetTPMUserPIN(); -#endif - -// Convert a NSS PRTime value into a base::Time object. -// We use a int64 instead of PRTime here to avoid depending on NSPR headers. -Time PRTimeToBaseTime(int64 prtime); - -#if defined(USE_NSS) -// Exposed for unittests only. |path| should be an existing directory under -// which the DB files will be placed. |description| is a user-visible name for -// the DB, as a utf8 string, which will be truncated at 32 bytes. -bool OpenTestNSSDB(const FilePath& path, const char* description); -void CloseTestNSSDB(); - -// NSS has a bug which can cause a deadlock or stall in some cases when writing -// to the certDB and keyDB. It also has a bug which causes concurrent key pair -// generations to scribble over each other. To work around this, we synchronize -// writes to the NSS databases with a global lock. The lock is hidden beneath a -// function for easy disabling when the bug is fixed. Callers should allow for -// it to return NULL in the future. -// -// See https://bugzilla.mozilla.org/show_bug.cgi?id=564011 -Lock* GetNSSWriteLock(); - -// A helper class that acquires the NSS write Lock while the AutoNSSWriteLock -// is in scope. -class AutoNSSWriteLock { - public: - AutoNSSWriteLock(); - ~AutoNSSWriteLock(); - private: - Lock *lock_; - DISALLOW_COPY_AND_ASSIGN(AutoNSSWriteLock); -}; - -#endif // defined(USE_NSS) - -} // namespace base - -#endif // BASE_NSS_UTIL_H_ diff --git a/base/nss_util_internal.h b/base/nss_util_internal.h deleted file mode 100644 index be8436a..0000000 --- a/base/nss_util_internal.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2011 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_NSS_SLOT_UTIL_H_ -#define BASE_NSS_SLOT_UTIL_H_ -#pragma once - -#include <secmodt.h> - -// These functions return a type defined in an NSS header, and so cannot be -// declared in nss_util.h. Hence, they are declared here. - -namespace base { - -// Returns a reference to the default NSS key slot for storing -// public-key data only (e.g. server certs). Caller must release -// returned reference with PK11_FreeSlot. -PK11SlotInfo* GetPublicNSSKeySlot(); - -// Returns a reference to the default slot for storing private-key and -// mixed private-key/public-key data. Returns a hardware (TPM) NSS -// key slot if on ChromeOS and EnableTPMForNSS() has been called -// successfully. Caller must release returned reference with -// PK11_FreeSlot. -PK11SlotInfo* GetPrivateNSSKeySlot(); - -} // namespace base - -#endif // BASE_NSS_UTIL_H_ diff --git a/base/openssl_util.cc b/base/openssl_util.cc deleted file mode 100644 index 2c20f45..0000000 --- a/base/openssl_util.cc +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2011 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/openssl_util.h" - -#include <openssl/err.h> -#include <openssl/ssl.h> - -#include "base/logging.h" -#include "base/memory/scoped_vector.h" -#include "base/memory/singleton.h" -#include "base/string_piece.h" -#include "base/synchronization/lock.h" - -namespace base { - -namespace { - -unsigned long CurrentThreadId() { - return static_cast<unsigned long>(PlatformThread::CurrentId()); -} - -// Singleton for initializing and cleaning up the OpenSSL library. -class OpenSSLInitSingleton { - public: - static OpenSSLInitSingleton* GetInstance() { - // We allow the SSL environment to leak for multiple reasons: - // - it is used from a non-joinable worker thread that is not stopped on - // shutdown, hence may still be using OpenSSL library after the AtExit - // runner has completed. - // - There are other OpenSSL related singletons (e.g. the client socket - // context) who's cleanup depends on the global environment here, but - // we can't control the order the AtExit handlers will run in so - // allowing the global environment to leak at least ensures it is - // available for those other singletons to reliably cleanup. - return Singleton<OpenSSLInitSingleton, - LeakySingletonTraits<OpenSSLInitSingleton> >::get(); - } - private: - friend struct DefaultSingletonTraits<OpenSSLInitSingleton>; - OpenSSLInitSingleton() { - SSL_load_error_strings(); - SSL_library_init(); - OpenSSL_add_all_algorithms(); - int num_locks = CRYPTO_num_locks(); - locks_.reserve(num_locks); - for (int i = 0; i < num_locks; ++i) - locks_.push_back(new base::Lock()); - CRYPTO_set_locking_callback(LockingCallback); - CRYPTO_set_id_callback(CurrentThreadId); - } - - ~OpenSSLInitSingleton() { - CRYPTO_set_locking_callback(NULL); - EVP_cleanup(); - ERR_free_strings(); - } - - static void LockingCallback(int mode, int n, const char* file, int line) { - OpenSSLInitSingleton::GetInstance()->OnLockingCallback(mode, n, file, line); - } - - void OnLockingCallback(int mode, int n, const char* file, int line) { - CHECK_LT(static_cast<size_t>(n), locks_.size()); - if (mode & CRYPTO_LOCK) - locks_[n]->Acquire(); - else - locks_[n]->Release(); - } - - // These locks are used and managed by OpenSSL via LockingCallback(). - ScopedVector<base::Lock> locks_; - - DISALLOW_COPY_AND_ASSIGN(OpenSSLInitSingleton); -}; - -// Callback routine for OpenSSL to print error messages. |str| is a -// NULL-terminated string of length |len| containing diagnostic information -// such as the library, function and reason for the error, the file and line -// where the error originated, plus potentially any context-specific -// information about the error. |context| contains a pointer to user-supplied -// data, which is currently unused. -// If this callback returns a value <= 0, OpenSSL will stop processing the -// error queue and return, otherwise it will continue calling this function -// until all errors have been removed from the queue. -int OpenSSLErrorCallback(const char* str, size_t len, void* context) { - DVLOG(1) << "\t" << StringPiece(str, len); - return 1; -} - -} // namespace - -void EnsureOpenSSLInit() { - (void)OpenSSLInitSingleton::GetInstance(); -} - -void ClearOpenSSLERRStack(const tracked_objects::Location& location) { - if (logging::DEBUG_MODE && VLOG_IS_ON(1)) { - int error_num = ERR_peek_error(); - if (error_num == 0) - return; - - std::string message; - location.Write(true, true, &message); - DVLOG(1) << "OpenSSL ERR_get_error stack from " << message; - ERR_print_errors_cb(&OpenSSLErrorCallback, NULL); - } else { - ERR_clear_error(); - } -} - -} // namespace base diff --git a/base/openssl_util.h b/base/openssl_util.h deleted file mode 100644 index 9ce7f81..0000000 --- a/base/openssl_util.h +++ /dev/null @@ -1,113 +0,0 @@ -// 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_OPENSSL_UTIL_H_ -#define BASE_OPENSSL_UTIL_H_ -#pragma once - -#include "base/basictypes.h" -#include "base/tracked.h" - -namespace base { - -// A helper class that takes care of destroying OpenSSL objects when it goes out -// of scope. -template <typename T, void (*destructor)(T*)> -class ScopedOpenSSL { - public: - ScopedOpenSSL() : ptr_(NULL) { } - explicit ScopedOpenSSL(T* ptr) : ptr_(ptr) { } - ~ScopedOpenSSL() { - reset(NULL); - } - - T* get() const { return ptr_; } - void reset(T* ptr) { - if (ptr != ptr_) { - if (ptr_) (*destructor)(ptr_); - ptr_ = ptr; - } - } - - private: - T* ptr_; - - DISALLOW_COPY_AND_ASSIGN(ScopedOpenSSL); -}; - -// Provides a buffer of at least MIN_SIZE bytes, for use when calling OpenSSL's -// SHA256, HMAC, etc functions, adapting the buffer sizing rules to meet those -// of the our base wrapper APIs. -// This allows the library to write directly to the caller's buffer if it is of -// sufficient size, but if not it will write to temporary |min_sized_buffer_| -// of required size and then its content is automatically copied out on -// destruction, with truncation as appropriate. -template<int MIN_SIZE> -class ScopedOpenSSLSafeSizeBuffer { - public: - ScopedOpenSSLSafeSizeBuffer(unsigned char* output, size_t output_len) - : output_(output), - output_len_(output_len) { - } - - ~ScopedOpenSSLSafeSizeBuffer() { - if (output_len_ < MIN_SIZE) { - // Copy the temporary buffer out, truncating as needed. - memcpy(output_, min_sized_buffer_, output_len_); - } - // else... any writing already happened directly into |output_|. - } - - unsigned char* safe_buffer() { - return output_len_ < MIN_SIZE ? min_sized_buffer_ : output_; - } - - private: - // Pointer to the caller's data area and it's associated size, where data - // written via safe_buffer() will [eventually] end up. - unsigned char* output_; - size_t output_len_; - - // Temporary buffer writen into in the case where the caller's - // buffer is not of sufficient size. - unsigned char min_sized_buffer_[MIN_SIZE]; - - DISALLOW_COPY_AND_ASSIGN(ScopedOpenSSLSafeSizeBuffer); -}; - -// Initialize OpenSSL if it isn't already initialized. This must be called -// before any other OpenSSL functions. -// This function is thread-safe, and OpenSSL will only ever be initialized once. -// OpenSSL will be properly shut down on program exit. -void EnsureOpenSSLInit(); - -// Drains the OpenSSL ERR_get_error stack. On a debug build the error codes -// are send to VLOG(1), on a release build they are disregarded. In most -// cases you should pass FROM_HERE as the |location|. -void ClearOpenSSLERRStack(const tracked_objects::Location& location); - -// Place an instance of this class on the call stack to automatically clear -// the OpenSSL error stack on function exit. -class OpenSSLErrStackTracer { - public: - // Pass FROM_HERE as |location|, to help track the source of OpenSSL error - // messages. Note any diagnostic emitted will be tagged with the location of - // the constructor call as it's not possible to trace a destructor's callsite. - explicit OpenSSLErrStackTracer(const tracked_objects::Location& location) - : location_(location) { - EnsureOpenSSLInit(); - } - ~OpenSSLErrStackTracer() { - ClearOpenSSLERRStack(location_); - } - - private: - const tracked_objects::Location location_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(OpenSSLErrStackTracer); -}; - -} // namespace base - -#endif // BASE_OPENSSL_UTIL_H_ diff --git a/base/sha1_win.cc b/base/sha1_win.cc index 853c244..233749b5 100644 --- a/base/sha1_win.cc +++ b/base/sha1_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -7,7 +7,9 @@ #include <windows.h> #include <wincrypt.h> -#include "base/crypto/scoped_capi_types.h" +// This file is not being compiled at the moment (see bug 47218). If we keep +// sha1 inside base, we cannot depend on src/crypto. +// #include "crypto/scoped_capi_types.h" #include "base/logging.h" namespace base { diff --git a/base/sha2.cc b/base/sha2.cc deleted file mode 100644 index e8c922c..0000000 --- a/base/sha2.cc +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2011 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/sha2.h" - -#include "base/crypto/secure_hash.h" -#include "base/scoped_ptr.h" -#include "base/stl_util-inl.h" - -namespace base { - -void SHA256HashString(const std::string& str, void* output, size_t len) { - scoped_ptr<base::SecureHash> ctx(base::SecureHash::Create( - base::SecureHash::SHA256)); - ctx->Update(str.data(), str.length()); - ctx->Finish(output, len); -} - -std::string SHA256HashString(const std::string& str) { - std::string output(SHA256_LENGTH, 0); - SHA256HashString(str, string_as_array(&output), output.size()); - return output; -} - -} // namespace base diff --git a/base/sha2.h b/base/sha2.h deleted file mode 100644 index b10b9f0..0000000 --- a/base/sha2.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2011 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_SHA2_H_ -#define BASE_SHA2_H_ -#pragma once - -#include <string> - -#include "base/base_api.h" - -namespace base { - -// These functions perform SHA-256 operations. -// -// Functions for SHA-384 and SHA-512 can be added when the need arises. - -enum { - SHA256_LENGTH = 32 // length in bytes of a SHA-256 hash -}; - -// Computes the SHA-256 hash of the input string 'str' and stores the first -// 'len' bytes of the hash in the output buffer 'output'. If 'len' > 32, -// only 32 bytes (the full hash) are stored in the 'output' buffer. -BASE_API void SHA256HashString(const std::string& str, - void* output, size_t len); - -// Convenience version of the above that returns the result in a 32-byte -// string. -BASE_API std::string SHA256HashString(const std::string& str); - -} // namespace base - -#endif // BASE_SHA2_H_ diff --git a/base/sha2_unittest.cc b/base/sha2_unittest.cc deleted file mode 100644 index b0321e8..0000000 --- a/base/sha2_unittest.cc +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2006-2008 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/sha2.h" - -#include "base/basictypes.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(Sha256Test, Test1) { - // Example B.1 from FIPS 180-2: one-block message. - std::string input1 = "abc"; - int expected1[] = { 0xba, 0x78, 0x16, 0xbf, - 0x8f, 0x01, 0xcf, 0xea, - 0x41, 0x41, 0x40, 0xde, - 0x5d, 0xae, 0x22, 0x23, - 0xb0, 0x03, 0x61, 0xa3, - 0x96, 0x17, 0x7a, 0x9c, - 0xb4, 0x10, 0xff, 0x61, - 0xf2, 0x00, 0x15, 0xad }; - - uint8 output1[base::SHA256_LENGTH]; - base::SHA256HashString(input1, output1, sizeof(output1)); - for (size_t i = 0; i < base::SHA256_LENGTH; i++) - EXPECT_EQ(expected1[i], static_cast<int>(output1[i])); - - uint8 output_truncated1[4]; // 4 bytes == 32 bits - base::SHA256HashString(input1, output_truncated1, sizeof(output_truncated1)); - for (size_t i = 0; i < sizeof(output_truncated1); i++) - EXPECT_EQ(expected1[i], static_cast<int>(output_truncated1[i])); -} - -TEST(Sha256Test, Test1_String) { - // Same as the above, but using the wrapper that returns a std::string. - // Example B.1 from FIPS 180-2: one-block message. - std::string input1 = "abc"; - int expected1[] = { 0xba, 0x78, 0x16, 0xbf, - 0x8f, 0x01, 0xcf, 0xea, - 0x41, 0x41, 0x40, 0xde, - 0x5d, 0xae, 0x22, 0x23, - 0xb0, 0x03, 0x61, 0xa3, - 0x96, 0x17, 0x7a, 0x9c, - 0xb4, 0x10, 0xff, 0x61, - 0xf2, 0x00, 0x15, 0xad }; - - std::string output1 = base::SHA256HashString(input1); - ASSERT_EQ(base::SHA256_LENGTH, output1.size()); - for (size_t i = 0; i < base::SHA256_LENGTH; i++) - EXPECT_EQ(expected1[i], static_cast<uint8>(output1[i])); -} - -TEST(Sha256Test, Test2) { - // Example B.2 from FIPS 180-2: multi-block message. - std::string input2 = - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; - int expected2[] = { 0x24, 0x8d, 0x6a, 0x61, - 0xd2, 0x06, 0x38, 0xb8, - 0xe5, 0xc0, 0x26, 0x93, - 0x0c, 0x3e, 0x60, 0x39, - 0xa3, 0x3c, 0xe4, 0x59, - 0x64, 0xff, 0x21, 0x67, - 0xf6, 0xec, 0xed, 0xd4, - 0x19, 0xdb, 0x06, 0xc1 }; - - uint8 output2[base::SHA256_LENGTH]; - base::SHA256HashString(input2, output2, sizeof(output2)); - for (size_t i = 0; i < base::SHA256_LENGTH; i++) - EXPECT_EQ(expected2[i], static_cast<int>(output2[i])); - - uint8 output_truncated2[6]; - base::SHA256HashString(input2, output_truncated2, sizeof(output_truncated2)); - for (size_t i = 0; i < sizeof(output_truncated2); i++) - EXPECT_EQ(expected2[i], static_cast<int>(output_truncated2[i])); -} - -TEST(Sha256Test, Test3) { - // Example B.3 from FIPS 180-2: long message. - std::string input3(1000000, 'a'); // 'a' repeated a million times - int expected3[] = { 0xcd, 0xc7, 0x6e, 0x5c, - 0x99, 0x14, 0xfb, 0x92, - 0x81, 0xa1, 0xc7, 0xe2, - 0x84, 0xd7, 0x3e, 0x67, - 0xf1, 0x80, 0x9a, 0x48, - 0xa4, 0x97, 0x20, 0x0e, - 0x04, 0x6d, 0x39, 0xcc, - 0xc7, 0x11, 0x2c, 0xd0 }; - - uint8 output3[base::SHA256_LENGTH]; - base::SHA256HashString(input3, output3, sizeof(output3)); - for (size_t i = 0; i < base::SHA256_LENGTH; i++) - EXPECT_EQ(expected3[i], static_cast<int>(output3[i])); - - uint8 output_truncated3[12]; - base::SHA256HashString(input3, output_truncated3, sizeof(output_truncated3)); - for (size_t i = 0; i < sizeof(output_truncated3); i++) - EXPECT_EQ(expected3[i], static_cast<int>(output_truncated3[i])); -} diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc index aadd5e1..d952dc9 100644 --- a/base/test/test_suite.cc +++ b/base/test/test_suite.cc @@ -15,7 +15,6 @@ #include "base/logging.h" #include "base/mac/scoped_nsautorelease_pool.h" #include "base/memory/scoped_ptr.h" -#include "base/nss_util.h" #include "base/path_service.h" #include "base/process_util.h" #include "base/test/multiprocess_test.h" @@ -214,14 +213,6 @@ void TestSuite::Initialize() { icu_util::Initialize(); -#if defined(USE_NSS) - // Trying to repeatedly initialize and cleanup NSS and NSPR may result in - // a deadlock. Such repeated initialization will happen when using test - // isolation. Prevent problems by initializing NSS here, so that the cleanup - // will be done only on process exit. - base::EnsureNSSInit(); -#endif // defined(USE_NSS) - CatchMaybeTests(); TestTimeouts::Initialize(); diff --git a/base/third_party/nss/LICENSE b/base/third_party/nss/LICENSE deleted file mode 100644 index 0367164..0000000 --- a/base/third_party/nss/LICENSE +++ /dev/null @@ -1,35 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ diff --git a/base/third_party/nss/README.chromium b/base/third_party/nss/README.chromium deleted file mode 100644 index 9b466c8..0000000 --- a/base/third_party/nss/README.chromium +++ /dev/null @@ -1,13 +0,0 @@ -Name: Network Security Services (NSS) -URL: http://www.mozilla.org/projects/security/pki/nss/ - -We extracted the SHA-256 source files, eliminated unneeded dependencies, -deleted or commented out unused code, and tweaked them for Chrome's source -tree. sha512.c is renamed sha512.cc so that it can include Chrome's C++ -header "base/basictypes.h". We define NOUNROLL256 to reduce the object code -size. - -In blapi.h and sha512.cc, replaced uint32 by unsigned int so that they can -be compiled with -DNO_NSPR_10_SUPPORT. NO_NSPR_10_SUPPORT turns off the -definition of the NSPR 1.0 types int8 - int64 and uint8 - uint64 to avoid -conflict with the same-named types defined in "base/basictypes.h". diff --git a/base/third_party/nss/blapi.h b/base/third_party/nss/blapi.h deleted file mode 100644 index b1f8dc0..0000000 --- a/base/third_party/nss/blapi.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * crypto.h - public data structures and prototypes for the crypto library - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id: blapi.h,v 1.27 2007/11/09 18:49:32 wtc%google.com Exp $ */ - -#ifndef _BLAPI_H_ -#define _BLAPI_H_ - -#include "base/third_party/nss/blapit.h" - -/******************************************/ - -extern SHA256Context *SHA256_NewContext(void); -extern void SHA256_DestroyContext(SHA256Context *cx, PRBool freeit); -extern void SHA256_Begin(SHA256Context *cx); -extern void SHA256_Update(SHA256Context *cx, const unsigned char *input, - unsigned int inputLen); -extern void SHA256_End(SHA256Context *cx, unsigned char *digest, - unsigned int *digestLen, unsigned int maxDigestLen); -extern SECStatus SHA256_HashBuf(unsigned char *dest, const unsigned char *src, - unsigned int src_length); -extern SECStatus SHA256_Hash(unsigned char *dest, const char *src); -extern void SHA256_TraceState(SHA256Context *cx); -extern unsigned int SHA256_FlattenSize(SHA256Context *cx); -extern SECStatus SHA256_Flatten(SHA256Context *cx,unsigned char *space); -extern SHA256Context * SHA256_Resurrect(unsigned char *space, void *arg); -extern void SHA256_Clone(SHA256Context *dest, SHA256Context *src); - -/******************************************/ - -extern SHA512Context *SHA512_NewContext(void); -extern void SHA512_DestroyContext(SHA512Context *cx, PRBool freeit); -extern void SHA512_Begin(SHA512Context *cx); -extern void SHA512_Update(SHA512Context *cx, const unsigned char *input, - unsigned int inputLen); -extern void SHA512_End(SHA512Context *cx, unsigned char *digest, - unsigned int *digestLen, unsigned int maxDigestLen); -extern SECStatus SHA512_HashBuf(unsigned char *dest, const unsigned char *src, - unsigned int src_length); -extern SECStatus SHA512_Hash(unsigned char *dest, const char *src); -extern void SHA512_TraceState(SHA512Context *cx); -extern unsigned int SHA512_FlattenSize(SHA512Context *cx); -extern SECStatus SHA512_Flatten(SHA512Context *cx,unsigned char *space); -extern SHA512Context * SHA512_Resurrect(unsigned char *space, void *arg); -extern void SHA512_Clone(SHA512Context *dest, SHA512Context *src); - -/******************************************/ - -extern SHA384Context *SHA384_NewContext(void); -extern void SHA384_DestroyContext(SHA384Context *cx, PRBool freeit); -extern void SHA384_Begin(SHA384Context *cx); -extern void SHA384_Update(SHA384Context *cx, const unsigned char *input, - unsigned int inputLen); -extern void SHA384_End(SHA384Context *cx, unsigned char *digest, - unsigned int *digestLen, unsigned int maxDigestLen); -extern SECStatus SHA384_HashBuf(unsigned char *dest, const unsigned char *src, - unsigned int src_length); -extern SECStatus SHA384_Hash(unsigned char *dest, const char *src); -extern void SHA384_TraceState(SHA384Context *cx); -extern unsigned int SHA384_FlattenSize(SHA384Context *cx); -extern SECStatus SHA384_Flatten(SHA384Context *cx,unsigned char *space); -extern SHA384Context * SHA384_Resurrect(unsigned char *space, void *arg); -extern void SHA384_Clone(SHA384Context *dest, SHA384Context *src); - -#endif /* _BLAPI_H_ */ diff --git a/base/third_party/nss/blapit.h b/base/third_party/nss/blapit.h deleted file mode 100644 index e16a084..0000000 --- a/base/third_party/nss/blapit.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * blapit.h - public data structures for the crypto library - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com> and - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id: blapit.h,v 1.20 2007/02/28 19:47:37 rrelyea%redhat.com Exp $ */ - -#ifndef _BLAPIT_H_ -#define _BLAPIT_H_ - -#include "base/third_party/nspr/prtypes.h" - -/* -** A status code. Status's are used by procedures that return status -** values. Again the motivation is so that a compiler can generate -** warnings when return values are wrong. Correct testing of status codes: -** -** SECStatus rv; -** rv = some_function (some_argument); -** if (rv != SECSuccess) -** do_an_error_thing(); -** -*/ -typedef enum _SECStatus { - SECWouldBlock = -2, - SECFailure = -1, - SECSuccess = 0 -} SECStatus; - -#define SHA256_LENGTH 32 /* bytes */ -#define SHA384_LENGTH 48 /* bytes */ -#define SHA512_LENGTH 64 /* bytes */ -#define HASH_LENGTH_MAX SHA512_LENGTH - -/* - * Input block size for each hash algorithm. - */ - -#define SHA256_BLOCK_LENGTH 64 /* bytes */ -#define SHA384_BLOCK_LENGTH 128 /* bytes */ -#define SHA512_BLOCK_LENGTH 128 /* bytes */ -#define HASH_BLOCK_LENGTH_MAX SHA512_BLOCK_LENGTH - -/*************************************************************************** -** Opaque objects -*/ - -struct SHA256ContextStr ; -struct SHA512ContextStr ; - -typedef struct SHA256ContextStr SHA256Context; -typedef struct SHA512ContextStr SHA512Context; -/* SHA384Context is really a SHA512ContextStr. This is not a mistake. */ -typedef struct SHA512ContextStr SHA384Context; - -#endif /* _BLAPIT_H_ */ diff --git a/base/third_party/nss/sha256.h b/base/third_party/nss/sha256.h deleted file mode 100644 index e641b49..0000000 --- a/base/third_party/nss/sha256.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2002 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _SHA_256_H_ -#define _SHA_256_H_ - -#include "base/third_party/nspr/prtypes.h" - -struct SHA256ContextStr { - union { - PRUint32 w[64]; /* message schedule, input buffer, plus 48 words */ - PRUint8 b[256]; - } u; - PRUint32 h[8]; /* 8 state variables */ - PRUint32 sizeHi,sizeLo; /* 64-bit count of hashed bytes. */ -}; - -#endif /* _SHA_256_H_ */ diff --git a/base/third_party/nss/sha512.cc b/base/third_party/nss/sha512.cc deleted file mode 100644 index 6ad0645..0000000 --- a/base/third_party/nss/sha512.cc +++ /dev/null @@ -1,1391 +0,0 @@ -/* - * sha512.c - implementation of SHA256, SHA384 and SHA512 - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2002 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id: sha512.c,v 1.9 2006/10/13 16:54:04 wtchang%redhat.com Exp $ */ - -// Prevent manual unrolling in the sha256 code, which reduces the binary code -// size from ~10k to ~1k. The performance should be reasonable for our use. -#define NOUNROLL256 1 - -#include "base/third_party/nspr/prtypes.h" /* for PRUintXX */ -#if defined(_X86_) || defined(SHA_NO_LONG_LONG) -#define NOUNROLL512 1 -#undef HAVE_LONG_LONG -#endif -#include "base/third_party/nss/blapi.h" -#include "base/third_party/nss/sha256.h" /* for struct SHA256ContextStr */ - -#include <stdlib.h> -#include <string.h> -#define PORT_New(type) static_cast<type*>(malloc(sizeof(type))) -#define PORT_ZFree(ptr, len) do { memset(ptr, 0, len); free(ptr); } while (0) -#define PORT_Strlen(s) static_cast<unsigned int>(strlen(s)) -#define PORT_Memcpy memcpy - -/* ============= Common constants and defines ======================= */ - -#define W ctx->u.w -#define B ctx->u.b -#define H ctx->h - -#define SHR(x,n) (x >> n) -#define SHL(x,n) (x << n) -#define Ch(x,y,z) ((x & y) ^ (~x & z)) -#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) - -/* Padding used with all flavors of SHA */ -static const PRUint8 pad[240] = { -0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - /* compiler will fill the rest in with zeros */ -}; - -/* ============= SHA256 implemenmtation ================================== */ - -/* SHA-256 constants, K256. */ -static const PRUint32 K256[64] = { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -}; - -/* SHA-256 initial hash values */ -static const PRUint32 H256[8] = { - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 -}; - -#if defined(_MSC_VER) && defined(_X86_) -#ifndef FORCEINLINE -#if (_MSC_VER >= 1200) -#define FORCEINLINE __forceinline -#else -#define FORCEINLINE __inline -#endif -#endif -#define FASTCALL __fastcall - -static FORCEINLINE PRUint32 FASTCALL -swap4b(PRUint32 dwd) -{ - __asm { - mov eax,dwd - bswap eax - } -} - -#define SHA_HTONL(x) swap4b(x) -#define BYTESWAP4(x) x = SHA_HTONL(x) - -#elif defined(LINUX) && defined(_X86_) -#undef __OPTIMIZE__ -#define __OPTIMIZE__ 1 -#undef __pentium__ -#define __pentium__ 1 -#include <byteswap.h> -#define SHA_HTONL(x) bswap_32(x) -#define BYTESWAP4(x) x = SHA_HTONL(x) - -#else /* neither windows nor Linux PC */ -#define SWAP4MASK 0x00FF00FF -#define SHA_HTONL(x) (t1 = (x), t1 = (t1 << 16) | (t1 >> 16), \ - ((t1 & SWAP4MASK) << 8) | ((t1 >> 8) & SWAP4MASK)) -#define BYTESWAP4(x) x = SHA_HTONL(x) -#endif - -#if defined(_MSC_VER) && defined(_X86_) -#pragma intrinsic (_lrotr, _lrotl) -#define ROTR32(x,n) _lrotr(x,n) -#define ROTL32(x,n) _lrotl(x,n) -#else -#define ROTR32(x,n) ((x >> n) | (x << ((8 * sizeof x) - n))) -#define ROTL32(x,n) ((x << n) | (x >> ((8 * sizeof x) - n))) -#endif - -/* Capitol Sigma and lower case sigma functions */ -#define S0(x) (ROTR32(x, 2) ^ ROTR32(x,13) ^ ROTR32(x,22)) -#define S1(x) (ROTR32(x, 6) ^ ROTR32(x,11) ^ ROTR32(x,25)) -#define s0(x) (t1 = x, ROTR32(t1, 7) ^ ROTR32(t1,18) ^ SHR(t1, 3)) -#define s1(x) (t2 = x, ROTR32(t2,17) ^ ROTR32(t2,19) ^ SHR(t2,10)) - -SHA256Context * -SHA256_NewContext(void) -{ - SHA256Context *ctx = PORT_New(SHA256Context); - return ctx; -} - -void -SHA256_DestroyContext(SHA256Context *ctx, PRBool freeit) -{ - if (freeit) { - PORT_ZFree(ctx, sizeof *ctx); - } -} - -void -SHA256_Begin(SHA256Context *ctx) -{ - memset(ctx, 0, sizeof *ctx); - memcpy(H, H256, sizeof H256); -} - -static void -SHA256_Compress(SHA256Context *ctx) -{ - { - register PRUint32 t1, t2; - -#if defined(IS_LITTLE_ENDIAN) - BYTESWAP4(W[0]); - BYTESWAP4(W[1]); - BYTESWAP4(W[2]); - BYTESWAP4(W[3]); - BYTESWAP4(W[4]); - BYTESWAP4(W[5]); - BYTESWAP4(W[6]); - BYTESWAP4(W[7]); - BYTESWAP4(W[8]); - BYTESWAP4(W[9]); - BYTESWAP4(W[10]); - BYTESWAP4(W[11]); - BYTESWAP4(W[12]); - BYTESWAP4(W[13]); - BYTESWAP4(W[14]); - BYTESWAP4(W[15]); -#endif - -#define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16]) - - /* prepare the "message schedule" */ -#ifdef NOUNROLL256 - { - int t; - for (t = 16; t < 64; ++t) { - INITW(t); - } - } -#else - INITW(16); - INITW(17); - INITW(18); - INITW(19); - - INITW(20); - INITW(21); - INITW(22); - INITW(23); - INITW(24); - INITW(25); - INITW(26); - INITW(27); - INITW(28); - INITW(29); - - INITW(30); - INITW(31); - INITW(32); - INITW(33); - INITW(34); - INITW(35); - INITW(36); - INITW(37); - INITW(38); - INITW(39); - - INITW(40); - INITW(41); - INITW(42); - INITW(43); - INITW(44); - INITW(45); - INITW(46); - INITW(47); - INITW(48); - INITW(49); - - INITW(50); - INITW(51); - INITW(52); - INITW(53); - INITW(54); - INITW(55); - INITW(56); - INITW(57); - INITW(58); - INITW(59); - - INITW(60); - INITW(61); - INITW(62); - INITW(63); - -#endif -#undef INITW - } - { - PRUint32 a, b, c, d, e, f, g, h; - - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; - f = H[5]; - g = H[6]; - h = H[7]; - -#define ROUND(n,a,b,c,d,e,f,g,h) \ - h += S1(e) + Ch(e,f,g) + K256[n] + W[n]; \ - d += h; \ - h += S0(a) + Maj(a,b,c); - -#ifdef NOUNROLL256 - { - int t; - for (t = 0; t < 64; t+= 8) { - ROUND(t+0,a,b,c,d,e,f,g,h) - ROUND(t+1,h,a,b,c,d,e,f,g) - ROUND(t+2,g,h,a,b,c,d,e,f) - ROUND(t+3,f,g,h,a,b,c,d,e) - ROUND(t+4,e,f,g,h,a,b,c,d) - ROUND(t+5,d,e,f,g,h,a,b,c) - ROUND(t+6,c,d,e,f,g,h,a,b) - ROUND(t+7,b,c,d,e,f,g,h,a) - } - } -#else - ROUND( 0,a,b,c,d,e,f,g,h) - ROUND( 1,h,a,b,c,d,e,f,g) - ROUND( 2,g,h,a,b,c,d,e,f) - ROUND( 3,f,g,h,a,b,c,d,e) - ROUND( 4,e,f,g,h,a,b,c,d) - ROUND( 5,d,e,f,g,h,a,b,c) - ROUND( 6,c,d,e,f,g,h,a,b) - ROUND( 7,b,c,d,e,f,g,h,a) - - ROUND( 8,a,b,c,d,e,f,g,h) - ROUND( 9,h,a,b,c,d,e,f,g) - ROUND(10,g,h,a,b,c,d,e,f) - ROUND(11,f,g,h,a,b,c,d,e) - ROUND(12,e,f,g,h,a,b,c,d) - ROUND(13,d,e,f,g,h,a,b,c) - ROUND(14,c,d,e,f,g,h,a,b) - ROUND(15,b,c,d,e,f,g,h,a) - - ROUND(16,a,b,c,d,e,f,g,h) - ROUND(17,h,a,b,c,d,e,f,g) - ROUND(18,g,h,a,b,c,d,e,f) - ROUND(19,f,g,h,a,b,c,d,e) - ROUND(20,e,f,g,h,a,b,c,d) - ROUND(21,d,e,f,g,h,a,b,c) - ROUND(22,c,d,e,f,g,h,a,b) - ROUND(23,b,c,d,e,f,g,h,a) - - ROUND(24,a,b,c,d,e,f,g,h) - ROUND(25,h,a,b,c,d,e,f,g) - ROUND(26,g,h,a,b,c,d,e,f) - ROUND(27,f,g,h,a,b,c,d,e) - ROUND(28,e,f,g,h,a,b,c,d) - ROUND(29,d,e,f,g,h,a,b,c) - ROUND(30,c,d,e,f,g,h,a,b) - ROUND(31,b,c,d,e,f,g,h,a) - - ROUND(32,a,b,c,d,e,f,g,h) - ROUND(33,h,a,b,c,d,e,f,g) - ROUND(34,g,h,a,b,c,d,e,f) - ROUND(35,f,g,h,a,b,c,d,e) - ROUND(36,e,f,g,h,a,b,c,d) - ROUND(37,d,e,f,g,h,a,b,c) - ROUND(38,c,d,e,f,g,h,a,b) - ROUND(39,b,c,d,e,f,g,h,a) - - ROUND(40,a,b,c,d,e,f,g,h) - ROUND(41,h,a,b,c,d,e,f,g) - ROUND(42,g,h,a,b,c,d,e,f) - ROUND(43,f,g,h,a,b,c,d,e) - ROUND(44,e,f,g,h,a,b,c,d) - ROUND(45,d,e,f,g,h,a,b,c) - ROUND(46,c,d,e,f,g,h,a,b) - ROUND(47,b,c,d,e,f,g,h,a) - - ROUND(48,a,b,c,d,e,f,g,h) - ROUND(49,h,a,b,c,d,e,f,g) - ROUND(50,g,h,a,b,c,d,e,f) - ROUND(51,f,g,h,a,b,c,d,e) - ROUND(52,e,f,g,h,a,b,c,d) - ROUND(53,d,e,f,g,h,a,b,c) - ROUND(54,c,d,e,f,g,h,a,b) - ROUND(55,b,c,d,e,f,g,h,a) - - ROUND(56,a,b,c,d,e,f,g,h) - ROUND(57,h,a,b,c,d,e,f,g) - ROUND(58,g,h,a,b,c,d,e,f) - ROUND(59,f,g,h,a,b,c,d,e) - ROUND(60,e,f,g,h,a,b,c,d) - ROUND(61,d,e,f,g,h,a,b,c) - ROUND(62,c,d,e,f,g,h,a,b) - ROUND(63,b,c,d,e,f,g,h,a) -#endif - - H[0] += a; - H[1] += b; - H[2] += c; - H[3] += d; - H[4] += e; - H[5] += f; - H[6] += g; - H[7] += h; - } -#undef ROUND -} - -#undef s0 -#undef s1 -#undef S0 -#undef S1 - -void -SHA256_Update(SHA256Context *ctx, const unsigned char *input, - unsigned int inputLen) -{ - unsigned int inBuf = ctx->sizeLo & 0x3f; - if (!inputLen) - return; - - /* Add inputLen into the count of bytes processed, before processing */ - if ((ctx->sizeLo += inputLen) < inputLen) - ctx->sizeHi++; - - /* if data already in buffer, attemp to fill rest of buffer */ - if (inBuf) { - unsigned int todo = SHA256_BLOCK_LENGTH - inBuf; - if (inputLen < todo) - todo = inputLen; - memcpy(B + inBuf, input, todo); - input += todo; - inputLen -= todo; - if (inBuf + todo == SHA256_BLOCK_LENGTH) - SHA256_Compress(ctx); - } - - /* if enough data to fill one or more whole buffers, process them. */ - while (inputLen >= SHA256_BLOCK_LENGTH) { - memcpy(B, input, SHA256_BLOCK_LENGTH); - input += SHA256_BLOCK_LENGTH; - inputLen -= SHA256_BLOCK_LENGTH; - SHA256_Compress(ctx); - } - /* if data left over, fill it into buffer */ - if (inputLen) - memcpy(B, input, inputLen); -} - -void -SHA256_End(SHA256Context *ctx, unsigned char *digest, - unsigned int *digestLen, unsigned int maxDigestLen) -{ - unsigned int inBuf = ctx->sizeLo & 0x3f; - unsigned int padLen = (inBuf < 56) ? (56 - inBuf) : (56 + 64 - inBuf); - PRUint32 hi, lo; -#ifdef SWAP4MASK - PRUint32 t1; -#endif - - hi = (ctx->sizeHi << 3) | (ctx->sizeLo >> 29); - lo = (ctx->sizeLo << 3); - - SHA256_Update(ctx, pad, padLen); - -#if defined(IS_LITTLE_ENDIAN) - W[14] = SHA_HTONL(hi); - W[15] = SHA_HTONL(lo); -#else - W[14] = hi; - W[15] = lo; -#endif - SHA256_Compress(ctx); - - /* now output the answer */ -#if defined(IS_LITTLE_ENDIAN) - BYTESWAP4(H[0]); - BYTESWAP4(H[1]); - BYTESWAP4(H[2]); - BYTESWAP4(H[3]); - BYTESWAP4(H[4]); - BYTESWAP4(H[5]); - BYTESWAP4(H[6]); - BYTESWAP4(H[7]); -#endif - padLen = PR_MIN(SHA256_LENGTH, maxDigestLen); - memcpy(digest, H, padLen); - if (digestLen) - *digestLen = padLen; -} - -/* Comment out unused code, mostly the SHA384 and SHA512 implementations. */ -#if 0 -SECStatus -SHA256_HashBuf(unsigned char *dest, const unsigned char *src, - unsigned int src_length) -{ - SHA256Context ctx; - unsigned int outLen; - - SHA256_Begin(&ctx); - SHA256_Update(&ctx, src, src_length); - SHA256_End(&ctx, dest, &outLen, SHA256_LENGTH); - - return SECSuccess; -} - - -SECStatus -SHA256_Hash(unsigned char *dest, const char *src) -{ - return SHA256_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); -} - - -void SHA256_TraceState(SHA256Context *ctx) { } - -unsigned int -SHA256_FlattenSize(SHA256Context *ctx) -{ - return sizeof *ctx; -} - -SECStatus -SHA256_Flatten(SHA256Context *ctx,unsigned char *space) -{ - PORT_Memcpy(space, ctx, sizeof *ctx); - return SECSuccess; -} - -SHA256Context * -SHA256_Resurrect(unsigned char *space, void *arg) -{ - SHA256Context *ctx = SHA256_NewContext(); - if (ctx) - PORT_Memcpy(ctx, space, sizeof *ctx); - return ctx; -} - -void SHA256_Clone(SHA256Context *dest, SHA256Context *src) -{ - memcpy(dest, src, sizeof *dest); -} - - -/* ======= SHA512 and SHA384 common constants and defines ================= */ - -/* common #defines for SHA512 and SHA384 */ -#if defined(HAVE_LONG_LONG) -#define ROTR64(x,n) ((x >> n) | (x << (64 - n))) -#define ROTL64(x,n) ((x << n) | (x >> (64 - n))) - -#define S0(x) (ROTR64(x,28) ^ ROTR64(x,34) ^ ROTR64(x,39)) -#define S1(x) (ROTR64(x,14) ^ ROTR64(x,18) ^ ROTR64(x,41)) -#define s0(x) (t1 = x, ROTR64(t1, 1) ^ ROTR64(t1, 8) ^ SHR(t1,7)) -#define s1(x) (t2 = x, ROTR64(t2,19) ^ ROTR64(t2,61) ^ SHR(t2,6)) - -#if PR_BYTES_PER_LONG == 8 -#define ULLC(hi,lo) 0x ## hi ## lo ## UL -#elif defined(_MSC_VER) -#define ULLC(hi,lo) 0x ## hi ## lo ## ui64 -#else -#define ULLC(hi,lo) 0x ## hi ## lo ## ULL -#endif - -#define SHA_MASK16 ULLC(0000FFFF,0000FFFF) -#define SHA_MASK8 ULLC(00FF00FF,00FF00FF) -#define SHA_HTONLL(x) (t1 = x, \ - t1 = ((t1 & SHA_MASK8 ) << 8) | ((t1 >> 8) & SHA_MASK8 ), \ - t1 = ((t1 & SHA_MASK16) << 16) | ((t1 >> 16) & SHA_MASK16), \ - (t1 >> 32) | (t1 << 32)) -#define BYTESWAP8(x) x = SHA_HTONLL(x) - -#else /* no long long */ - -#if defined(IS_LITTLE_ENDIAN) -#define ULLC(hi,lo) { 0x ## lo ## U, 0x ## hi ## U } -#else -#define ULLC(hi,lo) { 0x ## hi ## U, 0x ## lo ## U } -#endif - -#define SHA_HTONLL(x) ( BYTESWAP4(x.lo), BYTESWAP4(x.hi), \ - x.hi ^= x.lo ^= x.hi ^= x.lo, x) -#define BYTESWAP8(x) do { PRUint32 tmp; BYTESWAP4(x.lo); BYTESWAP4(x.hi); \ - tmp = x.lo; x.lo = x.hi; x.hi = tmp; } while (0) -#endif - -/* SHA-384 and SHA-512 constants, K512. */ -static const PRUint64 K512[80] = { -#if PR_BYTES_PER_LONG == 8 - 0x428a2f98d728ae22UL , 0x7137449123ef65cdUL , - 0xb5c0fbcfec4d3b2fUL , 0xe9b5dba58189dbbcUL , - 0x3956c25bf348b538UL , 0x59f111f1b605d019UL , - 0x923f82a4af194f9bUL , 0xab1c5ed5da6d8118UL , - 0xd807aa98a3030242UL , 0x12835b0145706fbeUL , - 0x243185be4ee4b28cUL , 0x550c7dc3d5ffb4e2UL , - 0x72be5d74f27b896fUL , 0x80deb1fe3b1696b1UL , - 0x9bdc06a725c71235UL , 0xc19bf174cf692694UL , - 0xe49b69c19ef14ad2UL , 0xefbe4786384f25e3UL , - 0x0fc19dc68b8cd5b5UL , 0x240ca1cc77ac9c65UL , - 0x2de92c6f592b0275UL , 0x4a7484aa6ea6e483UL , - 0x5cb0a9dcbd41fbd4UL , 0x76f988da831153b5UL , - 0x983e5152ee66dfabUL , 0xa831c66d2db43210UL , - 0xb00327c898fb213fUL , 0xbf597fc7beef0ee4UL , - 0xc6e00bf33da88fc2UL , 0xd5a79147930aa725UL , - 0x06ca6351e003826fUL , 0x142929670a0e6e70UL , - 0x27b70a8546d22ffcUL , 0x2e1b21385c26c926UL , - 0x4d2c6dfc5ac42aedUL , 0x53380d139d95b3dfUL , - 0x650a73548baf63deUL , 0x766a0abb3c77b2a8UL , - 0x81c2c92e47edaee6UL , 0x92722c851482353bUL , - 0xa2bfe8a14cf10364UL , 0xa81a664bbc423001UL , - 0xc24b8b70d0f89791UL , 0xc76c51a30654be30UL , - 0xd192e819d6ef5218UL , 0xd69906245565a910UL , - 0xf40e35855771202aUL , 0x106aa07032bbd1b8UL , - 0x19a4c116b8d2d0c8UL , 0x1e376c085141ab53UL , - 0x2748774cdf8eeb99UL , 0x34b0bcb5e19b48a8UL , - 0x391c0cb3c5c95a63UL , 0x4ed8aa4ae3418acbUL , - 0x5b9cca4f7763e373UL , 0x682e6ff3d6b2b8a3UL , - 0x748f82ee5defb2fcUL , 0x78a5636f43172f60UL , - 0x84c87814a1f0ab72UL , 0x8cc702081a6439ecUL , - 0x90befffa23631e28UL , 0xa4506cebde82bde9UL , - 0xbef9a3f7b2c67915UL , 0xc67178f2e372532bUL , - 0xca273eceea26619cUL , 0xd186b8c721c0c207UL , - 0xeada7dd6cde0eb1eUL , 0xf57d4f7fee6ed178UL , - 0x06f067aa72176fbaUL , 0x0a637dc5a2c898a6UL , - 0x113f9804bef90daeUL , 0x1b710b35131c471bUL , - 0x28db77f523047d84UL , 0x32caab7b40c72493UL , - 0x3c9ebe0a15c9bebcUL , 0x431d67c49c100d4cUL , - 0x4cc5d4becb3e42b6UL , 0x597f299cfc657e2aUL , - 0x5fcb6fab3ad6faecUL , 0x6c44198c4a475817UL -#else - ULLC(428a2f98,d728ae22), ULLC(71374491,23ef65cd), - ULLC(b5c0fbcf,ec4d3b2f), ULLC(e9b5dba5,8189dbbc), - ULLC(3956c25b,f348b538), ULLC(59f111f1,b605d019), - ULLC(923f82a4,af194f9b), ULLC(ab1c5ed5,da6d8118), - ULLC(d807aa98,a3030242), ULLC(12835b01,45706fbe), - ULLC(243185be,4ee4b28c), ULLC(550c7dc3,d5ffb4e2), - ULLC(72be5d74,f27b896f), ULLC(80deb1fe,3b1696b1), - ULLC(9bdc06a7,25c71235), ULLC(c19bf174,cf692694), - ULLC(e49b69c1,9ef14ad2), ULLC(efbe4786,384f25e3), - ULLC(0fc19dc6,8b8cd5b5), ULLC(240ca1cc,77ac9c65), - ULLC(2de92c6f,592b0275), ULLC(4a7484aa,6ea6e483), - ULLC(5cb0a9dc,bd41fbd4), ULLC(76f988da,831153b5), - ULLC(983e5152,ee66dfab), ULLC(a831c66d,2db43210), - ULLC(b00327c8,98fb213f), ULLC(bf597fc7,beef0ee4), - ULLC(c6e00bf3,3da88fc2), ULLC(d5a79147,930aa725), - ULLC(06ca6351,e003826f), ULLC(14292967,0a0e6e70), - ULLC(27b70a85,46d22ffc), ULLC(2e1b2138,5c26c926), - ULLC(4d2c6dfc,5ac42aed), ULLC(53380d13,9d95b3df), - ULLC(650a7354,8baf63de), ULLC(766a0abb,3c77b2a8), - ULLC(81c2c92e,47edaee6), ULLC(92722c85,1482353b), - ULLC(a2bfe8a1,4cf10364), ULLC(a81a664b,bc423001), - ULLC(c24b8b70,d0f89791), ULLC(c76c51a3,0654be30), - ULLC(d192e819,d6ef5218), ULLC(d6990624,5565a910), - ULLC(f40e3585,5771202a), ULLC(106aa070,32bbd1b8), - ULLC(19a4c116,b8d2d0c8), ULLC(1e376c08,5141ab53), - ULLC(2748774c,df8eeb99), ULLC(34b0bcb5,e19b48a8), - ULLC(391c0cb3,c5c95a63), ULLC(4ed8aa4a,e3418acb), - ULLC(5b9cca4f,7763e373), ULLC(682e6ff3,d6b2b8a3), - ULLC(748f82ee,5defb2fc), ULLC(78a5636f,43172f60), - ULLC(84c87814,a1f0ab72), ULLC(8cc70208,1a6439ec), - ULLC(90befffa,23631e28), ULLC(a4506ceb,de82bde9), - ULLC(bef9a3f7,b2c67915), ULLC(c67178f2,e372532b), - ULLC(ca273ece,ea26619c), ULLC(d186b8c7,21c0c207), - ULLC(eada7dd6,cde0eb1e), ULLC(f57d4f7f,ee6ed178), - ULLC(06f067aa,72176fba), ULLC(0a637dc5,a2c898a6), - ULLC(113f9804,bef90dae), ULLC(1b710b35,131c471b), - ULLC(28db77f5,23047d84), ULLC(32caab7b,40c72493), - ULLC(3c9ebe0a,15c9bebc), ULLC(431d67c4,9c100d4c), - ULLC(4cc5d4be,cb3e42b6), ULLC(597f299c,fc657e2a), - ULLC(5fcb6fab,3ad6faec), ULLC(6c44198c,4a475817) -#endif -}; - -struct SHA512ContextStr { - union { - PRUint64 w[80]; /* message schedule, input buffer, plus 64 words */ - PRUint32 l[160]; - PRUint8 b[640]; - } u; - PRUint64 h[8]; /* 8 state variables */ - PRUint64 sizeLo; /* 64-bit count of hashed bytes. */ -}; - -/* =========== SHA512 implementation ===================================== */ - -/* SHA-512 initial hash values */ -static const PRUint64 H512[8] = { -#if PR_BYTES_PER_LONG == 8 - 0x6a09e667f3bcc908UL , 0xbb67ae8584caa73bUL , - 0x3c6ef372fe94f82bUL , 0xa54ff53a5f1d36f1UL , - 0x510e527fade682d1UL , 0x9b05688c2b3e6c1fUL , - 0x1f83d9abfb41bd6bUL , 0x5be0cd19137e2179UL -#else - ULLC(6a09e667,f3bcc908), ULLC(bb67ae85,84caa73b), - ULLC(3c6ef372,fe94f82b), ULLC(a54ff53a,5f1d36f1), - ULLC(510e527f,ade682d1), ULLC(9b05688c,2b3e6c1f), - ULLC(1f83d9ab,fb41bd6b), ULLC(5be0cd19,137e2179) -#endif -}; - - -SHA512Context * -SHA512_NewContext(void) -{ - SHA512Context *ctx = PORT_New(SHA512Context); - return ctx; -} - -void -SHA512_DestroyContext(SHA512Context *ctx, PRBool freeit) -{ - if (freeit) { - PORT_ZFree(ctx, sizeof *ctx); - } -} - -void -SHA512_Begin(SHA512Context *ctx) -{ - memset(ctx, 0, sizeof *ctx); - memcpy(H, H512, sizeof H512); -} - -#if defined(SHA512_TRACE) -#if defined(HAVE_LONG_LONG) -#define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %016lx, %s = %016lx\n", \ - n, #e, d, #a, h); -#else -#define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %08x%08x, %s = %08x%08x\n", \ - n, #e, d.hi, d.lo, #a, h.hi, h.lo); -#endif -#else -#define DUMP(n,a,d,e,h) -#endif - -#if defined(HAVE_LONG_LONG) - -#define ADDTO(x,y) y += x - -#define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16]) - -#define ROUND(n,a,b,c,d,e,f,g,h) \ - h += S1(e) + Ch(e,f,g) + K512[n] + W[n]; \ - d += h; \ - h += S0(a) + Maj(a,b,c); \ - DUMP(n,a,d,e,h) - -#else /* use only 32-bit variables, and don't unroll loops */ - -#undef NOUNROLL512 -#define NOUNROLL512 1 - -#define ADDTO(x,y) y.lo += x.lo; y.hi += x.hi + (x.lo > y.lo) - -#define ROTR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n)) -#define ROTR64A(x,n,lo,hi) (x.lo << (64-n) | x.hi >> (n-32)) -#define SHR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n)) - -/* Capitol Sigma and lower case sigma functions */ -#define s0lo(x) (ROTR64a(x,1,lo,hi) ^ ROTR64a(x,8,lo,hi) ^ SHR64a(x,7,lo,hi)) -#define s0hi(x) (ROTR64a(x,1,hi,lo) ^ ROTR64a(x,8,hi,lo) ^ (x.hi >> 7)) - -#define s1lo(x) (ROTR64a(x,19,lo,hi) ^ ROTR64A(x,61,lo,hi) ^ SHR64a(x,6,lo,hi)) -#define s1hi(x) (ROTR64a(x,19,hi,lo) ^ ROTR64A(x,61,hi,lo) ^ (x.hi >> 6)) - -#define S0lo(x)(ROTR64a(x,28,lo,hi) ^ ROTR64A(x,34,lo,hi) ^ ROTR64A(x,39,lo,hi)) -#define S0hi(x)(ROTR64a(x,28,hi,lo) ^ ROTR64A(x,34,hi,lo) ^ ROTR64A(x,39,hi,lo)) - -#define S1lo(x)(ROTR64a(x,14,lo,hi) ^ ROTR64a(x,18,lo,hi) ^ ROTR64A(x,41,lo,hi)) -#define S1hi(x)(ROTR64a(x,14,hi,lo) ^ ROTR64a(x,18,hi,lo) ^ ROTR64A(x,41,hi,lo)) - -/* 32-bit versions of Ch and Maj */ -#define Chxx(x,y,z,lo) ((x.lo & y.lo) ^ (~x.lo & z.lo)) -#define Majx(x,y,z,lo) ((x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo)) - -#define INITW(t) \ - do { \ - PRUint32 lo, tm; \ - PRUint32 cy = 0; \ - lo = s1lo(W[t-2]); \ - lo += (tm = W[t-7].lo); if (lo < tm) cy++; \ - lo += (tm = s0lo(W[t-15])); if (lo < tm) cy++; \ - lo += (tm = W[t-16].lo); if (lo < tm) cy++; \ - W[t].lo = lo; \ - W[t].hi = cy + s1hi(W[t-2]) + W[t-7].hi + s0hi(W[t-15]) + W[t-16].hi; \ - } while (0) - -#define ROUND(n,a,b,c,d,e,f,g,h) \ - { \ - PRUint32 lo, tm, cy; \ - lo = S1lo(e); \ - lo += (tm = Chxx(e,f,g,lo)); cy = (lo < tm); \ - lo += (tm = K512[n].lo); if (lo < tm) cy++; \ - lo += (tm = W[n].lo); if (lo < tm) cy++; \ - h.lo += lo; if (h.lo < lo) cy++; \ - h.hi += cy + S1hi(e) + Chxx(e,f,g,hi) + K512[n].hi + W[n].hi; \ - d.lo += h.lo; \ - d.hi += h.hi + (d.lo < h.lo); \ - lo = S0lo(a); \ - lo += (tm = Majx(a,b,c,lo)); cy = (lo < tm); \ - h.lo += lo; if (h.lo < lo) cy++; \ - h.hi += cy + S0hi(a) + Majx(a,b,c,hi); \ - DUMP(n,a,d,e,h) \ - } -#endif - -static void -SHA512_Compress(SHA512Context *ctx) -{ -#if defined(IS_LITTLE_ENDIAN) - { -#if defined(HAVE_LONG_LONG) - PRUint64 t1; -#else - PRUint32 t1; -#endif - BYTESWAP8(W[0]); - BYTESWAP8(W[1]); - BYTESWAP8(W[2]); - BYTESWAP8(W[3]); - BYTESWAP8(W[4]); - BYTESWAP8(W[5]); - BYTESWAP8(W[6]); - BYTESWAP8(W[7]); - BYTESWAP8(W[8]); - BYTESWAP8(W[9]); - BYTESWAP8(W[10]); - BYTESWAP8(W[11]); - BYTESWAP8(W[12]); - BYTESWAP8(W[13]); - BYTESWAP8(W[14]); - BYTESWAP8(W[15]); - } -#endif - - { - PRUint64 t1, t2; -#ifdef NOUNROLL512 - { - /* prepare the "message schedule" */ - int t; - for (t = 16; t < 80; ++t) { - INITW(t); - } - } -#else - INITW(16); - INITW(17); - INITW(18); - INITW(19); - - INITW(20); - INITW(21); - INITW(22); - INITW(23); - INITW(24); - INITW(25); - INITW(26); - INITW(27); - INITW(28); - INITW(29); - - INITW(30); - INITW(31); - INITW(32); - INITW(33); - INITW(34); - INITW(35); - INITW(36); - INITW(37); - INITW(38); - INITW(39); - - INITW(40); - INITW(41); - INITW(42); - INITW(43); - INITW(44); - INITW(45); - INITW(46); - INITW(47); - INITW(48); - INITW(49); - - INITW(50); - INITW(51); - INITW(52); - INITW(53); - INITW(54); - INITW(55); - INITW(56); - INITW(57); - INITW(58); - INITW(59); - - INITW(60); - INITW(61); - INITW(62); - INITW(63); - INITW(64); - INITW(65); - INITW(66); - INITW(67); - INITW(68); - INITW(69); - - INITW(70); - INITW(71); - INITW(72); - INITW(73); - INITW(74); - INITW(75); - INITW(76); - INITW(77); - INITW(78); - INITW(79); -#endif - } -#ifdef SHA512_TRACE - { - int i; - for (i = 0; i < 80; ++i) { -#ifdef HAVE_LONG_LONG - printf("W[%2d] = %016lx\n", i, W[i]); -#else - printf("W[%2d] = %08x%08x\n", i, W[i].hi, W[i].lo); -#endif - } - } -#endif - { - PRUint64 a, b, c, d, e, f, g, h; - - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; - f = H[5]; - g = H[6]; - h = H[7]; - -#ifdef NOUNROLL512 - { - int t; - for (t = 0; t < 80; t+= 8) { - ROUND(t+0,a,b,c,d,e,f,g,h) - ROUND(t+1,h,a,b,c,d,e,f,g) - ROUND(t+2,g,h,a,b,c,d,e,f) - ROUND(t+3,f,g,h,a,b,c,d,e) - ROUND(t+4,e,f,g,h,a,b,c,d) - ROUND(t+5,d,e,f,g,h,a,b,c) - ROUND(t+6,c,d,e,f,g,h,a,b) - ROUND(t+7,b,c,d,e,f,g,h,a) - } - } -#else - ROUND( 0,a,b,c,d,e,f,g,h) - ROUND( 1,h,a,b,c,d,e,f,g) - ROUND( 2,g,h,a,b,c,d,e,f) - ROUND( 3,f,g,h,a,b,c,d,e) - ROUND( 4,e,f,g,h,a,b,c,d) - ROUND( 5,d,e,f,g,h,a,b,c) - ROUND( 6,c,d,e,f,g,h,a,b) - ROUND( 7,b,c,d,e,f,g,h,a) - - ROUND( 8,a,b,c,d,e,f,g,h) - ROUND( 9,h,a,b,c,d,e,f,g) - ROUND(10,g,h,a,b,c,d,e,f) - ROUND(11,f,g,h,a,b,c,d,e) - ROUND(12,e,f,g,h,a,b,c,d) - ROUND(13,d,e,f,g,h,a,b,c) - ROUND(14,c,d,e,f,g,h,a,b) - ROUND(15,b,c,d,e,f,g,h,a) - - ROUND(16,a,b,c,d,e,f,g,h) - ROUND(17,h,a,b,c,d,e,f,g) - ROUND(18,g,h,a,b,c,d,e,f) - ROUND(19,f,g,h,a,b,c,d,e) - ROUND(20,e,f,g,h,a,b,c,d) - ROUND(21,d,e,f,g,h,a,b,c) - ROUND(22,c,d,e,f,g,h,a,b) - ROUND(23,b,c,d,e,f,g,h,a) - - ROUND(24,a,b,c,d,e,f,g,h) - ROUND(25,h,a,b,c,d,e,f,g) - ROUND(26,g,h,a,b,c,d,e,f) - ROUND(27,f,g,h,a,b,c,d,e) - ROUND(28,e,f,g,h,a,b,c,d) - ROUND(29,d,e,f,g,h,a,b,c) - ROUND(30,c,d,e,f,g,h,a,b) - ROUND(31,b,c,d,e,f,g,h,a) - - ROUND(32,a,b,c,d,e,f,g,h) - ROUND(33,h,a,b,c,d,e,f,g) - ROUND(34,g,h,a,b,c,d,e,f) - ROUND(35,f,g,h,a,b,c,d,e) - ROUND(36,e,f,g,h,a,b,c,d) - ROUND(37,d,e,f,g,h,a,b,c) - ROUND(38,c,d,e,f,g,h,a,b) - ROUND(39,b,c,d,e,f,g,h,a) - - ROUND(40,a,b,c,d,e,f,g,h) - ROUND(41,h,a,b,c,d,e,f,g) - ROUND(42,g,h,a,b,c,d,e,f) - ROUND(43,f,g,h,a,b,c,d,e) - ROUND(44,e,f,g,h,a,b,c,d) - ROUND(45,d,e,f,g,h,a,b,c) - ROUND(46,c,d,e,f,g,h,a,b) - ROUND(47,b,c,d,e,f,g,h,a) - - ROUND(48,a,b,c,d,e,f,g,h) - ROUND(49,h,a,b,c,d,e,f,g) - ROUND(50,g,h,a,b,c,d,e,f) - ROUND(51,f,g,h,a,b,c,d,e) - ROUND(52,e,f,g,h,a,b,c,d) - ROUND(53,d,e,f,g,h,a,b,c) - ROUND(54,c,d,e,f,g,h,a,b) - ROUND(55,b,c,d,e,f,g,h,a) - - ROUND(56,a,b,c,d,e,f,g,h) - ROUND(57,h,a,b,c,d,e,f,g) - ROUND(58,g,h,a,b,c,d,e,f) - ROUND(59,f,g,h,a,b,c,d,e) - ROUND(60,e,f,g,h,a,b,c,d) - ROUND(61,d,e,f,g,h,a,b,c) - ROUND(62,c,d,e,f,g,h,a,b) - ROUND(63,b,c,d,e,f,g,h,a) - - ROUND(64,a,b,c,d,e,f,g,h) - ROUND(65,h,a,b,c,d,e,f,g) - ROUND(66,g,h,a,b,c,d,e,f) - ROUND(67,f,g,h,a,b,c,d,e) - ROUND(68,e,f,g,h,a,b,c,d) - ROUND(69,d,e,f,g,h,a,b,c) - ROUND(70,c,d,e,f,g,h,a,b) - ROUND(71,b,c,d,e,f,g,h,a) - - ROUND(72,a,b,c,d,e,f,g,h) - ROUND(73,h,a,b,c,d,e,f,g) - ROUND(74,g,h,a,b,c,d,e,f) - ROUND(75,f,g,h,a,b,c,d,e) - ROUND(76,e,f,g,h,a,b,c,d) - ROUND(77,d,e,f,g,h,a,b,c) - ROUND(78,c,d,e,f,g,h,a,b) - ROUND(79,b,c,d,e,f,g,h,a) -#endif - - ADDTO(a,H[0]); - ADDTO(b,H[1]); - ADDTO(c,H[2]); - ADDTO(d,H[3]); - ADDTO(e,H[4]); - ADDTO(f,H[5]); - ADDTO(g,H[6]); - ADDTO(h,H[7]); - } -} - -void -SHA512_Update(SHA512Context *ctx, const unsigned char *input, - unsigned int inputLen) -{ - unsigned int inBuf; - if (!inputLen) - return; - -#if defined(HAVE_LONG_LONG) - inBuf = (unsigned int)ctx->sizeLo & 0x7f; - /* Add inputLen into the count of bytes processed, before processing */ - ctx->sizeLo += inputLen; -#else - inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f; - ctx->sizeLo.lo += inputLen; - if (ctx->sizeLo.lo < inputLen) ctx->sizeLo.hi++; -#endif - - /* if data already in buffer, attemp to fill rest of buffer */ - if (inBuf) { - unsigned int todo = SHA512_BLOCK_LENGTH - inBuf; - if (inputLen < todo) - todo = inputLen; - memcpy(B + inBuf, input, todo); - input += todo; - inputLen -= todo; - if (inBuf + todo == SHA512_BLOCK_LENGTH) - SHA512_Compress(ctx); - } - - /* if enough data to fill one or more whole buffers, process them. */ - while (inputLen >= SHA512_BLOCK_LENGTH) { - memcpy(B, input, SHA512_BLOCK_LENGTH); - input += SHA512_BLOCK_LENGTH; - inputLen -= SHA512_BLOCK_LENGTH; - SHA512_Compress(ctx); - } - /* if data left over, fill it into buffer */ - if (inputLen) - memcpy(B, input, inputLen); -} - -void -SHA512_End(SHA512Context *ctx, unsigned char *digest, - unsigned int *digestLen, unsigned int maxDigestLen) -{ -#if defined(HAVE_LONG_LONG) - unsigned int inBuf = (unsigned int)ctx->sizeLo & 0x7f; - unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf); - PRUint64 lo, t1; - lo = (ctx->sizeLo << 3); -#else - unsigned int inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f; - unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf); - PRUint64 lo = ctx->sizeLo; - PRUint32 t1; - lo.lo <<= 3; -#endif - - SHA512_Update(ctx, pad, padLen); - -#if defined(HAVE_LONG_LONG) - W[14] = 0; -#else - W[14].lo = 0; - W[14].hi = 0; -#endif - - W[15] = lo; -#if defined(IS_LITTLE_ENDIAN) - BYTESWAP8(W[15]); -#endif - SHA512_Compress(ctx); - - /* now output the answer */ -#if defined(IS_LITTLE_ENDIAN) - BYTESWAP8(H[0]); - BYTESWAP8(H[1]); - BYTESWAP8(H[2]); - BYTESWAP8(H[3]); - BYTESWAP8(H[4]); - BYTESWAP8(H[5]); - BYTESWAP8(H[6]); - BYTESWAP8(H[7]); -#endif - padLen = PR_MIN(SHA512_LENGTH, maxDigestLen); - memcpy(digest, H, padLen); - if (digestLen) - *digestLen = padLen; -} - -SECStatus -SHA512_HashBuf(unsigned char *dest, const unsigned char *src, - unsigned int src_length) -{ - SHA512Context ctx; - unsigned int outLen; - - SHA512_Begin(&ctx); - SHA512_Update(&ctx, src, src_length); - SHA512_End(&ctx, dest, &outLen, SHA512_LENGTH); - - return SECSuccess; -} - - -SECStatus -SHA512_Hash(unsigned char *dest, const char *src) -{ - return SHA512_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); -} - - -void SHA512_TraceState(SHA512Context *ctx) { } - -unsigned int -SHA512_FlattenSize(SHA512Context *ctx) -{ - return sizeof *ctx; -} - -SECStatus -SHA512_Flatten(SHA512Context *ctx,unsigned char *space) -{ - PORT_Memcpy(space, ctx, sizeof *ctx); - return SECSuccess; -} - -SHA512Context * -SHA512_Resurrect(unsigned char *space, void *arg) -{ - SHA512Context *ctx = SHA512_NewContext(); - if (ctx) - PORT_Memcpy(ctx, space, sizeof *ctx); - return ctx; -} - -void SHA512_Clone(SHA512Context *dest, SHA512Context *src) -{ - memcpy(dest, src, sizeof *dest); -} - -/* ======================================================================= */ -/* SHA384 uses a SHA512Context as the real context. -** The only differences between SHA384 an SHA512 are: -** a) the intialization values for the context, and -** b) the number of bytes of data produced as output. -*/ - -/* SHA-384 initial hash values */ -static const PRUint64 H384[8] = { -#if PR_BYTES_PER_LONG == 8 - 0xcbbb9d5dc1059ed8UL , 0x629a292a367cd507UL , - 0x9159015a3070dd17UL , 0x152fecd8f70e5939UL , - 0x67332667ffc00b31UL , 0x8eb44a8768581511UL , - 0xdb0c2e0d64f98fa7UL , 0x47b5481dbefa4fa4UL -#else - ULLC(cbbb9d5d,c1059ed8), ULLC(629a292a,367cd507), - ULLC(9159015a,3070dd17), ULLC(152fecd8,f70e5939), - ULLC(67332667,ffc00b31), ULLC(8eb44a87,68581511), - ULLC(db0c2e0d,64f98fa7), ULLC(47b5481d,befa4fa4) -#endif -}; - -SHA384Context * -SHA384_NewContext(void) -{ - return SHA512_NewContext(); -} - -void -SHA384_DestroyContext(SHA384Context *ctx, PRBool freeit) -{ - SHA512_DestroyContext(ctx, freeit); -} - -void -SHA384_Begin(SHA384Context *ctx) -{ - memset(ctx, 0, sizeof *ctx); - memcpy(H, H384, sizeof H384); -} - -void -SHA384_Update(SHA384Context *ctx, const unsigned char *input, - unsigned int inputLen) -{ - SHA512_Update(ctx, input, inputLen); -} - -void -SHA384_End(SHA384Context *ctx, unsigned char *digest, - unsigned int *digestLen, unsigned int maxDigestLen) -{ -#define SHA_MIN(a,b) (a < b ? a : b) - unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH); - SHA512_End(ctx, digest, digestLen, maxLen); -} - -SECStatus -SHA384_HashBuf(unsigned char *dest, const unsigned char *src, - unsigned int src_length) -{ - SHA512Context ctx; - unsigned int outLen; - - SHA384_Begin(&ctx); - SHA512_Update(&ctx, src, src_length); - SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH); - - return SECSuccess; -} - -SECStatus -SHA384_Hash(unsigned char *dest, const char *src) -{ - return SHA384_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); -} - -void SHA384_TraceState(SHA384Context *ctx) { } - -unsigned int -SHA384_FlattenSize(SHA384Context *ctx) -{ - return sizeof(SHA384Context); -} - -SECStatus -SHA384_Flatten(SHA384Context *ctx,unsigned char *space) -{ - return SHA512_Flatten(ctx, space); -} - -SHA384Context * -SHA384_Resurrect(unsigned char *space, void *arg) -{ - return SHA512_Resurrect(space, arg); -} - -void SHA384_Clone(SHA384Context *dest, SHA384Context *src) -{ - memcpy(dest, src, sizeof *dest); -} -#endif /* Comment out unused code. */ - -/* ======================================================================= */ -#ifdef SELFTEST -#include <stdio.h> - -static const char abc[] = { "abc" }; -static const char abcdbc[] = { - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" -}; -static const char abcdef[] = { - "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" - "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" -}; - -void -dumpHash32(const unsigned char *buf, unsigned int bufLen) -{ - unsigned int i; - for (i = 0; i < bufLen; i += 4) { - printf(" %02x%02x%02x%02x", buf[i], buf[i+1], buf[i+2], buf[i+3]); - } - printf("\n"); -} - -void test256(void) -{ - unsigned char outBuf[SHA256_LENGTH]; - - printf("SHA256, input = %s\n", abc); - SHA256_Hash(outBuf, abc); - dumpHash32(outBuf, sizeof outBuf); - - printf("SHA256, input = %s\n", abcdbc); - SHA256_Hash(outBuf, abcdbc); - dumpHash32(outBuf, sizeof outBuf); -} - -void -dumpHash64(const unsigned char *buf, unsigned int bufLen) -{ - unsigned int i; - for (i = 0; i < bufLen; i += 8) { - if (i % 32 == 0) - printf("\n"); - printf(" %02x%02x%02x%02x%02x%02x%02x%02x", - buf[i ], buf[i+1], buf[i+2], buf[i+3], - buf[i+4], buf[i+5], buf[i+6], buf[i+7]); - } - printf("\n"); -} - -void test512(void) -{ - unsigned char outBuf[SHA512_LENGTH]; - - printf("SHA512, input = %s\n", abc); - SHA512_Hash(outBuf, abc); - dumpHash64(outBuf, sizeof outBuf); - - printf("SHA512, input = %s\n", abcdef); - SHA512_Hash(outBuf, abcdef); - dumpHash64(outBuf, sizeof outBuf); -} - -void time512(void) -{ - unsigned char outBuf[SHA512_LENGTH]; - - SHA512_Hash(outBuf, abc); - SHA512_Hash(outBuf, abcdef); -} - -void test384(void) -{ - unsigned char outBuf[SHA384_LENGTH]; - - printf("SHA384, input = %s\n", abc); - SHA384_Hash(outBuf, abc); - dumpHash64(outBuf, sizeof outBuf); - - printf("SHA384, input = %s\n", abcdef); - SHA384_Hash(outBuf, abcdef); - dumpHash64(outBuf, sizeof outBuf); -} - -int main (int argc, char *argv[], char *envp[]) -{ - int i = 1; - if (argc > 1) { - i = atoi(argv[1]); - } - if (i < 2) { - test256(); - test512(); - test384(); - } else { - while (i-- > 0) { - time512(); - } - printf("done\n"); - } - return 0; -} - -#endif |