// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.google.trillian.proto";
option java_outer_classname = "TrillianProto";
option go_package = "github.com/google/trillian";

package trillian;

import "crypto/keyspb/keyspb.proto";
import "crypto/sigpb/sigpb.proto";
import "google/protobuf/any.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

// What goes in here?
// Things which are exposed through the public trillian APIs.

// Defines the way empty / node / leaf hashes are constructed incorporating
// preimage protection, which can be application specific.
enum HashStrategy {
  // Hash strategy cannot be determined. Included to enable detection of
  // mismatched proto versions being used. Represents an invalid value.
  UNKNOWN_HASH_STRATEGY = 0;

  // Certificate Transparency strategy: leaf hash prefix = 0x00, node prefix =
  // 0x01, empty hash is digest([]byte{}), as defined in the specification.
  RFC6962_SHA256 = 1;

  // Sparse Merkle Tree strategy:  leaf hash prefix = 0x00, node prefix = 0x01,
  // empty branch is recursively computed from empty leaf nodes. 
  // NOT secure in a multi tree environment. For testing only.
  TEST_MAP_HASHER = 2;

  // Append-only log strategy where leaf nodes are defined as the ObjectHash.
  // All other properties are equal to RFC6962_SHA256.
  OBJECT_RFC6962_SHA256 = 3;

  // The CONIKS sparse tree hasher with SHA512_256 as the hash algorithm. 
  CONIKS_SHA512_256 = 4;
}

// State of the tree.
enum TreeState {
  // Tree state cannot be determined. Included to enable detection of
  // mismatched proto versions being used. Represents an invalid value.
  UNKNOWN_TREE_STATE = 0;

  // Active trees are able to respond to both read and write requests.
  ACTIVE = 1;

  // Frozen trees are only able to respond to read requests, writing to a frozen
  // tree is forbidden.
  FROZEN = 2;

  // Deprecated in favor of Tree.deleted.
  DEPRECATED_SOFT_DELETED = 3 [deprecated = true];

  // Deprecated in favor of Tree.deleted.
  DEPRECATED_HARD_DELETED = 4 [deprecated = true];
}

// Type of the tree.
enum TreeType {
  // Tree type cannot be determined. Included to enable detection of
  // mismatched proto versions being used. Represents an invalid value.
  UNKNOWN_TREE_TYPE = 0;

  // Tree represents a verifiable log.
  LOG = 1;

  // Tree represents a verifiable map.
  MAP  =2;
}

// Represents a tree, which may be either a verifiable log or map.
// Readonly attributes are assigned at tree creation, after which they may not
// be modified.
message Tree {
  // ID of the tree.
  // Readonly.
  int64 tree_id = 1;

  // State of the tree.
  // Trees are active after creation. At any point the tree may transition
  // between ACTIVE and FROZEN.
  TreeState tree_state = 2;

  // Type of the tree.
  // Readonly.
  TreeType tree_type = 3;

  // Hash strategy to be used by the tree.
  // Readonly.
  HashStrategy hash_strategy = 4;

  // Hash algorithm to be used by the tree.
  // Readonly.
  // TODO(gdbelvin): Deprecate in favor of signature_cipher_suite and hash_strategy.
  sigpb.DigitallySigned.HashAlgorithm hash_algorithm = 5;

  // Signature algorithm to be used by the tree.
  // Readonly.
  // TODO(gdbelvin): Deprecate in favor of signature_cipher_suite.
  sigpb.DigitallySigned.SignatureAlgorithm signature_algorithm = 6;

  // Signature cipher suite specifies the algorithms used to generate signatures.
  sigpb.DigitallySigned.SignatureCipherSuite signature_cipher_suite = 18;

  reserved 7;  // DuplicatePolicy (removed)

  // Display name of the tree.
  // Optional.
  string display_name = 8;

  // Description of the tree,
  // Optional.
  string description = 9;

  reserved 10;  // create_time_millis_since_epoch (removed)
  reserved 11;  // update_time_millis_since_epoch (removed)

  // Identifies the private key used for signing tree heads and entry
  // timestamps.
  // This can be any type of message to accommodate different key management
  // systems, e.g. PEM files, HSMs, etc.
  // Private keys are write-only: they're never returned by RPCs.
  // The private_key message can be changed after a tree is created, but the
  // underlying key must remain the same - this is to enable migrating a key
  // from one provider to another.
  google.protobuf.Any private_key = 12;

  // Storage-specific settings.
  // Varies according to the storage implementation backing Trillian.
  google.protobuf.Any storage_settings = 13;

  // The public key used for verifying tree heads and entry timestamps.
  // Readonly.
  keyspb.PublicKey public_key = 14;

  // Interval after which a new signed root is produced even if there have been
  // no submission.  If zero, this behavior is disabled.
  google.protobuf.Duration max_root_duration = 15;

  // Time of tree creation.
  // Readonly.
  google.protobuf.Timestamp create_time = 16;

  // Time of last tree update.
  // Readonly (automatically assigned on updates).
  google.protobuf.Timestamp update_time = 17;

  // If true, the tree has been deleted.
  // Deleted trees may be undeleted during a certain time window, after which
  // they're permanently deleted (and unrecoverable).
  // Readonly.
  bool deleted = 19;

  // Time of tree deletion, if any.
  // Readonly.
  google.protobuf.Timestamp delete_time = 20;
}

message SignedEntryTimestamp {
  int64 timestamp_nanos = 1;
  int64 log_id = 2;
  sigpb.DigitallySigned signature = 3;
}

// SignedLogRoot represents a commitment by a Log to a particular tree.
message SignedLogRoot {
  // epoch nanoseconds, good until 2500ish
  int64 timestamp_nanos = 1;
  bytes root_hash = 2;
  // TreeSize is the number of entries in the tree.
  int64 tree_size = 3;
  sigpb.DigitallySigned signature = 4;

  int64 log_id = 5;
  int64 tree_revision = 6;
}

// SignedMapRoot represents a commitment by a Map to a particular tree.
message SignedMapRoot {
  int64 timestamp_nanos = 1;
  bytes root_hash = 2;
  reserved 3;  // was MapperMetadata (removed, replaced by 'Any metadata').
	// TODO(al): define serialized format for the signature scheme.
  sigpb.DigitallySigned signature = 4;
  int64 map_id = 5;
  int64 map_revision = 6;
  // Metadata associated with the Map root.  This is set by the map personality
  // layer in a SetLeaves map request.  It could be used to persist state
  // needed to recreate the Map from an external data source.
  google.protobuf.Any metadata = 7;
}
