~ubuntu-branches/ubuntu/precise/classpath/precise

« back to all changes in this revision

Viewing changes to gnu/javax/crypto/sasl/srp/SRPServer.java

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2006-05-27 16:11:15 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20060527161115-h6e39eposdt5snb6
Tags: 2:0.91-3
* Install header files to /usr/include/classpath.
* debian/control: classpath: Conflict with jamvm < 1.4.3 and
  cacao < 0.96 (Closes: #368172).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* SRPServer.java -- 
 
2
   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
 
3
 
 
4
This file is a part of GNU Classpath.
 
5
 
 
6
GNU Classpath is free software; you can redistribute it and/or modify
 
7
it under the terms of the GNU General Public License as published by
 
8
the Free Software Foundation; either version 2 of the License, or (at
 
9
your option) any later version.
 
10
 
 
11
GNU Classpath is distributed in the hope that it will be useful, but
 
12
WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
General Public License for more details.
 
15
 
 
16
You should have received a copy of the GNU General Public License
 
17
along with GNU Classpath; if not, write to the Free Software
 
18
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 
19
USA
 
20
 
 
21
Linking this library statically or dynamically with other modules is
 
22
making a combined work based on this library.  Thus, the terms and
 
23
conditions of the GNU General Public License cover the whole
 
24
combination.
 
25
 
 
26
As a special exception, the copyright holders of this library give you
 
27
permission to link this library with independent modules to produce an
 
28
executable, regardless of the license terms of these independent
 
29
modules, and to copy and distribute the resulting executable under
 
30
terms of your choice, provided that you also meet, for each linked
 
31
independent module, the terms and conditions of the license of that
 
32
module.  An independent module is a module which is not derived from
 
33
or based on this library.  If you modify this library, you may extend
 
34
this exception to your version of the library, but you are not
 
35
obligated to do so.  If you do not wish to do so, delete this
 
36
exception statement from your version.  */
 
37
 
 
38
 
 
39
package gnu.javax.crypto.sasl.srp;
 
40
 
 
41
import gnu.java.security.Registry;
 
42
import gnu.java.security.util.PRNG;
 
43
import gnu.java.security.util.Util;
 
44
 
 
45
import gnu.javax.crypto.assembly.Direction;
 
46
import gnu.javax.crypto.cipher.CipherFactory;
 
47
import gnu.javax.crypto.cipher.IBlockCipher;
 
48
import gnu.javax.crypto.key.IKeyAgreementParty;
 
49
import gnu.javax.crypto.key.KeyAgreementFactory;
 
50
import gnu.javax.crypto.key.KeyAgreementException;
 
51
import gnu.javax.crypto.key.OutgoingMessage;
 
52
import gnu.javax.crypto.key.IncomingMessage;
 
53
import gnu.javax.crypto.key.srp6.SRP6KeyAgreement;
 
54
import gnu.javax.crypto.sasl.IllegalMechanismStateException;
 
55
import gnu.javax.crypto.sasl.InputBuffer;
 
56
import gnu.javax.crypto.sasl.IntegrityException;
 
57
import gnu.javax.crypto.sasl.OutputBuffer;
 
58
import gnu.javax.crypto.sasl.ServerMechanism;
 
59
 
 
60
import java.io.IOException;
 
61
import java.io.PrintWriter;
 
62
import java.io.ByteArrayOutputStream;
 
63
import java.io.UnsupportedEncodingException;
 
64
import java.math.BigInteger;
 
65
import java.util.Arrays;
 
66
import java.util.HashMap;
 
67
import java.util.StringTokenizer;
 
68
 
 
69
import javax.security.sasl.AuthenticationException;
 
70
import javax.security.sasl.SaslException;
 
71
import javax.security.sasl.SaslServer;
 
72
 
 
73
/**
 
74
 * <p>The SASL-SRP server-side mechanism.</p>
 
75
 */
 
76
public class SRPServer extends ServerMechanism implements SaslServer
 
77
{
 
78
 
 
79
  // Debugging methods and variables
 
80
  // -------------------------------------------------------------------------
 
81
 
 
82
  private static final String NAME = "SRPServer";
 
83
 
 
84
  //   private static final String ERROR = "ERROR";
 
85
  private static final String WARN = " WARN";
 
86
 
 
87
  private static final String INFO = " INFO";
 
88
 
 
89
  private static final String TRACE = "DEBUG";
 
90
 
 
91
  private static final boolean DEBUG = true;
 
92
 
 
93
  private static final int debuglevel = 3;
 
94
 
 
95
  private static final PrintWriter err = new PrintWriter(System.out, true);
 
96
 
 
97
  private static void debug(final String level, final Object obj)
 
98
  {
 
99
    err.println("[" + level + "] " + NAME + ": " + String.valueOf(obj));
 
100
  }
 
101
 
 
102
  // Constants and variables
 
103
  // -------------------------------------------------------------------------
 
104
 
 
105
  private String U = null; // client's username
 
106
 
 
107
  private BigInteger N, g, A, B;
 
108
 
 
109
  private byte[] s; // salt
 
110
 
 
111
  private byte[] cIV, sIV; // client+server IVs, when confidentiality is on
 
112
 
 
113
  private byte[] cn, sn; // client's and server's nonce
 
114
 
 
115
  private SRP srp; // SRP algorithm instance used by this server
 
116
 
 
117
  private byte[] sid; // session ID when re-used
 
118
 
 
119
  private int ttl = 360; // session time-to-live in seconds
 
120
 
 
121
  private byte[] cCB; // peer's channel binding'
 
122
 
 
123
  private String mandatory; // List of available options
 
124
 
 
125
  private String L = null;
 
126
 
 
127
  private String o;
 
128
 
 
129
  private String chosenIntegrityAlgorithm;
 
130
 
 
131
  private String chosenConfidentialityAlgorithm;
 
132
 
 
133
  private int rawSendSize = Registry.SASL_BUFFER_MAX_LIMIT;
 
134
 
 
135
  private byte[] K; // shared session key
 
136
 
 
137
  private boolean replayDetection = true; // whether Replay Detection is on
 
138
 
 
139
  private int inCounter = 0; // messages sequence numbers
 
140
 
 
141
  private int outCounter = 0;
 
142
 
 
143
  private IALG inMac, outMac; // if !null, use for integrity
 
144
 
 
145
  private CALG inCipher, outCipher; // if !null, use for confidentiality
 
146
 
 
147
  private IKeyAgreementParty serverHandler = KeyAgreementFactory.getPartyBInstance(Registry.SRP_SASL_KA);
 
148
 
 
149
  /** Our default source of randomness. */
 
150
  private PRNG prng = null;
 
151
 
 
152
  // Constructor(s)
 
153
  // -------------------------------------------------------------------------
 
154
 
 
155
  public SRPServer()
 
156
  {
 
157
    super(Registry.SASL_SRP_MECHANISM);
 
158
  }
 
159
 
 
160
  // Class methods
 
161
  // -------------------------------------------------------------------------
 
162
 
 
163
  // Instance methods
 
164
  // -------------------------------------------------------------------------
 
165
 
 
166
  // abstract methods implementation -----------------------------------------
 
167
 
 
168
  protected void initMechanism() throws SaslException
 
169
  {
 
170
    // TODO:
 
171
    // we must have a means to map a given username to a preferred
 
172
    // SRP hash algorithm; otherwise we end up using _always_ SHA.
 
173
    // for the time being get it from the mechanism properties map
 
174
    // and apply it for all users.
 
175
    final String mda = (String) properties.get(SRPRegistry.SRP_HASH);
 
176
    srp = SRP.instance(mda == null ? SRPRegistry.SRP_DEFAULT_DIGEST_NAME : mda);
 
177
  }
 
178
 
 
179
  protected void resetMechanism() throws SaslException
 
180
  {
 
181
    s = null;
 
182
    A = B = null;
 
183
    K = null;
 
184
    inMac = outMac = null;
 
185
    inCipher = outCipher = null;
 
186
 
 
187
    sid = null;
 
188
  }
 
189
 
 
190
  // javax.security.sasl.SaslServer interface implementation -----------------
 
191
 
 
192
  public byte[] evaluateResponse(final byte[] response) throws SaslException
 
193
  {
 
194
    switch (state)
 
195
      {
 
196
      case 0:
 
197
        if (response == null)
 
198
          {
 
199
            return null;
 
200
          }
 
201
        state++;
 
202
        return sendProtocolElements(response);
 
203
      case 1:
 
204
        if (!complete)
 
205
          {
 
206
            state++;
 
207
            return sendEvidence(response);
 
208
          }
 
209
      // else fall through
 
210
      default:
 
211
        throw new IllegalMechanismStateException("evaluateResponse()");
 
212
      }
 
213
  }
 
214
 
 
215
  protected byte[] engineUnwrap(final byte[] incoming, final int offset,
 
216
                                final int len) throws SaslException
 
217
  {
 
218
    //      if (DEBUG && debuglevel > 8) debug(TRACE, "==> engineUnwrap()");
 
219
    //
 
220
    //      if (inMac == null && inCipher == null) {
 
221
    //         throw new IllegalStateException("connection is not protected");
 
222
    //      }
 
223
    //
 
224
    //      if (DEBUG && debuglevel > 6) debug(TRACE, "Incoming buffer (before security): "+Util.dumpString(incoming, offset, len));
 
225
    //
 
226
    //      byte[] data = null;
 
227
    //      try {
 
228
    //         InputBuffer frameIn = InputBuffer.getInstance(incoming, offset, len);
 
229
    //         data = frameIn.getEOS();
 
230
    //         if (inMac != null) {
 
231
    //            byte[] received_mac = frameIn.getOS();
 
232
    //            if (DEBUG && debuglevel > 6) debug(TRACE, "Got C (received MAC): "+Util.dumpString(received_mac));
 
233
    //            inMac.update(data);
 
234
    //            if (replayDetection) {
 
235
    //               inCounter++;
 
236
    //               if (DEBUG && debuglevel > 6) debug(TRACE, "inCounter="+String.valueOf(inCounter));
 
237
    //               inMac.update(new byte[] {
 
238
    //                  (byte)(inCounter >>> 24),
 
239
    //                  (byte)(inCounter >>> 16),
 
240
    //                  (byte)(inCounter >>>  8),
 
241
    //                  (byte) inCounter });
 
242
    //            }
 
243
    //            final byte[] computed_mac = inMac.doFinal();
 
244
    //            if (DEBUG && debuglevel > 6) debug(TRACE, "Computed MAC: "+Util.dumpString(computed_mac));
 
245
    //            if (!Arrays.equals(received_mac, computed_mac))
 
246
    //               throw new IntegrityException("engineUnwrap()");
 
247
    //         }
 
248
    //         if (inCipher != null) {
 
249
    //            data = inCipher.doFinal(data);
 
250
    //         }
 
251
    //       } catch (IOException x) {
 
252
    //          if (x instanceof SaslException) {
 
253
    //             throw (SaslException) x;
 
254
    //          }
 
255
    //          throw new SaslException("engineUnwrap()", x);
 
256
    //       }
 
257
    //
 
258
    //      if (DEBUG && debuglevel > 6) debug(TRACE, "Incoming buffer (after security): "+Util.dumpString(data));
 
259
    //      if (DEBUG && debuglevel > 8) debug(TRACE, "<== engineUnwrap()");
 
260
    //      return data;
 
261
 
 
262
    if (DEBUG && debuglevel > 8)
 
263
      debug(TRACE, "==> engineUnwrap()");
 
264
 
 
265
    if (inMac == null && inCipher == null)
 
266
      {
 
267
        throw new IllegalStateException("connection is not protected");
 
268
      }
 
269
 
 
270
    if (DEBUG && debuglevel > 6)
 
271
      debug(TRACE, "Incoming buffer (before security): "
 
272
                   + Util.dumpString(incoming, offset, len));
 
273
 
 
274
    // at this point one, or both, of confidentiality and integrity protection
 
275
    // services are active.
 
276
 
 
277
    final byte[] result;
 
278
    try
 
279
      {
 
280
        if (inMac != null)
 
281
          { // integrity bytes are at the end of the stream
 
282
            final int macBytesCount = inMac.length();
 
283
            final int payloadLength = len - macBytesCount;
 
284
            final byte[] received_mac = new byte[macBytesCount];
 
285
            System.arraycopy(incoming, offset + payloadLength, received_mac, 0,
 
286
                             macBytesCount);
 
287
            if (DEBUG && debuglevel > 6)
 
288
              debug(TRACE, "Got C (received MAC): "
 
289
                           + Util.dumpString(received_mac));
 
290
            inMac.update(incoming, offset, payloadLength);
 
291
            if (replayDetection)
 
292
              {
 
293
                inCounter++;
 
294
                if (DEBUG && debuglevel > 6)
 
295
                  debug(TRACE, "inCounter=" + String.valueOf(inCounter));
 
296
                inMac.update(new byte[] { (byte) (inCounter >>> 24),
 
297
                                         (byte) (inCounter >>> 16),
 
298
                                         (byte) (inCounter >>> 8),
 
299
                                         (byte) inCounter });
 
300
              }
 
301
 
 
302
            final byte[] computed_mac = inMac.doFinal();
 
303
            if (DEBUG && debuglevel > 6)
 
304
              debug(TRACE, "Computed MAC: " + Util.dumpString(computed_mac));
 
305
            if (!Arrays.equals(received_mac, computed_mac))
 
306
              {
 
307
                throw new IntegrityException("engineUnwrap()");
 
308
              }
 
309
 
 
310
            // deal with the payload, which can be either plain or encrypted
 
311
            if (inCipher != null)
 
312
              {
 
313
                result = inCipher.doFinal(incoming, offset, payloadLength);
 
314
              }
 
315
            else
 
316
              {
 
317
                result = new byte[payloadLength];
 
318
                System.arraycopy(incoming, offset, result, 0, result.length);
 
319
              }
 
320
          }
 
321
        else
 
322
          { // no integrity protection; just confidentiality
 
323
          //            if (inCipher != null) {
 
324
            result = inCipher.doFinal(incoming, offset, len);
 
325
            //            } else {
 
326
            //               result = new byte[len];
 
327
            //               System.arraycopy(incoming, offset, result, 0, len);
 
328
            //            }
 
329
          }
 
330
      }
 
331
    catch (IOException x)
 
332
      {
 
333
        if (x instanceof SaslException)
 
334
          {
 
335
            throw (SaslException) x;
 
336
          }
 
337
        throw new SaslException("engineUnwrap()", x);
 
338
      }
 
339
    if (DEBUG && debuglevel > 6)
 
340
      debug(TRACE, "Incoming buffer (after security): "
 
341
                   + Util.dumpString(result));
 
342
    if (DEBUG && debuglevel > 8)
 
343
      debug(TRACE, "<== engineUnwrap()");
 
344
    return result;
 
345
  }
 
346
 
 
347
  protected byte[] engineWrap(final byte[] outgoing, final int offset,
 
348
                              final int len) throws SaslException
 
349
  {
 
350
    //      if (DEBUG && debuglevel > 8) debug(TRACE, "==> engineWrap()");
 
351
    //
 
352
    //      if (outMac == null && outCipher == null) {
 
353
    //         throw new IllegalStateException("connection is not protected");
 
354
    //      }
 
355
    //
 
356
    //      byte[] data = new byte[len];
 
357
    //      System.arraycopy(outgoing, offset, data, 0, len);
 
358
    //
 
359
    //      if (DEBUG && debuglevel > 6) debug(TRACE, "Outgoing buffer (before security) (hex): "+Util.dumpString(data));
 
360
    //      if (DEBUG && debuglevel > 6) debug(TRACE, "Outgoing buffer (before security) (str): \""+new String(data)+"\"");
 
361
    //
 
362
    //      final byte[] result;
 
363
    //      try {
 
364
    //         OutputBuffer frameOut = new OutputBuffer();
 
365
    //         // Process the data
 
366
    //         if (outCipher != null) {
 
367
    //            data = outCipher.doFinal(data);
 
368
    //            if (DEBUG && debuglevel > 6) debug(TRACE, "Encoding c (encrypted plaintext): "+Util.dumpString(data));
 
369
    //         } else {
 
370
    //            if (DEBUG && debuglevel > 6) debug(TRACE, "Encoding p (plaintext): "+Util.dumpString(data));
 
371
    //         }
 
372
    //         frameOut.setEOS(data);
 
373
    //         if (outMac != null) {
 
374
    //            outMac.update(data);
 
375
    //            if (replayDetection) {
 
376
    //               outCounter++;
 
377
    //               if (DEBUG && debuglevel > 6) debug(TRACE, "outCounter="+String.valueOf(outCounter));
 
378
    //               outMac.update(new byte[] {
 
379
    //                  (byte)(outCounter >>> 24),
 
380
    //                  (byte)(outCounter >>> 16),
 
381
    //                  (byte)(outCounter >>>  8),
 
382
    //                  (byte) outCounter});
 
383
    //            }
 
384
    //            byte[] C = outMac.doFinal();
 
385
    //            frameOut.setOS(C);
 
386
    //            if (DEBUG && debuglevel > 6) debug(TRACE, "Encoding C (integrity checksum): "+Util.dumpString(C));
 
387
    //         }
 
388
    //         result = frameOut.wrap();
 
389
    //
 
390
    //      } catch (IOException x) {
 
391
    //         if (x instanceof SaslException) {
 
392
    //            throw (SaslException) x;
 
393
    //         }
 
394
    //         throw new SaslException("engineWrap()", x);
 
395
    //      }
 
396
    //
 
397
    //      if (DEBUG && debuglevel > 8) debug(TRACE, "<== engineWrap()");
 
398
    //      return result;
 
399
 
 
400
    if (DEBUG && debuglevel > 8)
 
401
      debug(TRACE, "==> engineWrap()");
 
402
 
 
403
    if (outMac == null && outCipher == null)
 
404
      {
 
405
        throw new IllegalStateException("connection is not protected");
 
406
      }
 
407
 
 
408
    if (DEBUG && debuglevel > 6)
 
409
      debug(TRACE, "Outgoing buffer (before security) (hex): "
 
410
                   + Util.dumpString(outgoing, offset, len));
 
411
    if (DEBUG && debuglevel > 6)
 
412
      debug(TRACE, "Outgoing buffer (before security) (str): \""
 
413
                   + new String(outgoing, offset, len) + "\"");
 
414
 
 
415
    // at this point one, or both, of confidentiality and integrity protection
 
416
    // services are active.
 
417
 
 
418
    byte[] result;
 
419
    try
 
420
      {
 
421
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
 
422
        if (outCipher != null)
 
423
          {
 
424
            result = outCipher.doFinal(outgoing, offset, len);
 
425
            if (DEBUG && debuglevel > 6)
 
426
              debug(TRACE, "Encoding c (encrypted plaintext): "
 
427
                           + Util.dumpString(result));
 
428
 
 
429
            out.write(result);
 
430
 
 
431
            if (outMac != null)
 
432
              {
 
433
                outMac.update(result);
 
434
                if (replayDetection)
 
435
                  {
 
436
                    outCounter++;
 
437
                    if (DEBUG && debuglevel > 6)
 
438
                      debug(TRACE, "outCounter=" + String.valueOf(outCounter));
 
439
                    outMac.update(new byte[] { (byte) (outCounter >>> 24),
 
440
                                              (byte) (outCounter >>> 16),
 
441
                                              (byte) (outCounter >>> 8),
 
442
                                              (byte) outCounter });
 
443
                  }
 
444
                final byte[] C = outMac.doFinal();
 
445
                out.write(C);
 
446
                if (DEBUG && debuglevel > 6)
 
447
                  debug(TRACE, "Encoding C (integrity checksum): "
 
448
                               + Util.dumpString(C));
 
449
              } // else ciphertext only; do nothing
 
450
          }
 
451
        else
 
452
          { // no confidentiality; just integrity [+ replay detection]
 
453
            if (DEBUG && debuglevel > 6)
 
454
              debug(TRACE, "Encoding p (plaintext): "
 
455
                           + Util.dumpString(outgoing, offset, len));
 
456
 
 
457
            out.write(outgoing, offset, len);
 
458
 
 
459
            //            if (outMac != null) {
 
460
            outMac.update(outgoing, offset, len);
 
461
            if (replayDetection)
 
462
              {
 
463
                outCounter++;
 
464
                if (DEBUG && debuglevel > 6)
 
465
                  debug(TRACE, "outCounter=" + String.valueOf(outCounter));
 
466
                outMac.update(new byte[] { (byte) (outCounter >>> 24),
 
467
                                          (byte) (outCounter >>> 16),
 
468
                                          (byte) (outCounter >>> 8),
 
469
                                          (byte) outCounter });
 
470
              }
 
471
            final byte[] C = outMac.doFinal();
 
472
            out.write(C);
 
473
            if (DEBUG && debuglevel > 6)
 
474
              debug(TRACE, "Encoding C (integrity checksum): "
 
475
                           + Util.dumpString(C));
 
476
            //            } // else plaintext only; do nothing
 
477
          }
 
478
 
 
479
        result = out.toByteArray();
 
480
 
 
481
      }
 
482
    catch (IOException x)
 
483
      {
 
484
        if (x instanceof SaslException)
 
485
          {
 
486
            throw (SaslException) x;
 
487
          }
 
488
        throw new SaslException("engineWrap()", x);
 
489
      }
 
490
 
 
491
    if (DEBUG && debuglevel > 8)
 
492
      debug(TRACE, "<== engineWrap()");
 
493
    return result;
 
494
  }
 
495
 
 
496
  protected String getNegotiatedQOP()
 
497
  {
 
498
    if (inMac != null)
 
499
      {
 
500
        if (inCipher != null)
 
501
          {
 
502
            return Registry.QOP_AUTH_CONF;
 
503
          }
 
504
        else
 
505
          {
 
506
            return Registry.QOP_AUTH_INT;
 
507
          }
 
508
      }
 
509
    return Registry.QOP_AUTH;
 
510
  }
 
511
 
 
512
  protected String getNegotiatedStrength()
 
513
  {
 
514
    if (inMac != null)
 
515
      {
 
516
        if (inCipher != null)
 
517
          {
 
518
            return Registry.STRENGTH_HIGH;
 
519
          }
 
520
        else
 
521
          {
 
522
            return Registry.STRENGTH_MEDIUM;
 
523
          }
 
524
      }
 
525
    return Registry.STRENGTH_LOW;
 
526
  }
 
527
 
 
528
  protected String getNegotiatedRawSendSize()
 
529
  {
 
530
    return String.valueOf(rawSendSize);
 
531
  }
 
532
 
 
533
  protected String getReuse()
 
534
  {
 
535
    return Registry.REUSE_TRUE;
 
536
  }
 
537
 
 
538
  // other methods -----------------------------------------------------------
 
539
 
 
540
  private byte[] sendProtocolElements(final byte[] input) throws SaslException
 
541
  {
 
542
    if (DEBUG && debuglevel > 8)
 
543
      debug(TRACE, "==> sendProtocolElements()");
 
544
    if (DEBUG && debuglevel > 6)
 
545
      debug(TRACE, "C: " + Util.dumpString(input));
 
546
 
 
547
    // Client send U, I, sid, cn
 
548
    final InputBuffer frameIn = new InputBuffer(input);
 
549
    try
 
550
      {
 
551
        U = frameIn.getText(); // Extract username
 
552
        if (DEBUG && debuglevel > 6)
 
553
          debug(TRACE, "Got U (username): \"" + U + "\"");
 
554
        authorizationID = frameIn.getText(); // Extract authorisation ID
 
555
        if (DEBUG && debuglevel > 6)
 
556
          debug(TRACE, "Got I (userid): \"" + authorizationID + "\"");
 
557
        sid = frameIn.getEOS();
 
558
        if (DEBUG && debuglevel > 6)
 
559
          debug(TRACE, "Got sid (session ID): " + new String(sid));
 
560
        cn = frameIn.getOS();
 
561
        if (DEBUG && debuglevel > 6)
 
562
          debug(TRACE, "Got cn (client nonce): " + Util.dumpString(cn));
 
563
        cCB = frameIn.getEOS();
 
564
        if (DEBUG && debuglevel > 6)
 
565
          debug(TRACE, "Got cCB (client channel binding): "
 
566
                       + Util.dumpString(cCB));
 
567
      }
 
568
    catch (IOException x)
 
569
      {
 
570
        if (x instanceof SaslException)
 
571
          {
 
572
            throw (SaslException) x;
 
573
          }
 
574
        throw new AuthenticationException("sendProtocolElements()", x);
 
575
      }
 
576
 
 
577
    // do/can we re-use?
 
578
    if (ServerStore.instance().isAlive(sid))
 
579
      {
 
580
        final SecurityContext ctx = ServerStore.instance().restoreSession(sid);
 
581
        srp = SRP.instance(ctx.getMdName());
 
582
        K = ctx.getK();
 
583
        cIV = ctx.getClientIV();
 
584
        sIV = ctx.getServerIV();
 
585
        replayDetection = ctx.hasReplayDetection();
 
586
        inCounter = ctx.getInCounter();
 
587
        outCounter = ctx.getOutCounter();
 
588
        inMac = ctx.getInMac();
 
589
        outMac = ctx.getOutMac();
 
590
        inCipher = ctx.getInCipher();
 
591
        outCipher = ctx.getOutCipher();
 
592
 
 
593
        if (sn == null || sn.length != 16)
 
594
          {
 
595
            sn = new byte[16];
 
596
          }
 
597
        getDefaultPRNG().nextBytes(sn);
 
598
 
 
599
        setupSecurityServices(false);
 
600
 
 
601
        final OutputBuffer frameOut = new OutputBuffer();
 
602
        try
 
603
          {
 
604
            frameOut.setScalar(1, 0xFF);
 
605
            frameOut.setOS(sn);
 
606
            frameOut.setEOS(channelBinding);
 
607
          }
 
608
        catch (IOException x)
 
609
          {
 
610
            if (x instanceof SaslException)
 
611
              {
 
612
                throw (SaslException) x;
 
613
              }
 
614
            throw new AuthenticationException("sendProtocolElements()", x);
 
615
          }
 
616
        final byte[] result = frameOut.encode();
 
617
        if (DEBUG && debuglevel > 8)
 
618
          debug(TRACE, "<== sendProtocolElements()");
 
619
        if (DEBUG && debuglevel > 2)
 
620
          debug(INFO, "Old session...");
 
621
        if (DEBUG && debuglevel > 2)
 
622
          debug(INFO, "S: " + Util.dumpString(result));
 
623
        if (DEBUG && debuglevel > 2)
 
624
          debug(INFO, "  sn = " + Util.dumpString(sn));
 
625
        if (DEBUG && debuglevel > 2)
 
626
          debug(INFO, " sCB = " + Util.dumpString(channelBinding));
 
627
        return result;
 
628
      }
 
629
    else
 
630
      { // new session
 
631
        authenticator.activate(properties);
 
632
 
 
633
        // -------------------------------------------------------------------
 
634
        final HashMap mapB = new HashMap();
 
635
        //         mapB.put(SRP6KeyAgreement.HASH_FUNCTION,    srp.newDigest());
 
636
        mapB.put(SRP6KeyAgreement.HASH_FUNCTION, srp.getAlgorithm());
 
637
        mapB.put(SRP6KeyAgreement.HOST_PASSWORD_DB, authenticator);
 
638
 
 
639
        try
 
640
          {
 
641
            serverHandler.init(mapB);
 
642
            OutgoingMessage out = new OutgoingMessage();
 
643
            out.writeString(U);
 
644
            IncomingMessage in = new IncomingMessage(out.toByteArray());
 
645
            out = serverHandler.processMessage(in);
 
646
 
 
647
            in = new IncomingMessage(out.toByteArray());
 
648
            N = in.readMPI();
 
649
            g = in.readMPI();
 
650
            s = in.readMPI().toByteArray();
 
651
            B = in.readMPI();
 
652
          }
 
653
        catch (KeyAgreementException x)
 
654
          {
 
655
            throw new SaslException("sendProtocolElements()", x);
 
656
          }
 
657
        // -------------------------------------------------------------------
 
658
 
 
659
        if (DEBUG && debuglevel > 6)
 
660
          debug(TRACE, "Encoding N (modulus): " + Util.dump(N));
 
661
        if (DEBUG && debuglevel > 6)
 
662
          debug(TRACE, "Encoding g (generator): " + Util.dump(g));
 
663
        if (DEBUG && debuglevel > 6)
 
664
          debug(TRACE, "Encoding s (client's salt): " + Util.dumpString(s));
 
665
        if (DEBUG && debuglevel > 6)
 
666
          debug(TRACE, "Encoding B (server ephemeral public key): "
 
667
                       + Util.dump(B));
 
668
 
 
669
        // The server creates an options list (L), which consists of a
 
670
        // comma-separated list of option strings that specify the security
 
671
        // service options the server supports.
 
672
        L = createL();
 
673
        if (DEBUG && debuglevel > 6)
 
674
          debug(TRACE, "Encoding L (available options): \"" + L + "\"");
 
675
        if (DEBUG && debuglevel > 6)
 
676
          debug(TRACE, "Encoding sIV (server IV): " + Util.dumpString(sIV));
 
677
 
 
678
        final OutputBuffer frameOut = new OutputBuffer();
 
679
        try
 
680
          {
 
681
            frameOut.setScalar(1, 0x00);
 
682
            frameOut.setMPI(N);
 
683
            frameOut.setMPI(g);
 
684
            frameOut.setOS(s);
 
685
            frameOut.setMPI(B);
 
686
            frameOut.setText(L);
 
687
          }
 
688
        catch (IOException x)
 
689
          {
 
690
            if (x instanceof SaslException)
 
691
              {
 
692
                throw (SaslException) x;
 
693
              }
 
694
            throw new AuthenticationException("sendProtocolElements()", x);
 
695
          }
 
696
        final byte[] result = frameOut.encode();
 
697
        if (DEBUG && debuglevel > 8)
 
698
          debug(TRACE, "<== sendProtocolElements()");
 
699
        if (DEBUG && debuglevel > 2)
 
700
          debug(INFO, "New session...");
 
701
        if (DEBUG && debuglevel > 2)
 
702
          debug(INFO, "S: " + Util.dumpString(result));
 
703
        if (DEBUG && debuglevel > 2)
 
704
          debug(INFO, "   N = 0x" + N.toString(16));
 
705
        if (DEBUG && debuglevel > 2)
 
706
          debug(INFO, "   g = 0x" + g.toString(16));
 
707
        if (DEBUG && debuglevel > 2)
 
708
          debug(INFO, "   s = " + Util.dumpString(s));
 
709
        if (DEBUG && debuglevel > 2)
 
710
          debug(INFO, "   B = 0x" + B.toString(16));
 
711
        if (DEBUG && debuglevel > 2)
 
712
          debug(INFO, "   L = " + L);
 
713
        return result;
 
714
      }
 
715
  }
 
716
 
 
717
  private byte[] sendEvidence(final byte[] input) throws SaslException
 
718
  {
 
719
    if (DEBUG && debuglevel > 8)
 
720
      debug(TRACE, "==> sendEvidence()");
 
721
    if (DEBUG && debuglevel > 6)
 
722
      debug(TRACE, "C: " + Util.dumpString(input));
 
723
 
 
724
    // Client send A, M1, o, cIV
 
725
    final InputBuffer frameIn = new InputBuffer(input);
 
726
    final byte[] M1;
 
727
    try
 
728
      {
 
729
        A = frameIn.getMPI(); // Extract client's ephemeral public key
 
730
        if (DEBUG && debuglevel > 6)
 
731
          debug(TRACE, "Got A (client ephemeral public key): " + Util.dump(A));
 
732
        M1 = frameIn.getOS(); // Extract evidence
 
733
        if (DEBUG && debuglevel > 6)
 
734
          debug(TRACE, "Got M1 (client evidence): " + Util.dumpString(M1));
 
735
        o = frameIn.getText(); // Extract client's options list
 
736
        if (DEBUG && debuglevel > 6)
 
737
          debug(TRACE, "Got o (client chosen options): \"" + o + "\"");
 
738
        cIV = frameIn.getOS(); // Extract client's IV
 
739
        if (DEBUG && debuglevel > 6)
 
740
          debug(TRACE, "Got cIV (client IV): " + Util.dumpString(cIV));
 
741
      }
 
742
    catch (IOException x)
 
743
      {
 
744
        if (x instanceof SaslException)
 
745
          {
 
746
            throw (SaslException) x;
 
747
          }
 
748
        throw new AuthenticationException("sendEvidence()", x);
 
749
      }
 
750
 
 
751
    // Parse client's options and set security layer variables
 
752
    parseO(o);
 
753
 
 
754
    // ----------------------------------------------------------------------
 
755
    try
 
756
      {
 
757
        final OutgoingMessage out = new OutgoingMessage();
 
758
        out.writeMPI(A);
 
759
        final IncomingMessage in = new IncomingMessage(out.toByteArray());
 
760
        serverHandler.processMessage(in);
 
761
        K = serverHandler.getSharedSecret();
 
762
      }
 
763
    catch (KeyAgreementException x)
 
764
      {
 
765
        throw new SaslException("sendEvidence()", x);
 
766
      }
 
767
    // ----------------------------------------------------------------------
 
768
 
 
769
    if (DEBUG && debuglevel > 6)
 
770
      debug(TRACE, "K: " + Util.dumpString(K));
 
771
 
 
772
    final byte[] expected;
 
773
    try
 
774
      {
 
775
        expected = srp.generateM1(N, g, U, s, A, B, K, authorizationID, L, cn,
 
776
                                  cCB);
 
777
      }
 
778
    catch (UnsupportedEncodingException x)
 
779
      {
 
780
        throw new AuthenticationException("sendEvidence()", x);
 
781
      }
 
782
 
 
783
    // Verify client evidence
 
784
    if (!Arrays.equals(M1, expected))
 
785
      {
 
786
        throw new AuthenticationException("M1 mismatch");
 
787
      }
 
788
 
 
789
    setupSecurityServices(true);
 
790
 
 
791
    final byte[] M2;
 
792
    try
 
793
      {
 
794
        M2 = srp.generateM2(A, M1, K, U, authorizationID, o, sid, ttl, cIV,
 
795
                            sIV, channelBinding);
 
796
      }
 
797
    catch (UnsupportedEncodingException x)
 
798
      {
 
799
        throw new AuthenticationException("sendEvidence()", x);
 
800
      }
 
801
 
 
802
    final OutputBuffer frameOut = new OutputBuffer();
 
803
    try
 
804
      {
 
805
        frameOut.setOS(M2);
 
806
        frameOut.setOS(sIV);
 
807
        frameOut.setEOS(sid);
 
808
        frameOut.setScalar(4, ttl);
 
809
        frameOut.setEOS(channelBinding);
 
810
      }
 
811
    catch (IOException x)
 
812
      {
 
813
        if (x instanceof SaslException)
 
814
          {
 
815
            throw (SaslException) x;
 
816
          }
 
817
        throw new AuthenticationException("sendEvidence()", x);
 
818
      }
 
819
    final byte[] result = frameOut.encode();
 
820
    if (DEBUG && debuglevel > 2)
 
821
      debug(INFO, "S: " + Util.dumpString(result));
 
822
    if (DEBUG && debuglevel > 2)
 
823
      debug(INFO, "  M2 = " + Util.dumpString(M2));
 
824
    if (DEBUG && debuglevel > 2)
 
825
      debug(INFO, " sIV = " + Util.dumpString(sIV));
 
826
    if (DEBUG && debuglevel > 2)
 
827
      debug(INFO, " sid = " + new String(sid));
 
828
    if (DEBUG && debuglevel > 2)
 
829
      debug(INFO, " ttl = " + ttl);
 
830
    if (DEBUG && debuglevel > 2)
 
831
      debug(INFO, " sCB = " + Util.dumpString(channelBinding));
 
832
 
 
833
    if (DEBUG && debuglevel > 8)
 
834
      debug(TRACE, "<== sendEvidence()");
 
835
    return result;
 
836
  }
 
837
 
 
838
  private String createL()
 
839
  {
 
840
    if (DEBUG && debuglevel > 8)
 
841
      debug(TRACE, "==> createL()");
 
842
 
 
843
    String s = (String) properties.get(SRPRegistry.SRP_MANDATORY);
 
844
    if (s == null)
 
845
      {
 
846
        s = SRPRegistry.DEFAULT_MANDATORY;
 
847
      }
 
848
    if (!SRPRegistry.MANDATORY_NONE.equals(s)
 
849
        && !SRPRegistry.OPTION_REPLAY_DETECTION.equals(s)
 
850
        && !SRPRegistry.OPTION_INTEGRITY.equals(s)
 
851
        && !SRPRegistry.OPTION_CONFIDENTIALITY.equals(s))
 
852
      {
 
853
        if (DEBUG && debuglevel > 4)
 
854
          debug(WARN, "Unrecognised mandatory option (" + s
 
855
                      + "). Using default...");
 
856
        s = SRPRegistry.DEFAULT_MANDATORY;
 
857
      }
 
858
 
 
859
    mandatory = s;
 
860
 
 
861
    s = (String) properties.get(SRPRegistry.SRP_CONFIDENTIALITY);
 
862
    final boolean confidentiality = (s == null ? SRPRegistry.DEFAULT_CONFIDENTIALITY
 
863
                                              : Boolean.valueOf(s).booleanValue());
 
864
 
 
865
    s = (String) properties.get(SRPRegistry.SRP_INTEGRITY_PROTECTION);
 
866
    boolean integrity = (s == null ? SRPRegistry.DEFAULT_INTEGRITY
 
867
                                  : Boolean.valueOf(s).booleanValue());
 
868
 
 
869
    s = (String) properties.get(SRPRegistry.SRP_REPLAY_DETECTION);
 
870
    final boolean replayDetection = (s == null ? SRPRegistry.DEFAULT_REPLAY_DETECTION
 
871
                                              : Boolean.valueOf(s).booleanValue());
 
872
 
 
873
    final StringBuffer sb = new StringBuffer();
 
874
    sb.append(SRPRegistry.OPTION_SRP_DIGEST).append("=").append(
 
875
                                                                srp.getAlgorithm()).append(
 
876
                                                                                           ",");
 
877
 
 
878
    if (!SRPRegistry.MANDATORY_NONE.equals(mandatory))
 
879
      {
 
880
        sb.append(SRPRegistry.OPTION_MANDATORY).append("=").append(mandatory).append(
 
881
                                                                                     ",");
 
882
      }
 
883
    if (replayDetection)
 
884
      {
 
885
        sb.append(SRPRegistry.OPTION_REPLAY_DETECTION).append(",");
 
886
        // if replay detection is on then force integrity protection
 
887
        integrity = true;
 
888
      }
 
889
 
 
890
    int i;
 
891
    if (integrity)
 
892
      {
 
893
        for (i = 0; i < SRPRegistry.INTEGRITY_ALGORITHMS.length; i++)
 
894
          {
 
895
            sb.append(SRPRegistry.OPTION_INTEGRITY).append("=").append(
 
896
                                                                       SRPRegistry.INTEGRITY_ALGORITHMS[i]).append(
 
897
                                                                                                                   ",");
 
898
          }
 
899
      }
 
900
 
 
901
    if (confidentiality)
 
902
      {
 
903
        IBlockCipher cipher;
 
904
        for (i = 0; i < SRPRegistry.CONFIDENTIALITY_ALGORITHMS.length; i++)
 
905
          {
 
906
            cipher = CipherFactory.getInstance(SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i]);
 
907
            if (cipher != null)
 
908
              {
 
909
                sb.append(SRPRegistry.OPTION_CONFIDENTIALITY).append("=").append(
 
910
                                                                                 SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i]).append(
 
911
                                                                                                                                   ",");
 
912
              }
 
913
          }
 
914
      }
 
915
 
 
916
    final String result = sb.append(SRPRegistry.OPTION_MAX_BUFFER_SIZE).append(
 
917
                                                                               "=").append(
 
918
                                                                                           Registry.SASL_BUFFER_MAX_LIMIT).toString();
 
919
    if (DEBUG && debuglevel > 8)
 
920
      debug(TRACE, "<== createL()");
 
921
    return result;
 
922
  }
 
