| // Copyright 2021 The Chromium OS Authors. All rights reserved. |
| // 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 reporting; |
| |
| import "record_constants.proto"; |
| |
| // Record represents the data sent from the Reporting Client. |
| message Record { |
| // Record data as enqueued with an ReportingQueue::Enqueue call (required). |
| // Data structure requirements are set by the destination. For destinations |
| // expecting a proto - the proto will be MessageLite::SerializeToString(), and |
| // will be DeserializedFromString() in the destination handler, prior to being |
| // forwarded. |
| // |
| // Current expected formats (destination : type): |
| // Destination::UPLOAD_EVENTS : UploadEventsRequest |
| optional bytes data = 1; |
| |
| // The destination associated with this request as set with the |
| // ReportingQueueConfiguration (required). |
| optional Destination destination = 2; |
| |
| // The DMToken associated with this request as set with the |
| // ReportingQueueConfiuguration (required). |
| optional string dm_token = 3; |
| |
| // When the record was submitted to ReportingQueue::Enqueue. |
| // Represents UTC time since Unix epoch 1970-01-01T00:00:00Z in microseconds, |
| // to match Spanner timestamp format. |
| optional int64 timestamp_us = 4; |
| } |
| |
| // A Record with it's digest and the digest of the previous record. |
| message WrappedRecord { |
| // Record (required) |
| // Data provided by the Reporting Client. |
| optional Record record = 1; |
| |
| // Record Digest (required) |
| // SHA256 hash used to validate that the record has been retrieved without |
| // being manipulated while it was on the device or during transfer. |
| optional bytes record_digest = 2; |
| |
| // Last record digest (required) |
| // Created by client and used by server to verify that the sequence of records |
| // has not been tampered with. |
| optional bytes last_record_digest = 3; |
| } |
| |
| // Information about how the record was encrypted. |
| message EncryptionInfo { |
| // Encryption key (optional). |
| // Represents the client's X25519 public key used along with the server's |
| // private key (identified by |public_key_id|) for shared secret recreation |
| // by the server to get the symmetric key used for |encrypted_wrapped_record| |
| // encryption. |
| optional bytes encryption_key = 1; |
| |
| // Public key id (optional) |
| // Hash of the public key used to do encryption. Used to identity the |
| // private key for decryption. If no key_id is present, it is assumed that |
| // |key| has been transferred in plaintext. |
| optional int64 public_key_id = 2; |
| } |
| |
| // Tracking information for what order a record appears in. |
| message SequencingInformation { |
| // Sequencing ID (monotonic number, required) |
| // Tracks records processing progress and is used for confirming that this |
| // and all prior records have been processed. If the same number is |
| // encountered more than once, only one instance needs to be processed. If |
| // certain number is absent when higher are encountered, it indicates that |
| // some records have been lost and there is a gap in the records stream |
| // (what to do with that is a decision that the caller needs to make). |
| optional int64 sequencing_id = 1; |
| |
| // Generation ID (required). Unique per device and priority. Generated anew |
| // when previous record digest is not found at startup (e.g. after powerwash). |
| optional int64 generation_id = 2; |
| |
| // Priority (required). |
| optional Priority priority = 3; |
| } |
| |
| // Envelope for the |WrappedRecord| and associated metadata as it is stored on |
| // disk and sent to the server. |
| message EncryptedRecord { |
| // Encrypted Wrapped Record |
| // |WrappedRecord| encrypted with the |encryption_key| in |encryption_info|. |
| // When absent, indicates gap - respective record is irreparably corrupt or |
| // missing from Storage, and server side should log it as such and no longer |
| // expect client to deliver it. |
| optional bytes encrypted_wrapped_record = 1; |
| |
| // Must be present to facilitate decryption of encrypted record. |
| // If missing, the record is either not encrypted or missing. |
| // TODO(b/153651358): Disable an option to send record not encrypted. |
| optional EncryptionInfo encryption_info = 2; |
| |
| // Sequencing information (required). Must be present to allow |
| // tracking and confirmation of the events by server. |
| optional SequencingInformation sequencing_information = 3; |
| |
| // Compression information (optional). |
| optional CompressionInformation compression_information = 4; |
| } |
| |
| // Tracking information for what compression is used. |
| message CompressionInformation { |
| // Compression algorithms available for use |
| enum CompressionAlgorithm { |
| COMPRESSION_NONE = 0; |
| COMPRESSION_SNAPPY = 1; |
| } |
| |
| // Compression algorithm that is used if the record was |
| // compressed before being wrapped (optional). |
| optional CompressionAlgorithm compression_algorithm = 1; |
| } |
| |
| // Encryption public key as delivered from the server and stored in Storage. |
| // Signature ensures the key was actually sent by the server and not manipulated |
| // afterwards. |
| message SignedEncryptionInfo { |
| // Public asymmetric key (required). |
| optional bytes public_asymmetric_key = 1; |
| |
| // Public key id (required). |
| // Identifies private key matching |public_asymmetric_key| for the server. |
| // Matches Encryptor::PublicKeyId. |
| optional int32 public_key_id = 2; |
| |
| // Signature of |public_asymmetric_key| (required). |
| // Verified by client against a well-known signature. |
| optional bytes signature = 3; |
| } |