Comparing version 0.3.2 to 0.4.0
#!/usr/bin/env node | ||
var jwcrypto = require("../index"); | ||
var | ||
fs = require('fs'), | ||
jwcrypto = require("../index"); | ||
var cert_raw = process.argv[2]; | ||
var pk_raw = process.argv[3]; | ||
// Side effects Issue #24 | ||
require("../lib/algs/ds"); | ||
require("../lib/algs/rs"); | ||
var args = require('optimist') | ||
.usage('Check certificate\nUsage: $0') | ||
.alias('p', 'public') | ||
.describe('p', 'public key to sign') | ||
.demand('p') | ||
.alias('h', 'help') | ||
.describe('h', 'display this usage message') | ||
.alias('c', 'certificate') | ||
.describe('c', 'A certificate which you want to examine.') | ||
.demand('c') | ||
.alias('d', 'debug') | ||
.describe('d', 'Debug mode, useful for development of this tool') | ||
.boolean('d') | ||
.default('d', false); | ||
var argv = args.argv; | ||
if (argv.h) { | ||
args.showHelp(); | ||
process.exit(1); | ||
} | ||
var debug = argv.d; | ||
if (debug) console.log('Reading cert file=', argv.c); | ||
var cert_raw = fs.readFileSync(argv.c).toString('utf8'); | ||
var cert = jwcrypto.extractComponents(cert_raw); | ||
console.log("issuer: " + cert.payload.iss); | ||
console.log("full payload: " + JSON.stringify(cert.payload)); | ||
console.log("principal:" + JSON.stringify(cert.payload.principal)); | ||
console.log("key:" + cert.payload['public-key'].serialize()); | ||
console.log("key:" + JSON.stringify(cert.payload['public-key'], null, 4)); | ||
console.log("expiration:" + cert.payload.exp); | ||
if (debug) console.log('Reading public file=', argv.p); | ||
var pk_raw = fs.readFileSync(argv.p).toString('utf8'); | ||
var pk = jwcrypto.loadPublicKey(pk_raw); | ||
if (debug) console.log(JSON.stringify(JSON.parse(pk.serialize()), null, 4)); | ||
console.log("verifying the raw signature - no cert specific verification"); | ||
jwcrypto.verify(cert, pk, function(err, payload) { | ||
jwcrypto.verify(cert_raw, pk, function(err, payload) { | ||
if (err) { | ||
@@ -21,0 +57,0 @@ console.log("doesn't work"); |
@@ -7,2 +7,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public | ||
var libs = require("../../libs/minimal"); | ||
var version = require("../version"); | ||
var BigInteger = libs.BigInteger; | ||
@@ -75,3 +76,3 @@ | ||
function _getKeySizeFromYBitlength(size) { | ||
function _getKeySizeFromBitlength(size) { | ||
for (keysize in KEYSIZES) { | ||
@@ -99,33 +100,2 @@ var keysize_nbits = KEYSIZES[keysize].p.bitLength(); | ||
function serializeParamsToObject(keysize, obj) { | ||
// add other parameters, because we want these keys to be portable | ||
var params = getParams(keysize); | ||
obj.p = params.p.toString(16); | ||
obj.q = params.q.toString(16); | ||
obj.g = params.g.toString(16); | ||
} | ||
// this function will throw an exception if the parameters don't | ||
// match what's expected in KEYSIZES | ||
function keysizeFromObject(obj) { | ||
var p = new BigInteger(obj.p, 16); | ||
var q = new BigInteger(obj.q, 16); | ||
var g = new BigInteger(obj.g, 16); | ||
var keysize = _getKeySizeFromYBitlength(p.bitLength()); | ||
var params = getParams(keysize); | ||
// check! | ||
if (!p.equals(params.p)) | ||
throw "bad p"; | ||
if (!q.equals(params.q)) | ||
throw "bad q"; | ||
if (!g.equals(params.g)) | ||
throw "bad g"; | ||
return keysize; | ||
} | ||
function generate(keysize, rng, doneCB) { | ||
@@ -143,5 +113,5 @@ var params = getParams(keysize); | ||
// the secret key will compute y | ||
keypair.secretKey = new SecretKey(x, keypair.keysize); | ||
keypair.publicKey = new PublicKey(keypair.secretKey.y, keypair.keysize); | ||
keypair.secretKey = new SecretKey(x, keypair.keysize, params); | ||
keypair.publicKey = new PublicKey(keypair.secretKey.y, keypair.keysize, params); | ||
keypair.publicKey.algorithm = keypair.secretKey.algorithm = keypair.algorithm = 'DS'; | ||
@@ -153,5 +123,11 @@ | ||
var PublicKey = function(y, keysize) { | ||
var PublicKey = function(y, keysize, params) { | ||
this.y = y; | ||
this.keysize = keysize; | ||
if (keysize && params) { | ||
this.keysize = keysize; | ||
// copy params | ||
this.q = params.q; this.g = params.g; this.p = params.p; | ||
} | ||
}; | ||
@@ -161,34 +137,75 @@ | ||
PublicKey.prototype.serializeToObject = function(obj) { | ||
PublicKey.prototype._20120815_serializeToObject = function(obj) { | ||
obj.version = '2012.08.15'; | ||
obj.y = this.y.toBase64(); | ||
obj.p = this.p.toBase64(); | ||
obj.q = this.q.toBase64(); | ||
obj.g = this.g.toBase64(); | ||
}; | ||
PublicKey.prototype._LEGACY_serializeToObject = function(obj) { | ||
obj.y = this.y.toString(16); | ||
serializeParamsToObject(this.keysize, obj); | ||
obj.p = this.p.toString(16); | ||
obj.q = this.q.toString(16); | ||
obj.g = this.g.toString(16); | ||
}; | ||
PublicKey.prototype.serializeToObject = version.versionDispatcher('serializeToObject'); | ||
PublicKey.prototype.equals = function(other) { | ||
if (other == null) | ||
return false; | ||
return ((this.keysize == other.keysize) && (this.y.equals(other.y))); | ||
return (other.algorithm == this.algorithm && | ||
this.p.equals(other.p) && | ||
this.y.equals(other.y) && | ||
this.g.equals(other.g) && | ||
this.q.equals(other.q)); | ||
}; | ||
PublicKey.prototype.deserializeFromObject = function(obj) { | ||
PublicKey.prototype._LEGACY_deserializeFromObject = function(obj) { | ||
this.p = new BigInteger(obj.p, 16); | ||
this.q = new BigInteger(obj.q, 16); | ||
this.g = new BigInteger(obj.g, 16); | ||
this.y = new BigInteger(obj.y, 16); | ||
}; | ||
//this.keysize = _getKeySizeFromYBitlength(this.y.bitLength()); | ||
this.keysize = keysizeFromObject(obj); | ||
PublicKey.prototype._20120815_deserializeFromObject = function(obj) { | ||
this.p = BigInteger.fromBase64(obj.p); | ||
this.q = BigInteger.fromBase64(obj.q); | ||
this.g = BigInteger.fromBase64(obj.g); | ||
this.y = BigInteger.fromBase64(obj.y); | ||
}; | ||
PublicKey.prototype.deserializeFromObject = function(obj) { | ||
version.dispatchOnDataFormatVersion(this, 'deserializeFromObject', obj.version, obj); | ||
this.keysize = _getKeySizeFromBitlength(this.y.bitLength()); | ||
return this; | ||
}; | ||
function SecretKey(x, keysize, y) { | ||
// note: this deserialization code does not check that the public key is | ||
// well-formed (P and Q are primes, G is actually a generator, etc), and it | ||
// allows the use of any group (instead of being restricted to e.g. the | ||
// ones published by NIST). For sign/verify that is ok: when someone else | ||
// gives a public key, they're instructing us how to distinguish between good | ||
// signatures and forgeries, and giving us a corrupt pubkey is their | ||
// perogative (plus we have no secrets to lose). | ||
// | ||
// Do not use this approach for DH key agreement. In that world, we *do* have | ||
// a private key that could be lost, and a maliciously crafted pubkey could | ||
// be used to learn it. Additional checks would be necessary to do that | ||
// safely. | ||
function SecretKey(x, keysize, params) { | ||
this.x = x; | ||
var params = getParams(keysize); | ||
// compute y if need be | ||
if (params && keysize) { | ||
this.y = params.g.modPow(this.x, params.p); | ||
this.keysize = keysize; | ||
// compute y if need be | ||
if (!y && params) | ||
y = params.g.modPow(this.x, params.p); | ||
this.y = y; | ||
this.keysize = keysize; | ||
// copy params | ||
this.q = params.q; this.g = params.g; this.p = params.p; | ||
} | ||
}; | ||
@@ -198,18 +215,41 @@ | ||
SecretKey.prototype.serializeToObject = function(obj) { | ||
SecretKey.prototype._LEGACY_serializeToObject = function(obj) { | ||
obj.x = this.x.toString(16); | ||
serializeParamsToObject(this.keysize, obj); | ||
obj.p = this.p.toString(16); | ||
obj.q = this.q.toString(16); | ||
obj.g = this.g.toString(16); | ||
}; | ||
SecretKey.prototype.deserializeFromObject = function(obj) { | ||
SecretKey.prototype._20120815_serializeToObject = function(obj) { | ||
obj.version = '2012.08.15'; | ||
obj.x = this.x.toBase64(); | ||
obj.p = this.p.toBase64(); | ||
obj.q = this.q.toBase64(); | ||
obj.g = this.g.toBase64(); | ||
}; | ||
SecretKey.prototype.serializeToObject = version.versionDispatcher('serializeToObject'); | ||
SecretKey.prototype._LEGACY_deserializeFromObject = function(obj) { | ||
this.x = new BigInteger(obj.x, 16); | ||
//this.keysize = obj.keysize; | ||
this.keysize = keysizeFromObject(obj); | ||
this.p = new BigInteger(obj.p, 16); | ||
this.q = new BigInteger(obj.q, 16); | ||
this.g = new BigInteger(obj.g, 16); | ||
}; | ||
var params = getParams(keysize); | ||
// repetition, bad - FIXME | ||
this.y = params.g.modPow(this.x, params.p); | ||
SecretKey.prototype._20120815_deserializeFromObject = function(obj) { | ||
this.x = BigInteger.fromBase64(obj.x); | ||
this.p = BigInteger.fromBase64(obj.p); | ||
this.q = BigInteger.fromBase64(obj.q); | ||
this.g = BigInteger.fromBase64(obj.g); | ||
}; | ||
SecretKey.prototype.deserializeFromObject = function(obj) { | ||
version.dispatchOnDataFormatVersion(this, 'deserializeFromObject', obj.version, | ||
obj); | ||
this.keysize = _getKeySizeFromBitlength(this.p.bitLength()); | ||
return this; | ||
@@ -229,5 +269,5 @@ }; | ||
while(true) { | ||
k = randomNumberMod(params.q, rng); | ||
r = params.g.modPow(k, params.p).mod(params.q); | ||
k = randomNumberMod(this.q, rng); | ||
r = this.g.modPow(k, this.p).mod(this.q); | ||
if (r.equals(BigInteger.ZERO)) { | ||
@@ -239,9 +279,9 @@ console.log("oops r is zero"); | ||
// the hash | ||
var bigint_hash = doHash(params.hashAlg, message, params.q); | ||
var bigint_hash = doHash(params.hashAlg, message, this.q); | ||
// compute H(m) + (x*r) | ||
var message_dep = bigint_hash.add(this.x.multiply(r).mod(params.q)).mod(params.q); | ||
var message_dep = bigint_hash.add(this.x.multiply(r).mod(this.q)).mod(this.q); | ||
// compute s | ||
s = k.modInverse(params.q).multiply(message_dep).mod(params.q); | ||
s = k.modInverse(this.q).multiply(message_dep).mod(this.q); | ||
@@ -281,3 +321,3 @@ if (s.equals(BigInteger.ZERO)) { | ||
} | ||
var r = new BigInteger(signature.substring(0, hexlength), 16), | ||
@@ -287,7 +327,7 @@ s = new BigInteger(signature.substring(hexlength, hexlength*2), 16); | ||
// check rangeconstraints | ||
if ((r.compareTo(BigInteger.ZERO) < 0) || (r.compareTo(params.q) > 0)) { | ||
if ((r.compareTo(BigInteger.ZERO) < 0) || (r.compareTo(this.q) > 0)) { | ||
//return cb("problem with r: " + r.toString(16)); | ||
return cb("invalid signature"); | ||
} | ||
if ((s.compareTo(BigInteger.ZERO) < 0) || (s.compareTo(params.q) > 0)) { | ||
if ((s.compareTo(BigInteger.ZERO) < 0) || (s.compareTo(this.q) > 0)) { | ||
//return cb("problem with s"); | ||
@@ -297,9 +337,9 @@ return cb("invalid signature"); | ||
var w = s.modInverse(params.q); | ||
var u1 = doHash(params.hashAlg, message, params.q).multiply(w).mod(params.q); | ||
var u2 = r.multiply(w).mod(params.q); | ||
var v = params.g | ||
.modPow(u1,params.p) | ||
.multiply(this.y.modPow(u2,params.p)).mod(params.p) | ||
.mod(params.q); | ||
var w = s.modInverse(this.q); | ||
var u1 = doHash(params.hashAlg, message, this.q).multiply(w).mod(this.q); | ||
var u2 = r.multiply(w).mod(this.q); | ||
var v = this.g | ||
.modPow(u1,this.p) | ||
.multiply(this.y.modPow(u2,this.p)).mod(this.p) | ||
.mod(this.q); | ||
@@ -309,3 +349,3 @@ cb(null, v.equals(r)); | ||
// register this stuff | ||
// register this stuff | ||
algs.register("DS", { | ||
@@ -312,0 +352,0 @@ generate: generate, |
@@ -30,3 +30,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public | ||
var _getAlgorithm = function _getAlgorithm() { | ||
return this.algorithm + this.keysize.toString(); | ||
return this.algorithm + this.keysize.toString(); | ||
}; | ||
@@ -87,3 +87,3 @@ | ||
}, | ||
serialize: function() { | ||
@@ -112,2 +112,3 @@ return JSON.stringify(this.toSimpleObject()); | ||
exports.ALGS = ALGS; | ||
@@ -118,2 +119,1 @@ exports.PublicKey = PublicKey; | ||
exports.NotImplementedException = NotImplementedException; | ||
@@ -5,5 +5,6 @@ /* This Source Code Form is subject to the terms of the Mozilla Public | ||
var libs = require("../../libs/all"), | ||
algs = require("./index"); | ||
var BigInteger = libs.BigInteger; | ||
var libs = require("../../libs/all"), | ||
algs = require("./index"), | ||
version = require("../version"), | ||
BigInteger = libs.BigInteger; | ||
@@ -69,12 +70,19 @@ // supported keysizes | ||
PublicKey.prototype.serializeToObject = function(obj) { | ||
PublicKey.prototype._LEGACY_serializeToObject = function(obj) { | ||
obj.n = this.rsa.n.toString(); | ||
obj.e = this.rsa.e.toString(); | ||
// obj.value = this.rsa.serializePublicASN1(); | ||
}; | ||
PublicKey.prototype._20120815_serializeToObject = function(obj) { | ||
obj.version = '2012.08.15'; | ||
obj.modulus = this.rsa.n.toBase64(); | ||
obj.exponent = new BigInteger(this.rsa.e.toString(), 10).toBase64(); | ||
}; | ||
PublicKey.prototype.serializeToObject = version.versionDispatcher('serializeToObject'); | ||
PublicKey.prototype.equals = function(other) { | ||
if (other == null) | ||
return false; | ||
// FIXME: this is loser-ville if e is not an integer | ||
@@ -84,8 +92,17 @@ return ((this.rsa.n.equals(other.rsa.n)) && (this.rsa.e == other.rsa.e || this.rsa.e.equals(other.rsa.e)) && (this.algorithm == other.algorithm)); | ||
PublicKey.prototype.deserializeFromObject = function(obj) { | ||
this.rsa = new libs.RSAKey(); | ||
PublicKey.prototype._LEGACY_deserializeFromObject = function(obj) { | ||
this.rsa.n = new libs.BigInteger(obj.n, 10); | ||
this.rsa.e = new libs.BigInteger(obj.e, 10); | ||
// this.rsa.readPublicKeyFromPEMString(obj.value); | ||
}; | ||
PublicKey.prototype._20120815_deserializeFromObject = function(obj) { | ||
this.rsa.n = libs.BigInteger.fromBase64(obj.modulus); | ||
this.rsa.e = libs.BigInteger.fromBase64(obj.exponent); | ||
}; | ||
PublicKey.prototype.deserializeFromObject = function(obj) { | ||
this.rsa = new libs.RSAKey(); | ||
version.dispatchOnDataFormatVersion(this, 'deserializeFromObject', obj.version, obj); | ||
this.keysize = _getKeySizeFromRSAKeySize(this.rsa.n.bitLength()); | ||
@@ -110,4 +127,9 @@ return this; | ||
SecretKey.prototype.serializeToObject = function(obj) { | ||
// obj.value = this.rsa.serializePrivateASN1(); | ||
// | ||
// support for different data formats | ||
// | ||
SecretKey.prototype._LEGACY_serializeToObject = function(obj) { | ||
obj.version = undefined; | ||
obj.n = this.rsa.n.toString(); | ||
@@ -118,9 +140,29 @@ obj.e = this.rsa.e.toString(); | ||
SecretKey.prototype.deserializeFromObject = function(obj) { | ||
this.rsa = new libs.RSAKey(); | ||
// this.rsa.readPrivateKeyFromPEMString(obj.value); | ||
SecretKey.prototype._20120815_serializeToObject = function(obj) { | ||
obj.version = '2012.08.15'; | ||
obj.modulus = this.rsa.n.toBase64(); | ||
obj.exponent = new BigInteger(this.rsa.e.toString(), 10).toBase64(); | ||
obj.secretExponent = this.rsa.d.toBase64(); | ||
}; | ||
SecretKey.prototype.serializeToObject = version.versionDispatcher('serializeToObject'); | ||
SecretKey.prototype._LEGACY_deserializeFromObject = function(obj) { | ||
this.rsa.n = new BigInteger(obj.n, 10); | ||
this.rsa.e = new BigInteger(obj.e, 10); | ||
this.rsa.d = new BigInteger(obj.d, 10); | ||
}; | ||
SecretKey.prototype._20120815_deserializeFromObject = function(obj) { | ||
this.rsa.n = BigInteger.fromBase64(obj.modulus); | ||
this.rsa.e = BigInteger.fromBase64(obj.exponent); | ||
this.rsa.d = BigInteger.fromBase64(obj.secretExponent); | ||
}; | ||
SecretKey.prototype.deserializeFromObject = function(obj) { | ||
this.rsa = new libs.RSAKey(); | ||
version.dispatchOnDataFormatVersion(this, 'deserializeFromObject', obj.version, obj); | ||
this.keysize = _getKeySizeFromRSAKeySize(this.rsa.n.bitLength()); | ||
@@ -130,3 +172,3 @@ return this; | ||
// register this stuff | ||
// register this stuff | ||
algs.register("RS", { | ||
@@ -133,0 +175,0 @@ generate: generate, |
@@ -6,5 +6,8 @@ /* This Source Code Form is subject to the terms of the Mozilla Public | ||
var jwcrypto = require("./jwcrypto"), | ||
utils = require("./utils"); | ||
utils = require("./utils"), | ||
version = require("./version"); | ||
function serializeAssertionParamsInto(assertionParams, params) { | ||
var SERIALIZER = {}; | ||
SERIALIZER._LEGACY_serializeAssertionParamsInto = function(assertionParams, params) { | ||
// copy over only the parameters we care about into params | ||
@@ -15,5 +18,20 @@ params.iat = assertionParams.issuedAt ? assertionParams.issuedAt.valueOf() : undefined; | ||
params.aud = assertionParams.audience; | ||
}; | ||
SERIALIZER._20120815_serializeAssertionParamsInto = function(assertionParams, params) { | ||
this._LEGACY_serializeAssertionParamsInto(assertionParams, params); | ||
if (params.version) { | ||
if (params.version != "2012.08.15") | ||
throw new Error("cannot serialize an assertion in a different format than is prescribed by overlaying data structure, e.g. cert"); | ||
} else { | ||
params.version = "2012.08.15"; | ||
} | ||
} | ||
function extractAssertionParamsFrom(params) { | ||
var serializeAssertionParamsInto = function(assertionParams, params) { | ||
version.dispatchOnDataFormatVersion(SERIALIZER, 'serializeAssertionParamsInto', version.getDataFormatVersion(), assertionParams, params); | ||
}; | ||
SERIALIZER._LEGACY_extractAssertionParamsFrom = function(params) { | ||
var assertionParams = {}; | ||
@@ -29,5 +47,19 @@ assertionParams.issuedAt = utils.getDate(params.iat); | ||
delete params.aud; | ||
return assertionParams; | ||
}; | ||
SERIALIZER._20120815_extractAssertionParamsFrom = function(params) { | ||
delete params.version; | ||
var returnValue = this._LEGACY_extractAssertionParamsFrom(params); | ||
return returnValue; | ||
}; | ||
function extractAssertionParamsFrom(params) { | ||
return version.dispatchOnDataFormatVersion(SERIALIZER, 'extractAssertionParamsFrom', version.getDataFormatVersion(), params); | ||
}; | ||
exports.sign = function(payload, assertionParams, secretKey, cb) { | ||
@@ -34,0 +66,0 @@ var allParams = {}; |
@@ -9,12 +9,60 @@ /* This Source Code Form is subject to the terms of the Mozilla Public | ||
delay = utils.delay, | ||
version = require("./version"), | ||
und = require("./underscore.js"); | ||
exports.sign = function(publicKeyToSign, principal, | ||
assertionParams, additionalPayload, | ||
var SERIALIZER = {}; | ||
SERIALIZER._LEGACY_serializeCertParamsInto = function(certParams, params) { | ||
params['public-key'] = certParams.publicKey.toSimpleObject(); | ||
params.principal = certParams.principal; | ||
}; | ||
SERIALIZER._20120815_serializeCertParamsInto = function(certParams, params) { | ||
params['publicKey'] = certParams.publicKey.toSimpleObject(); | ||
params.principal = certParams.principal; | ||
params.version = "2012.08.15"; | ||
} | ||
var serializeCertParamsInto = function(certParams, params) { | ||
version.dispatchOnDataFormatVersion(SERIALIZER, 'serializeCertParamsInto', version.getDataFormatVersion(), certParams, params); | ||
}; | ||
SERIALIZER._LEGACY_extractCertParamsFrom = function(params) { | ||
var certParams = {}; | ||
certParams.publicKey = jwcrypto.loadPublicKey(JSON.stringify(params['public-key'])); | ||
delete params['public-key']; | ||
certParams.principal = params.principal; | ||
delete params.principal; | ||
return certParams; | ||
}; | ||
SERIALIZER._20120815_extractCertParamsFrom = function(params) { | ||
delete params.version; | ||
var certParams = {}; | ||
certParams.publicKey = jwcrypto.loadPublicKey(JSON.stringify(params.publicKey)); | ||
delete params.publicKey; | ||
certParams.principal = params.principal; | ||
delete params.principal; | ||
return certParams; | ||
}; | ||
function extractCertParamsFrom(params, originalComponents) { | ||
return version.dispatchOnDataFormatVersion(SERIALIZER, 'extractCertParamsFrom', originalComponents.payload.version, params); | ||
}; | ||
exports.sign = function(certParams, assertionParams, additionalPayload, | ||
secretKey, cb) { | ||
var payload = {}; | ||
utils.copyInto(additionalPayload || {}, payload); | ||
payload['public-key'] = publicKeyToSign.toSimpleObject(); | ||
payload.principal = principal; | ||
serializeCertParamsInto(certParams, payload); | ||
assertion.sign(payload, assertionParams, secretKey, cb); | ||
@@ -29,7 +77,7 @@ }; | ||
// compatible with old format | ||
var publicKey = jwcrypto.loadPublicKey(JSON.stringify(payload['public-key'])); | ||
delete payload['public-key']; | ||
var principal = payload.principal; | ||
delete payload.principal; | ||
cb(err, payload, assertionParams, {principal: principal, 'public-key': publicKey}); | ||
var originalComponents = jwcrypto.extractComponents(signedObject); | ||
var certParams = extractCertParamsFrom(payload, originalComponents); | ||
// make the key appear under both public-key and publicKey | ||
cb(err, payload, assertionParams, certParams); | ||
}); | ||
@@ -78,10 +126,10 @@ }; | ||
certParams: certParams}); | ||
if (i >= certs.length) | ||
cb(null, certParamsArray, certParams['public-key']); | ||
cb(null, certParamsArray, certParams.publicKey); | ||
else | ||
delay(verifyCert)(i, certParams['public-key'], certParamsArray, cb); | ||
delay(verifyCert)(i, certParams.publicKey, certParamsArray, cb); | ||
}); | ||
} | ||
// get the root public key | ||
@@ -97,5 +145,5 @@ getRoot(rootIssuer, function(err, rootPK) { | ||
}); | ||
}); | ||
}); | ||
}; | ||
@@ -132,8 +180,8 @@ | ||
// what was the last PK in the successful chain? | ||
var lastPK = certParamsArray[certParamsArray.length - 1].certParams['public-key']; | ||
var lastPK = certParamsArray[certParamsArray.length - 1].certParams.publicKey; | ||
// now verify the assertion | ||
assertion.verify(signedAssertion, lastPK, now, function(err, payload, assertionParams) { | ||
if (err) return cb(err); | ||
// we're good! | ||
@@ -140,0 +188,0 @@ cb(null, certParamsArray, payload, assertionParams); |
@@ -13,3 +13,4 @@ /* This Source Code Form is subject to the terms of the Mozilla Public | ||
rng = require("./rng"), | ||
libs = require("../libs/minimal"); | ||
libs = require("../libs/minimal"), | ||
version = require("./version"); | ||
@@ -62,3 +63,3 @@ var RNG = new rng.RNG(); | ||
throw new algs.NotImplementedException("algorithm " + opts.algorithm + " not implemented"); | ||
waitForSeed(function() { | ||
@@ -80,3 +81,3 @@ // generate on the specific algorithm | ||
exports.loadSecretKey = function(str) { | ||
return algs.SecretKey.deserialize(str); | ||
return algs.SecretKey.deserialize(str); | ||
}; | ||
@@ -97,3 +98,3 @@ | ||
var signatureValue = utils.hex2b64urlencode(rawSignature); | ||
delay(cb)(null, algBytes + "." + jsonBytes + "." + signatureValue); | ||
@@ -108,11 +109,11 @@ }); | ||
throw new MalformedException("malformed signature"); | ||
var parts = signedObject.split("."); | ||
if (parts.length != 3) { | ||
throw new MalformedException("signed object must have three parts, this one has " + parts.length); | ||
} | ||
} | ||
var headerSegment = parts[0]; | ||
var payloadSegment = parts[1]; | ||
var cryptoSegment = parts[2]; | ||
var cryptoSegment = parts[2]; | ||
@@ -139,3 +140,3 @@ // we verify based on the actual string | ||
var components = extractComponents(signedObject); | ||
// check that algorithm matches | ||
@@ -145,3 +146,3 @@ if (publicKey.getAlgorithm() != components.header.alg) { | ||
return; | ||
} | ||
} | ||
} catch (x) { | ||
@@ -156,3 +157,3 @@ cb("malformed signature"); | ||
return cb("malformed signature"); | ||
if (!result) | ||
@@ -171,11 +172,11 @@ return cb("invalid signature"); | ||
exports.generateKeys = function(opts, cb) { | ||
throw new Error("Not Implemented"); | ||
}; | ||
exports.encrypt = function(payload, encryptionAndMACKeys, cb) { | ||
throw new Error("Not Implemented"); | ||
}; | ||
exports.decrypt = function(encryptedPayload, encryptionAndMACKeys, cb) { | ||
throw new Error("Not Implemented"); | ||
}; | ||
@@ -190,1 +191,5 @@ | ||
exports.cert = require("./cert"); | ||
// versioning | ||
exports.getDataFormatVersion = version.getDataFormatVersion; | ||
exports.setDataFormatVersion = version.setDataFormatVersion; |
@@ -89,5 +89,13 @@ | ||
return this._bigint.probPrime(reps); | ||
}, | ||
toBase64: function() { | ||
return this._bigint.toBuffer().toString('base64'); | ||
} | ||
}; | ||
BigInteger.fromBase64 = function(b64_string) { | ||
var bi = bigint.fromBuffer(new Buffer(b64_string, 'base64')); | ||
return BigInteger._from_bigint(bi); | ||
}; | ||
nativeBigInteger = BigInteger; | ||
@@ -94,0 +102,0 @@ } catch (x) { |
@@ -8,2 +8,7 @@ var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
var ret = ""; | ||
// fix by bwarner | ||
if (h.length % 2 == 1) | ||
h = "0"+h; | ||
for(i = 0; i+3 <= h.length; i+=3) { | ||
@@ -10,0 +15,0 @@ c = parseInt(h.substring(i,i+3),16); |
@@ -9,2 +9,3 @@ preliminaries.js | ||
jsbn-patch.js | ||
bigint-patch.js | ||
exports_minimal.js |
@@ -27,2 +27,3 @@ // faking some objects so all goes well | ||
hex: function(){ | ||
throw new Error("Not Implemented"); | ||
} | ||
@@ -29,0 +30,0 @@ }; |
{ | ||
"name": "jwcrypto" | ||
, "version": "0.3.2" | ||
, "version": "0.4.0" | ||
, "dependencies": { | ||
"browserify": "1.8.1", | ||
"browserify": "1.13.5", | ||
"vows": "0.5.13", | ||
"optimist": "0.2.6", | ||
"uglify-js": "1.0.6", | ||
"uglify-js": "1.0.6" | ||
} | ||
, "optionalDependencies": { | ||
"bigint": "https://github.com/benadida/node-bigint/tarball/2ac68" | ||
} | ||
, "scripts": { | ||
"postinstall": "bash bundle.sh", | ||
"postinstall": "node ./scripts/bundle.js", | ||
"test": "./node_modules/.bin/vows" | ||
@@ -14,0 +16,0 @@ } |
@@ -85,4 +85,2 @@ JavaScript implementation of JSON Web Signatures and JSON Web Tokens, especially as needed by BrowserID. | ||
// also, if loading a secret key from somewhere | ||
// note how JWK determines automatically if it's a secret key | ||
// or public key. XXX should this be more explicit? | ||
var otherSecretKey = jwcrypto.loadSecretKey(storedSecretKey); | ||
@@ -110,3 +108,3 @@ | ||
// payload cannot contain reserved fields | ||
assertion.sign(payload, {issuer: "foo.com", expiresAt: new Date(), | ||
assertion.sign(payload, {issuer: "foo.com", expiresAt: new Date(new Date().valueOf() + 5000), | ||
issuedAt: new Date(), audience: "https://example.com"}, | ||
@@ -137,11 +135,18 @@ keypair.secretKey, | ||
var principal = {email: "someone@example.com"}; | ||
var assertionParams = {issuer: "foo.com", issuedAt: new Date(), | ||
expiresAt: new Date()}; | ||
// cert params, kid is optional, others are required | ||
var certParams = {kid: "key-2012-08-11", | ||
publicKey: keyToCertify, | ||
principal: principal}; | ||
var additionalPayload = {}; | ||
// payload cannot contain reserved fields | ||
cert.sign(keyToCertify, principal, | ||
assertionParams, additionalPayload, | ||
keypair.secretKey, | ||
function(err, signedObject) { | ||
cert.sign(certParams, | ||
assertionParams, additionalPayload, | ||
keypair.secretKey, | ||
function(err, signedObject) { | ||
// normal signedObject | ||
@@ -182,2 +187,32 @@ // can be verified with jwcrypto.verify | ||
// payload is the assertion payload, and assertionParams is the assertion params. | ||
}); | ||
}); | ||
Versioning | ||
==== | ||
The formats of public-keys, as well as the special payload parameters of assertions and certificates, will be versioned. | ||
Not indicating a version number in the serialized payload indicates | ||
the alpha format in the BrowserID specification from June | ||
2012. Otherwise, a version number is required. The BrowserID Beta version number is <tt>2012.08.15</tt>. | ||
By default, <tt>jwcrypto</tt> will use the latest format | ||
automatically, and will parse any past format (unless that becomes | ||
impossible, in which case we'll define behavior then.) | ||
The version of the data format can be discovered as: | ||
jwcrypto.DATA_FORMAT_VERSION | ||
If one wishes to use <tt>jwcrypto</tt> with an older data format: | ||
jwcrypto.setDataFormatVersion('2012.08.15'); | ||
or, to use the pre-versioning format: | ||
jwcrypto.setDataFormatVersion(''); | ||
or, to go back to the library default: | ||
jwcrypto.setDataFormatVersion(); | ||
@@ -33,3 +33,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public | ||
// yes, we're signing our own public key, cause it's easier for now | ||
cert.sign(keypair.publicKey, {email: "john@issuer.com"}, | ||
cert.sign({publicKey: keypair.publicKey, principal:{email: "john@issuer.com"}}, | ||
assertionParams, null, keypair.secretKey, self.callback); | ||
@@ -75,3 +75,3 @@ }); | ||
assert.isObject(certParams.principal); | ||
assert.isObject(certParams['public-key']); | ||
assert.isObject(certParams.publicKey); | ||
@@ -90,3 +90,3 @@ // make sure iss and exp are dates | ||
// expiration date | ||
var expiration = new Date(new Date().valueOf() + 60000); | ||
var expiration = new Date(new Date().valueOf() + 120000); | ||
@@ -114,7 +114,7 @@ // once the cert chain is done, sign a | ||
// generate the two certs | ||
cert.sign(intermediate_kp.publicKey, {host: "intermediate.root.com"}, | ||
cert.sign({publicKey: intermediate_kp.publicKey, principal: {host: "intermediate.root.com"}}, | ||
{issuer: "root.com", issuedAt: new Date(), expiresAt: expiration}, null, | ||
root_kp.secretKey, function (err, signedIntermediate) { | ||
cert.sign(user_kp.publicKey, {email: "john@root.com"}, | ||
{issuser: "intermediate.root.com", issuedAt: new Date(), expiresAt: expiration}, | ||
cert.sign({publicKey: user_kp.publicKey, principal: {email: "john@root.com"}}, | ||
{issuer: "intermediate.root.com", issuedAt: new Date(), expiresAt: expiration}, | ||
null, intermediate_kp.secretKey, | ||
@@ -218,3 +218,3 @@ function(err, signedUser) { | ||
// yes, we're signing our own public key, cause it's easier for now | ||
cert.sign(keypair.publicKey, {email: "user@example.com"}, | ||
cert.sign({publicKey: keypair.publicKey, principal: {email: "user@example.com"}}, | ||
assertionParams, null, keypair.secretKey, function(err, signedObj) { | ||
@@ -221,0 +221,0 @@ cert.verify(signedObj, keypair.publicKey, new Date(), self.callback); |
@@ -6,3 +6,3 @@ #!/usr/bin/env node | ||
const | ||
var | ||
vows = require('vows'), | ||
@@ -49,11 +49,11 @@ assert = require('assert'), | ||
throw "malformed signature " + typeof(signedObject); | ||
var parts = signedObject.split("."); | ||
if (parts.length != 3) { | ||
throw "signed object must have three parts, this one has " + parts.length; | ||
} | ||
} | ||
var headerSegment = parts[0]; | ||
var payloadSegment = parts[1]; | ||
var cryptoSegment = parts[2]; | ||
var cryptoSegment = parts[2]; | ||
@@ -74,5 +74,5 @@ // we verify based on the actual string | ||
const AUDIENCE = "http://foobar.com"; | ||
const ISSUER = "issuer.com"; | ||
const EMAIL = "john@example.com"; | ||
var AUDIENCE = "http://foobar.com"; | ||
var ISSUER = "issuer.com"; | ||
var EMAIL = "john@example.com"; | ||
@@ -108,4 +108,7 @@ var now = new Date(); | ||
// optionally a version | ||
// nothing else | ||
assert.equal(Object.keys(components.payload).length, 2); | ||
assert.ok(Object.keys(components.payload).length <= 3); | ||
assert.ok(Object.keys(components.payload).length >= 2); | ||
}, | ||
@@ -120,3 +123,3 @@ "has proper signature": function(components) { | ||
assert.ok(components.signature.length <= 80); | ||
assert.ok(components.signature.length > 75); | ||
assert.ok(components.signature.length > 75); | ||
} | ||
@@ -130,3 +133,3 @@ } | ||
topic: function() { | ||
jwcrypto.cert.sign(userKeypair.publicKey, {email: EMAIL}, | ||
jwcrypto.cert.sign({publicKey: userKeypair.publicKey, principal: {email: EMAIL}}, | ||
{issuedAt: now, issuer: ISSUER, expiresAt: in_a_minute}, | ||
@@ -161,6 +164,10 @@ {}, | ||
// assert.equal(JSON.stringify(components.payload.publicKey), userKeypair.publicKey.serialize()); | ||
assert.equal(JSON.stringify(components.payload['public-key']), userKeypair.publicKey.serialize()); | ||
// optionally version | ||
// nothing else | ||
assert.equal(Object.keys(components.payload).length, 5); | ||
assert.ok(Object.keys(components.payload).length <= 6); | ||
assert.ok(Object.keys(components.payload).length >= 5); | ||
}, | ||
@@ -167,0 +174,0 @@ "has proper signature": function(components) { |
@@ -6,3 +6,3 @@ #!/usr/bin/env node | ||
const | ||
var | ||
vows = require('vows'), | ||
@@ -12,2 +12,3 @@ assert = require('assert'), | ||
jwcrypto = require('../index'), | ||
utils = require('../lib/utils'), | ||
testUtils = require('./utils'); | ||
@@ -32,2 +33,10 @@ | ||
function mungePayload(signedObject) { | ||
var p = jwcrypto.extractComponents(signedObject); | ||
var payload = p.payload; | ||
payload.evilNewField = "evil"; | ||
var newPayloadSegment = utils.base64urlencode(JSON.stringify(payload)); | ||
return p.headerSegment+"."+newPayloadSegment+"."+p.cryptoSegment; | ||
} | ||
testUtils.addBatches(suite, function(alg, keysize) { | ||
@@ -107,3 +116,3 @@ var keypair; | ||
"payload is the same": function(err, payload) { | ||
assert.equal(JSON.stringify(payload), JSON.stringify(obj)); | ||
assert.equal(JSON.stringify(payload), JSON.stringify(obj)); | ||
}, | ||
@@ -116,3 +125,3 @@ "no error": function(err, payload) { | ||
topic: function(err, signedObject) { | ||
jwcrypto.verify(signedObject + "CRUD", keypair.publicKey, this.callback); | ||
jwcrypto.verify(mungePayload(signedObject), keypair.publicKey, this.callback); | ||
}, | ||
@@ -124,3 +133,3 @@ "errors": function(err, payload) { | ||
assert.isUndefined(payload); | ||
} | ||
} | ||
} | ||
@@ -143,3 +152,3 @@ }, | ||
"payload is the same": function(err, payload) { | ||
assert.equal(JSON.stringify(payload), JSON.stringify(obj)); | ||
assert.equal(JSON.stringify(payload), JSON.stringify(obj)); | ||
}, | ||
@@ -152,3 +161,4 @@ "no error": function(err, payload) { | ||
topic: function(err, signedObject) { | ||
jwcrypto.verify(signedObject + "CRUD", jwcrypto.loadPublicKey(keypair.publicKey.serialize()), | ||
jwcrypto.verify(mungePayload(signedObject), | ||
jwcrypto.loadPublicKey(keypair.publicKey.serialize()), | ||
this.callback); | ||
@@ -155,0 +165,0 @@ }, |
@@ -6,3 +6,3 @@ #!/usr/bin/env node | ||
const | ||
var | ||
vows = require('vows'), | ||
@@ -9,0 +9,0 @@ assert = require('assert'), |
@@ -13,3 +13,6 @@ /* This Source Code Form is subject to the terms of the Mozilla Public | ||
var VECTORS = [ | ||
// all "extracted" conformance test values are encoded as hex, | ||
// whether the key format is hex or otherwise. | ||
var ASSERTIONS = [ | ||
{ | ||
@@ -21,4 +24,102 @@ assertion: "eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiIxMjcuMC4wLjEiLCJleHAiOjEzMzU1NjI2OTg3NjgsImlhdCI6MTMzNTU1OTA5ODc2OCwicHVibGljLWtleSI6eyJhbGdvcml0aG0iOiJEUyIsInkiOiIyN2Y2OTgzMWIzNzdlMmY1NzRiZGE5Njg1YWJmNTM5OTY1ZDAyNDI2Mjg0ZDZmYzViOWVkMjA0MzJmN2U5Yjg1YTFjMjJiMTQ2M2I0NmQwMzljMTIzOWJkZWI2NDc1ZDZjMDM0MWJlZmRiYzBjYjJmMjQ4MTUzYjRjMzFkZDMxNWFjZjFkZmY0ZWUwYmY2NGY4OTUyN2VlMTlmNTkxNTM3NWFjZTNkNTZjMWQ1NDUzY2FjNmRkMTE4NzU3NTI3MmRhYjBlZGQzMGYxYjRlOTI2Yzg3YTNlNGFjYWY2NmY5MmZlZDFhMDRhYjI3Y2NjNDkxM2FmZTI0ZGRjZjNmZTk4IiwicCI6ImZmNjAwNDgzZGI2YWJmYzViNDVlYWI3ODU5NGIzNTMzZDU1MGQ5ZjFiZjJhOTkyYTdhOGRhYTZkYzM0ZjgwNDVhZDRlNmUwYzQyOWQzMzRlZWVhYWVmZDdlMjNkNDgxMGJlMDBlNGNjMTQ5MmNiYTMyNWJhODFmZjJkNWE1YjMwNWE4ZDE3ZWIzYmY0YTA2YTM0OWQzOTJlMDBkMzI5NzQ0YTUxNzkzODAzNDRlODJhMThjNDc5MzM0MzhmODkxZTIyYWVlZjgxMmQ2OWM4Zjc1ZTMyNmNiNzBlYTAwMGMzZjc3NmRmZGJkNjA0NjM4YzJlZjcxN2ZjMjZkMDJlMTciLCJxIjoiZTIxZTA0ZjkxMWQxZWQ3OTkxMDA4ZWNhYWIzYmY3NzU5ODQzMDljMyIsImciOiJjNTJhNGEwZmYzYjdlNjFmZGYxODY3Y2U4NDEzODM2OWE2MTU0ZjRhZmE5Mjk2NmUzYzgyN2UyNWNmYTZjZjUwOGI5MGU1ZGU0MTllMTMzN2UwN2EyZTllMmEzY2Q1ZGVhNzA0ZDE3NWY4ZWJmNmFmMzk3ZDY5ZTExMGI5NmFmYjE3YzdhMDMyNTkzMjllNDgyOWIwZDAzYmJjNzg5NmIxNWI0YWRlNTNlMTMwODU4Y2MzNGQ5NjI2OWFhODkwNDFmNDA5MTM2YzcyNDJhMzg4OTVjOWQ1YmNjYWQ0ZjM4OWFmMWQ3YTRiZDEzOThiZDA3MmRmZmE4OTYyMzMzOTdhIn0sInByaW5jaXBhbCI6eyJlbWFpbCI6ImJlbkBhZGlkYS5uZXQifX0.MklRRWfQweUwYR2crhFU2EuLyUOZlpY4zJgg9LSWDF1MQIGJtNZAclB_tU4sNWfWyrHBa6ICXGfT9mMbkWwPIZC714clAkCMAQXiL2FhuzZSHlnYRO0_BFLO0LqtxIbwdGAQ0WvmaS5lPCgwHdoJbIHPVupebT1C-nUUu21pBoFI_8sPjzINwGBlE6K6WQQy0KbF2m0VDZY5EAYa4mh4o84xiABCoYZYSEeA9FIzmYRJEVrqYHjQeVucZdqkDDCTEK49nVIR4hi8Mm1EItYDn__HDydZORotzfOHuLmB9xyVgBX_tcKJ9mND7MQJVeOumhDAx9QyXtRUhPhKUTDNgA~eyJhbGciOiJEUzEyOCJ9.eyJleHAiOjEzMzU1NTk0MTU3MzMsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6MTAwMDEifQ.BBoFaSGq0UAYDi9vdbsoBegeJ7FHVDxzODiV8MD8pF0emOPp1i_Uzg", | ||
var assertion = VECTORS[0].assertion; | ||
var pk = jwcrypto.loadPublicKeyFromObject(VECTORS[0].root); | ||
// lots of redundant stuff in here to make sure that we are doing | ||
// parsing of keys properly. | ||
var PUBLIC_KEYS = [ | ||
// some older format | ||
{key: | ||
{"algorithm":"RS","n":"13717766671510433111303151806101127171813773557424962001210686599690717644398501153133960329815327700526221729490916021955004415636643109524427762578738613915853895591332921269523141755077814022043323454871557827878869765578483437974192481801184235473918125161566266295979176194039841474030846700306142580608077665527626562098429368267997746767380874004089196208403356658867000112308693077043530239627194850786092251128137244380236693014852428390414510793421293487373711079360003639159681004539188014924495483277607084448583613608953997565952445532663265804891482606228128383798830560843667395414521699843061983900619","e":"65537"}, | ||
"algorithm": "RSA", | ||
"modulus": "6caa67a080c2f20e61d8395ed28914398c100e9d0dce3542dcf74013098438239873ac1376769f09f99779f21e68a529bc8d41145e27990ccd3522594844c35143884b135a1eb5ddf0944db124aa4f125a753f9e336a52c7e2dff89832509e6b2c3932dede84bc2c4d138ba956e0f00e2888365bc0f60125753eca43d4ae1ba09c74a9f70dd4b9063cae2d7857e21e12c2336e652d906aa462dd838053208bb5a5ef5bfe2d1f4a9584c95f16d6b81052c58df5fd4927d0aece42937ba25f0612d59dc92151f32fc86196f4e22a74ba410070683bf86f6cac24153185a867fbb149ea96471a0b10aabc390659b2f2db05305e58f66be80c2ff7798fa4e85673cb", | ||
"exponent": "10001" | ||
}, | ||
{key: | ||
{"algorithm":"DS","y":"85340755e9ccc1396aa37482e8e078f2a5c105f5ddf0fbd67c4c878638fa0d0ab6d500282739f3913f32854d0592c89721779997918464051f3a7a17ce8410a1282dbbe5a1fc7fa0925fc0dc3928dd1d021d1d47a4566ed33391313f99b6ce514ff6d6499cb78d3ea8d374768b72140bd5060b898d5a2afba3bc1fceec4ef58e43d4b0eb5ad06f3acf1574af94327137f36ede81bc7f34e8b52c4d57ef42380829259839202c420b60ddfba6238014b21f7d368b020e69ac4991639986e14f63588a1bf774ac9b4589357a2d12f4a1540afb4ec295a8bddf75446618d9ae07d24cc8e198cfdabbaec85d92e194db82a8c8e539ab6b081e9260f041fd549dd59c","p":"d6c4e5045697756c7a312d02c2289c25d40f9954261f7b5876214b6df109c738b76226b199bb7e33f8fc7ac1dcc316e1e7c78973951bfc6ff2e00cc987cd76fcfb0b8c0096b0b460fffac960ca4136c28f4bfb580de47cf7e7934c3985e3b3d943b77f06ef2af3ac3494fc3c6fc49810a63853862a02bb1c824a01b7fc688e4028527a58ad58c9d512922660db5d505bc263af293bc93bcd6d885a157579d7f52952236dd9d06a4fc3bc2247d21f1a70f5848eb0176513537c983f5a36737f01f82b44546e8e7f0fabc457e3de1d9c5dba96965b10a2a0580b0ad0f88179e10066107fb74314a07e6745863bc797b7002ebec0b000a98eb697414709ac17b401","q":"b1e370f6472c8754ccd75e99666ec8ef1fd748b748bbbc08503d82ce8055ab3b","g":"9a8269ab2e3b733a5242179d8f8ddb17ff93297d9eab00376db211a22b19c854dfa80166df2132cbc51fb224b0904abb22da2c7b7850f782124cb575b116f41ea7c4fc75b1d77525204cd7c23a15999004c23cdeb72359ee74e886a1dde7855ae05fe847447d0a68059002c3819a75dc7dcbb30e39efac36e07e2c404b7ca98b263b25fa314ba93c0625718bd489cea6d04ba4b0b7f156eeb4c56c44b50e4fb5bce9d7ae0d55b379225feb0214a04bed72f33e0664d290e7c840df3e2abb5e48189fa4e90646f1867db289c6560476799f7be8420a6dc01d078de437f280fff2d7ddf1248d56e1a54b933a41629d6c252983c58795105802d30d7bcd819cf6ef"}, | ||
"algorithm": "DSA", | ||
"y": "85340755e9ccc1396aa37482e8e078f2a5c105f5ddf0fbd67c4c878638fa0d0ab6d500282739f3913f32854d0592c89721779997918464051f3a7a17ce8410a1282dbbe5a1fc7fa0925fc0dc3928dd1d021d1d47a4566ed33391313f99b6ce514ff6d6499cb78d3ea8d374768b72140bd5060b898d5a2afba3bc1fceec4ef58e43d4b0eb5ad06f3acf1574af94327137f36ede81bc7f34e8b52c4d57ef42380829259839202c420b60ddfba6238014b21f7d368b020e69ac4991639986e14f63588a1bf774ac9b4589357a2d12f4a1540afb4ec295a8bddf75446618d9ae07d24cc8e198cfdabbaec85d92e194db82a8c8e539ab6b081e9260f041fd549dd59c", | ||
"p":"d6c4e5045697756c7a312d02c2289c25d40f9954261f7b5876214b6df109c738b76226b199bb7e33f8fc7ac1dcc316e1e7c78973951bfc6ff2e00cc987cd76fcfb0b8c0096b0b460fffac960ca4136c28f4bfb580de47cf7e7934c3985e3b3d943b77f06ef2af3ac3494fc3c6fc49810a63853862a02bb1c824a01b7fc688e4028527a58ad58c9d512922660db5d505bc263af293bc93bcd6d885a157579d7f52952236dd9d06a4fc3bc2247d21f1a70f5848eb0176513537c983f5a36737f01f82b44546e8e7f0fabc457e3de1d9c5dba96965b10a2a0580b0ad0f88179e10066107fb74314a07e6745863bc797b7002ebec0b000a98eb697414709ac17b401", | ||
"q":"b1e370f6472c8754ccd75e99666ec8ef1fd748b748bbbc08503d82ce8055ab3b", | ||
"g":"9a8269ab2e3b733a5242179d8f8ddb17ff93297d9eab00376db211a22b19c854dfa80166df2132cbc51fb224b0904abb22da2c7b7850f782124cb575b116f41ea7c4fc75b1d77525204cd7c23a15999004c23cdeb72359ee74e886a1dde7855ae05fe847447d0a68059002c3819a75dc7dcbb30e39efac36e07e2c404b7ca98b263b25fa314ba93c0625718bd489cea6d04ba4b0b7f156eeb4c56c44b50e4fb5bce9d7ae0d55b379225feb0214a04bed72f33e0664d290e7c840df3e2abb5e48189fa4e90646f1867db289c6560476799f7be8420a6dc01d078de437f280fff2d7ddf1248d56e1a54b933a41629d6c252983c58795105802d30d7bcd819cf6ef" | ||
}, | ||
// newer format stuff | ||
{key: {"algorithm":"RS","version":"2012.08.15","modulus":"Zx5aDEB62oTwkoTikAp4ck+HGQv4oIa8+L5KdjcANbvjR2jtXAjswepZrwvzYFhP/mwFl/Oy4YElW3OyPy9I6K0OR0xQgBsOprpEOFNEFs14Jy9LJi59yb4gA+xSUlN/SN8s0JKzQ2jYwD8ibZicZWt2C2vvyaBmWaUZm2o5V59DYH6D7ecZSPkwWi9PoD3lCeK2ZeJa7jZpD02bCvybbwyFnDPca2o9MP7/r8Fs6BWJqGAIxlDqvvLUZ+2CeKAie5a98lyBvE//kc0ANY9yjDcWp+c7IXx+lSn5AobiicM2PbiWUdqAXWOguf61ooT1yGazSAeAhZElcy+jd8VZ3Q==","exponent":"AQAB"}, | ||
algorithm: "RSA", | ||
modulus: "671e5a0c407ada84f09284e2900a78724f87190bf8a086bcf8be4a76370035bbe34768ed5c08ecc1ea59af0bf360584ffe6c0597f3b2e181255b73b23f2f48e8ad0e474c50801b0ea6ba4438534416cd78272f4b262e7dc9be2003ec5252537f48df2cd092b34368d8c03f226d989c656b760b6befc9a06659a5199b6a39579f43607e83ede71948f9305a2f4fa03de509e2b665e25aee36690f4d9b0afc9b6f0c859c33dc6b6a3d30feffafc16ce81589a86008c650eabef2d467ed8278a0227b96bdf25c81bc4fff91cd00358f728c3716a7e73b217c7e9529f90286e289c3363db89651da805d63a0b9feb5a284f5c866b3480780859125732fa377c559dd", | ||
exponent: "10001" | ||
}, | ||
{key: {"algorithm":"DS","version":"2012.08.15","y":"EgxmUUA4YD/wNDJH3mX+QTIiIwDtn2cAaCkXr0HGKFN3eTuoOqt6iCvTXEkFZCSIog9ml6wKIasJO8mcT+ZVD+40oD+CXKeRJ7LXPnpSuB5rSvgUxEtVY4/8wWra5RnhoHn8BOgb6tq/zOn9EEV6nE6h/t4rVb/dLW1QTono1Q8=","p":"/2AEg9tqv8W0Xqt4WUs1M9VQ2fG/Kpkqeo2qbcNPgEWtTm4MQp0zTu6q79fiPUgQvgDkzBSSy6MluoH/LVpbMFqNF+s79KBqNJ05LgDTKXRKUXk4A0ToKhjEeTNDj4keIq7vgS1pyPdeMmy3DqAAw/d239vWBGOMLvcX/CbQLhc=","q":"4h4E+RHR7XmRAI7Kqzv3dZhDCcM=","g":"xSpKD/O35h/fGGfOhBODaaYVT0r6kpZuPIJ+Jc+mz1CLkOXeQZ4TN+B6Lp4qPNXepwTRdfjr9q85fWnhELlq+xfHoDJZMp5IKbDQO7x4lrFbSt5T4TCFjMNNliaaqJBB9AkTbHJCo4iVydW8ytTzia8dekvROYvQct/6iWIzOXo="}, | ||
algorithm: "DSA", | ||
y: "120c66514038603ff0343247de65fe4132222300ed9f6700682917af41c6285377793ba83aab7a882bd35c4905642488a20f6697ac0a21ab093bc99c4fe6550fee34a03f825ca79127b2d73e7a52b81e6b4af814c44b55638ffcc16adae519e1a079fc04e81beadabfcce9fd10457a9c4ea1fede2b55bfdd2d6d504e89e8d50f", | ||
p: "ff600483db6abfc5b45eab78594b3533d550d9f1bf2a992a7a8daa6dc34f8045ad4e6e0c429d334eeeaaefd7e23d4810be00e4cc1492cba325ba81ff2d5a5b305a8d17eb3bf4a06a349d392e00d329744a5179380344e82a18c47933438f891e22aeef812d69c8f75e326cb70ea000c3f776dfdbd604638c2ef717fc26d02e17", | ||
q: "e21e04f911d1ed7991008ecaab3bf775984309c3", | ||
g: "c52a4a0ff3b7e61fdf1867ce84138369a6154f4afa92966e3c827e25cfa6cf508b90e5de419e1337e07a2e9e2a3cd5dea704d175f8ebf6af397d69e110b96afb17c7a03259329e4829b0d03bbc7896b15b4ade53e130858cc34d96269aa89041f409136c7242a38895c9d5bccad4f389af1d7a4bd1398bd072dffa896233397a" | ||
} | ||
]; | ||
var SECRET_KEYS = [ | ||
// some older format | ||
{key: {"algorithm":"RS","n":"20134313735633460324009287026871866843796618829620508645366930147178633379962222680717023249272820533094597858267338839317194088010291491177769775876107422860068508860247049222474149118476550449553385103674247179042986058916353175342114256161775949273688758085819167193333453685722288255237120463565853164873820456398458238032740006210438495274446844719785231515965591829050825221266535165134208095847989613986610614188375152043921071400070392986604047644804201712592855063810754615032686203014888431566402289466164948592805558518095237018685881993839526503295276463699240570317434052145766048425317464308591867033229","e":"65537","d":"19912193271912768320801042607377102668932573245998804451543589278716388359077643176037858688654784168210221181710168294726713423261654221419899755155622419476821952992478329009650113690967531941305721990776853634778706660704709014856093403708887290785737265461865564527956947482893699604420994640059160581474789494003360406077834187408037753163211562475595869258819628232479453155832681163098548915011781484585176809911841844302069549440225122202503690543386025709106303300834368406079203744646769675025699622363046762636041586213509577129540673029343027227311933661272432441022093661699434070335168027711025359541953"}, | ||
"algorithm": "RSA", | ||
"modulus": "9f7e96b93b49734d9879f490b67ed1ca8c82c6f2fd0348721a1c820b3bc5cdcbeb58af3a4c161443d4bee3c62bfb778c659170fb0307187bef2f397306fa9575fd5538880464a29629f198370897c0cdc3cfa6298aec9b38cb5da4f3e2c3f706d7d5b5e30ce20c9fd98c6eee91b911d91127739e9dac96d7c775e1fed22c13a5b56e205c8cdb809d28a8496e326ec2fbef1103a14e5ac7f4c864e934e22ba5797fff05be25b95e8599932ef8bd23dc08140c7ae39d4b4f52aec9607da6e51a68b08560707e72b6dde8d5b4f92a8e263c05078597e3f5dd8390581214d9beef4baa63f36a7488049dcd3f463248f14d472d1d6e3776ed68232c0b184bcad9768d", | ||
"exponent": "10001", | ||
"secretExponent": "9dbc25f7fee83f3e2863c4393222edfbf1468cd756de5e5169fd73a70470357d4cbda25e774d06b1a6bf3aa88c6adfea5bb0a119bdfed07a112c95166b7a7b41fb4ec2dfd1e86cdb31941b43a21de2b21ccb49bba0072be3d94c3d8c6d61fcf62992d3953ef27825c6931a4a9a977b4d3fa7d2b2b5a130752a702d1744680eecaabae446478a1178235049796f4d54e9092886f6ee8ae369f262ff378b459daa3e055358e7ffbb7ebce84bb2f4fe35029617a934f4cfefdaa8c3bae18e85a83a22e3080c33388df3f979f3316affe74e62fe6a4ac4cb2604ccd243fdaa07fd332f5b9b5e203ea127c8fa81608c253c2310eee12c18fc821fb59dda5621ead6c1" | ||
}, | ||
{key: | ||
{"algorithm":"DS","x":"c80486db596571fe799240b371b1a214b9809d45","p":"ff600483db6abfc5b45eab78594b3533d550d9f1bf2a992a7a8daa6dc34f8045ad4e6e0c429d334eeeaaefd7e23d4810be00e4cc1492cba325ba81ff2d5a5b305a8d17eb3bf4a06a349d392e00d329744a5179380344e82a18c47933438f891e22aeef812d69c8f75e326cb70ea000c3f776dfdbd604638c2ef717fc26d02e17","q":"e21e04f911d1ed7991008ecaab3bf775984309c3","g":"c52a4a0ff3b7e61fdf1867ce84138369a6154f4afa92966e3c827e25cfa6cf508b90e5de419e1337e07a2e9e2a3cd5dea704d175f8ebf6af397d69e110b96afb17c7a03259329e4829b0d03bbc7896b15b4ade53e130858cc34d96269aa89041f409136c7242a38895c9d5bccad4f389af1d7a4bd1398bd072dffa896233397a"}, | ||
"algorithm": "DSA", | ||
"x":"c80486db596571fe799240b371b1a214b9809d45", | ||
"p":"ff600483db6abfc5b45eab78594b3533d550d9f1bf2a992a7a8daa6dc34f8045ad4e6e0c429d334eeeaaefd7e23d4810be00e4cc1492cba325ba81ff2d5a5b305a8d17eb3bf4a06a349d392e00d329744a5179380344e82a18c47933438f891e22aeef812d69c8f75e326cb70ea000c3f776dfdbd604638c2ef717fc26d02e17","q":"e21e04f911d1ed7991008ecaab3bf775984309c3", | ||
"g":"c52a4a0ff3b7e61fdf1867ce84138369a6154f4afa92966e3c827e25cfa6cf508b90e5de419e1337e07a2e9e2a3cd5dea704d175f8ebf6af397d69e110b96afb17c7a03259329e4829b0d03bbc7896b15b4ade53e130858cc34d96269aa89041f409136c7242a38895c9d5bccad4f389af1d7a4bd1398bd072dffa896233397a" | ||
}, | ||
{ | ||
key: {"algorithm":"RS","version":"2012.08.15","modulus":"Zx5aDEB62oTwkoTikAp4ck+HGQv4oIa8+L5KdjcANbvjR2jtXAjswepZrwvzYFhP/mwFl/Oy4YElW3OyPy9I6K0OR0xQgBsOprpEOFNEFs14Jy9LJi59yb4gA+xSUlN/SN8s0JKzQ2jYwD8ibZicZWt2C2vvyaBmWaUZm2o5V59DYH6D7ecZSPkwWi9PoD3lCeK2ZeJa7jZpD02bCvybbwyFnDPca2o9MP7/r8Fs6BWJqGAIxlDqvvLUZ+2CeKAie5a98lyBvE//kc0ANY9yjDcWp+c7IXx+lSn5AobiicM2PbiWUdqAXWOguf61ooT1yGazSAeAhZElcy+jd8VZ3Q==","exponent":"AQAB","secretExponent":"Kh75xVtpU21OH2tsaE3+mSLnGlILgvbGpgyEufkJeul+kyLHIfr7StKBQ8Fr7oTkWBajykffX8GzEsIVoz2bWH+n/3OqxklHGM+pIiDRBUd0tvzYg4YmF4wz46ZakgpNSeTvl1r1IqnnL9AaLg5ShBL7Kvsx/XgplqCb7yHavnFoQiVB5Fg4fEoUxrOzRrTkssxS5rverkczW5speghsOiEffszkW8tF7rh/xdIelh8xGVfCANkLVaYb9L/4vgZ/ZcCvLcC2oFOCDB1335QSO9iNvMon71r3xER8397cYAFArRExfdYcts8NKkJJ86dsJhydoqG8as72VLge3dQYAQ=="}, | ||
algorithm: "RSA", | ||
modulus: "671e5a0c407ada84f09284e2900a78724f87190bf8a086bcf8be4a76370035bbe34768ed5c08ecc1ea59af0bf360584ffe6c0597f3b2e181255b73b23f2f48e8ad0e474c50801b0ea6ba4438534416cd78272f4b262e7dc9be2003ec5252537f48df2cd092b34368d8c03f226d989c656b760b6befc9a06659a5199b6a39579f43607e83ede71948f9305a2f4fa03de509e2b665e25aee36690f4d9b0afc9b6f0c859c33dc6b6a3d30feffafc16ce81589a86008c650eabef2d467ed8278a0227b96bdf25c81bc4fff91cd00358f728c3716a7e73b217c7e9529f90286e289c3363db89651da805d63a0b9feb5a284f5c866b3480780859125732fa377c559dd", | ||
exponent: "10001", | ||
secretExponent: "2a1ef9c55b69536d4e1f6b6c684dfe9922e71a520b82f6c6a60c84b9f9097ae97e9322c721fafb4ad28143c16bee84e45816a3ca47df5fc1b312c215a33d9b587fa7ff73aac6494718cfa92220d1054774b6fcd8838626178c33e3a65a920a4d49e4ef975af522a9e72fd01a2e0e528412fb2afb31fd782996a09bef21dabe7168422541e458387c4a14c6b3b346b4e4b2cc52e6bbdeae47335b9b297a086c3a211f7ecce45bcb45eeb87fc5d21e961f311957c200d90b55a61bf4bff8be067f65c0af2dc0b6a053820c1d77df94123bd88dbcca27ef5af7c4447cdfdedc600140ad11317dd61cb6cf0d2a4249f3a76c261c9da2a1bc6acef654b81eddd41801" | ||
}, | ||
{ | ||
key: {"algorithm":"DS","version":"2012.08.15","x":"rwzgsSIrU6h+BleE/2wDM7sZZtk=","p":"/2AEg9tqv8W0Xqt4WUs1M9VQ2fG/Kpkqeo2qbcNPgEWtTm4MQp0zTu6q79fiPUgQvgDkzBSSy6MluoH/LVpbMFqNF+s79KBqNJ05LgDTKXRKUXk4A0ToKhjEeTNDj4keIq7vgS1pyPdeMmy3DqAAw/d239vWBGOMLvcX/CbQLhc=","q":"4h4E+RHR7XmRAI7Kqzv3dZhDCcM=","g":"xSpKD/O35h/fGGfOhBODaaYVT0r6kpZuPIJ+Jc+mz1CLkOXeQZ4TN+B6Lp4qPNXepwTRdfjr9q85fWnhELlq+xfHoDJZMp5IKbDQO7x4lrFbSt5T4TCFjMNNliaaqJBB9AkTbHJCo4iVydW8ytTzia8dekvROYvQct/6iWIzOXo="}, | ||
algorithm: "DSA", | ||
p: "ff600483db6abfc5b45eab78594b3533d550d9f1bf2a992a7a8daa6dc34f8045ad4e6e0c429d334eeeaaefd7e23d4810be00e4cc1492cba325ba81ff2d5a5b305a8d17eb3bf4a06a349d392e00d329744a5179380344e82a18c47933438f891e22aeef812d69c8f75e326cb70ea000c3f776dfdbd604638c2ef717fc26d02e17", | ||
q: "e21e04f911d1ed7991008ecaab3bf775984309c3", | ||
g: "c52a4a0ff3b7e61fdf1867ce84138369a6154f4afa92966e3c827e25cfa6cf508b90e5de419e1337e07a2e9e2a3cd5dea704d175f8ebf6af397d69e110b96afb17c7a03259329e4829b0d03bbc7896b15b4ade53e130858cc34d96269aa89041f409136c7242a38895c9d5bccad4f389af1d7a4bd1398bd072dffa896233397a", | ||
x: "af0ce0b1222b53a87e065784ff6c0333bb1966d9" | ||
} | ||
]; | ||
var CERTS = [ | ||
{"cert": "eyJhbGciOiJSUzI1NiJ9.eyJwdWJsaWMta2V5Ijp7ImFsZ29yaXRobSI6IkRTIiwieSI6ImJlODNmMWNmNGRjMjU2OWFmODIyYjZiNWM1NDE3OTJlMzIxZDljNjE5NGVhNTY3MTQyZTk4NjllNDk1YmIyNWZiZjQ5NjkzYzZmNTc3ZWZlMTYyMDkzZWYyN2M3YzU1MGVjM2Q4MTBiZjAwNWU1MjNkM2VlNmM3NzM0NmUwNWZkY2Q5YWRmNTg0NjcwYjM2ODAwNWIxZWQyZTI2YWRjMGVlZjliMmE4NzFkN2Q1MWU1NjAxMzQ5ODIyNzEwZjMwMjhhNThiNWFmNDVmNzJiODM2NmY1MzA5MzZhOThjYTdlYWZjN2JhMzFkNmUxMzYzNjM2NWUxMTNhMGE1YjYyNmMiLCJwIjoiZmY2MDA0ODNkYjZhYmZjNWI0NWVhYjc4NTk0YjM1MzNkNTUwZDlmMWJmMmE5OTJhN2E4ZGFhNmRjMzRmODA0NWFkNGU2ZTBjNDI5ZDMzNGVlZWFhZWZkN2UyM2Q0ODEwYmUwMGU0Y2MxNDkyY2JhMzI1YmE4MWZmMmQ1YTViMzA1YThkMTdlYjNiZjRhMDZhMzQ5ZDM5MmUwMGQzMjk3NDRhNTE3OTM4MDM0NGU4MmExOGM0NzkzMzQzOGY4OTFlMjJhZWVmODEyZDY5YzhmNzVlMzI2Y2I3MGVhMDAwYzNmNzc2ZGZkYmQ2MDQ2MzhjMmVmNzE3ZmMyNmQwMmUxNyIsInEiOiJlMjFlMDRmOTExZDFlZDc5OTEwMDhlY2FhYjNiZjc3NTk4NDMwOWMzIiwiZyI6ImM1MmE0YTBmZjNiN2U2MWZkZjE4NjdjZTg0MTM4MzY5YTYxNTRmNGFmYTkyOTY2ZTNjODI3ZTI1Y2ZhNmNmNTA4YjkwZTVkZTQxOWUxMzM3ZTA3YTJlOWUyYTNjZDVkZWE3MDRkMTc1ZjhlYmY2YWYzOTdkNjllMTEwYjk2YWZiMTdjN2EwMzI1OTMyOWU0ODI5YjBkMDNiYmM3ODk2YjE1YjRhZGU1M2UxMzA4NThjYzM0ZDk2MjY5YWE4OTA0MWY0MDkxMzZjNzI0MmEzODg5NWM5ZDViY2NhZDRmMzg5YWYxZDdhNGJkMTM5OGJkMDcyZGZmYTg5NjIzMzM5N2EifSwicHJpbmNpcGFsIjp7ImVtYWlsIjoidXNlckBleGFtcGxlaWRwLmNvbSJ9LCJpYXQiOjEzNDI2MzQzNTU5MTMsImV4cCI6MTM0MjYzNDM2MTkxMywiaXNzIjoiZXhhbXBsZWlkcC5jb20ifQ.EOe_edjbSfgeyYZZgD1KaCax2ZBCi2_spd8ngvejRUaZZPsrSvNrmc3BZreTYSQAp895zmgSBbC7StaMBWclQzU4gBFMw9kXzSoDUOsXc3kBY1yYju0FsN1JwLf2znci_O1Tj4jEacJMHLRZSuEg0SVZJLQNgp7c4uHd4RSRR42sik8hB_fYAyzM57kZQCPV7Bx3ag_9aIDB1yiylAaMBHkxpOmDgJPEk-UMBMSgw4Mi7Daf7LpfdF7UExRr5hyrO_KUxCcxX2tU3WaH6lreFluPQYV5p_rr863WTg_iTu7OQBLiS2RR89VtKEVcf-b_mXF-dzU2n4T-ikK8GLCXkw", | ||
"issued_at":1342634355913,"expires_at":1342634361913,"issuer":"exampleidp.com", | ||
"email": "user@exampleidp.com", | ||
"certifierPublicKey": {"algorithm":"RS","n":"14992830413702950214310095212044491259620359262383741324696388958190897089691526259734048412721912364240221301689826865084526414386073707804839978986676709963946069225361038897793675105866773424177081334731736862288361853661697790251045350661007112837048725805572051406892322870828536513516637815563734426985085169776230353505099335068959396036415837272499551706990150656379682592552383284722119011793645821942132094135988926383389368449569136547237729302181561293580509148227224997417221099523657138090327493805636962561720869470208329064396135474786068129369609669835010448697628273776942729022409017231229381035477","e":"65537"}, | ||
"containedPublicKey": {"algorithm":"DS","y":"be83f1cf4dc2569af822b6b5c541792e321d9c6194ea567142e9869e495bb25fbf49693c6f577efe162093ef27c7c550ec3d810bf005e523d3ee6c77346e05fdcd9adf584670b368005b1ed2e26adc0eef9b2a871d7d51e5601349822710f3028a58b5af45f72b8366f530936a98ca7eafc7ba31d6e13636365e113a0a5b626c","p":"ff600483db6abfc5b45eab78594b3533d550d9f1bf2a992a7a8daa6dc34f8045ad4e6e0c429d334eeeaaefd7e23d4810be00e4cc1492cba325ba81ff2d5a5b305a8d17eb3bf4a06a349d392e00d329744a5179380344e82a18c47933438f891e22aeef812d69c8f75e326cb70ea000c3f776dfdbd604638c2ef717fc26d02e17","q":"e21e04f911d1ed7991008ecaab3bf775984309c3","g":"c52a4a0ff3b7e61fdf1867ce84138369a6154f4afa92966e3c827e25cfa6cf508b90e5de419e1337e07a2e9e2a3cd5dea704d175f8ebf6af397d69e110b96afb17c7a03259329e4829b0d03bbc7896b15b4ade53e130858cc34d96269aa89041f409136c7242a38895c9d5bccad4f389af1d7a4bd1398bd072dffa896233397a"} | ||
}, | ||
{ | ||
cert: "eyJhbGciOiJSUzI1NiJ9.eyJwdWJsaWNLZXkiOnsiYWxnb3JpdGhtIjoiRFMiLCJ2ZXJzaW9uIjoiMjAxMi4wOC4xNSIsInkiOiJFZ3htVVVBNFlEL3dOREpIM21YK1FUSWlJd0R0bjJjQWFDa1hyMEhHS0ZOM2VUdW9PcXQ2aUN2VFhFa0ZaQ1NJb2c5bWw2d0tJYXNKTzhtY1QrWlZEKzQwb0QrQ1hLZVJKN0xYUG5wU3VCNXJTdmdVeEV0Vlk0Lzh3V3JhNVJuaG9IbjhCT2diNnRxL3pPbjlFRVY2bkU2aC90NHJWYi9kTFcxUVRvbm8xUTg9IiwicCI6Ii8yQUVnOXRxdjhXMFhxdDRXVXMxTTlWUTJmRy9LcGtxZW8ycWJjTlBnRVd0VG00TVFwMHpUdTZxNzlmaVBVZ1F2Z0RrekJTU3k2TWx1b0gvTFZwYk1GcU5GK3M3OUtCcU5KMDVMZ0RUS1hSS1VYazRBMFRvS2hqRWVUTkRqNGtlSXE3dmdTMXB5UGRlTW15M0RxQUF3L2QyMzl2V0JHT01MdmNYL0NiUUxoYz0iLCJxIjoiNGg0RStSSFI3WG1SQUk3S3F6djNkWmhEQ2NNPSIsImciOiJ4U3BLRC9PMzVoL2ZHR2ZPaEJPRGFhWVZUMHI2a3BadVBJSitKYyttejFDTGtPWGVRWjRUTitCNkxwNHFQTlhlcHdUUmRmanI5cTg1ZlduaEVMbHEreGZIb0RKWk1wNUlLYkRRTzd4NGxyRmJTdDVUNFRDRmpNTk5saWFhcUpCQjlBa1RiSEpDbzRpVnlkVzh5dFR6aWE4ZGVrdlJPWXZRY3QvNmlXSXpPWG89In0sInByaW5jaXBhbCI6eyJlbWFpbCI6InVzZXJAZXhhbXBsZWlkcC5jb20ifSwidmVyc2lvbiI6IjIwMTIuMDguMTUiLCJpYXQiOjEzNDI4MDE2OTA1NzAsImV4cCI6MTM0MjgwMTY5NjU3MCwiaXNzIjoiZXhhbXBsZWlkcC5jb20ifQ.IP1owFXMabG0FtLJmp9owqy5KdaY1qMERNpaCgvBZxccofC4cGRqJGsvNbPMMWlxRYUt_jR6F2M_hSEXHDJQrAhthZGaZYEDTRZIkBVQO_ufA7_6VeeY5Z-cvUBaXEtJD0HsYJhSDRsUS3WdTyCJasv7csA6_4ovuNm69rmY3QxlQs0wux4tAN_5P5xM6Y4rZwZaBpdLRmwxGcObEsQ_OS6c8OER5TSXrbKaFPL5iThL5xI_mdi7mCqcwPnPtLwcV2ARQ3qFqd8Xf30RP5cAetC-0pwr4o4xuby81ZRjf-ulp5lIbLE_uZVTgSZbIR3aP6edqrdJ-wZYf_oDQnNQbA", | ||
"issued_at":1342801690570,"expires_at":1342801696570,"issuer":"exampleidp.com", | ||
"email":"user@exampleidp.com", | ||
certifierPublicKey: {"algorithm":"RS","version":"2012.08.15","modulus":"Zx5aDEB62oTwkoTikAp4ck+HGQv4oIa8+L5KdjcANbvjR2jtXAjswepZrwvzYFhP/mwFl/Oy4YElW3OyPy9I6K0OR0xQgBsOprpEOFNEFs14Jy9LJi59yb4gA+xSUlN/SN8s0JKzQ2jYwD8ibZicZWt2C2vvyaBmWaUZm2o5V59DYH6D7ecZSPkwWi9PoD3lCeK2ZeJa7jZpD02bCvybbwyFnDPca2o9MP7/r8Fs6BWJqGAIxlDqvvLUZ+2CeKAie5a98lyBvE//kc0ANY9yjDcWp+c7IXx+lSn5AobiicM2PbiWUdqAXWOguf61ooT1yGazSAeAhZElcy+jd8VZ3Q==","exponent":"AQAB"}, | ||
containedPublicKey: {"algorithm":"DS","version":"2012.08.15","y":"EgxmUUA4YD/wNDJH3mX+QTIiIwDtn2cAaCkXr0HGKFN3eTuoOqt6iCvTXEkFZCSIog9ml6wKIasJO8mcT+ZVD+40oD+CXKeRJ7LXPnpSuB5rSvgUxEtVY4/8wWra5RnhoHn8BOgb6tq/zOn9EEV6nE6h/t4rVb/dLW1QTono1Q8=","p":"/2AEg9tqv8W0Xqt4WUs1M9VQ2fG/Kpkqeo2qbcNPgEWtTm4MQp0zTu6q79fiPUgQvgDkzBSSy6MluoH/LVpbMFqNF+s79KBqNJ05LgDTKXRKUXk4A0ToKhjEeTNDj4keIq7vgS1pyPdeMmy3DqAAw/d239vWBGOMLvcX/CbQLhc=","q":"4h4E+RHR7XmRAI7Kqzv3dZhDCcM=","g":"xSpKD/O35h/fGGfOhBODaaYVT0r6kpZuPIJ+Jc+mz1CLkOXeQZ4TN+B6Lp4qPNXepwTRdfjr9q85fWnhELlq+xfHoDJZMp5IKbDQO7x4lrFbSt5T4TCFjMNNliaaqJBB9AkTbHJCo4iVydW8ytTzia8dekvROYvQct/6iWIzOXo="} | ||
} | ||
]; | ||
var BACKED_ASSERTIONS = [ | ||
{"assertion": "eyJhbGciOiJSUzI1NiJ9.eyJwdWJsaWMta2V5Ijp7ImFsZ29yaXRobSI6IkRTIiwieSI6IjczNzAxMTViMzAzNDllMzg5NzgwMzRlMTBjYjRkMzExYmFmNGVhYzkyZmM1M2IzNWMyYTc5ODBkZmEwZDVmZGY1NDYwOWQyYzU2YTNhNTc3NGRhYjg0YjAxZWVjN2E2Nzc2OTRjYWY1MDFlZGZhNGUzMDg1YWYzMjk3ZGZlNTg0NTkwZmFkN2Y1YjgzMzI3NDE5Njk0NWE5OTg1ODc4NGI1OGJmYzBiNjZhNjk3NGVjYjcwMjdkMzkwODliMDI2MjYzNTJhYjFjODZhYjliMmVlYmMwZmZiZGQwOWFkZDNkNDBlZDI0MjAyMzg4YjQ1ODg2ZGI3MTQyMzQ4NWRmNGUiLCJwIjoiZmY2MDA0ODNkYjZhYmZjNWI0NWVhYjc4NTk0YjM1MzNkNTUwZDlmMWJmMmE5OTJhN2E4ZGFhNmRjMzRmODA0NWFkNGU2ZTBjNDI5ZDMzNGVlZWFhZWZkN2UyM2Q0ODEwYmUwMGU0Y2MxNDkyY2JhMzI1YmE4MWZmMmQ1YTViMzA1YThkMTdlYjNiZjRhMDZhMzQ5ZDM5MmUwMGQzMjk3NDRhNTE3OTM4MDM0NGU4MmExOGM0NzkzMzQzOGY4OTFlMjJhZWVmODEyZDY5YzhmNzVlMzI2Y2I3MGVhMDAwYzNmNzc2ZGZkYmQ2MDQ2MzhjMmVmNzE3ZmMyNmQwMmUxNyIsInEiOiJlMjFlMDRmOTExZDFlZDc5OTEwMDhlY2FhYjNiZjc3NTk4NDMwOWMzIiwiZyI6ImM1MmE0YTBmZjNiN2U2MWZkZjE4NjdjZTg0MTM4MzY5YTYxNTRmNGFmYTkyOTY2ZTNjODI3ZTI1Y2ZhNmNmNTA4YjkwZTVkZTQxOWUxMzM3ZTA3YTJlOWUyYTNjZDVkZWE3MDRkMTc1ZjhlYmY2YWYzOTdkNjllMTEwYjk2YWZiMTdjN2EwMzI1OTMyOWU0ODI5YjBkMDNiYmM3ODk2YjE1YjRhZGU1M2UxMzA4NThjYzM0ZDk2MjY5YWE4OTA0MWY0MDkxMzZjNzI0MmEzODg5NWM5ZDViY2NhZDRmMzg5YWYxZDdhNGJkMTM5OGJkMDcyZGZmYTg5NjIzMzM5N2EifSwicHJpbmNpcGFsIjp7ImVtYWlsIjoidXNlckBleGFtcGxlaWRwLmNvbSJ9LCJpYXQiOjEzNDI2MzU5NTEwMjcsImV4cCI6MTM0MjYzNTk1NzAyNywiaXNzIjoiZXhhbXBsZWlkcC5jb20ifQ.ivdVg3r2kjU26PqicsHrCDKPK_9LNWMbZ7OjAdpXOsi4sGNdSolHM609eT-xoRUdhVz67sq9wnSmtUv1BMOupeSi7i4DCNSwUWHPBH4DOAswG0nCficHjvgrqaOCBOQ95Dk8dLLd9kcf1P_gLmkVVFAaKlPkOawWCoHaF8FBlBIgU9tWYJ5jbSCT6dCwKbBeESTzKzDHV53O6g1Fr-uMZ8-EXnMHhakkxXoF94Tpu-_cuwy3BNVMxWOLpuwb8S9PnF98DCRR9X_6e3UYMNlejOGjSEIalkhFb0dMlj93oIYqUjyrpZxwUPXDrhpxvQFW-tN2PXUAtlID6vjp_n52bg~eyJhbGciOiJEUzEyOCJ9.eyJpYXQiOjEzNDI2MzU5NTEwMjcsImV4cCI6MTM0MjYzNTk1NzAyNywiYXVkIjoiaHR0cHM6Ly9leGFtcGxlLmNvbSJ9.VVg3pg9wwe_g5Kg2GwgdnGtZftxPpGLqd-LHjucpiw9sgkDGHs-I5A", | ||
"certifyingKey": {"algorithm":"RS","n":"22065728673523995313275840949283186147733361077125922117151884405727929358603197277862449100403401708874580160739851743372607390289312514176219745745061161080731994997513081977238890869729018736569475296178956470173744597843997030482898117646152273158717073309419015545324220626878746740658868160778804057923124408381754223997324049665565313870157861356938746339320398255353426803343525261847622455643513993816581672201295385001276849331760685387802142681675064994849190179959904536701035730762770114494100415667933501396487866806200962527123706046621867087261935508571250402047499424810996126895397600099821060652017","e":"65537"}, | ||
"issued_at":1342635951027,"expires_at":1342635957027,"audience":"https://example.com", | ||
"email": 'user@exampleidp.com' | ||
}, | ||
{ | ||
assertion: "eyJhbGciOiJSUzI1NiJ9.eyJwdWJsaWNLZXkiOnsiYWxnb3JpdGhtIjoiRFMiLCJ2ZXJzaW9uIjoiMjAxMi4wOC4xNSIsInkiOiJFZ3htVVVBNFlEL3dOREpIM21YK1FUSWlJd0R0bjJjQWFDa1hyMEhHS0ZOM2VUdW9PcXQ2aUN2VFhFa0ZaQ1NJb2c5bWw2d0tJYXNKTzhtY1QrWlZEKzQwb0QrQ1hLZVJKN0xYUG5wU3VCNXJTdmdVeEV0Vlk0Lzh3V3JhNVJuaG9IbjhCT2diNnRxL3pPbjlFRVY2bkU2aC90NHJWYi9kTFcxUVRvbm8xUTg9IiwicCI6Ii8yQUVnOXRxdjhXMFhxdDRXVXMxTTlWUTJmRy9LcGtxZW8ycWJjTlBnRVd0VG00TVFwMHpUdTZxNzlmaVBVZ1F2Z0RrekJTU3k2TWx1b0gvTFZwYk1GcU5GK3M3OUtCcU5KMDVMZ0RUS1hSS1VYazRBMFRvS2hqRWVUTkRqNGtlSXE3dmdTMXB5UGRlTW15M0RxQUF3L2QyMzl2V0JHT01MdmNYL0NiUUxoYz0iLCJxIjoiNGg0RStSSFI3WG1SQUk3S3F6djNkWmhEQ2NNPSIsImciOiJ4U3BLRC9PMzVoL2ZHR2ZPaEJPRGFhWVZUMHI2a3BadVBJSitKYyttejFDTGtPWGVRWjRUTitCNkxwNHFQTlhlcHdUUmRmanI5cTg1ZlduaEVMbHEreGZIb0RKWk1wNUlLYkRRTzd4NGxyRmJTdDVUNFRDRmpNTk5saWFhcUpCQjlBa1RiSEpDbzRpVnlkVzh5dFR6aWE4ZGVrdlJPWXZRY3QvNmlXSXpPWG89In0sInByaW5jaXBhbCI6eyJlbWFpbCI6InVzZXJAZXhhbXBsZWlkcC5jb20ifSwidmVyc2lvbiI6IjIwMTIuMDguMTUiLCJpYXQiOjEzNDI4MDE2OTA1NzAsImV4cCI6MTM0MjgwMTY5NjU3MCwiaXNzIjoiZXhhbXBsZWlkcC5jb20ifQ.IP1owFXMabG0FtLJmp9owqy5KdaY1qMERNpaCgvBZxccofC4cGRqJGsvNbPMMWlxRYUt_jR6F2M_hSEXHDJQrAhthZGaZYEDTRZIkBVQO_ufA7_6VeeY5Z-cvUBaXEtJD0HsYJhSDRsUS3WdTyCJasv7csA6_4ovuNm69rmY3QxlQs0wux4tAN_5P5xM6Y4rZwZaBpdLRmwxGcObEsQ_OS6c8OER5TSXrbKaFPL5iThL5xI_mdi7mCqcwPnPtLwcV2ARQ3qFqd8Xf30RP5cAetC-0pwr4o4xuby81ZRjf-ulp5lIbLE_uZVTgSZbIR3aP6edqrdJ-wZYf_oDQnNQbA~eyJhbGciOiJEUzEyOCJ9.eyJpYXQiOjEzNDI4MDE2OTA1NzAsImV4cCI6MTM0MjgwMTY5NjU3MCwiYXVkIjoiaHR0cHM6Ly9leGFtcGxlLmNvbSIsInZlcnNpb24iOiIyMDEyLjA4LjE1In0.ytUhc5Zt71ZtUmYnf7jaRfC10Y4zbzQweNXIMRO-bC0z8wrBuM42gA", | ||
"issued_at":1342801690570,"expires_at":1342801696570, | ||
"audience":"https://example.com", | ||
"email": 'user@exampleidp.com', | ||
certifyingKey: {"algorithm":"RS","version":"2012.08.15","modulus":"Zx5aDEB62oTwkoTikAp4ck+HGQv4oIa8+L5KdjcANbvjR2jtXAjswepZrwvzYFhP/mwFl/Oy4YElW3OyPy9I6K0OR0xQgBsOprpEOFNEFs14Jy9LJi59yb4gA+xSUlN/SN8s0JKzQ2jYwD8ibZicZWt2C2vvyaBmWaUZm2o5V59DYH6D7ecZSPkwWi9PoD3lCeK2ZeJa7jZpD02bCvybbwyFnDPca2o9MP7/r8Fs6BWJqGAIxlDqvvLUZ+2CeKAie5a98lyBvE//kc0ANY9yjDcWp+c7IXx+lSn5AobiicM2PbiWUdqAXWOguf61ooT1yGazSAeAhZElcy+jd8VZ3Q==","exponent":"AQAB"} | ||
} | ||
]; | ||
var assertion = ASSERTIONS[0].assertion; | ||
var pk = jwcrypto.loadPublicKeyFromObject(ASSERTIONS[0].root); | ||
var now = new Date(); | ||
@@ -77,3 +178,172 @@ | ||
// check the public keys | ||
var addPublicKeyBatch = function(pkObject) { | ||
suite.addBatch({ | ||
"loading a public key": { | ||
topic: function() { | ||
return jwcrypto.loadPublicKey(JSON.stringify(pkObject.key)); | ||
}, | ||
"succeeds": function(pk) { | ||
assert.ok(pk); | ||
}, | ||
"has the right fields": function(pk) { | ||
if (pkObject.algorithm == "RSA") { | ||
assert.ok(pk.rsa.n); | ||
assert.ok(pk.rsa.e); | ||
} | ||
if (pkObject.algorithm == "DSA") { | ||
assert.ok(pk.y); | ||
assert.ok(pk.g); | ||
assert.ok(pk.q); | ||
assert.ok(pk.p); | ||
} | ||
}, | ||
"has fields with correct values": function(pk) { | ||
if (pkObject.algorithm == "RSA") { | ||
assert.equal(pk.rsa.n.toString(16), pkObject.modulus); | ||
assert.equal(pk.rsa.e.toString(16), pkObject.exponent); | ||
} | ||
if (pkObject.algorithm == "DSA") { | ||
assert.equal(pk.y.toString(16), pkObject.y); | ||
assert.equal(pk.g.toString(16), pkObject.g); | ||
assert.equal(pk.q.toString(16), pkObject.q); | ||
assert.equal(pk.p.toString(16), pkObject.p); | ||
} | ||
}, | ||
"two reserializations equals the same thing": function(pk) { | ||
assert.equal(jwcrypto.loadPublicKey(pk.serialize()).serialize(), pk.serialize()); | ||
} | ||
} | ||
}); | ||
}; | ||
PUBLIC_KEYS.forEach(function(pkObject) { | ||
addPublicKeyBatch(pkObject); | ||
}); | ||
// check the secret keys | ||
var addSecretKeyBatch = function(skObject) { | ||
suite.addBatch({ | ||
"loading a secret key": { | ||
topic: function() { | ||
return jwcrypto.loadSecretKey(JSON.stringify(skObject.key)); | ||
}, | ||
"succeeds": function(sk) { | ||
assert.ok(sk); | ||
}, | ||
"has the right fields": function(sk) { | ||
if (skObject.algorithm == "RSA") { | ||
assert.ok(sk.rsa.n); | ||
assert.ok(sk.rsa.d); | ||
assert.ok(sk.rsa.e); | ||
} | ||
if (skObject.algorithm == "DSA") { | ||
assert.ok(sk.x); | ||
assert.ok(sk.g); | ||
assert.ok(sk.q); | ||
assert.ok(sk.p); | ||
} | ||
}, | ||
"has fields with correct values": function(sk) { | ||
if (skObject.algorithm == "RSA") { | ||
assert.equal(sk.rsa.n.toString(16), skObject.modulus); | ||
assert.equal(sk.rsa.e.toString(16), skObject.exponent); | ||
assert.equal(sk.rsa.d.toString(16), skObject.secretExponent); | ||
} | ||
if (skObject.algorithm == "DSA") { | ||
assert.equal(sk.x.toString(16), skObject.x); | ||
assert.equal(sk.g.toString(16), skObject.g); | ||
assert.equal(sk.q.toString(16), skObject.q); | ||
assert.equal(sk.p.toString(16), skObject.p); | ||
} | ||
}, | ||
"two reserializations equals the same thing": function(sk) { | ||
assert.equal(jwcrypto.loadSecretKey(sk.serialize()).serialize(), sk.serialize()); | ||
} | ||
} | ||
}); | ||
}; | ||
SECRET_KEYS.forEach(function(skObject) { | ||
addSecretKeyBatch(skObject); | ||
}); | ||
// check the certs | ||
var addCertBatch = function(certObject) { | ||
suite.addBatch({ | ||
"verifying a cert": { | ||
topic: function() { | ||
var certifierPublicKey = jwcrypto.loadPublicKeyFromObject(certObject.certifierPublicKey); | ||
jwcrypto.cert.verify( | ||
certObject.cert, certifierPublicKey, | ||
new Date(certObject.issued_at), | ||
this.callback); | ||
}, | ||
"succeeds": function(err, payload, assertionParams, certParams) { | ||
assert.isNull(err); | ||
}, | ||
"contains the right parameters": function(err, payload, assertionParams, certParams) { | ||
assert.equal(assertionParams.issuedAt.valueOf(), certObject.issued_at); | ||
assert.equal(assertionParams.expiresAt.valueOf(), certObject.expires_at); | ||
assert.equal(assertionParams.issuer, certObject.issuer); | ||
}, | ||
"contains the right public key": function(err, payload, assertionParams, certParams) { | ||
assert.isDefined(certParams.publicKey, "public key not present under .publicKey parameter"); | ||
assert.ok(certParams.publicKey.equals(jwcrypto.loadPublicKeyFromObject(certObject.containedPublicKey))); | ||
}, | ||
"contains the right email": function(err, payload, assertionParams, certParams) { | ||
assert.equal(certParams.principal.email, certObject.email); | ||
} | ||
} | ||
}); | ||
}; | ||
CERTS.forEach(function(certObject) { | ||
addCertBatch(certObject); | ||
}); | ||
// check the backed assertions | ||
var addBackedAssertionBatch = function(backedAssertionObject) { | ||
suite.addBatch({ | ||
"verifying a backed assertion": { | ||
topic: function() { | ||
var certifyingKey = jwcrypto.loadPublicKeyFromObject(backedAssertionObject.certifyingKey); | ||
jwcrypto.cert.verifyBundle( | ||
backedAssertionObject.assertion, new Date(backedAssertionObject.issued_at), | ||
function(issuer, next) { | ||
// ignore issuer | ||
next(null, certifyingKey); | ||
}, | ||
this.callback); | ||
}, | ||
"succeeds": function(err, certParamsArray, payload, assertionParams) { | ||
assert.isNull(err); | ||
}, | ||
"contains the right parameters": function(err, certParamsArray, payload, assertionParams) { | ||
assert.equal(assertionParams.issuedAt.valueOf(), backedAssertionObject.issued_at); | ||
assert.equal(assertionParams.expiresAt.valueOf(), backedAssertionObject.expires_at); | ||
}, | ||
"certifies the right user": function(err, certParamsArray, payload, assertionParams) { | ||
assert.equal(certParamsArray[0].certParams.principal.email, backedAssertionObject.email); | ||
}, | ||
"contains the right audience": function(err, certParamsArray, payload, assertionParams) { | ||
assert.equal(assertionParams.audience, backedAssertionObject.audience); | ||
} | ||
} | ||
}); | ||
}; | ||
BACKED_ASSERTIONS.forEach(function(backedAssertionObject) { | ||
addBackedAssertionBatch(backedAssertionObject); | ||
}); | ||
suite.export(module); | ||
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
HTTP dependency
Supply chain riskContains a dependency which resolves to a remote HTTP URL which could be used to inject untrusted code and reduce overall package reliability.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
65
2
215
8
0
286624
6441
+ AddedBase64@0.1.4(transitive)
+ Addedbase64-js@0.0.2(transitive)
+ Addedbops@0.0.6(transitive)
+ Addedbrowserify@1.13.5(transitive)
+ Addedcoffee-script@1.12.7(transitive)
+ Addedconcat-stream@1.0.1(transitive)
+ Addedcrypto-browserify@0.4.0(transitive)
+ Addeddetective@0.1.1(transitive)
+ Addedhttp-browserify@0.1.14(transitive)
+ Addedindexof@0.0.1(transitive)
+ Addedoptimist@0.3.7(transitive)
+ Addedresolve@0.2.8(transitive)
+ Addedto-utf8@0.0.1(transitive)
+ Addeduglify-js@1.2.6(transitive)
+ Addedvm-browserify@0.0.4(transitive)
- Removedbigint@https://github.com/benadida/node-bigint/tarball/2ac68
- Removedbrowserify@1.8.1(transitive)
- Removedburrito@0.2.12(transitive)
- Removedcoffee-script@1.1.3(transitive)
- Removeddetective@0.0.4(transitive)
- Removedresolve@0.0.4(transitive)
- Removedtraverse@0.5.2(transitive)
- Removeduglify-js@1.1.1(transitive)
Updatedbrowserify@1.13.5