loolwsd.xml.in     |    7 ++++++
 wsd/FileServer.cpp |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 wsd/LOOLWSD.cpp    |    4 +++
 3 files changed, 68 insertions(+)

New commits:
commit 8db2911cd45a059262814f78b286d9419eab2045
Author: Pranav Kant <pran...@collabora.co.uk>
Date:   Mon Apr 10 13:42:29 2017 +0530

    security: Implement HTTP Public key pinning
    
    Though this guard the user against MITM attacks, but enabling this also
    has the potential to brick your websites. So, do not use it/enable it
    without understanding what it actually is.
    
    See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning
    
    Though this should work, but I have not been able to test it because of
    Firefox and Chrome's limitation/feature that key validation is not done
    when certificate chain terminates at a user-defined trust anchor and I
    couldn't find any way to temporarily enable the HPKP key validation for
    such CA chains.
    
    Change-Id: I64d4ff82b04c59642fa7b8bac2f8788a03950b28
    Reviewed-on: https://gerrit.libreoffice.org/36357
    Reviewed-by: pranavk <pran...@collabora.co.uk>
    Tested-by: pranavk <pran...@collabora.co.uk>
    (cherry picked from commit 1437a060ec9eb24c4b33fcbb1ed76950a861da81)
    Reviewed-on: https://gerrit.libreoffice.org/36379

diff --git a/loolwsd.xml.in b/loolwsd.xml.in
index a37ec2b5..511b5479 100644
--- a/loolwsd.xml.in
+++ b/loolwsd.xml.in
@@ -51,6 +51,13 @@
         <cert_file_path desc="Path to the cert file" 
relative="false">/etc/loolwsd/cert.pem</cert_file_path>
         <key_file_path desc="Path to the key file" 
relative="false">/etc/loolwsd/key.pem</key_file_path>
         <ca_file_path desc="Path to the ca file" 
relative="false">/etc/loolwsd/ca-chain.cert.pem</ca_file_path>
+       <hpkp desc="Enable HTTP Public key pinning" enable="false" 
report_only="false">
+           <max_age desc="HPKP's max-age directive - time in seconds browser 
should remember the pins" enable="true">1000</max_age>
+           <report_uri desc="HPKP's report-uri directive - pin validation 
failure are reported at this URL" enable="false"></report_uri>
+           <pins desc="Base64 encoded SPKI fingerprints of keys to be pinned">
+             <pin></pin>
+           </pins>
+       </hpkp>
     </ssl>
 
     <storage desc="Backend storage">
diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp
index 9f056903..b8448ddb 100644
--- a/wsd/FileServer.cpp
+++ b/wsd/FileServer.cpp
@@ -357,6 +357,63 @@ void FileServerRequestHandler::preprocessFile(const 
HTTPRequest& request, Poco::
         oss << "X-Frame-Options: deny\r\n";
     }
 
+    // Setup HTTP Public key pinning
+    if (LOOLWSD::isSSLEnabled() && config.getBool("ssl.hpkp[@enable]", false))
+    {
+        size_t i = 0;
+        std::string pinPath = "ssl.hpkp.pins.pin[" + std::to_string(i) + "]";
+        std::ostringstream hpkpOss;
+        bool keysPinned = false;
+        while (config.has(pinPath))
+        {
+            const auto pin = config.getString(pinPath, "");
+            if (!pin.empty())
+            {
+                hpkpOss << "pin-sha256=\"" << pin << "\"; ";
+                keysPinned = true;
+            }
+            pinPath = "ssl.hpkp.pins.pin[" + std::to_string(++i) + "]";
+        }
+
+        if (keysPinned && config.getBool("ssl.hpkp.max_age[@enable]", false))
+        {
+            int maxAge = 1000; // seconds
+            try
+            {
+                maxAge = config.getInt("ssl.hpkp.max_age", maxAge);
+            }
+            catch (Poco::SyntaxException& exc)
+            {
+                LOG_WRN("Invalid value of HPKP's max-age directive found in 
config file. Defaulting to "
+                        << maxAge);
+            }
+            hpkpOss << "max-age=" << maxAge << "; ";
+        }
+
+        if (keysPinned && config.getBool("ssl.hpkp.report_uri[@enable]", 
false))
+        {
+            const std::string reportUri = 
config.getString("ssl.hpkp.report_uri", "");
+            if (!reportUri.empty())
+            {
+                hpkpOss << "report-uri=" << reportUri << "; ";
+            }
+        }
+
+        if (!hpkpOss.str().empty())
+        {
+            if (config.getBool("ssl.hpkp[@report_only]", false))
+            {
+                // Only send validation failure reports to reportUri while 
still allowing UAs to
+                // connect to the server
+                oss << "Public-Key-Pins-Report-Only: " << hpkpOss.str() << 
"\r\n";
+            }
+            else
+            {
+                oss << "Public-Key-Pins: " << hpkpOss.str() << "\r\n";
+            }
+        }
+    }
+
     oss << "\r\n"
         << preprocess;
 
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 2d1c6779..0f91598e 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -623,6 +623,10 @@ void LOOLWSD::initialize(Application& self)
             { "ssl.cert_file_path", LOOLWSD_CONFIGDIR "/cert.pem" },
             { "ssl.key_file_path", LOOLWSD_CONFIGDIR "/key.pem" },
             { "ssl.ca_file_path", LOOLWSD_CONFIGDIR "/ca-chain.cert.pem" },
+            { "ssl.hpkp[@enable]", "false" },
+            { "ssl.hpkp[@report_only]", "false" },
+            { "ssl.hpkp.max_age[@enable]", "true" },
+            { "ssl.hpkp.report_uri[@enable]", "false" },
             { "storage.filesystem[@allow]", "false" },
             { "storage.wopi[@allow]", "true" },
             { "storage.wopi.host[0][@allow]", "true" },
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to