blob: bea3cc9ac3a72c477eb75fb5837d9fd24284f6b5 [file] [log] [blame]
rspangler@google.com49fdf182009-10-10 00:57:34 +00001// Copyright (c) 2009 The Chromium OS 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.
4
adlr@google.comc98a7ed2009-12-04 18:54:03 +00005#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_OMAHA_HASH_CALCULATOR_H__
6#define CHROMEOS_PLATFORM_UPDATE_ENGINE_OMAHA_HASH_CALCULATOR_H__
rspangler@google.com49fdf182009-10-10 00:57:34 +00007
rspangler@google.com49fdf182009-10-10 00:57:34 +00008#include <string>
Han Shen2643cb72012-06-26 14:45:33 -07009#include <unistd.h>
adlr@google.comc98a7ed2009-12-04 18:54:03 +000010#include <vector>
Darin Petkov36a58222010-10-07 22:00:09 -070011
rspangler@google.com49fdf182009-10-10 00:57:34 +000012#include <openssl/sha.h>
Darin Petkov36a58222010-10-07 22:00:09 -070013#include <base/basictypes.h>
14#include <base/logging.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +000015
Darin Petkov73058b42010-10-06 16:32:19 -070016// Omaha uses base64 encoded SHA-256 as the hash. This class provides a simple
rspangler@google.com49fdf182009-10-10 00:57:34 +000017// wrapper around OpenSSL providing such a formatted hash of data passed in.
Darin Petkov73058b42010-10-06 16:32:19 -070018// The methods of this class must be called in a very specific order: First the
19// ctor (of course), then 0 or more calls to Update(), then Finalize(), then 0
20// or more calls to hash().
rspangler@google.com49fdf182009-10-10 00:57:34 +000021
22namespace chromeos_update_engine {
23
24class OmahaHashCalculator {
25 public:
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070026 OmahaHashCalculator();
rspangler@google.com49fdf182009-10-10 00:57:34 +000027
28 // Update is called with all of the data that should be hashed in order.
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070029 // Update will read |length| bytes of |data|.
30 // Returns true on success.
31 bool Update(const char* data, size_t length);
rspangler@google.com49fdf182009-10-10 00:57:34 +000032
Darin Petkov36a58222010-10-07 22:00:09 -070033 // Updates the hash with up to |length| bytes of data from |file|. If |length|
34 // is negative, reads in and updates with the whole file. Returns the number
35 // of bytes that the hash was updated with, or -1 on error.
36 off_t UpdateFile(const std::string& name, off_t length);
37
rspangler@google.com49fdf182009-10-10 00:57:34 +000038 // Call Finalize() when all data has been passed in. This method tells
39 // OpenSSl that no more data will come in and base64 encodes the resulting
40 // hash.
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070041 // Returns true on success.
42 bool Finalize();
rspangler@google.com49fdf182009-10-10 00:57:34 +000043
44 // Gets the hash. Finalize() must have been called.
45 const std::string& hash() const {
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070046 DCHECK(!hash_.empty()) << "Call Finalize() first";
rspangler@google.com49fdf182009-10-10 00:57:34 +000047 return hash_;
48 }
49
Darin Petkovd7061ab2010-10-06 14:37:09 -070050 const std::vector<char>& raw_hash() const {
51 DCHECK(!raw_hash_.empty()) << "Call Finalize() first";
52 return raw_hash_;
53 }
54
Darin Petkov73058b42010-10-06 16:32:19 -070055 // Gets the current hash context. Note that the string will contain binary
56 // data (including \0 characters).
57 std::string GetContext() const;
58
59 // Sets the current hash context. |context| must the string returned by a
60 // previous OmahaHashCalculator::GetContext method call. Returns true on
61 // success, and false otherwise.
62 bool SetContext(const std::string& context);
63
Darin Petkovadb3cef2011-01-13 16:16:08 -080064 static bool RawHashOfBytes(const char* data,
65 size_t length,
66 std::vector<char>* out_hash);
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070067 static bool RawHashOfData(const std::vector<char>& data,
68 std::vector<char>* out_hash);
Darin Petkov698d0412010-10-13 10:59:44 -070069 static off_t RawHashOfFile(const std::string& name, off_t length,
70 std::vector<char>* out_hash);
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070071
rspangler@google.com49fdf182009-10-10 00:57:34 +000072 // Used by tests
73 static std::string OmahaHashOfBytes(const void* data, size_t length);
74 static std::string OmahaHashOfString(const std::string& str);
75 static std::string OmahaHashOfData(const std::vector<char>& data);
76
Jay Srinivasan51dcf262012-09-13 17:24:32 -070077 // Encodes data of given size as a base64 out string
Andrew de los Reyes89f17be2010-10-22 13:39:09 -070078 static bool Base64Encode(const void* data, size_t size, std::string* out);
79
Jay Srinivasan51dcf262012-09-13 17:24:32 -070080 // Decodes given base64-encoded in string into the out vector. Since the
81 // output can have null characters, we're returning a byte vector instead of
Jay Srinivasane56c8732012-10-17 12:19:27 -070082 // a string. This method works fine even if |raw_in| has any newlines.
83 // Any existing contents of |out| will be erased.
84 static bool Base64Decode(const std::string& raw_in, std::vector<char>* out);
Jay Srinivasan51dcf262012-09-13 17:24:32 -070085
rspangler@google.com49fdf182009-10-10 00:57:34 +000086 private:
Darin Petkovd7061ab2010-10-06 14:37:09 -070087 // If non-empty, the final base64 encoded hash and the raw hash. Will only be
88 // set to non-empty when Finalize is called.
rspangler@google.com49fdf182009-10-10 00:57:34 +000089 std::string hash_;
Darin Petkovd7061ab2010-10-06 14:37:09 -070090 std::vector<char> raw_hash_;
rspangler@google.com49fdf182009-10-10 00:57:34 +000091
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070092 // Init success
93 bool valid_;
94
rspangler@google.com49fdf182009-10-10 00:57:34 +000095 // The hash state used by OpenSSL
Darin Petkovd22cb292010-09-29 10:02:29 -070096 SHA256_CTX ctx_;
rspangler@google.com49fdf182009-10-10 00:57:34 +000097 DISALLOW_COPY_AND_ASSIGN(OmahaHashCalculator);
98};
99
100} // namespace chromeos_update_engine
101
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700102#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_OMAHA_HASH_CALCULATOR_H__