Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename to DSSE, update PAE, mark as v1 #37

Merged
merged 8 commits into from
Jun 21, 2021

Conversation

MarkLodato
Copy link
Collaborator

@MarkLodato MarkLodato commented Jun 4, 2021

Once this is submitted, we can rename the repo and tag as v1.0.0.

The name is now Dead Simple Signing Envelope.
The previous PAE required binary encoding, which can be tricky in some
langauges. The new PAE is pure ASCII so it can be implemented very
easily in almost any language.
@MarkLodato MarkLodato changed the title Rename to DSSE and update PAE Rename to DSSE, update PAE, mark as v1 Jun 4, 2021
@adityasaky adityasaky self-requested a review June 8, 2021 16:25
Copy link
Member

@adityasaky adityasaky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks reasonable to my eyes. I'd like to hear thoughts from some associated folks as well, as we move to 1.0.0.

@mnm678 @SantiagoTorres @trishankatdatadog @JustinCappos

@adityasaky
Copy link
Member

Also, is this blocked by any of #33, #34, #35, #36? I'm uncertain of the impact they'd have on the version number.

I think #35's consensus appears to be to distribute the pertinent information as part of the key rather than the signature.

Copy link
Collaborator

@trishankatdatadog trishankatdatadog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I really, really like how dead simple it is, really lives up to its name, greatly reduces scope for errors.

A few comments:

  1. Just to convince that we can still do canonical JSON, would you mind terribly much including an example on how to encode and decode a TUF or in-toto 1.0.0 payload?
  2. Am I understanding correctly that body is just an arbitrary sequence of bytes?
  3. Could you briefly explain why not to specify a generic media type?

@MarkLodato
Copy link
Collaborator Author

Also, is this blocked by any of #33, #34, #35, #36? I'm uncertain of the impact they'd have on the version number.

I think #35's consensus appears to be to distribute the pertinent information as part of the key rather than the signature.

Let's decide #34, which is whether to include the version in the JSON envelope. (It is already in the PAE.)

Otherwise, I suggest saying no to #33, #35, and #36 for v1. The entire idea of DSSE is that it is simple and avoids the pitfalls of JWS. We shouldn't add anything until there is both a strong case for it and a clear guidance so that it won't be misused. In particular:

@MarkLodato
Copy link
Collaborator Author

MarkLodato commented Jun 9, 2021

  1. Just to convince that we can still do canonical JSON, would you mind terribly much including an example on how to encode and decode a TUF or in-toto 1.0.0 payload?

No problem. I'll try to get to this soon.

  1. Am I understanding correctly that body is just an arbitrary sequence of bytes?

Yes. Added "Arbitrary". Does that help?

  1. Could you briefly explain why not to specify a generic media type?

Done. Please take a look at the latest commit.

@MarkLodato MarkLodato mentioned this pull request Jun 9, 2021
@MarkLodato
Copy link
Collaborator Author

From #33, it sounds like the addition of a timestamp would not affect the PAE, thus adding it would not invalidate signatures. Therefore I recommend deferring to a future minor revision, e.g. v1.1, because it would be backwards compatible with existing clients (they can just ignore that field).

Speaking of which, do we need some guidance on whether or not it's OK to ignore fields?

@mnm678
Copy link
Collaborator

mnm678 commented Jun 9, 2021

Speaking of which, do we need some guidance on whether or not it's OK to ignore fields?

This might be fine to leave for a future minor version, but it would be nice to let implementers (or future spec versions) add additional fields that may be ignored by clients who don't support them. As long as security features are added to new major versions, this would make backwards compatibility easier.

@MarkLodato
Copy link
Collaborator Author

Just to convince that we can still do canonical JSON, would you mind terribly much including an example on how to encode and decode a TUF or in-toto 1.0.0 payload?

Actually, @trishankatdatadog, could you explain the reasoning for this request? We already have an example in the implementation directory showing the signing and verifying of an arbitrary payload. Why would canoncial JSON payload be significantly different?

