summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meson.build38
-rw-r--r--src/sha1.cc16
-rw-r--r--src/sha1.hh15
-rw-r--r--src/sha1_md.cc16
-rw-r--r--src/sha1_openssl.cc13
-rw-r--r--test/sha1.cc17
6 files changed, 115 insertions, 0 deletions
diff --git a/meson.build b/meson.build
index b17ed18..7b751db 100644
--- a/meson.build
+++ b/meson.build
@@ -36,6 +36,8 @@ configure_file(input: 'src/config.h.in',
configuration : conf_data)
dbus_dep = dependency('sdbus-c++', version: '>= 2.0.0')
+md_dep = dependency('libmd', version: '>= 1.0.0', required: false)
+openssl_dep = dependency('openssl', version: '>= 1.0.0', required: false)
inc = include_directories('src')
@@ -203,6 +205,31 @@ base64_dep = declare_dependency(
link_with: base64_lib,
)
+if md_dep.found()
+ sha1_inner_source = 'src/sha1_md.cc'
+ sha1_inner_dep = md_dep
+elif openssl_dep.found()
+ sha1_inner_source = 'src/sha1_openssl.cc'
+ sha1_inner_dep = openssl_dep
+else
+ error('Need a library with SHA-1, either openssl or libmd')
+endif
+
+sha1_lib = library(
+ 'sha1',
+ sources: [
+ 'src/sha1.cc',
+ 'src/sha1.hh',
+ sha1_inner_source,
+ ],
+ include_directories: inc,
+ dependencies: [sha1_inner_dep],
+)
+sha1_dep = declare_dependency(
+ link_with: sha1_lib,
+ dependencies: [sha1_inner_dep],
+)
+
bluetooth_jukebox = executable(
'bluetooth-jukebox',
sources: [
@@ -355,6 +382,17 @@ test('base64', executable(
],
))
+test('sha1', executable(
+ 'test_sha1',
+ sources: ['test/sha1.cc'],
+ include_directories: inc,
+ dependencies : [
+ sha1_dep,
+ base64_dep,
+ test_dependencies,
+ ],
+))
+
run_clang_tidy = find_program('run-clang-tidy', required: false)
if run_clang_tidy.found()
diff --git a/src/sha1.cc b/src/sha1.cc
new file mode 100644
index 0000000..5d20ca9
--- /dev/null
+++ b/src/sha1.cc
@@ -0,0 +1,16 @@
+#include "sha1.hh"
+
+namespace sha1 {
+
+std::array<uint8_t, 20> hash(std::span<char const> input) {
+ // std::string and std::string_view -> std::span includes null terminating
+ // byte.
+ if (!input.empty() && input.back() == '\0') {
+ return hash(std::span{reinterpret_cast<uint8_t const*>(input.data()),
+ input.size() - 1});
+ }
+ return hash(
+ std::span{reinterpret_cast<uint8_t const*>(input.data()), input.size()});
+}
+
+} // namespace sha1
diff --git a/src/sha1.hh b/src/sha1.hh
new file mode 100644
index 0000000..a885a09
--- /dev/null
+++ b/src/sha1.hh
@@ -0,0 +1,15 @@
+#ifndef SHA1_HH
+#define SHA1_HH
+
+#include <array> // IWYU pragma: export
+#include <cstdint> // IWYU pragma: export
+#include <span> // IWYU pragma: export
+
+namespace sha1 {
+
+std::array<uint8_t, 20> hash(std::span<uint8_t const> input);
+std::array<uint8_t, 20> hash(std::span<char const> input);
+
+} // namespace sha1
+
+#endif // SHA1_HH
diff --git a/src/sha1_md.cc b/src/sha1_md.cc
new file mode 100644
index 0000000..274eb60
--- /dev/null
+++ b/src/sha1_md.cc
@@ -0,0 +1,16 @@
+#include "sha1.hh"
+
+#include <sha1.h>
+
+namespace sha1 {
+
+std::array<uint8_t, 20> hash(std::span<uint8_t const> input) {
+ std::array<uint8_t, 20> ret;
+ SHA1_CTX ctx;
+ SHA1Init(&ctx);
+ SHA1Update(&ctx, input.data(), input.size());
+ SHA1Final(ret.data(), &ctx);
+ return ret;
+}
+
+} // namespace sha1
diff --git a/src/sha1_openssl.cc b/src/sha1_openssl.cc
new file mode 100644
index 0000000..9e6d77e
--- /dev/null
+++ b/src/sha1_openssl.cc
@@ -0,0 +1,13 @@
+#include "sha1.hh"
+
+#include <openssl/sha.h>
+
+namespace sha1 {
+
+std::array<uint8_t, 20> hash(std::span<uint8_t const> input) {
+ std::array<uint8_t, 20> ret;
+ SHA1(input.data(), input.size(), ret.data());
+ return ret;
+}
+
+} // namespace sha1
diff --git a/test/sha1.cc b/test/sha1.cc
new file mode 100644
index 0000000..7441f01
--- /dev/null
+++ b/test/sha1.cc
@@ -0,0 +1,17 @@
+#include "sha1.hh"
+
+#include "base64.hh"
+
+#include <gtest/gtest.h>
+
+TEST(Sha1, sanity) {
+ EXPECT_EQ("L9ThxnotKPzthJ7hu3bnORuT6xI=",
+ base64::encode(
+ sha1::hash("The quick brown fox jumps over the lazy dog")));
+
+ EXPECT_EQ("3p8sf9JeGzr60+haC9F9mxANtLM=",
+ base64::encode(
+ sha1::hash("The quick brown fox jumps over the lazy cog")));
+
+ EXPECT_EQ("2jmj7l5rSw0yVb/vlWAYkK/YBwk=", base64::encode(sha1::hash("")));
+}