From b17e585eb7c3b131dfcd38a537be567efaaca73b Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Mon, 15 Jun 2015 14:34:17 -0400 Subject: Add SHA-1 support --- src/hash.ur | 2 ++ src/hash.urs | 2 ++ src/hashFFI.cc | 27 +++++++++++++++++++++++++++ src/hashFFI.h | 1 + src/hashFFI.urs | 2 ++ 5 files changed, 34 insertions(+) diff --git a/src/hash.ur b/src/hash.ur index 7492dd0..cca79d7 100644 --- a/src/hash.ur +++ b/src/hash.ur @@ -14,3 +14,5 @@ specific language governing permissions and limitations under the License. *) type digest = string val md5 = HashFFI.md5 + +val sha1 = HashFFI.sha1 diff --git a/src/hash.urs b/src/hash.urs index bc4a543..b0bfb69 100644 --- a/src/hash.urs +++ b/src/hash.urs @@ -19,3 +19,5 @@ val sql_digest : sql_injectable digest val sql_maxable_digest : sql_maxable digest val md5 : blob -> digest + +val sha1 : blob -> digest 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 #include +#include extern "C" { #include } @@ -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; + // Perform the SHA-1 operation. + Digest raw_result; + SHA1(reinterpret_cast(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_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; +} diff --git a/src/hashFFI.h b/src/hashFFI.h index 5ff8ea3..a454b99 100644 --- a/src/hashFFI.h +++ b/src/hashFFI.h @@ -22,6 +22,7 @@ extern "C" { #include uw_Basis_string uw_HashFFI_md5(struct uw_context*, const uw_Basis_blob); +uw_Basis_string uw_HashFFI_sha1(struct uw_context*, const uw_Basis_blob); #ifdef __cplusplus } diff --git a/src/hashFFI.urs b/src/hashFFI.urs index 55acadd..f9c6ba5 100644 --- a/src/hashFFI.urs +++ b/src/hashFFI.urs @@ -12,3 +12,5 @@ CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. *) val md5 : blob -> string + +val sha1 : blob -> string -- cgit v1.2.3