Skip to content

Commit

Permalink
update/clarify guard conditions per #7
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Gough committed Jun 3, 2017
2 parents cc9f66d + 6ee92d3 commit 2cd44e4
Show file tree
Hide file tree
Showing 5 changed files with 434 additions and 46 deletions.
9 changes: 0 additions & 9 deletions API/swagger.json

This file was deleted.

4 changes: 4 additions & 0 deletions docs/2.0/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
layout: swagger
data: ausdigital-tap_2-0_swagger
---
135 changes: 98 additions & 37 deletions docs/2.0/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ ausdigital-idp/1 | Version 1 of the [AusDigtial](http://ausdigital.org) [IDP](ht
Copyright (c) 2016 the Editor and Contributors. All rights reserved.

This Specification is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software Foundation;
terms of the GNU General Public License as published by the Free Software Foundation;
either version 3 of the License, or (at your option) any later version.

This Specification is distributed in the hope that it will be useful, but WITHOUT ANY
Expand Down Expand Up @@ -80,7 +80,7 @@ protocol specified in this document. The TAP is an autonomous agent in business-
document exchange.

A TAP might be provided by a commercial ledger service, or maintained as part of an
independent business system.
independent business system.

The TAP specification has two parts. The main part (ausdigital-tap/2) defines the protocol all peers
must follow (and interfaces they must provide) to send and receive business documents. The
Expand All @@ -98,9 +98,9 @@ repository. Future semantic payloads may be supported without change to the prot

All TAPs depend on the following Services:

* ausdigital-dcl/1
* ausdigital-dcp/1
* ausdigital-nry/1
* ausdigital-dcl/1
* ausdigital-dcp/1
* ausdigital-nry/1

TAPGW providers also depend on the
ausdigital-idp/1. TAPs do not need to
Expand All @@ -122,29 +122,44 @@ The `signature` part is created by a business system component trusted by the se

Receiving TAPs may also use the signature as a filter (messages with invalid signatures MAY be dropped by receiving TAPs, rather than delivered). This allows TAPs to buffer trusted components from anonymous denial of service attacks.

When a valid message is received, the TAP issues an HTTP 200 status and returns a response body with `Content-Type: text/json`, containing a HATEOS-style list of callback URLs.
When a valid message is received, the TAP issues an HTTP 200 status and returns a response body with `Content-Type: application/json`, containing received message information and optional HATEOS-style list of callback URLs.

![Illustration of HTTP 200 response](./tap_overview_response.png "Response 200 OK")
```
{
"data": {
"type": "TapMessage",
"id": "tap-generated UUID of the message",
"attributes": {
"documentHash": "proxied field 'hash' from message.json document",
"deliveryStatus": "processing"
}
}
}
```

See the TAP Protocol Details chapter for more information.


# TAP Protocol Details


The TAP Protocol is a very simple REST API. One business sends a message directly to another business' TAP endpoint (discovered via the `ausdigital/DCP` protocol):

* The sender uses the HTTP POST verb (over HTTPS) to send the signed message to a TAP.
* The TAP replies with a HATEOS-style list of callback URLs.
* The TAP notarises some non-sensitive but useful data to the blockchain.
* The sender uses the HTTP POST verb (over HTTPS) to send the signed message to a TAP,
* The sender MUST use HTTPS,
* The TAP MUST reply with received message info or error response,
* The TAP MAY include a HATEOS-style list of callback URLs in the response,
* The TAP MAY notarize some non-sensitive but useful data.


## Receiving a business message

When a message is sent to a TAP endpoint (via HTTP `POST`), it MUST validate the message before delivering it to the recipient:
When a message is sent to a TAP endpoint, it MUST validate the message before delivering it to the recipient:

* If the sender participant identifier is not valid, the message MUST NOT be delivered.
* If the signing key for the message is not in the sender participant identifier's published list of signing keys (and non-revoked at the time of signing, per `ausdigital/DCP` protocol), the message MUST NOT be delivered.
* If the message signature is not made with the signing key of the message, the message MUST NOT be delivered.
* If the message does not validate against the JSON schema, return HTTP error (400).
* If the sender participant identifier is not valid, an HTTP 200 may be returned but the message MUST NOT be delivered.
* If the signing key for the message is not in the sender participant identifier's published list of signing keys (and non-revoked at the time of signing, per `ausdigital/DCP` protocol), an HTTP 200 may be returned but the message MUST NOT be delivered.
* If the message signature is not made with the signing key of the message, and HTTP 200 may be returned but the message MUST NOT be delivered.


## Sending a business message
Expand All @@ -160,12 +175,12 @@ Pre-requisites:

The process is:

* Sign the business message
* Create hash of signed business document
* Create hash of the business document
* Sign the business document
* Create cyphertext of the signed business document
* Create message
* Generate message signature
* POST message and signature to the recipient TAP
* Create message.json file
* Generate message.json signature
* POST message.json and signature to the recipient TAP


### Sign the Business Document
Expand All @@ -189,37 +204,64 @@ gpg2 \
--clearsign "doc.json"
```

Please see (TODO: examples) for more detailed explanation and real-world examples.


### Create hash of signed business document

The following hash algorithms are approved for use:

* SHA256
* SHA256 (default)
* SHA384
* SHA512
* BLAKE2b
* BLAKE2s

It is not necessary to sign the hash, because the entire message is signed.

This hash is of the cleartext "signed business document". When the recipient decrypts the business document, they are able to verify the hash. If the recipient-generated hash does not match the hash in the message, the recipient MUST NOT provide business acceptance of the document.
This hash is of the cleartext "business document" before the signing. When the recipient decrypts the business document, they are able to verify the hash. If the recipient-generated hash does not match the hash in the message, the recipient MUST NOT provide business acceptance of the document.

The hash is calculated before the signing, so, if sender for some reasons calculates 2 different signatures using 2 different keys - the hash is still the same.

**TODO: this is a very strange paragraph.**
If a 3rd party is presented with a copy of the message (including this hash), and with a copy of the signed business document, they are able to verify that the hash of the signed business document matches the hash in the message. That way, if the recipient provides business acceptance of the document, the third party knows the document that was accepted matches the cleartext document they were shown (despite the fact the 3rd party does not have access to recipient key material).

Assuming the current working directory contains a signed document `signed_doc.txt`, a hash of the signed document `signed_doc.hash` can be created with openssl like this:
Assuming the current working directory contains a document `doc.txt`, a hash of the signed document `doc.hash` can be created with openssl like this:

```bash
openssl dgst -sha256 -out "signed_doc.hash" "signed_doc.txt"
openssl dgst -sha256 -out "doc.hash" "doc.txt"
```

For example, if your doc.txt contains text `{"document_type": "invoice"}` (ending with newline character) the result is:
```
SHA256(doc.txt)= 14a62c86caa60bb3987248e93e51cacd46392562475738d3213b44f457ee163b
```
where `14a62c86caa60bb3987248e93e51cacd46392562475738d3213b44f457ee163b` is a document hash in plan SHA256 HEX format.


### Create cyphertext of signed business document

The message does not contain plaintext of the business message (signed or otherwise). It contains the hash of the signed plaintext (as per above), and cyphertext of the plaintext message.
The message does not contain plaintext of the business document (signed or otherwise). It contains the hash of the plaintext (as per above), and cyphertext of the signed plaintext document.

The cyphertext is created using public key cryptography, using the appropriate public key for the recipient business endpoint. The public parts of these keypairs are discoverable using the appropriate DCP for each business identifier URNs, which is discoverable using the global DCL. Public keys MUST be published in ASCII-Armoured form in the DCP.

Example:

The cyphertext is created using public key cryptography, using the appropriate public key for the recipient business endpoint, and the appropriate private key of the sender. The public parts of these keypairs are discoverable using the appropriate DCP for each business identifier URNs, which is discoverable using the global DCL. Public keys MUST be published in ASCII-Armoured form in the DCP.
* Alice sends document to Bob
* Both Alice and Bob has public/private keypairs
* Both Alice and Bob published their public keys to the DCP
* Alice signs plaintext document by Alice's private key, having signed document as an output
* Alice encyphers signed document using Bob's public key, having encyphered value as a result
* Nobody except Bob can decypher the encyphered value (because only Bob owns his private keys)
...
* When message is received, Bob decyphers the encyphered value using his public key
* After that Bob validates the digital signature, using Alice's public key
* If everything went fine Bob can be sure that:

Use of mature and extensively scrutinised cryptography implementations is strongly encouraged. The following examples use GnuPG, although any compliant RFC4880 implementation could be used in an equivalent way.
1. Only he decyphered the document
2. This document has been signed by Alice.

Use of mature, well-known and extensively scrutinised cryptography implementations is strongly encouraged. The following examples use GnuPG, although any compliant RFC4880 implementation could be used in an equivalent way.

Assuming the recipient's public key is not already in the sender's GnuPG keyring, but is in the current working directory as `recipient.gpg`, it can be added to the sender's GnuPG keyring like this:

Expand All @@ -232,20 +274,41 @@ With GnuPG, this is only necessary once. Subsequent messages to the same recipie

#### Note about published keys

Once the recipient's key has been added to the sender's keyring, and assuming the current working directory contains a signed document `signed_doc.txt`, and the user namespace identifier of the recipient public key is `91f68ffafa1288ad55cb3e61e937870fb5598cc098e125fe29412ab3047f15e1@smp.testpoint.io` then cyphertext of signed business document can be created with:
Implementation-specific section.

Once the recipient's key has been added to the sender's keyring, and assuming the current working directory contains a signed document `signed_doc.txt`, and the user namespace identifier of the recipient public key is `91f68ffafa1288ad55cb3e61e937870fb5598cc098e125fe29412ab3047f15e1@dcp.testpoint.io` then cyphertext of signed business document can be created with:

```
gpg2 --armour \
--output "cyphertext.gpg"
--encrypt \
--recipient 91f68ffafa1288ad55cb3e61e937870fb5598cc098e125fe29412ab3047f15e1@smp.testpoint.io \
--recipient 91f68ffafa1288ad55cb3e61e937870fb5598cc098e125fe29412ab3047f15e1@dcp.testpoint.io \
signed_doc.txt
```

This will create a file `cyphertext.gpg` in the current working directory, which has ASCII-Armour encoding (suitable for inclusion in a json document).

### Message format

Typical TAP message is:
```
{
"cyphertext": "string",
"hash": "string",
"sender": "string",
"reference": "string"
}
```

* "cyphertext" contains encrypted signed document
* encrypted by receiver public key
* signed by sender private key
* "hash" contains cryptographic hash of the document (before signing and encryption)
* "sender" contains unique participant identifier of client
* sender must make his public keys, used for signing operations, available in the DCP
* "reference" contains additional information about conversations or original message (which this one is replies to)

### Compose Message
### Compose Message Example

The `message` part is a mixture of cleartext metadata (used by TAPs) and enciphered payload (used by trusted business system components). The cleartext metadata does not contain sensitive business information, whereas access to the business-sensitive information within the payload is not necessary for participating in the TAP protocol.

Expand Down Expand Up @@ -293,26 +356,25 @@ if __name__ == "__main__":
compose_message()
```


### Generate signature

The `signature` part is created by a business system component trusted by the sender (with access to the sender's private key material). The signature can also be used to uniquely identify the message contents.


Assuming the current working directory contains the message (as `message.json`), the following command will create a signature `message.sig`:

```bash
gpg2 --output message.sig --sign message.json
```

Implementation note: the easiest way to make sure that specific key is used for signature is to have only single private key in GPG keyring. GPG for linux support custom keyring location.


### Posting the message to the recipient TAP

Layered on top of HTTP Protocol:

* MUST use HTTPS (RFC2818).
* MUST use `Content-Type: multipart/form-data` (RFC2388)
* MUST NOT use `Content-Type: application/x-www-form-urlencode` (RFC1876 is NOT supported)
* MUST use only `Content-Type: multipart/form-data` (RFC2388)
* MAY explicitly declare `Content-Transfer-Encoding: base64`
* MUST NOT rely on additional TAP-related information in HTTP headers, such as message or conversation identifiers.

Expand All @@ -330,15 +392,14 @@ curl -X POST \

## Receipt and Technical Acknowledgement

When a valid message is received, the TAP issues an HTTP 200 status and returns a response body with `Content-Type: text/json`, containing a HATEOS-style list of callback URLs.
When a valid message is received, the TAP issues an HTTP 200 status and returns a response body with `Content-Type: application/json`, containing information about the message and optional HATEOS-style list of callback URLs.
Check the [API](http://ausdigital.org/specs/ausdigital-tap/2.0/api) for possible responses, success and errors.

TODO:

* example response.
* explain callback URLs
* explain callback semantic URLs
* define error responses.



# Related Material

Expand Down
31 changes: 31 additions & 0 deletions docs/2.0/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"title": "The TAP message body model.",
"id": "https://raw.githubusercontent.com/ausdigital/ausdigital-tap/master/docs/2.0/schema.json#",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": [
"cyphertext",
"hash",
"sender",
"reference"
],
"additionalProperties": false,
"properties": {
"cyphertext": {
"type": "string",
"description": "The TAP message cyphertext."
},
"hash": {
"type": "string",
"description": "The TAP message hash."
},
"sender": {
"type": "string",
"description": "The TAP message sender."
},
"reference": {
"type": "string",
"description": "The TAP message reference."
}
}
}

0 comments on commit 2cd44e4

Please sign in to comment.