changeset 4190:9ce5c89328f5

New configuration options to enable HTTP peers identification through certificates
author Alain Mazy <alain@mazy.be>
date Tue, 15 Sep 2020 15:47:28 +0200
parents 15572f0bd743
children 30ebe460e77a
files NEWS OrthancFramework/Sources/HttpServer/HttpServer.cpp OrthancFramework/Sources/HttpServer/HttpServer.h OrthancServer/Resources/Configuration.json OrthancServer/Sources/main.cpp
diffstat 5 files changed, 71 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Tue Sep 15 08:27:17 2020 +0200
+++ b/NEWS	Tue Sep 15 15:47:28 2020 +0200
@@ -1,6 +1,15 @@
 Pending changes in the mainline
 ===============================
 
+General
+-------
+
+* New configuration options to enable HTTP peers identification through certificates:
+  "SslVerifyPeers" & "SslTrustedClientCertificates"
+* New configuration option "SyncStorageArea" to commit the files on disk "inside" the DB
+  transaction and avoid DB - File system discrepencies in case of hard shutdown 
+  of the machine running Orthanc.  This comes with a cost: DICOM file ingestion is slower.
+
 Maintenance
 -----------
 
@@ -10,7 +19,7 @@
 * When checking DICOM allowed methods, if there are multiple modalities with the same AET, 
   differentiate them from the calling IP
 * Enable the access to raw frames in Philips ELSCINT1 proprietary compression
-* New configuration option "SyncStorageArea"
+
 
 
 Version 1.7.3 (2020-08-24)
--- a/OrthancFramework/Sources/HttpServer/HttpServer.cpp	Tue Sep 15 08:27:17 2020 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpServer.cpp	Tue Sep 15 15:47:28 2020 +0200
@@ -1060,6 +1060,7 @@
     remoteAllowed_ = false;
     authentication_ = false;
     ssl_ = false;
+    sslVerifyPeers_ = false;
     port_ = 8000;
     filter_ = NULL;
     keepAlive_ = false;
@@ -1150,6 +1151,11 @@
         // Set the timeout for the HTTP server
         "request_timeout_ms", requestTimeoutMilliseconds.c_str(),
 
+        // Set the client authentication
+        "ssl_verify_peer", (sslVerifyPeers_ ? "yes" : "no"),
+        // Set the trusted client certificates (for X509 mutual authentication)
+        sslVerifyPeers_ ? "ssl_ca_file" : NULL, trustedClientCertificates_.c_str(),
+
         // Set the SSL certificate, if any. This must be the last option.
         ssl_ ? "ssl_certificate" : NULL,
         certificate_.c_str(),
@@ -1257,6 +1263,23 @@
 #endif
   }
 
+  void HttpServer::SetSslVerifyPeers(bool enabled)
+  {
+    Stop();
+
+#if ORTHANC_ENABLE_SSL == 0
+    if (enabled)
+    {
+      throw OrthancException(ErrorCode_SslDisabled);
+    }
+    else
+    {
+      sslVerifyPeers_ = false;
+    }
+#else
+    sslVerifyPeers_ = enabled;
+#endif
+  }
 
   void HttpServer::SetKeepAliveEnabled(bool enabled)
   {
@@ -1285,6 +1308,12 @@
     certificate_ = path;
   }
 
+  void HttpServer::SetSslTrustedClientCertificates(const char* path)
+  {
+    Stop();
+    trustedClientCertificates_ = path;
+  }
+
   void HttpServer::SetRemoteAccessAllowed(bool allowed)
   {
     Stop();
--- a/OrthancFramework/Sources/HttpServer/HttpServer.h	Tue Sep 15 08:27:17 2020 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpServer.h	Tue Sep 15 15:47:28 2020 +0200
@@ -80,6 +80,8 @@
 
     bool remoteAllowed_;
     bool authentication_;
+    bool sslVerifyPeers_;
+    std::string trustedClientCertificates_;
     bool ssl_;
     std::string certificate_;
     uint16_t port_;
@@ -129,6 +131,10 @@
 
     void SetSslEnabled(bool enabled);
 
+    void SetSslVerifyPeers(bool enabled);
+
+    void SetSslTrustedClientCertificates(const char* path);
+
     bool IsKeepAliveEnabled() const
     {
       return keepAlive_;
--- a/OrthancServer/Resources/Configuration.json	Tue Sep 15 08:27:17 2020 +0200
+++ b/OrthancServer/Resources/Configuration.json	Tue Sep 15 15:47:28 2020 +0200
@@ -147,10 +147,22 @@
   // Whether or not SSL is enabled
   "SslEnabled" : false,
 
-  // Path to the SSL certificate in the PEM format (meaningful only if
-  // SSL is enabled)
+  // Path to the SSL certificate used by the HTTP server.
+  // Certifcate must be stored in the PEM format.
+  // meaningful only if SslEnabled is true. 
+  // The file must contain both the certificate and the private key.
   "SslCertificate" : "certificate.pem",
 
+  // Whether or not peer client certificates shall be checked.
+  // meaningfull only if SslEnabled is true
+  "SslVerifyPeers" : false,
+
+  // Path to the SSL certificate(s) that are trusted to verify
+  // peers identify. 
+  // Certifcate(s) must be stored in the PEM format.
+  // meaningfull only if SslVerifyPeers is true
+  "SslTrustedClientCertificates" : "trustedClientCertificates.pem",
+  
   // Whether or not the password protection is enabled (using HTTP
   // basic access authentication). Starting with Orthanc 1.5.8, if
   // "AuthenticationEnabled" is not explicitly set, authentication is
--- a/OrthancServer/Sources/main.cpp	Tue Sep 15 08:27:17 2020 +0200
+++ b/OrthancServer/Sources/main.cpp	Tue Sep 15 15:47:28 2020 +0200
@@ -1017,6 +1017,18 @@
         httpServer.SetSslEnabled(false);
       }
 
+      if (lock.GetConfiguration().GetBooleanParameter("SslVerifyPeers", false))
+      {
+        std::string trustedClientCertificates = lock.GetConfiguration().InterpretStringParameterAsPath(
+          lock.GetConfiguration().GetStringParameter("SslTrustedClientCertificates", "trustedCertificates.pem"));
+        httpServer.SetSslVerifyPeers(true);
+        httpServer.SetSslTrustedClientCertificates(trustedClientCertificates.c_str());
+      }
+      else
+      {
+        httpServer.SetSslVerifyPeers(false);
+      }
+
       if (lock.GetConfiguration().GetBooleanParameter("ExecuteLuaEnabled", false))
       {
         context.SetExecuteLuaEnabled(true);