StoresHTTP Store

HTTP Store

A Condensation HTTP store exposes seven HTTP/REST calls: three for storing and retrieving objects, three for modifying and listing boxes, and a combined modification call.

Retrieving an object

Request
GET /objects/HASH
[Range: range-specifier]
Response
200 OK
Content-Type: application/condensation-object

The object's content.

Returns the object identified by HASH (64 hexadecimal digits). If the object exists, the server replies with status code 200 OK, and sends the object's content. Otherwise, a 404 Not Found status code is returned.

Submitting an object

Request
PUT /objects/HASH
Condensation-Date: DATE
Condensation-Actor: PUBLIC KEY HASH
Condensation-Signature: SIGN(PRIVATE KEY, SHA256(DATE|"\0"|METHOD|"\0"|HOST|PATH))
Content-Type: application/condensation-object

OBJECT BYTES
Response
204 No Content

Stores a new object. Upon success, the server replies with 204 No Content. Note that the operation is also successful if the object already exists.

If the indicated HASH does not correspond to the SHA-256 sum of the received content, the server discards the object and returns status code 400 Bad Request.

If the signature is wrong, or the date too old, the server responds with 403 Forbidden. Condensation servers only accept objects from users that have an account.

Booking an object

Request
POST /objects/HASH
Condensation-Date: DATE
Condensation-Actor: PUBLIC KEY HASH
Condensation-Signature: SIGN(PRIVATE KEY, SHA256(DATE|"\0"|METHOD|"\0"|HOST|PATH))
Response
204 No Content

Books an existing object. The server replies with 204 No Content upon success, or 404 Not Found if the object does not exist.

Signatures are validated as for object submission.

Listing a box

Request
GET /accounts/ACCOUNT/BOX
Condensation-Watch: TIMEOUT ms
Response
200 OK
Content-Type: application/condensation-box
Last-Modified: DATE

HASH HASH HASH ...

Returns the set of hashes currently held in BOX. Each hash is 32 bytes long. The set is not ordered, and may contain duplicates.

Note that everybody can read boxes, not just the owner.

Some stores support a watch timeout. If the box is empty, the server will reply when an entry is added, or after the timeout expires. This is sometimes used to read message boxes.

Adding a hash

Request
PUT /accounts/ACCOUNT/BOX/HASH
Condensation-Date: DATE
Condensation-Actor: PUBLIC KEY HASH
Condensation-Signature: SIGN(PRIVATE KEY, SHA256(DATE|"\0"|METHOD|"\0"|HOST|PATH))
Response
204 No Content

Adds a box entry.

If the operation succeeds, the server replies with 204 No Content. If the operation is not allowed, the server responds with 403 Forbidden.

On the private and public boxes, only the account owner is allowed to add hashes. On the message box, anybody is allowed to add envelopes, and the signature is optional.

Removing a hash

Request
DELETE /accounts/ACCOUNT/BOX/HASH
Condensation-Date: DATE
Condensation-Actor: PUBLIC KEY HASH
Condensation-Signature: SIGN(PRIVATE KEY, SHA256(DATE|"\0"|METHOD|"\0"|HOST|PATH))
Response
204 No Content

Removes a box entry.

If the operation succeeds, the server replies with 204 No Content. If the operation is not allowed, the server responds with 403 Forbidden.

On the private and public boxes, only the account owner is allowed to remove hashes. Message envelopes can be removed by the account owner, or any actors listed as updated by.

Modifications

Request
POST /accounts
Condensation-Date: DATE
Condensation-Actor: PUBLIC KEY HASH
Condensation-Signature: SIGN(PRIVATE KEY, SHA256(DATE|"\0"|METHOD|"\0"|HOST|PATH|"\0"|MODIFICATIONS RECORD))
Content-Type: application/condensation-modifications

MODIFICATIONS RECORD
Response
204 No Content

Puts objects, and adds and removes box entries in a single request.

The payload is a record with the following structure:

put
  HASH BYTES*
    OBJECT BYTES
add
  ACCOUNT HASH BYTES*
    BOX LABEL*
      HASH BYTES*
remove
  ACCOUNT HASH BYTES*
    BOX LABEL*
      HASH BYTES*

