chromium/components/web_package/mojom/web_bundle_parser.mojom

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module web_package.mojom;

import "mojo/public/mojom/base/read_only_file.mojom";
import "url/mojom/url.mojom";

// Factory interface that constructs and binds the receivers that are used
// for parsing the Web Bundles.
interface WebBundleParserFactory {
  // Constructs a parser for the passed |data_source|.
  GetParserForDataSource(pending_receiver<WebBundleParser> receiver,
                         url.mojom.Url? base_url,
                         pending_remote<BundleDataSource> data_source);

  // Constructs a file based data source for the corresponding |file|.
  BindFileDataSource(pending_receiver<BundleDataSource> data_source,
                     mojo_base.mojom.ReadOnlyFile file);
};

// Parser interface to obtain metadata and multiple responses from the bound
// application/webbundle data provided on the construction at the factory above.
interface WebBundleParser {
  // Parses the integrity block of a Signed Web Bundle.
  ParseIntegrityBlock() => (BundleIntegrityBlock? Result,
                            BundleIntegrityBlockParseError? error);

  // Parses the (Signed) Web Bundle's metadata. If the optional `offset` is
  // specified, parsing will begin at the indicated offset, and the `length`
  // field of the Web Bundle will be ignored. If `offset` is not set, and the
  // bundle is read in a random-access context, then the `length` field of the
  // bundle will be used to determine the offset.
  ParseMetadata(uint64? offset)
      => (BundleMetadata? Result, BundleMetadataParseError? error);

  // Parses a response from the range
  // |[response_offset, response_offset + response_length)|.
  ParseResponse(uint64 response_offset,
                uint64 response_length)
      => (BundleResponse? Result, BundleResponseParseError? error);

  // Closes all the resources that the parser is using.
  // After calling this method the parser becomes unusable and the
  // client should not call any method of this interface after calling
  // this method.
  Close() => ();
};

// Data source that provides application/webbundle data to the parser.
interface BundleDataSource {
  // Reads up to |length| bytes starting with |offset|. Returns a non-null
  // buffer shorter than |length| iff the end of the stream is reached.
  Read(uint64 offset, uint64 length) => (array<uint8>? buffer);

  // Returns the length of the stream if it is known, or a negative value on
  // error.
  Length() => (int64 length);

  // Checks whether the stream is backed by a random-access context.
  IsRandomAccessContext() => (bool is_random_access);

  // Closes the resource from which this data source reads the data (e.g.
  // it closes the Web Bundle file).
  // After calling this method the data source becomes unusable and the
  // client should not call any method of this interface after calling
  // this method.
  Close() => ();
};

enum BundleParseErrorType {
  kParserInternalError,
  kFormatError,
  kVersionError,
};

struct BundleIntegrityBlockParseError {
  BundleParseErrorType type;
  string message;
};

struct BundleMetadataParseError {
  BundleParseErrorType type;
  string message;
};

struct BundleResponseParseError {
  BundleParseErrorType type;
  string message;
};

struct BundleIntegrityBlockAttributes {
  string web_bundle_id;

  // The CBOR representation of this block's attributes. This is only used for
  // signature verification and never re-parsed in higher layers.
  array<uint8> cbor;
};

struct BundleIntegrityBlock {
  // If size is 0, then no integrity block was found.
  uint64 size;
  array<BundleIntegrityBlockSignatureStackEntry> signature_stack;

  // Attributes of this integrity block.
  BundleIntegrityBlockAttributes attributes;
};

// Mapped to `web_package::Ed25519PublicKey`
struct Ed25519PublicKey {
  array<uint8, 32> bytes;
};

// Mapped to `web_package::Ed25519Signature`
struct Ed25519Signature {
  array<uint8, 64> bytes;
};

struct SignatureInfoEd25519 {
  // The public key of this signature stack entry.
  Ed25519PublicKey public_key;
  // The signature of this signature stack entry.
  Ed25519Signature signature;
};

// Mapped to `web_package::EcdsaP256PublicKey`
struct EcdsaP256PublicKey {
  array<uint8, 33> bytes;
};

// Mapped to `web_package::EcdsaP256SHA256Signature`
struct EcdsaP256SHA256Signature {
  array<uint8> bytes;
};

struct SignatureInfoEcdsaP256SHA256 {
  // The public key of this signature stack entry.
  EcdsaP256PublicKey public_key;
  // The signature of this signature stack entry.
  EcdsaP256SHA256Signature signature;
};

struct SignatureInfoUnknown {
};

union SignatureInfo {
  SignatureInfoUnknown unknown;
  SignatureInfoEd25519 ed25519;
  SignatureInfoEcdsaP256SHA256 ecdsa_p256_sha256;
};

struct BundleIntegrityBlockSignatureStackEntry {
  // The CBOR of the attributes of this signature stack entry.
  array<uint8> attributes_cbor;
  SignatureInfo signature_info;
};

// Bundle's metadata, i.e. information in sections other than "responses".
struct BundleMetadata {
  BundleFormatVersion version;
  url.mojom.Url? primary_url;
  map<url.mojom.Url, BundleResponseLocation> requests;
};

// WebBundle format version. Corresponds to a specific draft of
// https://wpack-wg.github.io/bundled-responses/draft-ietf-wpack-bundled-responses.html
enum BundleFormatVersion {
  kB1,  // Corresponds to draft-00
  kB2,  // Corresponds to draft-02
};

// Offset (within the webbundle file) and length of a response.
struct BundleResponseLocation {
  uint64 offset;
  uint64 length;
};

// Contains response headers and payload location.
struct BundleResponse {
  int32 response_code;
  map<string, string> response_headers;

  // Payload offset and length within the webbundle file.
  uint64 payload_offset;
  uint64 payload_length;
};