def _save_certificates(sip_address, crt, key, ca): crt = crt.strip() + os.linesep key = key.strip() + os.linesep ca = ca.strip() + os.linesep X509Certificate(crt) X509PrivateKey(key) X509Certificate(ca) makedirs(ApplicationData.get('tls')) certificate_path = ApplicationData.get( os.path.join('tls', sip_address + '.crt')) certificate_file = open(certificate_path, 'w') os.chmod(certificate_path, 0600) certificate_file.write(crt + key) certificate_file.close() ca_path = ApplicationData.get(os.path.join('tls', 'ca.crt')) try: existing_cas = open(ca_path).read().strip() + os.linesep except: certificate_file = open(ca_path, 'w') certificate_file.write(ca) certificate_file.close() else: if ca not in existing_cas: certificate_file = open(ca_path, 'w') certificate_file.write(existing_cas + ca) certificate_file.close() settings = SIPSimpleSettings() settings.tls.ca_list = ca_path settings.save() return certificate_path
def tls_credentials(self): # This property can be optimized to cache the credentials it loads from disk, # however this is not a time consuming operation (~ 3000 req/sec). -Luci settings = SIPSimpleSettings() tls_certificate = self.tls.certificate or settings.tls.certificate certificate = None private_key = None if tls_certificate is not None: try: certificate_data = open(tls_certificate.normalized).read() certificate = X509Certificate(certificate_data) private_key = X509PrivateKey(certificate_data) except (FileNotFoundError, GNUTLSError, UnicodeDecodeError): pass trusted_cas = [] ca_list = self.tls.ca_list or settings.tls.ca_list if ca_list is not None: if len(self.trusted_cas) > 0: trusted_cas = self.trusted_cas else: crt = None start = False try: ca_text = open(ca_list.normalized).read() except (FileNotFoundError, GNUTLSError, UnicodeDecodeError): ca_text = '' for line in ca_text.split("\n"): if "BEGIN CERT" in line: start = True crt = line + "\n" elif "END CERT" in line: crt = crt + line + "\n" end = True start = False try: trusted_cas.append(X509Certificate(crt)) except (GNUTLSError, ValueError) as e: continue elif start: crt = crt + line + "\n" self.trusted_cas = trusted_cas self.ca_list = ca_list credentials = X509Credentials(certificate, private_key, trusted_cas) credentials.verify_peer = self.tls.verify_server or settings.tls.certificate return credentials
def add_certificate_authority(self, ca): # not used anymore, let users add CAs in keychain instead try: X509Certificate(ca) except GNUTLSError, e: BlinkLogger().log_error(u"Invalid Certificate Authority: %s" % e) return False
def trusted_cas(content): trusted_cas = [] crt = '' start = False end = False content = content or '' content = content.decode() if isinstance(content, bytes) else content for line in content.split("\n"): if "BEGIN CERT" in line: start = True crt = line + "\n" elif "END CERT" in line: crt = crt + line + "\n" end = True start = False try: trusted_cas.append(X509Certificate(crt)) except (GNUTLSError, ValueError) as e: continue elif start: crt = crt + line + "\n" return trusted_cas
def save_certificates(self, response): passport = response["passport"] address = response["sip_address"] tls_folder = ApplicationData.get('tls') if not os.path.exists(tls_folder): os.mkdir(tls_folder, 0o700) ca = passport["ca"].strip() + os.linesep self.add_certificate_authority(ca) crt = passport["crt"].strip() + os.linesep try: X509Certificate(crt) except GNUTLSError as e: BlinkLogger().log_error("Invalid TLS certificate: %s" % e) return None key = passport["key"].strip() + os.linesep try: X509PrivateKey(key) except GNUTLSError as e: BlinkLogger().log_error("Invalid Private Key: %s" % e) return None crt_path = os.path.join(tls_folder, address + ".crt") f = open(crt_path, "w") os.chmod(crt_path, 0o600) f.write(crt) f.write(key) f.close() BlinkLogger().log_info("Saved new TLS Certificate and Private Key to %s" % crt_path) return crt_path
def __new__(cls, value): if isinstance(value, str): try: return X509Certificate(file_content(value)) except Exception, e: log.warn("Certificate file '%s' could not be loaded: %s" % (value, str(e))) return None
def __new__(cls, value): if isinstance(value, basestring): try: return X509Certificate(file_content(value)) except Exception as e: log.warn("Certificate file '%s' could not be loaded: %s" % (value, str(e))) return None else: raise TypeError('value should be a string')
def peer_certificate(self): if gnutls_certificate_type_get(self._c_object) != GNUTLS_CRT_X509: return None list_size = c_uint() cert_list = gnutls_certificate_get_peers(self._c_object, byref(list_size)) if list_size.value == 0: return None cert = cert_list[0] return X509Certificate(string_at(cert.data, cert.size), GNUTLS_X509_FMT_DER)
def tls_credentials(self): # This property can be optimized to cache the credentials it loads from disk, # however this is not a time consuming operation (~ 3000 req/sec). -Luci settings = SIPSimpleSettings() if self.tls.certificate is not None: certificate_data = open(self.tls.certificate.normalized).read() certificate = X509Certificate(certificate_data) private_key = X509PrivateKey(certificate_data) else: certificate = None private_key = None if settings.tls.ca_list is not None: # we should read all certificates in the file, rather than just the first -Luci trusted = [ X509Certificate(open(settings.tls.ca_list.normalized).read()) ] else: trusted = [] credentials = X509Credentials(certificate, private_key, trusted) credentials.verify_peer = self.tls.verify_server return credentials
def verify_server_certs(self, certs_cell): tls_link_cert = self.remote.peer_certificate.export(X509_FMT_DER) link_cert = None id_cert = None for type_num, cert in self.server_or_conn.parse_certs_cell(certs_cell): if type_num == 1: link_cert = cert if type_num == 2: id_cert = cert if not link_cert: raise ORError("Missing Link certificate in server CERTS cell") if not id_cert: raise ORError("Missing ID certificate in server CERTS cell") if link_cert != tls_link_cert: raise ORError( "Link certificate in CERTS cell does not match TLS link certificate" ) try: self.remote.peer_certificate.check_issuer( X509Certificate(id_cert, format=X509_FMT_DER)) except GNUTLSError: raise ORError("Link certificate is incorrectly signed") try: server_identity = RSA.import_key(id_cert) except (ValueError, IndexError, TypeError): raise ORError("Error in RSA key parsing") if self.server.config.server_fingerprint: server_fingerprint = self.server.config.server_fingerprint.strip( ).lower() server_key = DerSequence([server_identity.n, server_identity.e]).encode() remote_fingerprint = SHA1.new(server_key).hexdigest() if remote_fingerprint != server_fingerprint: raise ORError( "Server ID certificate does not match the configured fingerprint: " "expected {} but got {}".format( server_fingerprint.upper(), remote_fingerprint.upper()))
def tls_credentials(self): # This property can be optimized to cache the credentials it loads from disk, # however this is not a time consuming operation (~ 3000 req/sec). -Luci settings = SIPSimpleSettings() tls_certificate = self.tls.certificate or settings.tls.certificate if tls_certificate is not None: certificate_data = open(tls_certificate.normalized).read() certificate = X509Certificate(certificate_data) private_key = X509PrivateKey(certificate_data) else: certificate = None private_key = None credentials = X509Credentials(certificate, private_key, []) credentials.verify_peer = False return credentials
def save_certificates(self, response): passport = response["passport"] address = response["sip_address"] tls_folder = ApplicationData.get('tls') if not os.path.exists(tls_folder): os.mkdir(tls_folder, 0700) ca = passport["ca"].strip() + os.linesep self.add_certificate_authority(ca) crt = passport["crt"].strip() + os.linesep try: X509Certificate(crt) except GNUTLSError, e: BlinkLogger().log_error(u"Invalid TLS certificate: %s" % e) return None
def __init__(self, config, bind_and_activate=True): self.config = config if is_ipv6_address(self.config.listen_address): self.address_family = socket.AF_INET6 with open(self.config.cert, 'rb') as f: self.encoded_cert = f.read() with open(self.config.key, 'r') as f: self.key = f.read() with open(self.config.onion_secret_key, 'r') as f: self.onion_secret_key = f.read() self.set_handler() self.server_context = TLSContext( X509Credentials( X509Certificate(self.encoded_cert, format=X509_FMT_DER), X509PrivateKey(self.key)), config.priority_string_as_server) self.client_context = TLSContext(X509Credentials(), config.priority_string_as_client) self.identity_pubkey = RSA.import_key(self.encoded_cert) self.identity_privkey = RSA.import_key(self.key) self.onion_privkey = RSA.import_key(self.onion_secret_key) ntor_onion_secret_key = self.config.ntor_onion_secret_key.decode( "base64").strip() self.ntor_onion_key = NTorOnionKey( ntor_onion_secret_key, NTorKey(ntor_onion_secret_key).get_public()) self.fingerprint = self.make_digest_fingerprint() self.descriptor = self.create_bridge_descriptor() self.dir_identity_response = self.create_dir_response() self.print_fingerprint() SocketServer.ThreadingTCPServer.__init__(self, config.listen_address, ORMITMHandler, bind_and_activate)
def _parseTLS(factory, port, privateKey='server.pem', certKey=None, sslmethod=None, interface='', backlog=50): from gnutls.interfaces.twisted import X509Credentials from gnutls.crypto import X509Certificate, X509PrivateKey if certKey is None: certKey = privateKey cert = X509Certificate(open(certKey).read()) key = X509PrivateKey(open(privateKey).read()) cf = X509Credentials(cert, key) return ((int(port), factory, cf), { 'interface': interface, 'backlog': int(backlog) })
def add_certificate_authority(self, ca): # not used anymore, let users add CAs in keychain instead try: X509Certificate(ca) except GNUTLSError as e: BlinkLogger().log_error("Invalid Certificate Authority: %s" % e) return False settings = SIPSimpleSettings() must_save_ca = False if settings.tls.ca_list is not None: ca_path = settings.tls.ca_list.normalized else: tls_folder = ApplicationData.get('tls') if not os.path.exists(tls_folder): os.mkdir(tls_folder, 0o700) ca_path = os.path.join(tls_folder, 'ca.crt') must_save_ca = True try: existing_cas = open(ca_path, "r").read().strip() + os.linesep except: existing_cas = None ca_list = ca else: ca_list = existing_cas if ca in existing_cas else existing_cas + ca if ca_list != existing_cas: f = open(ca_path, "w") os.chmod(ca_path, 0o600) f.write(ca_list) f.close() BlinkLogger().log_debug("Added new Certificate Authority to %s" % ca_path) must_save_ca = True if must_save_ca: settings.tls.ca_list = ca_path settings.save() return True
def init_configurations(self): account_manager = AccountManager() settings = SIPSimpleSettings() # fixup default account self._selected_account = account_manager.default_account if self._selected_account is None: self._selected_account = account_manager.get_accounts()[0] # save default ca if needed ca = open(Resources.get('ca.crt'), "r").read().strip() try: X509Certificate(ca) except GNUTLSError as e: BlinkLogger().log_error("Invalid Certificate Authority: %s" % e) return tls_folder = ApplicationData.get('tls') if not os.path.exists(tls_folder): os.mkdir(tls_folder, 0o700) ca_path = os.path.join(tls_folder, 'ca.crt') try: existing_cas = open(ca_path, "r").read().strip() except Exception: existing_cas = None if ca == existing_cas: return with open(ca_path, "wb") as f: os.chmod(ca_path, 0o600) f.write(ca.encode()) BlinkLogger().log_debug("Added default Certificate Authority to %s" % ca_path) settings.tls.ca_list = ca_path settings.save()
def set_default_certificate_authority(self, ca): try: X509Certificate(ca) except GNUTLSError, e: BlinkLogger().log_error(u"Invalid Certificate Authority: %s" % e) return False
class TLSMixin(object): use_tls = True cert = X509Certificate(open('valid.crt').read()) key = X509PrivateKey(open('valid.key').read()) server_credentials = X509Credentials(cert, key)
def __init__(self, config, bind_and_activate=True): self.config = config if is_ipv6_address(self.config.listen_address): self.address_family = socket.AF_INET6 with open(self.config.cert, 'rb') as keyfile: self.encoded_cert = keyfile.read() with open(self.config.key, 'r') as keyfile: self.key = keyfile.read() with open(self.config.onion_secret_key, 'r') as keyfile: self.onion_secret_key = keyfile.read() self.set_handler() self.server_context = TLSContext( X509Credentials( X509Certificate(self.encoded_cert, format=X509_FMT_DER), X509PrivateKey(self.key)), self.config.priority_string_as_server) if self.has_tls_client_credentials(): self.tls_credentials = self.config.client_tls_credentials else: self.tls_credentials = X509Credentials() self.client_context = TLSContext(self.tls_credentials, self.config.priority_string_as_client) self.identity_pubkey = load_der_x509_certificate( self.encoded_cert, backend=_default_backend).public_key() self.identity_privkey = load_pem_private_key(self.key, password=None, backend=_default_backend) self.onion_privkey = load_pem_private_key(self.onion_secret_key, password=None, backend=_default_backend) if not isinstance(self.identity_pubkey, RSAPublicKey): raise RuntimeError( "Certificate of instance {} does not have an RSA key".format( self.config.listen_address)) if not isinstance(self.identity_privkey, RSAPrivateKey): raise RuntimeError("Key of instance {} is not an RSA key".format( self.config.listen_address)) if not isinstance(self.onion_privkey, RSAPrivateKey): raise RuntimeError( "Onion key of instance {} is not an RSA key".format( self.config.listen_address)) ntor_onion_secret_key = base64.b64decode( self.config.ntor_onion_secret_key.strip()) self.ntor_onion_key = NTorOnionKey( ntor_onion_secret_key, NTorKey(ntor_onion_secret_key).get_public()) self.fingerprint = self.make_digest_fingerprint() self.descriptor = self.create_bridge_descriptor() self.dir_identity_response = self.create_dir_response() self.print_fingerprint() SocketServer.ThreadingTCPServer.__init__(self, self.config.listen_address, ORMITMHandler, bind_and_activate)
def verify_server_certs(self, certs_cell): tls_link_cert = self.remote.peer_certificate.export(X509_FMT_DER) link_cert = None id_cert = None for type_num, cert in self.server_or_conn.parse_certs_cell(certs_cell): if type_num == 1: if link_cert is not None: raise ORError( "CERTS cell has more than one Link certificate") link_cert = cert if type_num == 2: if id_cert is not None: raise ORError( "CERTS cell has more than one ID certificate") id_cert = cert if not link_cert: raise ORError("Missing Link certificate in server CERTS cell") if not id_cert: raise ORError("Missing ID certificate in server CERTS cell") try: link_cert_object = X509Certificate(link_cert, format=X509_FMT_DER) self.server.tls_credentials.check_certificate(link_cert_object) except GNUTLSError as exn: raise ORError("Link certificate is invalid: " + str(exn)) try: id_cert_object = X509Certificate(id_cert, format=X509_FMT_DER) self.server.tls_credentials.check_certificate(id_cert_object) except GNUTLSError as exn: raise ORError("ID certificate is invalid: " + str(exn)) if not self.server.config.allow_link_cert_mismatch: if link_cert != tls_link_cert: raise ORError( "Link certificate in CERTS cell does not match TLS link certificate" ) try: self.remote.peer_certificate.check_issuer(id_cert_object) except GNUTLSError: raise ORError("Link certificate is incorrectly signed") try: server_key = load_der_x509_certificate( id_cert, backend=_default_backend).public_key() except (ValueError, TypeError, UnsupportedAlgorithm): raise ORError("Error in RSA key parsing") if not isinstance(server_key, RSAPublicKey): raise ORError("Server identity key is not a RSA key") if (self.server.config.server_fingerprint or self.server.config.log_server_fingerprint): remote_fingerprint = pubkey_fingerprint(server_key) if self.server.config.server_fingerprint: server_fingerprint = self.server.config.server_fingerprint.strip( ).lower() if remote_fingerprint != server_fingerprint: raise ORError( "Server ID certificate does not match the configured fingerprint: " "expected {} but got {}".format( server_fingerprint.upper(), remote_fingerprint.upper())) if self.server.config.log_server_fingerprint: logging.info("Router %s has fingerprint %s", self.server.config.server_address, remote_fingerprint.upper())