Skip to content

Commit

Permalink
Fix field option parsing, re-enable commented tests
Browse files Browse the repository at this point in the history
  • Loading branch information
maximecb committed Apr 18, 2024
1 parent 63410fb commit 75b8e1d
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 37 deletions.
25 changes: 23 additions & 2 deletions lib/protoboeuf/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ def self.parse_field_type(input)
type_name
end

# Parse a package name, e.g. foo.bar.bif
# Parse a package name, e.g. .foo.bar.bif
def self.parse_package_name(input)
name = +""

Expand All @@ -363,6 +363,16 @@ def self.parse_package_name(input)
name
end

# Parse a composite name, e.g. foo.bar.bif
def self.parse_composite_name(input)
name = +""
name << input.read_ident
while input.match '.'
name << '.' << input.read_ident
end
name
end

def self.parse_option_value(input)
input.eat_ws
ch = input.peek_ch
Expand All @@ -375,6 +385,8 @@ def self.parse_option_value(input)
return true
elsif input.match "false"
return false
else
return input.read_ident
end

raise ParseError.new("unknown option value type", input.pos)
Expand All @@ -400,7 +412,16 @@ def self.parse_field_options(input)

loop do
input.eat_ws
opt_name = input.read_ident

# Extension options are in parentheses, e.g.
# uint32 key = 1 [(google.api.field_behavior) = REQUIRED];
if input.match '('
opt_name = parse_composite_name(input)
input.expect ')'
else
opt_name = parse_composite_name(input)
end

