// Copyright 2021 The Pigweed Authors // // 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 // // https://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. // // Implementation of metadata formats specified in TUF Specification. // See https://theupdateframework.github.io/specification/latest/ syntax = "proto3"; package pw.software_update; import "google/protobuf/timestamp.proto"; // Metadata for a particular TUF role (e.g. targets metadata). // Was TufMetadata message SignedRootMetadata { // Serialized RootMetadata message that is the data portion of the metadata. bytes serialized_root_metadata = 1; // Signature of the canonical form of the role's serialized metadata // (serialized_root_metadata). repeated Signature signatures = 2; } message SignedTimestampMetadata { // Serialized TimestampMetadata message that is the data portion of the // metadata. bytes serialized_timestamp_metadata = 1; // Signature of the canonical form of the role's serialized metadata // (serialized_timestamp_metadata). repeated Signature signatures = 2; } message SignedSnapshotMetadata { // Serialized SnapshotMetadata message that is the data portion of the // metadata. bytes serialized_snapshot_metadata = 1; // Signature of the canonical form of the role's serialized metadata // (serialized_snapshot_metadata). repeated Signature signatures = 2; } message SignedTargetsMetadata { // Serialized TargetsMetadata message that is the data portion of the // metadata. bytes serialized_targets_metadata = 1; // Signature of the canonical form of the role's serialized metadata // (serialized_targets_metadata). repeated Signature signatures = 2; } message CommonMetadata { // Version number of the TUF Specification. // Follows the Semantic Versioning 2.0.0 (semver) format. Metadata is // written according to this version, and clients MUST verify that // "spec_version" matches the expected version number. // E.g. "1.0.0". string spec_version = 1; // Metadata file version. // Clients MUST NOT replace a metadata file with a version number less than // the one currently trusted. uint32 version = 2; // Expiration time for the metadata. // Indicates when this metadata should be considered expired and no longer // trusted by clients. Notice the TUF Specification defines this as a JSON // string following the ISO 8601 standard. The expected format of the date and // time string is "YYYY-MM-DDTHH:MM:SSZ". Time is always in UTC, and the "Z" // time zone designator is attached to indicate a zero UTC offset. // E.g. "2030-08-26T16:48:27Z". optional google.protobuf.Timestamp expires = 3; // Role type for the metadata. // Indicates the type of the metadata. Valid values are 'root', 'targets', // 'snapshot' and 'timestamp' as defined in the TUF spec, though we don't // plan to support 'mirrors'. // // This field serves as a "magic code" that identifies a particular type of // a metadata. During verification, the client is expected to check this // field against the expected role type immediately after verifying the // signatures of a metadata. This can be considered a "confidence booster" // in the absence of canonical protobuf -- i.e. it makes the various // `serialized_x_metadata` fields more tamper resistant. optional string role = 4; } // This content is signed. message RootMetadata { CommonMetadata common_metadata = 1; // Whether the repo supports consistent snapshots. If the repo has frequent // updates, you should set this to true. bool consistent_snapshot = 2; // Map from Keyid to Key. // Keyid is a unique identifier that identifies a cryptographic key. // Contains all of cryptographic keys used by this repository. repeated KeyMapping keys = 3; // KeyConfig is the list of keys use for a particular role and the threshold. // Threshold is number of keys of that role whose signatures are required in // order to consider a file as being properly signed by that role. SignatureRequirement root_signature_requirement = 4; SignatureRequirement timestamp_signature_requirement = 5; SignatureRequirement snapshot_signature_requirement = 6; SignatureRequirement targets_signature_requirement = 7; // This is NOT a part of the TUF Specification. reserved 8 to 31; // Reserved for TUF Specification changes. reserved 32 to 64; // Reserved for future Pigweed usage. reserved 65 to 255; // Reserved for project-specific usage. } // The timestamp role is used for freshness check of the snapshot. Any // project-specific update metadata should go in the top-level targets_metadata // or with the TargetFile information message TimestampMetadata { CommonMetadata common_metadata = 1; // Only one snapshot_metadata is used per timestamp. MetadataFile snapshot_metadata = 2; // This is NOT a part of the TUF Specification. reserved 3 to 31; // Reserved for TUF Specification changes. reserved 32 to 64; // Reserved for future Pigweed usage. reserved 65 to 255; // Reserved for project-specific usage. } // The snapshot role is used to ensure that the collection of targets_metadata // files is securely consistent (no target metadata mix and match). Any // project-specific update metadata should go in the top-level targets_metadata // or with the TargetFile information message SnapshotMetadata { CommonMetadata common_metadata = 1; // Map from Target metadata file name to MetadataFile. // File name can be an arbitrary name or a full file name with relative path. // This map should contain an entry for the top level targets role and all // delegated roles. repeated MetadataFile targets_metadata = 2; // This is NOT a part of the TUF Specification. reserved 3 to 31; // Reserved for TUF Specification changes. reserved 32 to 64; // Reserved for future Pigweed usage. reserved 65 to 255; // Reserved for project-specific usage. } // The targets role describes the target files that comprise the software // update. Targets metadata is organized in to a top-level targets metadata file // and optional multiple deligated targets metadata files // // The top-level targets metatdata is the correct place to put any // project-specific build version information, including build ID, hardware rev, // etc. message TargetsMetadata { CommonMetadata common_metadata = 1; // Collection of target file information repeated TargetFile target_files = 2; // Target file name can be an arbitrary name or a path that describes where // the file lives relative to the base directory of the repository, e.g. // "path/to/amber_tools/0". // TODO: When it is time to support delegation, add delegation information // here. // This is NOT a part of the TUF Specification. reserved 9 to 31; // Reserved for TUF Specification changes. reserved 32 to 64; // Reserved for future Pigweed usage. reserved 65 to 255; // Reserved for project-specific usage. } message Signature { // Identifier of the key, which is bytes of the SHA-256 hash of the // canonical form of the key. bytes key_id = 1; // The signature of the canonical form of the role's serialized metadata // (serialized_{root,timestamp,snapshot,targets}_metadata). bytes sig = 2; } message KeyMapping { // Identifier of the key, which is bytes of the SHA-256 hash of the // canonical form of the key. bytes key_id = 1; // Cryptographic key Key key = 2; } // Identifies an asymmetric cryptographic key. message Key { // Denotes a public key signature system, such as RSA or ECDSA. KeyType key_type = 1; // Denotes the signature scheme corresponding to the key type. For example: // "rsassa-pss-sha256" or "ecdsa-sha2-nistp256". KeyScheme scheme = 2; // Stores the serialized public key for this cryptographic algorithm. bytes keyval = 3; } // The set of cryptographic keys used by a specific role. For example, list of // key_ids used by the top level role "root". message SignatureRequirement { // Set of Keyid's. // Keyid is a unique identifier that identifies a cryptographic key. // E.g. "f2d5020d08aea06a0a9192eb6a4f549e17032ebefa1aa9ac167c1e3e727930d6". repeated bytes key_ids = 1; // Threshold of signatures required to trust given file. // In other words; the number of keys of that role whose signatures are // required in order to consider a file as being properly signed by that role. uint32 threshold = 2; } enum HashFunction { // Never use this in any TUF metadata. UNKNOWN_HASH_FUNCTION = 0; SHA256 = 1; } message Hash { HashFunction function = 1; // Digest of the cryptographic hash function computed on the target file. bytes hash = 2; } // Descriptor for a file stored in this repository. Linked to from target // metadata. message TargetFile { // Target file name can be an arbitrary name or a path that describes where // the file lives relative to the base directory of the repository, e.g. // "path/to/amber_tools/0". string file_name = 1; // Size of the target file (element payload) in bytes. This the size as stored // in the bundle. The final applied size can be different due to optional // compression. uint64 length = 2; // Map from algorithm name to Hash. // Algorithm name is the name of a cryptographic hash function. E.g. "sha256". // The Hash string is the hex digest of the cryptographic function computed on // the target file. E.g. // "65b8c67f51c993d898250f40aa57a317d854900b3a04895464313e48785440da". repeated Hash hashes = 3; // This is NOT a part of the TUF Specification. reserved 4 to 15; // Reserved for TUF Specification changes. reserved 16 to 31; // Reserved for future Pigweed usage. reserved 32 to 255; // Reserved for future project-specific usage. } message MetadataFile { // Target file name can be an arbitrary name or a path that describes where // the file lives relative to the base directory of the repository, e.g. // "path/to/target/0". optional string file_name = 1; // Metadata file version. E.g. 3. uint32 version = 2; // Size of the target file in bytes. optional uint64 length = 3; // Map from algorithm name to Hash. // Algorithm name is the name of a cryptographic hash function. E.g. "sha256". // The Hash is the hex digest of the cryptographic function computed on the // target file. E.g. // "65b8c67f51c993d898250f40aa57a317d854900b3a04895464313e48785440da". repeated Hash hashes = 4; } enum KeyType { // Never use this in any TUF metadata. UNKNOWN_KEY_TYPE = 0; RSA = 1; ED25519 = 2; ECDSA_SHA2_NISTP256 = 3; } enum KeyScheme { // Never use this in any TUF metadata. UNKNOWN_KEY_SCHEME = 0; // RSA Probabilistic signature scheme with appendix. // The underlying hash function is SHA256. // In TUF Specification, this is referred to as "rsassa-pss-sha256". RSASSA_PSS_SHA256_SCHEME = 1; // Elliptic Curve digital signature algorithm based on Twisted Edwards curves. // See https://ed25519.cr.yp.to/. // In TUF Specification, it is referred to as "ed25519". ED25519_SCHEME = 2; // Elliptic Curve Digital Signature Algorithm with NIST P-256 curve signing // and SHA-256 hashing. See // https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm In // TUF Specification, it is referred to as "ecdsa-sha2-nistp256". ECDSA_SHA2_NISTP256_SCHEME = 3; }