new SecureRandom ().nextBytes(sn);
getDefaultPRNG().nextBytes(sn);
  private byte[] sendProtocolElements(final byte[] input) throws SaslException  {    if (DEBUG && debuglevel > 8)      debug(TRACE, "==> sendProtocolElements()");    if (DEBUG && debuglevel > 6)      debug(TRACE, "C: " + Util.dumpString(input));    // Client send U, I, sid, cn    final InputBuffer frameIn = new InputBuffer(input);    try      {        U = frameIn.getText(); // Extract username        if (DEBUG && debuglevel > 6)          debug(TRACE, "Got U (username): \"" + U + "\"");        authorizationID = frameIn.getText(); // Extract authorisation ID        if (DEBUG && debuglevel > 6)          debug(TRACE, "Got I (userid): \"" + authorizationID + "\"");        sid = frameIn.getEOS();        if (DEBUG && debuglevel > 6)          debug(TRACE, "Got sid (session ID): " + new String(sid));        cn = frameIn.getOS();        if (DEBUG && debuglevel > 6)          debug(TRACE, "Got cn (client nonce): " + Util.dumpString(cn));        cCB = frameIn.getEOS();        if (DEBUG && debuglevel > 6)          debug(TRACE, "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];          }        new SecureRandom ().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 (DEBUG && debuglevel > 8)          debug(TRACE, "<== sendProtocolElements()");        if (DEBUG && debuglevel > 2)          debug(INFO, "Old session...");        if (DEBUG && debuglevel > 2)          debug(INFO, "S: " + Util.dumpString(result));        if (DEBUG && debuglevel > 2)          debug(INFO, "  sn = " + Util.dumpString(sn));        if (DEBUG && debuglevel > 2)          debug(INFO, " sCB = " + Util.dumpString(channelBinding));        return result;      }    else      { // new session        authenticator.activate(properties);        // -------------------------------------------------------------------        final HashMap mapB = new HashMap();        //         mapB.put(SRP6KeyAgreement.HASH_FUNCTION,    srp.newDigest());        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 (DEBUG && debuglevel > 6)          debug(TRACE, "Encoding N (modulus): " + Util.dump(N));        if (DEBUG && debuglevel > 6)          debug(TRACE, "Encoding g (generator): " + Util.dump(g));        if (DEBUG && debuglevel > 6)          debug(TRACE, "Encoding s (client's salt): " + Util.dumpString(s));        if (DEBUG && debuglevel > 6)          debug(TRACE, "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 (DEBUG && debuglevel > 6)          debug(TRACE, "Encoding L (available options): \"" + L + "\"");        if (DEBUG && debuglevel > 6)          debug(TRACE, "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 (DEBUG && debuglevel > 8)          debug(TRACE, "<== sendProtocolElements()");        if (DEBUG && debuglevel > 2)          debug(INFO, "New session...");        if (DEBUG && debuglevel > 2)          debug(INFO, "S: " + Util.dumpString(result));        if (DEBUG && debuglevel > 2)          debug(INFO, "   N = 0x" + N.toString(16));        if (DEBUG && debuglevel > 2)          debug(INFO, "   g = 0x" + g.toString(16));        if (DEBUG && debuglevel > 2)          debug(INFO, "   s = " + Util.dumpString(s));        if (DEBUG && debuglevel > 2)          debug(INFO, "   B = 0x" + B.toString(16));        if (DEBUG && debuglevel > 2)          debug(INFO, "   L = " + L);        return result;      }  }