rearranged cryptic ;) code. added a lazy email validator
This commit is contained in:
Родитель
1cbbca3206
Коммит
abf68d70ec
|
@ -5,9 +5,9 @@
|
|||
var crypto = require('crypto')
|
||||
var P = require('p-promise')
|
||||
var ClientApi = require('./api')
|
||||
var keyStretch = require('./keystretch')
|
||||
var pbkdf2 = require('./pbkdf2')
|
||||
var hkdf = require('../hkdf')
|
||||
var keyStretch = require('../crypto/keystretch')
|
||||
var pbkdf2 = require('../crypto/pbkdf2')
|
||||
var hkdf = require('../crypto/hkdf')
|
||||
var tokens = require('../tokens')({ trace: function () {}})
|
||||
var Bundle = tokens.Bundle
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
module.exports.buffersAreEqual = function buffersAreEqual(buffer1, buffer2) {
|
||||
var mismatch = buffer1.length - buffer2.length
|
||||
if (mismatch) {
|
||||
return false
|
||||
}
|
||||
for (var i = 0; i < buffer1.length; i++) {
|
||||
mismatch |= buffer1[i] ^ buffer2[i]
|
||||
}
|
||||
return mismatch === 0
|
||||
}
|
||||
|
||||
module.exports.xorBuffers = function xorBuffers(buffer1, buffer2) {
|
||||
if (buffer1.length !== buffer2.length) {
|
||||
throw new Error(
|
||||
'XOR buffers must be same length (%d != %d)',
|
||||
buffer1.length,
|
||||
buffer2.length
|
||||
)
|
||||
}
|
||||
var result = Buffer(buffer1.length)
|
||||
for (var i = 0; i < buffer1.length; i++) {
|
||||
result[i] = buffer1[i] ^ buffer2[i]
|
||||
}
|
||||
return result
|
||||
}
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
var P = require('p-promise')
|
||||
var pbkdf2 = require('./pbkdf2')
|
||||
var scrypt = require('../scrypt')
|
||||
var hkdf = require('../hkdf')
|
||||
var scrypt = require('./scrypt')
|
||||
var hkdf = require('./hkdf')
|
||||
|
||||
// The namespace for the salt functions
|
||||
const NAMESPACE = 'identity.mozilla.com/picl/v1/'
|
|
@ -3,37 +3,12 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var HEX_STRING = require('./validators').HEX_STRING
|
||||
var HEX_EMAIL = require('./validators').HEX_EMAIL
|
||||
var LAZY_EMAIL = require('./validators').LAZY_EMAIL
|
||||
|
||||
var P = require('p-promise')
|
||||
var scrypt = require('../scrypt')
|
||||
var hkdf = require('../hkdf')
|
||||
|
||||
function buffersAreEqual(buffer1, buffer2) {
|
||||
var mismatch = buffer1.length - buffer2.length
|
||||
if (mismatch) {
|
||||
return false
|
||||
}
|
||||
for (var i = 0; i < buffer1.length; i++) {
|
||||
mismatch |= buffer1[i] ^ buffer2[i]
|
||||
}
|
||||
return mismatch === 0
|
||||
}
|
||||
|
||||
function xorBuffers(buffer1, buffer2) {
|
||||
if (buffer1.length !== buffer2.length) {
|
||||
throw new Error(
|
||||
'XOR buffers must be same length (%d != %d)',
|
||||
buffer1.length,
|
||||
buffer2.length
|
||||
)
|
||||
}
|
||||
var result = Buffer(buffer1.length)
|
||||
for (var i = 0; i < buffer1.length; i++) {
|
||||
result[i] = buffer1[i] ^ buffer2[i]
|
||||
}
|
||||
return result
|
||||
}
|
||||
var scrypt = require('../crypto/scrypt')
|
||||
var hkdf = require('../crypto/hkdf')
|
||||
var butil = require('../crypto/butil')
|
||||
|
||||
module.exports = function (log, crypto, P, uuid, isA, error, db, mailer, isProduction) {
|
||||
|
||||
|
@ -49,7 +24,7 @@ module.exports = function (log, crypto, P, uuid, isA, error, db, mailer, isProdu
|
|||
tags: ["srp", "account"],
|
||||
validate: {
|
||||
payload: {
|
||||
email: isA.String().max(1024).required(),
|
||||
email: isA.String().max(255).regex(LAZY_EMAIL).required(),
|
||||
authPW: isA.String().min(64).max(64).regex(HEX_STRING).required(),
|
||||
preVerified: isA.Boolean(),
|
||||
service: isA.String().max(16).alphanum().optional(),
|
||||
|
@ -157,7 +132,7 @@ module.exports = function (log, crypto, P, uuid, isA, error, db, mailer, isProdu
|
|||
return hkdf(stretched, 'verifyHash', null, 32)
|
||||
.then(
|
||||
function (verifyHash) {
|
||||
if (!buffersAreEqual(verifyHash, emailRecord.verifyHash)) {
|
||||
if (!butil.buffersAreEqual(verifyHash, emailRecord.verifyHash)) {
|
||||
throw error.incorrectPassword(emailRecord.rawEmail)
|
||||
}
|
||||
return db.createSessionToken(
|
||||
|
@ -192,7 +167,7 @@ module.exports = function (log, crypto, P, uuid, isA, error, db, mailer, isProdu
|
|||
return hkdf(stretched, 'wrapwrapKey', null, 32)
|
||||
.then(
|
||||
function (wrapWrapKey) {
|
||||
return xorBuffers(wrapWrapKey, emailRecord.wrapWrapKb)
|
||||
return butil.xorBuffers(wrapWrapKey, emailRecord.wrapWrapKb)
|
||||
}
|
||||
)
|
||||
.then(
|
||||
|
@ -239,7 +214,7 @@ module.exports = function (log, crypto, P, uuid, isA, error, db, mailer, isProdu
|
|||
},
|
||||
validate: {
|
||||
payload: {
|
||||
email: isA.String().max(255).required(),
|
||||
email: isA.String().max(255).regex(LAZY_EMAIL).required(),
|
||||
authPW: isA.String().min(64).max(64).regex(HEX_STRING).required()
|
||||
},
|
||||
response: {
|
||||
|
@ -348,7 +323,7 @@ module.exports = function (log, crypto, P, uuid, isA, error, db, mailer, isProdu
|
|||
validate: {
|
||||
response: {
|
||||
schema: {
|
||||
email: isA.String().required(),
|
||||
email: isA.String().regex(LAZY_EMAIL).required(),
|
||||
verified: isA.Boolean().required()
|
||||
}
|
||||
}
|
||||
|
@ -517,7 +492,7 @@ module.exports = function (log, crypto, P, uuid, isA, error, db, mailer, isProdu
|
|||
},
|
||||
validate: {
|
||||
payload: {
|
||||
email: isA.String().max(255).required(),
|
||||
email: isA.String().max(255).regex(LAZY_EMAIL).required(),
|
||||
authPW: isA.String().min(64).max(64).regex(HEX_STRING).required()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,38 +2,13 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var HEX_EMAIL = require('./validators').HEX_EMAIL
|
||||
var HEX_STRING = require('./validators').HEX_STRING
|
||||
var LAZY_EMAIL = require('./validators').LAZY_EMAIL
|
||||
|
||||
var crypto = require('crypto')
|
||||
var scrypt = require('../scrypt')
|
||||
var hkdf = require('../hkdf')
|
||||
|
||||
function buffersAreEqual(buffer1, buffer2) {
|
||||
var mismatch = buffer1.length - buffer2.length
|
||||
if (mismatch) {
|
||||
return false
|
||||
}
|
||||
for (var i = 0; i < buffer1.length; i++) {
|
||||
mismatch |= buffer1[i] ^ buffer2[i]
|
||||
}
|
||||
return mismatch === 0
|
||||
}
|
||||
|
||||
function xorBuffers(buffer1, buffer2) {
|
||||
if (buffer1.length !== buffer2.length) {
|
||||
throw new Error(
|
||||
'XOR buffers must be same length (%d != %d)',
|
||||
buffer1.length,
|
||||
buffer2.length
|
||||
)
|
||||
}
|
||||
var result = Buffer(buffer1.length)
|
||||
for (var i = 0; i < buffer1.length; i++) {
|
||||
result[i] = buffer1[i] ^ buffer2[i]
|
||||
}
|
||||
return result
|
||||
}
|
||||
var scrypt = require('../crypto/scrypt')
|
||||
var hkdf = require('../crypto/hkdf')
|
||||
var butil = require('../crypto/butil')
|
||||
|
||||
module.exports = function (log, isA, error, db, mailer) {
|
||||
|
||||
|
@ -70,7 +45,7 @@ module.exports = function (log, isA, error, db, mailer) {
|
|||
return hkdf(oldStretched, 'verifyHash', null, 32)
|
||||
.then(
|
||||
function (verifyHash) {
|
||||
if(!buffersAreEqual(verifyHash, emailRecord.verifyHash)) {
|
||||
if(!butil.buffersAreEqual(verifyHash, emailRecord.verifyHash)) {
|
||||
throw error.incorrectPassword()
|
||||
}
|
||||
}
|
||||
|
@ -80,7 +55,7 @@ module.exports = function (log, isA, error, db, mailer) {
|
|||
return hkdf(oldStretched, 'wrapwrapKey', null, 32)
|
||||
.then(
|
||||
function (wrapWrapKey) {
|
||||
return xorBuffers(wrapWrapKey, emailRecord.wrapWrapKb)
|
||||
return butil.xorBuffers(wrapWrapKey, emailRecord.wrapWrapKb)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -134,7 +109,7 @@ module.exports = function (log, isA, error, db, mailer) {
|
|||
},
|
||||
validate: {
|
||||
payload: {
|
||||
email: isA.String().max(255).required(),
|
||||
email: isA.String().max(255).regex(LAZY_EMAIL).required(),
|
||||
oldAuthPW: isA.String().min(64).max(64).regex(HEX_STRING).required()
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +139,7 @@ module.exports = function (log, isA, error, db, mailer) {
|
|||
return hkdf(stretched, 'wrapwrapKey', null, 32)
|
||||
.then(
|
||||
function (wrapWrapKey) {
|
||||
return xorBuffers(wrapWrapKey, wrapKb)
|
||||
return butil.xorBuffers(wrapWrapKey, wrapKb)
|
||||
}
|
||||
)
|
||||
.then(
|
||||
|
@ -247,7 +222,7 @@ module.exports = function (log, isA, error, db, mailer) {
|
|||
},
|
||||
validate: {
|
||||
payload: {
|
||||
email: isA.String().max(1024).required()
|
||||
email: isA.String().max(255).regex(LAZY_EMAIL).required()
|
||||
},
|
||||
response: {
|
||||
schema: {
|
||||
|
@ -295,7 +270,7 @@ module.exports = function (log, isA, error, db, mailer) {
|
|||
},
|
||||
validate: {
|
||||
payload: {
|
||||
email: isA.String().max(1024).required()
|
||||
email: isA.String().max(255).regex(LAZY_EMAIL).required()
|
||||
},
|
||||
response: {
|
||||
schema: {
|
||||
|
|
|
@ -10,3 +10,5 @@ module.exports.HEX_STRING = /^(?:[a-fA-F0-9]{2})+$/
|
|||
// This is a pretty coarse match - basically /.+@.+/ on a hex string.
|
||||
|
||||
module.exports.HEX_EMAIL = /^(?:[a-fA-F0-9]{2})+40(?:[a-fA_F0-9]{2})+$/
|
||||
|
||||
module.exports.LAZY_EMAIL = /^[^@\s]+@[^@\s]+$/
|
||||
|
|
|
@ -75,7 +75,7 @@ TestServer.start(config.publicUrl)
|
|||
)
|
||||
}
|
||||
)
|
||||
/*/
|
||||
|
||||
test(
|
||||
'/account/create with malformed email address',
|
||||
function (t) {
|
||||
|
@ -90,12 +90,12 @@ TestServer.start(config.publicUrl)
|
|||
)
|
||||
}
|
||||
)
|
||||
/*/
|
||||
|
||||
test(
|
||||
'signup with same email, different case',
|
||||
function (t) {
|
||||
var email = 'TEST@EXAMPLE.COM'
|
||||
var email2 = 'test@example.com'
|
||||
var email = Math.random() + 'TEST@EXAMPLE.COM'
|
||||
var email2 = email.toLowerCase()
|
||||
var password = 'abcdef'
|
||||
return Client.create(config.publicUrl, email, password, { preVerified: true })
|
||||
.then(
|
||||
|
@ -116,8 +116,8 @@ TestServer.start(config.publicUrl)
|
|||
test(
|
||||
'the rawEmail is returned in the error on Incorrect Password errors',
|
||||
function (t) {
|
||||
var signupEmail = 'TestX@example.com'
|
||||
var loginEmail = 'testx@example.com'
|
||||
var signupEmail = Math.random() + 'Test@example.com'
|
||||
var loginEmail = signupEmail.toLowerCase()
|
||||
var password = 'abcdef'
|
||||
return Client.create(config.publicUrl, signupEmail, password, { preVerified: true})
|
||||
.then(
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var test = require('../ptaptest')
|
||||
var hkdf = require('../../hkdf')
|
||||
var hkdf = require('../../crypto/hkdf')
|
||||
|
||||
test(
|
||||
'hkdf basic',
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var test = require('../ptaptest')
|
||||
var keyStretch = require('../../client/keystretch')
|
||||
var keyStretch = require('../../crypto/keystretch')
|
||||
|
||||
test(
|
||||
'basic key stretching, test vectors',
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var test = require('../ptaptest')
|
||||
var pbkdf2 = require('../../client/pbkdf2')
|
||||
var pbkdf2 = require('../../crypto/pbkdf2')
|
||||
var test = require('../ptaptest')
|
||||
var ITERATIONS = 20000
|
||||
var LENGTH = 8 * 32
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var test = require('../ptaptest')
|
||||
var scrypt = require('../../scrypt')
|
||||
var scrypt = require('../../crypto/scrypt')
|
||||
|
||||
test(
|
||||
'scrypt basic',
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
*/
|
||||
|
||||
|
||||
module.exports = function (crypto, P, hkdf, error) {
|
||||
module.exports = function (crypto, P, hkdf, butil, error) {
|
||||
|
||||
|
||||
var HASH_ALGORITHM = 'sha256'
|
||||
|
@ -39,7 +39,7 @@ module.exports = function (crypto, P, hkdf, error) {
|
|||
return deriveBundleKeys(key, keyInfo, payload.length)
|
||||
.then(
|
||||
function (keys) {
|
||||
var ciphertext = xorBuffers(payload, keys[1])
|
||||
var ciphertext = butil.xorBuffers(payload, keys[1])
|
||||
var hmac = crypto.createHmac(HASH_ALGORITHM, keys[0])
|
||||
hmac.update(ciphertext)
|
||||
var mac = hmac.digest()
|
||||
|
@ -61,10 +61,10 @@ module.exports = function (crypto, P, hkdf, error) {
|
|||
var hmac = crypto.createHmac(HASH_ALGORITHM, keys[0])
|
||||
hmac.update(ciphertext)
|
||||
var mac = hmac.digest()
|
||||
if (!buffersAreEqual(mac, expectedHmac)) {
|
||||
if (!butil.buffersAreEqual(mac, expectedHmac)) {
|
||||
throw error.invalidSignature()
|
||||
}
|
||||
return xorBuffers(ciphertext, keys[1])
|
||||
return butil.xorBuffers(ciphertext, keys[1])
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -83,39 +83,5 @@ module.exports = function (crypto, P, hkdf, error) {
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
// Xor the contents of two equal-sized buffers.
|
||||
//
|
||||
function xorBuffers(buffer1, buffer2) {
|
||||
if (buffer1.length !== buffer2.length) {
|
||||
throw new Error(
|
||||
'XOR buffers must be same length (%d != %d)',
|
||||
buffer1.length,
|
||||
buffer2.length
|
||||
)
|
||||
}
|
||||
var result = Buffer(buffer1.length)
|
||||
for (var i = 0; i < buffer1.length; i++) {
|
||||
result[i] = buffer1[i] ^ buffer2[i]
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
// Time-invariant buffer comparison.
|
||||
// For checking hmacs without timing attacks.
|
||||
//
|
||||
function buffersAreEqual(buffer1, buffer2) {
|
||||
var mismatch = buffer1.length - buffer2.length
|
||||
if (mismatch) {
|
||||
return false
|
||||
}
|
||||
for (var i = 0; i < buffer1.length; i++) {
|
||||
mismatch |= buffer1[i] ^ buffer2[i]
|
||||
}
|
||||
return mismatch === 0
|
||||
}
|
||||
|
||||
|
||||
return Bundle
|
||||
}
|
||||
|
|
|
@ -6,13 +6,14 @@ var crypto = require('crypto')
|
|||
var inherits = require('util').inherits
|
||||
|
||||
var P = require('p-promise')
|
||||
var hkdf = require('../hkdf')
|
||||
var hkdf = require('../crypto/hkdf')
|
||||
var butil = require('../crypto/butil')
|
||||
|
||||
var error = require('./error')
|
||||
|
||||
module.exports = function (log) {
|
||||
|
||||
var Bundle = require('./bundle')(crypto, P, hkdf, error)
|
||||
var Bundle = require('./bundle')(crypto, P, hkdf, butil, error)
|
||||
var Token = require('./token')(log, crypto, P, hkdf, Bundle, error)
|
||||
|
||||
var KeyFetchToken = require('./key_fetch_token')(log, inherits, Token, error)
|
||||
|
|
Загрузка…
Ссылка в новой задаче