Need a way for the client to distinguish between authenticated (certain) and unauthenticated (likely) author SIDs in the context of a bundle list, since the bundle list does not verify manifest signatures for performance and battery life reasons.
39 KiB
Serval DNA REST API
Serval Project, September 2015
Introduction
The Serval DNA daemon that runs on every node in a Serval Mesh network gives applications access to the network through two main APIs:
-
the MDP API and MSP API provide "traditional" packet and stream transport, allowing applications to send and receive Serval network packets to and from nearby nodes with latencies of up to several seconds;
-
the HTTP REST API provides applications with access to the following Serval services:
This document describes the second of these, the HTTP REST API.
Protocol and port
The Serval DNA HTTP REST API is an HTTP 1.0 server that only accepts requests on the loopback interface (IPv4 address 127.0.0.1), TCP port 4110. It rejects requests that do not originate on the local host, by replying 403.
Security
The REST API is a clear-text interface; requests and responses are not encrypted. HTTP REST is not carried over any physical network link so it is not exposed to remote eavesdroppers. That means the only threat comes from local processes.
Linux prevents normal processes from accessing the traffic on local sockets between other processes, so to attack Serval DNA and its clients, a local process on the local host would have to gain super-user privilege (eg, through a privilege escalation vulnerability), which would give it many avenues for attacking Serval DNA and its clients. In this situation, encrypting client-server communications would offer no protection whatsoever.
Authentication
Clients of the HTTP REST API must authenticate themselves using Basic Authentication. This narrows the window for opportunistic attacks on the HTTP port by malicious applications that scan for open local ports to exploit. Any process wishing to use the REST API must supply valid authentication credentials (name/password), or will receive a 401 Unauthorized response.
Client applications obtain their REST API credentials via a back channel specific to their particular platform. This delegates the exercise of handing out credentials to the application layer, where users can (usually) exercise their own discretion. For example, on Android, a client app sends an Intent to the Serval Mesh app requesting a Serval REST credential, and will receive a reply only if it possesses the right Android Permission. When users install or run the client app, Android informs them that the app requests the "Serval Network" permission, and users may allow or deny it.
As a fall-back mechanism, created primarily to facilitate testing, HTTP REST API credentials can be configured using configuration options of the form:
api.restful.users.USERNAME.password=PASSWORD
PASSWORD is a cleartext secret, so the Serval DNA configuration file must be protected from unauthorised access or modification by other apps. That makes this mechanism unsuitable for general use.
Request
An HTTP REST request is a normal HTTP 1.0 GET or POST:
GET
A GET request consists of an initial "GET" line containing the path and HTTP version, followed by zero or more header lines, followed by a blank line. As usual for HTTP, all lines are terminated by an ASCII CR-LF sequence.
For example:
GET /restful/keyring/identities.json?pin=1234 HTTP/1.0
Authorization: Basic aGFycnk6cG90dGVy
Accept: */*
POST
A POST request is the same as a GET request except that the first word of the first line is "POST", the blank line is followed by a request body, and the following request headers are mandatory:
Request Content-Length
In a request, the Content-Length header gives the exact number of bytes (octets) in the request's body, which must be correct. Serval DNA will not process a request until it receives Content-Length bytes, so if Content-Length is too large, the request will suspend and eventually time out. Serval DNA will ignore any bytes received after it has read Content-Length bytes, so if Content-Length is too small, the request body will be malformed.
Request Content-Type
In a request, the Content-Type header gives the Internet Media Type of the body. Serval DNA currently supports the following media types in requests:
-
multipart/form-data; boundary= is used to send large parameters in POST requests
-
text/plain; charset=utf-8 is used for MeshMS message form parts
-
rhizome/manifest; format=text+binarysig is used for Rhizome manifest form parts
Request Range
HTTP 1.1 Range retrieval is partially supported. In a request, the Range header gives the start and end, in byte offsets, of the resource to be returned. The server may respond with exactly the range requested, in which case the response status code will be 206, or it may ignore the Range header and respond with the entire requested resource.
For example, the following header asks that the server omit the first 64 bytes and send only the next 64 bytes (note that ranges are inclusive of their end byte number):
Range: bytes=64-127
The specification allows for more than one start-end range to be supplied, separated by commas, however not all REST API operations support multi ranges. If a multi-range header is used in such a request, then the response may be the entire content or 501 Not Implemented.
Responses
An HTTP REST response is a normal HTTP 1.0 response consisting of a header block, a blank line, and an optional body, for example: As usual, all lines are terminated by an ASCII CR-LF sequence. For example:
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 78
{
"http_status_code": 200,
"http_status_message": "OK"
}
The lingua franca of the HTTP REST API is JSON in UTF-8 encoding. All Serval DNA HTTP REST responses have a Content-Type of application/json unless otherwise documented.
Some responses contain non-standard HTTP headers as part of the result they return to the client; for example, Rhizome response headers.
Response status code
The HTTP REST API response uses the HTTP status code to indicate the outcome of the request as follows:
200 OK
The operation was successful and no new entity was created. Most requests return this code to indicate success. Requests that create a new entity only return this code if the entity already existed, meaning that the creation was not performed but the request can be considered a success since the desired outcome was achieved: namely, the existence of the entity. (If the entity was created, then these requests return 201 Created instead.)
(Serval APIs are all idempotent with respect to creation: creating the same entity twice yields the same state as creating it once. This is an important property for a purely distributed network that has no central arbiter to enforce sequencing of operations.)
201 Created
The operation was successful and the entity was created. This code is only returned by requests that create new entities, in the case that the entity did not exist beforehand and has been created successfully.
202 Accepted
The operation was successful but the entity was not created. This code is only returned by requests that create new entities, in the case that the request was valid but the entity was not created because other existing entities take precedence. For example, the Rhizome REST API returns this code when inserting a bundle to a full Rhizome store if the new bundle's rank falls below all other bundles, so the new bundle itself would be evicted to make room.
206 Partial Content
The operation was successful and the response contains part of the requested content. This code is only returned by requests that fetch an entity (the fetched entity forms the body of the response) if the request supplied a Range header that specified less than the entire entity.
400 Bad Request
The HTTP request was malformed, and should not be repeated without modifications. This could be for several reasons:
- invalid syntax in the request header block
- a
POST
request MIME part is missing, duplicated or out of order - a
POST
request was given an unsupported MIME part - a
POST
request MIME part has missing or malformed content
401 Unauthorized
The request did not supply an "Authorization" header with a recognised credential. This response contains a "WWW-Authenticate" header that describes the missing credential:
HTTP/1.0 401 Unauthorized
Content-Type: application/json
Content-Length: 88
WWW-Authenticate: Basic "Serval RESTful API"
{
"http_status_code": 401
"http_status_message": "Unauthorized"
}
403 Forbidden
The request failed because the server does not accept requests from the originating host.
404 Not Found
The request failed because the HTTP request URI does not exist. This could be for several reasons:
- the request specified an incorrect path (typographic mistake)
- the path is unavailable because the API in question is unavailable (eg, the Rhizome REST API) is currently configured as disabled
- the path contains a reference to an entity (eg, SID, BID) that does not exist
405 Method Not Allowed
The request failed because the HTTP request method is not supported for the given path. Usually this means that a GET request was attempted on a path that only supports POST, or vice versa.
411 Length Required
A POST
request did not supply a Content-Length
header.
414 Request-URI Too Long
The request failed because the HTTP request URI was too long. The server persists the path and a few other pieces of the request in a fixed size request buffer, and this response is triggered if the collective size of these does not leave enough buffer for receiving the remainder of the request.
415 Unsupported Media Type
A POST
request failed because of an unsupported content type, which could be
for several reasons:
- the request's Content-Type header specified an unsupported media type
- a MIME part Content-Disposition was not “form-data”
- a MIME part Content-Type was unsupported
- a MIME part Content-Type specified an unsupported charset
416 Requested Range Not Satisfiable
The Range header specified a range whose start position falls outside the size of the requested entity.
419 Authentication Timeout
The request failed because the server does not possess and cannot derive the necessary cryptographic secret or credential. For example, updating a Rhizome bundle without providing the bundle secret. This code is not part of the HTTP standard.
422 Unprocessable Entity
A POST
request supplied data that was inconsistent or violates semantic
constraints, so cannot be processed. For example, the Rhizome
insert operation responds with 422 if the
manifest filesize and filehash fields do not match the supplied payload.
423 Locked
The request cannot be performed because a necessary resource is busy for reasons outside the control of the requester and server.
This code is returned by Rhizome requests if the Rhizome store database is currently locked by another process. The architecture of Serval DNA is being improved to prevent any process other than the Serval DNA daemon itself from directly accessing the Rhizome database. Once these improvements are done, this code should no longer occur except during unusual testing and development situations.
429 Too Many Requests
The request cannot be performed because a necessary resource is temporarily unavailable due to a high volume of concurrent requests.
The original use of this code was for Rhizome operations if the server's manifest table ran out of free manifests, which would only happen if there were many concurrent Rhizome requests holding manifest structures open in server memory.
This code may also be used to indicate temporary exhaustion of other finite resources. For example, if Serval DNA is ever limited to service only a few HTTP requests at a time, then this code will be returned to new requests that would exceed the limit.
431 Request Header Fields Too Large
The request header block was too long.
Initial implementations of Serval DNA allocated approximately 8 KiB of buffer memory for each request, and the HTTP server read each header line entirely into that buffer before parsing it. If a single header exceeded the size of this buffer, then the 431 response was returned.
500 Internal Server Error
The request failed because of an internal error in Serval DNA, not an error in the request itself. This could be for several reasons:
- software defect (bug)
- unavailable system resource (eg, memory, disk space)
- corrupted environment (eg, bad configuration, database inconsistency)
Internal errors of this kind may persist or may resolve if the request is re-tried, but in general they will persist because the cause is not transient. Temporary failures that can be resolved by re-trying the request are generally indicated by other status codes, such as 423.
501 Not Implemented
The requested operation is valid but not yet implemented. This is used for the following cases:
- a request Range header specifies a multi range
Cross-Origin Resource Sharing (CORS)
To support client-side JavaScript applications, Serval DNA has a limited implementation of Cross-Origin Resource Sharing. If a request contains an Origin header with either “null” or a single URI with scheme “http” or “https” or “file”, hostname “localhost” or “127.0.0.1” (or empty in the case of a “file” scheme), and optionally any port number, then the response will contain three Access-Control headers granting permission for other pages on the same site to access resources in the returned response.
For example, given the request:
GET /restful/keyring/identities.json HTTP/1.0
Origin: http://localhost:8080/
...
Serval DNA will respond:
HTTP/1.0 200 OK
Access-Control-Allow-Origin: http://localhost:8080
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Authorization
...
JSON result
All responses that convey no special content return the following JSON result object:
{
"http_status_code": ...,
"http_status_message": "..."
}
The http_status_code
field is an integer equal to the status
code that follows the HTTP/1.0
token in the first
line of the response.
The http_status_message
field is usually the same as the reason phrase text
that follows the code in the first line of the HTTP response. This reason
phrase may be a [standard phrase][status code], or it may be more explanatory;
for example, some 404 responses from Rhizome have phrases like, “Bundle not
found”, “Payload not found”, etc.
Some responses augment the JSON result object with extra fields; for example, Rhizome JSON result.
JSON table
Many HTTP REST responses that return a list of regular objects (eg, GET /restful/rhizome/bundlelist.json) use the following JSON table format:
{
"header":["fieldname1","fieldname2","fieldname3", ... ],
"rows":[
[field1, field2, field3, ... ],
[field1, field2, field3, ... ],
...
]
}
The JSON table format is more compact than the most straightforward JSON representation, an array of JSON objects, which has the overhead of redundantly repeating all field labels in every single object:
[
{
"fieldname1: field1,
"fieldname2: field2,
"fieldname3: field3,
...
},
{
"fieldname1: field1,
"fieldname2: field2,
"fieldname3: field3,
...
},
...
]
A JSON table can easily be transformed into its equivalent array of JSON objects. The test scripts use the following jq(1) expression to perform the transformation:
[
.header as $header |
.rows as $rows |
$rows | keys | .[] as $index |
[ $rows[$index] as $d | $d | keys | .[] as $i | {key:$header[$i], value:$d[$i]} ] |
from_entries |
.["__index"] = $index
]
Keyring REST API
The Keyring REST API allows client applications to query, unlock, lock, create, and modify Serval Identities in the keyring.
Identity unlocking
All Keyring API requests can supply a password using the optional pin parameter, which unlocks all keyring identities protected by that password prior to performing the request. Serval DNA caches every password it receives until the password is revoked using the lock request, so once an identity is unlocked, it remains visible until explicitly locked.
Identities with an empty password are permanently unlocked, and cannot be locked.
GET /restful/keyring/identities.json
Returns a list of all currently unlocked identities, in JSON table format. The table columns are:
- sid: the SID of the identity, a string of 64 hex digits
- did: the optional DID (telephone number) of the identity, either
null or a string of five or more digits from the set
123456789#0*
- name: the optional name of the identity, either null or a non-empty string of UTF-8 characters
GET /restful/keyring/add
Creates a new identity with a random SID. If the pin parameter is supplied, then the new identity will be protected by that password, and the password will be cached by Serval DNA so that the new identity is unlocked.
GET /restful/keyring/SID/set
Sets the DID and/or name of the unlocked identity that has the given SID. The following parameters are recognised:
- did: sets the DID (phone number); must be a string of five or more
digits from the set
123456789#0*
- name: sets the name; must be non-empty
If there is no unlocked identity with the given SID, this request returns 404 Not Found.
Rhizome REST API
A Rhizome bundle consists of a single manifest and an optional payload.
TBC
Rhizome response headers
All Rhizome requests that fetch or insert a single bundle, whatever the outcome, contain the following HTTP headers in the response:
Serval-Rhizome-Result-Bundle-Status-Code: -1|0|1|2|3|4|5|6|7
Serval-Rhizome-Result-Bundle-Status-Message: <text>
Serval-Rhizome-Result-Payload-Status-Code: -1|0|1|2|3|4|5|6|7|8
Serval-Rhizome-Result-Payload-Status-Message: <text>
- the
Serval-Rhizome-Result-Bundle-Status-Code
header is the integer bundle status code - the
Serval-Rhizome-Result-Bundle-Status-Message
header is the string bundle status message - the
Serval-Rhizome-Result-Payload-Status-Code
header is the integer payload status code - the
Serval-Rhizome-Result-Payload-Status-Message
header is the string payload status message
Rhizome response bundle headers
All Rhizome requests that successfully fetch or insert a single bundle contain the following HTTP headers in the response, which convey the core manifest fields:
Serval-Rhizome-Bundle-Id: <hex64bid>
Serval-Rhizome-Bundle-Version: <integer>
Serval-Rhizome-Bundle-Filesize: <integer>
If filesize is not zero, then the following HTTP header is present:
Serval-Rhizome-Bundle-Filehash: <hex128>
If the bundle is a journal, then the following HTTP header is present:
Serval-Rhizome-Bundle-Tail: <integer>
In addition, none, some or all of the following HTTP headers may be present, to convey optional fields that are present in the bundle's manifest:
Serval-Rhizome-Bundle-Sender: <hex64sid>
Serval-Rhizome-Bundle-Recipient: <hex64sid>
Serval-Rhizome-Bundle-BK: <hex64>
Serval-Rhizome-Bundle-Crypt: 0 or 1
Serval-Rhizome-Bundle-Service: <token>
Serval-Rhizome-Bundle-Name: <quotedstring>
Serval-Rhizome-Bundle-Date: <integer>
All single-bundle operations, unless otherwise specified, attempt to deduce the
bundle's author by finding whether the manifest's signature could be re-created
using a Rhizome Secret from a currently unlocked identity in the keyring. If
the manifest sender
field is present or the author has been cached in the
Rhizome database, then only that identity is tried, otherwise every single
identity in the keyring is tested. If a signing identity is found, then the
following HTTP header is present:
Serval-Rhizome-Bundle-Author: <hex64sid>
(Note that there is no manifest “author” field, and the “sender” field is optional, in order to support anonymous bundles. This is why the author must be deduced in this fashion. Serval DNA caches the authors it discovers, to avoid redundant re-testing of all keyring identities, but cached authors are not automatically treated as verified when read from the Rhizome database, because the database can be altered by external means.)
If the bundle's secret is known, either because it was supplied in the request or was deduced from the manifest's Bundle Key (BK) field and the author's Rhizome Secret (RS), then the following HTTP header is present:
Serval-Rhizome-Bundle-Secret: <hex64>
The following HTTP headers might be present at the sole discretion of the server, but they are not guaranteed, and future upgrades of Serval DNA may remove them. They reveal internal details of the storage of the bundle:
Serval-Rhizome-Bundle-Rowid: <integer>
Serval-Rhizome-Bundle-Inserttime: <integer>
Rhizome JSON result
All Rhizome requests to fetch or insert a single bundle that do not produce a special response content for the outcome, return the following augmented JSON result object as the HTTP response content:
{
"http_status_code": ...,
"http_status_message": "...",
"rhizome_bundle_status_code": ...,
"rhizome_bundle_status_message": "...",
"rhizome_payload_status_code": ...,
"rhizome_payload_status_message": "..."
}
- the
rhizome_bundle_status_code
field is the integer bundle status code - the
rhizome_bundle_status_message
field is the string bundle status message - the
rhizome_payload_status_code
field is the integer payload status code - the
rhizome_payload_status_message
field is the string payload status message
Bundle status code
All Rhizome operations that involve fetching and/or inserting a single manifest into the Rhizome store return a bundle status code, which describes the outcome of the operation. Some codes have different meanings in the context of a fetch or an insertion, and some codes can only be produced by insertions. The bundle status code determines the HTTP response code.
code | HTTP | meaning |
---|---|---|
-1 | 500 | internal error |
0 | 201 | "new"; (fetch) bundle not found; (insert) bundle added to store |
1 | 200 | "same"; (fetch) bundle found; (insert) bundle already in store |
2 | 200 | "duplicate"; (insert only) duplicate bundle already in store |
3 | 202 | "old"; (insert only) newer version of bundle already in store |
4 | 422 | "invalid"; (insert only) manifest is invalid |
5 | 419 | "fake"; (insert only) manifest signature is invalid |
6 | 422 | "inconsistent"; (insert only) manifest filesize/filehash does not match payload |
7 | 202 | "no room"; (insert only) doesn't fit; store may contain more important bundles |
8 | 419 | "readonly"; (insert only) cannot modify manifest because secret is unknown |
9 | 423 | "busy"; Rhizome store database is currently busy (re-try) |
Bundle status message
The bundle status message is a short English text that explains the meaning of its accompanying bundle status code, to assist with diagnosis. The message for a code may differ across requests and may change when Serval DNA is upgraded, so it cannot be relied upon as a means to programmatically detect the outcome of an operation.
Payload status code
All Rhizome operations that involve fetching and/or inserting a single payload into the Rhizome store return a payload status code, which describes the outcome of the payload operation, and elaborates on the the reason for the accompanying bundle status code. Some codes have different meanings in the context of a fetch or an insertion, and some codes can only be produced by insertions. The payload status code overrides the HTTP response code derived from the bundle status code if it is numerically higher.
code | HTTP | meaning |
---|---|---|
-1 | 500 | internal error |
0 | 201 | empty payload (zero length) |
1 | 201 | (fetch) payload not found; (insert) payload added to store |
2 | 200 | (fetch) payload found; (insert) payload already in store |
3 | 422 | payload size does not match manifest filesize field |
4 | 422 | payload hash does not match manifest filehash field |
5 | 419 | payload key unknown: (fetch) cannot decrypt; (insert) cannot encrypt |
6 | 202 | (insert only) payload is too big to fit in store |
7 | 202 | (insert only) payload evicted; other payloads are ranked higher |
Payload status message
The payload status message is short English text that explains the meaning of its accompanying payload status code, to assist diagnosis. The message for a code may differ across requests and may change when Serval DNA is upgraded, so it cannot be relied upon as a means to programmatically detect the outcome of an operation.
GET /restful/rhizome/bundlelist.json
Fetches a list of all bundles currently in Serval DNA's Rhizome store, in order of descending insertion time starting with the most recently inserted. The list is returned in the body of the response in JSON table format with the following columns:
-
.token
- either null or a string value that can be used as the token in a newsince request. -
_id
- the Rhizome database row identifier; a unique integer per bundle with no guarantees of sequence or re-use after deletion. -
service
- the string value of the manifest's service field, or null if the manifest has no service field. -
id
- the Bundle ID; a string containing 64 hexadecimal digits. -
version
- the bundle version; a positive integer with a maximum value of 2^64 − 1. -
date
- the bundle publication time; an integral Unix time or null if the manifest has no date field. This field is set by the bundle's creator and could have any value, due either to inaccuracies in the system clock used to make the time stamp, or deliberate falsification. This field can have values up to 2^64 − 1, so it is immune to the Y2038 problem. -
.inserttime
- the time that the bundle was inserted into the local Rhizome store. This field is created using the local system clock, so comparisons with thedate
field cannot be relied upon as having any meaning. -
.author
- the SID of the local (unlocked) identity that created the bundle; either a string containing 64 hexadecimal digits, or null if the author cannot be deduced (the manifest lacks a BK field) or is not an unlocked identity. In the case of null, the.fromhere
field will be 0 (“not authored here”). In the case of a SID, the.fromhere
indicates whether authorship was absent, likely or certain. -
.fromhere
- an integer flag that indicates whether the bundle was authored on the local device:-
0
(“absent”) means the bundle was not authored by any identity on this device, which could be because either:- the author's identity is not unlocked in the local keyring, or
- the author's identity is in the local keyring but does not verify cryptographically as the author.
-
1
(“likely”) means the author whose SID is given in the.author
field is present in the local keyring but authorship (the manifest's signature) has not been cryptographically verified, so attempting to update this bundle may yet fail. This is the usual value for most bundles in a list because cryptographic verification is not performed while listing bundles, since it is slow and costly in CPU and battery. -
2
(“certain”) means the author whose SID is given in the.author
field is present in the local keyring and has been cryptographically verified as the true author of the bundle, so it is possible to update this bundle. This value will usually only be returned for locally-authored bundles that have recently been examined individually (eg, GET /restful/rhizome/BID.rhm), if Serval DNA has cached the result of the verification in memory.
-
-
filesize
- the number of bytes in the bundle's payload; an integer zero or positive with a maximum value of 2^64 − 1. -
filehash
- if the bundle has a non-empty payload, then the SHA-512 hash of the payload content; a string containing 128 hexadecimal digits, otherwise null if the payload is empty (filesize = 0). -
sender
- the SID of the bundle's sender; either a string containing 64 hexadecimal digits, or null if the manifest has no sender field. -
recipient
- the SID of the bundle's recipient; either a string containing 64 hexadecimal digits, or null if the manifest has no recipient field. -
name
- the string value of the manifest's name field, or null if the manifest has no name field.
GET /restful/rhizome/newsince/TOKEN/bundlelist.json
TBC
GET /restful/rhizome/BID.rhm
Fetches the manifest for the bundle whose id is BID
(64 hex digits), eg:
/restful/rhizome/1702BD647D614DB72C36BD634B6870CA31040C2EEC5069AEC0C0841D0CC671BE.rhm
If the manifest is found in the local Rhizome store, then the response will be 200 OK and:
- the bundle status code will be 1
- the payload status code, if present in the response, is not relevant, so must be ignored
- the Rhizome response bundle headers give information about the found bundle, some of which is duplicated from the manifest
- the response's Content-Type is rhizome/manifest; format=text+binarysig
- the response's Content-Length is the size, in bytes, of the manifest with its binary signature appended
- the response's content is the Rhizome manifest in text format followed by a nul (0) byte followed by the manifest's binary signature
If the manifest is not found in the local Rhizome store, then the response will be 404 Bundle not found and:
- the bundle status code will be 0
- the payload status code, if present in the response, is not relevant, so must be ignored
- the Rhizome response bundle headers are absent from the response
- the response's content is the Rhizome JSON result object
GET /restful/rhizome/BID/raw.bin
Fetches the "raw" (encrypted) payload for the bundle whose id is BID
(64 hex
digits), eg:
/restful/rhizome/1702BD647D614DB72C36BD634B6870CA31040C2EEC5069AEC0C0841D0CC671BE/raw.bin
If the manifest and the payload are both found in the local Rhizome store, then the response will be 200 OK and:
- the bundle status code will be 1
- the payload status code will be 0 if the payload has zero length, otherwise 2
- the Rhizome response bundle headers give information about the found bundle, some of which is duplicated from the manifest
- the response's Content-Type is application/octet-stream
- the response's Content-Length is the size, in bytes, of the raw payload
- the response's content is the bundle's payload exactly as stored in Rhizome;
if the payload is encrypted (the manifest's
crypt
field is 1) then the payload is not decrypted
If the manifest is not found in the local Rhizome store, then the response will be 404 Bundle not found and:
- the bundle status code will be 0
- the payload status code, if present in the response, is not relevant, so must be ignored
- the Rhizome response bundle headers are absent from the response
- the response's content is the Rhizome JSON result object
If the manifest is found in the local Rhizome store but the payload is not found, then the response will be 404 Payload not found and:
- the bundle status code will be 1
- the payload status code will be 1
- the Rhizome response bundle headers give information about the found manifest
- the response's content is the Rhizome JSON result object
GET /restful/rhizome/BID/decrypted.bin
Fetches the decrypted payload for the bundle whose id is BID
(64 hex digits),
eg:
/restful/rhizome/1702BD647D614DB72C36BD634B6870CA31040C2EEC5069AEC0C0841D0CC671BE/decrypted.bin
The responses are identical to those for GET /restful/rhizome/BID/raw.bin, with the following additional case:
If the manifest and payload are both found and the payload is encrypted
(the manifest's crypt
field is 1), but the payload secret is not known,
then:
- the bundle status code will be 0
- the payload status code will be 5
- the Rhizome response bundle headers give information about the found manifest
- the response's content is the Rhizome JSON result object
For a bundle that has a sender and a recipient, the payload secret is determined as follows:
- if the recipient's identity is found (unlocked) in the keyring, then the secret is derived from the recipient's private key; otherwise
- if the recipient's identity is not found in the keyring (locked or missing) but the sender's identity is found (unlocked) in the keyring, then the secret is derived from the sender's private key; otherwise
- neither identity is found in the keyring (both are locked or missing), so the payload secret is unknown.
For all other bundles, the payload secret is derived from the Bundle Secret.
- if the correct Bundle Secret was supplied in the request then the payload secret is derived from it directly; otherwise
- if the manifest contains a
BK
field, and the bundle's author can be deduced from the manifest's signature and the author's identity is found (unlocked) in the keyring, then the Bundle Secret is derived from the BK field and the author's Rhizome Secret, then the payload secret is derived from that; otherwise - the Bundle Secret is unknown, so the payload secret is unknown.
POST /restful/rhizome/insert
TBC
MeshMS REST API
TBC
GET /restful/meshms/RECIPIENTSID/conversationlist.json
TBC
GET /restful/meshms/SENDERSID/RECIPIENTSID/messagelist.json
TBC
GET /restful/meshms/SENDERSID/RECIPIENTSID/newsince/TOKEN/messagelist.json
TBC
POST /restful/meshms/SENDERSID/RECIPIENTSID/sendmessage
TBC
Copyright 2015 Serval Project Inc.
Available under the Creative Commons Attribution 4.0 International licence.