-
Notifications
You must be signed in to change notification settings - Fork 0
Code Examples
The following code shows how to import the Bali Digital Notary™ package and how to initialize the notary API.
const debug = 1; // debug level: [0..3]
const bali = require('bali-component-framework').api(debug);
const account = bali.tag(); // new account
const directory = 'config/'; // for testing purposes only
const notary = require('bali-digital-notary').test(account, directory, debug);
The debug
level can be set to one of the following values:
- 0 - no logging to
console.log
orconsole.error
will occur - 1 - exceptions will be logged to
console.error
- 2 - additional validation of arguments passed into the API will occur
- 3 - detailed information will be logged to
console.log
Note that the above example uses a test version of the digital notary. The actual statements required depends on whether the code resides in a client application or if it is part of a secure service.
When implementing a client application that uses a BLE enabled hardware security module (HSM) use the following declarations:
const hsm = require('bali-hsm-proxy').proxy(directory, debug); // hardware security module proxy
const notary = require('bali-digital-notary').notary(hsm, account, directory, debug);
When implementing a secure remote service use something like the following declarations:
const notary = require('bali-digital-notary').service(debug);
The following code examples show how to generate a new notary key and its associated public certificate.
var certificate = await notary.generateKey();
console.log('public certificate: ' + certificate);
This code (and all code in these examples) must be run within an asynchronous function since it makes calls on the notary API which is also an asynchronous API. The notary key is kept private within the digital notary object whereas the public certificate is returned as a document.
The resulting public certificate document is displayed below using Bali Document Notation™.
public certificate: [
$publicKey: '09AJQ7NJSKSKBJMGT3K21KZTZZF2C58B42FP72BSBZQVZ56P9HV0'
$algorithms: [
$digest: "SHA512"
$signature: "ED25519"
]
](
$type: /bali/notary/Certificate/v1
$tag: #3Q63XLP6N0PHDMDC4YNTTJX4GS203CN7
$version: v1
$permissions: /bali/permissions/public/v1
$previous: none
)
All documents including this certificate are parameterized by standard attributes that are
required during the notarization process. These include the $type
of the document, the unique
$tag
and $version
string that identify the document, a named reference to the $permissions
that define who is allowed to access the document, and finally, a document citation to the
$previous
version of the document if one exists (in this case it doesn't since this is the first
version of the notary key).
The next code examples show how to notarize the public certificate using the new notary key to create a notarized contract.
certificate = await notary.notarizeDocument(certificate);
console.log('notarized certificate: ' + certificate);
The resulting notarized public certificate is displayed below.
notarized certificate: [
$protocol: v2
$timestamp: <2020-06-03T20:39:54.839>
$account: #XR3JC5SNH03M6R1K0XMKY3CDXF40CY5Z
$document: [
$publicKey: '09AJQ7NJSKSKBJMGT3K21KZTZZF2C58B42FP72BSBZQVZ56P9HV0'
$algorithms: [
$digest: "SHA512"
$signature: "ED25519"
]
](
$type: /bali/notary/Certificate/v1
$tag: #3Q63XLP6N0PHDMDC4YNTTJX4GS203CN7
$version: v1
$permissions: /bali/permissions/public/v1
$previous: none
)
$certificate: none
$signature: '
QRNDQ8VL46FCKGMYV2GLQMBHQD0RFMMN1XTV9LB3V17RX7TGAPVNKJ6H2D6T
D28MT0DMRJHBJ7YK345L2G0KYT6L8YRJKMGJX76F41R
'
]($type: /bali/notary/Contract/v1)
Notice that the document containing the public certificate has been embedded within a contract
that contains additional information about the $account
that owns the certificate, and a digital
$signature
that can be used to verify the authenticity of the certificate using the embedded
$publicKey
.
A private notary key must be activated using its associated notarized public certificate before it can be used to notarize additional documents. The next example shows how to do this.
var citation = await notary.activateKey(certificate);
console.log('certificate citation: ' + citation);
A document citation referencing the public certificate is returned. It is displayed below.
certificate citation: [
$protocol: v2
$tag: #3Q63XLP6N0PHDMDC4YNTTJX4GS203CN7
$version: v1
$digest: '
88WYW89LHWXMZ2P5B99JJKGXQ8RZTH59TFRRZCYYS7HBVNTX1X1DBY7L147Q
Q7A526SGWDY614WQ5KPPMMVPW5QZ70BL0NXLN96ZS9H
'
]($type: /bali/notary/Citation/v1)
Each document citation contains attributes describing the version of the security $protocol
used
to create the citation, the unique $tag
and $version
string for the cited document, and a
digital $digest
(or fingerprint) of the cited document that can be used to verify that the
document has not been modified or corrupted since it was created. If even a single character in
the cited document is changed, the digital digest in the document citation will be completely
different.
The next code example shows how to create and notarize an example transaction document. First, we create a new document specifying its type and using a JavaScript object to define the attributes that are included in the transaction.
const transaction = bali.instance('/starbucks/types/Transaction/v2.3', {
$timestamp: bali.moment(), // now
$consumer: 'Derk Norton',
$merchant: '<https://www.starbucks.com/>',
$amount: '4.95($currency: $USD)'
});
console.log('transaction: ' + transaction);
The result is the transaction document.
$transaction: [
$timestamp: <2020-06-03T20:39:54.906>
$consumer: "Derk Norton"
$merchant: <https://www.starbucks.com/>
$amount: 4.95($currency: $USD)
](
$type: /starbucks/types/Transaction/v2.3
$tag: #DF7V9NX82DNYFZ1FCGRSWSFDDKW6Y7R9
$version: v1
$permissions: /bali/permissions/Public/v1
$previous: none
)
Again, the transaction document is parameterized by the standard attributes that are required by all documents that are to be notarized.
Once we have defined a document containing the transaction information, we can notarize it as follows.
const contract = await notary.notarizeDocument(transaction);
console.log('contract: ' + contract);
The result is a notarized contract containing the transaction document.
contract: [
$protocol: v2
$timestamp: <2020-06-03T20:39:54.912>
$account: #XR3JC5SNH03M6R1K0XMKY3CDXF40CY5Z
$document: [
$timestamp: <2020-06-03T20:39:54.906>
$consumer: "Derk Norton"
$merchant: <https://www.starbucks.com/>
$amount: 4.95($currency: $USD)
](
$type: /starbucks/types/Transaction/v2.3
$tag: #DF7V9NX82DNYFZ1FCGRSWSFDDKW6Y7R9
$version: v1
$permissions: /bali/permissions/Public/v1
$previous: none
)
$certificate: [
$protocol: v2
$tag: #3Q63XLP6N0PHDMDC4YNTTJX4GS203CN7
$version: v1
$digest: '
88WYW89LHWXMZ2P5B99JJKGXQ8RZTH59TFRRZCYYS7HBVNTX1X1DBY7L147Q
Q7A526SGWDY614WQ5KPPMMVPW5QZ70BL0NXLN96ZS9H
'
]($type: /bali/notary/Citation/v1)
$signature: '
24GXP6Y6P1H0Y3P4LN2SXH0F9NR0JAVR4MQH9247X2FMXMJN2TH83XRZ0795
S0T2S3AWVLFCV7M3R7K8CTXC580R77KD5ANR7GKDR2H
'
]($type: /bali/notary/Contract/v1)
Notice that the structure of this contract is the same as the notarized public certificate.
However, in this contract, the $certificate
attribute contains a document citation to the public
certificate that can be used to validate the digital $signature
on this document. In fact,
it cites the public certificate for our private notary key since it was our notary key
that was used to notarize this transaction. Look closely and you will see that it matches
the certificate citation displayed earlier.
In the notarized public certificate, the $certificate
attribute was set to none
since it is
not possible to create a document citation to a document before that document exists and in the
case of the notarized public certificate, that document would be attempting to cite itself.
Now let's look at how one goes about validating a notarized contract.
const isValid = await notary.validDocument(contract, certificate);
console.log('is valid: ' + isValid);
It's very easy, we just pass to the notary the notarized contract for the transaction, along with the notarized public certificate cited within the transaction document. The digital notary knows how to use the public key within the public certificate to validate the digital signature within the transaction contract. Because the public certificate is the same one that was generated and notarized by our digital notary, the signature should be valid.
is valid: true
And it is.
Just as we have a document citation to our notarized public certificate, we can create a document citation to our newly notarized transaction document.
citation = await notary.citeDocument(transaction);
console.log('transaction citation: ' + citation);
Note that we pass in the transaction document, not the notarized contract.
The resulting document citation for the transaction is displayed below.
transaction citation: [
$protocol: v2
$tag: #DF7V9NX82DNYFZ1FCGRSWSFDDKW6Y7R9
$version: v1
$digest: '
MLQSXVJKJRKZ3VK80WMLQA78YD7XR8P74SQNHGR0JJC2XTBD1YFMWQABL8M3
MZ420WPTXCNS06CKLZFX2WA1ZZYT1M72536NS0PYADR
'
]($type: /bali/notary/Citation/v1)
It has the same attributes as any other document citation. The values of the identifying attributes and the digital digest are different from the values for the certificate citation of course since this one is citing a different document.
Similar to using a notarized public certificate to validate the digital signature in a notarized contract, we can use the digital digest in a document citation to verify that the cited document has not been modified or corrupted in any way.
const citationMatches = await notary.citationMatches(citation, transaction);
console.log('citation matches: ' + citationMatches);
In this case, the document citation and cited document are passed to the digital notary to confirm that the citation matches.
citation matches: true
Which of course it does.