summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
authorAndrew Morgan <andrew@amorgan.xyz>2019-04-01 14:09:33 +0100
committerAndrew Morgan <andrew@amorgan.xyz>2019-04-01 14:09:33 +0100
commit91460594195350a23b0c6ea5cffdcbfc55f0b00d (patch)
treed4aa971f022196f2470ae399cd530d0f0de57571 /synapse
parentWhitelist per domain (diff)
downloadsynapse-91460594195350a23b0c6ea5cffdcbfc55f0b00d.tar.xz
Ability to specify list of custom CA certificates
Diffstat (limited to 'synapse')
-rw-r--r--synapse/config/tls.py43
-rw-r--r--synapse/crypto/context_factory.py5
2 files changed, 47 insertions, 1 deletions
diff --git a/synapse/config/tls.py b/synapse/config/tls.py
index f0014902da..5e4ed8289d 100644
--- a/synapse/config/tls.py
+++ b/synapse/config/tls.py
@@ -19,6 +19,8 @@ import warnings
 from datetime import datetime
 from hashlib import sha256
 
+from twisted.internet._sslverify import trustRootFromCertificates, Certificate
+
 import six
 
 from unpaddedbase64 import encode_base64
@@ -70,6 +72,37 @@ class TlsConfig(Config):
 
         self.tls_fingerprints = list(self._original_tls_fingerprints)
 
+        # List of custom certificate authorities for TLS verification
+        self.federation_custom_ca_list = config.get(
+            "federation_custom_ca_list", [],
+        )
+
+        # Read in the CA certificates
+        cert_contents = []
+        try:
+            for ca_file in self.federation_custom_ca_list:
+                logger.debug("Reading custom CA certificate file: %s", ca_file)
+                with open(ca_file, 'rb') as f:
+                    cert_contents.append(ca_file.read())
+        except:
+            logger.exception("Failed to read custom CA certificate off disk!")
+            raise
+
+        # Parse the CA certificates
+        certs = []
+        try:
+            for cert in certs:
+                logger.debug("Parsing custom CA certificate file: %s", ca_file)
+                cert_base = Certificate.loadPEM(content)
+                certs.append(cert_base)
+
+            trust_root = trustRootFromCertificates(certs)
+        except:
+            logger.exception("Failed to parse custom CA certificate off disk!")
+            raise
+
+        self.federation_custom_ca_list = trust_root
+
         # This config option applies to non-federation HTTP clients
         # (e.g. for talking to recaptcha, identity servers, and such)
         # It should never be used in production, and is intended for
@@ -192,6 +225,16 @@ class TlsConfig(Config):
         #
         #tls_private_key_path: "%(tls_private_key_path)s"
 
+        # List of custom certificate authorities for federation traffic.
+        #
+        # Note that this list will replace those that are provided by your
+        # operating environment. Certificates must be in PEM format.
+        #
+        #federation_custom_ca_list:
+        #  - myca1.pem
+        #  - myca2.pem
+        #  - myca3.pem
+
         # ACME support: This will configure Synapse to request a valid TLS certificate
         # for your configured `server_name` via Let's Encrypt.
         #
diff --git a/synapse/crypto/context_factory.py b/synapse/crypto/context_factory.py
index b99159dbbd..7f747cd55a 100644
--- a/synapse/crypto/context_factory.py
+++ b/synapse/crypto/context_factory.py
@@ -128,7 +128,10 @@ class ClientTLSOptionsFactory(object):
 
     def __init__(self, config):
         # We don't use config options yet
-        self._options_validate = CertificateOptions(verify=True)
+        self._options_validate = CertificateOptions(
+            # This option implies verify=True
+            trustRoot=config.federation_custom_ca_list,
+        )
         self._options_novalidate = CertificateOptions(verify=False)
 
     def get_options(self, host, config):