Provide a copy ctor for Digest that copies the current hash context
authorJude Taylor <judet@fb.com>
Wed, 12 Apr 2017 16:40:55 +0000 (09:40 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Wed, 12 Apr 2017 16:49:48 +0000 (09:49 -0700)
Summary: opensource changes for t16702532

Reviewed By: yfeldblum

Differential Revision: D4846899

fbshipit-source-id: 67a610ff399e95c7cf1c9c8a5950f79bfc3aabb9

folly/ssl/OpenSSLHash.h
folly/ssl/test/OpenSSLHashTest.cpp

index baf9ec7..481a4f3 100644 (file)
@@ -33,6 +33,20 @@ class OpenSSLHash {
    public:
     Digest() : ctx_(EVP_MD_CTX_new()) {}
 
+    Digest(const Digest& other) {
+      ctx_ = EvpMdCtxUniquePtr(EVP_MD_CTX_new());
+      if (other.md_ != nullptr) {
+        hash_init(other.md_);
+        check_libssl_result(
+            1, EVP_MD_CTX_copy_ex(ctx_.get(), other.ctx_.get()));
+      }
+    }
+
+    Digest& operator=(const Digest& other) {
+      this->~Digest();
+      return *new (this) Digest(other);
+    }
+
     void hash_init(const EVP_MD* md) {
       md_ = md;
       check_libssl_result(1, EVP_DigestInit_ex(ctx_.get(), md, nullptr));
@@ -54,6 +68,7 @@ class OpenSSLHash {
       check_libssl_result(size, int(len));
       md_ = nullptr;
     }
+
    private:
     const EVP_MD* md_ = nullptr;
     EvpMdCtxUniquePtr ctx_{nullptr};
index c63bfd8..b9f6a7b 100644 (file)
@@ -45,6 +45,39 @@ TEST_F(OpenSSLHashTest, sha256) {
   EXPECT_EQ(expected, out);
 }
 
+TEST_F(OpenSSLHashTest, sha256_hashcopy) {
+  std::array<uint8_t, 32> expected, actual;
+
+  OpenSSLHash::Digest digest;
+  digest.hash_init(EVP_sha256());
+  digest.hash_update(ByteRange(StringPiece("foobar")));
+
+  OpenSSLHash::Digest copy(digest);
+
+  digest.hash_final(range(expected));
+  copy.hash_final(range(actual));
+
+  EXPECT_EQ(expected, actual);
+}
+
+TEST_F(OpenSSLHashTest, sha256_hashcopy_intermediate) {
+  std::array<uint8_t, 32> expected, actual;
+
+  OpenSSLHash::Digest digest;
+  digest.hash_init(EVP_sha256());
+  digest.hash_update(ByteRange(StringPiece("foo")));
+
+  OpenSSLHash::Digest copy(digest);
+
+  digest.hash_update(ByteRange(StringPiece("bar")));
+  copy.hash_update(ByteRange(StringPiece("bar")));
+
+  digest.hash_final(range(expected));
+  copy.hash_final(range(actual));
+
+  EXPECT_EQ(expected, actual);
+}
+
 TEST_F(OpenSSLHashTest, hmac_sha256) {
   auto key = ByteRange(StringPiece("qwerty"));