/* SRPServer.java -- 
   Copyright (C) 2003, 2006 Free Software Foundation, Inc.

This file is a part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version.  */


package gnu.javax.crypto.sasl.srp;

import gnu.java.security.Configuration;
import gnu.java.security.Registry;
import gnu.java.security.util.PRNG;
import gnu.java.security.util.Util;
import gnu.javax.crypto.assembly.Direction;
import gnu.javax.crypto.cipher.CipherFactory;
import gnu.javax.crypto.cipher.IBlockCipher;
import gnu.javax.crypto.key.IKeyAgreementParty;
import gnu.javax.crypto.key.IncomingMessage;
import gnu.javax.crypto.key.KeyAgreementException;
import gnu.javax.crypto.key.KeyAgreementFactory;
import gnu.javax.crypto.key.OutgoingMessage;
import gnu.javax.crypto.key.srp6.SRP6KeyAgreement;
import gnu.javax.crypto.sasl.IllegalMechanismStateException;
import gnu.javax.crypto.sasl.InputBuffer;
import gnu.javax.crypto.sasl.IntegrityException;
import gnu.javax.crypto.sasl.OutputBuffer;
import gnu.javax.crypto.sasl.ServerMechanism;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.logging.Logger;

import javax.security.sasl.AuthenticationException;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;

/**
 * The SASL-SRP server-side mechanism.
 */
