mirror of https://github.com/nucypher/nucypher.git
Modify character classes to use runtime files and directories: certificates and metadata
parent
47d50a9e1a
commit
9842b5d096
|
@ -45,7 +45,7 @@ class NucypherTokenActor:
|
||||||
self.checksum_public_address = checksum_address
|
self.checksum_public_address = checksum_address
|
||||||
|
|
||||||
if registry_filepath is not None:
|
if registry_filepath is not None:
|
||||||
EthereumContractRegistry.from_config(registry_filepath=registry_filepath)
|
EthereumContractRegistry(registry_filepath=registry_filepath)
|
||||||
|
|
||||||
self.token_agent = token_agent if token_agent is not None else NucypherTokenAgent()
|
self.token_agent = token_agent if token_agent is not None else NucypherTokenAgent()
|
||||||
self._transaction_cache = list() # track transactions transmitted
|
self._transaction_cache = list() # track transactions transmitted
|
||||||
|
|
|
@ -304,8 +304,9 @@ class Character(Teacher):
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
is_me: bool = True,
|
is_me: bool = True,
|
||||||
config_root=DEFAULT_CONFIG_ROOT,
|
|
||||||
network_middleware: RestMiddleware = None,
|
network_middleware: RestMiddleware = None,
|
||||||
|
known_certificates_dir: str = None,
|
||||||
|
known_metadata_dir: str = None,
|
||||||
crypto_power: CryptoPower = None,
|
crypto_power: CryptoPower = None,
|
||||||
crypto_power_ups: List[CryptoPowerUp] = None,
|
crypto_power_ups: List[CryptoPowerUp] = None,
|
||||||
federated_only: bool = False,
|
federated_only: bool = False,
|
||||||
|
@ -337,8 +338,9 @@ class Character(Teacher):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.config_root = config_root
|
|
||||||
self.federated_only = federated_only # type: bool
|
self.federated_only = federated_only # type: bool
|
||||||
|
self.known_certificates_dir = known_certificates_dir
|
||||||
|
self.known_metadata_dir = known_metadata_dir
|
||||||
|
|
||||||
#
|
#
|
||||||
# Power-ups and Powers
|
# Power-ups and Powers
|
||||||
|
@ -487,9 +489,12 @@ class Character(Teacher):
|
||||||
|
|
||||||
unresponsive_nodes = set()
|
unresponsive_nodes = set()
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
# FIXME
|
||||||
response = self.network_middleware.get_nodes_via_rest(rest_url,
|
response = self.network_middleware.get_nodes_via_rest(rest_url,
|
||||||
nodes_i_need=self._node_ids_to_learn_about_immediately,
|
nodes_i_need=self._node_ids_to_learn_about_immediately,
|
||||||
announce_nodes=announce_nodes)
|
announce_nodes=announce_nodes,
|
||||||
|
certificate_path=current_teacher.certificate_filepath)
|
||||||
except requests.exceptions.ConnectionError:
|
except requests.exceptions.ConnectionError:
|
||||||
unresponsive_nodes.add(current_teacher)
|
unresponsive_nodes.add(current_teacher)
|
||||||
teacher_rest_info = current_teacher.rest_information()[0]
|
teacher_rest_info = current_teacher.rest_information()[0]
|
||||||
|
|
|
@ -405,7 +405,7 @@ class Ursula(Character, VerifiableNode, Miner):
|
||||||
rest_host,
|
rest_host,
|
||||||
rest_port,
|
rest_port,
|
||||||
certificate=None,
|
certificate=None,
|
||||||
certificate_dir=None,
|
certificate_filepath: str = None,
|
||||||
db_name=None,
|
db_name=None,
|
||||||
is_me=True,
|
is_me=True,
|
||||||
interface_signature=None,
|
interface_signature=None,
|
||||||
|
@ -413,6 +413,7 @@ class Ursula(Character, VerifiableNode, Miner):
|
||||||
# Blockchain
|
# Blockchain
|
||||||
miner_agent=None,
|
miner_agent=None,
|
||||||
checksum_address: str = None,
|
checksum_address: str = None,
|
||||||
|
registry_filepath: str = None,
|
||||||
|
|
||||||
# Character
|
# Character
|
||||||
abort_on_learning_error: bool = False,
|
abort_on_learning_error: bool = False,
|
||||||
|
@ -443,7 +444,8 @@ class Ursula(Character, VerifiableNode, Miner):
|
||||||
Miner.__init__(self,
|
Miner.__init__(self,
|
||||||
is_me=is_me,
|
is_me=is_me,
|
||||||
miner_agent=miner_agent,
|
miner_agent=miner_agent,
|
||||||
checksum_address=checksum_address)
|
checksum_address=checksum_address,
|
||||||
|
registry_filepath=registry_filepath)
|
||||||
|
|
||||||
blockchain_power = BlockchainPower(blockchain=self.blockchain, account=self.checksum_public_address)
|
blockchain_power = BlockchainPower(blockchain=self.blockchain, account=self.checksum_public_address)
|
||||||
self._crypto_power.consume_power_up(blockchain_power)
|
self._crypto_power.consume_power_up(blockchain_power)
|
||||||
|
@ -489,26 +491,34 @@ class Ursula(Character, VerifiableNode, Miner):
|
||||||
curve=tls_curve,
|
curve=tls_curve,
|
||||||
host=rest_host,
|
host=rest_host,
|
||||||
certificate=certificate,
|
certificate=certificate,
|
||||||
certificate_dir=certificate_dir)
|
certificate_dir=self.known_certificates_dir)
|
||||||
|
|
||||||
tls_hosting_power = TLSHostingPower(rest_server=rest_server,
|
tls_hosting_power = TLSHostingPower(rest_server=rest_server,
|
||||||
keypair=tls_hosting_keypair)
|
keypair=tls_hosting_keypair)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Unless the caller passed a crypto power, we'll make our own TLSHostingPower for this stranger.
|
# Unless the caller passed a crypto power, we'll make our own TLSHostingPower for this stranger.
|
||||||
rest_server = ProxyRESTServer(
|
rest_server = ProxyRESTServer(
|
||||||
rest_host=rest_host,
|
rest_host=rest_host,
|
||||||
rest_port=rest_port,
|
rest_port=rest_port,
|
||||||
)
|
)
|
||||||
if certificate:
|
if certificate or certificate_filepath:
|
||||||
tls_hosting_power = TLSHostingPower(rest_server=rest_server, certificate=certificate)
|
tls_hosting_power = TLSHostingPower(rest_server=rest_server,
|
||||||
|
certificate_filepath=certificate_filepath,
|
||||||
|
certificate=certificate)
|
||||||
else:
|
else:
|
||||||
tls_hosting_keypair = HostingKeypair(
|
tls_hosting_keypair = HostingKeypair(
|
||||||
common_name=self.checksum_public_address,
|
common_name=self.checksum_public_address,
|
||||||
curve=tls_curve,
|
curve=tls_curve,
|
||||||
host=rest_host,
|
host=rest_host,
|
||||||
certificate_dir=certificate_dir)
|
certificate_filepath=certificate_filepath,
|
||||||
|
certificate_dir=self.known_certificates_dir)
|
||||||
|
|
||||||
tls_hosting_power = TLSHostingPower(rest_server=rest_server,
|
tls_hosting_power = TLSHostingPower(rest_server=rest_server,
|
||||||
keypair=tls_hosting_keypair)
|
keypair=tls_hosting_keypair)
|
||||||
|
|
||||||
self._crypto_power.consume_power_up(tls_hosting_power) # Make this work for not me for certificate to work
|
self._crypto_power.consume_power_up(tls_hosting_power) # Make this work for not me for certificate to work
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.log.info("Not adhering rest_server; we'll use the one on crypto_power..")
|
self.log.info("Not adhering rest_server; we'll use the one on crypto_power..")
|
||||||
|
|
||||||
|
|
|
@ -117,17 +117,13 @@ def ecdsa_verify(
|
||||||
def _save_tls_certificate(certificate: Certificate,
|
def _save_tls_certificate(certificate: Certificate,
|
||||||
directory: str,
|
directory: str,
|
||||||
common_name: str = None,
|
common_name: str = None,
|
||||||
is_me: bool = False,
|
|
||||||
force: bool = True,
|
force: bool = True,
|
||||||
) -> str:
|
) -> str:
|
||||||
|
|
||||||
if is_me is False and not common_name:
|
certificate_filepath = os.path.join(directory, '{}.pem'.format(common_name[2:8]))
|
||||||
raise NucypherConfigurationError('A common name must be passed to save another node\'s certificate.')
|
|
||||||
|
|
||||||
certificate_filepath = os.path.join(directory, '{}.pem'.format(common_name[:6]))
|
|
||||||
|
|
||||||
if force is False and os.path.isfile(certificate_filepath):
|
if force is False and os.path.isfile(certificate_filepath):
|
||||||
raise NucypherConfigurationError('A TLS certificate already exists at {}.'.format(certificate_filepath))
|
raise FileExistsError('A TLS certificate already exists at {}.'.format(certificate_filepath))
|
||||||
|
|
||||||
with open(certificate_filepath, 'wb') as certificate_file:
|
with open(certificate_filepath, 'wb') as certificate_file:
|
||||||
public_pem_bytes = certificate.public_bytes(Encoding.PEM)
|
public_pem_bytes = certificate.public_bytes(Encoding.PEM)
|
||||||
|
@ -146,9 +142,10 @@ def load_tls_certificate(filepath):
|
||||||
def generate_self_signed_certificate(common_name,
|
def generate_self_signed_certificate(common_name,
|
||||||
curve,
|
curve,
|
||||||
host,
|
host,
|
||||||
|
certificate_dir,
|
||||||
private_key=None,
|
private_key=None,
|
||||||
days_valid=365,
|
days_valid=365,
|
||||||
certificate_dir=None):
|
):
|
||||||
|
|
||||||
if not private_key:
|
if not private_key:
|
||||||
private_key = ec.generate_private_key(curve, default_backend())
|
private_key = ec.generate_private_key(curve, default_backend())
|
||||||
|
@ -169,10 +166,10 @@ def generate_self_signed_certificate(common_name,
|
||||||
cert = cert.add_extension(x509.SubjectAlternativeName([x509.DNSName(host)]), critical=False)
|
cert = cert.add_extension(x509.SubjectAlternativeName([x509.DNSName(host)]), critical=False)
|
||||||
cert = cert.sign(private_key, hashes.SHA512(), default_backend())
|
cert = cert.sign(private_key, hashes.SHA512(), default_backend())
|
||||||
|
|
||||||
if certificate_dir:
|
# if certificate_dir:
|
||||||
tls_certificate_filepath = _save_tls_certificate(cert, directory=certificate_dir, common_name=common_name)
|
tls_certificate_filepath = _save_tls_certificate(cert, directory=certificate_dir, common_name=common_name)
|
||||||
else:
|
# else:
|
||||||
tls_certificate_filepath = constants.CERTIFICATE_NOT_SAVED
|
# tls_certificate_filepath = constants.CERTIFICATE_NOT_SAVED
|
||||||
|
|
||||||
return cert, private_key, tls_certificate_filepath
|
return cert, private_key, tls_certificate_filepath
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ from umbral.keys import UmbralPrivateKey, UmbralPublicKey
|
||||||
from umbral.signing import Signature, Signer
|
from umbral.signing import Signature, Signer
|
||||||
|
|
||||||
from nucypher.crypto import api as API
|
from nucypher.crypto import api as API
|
||||||
from nucypher.crypto.api import generate_self_signed_certificate, _save_tls_certificate
|
from nucypher.crypto.api import generate_self_signed_certificate, _save_tls_certificate, load_tls_certificate
|
||||||
from nucypher.crypto.kits import MessageKit
|
from nucypher.crypto.kits import MessageKit
|
||||||
from nucypher.crypto.signing import SignatureStamp, StrangerStamp
|
from nucypher.crypto.signing import SignatureStamp, StrangerStamp
|
||||||
|
|
||||||
|
@ -132,46 +132,47 @@ class HostingKeypair(Keypair):
|
||||||
common_name=None,
|
common_name=None,
|
||||||
host=None,
|
host=None,
|
||||||
private_key: Union[UmbralPrivateKey, UmbralPublicKey] = None,
|
private_key: Union[UmbralPrivateKey, UmbralPublicKey] = None,
|
||||||
certificate=None,
|
|
||||||
curve=None,
|
curve=None,
|
||||||
generate_keys_if_needed=True,
|
certificate=None,
|
||||||
|
certificate_filepath: str = None,
|
||||||
certificate_dir=None,
|
certificate_dir=None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.curve = curve or self._DEFAULT_CURVE
|
self.curve = curve or self._DEFAULT_CURVE
|
||||||
self.certificate_filepath = None
|
|
||||||
|
|
||||||
if private_key:
|
if private_key:
|
||||||
super().__init__(private_key=private_key)
|
super().__init__(private_key=private_key)
|
||||||
|
|
||||||
elif certificate:
|
elif certificate:
|
||||||
self.certificate = certificate
|
|
||||||
super().__init__(public_key=certificate.public_key())
|
super().__init__(public_key=certificate.public_key())
|
||||||
|
|
||||||
elif generate_keys_if_needed:
|
elif certificate_filepath:
|
||||||
|
certificate = load_tls_certificate(filepath=certificate_filepath)
|
||||||
|
|
||||||
|
elif generate_certificate:
|
||||||
|
|
||||||
if not all((common_name, host)):
|
if not all((common_name, host)):
|
||||||
message = "If you don't supply the certificate, one will be generated for you." \
|
message = "If you don't supply the certificate, one will be generated for you." \
|
||||||
"But for that, you need to pass both host and common_name.."
|
"But for that, you need to pass both host and common_name.."
|
||||||
raise TypeError(message)
|
raise TypeError(message)
|
||||||
self.certificate, private_key, self.certificate_filepath = generate_self_signed_certificate(common_name=common_name,
|
|
||||||
private_key=private_key,
|
certificate, private_key, certificate_filepath = generate_self_signed_certificate(common_name=common_name,
|
||||||
curve=self.curve,
|
private_key=private_key,
|
||||||
host=host,
|
curve=self.curve,
|
||||||
)
|
host=host,
|
||||||
|
certificate_dir=certificate_dir)
|
||||||
|
|
||||||
super().__init__(private_key=private_key)
|
super().__init__(private_key=private_key)
|
||||||
else:
|
else:
|
||||||
raise TypeError("You didn't provide a cert, but also told us not to generate keys. Not sure what to do.")
|
raise TypeError("You didn't provide a cert, but also told us not to generate keys. Not sure what to do.")
|
||||||
|
|
||||||
if certificate_dir:
|
self.certificate = certificate
|
||||||
self.certificate_filepath = _save_tls_certificate(self.certificate,
|
self.certificate_filepath = certificate_filepath
|
||||||
directory=certificate_dir,
|
self.certificate_dir = certificate_dir
|
||||||
common_name=common_name,
|
|
||||||
is_me=False,
|
|
||||||
force=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
def generate_self_signed_cert(self, common_name):
|
def generate_self_signed_cert(self, common_name):
|
||||||
cryptography_key = self._privkey.to_cryptography_privkey()
|
cryptography_key = self._privkey.to_cryptography_privkey()
|
||||||
return generate_self_signed_certificate(common_name, default_curve(), cryptography_key)
|
return generate_self_signed_certificate(common_name, default_curve(),
|
||||||
|
cryptography_key, certificate_dir=self.certificate_dir)
|
||||||
|
|
||||||
def get_deployer(self, rest_app, port):
|
def get_deployer(self, rest_app, port):
|
||||||
return HendrixDeployTLS("start",
|
return HendrixDeployTLS("start",
|
||||||
|
|
|
@ -9,20 +9,18 @@ from umbral.fragments import CapsuleFrag
|
||||||
class RestMiddleware:
|
class RestMiddleware:
|
||||||
|
|
||||||
def consider_arrangement(self, arrangement, certificate_path):
|
def consider_arrangement(self, arrangement, certificate_path):
|
||||||
certificate = load_tls_certificate(filepath=certificate_path)
|
|
||||||
node = arrangement.ursula
|
node = arrangement.ursula
|
||||||
port = node.rest_interface.port
|
port = node.rest_interface.port
|
||||||
address = node.rest_interface.host
|
address = node.rest_interface.host
|
||||||
response = requests.post("https://{}:{}/consider_arrangement".format(address, port), bytes(arrangement), verify=certificate)
|
response = requests.post("https://{}:{}/consider_arrangement".format(address, port), bytes(arrangement), verify=certificate_path)
|
||||||
if not response.status_code == 200:
|
if not response.status_code == 200:
|
||||||
raise RuntimeError("Bad response: {}".format(response.content))
|
raise RuntimeError("Bad response: {}".format(response.content))
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def enact_policy(self, ursula, id, payload, certificate_path):
|
def enact_policy(self, ursula, id, payload, certificate_path):
|
||||||
certificate = load_tls_certificate(filepath=certificate_path)
|
|
||||||
port = ursula.rest_interface.port
|
port = ursula.rest_interface.port
|
||||||
address = ursula.rest_interface.host
|
address = ursula.rest_interface.host
|
||||||
response = requests.post('https://{}:{}/kFrag/{}'.format(address, port, id.hex()), payload, verify=certificate)
|
response = requests.post('https://{}:{}/kFrag/{}'.format(address, port, id.hex()), payload, verify=certificate_path)
|
||||||
if not response.status_code == 200:
|
if not response.status_code == 200:
|
||||||
raise RuntimeError("Bad response: {}".format(response.content))
|
raise RuntimeError("Bad response: {}".format(response.content))
|
||||||
return True, ursula.stamp.as_umbral_pubkey()
|
return True, ursula.stamp.as_umbral_pubkey()
|
||||||
|
|
Loading…
Reference in New Issue