1
0
mirror of https://github.com/danog/fast-srp.git synced 2024-11-26 20:04:49 +01:00

Restructured the project a bit

This commit is contained in:
Supereg 2020-04-12 19:01:18 +02:00
parent d8e2938064
commit 462b688de4
No known key found for this signature in database
GPG Key ID: 2F08948C5653D720
15 changed files with 194 additions and 185 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
node_modules
dist
lib

View File

@ -9,7 +9,7 @@ Creating the Verifier
---
```ts
import * as srp6a from 'fast-srp-hap';
import { SRP } from 'fast-srp-hap';
/**
* Computes the verifier of a user. Only needed to add the user to the auth system.
@ -19,12 +19,12 @@ import * as srp6a from 'fast-srp-hap';
* @return {Promise<{salt: Buffer, verifier: Buffer}>}
*/
async function srp6a_create_user(I: string, P: string) {
const salt = await srp6a.genKey(32);
const salt = await SRP.genKey(32);
return {
// The salt is required for authenticating the user later
salt,
verifier: srp6a.computeVerifier(srp6a.params[4096], salt, Buffer.from(I), Buffer.from(P)),
verifier: SRP.computeVerifier(SRP.params[4096], salt, Buffer.from(I), Buffer.from(P)),
};
}
@ -38,7 +38,7 @@ Server
---
```ts
import {Server, genKey, params} from 'fast-srp-hap';
import {SRP, SrpServer} from 'fast-srp-hap';
(async () => {
// Get the user details from somewhere
@ -46,7 +46,7 @@ import {Server, genKey, params} from 'fast-srp-hap';
username: 'username', // Or a Buffer
// If we have the plaintext password
salt: await genKey(32),
salt: await SRP.genKey(32),
password: 'password', // Or a Buffer
// If we have a saved verifier
@ -55,9 +55,9 @@ import {Server, genKey, params} from 'fast-srp-hap';
};
// Generate a secret key
const secret = await genKey(32);
const secret = await SRP.genKey(32);
const server = new Server(params[3076], user, secret); // For Apple SRP use params.hap
const server = new SrpServer(SRP.params[3076], user, secret); // For Apple SRP use params.hap
// ...
})();

View File

14
package-lock.json generated
View File

@ -1,13 +1,13 @@
{
"name": "fast-srp-hap",
"version": "1.1.0",
"version": "2.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/node": {
"version": "12.12.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.3.tgz",
"integrity": "sha512-opgSsy+cEF9N8MgaVPnWVtdJ3o4mV2aMHvDq7thkQUFt0EuOHJon4rQpJfhjmNHB+ikl0Cd6WhWIErOyQ+f7tw==",
"version": "10.17.19",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.19.tgz",
"integrity": "sha512-46/xThm3zvvc9t9/7M3AaLEqtOpqlYYYcCZbpYVAQHG20+oMZBkae/VMrn4BTi6AJ8cpack0mEXhGiKmDNbLrQ==",
"dev": true
},
"balanced-match": {
@ -105,9 +105,9 @@
"dev": true
},
"typescript": {
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz",
"integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==",
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
"integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
"dev": true
},
"vows": {

View File

@ -2,26 +2,34 @@
"name": "fast-srp-hap",
"description": "Secure Remote Password (SRP)",
"version": "1.1.0",
"main": "dist/index.js",
"main": "lib/srp.js",
"scripts": {
"prepare": "rm -rf dist && tsc",
"test": "vows dist/test/test_*.js --spec"
"clean": "rm -rf lib",
"build": "npm run clean && tsc",
"prepublishOnly": "npm run build",
"postpublish": "npm run clean",
"test": "vows lib/test/test_*.js --spec"
},
"repository": {
"type": "git",
"url": "https://github.com/zarmack/fast-srp"
"url": "https://github.com/homebridge/fast-srp-hap"
},
"author": "Zarmack Tanen",
"licence": "MIT",
"license": "MIT",
"engines": {
"node": ">=10.17.0"
},
"files": [
"jsbn",
"lib",
"dist/index.*",
"dist/lib"
"!lib/test",
"README.md",
"LICENSE"
],
"dependencies": {},
"devDependencies": {
"@types/node": "^12.12.3",
"typescript": "^3.6.4",
"@types/node": "^10.17.19",
"typescript": "^3.8.3",
"vows": "^0.8.3"
}
}

View File

@ -1,8 +0,0 @@
export * from './lib/srp';
export {
default as params,
SrpParams,
} from './lib/params';
export default module.exports;

View File

@ -14,7 +14,7 @@
// since these are meant to be used internally, all values are numbers. If
// you want to add parameter sets, you'll need to convert them to bignums.
import BigInteger = require('../../lib/jsbn');
import BigInteger = require('../jsbn/jsbn');
export function hex(s: string) {
return new BigInteger(s.split(/\s|\n/).join(''), 16);
@ -27,9 +27,7 @@ export interface SrpParams {
hash: string;
}
const params: {
[n: string]: SrpParams;
} = {
export const params = {
1024: {
N_length_bits: 1024,
N: hex(`

View File

@ -1,10 +1,11 @@
import * as crypto from 'crypto';
import * as assert from 'assert';
import BigInteger = require('../../lib/jsbn');
import crypto from 'crypto';
import assert from 'assert';
import BigInteger = require('../jsbn/jsbn');
import {SrpParams, params as srpParams} from './params';
import {SrpParams} from './params';
export { SrpParams } from './params';
var zero = new BigInteger(0, 10);
const zero = new BigInteger(0, 10);
function assert_(val: any, msg: string) {
if (!val)
@ -34,7 +35,7 @@ function padTo(n: Buffer, len: number) {
function padToN(number: BigInteger, params: SrpParams) {
assertIsBigInteger(number);
var n = number.toString(16).length % 2 != 0 ? '0' + number.toString(16) : number.toString(16);
const n = number.toString(16).length % 2 != 0 ? '0' + number.toString(16) : number.toString(16);
return padTo(Buffer.from(n, 'hex'), params.N_length_bits / 8);
}
@ -66,35 +67,68 @@ function getx(params: SrpParams, salt: Buffer, I: Buffer, P: Buffer) {
const hashIP = crypto.createHash(params.hash)
.update(Buffer.concat([I, Buffer.from(':'), P]))
.digest();
const hashX = crypto.createHash(params.hash)
const hashX: Buffer = crypto.createHash(params.hash)
.update(salt)
.update(hashIP)
.digest();
return new BigInteger(hashX);
}
/**
* The verifier is calculated as described in Section 3 of [SRP-RFC].
* We give the algorithm here for convenience.
*
* The verifier (v) is computed based on the salt (s), user name (I),
* password (P), and group parameters (N, g).
*
* x = H(s | H(I | ":" | P))
* v = g^x % N
*
* @param {object} params Group parameters, with .N, .g, .hash
* @param {Buffer} salt
* @param {Buffer} I User identity
* @param {Buffer} P User password
* @return {Buffer}
*/
export function computeVerifier(params: SrpParams, salt: Buffer, I: Buffer, P: Buffer) {
assertIsBuffer(salt, 'salt (salt)');
assertIsBuffer(I, 'identity (I)');
assertIsBuffer(P, 'password (P)');
var v_num = params.g.modPow(getx(params, salt, I, P), params.N);
return v_num.toBuffer(params.N_length_bits / 8);
export type GenKeyCallback = (err: Error | null, data: Buffer | null) => void;
export class SRP {
public static readonly params = srpParams;
/**
* The verifier is calculated as described in Section 3 of [SRP-RFC].
* We give the algorithm here for convenience.
*
* The verifier (v) is computed based on the salt (s), user name (I),
* password (P), and group parameters (N, g).
*
* x = H(s | H(I | ":" | P))
* v = g^x % N
*
* @param {object} params Group parameters, with .N, .g, .hash
* @param {Buffer} salt
* @param {Buffer} I User identity
* @param {Buffer} P User password
* @return {Buffer}
*/
public static computeVerifier(params: SrpParams, salt: Buffer, I: Buffer, P: Buffer): Buffer {
assertIsBuffer(salt, 'salt (salt)');
assertIsBuffer(I, 'identity (I)');
assertIsBuffer(P, 'password (P)');
const v_num = params.g.modPow(getx(params, salt, I, P), params.N);
return v_num.toBuffer(params.N_length_bits / 8);
}
/**
* Generate a random key.
*
* @param {number} [bytes=32] Length of key
* @param {function} [callback] If not provided a Promise is returned
* @return {Promise|void}
*/
public static genKey(callback: GenKeyCallback): void;
public static genKey(bytes: number, callback: GenKeyCallback): void;
public static genKey(bytes?: number): Promise<Buffer>;
public static genKey(bytes: number | GenKeyCallback = 32, callback?: GenKeyCallback): Promise<Buffer> | void {
// bytes is optional
if (typeof bytes !== 'number') {
callback = bytes as unknown as GenKeyCallback;
bytes = 32;
}
if (!callback) return new Promise((rs, rj) => SRP.genKey(bytes as number, (err, data) => err ? rj(err) : rs(data!)));
crypto.randomBytes(bytes, (err, buf) => {
if (err) return callback!(err, null);
return callback!(null, buf);
});
}
}
/**
@ -113,32 +147,6 @@ function getk(params: SrpParams) {
return new BigInteger(k_buf);
}
/**
* Generate a random key.
*
* @param {number} [bytes=32] Length of key
* @param {function} [callback] If not provided a Promise is returned
* @return {Promise|void}
*/
type GenKeyCallback = (err: Error | null, data: Buffer | null) => void;
export function genKey(callback: GenKeyCallback): void
export function genKey(bytes: number, callback: GenKeyCallback): void
export function genKey(bytes?: number): Promise<Buffer>
export function genKey(bytes: number | GenKeyCallback = 32, callback?: GenKeyCallback): Promise<Buffer> | void {
// bytes is optional
if (typeof bytes !== 'number') {
callback = bytes as unknown as GenKeyCallback;
bytes = 32;
}
if (!callback) return new Promise((rs, rj) => genKey(bytes as number, (err, data) => err ? rj(err) : rs(data!)));
crypto.randomBytes(bytes, (err, buf) => {
if (err) return callback!(err, null);
return callback!(null, buf);
});
}
/**
* The server key exchange message also contains the server's public
* value (B). The server calculates this value as B = k*v + g^b % N,
@ -147,7 +155,8 @@ export function genKey(bytes: number | GenKeyCallback = 32, callback?: GenKeyCal
*
* Note: as the tests imply, the entire expression is mod N.
*
* @param {object} params Group parameters, with .N, .g, .hash
* @param {SrpParams} params Group parameters, with .N, .g, .hash
* @param {BigInteger} k
* @param {BigInteger} v Verifier (stored)
* @param {BigInteger} b Server secret exponent
* @return {Buffer} B - The server public message
@ -168,7 +177,7 @@ function getB(params: SrpParams, k: BigInteger, v: BigInteger, b: BigInteger) {
* Note: for this implementation, we take that to mean 256/8 bytes.
*
* @param {object} params Group parameters, with .N, .g, .hash
* @param {BigInteger} a Client secret exponent
* @param {BigInteger} a_num Client secret exponent
* @return {BigInteger} A - The client public message
*/
function getA(params: SrpParams, a_num: BigInteger) {
@ -231,10 +240,10 @@ function client_getS(params: SrpParams, k_num: BigInteger, x_num: BigInteger, a_
* The TLS premastersecret as calculated by the server
*
* @param {BigInteger} params Group parameters, with .N, .g, .hash
* @param {BigInteger} v Verifier (stored on server)
* @param {BigInteger} A Ephemeral client public key (read from client)
* @param {BigInteger} b Server ephemeral private key (generated for session)
* @param {BigInteger} u {@see getu}
* @param {BigInteger} v_num Verifier (stored on server)
* @param {BigInteger} A_num Ephemeral client public key (read from client)
* @param {BigInteger} b_num Server ephemeral private key (generated for session)
* @param {BigInteger} u_num {@see getu}
* @return {Buffer}
*/
function server_getS(params: SrpParams, v_num: BigInteger, A_num: BigInteger, b_num: BigInteger, u_num: BigInteger) {
@ -255,7 +264,7 @@ function server_getS(params: SrpParams, v_num: BigInteger, A_num: BigInteger, b_
* Compute the shared session key K from S
*
* @param {object} params Group parameters, with .N, .g, .hash
* @param {Buffer} S Session key
* @param {Buffer} S_buf Session key
* @return {Buffer}
*/
function getK(params: SrpParams, S_buf: Buffer) {
@ -273,7 +282,7 @@ function getK(params: SrpParams, S_buf: Buffer) {
}
/**
*
*
* @param params SRP params
* @param u_buf User identity
* @param s_buf User salt
@ -291,13 +300,13 @@ function getM1(params: SrpParams, u_buf: Buffer, s_buf: Buffer, A_buf: Buffer, B
assertIsBuffer(B_buf!, 'server public key (B)');
assertIsBuffer(K_buf!, 'session key (K)');
var hN = crypto.createHash(params.hash).update(params.N.toBuffer(true)).digest();
var hG = crypto.createHash(params.hash).update(params.g.toBuffer(true)).digest();
const hN = crypto.createHash(params.hash).update(params.N.toBuffer(true)).digest();
const hG = crypto.createHash(params.hash).update(params.g.toBuffer(true)).digest();
for (var i = 0; i < hN.length; i++)
for (let i = 0; i < hN.length; i++)
hN[i] ^= hG[i];
var hU = crypto.createHash(params.hash).update(u_buf).digest();
const hU = crypto.createHash(params.hash).update(u_buf).digest();
return crypto.createHash(params.hash)
.update(hN).update(hU).update(s_buf)
@ -332,19 +341,19 @@ function equal(buf1: Buffer, buf2: Buffer) {
return buf1.toString('hex') === buf2.toString('hex');
}
export class Client {
private _params: SrpParams;
private _k: BigInteger;
private _x: BigInteger;
export class SrpClient {
private readonly _params: SrpParams;
private readonly _k: BigInteger;
private readonly _x: BigInteger;
/** Client private key */
private _a: BigInteger;
private readonly _a: BigInteger;
/** Client public key */
private _A: Buffer;
private readonly _A: Buffer;
/** User identity */
private _I?: Buffer;
private readonly _I?: Buffer;
/** User salt */
private _s?: Buffer;
private readonly _s?: Buffer;
/** Session key */
private _K?: Buffer;
@ -386,7 +395,7 @@ export class Client {
this._A = getA(params, this._a);
}
/**
* Returns the client's public key (A).
*
@ -395,7 +404,7 @@ export class Client {
computeA() {
return this._A;
}
/**
* Sets the server's public key (B).
*
@ -462,21 +471,21 @@ export type VerifierIdentity = BaseIdentity & {verifier: Buffer};
export type Identity = PasswordIdentity | VerifierIdentity;
export class Server {
private _params: SrpParams;
export class SrpServer {
private readonly _params: SrpParams;
/** Multiplier parameter (H(N, g)) */
private _k: BigInteger;
private readonly _k: BigInteger;
/** Server private key */
private _b: BigInteger;
private readonly _b: BigInteger;
/** Server public key */
private _B: Buffer;
private readonly _B: Buffer;
/** Verifier */
private _v: BigInteger;
private readonly _v: BigInteger;
/** User identity */
private _I?: Buffer;
private readonly _I?: Buffer;
/** User salt */
private _s?: Buffer;
private readonly _s?: Buffer;
/** Session key */
_K?: Buffer;
@ -500,7 +509,7 @@ export class Server {
* @param {Buffer} salt_buf User salt (from server)
* @param {Buffer} identity_buf Identity/username
* @param {Buffer} password_buf Password
* @param {Buffer} secret1_buf Client private key {@see genKey}
* @param {Buffer} secret2_buf Client private key {@see genKey}
*/
constructor(params: SrpParams, salt_buf: Buffer, identity_buf: Buffer, password_buf: Buffer, secret2_buf: Buffer)
constructor(params: SrpParams, verifier_buf: Buffer, secret2_buf: Buffer)
@ -516,7 +525,7 @@ export class Server {
assertIsBuffer(secret2_buf!, 'secret2');
this._b = new BigInteger(secret2_buf!);
this._v = new BigInteger(computeVerifier(params, salt_buf as Buffer, identity_buf!, password_buf!));
this._v = new BigInteger(SRP.computeVerifier(params, salt_buf as Buffer, identity_buf!, password_buf!));
this._I = identity_buf;
this._s = salt_buf as Buffer;
@ -533,6 +542,7 @@ export class Server {
const identity = salt_buf as Identity;
[secret2_buf, salt_buf, identity_buf, password_buf] = [identity_buf, undefined, undefined, undefined];
// noinspection SuspiciousTypeOfGuard
assert(identity.username instanceof Buffer || typeof identity.username === 'string', 'identity.username (I) must be a string or Buffer');
assertIsBuffer(identity.salt, 'identity.salt (s)');
assert('password' in identity || 'verifier' in identity, 'identity requires a password or verifier');
@ -546,7 +556,7 @@ export class Server {
if ('verifier' in identity) {
this._v = new BigInteger(identity.verifier);
} else {
this._v = new BigInteger(computeVerifier(
this._v = new BigInteger(SRP.computeVerifier(
params, identity.salt, username,
typeof identity.password === 'string' ? Buffer.from(identity.password) : identity.password
));

View File

@ -1,5 +1,4 @@
import {hex} from '../lib/params';
import BigInteger = require('../../lib/jsbn');
import {hex} from '../params';
// Modulus (N), as specified by the 3072-bit group of RFC 5054
export const N = hex(`

View File

@ -1,10 +1,8 @@
// @ts-ignore
import * as vows from 'vows';
import * as assert from 'assert';
import * as srp from '..';
import BigInteger = require('../../lib/jsbn');
delete exports.__esModule;
import vows from 'vows';
import assert from 'assert';
import {SRP, SrpClient, SrpParams, SrpServer} from "../srp";
import BigInteger = require('../../jsbn/jsbn');
interface Input {
/** Identity */
@ -36,7 +34,7 @@ interface ExpectedOutput {
import {N, g, I, p, a, A, b, B, s, v, u, S, K} from './hap_test_data';
const params = srp.params.hap;
const params = SRP.params.hap;
const inputs: Input = {
I: Buffer.from(I, 'ascii'),
@ -77,14 +75,14 @@ function numequal(a: BigInteger, b: BigInteger, msg?: string) {
assert(a.compareTo(b) === 0, msg);
}
function checkVectors(params: srp.SrpParams, inputs: Input, expected: ExpectedOutput, useVerifier = true) {
function checkVectors(params: SrpParams, inputs: Input, expected: ExpectedOutput, useVerifier = true) {
hexequal(inputs.I, Buffer.from('616c696365', 'hex'), 'I');
hexequal(srp.computeVerifier(params, inputs.salt, inputs.I, inputs.P), expected.v, 'v');
hexequal(SRP.computeVerifier(params, inputs.salt, inputs.I, inputs.P), expected.v, 'v');
const client = new srp.Client(params, inputs.salt, inputs.I, inputs.P, inputs.a, true);
const client = new SrpClient(params, inputs.salt, inputs.I, inputs.P, inputs.a, true);
const server = useVerifier ?
new srp.Server(params, {username: inputs.I, salt: inputs.salt, verifier: expected.v}, inputs.b) :
new srp.Server(params, inputs.salt, inputs.I, inputs.P, inputs.b);
new SrpServer(params, {username: inputs.I, salt: inputs.salt, verifier: expected.v}, inputs.b) :
new SrpServer(params, inputs.salt, inputs.I, inputs.P, inputs.b);
// @ts-ignore
numequal(client._k, new BigInteger(expected.k.toString('hex'), 16), 'k');

View File

@ -1,10 +1,8 @@
// @ts-ignore
import * as vows from 'vows';
import * as assert from 'assert';
import * as srp from '..';
import BigInteger = require('../../lib/jsbn');
delete exports.__esModule;
import vows from 'vows';
import assert from 'assert';
import {SRP, SrpClient, SrpParams, SrpServer} from '../srp';
import BigInteger = require('../../jsbn/jsbn');
/*
* Vectors from https://wiki.mozilla.org/Identity/AttachedServices/KeyServerProtocol
@ -19,7 +17,7 @@ function hex(s: string) {
return Buffer.from(s.split(/\s/).join(''), 'hex');
}
const params = srp.params[2048];
const params = SRP.params[2048];
interface Input {
/** Identity */
@ -318,12 +316,12 @@ function numequal(a: BigInteger, b: BigInteger, msg?: string) {
assert(a.compareTo(b) === 0, msg);
}
function checkVectors(params: srp.SrpParams, inputs: Input, expected: ExpectedOutput) {
function checkVectors(params: SrpParams, inputs: Input, expected: ExpectedOutput) {
hexequal(inputs.I, Buffer.from('616e6472c3a9406578616d706c652e6f7267', 'hex'), 'I');
hexequal(srp.computeVerifier(params, inputs.salt, inputs.I, inputs.P), expected.v, 'v');
hexequal(SRP.computeVerifier(params, inputs.salt, inputs.I, inputs.P), expected.v, 'v');
const client = new srp.Client(params, inputs.salt, inputs.I, inputs.P, inputs.a, false);
const server = new srp.Server(params, expected.v, inputs.b);
const client = new SrpClient(params, inputs.salt, inputs.I, inputs.P, inputs.a, false);
const server = new SrpServer(params, expected.v, inputs.b);
// @ts-ignore
numequal(client._k, new BigInteger(expected.k.toString('hex'), 16), 'k');

View File

@ -1,12 +1,10 @@
// @ts-ignore
import * as vows from 'vows';
import * as assert from 'assert';
import * as srp from '..';
import BigInteger = require('../../lib/jsbn');
import vows from 'vows';
import assert from 'assert';
import {SRP, SrpClient, SrpServer} from '../srp';
import BigInteger = require('../../jsbn/jsbn');
delete exports.__esModule;
const params = srp.params[1024];
const params = SRP.params[1024];
/*
* http://tools.ietf.org/html/rfc5054#appendix-B
@ -60,11 +58,11 @@ function asHex(num: number | BigInteger) {
vows.describe('RFC 5054').addBatch({
'Test vectors': {
topic() {
return srp.computeVerifier(params, s, I, P);
return SRP.computeVerifier(params, s, I, P);
},
'x'() {
const client = new srp.Client(params, s, I, P, a, false);
const client = new SrpClient(params, s, I, P, a, false);
// @ts-ignore
assert.equal(asHex(client._x), x_expected);
},
@ -74,37 +72,37 @@ vows.describe('RFC 5054').addBatch({
},
'k'() {
const client = new srp.Client(params, s, I, P, a, false);
const client = new SrpClient(params, s, I, P, a, false);
// @ts-ignore
assert.equal(asHex(client._k), k_expected);
},
'A'() {
const client = new srp.Client(params, s, I, P, a, false);
const client = new SrpClient(params, s, I, P, a, false);
assert.equal(client.computeA().toString('hex'), A_expected);
},
'B'(v: Buffer) {
const server = new srp.Server(params, v, b);
const server = new SrpServer(params, v, b);
assert.equal(server.computeB().toString('hex'), B_expected);
},
'u'() {
const client = new srp.Client(params, s, I, P, a, false);
const client = new SrpClient(params, s, I, P, a, false);
client.setB(Buffer.from(B_expected, 'hex'));
// @ts-ignore
assert.equal(asHex(client._u), u_expected);
},
'S client'() {
const client = new srp.Client(params, s, I, P, a, false);
const client = new SrpClient(params, s, I, P, a, false);
client.setB(Buffer.from(B_expected, 'hex'));
// @ts-ignore
assert.equal(client._S.toString('hex'), S_expected);
},
'S server'(v: Buffer) {
const server = new srp.Server(params, v, b);
const server = new SrpServer(params, v, b);
server.setA(Buffer.from(A_expected, 'hex'));
// @ts-ignore
assert.equal(server._S.toString('hex'), S_expected);

View File

@ -1,11 +1,9 @@
// @ts-ignore
import * as vows from 'vows';
import * as assert from 'assert';
import * as srp from '..';
import vows from 'vows';
import assert from 'assert';
import {SRP, SrpClient, SrpServer} from '../srp';
delete exports.__esModule;
const params = srp.params[4096];
const params = SRP.params[4096];
const salt = Buffer.from('salty');
const identity = Buffer.from('alice');
@ -13,7 +11,7 @@ const password = Buffer.from('password123');
assert(params, 'missing parameters');
let client: srp.Client, server: srp.Server;
let client: SrpClient, server: SrpServer;
let a: Buffer, A: Buffer;
let b: Buffer, B: Buffer;
let verifier: Buffer;
@ -21,25 +19,25 @@ let verifier: Buffer;
vows.describe('srp.js').addBatch({
'create Verifier'() {
verifier = srp.computeVerifier(params, salt, identity, password);
verifier = SRP.computeVerifier(params, salt, identity, password);
assert.equal(verifier.toString('hex'), 'f0e47f50f5dead8db8d93a279e3b62d6ff50854b31fbd3474a886bef916261717e84dd4fb8b4d27feaa5146db7b1cbbc274fdf96a132b5029c2cd72527427a9b9809d5a4d018252928b4fc343bc17ce63c1859d5806f5466014fc361002d8890aeb4d6316ff37331fc2761be0144c91cdd8e00ed0138c0ce51534d1b9a9ba629d7be34d2742dd4097daabc9ecb7aaad89e53c342b038f1d2adae1f2410b7884a3e9a124c357e421bccd4524467e1922660e0a4460c5f7c38c0877b65f6e32f28296282a93fc11bbabb7bb69bf1b3f9391991d8a86dd05e15000b7e38ba38a536bb0bf59c808ec25e791b8944719488b8087df8bfd7ff20822997a53f6c86f3d45d004476d6303301376bb25a9f94b552cce5ed40de5dd7da8027d754fa5f66738c7e3fc4ef3e20d625df62cbe6e7adfc21e47880d8a6ada37e60370fd4d8fc82672a90c29f2e72f35652649d68348de6f36d0e435c8bd42dd00155d35d501becc0661b43e04cdb2da84ce92b8bf49935d73d75efcbd1176d7bbccc3cc4d4b5fefcc02d478614ee1681d2ff3c711a61a7686eb852ae06fb8227be21fb8802719b1271ba1c02b13bbf0a2c2e459d9bedcc8d1269f6a785cb4563aa791b38fb038269f63f58f47e9051499549789269cc7b8ec7026fc34ba73289c4af829d5a532e723967ce9b6c023ef0fd0cfe37f51f10f19463b6534159a09ddd2f51f3b30033');
},
'create a and b': {
topic(this: any) {(async () => {
a = await srp.genKey(64);
b = await srp.genKey(32);
a = await SRP.genKey(64);
b = await SRP.genKey(32);
this.callback();
})()},
'use a and b'() {
client = new srp.Client(params, salt, identity, password, a, false);
client = new SrpClient(params, salt, identity, password, a, false);
// client produces A
A = client.computeA();
// create server
server = new srp.Server(params, verifier, b);
server = new SrpServer(params, verifier, b);
// server produces B
B = server.computeB();
@ -70,8 +68,8 @@ vows.describe('srp.js').addBatch({
},
'server rejects wrong M1'() {
const bad_client = new srp.Client(params, salt, identity, Buffer.from('bad'), a, false);
const server2 = new srp.Server(params, verifier, b);
const bad_client = new SrpClient(params, salt, identity, Buffer.from('bad'), a, false);
const server2 = new SrpServer(params, verifier, b);
bad_client.setB(server2.computeB());
assert.throws(() => server.checkM1(bad_client.computeM1()), /client did not use the same password/);
},
@ -81,7 +79,7 @@ vows.describe('srp.js').addBatch({
// reject 2*N too, but our Buffer-length checks reject it before the
// number itself is examined.
var server2 = new srp.Server(params, verifier, b);
var server2 = new SrpServer(params, verifier, b);
var Azero = Buffer.alloc(params.N_length_bits / 8);
Azero.fill(0);
//! var AN = params.N.toBuffer();
@ -95,7 +93,7 @@ vows.describe('srp.js').addBatch({
'client rejects bad B'() {
// server's "B" must be 1..N-1 . Reject 0 and N and N+1
var client2 = new srp.Client(params, salt, identity, password, a, false);
var client2 = new SrpClient(params, salt, identity, password, a, false);
var Bzero = Buffer.alloc(params.N_length_bits / 8);
Bzero.fill(0, 0, params.N_length_bits / 8);
//! var BN = params.N.toBuffer();
@ -108,13 +106,13 @@ vows.describe('srp.js').addBatch({
},
'client rejects bad M2'() {
client = new srp.Client(params, salt, identity, password, a, false);
client = new SrpClient(params, salt, identity, password, a, false);
// client produces A
A = client.computeA();
// create server
server = new srp.Server(params, verifier, b);
server = new SrpServer(params, verifier, b);
// server produces B
B = server.computeB();

View File

@ -1,12 +1,22 @@
{
"compilerOptions": {
"strict": true,
"target": "ES2018",
"module": "commonjs",
"lib": [
"es2015",
"es2016",
"es2017",
"es2018"
],
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "lib",
"rootDir": "src",
"outDir": "dist"
"strict": true,
"esModuleInterop": true
},
"include": [
"src/**/*"
"src/"
]
}