commit 4594e1fe2021e5e506c0a881b9921c585f72f75b
parent 73549a14de547c2f65c664ce4e76a76b68461ab9
Author: cfillion <cfillion@users.noreply.github.com>
Date: Wed, 5 Dec 2018 20:48:20 -0500
implement SHA256 on Linux
Diffstat:
3 files changed, 48 insertions(+), 38 deletions(-)
diff --git a/linux.tup b/linux.tup
@@ -20,7 +20,7 @@ SWELL := $(WDL)/swell
WDLSOURCE += $(SWELL)/swell-modstub-generic.cpp
export CURLSO
-LDFLAGS := -lstdc++ -lpthread -ldl -l${CURLSO:-curl} -lsqlite3 -lz
+LDFLAGS := -lstdc++ -lpthread -ldl -lcrypto -l${CURLSO:-curl} -lsqlite3 -lz
LDFLAGS += -Wl,--gc-sections
SOFLAGS := -shared
diff --git a/src/hash.cpp b/src/hash.cpp
@@ -1,53 +1,61 @@
#include "hash.hpp"
#include <cstdio>
+#include <vector>
+
+#ifdef __APPLE__
+# include <CommonCrypto/CommonDigest.h>
+# define CC(s) CC_##s
+#else
+# include <openssl/sha.h>
+# define CC(s) s
+#endif
+
+class Hash::SHA256Context : public Hash::Context {
+public:
+ SHA256Context() { CC(SHA256_Init)(&m_context); }
+ size_t hashSize() const { return CC(SHA256_DIGEST_LENGTH); }
+ void addData(const char *data, const size_t len) {
+ CC(SHA256_Update)(&m_context, data, len);
+ }
+ void getHash(unsigned char *out) { CC(SHA256_Final)(out, &m_context); }
+
+private:
+ CC(SHA256_CTX) m_context;
+};
Hash::Hash(const Algorithm algo)
: m_algo(algo)
{
switch(algo) {
case SHA256:
-#ifdef __APPLE__
- CC_SHA256_Init(&m_sha256Context);
-#endif
+ m_context = std::make_unique<SHA256Context>();
break;
}
}
void Hash::write(const char *data, const size_t len)
{
- switch(m_algo) {
- case SHA256:
-#ifdef __APPLE__
- CC_SHA256_Update(&m_sha256Context, data, len);
-#endif
- break;
- }
+ if(m_context)
+ m_context->addData(data, len);
}
const std::string &Hash::digest()
{
- if(!m_value.empty())
+ if(!m_context || !m_value.empty())
return m_value;
- switch(m_algo) {
- case SHA256:
-#ifdef __APPLE__
- unsigned char hash[2 + CC_SHA256_DIGEST_LENGTH] =
- {SHA256, CC_SHA256_DIGEST_LENGTH};
- CC_SHA256_Final(&hash[2], &m_sha256Context);
- setValue(hash, sizeof(hash));
-#endif
- break;
- }
+ const size_t hashSize = m_context->hashSize();
- return m_value;
-}
+ std::vector<unsigned char> multihash(2 + hashSize);
+ multihash[0] = m_algo;
+ multihash[1] = hashSize;
+ m_context->getHash(&multihash[2]);
-void Hash::setValue(const unsigned char *hash, size_t len)
-{
- m_value.resize(len * 2);
+ m_value.resize(multihash.size() * 2);
- for(size_t i = 0; i < len; ++i)
- sprintf(&m_value[i * 2], "%02x", hash[i]);
+ for(size_t i = 0; i < multihash.size(); ++i)
+ sprintf(&m_value[i * 2], "%02x", multihash[i]);
+
+ return m_value;
}
diff --git a/src/hash.hpp b/src/hash.hpp
@@ -1,12 +1,9 @@
#ifndef REAPACK_HASH_HPP
#define REAPACK_HASH_HPP
+#include <memory>
#include <string>
-#ifdef __APPLE__
-# include <CommonCrypto/CommonDigest.h>
-#endif
-
class Hash {
public:
enum Algorithm {
@@ -18,14 +15,19 @@ public:
const std::string &digest();
private:
- void setValue(const unsigned char *hash, size_t len);
+ class Context {
+ public:
+ virtual ~Context() = default;
+ virtual size_t hashSize() const = 0;
+ virtual void addData(const char *data, const size_t len) = 0;
+ virtual void getHash(unsigned char *out) = 0;
+ };
+
+ class SHA256Context;
Algorithm m_algo;
std::string m_value;
-
-#ifdef __APPLE__
- CC_SHA256_CTX m_sha256Context;
-#endif
+ std::unique_ptr<Context> m_context;
};
#endif