Exemple #1
0
def validate_descriptor(stream_info):
    try:
        hex_stream_name = stream_info['stream_name']
        key = stream_info['key']
        hex_suggested_file_name = stream_info['suggested_file_name']
        stream_hash = stream_info['stream_hash']
        blobs = stream_info['blobs']
    except KeyError as e:
        raise InvalidStreamDescriptorError("Missing '%s'" % (e.args[0]))
    if stream_info['blobs'][-1]['length'] != 0:
        raise InvalidStreamDescriptorError(
            "Does not end with a zero-length blob.")
    if any([
            False if blob_info['length'] > 0 else True
            for blob_info in stream_info['blobs'][:-1]
    ]):
        raise InvalidStreamDescriptorError("Contains zero-length data blob")
    if 'blob_hash' in stream_info['blobs'][-1]:
        raise InvalidStreamDescriptorError(
            "Stream terminator blob should not have a hash")

    verify_hex(key, "key")
    verify_hex(hex_suggested_file_name, "suggested file name")
    verify_hex(stream_hash, "stream_hash")

    calculated_stream_hash = get_stream_hash(hex_stream_name, key,
                                             hex_suggested_file_name, blobs)
    if calculated_stream_hash != stream_hash:
        raise InvalidStreamDescriptorError(
            "Stream hash does not match stream metadata")
    return True
    def validate(self):
        log.debug("Trying to validate stream descriptor for %s",
                  str(self.raw_info['stream_name']))
        try:
            hex_stream_name = self.raw_info['stream_name']
            key = self.raw_info['key']
            hex_suggested_file_name = self.raw_info['suggested_file_name']
            stream_hash = self.raw_info['stream_hash']
            blobs = self.raw_info['blobs']
        except KeyError as e:
            raise InvalidStreamDescriptorError("Missing '%s'" % (e.args[0]))
        for c in hex_suggested_file_name:
            if c not in '0123456789abcdef':
                raise InvalidStreamDescriptorError(
                    "Suggested file name is not a hex-encoded string")
        h = get_lbry_hash_obj()
        h.update(hex_stream_name)
        h.update(key)
        h.update(hex_suggested_file_name)

        def get_blob_hashsum(b):
            length = b['length']
            if length != 0:
                blob_hash = b['blob_hash']
            else:
                blob_hash = None
            blob_num = b['blob_num']
            iv = b['iv']
            blob_hashsum = get_lbry_hash_obj()
            if length != 0:
                blob_hashsum.update(blob_hash)
            blob_hashsum.update(str(blob_num))
            blob_hashsum.update(iv)
            blob_hashsum.update(str(length))
            return blob_hashsum.digest()

        blobs_hashsum = get_lbry_hash_obj()
        for blob in blobs:
            blobs_hashsum.update(get_blob_hashsum(blob))
        if blobs[-1]['length'] != 0:
            raise InvalidStreamDescriptorError(
                "Does not end with a zero-length blob.")
        h.update(blobs_hashsum.digest())
        if h.hexdigest() != stream_hash:
            raise InvalidStreamDescriptorError(
                "Stream hash does not match stream metadata")
        log.debug("It is validated")
        return defer.succeed(True)
Exemple #3
0
def get_stream_hash(hex_stream_name, key, hex_suggested_file_name, blob_infos):
    h = get_lbry_hash_obj()
    h.update(hex_stream_name)
    h.update(key)
    h.update(hex_suggested_file_name)
    blobs_hashsum = get_lbry_hash_obj()
    sorted_blob_infos = sorted(blob_infos, key=lambda x: x['blob_num'])
    for blob in sorted_blob_infos:
        blobs_hashsum.update(get_blob_hashsum(blob))
    if sorted_blob_infos[-1]['length'] != 0:
        raise InvalidStreamDescriptorError(
            "Does not end with a zero-length blob.")
    if 'blob_hash' in sorted_blob_infos[-1]:
        raise InvalidStreamDescriptorError(
            "Stream terminator blob should not have a hash")
    h.update(blobs_hashsum.digest())
    return h.hexdigest()
Exemple #4
0
def validate_descriptor(stream_info):
    try:
        hex_stream_name = stream_info['stream_name']
        key = stream_info['key']
        hex_suggested_file_name = stream_info['suggested_file_name']
        stream_hash = stream_info['stream_hash']
        blobs = stream_info['blobs']
    except KeyError as e:
        raise InvalidStreamDescriptorError("Missing '%s'" % (e.args[0]))

    verify_hex(key, "key")
    verify_hex(hex_suggested_file_name, "suggested file name")
    verify_hex(stream_hash, "stream_hash")

    calculated_stream_hash = get_stream_hash(hex_stream_name, key,
                                             hex_suggested_file_name, blobs)
    if calculated_stream_hash != stream_hash:
        raise InvalidStreamDescriptorError(
            "Stream hash does not match stream metadata")
    return True
Exemple #5
0
    def _return_options_and_validator_and_factories(self, sd_info):
        if not 'stream_type' in sd_info:
            raise InvalidStreamDescriptorError('No stream_type parameter in stream descriptor.')
        stream_type = sd_info['stream_type']
        validator = self._get_validator(stream_type)(sd_info)
        factories = [f for f in self._get_factories(stream_type) if f.can_download(validator)]

        d = validator.validate()

        def get_options():
            options = self._get_options(stream_type)
            return validator, options, factories

        d.addCallback(lambda _: get_options())
        return d
    def validate(self):
        log.debug("Trying to validate stream descriptor for %s",
                  str(self.raw_info['stream_name']))
        hex_stream_name = self.raw_info['stream_name']
        public_key = self.raw_info['public_key']
        key = self.raw_info['key']
        stream_hash = self.raw_info['stream_hash']
        h = get_lbry_hash_obj()
        h.update(hex_stream_name)
        h.update(public_key)
        h.update(key)
        if h.hexdigest() != stream_hash:
            raise InvalidStreamDescriptorError(
                "Stream hash does not match stream metadata")
        blobs = self.raw_info['blobs']

        def check_blob_signatures():
            for blob in blobs:
                length = blob['length']
                if length != 0:
                    blob_hash = blob['blob_hash']
                else:
                    blob_hash = None
                blob_num = blob['blob_num']
                revision = blob['revision']
                iv = blob['iv']
                signature = blob['signature']
                hashsum = get_lbry_hash_obj()
                hashsum.update(stream_hash)
                if length != 0:
                    hashsum.update(blob_hash)
                hashsum.update(str(blob_num))
                hashsum.update(str(revision))
                hashsum.update(iv)
                hashsum.update(str(length))
                if not verify_signature(hashsum.digest(), signature,
                                        public_key):
                    raise InvalidStreamDescriptorError(
                        "Invalid signature in stream descriptor")

        return threads.deferToThread(check_blob_signatures)
Exemple #7
0
 def check_blob_signatures():
     for blob in blobs:
         length = blob['length']
         if length != 0:
             blob_hash = blob['blob_hash']
         else:
             blob_hash = None
         blob_num = blob['blob_num']
         revision = blob['revision']
         iv = blob['iv']
         signature = blob['signature']
         hashsum = get_lbry_hash_obj()
         hashsum.update(stream_hash)
         if length != 0:
             hashsum.update(blob_hash)
         hashsum.update(str(blob_num))
         hashsum.update(str(revision))
         hashsum.update(iv)
         hashsum.update(str(length))
         if not verify_signature(hashsum.digest(), signature, public_key):
             raise InvalidStreamDescriptorError("Invalid signature in stream descriptor")
Exemple #8
0
def save_sd_info(blob_manager, sd_hash, sd_info):
    if not blob_manager.blobs.get(
            sd_hash) or not blob_manager.blobs[sd_hash].get_is_verified():
        descriptor_writer = BlobStreamDescriptorWriter(blob_manager)
        calculated_sd_hash = yield descriptor_writer.create_descriptor(sd_info)
        if calculated_sd_hash != sd_hash:
            raise InvalidStreamDescriptorError(
                "%s does not match calculated %s" %
                (sd_hash, calculated_sd_hash))
    stream_hash = yield blob_manager.storage.get_stream_hash_for_sd_hash(
        sd_hash)
    if not stream_hash:
        log.debug("Saving info for %s", sd_info['stream_name'].decode('hex'))
        stream_name = sd_info['stream_name']
        key = sd_info['key']
        stream_hash = sd_info['stream_hash']
        stream_blobs = sd_info['blobs']
        suggested_file_name = sd_info['suggested_file_name']
        yield blob_manager.storage.add_known_blobs(stream_blobs)
        yield blob_manager.storage.store_stream(stream_hash, sd_hash,
                                                stream_name, key,
                                                suggested_file_name,
                                                stream_blobs)
    defer.returnValue(stream_hash)
Exemple #9
0
def verify_hex(text, field_name):
    for c in text:
        if c not in '0123456789abcdef':
            raise InvalidStreamDescriptorError(
                "%s is not a hex-encoded string" % field_name)
def verify_hex(text, field_name):
    if not set(text).issubset(set(string.hexdigits)):
        raise InvalidStreamDescriptorError("%s is not a hex-encoded string" %
                                           field_name)