From acb7dd46f92873c1ff666d9585404966b2f6af9b Mon Sep 17 00:00:00 2001 From: Lloyd Hilaiel <lloyd@hilaiel.com> Date: Fri, 18 Nov 2011 17:04:37 -0700 Subject: [PATCH] store public key on disk as a certificate which has embedded creation time. use that as the value returned in /wsapi/session_context as domain_key_creation_time - now you can update keys at any time and outstanding client certs are expired automatically - closes #599 --- lib/secrets.js | 33 ++++++++++++++++-------------- package.json | 2 +- scripts/generate_ephemeral_keys.sh | 13 +++++++++++- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/lib/secrets.js b/lib/secrets.js index 1dffcad9f..32adfcb6c 100644 --- a/lib/secrets.js +++ b/lib/secrets.js @@ -36,7 +36,8 @@ const path = require('path'), fs = require('fs'), -jwk = require('jwcrypto/jwk'); +jwk = require('jwcrypto/jwk'), +jwt = require('jwcrypto/jwt'); exports.generate = function(chars) { var str = ""; @@ -92,29 +93,31 @@ exports.loadSecretKey = function(name, dir) { return jwk.SecretKey.deserialize(secret); } -exports.publicKeyCreationDate = function(name, dir) { - name = checkName(name); - dir = checkDir(dir); - var p = path.join(dir, name + ".publickey"); - var stats = fs.statSync(p); - return stats.ctime; -}; - -exports.loadPublicKey = function(name, dir) { +function readAndParseCert(name, dir) { name = checkName(name); dir = checkDir(dir); - var p = path.join(dir, name + ".publickey"); - var secret = undefined; + var p = path.join(dir, name + ".cert"); + var cert = undefined; // may throw - secret = fs.readFileSync(p).toString(); + cert = fs.readFileSync(p).toString(); - if (secret === undefined) { + if (cert === undefined) { return null; } // parse it // it should be a JSON structure with alg and serialized key // {alg: <ALG>, value: <SERIALIZED_KEY>} - return jwk.PublicKey.deserialize(secret); + var tok = new jwt.JWT(); + tok.parse(cert); + return JSON.parse(new Buffer(tok.payloadSegment, 'base64').toString()); } + +exports.publicKeyCreationDate = function(name, dir) { + return new Date(readAndParseCert(name, dir).iat); +}; + +exports.loadPublicKey = function(name, dir) { + return jwk.PublicKey.deserialize(JSON.stringify(readAndParseCert(name, dir)['public-key'])); +}; diff --git a/package.json b/package.json index 9c1befbef..7c1097c18 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ , "colors" : "0.5.0" , "sax" : "0.2.3" , "mimelib-noiconv" : "0.1.3" - , "jwcrypto": "https://github.com/mozilla/jwcrypto/tarball/083132cb" + , "jwcrypto": "https://github.com/mozilla/jwcrypto/tarball/e02d4ea" , "postprocess": "0.0.3" , "urlparse": "0.0.1" } diff --git a/scripts/generate_ephemeral_keys.sh b/scripts/generate_ephemeral_keys.sh index ee4869567..05e79374d 100755 --- a/scripts/generate_ephemeral_keys.sh +++ b/scripts/generate_ephemeral_keys.sh @@ -10,14 +10,25 @@ if [ -f $VAR/root.publickey ] ; then fi GENERATE_KEYPAIR=`which generate-keypair 2> /dev/null` +CERTIFY=`which certify 2> /dev/null` if [ ! -x "$GENERATE_KEYPAIR" ] ; then echo "can't find generate-keypair from the jwcrypto package. try: npm install" exit 1 fi +if [ ! -x "$CERTIFY" ] ; then + echo "can't find certify from the jwcrypto package. try: rm -rf node_modules && npm install" + exit 1 +fi + echo '*** Generating ephemeral keys used for testing ***' $GENERATE_KEYPAIR -k 128 -a rsa mkdir -p $VAR -mv key.publickey $VAR/root.publickey + +# public key will be stored as a self signed certificate with an embedded +# creation date (so that if the key is updated, we can revoke outstanding +# certificates - GH-599 & GH-600) +$CERTIFY -s key.secretkey -p key.publickey > $VAR/root.cert +rm key.publickey mv key.secretkey $VAR/root.secretkey -- GitLab