diff --git a/doc/ClientLog.md b/doc/ClientLog.md
index dee260cec..3389631bb 100644
--- a/doc/ClientLog.md
+++ b/doc/ClientLog.md
@@ -27,7 +27,6 @@ Non-opt builds (dbg-win and coverage-win) allow provide much more logging and ha
[LoggingLevel]
LC_CORE=5
LC_NET=4
-LC_PLUGIN=3
LC_SERVICE=3
LC_SETUP=3
LC_SHELL=3
diff --git a/doc/CustomizingOmaha.md b/doc/CustomizingOmaha.md
index 82dd951f9..aa77bd2b2 100644
--- a/doc/CustomizingOmaha.md
+++ b/doc/CustomizingOmaha.md
@@ -32,7 +32,6 @@ The following items **MUST** be changed before releasing a fork of Omaha. Prefe
> Generate new GUIDs for every interface and coclass. Changing the descriptive names for them isn't a bad idea either. (Do not, however, change code-level names such as `IAppBundle` or `GoogleUpdate3UserClass`.)
- * **`omaha\plugins\update\activex\update_control_idl.idl`**
> Generate new GUIDs for every interface and coclass.
diff --git a/doc/DeveloperSetupGuide.md b/doc/DeveloperSetupGuide.md
index 2a4f69d77..7fe8bd54f 100644
--- a/doc/DeveloperSetupGuide.md
+++ b/doc/DeveloperSetupGuide.md
@@ -4,7 +4,7 @@ These instructions are intended to assist the would-be Omaha developer with sett
We are striving to make the code build with the latest Windows toolchain from Microsoft. Since there is no continuous integration for this project, the code may not build using previous versions of the toolchain.
-#### Currently, the supported toolchain is Visual Studio 2019 Update 16.3.6 and Windows SDK 10.0.18362.0. ####
+#### Currently, the supported toolchain is Visual Studio 2019 Update 16.4.3 and Windows SDK 10.0.18362.0. ####
Visual Studio 2017 Update 15.9.16 should work too.
@@ -16,8 +16,6 @@ The following packages are required to build Omaha:
* A copy of the Omaha source code. This can be done by cloning this repository.
* Microsoft Visual Studio 2017 or 2019. The free Visual Studio Community edition is sufficient to build.
* Download [here](https://visualstudio.microsoft.com/downloads)
- * ATL Server headers
- * Download [here](http://atlserver.codeplex.com). Omaha needs this library for regular expression support.
* Windows 10 SDK.
* Download Windows 10 SDK [here](https://dev.windows.com/en-us/downloads/windows-10-sdk).
* Microsoft .NET Framework 2.0
diff --git a/doc/Omaha3SourceOrganization.md b/doc/Omaha3SourceOrganization.md
index 8e9004e9b..d18e6d4fd 100644
--- a/doc/Omaha3SourceOrganization.md
+++ b/doc/Omaha3SourceOrganization.md
@@ -31,7 +31,6 @@ omaha\
mi_exe_stub\ Produces a stub EXE, mi_exe_stub.exe, that will be combined
with a TAR to produce the untagged meta-installer. (The script to
actually do the merge lives in installers\, mentioned below.)
-plugins\ Produces the browser plugin, npGoogleUpdate3.dll.
recovery\ Produces tools for “Code Red” - a mechanism that the apps being
managed by Omaha can use to check Omaha’s integrity, and
restore it if it appears broken.
diff --git a/doc/Omaha3Walkthrough.md b/doc/Omaha3Walkthrough.md
index 484ab5894..a3ecb0604 100644
--- a/doc/Omaha3Walkthrough.md
+++ b/doc/Omaha3Walkthrough.md
@@ -35,7 +35,7 @@ The Omaha Client always operates at user privilege levels and owns the UI of Oma
* Setup - Create or update a permanent Omaha install, of either user or machine variety.
* Install - Invoke the COM server to create a state machine object, fill it out with apps to be managed, and call a suitable function on it such as `checkForUpdate()`, `download()`, or `install()`. From that point onwards, poll the state object as the COM server does the work for you, and update the UI as the states advance.
-In general, when referring to “the client”, we’re referring to the official Google Update client, which happens to live in the same executable as the COM Server; the role that the executable plays is decided simply by which command line is passed to it. However, there are other clients that may access the COM server; some of them we own (the web browser plugins), and some we do not own (partner applications which access our COM APIs directly). The server must stay as secure as possible, and sanitize all input.
+In general, when referring to “the client”, we’re referring to the official Google Update client, which happens to live in the same executable as the COM Server; the role that the executable plays is decided simply by which command line is passed to it. However, there are other clients that may access the COM server; The server must stay as secure as possible, and sanitize all input.
## Example Code Flow ##
@@ -50,7 +50,6 @@ appname=Google%20Chrome&needsadmin=False&lang=en"
* We check the machine to see if there’s already a user Omaha installed with a version newer than or equal to ours. (If it’s equal to ours, we will do some supplementary checking to make sure that the installed copy is sane and working properly, and if not, we over-install.) Let’s assume that there is no user Omaha installed. We will create the direct directory in `AppData`, copy over the files, and then make entries in the Registry to do the following:
* Register our COM servers
* Create scheduled tasks to check for an update every five hours
- * Expose our web browser plugins to IE/Firefox/Chrome/Safari/Opera
* Store initial configuration/state for Omaha itself in the Registry
* Register Omaha itself as an Omaha-managed application, so it can check for updates for itself
* The client then starts a new copy of itself in its permanent installed location, modifying the command line from `/install` to `/handoff`. Once again, the constant shell loads Goopdate and passes the command line along - this time, however, we’re using the constant shell in the newly-created permanent install of Omaha, rather than the one in the temp directory.
@@ -74,7 +73,6 @@ So, what files are actually in a permanent install of Omaha once it’s complete
| `GoogleUpdateBroker.exe`
GoogleUpdateOnDemand.exe
COM Forwarders. Both of these are small EXEs whose sole purpose is to take their own command line, append a command line switch to the end, and pass it to the Constant Shell. |
goopdate.dll | The central Omaha3 binary. |
goopdateres_*.dll | Resource-only DLLs, one per language, containing localized strings. As part of its startup, Goopdate will read the “lang” extra-args parameter if one exists (or the Registry) and select a language to load. |
- npGoogleUpdate3.dll | Our web browser plugin. (It actually contains two plugins: ActiveX plugins for IE, and an NPAPI plugin for Firefox, Chrome, and other browsers that use that.) Allows Javascript on selected subdomains of google.com to access and use the COM Server. |
psmachine.dll
psuser.dll | Custom marshaling stubs used by the COM Server. Used in order to work around some Windows bugs that are triggered by having both Machine and User Omaha installed simultaneously. |
The directory tree typically looks like this:
diff --git a/doc/ServerProtocolV2.md b/doc/ServerProtocolV2.md
index 09db2b743..ddc594070 100644
--- a/doc/ServerProtocolV2.md
+++ b/doc/ServerProtocolV2.md
@@ -180,7 +180,7 @@ _Request Attributes_
* client (optional): Similar to brand code.
* iid (optional): A random GUID used to uniquely count install attempts. For example, if a user fails to install then re-runs the installer and succeeds, we might want to count that as one "attempt".
* installage (optional): The number of days since the app was first installed.
- * installsource (optional): Specifies the source of the request. Examples include "oneclick", "clickonce", "ondemandupdate", "ondemandcheckforupdate", "offline", "scheduler", "core". This value is specified to the Omaha client on the command line.
+ * installsource (optional): Specifies the source of the request. Examples include "clickonce", "ondemandupdate", "ondemandcheckforupdate", "offline", "scheduler", "core". This value is specified to the Omaha client on the command line.
* fp (optional): Specifies a version-agnostic identifier for the last downloaded binary for this app. Usually "1.X" where X is the sha-256 hash of the downloaded binary.
_Response Attributes_
diff --git a/omaha/VERSION b/omaha/VERSION
index 19177a13a..a38f45a37 100644
--- a/omaha/VERSION
+++ b/omaha/VERSION
@@ -5,7 +5,4 @@
version_major = 1 # 1-65535
version_minor = 3 # 0-65535
version_build = 35 # 1-65535
-version_patch = 421 # 0-65535
-
-oneclick_plugin_version = 9
-update_plugin_version = 3
+version_patch = 441 # 0-65535
diff --git a/omaha/base/apply_tag.cc b/omaha/base/apply_tag.cc
index cc50e3ae0..c8809103d 100644
--- a/omaha/base/apply_tag.cc
+++ b/omaha/base/apply_tag.cc
@@ -18,8 +18,8 @@
#include "omaha/base/apply_tag.h"
#include
-#include
#include
+#include
#include
#include "omaha/base/utils.h"
@@ -40,15 +40,7 @@ ApplyTag::ApplyTag()
bool ApplyTag::IsValidTagString(const char* tag_string) {
ASSERT1(tag_string);
-
- CAtlRegExp regex;
- REParseError error = regex.Parse(kValidTagStringRegEx);
- if (error != REPARSE_ERROR_OK) {
- return false;
- }
-
- CAtlREMatchContext context;
- return !!regex.Match(tag_string, &context);
+ return std::regex_match(tag_string, std::regex(kValidTagStringRegEx));
}
HRESULT ApplyTag::Init(const TCHAR* signed_exe_file,
diff --git a/omaha/base/atl_regexp.cc b/omaha/base/atl_regexp.cc
deleted file mode 100644
index ac0babba5..000000000
--- a/omaha/base/atl_regexp.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2005-2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// ========================================================================
-
-#include "omaha/base/atl_regexp.h"
-
-#include
-#include
-
-namespace omaha {
-
-constexpr int kMaxArgs = 16;
-
-AtlRE::AtlRE(const TCHAR* pattern, bool case_sensitive) {
- ASSERT(pattern, (L""));
- REParseError status = re_.Parse(pattern, case_sensitive);
- ASSERT(status == REPARSE_ERROR_OK, (L""));
-}
-
-AtlRE::~AtlRE() {
-}
-
-bool AtlRE::DoMatchImpl(const TCHAR* text,
- CString* args[],
- int n,
- const TCHAR** match_end) const {
- // text may be NULL.
- ASSERT(args, (L""));
-
- if (!text) {
- return false;
- }
-
- AtlMatchContext matches;
- BOOL b = re_.Match(text, &matches, match_end);
- if (!b || matches.m_uNumGroups < static_cast(n)) {
- return false;
- }
-
- // Oddly enough, the Match call will make match_end
- // point off the end of the string if the result is at the
- // end of the string. We check this and handle it.
- if (match_end) {
- if ((*match_end - text) >= lstrlen(text)) {
- *match_end = NULL;
- }
- }
-
- const TCHAR* start = 0;
- const TCHAR* end = 0;
- for (int i = 0; i < n; ++i) {
- matches.GetMatch(i, &start, &end);
- const ptrdiff_t size = end - start;
- if (size > INT_MAX) {
- return false;
- }
- const int len = static_cast(size);
- ASSERT(args[i], (L""));
- // len+1 for the NULL character that's placed by lstrlen
- VERIFY1(lstrcpyn(args[i]->GetBufferSetLength(len), start, len + 1) != NULL);
- }
- return true;
-}
-
-} // namespace omaha
diff --git a/omaha/base/atl_regexp.h b/omaha/base/atl_regexp.h
deleted file mode 100644
index 1353a16d3..000000000
--- a/omaha/base/atl_regexp.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2005-2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// ========================================================================
-//
-// ATL Regular expression class that implements the RE interface.
-// See MSDN help for example patterns (lookup help on CAtlRegExp)
-// NOTE: This class adds about 8k to release builds.
-// TODO(omaha): add a unit test, showing examples, testing functionality
-// and perf.
-
-#ifndef OMAHA_COMMON_ATL_REGEXP_H__
-#define OMAHA_COMMON_ATL_REGEXP_H__
-
-#include
-#pragma warning(push)
-// enumerator 'identifier' in switch of enum 'enumeration' is not explicitly
-// handled by a case label
-#pragma warning(disable:4061)
-#include
-#pragma warning(pop)
-#include
-#include "base/basictypes.h"
-#include "omaha/base/regexp.h"
-#include "omaha/base/string.h"
-
-namespace omaha {
-
-// This class is essentially a copy of CAtlRECharTraitsWide from , but
-// I've replaced CRT functions that are not in our minicrt.
-//
-// TODO(omaha): do we need this?
-class CAtlRECharTraitsWideNoCrt
-{
-public:
- typedef WCHAR RECHARTYPE;
-
- // ATL80 addition.
- static size_t GetBitFieldForRangeArrayIndex(const RECHARTYPE *sz) throw()
- {
-#ifndef ATL_NO_CHECK_BIT_FIELD
- ATLASSERT(UseBitFieldForRange());
-#endif
- return static_cast(*sz);
- }
-
- static RECHARTYPE *Next(const RECHARTYPE *sz) throw()
- {
- return (RECHARTYPE *) (sz+1);
- }
-
- static int Strncmp(const RECHARTYPE *szLeft,
- const RECHARTYPE *szRight, size_t nCount) throw()
- {
- return String_StrNCmp(szLeft, szRight, nCount, false);
- }
-
- static int Strnicmp(const RECHARTYPE *szLeft,
- const RECHARTYPE *szRight, size_t nCount) throw()
- {
- return String_StrNCmp(szLeft, szRight, nCount,true);
- }
-
- static RECHARTYPE *Strlwr(RECHARTYPE *sz) throw()
- {
- return String_FastToLower(sz);
- }
-
- // In ATL 80 Strlwr must be passed a buffer size for security reasons.
- // TODO(omaha): Implement the function to consider the nSize param.
- static RECHARTYPE *Strlwr(RECHARTYPE *sz, int) throw()
- {
- return Strlwr(sz);
- }
-
- static long Strtol(const RECHARTYPE *sz,
- RECHARTYPE **szEnd, int nBase) throw()
- {
- return wcstol(sz, szEnd, nBase);
- }
-
- static int Isdigit(RECHARTYPE ch) throw()
- {
- return String_IsDigit(ch) ? 1 : 0;
- }
-
- static const RECHARTYPE** GetAbbrevs()
- {
- static const RECHARTYPE *s_szAbbrevs[] =
- {
- L"a([a-zA-Z0-9])", // alpha numeric
- L"b([ \\t])", // white space (blank)
- L"c([a-zA-Z])", // alpha
- L"d([0-9])", // digit
- L"h([0-9a-fA-F])", // hex digit
- L"n(\r|(\r?\n))", // newline
- L"q(\"[^\"]*\")|(\'[^\']*\')", // quoted string
- L"w([a-zA-Z]+)", // simple word
- L"z([0-9]+)", // integer
- NULL
- };
-
- return s_szAbbrevs;
- }
-
- static BOOL UseBitFieldForRange() throw()
- {
- return FALSE;
- }
-
- static int ByteLen(const RECHARTYPE *sz) throw()
- {
- return int(lstrlen(sz)*sizeof(WCHAR));
- }
-};
-
-typedef CAtlRegExp AtlRegExp;
-typedef CAtlREMatchContext AtlMatchContext;
-
-// implements the RE class using the ATL Regular Expressions class
-class AtlRE : public RE {
- public:
-
- AtlRE(const TCHAR* pattern, bool case_sensitive = true);
- virtual ~AtlRE();
-
- protected:
- // See regexp.h for an explanation.
- virtual bool DoMatchImpl(const TCHAR* text,
- CString* args[],
- int n,
- const TCHAR** match_end) const;
-
- private:
- mutable AtlRegExp re_;
- DISALLOW_COPY_AND_ASSIGN(AtlRE);
-};
-
-} // namespace omaha
-
-#endif // OMAHA_COMMON_ATL_REGEXP_H__
diff --git a/omaha/base/atl_regexp_unittest.cc b/omaha/base/atl_regexp_unittest.cc
deleted file mode 100644
index a1c426133..000000000
--- a/omaha/base/atl_regexp_unittest.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2005-2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// ========================================================================
-
-#include "omaha/base/atl_regexp.h"
-#include "omaha/testing/unit_test.h"
-
-namespace omaha {
-
-TEST(AtlRETest, AtlRE) {
- AtlRE newline_test_re(_T("ab{\\n}cd"));
- const TCHAR* newline_strings[] = { _T("\n"), _T("\r"), _T("\r\n") };
- for (size_t i = 0; i < arraysize(newline_strings); ++i) {
- CString content(_T("ab"));
- content.Append(newline_strings[i]);
- content.Append(_T("cd"));
- const TCHAR* content_ptr = content.GetString();
- CString newline;
- EXPECT_TRUE(RE::FindAndConsume(&content_ptr, newline_test_re, &newline));
- EXPECT_STREQ(newline, newline_strings[i]);
- }
-
- // Check that AtlRE works with Unicode characters.
- AtlRE one_two_three_four(_T("\x1234"));
- EXPECT_TRUE(RE::PartialMatch(_T("\x4321\x1234\x4321"), one_two_three_four));
-}
-
-} // namespace omaha
diff --git a/omaha/base/build.scons b/omaha/base/build.scons
index 7c5ea2f40..ddf551ed6 100644
--- a/omaha/base/build.scons
+++ b/omaha/base/build.scons
@@ -28,7 +28,6 @@ local_env = env.Clone()
inputs = [
'apply_tag.cc',
'app_util.cc',
- 'atl_regexp.cc',
'browser_utils.cc',
'cgi.cc',
'clipboard.cc',
@@ -61,7 +60,6 @@ inputs = [
'queue_timer.cc',
'reactor.cc',
'reg_key.cc',
- 'regexp.cc',
'registry_monitor_manager.cc',
'safe_format.cc',
'service_utils.cc',
diff --git a/omaha/base/const_config.h b/omaha/base/const_config.h
index 13bb02f4f..8b214c58e 100644
--- a/omaha/base/const_config.h
+++ b/omaha/base/const_config.h
@@ -25,24 +25,6 @@ namespace omaha {
#define kCiRegKeyShared GOOPDATE_MAIN_KEY kRegKeyShared
#define kRegValueReportIds _T("report_ids")
-// TODO(omaha): Move these plugin values someplace else. Since we're building
-// constants, that should probably be the customization header. Move the Omaha 3
-// plugin equivalents from config.cc there as well.
-
-// NOTE: ONECLICK_PLUGIN_VERSION_ANSI is defined in main.scons
-// For example: kOneClickProgId == "Google.OneClickCtrl.1"
-const TCHAR* const kOneClickProgId = COMPANY_NAME_IDENTIFIER
- _T(".OneClickCtrl.")
- _T(ONECLICK_PLUGIN_VERSION_ANSI);
-// The plug-in MIME type.
-// For example:
-// kOneClickPluginMimeTypeAnsi == "application/x-vnd.google.oneclickctrl.1"
-// TODO(omaha): Deal with the "Google.OneClickCtrl.%d") in
-// tools\goopdump\data_dumper_oneclick.cc after integrating goopdump.
-#define kOneClickPluginMimeTypeAnsi \
- "application/x-vnd." COMPANY_DOMAIN_BASE_ANSI ".oneclickctrl." \
- ONECLICK_PLUGIN_VERSION_ANSI
-
} // namespace omaha
#endif // OMAHA_BASE_CONST_CONFIG_H_
diff --git a/omaha/base/constants.h b/omaha/base/constants.h
index 577469e9f..048145778 100644
--- a/omaha/base/constants.h
+++ b/omaha/base/constants.h
@@ -113,8 +113,6 @@ const TCHAR* const kOmahaBrokerFileName =
MAIN_EXE_BASE_NAME _T("Broker.exe");
const TCHAR* const kOmahaOnDemandFileName =
MAIN_EXE_BASE_NAME _T("OnDemand.exe");
-const TCHAR* const kOmahaWebPluginFileName =
- MAIN_EXE_BASE_NAME _T("WebPlugin.exe");
const TCHAR* const kCrashHandlerFileName = CRASH_HANDLER_NAME _T(".exe");
const TCHAR* const kCrashHandler64FileName = CRASH_HANDLER_NAME _T("64.exe");
const TCHAR* const kOmahaMetainstallerFileName =
@@ -248,15 +246,6 @@ const TCHAR* const kChromeAppId = CHROME_APP_ID;
// Expands to HKEY_LOCAL_MACHINE\SOFTWARE\Google\UpdateDev
#define MACHINE_REG_UPDATE_DEV MACHINE_KEY REG_UPDATE_DEV
-// Regular expressions for the servers allowed to use the Omaha plugins.
-const TCHAR* const kSiteLockPatternStrings[] = {
- _T("^(gears)|(mail)|(tools)|(www)|(desktop)|(pack)|(chrome)|(drive)\\.google\\.com$"), // NOLINT
- _T("^www\\.google\\.(ad)|(bg)|(ca)|(cn)|(cz)|(de)|(es)|(fi)|(fr)|(gr)|(hr)|(hu)|(it)|(ki)|(kr)|(lt)|(lv)|(nl)|(no)|(pl)|(pt)|(ro)|(ru)|(sk)|(sg)|(sl)|(sr)|(vn)$"), // NOLINT
- _T("^www\\.google\\.co\\.(hu)|(id)|(il)|(it)|(jp)|(kr)|(th)|(uk)$"),
- _T("^www\\.google\\.com\\.(ar)|(au)|(br)|(cn)|(et)|(gr)|(hr)|(ki)|(lv)|(om)|(pl)|(pt)|(ru)|(sg)|(sv)|(tr)|(vn)$"), // NOLINT
- _T("^(www\\.)?chrome\\.com$"),
-};
-
//
// Minimum compatible shell version.
// Shell versions equal to or newer than the following version are compatible
@@ -323,13 +312,6 @@ const TCHAR* const kRegValueLastCheckPeriodSec = _T("LastCheckPeriodSec");
// Uses the production or the test cup keys.
const TCHAR* const kRegValueCupKeys = _T("TestKeys");
-// Allow a custom host pattern to be specified. For example,
-// "^https?://some_test_server\.google\.com/". For other examples, see
-// kSiteLockPatternStrings. The detailed regular expression syntax is documented
-// in the MSDN documentation for the CAtlRegExp class:
-// http://msdn.microsoft.com/en-us/library/k3zs4axe.aspx.
-const TCHAR* const kRegValueOneClickHostPattern = _T("OneClickHostPattern");
-
// Disables executable verification for application commands.
const TCHAR* const kRegValueSkipCommandVerification =
_T("NoAppCommandVerification");
@@ -415,13 +397,6 @@ const TCHAR* const kDefaultCountryCode = _T("us");
// the max length of the extra info we can store inside the install stubs.
const int kExtraMaxLength = 64 * 1024; // 64 KB
-#if defined(HAS_DEVICE_MANAGEMENT)
-
-// The maximum length of an enrollment token.
-const int kEnrollmentTokenMaxLength = 1024;
-
-#endif // defined(HAS_DEVICE_MANAGEMENT)
-
// Default brand code value when one is not specified.
// This has been specifically assigned to Omaha.
const TCHAR* const kDefaultGoogleUpdateBrandCode = _T("GGLS");
diff --git a/omaha/base/error.h b/omaha/base/error.h
index 71c7b783c..148bad296 100644
--- a/omaha/base/error.h
+++ b/omaha/base/error.h
@@ -449,11 +449,12 @@ const ULONG kFacilityOmaha = 67;
#define GOOGLEUPDATE_COMMANDLINE_E_NO_SCENARIO_HANDLER_MATCHED \
MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xC01)
-// OneClick custom error codes
-#define GOOPDATE_E_ONECLICK_HOSTCHECK_FAILED \
- MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xD01)
-#define GOOPDATE_E_ONECLICK_LANGUAGE_NOT_SUPPORTED \
- MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xD02)
+// OneClick custom error codes.
+// Obsolete.
+// #define GOOPDATE_E_ONECLICK_HOSTCHECK_FAILED \
+// MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xD01)
+// #define GOOPDATE_E_ONECLICK_LANGUAGE_NOT_SUPPORTED \
+// MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xD02)
// Usage stats / metrics error codes
#define GOOPDATE_E_METRICS_LOCK_INIT_FAILED \
diff --git a/omaha/base/logging.cc b/omaha/base/logging.cc
index a0d34208c..1b0ef0a76 100644
--- a/omaha/base/logging.cc
+++ b/omaha/base/logging.cc
@@ -101,7 +101,6 @@ struct {
LC_ENTRY(LC_SHELL),
LC_ENTRY(LC_CORE),
LC_ENTRY(LC_JS),
- LC_ENTRY(LC_PLUGIN),
LC_ENTRY(LC_SERVICE),
LC_ENTRY(LC_OPT),
LC_ENTRY(LC_NET),
diff --git a/omaha/base/logging.h b/omaha/base/logging.h
index 2a6d714af..ef7dbf937 100644
--- a/omaha/base/logging.h
+++ b/omaha/base/logging.h
@@ -129,7 +129,6 @@ namespace omaha {
// Shortcuts for different logging categories - no need to specify the category.
#define CORE_LOG(x, y) LC_LOG_DEBUG(omaha::LC_CORE, x, y)
#define NET_LOG(x, y) LC_LOG_DEBUG(omaha::LC_NET, x, y)
-#define PLUGIN_LOG(x, y) LC_LOG_DEBUG(omaha::LC_PLUGIN, x, y)
#define SERVICE_LOG(x, y) LC_LOG_DEBUG(omaha::LC_SERVICE, x, y)
#define SETUP_LOG(x, y) LC_LOG_DEBUG(omaha::LC_SETUP, x, y)
#define SHELL_LOG(x, y) LC_LOG_DEBUG(omaha::LC_SHELL, x, y)
@@ -154,7 +153,6 @@ enum LogCategory {
LC_SHELL,
LC_CORE,
LC_JS,
- LC_PLUGIN,
LC_SERVICE,
LC_OPT,
LC_NET,
diff --git a/omaha/base/process.cc b/omaha/base/process.cc
index 05a6b343b..7001bd7d4 100644
--- a/omaha/base/process.cc
+++ b/omaha/base/process.cc
@@ -159,7 +159,7 @@ bool Process::Running() const {
HANDLE Process::AssignToJob() {
// Make sure that the process handle is valid
if (!get(process_)) {
- return false;
+ return nullptr;
}
// Create a job
@@ -168,7 +168,7 @@ HANDLE Process::AssignToJob() {
UTIL_LOG(LEVEL_ERROR,
(_T("[Process::AssignToJob - CreateJobObject failed][0x%x]"),
HRESULTFromLastError()));
- return false;
+ return nullptr;
}
// Assign the process to the job
@@ -176,7 +176,7 @@ HANDLE Process::AssignToJob() {
UTIL_LOG(LEVEL_ERROR,
(_T("[Process::AssignToJob-AssignProcessToJobObject fail][0x%x]"),
HRESULTFromLastError()));
- return false;
+ return nullptr;
}
return release(job);
diff --git a/omaha/base/regexp.cc b/omaha/base/regexp.cc
deleted file mode 100644
index ba071ca06..000000000
--- a/omaha/base/regexp.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2005-2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// ========================================================================
-
-#include "omaha/base/regexp.h"
-#include "omaha/base/debug.h"
-
-namespace omaha {
-
-#define kMaxArgs 16
-
-bool RE::PartialMatch(const TCHAR* text, const RE& re, // 3..16 args
- CString * a0,
- CString * a1,
- CString * a2,
- CString * a3,
- CString * a4,
- CString * a5,
- CString * a6,
- CString * a7,
- CString * a8,
- CString * a9,
- CString * a10,
- CString * a11,
- CString * a12,
- CString * a13,
- CString * a14,
- CString * a15)
-{
- ASSERT(text, (L""));
- // a0 may be NULL
- // a1 may be NULL
- // a2 may be NULL
- // a3 may be NULL
- // a4 may be NULL
- // a5 may be NULL
- // a6 may be NULL
- // a7 may be NULL
- // a8 may be NULL
- // a9 may be NULL
- // a10 may be NULL
- // a11 may be NULL
- // a12 may be NULL
- // a13 may be NULL
- // a14 may be NULL
- // a15 may be NULL
-
- CString * args[kMaxArgs];
- int n = 0;
- if (a0 == NULL) goto done; args[n++] = a0;
- if (a1 == NULL) goto done; args[n++] = a1;
- if (a2 == NULL) goto done; args[n++] = a2;
- if (a3 == NULL) goto done; args[n++] = a3;
- if (a4 == NULL) goto done; args[n++] = a4;
- if (a5 == NULL) goto done; args[n++] = a5;
- if (a6 == NULL) goto done; args[n++] = a6;
- if (a7 == NULL) goto done; args[n++] = a7;
- if (a8 == NULL) goto done; args[n++] = a8;
- if (a9 == NULL) goto done; args[n++] = a9;
- if (a10 == NULL) goto done; args[n++] = a10;
- if (a11 == NULL) goto done; args[n++] = a11;
- if (a12 == NULL) goto done; args[n++] = a12;
- if (a13 == NULL) goto done; args[n++] = a13;
- if (a14 == NULL) goto done; args[n++] = a14;
- if (a15 == NULL) goto done; args[n++] = a15;
-
-done:
- return re.DoMatchImpl(text,args,n,NULL);
-}
-
-// Like PartialMatch(), except the "input" is advanced past the matched
-// text. Note: "input" is modified iff this routine returns true.
-// For example, "FindAndConsume(s, "(\\w+)", &word)" finds the next
-// word in "s" and stores it in "word".
-bool RE::FindAndConsume(const TCHAR **input, const RE& re,
- CString * a0,
- CString * a1,
- CString * a2,
- CString * a3,
- CString * a4,
- CString * a5,
- CString * a6,
- CString * a7,
- CString * a8,
- CString * a9,
- CString * a10,
- CString * a11,
- CString * a12,
- CString * a13,
- CString * a14,
- CString * a15)
-{
- ASSERT(input, (L""));
- // a0 may be NULL
- // a1 may be NULL
- // a2 may be NULL
- // a3 may be NULL
- // a4 may be NULL
- // a5 may be NULL
- // a6 may be NULL
- // a7 may be NULL
- // a8 may be NULL
- // a9 may be NULL
- // a10 may be NULL
- // a11 may be NULL
- // a12 may be NULL
- // a13 may be NULL
- // a14 may be NULL
- // a15 may be NULL
-
- CString * args[kMaxArgs];
- int n = 0;
- if (a0 == NULL) goto done; args[n++] = a0;
- if (a1 == NULL) goto done; args[n++] = a1;
- if (a2 == NULL) goto done; args[n++] = a2;
- if (a3 == NULL) goto done; args[n++] = a3;
- if (a4 == NULL) goto done; args[n++] = a4;
- if (a5 == NULL) goto done; args[n++] = a5;
- if (a6 == NULL) goto done; args[n++] = a6;
- if (a7 == NULL) goto done; args[n++] = a7;
- if (a8 == NULL) goto done; args[n++] = a8;
- if (a9 == NULL) goto done; args[n++] = a9;
- if (a10 == NULL) goto done; args[n++] = a10;
- if (a11 == NULL) goto done; args[n++] = a11;
- if (a12 == NULL) goto done; args[n++] = a12;
- if (a13 == NULL) goto done; args[n++] = a13;
- if (a14 == NULL) goto done; args[n++] = a14;
- if (a15 == NULL) goto done; args[n++] = a15;
-
-done:
- return re.DoMatchImpl(*input,args,n,input);
-}
-
-} // namespace omaha
-
diff --git a/omaha/base/regexp.h b/omaha/base/regexp.h
deleted file mode 100644
index 25781c1f0..000000000
--- a/omaha/base/regexp.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2005-2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// ========================================================================
-//
-// Implementors: There is only one function to implement -- DoMatchImpl
-// See below
-
-#ifndef OMAHA_COMMON_REGEXP_H__
-#define OMAHA_COMMON_REGEXP_H__
-
-#include
-
-namespace omaha {
-
-// Interface for regular expression matching. Also corresponds to a
-// pre-compiled regular expression. An "RE" object is safe for
-// concurrent use by multiple threads.
-class RE {
- public:
-
- // Matches "text" against "pattern". If pointer arguments are
- // supplied, copies matched sub-patterns into them. Use braces
- // "{", "}" within the regexp to indicate a pattern to be copied.
- //
- // Returns true iff all of the following conditions are satisfied:
- // a. some substring of "text" matches "pattern"
- // b. The number of matched sub-patterns is >= number of supplied pointers
- static bool PartialMatch(const TCHAR* text, const RE& re, // 3..16 args
- CString * a0 = NULL,
- CString * a1 = NULL,
- CString * a2 = NULL,
- CString * a3 = NULL,
- CString * a4 = NULL,
- CString * a5 = NULL,
- CString * a6 = NULL,
- CString * a7 = NULL,
- CString * a8 = NULL,
- CString * a9 = NULL,
- CString * a10 = NULL,
- CString * a11 = NULL,
- CString * a12 = NULL,
- CString * a13 = NULL,
- CString * a14 = NULL,
- CString * a15 = NULL);
-
- // Like PartialMatch(), except the "input" is advanced past the matched
- // text. Note: "input" is modified iff this routine returns true.
- // For example, "FindAndConsume(s, "{\\w+}", &word)" finds the next
- // word in "s" and stores it in "word".
- static bool FindAndConsume(const TCHAR** input, const RE& re,
- CString * a0 = NULL,
- CString * a1 = NULL,
- CString * a2 = NULL,
- CString * a3 = NULL,
- CString * a4 = NULL,
- CString * a5 = NULL,
- CString * a6 = NULL,
- CString * a7 = NULL,
- CString * a8 = NULL,
- CString * a9 = NULL,
- CString * a10 = NULL,
- CString * a11 = NULL,
- CString * a12 = NULL,
- CString * a13 = NULL,
- CString * a14 = NULL,
- CString * a15 = NULL);
-
- protected:
-
- // The behavior of this function is subject to how it's used
- // in PartialMatch() and FindAndConsume() above. See the header
- // description of those functions to understand how an implementation
- // should behave.
- // text is the text we're looking in
- // args is where matches should be outputted
- // n is the number of CStrings in args
- // match_end is a pointer to the position in text that
- // we ended matching on
- // returns true if data was found, false otherwise
- // Example:Suppose text = "google 1\nYahoo! 2\n ..." and the regexp
- // is something like "{\w+} \d". If args has two CStrings (n=2),
- // then args[0] = "google", arg[1] = "1" and match_end will point to the \n
- // before "Yahoo!"
- virtual bool DoMatchImpl(const TCHAR *text,
- CString * args[],
- int n,
- const TCHAR ** match_end) const = 0;
-};
-
-} // namespace omaha
-
-#endif // OMAHA_COMMON_REGEXP_H__
diff --git a/omaha/base/security/build.scons b/omaha/base/security/build.scons
index 8eaeaeb37..50df69290 100644
--- a/omaha/base/security/build.scons
+++ b/omaha/base/security/build.scons
@@ -36,7 +36,6 @@ security_inputs = [
'p256_ec.c',
'p256_ecdsa.c',
'p256_prng.c',
- 'sha.c',
'sha256.c',
'util.c',
]
diff --git a/omaha/base/security/hmac.c b/omaha/base/security/hmac.c
index 667076d6b..0eeb17a73 100644
--- a/omaha/base/security/hmac.c
+++ b/omaha/base/security/hmac.c
@@ -19,7 +19,6 @@
#include "util.h"
#include
-#include "sha.h"
#include "sha256.h"
static void HMAC_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
@@ -46,11 +45,6 @@ static void HMAC_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
}
}
-void HMAC_SHA_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
- SHA_init(&ctx->hash);
- HMAC_init(ctx, key, len);
-}
-
void HMAC_SHA256_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
SHA256_init(&ctx->hash);
HMAC_init(ctx, key, len);
diff --git a/omaha/base/security/hmac.h b/omaha/base/security/hmac.h
index baf545ff1..1ec70f971 100644
--- a/omaha/base/security/hmac.h
+++ b/omaha/base/security/hmac.h
@@ -28,7 +28,6 @@ typedef struct LITE_HMAC_CTX {
uint8_t opad[64];
} LITE_HMAC_CTX;
-void HMAC_SHA_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len);
void HMAC_SHA256_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len);
const uint8_t* HMAC_final(LITE_HMAC_CTX* ctx);
diff --git a/omaha/base/security/hmac_unittest.cc b/omaha/base/security/hmac_unittest.cc
index 339926a7e..a7adff700 100644
--- a/omaha/base/security/hmac_unittest.cc
+++ b/omaha/base/security/hmac_unittest.cc
@@ -32,32 +32,26 @@ static const struct KAT {
int md5_keylength; // md5 test keys are sometimes shorter.
const char* data;
const char* md5;
- const char* sha1;
const char* sha256;
} KATS[] = {
{"x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", 16, "Hi There",
"9294727a3638bb1c13f48ef8158bfc9d",
- "b617318655057264e28bc0b6fb378c8ef146be00",
"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"},
{"Jefe", 4, "what do ya want for nothing?",
"750c783e6ab0b503eaa86e310a5db738",
- "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79",
"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"},
{"xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 16,
"xdddddddddddddddddddddddddddddddddddddddddddddddddd"
"dddddddddddddddddddddddddddddddddddddddddddddddddd",
"56be34521d144c88dbb8c733f0e8b3f6",
- "125d7342b9ac11cd91a39af48aa17b4f63f175d3",
"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe"},
{"x0102030405060708090a0b0c0d0e0f10111213141516171819", 25,
"xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
"697eaf0aca3a3aea3a75164746ffaa79",
- "4c9007f4026250c6bc8414f9bf50c86c2d7235da",
"82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"},
{"x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", 16, "Test With Truncation",
"56461ef2342edc00f9bab995690efd4c",
- "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04",
"a3b6167473100ee06e0c796c2955552bfa6f7c0a6a8aef8b93f860aab0cd20c5"},
{"xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@@ -65,7 +59,7 @@ static const struct KAT {
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
80, "Test Using Larger Than Block-Size Key - Hash Key First",
"6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd",
- "aa4ae5e15272d00e95705637ce8a3b55ed402112", nullptr},
+ nullptr},
{"xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@@ -76,7 +70,7 @@ static const struct KAT {
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaa",
8 * 16 + 3, "Test Using Larger Than Block-Size Key - Hash Key First",
- nullptr, nullptr,
+ nullptr,
"60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54"},
{"xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@@ -86,7 +80,7 @@ static const struct KAT {
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size "
"Data",
"6f630fad67cda0ee1fb1f562db3aa53e",
- "e8e99d0f45237d786d6bbaa7965c7808bbff1a91", nullptr},
+ nullptr},
{"xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@@ -100,7 +94,7 @@ static const struct KAT {
"This is a test using a larger than block-size key and a larger t"
"han block-size data. The key needs to be hashed before being use"
"d by the HMAC algorithm.",
- nullptr, nullptr,
+ nullptr,
"9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2"},
{nullptr}};
@@ -114,16 +108,6 @@ TEST_F(HmacTest, RFC2202andRFC4131) {
string data = katp->data[0] ==
'x' ? omaha::a2b_hex(katp->data + 1) : katp->data;
- if (katp->sha1) {
- HMAC_SHA_init(&hmac, key.data(), key.size());
- HMAC_update(&hmac, data.data(), data.size());
-
- EXPECT_EQ(omaha::b2a_hex(
- reinterpret_cast(HMAC_final(&hmac)),
- HMAC_size(&hmac)),
- katp->sha1);
- }
-
if (katp->sha256) {
HMAC_SHA256_init(&hmac, key.data(), key.size());
HMAC_update(&hmac, data.data(), data.size());
diff --git a/omaha/base/security/sha.c b/omaha/base/security/sha.c
deleted file mode 100644
index 3b0a79585..000000000
--- a/omaha/base/security/sha.c
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2007-2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// ========================================================================
-//
-// Optimized for minimal code size.
-
-#include "sha.h"
-
-#include
-#include
-
-#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-static void SHA1_Transform(SHA_CTX* ctx) {
- uint32_t W[80];
- uint32_t A, B, C, D, E;
- uint8_t* p = ctx->buf;
- int t;
-
- for(t = 0; t < 16; ++t) {
- uint32_t tmp = (uint32_t)(*p++) << 24;
- tmp |= (uint32_t)(*p++) << 16;
- tmp |= (uint32_t)(*p++) << 8;
- tmp |= (uint32_t)(*p++);
- W[t] = tmp;
- }
-
- for(; t < 80; t++) {
- W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
- }
-
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
- E = ctx->state[4];
-
- for(t = 0; t < 80; t++) {
- uint32_t tmp = rol(5,A) + E + W[t];
-
- if (t < 20)
- tmp += (D^(B&(C^D))) + 0x5A827999;
- else if ( t < 40)
- tmp += (B^C^D) + 0x6ED9EBA1;
- else if ( t < 60)
- tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
- else
- tmp += (B^C^D) + 0xCA62C1D6;
-
- E = D;
- D = C;
- C = rol(30,B);
- B = A;
- A = tmp;
- }
-
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
- ctx->state[4] += E;
-}
-
-static const HASH_VTAB SHA_VTAB = {
- SHA_init,
- SHA_update,
- SHA_final,
- SHA_hash,
- SHA_DIGEST_SIZE
-};
-
-void SHA_init(SHA_CTX* ctx) {
- ctx->f = &SHA_VTAB;
- ctx->state[0] = 0x67452301;
- ctx->state[1] = 0xEFCDAB89;
- ctx->state[2] = 0x98BADCFE;
- ctx->state[3] = 0x10325476;
- ctx->state[4] = 0xC3D2E1F0;
- ctx->count = 0;
-}
-
-
-void SHA_update(SHA_CTX* ctx, const void* data, size_t len) {
- unsigned int i = (unsigned int)(ctx->count & 63);
- const uint8_t* p = (const uint8_t*)data;
-
- ctx->count += len;
-
- while (len--) {
- ctx->buf[i++] = *p++;
- if (i == 64) {
- SHA1_Transform(ctx);
- i = 0;
- }
- }
-}
-
-
-const uint8_t* SHA_final(SHA_CTX* ctx) {
- uint8_t *p = ctx->buf;
- uint64_t cnt = LITE_LShiftU64(ctx->count, 3);
- int i;
-
- SHA_update(ctx, (uint8_t*)"\x80", 1);
- while ((ctx->count & 63) != 56) {
- SHA_update(ctx, (uint8_t*)"\0", 1);
- }
- for (i = 0; i < 8; ++i) {
- uint8_t tmp = (uint8_t) LITE_RShiftU64(cnt, 56);
- cnt = LITE_LShiftU64(cnt, 8);
- SHA_update(ctx, &tmp, 1);
- }
-
- for (i = 0; i < 5; i++) {
- uint32_t tmp = ctx->state[i];
- *p++ = (uint8_t)(tmp >> 24);
- *p++ = (uint8_t)(tmp >> 16);
- *p++ = (uint8_t)(tmp >> 8);
- *p++ = (uint8_t)(tmp >> 0);
- }
-
- return ctx->buf;
-}
-
-/* Convenience function */
-const uint8_t* SHA_hash(const void* data, size_t len, uint8_t* digest) {
- SHA_CTX ctx;
- SHA_init(&ctx);
- SHA_update(&ctx, data, len);
- memcpy(digest, SHA_final(&ctx), SHA_DIGEST_SIZE);
- return digest;
-}
diff --git a/omaha/base/security/sha.h b/omaha/base/security/sha.h
deleted file mode 100644
index 43867e2be..000000000
--- a/omaha/base/security/sha.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2007-2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// ========================================================================
-
-#ifndef OMAHA_BASE_SECURITY_SHA_H_
-#define OMAHA_BASE_SECURITY_SHA_H_
-
-#include
-#include "hash-internal.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-typedef HASH_CTX SHA_CTX;
-
-void SHA_init(SHA_CTX* ctx);
-void SHA_update(SHA_CTX* ctx, const void* data, size_t len);
-const uint8_t* SHA_final(SHA_CTX* ctx);
-
-// Convenience method. Returns digest address.
-// NOTE: *digest needs to hold SHA_DIGEST_SIZE bytes.
-const uint8_t* SHA_hash(const void* data, size_t len, uint8_t* digest);
-
-#define SHA_DIGEST_SIZE 20
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif // OMAHA_BASE_SECURITY_SHA_H_
diff --git a/omaha/base/signatures.cc b/omaha/base/signatures.cc
index 7485f1606..549474cfd 100644
--- a/omaha/base/signatures.cc
+++ b/omaha/base/signatures.cc
@@ -19,12 +19,7 @@
// signatures of buffers.
#include "omaha/base/signatures.h"
-#include
#include
-#pragma warning(disable : 4245)
-// C4245 : conversion from 'type1' to 'type2', signed/unsigned mismatch
-#include
-#pragma warning(default : 4245)
#include
#include
@@ -32,18 +27,11 @@
#include "omaha/base/debug.h"
#include "omaha/base/error.h"
#include "omaha/base/logging.h"
-#include "omaha/base/security/sha256.h"
-#include "omaha/base/security/sha.h"
#include "omaha/base/string.h"
#include "omaha/base/utils.h"
namespace omaha {
-constexpr ALG_ID kHashAlgorithm = CALG_SHA1;
-constexpr DWORD kEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
-constexpr DWORD kCertificateNameType = CERT_NAME_SIMPLE_DISPLAY_TYPE;
-constexpr DWORD kKeyPairType = AT_SIGNATURE;
-
// Maximum file size allowed for performing authentication.
constexpr size_t kMaxFileSizeForAuthentication = 512 * 1024 * 1024; // 512MB
@@ -52,41 +40,6 @@ constexpr size_t kFileReadBufferSize = 128 * 1024;
namespace CryptDetails {
-void crypt_release_context(HCRYPTPROV provider) {
- UTIL_LOG(L3, (L"Releasing HCRYPTPROV 0x%08lx", provider));
- BOOL b = ::CryptReleaseContext(provider, 0 /*flags*/);
- ASSERT(b, (L""));
-}
-
-void crypt_close_store(HCERTSTORE store) {
- UTIL_LOG(L3, (L"Releasing HCERTSTORE 0x%08lx", store));
- BOOL b = ::CertCloseStore(store, 0 /*flags*/);
- ASSERT(b, (L""));
- ASSERT(::GetLastError() != CRYPT_E_PENDING_CLOSE, (L""));
-}
-
-void crypt_free_certificate(PCCERT_CONTEXT certificate) {
- UTIL_LOG(L3, (L"Releasing PCCERT_CONTEXT 0x%08lx", certificate));
- BOOL b = ::CertFreeCertificateContext(certificate);
- ASSERT(b, (L""));
-}
-
-void crypt_destroy_key(HCRYPTKEY key) {
- UTIL_LOG(L3, (L"Releasing HCRYPTKEY 0x%08lx", key));
- BOOL b = ::CryptDestroyKey(key);
- ASSERT(b, (L""));
-}
-
-void crypt_destroy_hash(HCRYPTHASH hash) {
- UTIL_LOG(L3, (L"Releasing HCRYPTHASH 0x%08lx", hash));
- BOOL b = ::CryptDestroyHash(hash);
- ASSERT(b, (L""));
-}
-
-typedef close_fun smart_destroy_hash;
-typedef scoped_any scoped_crypt_hash;
-
class SHA256Hash : public HashInterface {
public:
SHA256Hash() {
@@ -112,184 +65,12 @@ class SHA256Hash : public HashInterface {
DISALLOW_COPY_AND_ASSIGN(SHA256Hash);
};
-class SHA1Hash : public HashInterface {
- public:
- SHA1Hash() {
- SHA_init(&ctx_);
- }
- virtual ~SHA1Hash() {}
-
- virtual void update(const void* data, unsigned int len) {
- SHA_update(&ctx_, data, len);
- }
-
- virtual const uint8_t* final() {
- return SHA_final(&ctx_);
- }
-
- virtual size_t hash_size() const {
- return SHA_DIGEST_SIZE;
- }
-
- private:
- SHA_CTX ctx_;
-
- DISALLOW_COPY_AND_ASSIGN(SHA1Hash);
-};
-
-CryptDetails::HashInterface* CreateHasher(bool use_sha256) {
- if (use_sha256) {
- return new CryptDetails::SHA256Hash;
- } else {
- return new CryptDetails::SHA1Hash;
- }
+CryptDetails::HashInterface* CreateHasher() {
+ return new CryptDetails::SHA256Hash;
}
} // namespace CryptDetails
-// Base64 encode/decode functions are part of ATL Server
-HRESULT Base64::Encode(const std::vector& buffer_in,
- std::vector* encoded,
- bool break_into_lines) {
- ASSERT(encoded, (L""));
-
- if (buffer_in.empty()) {
- encoded->clear();
- return S_OK;
- }
-
- if (buffer_in.size() > INT_MAX) {
- return E_INVALIDARG;
- }
-
- int encoded_len =
- Base64EncodeGetRequiredLength(
- static_cast(buffer_in.size()),
- break_into_lines ? ATL_BASE64_FLAG_NONE : ATL_BASE64_FLAG_NOCRLF);
- ASSERT(encoded_len > 0, (L""));
-
- encoded->resize(encoded_len);
- int str_out_len = encoded_len;
-
- BOOL result = Base64Encode(
- &buffer_in.front(),
- static_cast(buffer_in.size()),
- reinterpret_cast(&encoded->front()),
- &str_out_len,
- break_into_lines ? ATL_BASE64_FLAG_NONE : ATL_BASE64_FLAG_NOCRLF);
- if (!result)
- return E_FAIL;
- ASSERT(str_out_len <= encoded_len, (L""));
- if (str_out_len < encoded_len)
- encoded->resize(str_out_len);
-
- return S_OK;
-}
-
-HRESULT Base64::Encode(const std::vector& buffer_in,
- CStringA* encoded,
- bool break_into_lines) {
- ASSERT(encoded, (L""));
-
- if (buffer_in.empty()) {
- return S_OK;
- }
-
- std::vector buffer_out;
- RET_IF_FAILED(Encode(buffer_in, &buffer_out, break_into_lines));
-
- if (buffer_out.size() > INT_MAX) {
- return E_FAIL;
- }
- encoded->Append(reinterpret_cast(&buffer_out.front()),
- static_cast(buffer_out.size()));
-
- return S_OK;
-}
-
-HRESULT Base64::Encode(const std::vector& buffer_in,
- CString* encoded,
- bool break_into_lines) {
- ASSERT(encoded, (L""));
-
- CStringA string_out;
- RET_IF_FAILED(Encode(buffer_in, &string_out, break_into_lines));
- *encoded = string_out;
-
- return S_OK;
-}
-
-HRESULT Base64::Decode(const std::vector& encoded,
- std::vector* buffer_out) {
- ASSERT(buffer_out, (L""));
-
- const size_t encoded_len = encoded.size();
- if (encoded_len > INT_MAX) {
- return E_INVALIDARG;
- }
-
- const int required_len = Base64DecodeGetRequiredLength(
- static_cast(encoded_len));
-
- buffer_out->resize(required_len);
-
- if (required_len == 0) {
- return S_OK;
- }
-
- int bytes_written = required_len;
- BOOL result = Base64Decode(reinterpret_cast(&encoded.front()),
- static_cast(encoded_len),
- &buffer_out->front(),
- &bytes_written);
- if (!result)
- return E_FAIL;
- ASSERT(bytes_written <= required_len, (L""));
- if (bytes_written < required_len) {
- buffer_out->resize(bytes_written);
- }
-
- return S_OK;
-}
-
-HRESULT Base64::Decode(const CStringA& encoded, std::vector* buffer_out) {
- ASSERT(buffer_out, (L""));
-
- size_t encoded_len = encoded.GetLength();
- std::vector buffer_in(encoded_len);
- if (encoded_len != 0) {
- memcpy(&buffer_in.front(), encoded.GetString(), encoded_len);
- }
-
- return Decode(buffer_in, buffer_out);
-}
-
-// Base64 in a CString -> binary
-HRESULT Base64::Decode(const CString& encoded, std::vector* buffer_out) {
- ASSERT(buffer_out, (L""));
-
- CW2A encoded_a(encoded.GetString());
-
- size_t encoded_len = ::strlen(encoded_a);
- std::vector buffer_in(encoded_len);
- if (encoded_len != 0) {
- memcpy(&buffer_in.front(), encoded_a, encoded_len);
- }
-
- return Decode(buffer_in, buffer_out);
-}
-
-const size_t CryptoHash::kSha1HashSize = 20;
-const size_t CryptoHash::kSha256HashSize = 32;
-
-CryptoHash::CryptoHash(HashAlgorithm hash_algorithm)
- : use_sha256_(hash_algorithm == kSha256) {
- ASSERT1(hash_algorithm == kSha1 || hash_algorithm == kSha256);
-}
-
-CryptoHash::~CryptoHash() {
-}
-
HRESULT CryptoHash::Compute(const TCHAR* filepath,
uint64 max_len,
std::vector* hash_out) {
@@ -357,7 +138,7 @@ HRESULT CryptoHash::ComputeOrValidate(const std::vector& filepaths,
static_assert(kFileReadBufferSize <= INT_MAX);
std::unique_ptr hasher(
- CryptDetails::CreateHasher(use_sha256_));
+ CryptDetails::CreateHasher());
for (size_t i = 0; i < filepaths.size(); ++i) {
scoped_hfile file_handle(::CreateFile(filepaths[i],
@@ -401,7 +182,7 @@ HRESULT CryptoHash::ComputeOrValidate(const std::vector& filepaths,
}
DWORD digest_size = static_cast(hash_size());
- std::vector digest_data(digest_size);
+ std::vector digest_data(digest_size);
memcpy(&digest_data.front(), hasher->final(), digest_size);
@@ -411,13 +192,9 @@ HRESULT CryptoHash::ComputeOrValidate(const std::vector& filepaths,
return S_OK;
}
- std::vector calculated_hash(digest_size);
- memcpy(&calculated_hash.front(), &digest_data.front(), digest_size);
CStringA base64_encoded_hash;
- Base64::Encode(calculated_hash, &base64_encoded_hash, false);
- CString hash = AnsiToWideString(base64_encoded_hash,
- base64_encoded_hash.GetLength());
- REPORT_LOG(L1, (_T("[actual hash=%s]"), hash));
+ Base64Escape(digest_data.data(), digest_size, &base64_encoded_hash, true);
+ REPORT_LOG(L1, (_T("[actual hash=%S]"), base64_encoded_hash));
return SIGS_E_INVALID_SIGNATURE;
} else {
hash_out->resize(digest_size);
@@ -437,7 +214,7 @@ HRESULT CryptoHash::ComputeOrValidate(const std::vector& buffer_in,
}
std::unique_ptr hasher(
- CryptDetails::CreateHasher(use_sha256_));
+ CryptDetails::CreateHasher());
const size_t datalen = buffer_in.size();
const uint8* data = datalen ? &buffer_in.front() : NULL;
@@ -459,683 +236,6 @@ HRESULT CryptoHash::ComputeOrValidate(const std::vector& buffer_in,
}
}
-// To sign data you need a CSP with the proper private key installed.
-// To get a signing certificate you start with a PFX file. This file
-// encodes a "certificate store" which can hold more than one
-// certificate. (In general it can hold a certificate chain, but we
-// only use the signing certificate.) There are special APIs to verify
-// the format of a PFX file and read it into a new certificate store. A
-// password must be specified to read the PFX file as it is encrypted.
-// The password was set when the PFX file was exported or otherwise
-// created. Then you search for the proper certificate in the store
-// (using the subject_name which tells who the certificate was issued
-// to). Finally, to get a CSP with the certificate's private key
-// available there is a special API, CryptAcquireCertificatePrivateKey,
-// that takes a CSP and a certificate and makes the private key of the
-// certificate the private key of the CSP.
-
-CryptoSigningCertificate::CryptoSigningCertificate() : key_spec_(0) {
-}
-
-CryptoSigningCertificate::~CryptoSigningCertificate() {
-}
-
-HRESULT CryptoSigningCertificate::ImportCertificate(
- const TCHAR * filepath,
- const TCHAR * password,
- const TCHAR * subject_name) {
- ASSERT(filepath, (L""));
- ASSERT(password, (L""));
-
- std::vector buffer;
- HRESULT hr = ReadEntireFile(filepath, kMaxCertificateSize, &buffer);
- if (FAILED(hr)) {
- UTIL_LOG(LE, (L"[CryptoSigningCertificate::ImportCertificate]"
- L"['%s' not read, hr 0x%08lx]", filepath, hr));
- return hr;
- }
- return ImportCertificate(buffer, password, subject_name);
-}
-
-HRESULT CryptoSigningCertificate::ImportCertificate(
- const std::vector& certificate_in,
- const TCHAR * password,
- const TCHAR * subject_name) {
- ASSERT(password, (L""));
- ASSERT1(!certificate_in.empty());
-
- UTIL_LOG(L2, (L"[CryptoSigningCertificate::ImportCertificate]"
- L"[%d bytes, subject_name '%s']",
- certificate_in.size(), subject_name ? subject_name : L""));
-
- if (certificate_in.size() > INT_MAX) {
- return E_INVALIDARG;
- }
-
- // CryptoAPI treats the certificate as a "blob"
- CRYPT_DATA_BLOB blob;
- blob.cbData = static_cast(certificate_in.size());
- blob.pbData = const_cast(&certificate_in.front());
-
- // Ensure that it is PFX formatted
- BOOL b = ::PFXIsPFXBlob(&blob);
- if (!b) {
- ASSERT(0, (L"Invalid PFX certificate, err 0x%08lx", ::GetLastError()));
- return SIGS_E_INVALID_PFX_CERTIFICATE;
- }
-
- // Make sure the password checks out
- b = ::PFXVerifyPassword(&blob, password, 0 /* flags */);
- if (!b) {
- UTIL_LOG(LE, (L"[CryptoSigningCertificate::ImportCertificate]"
- L"[invalid password, err 0x%08lx]", ::GetLastError()));
- return SIGS_E_INVALID_PASSWORD;
- }
-
- // Do the import from the certificate to a new certificate store
- // TODO(omaha): Check that this is in fact a new certificate store, not an
- // existing one. If it is an existing one we'll need to delete the
- // certificate later.
- // The last parameter to ::PFXImportCertStore() is 0, indicating that we want
- // the CSP to be "silent"; i.e., not prompt.
- reset(store_, ::PFXImportCertStore(&blob, password, 0));
- if (!store_) {
- DWORD err = ::GetLastError();
- ASSERT(0, (L"Failed to import PFX certificate into a certificate store, "
- L"err 0x%08lx", err));
- return HRESULT_FROM_WIN32(err);
- }
- UTIL_LOG(L3, (L"[CryptoSigningCertificate::ImportCertificate]"
- L"[new store 0x%08lx]", get(store_)));
-
- // Now that we have a store, look for the correct certificate. (There may
- // have been more than one in the PFX file, e.g., a certificate chain.)
- PCCERT_CONTEXT certificate_context = NULL;
- while ((certificate_context =
- ::CertEnumCertificatesInStore(get(store_),
- certificate_context)) != NULL) {
- // Have a certificate, does it look like the right one? Check the name
- DWORD name_len = ::CertGetNameString(certificate_context,
- kCertificateNameType,
- 0 /*flags*/,
- NULL,
- NULL,
- 0);
- if (name_len <= 1) {
- // Name attribute not found - should never happen
- ASSERT(0, (L"CryptoSigningCertificate::ImportCertificate failed to get "
- L"certificate name length, err 0x%08lx", ::GetLastError()));
- continue;
- }
- // name_len includes the terminating null
-
- std::vector name;
- name.resize(name_len);
- ASSERT1(!name.empty());
- DWORD name_len2 = ::CertGetNameString(certificate_context,
- kCertificateNameType,
- 0,
- NULL,
- &name.front(),
- name_len);
- ASSERT(name_len2 == name_len, (L""));
-
- UTIL_LOG(L3, (L"[CryptoSigningCertificate::ImportCertificate]"
- L"[found '%s' in store]", &name.front()));
-
- // Check the name if the user so desires. (If subject_name == NULL then
- // the first certificate found is used.)
- if (subject_name && (0 != String_StrNCmp(&name.front(),
- subject_name,
- ::lstrlen(subject_name),
- false))) {
- // name mismatch
- UTIL_LOG(L3, (L"[CryptoSigningCertificate::ImportCertificate]"
- L"[not the right certificate, we're looking for '%s']",
- subject_name));
- continue;
- }
-
- // This is the right certificate
- subject_name_ = &name.front();
- reset(certificate_, certificate_context);
- UTIL_LOG(L3, (L"[CryptoSigningCertificate::ImportCertificate]"
- L"[new certificate 0x%08lx]", get(certificate_)));
- break;
- }
-
- return S_OK;
-}
-
-HRESULT CryptoSigningCertificate::GetCSPContext(HCRYPTPROV* csp_context) {
- ASSERT(csp_context, (L""));
- ASSERT(get(certificate_), (L""));
-
- // CSP may have already been used - reset it
- reset(csp_);
-
- // Create a CSP context using the private key of the certificate we imported
- // earlier.
- HCRYPTPROV csp = NULL;
- BOOL must_free_csp = FALSE;
- BOOL b = ::CryptAcquireCertificatePrivateKey(get(certificate_),
- 0 /*flags*/,
- 0 /*reserved*/,
- &csp,
- &key_spec_,
- &must_free_csp);
- if (!b) {
- DWORD err = ::GetLastError();
- ASSERT(0, (L"CryptoSigningCertificate::GetCSPContext "
- L"CryptAcquireCertificatePrivateKey failed, err 0x%08lx", err));
- return HRESULT_FROM_WIN32(err);
- }
-
- // (Funky API returns a boolean which tells you whether it is your
- // responsibility to delete the CSP context or not.)
- if (must_free_csp) {
- reset(csp_, csp);
- }
- if (get(csp_)) {
- UTIL_LOG(L3, (L"[CryptoSigningCertificate::GetCSPContext new CSP 0x%08lx]",
- get(csp_)));
- }
-
- ASSERT(key_spec_ == AT_SIGNATURE || key_spec_ == AT_KEYEXCHANGE, (L""));
- if (key_spec_ != kKeyPairType) {
- UTIL_LOG(LE, (L"[CryptoSigningCertificate::GetCSPContext]"
- L"[requires a AT_SIGNATURE type key]"));
- return SIGS_E_INVALID_KEY_TYPE;
- }
-
-#ifdef _DEBUG
- // Which CSP did we get?
- char csp_name[256] = {0};
- DWORD csp_name_len = arraysize(csp_name);
- b = ::CryptGetProvParam(csp,
- PP_NAME,
- reinterpret_cast(&csp_name[0]),
- &csp_name_len,
- 0 /*flags*/);
- if (!b) {
- DWORD err = ::GetLastError();
- UTIL_LOG(LE, (L"[CryptoSigningCertificate::GetCSPContext]"
- L"[error getting CSP name, err 0x%08lx]", err));
- }
- DWORD csp_prov_type;
- DWORD csp_prov_type_len = sizeof(csp_prov_type);
- b = ::CryptGetProvParam(csp,
- PP_PROVTYPE,
- reinterpret_cast(&csp_prov_type),
- &csp_prov_type_len,
- 0 /*flags*/);
- if (!b) {
- DWORD err = ::GetLastError();
- UTIL_LOG(LE, (L"[CryptoSigningCertificate::GetCSPContext]"
- L"[error getting CSP provtype, err 0x%08lx]", err));
- }
- char csp_container[256] = {0};
- DWORD csp_container_len = arraysize(csp_container);
- b = ::CryptGetProvParam(csp,
- PP_CONTAINER,
- reinterpret_cast(&csp_container[0]),
- &csp_container_len,
- 0 /*flags*/);
- if (!b) {
- DWORD err = ::GetLastError();
- UTIL_LOG(LE, (L"[CryptoSigningCertificate::GetCSPContext]"
- L"[error getting CSP current container name, err 0x%08lx]",
- err));
- }
- UTIL_LOG(L2, (L"[CryptoSigningCertificate::GetCSPContext]"
- L"[have CSP '%S' (provtype %d) key container '%S']",
- csp_name, csp_prov_type, csp_container));
- // End of which CSP did we get
-#endif
-
- *csp_context = csp;
-
- UTIL_LOG(L2, (L"[CryptoSigningCertificate::GetCSPContext]"
- L"[getting CSP with private key from certificate]"
- L"[HCRYPTPROV 0x%08lx]", csp));
-
- return S_OK;
-}
-
-// To sign some data using CryptoAPI you first hash it into a hash
-// object, then sign it using the CSP. The CSP needs to have the
-// private key, of type AT_SIGNATURE, in it already, as it isn't a
-// parameter of the CryptSignHash API. The CryptoSigningCertificate
-// can provide such a CSP.
-
-CryptoComputeSignature::CryptoComputeSignature(
- CryptoSigningCertificate* certificate)
- : certificate_(certificate) {
-}
-
-CryptoComputeSignature::~CryptoComputeSignature() {
-}
-
-HRESULT CryptoComputeSignature::Sign(TCHAR const * const filepath,
- uint32 max_len,
- std::vector* signature_out) {
- ASSERT(filepath, (L""));
- std::vector buffer;
- HRESULT hr = ReadEntireFile(filepath, max_len, &buffer);
- if (FAILED(hr)) {
- UTIL_LOG(LE, (L"[CryptoComputeSignature::Sign]"
- L"['%s not read, hr 0x%08lx]", filepath, hr));
- return hr;
- }
- return Sign(buffer, signature_out);
-}
-
-HRESULT CryptoComputeSignature::Sign(const std::vector& buffer_in,
- std::vector* signature_out) {
- ASSERT(signature_out, (L""));
- ASSERT1(!buffer_in.empty());
-
- UTIL_LOG(L2, (L"[CryptoComputeSignature::Sign]"
- L"[buffer of %d bytes]", buffer_in.size()));
-
- if (buffer_in.size() > INT_MAX) {
- return E_INVALIDARG;
- }
-
- // Get the proper CSP with the private key (certificate retains ownership)
- HCRYPTPROV csp = NULL;
- HRESULT hr = certificate_->GetCSPContext(&csp);
- ASSERT(SUCCEEDED(hr) && csp, (L""));
-
- // Hash the data
- CryptDetails::scoped_crypt_hash hash;
- BOOL b = ::CryptCreateHash(csp, kHashAlgorithm, 0, 0, address(hash));
- if (!b) {
- // hash is now invalid, but might not be NULL, so stomp on it
- DWORD err = ::GetLastError();
- ASSERT(!hash, (L""));
- UTIL_LOG(LE, (L"[CryptoComputeSignature::Sign]"
- L"[could not create hash, err 0x%08lx]", err));
- return HRESULT_FROM_WIN32(err);
- }
- UTIL_LOG(L3, (L"CryptoComputeSignature::Sign new hash 0x%08lx", get(hash)));
-
- b = ::CryptHashData(get(hash),
- &buffer_in.front(),
- static_cast(buffer_in.size()),
- 0);
- if (!b) {
- DWORD err = ::GetLastError();
- UTIL_LOG(LE, (L"[CryptoComputeSignature::Sign]"
- L"[could not hash data, err 0x%08lx]", err));
- return HRESULT_FROM_WIN32(err);
- }
-
- // Sign the hash (first get length, then allocate buffer and do real signing)
- DWORD signature_len = 0;
- b = ::CryptSignHash(get(hash),
- kKeyPairType,
- NULL,
- 0 /*flags*/,
- NULL,
- &signature_len);
- if (!b && ::GetLastError() != ERROR_MORE_DATA) {
- DWORD err = ::GetLastError();
- UTIL_LOG(LE, (L"[CryptoComputeSignature::Sign]"
- L"[could not compute size of signature, err 0x%08lx]", err));
- return HRESULT_FROM_WIN32(err);
- }
- signature_out->resize(signature_len);
- b = ::CryptSignHash(get(hash),
- kKeyPairType,
- NULL,
- 0,
- &signature_out->front(),
- &signature_len);
- if (!b) {
- DWORD err = ::GetLastError();
- UTIL_LOG(LE, (L"[CryptoComputeSignature::Sign]"
- L"[could not compute signature, err 0x%08lx]", err));
- return HRESULT_FROM_WIN32(err);
- }
- ASSERT(signature_len == signature_out->size(), (L""));
-
- UTIL_LOG(L3, (L"[CryptoComputeSignature::Sign]"
- L"[have %d byte signature]", signature_out->size()));
-
- return S_OK;
-}
-
-// To verify signed data you need a CSP, and you also need the public
-// key extracted from a certificate. The CSP can be any RSA CSP on the
-// machine, the default one is fine. To get the public key you start
-// by importing a certificate in standard "DER encoded" format. That
-// returns a giant data structure, one field of which is the public key
-// in a format that CryptoAPI understands. You import this public key
-// into the CSP with the CryptImportPublicKey() API, and then create a
-// key object from it suitable for use with the verification API.
-
-CryptoSignatureVerificationCertificate::CryptoSignatureVerificationCertificate() { // NOLINT
-}
-
-CryptoSignatureVerificationCertificate::~CryptoSignatureVerificationCertificate() { // NOLINT
-}
-
-HRESULT CryptoSignatureVerificationCertificate::ImportCertificate(
- const TCHAR * filepath,
- const TCHAR * subject_name) {
- ASSERT(filepath, (L""));
- std::vector buffer;
- HRESULT hr = ReadEntireFile(filepath, kMaxCertificateSize, &buffer);
- if (FAILED(hr)) {
- UTIL_LOG(LE, (L"[CryptoSignatureVerificationCertificate::ImportCertificate]"
- L"['%s' not read, hr 0x%08lx]", filepath, hr));
- return hr;
- }
- return ImportCertificate(buffer, subject_name);
-}
-
-HRESULT CryptoSignatureVerificationCertificate::ImportCertificate(
- const std::vector& certificate_in,
- const TCHAR * subject_name) {
- // Import the certificate
- ASSERT1(!certificate_in.empty());
-
- if (certificate_in.size() > INT_MAX) {
- return E_INVALIDARG;
- }
-
- reset(certificate_,
- ::CertCreateCertificateContext(
- kEncodingType,
- &certificate_in.front(),
- static_cast(certificate_in.size())));
- if (!certificate_) {
- DWORD err = ::GetLastError();
- UTIL_LOG(LE, (L"[CryptoSignatureVerificationCertificate::ImportCertificate]"
- L"[could not import certificate, err 0x%08lx]", err));
- return SIGS_E_INVALID_DER_CERTIFICATE;
- }
- UTIL_LOG(L3, (L"[CryptoSignatureVerificationCertificate::ImportCertificate]"
- L"[new certificate 0x%08lx]", get(certificate_)));
-
- // Get certificate's subject name
- DWORD name_len = ::CertGetNameString(get(certificate_),
- kCertificateNameType,
- 0 /*flags*/,
- NULL,
- NULL,
- 0);
- if (name_len <= 1) {
- // Name attribute not found - should never happen
- ASSERT(0, (L"CryptoSignatureVerificationCertificate failed to get "
- L"certificate name length, err 0x%08lx", ::GetLastError()));
- return E_FAIL;
- }
- // name_len includes the terminating NULL
-
- std::vector name;
- name.resize(name_len);
- ASSERT1(!name.empty());
- DWORD name_len2 = ::CertGetNameString(get(certificate_),
- kCertificateNameType,
- 0,
- NULL,
- &name.front(),
- name_len);
- ASSERT(name_len2 == name_len, (L""));
-
- UTIL_LOG(L3, (L"[CryptoSignatureVerificationCertificate::ImportCertificate]"
- L"['%s' is subject of certificate]", &name.front()));
-
- subject_name_ = &name.front();
-
- // Check the name if the user so desires.
- if (subject_name && (0 != String_StrNCmp(&name.front(),
- subject_name,
- ::lstrlen(subject_name), false))) {
- // name mismatch
- UTIL_LOG(L3, (L"[CryptoSignatureVerificationCertificate::ImportCertificate]"
- L"[not the right certificate, we're looking for '%s']",
- subject_name));
- return E_FAIL;
- }
-
- return S_OK;
-}
-
-HRESULT CryptoSignatureVerificationCertificate::GetCSPContextAndKey(
- HCRYPTPROV* csp_context,
- HCRYPTKEY* public_key) {
- ASSERT(csp_context, (L""));
- ASSERT(public_key, (L""));
- ASSERT(get(certificate_), (L""));
-
- // Get the public key out of the certificate
- PCERT_INFO cert_info = get(certificate_)->pCertInfo;
- ASSERT(cert_info, (L""));
- PCERT_PUBLIC_KEY_INFO public_key_info = &cert_info->SubjectPublicKeyInfo;
- ASSERT(public_key_info, (L""));
-
- // Reset the CSP and key in case it has been used already
- reset(key_);
- reset(csp_);
-
- // Get the default CSP. With CRYPT_VERIFYCONTEXT don't need to worry
- // about creating/destroying a key container.
- // TODO(omaha): Why wasn't PROV_RSA_SIG available? Maybe looking for the
- // default isn't a good idea?
- const DWORD provider_type = PROV_RSA_FULL;
- BOOL b = ::CryptAcquireContext(address(csp_),
- NULL,
- NULL,
- provider_type,
- CRYPT_VERIFYCONTEXT|CRYPT_SILENT);
- if (!b) {
- DWORD err = ::GetLastError();
- UTIL_LOG(LE, (L"[GetCSPContextAndKey]"
- L"[failed to acquire CSP, err 0x%08lx]", err));
- return HRESULT_FROM_WIN32(err);
- }
- UTIL_LOG(L3, (L"[CryptoSignatureVerificationCertificate::GetCSPContextAndKey]"
- L"[new CSP 0x%08lx]", get(csp_)));
-
- // Convert the public key in encoded form into a CryptoAPI HCRYPTKEY
- b = ::CryptImportPublicKeyInfo(get(csp_),
- kEncodingType,
- public_key_info,
- address(key_));
- if (!b) {
- DWORD err = ::GetLastError();
- UTIL_LOG(LE, (L"[GetCSPContextAndKey]"
- L"[failed to import public key, err 0x%08lx]", err));
- return HRESULT_FROM_WIN32(err);
- }
- UTIL_LOG(L3, (L"[CryptoSignatureVerificationCertificate::GetCSPContextAndKey]"
- L"[new key 0x%08lx]", get(key_)));
-
- *csp_context = get(csp_);
- *public_key = get(key_);
-
- return S_OK;
-}
-
-// To verify the signature of some data using CryptoAPI you first hash
-// it into a hash object, then verify it using the CSP and a public key.
-// In this case the CryptVerifySignature takes the key (of type
-// AT_SIGNATURE) as a separate parameter. The
-// CryptoSignatureVerificationCertificate can provide the proper CSP and
-// the public key from the certificate.
-
-CryptoVerifySignature::CryptoVerifySignature(
- CryptoSignatureVerificationCertificate& certificate) // NOLINT
- : certificate_(&certificate) {
-}
-
-CryptoVerifySignature::~CryptoVerifySignature() {
-}
-
-HRESULT CryptoVerifySignature::Validate(const TCHAR* filepath,
- uint32 max_len,
- const std::vector& signature_in) {
- ASSERT(filepath, (L""));
- std::vector buffer;
- HRESULT hr = ReadEntireFile(filepath, max_len, &buffer);
- if (FAILED(hr)) {
- UTIL_LOG(LE, (L"[CryptoVerifySignature::Validate]"
- L"['%s' not read, hr 0x%08lx]", filepath, hr));
- return hr;
- }
- return Validate(buffer, signature_in);
-}
-
-HRESULT CryptoVerifySignature::Validate(const std::vector& buffer_in,
- const std::vector& signature_in) {
- ASSERT(certificate_, (L""));
- ASSERT1(!buffer_in.empty());
- ASSERT1(!signature_in.empty());
-
- UTIL_LOG(L2, (L"[CryptoVerifySignature::Validate]"
- L"[buffer of %d bytes, signature of %d bytes]",
- buffer_in.size(), signature_in.size()));
-
- if (buffer_in.size() > INT_MAX || signature_in.size() > INT_MAX) {
- return E_INVALIDARG;
- }
-
- // Get the CSP context and the public key from the certificate
- HCRYPTPROV csp = NULL;
- HCRYPTKEY key = NULL;
- HRESULT hr = certificate_->GetCSPContextAndKey(&csp, &key);
- ASSERT(SUCCEEDED(hr) && csp && key, (L""));
-
- // Hash the data
- CryptDetails::scoped_crypt_hash hash;
- BOOL b = ::CryptCreateHash(csp, kHashAlgorithm, 0, 0, address(hash));
- if (!b) {
- // hash is now invalid, but might not be NULL, so stomp on it
- DWORD err = ::GetLastError();
- ASSERT(!hash, (L""));
- UTIL_LOG(LE, (L"[CrypoVerifySignature::Validate]"
- L"[could not create hash], err 0x%08lx", err));
- return HRESULT_FROM_WIN32(err);
- }
-
- b = ::CryptHashData(get(hash),
- &buffer_in.front(),
- static_cast(buffer_in.size()),
- 0 /*flags*/);
- if (!b) {
- DWORD err = ::GetLastError();
- UTIL_LOG(LE, (L"[CryptoVerifySignature::Validate]"
- L"[could not hash data, err 0x%08lx]", err));
- return HRESULT_FROM_WIN32(err);
- }
-
- // Verify the hash
- b = ::CryptVerifySignature(get(hash),
- &signature_in.front(),
- static_cast(signature_in.size()),
- key,
- NULL,
- 0 /*flags*/);
- if (!b) {
- DWORD err = ::GetLastError();
-#ifdef LOGGING
- CString encoded_signature;
- Base64::Encode(signature_in, &encoded_signature, false);
-
- UTIL_LOG(LE, (_T("CryptoVerifySignature::Validate could not ")
- _T("verify signature, err 0x%08lx with sig \"%s\""),
- err, encoded_signature));
-#endif
- if (err == NTE_BAD_SIGNATURE)
- return SIGS_E_INVALID_SIGNATURE;
- else
- return HRESULT_FROM_WIN32(err);
- }
-
- return S_OK;
-}
-
-HRESULT SignData(const TCHAR* certificate_path,
- const TCHAR* certificate_password,
- const TCHAR* certificate_subject_name,
- const std::vector& data,
- CString* signature_base64) {
- ASSERT(certificate_path, (L""));
- ASSERT(certificate_password, (L""));
- // certificate_subject_name can be NULL
- ASSERT(signature_base64, (L""));
-
- CryptoSigningCertificate certificate;
- RET_IF_FAILED(certificate.ImportCertificate(certificate_path,
- certificate_password,
- certificate_subject_name));
-
- CryptoComputeSignature signer(&certificate);
- std::vector signature;
- RET_IF_FAILED(signer.Sign(data, &signature));
- RET_IF_FAILED(Base64::Encode(signature, signature_base64, false));
-
- return S_OK;
-}
-
-HRESULT VerifyData(const TCHAR* certificate_path,
- const TCHAR* certificate_subject_name,
- const std::vector& data,
- const TCHAR* signature_base64) {
- ASSERT(certificate_path, (L""));
- // certificate_subject_name can be NULL
- ASSERT(signature_base64, (L""));
-
- std::vector signature;
- RET_IF_FAILED(Base64::Decode(CString(signature_base64), &signature));
-
- CryptoSignatureVerificationCertificate certificate;
- RET_IF_FAILED(certificate.ImportCertificate(certificate_path,
- certificate_subject_name));
-
- CryptoVerifySignature verifier(certificate);
- RET_IF_FAILED(verifier.Validate(data, signature));
-
- return S_OK;
-}
-
-HRESULT VerifyData(const std::vector& certificate_buffer,
- const TCHAR* certificate_subject_name,
- const std::vector& data,
- const TCHAR* signature_base64) {
- // certificate_subject_name can be NULL
- ASSERT(signature_base64, (L""));
-
- std::vector signature;
- RET_IF_FAILED(Base64::Decode(CString(signature_base64), &signature));
-
- CryptoSignatureVerificationCertificate certificate;
- RET_IF_FAILED(certificate.ImportCertificate(certificate_buffer,
- certificate_subject_name));
-
- CryptoVerifySignature verifier(certificate);
- RET_IF_FAILED(verifier.Validate(data, signature));
-
- return S_OK;
-}
-
-HRESULT VerifyFileHash(const std::vector& files,
- const CString& expected_hash) {
- ASSERT1(!files.empty());
-
- std::vector hash_vector;
- RET_IF_FAILED(Base64::Decode(expected_hash, &hash_vector));
-
- CryptoHash crypto(CryptoHash::kSha1);
- if (!crypto.IsValidSize(hash_vector.size())) {
- return E_INVALIDARG;
- }
- return crypto.Validate(files, kMaxFileSizeForAuthentication, hash_vector);
-}
-
HRESULT VerifyFileHashSha256(const std::vector& files,
const CString& expected_hash) {
ASSERT1(!files.empty());
@@ -1145,7 +245,7 @@ HRESULT VerifyFileHashSha256(const std::vector& files,
return E_INVALIDARG;
}
- CryptoHash crypto(CryptoHash::kSha256);
+ CryptoHash crypto;
if (!crypto.IsValidSize(hash_vector.size())) {
return E_INVALIDARG;
}
diff --git a/omaha/base/signatures.h b/omaha/base/signatures.h
index 8a5b3f42a..f1c7dc3c1 100644
--- a/omaha/base/signatures.h
+++ b/omaha/base/signatures.h
@@ -27,34 +27,15 @@
#include
#include
#include "base/basictypes.h"
+#include "omaha/base/security/sha256.h"
#include "omaha/third_party/smartany/scoped_any.h"
namespace omaha {
class CryptoHash;
-class CryptoComputeSignature;
-class CryptoVerifySignature;
-class CryptoSigningCertificate;
-class CryptoSignatureVerificationCertificate;
-// Useful scoped pointers for working with CryptoAPI objects
namespace CryptDetails {
-void crypt_close_store(HCERTSTORE);
-void crypt_release_context(HCRYPTPROV);
-void crypt_free_certificate(PCCERT_CONTEXT);
-void crypt_destroy_key(HCRYPTKEY);
-
-typedef close_fun smart_close_store; // NOLINT
-typedef close_fun smart_release_context; // NOLINT
-typedef close_fun smart_free_certificate; // NOLINT
-typedef close_fun smart_destroy_key; // NOLINT
-
-typedef scoped_any scoped_crypt_store; // NOLINT
-typedef scoped_any scoped_crypt_context; // NOLINT
-typedef scoped_any scoped_crypt_cert; // NOLINT
-typedef scoped_any scoped_crypt_key; // NOLINT
-
class HashInterface {
public:
virtual ~HashInterface() {}
@@ -64,52 +45,15 @@ class HashInterface {
virtual size_t hash_size() const = 0;
};
-HashInterface* CreateHasher(bool use_sha256);
+HashInterface* CreateHasher();
} // namespace CryptDetails
-
-// A namespace for encoding binary into base64 (portable ASCII) representation
-// and for decoding it again.
-namespace Base64 {
-
-// Binary -> base64 in a buffer
-HRESULT Encode(const std::vector& buffer_in,
- std::vector* encoded,
- bool break_into_lines = true);
-
-// Binary -> base64 in a string
-HRESULT Encode(const std::vector& buffer_in,
- CStringA* encoded,
- bool break_into_lines = true);
-
-// Binary -> base64 in a wide string
-HRESULT Encode(const std::vector& buffer_in,
- CString* encoded,
- bool break_into_lines = true);
-
-// Base64 in a buffer -> binary
-HRESULT Decode(const std::vector& encoded,
- std::vector* buffer_out);
-
-// Base64 in a CStringA -> binary
-HRESULT Decode(const CStringA& encoded, std::vector* buffer_out);
-
-// Base64 in a CString -> binary
-HRESULT Decode(const CString& encoded, std::vector* buffer_out);
-
-} // namespace Base64
-
-// Compute and validate SHA-1 or SHA256 hashes of data.
+// Compute and validate SHA256 hashes of data.
class CryptoHash {
public:
- enum HashAlgorithm {
- kSha1 = 0,
- kSha256
- };
-
- explicit CryptoHash(HashAlgorithm hash_algorithm);
- ~CryptoHash();
+ CryptoHash() = default;
+ ~CryptoHash() = default;
// Hash a file
HRESULT Compute(const TCHAR * filepath,
@@ -144,7 +88,7 @@ class CryptoHash {
}
size_t hash_size() const {
- return use_sha256_ ? kSha256HashSize : kSha1HashSize;
+ return SHA256_DIGEST_SIZE;
}
private:
@@ -159,167 +103,9 @@ class CryptoHash {
const std::vector* hash_in,
std::vector* hash_out);
- static const size_t kSha1HashSize;
- static const size_t kSha256HashSize;
-
- const bool use_sha256_;
-
DISALLOW_COPY_AND_ASSIGN(CryptoHash);
};
-
-// Import and use a certificate for signing data (has a private key)
-class CryptoSigningCertificate {
- public:
- CryptoSigningCertificate();
- ~CryptoSigningCertificate();
-
- // Import certificate - with both public key and private key.
- // Must be in PFX format. Password must unlock the PFX file.
- // subject_name is the certificate's subject name (who it was
- // issued to) - if not NULL then it is checked for an exact
- // match against the certificate.
-
- // User can get the certificate in PFX format by following the procedure at
- // http://support.globalsign.net/en/objectsign/transform.cfm
-
- HRESULT ImportCertificate(const TCHAR * filepath,
- const TCHAR * password,
- const TCHAR * subject_name);
-
- HRESULT ImportCertificate(const std::vector& certificate_in,
- const TCHAR * password,
- const TCHAR * subject_name);
-
- CString subject_name() { return subject_name_; }
-
- private:
- static const int kMaxCertificateSize = 100000;
-
- CryptDetails::scoped_crypt_store store_;
- CryptDetails::scoped_crypt_cert certificate_;
- CryptDetails::scoped_crypt_context csp_;
- CString subject_name_;
- DWORD key_spec_;
-
- friend class CryptoComputeSignature;
- // Get the CSP with the private key
- // (CryptoSigningCertificate retains ownership of csp_context.)
- HRESULT GetCSPContext(HCRYPTPROV* csp_context);
-
- DISALLOW_COPY_AND_ASSIGN(CryptoSigningCertificate);
-};
-
-
-// Compute digital signatures
-class CryptoComputeSignature {
- public:
- explicit CryptoComputeSignature(CryptoSigningCertificate* certificate);
- ~CryptoComputeSignature();
-
- // Sign a file, returning a separate signature
- HRESULT Sign(const TCHAR * filepath,
- uint32 max_len,
- std::vector* signature_out);
-
- // Sign a chunk of memory, returning a separate signature
- HRESULT Sign(const std::vector& buffer_in,
- std::vector* signature_out);
-
- private:
- // Does not take ownership of the certificate
- CryptoSigningCertificate* const certificate_;
-
- DISALLOW_COPY_AND_ASSIGN(CryptoComputeSignature);
-};
-
-
-// Import and use a certificate for verifying signatures (has public key only)
-class CryptoSignatureVerificationCertificate {
- public:
- CryptoSignatureVerificationCertificate();
- ~CryptoSignatureVerificationCertificate();
-
- // Import certificate - with only public key. Must be in DER (.cer) format.
- // subject_name is the certificate's subject name (who it was
- // issued to) - if not NULL then it is checked for an exact
- // match against the certificate.
-
- // User can get certificate in DER format (.cer) by exporting from
- // certmgr.exe, using openssl, etc.)
-
- HRESULT ImportCertificate(const TCHAR * filepath,
- const TCHAR * subject_name);
- HRESULT ImportCertificate(const std::vector& certificate_in,
- const TCHAR * subject_name);
-
- CString subject_name() { return subject_name_; }
-
- private:
- static const int kMaxCertificateSize = 100000;
-
- CryptDetails::scoped_crypt_cert certificate_;
- CryptDetails::scoped_crypt_context csp_;
- CryptDetails::scoped_crypt_key key_;
- CString subject_name_;
-
- friend class CryptoVerifySignature;
- // Get the CSP and the public key
- // (CryptoSignatureVerificationCertificate retains ownership of csp_context
- // and public_key.)
- HRESULT GetCSPContextAndKey(HCRYPTPROV* csp_context, HCRYPTKEY* public_key);
-
- DISALLOW_COPY_AND_ASSIGN(CryptoSignatureVerificationCertificate);
-};
-
-
-// Verify digital signatures
-class CryptoVerifySignature {
- public:
- explicit CryptoVerifySignature(
- CryptoSignatureVerificationCertificate& certificate); // NOLINT
- ~CryptoVerifySignature();
-
- // Validate signature of a file, signature given separately
- HRESULT Validate(const TCHAR * filepath,
- uint32 max_len,
- const std::vector& signature_in);
-
- // Validate signature of a buffer of data, signature given separately
- HRESULT Validate(const std::vector& buffer_in,
- const std::vector& signature_in);
-
- private:
- // Does not take ownership of the certificate
- CryptoSignatureVerificationCertificate* const certificate_;
-
- DISALLOW_COPY_AND_ASSIGN(CryptoVerifySignature);
-};
-
-// All-in-one routine to sign a chunk of data and return the signature
-// (encoded in base64)
-HRESULT SignData(const TCHAR* certificate_path,
- const TCHAR* certificate_password,
- const TCHAR* certificate_subject_name,
- const std::vector& data,
- CString* signature_base64);
-
-// All-in-one routine to verify the signature of a chunk of data
-HRESULT VerifyData(const TCHAR* certificate_path,
- const TCHAR* certificate_subject_name,
- const std::vector& data,
- const TCHAR* signature_base64);
-
-HRESULT VerifyData(const std::vector& certificate_buffer,
- const TCHAR* certificate_subject_name,
- const std::vector& data,
- const TCHAR* signature_base64);
-
-// Verifies that the files' SHA1 hash is the expected_hash. The hash is
-// base64 encoded.
-HRESULT VerifyFileHash(const std::vector& files,
- const CString& expected_hash);
-
// Verifies that the files' SHA256 hash is the expected_hash. The hash is
// hex-digit encoded.
HRESULT VerifyFileHashSha256(const std::vector& files,
diff --git a/omaha/base/signatures_unittest.cc b/omaha/base/signatures_unittest.cc
index 6031046ea..562ab5402 100644
--- a/omaha/base/signatures_unittest.cc
+++ b/omaha/base/signatures_unittest.cc
@@ -35,30 +35,6 @@ namespace omaha {
namespace {
-struct {
- const char* binary;
- const char* base64;
-} test_data[] = {
- "", "",
- "what", "d2hhdA==",
- "what will print out", "d2hhdCB3aWxsIHByaW50IG91dA==",
- "foobar", "Zm9vYmFy",
- "a man, a plan, a canal: panama!", "YSBtYW4sIGEgcGxhbiwgYSBjYW5hbDogcGFuYW1hIQ==", // NOLINT
-};
-
-// This test data from http://en.wikipedia.org/wiki/SHA-1:
-const struct {
- const char* binary;
- byte hash[20];
-} test_hash[] = {
- "The quick brown fox jumps over the lazy dog",
- 0x2f, 0xd4, 0xe1, 0xc6, 0x7a, 0x2d, 0x28, 0xfc, 0xed, 0x84,
- 0x9e, 0xe1, 0xbb, 0x76, 0xe7, 0x39, 0x1b, 0x93, 0xeb, 0x12,
- "The quick brown fox jumps over the lazy cog",
- 0xde, 0x9f, 0x2c, 0x7f, 0xd2, 0x5e, 0x1b, 0x3a, 0xfa, 0xd3,
- 0xe8, 0x5a, 0x0b, 0xd1, 0x7d, 0x9b, 0x10, 0x0d, 0xb4, 0xb3,
-};
-
// This test data from http://en.wikipedia.org/wiki/SHA-2:
struct {
const char* binary;
@@ -84,46 +60,8 @@ struct {
} // namespace
-TEST(SignaturesTest, Base64) {
- for (size_t i = 0; i != arraysize(test_data); i++) {
- std::vector buffer(strlen(test_data[i].binary));
- if (strlen(test_data[i].binary) != 0) {
- memcpy(&buffer.front(), test_data[i].binary, strlen(test_data[i].binary));
- }
- CStringA test_e;
- ASSERT_SUCCEEDED(Base64::Encode(buffer, &test_e));
- ASSERT_STREQ(test_e, test_data[i].base64);
- std::vector test_d;
- uint32 test_d_written = 0;
- ASSERT_SUCCEEDED(Base64::Decode(test_e, &test_d));
- ASSERT_EQ(test_d.size(), strlen(test_data[i].binary));
- if (strlen(test_data[i].binary) != 0) {
- ASSERT_EQ(0, memcmp(&test_d.front(),
- test_data[i].binary,
- strlen(test_data[i].binary)));
- }
- }
-}
-
-TEST(SignaturesTest, CryptoHash) {
- CryptoHash chash(CryptoHash::kSha1);
- for (size_t i = 0; i != arraysize(test_hash); i++) {
- std::vector buffer(strlen(test_hash[i].binary));
- if (!buffer.empty()) {
- memcpy(&buffer.front(), test_hash[i].binary, strlen(test_hash[i].binary));
- }
- std::vector hash;
- ASSERT_SUCCEEDED(chash.Compute(buffer, &hash));
- ASSERT_EQ(hash.size(), chash.hash_size());
- ASSERT_EQ(0, memcmp(&hash.front(),
- test_hash[i].hash,
- hash.size()));
- ASSERT_SUCCEEDED(chash.Validate(buffer, hash));
- }
-}
-
TEST(SignaturesTest, CryptoHashSha256) {
- CryptoHash chash(CryptoHash::kSha256);
+ CryptoHash chash;
for (size_t i = 0; i != arraysize(test_hash256); i++) {
std::vector buffer(strlen(test_hash256[i].binary));
@@ -142,118 +80,6 @@ TEST(SignaturesTest, CryptoHashSha256) {
}
}
-TEST(SignaturesTest, CreationVerification) {
- CString module_directory = app_util::GetModuleDirectory(NULL);
- ASSERT_FALSE(module_directory.IsEmpty());
- CString directory;
- directory.Format(_T("%s\\unittest_support"), module_directory);
-
- CString encoded_cert_with_private_key_path;
- encoded_cert_with_private_key_path.AppendFormat(
- _T("%s\\certificate-with-private-key.pfx"), directory);
- CString encoded_cert_without_private_key_path;
- encoded_cert_without_private_key_path.AppendFormat(
- _T("%s\\certificate-without-private-key.cer"), directory);
- CString raw_test_data_path;
- raw_test_data_path.AppendFormat(_T("%s\\declaration.txt"), directory);
-
- // Get cert with private key and cert without private key.
- std::vector encoded_cert_with_private_key;
- std::vector encoded_cert_without_private_key;
- ASSERT_SUCCEEDED(ReadEntireFile(encoded_cert_with_private_key_path,
- 0,
- &encoded_cert_with_private_key));
- ASSERT_SUCCEEDED(ReadEntireFile(encoded_cert_without_private_key_path,
- 0,
- &encoded_cert_without_private_key));
- CString cert_password = _T("f00bar");
- CString cert_subject_name = _T("Unofficial Google Test");
-
- // Get testdata.
- std::vector raw_testdata;
- ASSERT_SUCCEEDED(ReadEntireFile(raw_test_data_path, 0, &raw_testdata));
-
- // Create a signing certificate.
- CryptoSigningCertificate signing_certificate;
- ASSERT_SUCCEEDED(signing_certificate.ImportCertificate(
- encoded_cert_with_private_key, cert_password, cert_subject_name));
-
- // Create a signature object and sign the test data.
- std::vector signature;
- CryptoComputeSignature signer(&signing_certificate);
- ASSERT_SUCCEEDED(signer.Sign(raw_testdata, &signature));
-
- // Create a validating certificate.
- CryptoSignatureVerificationCertificate verification_certificate;
- ASSERT_SUCCEEDED(verification_certificate.ImportCertificate(
- encoded_cert_without_private_key, cert_subject_name));
-
- // Create a signature object and verify the test data's signature.
- CryptoVerifySignature verifier(verification_certificate);
- ASSERT_SUCCEEDED(verifier.Validate(raw_testdata, signature));
-
- // Mess up the signature and show it doesn't verify.
- size_t mid = signature.size() / 2;
- byte mid_byte = signature[mid];
- signature[mid] = ~mid_byte;
- ASSERT_FAILED(verifier.Validate(raw_testdata, signature));
-
- // Restore the signature, mess up the test data, and show it doesn't verify.
- signature[mid] = mid_byte;
- mid = raw_testdata.size() / 2;
- mid_byte = raw_testdata[mid];
- raw_testdata[mid] = ~mid_byte;
- ASSERT_FAILED(verifier.Validate(raw_testdata, signature));
-}
-
-TEST(SignaturesTest, VerifyFileHash) {
- const CString executable_path(app_util::GetCurrentModuleDirectory());
-
- const CString source_file1 = ConcatenatePath(
- executable_path,
- _T("unittest_support\\download_cache_test\\")
- _T("{89640431-FE64-4da8-9860-1A1085A60E13}\\gears-win32-opt.msi"));
-
- const CString hash_file1 = _T("ImV9skETZqGFMjs32vbZTvzAYJU=");
-
- const CString source_file2 = ConcatenatePath(
- executable_path,
- _T("unittest_support\\download_cache_test\\")
- _T("{7101D597-3481-4971-AD23-455542964072}\\livelysetup.exe"));
-
- const CString hash_file2 = _T("Igq6bYaeXFJCjH770knXyJ6V53s=");
-
- const CString hash_files = _T("e2uzy96jlusKbADl87zie6F5iwE=");
-
- const CString bad_hash = _T("sFzmoHgCbowEnioqVb8WanTYbhIabcde=");
-
- std::vector files;
-
- // Authenticate one file.
- files.push_back(source_file1);
- EXPECT_HRESULT_SUCCEEDED(VerifyFileHash(files, hash_file1));
-
- // Incorrect hash.
- EXPECT_EQ(SIGS_E_INVALID_SIGNATURE, VerifyFileHash(files, hash_file2));
-
- // Bad hash.
- EXPECT_EQ(E_INVALIDARG, VerifyFileHash(files, bad_hash));
- EXPECT_EQ(E_INVALIDARG, VerifyFileHash(files, _T("")));
-
- // Authenticate two files.
- files.push_back(source_file2);
- EXPECT_HRESULT_SUCCEEDED(VerifyFileHash(files, hash_files));
-
- // Round trip through CryptoHash::Compute to verify the hash of two files.
- CryptoHash crypto(CryptoHash::kSha1);
- std::vector hash_out;
- EXPECT_HRESULT_SUCCEEDED(crypto.Compute(files, 0, &hash_out));
-
- CStringA actual_hash_files;
- EXPECT_HRESULT_SUCCEEDED(Base64::Encode(hash_out, &actual_hash_files));
- EXPECT_STREQ(hash_files, CString(actual_hash_files));
-}
-
TEST(SignaturesTest, VerifyFileHashSha256) {
const CString executable_path(app_util::GetCurrentModuleDirectory());
@@ -293,7 +119,7 @@ TEST(SignaturesTest, VerifyFileHashSha256) {
EXPECT_HRESULT_SUCCEEDED(VerifyFileHashSha256(files, hash_files));
// Round trip through CryptoHash::Compute to verify the hash of two files.
- CryptoHash crypto(CryptoHash::kSha256);
+ CryptoHash crypto;
std::vector hash_out;
EXPECT_HRESULT_SUCCEEDED(crypto.Compute(files, 0, &hash_out));
diff --git a/omaha/base/string.cc b/omaha/base/string.cc
index f8cd8f040..95a0c92db 100644
--- a/omaha/base/string.cc
+++ b/omaha/base/string.cc
@@ -708,12 +708,6 @@ case 2:
#define kWebSafeBase64Chars "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
-int Base64Escape(const char *src, int szsrc, char *dest, int szdest) {
- ASSERT(dest, (L""));
- ASSERT(src, (L""));
-
- return Base64EscapeInternal(src, szsrc, dest, szdest, kBase64Chars, true);
-}
int WebSafeBase64Escape(const char *src, int szsrc, char *dest,
int szdest, bool do_padding) {
ASSERT(dest, (L""));
@@ -995,6 +989,15 @@ int Base64Unescape(const char *src, int len_src, char *dest, int len_dest) {
return Base64UnescapeInternal(src, len_src, dest, len_dest, UnBase64);
}
+int Base64Unescape(const CStringA& src, CStringA* dest) {
+ ASSERT1(dest);
+
+ int len = src.GetLength();
+ int unescape_len = Base64Unescape(src, len, dest->GetBuffer(len + 1), len);
+ dest->ReleaseBufferSetLength(unescape_len >= 0 ? unescape_len : 0);
+ return unescape_len;
+}
+
int WebSafeBase64Unescape(const char *src, int szsrc, char *dest, int szdest) {
ASSERT(dest, (L""));
ASSERT(src, (L""));
@@ -2236,4 +2239,3 @@ bool SafeHexStringToVector(const CStringW& str, std::vector* vec_out) {
}
} // namespace omaha
-
diff --git a/omaha/base/string.h b/omaha/base/string.h
index ad9f1b636..682075640 100644
--- a/omaha/base/string.h
+++ b/omaha/base/string.h
@@ -121,7 +121,6 @@ int CalculateBase64EscapedLen(int input_len);
// to escape them. It also has an extra parameter "do_padding",
// which when set to false will prevent padding with "=".
// ----------------------------------------------------------------------
-int Base64Escape(const char *src, int slen, char *dest, int szdest);
int WebSafeBase64Escape(const char *src, int slen, char *dest,
int szdest, bool do_padding);
void WebSafeBase64Escape(const CStringA& src, CStringA* dest);
@@ -143,6 +142,7 @@ void WebSafeBase64Escape(const char *src, int szsrc,
// destination buffer or -1 in case of a decoding error.
// ----------------------------------------------------------------------
int Base64Unescape(const char *src, int slen, char *dest, int len_dest);
+int Base64Unescape(const CStringA& src, CStringA* dest);
int WebSafeBase64Unescape(const char *src, int slen, char *dest, int szdest);
#ifdef UNICODE
diff --git a/omaha/base/string_unittest.cc b/omaha/base/string_unittest.cc
index 27d7fae0e..0b9686e06 100644
--- a/omaha/base/string_unittest.cc
+++ b/omaha/base/string_unittest.cc
@@ -720,6 +720,38 @@ TEST(StringTest, WideToAnsiDirect) {
}
}
+TEST(StringTest, Base64) {
+ struct {
+ const char* binary;
+ const char* base64;
+ } test_data[] = {
+ "", "",
+ "what", "d2hhdA==",
+ "what will print out", "d2hhdCB3aWxsIHByaW50IG91dA==",
+ "foobar", "Zm9vYmFy",
+ "a man, a plan, a canal: panama!", "YSBtYW4sIGEgcGxhbiwgYSBjYW5hbDogcGFuYW1hIQ==", // NOLINT
+ };
+
+ for (size_t i = 0; i != arraysize(test_data); i++) {
+ CStringA test_e;
+ Base64Escape(test_data[i].binary,
+ strlen(test_data[i].binary),
+ &test_e,
+ true);
+ EXPECT_STREQ(test_e, test_data[i].base64);
+
+ CStringA test_d;
+ ASSERT_GE(Base64Unescape(test_e, &test_d), 0);
+ EXPECT_STREQ(test_d, test_data[i].binary);
+ }
+}
+
+TEST(StringTest, Base64Unescape) {
+ CStringA input("AAAAAAAA");
+ CStringA output;
+ ASSERT_EQ(Base64Unescape(input, &output), input.GetLength() * 3 / 4);
+}
+
TEST(StringTest, TextToLinesAndBack) {
const TCHAR sample_input[] = L"Now is the time\r\nfor all good men\r\nto come to the aid of their country";
const TCHAR* sample_lines[] = { L"Now is the time", L"for all good men", L"to come to the aid of their country" };
diff --git a/omaha/base/utils.h b/omaha/base/utils.h
index 2296009cb..506ae25c7 100644
--- a/omaha/base/utils.h
+++ b/omaha/base/utils.h
@@ -859,6 +859,23 @@ inline bool IsLocalSystemSid(const TCHAR* sid) {
return _tcsicmp(sid, kLocalSystemSid) == 0;
}
+// Returns true if the argument is a uuid. In Microsoft parlance, a UUID is a
+// GUID without the curly braces, as defined by ::UuidFromString().
+inline bool IsUuid(const CString& s) {
+ if (s.IsEmpty()) {
+ return false;
+ }
+
+ // We can use ::UuidFromString() instead of the following code. However,
+ // ::UuidFromString() requires taking a dependency on Rpcrt4.lib, and also
+ // uses NT types such as RPC_STATUS for the return code and RPC_WSTR for the
+ // input string. So this code reuses IsGuid() instead.
+ CString guid(s);
+ guid.Insert(0, _T('{'));
+ guid.AppendChar(_T('}'));
+ return IsGuid(guid);
+}
+
// Deletes an object. The functor is useful in for_each algorithms.
struct DeleteFun {
template void operator()(T ptr) { delete ptr; }
diff --git a/omaha/base/utils_unittest.cc b/omaha/base/utils_unittest.cc
index 00d0e32c1..84662fe4c 100644
--- a/omaha/base/utils_unittest.cc
+++ b/omaha/base/utils_unittest.cc
@@ -16,11 +16,12 @@
#include
#include
#include
+
#include