blob: b9bfa4f29baeb74eaf399bda1ae70354692ba61d [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
Gilad Arnoldcf175a02014-07-10 16:48:47 -07005#ifndef UPDATE_ENGINE_OMAHA_HASH_CALCULATOR_H_
6#define UPDATE_ENGINE_OMAHA_HASH_CALCULATOR_H_
rspangler@google.com49fdf182009-10-10 00:57:34 +00007
Ben Chan05735a12014-09-03 07:48:22 -07008#include <openssl/sha.h>
Han Shen2643cb72012-06-26 14:45:33 -07009#include <unistd.h>
Ben Chan05735a12014-09-03 07:48:22 -070010
11#include <string>
adlr@google.comc98a7ed2009-12-04 18:54:03 +000012#include <vector>
Darin Petkov36a58222010-10-07 22:00:09 -070013
Darin Petkov36a58222010-10-07 22:00:09 -070014#include <base/logging.h>
Ben Chan05735a12014-09-03 07:48:22 -070015#include <base/macros.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +000016
Darin Petkov73058b42010-10-06 16:32:19 -070017// Omaha uses base64 encoded SHA-256 as the hash. This class provides a simple
rspangler@google.com49fdf182009-10-10 00:57:34 +000018// wrapper around OpenSSL providing such a formatted hash of data passed in.
Darin Petkov73058b42010-10-06 16:32:19 -070019// The methods of this class must be called in a very specific order: First the
20// ctor (of course), then 0 or more calls to Update(), then Finalize(), then 0
21// or more calls to hash().
rspangler@google.com49fdf182009-10-10 00:57:34 +000022
23namespace chromeos_update_engine {
24
25class OmahaHashCalculator {
26 public:
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070027 OmahaHashCalculator();
rspangler@google.com49fdf182009-10-10 00:57:34 +000028
29 // Update is called with all of the data that should be hashed in order.
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070030 // Update will read |length| bytes of |data|.
31 // Returns true on success.
32 bool Update(const char* data, size_t length);
rspangler@google.com49fdf182009-10-10 00:57:34 +000033
Darin Petkov36a58222010-10-07 22:00:09 -070034 // Updates the hash with up to |length| bytes of data from |file|. If |length|
35 // is negative, reads in and updates with the whole file. Returns the number
36 // of bytes that the hash was updated with, or -1 on error.
37 off_t UpdateFile(const std::string& name, off_t length);
38
rspangler@google.com49fdf182009-10-10 00:57:34 +000039 // Call Finalize() when all data has been passed in. This method tells
40 // OpenSSl that no more data will come in and base64 encodes the resulting
41 // hash.
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070042 // Returns true on success.
43 bool Finalize();
rspangler@google.com49fdf182009-10-10 00:57:34 +000044
45 // Gets the hash. Finalize() must have been called.
46 const std::string& hash() const {
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070047 DCHECK(!hash_.empty()) << "Call Finalize() first";
rspangler@google.com49fdf182009-10-10 00:57:34 +000048 return hash_;
49 }
50
Darin Petkovd7061ab2010-10-06 14:37:09 -070051 const std::vector<char>& raw_hash() const {
52 DCHECK(!raw_hash_.empty()) << "Call Finalize() first";
53 return raw_hash_;
54 }
55
Darin Petkov73058b42010-10-06 16:32:19 -070056 // Gets the current hash context. Note that the string will contain binary
57 // data (including \0 characters).
58 std::string GetContext() const;
59
60 // Sets the current hash context. |context| must the string returned by a
61 // previous OmahaHashCalculator::GetContext method call. Returns true on
62 // success, and false otherwise.
63 bool SetContext(const std::string& context);
64
Darin Petkovadb3cef2011-01-13 16:16:08 -080065 static bool RawHashOfBytes(const char* data,
66 size_t length,
67 std::vector<char>* out_hash);
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070068 static bool RawHashOfData(const std::vector<char>& data,
69 std::vector<char>* out_hash);
Darin Petkov698d0412010-10-13 10:59:44 -070070 static off_t RawHashOfFile(const std::string& name, off_t length,
71 std::vector<char>* out_hash);
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070072
rspangler@google.com49fdf182009-10-10 00:57:34 +000073 // Used by tests
74 static std::string OmahaHashOfBytes(const void* data, size_t length);
75 static std::string OmahaHashOfString(const std::string& str);
76 static std::string OmahaHashOfData(const std::vector<char>& data);
77
Jay Srinivasan51dcf262012-09-13 17:24:32 -070078 // Encodes data of given size as a base64 out string
Andrew de los Reyes89f17be2010-10-22 13:39:09 -070079 static bool Base64Encode(const void* data, size_t size, std::string* out);
80
Jay Srinivasan51dcf262012-09-13 17:24:32 -070081 // Decodes given base64-encoded in string into the out vector. Since the
82 // output can have null characters, we're returning a byte vector instead of
Jay Srinivasane56c8732012-10-17 12:19:27 -070083 // a string. This method works fine even if |raw_in| has any newlines.
84 // Any existing contents of |out| will be erased.
85 static bool Base64Decode(const std::string& raw_in, std::vector<char>* out);
Jay Srinivasan51dcf262012-09-13 17:24:32 -070086
rspangler@google.com49fdf182009-10-10 00:57:34 +000087 private:
Darin Petkovd7061ab2010-10-06 14:37:09 -070088 // If non-empty, the final base64 encoded hash and the raw hash. Will only be
89 // set to non-empty when Finalize is called.
rspangler@google.com49fdf182009-10-10 00:57:34 +000090 std::string hash_;
Darin Petkovd7061ab2010-10-06 14:37:09 -070091 std::vector<char> raw_hash_;
rspangler@google.com49fdf182009-10-10 00:57:34 +000092
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070093 // Init success
94 bool valid_;
95
rspangler@google.com49fdf182009-10-10 00:57:34 +000096 // The hash state used by OpenSSL
Darin Petkovd22cb292010-09-29 10:02:29 -070097 SHA256_CTX ctx_;
rspangler@google.com49fdf182009-10-10 00:57:34 +000098 DISALLOW_COPY_AND_ASSIGN(OmahaHashCalculator);
99};
100
101} // namespace chromeos_update_engine
102
Gilad Arnoldcf175a02014-07-10 16:48:47 -0700103#endif // UPDATE_ENGINE_OMAHA_HASH_CALCULATOR_H_