examples/helpers.js
function makeSNICallback() {
    var caKey = fs.readFileSync(__dirname + '/../cert/dummy.key', 'utf8'),
        caCert = fs.readFileSync(__dirname + '/../cert/dummy.crt', 'utf8'),
        serial = Math.floor(Date.now() / 1000),
        cache = {};

    var ver = process.version.match(/^v(\d+)\.(\d+)/);
    var canUseSNI = ver[1] > 1 || ver[2] >= 12; // >= 0.12.0
    console.log('Per-site certificate generation is: ' + (canUseSNI ? 'ENABLED' : 'DISABLED'));
    console.log('Feature requires SNI support (node >= v0.12), running version is: ' + ver[0]);

    if(!canUseSNI) {
        return undefined;
    }
    var createCertificateAsync = Promise.promisify(pem.createCertificate);

    return function SNICallback(servername, cb) {
        if(!cache.hasOwnProperty(servername)) {
            // Slow path, put a promise for the cert into cache. Need to increment
            // the serial or browsers will complain.
            console.log('Generating new TLS certificate for: ' + servername);
            var certOptions = {
                commonName: servername,
                serviceKey: caKey,
                serviceCertificate: caCert,
                serial: serial++,
                days: 3650
            };
            cache[servername] = createCertificateAsync(certOptions).then(function (keys) {
                return tls.createSecureContext({
                    key: keys.clientKey,
                    cert: keys.certificate,
                    ca: caCert
                }).context;
            });
        }
        cache[servername].then(function (ctx) {
            cb(null, ctx);
        }).catch(function (err) {
            console.log('Error generating TLS certificate: ', err);
            cb(err, null);
        });
    }
}
function makeSNICallback() {
    var caKey = fs.readFileSync(__dirname + '/../cert/dummy.key', 'utf8'),
        caCert = fs.readFileSync(__dirname + '/../cert/dummy.crt', 'utf8'),
        serial = Math.floor(Date.now() / 1000),
        cache = {};

    var ver = process.version.match(/^v(\d+)\.(\d+)/);
    var canUseSNI = ver[1] > 1 || ver[2] >= 12; // >= 0.12.0
    console.log('Per-site certificate generation is: ' + (canUseSNI ? 'ENABLED' : 'DISABLED'));
    console.log('Feature requires SNI support (node >= v0.12), running version is: ' + ver[0]);

    if(!canUseSNI) {
        return undefined;
    }
    var createCertificateAsync = Promise.promisify(pem.createCertificate);

    return function SNICallback(servername, cb) {
        if(!cache.hasOwnProperty(servername)) {
            // Slow path, put a promise for the cert into cache. Need to increment
            // the serial or browsers will complain.
            console.log('Generating new TLS certificate for: ' + servername);
            var certOptions = {
                commonName: servername,
                serviceKey: caKey,
                serviceCertificate: caCert,
                serial: serial++,
                days: 3650
            };
            cache[servername] = createCertificateAsync(certOptions).then(function (keys) {
                return tls.createSecureContext({
                    key: keys.clientKey,
                    cert: keys.certificate,
                    ca: caCert
                }).context;
            });
        }
        cache[servername].then(function (ctx) {
            cb(null, ctx);
        }).catch(function (err) {
            console.log('Error generating TLS certificate: ', err);
            cb(err, null);
        });
    }
}
function makeSNICallback ( ) { var caKey = fs . readFileSync ( __dirname + '/../cert/dummy.key' , 'utf8' ) , caCert = fs . readFileSync ( __dirname + '/../cert/dummy.crt' , 'utf8' ) , serial = Math . floor ( Date . now ( ) / 1000 ) , cache = { } ; var ver = process . version . match ( / ^v(\d+)\.(\d+) / ) ; var canUseSNI = ver [ 1 ] > 1 || ver [ 2 ] >= 12 ; // >= 0.12.0 console . log ( 'Per-site certificate generation is: ' + ( canUseSNI ? 'ENABLED' : 'DISABLED' ) ) ; console . log ( 'Feature requires SNI support (node >= v0.12), running version is: ' + ver [ 0 ] ) ; if ( ! canUseSNI ) { return undefined ; } var createCertificateAsync = Promise . promisify ( pem . createCertificate ) ; return function SNICallback ( servername , cb ) { if ( ! cache . hasOwnProperty ( servername ) ) { // Slow path, put a promise for the cert into cache. Need to increment // the serial or browsers will complain. console . log ( 'Generating new TLS certificate for: ' + servername ) ; var certOptions = { commonName : servername , serviceKey : caKey , serviceCertificate : caCert , serial : serial ++ , days : 3650 } ; cache [ servername ] = createCertificateAsync ( certOptions ) . then ( function ( keys ) { return tls . createSecureContext ( { key : keys . clientKey , cert : keys . certificate , ca : caCert } ) . context ; } ) ; } cache [ servername ] . then ( function ( ctx ) { cb ( null , ctx ) ; } ) . catch ( function ( err ) { console . log ( 'Error generating TLS certificate: ' , err ) ; cb ( err , null ) ; } ) ; } }
Return an SNICallback to dynamically generate certificates signed by a CA.

This allows you to install 'dummy.crt' as a root cert once, and then access all TLS sites
without any further warnings from your browser.

NOTE: This only works in node 0.12; in older versions it is not possible to generate certs
asynchronously, because there was no callback argument for SNICallback.
NOTE: The OpenSSL command must be in your $PATH for the 'pem' library to work.
NOTE: No cache eviction is implemented, this will eventually run out of memory if
implemented "as is" in a long-running process.
Return an SNICallback to dynamically generate certificates signed by a CA .