in sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java [1912:2014]
protected void prepareNewKeys() throws Exception {
byte[] k = kex.getK();
byte[] h = kex.getH();
Digest hash = kex.getHash();
boolean debugEnabled = log.isDebugEnabled();
if (sessionId == null) {
sessionId = h.clone();
if (debugEnabled) {
log.debug("prepareNewKeys({}) session ID={}", this, BufferUtils.toHex(':', sessionId));
}
}
Buffer buffer = new ByteArrayBuffer();
buffer.putBytes(k);
buffer.putRawBytes(h);
buffer.putByte((byte) 0x41);
buffer.putRawBytes(sessionId);
int pos = buffer.available();
byte[] buf = buffer.array();
hash.update(buf, 0, pos);
byte[] iv_c2s = hash.digest();
int j = pos - sessionId.length - 1;
buf[j]++;
hash.update(buf, 0, pos);
byte[] iv_s2c = hash.digest();
buf[j]++;
hash.update(buf, 0, pos);
byte[] e_c2s = hash.digest();
buf[j]++;
hash.update(buf, 0, pos);
byte[] e_s2c = hash.digest();
buf[j]++;
hash.update(buf, 0, pos);
byte[] mac_c2s = hash.digest();
buf[j]++;
hash.update(buf, 0, pos);
byte[] mac_s2c = hash.digest();
boolean serverSession = isServerSession();
String value = getNegotiatedKexParameter(KexProposalOption.S2CENC);
Cipher s2ccipher = ValidateUtils.checkNotNull(
NamedFactory.create(getCipherFactories(), value), "Unknown s2c cipher: %s", value);
e_s2c = resizeKey(e_s2c, s2ccipher.getKdfSize(), hash, k, h);
Mac s2cmac;
if (s2ccipher.getAuthenticationTagSize() == 0) {
value = getNegotiatedKexParameter(KexProposalOption.S2CMAC);
s2cmac = NamedFactory.create(getMacFactories(), value);
if (s2cmac == null) {
throw new SshException(SshConstants.SSH2_DISCONNECT_MAC_ERROR, "Unknown s2c MAC: " + value);
}
mac_s2c = resizeKey(mac_s2c, s2cmac.getBlockSize(), hash, k, h);
s2cmac.init(mac_s2c);
} else {
s2cmac = null;
}
value = getNegotiatedKexParameter(KexProposalOption.S2CCOMP);
Compression s2ccomp = NamedFactory.create(getCompressionFactories(), value);
if (s2ccomp == null) {
throw new SshException(SshConstants.SSH2_DISCONNECT_COMPRESSION_ERROR, "Unknown s2c compression: " + value);
}
value = getNegotiatedKexParameter(KexProposalOption.C2SENC);
Cipher c2scipher = ValidateUtils.checkNotNull(
NamedFactory.create(getCipherFactories(), value), "Unknown c2s cipher: %s", value);
e_c2s = resizeKey(e_c2s, c2scipher.getKdfSize(), hash, k, h);
Mac c2smac;
if (c2scipher.getAuthenticationTagSize() == 0) {
value = getNegotiatedKexParameter(KexProposalOption.C2SMAC);
c2smac = NamedFactory.create(getMacFactories(), value);
if (c2smac == null) {
throw new SshException(SshConstants.SSH2_DISCONNECT_MAC_ERROR, "Unknown c2s MAC: " + value);
}
mac_c2s = resizeKey(mac_c2s, c2smac.getBlockSize(), hash, k, h);
c2smac.init(mac_c2s);
} else {
c2smac = null;
}
value = getNegotiatedKexParameter(KexProposalOption.C2SCOMP);
Compression c2scomp = NamedFactory.create(getCompressionFactories(), value);
if (c2scomp == null) {
throw new SshException(SshConstants.SSH2_DISCONNECT_COMPRESSION_ERROR, "Unknown c2s compression: " + value);
}
if (serverSession) {
outSettings = new MessageCodingSettings(s2ccipher, s2cmac, s2ccomp, Cipher.Mode.Encrypt, e_s2c, iv_s2c);
inSettings = new MessageCodingSettings(c2scipher, c2smac, c2scomp, Cipher.Mode.Decrypt, e_c2s, iv_c2s);
} else {
outSettings = new MessageCodingSettings(c2scipher, c2smac, c2scomp, Cipher.Mode.Encrypt, e_c2s, iv_c2s);
inSettings = new MessageCodingSettings(s2ccipher, s2cmac, s2ccomp, Cipher.Mode.Decrypt, e_s2c, iv_s2c);
}
}