Server that acts as a Drone gate using the Open Registry SDK
This example Express app showcases the ease of use with which the Open-Registry-SDK can be combined into existing applications to provide direct blockchain integration, allowing a developer to look up Things which have been previously registered through Ethereum and verify their identity. This way of conducting identity validation has a wide range of potential applications but in this app we use it to demonstrate machine access control for drones tagged with a BLE chip registered through the Open-Registry-SDK under a specific owner.
An increasingly automated world provides myriad exciting opportunities but not without new, unique challenges. Without human delivery drivers how does one know that a trusted party is trying to gain access to their home? This server supports a "smart gate" which can read a BLE tag (attached to a delivery drone), determine the identity from the chip and request the server to conduct the identity validation steps outlined below. If the drone passes validation the gate would open, allowing the drone to deliver it's payload. If not valid or the owner was not granted access, the gate would remain closed.
In addition to Open-Registry-SDK usage the server provides a number of features illustrative of real-world use:
- stores the list of known drone owners (via the
Registrants
model) - allows drone access to be toggled on or off (over HTTP via the
/registrants
endpoint or graphically on the settings page delivered through/setttings
)
This application primarily uses two features of the Open-Registry-SDK in two main endpoints:requestChallenge
and verifyChallenge
.
A client supplies an identifying URN for an already registered Thing and the server will look up the object's public key by using the Open-Registry-SDK. If a public key exists and it supports a common challenge protocol with the server, then the server generates a challenge and sends it back to the client.
The client must then sign the challenge and send it back to the verifyChallenge
endpoint. If the client does so, the server will again use the Open-Registry-SDK to verify that the signature that was returned is valid and responds to the client with the outcome of the test.
-
- hasRegistrant(address) ⇒
Boolean
- checkAccess(address) ⇒
Boolean
- setAccess(address, access)
- getAll() ⇒
Object
- hasRegistrant(address) ⇒
-
- add(challenge)
- check(challenge) ⇒
boolean
-
- protocols :
Object
- generateChallenge(protocol) ⇒
String
- parseURN(urn) ⇒
Object
- signatureToAns1(signature) ⇒
String
- validateFields(requestSchema) ⇒
function
- makeErrorCatcher(req, res) ⇒
function
- inner
- ~hash(byteBuffer, algorithm, outEncoding) ⇒
String
- ~PKCS1Pad(hexDigest) ⇒
String
- ~hash(byteBuffer, algorithm, outEncoding) ⇒
- protocols :
Request All Registrants Info (address, name, access)
GET /registrants
Success-Response:
HTTP/1.1 200 OK
{
"0xdc3a9db694bcdd55ebae4a89b22ac6d12b3f0c24": {
name: "Chronicled Community",
access: true
},
"0x0000000000000000000000000000000000000001": {
name: "Amazon",
access: false
},
"0x0000000000000000000000000000000000000002": {
name: "Dominos",
access: false
}
}
Modify access permissions for registrant
POST /registrants
Name | Type | Description |
---|---|---|
access | Boolean | access boolean for registrant |
registrantAddress | String | registrantAddress |
Success-Response:
HTTP/1.1 200 OK
{
"modified" : 1
}
Error-Response:
HTTP/1.1 404 Not Found
{
"reason": "Registrant does not exist"
}
Request a challenge based on a Thing's identity, to verify return it to the [verifyChallenge](#api_verifyChallenge) route within a 5 minute time window.
POST /requestChallenge
Name | Type | Description |
---|---|---|
identity | String | The identifying URN for the thing that will be challenged |
Success-Response:
HTTP/1.1 200 OK
{
"challenge" : "8b2c583afdcea8f41e59a330181a72a8058490bc1c9cbf3455d632de3db0b1b1"
}
Error-Response:
HTTP/1.1 400 Not Found
{
"reason": "Thing\'s public key protocol is not supported"
}
verify a challenge that has been signed by a Thing's public key
POST /verifyChallenge
Name | Type | Description |
---|---|---|
identity | String | The identifying URN for the thing that has been challenged |
challenge | String | The challenge that was sent to the thing |
signature | String | The string that resulted when the Thing signed the challenge |
Success-Response:
HTTP/1.1 200 OK
{
"verified" : true
}
Error-Response:
HTTP/1.1 400 Not Found
{
"reason": "Thing does not have a supported public key"
}
Registrants module
- models/registrants
- hasRegistrant(address) ⇒
Boolean
- checkAccess(address) ⇒
Boolean
- setAccess(address, access)
- getAll() ⇒
Object
- hasRegistrant(address) ⇒
check to see if the registrant at the given address is present
Returns: Boolean
- hasRegistrant
Param | Type | Description |
---|---|---|
address | String |
address of Registrant |
checks to see if a registrat at the given address has access
Returns: Boolean
- hasAccess
Param | Type | Description |
---|---|---|
address | String |
address of Registrant |
sets the access value for a given registrant at an address to a boolean
Param | Type | Description |
---|---|---|
address | String |
address of Registrant |
access | Boolean |
access permission for Registrant |
return collection of registrantAddresses and registrant objects
Challenges module
- models/challenges
- add(challenge)
- check(challenge) ⇒
boolean
stores added challenge for five minutes in Set
Param | Type | Description |
---|---|---|
challenge | string |
challenge to be added |
checks set to see if challenge has been added to it
Returns: boolean
- isPresent
Param | Type | Description |
---|---|---|
challenge | string |
challenge to be checked |
Utils module
- utils
- protocols :
Object
- generateChallenge(protocol) ⇒
String
- parseURN(urn) ⇒
Object
- signatureToAns1(signature) ⇒
String
- validateFields(requestSchema) ⇒
function
- makeErrorCatcher(req, res) ⇒
function
- inner
- ~hash(byteBuffer, algorithm, outEncoding) ⇒
String
- ~PKCS1Pad(hexDigest) ⇒
String
- ~hash(byteBuffer, algorithm, outEncoding) ⇒
- protocols :
collection of public key protocols recognized by the server
generates a random challenge based on the protocol given
Returns: String
- challenge
Param | Type | Description |
---|---|---|
protocol | String |
any supported protocol |
takes a formatted URN and returns an object with fields 'valid' (Bool), 'protocol' (String), and 'value' (String)
Returns: Object
- parsedUrn
Param | Type | Description |
---|---|---|
urn | String |
a urn of the format protocol: |
takes a given challenge (hex string) and converts it to Ans1 format
Returns: String
- Ans1
Param | Type | Description |
---|---|---|
signature | String |
hex string |
takes a request schema object and returns a piece of express middleware that uses 'express-validator' to ensure the fields in the request body are valid
Returns: function
- validateFieldsMiddleware
Param | Type | Description |
---|---|---|
requestSchema | Object |
An request schema (see 'express-validator') |
takes a request and response object and returns a function that acts as an error catcher in a promise chain
Returns: function
- errorHandler
Param | Type | Description |
---|---|---|
req | Express.Request |
An Express Request Object |
res | Express.Response |
An Express Response Object |
Returns a hash string based on the original byte buffer, algorith, and outEncoding
Returns: String
- hash
Param | Type | Description |
---|---|---|
byteBuffer | Node.Byte |
byte buffer used for hashing |
algorithm | String |
algorithm used to hash (ex. 'sha256') |
outEncoding | String |
type of output (ex. 'hex') |
adds padding to a random hex string to output a PKCS #1 padded SHA1 sum (256-byte hex value)
Returns: String
- sha1
Param | Type | Description |
---|---|---|
hexDigest | String |
hex string that will be padded |