public static KexAgreement findAgreement(KexInitData s, KexInitData c) throws IOException { KexAgreement a = new KexAgreement(); a.kexAlgorithm = Tools.findFirstMatchingElement(c.getKexAlgorithms(), s.getKexAlgorithms()); a.serverHostKeyAlgorithm = Tools.findFirstMatchingElement( c.getServerHostKeyAlgorithms(), s.getServerHostKeyAlgorithms()); a.clientToServerCryptoAlgorithm = Tools.findFirstMatchingElement( c.getClientToServerCryptoAlgorithms(), s.getClientToServerCryptoAlgorithms()); a.serverToClientCryptoAlgorithm = Tools.findFirstMatchingElement( c.getServerToClientCryptoAlgorithms(), s.getServerToClientCryptoAlgorithms()); a.MACClientToServer = Tools.findFirstMatchingElement(c.getMACClientToServer(), s.getMACClientToServer()); a.MACServerToClient = Tools.findFirstMatchingElement(c.getMACServerToClient(), s.getMACServerToClient()); a.languageClientToServer = Tools.findFirstMatchingElement( c.getLanguagesClientToServer(), s.getLanguagesClientToServer()); a.languageServerToClient = Tools.findFirstMatchingElement( c.getLanguagesServerToClient(), s.getLanguagesServerToClient()); a.compressionClientToServer = Tools.findFirstMatchingElement( c.getCompressionClientToServer(), s.getCompressionClientToServer()); a.compressionServerToClient = Tools.findFirstMatchingElement( c.getCompressionServerToClient(), s.getCompressionServerToClient()); // @todo better handling of errors an exception - perhaps even throw exception // in comparator itself? Not an IO exception, but AgreementFailedException... if (a.kexAlgorithm == null) { throw new IOException("Could not agree upon KEX algorithm"); } if (a.serverHostKeyAlgorithm == null) { throw new IOException("Could not agree upon Server Host Key algorithm"); } if (a.clientToServerCryptoAlgorithm == null) { throw new IOException("Could not agree upon C->S Crypto algorithm"); } if (a.serverToClientCryptoAlgorithm == null) { throw new IOException("Could not agree upon S->C Crypto algorithm"); } if (a.MACClientToServer == null) { throw new IOException("Could not agree upon C->S MAC algorithm"); } if (a.MACServerToClient == null) { throw new IOException("Could not agree upon S->C MAC algorithm"); } // Note that we may have an empty string, but should NEVER have null for these // last two items. if (a.compressionClientToServer == null) { throw new IOException("Could not agree upon C->S Compression algorithm"); } if (a.compressionServerToClient == null) { throw new IOException("Could not agree upon S->C Compression algorithm"); } // Language is entirely optional, so null is valid. /** * if (a.languageClientToServer == null) { throw new IOException("Could not agree upon C->S * language"); } if (a.languageServerToClient == null) { throw new IOException("Could not agree * upon S->C language"); } */ return a; }