diff --git a/lib/protocol/kex.js b/lib/protocol/kex.js index 811e631b..0c2a1184 100644 --- a/lib/protocol/kex.js +++ b/lib/protocol/kex.js @@ -1539,6 +1539,17 @@ const createKeyExchange = (() => { } } + // Oakley Group 2 (RFC 2409 section 6.2), used by diffie-hellman-group1-sha1. + // BoringSSL (e.g. Electron) does not provide it as a named group, so it is + // always built from its prime and generator instead. + const MODP2_PRIME = Buffer.from( + 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' + + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' + + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' + + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF', + 'hex' + ); + class DHExchange extends KeyExchange { constructor(groupName, hashName, ...args) { super(...args); @@ -1566,7 +1577,9 @@ const createKeyExchange = (() => { } generateKeys() { if (!this._dh) { - this._dh = createDiffieHellmanGroup(this.groupName); + this._dh = (this.groupName === 'modp2' + ? createDiffieHellman(MODP2_PRIME, 2) + : createDiffieHellmanGroup(this.groupName)); this._public = this._dh.generateKeys(); } } diff --git a/test/test-kex-group1.js b/test/test-kex-group1.js new file mode 100644 index 00000000..25f240fd --- /dev/null +++ b/test/test-kex-group1.js @@ -0,0 +1,36 @@ +'use strict'; + +// Some crypto backends (e.g. BoringSSL, as used by Electron) do not provide the +// legacy 'modp1' and 'modp2' named groups. Remove them before loading the +// library to make sure diffie-hellman-group1-sha1 does not need them. +const crypto = require('crypto'); +const createDiffieHellmanGroup = crypto.createDiffieHellmanGroup; +crypto.createDiffieHellmanGroup = (name) => { + if (name === 'modp1' || name === 'modp2') + throw new Error('Unknown DH group'); + return createDiffieHellmanGroup(name); +}; + +const { fixtureKey, mustCall, setup } = require('./common.js'); + +const debug = false; + +const algorithms = { kex: [ 'diffie-hellman-group1-sha1' ] }; +const { client, server } = setup( + 'diffie-hellman-group1-sha1 without named group support', + { + client: { username: 'Password User', password: '12345', algorithms }, + server: { hostKeys: [ fixtureKey('ssh_host_rsa_key').raw ], algorithms }, + debug, + } +); + +server.on('connection', mustCall((conn) => { + conn.on('authentication', mustCall((ctx) => { + ctx.accept(); + })); +})); + +client.on('ready', mustCall(() => { + client.end(); +}));