private void receive_newkeys(Buffer buf, KeyExchange kex) { updateKeys(kex); m_in_kex = false; }
private void updateKeys(KeyExchange kex) { byte[] K = kex.getK(); byte[] H = kex.getH(); HASH hash = kex.getHash(); string[] guess = kex.m_guess; if (m_session_id == null) { m_session_id = new byte[H.Length]; Array.Copy(H, 0, m_session_id, 0, H.Length); } /* Initial IV client to server: HASH (K || H || "A" || session_id) Initial IV server to client: HASH (K || H || "B" || session_id) Encryption key client to server: HASH (K || H || "C" || session_id) Encryption key server to client: HASH (K || H || "D" || session_id) Integrity key client to server: HASH (K || H || "E" || session_id) Integrity key server to client: HASH (K || H || "F" || session_id) */ m_buf.reset(); m_buf.putMPInt(K); m_buf.putByte(H); m_buf.putByte((byte)0x41); m_buf.putByte(m_session_id); hash.update(m_buf.m_buffer, 0, m_buf.m_index); m_IVc2s = hash.digest(); int j = m_buf.m_index - m_session_id.Length - 1; m_buf.m_buffer[j]++; hash.update(m_buf.m_buffer, 0, m_buf.m_index); m_IVs2c = hash.digest(); m_buf.m_buffer[j]++; hash.update(m_buf.m_buffer, 0, m_buf.m_index); m_Ec2s = hash.digest(); m_buf.m_buffer[j]++; hash.update(m_buf.m_buffer, 0, m_buf.m_index); m_Es2c = hash.digest(); m_buf.m_buffer[j]++; hash.update(m_buf.m_buffer, 0, m_buf.m_index); m_MACc2s = hash.digest(); m_buf.m_buffer[j]++; hash.update(m_buf.m_buffer, 0, m_buf.m_index); m_MACs2c = hash.digest(); try { Class c; c = Class.ForName(getConfig(guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC])); m_s2ccipher = (Cipher)(c.Instance()); while (m_s2ccipher.BlockSize > m_Es2c.Length) { m_buf.reset(); m_buf.putMPInt(K); m_buf.putByte(H); m_buf.putByte(m_Es2c); hash.update(m_buf.m_buffer, 0, m_buf.m_index); byte[] foo = hash.digest(); byte[] bar = new byte[m_Es2c.Length + foo.Length]; Array.Copy(m_Es2c, 0, bar, 0, m_Es2c.Length); Array.Copy(foo, 0, bar, m_Es2c.Length, foo.Length); m_Es2c = bar; } m_s2ccipher.init(jsch.Cipher.DECRYPT_MODE, m_Es2c, m_IVs2c); m_cipher_size = m_s2ccipher.IVSize; c = Class.ForName(getConfig(guess[KeyExchange.PROPOSAL_MAC_ALGS_STOC])); m_s2cmac = (MAC)(c.Instance()); m_s2cmac.init(m_MACs2c); m_mac_buf = new byte[m_s2cmac.BlockSize]; c = Class.ForName(getConfig(guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS])); m_c2scipher = (Cipher)(c.Instance()); while (m_c2scipher.BlockSize > m_Ec2s.Length) { m_buf.reset(); m_buf.putMPInt(K); m_buf.putByte(H); m_buf.putByte(m_Ec2s); hash.update(m_buf.m_buffer, 0, m_buf.m_index); byte[] foo = hash.digest(); byte[] bar = new byte[m_Ec2s.Length + foo.Length]; Array.Copy(m_Ec2s, 0, bar, 0, m_Ec2s.Length); Array.Copy(foo, 0, bar, m_Ec2s.Length, foo.Length); m_Ec2s = bar; } m_c2scipher.init(jsch.Cipher.ENCRYPT_MODE, m_Ec2s, m_IVc2s); c = Class.ForName(getConfig(guess[KeyExchange.PROPOSAL_MAC_ALGS_CTOS])); m_c2smac = (MAC)(c.Instance()); m_c2smac.init(m_MACc2s); if (!guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS].Equals("none")) { string foo = getConfig(guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS]); if (foo != null) { try { c = Class.ForName(foo); m_deflater = (Compression)(c.Instance()); int level = 6; try { level = int.Parse(getConfig("compression_level")); } catch (Exception) { } m_deflater.init(Compression.DEFLATER, level); } catch (Exception) { Console.Error.WriteLine(foo + " isn't accessible."); } } } else { if (m_deflater != null) m_deflater = null; } if (!guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC].Equals("none")) { string foo = getConfig(guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC]); if (foo != null) { try { c = Class.ForName(foo); m_inflater = (Compression)(c.Instance()); m_inflater.init(Compression.INFLATER, 0); } catch (Exception) { Console.Error.WriteLine(foo + " isn't accessible."); } } } else { if (m_inflater != null) m_inflater = null; } } catch (Exception e) { Console.Error.WriteLine("updatekeys: " + e); } }
private void checkHost(string host, KeyExchange kex) { string shkc = getConfig("StrictHostKeyChecking"); byte[] K_S = kex.getHostKey(); string key_type = kex.getKeyType(); string key_fprint = kex.getFingerPrint(); m_hostkey = new HostKey(host, K_S); HostKeyRepository hkr = m_jsch.getHostKeyRepository(); int i = 0; lock (hkr) { i = hkr.check(host, K_S); } bool insert = false; if ((shkc.Equals("ask") || shkc.Equals("yes")) && i == HostKeyRepository.CHANGED) { string file = null; lock (hkr) { file = hkr.getKnownHostsRepositoryID(); } if (file == null) file = "known_hosts"; string message = "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!\n" + "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n" + "Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n" + "It is also possible that the " + key_type + " host key has just been changed.\n" + "The fingerprint for the " + key_type + " key sent by the remote host is\n" + key_fprint + ".\n" + "Please contact your system administrator.\n" + "Add correct host key in " + file + " to get rid of this message."; bool b = false; if (m_userinfo != null) b = m_userinfo.promptYesNo(message + "\nDo you want to delete the old key and insert the new key?"); //throw new JSchException("HostKey has been changed: "+host); if (!b) throw new JSchException("HostKey has been changed: " + host); else lock (hkr) { hkr.remove(host, (key_type.Equals("DSA") ? "ssh-dss" : "ssh-rsa"), null); insert = true; } } if ((shkc.Equals("ask") || shkc.Equals("yes")) && (i != HostKeyRepository.OK) && !insert) { if (shkc.Equals("yes")) throw new JSchException("reject HostKey: " + host); if (m_userinfo != null) { bool foo = m_userinfo.promptYesNo( "The authenticity of host '" + host + "' can't be established.\n" + key_type + " key fingerprint is " + key_fprint + ".\n" + "Are you sure you want to continue connecting?" ); if (!foo) throw new JSchException("reject HostKey: " + host); insert = true; } else { if (i == HostKeyRepository.NOT_INCLUDED) throw new JSchException("UnknownHostKey: " + host + ". " + key_type + " key fingerprint is " + key_fprint); else throw new JSchException("HostKey has been changed: " + host); } } if (shkc.Equals("no") && HostKeyRepository.NOT_INCLUDED == i) insert = true; if (insert) lock (hkr) { hkr.add(host, K_S, m_userinfo); } }