[Libreoffice-commits] online.git: test/WopiProofTests.cpp wsd/ProofKey.cpp wsd/ProofKey.hpp
Michael Meeks (via logerrit)
logerrit at kemper.freedesktop.org
Wed Apr 8 21:21:13 UTC 2020
test/WopiProofTests.cpp | 74 ++++++++++++++++++++++++++++++++++++++++++------
wsd/ProofKey.cpp | 34 +++++++++++++++-------
wsd/ProofKey.hpp | 3 +
3 files changed, 92 insertions(+), 19 deletions(-)
New commits:
commit 668007544b89d9cb29aa8a62405de95cb7a7c02f
Author: Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Wed Apr 8 21:39:54 2020 +0100
Commit: Michael Meeks <michael.meeks at collabora.com>
CommitDate: Wed Apr 8 23:20:55 2020 +0200
Proof: generate our own key, and verify our own signatures.
Change-Id: If805c89a3b6618d6e34e7421b20077c4f0a48cb3
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/91940
Tested-by: Michael Meeks <michael.meeks at collabora.com>
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/test/WopiProofTests.cpp b/test/WopiProofTests.cpp
index 6ad0b4268..446ec07b6 100644
--- a/test/WopiProofTests.cpp
+++ b/test/WopiProofTests.cpp
@@ -22,7 +22,7 @@
#include <openssl/bn.h>
#include <openssl/pem.h>
#include <openssl/buffer.h>
-
+#include <openssl/opensslv.h>
/// Delta unit-tests.
class WopiProofTests : public CPPUNIT_NS::TestFixture
@@ -31,17 +31,26 @@ class WopiProofTests : public CPPUNIT_NS::TestFixture
CPPUNIT_TEST(testCapiBlob);
CPPUNIT_TEST(testExistingProof);
+ CPPUNIT_TEST(testOurProof);
CPPUNIT_TEST_SUITE_END();
void testCapiBlob();
void testExistingProof();
+ void testOurProof();
BIGNUM *Base64ToNum(const std::string &str)
{
std::vector<unsigned char> vec = Proof::Base64ToBytes(str);
return BN_bin2bn(&vec[0], vec.size(), nullptr);
}
+
+ void verifySignature(const std::string &access,
+ const std::string &uri,
+ uint64_t ticks,
+ const std::string &discoveryModulus,
+ const std::string &discoveryExponent,
+ const std::string &msgProof);
};
void WopiProofTests::testCapiBlob()
@@ -55,21 +64,24 @@ void WopiProofTests::testCapiBlob()
LOK_ASSERT_EQUAL(capiEncoded, std::string("BgIAAACkAABSU0ExAAgAAAEAAQDFEthb5dkE+fGnJgsmY3IXmoFxj1cOwVYLpLNTEksnVRzbXcPfaSl/kFxn5b4QajhH1sTtXECZY6ZUyiDi1NG5ukFc9Fppgt0ywnuJqNBRWPfvLTOaVZRTtr8X8hqL+dPldOI3qFUW2zF6DEsAO9y74l3s6MqNjawCME5X0jb28TOrbXXsDfIGLEN3VBFO3wyhlRZKOmR9ZiqxQbpOz0Ltgv3HYci9OVN9c8YYV5T+fHI0Wtxg4F9lJHlB6MHPV9seVqr4ieM027NG89LhHm9BJEtceII09JgmkwLFUB/s2YGirUwZewk0efw1GL861PE7Vjdn2bIdmGSCRfFQlnPQ"));
}
-void WopiProofTests::testExistingProof()
+void WopiProofTests::verifySignature(const std::string &access,
+ const std::string &uri,
+ uint64_t ticks,
+ const std::string &discoveryModulus,
+ const std::string &discoveryExponent,
+ const std::string &msgProofStr)
{
- std::vector<unsigned char> proof = Proof::GetProof(
- "yZhdN1qgywcOQWhyEMVpB6NE3pvBksvcLXsrFKXNtBeDTPW%2fu62g2t%2fOCWSlb3jUGaz1zc%2fzOzbNgAredLdhQI1Q7sPPqUv2owO78olmN74DV%2fv52OZIkBG%2b8jqjwmUobcjXVIC1BG9g%2fynMN0itZklL2x27Z2imCF6xELcQUuGdkoXBj%2bI%2bTlKM", // access token
- "https://contoso.com/wopi/files/vHxYyRGM8VfmSGwGYDBMIQPzuE+sSC6kw+zWZw2Nyg?access_token=yZhdN1qgywcOQWhyEMVpB6NE3pvBksvcLXsrFKXNtBeDTPW%2fu62g2t%2fOCWSlb3jUGaz1zc%2fzOzbNgAredLdhQI1Q7sPPqUv2owO78olmN74DV%2fv52OZIkBG%2b8jqjwmUobcjXVIC1BG9g%2fynMN0itZklL2x27Z2imCF6xELcQUuGdkoXBj%2bI%2bTlKM", // uri
- UINT64_C(635655897610773532)); // ticks
+#if OPENSSL_VERSION_NUMBER > 0x10100000L
+ std::vector<unsigned char> proof = Proof::GetProof(access, uri, ticks);
- BIGNUM *modulus = Base64ToNum("0HOWUPFFgmSYHbLZZzdWO/HUOr8YNfx5NAl7GUytooHZ7B9QxQKTJpj0NIJ4XEskQW8e4dLzRrPbNOOJ+KpWHttXz8HoQXkkZV/gYNxaNHJ8/pRXGMZzfVM5vchhx/2C7ULPTrpBsSpmfWQ6ShaVoQzfThFUd0MsBvIN7HVtqzPx9jbSV04wAqyNjcro7F3iu9w7AEsMejHbFlWoN+J05dP5ixryF7+2U5RVmjMt7/dYUdCoiXvCMt2CaVr0XEG6udHU4iDKVKZjmUBc7cTWRzhqEL7lZ1yQfylp38Nd2xxVJ0sSU7OkC1bBDlePcYGaF3JjJgsmp/H5BNnlW9gSxQ==");
- BIGNUM *exponent = Base64ToNum("AQAB");
+ BIGNUM *modulus = Base64ToNum(discoveryModulus);
+ BIGNUM *exponent = Base64ToNum(discoveryExponent);
RSA *rsa = RSA_new();
LOK_ASSERT(rsa != nullptr);
LOK_ASSERT_EQUAL(1, RSA_set0_key(rsa, modulus, exponent, nullptr));
- std::vector<unsigned char> msgProof = Proof::Base64ToBytes("IflL8OWCOCmws5qnDD5kYMraMGI3o+T+hojoDREbjZSkxbbx7XIS1Av85lohPKjyksocpeVwqEYm9nVWfnq05uhDNGp2MsNyhPO9unZ6w25Rjs1hDFM0dmvYx8wlQBNZ/CFPaz3inCMaaP4PtU85YepaDccAjNc1gikdy3kSMeG1XZuaDixHvMKzF/60DMfLMBIu5xP4Nt8i8Gi2oZs4REuxi6yxOv2vQJQ5+8Wu2Olm8qZvT4FEIQT9oZAXebn/CxyvyQv+RVpoU2gb4BreXAdfKthWF67GpJyhr+ibEVDoIIolUvviycyEtjsaEBpOf6Ne/OLRNu98un7WNDzMTQ==");
+ std::vector<unsigned char> msgProof = Proof::Base64ToBytes(msgProofStr);
Poco::Crypto::DigestEngine digestEngine("SHA256");
digestEngine.update(proof.data(), proof.size());
@@ -81,6 +93,50 @@ void WopiProofTests::testExistingProof()
rsa));
RSA_free(rsa);
+#else
+ (void)access; (void)uri; (void)ticks;
+ (void)discoveryModulus; (void)discoveryExponent;
+ (void)msgProofStr;
+ std::cerr << "OpenSSL too old to verify keys easily " << OPENSSL_VERSION_TEXT << " needs to be 1.1.0 at least\n";
+#endif
+}
+
+void WopiProofTests::testExistingProof()
+{
+ verifySignature(
+ "yZhdN1qgywcOQWhyEMVpB6NE3pvBksvcLXsrFKXNtBeDTPW%2fu62g2t%2fOCWSlb3jUGaz1zc%2fzOzbNgAredLdhQI1Q7sPPqUv2owO78olmN74DV%2fv52OZIkBG%2b8jqjwmUobcjXVIC1BG9g%2fynMN0itZklL2x27Z2imCF6xELcQUuGdkoXBj%2bI%2bTlKM", // access token
+ "https://contoso.com/wopi/files/vHxYyRGM8VfmSGwGYDBMIQPzuE+sSC6kw+zWZw2Nyg?access_token=yZhdN1qgywcOQWhyEMVpB6NE3pvBksvcLXsrFKXNtBeDTPW%2fu62g2t%2fOCWSlb3jUGaz1zc%2fzOzbNgAredLdhQI1Q7sPPqUv2owO78olmN74DV%2fv52OZIkBG%2b8jqjwmUobcjXVIC1BG9g%2fynMN0itZklL2x27Z2imCF6xELcQUuGdkoXBj%2bI%2bTlKM", // uri
+ UINT64_C(635655897610773532), // ticks
+ "0HOWUPFFgmSYHbLZZzdWO/HUOr8YNfx5NAl7GUytooHZ7B9QxQKTJpj0NIJ4XEskQW8e4dLzRrPbNOOJ+KpWHttXz8HoQXkkZV/gYNxaNHJ8/pRXGMZzfVM5vchhx/2C7ULPTrpBsSpmfWQ6ShaVoQzfThFUd0MsBvIN7HVtqzPx9jbSV04wAqyNjcro7F3iu9w7AEsMejHbFlWoN+J05dP5ixryF7+2U5RVmjMt7/dYUdCoiXvCMt2CaVr0XEG6udHU4iDKVKZjmUBc7cTWRzhqEL7lZ1yQfylp38Nd2xxVJ0sSU7OkC1bBDlePcYGaF3JjJgsmp/H5BNnlW9gSxQ==", // modulus
+ "AQAB", // exponent
+ "IflL8OWCOCmws5qnDD5kYMraMGI3o+T+hojoDREbjZSkxbbx7XIS1Av85lohPKjyksocpeVwqEYm9nVWfnq05uhDNGp2MsNyhPO9unZ6w25Rjs1hDFM0dmvYx8wlQBNZ/CFPaz3inCMaaP4PtU85YepaDccAjNc1gikdy3kSMeG1XZuaDixHvMKzF/60DMfLMBIu5xP4Nt8i8Gi2oZs4REuxi6yxOv2vQJQ5+8Wu2Olm8qZvT4FEIQT9oZAXebn/CxyvyQv+RVpoU2gb4BreXAdfKthWF67GpJyhr+ibEVDoIIolUvviycyEtjsaEBpOf6Ne/OLRNu98un7WNDzMTQ=="); // message proof
+}
+
+void WopiProofTests::testOurProof()
+{
+ Proof gen(Proof::Type::CreateKey);
+
+ const VecOfStringPairs& discovery = gen.GetProofKeyAttributes();
+ int len = discovery.size();
+ LOK_ASSERT_EQUAL(3, len);
+ LOK_ASSERT_EQUAL(discovery[0].first, std::string("value"));
+ LOK_ASSERT_EQUAL(discovery[1].first, std::string("modulus"));
+ std::string modulus = discovery[1].second;
+ LOK_ASSERT_EQUAL(discovery[2].first, std::string("exponent"));
+ std::string exponent = discovery[2].second;
+
+ std::string access_token = "!££$%£^$-!---~@@{}OP";
+ std::string uri = "https://user@short.com:12345/blah?query_string=foo";
+ VecOfStringPairs pairs = gen.GetProofHeaders(access_token, uri);
+ len = pairs.size();
+ LOK_ASSERT_EQUAL(2, len);
+ LOK_ASSERT_EQUAL(pairs[0].first, std::string("X-WOPI-TimeStamp"));
+ std::string timestamp = pairs[0].second;
+ LOK_ASSERT_EQUAL(pairs[1].first, std::string("X-WOPI-Proof"));
+ std::string proof = pairs[1].second;
+
+ uint64_t ticks = std::stoull(timestamp.c_str(), nullptr, 10);
+ verifySignature(access_token, uri, ticks, modulus, exponent, proof);
}
CPPUNIT_TEST_SUITE_REGISTRATION(WopiProofTests);
diff --git a/wsd/ProofKey.cpp b/wsd/ProofKey.cpp
index b78499da0..01817ed8f 100644
--- a/wsd/ProofKey.cpp
+++ b/wsd/ProofKey.cpp
@@ -108,6 +108,29 @@ std::vector<unsigned char> Proof::Base64ToBytes(const std::string &str)
return vec;
}
+void Proof::initialize()
+{
+ if (m_pKey)
+ {
+ const auto m = m_pKey->modulus();
+ const auto e = m_pKey->encryptionExponent();
+ const auto capiBlob = RSA2CapiBlob(m, e);
+
+ m_aAttribs.emplace_back("value", BytesToBase64(capiBlob));
+ m_aAttribs.emplace_back("modulus", BytesToBase64(m));
+ m_aAttribs.emplace_back("exponent", BytesToBase64(e));
+ }
+
+}
+
+Proof::Proof(Type)
+ : m_pKey(new Poco::Crypto::RSAKey(
+ Poco::Crypto::RSAKey::KeyLength::KL_2048,
+ Poco::Crypto::RSAKey::Exponent::EXP_LARGE))
+{
+ initialize();
+}
+
Proof::Proof()
: m_pKey([]() -> Poco::Crypto::RSAKey* {
const auto keyPath = ProofKeyPath();
@@ -138,16 +161,7 @@ Proof::Proof()
return nullptr;
}())
{
- if (m_pKey)
- {
- const auto m = m_pKey->modulus();
- const auto e = m_pKey->encryptionExponent();
- const auto capiBlob = RSA2CapiBlob(m, e);
-
- m_aAttribs.emplace_back("value", BytesToBase64(capiBlob));
- m_aAttribs.emplace_back("modulus", BytesToBase64(m));
- m_aAttribs.emplace_back("exponent", BytesToBase64(e));
- }
+ initialize();
}
std::string Proof::ProofKeyPath()
diff --git a/wsd/ProofKey.hpp b/wsd/ProofKey.hpp
index 6fc29eb84..9ac3c7b1c 100644
--- a/wsd/ProofKey.hpp
+++ b/wsd/ProofKey.hpp
@@ -29,6 +29,9 @@ class WopiProofTests;
class Proof {
friend class WopiProofTests;
+ void initialize();
+ enum Type { CreateKey };
+ Proof(Type);
public:
Proof();
VecOfStringPairs GetProofHeaders(const std::string& access_token, const std::string& uri) const;
More information about the Libreoffice-commits
mailing list