diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2017-07-21 15:33:19 +0100 |
---|---|---|
committer | Jan Holesovsky <kendy@collabora.com> | 2017-10-03 21:52:45 +0200 |
commit | 79053911fc51bd0144144c34db944c24b42d3756 (patch) | |
tree | f52e0e795762e391fa28f4358c73134e49208969 /common | |
parent | 60d72b9e5a8e270c7132abf14d05e12a060ef1be (diff) |
Support key logic and verification.
Change-Id: Ie55150b99df3e80239236571af185502196ad3e9
Reviewed-on: https://gerrit.libreoffice.org/43097
Reviewed-by: Jan Holesovsky <kendy@collabora.com>
Tested-by: Jan Holesovsky <kendy@collabora.com>
(cherry picked from commit 56385cb8ac2a57af4eb70bc8bc7313a9299533c3)
Reviewed-on: https://gerrit.libreoffice.org/43099
Diffstat (limited to 'common')
-rw-r--r-- | common/Crypto.cpp | 141 | ||||
-rw-r--r-- | common/Crypto.hpp | 37 |
2 files changed, 178 insertions, 0 deletions
diff --git a/common/Crypto.cpp b/common/Crypto.cpp new file mode 100644 index 000000000..aa268ae3c --- /dev/null +++ b/common/Crypto.cpp @@ -0,0 +1,141 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "config.h" + +#if ENABLE_SUPPORT_KEY + +#include <Poco/DigestStream.h> +#include <Poco/Base64Decoder.h> +#include <Poco/DateTimeParser.h> +#include <Poco/Crypto/RSADigestEngine.h> + +#include <fstream> +#include <sstream> +#include <iostream> + +#include "Log.hpp" +#include "Crypto.hpp" + +using namespace Poco; +using namespace Poco::Crypto; + +struct SupportKeyImpl +{ + bool _invalid; + std::string _key; + std::string _data; + std::string _signature; + DateTime _expiry; + // Key format: iso-expiry-date:field1:field2:field:...:<signature> + SupportKeyImpl(const std::string &key) + : _invalid(true), _key(key) + { + LOG_INF("Support key '" << key << "' provided"); + size_t firstColon = key.find(':'); + if (firstColon != std::string::npos) + { + std::string expiry(key.substr(0, firstColon)); + LOG_INF("Support key with expiry '" << expiry << "'"); + + try { + int timeZoneDifferential = 0; + Poco::DateTimeParser::parse(expiry, _expiry, timeZoneDifferential); + + size_t lastColon = key.rfind(":"); + if (lastColon != std::string::npos) + { + _signature = key.substr(lastColon + 1, + key.length() - lastColon); + _data = key.substr(0, lastColon); + std::cout << "signature '" << _signature << "' data '" << _data << "'\n"; + + _invalid = false; + } + } catch (SyntaxException &e) { + LOG_ERR("Invalid support key expiry '" << expiry << "'"); + } + } + } +}; + +SupportKey::SupportKey(const std::string &key) : + _impl(new SupportKeyImpl(key)) +{ +} + +SupportKey::~SupportKey() +{ +} + +bool SupportKey::verify() +{ + if (_impl->_invalid) + { + LOG_ERR("Basic key structure is invalid."); + return false; + } + + std::ifstream pubStream; + try { + pubStream.open ("pubKey.pub", std::ifstream::in); + if (pubStream.fail()) + { + LOG_ERR("Failed to open support public key."); + return false; + } + } catch (...) { + LOG_ERR("Exception opening public key"); + return false; + } + try { + RSAKey keyPub(&pubStream); + RSADigestEngine rsaEngine(keyPub, RSADigestEngine::DigestType::DIGEST_SHA1); + rsaEngine.update(_impl->_data); + + std::istringstream sigStream(_impl->_signature); + Poco::Base64Decoder rawStream(sigStream); + + std::istreambuf_iterator<char> eos; + std::vector<unsigned char> rawSignature(std::istreambuf_iterator<char>(rawStream), eos); + LOG_INF("Signature of length " << rawSignature.size() + << " data size: " << _impl->_data.length()); + if (!rsaEngine.verify(rawSignature)) + { + LOG_ERR("Support key is not correctly signed."); + return false; + } + } catch (...) { + LOG_ERR("Exception validating support key."); + return false; + } + LOG_INF("Support key correctly signed."); + return true; +} + +int SupportKey::validDaysRemaining() +{ + if (!verify()) + { + LOG_ERR("Support key signature is invalid."); + return 0; + } + Timespan remaining = _impl->_expiry - DateTime(); + int days = remaining.days(); + if (days > 0) + LOG_INF("Support key has " << days << " remaining"); + else + LOG_ERR("Support key has expired for " << -days << " days"); + + return days; +} + +#endif // ENABLE_SUPPORT_KEY + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/common/Crypto.hpp b/common/Crypto.hpp new file mode 100644 index 000000000..94b194cc2 --- /dev/null +++ b/common/Crypto.hpp @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_CRYPTO_HPP +#define INCLUDED_CRYPTO_HPP + +#if ENABLE_SUPPORT_KEY + +#include <memory> + +struct SupportKeyImpl; + +class SupportKey { + std::unique_ptr<SupportKeyImpl> _impl; + +public: + SupportKey(const std::string &key); + virtual ~SupportKey(); + + /// Check the key is validly signed. + bool verify(); + + /// How many days until key expires + int validDaysRemaining(); +}; + +#endif + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |