Skip to content
This repository was archived by the owner on Aug 2, 2022. It is now read-only.

Adding an alternative option for browser to generate key pairs (release/21.0.x branch) #749

Merged
merged 4 commits into from
Jun 9, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/eosjs-ecc-migration.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import {PrivateKey, PublicKey, Signature} from './eosjs-jssig';
import {generateKeyPair} from './eosjs-key-conversions';
import {KeyType} from './eosjs-numeric';
import {ec as EC} from 'elliptic';

export const ecc = {
initialize: () => console.error('Method deprecated'),
unsafeRandomKey: () => console.error('Method deprecated'),
randomKey: (cpuEntropyBits?: number): Promise<string> => {
randomKey: (
cpuEntropyBits?: number, options: { secureEnv?: boolean, ecOptions?: EC.GenKeyPairOptions } = {}
): Promise<string> => {
if (cpuEntropyBits !== undefined) {
console.warn('Argument `cpuEntropyBits` is deprecated, ' +
'use the options argument instead');
}

const { privateKey } = generateKeyPair(KeyType.k1);
const { privateKey } = generateKeyPair(KeyType.k1, options);
return Promise.resolve(privateKey.toLegacyString());
},
seedPrivate: () => console.error('Method deprecated'),
Expand Down
12 changes: 6 additions & 6 deletions src/eosjs-key-conversions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@ export const constructElliptic = (type: KeyType): EC => {
return new EC('p256') as any;
};

export const generateKeyPair = (type: KeyType, options?: EC.GenKeyPairOptions):
export const generateKeyPair = (type: KeyType, options: { secureEnv?: boolean, ecOptions?: EC.GenKeyPairOptions } = {}):
{publicKey: PublicKey, privateKey: PrivateKey} => {
if (process.env.EOSJS_KEYGEN_ALLOWED !== 'true') {
if (!options.secureEnv) {
throw new Error('Key generation is completely INSECURE in production environments in the browser. ' +
'If you are absolutely certain this does NOT describe your environment, add an environment variable ' +
'`EOSJS_KEYGEN_ALLOWED` set to \'true\'. If this does describe your environment and you add the ' +
'environment variable, YOU DO SO AT YOUR OWN RISK AND THE RISK OF YOUR USERS.');
'If you are absolutely certain this does NOT describe your environment, set `secureEnv` in your ' +
'options to `true`. If this does describe your environment and you set `secureEnv` to `true`, ' +
'YOU DO SO AT YOUR OWN RISK AND THE RISK OF YOUR USERS.');
}
let ec;
if (type === KeyType.k1) {
ec = new EC('secp256k1') as any;
} else {
ec = new EC('p256') as any;
}
const ellipticKeyPair = ec.genKeyPair(options);
const ellipticKeyPair = ec.genKeyPair(options.ecOptions);
const publicKey = PublicKey.fromElliptic(ellipticKeyPair, type, ec);
const privateKey = PrivateKey.fromElliptic(ellipticKeyPair, type, ec);
return {publicKey, privateKey};
Expand Down
3 changes: 1 addition & 2 deletions src/tests/eosjs-ecc-migration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ describe('ecc Migration', () => {
});

it('verifies `randomKey` calls generateKeyPair', async () => {
process.env.EOSJS_KEYGEN_ALLOWED = 'true';
console.warn = jest.fn();
const privateKey = await eccMigration.randomKey(0);
const privateKey = await eccMigration.randomKey(0, { secureEnv: true });
expect(console.warn).toHaveBeenCalledWith('Argument `cpuEntropyBits` is deprecated, ' +
'use the options argument instead');
expect(typeof privateKey).toEqual('string');
Expand Down
12 changes: 4 additions & 8 deletions src/tests/eosjs-jssig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,14 @@ describe('JsSignatureProvider', () => {
// These are simplified tests simply to verify a refactor didn't mess with existing code
describe('secp256k1 elliptic', () => {
it('generates a private and public key pair', () => {
process.env.EOSJS_KEYGEN_ALLOWED = 'true';
const {privateKey, publicKey} = generateKeyPair(KeyType.k1);
const {privateKey, publicKey} = generateKeyPair(KeyType.k1, { secureEnv: true });
expect(privateKey).toBeInstanceOf(PrivateKey);
expect(privateKey.isValid()).toBeTruthy();
expect(publicKey).toBeInstanceOf(PublicKey);
expect(publicKey.isValid()).toBeTruthy();
});

it('throws error with no EOSJS_KEYGEN_ALLOWED environment variable', () => {
process.env.EOSJS_KEYGEN_ALLOWED = null;
it('throws error with no options.secureEnv variable', () => {
expect(() => generateKeyPair(KeyType.k1)).toThrowError();
});

Expand Down Expand Up @@ -202,16 +200,14 @@ describe('JsSignatureProvider', () => {

describe('p256 elliptic', () => {
it('generates a private and public key pair', () => {
process.env.EOSJS_KEYGEN_ALLOWED = 'true';
const {privateKey, publicKey} = generateKeyPair(KeyType.r1);
const {privateKey, publicKey} = generateKeyPair(KeyType.r1, { secureEnv: true });
expect(privateKey).toBeInstanceOf(PrivateKey);
expect(privateKey.isValid()).toBeTruthy();
expect(publicKey).toBeInstanceOf(PublicKey);
expect(publicKey.isValid()).toBeTruthy();
});

it('throws error with no EOSJS_KEYGEN_ALLOWED environment variable', () => {
process.env.EOSJS_KEYGEN_ALLOWED = null;
it('throws error with no options.secureEnv variable', () => {
expect(() => generateKeyPair(KeyType.r1)).toThrowError();
});

Expand Down