summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2017-07-21 15:33:19 +0100
committerJan Holesovsky <kendy@collabora.com>2017-10-03 21:52:45 +0200
commit79053911fc51bd0144144c34db944c24b42d3756 (patch)
treef52e0e795762e391fa28f4358c73134e49208969 /common
parent60d72b9e5a8e270c7132abf14d05e12a060ef1be (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.cpp141
-rw-r--r--common/Crypto.hpp37
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: */