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

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

Issue 8459001: Extract the certificate to use in the download protection pingback. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Address Noe and Matt's comments 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 <wincrypt.h> 8 #include <wincrypt.h>
9
9 #include "base/file_path.h" 10 #include "base/file_path.h"
11 #include "base/logging.h"
12 #include "base/scoped_ptr.h"
13 #include "crypto/scoped_capi_types.h"
14 #include "chrome/common/safe_browsing/csd.pb.h"
10 15
11 namespace safe_browsing { 16 namespace safe_browsing {
12 namespace signature_util { 17 namespace {
18 using crypto::ScopedCAPIHandle;
19 using crypto::CAPIDestroyer;
20 using crypto::CAPIDestroyerWithFlags;
13 21
14 bool IsSigned(const FilePath& file_path) { 22 // Free functor for scoped_ptr_malloc.
23 class FreeConstCertContext {
24 public:
25 void operator()(const CERT_CONTEXT* cert_context) const {
26 CertFreeCertificateContext(cert_context);
27 }
28 };
29
30 // Tries to extract the signing certificate from |file_path|. On success,
31 // the |certificate_contents| field of |signature_info| is populated with the
32 // DER-encoded X.509 certificate.
33 void GetCertificateContents(
34 const FilePath& file_path,
35 ClientDownloadRequest_SignatureInfo* signature_info) {
36 // Largely based on http://support.microsoft.com/kb/323809
15 // Get message handle and store handle from the signed file. 37 // Get message handle and store handle from the signed file.
16 BOOL result = CryptQueryObject(CERT_QUERY_OBJECT_FILE, 38 typedef CAPIDestroyer<HCRYPTMSG, CryptMsgClose> CryptMsgDestroyer;
17 file_path.value().c_str(), 39 ScopedCAPIHandle<HCRYPTMSG, CryptMsgDestroyer> crypt_msg;
18 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, 40 typedef CAPIDestroyerWithFlags<
19 CERT_QUERY_FORMAT_FLAG_BINARY, 41 HCERTSTORE, CertCloseStore, 0> CertStoreDestroyer;
20 0, // flags 42 ScopedCAPIHandle<HCERTSTORE, CertStoreDestroyer> cert_store;
21 NULL, // encoding 43
22 NULL, // content type 44 VLOG(2) << "Looking for signature in: " << file_path.value();
23 NULL, // format type 45 if (!CryptQueryObject(CERT_QUERY_OBJECT_FILE,
24 NULL, // HCERTSTORE 46 file_path.value().c_str(),
25 NULL, // HCRYPTMSG 47 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
26 NULL); // context 48 CERT_QUERY_FORMAT_FLAG_BINARY,
27 return result == TRUE; 49 0, // flags
50 NULL, // encoding
51 NULL, // content type
52 NULL, // format type
53 cert_store.receive(),
54 crypt_msg.receive(),
55 NULL)) { // context
56 VLOG(2) << "No signature found.";
57 return;
58 }
59
60 // Get the signer information size.
61 DWORD signer_info_size;
62 if (!CryptMsgGetParam(crypt_msg.get(),
63 CMSG_SIGNER_INFO_PARAM,
64 0, // index
65 NULL, // no buffer when checking the size
66 &signer_info_size)) {
67 VLOG(2) << "Failed to get signer info size";
68 return;
69 }
70
71 // Get the signer information.
72 scoped_array<BYTE> signer_info_buffer(new BYTE[signer_info_size]);
73 CMSG_SIGNER_INFO* signer_info =
74 reinterpret_cast<CMSG_SIGNER_INFO*>(signer_info_buffer.get());
75 if (!CryptMsgGetParam(crypt_msg.get(),
76 CMSG_SIGNER_INFO_PARAM,
77 0, // index
78 signer_info,
79 &signer_info_size)) {
80 VLOG(2) << "Failed to get signer info";
81 return;
82 }
83
84 // Search for the signer certificate in the temporary certificate store.
85 CERT_INFO cert_info;
86 cert_info.Issuer = signer_info->Issuer;
87 cert_info.SerialNumber = signer_info->SerialNumber;
88
89 scoped_ptr_malloc<const CERT_CONTEXT, FreeConstCertContext> cert_context(
90 CertFindCertificateInStore(
91 cert_store.get(),
92 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
93 0, // flags
94 CERT_FIND_SUBJECT_CERT,
95 &cert_info,
96 NULL)); // no previous context
97 if (!cert_context.get()) {
98 VLOG(2) << "Failed to get CERT_CONTEXT";
99 return;
100 }
101
102 signature_info->set_certificate_contents(cert_context->pbCertEncoded,
103 cert_context->cbCertEncoded);
104 VLOG(2) << "Successfully extracted cert";
105 }
106 } // namespace
107
108 SignatureUtil::SignatureUtil() {}
109
110 SignatureUtil::~SignatureUtil() {}
111
112 void SignatureUtil::CheckSignature(
113 const FilePath& file_path,
114 ClientDownloadRequest_SignatureInfo* signature_info) {
115 GetCertificateContents(file_path, signature_info);
116 // TODO(bryner): Populate is_trusted.
28 } 117 }
29 118
30 } // namespace signature_util
31 } // namespace safe_browsing 119 } // namespace safe_browsing
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/signature_util_posix.cc ('k') | chrome/browser/safe_browsing/signature_util_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698