Home | History | Annotate | Download | only in common
      1 //
      2 // Copyright (C) 2009 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #ifndef UPDATE_ENGINE_COMMON_HASH_CALCULATOR_H_
     18 #define UPDATE_ENGINE_COMMON_HASH_CALCULATOR_H_
     19 
     20 #include <openssl/sha.h>
     21 #include <unistd.h>
     22 
     23 #include <string>
     24 #include <vector>
     25 
     26 #include <base/logging.h>
     27 #include <base/macros.h>
     28 #include <brillo/secure_blob.h>
     29 
     30 // Omaha uses base64 encoded SHA-256 as the hash. This class provides a simple
     31 // wrapper around OpenSSL providing such a formatted hash of data passed in.
     32 // The methods of this class must be called in a very specific order: First the
     33 // ctor (of course), then 0 or more calls to Update(), then Finalize(), then 0
     34 // or more calls to hash().
     35 
     36 namespace chromeos_update_engine {
     37 
     38 class HashCalculator {
     39  public:
     40   HashCalculator();
     41 
     42   // Update is called with all of the data that should be hashed in order.
     43   // Update will read |length| bytes of |data|.
     44   // Returns true on success.
     45   bool Update(const void* data, size_t length);
     46 
     47   // Updates the hash with up to |length| bytes of data from |file|. If |length|
     48   // is negative, reads in and updates with the whole file. Returns the number
     49   // of bytes that the hash was updated with, or -1 on error.
     50   off_t UpdateFile(const std::string& name, off_t length);
     51 
     52   // Call Finalize() when all data has been passed in. This method tells
     53   // OpenSSl that no more data will come in and base64 encodes the resulting
     54   // hash.
     55   // Returns true on success.
     56   bool Finalize();
     57 
     58   // Gets the hash. Finalize() must have been called.
     59   const std::string& hash() const {
     60     DCHECK(!hash_.empty()) << "Call Finalize() first";
     61     return hash_;
     62   }
     63 
     64   const brillo::Blob& raw_hash() const {
     65     DCHECK(!raw_hash_.empty()) << "Call Finalize() first";
     66     return raw_hash_;
     67   }
     68 
     69   // Gets the current hash context. Note that the string will contain binary
     70   // data (including \0 characters).
     71   std::string GetContext() const;
     72 
     73   // Sets the current hash context. |context| must the string returned by a
     74   // previous HashCalculator::GetContext method call. Returns true on success,
     75   // and false otherwise.
     76   bool SetContext(const std::string& context);
     77 
     78   static bool RawHashOfBytes(const void* data,
     79                              size_t length,
     80                              brillo::Blob* out_hash);
     81   static bool RawHashOfData(const brillo::Blob& data,
     82                             brillo::Blob* out_hash);
     83   static off_t RawHashOfFile(const std::string& name, off_t length,
     84                              brillo::Blob* out_hash);
     85 
     86   // Used by tests
     87   static std::string HashOfBytes(const void* data, size_t length);
     88   static std::string HashOfString(const std::string& str);
     89   static std::string HashOfData(const brillo::Blob& data);
     90 
     91  private:
     92   // If non-empty, the final base64 encoded hash and the raw hash. Will only be
     93   // set to non-empty when Finalize is called.
     94   std::string hash_;
     95   brillo::Blob raw_hash_;
     96 
     97   // Init success
     98   bool valid_;
     99 
    100   // The hash state used by OpenSSL
    101   SHA256_CTX ctx_;
    102   DISALLOW_COPY_AND_ASSIGN(HashCalculator);
    103 };
    104 
    105 }  // namespace chromeos_update_engine
    106 
    107 #endif  // UPDATE_ENGINE_COMMON_HASH_CALCULATOR_H_
    108