}
public boolean next(Buffer buffer) throws Exception {
byte cmd = buffer.getByte();
if (cmd != expected) {
throw new SshException(SshConstants.SSH2_DISCONNECT_KEY_EXCHANGE_FAILED,
"Protocol error: expected packet " + expected + ", got " + cmd);
}
if (cmd == SshConstants.SSH_MSG_KEX_DH_GEX_GROUP) {
log.debug("Received SSH_MSG_KEX_DH_GEX_GROUP");
p = buffer.getMPIntAsBytes();
g = buffer.getMPIntAsBytes();
dh = getDH(new BigInteger(p), new BigInteger(g));
hash = dh.getHash();
hash.init();
e = dh.getE();
log.debug("Send SSH_MSG_KEX_DH_GEX_INIT");
buffer = session.createBuffer(SshConstants.SSH_MSG_KEX_DH_GEX_INIT);
buffer.putMPInt(e);
session.writePacket(buffer);
expected = SshConstants.SSH_MSG_KEX_DH_GEX_REPLY;
return false;
}
if (cmd == SshConstants.SSH_MSG_KEX_DH_GEX_REPLY) {
log.debug("Received SSH_MSG_KEX_DH_GEX_REPLY");
byte[] K_S = buffer.getBytes();
f = buffer.getMPIntAsBytes();
byte[] sig = buffer.getBytes();
dh.setF(f);
K = dh.getK();
buffer = new Buffer(K_S);
serverKey = buffer.getRawPublicKey();
final String keyAlg;
if (serverKey instanceof RSAPublicKey) {
keyAlg = KeyPairProvider.SSH_RSA;
} else if (serverKey instanceof DSAPublicKey) {
keyAlg = KeyPairProvider.SSH_DSS;
} else if (serverKey instanceof ECPublicKey) {
keyAlg = ECCurves.ECDSA_SHA2_PREFIX + ECCurves.getCurveName(((ECPublicKey) serverKey).getParams());
} else {
throw new SshException("Unsupported server key type");
}
buffer = new Buffer();
buffer.putString(V_C);
buffer.putString(V_S);
buffer.putString(I_C);
buffer.putString(I_S);
buffer.putString(K_S);
buffer.putInt(min);
buffer.putInt(prf);
buffer.putInt(max);
buffer.putMPInt(p);
buffer.putMPInt(g);
buffer.putMPInt(e);
buffer.putMPInt(f);
buffer.putMPInt(K);
hash.update(buffer.array(), 0, buffer.available());
H = hash.digest();
Signature verif = NamedFactory.Utils.create(session.getFactoryManager().getSignatureFactories(), keyAlg);
verif.init(serverKey, null);
verif.update(H, 0, H.length);
if (!verif.verify(sig)) {
throw new SshException(SshConstants.SSH2_DISCONNECT_KEY_EXCHANGE_FAILED,
"KeyExchange signature verification failed");
}
return true;
}