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

Side by Side Diff: chrome/browser/safe_browsing/signature_util_win.cc

Issue 8536035: Include the full certificate chain in the download pingback. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/safe_browsing/signature_util.h" 5 #include "chrome/browser/safe_browsing/signature_util.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <softpub.h> 8 #include <softpub.h>
9 #include <wincrypt.h> 9 #include <wincrypt.h>
10 #include <wintrust.h> 10 #include <wintrust.h>
11 11
12 #include "base/file_path.h" 12 #include "base/file_path.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/scoped_ptr.h" 14 #include "base/scoped_ptr.h"
15 #include "crypto/scoped_capi_types.h" 15 #include "crypto/scoped_capi_types.h"
16 #include "chrome/common/safe_browsing/csd.pb.h" 16 #include "chrome/common/safe_browsing/csd.pb.h"
17 17
18 #pragma comment(lib, "crypt32.lib") 18 #pragma comment(lib, "crypt32.lib")
19 #pragma comment(lib, "wintrust.lib") 19 #pragma comment(lib, "wintrust.lib")
20 20
21 namespace safe_browsing { 21 namespace safe_browsing {
22 namespace { 22 namespace {
23 using crypto::ScopedCAPIHandle; 23 using crypto::ScopedCAPIHandle;
24 using crypto::CAPIDestroyer; 24 using crypto::CAPIDestroyer;
25 using crypto::CAPIDestroyerWithFlags; 25 using crypto::CAPIDestroyerWithFlags;
26 26
27 // Free functor for scoped_ptr_malloc. 27 // Free functors for scoped_ptr_malloc.
28 class FreeConstCertContext { 28 class FreeConstCertContext {
29 public: 29 public:
30 void operator()(const CERT_CONTEXT* cert_context) const { 30 void operator()(const CERT_CONTEXT* cert_context) const {
31 CertFreeCertificateContext(cert_context); 31 if (cert_context) {
32 CertFreeCertificateContext(cert_context);
33 }
34 }
35 };
36
37 class FreeConstCertChainContext {
38 public:
39 void operator()(const CERT_CHAIN_CONTEXT* cert_chain_context) const {
40 if (cert_chain_context) {
41 CertFreeCertificateChain(cert_chain_context);
42 }
32 } 43 }
33 }; 44 };
34 45
35 // Tries to extract the signing certificate from |file_path|. On success, 46 // Tries to extract the signing certificate from |file_path|. On success,
36 // the |certificate_contents| field of |signature_info| is populated with the 47 // the |certificate_contents| field of |signature_info| is populated with the
37 // DER-encoded X.509 certificate. 48 // DER-encoded X.509 certificate.
38 void GetCertificateContents( 49 void GetCertificateContents(
39 const FilePath& file_path, 50 const FilePath& file_path,
40 ClientDownloadRequest_SignatureInfo* signature_info) { 51 ClientDownloadRequest_SignatureInfo* signature_info) {
41 // Largely based on http://support.microsoft.com/kb/323809 52 // Largely based on http://support.microsoft.com/kb/323809
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 108 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
98 0, // flags 109 0, // flags
99 CERT_FIND_SUBJECT_CERT, 110 CERT_FIND_SUBJECT_CERT,
100 &cert_info, 111 &cert_info,
101 NULL)); // no previous context 112 NULL)); // no previous context
102 if (!cert_context.get()) { 113 if (!cert_context.get()) {
103 VLOG(2) << "Failed to get CERT_CONTEXT"; 114 VLOG(2) << "Failed to get CERT_CONTEXT";
104 return; 115 return;
105 } 116 }
106 117
107 signature_info->set_certificate_contents(cert_context->pbCertEncoded, 118 // Follow the chain of certificates to a trusted root.
108 cert_context->cbCertEncoded); 119 CERT_CHAIN_PARA cert_chain_params;
109 VLOG(2) << "Successfully extracted cert"; 120 memset(&cert_chain_params, 0, sizeof(cert_chain_params));
121 cert_chain_params.cbSize = sizeof(cert_chain_params);
122
123 const CERT_CHAIN_CONTEXT* cert_chain_context = NULL;
124 if (!CertGetCertificateChain(NULL, // default chain engine
125 cert_context.get(),
126 // TODO(bryner): should this verify at the
127 // executable's embedded timestamp?
128 NULL, // verify at the current time
129 NULL, // no additional store
130 &cert_chain_params,
131 0, // default flags
132 NULL, // reserved parameter
133 &cert_chain_context)) {
134 VLOG(2) << "Failed to get certificate chain.";
135 return;
136 }
137
138 typedef scoped_ptr_malloc<const CERT_CHAIN_CONTEXT,
139 FreeConstCertChainContext> ScopedCertChainContext;
140 ScopedCertChainContext scoped_cert_chain_context(cert_chain_context);
141 for (size_t i = 0; i < cert_chain_context->cChain; ++i) {
142 CERT_SIMPLE_CHAIN* simple_chain = cert_chain_context->rgpChain[i];
143 ClientDownloadRequest_CertificateChain* chain =
144 signature_info->add_certificate_chain();
145 for (size_t j = 0; j < simple_chain->cElement; ++j) {
146 CERT_CHAIN_ELEMENT* element = simple_chain->rgpElement[j];
147 chain->add_element()->set_certificate(
148 element->pCertContext->pbCertEncoded,
149 element->pCertContext->cbCertEncoded);
150 }
151 }
110 } 152 }
111 153
112 bool CheckTrust(const FilePath& file_path) { 154 bool CheckTrust(const FilePath& file_path) {
113 WINTRUST_FILE_INFO file_info; 155 WINTRUST_FILE_INFO file_info;
114 file_info.cbStruct = sizeof(file_info); 156 file_info.cbStruct = sizeof(file_info);
115 file_info.pcwszFilePath = file_path.value().c_str(); 157 file_info.pcwszFilePath = file_path.value().c_str();
116 file_info.hFile = NULL; 158 file_info.hFile = NULL;
117 file_info.pgKnownSubject = NULL; 159 file_info.pgKnownSubject = NULL;
118 160
119 WINTRUST_DATA wintrust_data; 161 WINTRUST_DATA wintrust_data;
120 wintrust_data.cbStruct = sizeof(wintrust_data); 162 wintrust_data.cbStruct = sizeof(wintrust_data);
121 wintrust_data.pPolicyCallbackData = NULL; 163 wintrust_data.pPolicyCallbackData = NULL;
122 wintrust_data.pSIPClientData = NULL; 164 wintrust_data.pSIPClientData = NULL;
123 wintrust_data.dwUIChoice = WTD_UI_NONE; 165 wintrust_data.dwUIChoice = WTD_UI_NONE;
124 wintrust_data.fdwRevocationChecks = WTD_REVOKE_NONE; 166 wintrust_data.fdwRevocationChecks = WTD_REVOKE_NONE;
125 wintrust_data.dwUnionChoice = WTD_CHOICE_FILE; 167 wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
126 wintrust_data.pFile = &file_info; 168 wintrust_data.pFile = &file_info;
127 wintrust_data.dwStateAction = WTD_STATEACTION_IGNORE; 169 wintrust_data.dwStateAction = WTD_STATEACTION_IGNORE;
Ryan Sleevi 2011/11/12 22:06:17 FWIW, you could save yourself the chain extraction
128 wintrust_data.hWVTStateData = NULL; 170 wintrust_data.hWVTStateData = NULL;
129 wintrust_data.pwszURLReference = NULL; 171 wintrust_data.pwszURLReference = NULL;
130 wintrust_data.dwProvFlags = 0; // don't set any flags 172 wintrust_data.dwProvFlags = 0; // don't set any flags
131 wintrust_data.dwUIContext = WTD_UICONTEXT_EXECUTE; 173 wintrust_data.dwUIContext = WTD_UICONTEXT_EXECUTE;
132 174
133 // The WINTRUST_ACTION_GENERIC_VERIFY_V2 policy verifies that the certificate 175 // The WINTRUST_ACTION_GENERIC_VERIFY_V2 policy verifies that the certificate
134 // chains up to a trusted root CA, and that it has appropriate permission to 176 // chains up to a trusted root CA, and that it has appropriate permission to
135 // sign code. 177 // sign code.
136 GUID policy_guid = WINTRUST_ACTION_GENERIC_VERIFY_V2; 178 GUID policy_guid = WINTRUST_ACTION_GENERIC_VERIFY_V2;
137 179
138 return (WinVerifyTrust(static_cast<HWND>(INVALID_HANDLE_VALUE), 180 return (WinVerifyTrust(static_cast<HWND>(INVALID_HANDLE_VALUE),
139 &policy_guid, 181 &policy_guid,
140 &wintrust_data) == ERROR_SUCCESS); 182 &wintrust_data) == ERROR_SUCCESS);
141 } 183 }
142 } // namespace 184 } // namespace
143 185
144 SignatureUtil::SignatureUtil() {} 186 SignatureUtil::SignatureUtil() {}
145 187
146 SignatureUtil::~SignatureUtil() {} 188 SignatureUtil::~SignatureUtil() {}
147 189
148 void SignatureUtil::CheckSignature( 190 void SignatureUtil::CheckSignature(
149 const FilePath& file_path, 191 const FilePath& file_path,
150 ClientDownloadRequest_SignatureInfo* signature_info) { 192 ClientDownloadRequest_SignatureInfo* signature_info) {
151 GetCertificateContents(file_path, signature_info); 193 GetCertificateContents(file_path, signature_info);
152 signature_info->set_trusted(CheckTrust(file_path)); 194 signature_info->set_trusted(CheckTrust(file_path));
153 } 195 }
154 196
155 } // namespace safe_browsing 197 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698