diff --git a/CMakeLists.txt b/CMakeLists.txt index 091a2fb..9f84db2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,6 +60,7 @@ find_package(PkgConfig) pkg_check_modules(FFMPEG REQUIRED libavutil libavcodec libavformat) pkg_check_modules(LIBEVENT REQUIRED libevent) pkg_check_modules(GLOG REQUIRED libglog) +pkg_check_modules(OPENSSL REQUIRED libcrypto) # Check if ffmpeg support "stimeout". set(CMAKE_REQUIRED_INCLUDES ${FFMPEG_INCLUDES}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 507081d..0d6f2d6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,12 +35,14 @@ set(MOONFIRE_DEPS ${LIBEVENT_LIBRARIES} ${GFLAGS_LIBRARIES} ${GLOG_LIBRARIES} + ${OPENSSL_LIBRARIES} ${PROFILER_LIBRARIES} ${PROTOBUF_LIBRARIES} ${RE2_LIBRARIES}) set(MOONFIRE_NVR_SRCS coding.cc + crypto.cc ffmpeg.cc filesystem.cc http.cc @@ -61,7 +63,7 @@ install_programs(/bin FILES moonfire-nvr) include_directories(${GTest_INCLUDE_DIR}) include_directories(${GMock_INCLUDE_DIR}) -foreach(test coding http moonfire-nvr recording string) +foreach(test coding crypto http moonfire-nvr recording string) add_executable(${test}-test ${test}-test.cc testutil.cc) target_link_libraries(${test}-test GTest GMock moonfire-nvr-lib) add_test(NAME ${test}-test diff --git a/src/crypto-test.cc b/src/crypto-test.cc new file mode 100644 index 0000000..d3e91ce --- /dev/null +++ b/src/crypto-test.cc @@ -0,0 +1,67 @@ +// This file is part of Moonfire NVR, a security camera network video recorder. +// Copyright (C) 2016 Scott Lamb +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// crypto-test.cc: tests of the crypto.h interface. + +#include +#include +#include +#include + +#include "crypto.h" +#include "string.h" + +DECLARE_bool(alsologtostderr); + +namespace moonfire_nvr { +namespace { + +TEST(DigestTest, Sha1) { + auto sha1 = Digest::SHA1(); + EXPECT_EQ("da 39 a3 ee 5e 6b 4b 0d 32 55 bf ef 95 60 18 90 af d8 07 09", + ToHex(sha1->Finalize())); + + sha1 = Digest::SHA1(); + sha1->Update("hello"); + sha1->Update(" world"); + EXPECT_EQ("2a ae 6c 35 c9 4f cf b4 15 db e9 5f 40 8b 9c e9 1e e8 46 ed", + ToHex(sha1->Finalize())); +} + +} // namespace +} // namespace moonfire_nvr + +int main(int argc, char **argv) { + FLAGS_alsologtostderr = true; + google::ParseCommandLineFlags(&argc, &argv, true); + testing::InitGoogleTest(&argc, argv); + google::InitGoogleLogging(argv[0]); + return RUN_ALL_TESTS(); +} diff --git a/src/crypto.cc b/src/crypto.cc new file mode 100644 index 0000000..9b7b255 --- /dev/null +++ b/src/crypto.cc @@ -0,0 +1,61 @@ +// This file is part of Moonfire NVR, a security camera network video recorder. +// Copyright (C) 2016 Scott Lamb +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// crypto.cc: see crypto.h. + +#include "crypto.h" + +#include + +namespace moonfire_nvr { + +std::unique_ptr Digest::SHA1() { + std::unique_ptr d(new Digest); + CHECK_EQ(1, EVP_DigestInit_ex(d->ctx_, EVP_sha1(), nullptr)); + return d; +} + +Digest::Digest() { ctx_ = CHECK_NOTNULL(EVP_MD_CTX_create()); } + +Digest::~Digest() { EVP_MD_CTX_destroy(ctx_); } + +void Digest::Update(re2::StringPiece data) { + CHECK_EQ(1, EVP_DigestUpdate(ctx_, data.data(), data.size())); +} + +std::string Digest::Finalize() { + std::string out; + out.resize(EVP_MD_CTX_size(ctx_)); + auto *p = reinterpret_cast(&out[0]); + CHECK_EQ(1, EVP_DigestFinal_ex(ctx_, p, nullptr)); + return out; +} + +} // namespace moonfire_nvr diff --git a/src/crypto.h b/src/crypto.h new file mode 100644 index 0000000..9b1033a --- /dev/null +++ b/src/crypto.h @@ -0,0 +1,63 @@ +// This file is part of Moonfire NVR, a security camera network video recorder. +// Copyright (C) 2016 Scott Lamb +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations including +// the two. +// +// You must obey the GNU General Public License in all respects for all +// of the code used other than OpenSSL. If you modify file(s) with this +// exception, you may extend this exception to your version of the +// file(s), but you are not obligated to do so. If you do not wish to do +// so, delete this exception statement from your version. If you delete +// this exception statement from all source files in the program, then +// also delete it here. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// crypto.h: cryptographic functions. + +#ifndef MOONFIRE_NVR_CRYPTO_H +#define MOONFIRE_NVR_CRYPTO_H + +#include + +#include +#include + +namespace moonfire_nvr { + +class Digest { + public: + static std::unique_ptr SHA1(); + ~Digest(); + + // PRE: Finalize() has not been called. + void Update(re2::StringPiece data); + + // PRE: Finalize() has not been called. + std::string Finalize(); + + private: + Digest(); + Digest(const Digest &) = delete; + void operator=(const Digest &) = delete; + EVP_MD_CTX *ctx_ = nullptr; +}; + +} // namespace moonfire_nvr + +#endif // MOONFIRE_NVR_CRYPTO_H