1. Make your backend service OCN-ready

In order for your backend service to be OCN-ready, it must:

  1. Implement the OCPI 2.2 API, the shared communication protocol for the OCN

  2. Implement the OCN Notary in order to sign and verify OCN messages

Access the full OCN technical documentation here.

1. Implement the OCPI 2.2 API

The OCPI protocol is the common communication protocol for the OCN. Each OCN node implements the OCPI 2.2 API (see, for example, the Kotlin implementation of the OCPI 2.2 API for the OCN node here), and every backend-service that communicates with an OCN node must also implement the OCPI 2.2 API.

Using the OCN Bridge

Using the OCN Bridge is an alternative to implementing the full OCPI 2.2 API in your backend service. The OCN Bridge provides an OCPI interface using pluggable backend APIs. You can instantiate an instance of the Bridge, which will proxy your requests and responses with other OCN parties.

In addition to the OCPI 2.2 implementation, the OCN Bridge also provides services to interact with an OCN node (i.e. register with a node, get connection status to a node) and the OCN Registry.

Examples:

public async getNodeInfo(nodeURL: string): Promise<INodeInfo> {
    const res = await fetch(new URL("/ocn/registry/node-info", nodeURL).href)
    return res.json()
}

You can view documentation on how to to implement the OCN Bridge here.

The OCN Bridge simplifies the implementation of the OCPI interface, but it is not required to use in your backend service. Note that the OCN Bridge can only be implemented in JavaScript environments.

2. Implement the OCN Notary

The OCN Notary is a package that enables the verification of OCN signature, which are used to sign and verify OCN requests using public/private key-pairs.

OCN Signatures

Taking a cue from the blockchain community, we have developed a message signing and verifying system for the Open Charging Network.

Under the hood it uses the Elliptic Curve Digital Signature Algorithm (ECDSA) as implemented by Ethereum. The signature itself holds a JSON Object containing all the necessary data for the recipient to verify the data it is receiving.

Not only do requests need to be signed, but responses too.

Signing Requests

For requests, the signature is appended to the outgoing OCPI 2.2 headers:

Authorization: Token 0ea32164-515f-418b-8bef-39f3817ea090

X-Request-ID: 71d62c5b-5017-493e-be00-3f5ad4e34fff

X-Correlation-ID: 9881b6f7-63aa-40d2-b9c2-d6daa69c11fb

OCPI-From-Country-Code: CH OCPI-From-Party-Id:

MSP OCPI-To-Country-Code: CH OCPI-To-Party-Id:

CPO OCN-Signature: eyJmaWVsZHMiOlsiJFsnaGVhZGVycyddWyd4L (truncated)...

Signing Responses

For responses, the signature is appended to the outgoing OCPI 2.2 JSON response body:

{

"status_code": 1000,

"data": { "result": "ACCEPTED" },

"timestamp": "2020-03-02T12:48:33.005Z",

"ocn_signature": "eyJmaWVsZHMiOlsiJFsnaGVhZGVycyddWyd4L (truncated)..."

}

The idea is that the recipient can use this signature to verify that the message has been signed correctly and has not been modified by an unauthorized party.

What do we mean by unauthorized?

For the OCN to function properly, there are cases where an intermediary (i.e. an OCN node) needs to modify the request/response. Such an example would be the response_url in the JSON body of requests made to the receiver interface of the OCPI commands module. As the recipient does not have access to the response_url defined by the sender, the OCN Node must modify the value. In an OCN signature, this is known as “stashing”. The signature object contains the history of rewrites, with the previous signature being stashed by the party modifying the data. When a recipient then verifies a signature, the rewrites are also verified.

Let’s take a closer look at what the signature actually is:

interface Signature {

val fields: Array val hash: String

val rsv: String

val signatory: String

val rewrites: Array

}

interface Rewrite {

val rewrittenFields: Map<String, Any?>

val hash: String

val rsv: String

val signatory: String

}

The signature itself contains everything needed to verify the most-recent version of the sent data, i.e. by the sender or OCN node depending on whether any values needed to be modified. Provided is a list of jsonpath fields which can be used to recreate the message as signed by the sender, with the original order of values preserved. The values are hashed using keccak-256, as implemented by Ethereum. The resultant hash is actually the message which is signed. The RSV is the signature, produced by ECDSA using an Ethereum wallet’s private key. The signatory refers to the address of the wallet that was used to sign the message.

The list of rewrites contains an object containing the previous hash, rsv and signatory. It also allows the original message to be recreated by storing the fields which have been rewritten. For example, a commands receiver request might have the following rewrite by the OCN node:

1Rewrite( 2 rewrittenFields = mapOf("$['body']['response_url']" to "https://emsp.net/ocpi/2.2/sender/commands/START_SESSION/acfbb8d2-bd49-4837-97e2-d2c38f6bae55"), 3 hash = "0x1ce93f156bc5b3a5c26c5f2499db7bfa2b38c37fd32616fc6487175b86f41eb2", 4 rsv = "0x16e8b9c4e44f4646235fca85a594b5a31057930676d338d111ae985a4f0d9d4214705a0a2ae18c4dfd014581e96eb4625137a937853d4b2d17a0f3a22750f6ac1c", 5 signatory = "0x25e4fca0a0e5107d06d71ed78f687827208d5ff9" 6)

The Signatory

Of course, the signatory of both the OCN Signature and its rewrites should be independently validated. The verification of the signature only tells us that the message was signed by the signatory provided. The signatory itself could be any Ethereum wallet address. The address of both the original sender and their OCN node can be found in the OCN Registry[link to repo].

Now that we know how the signature functions, how do we actually use it? Enter the OCN Notary.

Implementing the OCN Notary

The OCN Notary implements the above Signature and Rewrite interfaces. It can deserialize an incoming OCN Signature and verify its contents. It can be used to sign an OCPI request, and likewise to stash/rewrite values in a request.

Currently the Notary library is available as an NPM package and as a Maven package for languages targeting the JVM. See the OCN Notary repository to find more information for each package.

OCN Network v1.0 Open API 3.0 Specs

You can find the API specification document in the OCN Node repository, here: Open API 3.0 specs

Using this specification, it is possible to generate client code and test implementations. For more information, see https://swagger.io/docs/specification/about/.

Note that this document was generated using unmodified source code in the master branch. As such, certain features of the specification format might be missing, such as examples for HTTP requests and responses.

Last updated