(cfg, listener)
| 215 | |
| 216 | class Server extends EventEmitter { |
| 217 | constructor(cfg, listener) { |
| 218 | super(); |
| 219 | |
| 220 | if (typeof cfg !== 'object' || cfg === null) |
| 221 | throw new Error('Missing configuration object'); |
| 222 | |
| 223 | const hostKeys = Object.create(null); |
| 224 | const hostKeyAlgoOrder = []; |
| 225 | |
| 226 | const hostKeys_ = cfg.hostKeys; |
| 227 | if (!Array.isArray(hostKeys_)) |
| 228 | throw new Error('hostKeys must be an array'); |
| 229 | |
| 230 | const cfgAlgos = ( |
| 231 | typeof cfg.algorithms === 'object' && cfg.algorithms !== null |
| 232 | ? cfg.algorithms |
| 233 | : {} |
| 234 | ); |
| 235 | |
| 236 | const hostKeyAlgos = generateAlgorithmList( |
| 237 | cfgAlgos.serverHostKey, |
| 238 | DEFAULT_SERVER_HOST_KEY, |
| 239 | SUPPORTED_SERVER_HOST_KEY |
| 240 | ); |
| 241 | for (let i = 0; i < hostKeys_.length; ++i) { |
| 242 | let privateKey; |
| 243 | if (Buffer.isBuffer(hostKeys_[i]) || typeof hostKeys_[i] === 'string') |
| 244 | privateKey = parseKey(hostKeys_[i]); |
| 245 | else |
| 246 | privateKey = parseKey(hostKeys_[i].key, hostKeys_[i].passphrase); |
| 247 | |
| 248 | if (privateKey instanceof Error) |
| 249 | throw new Error(`Cannot parse privateKey: ${privateKey.message}`); |
| 250 | |
| 251 | if (Array.isArray(privateKey)) { |
| 252 | // OpenSSH's newer format only stores 1 key for now |
| 253 | privateKey = privateKey[0]; |
| 254 | } |
| 255 | |
| 256 | if (privateKey.getPrivatePEM() === null) |
| 257 | throw new Error('privateKey value contains an invalid private key'); |
| 258 | |
| 259 | // Discard key if we already found a key of the same type |
| 260 | if (hostKeyAlgoOrder.includes(privateKey.type)) |
| 261 | continue; |
| 262 | |
| 263 | if (privateKey.type === 'ssh-rsa') { |
| 264 | // SSH supports multiple signature hashing algorithms for RSA, so we add |
| 265 | // the algorithms in the desired order |
| 266 | let sha1Pos = hostKeyAlgos.indexOf('ssh-rsa'); |
| 267 | const sha256Pos = hostKeyAlgos.indexOf('rsa-sha2-256'); |
| 268 | const sha512Pos = hostKeyAlgos.indexOf('rsa-sha2-512'); |
| 269 | if (sha1Pos === -1) { |
| 270 | // Fall back to giving SHA1 the lowest priority |
| 271 | sha1Pos = Infinity; |
| 272 | } |
| 273 | [sha1Pos, sha256Pos, sha512Pos].sort(compareNumbers).forEach((pos) => { |
| 274 | if (pos === -1) |
nothing calls this directly
no test coverage detected