tart-transport-tls

TLS transport implementation for tart

tart-transport-tls

Stability: 1 - Experimental

TLS transport implementation for Tiny Actor Run-Time in JavaScript.

@dalnefre, @tristanls

An implementation of a TLS transport for Tiny Actor Run-Time in JavaScript.

To run the below example run:

npm run readme
"use strict";
 
var fs = require('fs');
var path = require('path');
var tart = require('tart');
var tls = require('tls');
var transport = require('../index.js');
 
var sponsor = tart.minimal();
 
var send = sponsor(transport.sendBeh);
var sendWithOptions = sponsor(transport.sendWithOptions({
    key: fs.readFileSync(path.normalize(path.join(__dirname, 'readme/client-key.pem'))),
    cert: fs.readFileSync(path.normalize(path.join(__dirname, 'readme/client-cert.pem'))),
    rejectUnauthorized: true,
    secureProtocol: "TLSv1_method",
    ca: [fs.readFileSync(path.normalize(path.join(__dirname, 'readme/server-cert.pem')))]
}));
 
var receivedMessageCount = 0;
var receptionist = sponsor(function (message) {
    console.log('received message:', message);
    receivedMessageCount++;
    if (receivedMessageCount >= 2) {
        close(); // close listening server 
    }
});
 
var serverCapabilities = transport.server(receptionist);
var close = sponsor(serverCapabilities.closeBeh);
var listen = sponsor(serverCapabilities.listenBeh);
 
var fail = sponsor(function (error) {
    console.dir(error);
});
 
var listenAck = sponsor(function listenAckBeh(message) {
    console.log('transport listening on tcp://' + message.host + ':' + message.port);
    sendWithOptions({
        address: 'tcp://localhost:7847/#t5YM5nxnJ/xkPTo3gtHEyLdwMRFIwyJOv5kvcFs+FoMGdyoDNgSLolq0',
        content: '{"some":{"json":"content"},"foo":true}',
        fail: fail,
        okfunction () {
            console.log('foo sent');
        }
    });
    send({
        address: 'tcp://localhost:7847/#I0InGCVn0ApX0YBnF5+JFMheKOajHkaTrNthYRI2hOj4GrM5IaWO1Cv0',
        content: '{"some":{"json":"content"},"bar":true}',
 
        key: fs.readFileSync(path.normalize(path.join(__dirname, 'readme/client-key.pem'))),
        cert: fs.readFileSync(path.normalize(path.join(__dirname, 'readme/client-cert.pem'))),
        rejectUnauthorized: true,
        secureProtocol: "TLSv1_method",
        ca: [fs.readFileSync(path.normalize(path.join(__dirname, 'readme/server-cert.pem')))],
 
        fail: fail,
        okfunction () {
            console.log('bar sent');
        }
    });    
});
 
listen({
    host: 'localhost', 
    port: 7847, 
 
    // TLS options 
 
    key: fs.readFileSync(path.normalize(path.join(__dirname, 'readme/server-key.pem'))),
    cert: fs.readFileSync(path.normalize(path.join(__dirname, 'readme/server-cert.pem'))),
    rejectUnauthorized: true,
    secureProtocol: "TLSv1_method",
    // This is necessary only if using the client certificate authentication. 
    requestCert: true,
    // This is necessary only if the client uses the self-signed certificate. 
    ca: [fs.readFileSync(path.normalize(path.join(__dirname, 'readme/client-cert.pem')))],
 
    // customers 
 
    ok: listenAck,
    fail: fail
});
npm test

Public API

Actor behavior that will attempt to send messages over TLS.

Message format:

  • address: String TCP address in URI format. Scheme, host, and port are required. Framgment is optional but usually necessary. For example: tcp://localhost:7847/#t5YM5nxnJ/xkPTo....
  • content: String JSON content to be sent.
  • fail: Actor function (error) {} (Default: undefined) Optional actor to report error (if any).
  • ok: Actor function () {} (Default: undefined) Optional actor to report successful send to the destination.

TLS Options:

var send = sponsor(transport.sendBeh);
send({
    address: 'tcp://localhost:7847/#ZkiLrAwGX7N1eeOXXMAeoVp7vsYJKeISjfT5fESfkRiZOIpkPx1bAS8y', 
    content: '{"some":{"json":"content"}}',
    key: fs.readFileSync('client-key.pem'),
    cert: fs.readFileSync('client-cert.pem'),
    rejectUnauthorized: true,
    secureProtocol: "TLSv1_method",
    ca: [fs.readFileSync('server-cert.pem')]
});

Creates an actor behavior identical to transport.sendBeh, except that TLS Options portion for every send will be automatically populated from tlsOptions provided.

var sendWithOptions = sponsor(transport.sendWithOptions({
    key: fs.readFileSync('client-key.pem'),
    cert: fs.readFileSync('client-cert.pem'),
    rejectUnauthorized: true,
    secureProtocol: "TLSv1_method",
    ca: [fs.readFileSync('server-cert.pem')]    
}));
sendWithOptions = send({
    address: 'tcp://localhost:7847/#ZkiLrAwGX7N1eeOXXMAeoVp7vsYJKeISjfT5fESfkRiZOIpkPx1bAS8y', 
    content: '{"some":{"json":"content"}}'    
});
  • receptionist: Actor function (message) {} Actor to forward traffic received by this server in {address: <URI>, contents: <json>} format.
  • Return: Object An object containing behaviors for listen and close capabilities.

Creates an entangled pair of capabilities that will control a single TLS server.

Actor behavior that will close a listening server.

Message is an ack Actor function () {}, an actor that will be sent an empty message once the server closes.

var serverCapabilities = transport.server(receptionist);
var close = sponsor(serverCapabilities.closeBeh);
close(sponsor(function ack() {
    console.log('acked close'); 
});

Actor behavior that will create a new listening TLS server.

Message format:

  • host: String TLS host to listen on.
  • port: Number TLS port to listen on.
  • ok: Actor function (message) {} Optional actor to receive acknowledgment once the server is listening.
  • fail: Actor function (error) {} Optional actor to receive any errors when starting the TLS transport.

TLS Options:

var serverCapabilities = transport.server(receptionist);
var listen = sponsor(serverCapabilities.listenBeh);
listen({
    host: 'localhost',
    port: 7847,
 
    key: fs.readFileSync('server-key.pem'),
    cert: fs.readFileSync('server-cert.pem'),
    rejectUnauthorized: true,
    secureProtocol: "TLSv1_method",
    // This is necessary only if using the client certificate authentication. 
    requestCert: true,
    // This is necessary only if the client uses the self-signed certificate. 
    ca: [fs.readFileSync('client-cert.pem')],
 
    ok: sponsor(function listenAckBeh(message) {
        console.log('transport listening on tcp://' + message.host + ':' + message.port);
    }),
    fail: sponsor(function failBeh(message) {
        console.error(message);
    })
});