Skip to content

Commit

Permalink
First commit of the new bundle format. (#1)
Browse files Browse the repository at this point in the history
* First commit of the new bundle format.

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Clarfied the checkpoint comment.

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Added apache license

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Update protos/sigstore_bundle.proto

Co-authored-by: Hayden B <hblauzvern@gmail.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Update protos/sigstore_bundle.proto

Co-authored-by: Hayden B <hblauzvern@gmail.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Update protos/sigstore_bundle.proto

Co-authored-by: Hayden B <hblauzvern@gmail.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Specify TimeStampResponse instead of TimeStampToken.
Use specific commit hash instead of branch name.

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Use commit hash instead of branch

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Update protos/sigstore_rekor.proto

Co-authored-by: Hayden B <hblauzvern@gmail.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Update protos/sigstore_common.proto

Co-authored-by: Hayden B <hblauzvern@gmail.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Apply suggestions from code review

Co-authored-by: Hayden B <hblauzvern@gmail.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Update protos/sigstore_rekor.proto

Co-authored-by: Hayden B <hblauzvern@gmail.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Update protos/sigstore_rekor.proto

Co-authored-by: Hayden B <hblauzvern@gmail.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* s/der_bytes/raw_bytes/

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Clarified a comment on public key hint.

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Updated comments to reflect the discussion in the PR.

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
Co-authored-by: Hayden B <hblauzvern@gmail.com>
  • Loading branch information
kommendorkapten and haydentherapper committed Oct 31, 2022
1 parent 1005897 commit d6bebac
Show file tree
Hide file tree
Showing 5 changed files with 349 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*~
51 changes: 51 additions & 0 deletions protos/envelope.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// https://raw.githubusercontent.com/secure-systems-lab/dsse/9c813476bd36de70a5738c72e784f123ecea16af/envelope.proto

// 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";

package io.intoto;

option go_package = "github.com/secure-systems-lab/dsse";

// An authenticated message of arbitrary type.
message Envelope {
// Message to be signed. (In JSON, this is encoded as base64.)
// REQUIRED.
bytes payload = 1;

// String unambiguously identifying how to interpret payload.
// REQUIRED.
string payloadType = 2;

// Signature over:
// PAE(type, body)
// Where PAE is defined as:
// PAE(type, body) = "DSSEv1" + SP + LEN(type) + SP + type + SP + LEN(body) + SP + body
// + = concatenation
// SP = ASCII space [0x20]
// "DSSEv1" = ASCII [0x44, 0x53, 0x53, 0x45, 0x76, 0x31]
// LEN(s) = ASCII decimal encoding of the byte length of s, with no leading zeros
// REQUIRED (length >= 1).
repeated Signature signatures = 3;
}

message Signature {
// Signature itself. (In JSON, this is encoded as base64.)
// REQUIRED.
bytes sig = 1;

// *Unauthenticated* hint identifying which public key was used.
// OPTIONAL.
string keyid = 2;
}
77 changes: 77 additions & 0 deletions protos/sigstore_bundle.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2022 The Sigstore 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
//
// 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";
package dev.sigstore.bundle.v1;

// https://raw.githubusercontent.com/secure-systems-lab/dsse/9c813476bd36de70a5738c72e784f123ecea16af/envelope.proto
import "envelope.proto";
import "sigstore_common.proto";
import "sigstore_rekor.proto";

option go_package = "github.com/sigstore/proto/bundle/v1";
option java_package = "dev.sigstore.proto.bundle.v1";
option java_multiple_files = true;
option java_outer_classname = "BundleProto";

// Notes on versioning.
// The primary message ('Bundle') MUST be versioned, by populating the
// 'media_type' field. Semver-ish (only major/minor versions) scheme MUST
// be used. The current version as specified by this file is:
// application/vnd.dev.sigstore.bundle+json;version=0.1
// The semantic version is thus '0.1'.

// Various timestamped counter signatures over the artifacts signature.
// Currently only RFC3161 signatures are provided. More formats may be added
// in the future.
message TimestampVerificationData {
// A list of RFC3161 signed timestamps provided by the user.
// This can be used when the entry has not been stored on a
// transparency log, or in conjuction for a stronger trust model.
// Clients MUST verify the hashed message in the message imprint
// against the signature in the bundle.
repeated dev.sigstore.common.v1.RFC3161SignedTimestamp rfc3161_timestamps = 1;
}

// VerificationData contains extra data that can be used to verify things
// such as transparency and timestamp of the signature creation.
// As this message can be either empty (no inclusion proof or timestamps), or a combination of
// an arbitrarily number of transparency log entries and signed timestamps,
// it is the client's responsibility to implement any required verification
// policies.
message VerificationData {
// This is the inclusion promise and/or proof, where
// the timestamp is coming from the transparency log.
repeated dev.sigstore.rekor.v1.TransparencyLogEntry tlog_entries = 1;
// Timestamp verification data, over the artifact's signature.
TimestampVerificationData timestamp_verification_data = 2;
}

message Bundle {
// MUST be application/vnd.dev.sigstore.bundle+json;version=0.1
// when encoded as JSON.
string media_type = 1;
VerificationData verification_data = 2;
dev.sigstore.common.v1.VerificationMaterial verification_material = 3;
oneof content {
dev.sigstore.common.v1.MessageSignature message_signature = 4;
// A DSSE envelope can contain arbitrary payloads.
// Verifiers must verify that the payload type is a
// supported and expected type. This is part of the DSSE
// protocol which is defined here https://github.com/secure-systems-lab/dsse/blob/master/protocol.md
io.intoto.Envelope dsse_envelope = 5;
}
// Reserved for future additions of artifact types.
reserved 6 to 50;
}
107 changes: 107 additions & 0 deletions protos/sigstore_common.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright 2022 The Sigstore 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
//
// 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";
package dev.sigstore.common.v1;

option go_package = "github.com/sigstore/proto/common/v1";
option java_package = "dev.sigstore.proto.common.v1";
option java_multiple_files = true;
option java_outer_classname = "CommonProto";

// This package defines commonly used message types within the Sigstore
// community.

// Only a subset of the secure hash standard algorithms are supported.
// See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf for more
// details.
// UNSPECIFIED SHOULD not be used, primary reason for inclusion is to force
// any proto JSON serialization to emit the used hash algorithm, as default
// option is to *omit* the default value of an emum (which is the first
// value, represented by '0'.
enum HashAlgorithm {
HASH_ALGORITHM_UNSPECIFIED = 0;
SHA2_256 = 1;
SHA2_512 = 2;
}

// HashOutput captures a digest of a 'message' (generic octet sequence)
// and the corresponding hash algorithm used.
message HashOutput {
HashAlgorithm algorithm = 1;
// This is the raw octets of the message digest as computed by
// the hash algorithm.
bytes digest = 2;
}

// MessageSignature stores the computed signature over a message.
message MessageSignature {
// Message digest can be used to identify the artifact.
HashOutput message_digest = 1;
// The raw bytes as returned from the signature algorithm.
// The signature algorithm (and so the format of the signature bytes)
// are determined by the contents of the 'verification_material',
// either a key-pair or a certificate. If using a certificate, the
// certificate contains the required information on the signature
// algorithm.
// When using a key pair, the algorithm MUST be part of the public
// key, which MUST be communicated out-of-band.
bytes signature = 2;
}

// This message holds a RFC 3161 timestamp.
message RFC3161SignedTimestamp {
// Signed timestamp is the DER encoded TimeStampResponse.
// See https://www.rfc-editor.org/rfc/rfc3161.html#section-2.4.2
bytes signed_timestamp = 1;
}


// PublicKeyIdentifier can be used to identify an (out of band) delivered
// key, to verify a signature.
message PublicKeyIdentifier {
// Optional unauthenticated hint on which key to use.
// The format of the hint must be agreed upon out of band by the
// signer and the verifiers, and so is not subject to this
// specification.
// Example use-case is to specify the public key to use, from a
// trusted key-ring.
// Implementors are RECOMMENDED derive the value from the public
// key as described in https://www.rfc-editor.org/rfc/rfc3280#section-4.2.1.1
string hint = 1;
}

message X509Certificate {
// DER-encoded X.509 certificate.
bytes raw_bytes = 1;
}

// A chain of X.509 certificates.
message X509CertificateChain {
// The chain of certificates, with indices 0 to n.
// The first certificate in the array must be the leaf
// certificate used for signing. Any intermediate certificates
// must be stored as offset 1 to n-1, and the root certificate at
// position n.
repeated X509Certificate certificates = 1;
}

// VerificationMaterial captures details on the materials used to verify
// signatures.
message VerificationMaterial {
oneof content {
PublicKeyIdentifier public_key = 1;
X509CertificateChain x509_certificate_chain = 2;
}
}
113 changes: 113 additions & 0 deletions protos/sigstore_rekor.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright 2022 The Sigstore 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
//
// 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";
package dev.sigstore.rekor.v1;

option go_package = "github.com/sigstore/proto/rekor/v1";
option java_package = "dev.sigstore.proto.rekor.v1";
option java_multiple_files = true;
option java_outer_classname = "RekorProto";

// KindVersion contains the entry's kind and api version.
message KindVersion {
// Kind is the type of entry being stored in the log.
// See here for a list: https://github.com/sigstore/rekor/tree/main/pkg/types
string kind = 1;
// The specific api version of the type.
string version = 2;
}

// The checkpoint contains a signature of the tree head (root hash),
// size of the tree, the transparency log's unique identifier (log ID),
// hostname and the current time.
// The result is a string, the format is described here
// https://github.com/transparency-dev/formats/blob/main/log/README.md
// The details are here https://github.com/sigstore/rekor/blob/a6e58f72b6b18cc06cefe61808efd562b9726330/pkg/util/signed_note.go#L114
// The signature has the same format as
// InclusionPromise.signed_entry_timestamp. See below for more details.
message Checkpoint {
string envelope = 1;
}

// InclusionProof is the proof returned from the transparency log. Can
// be used for on line verification against the log.
message InclusionProof {
// The index of the entry in the log.
int64 log_index = 1;
// The hash digest stored at the root of the merkle tree at the time
// the proof was generated.
bytes root_hash = 2;
// The size of the merkle tree at the time the proof was generated.
int64 tree_size = 3;
// A list of hashes required to compute the inclusion proof, sorted
// in order from leaf to root.
// Not that leaf and root hashes are not included.
// The root has is available separately in this message, and the
// leaf hash should be calculated by the client.
repeated bytes hashes = 4;
// Signature of the tree head, as of the time of this proof was
// generated. See above info on 'Checkpoint' for more details.
Checkpoint checkpoint = 5;
}

// The inclusion promise is calculated by Rekor. It's calculated as a
// signature over a canonical JSON serialization of the persisted entry, the
// log ID, log index and the integration timestamp.
// See https://github.com/sigstore/rekor/blob/a6e58f72b6b18cc06cefe61808efd562b9726330/pkg/api/entries.go#L54
// The format of the signature depends on the transparency log's public key.
// If the signature algorithm requires a hash function and/or a signature
// scheme (e.g. RSA) those has to be retrieved out-of-band from the log's
// operators, together with the public key.
// This is used to verify the integration timestamp's value and that the log
// has promised to include the entry.
message InclusionPromise {
bytes signed_entry_timestamp = 1;
}

// LogId captures the identity of a transparency log.
message LogId {
// The unique id of the log, represented as the SHA-256 hash
// of the log's public key, computed over the DER encoding.
// This is similar to how it works for certificate transparency logs:
// https://www.rfc-editor.org/rfc/rfc6962#section-3.2
bytes key_id = 1;
}

// TransparencyLogEntry captures all the details required from Rekor to
// reconstruct an entry, given that the payload is provided via other means.
// This type can easily be created from the existing response from Rekor.
// Future iterations could rely on Rekor returning the minimal set of
// attributes (excluding the payload) that are required for verifying the
// inclusion promise. The inclusion promise (called SignedEntryTimestamp in
// the response from Rekor) is similar to a Signed Certificate Timestamp
// as described here https://www.rfc-editor.org/rfc/rfc9162#name-signed-certificate-timestam.
message TransparencyLogEntry {
// The index of the entry in the log.
int64 log_index = 1;
// The unique identifier of the log.
LogId log_id = 2;
// The kind (type) and version of the object associated with this
// entry. These values are required to construct the entry during
// verification.
KindVersion kind_version = 3;
// The UNIX timestamp from the log when the entry was persisted.
int64 integrated_time = 4;
// The inclusion promise/signed entry timestamp from the log.
InclusionPromise inclusion_promise = 5;
// The inclusion proof can be used for online verification that the
// entry was appended to the log, and that the log has not been
// altered.
InclusionProof inclusion_proof = 6;
}

0 comments on commit d6bebac

Please sign in to comment.