// 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.

syntax = "proto2";

option optimize_for = LITE_RUNTIME;

package openscreen.cast.proto;

message CastMessage {
  // Always pass a version of the protocol for future compatibility
  // requirements.
  enum ProtocolVersion {
    CASTV2_1_0 = 0;
    CASTV2_1_1 = 1;  // message chunking support (deprecated).
    CASTV2_1_2 = 2;  // reworked message chunking.
    CASTV2_1_3 = 3;  // binary payload over utf8.
  }
  required ProtocolVersion protocol_version = 1;

  // source and destination ids identify the origin and destination of the
  // message.  They are used to route messages between endpoints that share a
  // device-to-device channel.
  //
  // For messages between applications:
  //   - The sender application id is a unique identifier generated on behalf of
  //     the sender application.
  //   - The receiver id is always the the session id for the application.
  //
  // For messages to or from the sender or receiver platform, the special ids
  // 'sender-0' and 'receiver-0' can be used.
  //
  // For messages intended for all endpoints using a given channel, the
  // wildcard destination_id '*' can be used.
  required string source_id = 2;
  required string destination_id = 3;

  // This is the core multiplexing key.  All messages are sent on a namespace
  // and endpoints sharing a channel listen on one or more namespaces.  The
  // namespace defines the protocol and semantics of the message.
  required string namespace = 4;

  // Encoding and payload info follows.

  // What type of data do we have in this message.
  enum PayloadType {
    STRING = 0;
    BINARY = 1;
  }
  required PayloadType payload_type = 5;

  // Depending on payload_type, exactly one of the following optional fields
  // will always be set.
  optional string payload_utf8 = 6;
  optional bytes payload_binary = 7;

  // --- Begin new 1.1 fields.

  // Flag indicating whether there are more chunks to follow for this message.
  // If the flag is false or is not present, then this is the last (or only)
  // chunk of the message.
  optional bool continued = 8;

  // If this is a chunk of a larger message, and the remaining length of the
  // message payload (the sum of the lengths of the payloads of the remaining
  // chunks) is known, this field will indicate that length. For a given
  // chunked message, this field should either be present in all of the chunks,
  // or in none of them.
  optional uint32 remaining_length = 9;
}

enum SignatureAlgorithm {
  UNSPECIFIED = 0;
  RSASSA_PKCS1v15 = 1;
  RSASSA_PSS = 2;
}

enum HashAlgorithm {
  SHA1 = 0;
  SHA256 = 1;
}

// Messages for authentication protocol between a sender and a receiver.
message AuthChallenge {
  optional SignatureAlgorithm signature_algorithm = 1
      [default = RSASSA_PKCS1v15];
  optional bytes sender_nonce = 2;
  optional HashAlgorithm hash_algorithm = 3 [default = SHA1];
}

message AuthResponse {
  required bytes signature = 1;
  required bytes client_auth_certificate = 2;
  repeated bytes intermediate_certificate = 3;
  optional SignatureAlgorithm signature_algorithm = 4
      [default = RSASSA_PKCS1v15];
  optional bytes sender_nonce = 5;
  optional HashAlgorithm hash_algorithm = 6 [default = SHA1];
  optional bytes crl = 7;
}

message AuthError {
  enum ErrorType {
    INTERNAL_ERROR = 0;
    NO_TLS = 1;  // The underlying connection is not TLS
    SIGNATURE_ALGORITHM_UNAVAILABLE = 2;
  }
  required ErrorType error_type = 1;
}

message DeviceAuthMessage {
  // Request fields
  optional AuthChallenge challenge = 1;
  // Response fields
  optional AuthResponse response = 2;
  optional AuthError error = 3;
}
