/// <summary>Calculates the effective user session key.</summary>
/// <remarks>Calculates the effective user session key.</remarks>
/// <param name="challenge">The server challenge.</param>
/// <param name="dest">
/// The destination array in which the user session key will be
/// placed.
/// </param>
/// <param name="offset">
/// The offset in the destination array at which the
/// session key will start.
/// </param>
/// <exception cref="SharpCifs.Smb.SmbException"></exception>
internal void GetUserSessionKey(byte[] challenge, byte[] dest, int offset)
{
if (HashesExternal)
{
return;
}
try
{
Md4 md4 = new Md4();
md4.Update(Runtime.GetBytesForString(Password, SmbConstants.UniEncoding)
);
switch (LmCompatibility)
{
case 0:
case 1:
case 2:
{
md4.Update(md4.Digest());
md4.Digest(dest, offset, 16);
break;
}
case 3:
case 4:
case 5:
{
if (ClientChallenge == null)
{
ClientChallenge = new byte[8];
Random.NextBytes(ClientChallenge);
}
Hmact64 hmac = new Hmact64(md4.Digest());
hmac.Update(Runtime.GetBytesForString(Username.ToUpper(), SmbConstants.UniEncoding
));
hmac.Update(Runtime.GetBytesForString(Domain.ToUpper(), SmbConstants.UniEncoding
));
byte[] ntlmv2Hash = hmac.Digest();
hmac = new Hmact64(ntlmv2Hash);
hmac.Update(challenge);
hmac.Update(ClientChallenge);
Hmact64 userKey = new Hmact64(ntlmv2Hash);
userKey.Update(hmac.Digest());
userKey.Digest(dest, offset, 16);
break;
}
default:
{
md4.Update(md4.Digest());
md4.Digest(dest, offset, 16);
break;
}
}
}
catch (Exception e)
{
throw new SmbException(string.Empty, e);
}
}