[Libreoffice-commits] online.git: kit/ChildSession.cpp loleaflet/js loleaflet/src

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Nov 9 08:07:11 UTC 2018


 kit/ChildSession.cpp             |  100 +++++++++++++++++++++++++++++++++++++--
 loleaflet/js/toolbar.js          |    4 +
 loleaflet/src/control/Signing.js |   17 ++++++
 3 files changed, 118 insertions(+), 3 deletions(-)

New commits:
commit 37e1e208c218077c46c5370d2caf5be722e7452e
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Fri Nov 9 08:47:49 2018 +0100
Commit:     Tomaž Vajngerl <quikee at gmail.com>
CommitDate: Fri Nov 9 09:06:51 2018 +0100

    add "sign" function to infobar to sign with a one-time cert.
    
    In addition:
    - add methods to transport the certificate chain, signing
    certificate and signing certificate to WSD
    - add conversion of PEM cert. format to DER
    - add transporting the certificate chain to the LO core
    - run the signing function with the signing cert. and the
    private key
    
    Change-Id: I1a005e88cacbd81144df40d315197561401db427
    Reviewed-on: https://gerrit.libreoffice.org/63156
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
    Tested-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index 4e6c3ef7a..b775c6784 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -21,8 +21,11 @@
 #include <Poco/Net/WebSocket.h>
 #include <Poco/StringTokenizer.h>
 #include <Poco/URI.h>
+#include <Poco/BinaryReader.h>
+#include <Poco/Base64Decoder.h>
 
 #include <common/FileUtil.hpp>
+#include <common/JsonUtil.hpp>
 #include "KitHelper.hpp"
 #include <Log.hpp>
 #include <Png.hpp>
@@ -245,7 +248,9 @@ bool ChildSession::_handleInput(const char *buffer, int length)
                tokens[0] == "saveas" ||
                tokens[0] == "useractive" ||
                tokens[0] == "userinactive" ||
