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

WIP: TD Signatures #1151

Closed
wants to merge 17 commits into from
Closed

WIP: TD Signatures #1151

wants to merge 17 commits into from

Conversation

mmccool
Copy link
Contributor

@mmccool mmccool commented May 26, 2021

Initial definition of TD Signatures

  • Structure to extract content based on XML Signatures
  • Uses a query (JSONPointer or one of the query forms supported by directories) to extract the TD subset to sign
  • Multiple signatures can be chained
  • Actual signing algorithm uses JWS/JWA

TO DO:

  • An example or two would be helpful
  • Definition of enumerated types would be better
  • Default values would be useful (especially as some enumerated types only have one value at present)
  • "Signatures" is showing up mixed in with SecuritySchemes because it is defined in the wot-security ontology. Needs to be restructured; maybe a major section under "Security"?
  • Canonicalization needs to be defined over Partial TDs (easy) but ideally TD Fragments (maybe; harder) Do canonicalization (and expansion) first.
  • Include stronger key classes (512 key strength): (nistP384), nistP512, (sha384), sha512, x448; discuss in best practices document. Edit: spec use of JWA sig algs in RFC7518 plus Ed448 and Ed25519 from RFC8037; use consistent names
  • Cite JSON web signatures, and also cite external references for signature validation process
  • Support keys, and leave partial signature objects in TD (including keys) so they can be signed if necessary
  • Support array of SignedInfo sub-objects in signature, following XML signatures
  • Update JSON Schema
  • Resolve name conflict for "Signature"

Preview | Diff

@mmccool
Copy link
Contributor Author

mmccool commented May 28, 2021