public class SRPServer
    extends ServerMechanism
    implements SaslServer
{
  private static final Logger log = Logger.getLogger(SRPServer.class.getName());
  private String U = null; // client's username
  private BigInteger N, g, A, B;
  private byte[] s; // salt
  private byte[] cIV, sIV; // client+server IVs, when confidentiality is on
  private byte[] cn, sn; // client's and server's nonce
  private SRP srp; // SRP algorithm instance used by this server
  private byte[] sid; // session ID when re-used
  private int ttl = 360; // session time-to-live in seconds
  private byte[] cCB; // peer's channel binding'
  private String mandatory; // List of available options
  private String L = null;
  private String o;
  private String chosenIntegrityAlgorithm;
  private String chosenConfidentialityAlgorithm;
  private int rawSendSize = Registry.SASL_BUFFER_MAX_LIMIT;
  private byte[] K; // shared session key
  private boolean replayDetection = true; // whether Replay Detection is on
  private int inCounter = 0; // messages sequence numbers
  private int outCounter = 0;
  private IALG inMac, outMac; // if !null, use for integrity
  private CALG inCipher, outCipher; // if !null, use for confidentiality
  private IKeyAgreementParty serverHandler =
      KeyAgreementFactory.getPartyBInstance(Registry.SRP_SASL_KA);
  /** Our default source of randomness. */
  private PRNG prng = null;

  public SRPServer()
  {
    super(Registry.SASL_SRP_MECHANISM);
  }

  protected void initMechanism() throws SaslException
  {
    // TODO:
    // we must have a means to map a given username to a preferred
    // SRP hash algorithm; otherwise we end up using _always_ SHA.
    // for the time being get it from the mechanism properties map
    // and apply it for all users.
    final String mda = (String) properties.get(SRPRegistry.SRP_HASH);
    srp = SRP.instance(mda == null ? SRPRegistry.SRP_DEFAULT_DIGEST_NAME : mda);
  }

  protected void resetMechanism() throws SaslException
  {
    s = null;
    A = B = null;
    K = null;
    inMac = outMac = null;
    inCipher = outCipher = null;
    sid = null;
  }

  public byte[] evaluateResponse(final byte[] response) throws SaslException
  {
    switch (state)
      {
      case 0:
        if (response == null)
          return null;
        state++;
        return sendProtocolElements(response);
      case 1:
        if (! complete)
          {
            state++;
            return sendEvidence(response);
          }
      // else fall through
      default:
        throw new IllegalMechanismStateException("evaluateResponse()");
      }
  }

  protected byte[] engineUnwrap(final byte[] incoming, final int offset,
                                final int len) throws SaslException
  {
    if (Configuration.DEBUG)
      log.entering(this.getClass().getName(), "engineUnwrap");
    if (inMac == null && inCipher == null)
      throw new IllegalStateException("connection is not protected");
    if (Configuration.DEBUG)
      log.fine("Incoming buffer (before security): "
               + Util.dumpString(incoming, offset, len));
    // at this point one, or both, of confidentiality and integrity protection
    // services are active.
    final byte[] result;
    try
      {
        if (inMac != null)
          { // integrity bytes are at the end of the stream
            final int macBytesCount = inMac.length();
            final int payloadLength = len - macBytesCount;
            final byte[] received_mac = new byte[macBytesCount];
            System.arraycopy(incoming, offset + payloadLength, received_mac, 0,
                             macBytesCount);
            if (Configuration.DEBUG)
              log.fine("Got C (received MAC): " + Util.dumpString(received_mac));
            inMac.update(incoming, offset, payloadLength);
            if (replayDetection)
              {
                inCounter++;
                if (Configuration.DEBUG)
                  log.fine("inCounter=" + String.valueOf(inCounter));
                inMac.update(new byte[] {
                    (byte)(inCounter >>> 24),
                    (byte)(inCounter >>> 16),
                    (byte)(inCounter >>> 8),
                    (byte) inCounter });
              }
            final byte[] computed_mac = inMac.doFinal();
            if (Configuration.DEBUG)
              log.fine("Computed MAC: " + Util.dumpString(computed_mac));
            if (! Arrays.equals(received_mac, computed_mac))
              throw new IntegrityException("engineUnwrap()");
            // deal with the payload, which can be either plain or encrypted
            if (inCipher != null)
              result = inCipher.doFinal(incoming, offset, payloadLength);
            else
              {
                result = new byte[payloadLength];
                System.arraycopy(incoming, offset, result, 0, result.length);
              }
          }
        else // no integrity protection; just confidentiality
          result = inCipher.doFinal(incoming, offset, len);
      }
    catch (IOException x)
      {
        if (x instanceof SaslException)
          throw (SaslException) x;
        throw new SaslException("engineUnwrap()", x);
      }
    if (Configuration.DEBUG)
      {
        log.fine("Incoming buffer (after security): " + Util.dumpString(result));
        log.exiting(this.getClass().getName(), "engineUnwrap");
      }
    return result;
  }

  protected byte[] engineWrap(final byte[] outgoing, final int offset,
                              final int len) throws SaslException
  {
    if (Configuration.DEBUG)
      log.entering(this.getClass().getName(), "engineWrap");
    if (outMac == null && outCipher == null)
      throw new IllegalStateException("connection is not protected");
    if (Configuration.DEBUG)
      {
        log.fine("Outgoing buffer (before security) (hex): "
                 + Util.dumpString(outgoing, offset, len));
        log.fine("Outgoing buffer (before security) (str): \""
                 + new String(outgoing, offset, len) + "\"");
      }
    // at this point one, or both, of confidentiality and integrity protection
    // services are active.
    byte[] result;
    try
      {
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        if (outCipher != null)
          {
            result = outCipher.doFinal(outgoing, offset, len);
            if (Configuration.DEBUG)
              log.fine("Encoding c (encrypted plaintext): "
                       + Util.dumpString(result));
            out.write(result);
            if (outMac != null)
              {
                outMac.update(result);
                if (replayDetection)
                  {
                    outCounter++;
                    if (Configuration.DEBUG)
                      log.fine("outCounter=" + outCounter);
                    outMac.update(new byte[] {
                        (byte)(outCounter >>> 24),
                        (byte)(outCounter >>> 16),
                        (byte)(outCounter >>> 8),
                        (byte) outCounter });
                  }
                final byte[] C = outMac.doFinal();
                out.write(C);
                if (Configuration.DEBUG)
                  log.fine("Encoding C (integrity checksum): " + Util.dumpString(C));
              }
            // else ciphertext only; do nothing
          }
        else // no confidentiality; just integrity [+ replay detection]
          {
            if (Configuration.DEBUG)
              log.fine("Encoding p (plaintext): "
                       + Util.dumpString(outgoing, offset, len));
            out.write(outgoing, offset, len);
            outMac.update(outgoing, offset, len);
            if (replayDetection)
              {
                outCounter++;
                if (Configuration.DEBUG)
                  log.fine("outCounter=" + outCounter);
                outMac.update(new byte[] {
                    (byte)(outCounter >>> 24),
                    (byte)(outCounter >>> 16),
                    (byte)(outCounter >>> 8),
                    (byte) outCounter });
              }
            final byte[] C = outMac.doFinal();
            out.write(C);
            if (Configuration.DEBUG)
              log.fine("Encoding C (integrity checksum): " + Util.dumpString(C));
          }
        result = out.toByteArray();
      }
    catch (IOException x)
      {
        if (x instanceof SaslException)
          throw (SaslException) x;
        throw new SaslException("engineWrap()", x);
      }
    if (Configuration.DEBUG)
      log.exiting(this.getClass().getName(), "engineWrap");
    return result;
  }

  protected String getNegotiatedQOP()
  {
    if (inMac != null)
      {
        if (inCipher != null)
          return Registry.QOP_AUTH_CONF;
        return Registry.QOP_AUTH_INT;
      }
    return Registry.QOP_AUTH;
  }

  protected String getNegotiatedStrength()
  {
    if (inMac != null)
      {
        if (inCipher != null)
          return Registry.STRENGTH_HIGH;
        return Registry.STRENGTH_MEDIUM;
      }
    return Registry.STRENGTH_LOW;
  }

  protected String getNegotiatedRawSendSize()
  {
    return String.valueOf(rawSendSize);
  }

  protected String getReuse()
  {
    return Registry.REUSE_TRUE;
  }

  private byte[] sendProtocolElements(final byte[] input) throws SaslException
  {
    if (Configuration.DEBUG)
      {
        log.entering(this.getClass().getName(), "sendProtocolElements");
        log.fine("C: " + Util.dumpString(input));
      }
    // Client send U, I, sid, cn
    final InputBuffer frameIn = new InputBuffer(input);
    try
      {
        U = frameIn.getText(); // Extract username
        if (Configuration.DEBUG)
          log.fine("Got U (username): \"" + U + "\"");
        authorizationID = frameIn.getText(); // Extract authorisation ID
        if (Configuration.DEBUG)
          log.fine("Got I (userid): \"" + authorizationID + "\"");
        sid = frameIn.getEOS();
        if (Configuration.DEBUG)
          log.fine("Got sid (session ID): " + new String(sid));
        cn = frameIn.getOS();
        if (Configuration.DEBUG)
          log.fine("Got cn (client nonce): " + Util.dumpString(cn));
        cCB = frameIn.getEOS();
        if (Configuration.DEBUG)
          log.fine("Got cCB (client channel binding): " + Util.dumpString(cCB));
      }
    catch (IOException x)
      {
        if (x instanceof SaslException)
          throw (SaslException) x;
        throw new AuthenticationException("sendProtocolElements()", x);
      }
    // do/can we re-use?
    if (ServerStore.instance().isAlive(sid))
      {
        final SecurityContext ctx = ServerStore.instance().restoreSession(sid);
        srp = SRP.instance(ctx.getMdName());
        K = ctx.getK();
        cIV = ctx.getClientIV();
        sIV = ctx.getServerIV();
        replayDetection = ctx.hasReplayDetection();
        inCounter = ctx.getInCounter();
        outCounter = ctx.getOutCounter();
        inMac = ctx.getInMac();
        outMac = ctx.getOutMac();
        inCipher = ctx.getInCipher();
        outCipher = ctx.getOutCipher();
        if (sn == null || sn.length != 16)
          sn = new byte[16];
        getDefaultPRNG().nextBytes(sn);
        setupSecurityServices(false);
        final OutputBuffer frameOut = new OutputBuffer();
        try
          {
            frameOut.setScalar(1, 0xFF);
            frameOut.setOS(sn);
            frameOut.setEOS(channelBinding);
          }
        catch (IOException x)
          {
            if (x instanceof SaslException)
              throw (SaslException) x;
            throw new AuthenticationException("sendProtocolElements()", x);
          }
        final byte[] result = frameOut.encode();
        if (Configuration.DEBUG)
          {
            log.fine("Old session...");
            log.fine("S: " + Util.dumpString(result));
            log.fine("  sn = " + Util.dumpString(sn));
            log.fine(" sCB = " + Util.dumpString(channelBinding));
            log.exiting(this.getClass().getName(), "sendProtocolElements");
          }
        return result;
      }
    else
      { // new session
        authenticator.activate(properties);
        // -------------------------------------------------------------------
        final HashMap mapB = new HashMap();
        mapB.put(SRP6KeyAgreement.HASH_FUNCTION, srp.getAlgorithm());
        mapB.put(SRP6KeyAgreement.HOST_PASSWORD_DB, authenticator);
        try
          {
            serverHandler.init(mapB);
            OutgoingMessage out = new OutgoingMessage();
            out.writeString(U);
            IncomingMessage in = new IncomingMessage(out.toByteArray());
            out = serverHandler.processMessage(in);
            in = new IncomingMessage(out.toByteArray());
            N = in.readMPI();
            g = in.readMPI();
            s = in.readMPI().toByteArray();
            B = in.readMPI();
          }
        catch (KeyAgreementException x)
          {
            throw new SaslException("sendProtocolElements()", x);
          }
        // -------------------------------------------------------------------
        if (Configuration.DEBUG)
          {
            log.fine("Encoding N (modulus): " + Util.dump(N));
            log.fine("Encoding g (generator): " + Util.dump(g));
            log.fine("Encoding s (client's salt): " + Util.dumpString(s));
            log.fine("Encoding B (server ephemeral public key): " + Util.dump(B));
          }
        // The server creates an options list (L), which consists of a
        // comma-separated list of option strings that specify the security
        // service options the server supports.
        L = createL();
        if (Configuration.DEBUG)
          {
            log.fine("Encoding L (available options): \"" + L + "\"");
            log.fine("Encoding sIV (server IV): " + Util.dumpString(sIV));
          }
        final OutputBuffer frameOut = new OutputBuffer();
        try
          {
            frameOut.setScalar(1, 0x00);
            frameOut.setMPI(N);
            frameOut.setMPI(g);
            frameOut.setOS(s);
            frameOut.setMPI(B);
            frameOut.setText(L);
          }
        catch (IOException x)
          {
            if (x instanceof SaslException)
              throw (SaslException) x;
            throw new AuthenticationException("sendProtocolElements()", x);
          }
        final byte[] result = frameOut.encode();
        if (Configuration.DEBUG)
          {
            log.fine("New session...");
            log.fine("S: " + Util.dumpString(result));
            log.fine("   N = 0x" + N.toString(16));
            log.fine("   g = 0x" + g.toString(16));
            log.fine("   s = " + Util.dumpString(s));
            log.fine("   B = 0x" + B.toString(16));
            log.fine("   L = " + L);
            log.exiting(this.getClass().getName(), "sendProtocolElements");
          }
        return result;
      }
  }

  private byte[] sendEvidence(final byte[] input) throws SaslException
  {
    if (Configuration.DEBUG)
      {
        log.entering(this.getClass().getName(), "sendEvidence");
        log.fine("C: " + Util.dumpString(input));
      }
    // Client send A, M1, o, cIV
    final InputBuffer frameIn = new InputBuffer(input);
    final byte[] M1;
    try
      {
        A = frameIn.getMPI(); // Extract client's ephemeral public key
        if (Configuration.DEBUG)
          log.fine("Got A (client ephemeral public key): " + Util.dump(A));
        M1 = frameIn.getOS(); // Extract evidence
        if (Configuration.DEBUG)
          log.fine("Got M1 (client evidence): " + Util.dumpString(M1));
        o = frameIn.getText(); // Extract client's options list
        if (Configuration.DEBUG)
          log.fine("Got o (client chosen options): \"" + o + "\"");
        cIV = frameIn.getOS(); // Extract client's IV
        if (Configuration.DEBUG)
          log.fine("Got cIV (client IV): " + Util.dumpString(cIV));
      }
    catch (IOException x)
      {
        if (x instanceof SaslException)
          throw (SaslException) x;
        throw new AuthenticationException("sendEvidence()", x);
      }
    // Parse client's options and set security layer variables
    parseO(o);
    // ----------------------------------------------------------------------
    try
      {
        final OutgoingMessage out = new OutgoingMessage();
        out.writeMPI(A);
        final IncomingMessage in = new IncomingMessage(out.toByteArray());
        serverHandler.processMessage(in);
        K = serverHandler.getSharedSecret();
      }
    catch (KeyAgreementException x)
      {
        throw new SaslException("sendEvidence()", x);
      }
    // ----------------------------------------------------------------------
    if (Configuration.DEBUG)
      log.fine("K: " + Util.dumpString(K));
    final byte[] expected;
    try
      {
        expected = srp.generateM1(N, g, U, s, A, B, K, authorizationID, L, cn,
                                  cCB);
      }
    catch (UnsupportedEncodingException x)
      {
        throw new AuthenticationException("sendEvidence()", x);
      }
    // Verify client evidence
    if (! Arrays.equals(M1, expected))
      throw new AuthenticationException("M1 mismatch");
    setupSecurityServices(true);
    final byte[] M2;
    try
      {
        M2 = srp.generateM2(A, M1, K, U, authorizationID, o, sid, ttl, cIV,
                            sIV, channelBinding);
      }
    catch (UnsupportedEncodingException x)
      {
        throw new AuthenticationException("sendEvidence()", x);
      }
    final OutputBuffer frameOut = new OutputBuffer();
    try
      {
        frameOut.setOS(M2);
        frameOut.setOS(sIV);
        frameOut.setEOS(sid);
        frameOut.setScalar(4, ttl);
        frameOut.setEOS(channelBinding);
      }
    catch (IOException x)
      {
        if (x instanceof SaslException)
          throw (SaslException) x;
        throw new AuthenticationException("sendEvidence()", x);
      }
    final byte[] result = frameOut.encode();
    if (Configuration.DEBUG)
      {
        log.fine("S: " + Util.dumpString(result));
        log.fine("  M2 = " + Util.dumpString(M2));
        log.fine(" sIV = " + Util.dumpString(sIV));
        log.fine(" sid = " + new String(sid));
        log.fine(" ttl = " + ttl);
        log.fine(" sCB = " + Util.dumpString(channelBinding));
        log.exiting(this.getClass().getName(), "sendEvidence");
      }
    return result;
  }

  private String createL()
  {
    if (Configuration.DEBUG)
      log.entering(this.getClass().getName(), "createL()");
    String s = (String) properties.get(SRPRegistry.SRP_MANDATORY);
    if (s == null)
      s = SRPRegistry.DEFAULT_MANDATORY;

    if (! SRPRegistry.MANDATORY_NONE.equals(s)
        && ! SRPRegistry.OPTION_REPLAY_DETECTION.equals(s)
        && ! SRPRegistry.OPTION_INTEGRITY.equals(s)
        && ! SRPRegistry.OPTION_CONFIDENTIALITY.equals(s))
      {
        if (Configuration.DEBUG)
          log.fine("Unrecognised mandatory option (" + s + "). Using default...");
        s = SRPRegistry.DEFAULT_MANDATORY;
      }
    mandatory = s;
    s = (String) properties.get(SRPRegistry.SRP_CONFIDENTIALITY);
    final boolean confidentiality = (s == null ? SRPRegistry.DEFAULT_CONFIDENTIALITY
                                               : Boolean.valueOf(s).booleanValue());
    s = (String) properties.get(SRPRegistry.SRP_INTEGRITY_PROTECTION);
    boolean integrity = (s == null ? SRPRegistry.DEFAULT_INTEGRITY
                                   : Boolean.valueOf(s).booleanValue());
    s = (String) properties.get(SRPRegistry.SRP_REPLAY_DETECTION);
    final boolean replayDetection = (s == null ? SRPRegistry.DEFAULT_REPLAY_DETECTION
                                               : Boolean.valueOf(s).booleanValue());
    final StringBuffer sb = new StringBuffer();
    sb.append(SRPRegistry.OPTION_SRP_DIGEST).append("=")
      .append(srp.getAlgorithm()).append(",");

    if (! SRPRegistry.MANDATORY_NONE.equals(mandatory))
      sb.append(SRPRegistry.OPTION_MANDATORY)
        .append("=").append(mandatory).append(",");

    if (replayDetection)
      {
        sb.append(SRPRegistry.OPTION_REPLAY_DETECTION).append(",");
        // if replay detection is on then force integrity protection
        integrity = true;
      }
    int i;
    if (integrity)
      {
        for (i = 0; i < SRPRegistry.INTEGRITY_ALGORITHMS.length; i++)
          sb.append(SRPRegistry.OPTION_INTEGRITY).append("=")
            .append(SRPRegistry.INTEGRITY_ALGORITHMS[i]).append(",");
      }
    if (confidentiality)
      {
        IBlockCipher cipher;
        for (i = 0; i < SRPRegistry.CONFIDENTIALITY_ALGORITHMS.length; i++)
          {
            cipher = CipherFactory.getInstance(SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i]);
            if (cipher != null)
              sb.append(SRPRegistry.OPTION_CONFIDENTIALITY).append("=")
                .append(SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i]).append(",");
          }
      }
    final String result = sb.append(SRPRegistry.OPTION_MAX_BUFFER_SIZE)
                            .append("=").append(Registry.SASL_BUFFER_MAX_LIMIT)
                            .toString();
    if (Configuration.DEBUG)
      log.exiting(this.getClass().getName(), "createL");
    return result;
  }

  // Parse client's options and set security layer variables
  private void parseO(final String o) throws AuthenticationException
  {
    this.replayDetection = false;
    boolean integrity = false;
    boolean confidentiality = false;
    String option;
    int i;

    final StringTokenizer st = new StringTokenizer(o.toLowerCase(), ",");
    while (st.hasMoreTokens())
      {
        option = st.nextToken();
        if (Configuration.DEBUG)
          log.fine("option: <" + option + ">");
        if (option.equals(SRPRegistry.OPTION_REPLAY_DETECTION))
          replayDetection = true;
        else if (option.startsWith(SRPRegistry.OPTION_INTEGRITY + "="))
          {
            if (integrity)
              throw new AuthenticationException(
                  "Only one integrity algorithm may be chosen");
            option = option.substring(option.indexOf('=') + 1);
            if (Configuration.DEBUG)
              log.fine("algorithm: <" + option + ">");
            for (i = 0; i < SRPRegistry.INTEGRITY_ALGORITHMS.length; i++)
              {
                if (SRPRegistry.INTEGRITY_ALGORITHMS[i].equals(option))
                  {
                    chosenIntegrityAlgorithm = option;
                    integrity = true;
                    break;
                  }
              }
            if (! integrity)
              throw new AuthenticationException("Unknown integrity algorithm: "
                                                + option);
          }
        else if (option.startsWith(SRPRegistry.OPTION_CONFIDENTIALITY + "="))
          {
            if (confidentiality)
              throw new AuthenticationException(
                  "Only one confidentiality algorithm may be chosen");
            option = option.substring(option.indexOf('=') + 1);
            if (Configuration.DEBUG)
              log.fine("algorithm: <" + option + ">");
            for (i = 0; i < SRPRegistry.CONFIDENTIALITY_ALGORITHMS.length; i++)
              {
                if (SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i].equals(option))
                  {
                    chosenConfidentialityAlgorithm = option;
                    confidentiality = true;
                    break;
                  }
              }
            if (! confidentiality)
              throw new AuthenticationException("Unknown confidentiality algorithm: "
                                                + option);
          }
        else if (option.startsWith(SRPRegistry.OPTION_MAX_BUFFER_SIZE + "="))
          {
            final String maxBufferSize = option.substring(option.indexOf('=') + 1);
            try
              {
                rawSendSize = Integer.parseInt(maxBufferSize);
                if (rawSendSize > Registry.SASL_BUFFER_MAX_LIMIT
                    || rawSendSize < 1)
                  throw new AuthenticationException(
                      "Illegal value for 'maxbuffersize' option");
              }
            catch (NumberFormatException x)
              {
                throw new AuthenticationException(
                    SRPRegistry.OPTION_MAX_BUFFER_SIZE + "=" + maxBufferSize, x);
              }
          }
      }
    // check if client did the right thing
    if (replayDetection)
      {
        if (! integrity)
          throw new AuthenticationException(
              "Missing integrity protection algorithm but replay detection is chosen");
      }
    if (mandatory.equals(SRPRegistry.OPTION_REPLAY_DETECTION))
      {
        if (! replayDetection)
          throw new AuthenticationException(
              "Replay detection is mandatory but was not chosen");
      }
    if (mandatory.equals(SRPRegistry.OPTION_INTEGRITY))
      {
        if (! integrity)
          throw new AuthenticationException(
              "Integrity protection is mandatory but was not chosen");
      }
    if (mandatory.equals(SRPRegistry.OPTION_CONFIDENTIALITY))
      {
        if (! confidentiality)
          throw new AuthenticationException(
              "Confidentiality is mandatory but was not chosen");
      }
    int blockSize = 0;
    if (chosenConfidentialityAlgorithm != null)
      {
        final IBlockCipher cipher = CipherFactory.getInstance(chosenConfidentialityAlgorithm);
        if (cipher != null)
          blockSize = cipher.defaultBlockSize();
        else // should not happen
          throw new AuthenticationException("Confidentiality algorithm ("
                                            + chosenConfidentialityAlgorithm
                                            + ") not available");
      }
    sIV = new byte[blockSize];
    if (blockSize > 0)
      getDefaultPRNG().nextBytes(sIV);
  }

  private void setupSecurityServices(final boolean newSession)
      throws SaslException
  {
    complete = true; // signal end of authentication phase
    if (newSession)
      {
        outCounter = inCounter = 0;
        // instantiate cipher if confidentiality protection filter is active
        if (chosenConfidentialityAlgorithm != null)
          {
            if (Configuration.DEBUG)
              log.fine("Activating confidentiality protection filter");
            inCipher = CALG.getInstance(chosenConfidentialityAlgorithm);
            outCipher = CALG.getInstance(chosenConfidentialityAlgorithm);
          }
        // instantiate hmacs if integrity protection filter is active
        if (chosenIntegrityAlgorithm != null)
          {
            if (Configuration.DEBUG)
              log.fine("Activating integrity protection filter");
            inMac = IALG.getInstance(chosenIntegrityAlgorithm);
            outMac = IALG.getInstance(chosenIntegrityAlgorithm);
          }
        // generate a new sid if at least integrity is used
        sid = (inMac != null ? ServerStore.getNewSessionID() : new byte[0]);
      }
    else // same session new keys
      K = srp.generateKn(K, cn, sn);

    final KDF kdf = KDF.getInstance(K);
    // initialise in/out ciphers if confidentaility protection is used
    if (inCipher != null)
      {
        outCipher.init(kdf, sIV, Direction.FORWARD);
        inCipher.init(kdf, cIV, Direction.REVERSED);
      }
    // initialise in/out macs if integrity protection is used
    if (inMac != null)
      {
        outMac.init(kdf);
        inMac.init(kdf);
      }
    if (sid != null && sid.length != 0)
      { // update the security context and save in map
        if (Configuration.DEBUG)
          log.fine("Updating security context for sid = " + new String(sid));
        ServerStore.instance().cacheSession(ttl,
                                            new SecurityContext(srp.getAlgorithm(),
                                                                sid,
                                                                K,
                                                                cIV,
                                                                sIV,
                                                                replayDetection,
                                                                inCounter,
                                                                outCounter,
                                                                inMac, outMac,
                                                                inCipher,
                                                                outCipher));
      }
  }

  private PRNG getDefaultPRNG()
  {
    if (prng == null)
      prng = PRNG.getInstance();
    return prng;
  }
}
