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

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

Powered by Google App Engine
This is Rietveld 408576698