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