}
if( srpServer == null )
throw new LoginException("Failed to access a SRPServerInterface instance");
byte[] M1, M2;
SRPClientSession client = null;
try
{ // Perform the SRP login protocol
if( trace )
log.trace("Getting SRP parameters for username: "+username);
CryptoUtil.init();
Object[] sessionInfo = srpServer.getSRPParameters(username, multipleSessions);
params = (SRPParameters) sessionInfo[0];
sessionID = (Integer) sessionInfo[1];
if( sessionID == null )
sessionID = new Integer(0);
if( trace )
{
log.trace("SessionID: "+sessionID);
log.trace("N: "+CryptoUtil.tob64(params.N));
log.trace("g: "+CryptoUtil.tob64(params.g));
log.trace("s: "+CryptoUtil.tob64(params.s));
log.trace("cipherAlgorithm: "+params.cipherAlgorithm);
log.trace("hashAlgorithm: "+params.hashAlgorithm);
}
byte[] hn = CryptoUtil.newDigest().digest(params.N);
if( trace )
log.trace("H(N): "+CryptoUtil.tob64(hn));
byte[] hg = CryptoUtil.newDigest().digest(params.g);
if( trace )
{
log.trace("H(g): "+CryptoUtil.tob64(hg));
log.trace("Creating SRPClientSession");
}
if( abytes != null )
client = new SRPClientSession(username, password, params, abytes);
else
client = new SRPClientSession(username, password, params);
if( trace )
log.trace("Generating client public key");
byte[] A = client.exponential();
if( trace )
log.trace("Exchanging public keys");
byte[] B = srpServer.init(username, A, sessionID.intValue());
if( trace )
log.trace("Generating server challenge");
M1 = client.response(B);
if( trace )
log.trace("Exchanging challenges");
sessionKey = client.getSessionKey();
if( auxChallenge != null )
{
auxChallenge = encryptAuxChallenge(auxChallenge, params.cipherAlgorithm,
params.cipherIV, sessionKey);
M2 = srpServer.verify(username, M1, auxChallenge, sessionID.intValue());
}
else
{
M2 = srpServer.verify(username, M1, sessionID.intValue());
}
}
catch(Exception e)
{
if (e instanceof LoginException) throw (LoginException) e;
final LoginException loginException = new LoginException("Failed to complete SRP login (" + e.getMessage() + ")");
loginException.initCause(e);
throw loginException;
}
if( trace )
log.trace("Verifying server response");
if( client.verify(M2) == false )
throw new LoginException("Failed to validate server reply");
if( trace )
log.trace("Login succeeded");
// Put the principal and the client challenge into the sharedState map