($and/ <== DO NOT REMOVE - switch for preventing MathML interpretation of dollar signs on this page)

About

This proposal specifies the basic process for signing XDI graphs, in particular XDI messages as specified in XDI Message Patterns. For discussion see the Discussion page.

Change Log

Scope

An XDI signature may be applied to any XDI subgraph (see Graph Model Structure. The signature covers the entire XDI subgraph rooted in that context node at that point in time. The focus of this proposal is signing XDI messages, however the process is the same for signing any other XDI context.

Terminology

Usage

XDI requests and responses SHOULD be signed, to ensure message integrity and authenticity. XDISecurity defines other mechanisms to achieve integrity and authenticity. This specification defines signatures that require SHA-256 or greater hashing, and allows for HMAC, RSA and ECDSA algorithms. In the future, additional hashing and encryption algorithms may be added.

Signatures over sub-graphs are established in a manner such that the signature may be included in the graph.

Recipients of signed XDI messages SHOULD validate all signatures present.

Allowed Key representations

pkcs8, pem, der x509v3 etc…

Graph Normalization Rules

Signing XDI messages involves first normalizing to the XdiFlatSerialization, and afterwards, incorporation of a Signature Block in a manner not disruptive to validators.

XdiFlatSerialization is the only serialization format used for signature creation and validation. Implementations that choose to transfer XDI messages in another serialization format MUST re-serialize the message in XdiFlatSerialization prior to attempting validation.

XDI Notation Normalization

The following steps MUST be performed in this order to produce the Normalized Graph. These requirements apply to message senders as well as message recipients.

  1. Ensure the sub-graph is UTF-8 encoded and formatted as defined in XdiFlatSerialization.

  2. All unquoted white space and new lines MUST be removed (TODO: better clarify ‘’white space’’. should this go into XdiFlatSerialization?)

  3. All JSON ‘’keys’’ in the unsigned graph MUST be sorted in UTF-8 byte-order.

Constructing the Signature block

(alg, key url, web key, key id, cert url, cert thumbprint, type, content type, critical must understand)

To construct the Signature Block, the following statements MUST be added to the end of the Normalized Graph:

  1. postpend the signature type (see Signature types below).

  2. postpend information pertaining to the public key associated with the signing key, which MUST be one of the following:
    1. the XDI location of the public key.
    2. the public key value itself as an XDI literal value.
    3. an HTTP URI of the public key. This resource MUST provide a mechanism for integrity protection. For example, use of transport channel protection such as TLS.
    4. an HTTP URI of the x509v3 certificate that includes the public key.

In addition, the following statements MAY be added to the end of the Normalized Graph:

  1. optionally, postpend a unique message identifier if the signature is that of the message sender.
  2. optionally, postponed the requestors message identifier if the signature is that of the responder (in response to).

  3. optionally, postpend a date/time value representing the moment the message was signed.
  4. optionally, include the <$critical> dictionary term. $critical indicates that processing of the included optional Signature Block statements above MUST be supported by the recipient, and that signature validation MUST be performed.

  5. calculate the hash (as indicated by the signature type above) over the full concatenation of the Normalized Graph and the Signature Block items above.

  6. encrypt the hash with the private key corresponding to the indicated key above.
  7. postpend the resulting signature to the message.

Need to add support for detached signatures as well?

For example, assuming the following graph in XDI Display form:

[=]!:uuid:1111/$is$ref/=alice
([=]!:uuid:1111)/$ref/
=alice/$ref/[=]!:uuid:1111
(=alice)/$ref/([=]!:uuid:1111)
/$is$ref/([=]!:uuid:1111)
[=]!:uuid:1111<#name>&/&/"Alice"
[=]!:uuid:1111<#email>&/&/"alice@alice.com"
[=]!:uuid:1111/#friend/=bob

produces the ‘’’Normalized Graph’’’:

{"/$is$ref":["([=]!:uuid:1111)"],"(=alice)/$ref":["([=]!:uuid:1111)"],"([=]!:uuid:1111)/$ref":[""],"=alice/$ref":["[=]!:uuid:1111"],"[=]!:uuid:1111/$is$ref":["=alice"],"[=]!:uuid:1111/#friend":["=bob"],"[=]!:uuid:1111<#email>&/&":"alice@alice.com","[=]!:uuid:1111<#name>&/&":"Alice"}

for demonstration purposes, the remainder of the examples will use the ‘pretty print’ form of the XDI JSON Flat serialization:

{
  "(=alice)/$ref": [
    "([=]!:uuid:1111)"
  ],
  "([=]!:uuid:1111)/$ref": [
    ""
  ],
  "/$is$ref": [
    "([=]!:uuid:1111)"
  ],
  "=alice/$ref": [
    "[=]!:uuid:1111"
  ],
  "[=]!:uuid:1111/$is$ref": [
    "=alice"
  ],
  "[=]!:uuid:1111/#friend": [
    "=bob"
  ],
  "[=]!:uuid:1111<#email>&/&": "alice@alice.com",
  "[=]!:uuid:1111<#name>&/&": "Alice"
}

{
  "(=alice)/$ref": [
    "([=]!:uuid:1111)"
  ],
  "([=]!:uuid:1111)/$ref": [
    ""
  ],
  "/$is$ref": [
    "([=]!:uuid:1111)"
  ],
  "=alice/$ref": [
    "[=]!:uuid:1111"
  ],
  "[=]!:uuid:1111/$is$ref": [
    "=alice"
  ],
  "[=]!:uuid:1111/#friend": [
    "=bob"
  ],
  "[=]!:uuid:1111<#email>&/&": "alice@alice.com",
  "[=]!:uuid:1111<#name>&/&": "Alice",
  “=alice<$sig>/$is#”: "$rsa$sha$256”,
  “=alice[$sig]@1$keypair$public<$key>&/&”: "the-key"
}

{
  "(=alice)/$ref": [
    "([=]!:uuid:1111)"
  ],
  "([=]!:uuid:1111)/$ref": [
    ""
  ],
  "/$is$ref": [
    "([=]!:uuid:1111)"
  ],
  "=alice/$ref": [
    "[=]!:uuid:1111"
  ],
  "[=]!:uuid:1111/$is$ref": [
    "=alice"
  ],
  "[=]!:uuid:1111/#friend": [
    "=bob"
  ],
  "[=]!:uuid:1111<#email>&/&": "alice@alice.com",
  "[=]!:uuid:1111<#name>&/&": "Alice",
  “=alice<$sig>/$is#”: "$rsa$sha$256",
  “=alice[$sig]@1$keypair$public<$key>&/&”: "the-key",
  “=alice<$sig>&/&”: "c1g23p…"
}

Note that the XDI Converter tool currently does not sort in a manner consistent with the above JSON example.

Note: since all XDI literals are uniquely identified by the two-segment XDI address representing the XDI subject and predicate, and all other XDI statements consist of three-segment XDI addresses, the ASCII ordering of the unsigned graph can be performed entirely against XDI addresses and ignore literal data values.

Key Retrieval

Security of retrieval

Methods, metadata

 This should move to the SecMech spec. 

Signature Validation

Message recipients SHOULD validate the signature on all signed messages.

Message recipients SHOULD retrieve signing key metadata from the message senders graph.

Signature Types

The intention of the XDI Technical Committee is for XDI Signatures to support all popular signature algorithms. To do this, a branch of the XDI $ Dictionary will need to specify $ words for each supported algorithm and subcontexts as needed for variants. At a minimum (from draft-ietf-jose-json-web-signature-23):

ToDo

Examples

Signed XDI Message

 needs updating after TC reviews and agrees to changes  The only difference between an unsigned and signed XDI message a signed message is the presence of the signature statement.

Note: for readability, the three UUIDs in this example have been truncated to a single integer.

([+]!:uuid:1)/$set/[+]!:uuid:1[$msg]!:uuid:2
[+]!:uuid:1[$msg]!:uuid:2/$is()/[=]!:uuid:3
[+]!:uuid:1[$msg]!:uuid:2<$t>&/&/"2011-04-10T22:22:22Z"
[+]!:uuid:1[$msg]!:2$rsa$512<$sig>&/&/"nihUFQg4mDhLgecvhIcKb9Gz8VRTOlw+adiZOBBXgK4JodEe5aFfCqm8WcRIT8GLLXSk8PsUP4//SsKqUBQkpotcAqQAhtz2v9kCWdoUDnAOtFZkd/CnsZ1sge0ndha40wWDV+nOWyJxkYgicvB8POYtSmldLLepPGMz+J7/Uws="
[+]!:uuid:1[$msg]!:2/$do/[=]!:uuid:3[+]!:uuid:1$do
[+]!:uuid:1[$msg]!:uuid:2$do/$get/[=]!:uuid:3<#email>


CategoryProposal CategorySecurity CategorySignatures CategoryMediumPriority

XdiSignature (last edited 2014-03-29 23:26:02 by drummond-xns)