in Sources/NIOSSH/Key Exchange/SSHKeyExchangeStateMachine.swift [245:279]
mutating func handle(keyExchangeReply message: SSHMessage.KeyExchangeECDHReplyMessage) throws -> EventLoopFuture<SSHMultiMessage?> {
switch self.state {
case .keyExchangeInitSent(exchange: var exchanger, negotiated: let negotiated):
switch self.role {
case .client:
guard message.hostKey.keyPrefix.elementsEqual(negotiated.negotiatedHostKeyAlgorithm.utf8) else {
throw NIOSSHError.invalidHostKeyForKeyExchange(expected: negotiated.negotiatedHostKeyAlgorithm,
got: message.hostKey.keyPrefix)
}
let result = try exchanger.receiveServerKeyExchangePayload(
serverKeyExchangeMessage: message,
initialExchangeBytes: &self.initialExchangeBytes,
allocator: self.allocator,
expectedKeySizes: negotiated.negotiatedProtection.keySizes
)
self.state = .keysExchanged(result: result, protection: try negotiated.negotiatedProtection.init(initialKeys: result.keys), negotiated: negotiated)
// Ok, we've modified the state, now we can ask the user if they like this host key.
guard case .client(let clientConfig) = self.role else {
preconditionFailure("Should not be in .keyExchangeInitSent as server")
}
let promise = self.loop.makePromise(of: Void.self)
clientConfig.serverAuthDelegate.validateHostKey(hostKey: message.hostKey, validationCompletePromise: promise)
return promise.futureResult.map {
SSHMultiMessage(SSHMessage.newKeys)
}
case .server:
preconditionFailure("Servers cannot enter key exchange init sent.")
}
case .idle, .keyExchangeSent, .keyExchangeReceived, .awaitingKeyExchangeInit, .awaitingKeyExchangeInitInvalidGuess, .keyExchangeInitReceived, .keysExchanged, .newKeysSent, .newKeysReceived, .complete:
throw SSHKeyExchangeError.unexpectedMessage
}
}