Skip to content

Commit

Permalink
Merge pull request #4 from xtralifecloud/publicKeyCaching
Browse files Browse the repository at this point in the history
Addition of a publicKey cache
  • Loading branch information
maeltm committed Aug 29, 2019
2 parents f6ba78d + d47cf38 commit 2f0d11f
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
17 changes: 17 additions & 0 deletions lib/main.js
Expand Up @@ -4,6 +4,8 @@ var crypto = require('crypto');
var https = require('https');
var url = require('url');

var cache = {}; // (publicKey -> cert) cache

function verifyPublicKeyUrl(publicKeyUrl) {
var parsedUrl = url.parse(publicKeyUrl);
if (parsedUrl.protocol !== 'https:') {
Expand Down Expand Up @@ -37,13 +39,28 @@ function getAppleCertificate(publicKeyUrl, callback) {
return;
}

if (cache[publicKeyUrl]) {
return callback(null, cache[publicKeyUrl]);
}

https.get(publicKeyUrl, function (res) {
var data = '';
res.on('data', function(chunk) {
data += chunk.toString('base64');
});
res.on('end', function() {
var cert = convertX509CertToPEM(data);

if (res.headers['cache-control']) { // if there's a cache-control header
var expire = res.headers['cache-control'].match(/max-age=([0-9]+)/);
if (expire) { // if we got max-age
cache[publicKeyUrl] = cert; // save in cache
// we'll expire the cache entry later, as per max-age
setTimeout(function () {
delete cache[publicKeyUrl];
}, parseInt(expire[1], 10) * 1000);
}
}
callback(null, cert);
});
}).on('error', function(e) {
Expand Down
46 changes: 46 additions & 0 deletions test/integrationTest.js
@@ -0,0 +1,46 @@
/*
global toString
*/
'use strict';

var assert = require('assert');
var verifier = require('../lib/main');

function isError(error) {
return toString.call(error) === '[object Error]';
}

// a real token is used to check caching behavior
// but sharing it should have no security consequences
var testToken = {
playerId: 'G:1965586982',
publicKeyUrl: 'https://static.gc.apple.com/public-key/gc-prod-4.cer',
timestamp: 1565257031287,
signature: 'uqLBTr9Uex8zCpc1UQ1MIDMitb+HUat2Mah4Kw6AVLSGe0gGNJXlih2i5X+0Z'+
'wVY0S9zY2NHWi2gFjmhjt\/4kxWGMkupqXX5H\/qhE2m7hzox6lZJpH98ZEUbouWRfZX2ZhU'+
'lCkAX09oRNi7fI7mWL1\/o88MaI\/y6k6tLr14JTzmlxgdyhw+QRLxRPA6NuvUlRSJpyJ4aG'+
'tNH5\/wHdKQWL8nUnFYiYmaY8R7IjzNxPfy8UJTUWmeZvMSgND4u8EjADPsz7ZtZyWAPi8kY'+
'cAb6M8k0jwLD3vrYCB8XXyO2RQb/FY2TM4zJuI7PzLlvvgOJXbbfVtHx7Evnm5NYoyzgzw==',
salt: 'DzqqrQ==',
bundleId: 'cloud.xtralife.gamecenterauth'
};

describe('caching test', function () {
it('should be slow for first check',
function (done) {
verifier.verify(testToken, function (error) {
assert.equal(isError(error), false);
done();
});
});

it('should take less than 2ms for next checks',
function (done) {
this.timeout(2);
verifier.verify(testToken, function (error) {
assert.equal(isError(error), false);
done();
});
});
});

0 comments on commit 2f0d11f

Please sign in to comment.