pub struct Policy { /* private fields */ }Expand description
What a host will run.
The default runs decoders embedded in the container and nothing else. That is the case the format is designed around: the dataset carries the code that reads it, so there is nothing to fetch and nothing to decide. A decoder named by a URI is a different proposition, because a dataset that names one can cause a host to go and get something and then execute it, and this crate will not do that unless a host has said so with a resolver of its own.
There is no boolean here on purpose. Turning external decoders on means writing the thing that goes and finds them, which is not something anybody does by accident.
Implementations§
Source§impl Policy
impl Policy
Sourcepub const fn embedded_only() -> Self
pub const fn embedded_only() -> Self
Embedded decoders and nothing else, which is the default.
Sourcepub fn with_external_decoders_resolved_by(
resolver: impl Resolve + 'static,
) -> Self
pub fn with_external_decoders_resolved_by( resolver: impl Resolve + 'static, ) -> Self
Also runs decoders that live outside the container, using this resolver to find them.
The bytes the resolver returns are hashed and compared to the digest in the container in exactly the same way an embedded module is. A resolver that returns the wrong module, or a registry that has been tampered with, fails here rather than at the compiler.
Source§impl Policy
impl Policy
Sourcepub fn decoder<'a>(
&self,
container: &Container<'a>,
) -> Result<Verified<'a>, Untrusted>
pub fn decoder<'a>( &self, container: &Container<'a>, ) -> Result<Verified<'a>, Untrusted>
Finds the decoder this container names and hands it over only if it hashes to what the container says.
This is the whole of the trust boundary for a decoder, and hashing is not a step it can be asked to skip. There is no flag here, and there is nowhere else to get the bytes.
The hash is over the module alone. The container’s root digest covers the header and the footer, which is what makes a container cheap to open, so a byte changed inside the decoder section parses perfectly well and is caught here instead. That is the case this exists for.
A decoder that lives outside the container is refused unless this policy was built with a resolver. Whatever the resolver returns is hashed exactly like an embedded module, so a registry that hands back the wrong thing fails here rather than at the compiler.
§Errors
Returns Untrusted::Missing if the container names no decoder, Untrusted::External if
the module lives outside the container and this policy has no resolver,
Untrusted::Unresolved if it has one and the resolver found nothing, Untrusted::Lost
if an embedded module names a section that is not in the file, and Untrusted::Digest,
carrying both digests, if the bytes are not the module the container names.
Sourcepub fn decoder_read<'a>(
&self,
record: &DecoderRef<'a>,
embedded: Option<Vec<u8>>,
) -> Result<Verified<'a>, Untrusted>
pub fn decoder_read<'a>( &self, record: &DecoderRef<'a>, embedded: Option<Vec<u8>>, ) -> Result<Verified<'a>, Untrusted>
The same check, for a host that read the module out of the file itself.
A host that is not holding the container cannot be handed a slice of it, so it reads the
section named by iris_format::Directory::decoder_section and passes the bytes here.
embedded is None when there is no such section, which is the same thing as an embedded
record naming a section the file does not have.
Everything after that point is identical, deliberately. The bytes are hashed and compared against the record the same way whether they arrived as a borrow of a resident file, as a read through a window, or from a resolver, because how they were obtained is exactly the thing the digest exists to stop mattering.
§Errors
See Policy::decoder.