Beispiel #1
0
 def __init__(self, certificate):
     if not isinstance(certificate, Certificate):
         if os.path.isfile(certificate):
             certificate = Certificate.loadPEM(open(certificate).read())
         else:
             certificate = Certificate.loadPEM(certificate)
     self._original = certificate
     self.certificate = certificate.dumpPEM()
Beispiel #2
0
    def main(self, reactor, options):
        certificates_path = FilePath(options["certificates-directory"])
        ca = Certificate.loadPEM(
            certificates_path.child(b"cluster.crt").getContent())
        # This is a hack; from_path should be more
        # flexible. https://clusterhq.atlassian.net/browse/FLOC-1865
        control_credential = ControlCredential.from_path(
            certificates_path, b"service")

        top_service = MultiService()
        persistence = ConfigurationPersistenceService(
            reactor, options["data-path"])
        persistence.setServiceParent(top_service)
        cluster_state = ClusterStateService(reactor)
        cluster_state.setServiceParent(top_service)
        api_service = create_api_service(
            persistence, cluster_state, serverFromString(
                reactor, options["port"]),
            rest_api_context_factory(ca, control_credential))
        api_service.setServiceParent(top_service)
        amp_service = ControlAMPService(
            reactor, cluster_state, persistence, serverFromString(
                reactor, options["agent-port"]),
            amp_server_context_factory(ca, control_credential))
        amp_service.setServiceParent(top_service)
        return main_for_service(reactor, top_service)
Beispiel #3
0
    def main(self, reactor, options):
        certificates_path = FilePath(options["certificates-directory"])
        ca = Certificate.loadPEM(
            certificates_path.child(b"cluster.crt").getContent())
        # This is a hack; from_path should be more
        # flexible. https://clusterhq.atlassian.net/browse/FLOC-1865
        control_credential = ControlCredential.from_path(
            certificates_path, b"service")

        top_service = MultiService()
        persistence = ConfigurationPersistenceService(reactor,
                                                      options["data-path"])
        persistence.setServiceParent(top_service)
        cluster_state = ClusterStateService(reactor)
        cluster_state.setServiceParent(top_service)
        api_service = create_api_service(
            persistence, cluster_state,
            serverFromString(reactor, options["port"]),
            rest_api_context_factory(ca, control_credential))
        api_service.setServiceParent(top_service)
        amp_service = ControlAMPService(
            reactor, cluster_state, persistence,
            serverFromString(reactor, options["agent-port"]),
            amp_server_context_factory(ca, control_credential))
        amp_service.setServiceParent(top_service)
        return main_for_service(reactor, top_service)
Beispiel #4
0
 def test_ssl(self):
     """
     When passed an SSL strports description, L{clientFromString} returns a
     L{SSL4ClientEndpoint} instance initialized with the values from the
     string.
     """
     reactor = object()
     client = endpoints.clientFromString(
         reactor, "ssl:host=example.net:port=4321:privateKey=%s:"
         "certKey=%s:bindAddress=10.0.0.3:timeout=3:caCertsDir=%s" %
         (escapedPEMPathName, escapedPEMPathName, escapedCAsPathName))
     self.assertIsInstance(client, endpoints.SSL4ClientEndpoint)
     self.assertIdentical(client._reactor, reactor)
     self.assertEquals(client._host, "example.net")
     self.assertEquals(client._port, 4321)
     self.assertEquals(client._timeout, 3)
     self.assertEquals(client._bindAddress, "10.0.0.3")
     certOptions = client._sslContextFactory
     self.assertIsInstance(certOptions, CertificateOptions)
     ctx = certOptions.getContext()
     self.assertIsInstance(ctx, ContextType)
     self.assertEquals(Certificate(certOptions.certificate),
                       testCertificate)
     privateCert = PrivateCertificate(certOptions.certificate)
     privateCert._setPrivateKey(KeyPair(certOptions.privateKey))
     self.assertEquals(privateCert, testPrivateCertificate)
     expectedCerts = [
         Certificate.loadPEM(x.getContent()) for x in
         [casPath.child("thing1.pem"),
          casPath.child("thing2.pem")]
         if x.basename().lower().endswith('.pem')
     ]
     self.assertEquals([Certificate(x) for x in certOptions.caCerts],
                       expectedCerts)
Beispiel #5
0
    def connect(self, host=None, port=None, cert=None, key=None):
        '''
        Connect to another portal somewhere. If retry is set, will attempt to reconnect
        with the target continuously. As of the time of this writing, you cannot stop a 
        polling connection without taking down the portal.

        :param retry: continuously attempt to connect on drops or rejections
        :type retry: bool.
        '''

        host = host if host else self.host
        port = port if port else self.port
        cert = cert if cert else self.certCa
        key = key if key else self.keyPrivate  # ???

        # the first term is the name the server is using in the cert (for now)
        ctx = optionsForClientTLS(u"pds.production", Certificate.loadPEM(cert), PrivateCertificate.loadPEM(key))

        factory = RiffleClientFactory()
        SSL4ClientEndpoint(reactor, host, port, ctx,).connect(factory)

        print 'Connecting to ' + host + ':' + str(port)
        avatar = yield factory.login(self)

        defer.returnValue(Levy(avatar))
Beispiel #6
0
def get_configuration(options):
    """
    Load and validate the configuration in the file specified by the given
    options.

    :param DatasetAgentOptions options: The dataset agent options specifying
        the location of the configuration.

    :return: A ``dict`` representing the configuration loaded from the file.
    """
    agent_config = options[u'agent-config']
    configuration = yaml.safe_load(agent_config.getContent())

    validate_configuration(configuration=configuration)

    configuration['control-service'].setdefault('port', 4524)

    path = agent_config.parent()
    # This is a hack; from_path should be more
    # flexible. https://clusterhq.atlassian.net/browse/FLOC-1865
    configuration['ca-certificate'] = Certificate.loadPEM(
        path.child(b"cluster.crt").getContent())
    configuration['node-credential'] = NodeCredential.from_path(path, b"node")

    return configuration
Beispiel #7
0
def get_context_factory(cert_path, pkey_path):
    """OpenSSL context factory.

    Generates an OpenSSL context factory using Twisted's CertificateOptions class.
    This will keep a server cipher order.

    Args:
        cert_path (string): The path to the certificate file
        pkey_path (string): The path to the private key file

    Returns:
        twisted.internet.ssl.CertificateOptions: An OpenSSL context factory
    """

    with open(cert_path) as cert:
        certificate = Certificate.loadPEM(cert.read()).original
    with open(pkey_path) as pkey:
        private_key = KeyPair.load(pkey.read(), FILETYPE_PEM).original
    ciphers = AcceptableCiphers.fromOpenSSLCipherString(TLS_CIPHERS)
    cert_options = CertificateOptions(
        privateKey=private_key,
        certificate=certificate,
        raiseMinimumTo=TLSVersion.TLSv1_2,
        acceptableCiphers=ciphers,
    )
    ctx = cert_options.getContext()
    ctx.use_certificate_chain_file(cert_path)
    ctx.set_options(SSL_OP_NO_RENEGOTIATION)

    return cert_options
Beispiel #8
0
def get_configuration(options):
    """
    Load and validate the configuration in the file specified by the given
    options.

    :param DatasetAgentOptions options: The dataset agent options specifying
        the location of the configuration.

    :return: A ``dict`` representing the configuration loaded from the file.
    """
    agent_config = options[u'agent-config']
    configuration = yaml.safe_load(agent_config.getContent())

    validate_configuration(configuration=configuration)

    configuration['control-service'].setdefault('port', 4524)

    path = agent_config.parent()
    # This is a hack; from_path should be more
    # flexible. https://clusterhq.atlassian.net/browse/FLOC-1865
    configuration['ca-certificate'] = Certificate.loadPEM(
        path.child(b"cluster.crt").getContent())
    configuration['node-credential'] = NodeCredential.from_path(path, b"node")

    return configuration
