@Override public boolean next(Message msg, SSHPacket packet) throws GeneralSecurityException, TransportException { if (msg != Message.KEXDH_31) throw new TransportException( DisconnectReason.KEY_EXCHANGE_FAILED, "Unexpected packet: " + msg); log.debug("Received SSH_MSG_KEXDH_REPLY"); final byte[] K_S; final BigInteger f; final byte[] sig; // signature sent by server try { K_S = packet.readBytes(); f = packet.readMPInt(); sig = packet.readBytes(); hostKey = new Buffer.PlainBuffer(K_S).readPublicKey(); } catch (Buffer.BufferException be) { throw new TransportException(be); } dh.computeK(f); final Buffer.PlainBuffer buf = new Buffer.PlainBuffer() .putString(V_C) .putString(V_S) .putString(I_C) .putString(I_S) .putString(K_S) .putMPInt(dh.getE()) .putMPInt(f) .putMPInt(dh.getK()); sha1.update(buf.array(), buf.rpos(), buf.available()); H = sha1.digest(); Signature signature = Factory.Named.Util.create( trans.getConfig().getSignatureFactories(), KeyType.fromKey(hostKey).toString()); signature.init(hostKey, null); signature.update(H, 0, H.length); if (!signature.verify(sig)) throw new TransportException( DisconnectReason.KEY_EXCHANGE_FAILED, "KeyExchange signature verification failed"); return true; }
@Override public void init(Transport trans, String V_S, String V_C, byte[] I_S, byte[] I_C) throws GeneralSecurityException, TransportException { this.trans = trans; this.V_S = V_S; this.V_C = V_C; this.I_S = Arrays.copyOf(I_S, I_S.length); this.I_C = Arrays.copyOf(I_C, I_C.length); sha1.init(); initDH(dh); log.debug("Sending SSH_MSG_KEXDH_INIT"); trans.write(new SSHPacket(Message.KEXDH_INIT).putMPInt(dh.getE())); }