Node.js TLS connections, requests, servers, etc.

The first thing you’ll need to be aware of is that node.js is a fast moving project. This tutorial was written for node.js 0.4.2 but may work or be useful for later versions of node. Secondly, my code examples are in CoffeeScript which compiles to Javascript but has Python/Ruby-like syntax. I find the code to be cleaner and faster to write.

Next up are some administrative details. If you’re going to make TLS/SSL requests you’ll need to have or generate keys and certificates. I’ve included the basic commands to get you started without understanding this step because you need something running now. I understand.

openssl genrsa -out server.key 1024
openssl req -new -key key.pem -out csr.pem
openssl x509 -req -in csr.pem -signkey key.pem -out cert.pem

Fortunately creating a server that listens for TLS connections is quite simple. It is nearly exactly like creating a server that listens without the security using the net lib where here we require tls.

fs = require 'fs'
tls = require 'tls'

privatekey = fs.readFileSync 'server.key'
cert = fs.readFileSync 'cert.pem'
ca = fs.readFileSync 'cert.pem'

options = {key: privatekey, cert: cert, ca: ca}

tlsserver = tls.createServer options, (s) ->
                s.write "This is S(SL)parta!"
tlsserver.listen 8989

You may now be wondering what that hash with options is for. The key is used to encrypt and decrypt on the server side of the connection. The cert is a token used to verify the identity of a server and who runs it. Usually certs are signed by a third party like or Verisign. The ‘ca’ bit is the certificate authority which lists certificates that can be trusted without being signed by a trusted authority, trusted authorities to contact for such lists, or the default list of authorities to contact. If you’re using a self-signed certificate like the one I’ve generated you’ll want to include it in your ca string or you will get errors from openssl about self-signed certificates.

The server part of this equation is rather well documented. The client bit, however, is much less elucidated in the node docs. Problem solved.

tls = require 'tls'
fs = require 'fs'

crt = fs.readFileSync 'cert.pem'
ca = fs.readFileSync 'cert.pem'
options = {cert: crt, ca: ca}

s = tls.connect 8989, options, ->
        s.connected = true
        s.write 'Client Connected.'
        s.setEncoding 'utf-8'
        if s.authorizationError
                console.log 'Authorization Error: ' + s.authorizationError
                console.log 'Authorized a Secure SSL/TLS Connection.'

s.on 'data', (d) ->
        console.log 'RCV:' + d

s.on 'error', (e) ->
        console.log error

Questions, suggestions, and comments are encouraged.