github.com/mre-fog/trillianxx@v1.1.2-0.20180615153820-ae375a99d36a/trillian_log_api.proto (about) 1 // Copyright 2016 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 syntax = "proto3"; 16 17 package trillian; 18 19 option go_package = "github.com/google/trillian"; 20 option java_multiple_files = true; 21 option java_outer_classname = "TrillianLogApiProto"; 22 option java_package = "com.google.trillian.proto"; 23 24 import "google/api/annotations.proto"; 25 import "google/protobuf/timestamp.proto"; 26 import "google/rpc/status.proto"; 27 import "trillian.proto"; 28 29 // Provides access to a Verifiable Log data structure as defined in the 30 // [Verifiable Data Structures](docs/VerifiableDataStructures.pdf) paper. 31 // 32 // The API supports adding new entries to be integrated into the log's tree. It 33 // does not provide arbitrary tree modifications. Additionally, it has read 34 // operations such as obtaining tree leaves, inclusion/consistency proofs etc. 35 service TrillianLog { 36 // Adds a single leaf to the queue. 37 rpc QueueLeaf (QueueLeafRequest) returns (QueueLeafResponse) { 38 option (google.api.http) = { 39 post: "/v1beta1/logs/{log_id}/leaves" 40 body: "*" 41 }; 42 } 43 44 // Adds a single leaf with an assigned sequence number. 45 // Warning: This RPC is under development, don't use it. 46 rpc AddSequencedLeaf (AddSequencedLeafRequest) returns (AddSequencedLeafResponse) { 47 option (google.api.http) = { 48 post: "/v1beta1/logs/{log_id}/leaves:sequenced" 49 body: "*" 50 }; 51 } 52 53 // 54 // No direct equivalent at the storage level. 55 // 56 57 // Returns inclusion proof for a leaf with a given index in a given tree. 58 rpc GetInclusionProof (GetInclusionProofRequest) returns (GetInclusionProofResponse) { 59 option (google.api.http) = { 60 get: "/v1beta1/logs/{log_id}/leaves/{leaf_index}:inclusion_proof" 61 }; 62 } 63 // Returns inclusion proof for a leaf with a given identity hash in a given 64 // tree. 65 rpc GetInclusionProofByHash (GetInclusionProofByHashRequest) returns (GetInclusionProofByHashResponse) { 66 option (google.api.http) = { 67 get: "/v1beta1/logs/{log_id}/leaves:inclusion_by_hash" 68 }; 69 } 70 // Returns consistency proof between two versions of a given tree. 71 rpc GetConsistencyProof (GetConsistencyProofRequest) returns (GetConsistencyProofResponse) { 72 option (google.api.http) = { 73 get: "/v1beta1/logs/{log_id}:consistency_proof" 74 }; 75 } 76 77 // Returns the latest signed log root for a given tree. Corresponds to the 78 // ReadOnlyLogTreeTX.LatestSignedLogRoot storage interface. 79 rpc GetLatestSignedLogRoot (GetLatestSignedLogRootRequest) returns (GetLatestSignedLogRootResponse) { 80 option (google.api.http) = { 81 get: "/v1beta1/logs/{log_id}/roots:latest" 82 }; 83 } 84 85 // Returns the total number of leaves that have been integrated into the 86 // given tree. Corresponds to the ReadOnlyLogTreeTX.GetSequencedLeafCount 87 // storage interface. 88 // DO NOT USE - FOR DEBUGGING/TEST ONLY 89 rpc GetSequencedLeafCount (GetSequencedLeafCountRequest) returns (GetSequencedLeafCountResponse) { 90 option (google.api.http) = { 91 get: "/v1beta1/logs/{log_id}/leaves:sequenced_count" 92 }; 93 } 94 95 // Returns log entry and the corresponding inclusion proof for a given leaf 96 // index in a given tree. If the requested tree is unavailable but the leaf is in scope 97 // for the current tree, return a proof in that tree instead. 98 rpc GetEntryAndProof (GetEntryAndProofRequest) returns (GetEntryAndProofResponse) { 99 option (google.api.http) = { 100 get: "/v1beta1/logs/{log_id}/leaves/{leaf_index}" 101 }; 102 } 103 104 // 105 // Initialisation APIs. 106 // 107 108 rpc InitLog (InitLogRequest) returns (InitLogResponse) { 109 option (google.api.http) = { 110 post: "/v1beta1/logs/{log_id}:init" 111 }; 112 } 113 114 // 115 // Batch APIs. Correspond to `storage.ReadOnlyLogTreeTX` batch queries. 116 // 117 118 // Adds a batch of leaves to the queue. 119 rpc QueueLeaves (QueueLeavesRequest) returns (QueueLeavesResponse) { 120 } 121 122 // Stores leaves from the provided batch and associates them with the log 123 // positions according to the `LeafIndex` field. The indices must be 124 // contiguous. 125 // 126 // Warning: This RPC is under development, don't use it. 127 rpc AddSequencedLeaves (AddSequencedLeavesRequest) returns (AddSequencedLeavesResponse) { 128 } 129 130 // Returns a batch of leaves located in the provided positions. 131 rpc GetLeavesByIndex (GetLeavesByIndexRequest) returns (GetLeavesByIndexResponse) { 132 } 133 // Returns a batch of leaves in a sequential range. 134 rpc GetLeavesByRange (GetLeavesByRangeRequest) returns (GetLeavesByRangeResponse) { 135 } 136 // Returns a batch of leaves by their `merkle_leaf_hash` values. 137 rpc GetLeavesByHash (GetLeavesByHashRequest) returns (GetLeavesByHashResponse) { 138 } 139 } 140 141 // ChargeTo describes the user(s) associated with the request whose quota should 142 // be checked and charged. 143 message ChargeTo { 144 // user is a list of personality-defined strings. 145 // Trillian will treat them as /User/%{user}/... keys when checking and 146 // charging quota. 147 // If one or more of the specified users has insufficient quota, the 148 // request will be denied. 149 // 150 // As an example, a Certificate Transparency frontend might set the following 151 // user strings when sending a QueueLeaves request to the Trillian log: 152 // - The requesting IP address. 153 // This would limit the number of requests per IP. 154 // - The "intermediate-<hash>" for each of the intermediate certificates in 155 // the submitted chain. 156 // This would have the effect of limiting the rate of submissions under 157 // a given intermediate/root. 158 repeated string user = 1; 159 } 160 161 message QueueLeafRequest { 162 int64 log_id = 1; 163 LogLeaf leaf = 2; 164 ChargeTo charge_to = 3; 165 } 166 167 message QueueLeafResponse { 168 QueuedLogLeaf queued_leaf = 2; 169 } 170 171 message AddSequencedLeafRequest { 172 int64 log_id = 1; 173 LogLeaf leaf = 2; 174 ChargeTo charge_to = 3; 175 } 176 177 message AddSequencedLeafResponse { 178 QueuedLogLeaf result = 2; 179 } 180 181 message GetInclusionProofRequest { 182 int64 log_id = 1; 183 int64 leaf_index = 2; 184 int64 tree_size = 3; 185 ChargeTo charge_to = 4; 186 } 187 188 message GetInclusionProofResponse { 189 Proof proof = 2; 190 SignedLogRoot signed_log_root = 3; 191 } 192 193 message GetInclusionProofByHashRequest { 194 int64 log_id = 1; 195 bytes leaf_hash = 2; 196 int64 tree_size = 3; 197 bool order_by_sequence = 4; 198 ChargeTo charge_to = 5; 199 } 200 201 message GetInclusionProofByHashResponse { 202 // Logs can potentially contain leaves with duplicate hashes so it's possible 203 // for this to return multiple proofs. 204 repeated Proof proof = 2; 205 SignedLogRoot signed_log_root = 3; 206 } 207 208 message GetConsistencyProofRequest { 209 int64 log_id = 1; 210 int64 first_tree_size = 2; 211 int64 second_tree_size = 3; 212 ChargeTo charge_to = 4; 213 } 214 215 message GetConsistencyProofResponse { 216 Proof proof = 2; 217 SignedLogRoot signed_log_root = 3; 218 } 219 220 message GetLatestSignedLogRootRequest { 221 int64 log_id = 1; 222 ChargeTo charge_to = 2; 223 } 224 225 message GetLatestSignedLogRootResponse { 226 SignedLogRoot signed_log_root = 2; 227 } 228 229 message GetSequencedLeafCountRequest { 230 int64 log_id = 1; 231 ChargeTo charge_to = 2; 232 } 233 234 message GetSequencedLeafCountResponse { 235 int64 leaf_count = 2; 236 } 237 238 message GetEntryAndProofRequest { 239 int64 log_id = 1; 240 int64 leaf_index = 2; 241 int64 tree_size = 3; 242 ChargeTo charge_to = 4; 243 } 244 245 message GetEntryAndProofResponse { 246 Proof proof = 2; 247 LogLeaf leaf = 3; 248 SignedLogRoot signed_log_root = 4; 249 } 250 251 message InitLogRequest { 252 int64 log_id = 1; 253 ChargeTo charge_to = 2; 254 } 255 256 message InitLogResponse { 257 SignedLogRoot created = 1; 258 } 259 260 message QueueLeavesRequest { 261 int64 log_id = 1; 262 repeated LogLeaf leaves = 2; 263 ChargeTo charge_to = 3; 264 } 265 266 message QueueLeavesResponse { 267 // Same number and order as in the corresponding request. 268 repeated QueuedLogLeaf queued_leaves = 2; 269 } 270 271 message AddSequencedLeavesRequest { 272 int64 log_id = 1; 273 repeated LogLeaf leaves = 2; 274 ChargeTo charge_to = 4; 275 } 276 277 message AddSequencedLeavesResponse { 278 // Same number and order as in the corresponding request. 279 repeated QueuedLogLeaf results = 2; 280 } 281 282 message GetLeavesByIndexRequest { 283 int64 log_id = 1; 284 repeated int64 leaf_index = 2; 285 ChargeTo charge_to = 5; 286 } 287 288 message GetLeavesByIndexResponse { 289 // TODO(gbelvin) reply with error codes. Reuse QueuedLogLeaf? 290 repeated LogLeaf leaves = 2; 291 SignedLogRoot signed_log_root = 3; 292 } 293 294 message GetLeavesByRangeRequest { 295 int64 log_id = 1; 296 int64 start_index = 2; 297 int64 count = 3; 298 ChargeTo charge_to = 4; 299 } 300 301 message GetLeavesByRangeResponse { 302 // Returned log leaves starting from the `start_index` of the request, in 303 // order. There may be fewer than `request.count` leaves returned, if the 304 // requested range extended beyond the size of the tree or if the server opted 305 // to return fewer leaves than requested. 306 repeated LogLeaf leaves = 1; 307 SignedLogRoot signed_log_root = 2; 308 } 309 310 message GetLeavesByHashRequest { 311 int64 log_id = 1; 312 repeated bytes leaf_hash = 2; 313 bool order_by_sequence = 3; 314 ChargeTo charge_to = 5; 315 } 316 317 message GetLeavesByHashResponse { 318 // TODO(gbelvin) reply with error codes. Reuse QueuedLogLeaf? 319 repeated LogLeaf leaves = 2; 320 SignedLogRoot signed_log_root = 3; 321 } 322 323 // A result of submitting an entry to the log. Output only. 324 // TODO(pavelkalinnikov): Consider renaming it to AddLogLeafResult or the like. 325 message QueuedLogLeaf { 326 // The leaf as it was stored by Trillian. Empty unless `status.code` is: 327 // - `google.rpc.OK`: the `leaf` data is the same as in the request. 328 // - `google.rpc.ALREADY_EXISTS` or 'google.rpc.FAILED_PRECONDITION`: the 329 // `leaf` is the conflicting one already in the log. 330 LogLeaf leaf = 1; 331 332 // The status of adding the leaf. 333 // - `google.rpc.OK`: successfully added. 334 // - `google.rpc.ALREADY_EXISTS`: the leaf is a duplicate of an already 335 // existing one. Either `leaf_identity_hash` is the same in the `LOG` 336 // mode, or `leaf_index` in the `PREORDERED_LOG`. 337 // - `google.rpc.FAILED_PRECONDITION`: A conflicting entry is already 338 // present in the log, e.g., same `leaf_index` but different `leaf_data`. 339 google.rpc.Status status = 2; 340 } 341 342 // A leaf of the log's Merkle tree, corresponds to a single log entry. Each leaf 343 // has a unique `leaf_index` in the scope of this tree. 344 message LogLeaf { 345 // Output only. The hash over `leaf_data`. 346 bytes merkle_leaf_hash = 1; 347 348 // Required. The arbitrary data associated with this log entry. Validity of 349 // this field is governed by the call site (personality). 350 bytes leaf_value = 2; 351 // The arbitrary metadata, e.g., a timestamp. 352 bytes extra_data = 3; 353 354 // Output only in `LOG` mode. Required in `PREORDERED_LOG` mode. 355 // The index of the leaf in the Merkle tree, i.e., the position of the 356 // corresponding entry in the log. For normal logs this value will be 357 // assigned by the LogSigner. 358 int64 leaf_index = 4; 359 360 // The hash over the identity of this leaf. If empty, assumed to be the same 361 // as `merkle_leaf_hash`. It is a mechanism for the personality to provide a 362 // hint to Trillian that two leaves should be considered "duplicates" even 363 // though their `leaf_value`s differ. 364 // 365 // E.g., in a CT personality multiple `add-chain` calls for an identical 366 // certificate would produce differing `leaf_data` bytes (due to the 367 // presence of SCT elements), with just this information Trillian would be 368 // unable to determine that. Within the context of the CT personality, these 369 // entries are dupes, so it sets `leaf_identity_hash` to `H(cert)`, which 370 // allows Trillian to detect the duplicates. 371 // 372 // Continuing the CT example, for a CT mirror personality (which must allow 373 // dupes since the source log could contain them), the part of the 374 // personality which fetches and submits the entries might set 375 // `leaf_identity_hash` to `H(leaf_index||cert)`. 376 // TODO(pavelkalinnikov): Consider instead using `H(cert)` and allowing 377 // identity hash dupes in `PREORDERED_LOG` mode, for it can later be 378 // upgraded to `LOG` which will need to correctly detect duplicates with 379 // older entries when new ones get queued. 380 bytes leaf_identity_hash = 5; 381 382 // Output only. The time at which this leaf was passed to `QueueLeaves`. 383 // This value will be determined and set by the LogServer. Equals zero if 384 // the entry was submitted without queuing. 385 google.protobuf.Timestamp queue_timestamp = 6; 386 // Output only. The time at which this leaf was integrated into the tree. 387 // This value will be determined and set by the LogSigner. 388 google.protobuf.Timestamp integrate_timestamp = 7; 389 } 390 391 // A consistency or inclusion proof for a Merkle tree. Output only. 392 message Proof { 393 int64 leaf_index = 1; 394 reserved 2; // Contained internal node details, no longer provided to clients. 395 repeated bytes hashes = 3; 396 }