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)
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()
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
def _handlePairing(self, packet): self._cancelTimeout() if packet.get("pair") is True: if self.status == InternalStatus.REQUESTED: info("Pair answer") certificate = Certificate(self.transport.getPeerCertificate()).dumpPEM() self.status = InternalStatus.PAIRED if self.isTrusted(): self.factory.database.updateDevice(self.identifier, self.name, self.device) else: self.factory.database.pairDevice(self.identifier, certificate, self.name, self.device) else: info("Pair request") pair = Packet.createPair(False) if self.status == InternalStatus.PAIRED or self.isTrusted(): info("I'm already paired, but they think I'm not") self.factory.database.updateDevice(self.identifier, self.name, self.device) pair.set("pair", True) else: info("Pairing started by the other end, rejecting their request") self._sendPacket(pair) else: info("Unpair request") if self.status == InternalStatus.REQUESTED: info("Canceled by other peer") self.status = InternalStatus.NOT_PAIRED self.factory.database.unpairDevice(self.identifier)
def _identityVerifyingInfoCallback(self, connection, where, ret): """ Override the base implementation to provide better hostname verification. @param connection: the connection which is handshaking. @type connection: L{OpenSSL.SSL.Connection} @param where: flags indicating progress through a TLS handshake. @type where: L{int} @param ret: ignored @type ret: ignored """ if where & SSL_CB_HANDSHAKE_START: _maybeSetHostNameIndication(connection, self._hostnameBytes) elif where & SSL_CB_HANDSHAKE_DONE: if self._ctx.get_verify_mode() != SSL.VERIFY_NONE: try: peer_cert = Certificate(connection.get_peer_certificate()) _matchHostname(peer_cert, self._hostname) except CertMatchError as ex: log.error(str(ex)) f = Failure() transport = connection.get_app_data() transport.failVerification(f)
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)
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
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))
def remote_login(self, client): # print 'Remote login!' peerCertificate = Certificate.peerFromTransport(self.broker.transport) pdid = peerCertificate.getSubject().commonName.decode('utf-8') avatar, logout = yield self.portal.login(pdid, client) avatar = pb.AsReferenceable(avatar, "perspective") # Formerly in _cbLogin, moved here to make the deferred chain cleaner puid = avatar.processUniqueID() # only call logout once, whether the connection is dropped (disconnect) # or a logout occurs (cleanup), and be careful to drop the reference to # it in either case logout = [logout] def maybeLogout(): if not logout: return fn = logout[0] del logout[0] fn() self.broker._localCleanup[puid] = maybeLogout self.broker.notifyOnDisconnect(maybeLogout) defer.returnValue(avatar)
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)
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)
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)
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 create_certificate_authority(keypair, dn, request, serial, validity_period, digest, start=None): """ Sign a CertificateRequest with extensions for use as a CA certificate. See https://www.openssl.org/docs/apps/x509v3_config.html#Basic-Constraints for further information. This code based on ``twisted.internet.ssl.KeyPair.signRequestObject`` :param KeyPair keypair: The private/public key pair. :param DistinguishedName dn: The ``DistinguishedName`` for the certificate. :param CertificateRequest request: The signing request object. :param int serial: The certificate serial number. :param int validity_period: The number of seconds from ``start`` after which the certificate expires. :param bytes digest: The digest algorithm to use. :param datetime start: The datetime from which the certificate is valid. Defaults to current date and time. """ if start is None: start = datetime.datetime.utcnow() expire = start + datetime.timedelta(seconds=validity_period) start = start.strftime(b"%Y%m%d%H%M%SZ") expire = expire.strftime(b"%Y%m%d%H%M%SZ") req = request.original cert = crypto.X509() cert.set_subject(req.get_subject()) cert.set_pubkey(req.get_pubkey()) cert.set_notBefore(start) cert.set_notAfter(expire) cert.set_serial_number(serial) cert.add_extensions([ crypto.X509Extension("basicConstraints", True, "CA:TRUE, pathlen:0"), crypto.X509Extension("keyUsage", True, "keyCertSign, cRLSign"), crypto.X509Extension("subjectKeyIdentifier", False, "hash", subject=cert), ]) cert.add_extensions([ crypto.X509Extension( "authorityKeyIdentifier", False, "keyid:always", issuer=cert ) ]) cert.set_issuer(cert.get_subject()) cert.sign(keypair.original, digest) return Certificate(cert)
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
def settings_acknowledged(self, event: SettingsAcknowledged) -> None: self.metadata['settings_acknowledged'] = True # Send off all the pending requests as now we have # established a proper HTTP/2 connection self._send_pending_requests() # Update certificate when our HTTP/2 connection is established self.metadata['certificate'] = Certificate(self.transport.getPeerCertificate())
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 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
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])
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())])
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])
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))
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)
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))
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)
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
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
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
def from_path(cls, path): """ :param FilePath path: Directory where private key and certificate are stored. """ if not path.isdir(): raise PathError( b"Path {path} is not a directory.".format(path=path.path) ) certPath = path.child(certificate_filename) keyPath = path.child(key_filename) if not certPath.isfile(): raise PathError( b"Certificate file {path} does not exist.".format( path=certPath.path) ) if not keyPath.isfile(): raise PathError( b"Private key file {path} does not exist.".format( path=keyPath.path) ) try: certFile = certPath.open() except IOError: raise PathError( (b"Certificate file {path} could not be opened. " b"Check file permissions.").format( path=certPath.path) ) try: keyFile = keyPath.open() except IOError: raise PathError( (b"Private key file {path} could not be opened. " b"Check file permissions.").format( path=keyPath.path) ) certificate = Certificate.load( certFile.read(), format=crypto.FILETYPE_PEM) keypair = FlockerKeyPair( keypair=KeyPair.load(keyFile.read(), format=crypto.FILETYPE_PEM) ) return cls(path=path, certificate=certificate, keypair=keypair)
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
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, )
def sign_certificate_request(keypair, dn, request, serial, validity_period, digest, start=None, additional_extensions=()): """ Sign a CertificateRequest and return a Certificate. This code based on ``twisted.internet.ssl.KeyPair.signRequestObject`` :param KeyPair keypair: The private/public key pair. :param X509Name dn: The distinguished name for the certificate. :param CertificateRequest request: The signing request object. :param int serial: The certificate serial number. :param int validity_period: The number of seconds from ``start`` after which the certificate expires. :param bytes digest: The digest algorithm to use. :param datetime start: The datetime from which the certificate is valid. Defaults to current date and time. :param additional_extensions: A sequence of additional ``X509Extension`` objects to add to the certificate. """ if start is None: start = datetime.datetime.utcnow() expire = start + datetime.timedelta(seconds=validity_period) start = start.strftime(b"%Y%m%d%H%M%SZ") expire = expire.strftime(b"%Y%m%d%H%M%SZ") req = request.original cert = crypto.X509() cert.set_issuer(dn) cert.set_subject(req.get_subject()) cert.set_pubkey(req.get_pubkey()) cert.set_notBefore(start) cert.set_notAfter(expire) cert.set_serial_number(serial) cert.add_extensions(additional_extensions) cert.sign(keypair.original, digest) return Certificate(cert)
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)
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)
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 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'))
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)
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 startTLS(self, certificate, *verifyAuthorities): if self.hostCertificate is None: self.hostCertificate = certificate self._justStartedTLS = True self.transport.startTLS(certificate.options(*verifyAuthorities)) stlsb = self._startingTLSBuffer if stlsb is not None: self._startingTLSBuffer = None for box in stlsb: self.sendPacket(box) else: raise RuntimeError( "Previously authenticated connection between %s and %s " "is trying to re-establish as %s" % ( self.hostCertificate, Certificate.peerFromTransport(self.transport), (certificate, verifyAuthorities)))
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
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)
def startTLS(self, certificate, *verifyAuthorities): if self.hostCertificate is None: self.hostCertificate = certificate self._justStartedTLS = True self.transport.startTLS(certificate.options(*verifyAuthorities)) stlsb = self._startingTLSBuffer if stlsb is not None: self._startingTLSBuffer = None for box in stlsb: self.sendPacket(box) else: raise RuntimeError( "Previously authenticated connection between %s and %s " "is trying to re-establish as %s" % (self.hostCertificate, Certificate.peerFromTransport(self.transport), (certificate, verifyAuthorities)))
def load_certificate_file(path): """ Load a certificate from a specified path. :param FilePath path: Absolute path to certificate file. :return: A ``Certificate`` instance representing the parsed certificate data. """ try: certificate_file = path.open() except IOError as e: code, failure = e raise PathError(b"Certificate file could not be opened.", e.filename, code, failure) certificate = Certificate.load(certificate_file.read(), format=crypto.FILETYPE_PEM) return certificate
def initWithCoder_(self, coder): """ Initialize model object with the content from the L{NSCoder}. """ self = NSObject.init(self) if self is None: return None self.account = None self.cert = None self.name = coder.decodeObjectForKey_("name") self.email = coder.decodeObjectForKey_("email") certBytes, lenBytes = coder.decodeBytesForKey_returnedLength_( "cert", None ) print lenBytes if lenBytes: self.cert = Certificate.load(certBytes) return self
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)
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)
def sign_ca_cert(key, requestObject, dn): from OpenSSL.crypto import X509, X509Extension from twisted.internet.ssl import Certificate req = requestObject.original cert = X509() dn._copyInto(cert.get_issuer()) cert.set_subject(req.get_subject()) cert.set_pubkey(req.get_pubkey()) cert.gmtime_adj_notBefore(0) cert.gmtime_adj_notAfter(60 * 60) cert.set_serial_number(1) cert.add_extensions([ X509Extension(b"basicConstraints", True, b"CA:TRUE"), # Not necessarily a good way to populate subjectAltName but it # quiets the deprecation warning we get from service_identity. X509Extension(b"subjectAltName", True, b"DNS:" + dn.commonName), ]) cert.sign(key.original, "sha256") return Certificate(cert)
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)
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)
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))
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 load_certificate_file(path): """ Load a certificate from a specified path. :param FilePath path: Absolute path to certificate file. :return: A ``Certificate`` instance representing the parsed certificate data. """ try: certificate_file = path.open() except IOError as e: code, failure = e raise PathError( b"Certificate file could not be opened.", e.filename, code, failure ) certificate = Certificate.load( certificate_file.read(), format=crypto.FILETYPE_PEM) return certificate
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))
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)
def login2(self, portal): self.portal = portal # Returns a _RifflePortalWrapper remote reference. Set a timeout # in case the connection is down self.setTimeout(TIMEOUT) root = yield self.getRootObject() # Reset the timeout, indicating we've made the connection and are done waiting self.setTimeout(None) # Extract the name from credentials peerCertificate = Certificate.peerFromTransport(self._broker.transport) pdid = peerCertificate.getSubject().commonName.decode('utf-8') # Returns the server's avatar based on the client's interpretation # 'other' is the other end of the connection. other = self.portal.partialLogin(pdid) # Convert to remote referentiable for transmission referencibleOther = pb.AsReferenceable(other, "perspective") # Here is the problem. The login call triggers the init call, and that # starts the chain of riffle callbacks, but this object won't be back in time by then! # Avatar is the remotely described API object avatar = yield root.callRemote('login', referencibleOther) other.remote = Levy(avatar) # This is absolutely not needed. The point of this method is to registers # the new connections with the portal, but we already have all the pieces. # a, b = yield self.portal.login(pdid, avatar) # tttteeeemmmpppppoooorrraaaarrryyy realm = self.portal.findRealm(pdid) realm.attach(other, avatar) avatar.callRemote('handshake') other.perspective_handshake() defer.returnValue(avatar)
def send_response(self): client = self.transport.getPeer() req_uri = self.lines[0].split(" ")[1] headers = {l.split(':')[0]:l.split(':')[1].strip() for l in self.lines[2:-1]} user_agent = headers.get('User-Agent', 'Unknown') try: peer_certificate = Certificate.peerFromTransport(self.transport) f = peer_certificate.digest() self.sendLine("HTTP/1.1 401 Unauthorized") self.sendLine(self.headers()) self.sendLine("") self.transport.write(json.dumps(self.bodies['unauthorized'])) self.transport.loseConnection() self.chirp({'f': f, 'tf': f.replace(":","")[:25].lower(), 'ip': client.host, 'useragent': user_agent, 'location': req_uri.split("?")[0]}) except CertificateError as e: log.error("CertificateError Exception: {}".format(e)) self.sendLine("HTTP/1.1 403 Forbidden") self.sendLine(self.headers()) self.sendLine("") response = self.bodies['forbidden'] response['message'] = response['message'].format(req_uri.split("?")[0]) self.transport.write(json.dumps(response)) self.transport.loseConnection() except Exception as e: log.error("Exception send_response: {}".format(e)) self.sendLine("HTTP/1.1 400 Bad Request") self.sendLine(self.headers()) self.sendLine("") self.transport.write(json.dumps(self.bodies['bad'])) self.transport.loseConnection() d = defer.Deferred() d.callback("Success") return d