secure-systems-lab / dsse

A specification for signing methods and formats used by Secure Systems Lab projects.
https://dsse.dev
Apache License 2.0
63 stars 17 forks source link

Design: Where to put timestamps in envelope? #33

Open dlorenc opened 3 years ago

dlorenc commented 3 years ago

Some signing schemes, particularly around artifacts and metadata, rely on timestamp authorities to attest to when a signature was produced. (JARs and Authenticode are examples of this in the wild today).

In this case, the keyID and signature are no longer enough to actually verify that a signature is correct. We have to also check that the signature was produced during the validity window for that key. I think it might make sense to add a field for this somewhere in the envelope.

trishankatdatadog commented 3 years ago

I don't think it needs to be in the signature envelope itself. It could be part of the signed content, but looking forward to objections here.

dlorenc commented 3 years ago

I don't think putting it in the signed content itself would work - what we really need is proof that the signature was created during the validity window of the key, not the signed content.

So we have something like:

Bob signs Payload A with Key A, getting Signature A. Bob hashes this signature itself and asks the Trusted Timestamp Authority to "timestamp" that. The Timestamp Authority generates a Payload B containing its own system clock and this payload digest, and signs that.

This way we have independent, non-repudiatable proof that the signature existed before a specific time (typically the key expiry)

trishankatdatadog commented 3 years ago

Yes, this makes sense.

MarkLodato commented 3 years ago

Dan, could you write a brief concrete proposal on how that would work in practice? It sounds like this wouldn't be just a timestamp but rather a single field containing both timestamp and signature. Are there any standards or conventions for how this is conveyed? Do different timestamp authorities use different ones?

dlorenc commented 3 years ago

There's a standard that contains both the timestamp and signature together defined in rfc3161. There are alternates such as https://github.com/cyborch/tsa-json, that also do the same thing.

I think the simplest would be add a new, optional field to the "signature" type to contain this, and treat it as an opaque byte string.

MarkLodato commented 3 years ago

Do you also need a type to indicate how to interpret it?

And either way, this does not affect the signature itself (i.e. the PAE), correct?

dlorenc commented 3 years ago

We don't have a type on the sig field, so I don't think we would need a type here either: https://github.com/secure-systems-lab/signing-spec/blob/master/envelope.proto#L29

I'd be fine either way. And correct - this does not affect the PAE layer.

MarkLodato commented 3 years ago

So basically we'd say that keyid is a hint for both sig and timestamp? That seems OK to start with.

trishankatdatadog commented 3 years ago

So basically we'd say that keyid is a hint for both sig and timestamp? That seems OK to start with.

Mark, this is not clear to me. Could you elaborate?

I'd be fine either way. And correct - this does not affect the PAE layer.

Dan, do you mean sticking the timeserver-signed H(timestamp|signature) alongside the original signature?

dlorenc commented 3 years ago

My idea would basically be this modification, applied here: https://github.com/secure-systems-lab/signing-spec/blob/master/envelope.proto#L26

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;

  // *Separately authenticated* timestamp attesting to when the sig itself occurred.
  // OPTIONAL.
  bytes timestamp = 3;
}
trishankatdatadog commented 3 years ago

My idea would basically be this modification, applied here: https://github.com/secure-systems-lab/signing-spec/blob/master/envelope.proto#L26

Good: this is what I had in mind also. I don't think the keyid could be multiplexed for this, but i might have misunderstood Mark's proposal.

dlorenc commented 3 years ago

Yeah, I'm not sure I understand that part either.

MarkLodato commented 3 years ago

To confirm, this is not blocking #37 because the timestamp does not appear in the PAE, correct?

Sorry for the confusion around keyid. The consumer needs to know how to interpret the timestamp field, namely what format and authority (public key) to use. Is the suggestion that this is tied to the public key used for sig (and hinted by keyid)? For example, if key X signed sig, then the consumer would know that the timestamp field is expected to be in the RFC 3161 format and signed by key Y?

A few other questions:

dlorenc commented 3 years ago

To confirm, this is not blocking #37 because the timestamp does not appear in the PAE, correct?

I don't think this blocks the changes in #37 except for maybe the V1 part.

dlorenc commented 3 years ago

Whoops, wrong button.

trishankatdatadog commented 3 years ago

Sorry for the confusion around keyid. The consumer needs to know how to interpret the timestamp field, namely what format and authority (public key) to use. Is the suggestion that this is tied to the public key used for sig (and hinted by keyid)? For example, if key X signed sig, then the consumer would know that the timestamp field is expected to be in the RFC 3161 format and signed by key Y?

Good questions. I don't think these crucial information (perhaps even part of the signed metadata) should be implicitly tied to the keyid. Dan, WDYT?

shizhMSFT commented 3 years ago

In my understanding, we can put TimeStampToken as defined in RFC3161#2.4.2, which is encoded in ASN.1 BER, in the timestamp field.

As defined in RFC3161, we can extract the generalized timestamp from the TSTInfo. The real issues here are how we verify the time stamp token. Precisely, how do we find the public key / certificates to verify?

One is to set CertReq to true in the time stamping request to the TSA server, and the partial cert chain is embedded in the TimeStampToken. In this case, the consumer follows the PKI. Otherwise, information equivalent to timestamp.keyid is required unless the consumer is using few private timestamp servers. Apparently, the timestamp.keyid cannot be hinted by keyid since the signer and the TSA cannot be the same party.

dlorenc commented 3 years ago

@shizhMSFT that all matches my understanding.

There are a few other timestamp formats we're investigating too. Cc @asraa can give the latest updates there.

MarkLodato commented 3 years ago

So it sounds like the consensus is to add a single timestamp field with semantics equivalent to sig: the producer and consumer agree on the details out of band? And we can always add more fields later if needed, after trying this in the real world.

If so, I'll send out a PR to add such a field.

dlorenc commented 3 years ago

I'm in no huge particular rush on this one, so if we want to leave this open to bake a little more that's fine with me.

MarkLodato commented 3 years ago

Sounds good. It might also be good to start with an implementation before changing the spec.

asraa commented 3 years ago

So it sounds like the consensus is to add a single timestamp field with semantics equivalent to sig: the producer and consumer agree on the details out of band? And we can always add more fields later if needed, after trying this in the real world.

Yeah. Seems like it. Agreed that TimeStampToken for an RFC 3161 would match this. Other signature formats we're exploring based on signed notes would include the same information as this, including at least a reference to a certificate chain to use for verification.

Even then you would need a root CA to provide out of band to verify the chain against, so yes, I think you will need to agree on at least one thing to trust out of band.

colek42 commented 1 year ago

We extended DSSE to support timestamps. The timestamp is a counter signature to the signature on the data.

Here is our implementation: https://github.com/testifysec/go-witness/blob/main/dsse/dsse.go#L56

We would like to upstream this