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