Beispiel #9
0
 def getCertificate(self, subject):
     log.msg(format='Retreving certificate for %(name)s',
             name=subject)
     certPath = self.publicPath.child(subject)
     if not certPath.exists():
         raise CertificateNotFound
     cert = Certificate.loadPEM(certPath.getContent())
     return defer.succeed(cert)
Beispiel #10
0
def _get_http_client():
    response = yield treq.get(ca)
    pemdata = yield response.text()
    cert = Certificate.loadPEM(pemdata)
    policy = BrowserLikePolicyForHTTPS(trustRoot=cert)
    agent = Agent(reactor, contextFactory=policy)
    client = treq.client.HTTPClient(agent)
    returnValue(client)
Beispiel #11
0
def main(reactor):
    pemBytes = FilePath(b"ca-private-cert.pem").getContent()
    certificateAuthority = Certificate.loadPEM(pemBytes)
    myCertificate = PrivateCertificate.loadPEM(pemBytes)
    serverEndpoint = SSL4ServerEndpoint(
        reactor, 4321, myCertificate.options(certificateAuthority))
    serverEndpoint.listen(Factory.forProtocol(ReportWhichClient))
    return Deferred()
    def loadPEM(cls, pemData):
        cert = X509Certificate()
        cert.__internalTwistedCert = Certificate.loadPEM(pemData)

        asn1cert = decoder.decode(pem.readPemFromFile(StringIO(pemData)),
                                  asn1Spec=rfc2459.Certificate())[0]
        cert.__internalAsn1 = asn1cert

        return cert
Beispiel #13
0
def main(reactor):
    pemBytes = FilePath(b"ca-private-cert.pem").getContent()
    certificateAuthority = Certificate.loadPEM(pemBytes)
    myCertificate = PrivateCertificate.loadPEM(pemBytes)
    serverEndpoint = SSL4ServerEndpoint(
        reactor, 4321, myCertificate.options(certificateAuthority)
    )
    serverEndpoint.listen(Factory.forProtocol(ReportWhichClient))
    return Deferred()
Beispiel #14
0
def main(reactor):
    pem = generate_certs.and_generate()
    caPem = FilePath(b"ca-private-cert.pem").getContent()
    clientEndpoint = SSL4ClientEndpoint(
        reactor,
        u"localhost",
        4321,
        optionsForClientTLS(u"the-authority", Certificate.loadPEM(caPem),
                            PrivateCertificate.loadPEM(pem)),
    )
    clientEndpoint = SSL4ClientEndpoint(
        reactor,
        u"localhost",
        4321,
        optionsForClientTLS(u"the-authority", Certificate.loadPEM(caPem),
                            PrivateCertificate.loadPEM(pem)),
    )
    proto = yield clientEndpoint.connect(Factory.forProtocol(SendAnyData))
    yield proto.deferred
Beispiel #15
0
 def getTlsAuthority_(self, startTlsCaCert):
     if startTlsCaCert is None:
         return None
     authorities = [str(cert) for cert in pem.parse_file(startTlsCaCert)]
     if len(authorities) != 1:
         raise Exception(
             ("The provided CA cert file, '{0}', "
              "contained {1} certificates.  It must contain exactly one."
              ).format(startTlsCaCert, len(authorities)))
     return Certificate.loadPEM(authorities[0])
Beispiel #16
0
 def getTlsAuthority_(self, startTlsCaCert):
     if startTlsCaCert is None:
         return None
     authorities = [str(cert) for cert in pem.parse_file(startTlsCaCert)] 
     if len(authorities) != 1:
         raise Exception(
             ("The provided CA cert file, '{0}', "
             "contained {1} certificates.  It must contain exactly one.").format(
                 startTlsCaCert, len(authorities)))
     return Certificate.loadPEM(authorities[0])
Beispiel #17
0
    def open(self, port=None, cert=None):
        '''
        Listen for connections on the given port. 
        '''
        port = port if port else self.port
        cert = cert if cert else self.certCa

        ca = Certificate.loadPEM(cert)
        myCertificate = PrivateCertificate.loadPEM(cert)

        SSL4ServerEndpoint(reactor, port, myCertificate.options(ca)).listen(RiffleServerFactory(self))
Beispiel #18
0
def get_test_https_policy():
    """Get a test IPolicyForHTTPS which trusts the test CA cert

    Returns:
        IPolicyForHTTPS
    """
    ca_file = get_test_ca_cert_file()
    with open(ca_file) as stream:
        content = stream.read()
    cert = Certificate.loadPEM(content)
    trust_root = trustRootFromCertificates([cert])
    return BrowserLikePolicyForHTTPS(trustRoot=trust_root)
Beispiel #19
0
def start_ssl_cmd_server():
    with open(settings["Agent_Cert"], 'r') as certfile:
        certdata = certfile.read()
    if settings["Agent_Priv_Key"] != settings["Agent_Cert"]:
        with open(settings.get("Agent_Priv_Key"), 'r') as keyfile:
            certdata += keyfile.read()
    with open(settings.get("Broker_Cert"), 'r') as f:
        authdata = f.read()
    certificate = PrivateCertificate.loadPEM(certdata)
    authority = Certificate.loadPEM(authdata)
    factory = Factory.forProtocol(CommandHandler)
    reactor.listenSSL(int(settings.get("Command_Port")), factory, certificate.options(authority))
Beispiel #20
0
    def start_ssl(self):
        log.debug("Enabling SSL with PKey: %s, Cert: %s", self.pkey, self.cert)
        check_ssl_keys()

        with open(configmanager.get_config_dir(self.cert)) as cert:
            certificate = Certificate.loadPEM(cert.read()).original
        with open(configmanager.get_config_dir(self.pkey)) as pkey:
            private_key = KeyPair.load(pkey.read(), FILETYPE_PEM).original
        options = CertificateOptions(privateKey=private_key, certificate=certificate, method=SSL.SSLv23_METHOD)
        options.getContext().set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3)

        self.socket = reactor.listenSSL(self.port, self.site, options)
        log.info("Serving on %s:%s view at https://127.0.0.1:%s", "0.0.0.0", self.port, self.port)
Beispiel #21
0
def start_ssl_cmd_server():
    with open(settings["Agent_Cert"], 'r') as certfile:
        certdata = certfile.read()
    if settings["Agent_Priv_Key"] != settings["Agent_Cert"]:
        with open(settings.get("Agent_Priv_Key"), 'r') as keyfile:
            certdata += keyfile.read()
    with open(settings.get("Broker_Cert"), 'r') as f:
        authdata = f.read()
    certificate = PrivateCertificate.loadPEM(certdata)
    authority = Certificate.loadPEM(authdata)
    factory = Factory.forProtocol(CommandHandler)
    reactor.listenSSL(int(settings.get("Command_Port")), factory,
                      certificate.options(authority))
Beispiel #22
0
    def fromFilePath(cls, filePath):
        privatePath = filePath.child('private')
        publicPath = filePath.child('public')
        csrPath = filePath.child('csr')

        issuerPath = filePath.child('issuer')
        if issuerPath.exists():
            issuer = issuerPath.getContent()
            key = KeyPair.loadPEM(privatePath.child(issuer).getContent())
            cert = Certificate.loadPEM(publicPath.child(issuer).getContent())

        store = cls(publicPath, privatePath, csrPath, key, cert, issuer)
        return store
