'use strict'; const assert = require('assert'); const { fixtureKey, mustCall, setup, } = require('./common.js'); const debug = false; [ { desc: 'RSA user key (old OpenSSH)', hostKey: fixtureKey('id_rsa') }, { desc: 'RSA user key (new OpenSSH)', hostKey: fixtureKey('openssh_new_rsa') }, { desc: 'DSA host key', hostKey: fixtureKey('ssh_host_dsa_key') }, { desc: 'ECDSA host key', hostKey: fixtureKey('ssh_host_ecdsa_key') }, { desc: 'PPK', hostKey: fixtureKey('id_rsa.ppk') }, ].forEach((test) => { const { desc, hostKey } = test; const clientKey = fixtureKey('openssh_new_rsa'); const username = 'KeyUser'; const { server } = setup( desc, { client: { username, privateKey: clientKey.raw, algorithms: { serverHostKey: [ hostKey.key.type ], } }, server: { hostKeys: [ hostKey.raw ] }, debug, } ); server.on('connection', mustCall((conn) => { let authAttempt = 0; conn.on('authentication', mustCall((ctx) => { assert(ctx.username === username, `Wrong username: ${ctx.username}`); switch (++authAttempt) { case 1: assert(ctx.method === 'none', `Wrong auth method: ${ctx.method}`); return ctx.reject(); case 3: assert(ctx.signature, 'Missing publickey signature'); // FALLTHROUGH case 2: assert(ctx.method === 'publickey', `Wrong auth method: ${ctx.method}`); assert(ctx.key.algo === clientKey.key.type, `Wrong key algo: ${ctx.key.algo}`); assert.deepStrictEqual(clientKey.key.getPublicSSH(), ctx.key.data, 'Public key mismatch'); break; } if (ctx.signature) { assert(clientKey.key.verify(ctx.blob, ctx.signature) === true, 'Could not verify publickey signature'); } ctx.accept(); }, 3)).on('ready', mustCall(() => { conn.end(); })); })); }); { const RSA_KEY = fixtureKey('ssh_host_rsa_key'); const ECDSA_KEY = fixtureKey('ssh_host_ecdsa_key'); [ RSA_KEY, ECDSA_KEY ].forEach((key) => { const selKeyType = key.key.type; const clientKey = fixtureKey('openssh_new_rsa'); const username = 'KeyUser'; const { client, server } = setup( `Multiple host key types (${key.type} selected)`, { client: { username, privateKey: clientKey.raw, algorithms: { serverHostKey: [ selKeyType ], } }, server: { hostKeys: [ RSA_KEY.raw, ECDSA_KEY.raw ] }, debug, } ); server.on('connection', mustCall((conn) => { let authAttempt = 0; conn.on('authentication', mustCall((ctx) => { assert(ctx.username === username, `Wrong username: ${ctx.username}`); switch (++authAttempt) { case 1: assert(ctx.method === 'none', `Wrong auth method: ${ctx.method}`); return ctx.reject(); case 3: assert(ctx.signature, 'Missing publickey signature'); // FALLTHROUGH case 2: assert(ctx.method === 'publickey', `Wrong auth method: ${ctx.method}`); assert(ctx.key.algo === clientKey.key.type, `Wrong key algo: ${ctx.key.algo}`); assert.deepStrictEqual(clientKey.key.getPublicSSH(), ctx.key.data, 'Public key mismatch'); break; } if (ctx.signature) { assert(clientKey.key.verify(ctx.blob, ctx.signature) === true, 'Could not verify publickey signature'); } ctx.accept(); }, 3)).on('ready', mustCall(() => { conn.end(); })); })); client.on('handshake', mustCall((info) => { assert(info.serverHostKey === selKeyType, 'Wrong host key selected'); })); }); }