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
3 // found in the LICENSE file.
5 #include "chrome/browser/safe_browsing/signature_util.h"
11 #include "base/files/file_path.h"
12 #include "base/logging.h"
13 #include "chrome/common/safe_browsing/csd.pb.h"
15 #pragma comment(lib, "wintrust.lib")
17 namespace safe_browsing
{
19 SignatureUtil::SignatureUtil() {}
21 SignatureUtil::~SignatureUtil() {}
23 void SignatureUtil::CheckSignature(
24 const base::FilePath
& file_path
,
25 ClientDownloadRequest_SignatureInfo
* signature_info
) {
26 VLOG(2) << "Checking signature for " << file_path
.value();
28 WINTRUST_FILE_INFO file_info
= {0};
29 file_info
.cbStruct
= sizeof(file_info
);
30 file_info
.pcwszFilePath
= file_path
.value().c_str();
31 file_info
.hFile
= NULL
;
32 file_info
.pgKnownSubject
= NULL
;
34 WINTRUST_DATA wintrust_data
= {0};
35 wintrust_data
.cbStruct
= sizeof(wintrust_data
);
36 wintrust_data
.pPolicyCallbackData
= NULL
;
37 wintrust_data
.pSIPClientData
= NULL
;
38 wintrust_data
.dwUIChoice
= WTD_UI_NONE
;
39 wintrust_data
.fdwRevocationChecks
= WTD_REVOKE_NONE
;
40 wintrust_data
.dwUnionChoice
= WTD_CHOICE_FILE
;
41 wintrust_data
.pFile
= &file_info
;
42 wintrust_data
.dwStateAction
= WTD_STATEACTION_VERIFY
;
43 wintrust_data
.hWVTStateData
= NULL
;
44 wintrust_data
.pwszURLReference
= NULL
;
45 // Disallow revocation checks over the network.
46 wintrust_data
.dwProvFlags
= WTD_CACHE_ONLY_URL_RETRIEVAL
;
47 wintrust_data
.dwUIContext
= WTD_UICONTEXT_EXECUTE
;
49 // The WINTRUST_ACTION_GENERIC_VERIFY_V2 policy verifies that the certificate
50 // chains up to a trusted root CA, and that it has appropriate permission to
52 GUID policy_guid
= WINTRUST_ACTION_GENERIC_VERIFY_V2
;
54 LONG result
= WinVerifyTrust(static_cast<HWND
>(INVALID_HANDLE_VALUE
),
58 CRYPT_PROVIDER_DATA
* prov_data
= WTHelperProvDataFromStateData(
59 wintrust_data
.hWVTStateData
);
61 if (prov_data
->csSigners
> 0) {
62 signature_info
->set_trusted(result
== ERROR_SUCCESS
);
64 for (DWORD i
= 0; i
< prov_data
->csSigners
; ++i
) {
65 const CERT_CHAIN_CONTEXT
* cert_chain_context
=
66 prov_data
->pasSigners
[i
].pChainContext
;
67 if (!cert_chain_context
)
69 for (DWORD j
= 0; j
< cert_chain_context
->cChain
; ++j
) {
70 CERT_SIMPLE_CHAIN
* simple_chain
= cert_chain_context
->rgpChain
[j
];
71 ClientDownloadRequest_CertificateChain
* chain
=
72 signature_info
->add_certificate_chain();
75 for (DWORD k
= 0; k
< simple_chain
->cElement
; ++k
) {
76 CERT_CHAIN_ELEMENT
* element
= simple_chain
->rgpElement
[k
];
77 chain
->add_element()->set_certificate(
78 element
->pCertContext
->pbCertEncoded
,
79 element
->pCertContext
->cbCertEncoded
);
84 // Free the provider data.
85 wintrust_data
.dwStateAction
= WTD_STATEACTION_CLOSE
;
86 WinVerifyTrust(static_cast<HWND
>(INVALID_HANDLE_VALUE
),
87 &policy_guid
, &wintrust_data
);
91 } // namespace safe_browsing