new SecureRandom ().nextBytes(cIV);
getDefaultPRNG().nextBytes(cIV);
  private String createO(final String aol) throws AuthenticationException  {    if (DEBUG && debuglevel > 8)      debug(TRACE, "==> createO(\"" + aol + "\")");    boolean replaydetectionAvailable = false;    boolean integrityAvailable = false;    boolean confidentialityAvailable = false;    String option, mandatory = SRPRegistry.DEFAULT_MANDATORY;    int i;    String mdName = SRPRegistry.SRP_DEFAULT_DIGEST_NAME;    final StringTokenizer st = new StringTokenizer(aol, ",");    while (st.hasMoreTokens())      {        option = st.nextToken();        if (option.startsWith(SRPRegistry.OPTION_SRP_DIGEST + "="))          {            option = option.substring(option.indexOf('=') + 1);            if (DEBUG && debuglevel > 6)              debug(TRACE, "mda: <" + option + ">");            for (i = 0; i < SRPRegistry.INTEGRITY_ALGORITHMS.length; i++)              {                if (SRPRegistry.SRP_ALGORITHMS[i].equals(option))                  {                    mdName = option;                    break;                  }              }          }        else if (option.equals(SRPRegistry.OPTION_REPLAY_DETECTION))          {            replaydetectionAvailable = true;          }        else if (option.startsWith(SRPRegistry.OPTION_INTEGRITY + "="))          {            option = option.substring(option.indexOf('=') + 1);            if (DEBUG && debuglevel > 6)              debug(TRACE, "ialg: <" + option + ">");            for (i = 0; i < SRPRegistry.INTEGRITY_ALGORITHMS.length; i++)              {                if (SRPRegistry.INTEGRITY_ALGORITHMS[i].equals(option))                  {                    chosenIntegrityAlgorithm = option;                    integrityAvailable = true;                    break;                  }              }          }        else if (option.startsWith(SRPRegistry.OPTION_CONFIDENTIALITY + "="))          {            option = option.substring(option.indexOf('=') + 1);            if (DEBUG && debuglevel > 6)              debug(TRACE, "calg: <" + option + ">");            for (i = 0; i < SRPRegistry.CONFIDENTIALITY_ALGORITHMS.length; i++)              {                if (SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i].equals(option))                  {                    chosenConfidentialityAlgorithm = option;                    confidentialityAvailable = true;                    break;                  }              }          }        else if (option.startsWith(SRPRegistry.OPTION_MANDATORY + "="))          {            mandatory = option.substring(option.indexOf('=') + 1);          }        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                                                      + "="                                                      + String.valueOf(maxBufferSize),                                                  x);              }          }      }    replayDetection = replaydetectionAvailable                      && Boolean.valueOf(                                         (String) properties.get(SRPRegistry.SRP_REPLAY_DETECTION)).booleanValue();    boolean integrity = integrityAvailable                        && Boolean.valueOf(                                           (String) properties.get(SRPRegistry.SRP_INTEGRITY_PROTECTION)).booleanValue();    boolean confidentiality = confidentialityAvailable                              && Boolean.valueOf(                                                 (String) properties.get(SRPRegistry.SRP_CONFIDENTIALITY)).booleanValue();    // make sure we do the right thing    if (SRPRegistry.OPTION_REPLAY_DETECTION.equals(mandatory))      {        replayDetection = true;        integrity = true;      }    else if (SRPRegistry.OPTION_INTEGRITY.equals(mandatory))      {        integrity = true;      }    else if (SRPRegistry.OPTION_CONFIDENTIALITY.equals(mandatory))      {        confidentiality = true;      }    if (replayDetection)      {        if (chosenIntegrityAlgorithm == null)          {            throw new AuthenticationException(                                              "Replay detection is required but no "                                                  + "integrity protection algorithm was chosen");          }      }    if (integrity)      {        if (chosenIntegrityAlgorithm == null)          {            throw new AuthenticationException(                                              "Integrity protection is required but no "                                                  + "algorithm was chosen");          }      }    if (confidentiality)      {        if (chosenConfidentialityAlgorithm == null)          {            throw new AuthenticationException(                                              "Confidentiality protection is required "                                                  + "but no algorithm was chosen");          }      }    // 1. check if we'll be using confidentiality; if not set IV to 0-byte    if (chosenConfidentialityAlgorithm == null)      {        cIV = new byte[0];      }    else      {        // 2. get the block size of the cipher        final IBlockCipher cipher = CipherFactory.getInstance(chosenConfidentialityAlgorithm);        if (cipher == null)          {            throw new AuthenticationException("createO()",                                              new NoSuchAlgorithmException());          }        final int blockSize = cipher.defaultBlockSize();        // 3. generate random iv        cIV = new byte[blockSize];        new SecureRandom ().nextBytes(cIV);      }    srp = SRP.instance(mdName);    // Now create the options list specifying which of the available options    // we have chosen.    // For now we just select the defaults. Later we need to add support for    // properties (perhaps in a file) where a user can specify the list of    // algorithms they would prefer to use.    final StringBuffer sb = new StringBuffer();    sb.append(SRPRegistry.OPTION_SRP_DIGEST).append("=").append(mdName).append(                                                                               ",");    if (replayDetection)      {        sb.append(SRPRegistry.OPTION_REPLAY_DETECTION).append(",");      }    if (integrity)      {        sb.append(SRPRegistry.OPTION_INTEGRITY).append("=").append(                                                                   chosenIntegrityAlgorithm).append(                                                                                                    ",");      }    if (confidentiality)      {        sb.append(SRPRegistry.OPTION_CONFIDENTIALITY).append("=").append(                                                                         chosenConfidentialityAlgorithm).append(                                                                                                                ",");      }    final String result = sb.append(SRPRegistry.OPTION_MAX_BUFFER_SIZE).append(                                                                               "=").append(                                                                                           Registry.SASL_BUFFER_MAX_LIMIT).toString();    if (DEBUG && debuglevel > 8)      debug(TRACE, "<== createO() --> " + result);    return result;  }