I've been thinking about our discussion around signing, canonicalization, and named objects (security schemes, data schemas) and round-tripping and have the following comments:

  1. For computing signatures, it would be convenient to perform the queries on an "expanded" version of the canonical form where all references (e.g. to named security schemes, data schemas, and even prefixes) are replaced by the object they reference. This is closer to the ideal of signing the information rather than the serialization.
  2. Unfortunately, the "expanded form" would not currently be a TD because, for example, "security" MUST use a string and does not allow a SecurityScheme object in place of these strings. We have, however, discussed doing this (see WIP: Simplified inline security definitions #945; we however deferred this to TD 2.0, but I'm not sure the reason for doing so, compatibility, holds that much water anymore, so we could revisit). Likewise we would have to update "schema" inside Forms (and maybe elsewhere...) to allow both strings (referencing schemaDefinitions) and inlined DataSchema objects.
  3. IF we updated "security" and "schema" to allow objects as well as strings, then we could redefine the Canonical form to always inline objects. We could also update it to expand all prefixes into URLs. Then we could use it directly in signing, and would not have to worry about maintaining prefixes during round-tripping. HOWEVER... it would be VERY verbose, and as such not very useful for purposes outside of signing (i.e. computing differences).
  4. I'm thinking we could perhaps define two canonical forms: Compact and Expanded. Compact would use named objects and prefixes. Expanded would replace all named objects with their referents and would expand all prefixes. This still depends on allowing objects in "security" and "schema" though; otherwise the "expanded" form would not actually validate as a TD.

As a short-term fix, I'm thinking of adding an "expansion" step to the signing process. In the new process, a signer/validator would first canonicalize the TD (resulting in a "compact" form as currently defined), then "expand" it (resulting in a JSON-LD document that would not technically be a TD... but it would only appear internally in the signing process), then do queries and the rest of the current signature generation process. I will proceed with updating the PR in this fashion.

Later on, if we do allow inlined objects, we can define the "Expanded Canonical TD" (in addition to the current "Canonical TD", which I think we should keep, as it would be more "compact") and use it for signing directly.

@mmccool
Copy link
Contributor Author

mmccool commented May 28, 2021

hmmm... for the purpose of signatures, "Expanded Form" may also want to remove relative URLs and express everything using absolute URLs, and remove "base". Is there any reason we should not do this? On the one hand, it would make it easier to prevent changes to URLS by signing just the interactions. On the other hand, we may WANT to be able to separately sign the base and the relative endpoint URLs (e.g. if the base is an IP address assigned by a DHCP server and is subject to change).

I think for now I will NOT expand URLs.

@mmccool
Copy link
Contributor Author

mmccool commented Jun 2, 2021

  • Added array of SignedInfo objects to allow multiple things to be signed at once (this is consistent with XML signatures)
  • Added more sig algs after discussion in Security TF; 512-bit class signatures are really needed for long-term validation, e.g. for ThingModels.
  • Changed names of fields (query->reference, hash->digest) to align with XML Signatures
  • Updated text describing signing and validation process to include template in TD during signing to allow signing template, including sigAlg (and later, keys, once I add them...)

New problems noted:

  • The term "Signature" was already being used for something else in the information model, causing a name clash. I may have to pick another name for this field... probably "proofs". Sigh...
  • Need to rename algs to match JWS and add a citation to that. Not clear though if x448 and x25519 are supported by JWS; need to check..
  • Need to add way to specify keys. Plan is to add an optional "key" field to Signature object which would always be a URL. It can of course refer to external keys. However, then separate from signatures I was thinking of proposing a "keys" array and then the URL could be a fragment identifier (JSON pointer) to select an "internal" key from this array. The elements of the keys array should be some base64-encoded key representation, e.g. PEM or DER. Since the keys are part of the TD, they could then by signed by the SignedInfo if that is what people want, but the same key can also easily be re-used for different sigs. Note: an alternative would be to use named keys, but if the key reference is a URL using a fragment identifier/JSON pointer is more consistent.

@mmccool
Copy link
Contributor Author

mmccool commented Jun 4, 2021

Recent updates:

  • Specs for JWS (RFC7515) signature algorithms are specified in a separate RFC now, JWA, aka RFC7518. However, algorithms for x448 and x25519 are not in JWA, but in yet another RFC8037. Added citations to all of them and explicitly listed the sig algs that can be used, consistent with RFC7518 + RFC8037.
  • Minor editorial fixes: references to XML signatures spec fixed, fixed typos, clarified relationship to JWS, fixed typo (query -> reference), fixed RFC2119 keywords (must -> MUST) in assertions for signature process, clarified validation tweak needed to deal with partial Signature object, etc.

@mmccool
Copy link
Contributor Author

mmccool commented Jun 4, 2021

Next up, I wanted to figure out how to do keys. Rather than reinvent the wheel, my basic plan is to include JWS header values in the Signature object, then update the spec to generate the "sig" value using JWS, including steps like base64url encoding the header and payload. This sounds more complicated than it is, because the goal is to reuse tested JWS libraries, so the input text to be signed would just be the JCS form of the signedInfo object (with digests filled in) and we could lean on the JWS spec for details of signing and validation.

JWS specifies various header parameters for specifying keys. These parameters can either embed keys directly or refer to external keys or key sets using URLs. Keys can be represented using X.509 certs or a JWK or a JWK set (then using an id to select a key from that JWK set). A JWK basically includes the same parameters as the JWS, plus a few more for allowable usages. There is also support for encrypted keys.

Anyway, I want to avoid specifying my own ontology for this, so went to see if one is available. There IS one, being developed by the same guys doing DID, but it is unfortunately only a CG draft at this point: https://w3c-ccg.github.io/security-vocab/

Since JWK embeds the same parameters as JWS I think the simplest solution is just to support the (very small) subset of JWS that references an element of an external JWK set and NOT embed keys in Signature objects. It would also be possible in theory to embed a JWK set in a TD but the occasional need for encrypted keys and the immaturity of the ontology is giving me pause. So I won't suggest doing that either.

Therefore my plan is to JUST add the "jku" and "kid" fields for JWS to the Signature object, and require reference therefore to EXTERNAL keys in a JWK Set. The jku field would have to be a secure external absolute URL (https://...) and the kid would be a string indexing into the KWS set. I can specify the types for these directly in the wotsec ontology, avoiding the need for a complex external ontology for JWK or the risks associated with encoding keys directly in a TD.

@mmccool
Copy link
Contributor Author

mmccool commented Jun 4, 2021

Added jku and kid as discussed. Since JWS includes the header, I may be able to simplify other steps like inserting the template Signature into the TD prior to running the query. I'll review the JWS spec and confirm that the header is included in the Signature, and if it is I will remove this requirement, the validation exception, etc.

@mmccool
Copy link
Contributor Author

mmccool commented Jun 16, 2021

Signing procedure can be simplified since the JWS includes the header information as part of its definition. Current version works, it is just (slightly) more complicated than it needs to be.

@mmccool
Copy link
Contributor Author

mmccool commented Jun 16, 2021

Open question: currently only external keys can be referenced. Do we have any use cases that NEED (public) keys/certs to be included IN the TD? Basically, doing only a subset of JWS, since doing the whole thing will require a much more complex vocabulary. So I want to confirm that the subset we are doing is appropriate.

@OliverPfaff
Copy link

Review comments for https://pr-preview.s3.amazonaws.com/w3c/wot-thing-description/1151/075fcc6...mmccool:3daee68.html#sec-security-vocabulary-definition:

  • "Signature“ is an ambiguous term that easily creates confusion. The suggestion is to use more qualified terms e.g. “signature value” (checksum), “signature object” (checksum plus metadata evtl. plus signed data), “signature algorithm” (scheme to produce and verify signature values) instead

  • The W3C initiative Verifiable Credentials (VCs) distinguishes the terms “verification” (check correctness [maths]) and “validation” (check fitness [expectation match]). The present text appears to use the term “validation” for “check correctness (maths)”. This could create confusion

  • The specification describes a procedure for generating and verifying signature objects (in case of TDs). Since the generating and verification of signature objects is an outstanding primitive in security, it is usual to have specification texts that are designated to security for specifying the generation and verification of signature objects. Well-known examples are PKCS#7 (RFC 2315), CMS (RFC 5652), XML Signature (RFC 3275 and W3C Recommendation), JWS (RFC 7515). A designated specification text would better match the current practices in security. Especially as the proposed mechanisms explores the vacuum between XML Signature (has the required features but is not the desired form-factor) and JWS (is the desired form-factor but does not have the required features). A “JWS++” spec. that closes the gap between XML Signature and JWS might be a good next step. That could be an enhancement of or update to RFC 7515 that covers enveloped signatures. It would also make sense to address/include the IETF community from where JWS originated (originally: jose WG) in this process. Note: this is not meant to prohibit or block next steps (it is understood that such liaisons will likely not be formed quickly). It is meant to establish a community that can bear the mid/long-term commitments behind this (bigger) wheel

  • Explicitly referring to the limitations of alternatives would help to motivate the TD-specific approach:
    -- XML Signature: not the preferred form-factor (XML vs. JSON
    -- JWS: not the preferred object type (a TD signed with JWS in enveloping form is no TD object anymore, .td vs. .jws)

  • Explicitly stating design goals e.g. “signed TD documents shall be TD documents”, “signature objects for TD documents shall not exist in detached form” would further help.

  • My understanding is that the proposal re-incarnates key element from XML Signature in form of JSON (in presence of a requirement “enveloped signature for TD” and in absence of the support of "enveloped signatures in JWS”). This seems to include “SignedInfo”, “reference”, “referenceType”, “digest(Value)”, “digestAlg” (modulo writing details). It would help to have explicit text and style/font for:
    -- XML Signature-native abstractions e.g. “SignedInfo” that appear in re-incarnated (JSON) form, with/without writing changes
    -- JWS-native abstractions that appear in as-is (JSON) form - modulo some profiling
    -- DIY abstractions (extensions to XML Signature and JWS) that also appear

  • The enveloped signature trick in XML Signature is mostly done by specific xs:Transforms values (see https://www.w3.org/TR/xmldsig-core1/#sec-EnvelopedSignature). But xs:Transforms is not mapped (or its mapping is hard to get). This presents a disconnect for those with XML Signature background who read about TD Signatures first

  • The interpretation of several abstractions appears to be straight-forward (appear to be ca. 1:1 mappings to XML Signature or JWS):
    -- reference (String) = Attribute Type in xs:Reference
    -- digest (String) = xs:DigestValue
    -- digestAlg (String) = Attribute Algorithm in xs:DigestAlgorithm
    -- sig (String) = DYI (keyword to refer to JWS)
    -- alg (String) = jws:alg
    -- jku (String) = jws:jku
    -- kid (String) = jws:kid

But I have difficulties in mapping other critical items esp. reference (String) and SignedInfo. Since xs:Reference and xs:SignedInfo are keys to the functional premium of XML Signature over JWS their conceptual mapping in TD Signature would be important to describe

  • Design details should be checked by quick prototyping i.e. things should be proceeded according the IETF model “rough consensus and running code”. The comments above aim at helping to establish “rough consensus”

@sebastiankb
Copy link
Contributor

I like to discuss this PR in today's TD call. It would be great also to see some TD examples that uses the TD signature approach. This should be also included in the TD spec for better understanding.

@mmccool
Copy link
Contributor Author

mmccool commented Sep 3, 2021

@OliverPfaff thanks for your review! Regarding the names of various things, those can certainly be changed if better alternatives can be found. As noted above “Signature” also conflicts with its use for a different purpose elsewhere in the spec. Rather than “Signature Object” however, I was considering “Proofs” to align with LD-Proofs. I’ll have to think more about the other terminology points noted…

Re “should this be a separate spec”: well, I expect there WILL eventually be a spec for JSON-LD documents more generally that we may also want yo support in the future. But that will require RDF processing to compute/validate. So the gap here is an “enveloped” signature for JSON which we indeed might want to bring to the JOSE community.

Implementations are of course needed. My understanding is canonicalization is being implemented and after that computing signatures can be done using a TD Directory to collect the appropriate fragments (resolving JSON queries) and exist JWS libraries…

Anyway, hopefully you can attend Monday’s meeting and we can discuss concrete improvements and/or alternatives then.

@mmccool
Copy link
Contributor Author

mmccool commented Sep 6, 2021

Discussion in Security call:

  • Oliver: three actions: 1. work on description, esp. mappings to XML Signatures and JWS. 2. Need for two interoperable implementations. Needed by next plugfest. 3. Clairify with IETF on next steps. There is gap in JWS/JOSE that needs to be addressed; features from XML Signatures are needed here, but if IETF fills the gap, we could end up with a non-conformant signatures approach. We probably should at least discuss this with the IETF community, i.e. at a BoF. But... JOSE is a closed working group, COSE is still open (but is working on CBOR).
  • McCool: I was thinking we could do signatures as an explicit extension, and not in the core spec. We could do it as a Note for now, then work with IETF to make it an official spec that could be applicable to things that are not TDs. Of course the extension would be expressed using JSON-LD concepts, but we could also define a JSON Schema.
  • Phillip: Could we put it in security best practices?
  • McCool: That would be a way to recommend it without making it normative.

Actions:

  1. (Kaz) Set up a repo for the new document. Something generic like enveloped-json-signatures; note, not associated with wot. If using wot prefix is required, then it can be wot-enveloped-json-signatures (or how about wot-ejs, since will be easier to share).
  2. (McCool) Extract the current spec for signatures and put it in a separate document. Will just copy the TD spec, delete everything not related to signatures, make it a W3C (Draft) Note, etc.
  3. (McCool) Cleanup, following Oliver's suggestions. In particular, relate explicitly to XML Signatures and JWS, explain motivation, put in tables to compare and map features, etc.
  4. (Kaz, McCool) Reach out to W3C TAG to discuss.
  5. (Oliver, McCool) Reach out to IETF, JOSE/COSE/JWS community to get alignment, and converge on a standard. IETF 112 is Nov 6-12, and/or we could invite someone (Carsten Bormann would be good to reach out to) to our F2F.
  6. We still want implementations for IETF "working code" process. Need at least one to drive discussion at IETF, two if we want to proceed to a W3C REC. Two would be a good idea to test interop even if doing an IETF RFC.
  7. Discuss (e.g. at F2F) whether this should go into our next WoT WG charter. McCool's opinion: not critical to be in our charter if our goal is to make it an IETF RFC that we can just cite, then our only action will be to cite it for TD 2.0. For TD 1.x it would be optional/experimental and invokable by using an extension vocabulary.

Update: moved these actions to an issue, see w3c/wot-ejs#10, to make their completion easier to track.

@mmccool
Copy link
Contributor Author

mmccool commented Sep 6, 2021

See w3c/wot-security-best-practices#14 - there might be use cases for EJS in data returned by WoT Things, not just TDs (although TDs are data returned by a TDD and a TDD is a Thing so...)

@sebastiankb
Copy link
Contributor

from today's TD call:

@sebastiankb sebastiankb closed this Sep 8, 2021
@ashimura
Copy link
Contributor

ashimura commented Sep 8, 2021

@mmccool and @sebastiankb I've just created a dedicated repo named wot-ejs for that purpose :)

@mmccool mmccool mentioned this pull request Sep 14, 2021
@mmccool
Copy link
Contributor Author

mmccool commented Sep 19, 2021

To clarify though: there is NOT currently a version of this being developed at IETF. But that's where it should be developed, and we want to avoid a potential future conflict. So we're spinning this off with the intention of developing it further elsewhere, possibly at IETF.

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.

4 participants