923
 
 
924
  // Parse client's options and set security layer variables
 
925
  private void parseO(final String o) throws AuthenticationException
 
926
  {
 
927
    this.replayDetection = false;
 
928
    boolean integrity = false;
 
929
    boolean confidentiality = false;
 
930
    String option;
 
931
    int i;
 
932
 
 
933
    final StringTokenizer st = new StringTokenizer(o.toLowerCase(), ",");
 
934
    while (st.hasMoreTokens())
 
935
      {
 
936
        option = st.nextToken();
 
937
        if (DEBUG && debuglevel > 6)
 
938
          debug(TRACE, "option: <" + option + ">");
 
939
        if (option.equals(SRPRegistry.OPTION_REPLAY_DETECTION))
 
940
          {
 
941
            replayDetection = true;
 
942
          }
 
943
        else if (option.startsWith(SRPRegistry.OPTION_INTEGRITY + "="))
 
944
          {
 
945
            if (integrity)
 
946
              {
 
947
                throw new AuthenticationException(
 
948
                                                  "Only one integrity algorithm may be chosen");
 
949
              }
 
950
            else
 
951
              {
 
952
                option = option.substring(option.indexOf('=') + 1);
 
953
                if (DEBUG && debuglevel > 6)
 
954
                  debug(TRACE, "algorithm: <" + option + ">");
 
955
                for (i = 0; i < SRPRegistry.INTEGRITY_ALGORITHMS.length; i++)
 
956
                  {
 
957
                    if (SRPRegistry.INTEGRITY_ALGORITHMS[i].equals(option))
 
958
                      {
 
959
                        chosenIntegrityAlgorithm = option;
 
960
                        integrity = true;
 
961
                        break;
 
962
                      }
 
963
                  }
 
964
                if (!integrity)
 
965
                  {
 
966
                    throw new AuthenticationException(
 
967
                                                      "Unknown integrity algorithm: "
 
968
                                                          + option);
 
969
                  }
 
970
              }
 
971
          }
 
972
        else if (option.startsWith(SRPRegistry.OPTION_CONFIDENTIALITY + "="))
 
973
          {
 
974
            if (confidentiality)
 
975
              {
 
976
                throw new AuthenticationException(
 
977
                                                  "Only one confidentiality algorithm may be chosen");
 
978
              }
 
979
            else
 
980
              {
 
981
                option = option.substring(option.indexOf('=') + 1);
 
982
                if (DEBUG && debuglevel > 6)
 
983
                  debug(TRACE, "algorithm: <" + option + ">");
 
984
                for (i = 0; i < SRPRegistry.CONFIDENTIALITY_ALGORITHMS.length; i++)
 
985
                  {
 
986
                    if (SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i].equals(option))
 
987
                      {
 
988
                        chosenConfidentialityAlgorithm = option;
 
989
                        confidentiality = true;
 
990
                        break;
 
991
                      }
 
992
                  }
 
993
                if (!confidentiality)
 
994
                  {
 
995
                    throw new AuthenticationException(
 
996
                                                      "Unknown confidentiality algorithm: "
 
997
                                                          + option);
 
998
                  }
 
999
              }
 
1000
          }
 
1001
        else if (option.startsWith(SRPRegistry.OPTION_MAX_BUFFER_SIZE + "="))
 
1002
          {
 
1003
            final String maxBufferSize = option.substring(option.indexOf('=') + 1);
 
1004
            try
 
1005
              {
 
1006
                rawSendSize = Integer.parseInt(maxBufferSize);
 
1007
                if (rawSendSize > Registry.SASL_BUFFER_MAX_LIMIT
 
1008
                    || rawSendSize < 1)
 
1009
                  throw new AuthenticationException(
 
1010
                                                    "Illegal value for 'maxbuffersize' option");
 
1011
              }
 
1012
            catch (NumberFormatException x)
 
1013
              {
 
1014
                throw new AuthenticationException(
 
1015
                                                  SRPRegistry.OPTION_MAX_BUFFER_SIZE
 
1016
                                                      + "="
 
1017
                                                      + String.valueOf(maxBufferSize),
 
1018
                                                  x);
 
1019
              }
 
1020
          }
 
1021
      }
 
