five-bells-shared
Advanced tools
Comparing version 12.2.2 to 12.2.3
{ | ||
"name": "five-bells-shared", | ||
"version": "12.2.2", | ||
"version": "12.2.3", | ||
"description": "Shared components for Five Bells projects.", | ||
@@ -31,2 +31,3 @@ "keywords": [ | ||
"dependencies": { | ||
"base64url": "^1.0.6", | ||
"bcrypt": "^0.8.5", | ||
@@ -33,0 +34,0 @@ "canonical-json": "0.0.4", |
@@ -18,6 +18,3 @@ { | ||
"description": "RSA exponent.", | ||
"oneOf": [ | ||
{ "$ref": "Base64.json" }, | ||
{ "$ref": "Base64URL.json" } | ||
] | ||
"$ref": "Base64URL.json" | ||
}, | ||
@@ -24,0 +21,0 @@ "required": ["type", "n", "e"], |
{ | ||
"sampleNotification": { | ||
"id": "6821484d-6ca7-4157-b15b-388c49637111", | ||
"subscription_id": | ||
"c6345f6e-d3c9-440b-8aa0-f0077c0c40f4", | ||
"transfer_id": "ba32d964-f143-4b67-b470-d258025288d4", | ||
"retry_count": 1, | ||
"retry_at": 1457645427712 | ||
"id": "http://localhost/transfers/155dff3f-4915-44df-a707-acc4b527bcbd", | ||
"subscription": "c6345f6e-d3c9-440b-8aa0-f0077c0c40f4", | ||
"event": "transfer.update", | ||
"resource": { | ||
"debits": [ | ||
{ | ||
"account": "http://localhost/accounts/alice", | ||
"amount": "10", | ||
"authorized": true | ||
} | ||
], | ||
"credits": [ | ||
{ | ||
"account": "http://localhost/accounts/bob", | ||
"amount": "10" | ||
} | ||
], | ||
"ledger": "http://localhost", | ||
"state": "executed" | ||
} | ||
}, | ||
"expectedSignedNotification": { | ||
"id": "6821484d-6ca7-4157-b15b-388c49637111", | ||
"subscription_id": "c6345f6e-d3c9-440b-8aa0-f0077c0c40f4", | ||
"transfer_id": "ba32d964-f143-4b67-b470-d258025288d4", | ||
"retry_count": 1, | ||
"retry_at": 1457645427712, | ||
"id": "http://localhost/transfers/155dff3f-4915-44df-a707-acc4b527bcbd", | ||
"subscription": "c6345f6e-d3c9-440b-8aa0-f0077c0c40f4", | ||
"event": "transfer.update", | ||
"resource": { | ||
"debits": [ | ||
{ | ||
"account": "http://localhost/accounts/alice", | ||
"amount": "10", | ||
"authorized": true | ||
} | ||
], | ||
"credits": [ | ||
{ | ||
"account": "http://localhost/accounts/bob", | ||
"amount": "10" | ||
} | ||
], | ||
"ledger": "http://localhost", | ||
"state": "executed" | ||
}, | ||
"signature": { | ||
@@ -21,4 +50,4 @@ "algorithm": "ES256", | ||
"curve": "P-256", | ||
"x": "fe6c0b5f44f167591005775e2cdb25c9ee6e885f3ff16cce418ce8a67fa2f93e", | ||
"y": "4a839e3c4289ccf6a6c341fb860da3fb5173e5ddd4137bf7f44e0271c29f147a" | ||
"x": "ZmU2YzBiNWY0NGYxNjc1OTEwMDU3NzVlMmNkYjI1YzllZTZlODg1ZjNmZjE2Y2NlNDE4Y2U4YTY3ZmEyZjkzZQ", | ||
"y": "NGE4MzllM2M0Mjg5Y2NmNmE2YzM0MWZiODYwZGEzZmI1MTczZTVkZGQ0MTM3YmY3ZjQ0ZTAyNzFjMjlmMTQ3YQ" | ||
} | ||
@@ -28,7 +57,22 @@ } | ||
"expectedRSASignedNotification": { | ||
"id": "6821484d-6ca7-4157-b15b-388c49637111", | ||
"subscription_id": "c6345f6e-d3c9-440b-8aa0-f0077c0c40f4", | ||
"transfer_id": "ba32d964-f143-4b67-b470-d258025288d4", | ||
"retry_count": 1, | ||
"retry_at": 1457645427712, | ||
"id": "http://localhost/transfers/155dff3f-4915-44df-a707-acc4b527bcbd", | ||
"subscription": "c6345f6e-d3c9-440b-8aa0-f0077c0c40f4", | ||
"event": "transfer.update", | ||
"resource": { | ||
"debits": [ | ||
{ | ||
"account": "http://localhost/accounts/alice", | ||
"amount": "10", | ||
"authorized": true | ||
} | ||
], | ||
"credits": [ | ||
{ | ||
"account": "http://localhost/accounts/bob", | ||
"amount": "10" | ||
} | ||
], | ||
"ledger": "http://localhost", | ||
"state": "executed" | ||
}, | ||
"signature": { | ||
@@ -38,3 +82,3 @@ "algorithm": "PS256", | ||
"type": "RSA", | ||
"e": "NjU1Mzc=", | ||
"e": "NjU1Mzc", | ||
"n": "Njc1NTkwOTcxMTE2NTEwMTIyODY4MzE0NjkwMzkxODI3NTAyMjQ4MzA1NzQ3NzA0NTkxNDg3MzA4MzI4MzQ3ODEzODgyNTgwMTIzMDU1NzE4OTM1MjAyMTY2Njk0OTIwODcxMDkzMzcwNjA2MDc5NTU3Mzg2ODg1MjI3MTY0MTE2NTkwMDYxNTkzMDU0NTQyMDgyMzU0Nzc5NjczMzExODExMzMwNzkwNjI0NTMxNjIxMjg2OTg0MTE3NDgwNzM3MzUwNzUwNjM4Mzg0MjYzNDMwMjczNDQ0OTIwNDgyODY5MDc2MTgzNDEwOTc1NTU2NDM4MzYxNTg4MTIyNzIxNzU0NzU2ODcwNDAyMTI3OTcxNzIxMTc2MjkxMTE2MzEwNzIxMzEyOTExMTgwNTMyNDE5ODE4NzM0NjYwNTE3MDc0MDIxNDE4Nzc3Mjc5NjcwNDkyNjc1NDA5NzU1NTk2MzUxOTAwOTAwMTA5NDMyMzAzNzg2NjExMTA3NTExNjk1NDU2MzUwNzI5NDQ5NTE4NzkxNTQ1NTAxMjkzNDcwNzExNzI3MzExNDgwMDY3Njk2MDQ3MDgwNDAwMzE5Njk2MzYxNjk3NTY0MTg2NzIxNDI3NDMwNDIyMDk3MzExNjgxNjQxNDkyNjM2Nzk1ODQxNDE5MTY5MjM1NzM1MTUzNDA2MDc1MDk1OTk3NTc2MDA4NDE3NTEyMjgzMjY5MTI3NDU1OTU4OTM3MTk5MDI1MDMxNTM4NTIyMzE5MTg5MTMyOTM3NDgyNzg2NzE3MzAxMDM0MjkyMDM2NTEzMzQ2NDU2OTE4MzcwOTk1NzQyMDM5NzAwOTkyNDM3NzY5OTM1NDQ2OTc1OTIxNDE1NjQyMTU2NzIxMzkzMTAwMjQyMDkxMTk1NTIyMjQ5ODc3NTk3NzY2MjE3NzE2MDc4MzgxNzY1MjYxMDIyNjY4NjEwNzE0NTY1MTk5ODkzODcxMTU0NDQ5NTQzMzk4NjQzNTA0Njc3NjIwNjEwOTY5ODkwNzE2MDk0MTM5NjcxOTQ1MjY2ODEzNzY1MTkyOTc4Mjc0NjcwMTk2Njc5NDM5MTM4MjgxMTk5MTc5Nzg5NjIzMzU5ODk0MTExOTEwOTAxNTYyMTg1NjE1ODcxMzQ5NjQzOTA5MjcwMDg3ODM0MzUxNTg5NTA3MjgxOTc5NzE4MzQxMzkxNzc0NjE0NzI1NzI3MjQ0ODQ0MDM0NTUyNzg2ODQxNzM3MDQ5NDc0ODU4NTY3OTAxOTY4NTcyMjcxMTY2NDk5OTgzNjI0MjkyODcwMjM5ODY0Njk4ODU0ODY3ODAyMzk5NTUxNTE3MDcyOTI0MDk1OTUzMjY4MzEzNzk4Nzg5MDEyODUzNjc4OTU5NjE1MTg1NTUxNzQwMTU0MzYxODc3OTM3NjkxMzg4MzU0MDc1Nzk0ODA4OTQxOTEwNzkxMDA3Njc2MzQzNTcyODUwNjY4NTM3MjU2NjU5MDU1Mzk2ODE5ODc0OTk0NDA2NzMzNzc0NTEwMjE0MzYyMDYxNjc0MDc4OTI2NTEzODYwOTczMjEzNTY2OTQ1MDYwNjk5MjEyNTg5Njk2Njg2NjA4NjMwODYxOTA3OTQ2NTUyNzQzNzM5OTUyMDkzNTQxMzUxNjcx" | ||
@@ -41,0 +85,0 @@ } |
@@ -13,2 +13,13 @@ 'use strict' | ||
const Validator = require('../lib/validator') | ||
const validator = new Validator() | ||
validator.loadSharedSchemas() | ||
function validateNotification (json) { | ||
const validatorResult = validator.create('Notification')(json) | ||
if (!validatorResult.valid) { | ||
throw new Error('Notification schema validation error: ' + validatorResult.errors[0]) | ||
} | ||
} | ||
// Set up keys | ||
@@ -30,2 +41,3 @@ const prvPEM = fs.readFileSync('test/data/signKeyPrv.pem', 'utf8') | ||
const signedJSON = jsonSigning.sign(signData.sampleNotification, jsonSigning.types.ES256, prvKey, pubKey) | ||
expect(validateNotification.bind(validator.validateNotification, signedJSON)).to.not.throw(Error) | ||
// Do not check signature.value, because this value changes every time it signs | ||
@@ -69,2 +81,3 @@ delete signedJSON.signature.value | ||
const signedJSON = jsonSigning.sign(signData.sampleNotification, jsonSigning.types.PS256, prvRSAPEM) | ||
expect(validateNotification.bind(validator.validateNotification, signedJSON)).to.not.throw(Error) | ||
// Do not check signature.value, because this value changes every time it signs | ||
@@ -71,0 +84,0 @@ delete signedJSON.signature.value |
@@ -7,2 +7,3 @@ // JSON Cleartext Signing | ||
const _ = require('lodash') | ||
const base64url = require('base64url') | ||
@@ -27,2 +28,15 @@ // Constants for crypto algorithm types (ECDSA and RSA) | ||
/** | ||
* Returns a JSON Web Signature (JWS) | ||
* @param {string} algorithm - The algorithm used to sign the JSON. | ||
* @param {string} payload - The JSON to verify. | ||
* @param {Base64URL} signature - The base64URL-encoded signature for the JSON. | ||
@ @returns {string} | ||
*/ | ||
function makeJWSString (algorithm, payload, signature) { | ||
return base64url.encode(JSON.stringify({alg: algorithm})) + '\.' + | ||
base64url.encode(JSON.stringify(payload)) + '\.' + | ||
signature | ||
} | ||
// Sign JSON object, using ECDSA P-256 private key and public key. | ||
@@ -53,4 +67,4 @@ // Insert 'signature' block in the JSON object. | ||
} | ||
const hX = pubKeyHex.slice(2, 66) | ||
const hY = pubKeyHex.slice(66, 130) | ||
const hX = base64url.encode(pubKeyHex.slice(2, 66)) | ||
const hY = base64url.encode(pubKeyHex.slice(66, 130)) | ||
@@ -83,4 +97,4 @@ const signedJSON = _.cloneDeep(json) | ||
// jsrsasign stores public key components "e" as Number, and "n" as BigInteger | ||
const pubkeyE = new Buffer(prvKeyObj.e.toString()).toString('base64') | ||
const pubkeyN = new Buffer(prvKeyObj.n.toString()).toString('base64') | ||
const pubkeyE = base64url.encode(new Buffer(prvKeyObj.e.toString())) | ||
const pubkeyN = base64url.encode(new Buffer(prvKeyObj.n.toString())) | ||
const signedJSON = _.cloneDeep(json) | ||
@@ -101,2 +115,6 @@ signedJSON.signature = { | ||
module.exports.verify = function (json, cryptoType, pubKey) { | ||
if (!json || !json.signature || !json.signature.value) { | ||
throw new ServerError('Invalid input for JSON verification') | ||
} | ||
if (!pubKey) throw new ServerError('Problem reading public key for JSON signing') | ||
if (cryptoType === ES256) return verifyECDSA(json, pubKey) | ||
@@ -108,13 +126,2 @@ else if (cryptoType === PS256) return verifyRSA(json, pubKey) | ||
function verifyECDSA (json, pubKey) { | ||
if (!json || !json.signature || !json.signature.value) { | ||
throw new ServerError('Invalid input for JSON verification') | ||
} | ||
const jsonWithoutSignature = _.omit(json, 'signature') | ||
let strPayload = new Buffer(JSON.stringify(jsonWithoutSignature)).toString('base64') | ||
// chop trailing '==' | ||
if (_.endsWith(strPayload, '==')) { | ||
strPayload = strPayload.slice(0, strPayload.length - 2) | ||
} | ||
// check pub key coordinates X and Y in signature | ||
@@ -128,4 +135,4 @@ const pubKeyHex = pubKey.pubKeyHex | ||
} | ||
const hX = pubKeyHex.slice(2, 66) | ||
const hY = pubKeyHex.slice(66, 130) | ||
const hX = base64url.encode(pubKeyHex.slice(2, 66)) | ||
const hY = base64url.encode(pubKeyHex.slice(66, 130)) | ||
if (json.signature.publicKey.x !== hX || json.signature.publicKey.y !== hY) { | ||
@@ -135,4 +142,3 @@ throw new ServerError('Public key mismatch in JSON signature verification') | ||
const jws = 'eyJhbGciOiJFUzI1NiJ9\.' + // Base64 encoded {"alg":"ES256"} | ||
strPayload + '\.' + json.signature.value | ||
const jws = makeJWSString(ES256, _.omit(json, 'signature'), json.signature.value) | ||
return KJUR.jws.JWS.verify(jws, pubKey) // eslint-disable-line no-undef | ||
@@ -142,23 +148,12 @@ } | ||
function verifyRSA (json, pubKey) { | ||
if (!json || !json.signature || !json.signature.value) { | ||
throw new ServerError('Invalid input for JSON verification') | ||
} | ||
if (!pubKey) throw new ServerError('Problem reading public key for JSON signing') | ||
const pubKeyObj = parseKey(pubKey) | ||
const jsonWithoutSignature = _.omit(json, 'signature') | ||
let strPayload = new Buffer(JSON.stringify(jsonWithoutSignature)).toString('base64') | ||
// chop trailing '==' | ||
if (_.endsWith(strPayload, '==')) { | ||
strPayload = strPayload.slice(0, strPayload.length - 2) | ||
} | ||
// Check pub key parameters | ||
const pubkeyE = new Buffer(pubKeyObj.e.toString()).toString('base64') | ||
const pubkeyN = new Buffer(pubKeyObj.n.toString()).toString('base64') | ||
const pubkeyE = base64url.encode(new Buffer(pubKeyObj.e.toString())) | ||
const pubkeyN = base64url.encode(new Buffer(pubKeyObj.n.toString())) | ||
if (json.signature.publicKey.e !== pubkeyE || json.signature.publicKey.n !== pubkeyN) { | ||
throw new ServerError('Public key mismatch in JSON signature verification') | ||
} | ||
const jws = 'eyJhbGciOiJQUzI1NiJ9\.' + // Base64 encoded {"alg":"PS256"} | ||
strPayload + '\.' + json.signature.value | ||
const jws = makeJWSString(PS256, _.omit(json, 'signature'), json.signature.value) | ||
return KJUR.jws.JWS.verify(jws, pubKeyObj, [PS256]) // eslint-disable-line no-undef | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
1774341
4212
18
+ Addedbase64url@^1.0.6
+ Addedbase64url@1.0.6(transitive)
+ Addedcamelcase@1.2.1(transitive)
+ Addedcamelcase-keys@1.0.0(transitive)
+ Addedconcat-stream@1.4.11(transitive)
+ Addedget-stdin@4.0.1(transitive)
+ Addedindent-string@1.2.2(transitive)
+ Addedis-finite@1.1.0(transitive)
+ Addedmap-obj@1.0.1(transitive)
+ Addedmeow@2.0.0(transitive)
+ Addedminimist@1.2.8(transitive)
+ Addedobject-assign@1.0.0(transitive)
+ Addedrepeating@1.1.3(transitive)
+ Addedtypedarray@0.0.7(transitive)