1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59:
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68:
69: import ;
70: import ;
71: import ;
72:
73:
76: public class SRPServer
77: extends ServerMechanism
78: implements SaslServer
79: {
80: private static final Logger log = Logger.getLogger(SRPServer.class.getName());
81: private String U = null;
82: private BigInteger N, g, A, B;
83: private byte[] s;
84: private byte[] cIV, sIV;
85: private byte[] cn, sn;
86: private SRP srp;
87: private byte[] sid;
88: private int ttl = 360;
89: private byte[] cCB;
90: private String mandatory;
91: private String L = null;
92: private String o;
93: private String chosenIntegrityAlgorithm;
94: private String chosenConfidentialityAlgorithm;
95: private int rawSendSize = Registry.SASL_BUFFER_MAX_LIMIT;
96: private byte[] K;
97: private boolean replayDetection = true;
98: private int inCounter = 0;
99: private int outCounter = 0;
100: private IALG inMac, outMac;
101: private CALG inCipher, outCipher;
102: private IKeyAgreementParty serverHandler =
103: KeyAgreementFactory.getPartyBInstance(Registry.SRP_SASL_KA);
104:
105: private PRNG prng = null;
106:
107: public SRPServer()
108: {
109: super(Registry.SASL_SRP_MECHANISM);
110: }
111:
112: protected void initMechanism() throws SaslException
113: {
114:
115:
116:
117:
118:
119: final String mda = (String) properties.get(SRPRegistry.SRP_HASH);
120: srp = SRP.instance(mda == null ? SRPRegistry.SRP_DEFAULT_DIGEST_NAME : mda);
121: }
122:
123: protected void resetMechanism() throws SaslException
124: {
125: s = null;
126: A = B = null;
127: K = null;
128: inMac = outMac = null;
129: inCipher = outCipher = null;
130: sid = null;
131: }
132:
133: public byte[] evaluateResponse(final byte[] response) throws SaslException
134: {
135: switch (state)
136: {
137: case 0:
138: if (response == null)
139: return null;
140: state++;
141: return sendProtocolElements(response);
142: case 1:
143: if (! complete)
144: {
145: state++;
146: return sendEvidence(response);
147: }
148:
149: default:
150: throw new IllegalMechanismStateException("evaluateResponse()");
151: }
152: }
153:
154: protected byte[] engineUnwrap(final byte[] incoming, final int offset,
155: final int len) throws SaslException
156: {
157: if (Configuration.DEBUG)
158: log.entering(this.getClass().getName(), "engineUnwrap");
159: if (inMac == null && inCipher == null)
160: throw new IllegalStateException("connection is not protected");
161: if (Configuration.DEBUG)
162: log.fine("Incoming buffer (before security): "
163: + Util.dumpString(incoming, offset, len));
164:
165:
166: final byte[] result;
167: try
168: {
169: if (inMac != null)
170: {
171: final int macBytesCount = inMac.length();
172: final int payloadLength = len - macBytesCount;
173: final byte[] received_mac = new byte[macBytesCount];
174: System.arraycopy(incoming, offset + payloadLength, received_mac, 0,
175: macBytesCount);
176: if (Configuration.DEBUG)
177: log.fine("Got C (received MAC): " + Util.dumpString(received_mac));
178: inMac.update(incoming, offset, payloadLength);
179: if (replayDetection)
180: {
181: inCounter++;
182: if (Configuration.DEBUG)
183: log.fine("inCounter=" + String.valueOf(inCounter));
184: inMac.update(new byte[] {
185: (byte)(inCounter >>> 24),
186: (byte)(inCounter >>> 16),
187: (byte)(inCounter >>> 8),
188: (byte) inCounter });
189: }
190: final byte[] computed_mac = inMac.doFinal();
191: if (Configuration.DEBUG)
192: log.fine("Computed MAC: " + Util.dumpString(computed_mac));
193: if (! Arrays.equals(received_mac, computed_mac))
194: throw new IntegrityException("engineUnwrap()");
195:
196: if (inCipher != null)
197: result = inCipher.doFinal(incoming, offset, payloadLength);
198: else
199: {
200: result = new byte[payloadLength];
201: System.arraycopy(incoming, offset, result, 0, result.length);
202: }
203: }
204: else
205: result = inCipher.doFinal(incoming, offset, len);
206: }
207: catch (IOException x)
208: {
209: if (x instanceof SaslException)
210: throw (SaslException) x;
211: throw new SaslException("engineUnwrap()", x);
212: }
213: if (Configuration.DEBUG)
214: {
215: log.fine("Incoming buffer (after security): " + Util.dumpString(result));
216: log.exiting(this.getClass().getName(), "engineUnwrap");
217: }
218: return result;
219: }
220:
221: protected byte[] engineWrap(final byte[] outgoing, final int offset,
222: final int len) throws SaslException
223: {
224: if (Configuration.DEBUG)
225: log.entering(this.getClass().getName(), "engineWrap");
226: if (outMac == null && outCipher == null)
227: throw new IllegalStateException("connection is not protected");
228: if (Configuration.DEBUG)
229: {
230: log.fine("Outgoing buffer (before security) (hex): "
231: + Util.dumpString(outgoing, offset, len));
232: log.fine("Outgoing buffer (before security) (str): \""
233: + new String(outgoing, offset, len) + "\"");
234: }
235:
236:
237: byte[] result;
238: try
239: {
240: final ByteArrayOutputStream out = new ByteArrayOutputStream();
241: if (outCipher != null)
242: {
243: result = outCipher.doFinal(outgoing, offset, len);
244: if (Configuration.DEBUG)
245: log.fine("Encoding c (encrypted plaintext): "
246: + Util.dumpString(result));
247: out.write(result);
248: if (outMac != null)
249: {
250: outMac.update(result);
251: if (replayDetection)
252: {
253: outCounter++;
254: if (Configuration.DEBUG)
255: log.fine("outCounter=" + outCounter);
256: outMac.update(new byte[] {
257: (byte)(outCounter >>> 24),
258: (byte)(outCounter >>> 16),
259: (byte)(outCounter >>> 8),
260: (byte) outCounter });
261: }
262: final byte[] C = outMac.doFinal();
263: out.write(C);
264: if (Configuration.DEBUG)
265: log.fine("Encoding C (integrity checksum): " + Util.dumpString(C));
266: }
267:
268: }
269: else
270: {
271: if (Configuration.DEBUG)
272: log.fine("Encoding p (plaintext): "
273: + Util.dumpString(outgoing, offset, len));
274: out.write(outgoing, offset, len);
275: outMac.update(outgoing, offset, len);
276: if (replayDetection)
277: {
278: outCounter++;
279: if (Configuration.DEBUG)
280: log.fine("outCounter=" + outCounter);
281: outMac.update(new byte[] {
282: (byte)(outCounter >>> 24),
283: (byte)(outCounter >>> 16),
284: (byte)(outCounter >>> 8),
285: (byte) outCounter });
286: }
287: final byte[] C = outMac.doFinal();
288: out.write(C);
289: if (Configuration.DEBUG)
290: log.fine("Encoding C (integrity checksum): " + Util.dumpString(C));
291: }
292: result = out.toByteArray();
293: }
294: catch (IOException x)
295: {
296: if (x instanceof SaslException)
297: throw (SaslException) x;
298: throw new SaslException("engineWrap()", x);
299: }
300: if (Configuration.DEBUG)
301: log.exiting(this.getClass().getName(), "engineWrap");
302: return result;
303: }
304:
305: protected String getNegotiatedQOP()
306: {
307: if (inMac != null)
308: {
309: if (inCipher != null)
310: return Registry.QOP_AUTH_CONF;
311: return Registry.QOP_AUTH_INT;
312: }
313: return Registry.QOP_AUTH;
314: }
315:
316: protected String getNegotiatedStrength()
317: {
318: if (inMac != null)
319: {
320: if (inCipher != null)
321: return Registry.STRENGTH_HIGH;
322: return Registry.STRENGTH_MEDIUM;
323: }
324: return Registry.STRENGTH_LOW;
325: }
326:
327: protected String getNegotiatedRawSendSize()
328: {
329: return String.valueOf(rawSendSize);
330: }
331:
332: protected String getReuse()
333: {
334: return Registry.REUSE_TRUE;
335: }
336:
337: private byte[] sendProtocolElements(final byte[] input) throws SaslException
338: {
339: if (Configuration.DEBUG)
340: {
341: log.entering(this.getClass().getName(), "sendProtocolElements");
342: log.fine("C: " + Util.dumpString(input));
343: }
344:
345: final InputBuffer frameIn = new InputBuffer(input);
346: try
347: {
348: U = frameIn.getText();
349: if (Configuration.DEBUG)
350: log.fine("Got U (username): \"" + U + "\"");
351: authorizationID = frameIn.getText();
352: if (Configuration.DEBUG)
353: log.fine("Got I (userid): \"" + authorizationID + "\"");
354: sid = frameIn.getEOS();
355: if (Configuration.DEBUG)
356: log.fine("Got sid (session ID): " + new String(sid));
357: cn = frameIn.getOS();
358: if (Configuration.DEBUG)
359: log.fine("Got cn (client nonce): " + Util.dumpString(cn));
360: cCB = frameIn.getEOS();
361: if (Configuration.DEBUG)
362: log.fine("Got cCB (client channel binding): " + Util.dumpString(cCB));
363: }
364: catch (IOException x)
365: {
366: if (x instanceof SaslException)
367: throw (SaslException) x;
368: throw new AuthenticationException("sendProtocolElements()", x);
369: }
370:
371: if (ServerStore.instance().isAlive(sid))
372: {
373: final SecurityContext ctx = ServerStore.instance().restoreSession(sid);
374: srp = SRP.instance(ctx.getMdName());
375: K = ctx.getK();
376: cIV = ctx.getClientIV();
377: sIV = ctx.getServerIV();
378: replayDetection = ctx.hasReplayDetection();
379: inCounter = ctx.getInCounter();
380: outCounter = ctx.getOutCounter();
381: inMac = ctx.getInMac();
382: outMac = ctx.getOutMac();
383: inCipher = ctx.getInCipher();
384: outCipher = ctx.getOutCipher();
385: if (sn == null || sn.length != 16)
386: sn = new byte[16];
387: getDefaultPRNG().nextBytes(sn);
388: setupSecurityServices(false);
389: final OutputBuffer frameOut = new OutputBuffer();
390: try
391: {
392: frameOut.setScalar(1, 0xFF);
393: frameOut.setOS(sn);
394: frameOut.setEOS(channelBinding);
395: }
396: catch (IOException x)
397: {
398: if (x instanceof SaslException)
399: throw (SaslException) x;
400: throw new AuthenticationException("sendProtocolElements()", x);
401: }
402: final byte[] result = frameOut.encode();
403: if (Configuration.DEBUG)
404: {
405: log.fine("Old session...");
406: log.fine("S: " + Util.dumpString(result));
407: log.fine(" sn = " + Util.dumpString(sn));
408: log.fine(" sCB = " + Util.dumpString(channelBinding));
409: log.exiting(this.getClass().getName(), "sendProtocolElements");
410: }
411: return result;
412: }
413: else
414: {
415: authenticator.activate(properties);
416:
417: final HashMap mapB = new HashMap();
418: mapB.put(SRP6KeyAgreement.HASH_FUNCTION, srp.getAlgorithm());
419: mapB.put(SRP6KeyAgreement.HOST_PASSWORD_DB, authenticator);
420: try
421: {
422: serverHandler.init(mapB);
423: OutgoingMessage out = new OutgoingMessage();
424: out.writeString(U);
425: IncomingMessage in = new IncomingMessage(out.toByteArray());
426: out = serverHandler.processMessage(in);
427: in = new IncomingMessage(out.toByteArray());
428: N = in.readMPI();
429: g = in.readMPI();
430: s = in.readMPI().toByteArray();
431: B = in.readMPI();
432: }
433: catch (KeyAgreementException x)
434: {
435: throw new SaslException("sendProtocolElements()", x);
436: }
437:
438: if (Configuration.DEBUG)
439: {
440: log.fine("Encoding N (modulus): " + Util.dump(N));
441: log.fine("Encoding g (generator): " + Util.dump(g));
442: log.fine("Encoding s (client's salt): " + Util.dumpString(s));
443: log.fine("Encoding B (server ephemeral public key): " + Util.dump(B));
444: }
445:
446:
447:
448: L = createL();
449: if (Configuration.DEBUG)
450: {
451: log.fine("Encoding L (available options): \"" + L + "\"");
452: log.fine("Encoding sIV (server IV): " + Util.dumpString(sIV));
453: }
454: final OutputBuffer frameOut = new OutputBuffer();
455: try
456: {
457: frameOut.setScalar(1, 0x00);
458: frameOut.setMPI(N);
459: frameOut.setMPI(g);
460: frameOut.setOS(s);
461: frameOut.setMPI(B);
462: frameOut.setText(L);
463: }
464: catch (IOException x)
465: {
466: if (x instanceof SaslException)
467: throw (SaslException) x;
468: throw new AuthenticationException("sendProtocolElements()", x);
469: }
470: final byte[] result = frameOut.encode();
471: if (Configuration.DEBUG)
472: {
473: log.fine("New session...");
474: log.fine("S: " + Util.dumpString(result));
475: log.fine(" N = 0x" + N.toString(16));
476: log.fine(" g = 0x" + g.toString(16));
477: log.fine(" s = " + Util.dumpString(s));
478: log.fine(" B = 0x" + B.toString(16));
479: log.fine(" L = " + L);
480: log.exiting(this.getClass().getName(), "sendProtocolElements");
481: }
482: return result;
483: }
484: }
485:
486: private byte[] sendEvidence(final byte[] input) throws SaslException
487: {
488: if (Configuration.DEBUG)
489: {
490: log.entering(this.getClass().getName(), "sendEvidence");
491: log.fine("C: " + Util.dumpString(input));
492: }
493:
494: final InputBuffer frameIn = new InputBuffer(input);
495: final byte[] M1;
496: try
497: {
498: A = frameIn.getMPI();
499: if (Configuration.DEBUG)
500: log.fine("Got A (client ephemeral public key): " + Util.dump(A));
501: M1 = frameIn.getOS();
502: if (Configuration.DEBUG)
503: log.fine("Got M1 (client evidence): " + Util.dumpString(M1));
504: o = frameIn.getText();
505: if (Configuration.DEBUG)
506: log.fine("Got o (client chosen options): \"" + o + "\"");
507: cIV = frameIn.getOS();
508: if (Configuration.DEBUG)
509: log.fine("Got cIV (client IV): " + Util.dumpString(cIV));
510: }
511: catch (IOException x)
512: {
513: if (x instanceof SaslException)
514: throw (SaslException) x;
515: throw new AuthenticationException("sendEvidence()", x);
516: }
517:
518: parseO(o);
519:
520: try
521: {
522: final OutgoingMessage out = new OutgoingMessage();
523: out.writeMPI(A);
524: final IncomingMessage in = new IncomingMessage(out.toByteArray());
525: serverHandler.processMessage(in);
526: K = serverHandler.getSharedSecret();
527: }
528: catch (KeyAgreementException x)
529: {
530: throw new SaslException("sendEvidence()", x);
531: }
532:
533: if (Configuration.DEBUG)
534: log.fine("K: " + Util.dumpString(K));
535: final byte[] expected;
536: try
537: {
538: expected = srp.generateM1(N, g, U, s, A, B, K, authorizationID, L, cn,
539: cCB);
540: }
541: catch (UnsupportedEncodingException x)
542: {
543: throw new AuthenticationException("sendEvidence()", x);
544: }
545:
546: if (! Arrays.equals(M1, expected))
547: throw new AuthenticationException("M1 mismatch");
548: setupSecurityServices(true);
549: final byte[] M2;
550: try
551: {
552: M2 = srp.generateM2(A, M1, K, U, authorizationID, o, sid, ttl, cIV,
553: sIV, channelBinding);
554: }
555: catch (UnsupportedEncodingException x)
556: {
557: throw new AuthenticationException("sendEvidence()", x);
558: }
559: final OutputBuffer frameOut = new OutputBuffer();
560: try
561: {
562: frameOut.setOS(M2);
563: frameOut.setOS(sIV);
564: frameOut.setEOS(sid);
565: frameOut.setScalar(4, ttl);
566: frameOut.setEOS(channelBinding);
567: }
568: catch (IOException x)
569: {
570: if (x instanceof SaslException)
571: throw (SaslException) x;
572: throw new AuthenticationException("sendEvidence()", x);
573: }
574: final byte[] result = frameOut.encode();
575: if (Configuration.DEBUG)
576: {
577: log.fine("S: " + Util.dumpString(result));
578: log.fine(" M2 = " + Util.dumpString(M2));
579: log.fine(" sIV = " + Util.dumpString(sIV));
580: log.fine(" sid = " + new String(sid));
581: log.fine(" ttl = " + ttl);
582: log.fine(" sCB = " + Util.dumpString(channelBinding));
583: log.exiting(this.getClass().getName(), "sendEvidence");
584: }
585: return result;
586: }
587:
588: private String createL()
589: {
590: if (Configuration.DEBUG)
591: log.entering(this.getClass().getName(), "createL()");
592: String s = (String) properties.get(SRPRegistry.SRP_MANDATORY);
593: if (s == null)
594: s = SRPRegistry.DEFAULT_MANDATORY;
595:
596: if (! SRPRegistry.MANDATORY_NONE.equals(s)
597: && ! SRPRegistry.OPTION_REPLAY_DETECTION.equals(s)
598: && ! SRPRegistry.OPTION_INTEGRITY.equals(s)
599: && ! SRPRegistry.OPTION_CONFIDENTIALITY.equals(s))
600: {
601: if (Configuration.DEBUG)
602: log.fine("Unrecognised mandatory option (" + s + "). Using default...");
603: s = SRPRegistry.DEFAULT_MANDATORY;
604: }
605: mandatory = s;
606: s = (String) properties.get(SRPRegistry.SRP_CONFIDENTIALITY);
607: final boolean confidentiality = (s == null ? SRPRegistry.DEFAULT_CONFIDENTIALITY
608: : Boolean.valueOf(s).booleanValue());
609: s = (String) properties.get(SRPRegistry.SRP_INTEGRITY_PROTECTION);
610: boolean integrity = (s == null ? SRPRegistry.DEFAULT_INTEGRITY
611: : Boolean.valueOf(s).booleanValue());
612: s = (String) properties.get(SRPRegistry.SRP_REPLAY_DETECTION);
613: final boolean replayDetection = (s == null ? SRPRegistry.DEFAULT_REPLAY_DETECTION
614: : Boolean.valueOf(s).booleanValue());
615: final StringBuffer sb = new StringBuffer();
616: sb.append(SRPRegistry.OPTION_SRP_DIGEST).append("=")
617: .append(srp.getAlgorithm()).append(",");
618:
619: if (! SRPRegistry.MANDATORY_NONE.equals(mandatory))
620: sb.append(SRPRegistry.OPTION_MANDATORY)
621: .append("=").append(mandatory).append(",");
622:
623: if (replayDetection)
624: {
625: sb.append(SRPRegistry.OPTION_REPLAY_DETECTION).append(",");
626:
627: integrity = true;
628: }
629: int i;
630: if (integrity)
631: {
632: for (i = 0; i < SRPRegistry.INTEGRITY_ALGORITHMS.length; i++)
633: sb.append(SRPRegistry.OPTION_INTEGRITY).append("=")
634: .append(SRPRegistry.INTEGRITY_ALGORITHMS[i]).append(",");
635: }
636: if (confidentiality)
637: {
638: IBlockCipher cipher;
639: for (i = 0; i < SRPRegistry.CONFIDENTIALITY_ALGORITHMS.length; i++)
640: {
641: cipher = CipherFactory.getInstance(SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i]);
642: if (cipher != null)
643: sb.append(SRPRegistry.OPTION_CONFIDENTIALITY).append("=")
644: .append(SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i]).append(",");
645: }
646: }
647: final String result = sb.append(SRPRegistry.OPTION_MAX_BUFFER_SIZE)
648: .append("=").append(Registry.SASL_BUFFER_MAX_LIMIT)
649: .toString();
650: if (Configuration.DEBUG)
651: log.exiting(this.getClass().getName(), "createL");
652: return result;
653: }
654:
655:
656: private void parseO(final String o) throws AuthenticationException
657: {
658: this.replayDetection = false;
659: boolean integrity = false;
660: boolean confidentiality = false;
661: String option;
662: int i;
663:
664: final StringTokenizer st = new StringTokenizer(o.toLowerCase(), ",");
665: while (st.hasMoreTokens())
666: {
667: option = st.nextToken();
668: if (Configuration.DEBUG)
669: log.fine("option: <" + option + ">");
670: if (option.equals(SRPRegistry.OPTION_REPLAY_DETECTION))
671: replayDetection = true;
672: else if (option.startsWith(SRPRegistry.OPTION_INTEGRITY + "="))
673: {
674: if (integrity)
675: throw new AuthenticationException(
676: "Only one integrity algorithm may be chosen");
677: option = option.substring(option.indexOf('=') + 1);
678: if (Configuration.DEBUG)
679: log.fine("algorithm: <" + option + ">");
680: for (i = 0; i < SRPRegistry.INTEGRITY_ALGORITHMS.length; i++)
681: {
682: if (SRPRegistry.INTEGRITY_ALGORITHMS[i].equals(option))
683: {
684: chosenIntegrityAlgorithm = option;
685: integrity = true;
686: break;
687: }
688: }
689: if (! integrity)
690: throw new AuthenticationException("Unknown integrity algorithm: "
691: + option);
692: }
693: else if (option.startsWith(SRPRegistry.OPTION_CONFIDENTIALITY + "="))
694: {
695: if (confidentiality)
696: throw new AuthenticationException(
697: "Only one confidentiality algorithm may be chosen");
698: option = option.substring(option.indexOf('=') + 1);
699: if (Configuration.DEBUG)
700: log.fine("algorithm: <" + option + ">");
701: for (i = 0; i < SRPRegistry.CONFIDENTIALITY_ALGORITHMS.length; i++)
702: {
703: if (SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i].equals(option))
704: {
705: chosenConfidentialityAlgorithm = option;
706: confidentiality = true;
707: break;
708: }
709: }
710: if (! confidentiality)
711: throw new AuthenticationException("Unknown confidentiality algorithm: "
712: + option);
713: }
714: else if (option.startsWith(SRPRegistry.OPTION_MAX_BUFFER_SIZE + "="))
715: {
716: final String maxBufferSize = option.substring(option.indexOf('=') + 1);
717: try
718: {
719: rawSendSize = Integer.parseInt(maxBufferSize);
720: if (rawSendSize > Registry.SASL_BUFFER_MAX_LIMIT
721: || rawSendSize < 1)
722: throw new AuthenticationException(
723: "Illegal value for 'maxbuffersize' option");
724: }
725: catch (NumberFormatException x)
726: {
727: throw new AuthenticationException(
728: SRPRegistry.OPTION_MAX_BUFFER_SIZE + "=" + maxBufferSize, x);
729: }
730: }
731: }
732:
733: if (replayDetection)
734: {
735: if (! integrity)
736: throw new AuthenticationException(
737: "Missing integrity protection algorithm but replay detection is chosen");
738: }
739: if (mandatory.equals(SRPRegistry.OPTION_REPLAY_DETECTION))
740: {
741: if (! replayDetection)
742: throw new AuthenticationException(
743: "Replay detection is mandatory but was not chosen");
744: }
745: if (mandatory.equals(SRPRegistry.OPTION_INTEGRITY))
746: {
747: if (! integrity)
748: throw new AuthenticationException(
749: "Integrity protection is mandatory but was not chosen");
750: }
751: if (mandatory.equals(SRPRegistry.OPTION_CONFIDENTIALITY))
752: {
753: if (! confidentiality)
754: throw new AuthenticationException(
755: "Confidentiality is mandatory but was not chosen");
756: }
757: int blockSize = 0;
758: if (chosenConfidentialityAlgorithm != null)
759: {
760: final IBlockCipher cipher = CipherFactory.getInstance(chosenConfidentialityAlgorithm);
761: if (cipher != null)
762: blockSize = cipher.defaultBlockSize();
763: else
764: throw new AuthenticationException("Confidentiality algorithm ("
765: + chosenConfidentialityAlgorithm
766: + ") not available");
767: }
768: sIV = new byte[blockSize];
769: if (blockSize > 0)
770: getDefaultPRNG().nextBytes(sIV);
771: }
772:
773: private void setupSecurityServices(final boolean newSession)
774: throws SaslException
775: {
776: complete = true;
777: if (newSession)
778: {
779: outCounter = inCounter = 0;
780:
781: if (chosenConfidentialityAlgorithm != null)
782: {
783: if (Configuration.DEBUG)
784: log.fine("Activating confidentiality protection filter");
785: inCipher = CALG.getInstance(chosenConfidentialityAlgorithm);
786: outCipher = CALG.getInstance(chosenConfidentialityAlgorithm);
787: }
788:
789: if (chosenIntegrityAlgorithm != null)
790: {
791: if (Configuration.DEBUG)
792: log.fine("Activating integrity protection filter");
793: inMac = IALG.getInstance(chosenIntegrityAlgorithm);
794: outMac = IALG.getInstance(chosenIntegrityAlgorithm);
795: }
796:
797: sid = (inMac != null ? ServerStore.getNewSessionID() : new byte[0]);
798: }
799: else
800: K = srp.generateKn(K, cn, sn);
801:
802: final KDF kdf = KDF.getInstance(K);
803:
804: if (inCipher != null)
805: {
806: outCipher.init(kdf, sIV, Direction.FORWARD);
807: inCipher.init(kdf, cIV, Direction.REVERSED);
808: }
809:
810: if (inMac != null)
811: {
812: outMac.init(kdf);
813: inMac.init(kdf);
814: }
815: if (sid != null && sid.length != 0)
816: {
817: if (Configuration.DEBUG)
818: log.fine("Updating security context for sid = " + new String(sid));
819: ServerStore.instance().cacheSession(ttl,
820: new SecurityContext(srp.getAlgorithm(),
821: sid,
822: K,
823: cIV,
824: sIV,
825: replayDetection,
826: inCounter,
827: outCounter,
828: inMac, outMac,
829: inCipher,
830: outCipher));
831: }
832: }
833:
834: private PRNG getDefaultPRNG()
835: {
836: if (prng == null)
837: prng = PRNG.getInstance();
838: return prng;
839: }
840: }