Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Unified Diff: third_party/omaha/src/base/extractor.cc

Issue 423293004: Move app_installer into chromium. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« third_party/omaha/omaha.gyp ('K') | « third_party/omaha/src/base/extractor.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/omaha/src/base/extractor.cc
diff --git a/third_party/omaha/src/base/extractor.cc b/third_party/omaha/src/base/extractor.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4fca55d00ed7979004bdf1c3fc201e427e3909a1
--- /dev/null
+++ b/third_party/omaha/src/base/extractor.cc
@@ -0,0 +1,257 @@
+// 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 "extractor.h"
+
+#include <windows.h>
+#include <wintrust.h>
+#include <crtdbg.h>
+#pragma warning(push)
+// C4100: unreferenced formal parameter
+// C4310: cast truncates constant value
+// C4548: expression before comma has no effect
+#pragma warning(disable : 4100 4310 4548)
+#include "base/basictypes.h"
+#pragma warning(pop)
+
+namespace omaha {
+
+#define AFFILIATE_ID_MAGIC "Gact"
+
+TagExtractor::TagExtractor()
+ : file_handle_(INVALID_HANDLE_VALUE),
+ file_mapping_(NULL),
+ file_base_(NULL),
+ file_length_(0),
+ cert_length_(0),
+ cert_dir_base_(NULL) {
+}
+
+TagExtractor::~TagExtractor() {
+ CloseFile();
+}
+
+bool TagExtractor::OpenFile(const TCHAR* filename) {
+ CloseFile();
+ file_handle_ = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (IsFileOpen()) {
+ file_mapping_ = CreateFileMapping(file_handle_, NULL, PAGE_READONLY,
+ 0, 0, NULL);
+ if (file_mapping_ != NULL) {
+ file_base_ = MapViewOfFile(file_mapping_, FILE_MAP_READ, 0, 0, 0);
+ if (file_base_ != NULL) {
+ MEMORY_BASIC_INFORMATION info = {0};
+ if (::VirtualQuery(file_base_, &info, sizeof(info))) {
+ file_length_ = info.RegionSize;
+ return true;
+ }
+ }
+ CloseHandle(file_mapping_);
+ }
+ CloseFile();
+ }
+ return false;
+}
+
+bool TagExtractor::IsFileOpen() const {
+ return file_handle_ != INVALID_HANDLE_VALUE;
+}
+
+void TagExtractor::CloseFile() {
+ if (file_base_ != NULL) {
+ UnmapViewOfFile(file_base_);
+ file_base_ = NULL;
+ }
+ if (file_mapping_ != NULL) {
+ CloseHandle(file_mapping_);
+ file_mapping_ = NULL;
+ }
+ if (IsFileOpen()) {
+ CloseHandle(file_handle_);
+ file_handle_ = INVALID_HANDLE_VALUE;
+ }
+}
+
+bool TagExtractor::ExtractTag(const char* binary_file,
+ size_t binary_file_length,
+ char* tag_buffer,
+ int* tag_buffer_len) {
+ file_length_ = binary_file_length;
+ return InternalExtractTag(binary_file, tag_buffer, tag_buffer_len);
+}
+
+bool TagExtractor::ExtractTag(char* tag_buffer, int* tag_buffer_len) {
+ if (tag_buffer_len == NULL) {
+ return false;
+ }
+ if (!IsFileOpen()) {
+ return false;
+ }
+
+ return InternalExtractTag(static_cast<char*>(file_base_),
+ tag_buffer,
+ tag_buffer_len);
+}
+
+bool TagExtractor::InternalReadCertificate(const char* file_buffer) {
+ if (!file_buffer) {
+ return false;
+ }
+
+ const void* certificate_directory_pointer =
+ GetCertificateDirectoryPointer(file_buffer);
+ if (NULL == certificate_directory_pointer) {
+ return false;
+ }
+ const void* asn1_signature_pointer =
+ GetASN1SignaturePointer(certificate_directory_pointer);
+ if (NULL == asn1_signature_pointer) {
+ return false;
+ }
+ DWORD asn1_signature_length =
+ GetASN1SignatureLength(asn1_signature_pointer);
+ if (0 == asn1_signature_length) {
+ return false;
+ }
+
+ cert_length_ = asn1_signature_length;
+ cert_dir_base_ = certificate_directory_pointer;
+
+ return true;
+}
+
+bool TagExtractor::InternalExtractTag(const char* file_buffer,
+ char* tag_buffer,
+ int* tag_buffer_len) {
+ if (!file_buffer) {
+ return false;
+ }
+
+ if (!InternalReadCertificate(file_buffer)) {
+ return false;
+ }
+
+ const char* read_base = static_cast<const char*>(cert_dir_base_) +
+ cert_length_;
+ if (read_base >= file_buffer + file_length_) {
+ // The file is not tagged.
+ return false;
+ }
+
+ return ReadTag(read_base, tag_buffer, tag_buffer_len);
+}
+
+bool TagExtractor::ReadTag(const char* tag_pointer,
+ char* tag_buffer,
+ int* tag_buffer_len) const {
+ int mc = memcmp(tag_pointer,
+ AFFILIATE_ID_MAGIC,
+ arraysize(AFFILIATE_ID_MAGIC) - 1);
+ if (0 != mc) {
+ return false;
+ }
+ tag_pointer += arraysize(AFFILIATE_ID_MAGIC) - 1;
+
+ uint16 id_len = 0;
+ const unsigned char* id_len_serialized =
+ reinterpret_cast<const unsigned char*>(tag_pointer);
+ id_len = id_len_serialized[0] << 8;
+ // unsigned char and uint16 get promoted to int.
+ id_len = static_cast<uint16>(id_len + id_len_serialized[1]);
+
+ int buffer_size_required = id_len + 1;
+ if (tag_buffer == NULL) {
+ *tag_buffer_len = buffer_size_required;
+ return true;
+ }
+ if (*tag_buffer_len < buffer_size_required) {
+ return false;
+ }
+ tag_pointer += sizeof(id_len);
+ memcpy(tag_buffer, tag_pointer, id_len);
+ tag_buffer[id_len] = '\0';
+ return true;
+}
+
+const void* TagExtractor::GetCertificateDirectoryPointer(
+ const void* base) const {
+ const char* image_base = reinterpret_cast<const char*>(base);
+
+ // Is this a PEF?
+ const IMAGE_DOS_HEADER* dos_header =
+ reinterpret_cast<const IMAGE_DOS_HEADER *>(image_base);
+ if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) {
+ return NULL;
+ }
+
+ // Get PE header.
+ const IMAGE_NT_HEADERS* nt_headers = reinterpret_cast<const IMAGE_NT_HEADERS*>
+ (image_base + dos_header->e_lfanew);
+
+ // Again, is this a PEF? This code should get an F for not being endian-
+ // safe, but it gets an A for working in the real world.
+ if (nt_headers->Signature != IMAGE_NT_SIGNATURE) {
+ return NULL;
+ }
+
+ const IMAGE_DATA_DIRECTORY* idd =
+ reinterpret_cast<const IMAGE_DATA_DIRECTORY *>
+ (&nt_headers->
+ OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY]);
+ if (idd->VirtualAddress != NULL) {
+ return image_base + idd->VirtualAddress;
+ }
+ return NULL;
+}
+
+const void* TagExtractor::GetASN1SignaturePointer(const void* base) const {
+ const WIN_CERTIFICATE* cert =
+ reinterpret_cast<const WIN_CERTIFICATE *>(base);
+ return cert->bCertificate;
+}
+
+int TagExtractor::GetASN1SignatureLength(const void* base) const {
+ const unsigned char* sig_base =
+ reinterpret_cast<const unsigned char*>(base);
+
+ // No, this isn't a full ASN.1 parser. We're just doing the very bare
+ // minimum to extract a length.
+ if (*sig_base++ == 0x30 && *sig_base++ == 0x82) {
+ int len = (*sig_base++ << 8);
+ len += *sig_base++;
+ // Windows pads the certificate directory to align at a 8-byte boundary.
+ // This piece of code it trying to replicate the logic that is used to
+ // calculate the padding to be added to the certificate. It returns
+ // the entire length of the certificate directory from the windows
+ // certificate directory start to the end of padding.
+ // The windows certificate directory has the following structure
+ // <WIN_CERTIFICATE><Certificate><Padding>.
+ // WIN_CERTIFICATE is the windows certificate directory structure.
+ // <Certificate> has the following format:
+ // <Magic(2 bytes)><Cert length(2 bytes)><Certificate Data>
+ // Note that the "Cert length" does not include the magic bytes or
+ // the length.
+ //
+ // Hence the total length of the certificate is:
+ // cert_length + "WIN_CERTIFICATE header size" + magic + length
+ // + padding = (cert length + 8 + 2 + 2 + 7) & (0-8)
+ return (len + 8 + 2 + 2 + 7) & 0xffffff8;
+ }
+ return 0;
+}
+
+} // namespace omaha
+
« third_party/omaha/omaha.gyp ('K') | « third_party/omaha/src/base/extractor.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698