@MarkLodato
Copy link
Collaborator Author

And I ask simply to prioritize my time, not because I think it's unreasonable.

@trishankatdatadog
Copy link
Collaborator

And I ask simply to prioritize my time, not because I think it's unreasonable.

No problem, understood. I think as long as someone else can quickly double check here, we are good to go. I'm 99% certain it will work, I just want to make sure we didn't miss anything.

Incidentally, how soon do you need a 1.0.0 while we are checking this? Do you have a blocker?

@MarkLodato
Copy link
Collaborator Author

No hard deadline. We're starting to see various projects implement this spec so it would be good to get this change through sooner rather than later to minimize the number of things that need to get cleaned up.

@trishankatdatadog
Copy link
Collaborator

Gabish. Let me look at your code tonight and tinker with it.

@trishankatdatadog
Copy link
Collaborator

Gabish. Let me look at your code tonight and tinker with it.

Unfortunately, I have to wake up early today, so this is not happening tonight, but hopefully later today...

@trishankatdatadog
Copy link
Collaborator

trishankatdatadog commented Jun 10, 2021

Unfortunately, I have to wake up early today, so this is not happening tonight, but hopefully later today...

Okay, so I finally understand how this works. I tested signing and verifying SecureSystemsLib-style Canonical JSON with DSSE. Interested readers can find the source code here. A few observations:

  1. Signatures issued prior to DSSE are of course not going to be verifiable with DSSE, as DSSE also expects the payload type to be signed. So, there's no two ways about it, it's a breaking change that needs to be fixed with something higher-level like TAP 14 for TUF and I'm not sure what for in-toto (cc @adityasaky).
  2. The payload for SecureSystemsLib for DSSE needs to be the literal Canonical JSON. Any SecureSystemsLib-compatible implementation must always write Canonical JSON back to disk in order for signatures from different roles/functionaries on the same exact payload to be verifiable.
  3. Threshold signatures of course continue to work.
  4. I need to think about whether DSSE does or should solve the exclusive ownership problem (or whether it is even applicable).

@mnm678 @SantiagoTorres @adityasaky @JustinCappos please fact-check me here, including my code, thanks.

@mnm678
Copy link
Collaborator

mnm678 commented Jun 11, 2021