Beispiel #23
0
def _create_tls_client_context(config, cbdir, log):
    """
    Create a CertificateOptions object for use with TLS listening endpoints.
    """
    # server hostname: The expected name of the remote host.
    hostname = config['hostname']

    # explicit trust (certificate) root
    ca_certs = None
    if 'ca_certificates' in config:
        log.info("TLS client using explicit trust ({cnt_certs} certificates)", cnt_certs=len(config['ca_certificates']))
        ca_certs = []
        for cert_fname in [os.path.abspath(os.path.join(cbdir, x)) for x in (config['ca_certificates'])]:
            cert = crypto.load_certificate(
                crypto.FILETYPE_PEM,
                six.u(open(cert_fname, 'r').read())
            )
            log.info("TLS client trust root CA certificate loaded from '{fname}'", fname=cert_fname)
            ca_certs.append(cert)
        ca_certs = OpenSSLCertificateAuthorities(ca_certs)
    else:
        log.info("TLS client using platform trust")

    # client key/cert to use
    client_cert = None
    if 'key' in config:
        if 'certificate' not in config:
            raise Exception('TLS client key present, but certificate missing')

        key_fname = os.path.abspath(os.path.join(cbdir, config['key']))
        with open(key_fname, 'r') as f:
            private_key = KeyPair.load(f.read(), format=crypto.FILETYPE_PEM)
            log.info("Loaded client TLS key from '{key_fname}'", key_fname=key_fname)

        cert_fname = os.path.abspath(os.path.join(cbdir, config['certificate']))
        with open(cert_fname, 'r') as f:
            cert = Certificate.loadPEM(f.read(),)
            log.info("Loaded client TLS certificate from '{cert_fname}' (cn='{cert_cn}', sha256={cert_sha256}..)",
                     cert_fname=cert_fname,
                     cert_cn=cert.getSubject().CN,
                     cert_sha256=cert.digest('sha256')[:12])

        client_cert = PrivateCertificate.fromCertificateAndKeyPair(cert, private_key)
    else:
        if 'certificate' in config:
            log.warn('TLS client certificate present, but key is missing')

    # create TLS client context
    ctx = optionsForClientTLS(hostname, trustRoot=ca_certs, clientCertificate=client_cert)

    return ctx
Beispiel #24
0
def _create_tls_client_context(config, cbdir, log):
    """
    Create a CertificateOptions object for use with TLS listening endpoints.
    """
    # server hostname: The expected name of the remote host.
    hostname = config['hostname']

    # explicit trust (certificate) root
    ca_certs = None
    if 'ca_certificates' in config:
        log.info("TLS client using explicit trust ({cnt_certs} certificates)", cnt_certs=len(config['ca_certificates']))
        ca_certs = []
        for cert_fname in [os.path.abspath(os.path.join(cbdir, x)) for x in (config['ca_certificates'])]:
            cert = crypto.load_certificate(
                crypto.FILETYPE_PEM,
                six.u(open(cert_fname, 'r').read())
            )
            log.info("TLS client trust root CA certificate loaded from '{fname}'", fname=cert_fname)
            ca_certs.append(cert)
        ca_certs = OpenSSLCertificateAuthorities(ca_certs)
    else:
        log.info("TLS client using platform trust")

    # client key/cert to use
    client_cert = None
    if 'key' in config:
        if 'certificate' not in config:
            raise Exception('TLS client key present, but certificate missing')

        key_fname = os.path.abspath(os.path.join(cbdir, config['key']))
        with open(key_fname, 'r') as f:
            private_key = KeyPair.load(f.read(), format=crypto.FILETYPE_PEM)
            log.info("Loaded client TLS key from '{key_fname}'", key_fname=key_fname)

        cert_fname = os.path.abspath(os.path.join(cbdir, config['certificate']))
        with open(cert_fname, 'r') as f:
            cert = Certificate.loadPEM(f.read(),)
            log.info("Loaded client TLS certificate from '{cert_fname}' (cn='{cert_cn}', sha256={cert_sha256}..)",
                     cert_fname=cert_fname,
                     cert_cn=cert.getSubject().CN,
                     cert_sha256=cert.digest('sha256')[:12])

        client_cert = PrivateCertificate.fromCertificateAndKeyPair(cert, private_key)
    else:
        if 'certificate' in config:
            log.warn('TLS client certificate present, but key is missing')

    # create TLS client context
    ctx = optionsForClientTLS(hostname, trustRoot=ca_certs, clientCertificate=client_cert)

    return ctx
Beispiel #25
0
def compute_tls_options():
    '''
    Returns TLS connection options.
    '''
    # tls
    cert_path = '../cert/example.crt'
    cert_data = open(cert_path).read()
    certificate = Certificate.loadPEM(cert_data)

    return optionsForClientTLS(
        hostname=AUTHORITY,
        acceptableProtocols=[b'h2'],
        trustRoot=certificate,
    )
Beispiel #26
0
def create_agent(ca_cert, client_cert, client_key):
    ca_certificate = Certificate.loadPEM(FilePath(ca_cert).getContent())
    client_certificate = PrivateCertificate.loadPEM(
        FilePath(client_cert).getContent() + b"\n" +
        FilePath(client_key).getContent())

    customPolicy = BrowserLikePolicyForHTTPSWithClientCertificate(
        trustRoot=ca_certificate,
        clientCertificate=client_certificate)

    pool = HTTPConnectionPool(reactor, persistent=True)
    agent = Agent(reactor, customPolicy, pool=pool)

    return agent
Beispiel #27
0
def create_agent(ca_cert, client_cert, client_key):
    ca_certificate = Certificate.loadPEM(FilePath(ca_cert).getContent())
    client_certificate = PrivateCertificate.loadPEM(
        FilePath(client_cert).getContent() + b"\n" +
        FilePath(client_key).getContent())

    customPolicy = BrowserLikePolicyForHTTPSWithClientCertificate(
        trustRoot=ca_certificate, clientCertificate=client_certificate)

    pool = HTTPConnectionPool(reactor, persistent=True)
    pool.maxPersistentPerHost = CONNECTION_COUNT
    agent = Agent(reactor, customPolicy, pool=pool)

    return agent
Beispiel #28
0
 def from_paths(
     cls, endpoint, private_key_path: FilePath, cert_path: FilePath
 ) -> "_TLSEndpointWrapper":
     """
     Create an endpoint with the given private key and certificate paths on
     the filesystem.
     """
     certificate = Certificate.loadPEM(cert_path.getContent()).original
     private_key = PrivateCertificate.loadPEM(
         cert_path.getContent() + b"\n" + private_key_path.getContent()
     ).privateKey.original
     certificate_options = CertificateOptions(
         privateKey=private_key, certificate=certificate
     )
     return cls(endpoint=endpoint, context_factory=certificate_options)
Beispiel #29
0
    def start_ssl(self):
        log.debug("Enabling SSL with PKey: %s, Cert: %s", self.pkey, self.cert)
        check_ssl_keys()

        with open(configmanager.get_config_dir(self.cert)) as cert:
            certificate = Certificate.loadPEM(cert.read()).original
        with open(configmanager.get_config_dir(self.pkey)) as pkey:
            private_key = KeyPair.load(pkey.read(), FILETYPE_PEM).original
        options = CertificateOptions(privateKey=private_key, certificate=certificate, method=SSL.SSLv23_METHOD)
        ctx = options.getContext()
        ctx.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3)
        ctx.use_certificate_chain_file(configmanager.get_config_dir(self.cert))

        self.socket = reactor.listenSSL(self.port, self.site, options, interface=self.interface)
        log.info("Serving on %s:%s view at https://%s:%s", self.interface, self.port, self.interface, self.port)