input.expect '='
opt_value = parse_option_value(input)
options[opt_name.to_sym] = opt_value
Expand Down
10 changes: 5 additions & 5 deletions test/fixtures/sigstore/sigstore_bundle.proto
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ message VerificationMaterial {
// When used in a `0.3` bundle with the PGI and "keyless" signing,
// form (3) MUST be used.
oneof content {
//dev.sigstore.common.v1.PublicKeyIdentifier public_key = 1 [(google.api.field_behavior) = REQUIRED];
//dev.sigstore.common.v1.X509CertificateChain x509_certificate_chain = 2 [(google.api.field_behavior) = REQUIRED];
//dev.sigstore.common.v1.X509Certificate certificate = 5 [(google.api.field_behavior) = REQUIRED];
dev.sigstore.common.v1.PublicKeyIdentifier public_key = 1 [(google.api.field_behavior) = REQUIRED];
dev.sigstore.common.v1.X509CertificateChain x509_certificate_chain = 2 [(google.api.field_behavior) = REQUIRED];
dev.sigstore.common.v1.X509Certificate certificate = 5 [(google.api.field_behavior) = REQUIRED];
}

// An inclusion proof and an optional signed timestamp from the log.
Expand Down Expand Up @@ -128,7 +128,7 @@ message Bundle {
// (key hint) and the `content` is a DSSE envelope, the key hints
// MUST be exactly the same in the verification material and in the
// DSSE envelope.
//VerificationMaterial verification_material = 2 [(google.api.field_behavior) = REQUIRED];
VerificationMaterial verification_material = 2 [(google.api.field_behavior) = REQUIRED];

oneof content {
//dev.sigstore.common.v1.MessageSignature message_signature = 3 [(google.api.field_behavior) = REQUIRED];
Expand All @@ -138,7 +138,7 @@ message Bundle {
// 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 = 4 [(google.api.field_behavior) = REQUIRED];
io.intoto.Envelope dsse_envelope = 4 [(google.api.field_behavior) = REQUIRED];
}

// Reserved for future additions of artifact types.
Expand Down
19 changes: 6 additions & 13 deletions test/fixtures/sigstore/sigstore_common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -129,26 +129,20 @@ message MessageSignature {
// algorithm.
// When using a key pair, the algorithm MUST be part of the public
// key, which MUST be communicated out-of-band.

// FIXME:
//bytes signature = 2 [(google.api.field_behavior) = REQUIRED];
bytes signature = 2 [(google.api.field_behavior) = REQUIRED];
}

// LogId captures the identity of a transparency log.
message LogId {

// FIXME:
// The unique identity of the log, represented by its public key.
//bytes key_id = 1 [(google.api.field_behavior) = REQUIRED];
bytes key_id = 1 [(google.api.field_behavior) = REQUIRED];
}

// This message holds a RFC 3161 timestamp.
message RFC3161SignedTimestamp {

// FIXME:
// Signed timestamp is the DER encoded TimeStampResponse.
// See https://www.rfc-editor.org/rfc/rfc3161.html#section-2.4.2
//bytes signed_timestamp = 1 [(google.api.field_behavior) = REQUIRED];
bytes signed_timestamp = 1 [(google.api.field_behavior) = REQUIRED];
}

message PublicKey {
Expand Down Expand Up @@ -178,8 +172,7 @@ message PublicKeyIdentifier {

// An ASN.1 OBJECT IDENTIFIER
message ObjectIdentifier {
// FIXME:
//repeated int32 id = 1 [(google.api.field_behavior) = REQUIRED];
repeated int32 id = 1 [(google.api.field_behavior) = REQUIRED];
}

// An OID and the corresponding (byte) value.
Expand All @@ -195,7 +188,7 @@ message DistinguishedName {

message X509Certificate {
// DER-encoded X.509 certificate.
//bytes raw_bytes = 1 [(google.api.field_behavior) = REQUIRED];
bytes raw_bytes = 1 [(google.api.field_behavior) = REQUIRED];
}

enum SubjectAlternativeNameType {
Expand Down Expand Up @@ -241,5 +234,5 @@ message TimeRange {
google.protobuf.Timestamp start = 1;

// FIXME: codegen chokes on "end" field
//optional google.protobuf.Timestamp end = 2;
optional google.protobuf.Timestamp end = 2;
}
28 changes: 14 additions & 14 deletions test/fixtures/sigstore/sigstore_rekor.proto
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ option ruby_package = "Sigstore::Rekor::V1";
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 [(google.api.field_behavior) = REQUIRED];
string kind = 1 [(google.api.field_behavior) = REQUIRED];

// The specific api version of the type.
//string version = 2 [(google.api.field_behavior) = REQUIRED];
string version = 2 [(google.api.field_behavior) = REQUIRED];
}

// The checkpoint MUST contain an origin string as a unique log identifier,
Expand All @@ -46,32 +46,32 @@ message KindVersion {
// and https://github.com/C2SP/C2SP/blob/main/tlog-checkpoint.md.
// An example implementation can be found in https://github.com/sigstore/rekor/blob/main/pkg/util/signed_note.go
message Checkpoint {
//string envelope = 1 [(google.api.field_behavior) = REQUIRED];
string envelope = 1 [(google.api.field_behavior) = REQUIRED];
}

// InclusionProof is the proof returned from the transparency log. Can
// be used for offline or online verification against the log.
message InclusionProof {
// The index of the entry in the tree it was written to.
//int64 log_index = 1 [(google.api.field_behavior) = REQUIRED];
int64 log_index = 1 [(google.api.field_behavior) = REQUIRED];

// The hash digest stored at the root of the merkle tree at the time
// the proof was generated.
//bytes root_hash = 2 [(google.api.field_behavior) = REQUIRED];
bytes root_hash = 2 [(google.api.field_behavior) = REQUIRED];

// The size of the merkle tree at the time the proof was generated.
//int64 tree_size = 3 [(google.api.field_behavior) = REQUIRED];
int64 tree_size = 3 [(google.api.field_behavior) = REQUIRED];

// A list of hashes required to compute the inclusion proof, sorted
// in order from leaf to root.
// Note that leaf and root hashes are not included.
// The root hash is available separately in this message, and the
// leaf hash should be calculated by the client.
//repeated bytes hashes = 4 [(google.api.field_behavior) = REQUIRED];
repeated bytes hashes = 4 [(google.api.field_behavior) = REQUIRED];

// 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 [(google.api.field_behavior) = REQUIRED];
Checkpoint checkpoint = 5 [(google.api.field_behavior) = REQUIRED];
}

// The inclusion promise is calculated by Rekor. It's calculated as a
Expand All @@ -85,7 +85,7 @@ message InclusionProof {
// 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 [(google.api.field_behavior) = REQUIRED];
bytes signed_entry_timestamp = 1 [(google.api.field_behavior) = REQUIRED];
}

// TransparencyLogEntry captures all the details required from Rekor to
Expand All @@ -98,18 +98,18 @@ message InclusionPromise {
// as described here https://www.rfc-editor.org/rfc/rfc6962.html#section-3.2.
message TransparencyLogEntry {
// The global index of the entry, used when querying the log by index.
//int64 log_index = 1 [(google.api.field_behavior) = REQUIRED];
int64 log_index = 1 [(google.api.field_behavior) = REQUIRED];

// The unique identifier of the log.
//dev.sigstore.common.v1.LogId log_id = 2 [(google.api.field_behavior) = REQUIRED];
dev.sigstore.common.v1.LogId log_id = 2 [(google.api.field_behavior) = REQUIRED];

// 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 [(google.api.field_behavior) = REQUIRED];
KindVersion kind_version = 3 [(google.api.field_behavior) = REQUIRED];

// The UNIX timestamp from the log when the entry was persisted.
//int64 integrated_time = 4 [(google.api.field_behavior) = REQUIRED];
int64 integrated_time = 4 [(google.api.field_behavior) = REQUIRED];

// The inclusion promise/signed entry timestamp from the log.
// Required for v0.1 bundles, and MUST be verified.
Expand All @@ -120,7 +120,7 @@ message TransparencyLogEntry {
// The inclusion proof can be used for offline or online verification
// that the entry was appended to the log, and that the log has not been
// altered.
//InclusionProof inclusion_proof = 6 [(google.api.field_behavior) = REQUIRED];
InclusionProof inclusion_proof = 6 [(google.api.field_behavior) = REQUIRED];

// Optional. The canonicalized transparency log entry, used to
// reconstruct the Signed Entry Timestamp (SET) during verification.
Expand Down
12 changes: 9 additions & 3 deletions test/fixtures/sigstore/sigstore_trustroot.proto
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ message TransparencyLogInstance {
// SubjectPublicKeyInfo.
// See https://www.rfc-editor.org/rfc/rfc6962#section-3.2
dev.sigstore.common.v1.LogId log_id = 4;

// The checkpoint key identifier for the log used in a checkpoint.
// Optional, not provided for logs that do not generate checkpoints.
// For logs that do generate checkpoints, if not set, assume
Expand All @@ -68,17 +69,20 @@ message CertificateAuthority {
// The root certificate MUST be self-signed, and so the subject and
// issuer are the same.
dev.sigstore.common.v1.DistinguishedName subject = 1;

// The URI identifies the certificate authority.
//
// It is RECOMMENDED that the URI is the base URL for the certificate
// authority, that can be provided to any SDK/client provided
// by the certificate authority to interact with the certificate
// authority.
string uri = 2;

// The certificate chain for this CA. The last certificate in the chain
// MUST be the trust anchor. The trust anchor MAY be a self-signed root
// CA certificate or MAY be an intermediate CA certificate.
dev.sigstore.common.v1.X509CertificateChain cert_chain = 3;

// The time the *entire* chain was valid. This is at max the
// longest interval when *all* certificates in the chain were valid,
// but it MAY be shorter. Clients MUST check timestamps against *both*
Expand Down Expand Up @@ -126,6 +130,7 @@ message TrustedRoot {
// type defined in the old format:
// application/vnd.dev.sigstore.trustedroot+json;version=0.1
string media_type = 1;

// A set of trusted Rekor servers.
repeated TransparencyLogInstance tlogs = 2;
// A set of trusted certificate authorities (e.g Fulcio), and any
Expand All @@ -137,13 +142,14 @@ message TrustedRoot {
// The certificates are intended to be used for verifying artifact
// signatures.
repeated CertificateAuthority certificate_authorities = 3;

// A set of trusted certificate transparency logs.
repeated TransparencyLogInstance ctlogs = 4;

// A set of trusted timestamping authorities.
repeated CertificateAuthority timestamp_authorities = 5;
}


// SigningConfig represents the trusted entities/state needed by Sigstore
// signing. In particular, it primarily contains service URLs that a Sigstore
// signer may need to connect to for the online aspects of signing.
Expand Down Expand Up @@ -187,8 +193,8 @@ message ClientTrustConfig {
string media_type = 1;

// The root of trust, which MUST be present.
//TrustedRoot trusted_root = 2 [(google.api.field_behavior) = REQUIRED];
TrustedRoot trusted_root = 2 [(google.api.field_behavior) = REQUIRED];

// Configuration for signing clients, which MUST be present.
//SigningConfig signing_config = 3 [(google.api.field_behavior) = REQUIRED];
SigningConfig signing_config = 3 [(google.api.field_behavior) = REQUIRED];
}

0 comments on commit 75b8e1d

Please sign in to comment.