Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@shigeki
Created November 13, 2014 02:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shigeki/de5748cc0deb980bcb35 to your computer and use it in GitHub Desktop.
Save shigeki/de5748cc0deb980bcb35 to your computer and use it in GitHub Desktop.
Example Code to use OCSP Stapling in Node.js
var http = require('http');
var https = require('https');
var fs = require('fs');
var rfc2560 = require('asn1.js-rfc2560');
var OCSPResponse = rfc2560.OCSPResponse;
var BasicOCSPResponse = rfc2560.BasicOCSPResponse;
var ocsp_uri = 'http://ocsp2.globalsign.com/gsorganizationvalsha2g2';
var ocsp_dst = require('url').parse(ocsp_uri);
// ocsp_request.der can be generated beforehand by using openssl
// openssl ocsp -issuer /home/ohtsu/tmp/cert/ca.pem -cert /home/ohtsu/tmp/cert/server.pem -reqout req.der
var ocsp_request_der = fs.readFileSync('./ocsp_request.der');
var port = 443;
var ocsp_req_timeout = 3 * 1000;
var cache = {nextUpdate: 0, der: null, lock: false};
var opts = {
key: fs.readFileSync('/home/ohtsu/tmp/cert/server.key'),
ca: fs.readFileSync('/home/ohtsu/tmp/cert/ca.pem'),
cert: fs.readFileSync('/home/ohtsu/tmp/cert/server.pem')
};
var server = https.createServer(opts, function(req, res) {
res.end('Hello TLS Server');
});
server.on('OCSPRequest', function(cert, issuer, cb) {
var now = Date.now();
if (now > cache.nextUpdate && !cache.lock) {
cache.lock = true;
cache.der = null;
HandleOCSPrequest(cb);
} else {
var msg = cache.der ? 'cache hit!': 'terminated';
console.log( 'OCSP Response:', msg);
cb(null, cache.der);
}
});
server.listen(port);
function HandleOCSPrequest(cb) {
var opts = {
host: ocsp_dst.host,
method: 'POST',
path: ocsp_dst.path,
headers: {'content-type': 'application/ocsp-request',
'content-length': ocsp_request_der.length}
};
var req = http.request(opts, function(res) {
var buflist = [];
res.on('data', function(chunk) {
buflist.push(chunk);
});
res.on('end', function() {
var der = Buffer.concat(buflist);
var ocsp_res = OCSPResponse.decode(der, 'der');
var b_res = BasicOCSPResponse.decode(ocsp_res.responseBytes.response, 'der');
var res = b_res.tbsResponseData.responses[0];
cache = {nextUpdate: res.nextUpdate, der: der, lock: false};
console.log('OCSP Response: cache updated!');
cb(null, der);
});
});
// Error and Timeout to OCSP server terminate OCSP stapling
req.setTimeout(ocsp_req_timeout, function() {
req.abort();
req.emit('error', new Error('timeout'));
});
req.on('error', function(e) {
console.log('problem with OCSP request: ' + e.message);
if (cache.lock === null) {
cache = {nextUpdate: Infinity, der: null, lock: null};
cb(null, null);
}
});
req.end(ocsp_request_der);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment