[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