Beispiel #30
0
def certsFromBundle(path, x509=False):
    PEM_RE = re.compile(
        "-----BEGIN CERTIFICATE-----\r?.+?\r?"
        "-----END CERTIFICATE-----\r?\n?"
        "", re.DOTALL)
    if not os.path.isfile(path):
        log.warn("Attempted to load non-existent certificate bundle path %s" %
                 path)
        return []

    pems = FilePath(path).getContent()
    cstr = [match.group(0) for match in PEM_RE.finditer(pems)]
    certs = [Certificate.loadPEM(cert) for cert in cstr]
    if x509:
        certs = [cert.original for cert in certs]
    return certs
Beispiel #31
0
def certsFromBundle(path, x509=False):
    PEM_RE = re.compile(
        "-----BEGIN CERTIFICATE-----\r?.+?\r?"
        "-----END CERTIFICATE-----\r?\n?""",
        re.DOTALL)
    if not os.path.isfile(path):
        log.warn("Attempted to load non-existent certificate bundle path %s"
                 % path)
        return []

    pems = FilePath(path).getContent()
    cstr = [match.group(0) for match in PEM_RE.finditer(pems)]
    certs = [Certificate.loadPEM(cert) for cert in cstr]
    if x509:
        certs = [cert.original for cert in certs]
    return certs
    def setUp(self):
        description = yield self._httpbin_process.server_description(
            reactor)
        self.baseurl = URL(scheme=u"https",
                           host=description.host,
                           port=description.port).asText()

        root = trustRootFromCertificates(
            [Certificate.loadPEM(description.cacert)],
        )
        self.agent = Agent(
            reactor,
            contextFactory=BrowserLikePolicyForHTTPS(root),
        )

        self.pool = HTTPConnectionPool(reactor, False)
Beispiel #33
0
 def test_chainCerts(self):
     """
     L{chainCerts} loads all but the first cert in a file.
     """
     data = FilePath(__file__).sibling('data').child('certs')
     cert1 = data.child('cert1.pem').getContent()
     cert2 = data.child('cert2.pem').getContent()
     cert3 = data.child('cert3.pem').getContent()
     expected = [
         Certificate.loadPEM(cert) for cert in [cert2, cert3]]
     chain = chainCerts(cert1 + '\n' + cert2 + '\n' + cert3)
     self.assertEqual(len(chain), 2)
     self.assertEqual(
         chain[0].digest('sha256'), expected[0].digest('sha256'))
     self.assertEqual(
         chain[1].digest('sha256'), expected[1].digest('sha256'))
Beispiel #34
0
    def start_ssl(self):
        check_ssl_keys()
        log.debug('Enabling SSL with PKey: %s, Cert: %s', self.pkey, self.cert)

        with open(configmanager.get_config_dir(self.cert)) as cert:
            certificate = Certificate.loadPEM(cert.read()).original
        with open(configmanager.get_config_dir(self.pkey)) as pkey:
            private_key = KeyPair.load(pkey.read(), FILETYPE_PEM).original
        options = CertificateOptions(privateKey=private_key, certificate=certificate, method=SSL.SSLv23_METHOD)
        ctx = options.getContext()
        ctx.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3)
        ctx.use_certificate_chain_file(configmanager.get_config_dir(self.cert))

        self.socket = reactor.listenSSL(self.port, self.site, options, interface=self.interface)
        ip = self.socket.getHost().host
        ip = '[%s]' % ip if is_ipv6(ip) else ip
        log.info('Serving at https://%s:%s%s', ip, self.port, self.base)
Beispiel #35
0
 def connect_to_one_broker_TLS(self, p_pyhouse_obj, p_broker):
     l_host = p_broker.BrokerAddress
     l_port = p_broker.BrokerPort
     l_username = p_broker.UserName
     l_password = p_broker.Password
     l_clientID = 'PyH-' + p_pyhouse_obj.Computer.Name
     LOG.info('Connecting via TLS...')
     #  l_factory = protocol.Factory.forProtocol(echoclient.EchoClient)
     l_factory = PyHouseMqttFactory(p_pyhouse_obj, l_clientID, p_broker, l_username, l_password)
     l_certData = PEM_FILE.getContent()
     l_authority = Certificate.loadPEM(l_certData)
     l_options = optionsForClientTLS(l_host.decode('utf-8'), l_authority)
     l_endpoint = SSL4ClientEndpoint(p_pyhouse_obj.Twisted.Reactor, l_host, l_port, l_options)
     l_client = yield l_endpoint.connect(l_factory)
     l_done = defer.Deferred()
     l_client.connectionLost = lambda reason: l_done.callback(None)
     yield l_done
Beispiel #36
0
 def _serviceDescription(self):
     """
     Produce a description of the service we should start.
     """
     ca = Certificate.loadPEM(
         FilePath(self.caPath.encode('utf-8')).getContent())
     certBytes = FilePath(self.certPath.encode('utf-8')).getContent()
     cert = PrivateCertificate.loadPEM(certBytes)
     # Can't use PrivateCertificate.options until Twisted #6361 is fixed
     options = CertificateOptions(
         privateKey=cert.privateKey.original,
         certificate=cert.original,
         trustRoot=ca,
         extraCertChain=chainCerts(certBytes))
     router = IndexRouter(store=self.store)
     return _ServiceDescription(
         reactor=reactor, port=self.port, interface=self.interface,
         options=options, router=router)
Beispiel #37
0
 def test_unreadableCertificate(self):
     """
     If a certificate in the directory is unreadable,
     L{endpoints._loadCAsFromDir} will ignore that certificate.
     """
     class UnreadableFilePath(FilePath):
         def getContent(self):
             data = FilePath.getContent(self)
             # There is a duplicate of thing2.pem, so ignore anything that
             # looks like it.
             if data == casPath.child("thing2.pem").getContent():
                 raise IOError(EPERM)
             else:
                 return data
     casPathClone = casPath.child("ignored").parent()
     casPathClone.clonePath = UnreadableFilePath
     self.assertEqual(
         [Certificate(x) for x in endpoints._loadCAsFromDir(casPathClone)],
         [Certificate.loadPEM(casPath.child("thing1.pem").getContent())])
Beispiel #38
0
 def test_unreadableCertificate(self):
     """
     If a certificate in the directory is unreadable,
     L{endpoints._loadCAsFromDir} will ignore that certificate.
     """
     class UnreadableFilePath(FilePath):
         def getContent(self):
             data = FilePath.getContent(self)
             # There is a duplicate of thing2.pem, so ignore anything that
             # looks like it.
             if data == casPath.child("thing2.pem").getContent():
                 raise IOError(EPERM)
             else:
                 return data
     casPathClone = casPath.child("ignored").parent()
     casPathClone.clonePath = UnreadableFilePath
     self.assertEqual(
         [Certificate(x) for x in endpoints._loadCAsFromDir(casPathClone)],
         [Certificate.loadPEM(casPath.child("thing1.pem").getContent())])
Beispiel #39
0
    def _get_ssl_context(self):

        client_ca = get_certificate(self.client_ca_cert_path)
        if not client_ca:
            try:
                ca = mTLS.generate_new_certificate(is_ca_generation_request=True, ca_cert_path=self.client_ca_cert_path, username="******")
                if ca is not None:
                    save_certificate(self.client_ca_cert_path, ca)
                    client_ca = ca
            except Exception as e:
                log.error("Exception: {}".format(e))
                raise e

        client_ca_pem = "{}\n{}".format(base64.b64decode(client_ca.get('c')), base64.b64decode(client_ca.get('k')))
        certificate_authority = Certificate.loadPEM(client_ca_pem)

        self.server_ca_cert_path = self.server_cert_path+"_ca"
        server_cert = get_certificate(self.server_cert_path)
        server_cert_ca = get_certificate(self.server_ca_cert_path)
        if not server_cert:
            try:
                if not server_cert_ca:
                    ca = mTLS.generate_new_certificate(is_ca_generation_request=True, ca_cert_path=self.server_ca_cert_path, username="******")
                    if ca is not None:
                        save_certificate(self.server_ca_cert_path, ca)

                _server_cert = mTLS.generate_new_certificate(ca_cert_path=self.server_ca_cert_path, username="******", ip=self.ip)

                if _server_cert is not None:
                    save_certificate(self.server_cert_path, _server_cert)
                    server_cert = _server_cert
                else:
                    raise Exception("Server Certificate generation failed. Cert:{}".format(_server_cert))

            except Exception as e:
                log.error("Exception: {}".format(e))
                raise e

        server_cert_pem = "{}\n{}".format(base64.b64decode(server_cert.get('c')), base64.b64decode(server_cert.get('k')))
        server_cert = PrivateCertificate.loadPEM(server_cert_pem)

        return server_cert.options(certificate_authority)