1. Signatures issued prior to DSSE are of course not going to be verifiable with DSSE, as DSSE also expects the payload type to be signed. So, there's no two ways about it, it's a breaking change that needs to be fixed with something higher-level like [TAP 14 for TUF](https://github.com/theupdateframework/taps/blob/master/tap14.md) and I'm not sure what for in-toto (cc @adityasaky).

@trishankatdatadog That makes sense, changing the signature wrapper will make existing clients unable to parse the new metadata. TUF is amassing a collection of TAPs with breaking changes, so this could fit into an eventual 2.0.0 release, including TAP 14 for version management.

4\. I need to think about whether DSSE does or should solve the [exclusive ownership](https://www.bolet.org/~pornin/2005-acns-pornin+stern.pdf) problem (or whether it is even applicable).

This is an interesting question. I don't think we need exclusive ownership in TUF (or in-toto?). Delegations are processed top-down, so the reverse property shouldn't be needed.

@adityasaky
Copy link
Member

I'm not sure what for in-toto

@trishankatdatadog ITE-5 requires implementations to support both envelopes, and the pseudocode shows how current envelopes must be handled. https://github.com/in-toto/ITE/blob/master/ITE/5/README.adoc#backwards-compatibility

However, there's probably a broader conversation here which likely belongs in an ITE-5 specific thread regarding how long implementations are expected to support both, I think? I may be wrong...

@adityasaky adityasaky self-requested a review June 14, 2021 15:28
@adityasaky
Copy link
Member

Taking stock, I think the only open discussion that's still being considered is #33. Am I correct? Where do folks stand on the rest of the changes here?

@trishankatdatadog , if I'm not mistaken, you've given your approval. @mnm678, @SantiagoTorres any overall thoughts? 😄

Copy link
Collaborator

@mnm678 mnm678 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! As you say @adityasaky, it would be good to decide about #33 before merging this as 1.0, but otherwise I think it's good to go.

@trishankatdatadog
Copy link
Collaborator

No, I haven't given my approval yet. I think it's good to go, but I just want to make sure the exclusive ownership problem doesn't apply, or is something that we solve on a lower-level (i.e., the cryptographic algorithm and schemes). Let me try asking Pornin and friends for advice.

@dlorenc
Copy link

dlorenc commented Jun 15, 2021

This might be fine to leave for a future minor version, but it would be nice to let implementers (or future spec versions) add additional fields that may be ignored by clients who don't support them. As long as security features are added to new major versions, this would make backwards compatibility easier.

If we're not going to do #33 here I think @mnm678's suggestion would be good to have instead. I can think of lots of other info I want to stick on an envelope somewhere, simply allowing extra fields would be enough for now.

@MarkLodato
Copy link
Collaborator Author

If we're not going to do #33 here I think @mnm678's suggestion would be good to have instead. I can think of lots of other info I want to stick on an envelope somewhere, simply allowing extra fields would be enough for now.

Done. To clarify, this is about ignored unrecognized (and thus unauthenticated) fields.

Since this PR seems to have become everything we want for v1, I also added a new change that warrants review: allowing zero signatures. I think this is a logical thing to do since we allow multiple signatures, and one could always use a dummy signature to get around the ">= 1 signature" requirement. But I wanted to get feedback from you all first to make sure you agree with the change. (We'd like to use this for SLSA.)

Copy link
Collaborator

@mnm678 mnm678 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor comment, but LGTM

envelope.md Outdated Show resolved Hide resolved
envelope.md Outdated Show resolved Hide resolved
@MarkLodato
Copy link
Collaborator Author

Since this PR seems to have become everything we want for v1, I also added a new change that warrants review: allowing zero signatures. I think this is a logical thing to do since we allow multiple signatures, and one could always use a dummy signature to get around the ">= 1 signature" requirement. But I wanted to get feedback from you all first to make sure you agree with the change. (We'd like to use this for SLSA.)

Note: I reverted this change and moved it to #38.

protocol.md Outdated
le64(n) := 64-bit little-endian encoding of `n`, where 0 <= n < 2^63
```python
PAE(type, body) := "DSSEv1 <len(type)> <type> <len(body)> <body>"
len(s) := ASCII decimal encoding of the byte length of s, with no leading zeros
Copy link

@wietse-gmail wietse-gmail Jun 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add that lt-type-gt and lt-body-gt have no leading or trailing space (just like the lengths have no leading zeros)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pushed an update. Does that help clarify (using + SP + to make it more clear that a single space is used)?

@trishankatdatadog
Copy link
Collaborator

No, I haven't given my approval yet. I think it's good to go, but I just want to make sure the exclusive ownership problem doesn't apply, or is something that we solve on a lower-level (i.e., the cryptographic algorithm and schemes). Let me try asking Pornin and friends for advice.

Ok, I read up exclusive ownership (EO). The problem is roughly as follows. Given an original public key from A, which used its private key to sign a message m with signature s, transformations 5 and 7 would destroy conservative and destructive EO respectively:

image

In transformation 5, we have a different public key from B fooling a validator into accepting m and s from A. (Not the worst thing ever, but concerning.) In transformation 7, we have a different public key from B fooling a validator into accepting m` from B but with s from A. (Definitely bad.)

The TLDR for us is that, assuming that TUF and in-toto clients have a known good copy of the appropriate root public keys (the root role for TUF and root layout functionary for in-toto), the EO problem should not apply to them, because they always used a fixed, known, and trusted public key A for any TUF role or in-toto functionary. However, DSSE should warn other client applications about the EO problem if they do not distribute public keys securely (especially using cryptosystems such as RSA and DSS that do not provide EO). I could have misunderstood something, so it would be good if someone could double-check my understanding.

@trishankatdatadog
Copy link
Collaborator

The TLDR for us is that, assuming that TUF and in-toto clients have a known good copy of the appropriate root public keys (the root role for TUF and root layout functionary for in-toto), the EO problem should not apply to them, because they always used a fixed, known, and trusted public key A for any TUF role or in-toto functionary. However, DSSE should warn other client applications about the EO problem if they do not distribute public keys securely (especially using cryptosystems such as RSA and DSS that do not provide EO). I could have misunderstood something, so it would be good if someone could double-check my understanding.

@pornin, would you mind terribly much checking my understanding here?

@pornin
Copy link

pornin commented Jun 21, 2021

I don't know the context here, but, yes, this seems to be the correct understanding here. A signature algorithm can be seen as transferring "trust" from the public key to the signed data: IF there is a message m, and a signature s, and a public key pk, AND verify(pk, m, s) = true, THEN whoever controls the private key sk that matches pk must have been involved. Thus, if pk is "trusted", then that trust is conveyed to the message m. The gist of all the talk about exclusive ownership is that the trust does not goes into the other direction, i.e. there is no information flow FROM the message m TO the public key. For instance, there is no guarantee that s was originally produced with the signature algorithm, or that the public and private key existed at all at that time.

In PKI (X.509) contexts, where you have root public keys and intermediate CAs, and you verify certificate chains starting from the root, there is nominally no problem. You can run into trouble in some implementations, though, if you try to infer properties of the public key by looking at the signature and the message. In 2005, our example was revocation. In X.509, a certificate can be revoked or not-revoked; the revocation status can be obtained from a signed object (CRL or OCSP response) that is nominally issued (signed) by an authorized party, and there are conditions on who can sign it (e.g. an OCSP response is valid if it is signed by the same CA as the certificate whose revocation status is to be ascertained, or if it is signed by an "OCSP responder" whose certificate contains a specific tagging extension, and is signed by the CA). Trouble can happen if you begin to assume that revocation status is unique and well-defined, i.e. that if you find a CA with a public key that matches the signature on the certificate, and an OCSP response signed by that CA that says "this is not revoked", and then you begin to believe that the certificate is "not revoked" in absolute terms. Since signature algorithms, in general, do not ensure exclusive ownership, there could be another CA with a different public key and another OCSP response that instead says "this certificate is revoked". In other words, signatures guarantee a downward information flow ("this CA says this certificate is valid and not revoked, and I trust that because I trust that CA") but not an upward flow (you cannot conclude that "every CA matching that certificate must agree that it is valid and not revoked, even those I don't trust").

There have been a couple of recent papers that investigate these notions more thoroughly:

@trishankatdatadog
Copy link
Collaborator

I don't know the context here, but, yes, this seems to be the correct understanding here. A signature algorithm can be seen as transferring "trust" from the public key to the signed data: IF there is a message m, and a signature s, and a public key pk, AND verify(pk, m, s) = true, THEN whoever controls the private key sk that matches pk must have been involved. Thus, if pk is "trusted", then that trust is conveyed to the message m. The gist of all the talk about exclusive ownership is that the trust does not goes into the other direction, i.e. there is no information flow FROM the message m TO the public key. For instance, there is no guarantee that s was originally produced with the signature algorithm, or that the public and private key existed at all at that time.

In PKI (X.509) contexts, where you have root public keys and intermediate CAs, and you verify certificate chains starting from the root, there is nominally no problem. You can run into trouble in some implementations, though, if you try to infer properties of the public key by looking at the signature and the message. In 2005, our example was revocation. In X.509, a certificate can be revoked or not-revoked; the revocation status can be obtained from a signed object (CRL or OCSP response) that is nominally issued (signed) by an authorized party, and there are conditions on who can sign it (e.g. an OCSP response is valid if it is signed by the same CA as the certificate whose revocation status is to be ascertained, or if it is signed by an "OCSP responder" whose certificate contains a specific tagging extension, and is signed by the CA). Trouble can happen if you begin to assume that revocation status is unique and well-defined, i.e. that if you find a CA with a public key that matches the signature on the certificate, and an OCSP response signed by that CA that says "this is not revoked", and then you begin to believe that the certificate is "not revoked" in absolute terms. Since signature algorithms, in general, do not ensure exclusive ownership, there could be another CA with a different public key and another OCSP response that instead says "this certificate is revoked". In other words, signatures guarantee a downward information flow ("this CA says this certificate is valid and not revoked, and I trust that because I trust that CA") but not an upward flow (you cannot conclude that "every CA matching that certificate must agree that it is valid and not revoked, even those I don't trust").

Got it, thanks very much, Thomas, I think we're on the same page! @SantiagoTorres and I also agreed earlier today that it does not look like EO applies to applications like TUF and in-toto where there is a hierarchy of trust for exactly which public keys to use for which messages.

Copy link
Collaborator

@trishankatdatadog trishankatdatadog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost LGTM, thanks, just a few more things, please @MarkLodato:

  1. Please clarify that DSSE by itself cannot and does not solve the exclusive ownership problem, and that applications must be careful to establish a secure hierarchy of trust for which public keys to use for which messages.
  2. Please update your reference implementation to use the optional keyids to efficiently find which verifier/public key to use for which signatures (like so). This will help readers implement efficient implementations out of the box.

@SantiagoTorres @mnm678 am I being unreasonable here?

@mnm678
Copy link
Collaborator

mnm678 commented Jun 21, 2021

Almost LGTM, thanks, just a few more things, please @MarkLodato:

1. Please clarify that DSSE by itself cannot and does not solve the exclusive ownership problem, and that applications must be careful to establish a secure hierarchy of trust for which public keys to use for which messages.

This might fit well into a more general 'out of scope' section that could include DoS attacks, etc.

2. Please update your reference implementation to use the optional keyids to efficiently find which verifier/public key to use for which signatures ([like so](https://github.com/trishankatdatadog/signing-spec/tree/fde1e9e7a4b65e88edab896a7acc8904fc6c6e9a/implementation)). This will help readers implement efficient implementations out of the box.

I don't think the reference implementation needs to include the optional fields, at the very least I don't think that this is a blocker.

@MarkLodato
Copy link
Collaborator Author

@trishankatdatadog

  1. Is ddb48b2 sufficient? We already say that PKI is out of scope, and exclusive ownership seems to be a property of PKI.
  2. Implemented in 04e1715. I'm just using a fingerprint as an example, since the spec says that it is opaque. I agree it's valuable because it shows how the keyid filtering works.

@trishankatdatadog
Copy link
Collaborator

@trishankatdatadog

  1. Is ddb48b2 sufficient? We already say that PKI is out of scope, and exclusive ownership seems to be a property of PKI.

At least we noted it, thanks. I wouldn't say EO is a property of PKI, but PKI helps to avoid EO problems.

  1. Implemented in 04e1715. I'm just using a fingerprint as an example, since the spec says that it is opaque. I agree it's valuable because it shows how the keyid filtering works.

Wonderful, thanks! We can make this more efficient by being able to index verifiers by keyid, but this should work for now.

@adityasaky
Copy link
Member

Thanks, @trishankatdatadog and @MarkLodato! I think we're good to merge and release?

@MarkLodato
Copy link
Collaborator Author

Yay! I'll do that now and tag.

@MarkLodato MarkLodato merged commit cacf247 into secure-systems-lab:master Jun 21, 2021
@MarkLodato MarkLodato deleted the dsse branch June 21, 2021 20:29
@adityasaky
Copy link
Member

Thanks a lot for all your work on this, @MarkLodato. 😄

@adityasaky
Copy link
Member

I'm going to rename this repository in a moment. https://github.com/secure-systems-lab/dsse is what I have in mind.

@MarkLodato
Copy link
Collaborator Author

Sounds good to me!

@adityasaky
Copy link
Member

Done! I think github mostly handles renames well, but some remotes may need to be updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create a reference implementation and test vectors Choose a more specific name than "signing-spec"
7 participants