def connect_ssl(self, client_hello): """Sets up both ends of SSL termination. Note that client_socket MUST have the TLS ClientHello as the first thing recv() returns or else pyOpenSSL will bail. Returns setup success. """ server_name = client_hello.extensions.get("server_name") if server_name: server_name = server_name.data self.hostname = server_name try: # Send our own client hello to the other side self._setup_server_connection(server_name) server_cert = self.server_socket.get_peer_certificate() handler_cert = self.handler.on_certificate(server_cert) ciphers_list = self.handler.on_server_cipher_suites(client_hello) context = SSL.Context(SSL.SSLv23_METHOD) context.set_verify(SSL.VERIFY_NONE, stub_verify) if ciphers_list is not None: context.set_cipher_list(ciphers_list) if handler_cert is not None: context.use_certificate_chain_file(handler_cert) context.use_privatekey_file(handler_cert) # Required for anonymous/ephemeral DH cipher suites context.load_tmp_dh("./dhparam") # Required for anonymous/ephemeral ECDH cipher suites # The API is not available in the old version of pyOpenSSL which we # currently use. Without the code below, anonymous and ephemeral # ECDH cipher suites will not be used. if hasattr(context, "set_tmp_ecdh"): curve = crypto.get_elliptic_curve("prime256v1") context.set_tmp_ecdh(curve) # Send our ServerHello to the Client. Note that the Client's ClientHello # MUST be the first thing that self.client_socket.recv() returns self.client_socket.setblocking(False) connection = SSL.Connection(context, self.client_socket) connection.set_accept_state() self._do_ssl_handshake(connection) self.client_socket.setblocking(True) self.client_socket = ConnectionWrapper(connection) # Let the server know our sockets have changed self.server.update_sockets(self) except SSL.Error as e: self.handler.on_ssl_error(e) return False self.handler.on_ssl_establish() self.ssl = True return True
def _start_client_ssl_connection(self): server_cert = self.server_socket.get_peer_certificate() handler_cert = self.handler.on_certificate(server_cert) ciphers_list = self.handler.on_server_cipher_suites(self.client_hello) context = SSL.Context(SSL.SSLv23_METHOD) context.set_verify(SSL.VERIFY_NONE, stub_verify) if ciphers_list is not None: context.set_cipher_list(ciphers_list) if handler_cert is not None: context.use_certificate_chain_file(handler_cert) context.use_privatekey_file(handler_cert) # Required for anonymous/ephemeral DH cipher suites context.load_tmp_dh("./dhparam") # Required for anonymous/ephemeral ECDH cipher suites # The API is not available in the old version of pyOpenSSL which we # currently use. Without the code below, anonymous and ephemeral # ECDH cipher suites will not be used. if hasattr(context, "set_tmp_ecdh"): curve = crypto.get_elliptic_curve("prime256v1") context.set_tmp_ecdh(curve) # Send our ServerHello to the Client. Note that the Client's ClientHello # MUST be the first thing that self.client_socket.recv() returns connection = SSL.Connection(context, self.client_socket) connection.set_accept_state() self.client_socket = ConnectionWrapper(connection) self.client_bridge_fn = self._gen_ssl_connect_fn( connection, self._on_client_ssl_established) # Start the handshake self.client_bridge_fn() # Only listen for client events until the connection is established self.set_select_fds(rlist=[self.client_socket])
def _start_client_ssl_connection(self): server_cert = self.server_socket.get_peer_certificate() handler_cert = self.handler.on_certificate(server_cert) ciphers_list = self.handler.on_server_cipher_suites(self.client_hello) context = SSL.Context(SSL.SSLv23_METHOD) context.set_verify(SSL.VERIFY_NONE, stub_verify) if ciphers_list is not None: context.set_cipher_list(ciphers_list) if handler_cert is not None: context.use_certificate_chain_file(handler_cert) context.use_privatekey_file(handler_cert) # Required for anonymous/ephemeral DH cipher suites context.load_tmp_dh("./dhparam") # Required for anonymous/ephemeral ECDH cipher suites # The API is not available in the old version of pyOpenSSL which we # currently use. Without the code below, anonymous and ephemeral # ECDH cipher suites will not be used. if hasattr(context, "set_tmp_ecdh"): curve = crypto.get_elliptic_curve("prime256v1") context.set_tmp_ecdh(curve) # Send our ServerHello to the Client. Note that the Client's ClientHello # MUST be the first thing that self.client_socket.recv() returns connection = SSL.Connection(context, self.client_socket) connection.set_accept_state() self.client_socket = ConnectionWrapper(connection) self.client_bridge_fn = self._gen_ssl_connect_fn(connection, self._on_client_ssl_established) # Start the handshake self.client_bridge_fn() # Only listen for client events until the connection is established self.set_select_fds(rlist=[self.client_socket])
def create_basic_sslcontext(): ssl_ctx = SSL.Context(SSL.SSLv23_METHOD) ssl_ctx.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3 | SSL.OP_CIPHER_SERVER_PREFERENCE) ssl_ctx.set_cipher_list(":".join(_SUPPROT_CIPHERS_SUITES)) # NOTE: cipher suite related to ECDHE will need this ssl_ctx.set_tmp_ecdh(crypto.get_elliptic_curve('prime256v1')) return ssl_ctx
def getContext(self): context = SSL.Context(SSL.SSLv23_METHOD) try: _ecCurve = crypto.get_elliptic_curve(_defaultCurveName) context.set_tmp_ecdh(_ecCurve) except Exception: logger.exception("Failed to enable elliptic curve for TLS") context.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3) context.set_cipher_list("!ADH:HIGH+kEDH:!AECDH:HIGH+kEECDH") return context
def configure_context(context, config): try: _ecCurve = crypto.get_elliptic_curve(_defaultCurveName) context.set_tmp_ecdh(_ecCurve) except Exception: logger.exception("Failed to enable elliptic curve for TLS") context.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3) context.use_certificate_chain_file(config.tls_certificate_file) context.use_privatekey(config.tls_private_key) # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ context.set_cipher_list( "ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES256:ECDH+AES128:!aNULL:!SHA1")
def configure_context(context, config): try: _ecCurve = crypto.get_elliptic_curve(_defaultCurveName) context.set_tmp_ecdh(_ecCurve) except Exception: logger.exception("Failed to enable elliptic curve for TLS") context.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3) context.use_certificate_chain_file(config.tls_certificate_file) context.use_privatekey(config.tls_private_key) # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ context.set_cipher_list( "ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES256:ECDH+AES128:!aNULL:!SHA1" )
def configure_context(context, config): try: _ecCurve = crypto.get_elliptic_curve(_defaultCurveName) context.set_tmp_ecdh(_ecCurve) except Exception: logger.exception("Failed to enable elliptic curve for TLS") context.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3) context.use_certificate_chain_file(config.tls_certificate_file) if not config.no_tls: context.use_privatekey(config.tls_private_key) context.load_tmp_dh(config.tls_dh_params_path) context.set_cipher_list("!ADH:HIGH+kEDH:!AECDH:HIGH+kEECDH")
def main(): mod = AnsibleModule( argument_spec=dict(ca_cn=dict(required=True, type='str'), save_ca_key=dict(default=False, type='bool'), clients=dict(type='list'), output_path=dict(type='str'), curve=dict(default='prime256v1', type='str')), supports_check_mode=True, add_file_common_args=True, ) km = KeyManager(crypto.get_elliptic_curve(mod.params.get('curve')), CN=mod.params.get('ca_cn')) km.add_clients(mod.params.get('clients')) out = {'changed': True, 'result': km.export()} mod.exit_json(**out)
def _tlsstartup(cnn): authname = None cert = None if libssl: # most fully featured SSL function ctx = libssl.Context(libssl.SSLv23_METHOD) ctx.set_options(libssl.OP_NO_SSLv2 | libssl.OP_NO_SSLv3 | libssl.OP_NO_TLSv1 | libssl.OP_NO_TLSv1_1 | libssl.OP_CIPHER_SERVER_PREFERENCE) ctx.set_cipher_list( 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:' 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384') ctx.set_tmp_ecdh(crypto.get_elliptic_curve('secp384r1')) ctx.use_certificate_file('/etc/confluent/srvcert.pem') ctx.use_privatekey_file('/etc/confluent/privkey.pem') ctx.set_verify(libssln.VERIFY_PEER, lambda *args: True) libssln._lib.SSL_CTX_set_cert_verify_callback(ctx._context, verify_stub, ffi.NULL) cnn = libssl.Connection(ctx, cnn) cnn.set_accept_state() cnn.do_handshake() cert = cnn.get_peer_certificate() else: try: # Try relatively newer python TLS function ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ctx.options |= ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 ctx.options |= ssl.OP_CIPHER_SERVER_PREFERENCE ctx.set_ciphers( 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:' 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384') ctx.load_cert_chain('/etc/confluent/srvcert.pem', '/etc/confluent/privkey.pem') cnn = ctx.wrap_socket(cnn, server_side=True) except AttributeError: # Python 2.6 era, go with best effort cnn = ssl.wrap_socket(cnn, keyfile="/etc/confluent/privkey.pem", certfile="/etc/confluent/srvcert.pem", ssl_version=ssl.PROTOCOL_TLSv1, server_side=True) sessionhdl(cnn, authname, cert=cert)
def get_context(self): """Return an SSL.Context from self attributes.""" cont = SSL.Context(SSL.SSLv23_METHOD) # override: ciphers = ( 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:' 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:' '!aNULL:!eNULL:!MD5:!DSS:!RC4:!SSLv2' ) cont.set_options(SSL.OP_NO_COMPRESSION | SSL.OP_SINGLE_DH_USE | SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3) cont.set_cipher_list(ciphers) if self.dhparam is not None: cont.load_tmp_dh(self.dhparam) cont.set_tmp_ecdh(crypto.get_elliptic_curve('prime256v1')) # end override cont.use_privatekey_file(self.private_key) if self.certificate_chain: cont.load_verify_locations(self.certificate_chain) cont.use_certificate_file(self.certificate) return cont
def get_context(self): """Return an SSL.Context from self attributes.""" # See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/442473 c = SSL.Context(SSL.SSLv23_METHOD) c.set_options(SSL.OP_NO_SSLv2) c.set_options(SSL.OP_NO_SSLv3) if self.dh_params: c.load_tmp_dh(self.dh_params) c.set_tmp_ecdh(crypto.get_elliptic_curve('prime256v1')) c.set_options(SSL.OP_SINGLE_DH_USE) c.set_cipher_list(':'.join(( 'ECDHE-ECDSA-AES128-GCM-SHA256', 'ECDHE-RSA-AES128-GCM-SHA256', 'ECDHE-ECDSA-AES128-SHA256', 'ECDHE-RSA-AES128-SHA256', 'ECDHE-ECDSA-AES128-SHA', 'ECDHE-RSA-AES128-SHA', 'ECDHE-ECDSA-AES256-GCM-SHA384', 'ECDHE-RSA-AES256-GCM-SHA384', 'ECDHE-ECDSA-AES256-SHA384', 'ECDHE-RSA-AES256-SHA384', 'ECDHE-RSA-AES256-SHA', 'ECDHE-ECDSA-AES256-SHA', 'AES128-GCM-SHA256', 'AES128-SHA256', 'AES128-SHA', 'AES256-GCM-SHA384', 'AES256-SHA256', 'AES256-SHA', 'DES-CBC3-SHA', ))) c.use_privatekey_file(self.private_key) if self.certificate_chain: c.load_verify_locations(self.certificate_chain) c.use_certificate_file(self.certificate) return c
def cacheContext(self): if self._context is None: ctx = self._contextFactory(self.sslmethod) # SSL hardening # ctx.set_options(SSL_DEFAULT_OPTIONS) if self._ciphers: ctx.set_cipher_list(self._ciphers) self.log.info("Using explicit cipher list.") else: ctx.set_cipher_list(SSL_DEFAULT_CIPHERS) self.log.info("Using default cipher list.") # Activate DH(E) # # http://linux.die.net/man/3/ssl_ctx_set_tmp_dh # http://linux.die.net/man/1/dhparam # if self._dhParamFilename: try: ctx.load_tmp_dh(self._dhParamFilename) except Exception: self.log.failure("Error: OpenSSL DH modes not active - failed to load DH parameter file [{log_failure}]") else: self.log.info("Ok, OpenSSL Diffie-Hellman ciphers parameter file loaded.") else: self.log.warn("OpenSSL DH modes not active - missing DH param file") # Activate ECDH(E) # # This needs pyOpenSSL 0.15 # try: # without setting a curve, ECDH won't be available even if listed # in SSL_DEFAULT_CIPHERS! # curve must be one of OpenSSL.crypto.get_elliptic_curves() # curve = crypto.get_elliptic_curve(ECDH_DEFAULT_CURVE_NAME) ctx.set_tmp_ecdh(curve) except Exception: self.log.failure("Warning: OpenSSL failed to set ECDH default curve [{log_failure}]") else: self.log.info("Ok, OpenSSL is using ECDH elliptic curve {curve}", curve=ECDH_DEFAULT_CURVE_NAME) # load certificate (chain) into context # if not self._chainedCertificate: cert = crypto.load_certificate(crypto.FILETYPE_PEM, self._certificateString) ctx.use_certificate(cert) else: # http://pyopenssl.sourceforge.net/pyOpenSSL.html/openssl-context.html # there is no "use_certificate_chain" function, so we need to create # a temporary file writing the certificate chain file f = tempfile.NamedTemporaryFile(delete=False) f.write(self._certificateString) f.close() ctx.use_certificate_chain_file(f.name) store = ctx.get_cert_store() for cert in self._ca_certs: store.add_cert(cert.original) ctx.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, self._verify_peer) # load private key into context # key = crypto.load_privatekey(crypto.FILETYPE_PEM, self._privateKeyString) ctx.use_privatekey(key) ctx.check_privatekey() # set cached context # self._context = ctx
def set_curve(self, curve_name): curve = get_elliptic_curve(curve_name) self._context.set_tmp_ecdh(curve)
def cacheContext(self): if self._context is None: ctx = self._contextFactory(self.sslmethod) # SSL hardening # ctx.set_options(SSL_DEFAULT_OPTIONS) if self._ciphers: ctx.set_cipher_list(self._ciphers) self.log.info("Using explicit cipher list.") else: ctx.set_cipher_list(SSL_DEFAULT_CIPHERS) self.log.info("Using default cipher list.") # Activate DH(E) # # http://linux.die.net/man/3/ssl_ctx_set_tmp_dh # http://linux.die.net/man/1/dhparam # if self._dhParamFilename: try: ctx.load_tmp_dh(self._dhParamFilename) except Exception: self.log.failure( "Error: OpenSSL DH modes not active - failed to load DH parameter file [{log_failure}]" ) else: self.log.info( "Ok, OpenSSL Diffie-Hellman ciphers parameter file loaded." ) else: self.log.warn( "OpenSSL DH modes not active - missing DH param file") # Activate ECDH(E) # # This needs pyOpenSSL 0.15 # try: # without setting a curve, ECDH won't be available even if listed # in SSL_DEFAULT_CIPHERS! # curve must be one of OpenSSL.crypto.get_elliptic_curves() # curve = crypto.get_elliptic_curve(ECDH_DEFAULT_CURVE_NAME) ctx.set_tmp_ecdh(curve) except Exception: self.log.failure( "Warning: OpenSSL failed to set ECDH default curve [{log_failure}]" ) else: self.log.info( "Ok, OpenSSL is using ECDH elliptic curve {curve}", curve=ECDH_DEFAULT_CURVE_NAME) # load certificate (chain) into context # if not self._chainedCertificate: cert = crypto.load_certificate(crypto.FILETYPE_PEM, self._certificateString) ctx.use_certificate(cert) else: # http://pyopenssl.sourceforge.net/pyOpenSSL.html/openssl-context.html # there is no "use_certificate_chain" function, so we need to create # a temporary file writing the certificate chain file f = tempfile.NamedTemporaryFile(delete=False) f.write(self._certificateString) f.close() ctx.use_certificate_chain_file(f.name) # load private key into context # key = crypto.load_privatekey(crypto.FILETYPE_PEM, self._privateKeyString) ctx.use_privatekey(key) ctx.check_privatekey() # set cached context # self._context = ctx
def cacheContext(self): if self._context is None: ctx = self._contextFactory(self.sslmethod) ## SSL hardening ## ctx.set_options(SSL_DEFAULT_OPTIONS) if self._ciphers: ctx.set_cipher_list(self._ciphers) log.msg("Using explicit cipher list.") else: ctx.set_cipher_list(SSL_DEFAULT_CIPHERS) log.msg("Using default cipher list.") ## Activate DH(E) ## ## http://linux.die.net/man/3/ssl_ctx_set_tmp_dh ## http://linux.die.net/man/1/dhparam ## if self._dhParamFilename: try: ctx.load_tmp_dh(self._dhParamFilename) except Exception as e: log.msg("Error: OpenSSL DH modes not active - failed to load DH parameter file [{}]".format(e)) else: log.msg("Ok, OpenSSL Diffie-Hellman ciphers parameter file loaded.") else: log.msg("Warning: OpenSSL DH modes not active - missing DH param file") ## Activate ECDH(E) ## ## This needs pyOpenSSL 0.15 ## try: ## without setting a curve, ECDH won't be available even if listed ## in SSL_DEFAULT_CIPHERS! ## curve must be one of OpenSSL.crypto.get_elliptic_curves() ## curve = crypto.get_elliptic_curve(ECDH_DEFAULT_CURVE_NAME) ctx.set_tmp_ecdh(curve) except Exception as e: log.msg("Warning: OpenSSL failed to set ECDH default curve [{}]".format(e)) else: log.msg("Ok, OpenSSL is using ECDH elliptic curve {}".format(ECDH_DEFAULT_CURVE_NAME)) ## load certificate (chain) into context ## if not self._chainedCertificate: cert = crypto.load_certificate(crypto.FILETYPE_PEM, self._certificateString) ctx.use_certificate(cert) else: # http://pyopenssl.sourceforge.net/pyOpenSSL.html/openssl-context.html # there is no "use_certificate_chain" function, so we need to create # a temporary file writing the certificate chain file f = tempfile.NamedTemporaryFile(delete = False) f.write(self._certificateString) f.close() ctx.use_certificate_chain_file(f.name) ## load private key into context ## key = crypto.load_privatekey(crypto.FILETYPE_PEM, self._privateKeyString) ctx.use_privatekey(key) ctx.check_privatekey() ## set cached context ## self._context = ctx