summary refs log tree commit diff
path: root/docs/server-server/signing.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/server-server/signing.rst')
-rw-r--r--docs/server-server/signing.rst151
1 files changed, 0 insertions, 151 deletions
diff --git a/docs/server-server/signing.rst b/docs/server-server/signing.rst
deleted file mode 100644
index 60c701ca91..0000000000
--- a/docs/server-server/signing.rst
+++ /dev/null
@@ -1,151 +0,0 @@
-Signing JSON
-============
-
-JSON is signed by encoding the JSON object without ``signatures`` or ``unsigned``
-keys using a canonical encoding. The JSON bytes are then signed using the
-signature algorithm and the signature encoded using base64 with the padding
-stripped. The resulting base64 signature is added to an object under the
-*signing key identifier* which is added to the ``signatures`` object under the
-name of the server signing it which is added back to the original JSON object
-along with the ``unsigned`` object.
-
-The *signing key identifier* is the concatenation of the *signing algorithm*
-and a *key version*. The *signing algorithm* identifies the algorithm used to
-sign the JSON. The currently support value for *signing algorithm* is
-``ed25519`` as implemented by NACL (http://nacl.cr.yp.to/). The *key version*
-is used to distinguish between different signing keys used by the same entity.
-
-The ``unsigned`` object and the ``signatures`` object are not covered by the
-signature. Therefore intermediate servers can add unsigneddata such as time stamps
-and additional signatures.
-
-
-::
-
-  {
-     "name": "example.org",
-     "signing_keys": {
-       "ed25519:1": "XSl0kuyvrXNj6A+7/tkrB9sxSbRi08Of5uRhxOqZtEQ"
-     },
-     "unsigned": {
-        "retrieved_ts_ms": 922834800000
-     },
-     "signatures": {
-        "example.org": {
-           "ed25519:1": "s76RUgajp8w172am0zQb/iPTHsRnb4SkrzGoeCOSFfcBY2V/1c8QfrmdXHpvnc2jK5BD1WiJIxiMW95fMjK7Bw"
-        }
-     }
-  }
-
-::
-
-  def sign_json(json_object, signing_key, signing_name):
-      signatures = json_object.pop("signatures", {})
-      unsigned = json_object.pop("unsigned", None)
-
-      signed = signing_key.sign(encode_canonical_json(json_object))
-      signature_base64 = encode_base64(signed.signature)
-
-      key_id = "%s:%s" % (signing_key.alg, signing_key.version)
-      signatures.setdefault(sigature_name, {})[key_id] = signature_base64
-
-      json_object["signatures"] = signatures
-      if unsigned is not None:
-          json_object["unsigned"] = unsigned
-
-      return json_object
-
-Checking for a Signature
-------------------------
-
-To check if an entity has signed a JSON object a server does the following
-
-1. Checks if the ``signatures`` object contains an entry with the name of the
-   entity. If the entry is missing then the check fails.
-2. Removes any *signing key identifiers* from the entry with algorithms it
-   doesn't understand. If there are no *signing key identifiers* left then the
-   check fails.
-3. Looks up *verification keys* for the remaining *signing key identifiers*
-   either from a local cache or by consulting a trusted key server. If it
-   cannot find a *verification key* then the check fails.
-4. Decodes the base64 encoded signature bytes. If base64 decoding fails then
-   the check fails.
-5. Checks the signature bytes using the *verification key*. If this fails then
-   the check fails. Otherwise the check succeeds.
-
-Canonical JSON
---------------
-
-The canonical JSON encoding for a value is the shortest UTF-8 JSON encoding
-with dictionary keys lexicographically sorted by unicode codepoint. Numbers in
-the JSON value must be integers in the range [-(2**53)+1, (2**53)-1].
-
-::
-
- import json
-
- def canonical_json(value):
-     return json.dumps(
-         value,
-         ensure_ascii=False,
-         separators=(',',':'),
-         sort_keys=True,
-     ).encode("UTF-8")
-
-Grammar
-+++++++
-
-Adapted from the grammar in http://tools.ietf.org/html/rfc7159 removing
-insignificant whitespace, fractions, exponents and redundant character escapes
-
-::
-
- value     = false / null / true / object / array / number / string
- false     = %x66.61.6c.73.65
- null      = %x6e.75.6c.6c
- true      = %x74.72.75.65
- object    = %x7B [ member *( %x2C member ) ] %7D
- member    = string %x3A value
- array     = %x5B [ value *( %x2C value ) ] %5B
- number    = [ %x2D ] int
- int       = %x30 / ( %x31-39 *digit )
- digit     = %x30-39
- string    = %x22 *char %x22
- char      = unescaped / %x5C escaped
- unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
- escaped   = %x22 ; "    quotation mark  U+0022
-           / %x5C ; \    reverse solidus U+005C
-           / %x62 ; b    backspace       U+0008
-           / %x66 ; f    form feed       U+000C
-           / %x6E ; n    line feed       U+000A
-           / %x72 ; r    carriage return U+000D
-           / %x74 ; t    tab             U+0009
-           / %x75.30.30.30 (%x30-37 / %x62 / %x65-66) ; u000X
-           / %x75.30.30.31 (%x30-39 / %x61-66)        ; u001X
-
-Signing Events
-==============
-
-Signing events is a more complicated process since servers can choose to redact
-non-essential event contents. Before signing the event it is encoded as
-Canonical JSON and hashed using SHA-256. The resulting hash is then stored
-in the event JSON in a ``hash`` object under a ``sha256`` key. Then all
-non-essential keys are stripped from the event object, and the resulting object
-which included the ``hash`` key is signed using the JSON signing algorithm.
-
-Servers can then transmit the entire event or the event with the non-essential
-keys removed. Receiving servers can then check the entire event if it is
-present by computing the SHA-256 of the event excluding the ``hash`` object, or
-by using the ``hash`` object included in the event if keys have been redacted.
-
-New hash functions can be introduced by adding additional keys to the ``hash``
-object. Since the ``hash`` object cannot be redacted a server shouldn't allow
-too many hashes to be listed, otherwise a server might embed illict data within
-the ``hash`` object. For similar reasons a server shouldn't allow hash values
-that are too long.
-
-[[TODO(markjh): We might want to specify a maximum number of keys for the
-``hash`` and we might want to specify the maximum output size of a hash]]
-
-[[TODO(markjh) We might want to allow the server to omit the output of well
-known hash functions like SHA-256 when none of the keys have been redacted]]