-               tokens[0] == "windowcommand");
+               tokens[0] == "windowcommand" ||
+               tokens[0] == "asksignaturestatus" ||
+               tokens[0] == "signdocument");
 
         if (tokens[0] == "clientzoom")
         {
@@ -1112,9 +1117,98 @@ bool ChildSession::sendWindowCommand(const char* /*buffer*/, int /*length*/, con
     return true;
 }
 
-bool ChildSession::signDocumentContent(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& /*tokens*/)
+namespace
 {
-    return true;
+
+std::string extractCertificate(const std::string & certificate)
+{
+    const std::string header("-----BEGIN CERTIFICATE-----");
+    const std::string footer("-----END CERTIFICATE-----");
+
+    std::string result;
+
+    size_t pos1 = certificate.find(header);
+    if (pos1 == std::string::npos)
+        return result;
+
+    size_t pos2 = certificate.find(footer, pos1 + 1);
+    if (pos2 == std::string::npos)
+        return result;
+
+    pos1 = pos1 + std::string(header).length();
+    pos2 = pos2 - pos1;
+
+    return certificate.substr(pos1, pos2);
+}
+
+std::string extractPrivateKey(const std::string & privateKey)
+{
+    const std::string header("-----BEGIN PRIVATE KEY-----");
+    const std::string footer("-----END PRIVATE KEY-----");
+
+    std::string result;
+
+    size_t pos1 = privateKey.find(header);
+    if (pos1 == std::string::npos)
+        return result;
+
+    size_t pos2 = privateKey.find(footer, pos1 + 1);
+    if (pos2 == std::string::npos)
+        return result;
+
+    pos1 = pos1 + std::string(header).length();
+    pos2 = pos2 - pos1;
+
+    return privateKey.substr(pos1, pos2);
+}
+
+std::vector<unsigned char> decodeBase64(const std::string & inputBase64)
+{
+    std::istringstream stream(inputBase64);
+    Poco::Base64Decoder base64Decoder(stream);
+    std::istreambuf_iterator<char> eos;
+    return std::vector<unsigned char>(std::istreambuf_iterator<char>(base64Decoder), eos);
+}
+
+}
+
+bool ChildSession::signDocumentContent(const char* buffer, int length, const std::vector<std::string>& /*tokens*/)
+{
+    bool bResult = true;
+
+    const std::string firstLine = getFirstLine(buffer, length);
+    const char* data = buffer + firstLine.size() + 1;
+    const int size = length - firstLine.size() - 1;
+    std::string json(data, size);
+
+    Poco::JSON::Parser parser;
+    Poco::JSON::Object::Ptr root = parser.parse(json).extract<Poco::JSON::Object::Ptr>();
+
+    for (auto& chainPtr : *root->getArray("chain"))
+    {
+        assert(chainPtr.isString());
+        std::string chainCertificate = chainPtr;
+        std::vector<unsigned char> binaryChainCertificate = decodeBase64(extractCertificate(chainCertificate));
+
+        bResult = getLOKitDocument()->addCertificate(
+            binaryChainCertificate.data(),
+            binaryChainCertificate.size());
+
+        if (!bResult)
+            return false;
+    }
+
+    std::string x509Certificate = JsonUtil::getJSONValue<std::string>(root, "x509Certificate");
+    std::vector<unsigned char> binaryCertificate = decodeBase64(extractCertificate(x509Certificate));
+
+    std::string privateKey = JsonUtil::getJSONValue<std::string>(root, "privateKey");
+    std::vector<unsigned char> binaryPrivateKey = decodeBase64(extractPrivateKey(privateKey));
+
+    bResult = getLOKitDocument()->insertCertificate(
+                    binaryCertificate.data(), binaryCertificate.size(),
+                    binaryPrivateKey.data(), binaryPrivateKey.size());
+
+    return bResult;
 }
 
 bool ChildSession::askSignatureStatus(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& /*tokens*/)
diff --git a/loleaflet/js/toolbar.js b/loleaflet/js/toolbar.js
index 53a3a1b7b..51b84902c 100644
--- a/loleaflet/js/toolbar.js
+++ b/loleaflet/js/toolbar.js
@@ -234,6 +234,9 @@ function onClick(e, id, item, subItem) {
 	else if (id === 'logout') {
 		map.signingLogout();
 	}
+	else if (id === 'sign') {
+		map.signDocument();
+	}
 }
 
 function setBorders(left, right, bottom, top, horiz, vert) {
@@ -767,6 +770,7 @@ function createToolbar() {
 		items: [
 			{type: 'html',  id: 'left'},
 			{type: 'html', id: 'logo', html: '<p><b>Vereign</b></p>'},
+			{type: 'button',  id: 'sign',  caption: 'Sign', img: '', hint: _('Sign document')},
 			{type: 'break' },
 			{type: 'html', id: 'user-label', html: '<p>User:</p>'},
 			{type: 'html', id: 'user', html: '<none>'},
diff --git a/loleaflet/src/control/Signing.js b/loleaflet/src/control/Signing.js
index 58191aa4d..0264d2b0c 100644
--- a/loleaflet/src/control/Signing.js
+++ b/loleaflet/src/control/Signing.js
@@ -34,6 +34,23 @@ L.Map.include({
 	showSignDocument: function() {
 		this.signingLogin();
 	},
+	signDocument: function() {
+		if (library) {
+			var map = this;
+			library.getCurrentlyLoggedInUUID().then(function(result) {
+				if (isSuccess(result)) {
+					var UUID = result.data;
+					library.getOneTimeCertificateByPassport(UUID).then(function(result) {
+						if (isSuccess(result)) {
+							var otp = result.data;
+							var blob = new Blob(['signdocument\n', JSON.stringify(otp)]);
+							map._socket.sendMessage(blob);
+						}
+					});
+				}
+			});
+		}
+	},
 	signingLogout: function() {
 		if (library) {
 			library.logout().then(function(result) {


More information about the Libreoffice-commits mailing list