Exemple #1
0
    def create_v2_instances(self):
        instances = []

        for i in range(0, self.num_instances):
            instance_key = Crypto.PublicKey.RSA.generate(1024)
            instance_address = util.calc_onion_address(instance_key)
            logger.debug("Created a key for instance %s.onion.",
                         instance_address)
            instances.append((instance_address, instance_key))

        return instances
Exemple #2
0
    def load_v2_master_key(self, master_key_path):
        if master_key_path:
            # Try load the specified private key file
            master_key = util.key_decrypt_prompt(master_key_path)
            if not master_key:
                logger.error("The specified master private key %s could not "
                             "be loaded.", os.path.abspath(master_key))
                sys.exit(1)

            master_onion_address = util.calc_onion_address(master_key)
            logger.info("Successfully loaded a master key for service "
                        "%s.onion.", master_onion_address)
        else:
            # No key specified, begin generating a new one.
            master_key = Crypto.PublicKey.RSA.generate(1024)
            master_onion_address = util.calc_onion_address(master_key)
            logger.debug("Created a new master key for service %s.onion.",
                         master_onion_address)

        return master_key, master_onion_address
Exemple #3
0
def descriptor_received(descriptor_content):
    """
    Process onion service descriptors retrieved from the HSDir system or
    received directly over the metadata channel.
    """

    try:
        parsed_descriptor = stem.descriptor.hidden_service_descriptor.\
            HiddenServiceDescriptor(descriptor_content, validate=True)
    except ValueError:
        logger.exception("Received an invalid service descriptor.")
        return None

    # Ensure the received descriptor matches the requested descriptor
    permanent_key = Crypto.PublicKey.RSA.importKey(
        parsed_descriptor.permanent_key)
    descriptor_onion_address = util.calc_onion_address(permanent_key)

    known_descriptor, instance_changed = False, False
    for instance in [
            instance for service in config.services
            for instance in service.instances
    ]:
        if instance.onion_address == descriptor_onion_address:
            instance_changed |= instance.update_descriptor(parsed_descriptor)
            known_descriptor = True

    if instance_changed:
        logger.info(
            "The introduction point set has changed for instance "
            "%s.onion.", descriptor_onion_address)

    if not known_descriptor:
        # No matching service instance was found for the descriptor
        logger.debug("Received a descriptor for an unknown service:\n%s",
                     descriptor_content.decode('utf-8'))
        logger.warning(
            "Received a descriptor with address %s.onion that "
            "did not match any configured service instances.",
            descriptor_onion_address)

    return None
Exemple #4
0
def generate_service_descriptor(permanent_key,
                                introduction_point_list=None,
                                replica=0,
                                timestamp=None,
                                deviation=0):
    """
    High-level interface for generating a signed HS descriptor
    """

    if not timestamp:
        timestamp = datetime.datetime.utcnow()
    unix_timestamp = int(timestamp.strftime("%s"))

    permanent_key_block = make_public_key_block(permanent_key)
    permanent_id = util.calc_permanent_id(permanent_key)

    # Calculate the current secret-id-part for this hidden service
    # Deviation allows the generation of a descriptor for a different time
    # period.
    time_period = (util.get_time_period(unix_timestamp, permanent_id) +
                   int(deviation))

    secret_id_part = util.calc_secret_id_part(time_period, None, replica)
    descriptor_id = util.calc_descriptor_id(permanent_id, secret_id_part)

    if not introduction_point_list:
        onion_address = util.calc_onion_address(permanent_key)
        raise ValueError("No introduction points for service %s.onion." %
                         onion_address)

    # Generate the introduction point section of the descriptor
    intro_section = make_introduction_points_part(introduction_point_list)

    unsigned_descriptor = generate_hs_descriptor_raw(
        desc_id_base32=util.base32_encode_str(descriptor_id),
        permanent_key_block=permanent_key_block,
        secret_id_part_base32=util.base32_encode_str(secret_id_part),
        publication_time=util.rounded_timestamp(timestamp),
        introduction_points_part=intro_section)

    signed_descriptor = sign_descriptor(unsigned_descriptor, permanent_key)
    return signed_descriptor
Exemple #5
0
    def __init__(self, controller, service_key=None, instances=None):
        """
        Initialise a HiddenService object.
        """
        self.controller = controller

        # Service key must be a valid PyCrypto RSA key object
        if isinstance(service_key, Crypto.PublicKey.RSA._RSAobj):
            self.service_key = service_key
        else:
            raise ValueError("Service key is not a valid RSA object.")

        # List of instances for this onion service
        if not instances:
            instances = []
        self.instances = instances

        # Calculate the onion address for this service
        self.onion_address = util.calc_onion_address(self.service_key)

        # Timestamp when this descriptor was last attempted
        self.uploaded = None