private void updateKeys(KeyExchange kex)
{
byte[] K=kex.getK();
byte[] H=kex.getH();
HASH hash=kex.getHash();
String[] guess=kex._guess;
if(session_id==null)
{
session_id=new byte[H.Length];
System.Array.Copy(H, 0, 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)
*/
buf.Reset();
buf.WriteMPInt(K);
buf.WriteByte(H);
buf.WriteByte((byte)0x41);
buf.WriteByte(session_id);
hash.update(buf.buffer, 0, buf.index);
IVc2s=hash.digest();
int j=buf.index-session_id.Length-1;
buf.buffer[j]++;
hash.update(buf.buffer, 0, buf.index);
IVs2c=hash.digest();
buf.buffer[j]++;
hash.update(buf.buffer, 0, buf.index);
Ec2s=hash.digest();
buf.buffer[j]++;
hash.update(buf.buffer, 0, buf.index);
Es2c=hash.digest();
buf.buffer[j]++;
hash.update(buf.buffer, 0, buf.index);
MACc2s=hash.digest();
buf.buffer[j]++;
hash.update(buf.buffer, 0, buf.index);
MACs2c=hash.digest();
try
{
s2ccipher = (Cipher)System.Activator.CreateInstance(System.Type.GetType(getConfig(guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC])));
while(s2ccipher.getBlockSize()>Es2c.Length)
{
buf.Reset();
buf.WriteMPInt(K);
buf.WriteByte(H);
buf.WriteByte(Es2c);
hash.update(buf.buffer, 0, buf.index);
byte[] foo=hash.digest();
byte[] bar=new byte[Es2c.Length+foo.Length];
System.Array.Copy(Es2c, 0, bar, 0, Es2c.Length);
System.Array.Copy(foo, 0, bar, Es2c.Length, foo.Length);
Es2c=bar;
}
s2ccipher.init(Cipher.DECRYPT_MODE, Es2c, IVs2c);
cipher_size=s2ccipher.getIVSize();
s2cmac = (MAC)System.Activator.CreateInstance(System.Type.GetType(getConfig(guess[KeyExchange.PROPOSAL_MAC_ALGS_STOC])));
s2cmac.init(MACs2c);
mac_buf=new byte[s2cmac.getBlockSize()];
c2scipher = (Cipher)System.Activator.CreateInstance(System.Type.GetType(getConfig(guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS])));
while(c2scipher.getBlockSize()>Ec2s.Length)
{
buf.Reset();
buf.WriteMPInt(K);
buf.WriteByte(H);
buf.WriteByte(Ec2s);
hash.update(buf.buffer, 0, buf.index);
byte[] foo=hash.digest();
byte[] bar=new byte[Ec2s.Length+foo.Length];
System.Array.Copy(Ec2s, 0, bar, 0, Ec2s.Length);
System.Array.Copy(foo, 0, bar, Ec2s.Length, foo.Length);
Ec2s=bar;
}
c2scipher.init(Cipher.ENCRYPT_MODE, Ec2s, IVc2s);
c2smac = (MAC)System.Activator.CreateInstance(System.Type.GetType(getConfig(guess[KeyExchange.PROPOSAL_MAC_ALGS_CTOS])));
c2smac.init(MACc2s);
if(!(guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS] == "none"))
{
String foo=getConfig(guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS]);
if(foo!=null)
{
try
{
deflater = (Compression)System.Activator.CreateInstance(System.Type.GetType(foo));
int level=6;
try{ level=System.Convert.ToInt32(getConfig("compression_level"));}
catch(Exception){ }
deflater.init(Compression.DEFLATER, level);
}
catch(Exception)
{
System.Console.Error.WriteLine(foo+" isn't accessible.");
}
}
}
else
{
if(deflater!=null)
{
deflater=null;
}
}
if(guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC] != "none")
{
String foo=getConfig(guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC]);
if(foo!=null)
{
try
{
inflater = (Compression)System.Activator.CreateInstance(System.Type.GetType(foo));
inflater.init(Compression.INFLATER, 0);
}
catch(Exception)
{
System.Console.Error.WriteLine(foo+" isn't accessible.");
}
}
}
else
{
if(inflater!=null)
{
inflater=null;
}
}
}
catch(Exception e){ System.Console.Error.WriteLine("updatekeys: "+e); }
}