Beispiel #40
0
def treq_with_authentication(reactor, ca_path, user_cert_path, user_key_path):
    """
    Create a ``treq``-API object that implements the REST API TLS
    authentication.

    That is, validating the control service as well as presenting a
    certificate to the control service for authentication.

    :param reactor: The reactor to use.
    :param FilePath ca_path: Absolute path to the public cluster certificate.
    :param FilePath user_cert_path: Absolute path to the user certificate.
    :param FilePath user_key_path: Absolute path to the user private key.

    :return: ``treq`` compatible object.
    """
    ca = Certificate.loadPEM(ca_path.getContent())
    user_credential = UserCredential.from_files(user_cert_path, user_key_path)
    policy = ControlServicePolicy(
        ca_certificate=ca, client_credential=user_credential.credential)
    return HTTPClient(Agent(reactor, contextFactory=policy))
Beispiel #41
0
def objectsFromPEM(pemdata):
    """
    Load some objects from a PEM.
    """
    certificates = []
    keys = []
    for line in pemdata.split("\n"):
        if line.startswith('-----BEGIN'):
            if 'CERTIFICATE' in line:
                blobs = certificates
            else:
                blobs = keys
            blobs.append('')
        blobs[-1] += line
        blobs[-1] += '\n'
    keys = [KeyPair.load(key, FILETYPE_PEM) for key in keys]
    certificates = [
        Certificate.loadPEM(certificate) for certificate in certificates
    ]
    return PEMObjects(keys=keys, certificates=certificates)
Beispiel #42
0
def treq_with_authentication(reactor, ca_path, user_cert_path, user_key_path):
    """
    Create a ``treq``-API object that implements the REST API TLS
    authentication.

    That is, validating the control service as well as presenting a
    certificate to the control service for authentication.

    :param reactor: The reactor to use.
    :param FilePath ca_path: Absolute path to the public cluster certificate.
    :param FilePath user_cert_path: Absolute path to the user certificate.
    :param FilePath user_key_path: Absolute path to the user private key.

    :return: ``treq`` compatible object.
    """
    ca = Certificate.loadPEM(ca_path.getContent())
    user_credential = UserCredential.from_files(user_cert_path, user_key_path)
    policy = ControlServicePolicy(ca_certificate=ca,
                                  client_credential=user_credential.credential)
    return HTTPClient(Agent(reactor, contextFactory=policy))
Beispiel #43
0
def _context_factory_and_credential(path, host, port):
    """
    Load a TLS context factory for the AMP client from the path where
    configuration and certificates live.

    The CA certificate and node private key and certificate are expected
    to be siblings of the configuration file.

    :param FilePath path: Path to directory where configuration lives.
    :param bytes host: The host we will be connecting to.
    :param int port: The port we will be connecting to.

    :return: ``_TLSContext`` instance.
    """
    ca = Certificate.loadPEM(path.child(b"cluster.crt").getContent())
    # This is a hack; from_path should be more
    # flexible. https://clusterhq.atlassian.net/browse/FLOC-1865
    node_credential = NodeCredential.from_path(path, b"node")
    policy = ControlServicePolicy(ca_certificate=ca, client_credential=node_credential.credential)
    return _TLSContext(context_factory=policy.creatorForNetloc(host, port), node_credential=node_credential)
Beispiel #44
0
def chainCerts(data):
    """
    Matches and returns any certificates found except the first match.

    Regex code copied from L{twisted.internet.endpoints._parseSSL}.
    Related ticket: https://twistedmatrix.com/trac/ticket/7732

    @type path: L{bytes}
    @param data: PEM-encoded data containing the certificates.

    @rtype: L{list} containing L{Certificate}s.
    """
    matches = re.findall(
        r'(-----BEGIN CERTIFICATE-----\n.+?\n-----END CERTIFICATE-----)',
        data,
        flags=re.DOTALL)
    chainCertificates = [
        Certificate.loadPEM(chainCertPEM).original
        for chainCertPEM in matches]
    return chainCertificates[1:]
def objectsFromPEM(pemdata):
    """
    Load some objects from a PEM.
    """
    certificates = []
    keys = []
    blobs = [b""]
    for line in pemdata.split(b"\n"):
        if line.startswith(b'-----BEGIN'):
            if b'CERTIFICATE' in line:
                blobs = certificates
            else:
                blobs = keys
            blobs.append(b'')
        blobs[-1] += line
        blobs[-1] += b'\n'
    keys = [KeyPair.load(key, FILETYPE_PEM) for key in keys]
    certificates = [Certificate.loadPEM(certificate)
                    for certificate in certificates]
    return PEMObjects(keys=keys, certificates=certificates)
Beispiel #46
0
def _context_factory_and_credential(path, host, port):
    """
    Load a TLS context factory for the AMP client from the path where
    configuration and certificates live.

    The CA certificate and node private key and certificate are expected
    to be siblings of the configuration file.

    :param FilePath path: Path to directory where configuration lives.
    :param bytes host: The host we will be connecting to.
    :param int port: The port we will be connecting to.

    :return: ``_TLSContext`` instance.
    """
    ca = Certificate.loadPEM(path.child(b"cluster.crt").getContent())
    # This is a hack; from_path should be more
    # flexible. https://clusterhq.atlassian.net/browse/FLOC-1865
    node_credential = NodeCredential.from_path(path, b"node")
    policy = ControlServicePolicy(ca_certificate=ca,
                                  client_credential=node_credential.credential)
    return _TLSContext(context_factory=policy.creatorForNetloc(host, port),
                       node_credential=node_credential)
Beispiel #47
0
def treq_with_authentication(reactor, certificates_path):
    """
    Create a ``treq``-API object that implements the REST API TLS
    authentication.

    That is, validating the control service as well as presenting a
    certificate to the control service for authentication.

    :param reactor: The reactor to use.
    :param FilePath certificates_path: Directory where certificates and
        private key can be found.

    :return: ``treq`` compatible object.
    """
    ca = Certificate.loadPEM(
        certificates_path.child(b"cluster.crt").getContent())
    # This is a hack; from_path should be more
    # flexible. https://clusterhq.atlassian.net/browse/FLOC-1865
    user_credential = UserCredential.from_path(certificates_path, u"user")
    policy = ControlServicePolicy(ca_certificate=ca,
                                  client_credential=user_credential.credential)
    return HTTPClient(Agent(reactor, contextFactory=policy))
Beispiel #48
0
def treq_with_authentication(reactor, certificates_path):
    """
    Create a ``treq``-API object that implements the REST API TLS
    authentication.

    That is, validating the control service as well as presenting a
    certificate to the control service for authentication.

    :param reactor: The reactor to use.
    :param FilePath certificates_path: Directory where certificates and
        private key can be found.

    :return: ``treq`` compatible object.
    """
    ca = Certificate.loadPEM(
        certificates_path.child(b"cluster.crt").getContent())
    # This is a hack; from_path should be more
    # flexible. https://clusterhq.atlassian.net/browse/FLOC-1865
    user_credential = UserCredential.from_path(certificates_path, u"user")
    policy = ControlServicePolicy(
        ca_certificate=ca, client_credential=user_credential.credential)
    return HTTPClient(Agent(reactor, contextFactory=policy))
