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
Registrantsmodel) - allows drone access to be toggled on or off (over HTTP via the
/registrantsendpoint 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 |