UNPKG

node-kms

Version:

A client implementation of the Key Management Service (KMS) for JavaScript -- for both node.js and browser.

261 lines (186 loc) 7.03 kB
# node-kms # A JavaScript implementation of Key Management Service (KMS) for current web browsers and node.js-based servers. The KMS API is described in [[draft-abiggs-saag-key-management-service-02](https://tools.ietf.org/html/draft-abiggs-saag-key-management-service-02)]. <!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> <a name='toc'> - [Installing](#installing) - [Basics](#basics) - [KeyObjects](#keyobjects) - [Creating](#creating) - [Importing/Exporting](#importingexporting) - [Obtaining a `node-jose` Key](#obtaining-a-node-jose-key) - [Contexts](#contexts) - [Creating and Initializing](#creating-and-initializing) - [Generating an Ephemeral EC Key](#generating-an-ephemeral-ec-key) - [Deriving an Ephemeral Shared Key](#deriving-an-ephemeral-shared-key) - [Requests](#requests) - [Creating](#creating-1) - [Wrapping](#wrapping) - [Responses](#responses) - [Creating](#creating-2) - [Unwrapping](#unwrapping) <!-- END doctoc generated TOC please keep comment here to allow auto update --> ## Installing ## To install the latest from [NPM](https://npmjs.com/): ``` npm install node-kms ``` Or to install a specific release: ``` npm install node-kms@0.3.0 ``` Alternatively, the latest unpublished code can be installed directly from the repository: ``` npm install git+ssh://git@github.com:cisco/node-kms.git ``` ## Basics ## Require the library as normal: ``` var KMS = require('node-kms'); ``` This library uses [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) for many operations. This library supports [Browserify](http://browserify.org/). To use in a web browser, `require('node-kms')` and bundle with the rest of your app. ## KeyObjects ## A KMS KeyObject wraps a JSON Web Key (JWK) to provide more semantics: a URI to locate it; the creating user and client; the date/time of when a key is created, bound, and/or expires; and the owning resource (once bound). ### Creating ### To create an empty KeyObject: ``` var keyobj = new KMS.KeyObject(); ``` None of the KMS.KeyObject properties are set. Alternatively, to create a KeyObject from a JSON or POJO representation: ``` // {input} is one of: // * a JSON object (where date/times are RFC3339-encoded Strings) // * a POJO (where date/times are Date objects) var keyobj = new.KeyObject(input); ``` ### Importing/Exporting ### **NOTE**: The JSON representation includes all properties for a KeyObject, including the full JWK (if present). This can expose secret key material if not carefully handled; do not save to durable storage without protecting it (e.g., encrypting to a JWE). To import a KeyObject from a JSON object: ``` // {input} is one of: // * a JSON object (where date/times are RFC3339-encoded Strings) // * a POJO (where date/times are Date objects) // * an existing KeyObject instance keyobj = KMS.fromObject(input); ``` In the case where `input` is already a KeyObject, it is returned as-is. To export a KeyObject to a JSON object: ``` var output = keyobj.toJSON(); ``` ### Obtaining a `node-jose` Key ### To convert the `jwk` property of a KeyObject to a `node-jose` Key (to use for encryption or signatures): ``` var jwk; keyobj.asKey(). then(function(result) { // {result} is a jose.JWK.Key jwk = result; }); ``` If `jwk` is not set on the KeyObject, the returned Promise is rejected. ## Contexts ## The KMS.Context holds onto information necessary to wrap Requests and unwrap Responses. ### Creating and Initializing ### To create an empty Context: ``` var kmsCtx = new KMS.Context(); ``` None of the Context properties are set. To finish initializing the Context, set the `clientInfo` and `serverInfo` properties: ``` // {clientId} is a String containing an identifier for the client or session // {userId} is a String containing the user's identifier // {oauth2token} is a String containing an OAuth2 Bearer token kmsCtx.clientInfo = { clientId: clientId, credential: { userId: userId, bearer: oauth2token } }; // {serverPublicKey} is a JWK JSON object kmsCtx.serverInfo = { key: serverPublicKey }; ``` ### Generating an Ephemeral EC Key ### To create a KeyObject representing the local ECDH key: ``` kmsCtx.createECDHKey(). then(function(result) { // {result} is a KMS.KeyObject wrapping a "EC" JWK kmsCtx.ephemeralKey = result; }) ``` ### Deriving an Ephemeral Shared Key ### To derive an ephemeral shared key -- such as the result of the ECDHE handshake: ``` // {remoteECDH} is a KMS.KeyObject wrapping a "EC" JWK kmsCrx.deriveEphemeralKey(remoteECDH). then(function(result) { // {result} is a KMS.KeyObject wrapping a "oct" JWK kmsCtx.ephemeralKey = result; }); ``` ## Requests ## The KMS.Request embodies a single request from a client to the KMS. A Request instance has the following (read/write) properties: * `body` -- the full (plaintext) JSON to be sent to the KMS * `requestId` -- the unique id for this request * `uri` -- the URI of the request (e.g., "/ecdhe/", "/resources", etc.) * `method` -- the method (verb) for the request (e.g., "create", "retrieve", etc.) * `wrapped` -- the wrapped (encrypted) `body` When a new `body` is set, the previous `requestId`, `method`, and `uri` are remembered, overwriting any new values that might have been in the provided JSON. ### Creating ### To create an empty request: ``` var request = new KMS.Request(); ``` To create a request starting with a constructed body: ``` // {input} is a JSON object representing the request var request = new KMS.Request(input); ``` ### Wrapping ### To wrap (encrypt) the Request into a JWE for transmitting to a KMS server, using an ephemeral shared key: ``` var output; request.wrap(kmsCtx). then(function(result) { // {result} is a String of the JWE in the Compact Serialization // request.wrapped is also set to {result} output = result; }); ``` ## Responses ## The KMS.Response embodies a single response to a client from the KMS. A Response instance has the following (read/write) properties: * `body` -- the full (plaintext) JSON received from the KMS * `requestId` -- the id for the corresponding request * `status` -- the status code of the response * `reason` -- the string reason (if any) * `wrapped` -- the protected (encrypted or signed) `body` ### Creating ### To create an empty KMS.Response: ``` var response = new KMS.Response(); ``` To creat a KMS.Response with a received wrapped body: ``` // {input} is a String of the JWE (or JWS) using the Compact Serialization var response = new KMS.Response(input); ``` ### Unwrapping ### To unwrap a response into the plaintext body: ``` var input; response.unwrap(kmsCtx). then(function(result) { // {result} is the plaintext JSON object // response.body is also set to {result} input = result; }); ```