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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/safe_browsing/signature_util_win.cc
===================================================================
--- chrome/browser/safe_browsing/signature_util_win.cc (revision 108613)
+++ chrome/browser/safe_browsing/signature_util_win.cc (working copy)
@@ -6,26 +6,114 @@
#include <windows.h>
#include <wincrypt.h>
+
#include "base/file_path.h"
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "crypto/scoped_capi_types.h"
+#include "chrome/common/safe_browsing/csd.pb.h"
namespace safe_browsing {
-namespace signature_util {
+namespace {
+using crypto::ScopedCAPIHandle;
+using crypto::CAPIDestroyer;
+using crypto::CAPIDestroyerWithFlags;
-bool IsSigned(const FilePath& file_path) {
+// Free functor for scoped_ptr_malloc.
+class FreeConstCertContext {
+ public:
+ void operator()(const CERT_CONTEXT* cert_context) const {
+ CertFreeCertificateContext(cert_context);
+ }
+};
+
+// Tries to extract the signing certificate from |file_path|. On success,
+// the |certificate_contents| field of |signature_info| is populated with the
+// DER-encoded X.509 certificate.
+void GetCertificateContents(
+ const FilePath& file_path,
+ ClientDownloadRequest_SignatureInfo* signature_info) {
+ // Largely based on http://support.microsoft.com/kb/323809
// Get message handle and store handle from the signed file.
- BOOL result = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
- file_path.value().c_str(),
- CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
- CERT_QUERY_FORMAT_FLAG_BINARY,
- 0, // flags
- NULL, // encoding
- NULL, // content type
- NULL, // format type
- NULL, // HCERTSTORE
- NULL, // HCRYPTMSG
- NULL); // context
- return result == TRUE;
+ typedef CAPIDestroyer<HCRYPTMSG, CryptMsgClose> CryptMsgDestroyer;
+ ScopedCAPIHandle<HCRYPTMSG, CryptMsgDestroyer> crypt_msg;
+ typedef CAPIDestroyerWithFlags<
+ HCERTSTORE, CertCloseStore, 0> CertStoreDestroyer;
+ ScopedCAPIHandle<HCERTSTORE, CertStoreDestroyer> cert_store;
+
+ VLOG(2) << "Looking for signature in: " << file_path.value();
+ if (!CryptQueryObject(CERT_QUERY_OBJECT_FILE,
+ file_path.value().c_str(),
+ CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
+ CERT_QUERY_FORMAT_FLAG_BINARY,
+ 0, // flags
+ NULL, // encoding
+ NULL, // content type
+ NULL, // format type
+ cert_store.receive(),
+ crypt_msg.receive(),
+ NULL)) { // context
+ VLOG(2) << "No signature found.";
+ return;
+ }
+
+ // Get the signer information size.
+ DWORD signer_info_size;
+ if (!CryptMsgGetParam(crypt_msg.get(),
+ CMSG_SIGNER_INFO_PARAM,
+ 0, // index
+ NULL, // no buffer when checking the size
+ &signer_info_size)) {
+ VLOG(2) << "Failed to get signer info size";
+ return;
+ }
+
+ // Get the signer information.
+ scoped_array<BYTE> signer_info_buffer(new BYTE[signer_info_size]);
+ CMSG_SIGNER_INFO* signer_info =
+ reinterpret_cast<CMSG_SIGNER_INFO*>(signer_info_buffer.get());
+ if (!CryptMsgGetParam(crypt_msg.get(),
+ CMSG_SIGNER_INFO_PARAM,
+ 0, // index
+ signer_info,
+ &signer_info_size)) {
+ VLOG(2) << "Failed to get signer info";
+ return;
+ }
+
+ // Search for the signer certificate in the temporary certificate store.
+ CERT_INFO cert_info;
+ cert_info.Issuer = signer_info->Issuer;
+ cert_info.SerialNumber = signer_info->SerialNumber;
+
+ scoped_ptr_malloc<const CERT_CONTEXT, FreeConstCertContext> cert_context(
+ CertFindCertificateInStore(
+ cert_store.get(),
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ 0, // flags
+ CERT_FIND_SUBJECT_CERT,
+ &cert_info,
+ NULL)); // no previous context
+ if (!cert_context.get()) {
+ VLOG(2) << "Failed to get CERT_CONTEXT";
+ return;
+ }
+
+ signature_info->set_certificate_contents(cert_context->pbCertEncoded,
+ cert_context->cbCertEncoded);
+ VLOG(2) << "Successfully extracted cert";
}
+} // namespace
-} // namespace signature_util
+SignatureUtil::SignatureUtil() {}
+
+SignatureUtil::~SignatureUtil() {}
+
+void SignatureUtil::CheckSignature(
+ const FilePath& file_path,
+ ClientDownloadRequest_SignatureInfo* signature_info) {
+ GetCertificateContents(file_path, signature_info);
+ // TODO(bryner): Populate is_trusted.
+}
+
} // namespace safe_browsing
« 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