Beispiel #49
0
    def start_ssl(self):
        check_ssl_keys()
        log.debug('Enabling SSL with PKey: %s, Cert: %s', self.pkey, self.cert)

        with open(configmanager.get_config_dir(self.cert)) as cert:
            certificate = Certificate.loadPEM(cert.read()).original
        with open(configmanager.get_config_dir(self.pkey)) as pkey:
            private_key = KeyPair.load(pkey.read(), FILETYPE_PEM).original
        options = CertificateOptions(privateKey=private_key,
                                     certificate=certificate,
                                     method=SSL.SSLv23_METHOD)
        ctx = options.getContext()
        ctx.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3)
        ctx.use_certificate_chain_file(configmanager.get_config_dir(self.cert))

        self.socket = reactor.listenSSL(self.port,
                                        self.site,
                                        options,
                                        interface=self.interface)
        ip = self.socket.getHost().host
        ip = '[%s]' % ip if is_ipv6(ip) else ip
        log.info('Serving at https://%s:%s%s', ip, self.port, self.base)
Beispiel #50
0
 def test_ssl(self):
     """
     When passed an SSL strports description, L{clientFromString} returns a
     L{SSL4ClientEndpoint} instance initialized with the values from the
     string.
     """
     reactor = object()
     client = endpoints.clientFromString(
         reactor,
         "ssl:host=example.net:port=4321:privateKey=%s:"
         "certKey=%s:bindAddress=10.0.0.3:timeout=3:caCertsDir=%s" %
          (escapedPEMPathName,
           escapedPEMPathName,
           escapedCAsPathName))
     self.assertIsInstance(client, endpoints.SSL4ClientEndpoint)
     self.assertIdentical(client._reactor, reactor)
     self.assertEqual(client._host, "example.net")
     self.assertEqual(client._port, 4321)
     self.assertEqual(client._timeout, 3)
     self.assertEqual(client._bindAddress, "10.0.0.3")
     certOptions = client._sslContextFactory
     self.assertIsInstance(certOptions, CertificateOptions)
     ctx = certOptions.getContext()
     self.assertIsInstance(ctx, ContextType)
     self.assertEqual(Certificate(certOptions.certificate),
                       testCertificate)
     privateCert = PrivateCertificate(certOptions.certificate)
     privateCert._setPrivateKey(KeyPair(certOptions.privateKey))
     self.assertEqual(privateCert, testPrivateCertificate)
     expectedCerts = [
         Certificate.loadPEM(x.getContent()) for x in
             [casPath.child("thing1.pem"), casPath.child("thing2.pem")]
         if x.basename().lower().endswith('.pem')
     ]
     self.assertEqual(sorted((Certificate(x) for x in certOptions.caCerts),
                             key=lambda cert: cert.digest()),
                      sorted(expectedCerts,
                             key=lambda cert: cert.digest()))
Beispiel #51
0
def getPolicyForHTTPS(trustRoot=None):

    if SKIP_SSL_CHECK:
        log.info("---------------------------------------")
        log.info("SKIPPING SSL CERT VERIFICATION!!!")
        log.info("I assume you know WHAT YOU ARE DOING...")
        log.info("---------------------------------------")

        class WebClientContextFactory(ClientContextFactory):
            """
            A web context factory which ignores the hostname and port and does
            no certificate verification.
            """
            def getContext(self, hostname, port):
                return ClientContextFactory.getContext(self)

        contextFactory = WebClientContextFactory()
        return contextFactory

    if isinstance(trustRoot, str):
        trustRoot = Certificate.loadPEM(FilePath(trustRoot).getContent())

    return BrowserLikePolicyForHTTPS(trustRoot)
Beispiel #52
0
def getPolicyForHTTPS(trustRoot=None):

    if SKIP_SSL_CHECK:
        log.info("---------------------------------------")
        log.info("SKIPPING SSL CERT VERIFICATION!!!")
        log.info("I assume you know WHAT YOU ARE DOING...")
        log.info("---------------------------------------")

        class WebClientContextFactory(ClientContextFactory):
            """
            A web context factory which ignores the hostname and port and does
            no certificate verification.
            """
            def getContext(self, hostname, port):
                return ClientContextFactory.getContext(self)

        contextFactory = WebClientContextFactory()
        return contextFactory

    if isinstance(trustRoot, str):
        trustRoot = Certificate.loadPEM(FilePath(trustRoot).getContent())

    return BrowserLikePolicyForHTTPS(trustRoot)
Beispiel #53
0
        reactor.stop()

    def sendRequest(self):
        request_headers = [
            (':method', 'GET'),
            (':authority', AUTHORITY),
            (':scheme', 'https'),
            (':path', PATH),
            ('user-agent', 'hyper-h2/1.0.0'),
        ]
        self.conn.send_headers(1, request_headers, end_stream=True)
        self.request_made = True


certData = open('cert/example.crt').read()
certificate = Certificate.loadPEM(certData)

options = optionsForClientTLS(
    hostname=AUTHORITY,
    acceptableProtocols=[b'h2'],
    trustRoot=certificate,
)


class ShowCertificate(Protocol):
    def connectionMade(self):
        self.transport.write(b"GET / HTTP/1.0\r\n\r\n")
        self.done = defer.Deferred()

    def dataReceived(self, data):
        certificate = Certificate(self.transport.getPeerCertificate())
Beispiel #54
0
from twisted.python.filepath import FilePath
from twisted.test.proto_helpers import (
    MemoryReactor, RaisingMemoryReactor, StringTransport)
from twisted.internet.protocol import ClientFactory, Protocol
from twisted.internet.address import IPv4Address, IPv6Address
from twisted.internet import (_endpointspy3 as endpoints, error, defer,
                              interfaces, reactor)

from twisted.test import __file__ as testInitPath
pemPath = FilePath(testInitPath.encode("utf-8")).sibling(b"server.pem")

try:
    from twisted.test.test_sslverify import makeCertificate
    from twisted.internet.ssl import (CertificateOptions, Certificate,
                                      PrivateCertificate)
    testCertificate = Certificate.loadPEM(pemPath.getContent())
    testPrivateCertificate = PrivateCertificate.loadPEM(pemPath.getContent())

    skipSSL = False
except ImportError:
    skipSSL = "OpenSSL is required to construct SSL Endpoints"


class TestProtocol(Protocol):
    """
    Protocol whose only function is to callback deferreds on the
    factory when it is connected or disconnected.
    """

    def __init__(self):
        self.data = []
