Almost there...
git-svn-id: svn://chrome-svn/chromeos/trunk@24 06c00378-0e64-4dae-be16-12b19f9950a1
diff --git a/omaha_hash_calculator.cc b/omaha_hash_calculator.cc
new file mode 100644
index 0000000..41dcdee
--- /dev/null
+++ b/omaha_hash_calculator.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <openssl/bio.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include "glog/logging.h"
+#include "update_engine/omaha_hash_calculator.h"
+
+namespace chromeos_update_engine {
+
+OmahaHashCalculator::OmahaHashCalculator() {
+ CHECK_EQ(1, SHA1_Init(&ctx_));
+}
+
+// Update is called with all of the data that should be hashed in order.
+// Mostly just passes the data through to OpenSSL's SHA1_Update()
+void OmahaHashCalculator::Update(const char* data, size_t length) {
+ CHECK(hash_.empty()) << "Can't Update after hash is finalized";
+ COMPILE_ASSERT(sizeof(size_t) <= sizeof(unsigned long),
+ length_param_may_be_truncated_in_SHA1_Update);
+ CHECK_EQ(1, SHA1_Update(&ctx_, data, length));
+}
+
+// Call Finalize() when all data has been passed in. This mostly just
+// calls OpenSSL's SHA1_Final() and then base64 encodes the hash.
+void OmahaHashCalculator::Finalize() {
+ CHECK(hash_.empty()) << "Don't call Finalize() twice";
+ unsigned char md[SHA_DIGEST_LENGTH];
+ CHECK_EQ(1, SHA1_Final(md, &ctx_));
+
+ // Convert md to base64 encoding and store it in hash_
+ BIO *b64 = BIO_new(BIO_f_base64());
+ CHECK(b64);
+ BIO *bmem = BIO_new(BIO_s_mem());
+ CHECK(bmem);
+ b64 = BIO_push(b64, bmem);
+ CHECK_EQ(sizeof(md), BIO_write(b64, md, sizeof(md)));
+ CHECK_EQ(1, BIO_flush(b64));
+
+ BUF_MEM *bptr = NULL;
+ BIO_get_mem_ptr(b64, &bptr);
+ hash_.assign(bptr->data, bptr->length - 1);
+
+ BIO_free_all(b64);
+}
+
+std::string OmahaHashCalculator::OmahaHashOfBytes(
+ const void* data, size_t length) {
+ OmahaHashCalculator calc;
+ calc.Update(reinterpret_cast<const char*>(data), length);
+ calc.Finalize();
+ return calc.hash();
+}
+
+std::string OmahaHashCalculator::OmahaHashOfString(
+ const std::string& str) {
+ return OmahaHashOfBytes(str.data(), str.size());
+}
+
+std::string OmahaHashCalculator::OmahaHashOfData(
+ const std::vector<char>& data) {
+ return OmahaHashOfBytes(&data[0], data.size());
+}
+
+} // namespace chromeos_update_engine