1022
 
 
1023
    // check if client did the right thing
 
1024
    if (replayDetection)
 
1025
      {
 
1026
        if (!integrity)
 
1027
          {
 
1028
            throw new AuthenticationException(
 
1029
                                              "Missing integrity protection algorithm "
 
1030
                                                  + "but replay detection is chosen");
 
1031
          }
 
1032
      }
 
1033
    if (mandatory.equals(SRPRegistry.OPTION_REPLAY_DETECTION))
 
1034
      {
 
1035
        if (!replayDetection)
 
1036
          {
 
1037
            throw new AuthenticationException(
 
1038
                                              "Replay detection is mandatory but was not chosen");
 
1039
          }
 
1040
      }
 
1041
    if (mandatory.equals(SRPRegistry.OPTION_INTEGRITY))
 
1042
      {
 
1043
        if (!integrity)
 
1044
          {
 
1045
            throw new AuthenticationException(
 
1046
                                              "Integrity protection is mandatory but was not chosen");
 
1047
          }
 
1048
      }
 
1049
    if (mandatory.equals(SRPRegistry.OPTION_CONFIDENTIALITY))
 
1050
      {
 
1051
        if (!confidentiality)
 
1052
          {
 
1053
            throw new AuthenticationException(
 
1054
                                              "Confidentiality is mandatory but was not chosen");
 
1055
          }
 
1056
      }
 