Beispiel #55
0
        '..', '..', '..', '..', 'router', '.crossbar', 'intermediate.cert.pem',
    )

    tls_transport = {
        "type": "websocket",
        "url": "wss://127.0.0.1:8083/ws",
        "endpoint": SSL4ClientEndpoint(
            reactor, '127.0.0.1', 8083,
            optionsForClientTLS(
                'localhost',
                # XXX why do I need BOTH the intermediate and actual
                # cert? Did I create the CA/intermediate certificates
                # incorrectly?
                trustRoot=trustRootFromCertificates(
                    [
                        Certificate.loadPEM(open(cert_fname).read()),
                        Certificate.loadPEM(open(inter_cert_fname).read()),
                    ]
                ),
            ),
        )
    }

    unix_transport = {
        "type": "websocket",
        "url": "ws://localhost/ws",
        "endpoint": UNIXClientEndpoint(
            reactor,
            os.path.join(
                os.path.split(__file__)[0],
                '..', '..', '..', '..', 'router', '.crossbar', 'intermediate.cert.pem',
Beispiel #56
0
def _create_tls_server_context(config, cbdir, log):
    """
    Create a CertificateOptions object for use with TLS listening endpoints.
    """
    # server private key
    key_filepath = abspath(join(cbdir, config['key']))
    log.info("Loading server TLS key from {key_filepath}", key_filepath=key_filepath)
    with open(key_filepath) as key_file:
        # server certificate (but only the server cert, no chain certs)
        cert_filepath = abspath(join(cbdir, config['certificate']))
        log.info("Loading server TLS certificate from {cert_filepath}", cert_filepath=cert_filepath)
        with open(cert_filepath) as cert_file:
            key = KeyPair.load(key_file.read(), crypto.FILETYPE_PEM).original
            cert = Certificate.loadPEM(cert_file.read()).original

    # list of certificates that complete your verification chain
    extra_certs = None
    if 'chain_certificates' in config:
        extra_certs = []
        for fname in config['chain_certificates']:
            extra_cert_filepath = abspath(join(cbdir, fname))
            with open(extra_cert_filepath, 'r') as f:
                extra_certs.append(Certificate.loadPEM(f.read()).original)
            log.info("Loading server TLS chain certificate from {extra_cert_filepath}", extra_cert_filepath=extra_cert_filepath)

    # list of certificate authority certificate objects to use to verify the peer's certificate
    ca_certs = None
    if 'ca_certificates' in config:
        ca_certs = []
        for fname in config['ca_certificates']:
            ca_cert_filepath = abspath(join(cbdir, fname))
            with open(ca_cert_filepath, 'r') as f:
                ca_certs.append(Certificate.loadPEM(f.read()).original)
            log.info("Loading server TLS CA certificate from {ca_cert_filepath}", ca_cert_filepath=ca_cert_filepath)

    # ciphers we accept
    #
    # We prefer to make every single cipher (6 in total) _explicit_ (to reduce chances either we or the pattern-matching
    # language inside OpenSSL messes up) and drop support for Windows XP (we do WebSocket anyway).
    #
    # We don't use AES256 and SHA384, to reduce number of ciphers and since the additional
    # security gain seems not worth the additional performance drain.
    #
    # We also don't use ECDSA, since EC certificates a rare in the wild.
    #
    # The effective list of ciphers determined from an OpenSSL cipher string:
    #
    #   openssl ciphers -v 'ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:'
    #
    # References:
    #
    #  * https://www.ssllabs.com/ssltest/analyze.html?d=myserver.com
    #  * http://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    #  * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT
    #  * https://wiki.mozilla.org/Talk:Security/Server_Side_TLS
    #
    if 'ciphers' in config:
        log.info("Using explicit TLS ciphers from config")
        crossbar_ciphers = AcceptableCiphers.fromOpenSSLCipherString(config['ciphers'])
    else:
        log.info("Using secure default TLS ciphers")
        crossbar_ciphers = AcceptableCiphers.fromOpenSSLCipherString(
            # AEAD modes (GCM)
            # 'ECDHE-ECDSA-AES128-GCM-SHA256:'
            'ECDHE-RSA-AES128-GCM-SHA256:'
            # 'ECDHE-ECDSA-AES256-GCM-SHA384:'
            # 'ECDHE-RSA-AES256-GCM-SHA384:'
            'DHE-RSA-AES128-GCM-SHA256:'
            # 'DHE-RSA-AES256-GCM-SHA384:'

            # CBC modes
            'ECDHE-RSA-AES128-SHA256:'
            'DHE-RSA-AES128-SHA256:'
            'ECDHE-RSA-AES128-SHA:'
            'DHE-RSA-AES128-SHA:'
        )

    # DH modes require a parameter file
    if 'dhparam' in config:
        dhpath = FilePath(abspath(join(cbdir, config['dhparam'])))
        dh_params = DiffieHellmanParameters.fromFile(dhpath)
    else:
        dh_params = None
        log.warn("No OpenSSL DH parameter file set - DH cipher modes will be deactive!")

    # create a TLS context factory
    # see: https://twistedmatrix.com/documents/current/api/twisted.internet.ssl.CertificateOptions.html
    ctx = CertificateOptions(
        privateKey=key,
        certificate=cert,
        extraCertChain=extra_certs,
        verify=(ca_certs is not None),
        caCerts=ca_certs,
        dhParameters=dh_params,
        acceptableCiphers=crossbar_ciphers,

        # TLS hardening
        method=TLSv1_2_METHOD,
        enableSingleUseKeys=True,
        enableSessions=False,
        enableSessionTickets=False,
        fixBrokenPeers=False,
    )

    # Without a curve being set, ECDH won't be available even if listed
    # in acceptable ciphers!
    #
    # The curves available in OpenSSL can be listed:
    #
    #   openssl ecparam -list_curves
    #
    # prime256v1: X9.62/SECG curve over a 256 bit prime field
    #
    # This is elliptic curve "NIST P-256" from here
    # http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
    #
    # This seems to be the most widely used curve
    #
    # http://crypto.stackexchange.com/questions/11310/with-openssl-and-ecdhe-how-to-show-the-actual-curve-being-used
    #
    # and researchers think it is "ok" (other than wrt timing attacks etc)
    #
    # https://twitter.com/hyperelliptic/status/394258454342148096
    #
    if ctx._ecCurve is None:
        log.warn("No OpenSSL elliptic curve set - EC cipher modes will be deactive!")
    else:
        if ctx._ecCurve.snName != "prime256v1":
            log.info("OpenSSL is using elliptic curve {curve}", curve=ctx._ecCurve.snName)
        else:
            log.info("OpenSSL is using elliptic curve prime256v1 (NIST P-256)")

    return ctx
Beispiel #57
0
def _create_tls_server_context(config, cbdir, log):
    """
    Create a CertificateOptions object for use with TLS listening endpoints.
    """
    # server private key
    key_filepath = abspath(join(cbdir, config['key']))
    log.info("Loading server TLS key from {key_filepath}",
             key_filepath=key_filepath)
    with open(key_filepath) as key_file:
        # server certificate (but only the server cert, no chain certs)
        cert_filepath = abspath(join(cbdir, config['certificate']))
        log.info("Loading server TLS certificate from {cert_filepath}",
                 cert_filepath=cert_filepath)
        with open(cert_filepath) as cert_file:
            key = KeyPair.load(key_file.read(), crypto.FILETYPE_PEM).original
            cert = Certificate.loadPEM(cert_file.read()).original

    # list of certificates that complete your verification chain
    extra_certs = None
    if 'chain_certificates' in config:
        extra_certs = []
        for fname in config['chain_certificates']:
            extra_cert_filepath = abspath(join(cbdir, fname))
            with open(extra_cert_filepath, 'r') as f:
                extra_certs.append(Certificate.loadPEM(f.read()).original)
            log.info(
                "Loading server TLS chain certificate from {extra_cert_filepath}",
                extra_cert_filepath=extra_cert_filepath)

    # list of certificate authority certificate objects to use to verify the peer's certificate
    ca_certs = None
    if 'ca_certificates' in config:
        ca_certs = []
        for fname in config['ca_certificates']:
            ca_cert_filepath = abspath(join(cbdir, fname))
            with open(ca_cert_filepath, 'r') as f:
                ca_certs.append(Certificate.loadPEM(f.read()).original)
            log.info(
                "Loading server TLS CA certificate from {ca_cert_filepath}",
                ca_cert_filepath=ca_cert_filepath)

    # ciphers we accept
    #
    # We prefer to make every single cipher (6 in total) _explicit_ (to reduce chances either we or the pattern-matching
    # language inside OpenSSL messes up) and drop support for Windows XP (we do WebSocket anyway).
    #
    # We don't use AES256 and SHA384, to reduce number of ciphers and since the additional
    # security gain seems not worth the additional performance drain.
    #
    # We also don't use ECDSA, since EC certificates a rare in the wild.
    #
    # The effective list of ciphers determined from an OpenSSL cipher string:
    #
    #   openssl ciphers -v 'ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:'
    #
    # References:
    #
    #  * https://www.ssllabs.com/ssltest/analyze.html?d=myserver.com
    #  * http://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    #  * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT
    #  * https://wiki.mozilla.org/Talk:Security/Server_Side_TLS
    #
    if 'ciphers' in config:
        log.info("Using explicit TLS ciphers from config")
        crossbar_ciphers = AcceptableCiphers.fromOpenSSLCipherString(
            config['ciphers'])
    else:
        log.info("Using secure default TLS ciphers")
        crossbar_ciphers = AcceptableCiphers.fromOpenSSLCipherString(
            # AEAD modes (GCM)
            # 'ECDHE-ECDSA-AES128-GCM-SHA256:'
            'ECDHE-RSA-AES128-GCM-SHA256:'
            # 'ECDHE-ECDSA-AES256-GCM-SHA384:'
            # 'ECDHE-RSA-AES256-GCM-SHA384:'
            'DHE-RSA-AES128-GCM-SHA256:'
            # 'DHE-RSA-AES256-GCM-SHA384:'

            # CBC modes
            'ECDHE-RSA-AES128-SHA256:'
            'DHE-RSA-AES128-SHA256:'
            'ECDHE-RSA-AES128-SHA:'
            'DHE-RSA-AES128-SHA:')

    # DH modes require a parameter file
    if 'dhparam' in config:
        dhpath = FilePath(abspath(join(cbdir, config['dhparam'])))
        dh_params = DiffieHellmanParameters.fromFile(dhpath)
    else:
        dh_params = None
        log.warn(
            "No OpenSSL DH parameter file set - DH cipher modes will be deactive!"
        )

    ctx = CertificateOptions(
        privateKey=key,
        certificate=cert,
        extraCertChain=extra_certs,
        verify=(ca_certs is not None),
        caCerts=ca_certs,
        dhParameters=dh_params,
        acceptableCiphers=crossbar_ciphers,

        # Disable SSLv3 and TLSv1 -- only allow TLSv1.1 or higher
        #
        # We are using Twisted private stuff (from twisted.internet._sslverify import TLSVersion),
        # as OpenSSL.SSL.TLSv1_1_METHOD wont work:
        #
        # [ERROR] File "../twisted/internet/_sslverify.py", line 1530, in __init__
        #    if raiseMinimumTo > self._defaultMinimumTLSVersion:
        #       builtins.TypeError: '>' not supported between instances of 'int' and 'NamedConstant'
        #
        raiseMinimumTo=TLSVersion.TLSv1_1,

        # TLS hardening
        enableSingleUseKeys=True,
        enableSessions=False,
        enableSessionTickets=False,
        fixBrokenPeers=False,
    )

    # Without a curve being set, ECDH won't be available even if listed
    # in acceptable ciphers!
    #
    # The curves available in OpenSSL can be listed:
    #
    #   openssl ecparam -list_curves
    #
    # prime256v1: X9.62/SECG curve over a 256 bit prime field
    #
    # This is elliptic curve "NIST P-256" from here
    # http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
    #
    # This seems to be the most widely used curve
    #
    # http://crypto.stackexchange.com/questions/11310/with-openssl-and-ecdhe-how-to-show-the-actual-curve-being-used
    #
    # and researchers think it is "ok" (other than wrt timing attacks etc)
    #
    # https://twitter.com/hyperelliptic/status/394258454342148096
    #
    if False:
        # FIXME: this doesn't work anymore with Twisted 18.4. (there now seems more complex machinery
        # in self._ecChooser)
        if ctx._ecCurve is None:
            log.warn(
                "No OpenSSL elliptic curve set - EC cipher modes will be deactive!"
            )
        else:
            if ctx._ecCurve.snName != "prime256v1":
                log.info("OpenSSL is using elliptic curve {curve}",
                         curve=ctx._ecCurve.snName)
            else:
                log.info(
                    "OpenSSL is using elliptic curve prime256v1 (NIST P-256)")

    return ctx
Beispiel #58
0
 def _get_digest(cert):
     from twisted.internet.ssl import Certificate
     return Certificate.loadPEM(cert).digest()
Beispiel #59
0
 def _getCert(self):
     """
     Get the SSL certificate from an Axiom store directory.
     """
     certFile = FilePath(self.dbdir).child('files').child('server.pem')
     return Certificate.loadPEM(certFile.getContent())
Beispiel #60
0
def _certificates_for_authority_and_server(service_identity, key_size=1024):
    """
    Create a self-signed CA certificate and server certificate signed
    by the CA.

    :param service_identity: The identity (hostname) of the server.
    :type service_identity: :py:class:`unicode`

    :param key_size: (optional) The size of CA's and server's private
        RSA keys.  Defaults to 1024 bits, which is the minimum allowed
        by OpenSSL Contexts at the default security level as of 1.1.
    :type key_size: :py:class:`int`

    :return: a 3-tuple of ``(certificate_authority_certificate,
             server_private_key, server_certificate)``.
    :rtype: :py:class:`tuple` of (:py:class:`sslverify.Certificate`,
            :py:class:`OpenSSL.crypto.PKey`,
            :py:class:`OpenSSL.crypto.X509`)
    """
    common_name_for_ca = x509.Name(
        [x509.NameAttribute(NameOID.COMMON_NAME, u'Testing Example CA')])
    common_name_for_server = x509.Name(
        [x509.NameAttribute(NameOID.COMMON_NAME, u'Testing Example Server')])
    one_day = datetime.timedelta(1, 0, 0)
    private_key_for_ca = rsa.generate_private_key(public_exponent=65537,
                                                  key_size=key_size,
                                                  backend=default_backend())
    public_key_for_ca = private_key_for_ca.public_key()
    ca_certificate = (x509.CertificateBuilder().subject_name(
        common_name_for_ca).issuer_name(common_name_for_ca).not_valid_before(
            datetime.datetime.today() -
            one_day).not_valid_after(datetime.datetime.today() +
                                     one_day).serial_number(
                                         x509.random_serial_number()).
                      public_key(public_key_for_ca).add_extension(
                          x509.BasicConstraints(ca=True, path_length=9),
                          critical=True,
                      ).sign(private_key=private_key_for_ca,
                             algorithm=hashes.SHA256(),
                             backend=default_backend()))
    private_key_for_server = rsa.generate_private_key(
        public_exponent=65537, key_size=key_size, backend=default_backend())
    public_key_for_server = private_key_for_server.public_key()
    server_certificate = (
        x509.CertificateBuilder().subject_name(common_name_for_server).
        issuer_name(common_name_for_ca).not_valid_before(
            datetime.datetime.today() -
            one_day).not_valid_after(datetime.datetime.today() +
                                     one_day).serial_number(
                                         x509.random_serial_number()).
        public_key(public_key_for_server).add_extension(
            x509.BasicConstraints(ca=False, path_length=None),
            critical=True,
        ).add_extension(
            x509.SubjectAlternativeName([x509.DNSName(service_identity)]),
            critical=True,
        ).sign(private_key=private_key_for_ca,
               algorithm=hashes.SHA256(),
               backend=default_backend()))

    ca_self_cert = Certificate.loadPEM(
        ca_certificate.public_bytes(Encoding.PEM))

    pkey = PKey.from_cryptography_key(private_key_for_server)
    x509_server_certificate = X509.from_cryptography(server_certificate)

    return ca_self_cert, pkey, x509_server_certificate