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