1057
 
 
1058
    int blockSize = 0;
 
1059
    if (chosenConfidentialityAlgorithm != null)
 
1060
      {
 
1061
        final IBlockCipher cipher = CipherFactory.getInstance(chosenConfidentialityAlgorithm);
 
1062
        if (cipher != null)
 
1063
          {
 
1064
            blockSize = cipher.defaultBlockSize();
 
1065
          }
 
1066
        else
 
1067
          { // should not happen
 
1068
            throw new AuthenticationException("Confidentiality algorithm ("
 
1069
                                              + chosenConfidentialityAlgorithm
 
1070
                                              + ") not available");
 
1071
          }
 
1072
      }
 
1073
 
 
1074
    sIV = new byte[blockSize];
 
1075
    if (blockSize > 0)
 
1076
      getDefaultPRNG().nextBytes(sIV);
 
1077
  }
 
1078
 
 
1079
  private void setupSecurityServices(final boolean newSession)
 
1080
      throws SaslException
 
1081
  {
 
1082
    complete = true; // signal end of authentication phase
 
1083
    if (newSession)
 
1084
      {
 
1085
        outCounter = inCounter = 0;
 
1086
        // instantiate cipher if confidentiality protection filter is active
 
1087
        if (chosenConfidentialityAlgorithm != null)
 
1088
          {
 
1089
            if (DEBUG && debuglevel > 2)
 
1090
              debug(INFO, "Activating confidentiality protection filter");
 
1091
            inCipher = CALG.getInstance(chosenConfidentialityAlgorithm);
 
1092
            outCipher = CALG.getInstance(chosenConfidentialityAlgorithm);
 
1093
          }
 
1094
        // instantiate hmacs if integrity protection filter is active
 
1095
        if (chosenIntegrityAlgorithm != null)
 
1096
          {
 
1097
            if (DEBUG && debuglevel > 2)
 
1098
              debug(INFO, "Activating integrity protection filter");
 
1099
            inMac = IALG.getInstance(chosenIntegrityAlgorithm);
 
1100
            outMac = IALG.getInstance(chosenIntegrityAlgorithm);
 
1101
          }
 
1102
 
 
1103
        // generate a new sid if at least integrity is used
 
1104
        sid = (inMac != null ? ServerStore.getNewSessionID() : new byte[0]);
 
1105
      }
 
1106
    else
 
1107
      { // same session new keys
 
1108
        K = srp.generateKn(K, cn, sn);
 
1109
      }
 
1110
 
 
1111
    final KDF kdf = KDF.getInstance(K);
 
1112
 
 
1113
    // initialise in/out ciphers if confidentaility protection is used
 
1114
    if (inCipher != null)
 
1115
      {
 
1116
        outCipher.init(kdf, sIV, Direction.FORWARD);
 
1117
        inCipher.init(kdf, cIV, Direction.REVERSED);
 
1118
      }
 
1119
    // initialise in/out macs if integrity protection is used
 
1120
    if (inMac != null)
 
1121
      {
 
1122
        outMac.init(kdf);
 
1123
        inMac.init(kdf);
 
1124
      }
 
1125
 
 
1126
    if (sid != null && sid.length != 0)
 
1127
      { // update the security context and save in map
 
1128
        if (DEBUG && debuglevel > 2)
 
1129
          debug(INFO, "Updating security context for sid = " + new String(sid));
 
1130
        ServerStore.instance().cacheSession(
 
1131
                                            ttl,
 
1132
                                            new SecurityContext(
 
1133
                                                                srp.getAlgorithm(),
 
1134
                                                                sid,
 
1135
                                                                K,
 
1136
                                                                cIV,
 
1137
                                                                sIV,
 
1138
                                                                replayDetection,
 
1139
                                                                inCounter,
 
1140
                                                                outCounter,
 
1141
                                                                inMac, outMac,
 
1142
                                                                inCipher,
 
1143
                                                                outCipher));
 
1144
      }
 
1145
  }
 
1146
 
 
1147
  private PRNG getDefaultPRNG()
 
1148
  {
 
1149
    if (prng == null)
 
1150
      prng = PRNG.getInstance();
 
1151
 
 
1152
    return prng;
 
1153
  }
 
1154
}