Ejemplo n.º 1
0
    def _refresh_signing_keymgr(self):
        # Refresh key manager metadata
        self._key_mgr_filename = "key_mgr.json"  # TODO (AV): make this a constant or config value
        self._key_mgr = None

        key_mgr_path = join(context.av_data_dir, self._key_mgr_filename)
        try:
            untrusted_key_mgr = fetch_channel_signing_data(
                context.signing_metadata_url_base, self._key_mgr_filename)
            verify_trust_delegation("key_mgr", untrusted_key_mgr,
                                    self._trusted_root)
            self._key_mgr = untrusted_key_mgr
            write_trust_metadata_to_file(self._key_mgr, key_mgr_path)
        except (
                ConnectionError,
                HTTPError,
        ) as err:
            log.warn(
                f"Could not retrieve {self.channel.base_url}/{self._key_mgr_filename}: {err}"
            )
        # TODO (AV): much more sensible error handling here
        except Exception as err:
            log.error(err)

        # If key_mgr is unavailable from server, fall back to copy on disk
        if self._key_mgr is None and exists(key_mgr_path):
            self._key_mgr = load_trust_metadata_from_file(key_mgr_path)
Ejemplo n.º 2
0
    def _refresh_signing_root(self):
        # TODO (AV): formalize paths for `*.root.json` and `key_mgr.json` on server-side
        self._trusted_root = INITIAL_TRUST_ROOT

        # Load current trust root metadata from filesystem
        latest_root_id, latest_root_path = -1, None
        for cur_path in iglob(join(context.av_data_dir, "[0-9]*.root.json")):
            # TODO (AV): better pattern matching in above glob
            cur_id = basename(cur_path).split(".")[0]
            if cur_id.isdigit():
                cur_id = int(cur_id)
                if cur_id > latest_root_id:
                    latest_root_id, latest_root_path = cur_id, cur_path

        if latest_root_path is None:
            log.debug(f"No root metadata in {context.av_data_dir}. "
                      "Using built-in root metadata.")
        else:
            log.info(f"Loading root metadata from {latest_root_path}.")
            self._trusted_root = load_trust_metadata_from_file(
                latest_root_path)

        # Refresh trust root metadata
        attempt_refresh = True
        while attempt_refresh:
            # TODO (AV): caching mechanism to reduce number of refresh requests
            next_version_of_root = 1 + self._trusted_root['signed']['version']
            next_root_fname = str(next_version_of_root) + '.root.json'
            next_root_path = join(context.av_data_dir, next_root_fname)
            try:
                update_url = f"{self.channel.base_url}/{next_root_fname}"
                log.info(
                    f"Fetching updated trust root if it exists: {update_url}")

                # TODO (AV): support fetching root data with credentials
                untrusted_root = fetch_channel_signing_data(
                    context.signing_metadata_url_base, next_root_fname)

                verify_trust_root(self._trusted_root, untrusted_root)

                # New trust root metadata checks out
                self._trusted_root = untrusted_root
                write_trust_metadata_to_file(self._trusted_root,
                                             next_root_path)

            # TODO (AV): more error handling improvements (?)
            except (HTTPError, ) as err:
                # HTTP 404 implies no updated root.json is available, which is
                # not really an "error" and does not need to be logged.
                if err.response.status_code not in (404, ):
                    log.error(err)
                attempt_refresh = False
            except Exception as err:
                log.error(err)
                attempt_refresh = False