content_verify_job.h revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file.
4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#ifndef EXTENSIONS_BROWSER_CONTENT_VERIFY_JOB_H_
6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#define EXTENSIONS_BROWSER_CONTENT_VERIFY_JOB_H_
7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <string>
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/callback.h"
11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/memory/ref_counted.h"
12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/threading/thread_checker.h"
14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace base {
16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class FilePath;
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace crypto {
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class SecureHash;
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace extensions {
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class ContentHashReader;
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Objects of this class are responsible for verifying that the actual content
28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// read from an extension file matches an expected set of hashes. This class
29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// can be created on any thread but the rest of the methods should be called
30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// from only one thread.
31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class ContentVerifyJob : public base::RefCountedThreadSafe<ContentVerifyJob> {
32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public:
33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  enum FailureReason {
34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // No failure.
35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    NONE,
36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Failed because there were no expected hashes.
38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    NO_HASHES,
39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Some of the content read did not match the expected hash.
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    HASH_MISMATCH
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  };
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  typedef base::Callback<void(FailureReason)> FailureCallback;
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // The |failure_callback| will be called at most once if there was a failure.
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ContentVerifyJob(ContentHashReader* hash_reader,
47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                   const FailureCallback& failure_callback);
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // This begins the process of getting expected hashes, so it should be called
50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // as early as possible.
51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void Start();
52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Call this to add more bytes to verify. If at any point the read bytes
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // don't match the expected hashes, this will dispatch the failure
55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // callback. The failure callback will only be run once even if more bytes
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // are read. Make sure to call DoneReading so that any final bytes that were
57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // read that didn't align exactly on a block size boundary get their hash
58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // checked as well.
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void BytesRead(int count, const char* data);
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Call once when finished adding bytes via BytesRead.
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void DoneReading();
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  class TestDelegate {
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)   public:
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // These methods will be called inside BytesRead/DoneReading respectively.
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // If either return something other than NONE, then the failure callback
68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // will be dispatched with that reason.
69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    virtual FailureReason BytesRead(const std::string& extension_id,
70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                    int count,
71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                    const char* data) = 0;
72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    virtual FailureReason DoneReading(const std::string& extension_id) = 0;
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  };
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  static void SetDelegateForTests(TestDelegate* delegate);
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private:
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ContentVerifyJob);
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual ~ContentVerifyJob();
81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  friend class base::RefCountedThreadSafe<ContentVerifyJob>;
82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Called each time we're done adding bytes for the current block, and are
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // ready to finish the hash operation for those bytes and make sure it matches
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // what was expected for that block.
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void FinishBlock();
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Dispatches the failure callback with the given reason.
89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void DispatchFailureCallback(FailureReason reason);
90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Called when our ContentHashReader has finished initializing.
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void OnHashesReady(bool success);
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Indicates whether the caller has told us they are done calling BytesRead.
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool done_reading_;
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Set to true once hash_reader_ has read its expected hashes.
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool hashes_ready_;
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // While we're waiting for the callback from the ContentHashReader, we need
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // to queue up bytes any bytes that are read.
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string queue_;
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The total bytes we've read.
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int64 total_bytes_read_;
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The index of the block we're currently on.
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int current_block_;
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The hash we're building up for the bytes of |current_block_|.
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<crypto::SecureHash> current_hash_;
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The number of bytes we've already input into |current_hash_|.
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int current_hash_byte_count_;
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<ContentHashReader> hash_reader_;
117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Called once if verification fails.
119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  FailureCallback failure_callback_;
120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // For ensuring methods on called on the right thread.
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::ThreadChecker thread_checker_;
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)};
124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace extensions
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif  // EXTENSIONS_BROWSER_CONTENT_VERIFY_JOB_H_
128