summaryrefslogtreecommitdiff
path: root/src/hashFFI.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/hashFFI.cc')
-rw-r--r--src/hashFFI.cc27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/hashFFI.cc b/src/hashFFI.cc
index ab20030..f349ba4 100644
--- a/src/hashFFI.cc
+++ b/src/hashFFI.cc
@@ -18,6 +18,7 @@
#include <cstdio>
#include <openssl/md5.h>
+#include <openssl/sha.h>
extern "C" {
#include <urweb/urweb_cpp.h>
}
@@ -70,3 +71,29 @@ uw_Basis_string uw_HashFFI_md5(uw_context* const context,
"failed to properly terminate digest");
return result;
}
+
+uw_Basis_string uw_HashFFI_sha1(uw_context* const context,
+ const uw_Basis_blob input) {
+ using Digest = std::array<unsigned char, SHA_DIGEST_LENGTH>;
+ // Perform the SHA-1 operation.
+ Digest raw_result;
+ SHA1(reinterpret_cast<unsigned char*>(input.data), input.size,
+ raw_result.data());
+ // Convert it to a hex string. This will be twice as large (two hex digits
+ // per byte), plus an additional byte for the null terminator.
+ const auto result_length = 2 * raw_result.size() + 1;
+ uw_Basis_string result =
+ reinterpret_cast<uw_Basis_string>(uw_malloc(context, result_length));
+ Assert(context, result, BOUNDED_RETRY,
+ "unable to allocate memory for digest");
+ for (Digest::size_type i = 0; i < raw_result.size(); i++) {
+ sprintf(result + 2 * i, "%02x", raw_result[i]);
+ }
+ // Make sure the string is properly terminated.
+ for (std::size_t i = 0; i < result_length - 2; i++) {
+ Assert(context, result[i] != '\0', "null byte in digest");
+ }
+ Assert(context, result[result_length - 1] == '\0',
+ "failed to properly terminate digest");
+ return result;
+}