Records marked with a star (*) can be repeated as many times as necessary. Empty sections may be skipped. Hashes are stored as 32 bytes (not as hashes).

Modifications are carried out as follows:

  1. The server reads the modifications record, and fails with 400 Bad Request if there is an error.
  2. The server verifies the request, and responds with 403 Forbidden if it is invalid or not allowed.
  3. The server now stores all submitted objects. Objects may be stored in any order, or concurrently. If this fails, processing is stopped, and the corresponding error is returned.
  4. The server then attempts to add box entries. Additions may be processed in any order, or concurrently. If this fails, processing is stopped, and the corresponding error is returned.
  5. The server finally removes box entries, and ignores all errors.
  6. The server responds with 204 No Content.

Storage system errors

To all above requests, the server may respond with 500 Internal Server Error if the underlying storage system fails to carry out the request, or reports an error.

Boxes

A server must support the following boxes:

It may support other boxes as well.

Other URIs

For any URI not specified above, the server should return 404 Not Found. This also applies to URIs with incomplete hashes, or unsupported boxes.

Signatures mature

A store may require signatures for all PUT, POST and DELETE requests to authenticate the user. This protects the storage service provider (server) – who may want to charge for the service – from unauthorized access.

Note that request signatures do not protect the user's data. Data is protected through end-to-end encryption and end-to-end signatures, and does not need any additional protection.

Signatures for put, book, add, and remove requests

The signature for a put, book, add or remove request is calculated as follows:

Condensation-Date 0 Method 0 Host PUT Hash to signSHA-256 of  2013-12-11T16:04:22.000Z condensation.iolocalhost:8080 /objects/7df84cd2f426a2c34d50deaa6cc1a7b17f2085350a3aaebcecbb11a2987b62cd Key Private key of Condensation-Actor Byte 0 Condensation-Signature RSA/PSS signature of Hash to sign using Key Path

and added to the HTTP header as shown in the following example:

PUT /objects/7df84cd2f426a2c34d50deaa6cc1a7b17f2085350a3aaebcecbb11a2987b62cd HTTP/1.1
Host: condensation.io
Condensation-Date: 2013-12-11T16:04:22.000Z
Condensation-Actor: f056974f4efd71246917314c1cb878c1af3e81057df5692b992f2a9cec8f3828
Condensation-Signature: 80810b874799341789fcf033935e2d6272c284581ca9b47228260bc4ccaada77465dadd44a0d2e4fed58fb2fdc26ffaa21f9bca01882d7f937f80271d7d4401ef24e554e2e15474cc928b6ddcd80d6d2a3f163f90e1d38f9452276e62e74b1c249bd76d11827e59cc9270e29dff595d4fd2344d66ed903aed0a56da98d7252295e1d031be861d8ae8a7106cb446fe0fafbb74576625bdf1c1cf23232c0050827bf7fdf7c202a4f8764b643a995c4e7744cdddcef5b5e5f90344872236f7333086c3cd71a8ea7aef05339ce32eb32057590797550a41c816113a75c190b82812b7224874d03f720bc2139843627161bf02d7f579620edf5bac29d1be1a6aa67b9
...

Actor hash and signature are hex-encoded.

Signature for modify requests

The signature for submitting modifications is similar, but also covers the submitted modifications (post data):

Condensation-Date 0 0 POST Hash to signSHA-256 of Host Path condensation.iolocalhost:8080 /accounts Key Private key of Condensation-Actor Byte 0 Condensation-Signature RSA/PSS signature of Hash to sign using Key 0 Post data Method  2013-12-11T16:04:22.000Z

Dates mature

Requests with a date that is more than a few minutes off should be rejected to prevent replay attacks.

The date is indicated using the Condensation-Date header, since some clients (e.g. JavaScript within the web browser) do not have access to the standard Date header field. Clients may of course send the Date header, too.

The date is written using the ISO 8601 format YYYY-MM-DDTmm:hh:ss.sssZ.

Public key

The user's public key must be known to the server to verify these signatures. For that, the user must first put its public key, and sign that request with that key.

HTTP vs. HTTPS

A HTTP store may be accessed via HTTP or HTTPS.