2 Copyright (C) 2003, 2006 Free Software Foundation, Inc.
4 This file is a part of GNU Classpath.
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.
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.
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
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
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. */
39 package gnu.javax.crypto.sasl.srp;
41 import gnu.java.lang.CPStringBuilder;
43 import gnu.java.security.Configuration;
44 import gnu.java.security.Registry;
45 import gnu.java.security.util.PRNG;
46 import gnu.java.security.util.Util;
47 import gnu.javax.crypto.assembly.Direction;
48 import gnu.javax.crypto.cipher.CipherFactory;
49 import gnu.javax.crypto.cipher.IBlockCipher;
50 import gnu.javax.crypto.key.IKeyAgreementParty;
51 import gnu.javax.crypto.key.IncomingMessage;
52 import gnu.javax.crypto.key.KeyAgreementException;
53 import gnu.javax.crypto.key.KeyAgreementFactory;
54 import gnu.javax.crypto.key.OutgoingMessage;
55 import gnu.javax.crypto.key.srp6.SRP6KeyAgreement;
56 import gnu.javax.crypto.sasl.IllegalMechanismStateException;
57 import gnu.javax.crypto.sasl.InputBuffer;
58 import gnu.javax.crypto.sasl.IntegrityException;
59 import gnu.javax.crypto.sasl.OutputBuffer;
60 import gnu.javax.crypto.sasl.ServerMechanism;
62 import java.io.ByteArrayOutputStream;
63 import java.io.IOException;
64 import java.io.UnsupportedEncodingException;
65 import java.math.BigInteger;
66 import java.util.Arrays;
67 import java.util.HashMap;
68 import java.util.StringTokenizer;
69 import java.util.logging.Logger;
71 import javax.security.sasl.AuthenticationException;
72 import javax.security.sasl.SaslException;
73 import javax.security.sasl.SaslServer;
76 * The SASL-SRP server-side mechanism.
78 public class SRPServer
79 extends ServerMechanism
82 private static final Logger log = Logger.getLogger(SRPServer.class.getName());
83 private String U = null; // client's username
84 private BigInteger N, g, A, B;
85 private byte[] s; // salt
86 private byte[] cIV, sIV; // client+server IVs, when confidentiality is on
87 private byte[] cn, sn; // client's and server's nonce
88 private SRP srp; // SRP algorithm instance used by this server
89 private byte[] sid; // session ID when re-used
90 private int ttl = 360; // session time-to-live in seconds
91 private byte[] cCB; // peer's channel binding'
92 private String mandatory; // List of available options
93 private String L = null;
95 private String chosenIntegrityAlgorithm;
96 private String chosenConfidentialityAlgorithm;
97 private int rawSendSize = Registry.SASL_BUFFER_MAX_LIMIT;
98 private byte[] K; // shared session key
99 private boolean replayDetection = true; // whether Replay Detection is on
100 private int inCounter = 0; // messages sequence numbers
101 private int outCounter = 0;
102 private IALG inMac, outMac; // if !null, use for integrity
103 private CALG inCipher, outCipher; // if !null, use for confidentiality
104 private IKeyAgreementParty serverHandler =
105 KeyAgreementFactory.getPartyBInstance(Registry.SRP_SASL_KA);
106 /** Our default source of randomness. */
107 private PRNG prng = null;
111 super(Registry.SASL_SRP_MECHANISM);
114 protected void initMechanism() throws SaslException
117 // we must have a means to map a given username to a preferred
118 // SRP hash algorithm; otherwise we end up using _always_ SHA.
119 // for the time being get it from the mechanism properties map
120 // and apply it for all users.
121 final String mda = (String) properties.get(SRPRegistry.SRP_HASH);
122 srp = SRP.instance(mda == null ? SRPRegistry.SRP_DEFAULT_DIGEST_NAME : mda);
125 protected void resetMechanism() throws SaslException
130 inMac = outMac = null;
131 inCipher = outCipher = null;
135 public byte[] evaluateResponse(final byte[] response) throws SaslException
140 if (response == null)
143 return sendProtocolElements(response);
148 return sendEvidence(response);
152 throw new IllegalMechanismStateException("evaluateResponse()");
156 protected byte[] engineUnwrap(final byte[] incoming, final int offset,
157 final int len) throws SaslException
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 // at this point one, or both, of confidentiality and integrity protection
167 // services are active.
172 { // integrity bytes are at the end of the stream
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,
178 if (Configuration.DEBUG)
179 log.fine("Got C (received MAC): " + Util.dumpString(received_mac));
180 inMac.update(incoming, offset, payloadLength);
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),
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 // deal with the payload, which can be either plain or encrypted
198 if (inCipher != null)
199 result = inCipher.doFinal(incoming, offset, payloadLength);
202 result = new byte[payloadLength];
203 System.arraycopy(incoming, offset, result, 0, result.length);
206 else // no integrity protection; just confidentiality
207 result = inCipher.doFinal(incoming, offset, len);
209 catch (IOException x)
211 if (x instanceof SaslException)
212 throw (SaslException) x;
213 throw new SaslException("engineUnwrap()", x);
215 if (Configuration.DEBUG)
217 log.fine("Incoming buffer (after security): " + Util.dumpString(result));
218 log.exiting(this.getClass().getName(), "engineUnwrap");
223 protected byte[] engineWrap(final byte[] outgoing, final int offset,
224 final int len) throws SaslException
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)
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) + "\"");
237 // at this point one, or both, of confidentiality and integrity protection
238 // services are active.
242 final ByteArrayOutputStream out = new ByteArrayOutputStream();
243 if (outCipher != null)
245 result = outCipher.doFinal(outgoing, offset, len);
246 if (Configuration.DEBUG)
247 log.fine("Encoding c (encrypted plaintext): "
248 + Util.dumpString(result));
252 outMac.update(result);
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 });
264 final byte[] C = outMac.doFinal();
266 if (Configuration.DEBUG)
267 log.fine("Encoding C (integrity checksum): " + Util.dumpString(C));
269 // else ciphertext only; do nothing
271 else // no confidentiality; just integrity [+ replay detection]
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);
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 });
289 final byte[] C = outMac.doFinal();
291 if (Configuration.DEBUG)
292 log.fine("Encoding C (integrity checksum): " + Util.dumpString(C));
294 result = out.toByteArray();
296 catch (IOException x)
298 if (x instanceof SaslException)
299 throw (SaslException) x;
300 throw new SaslException("engineWrap()", x);
302 if (Configuration.DEBUG)
303 log.exiting(this.getClass().getName(), "engineWrap");
307 protected String getNegotiatedQOP()
311 if (inCipher != null)
312 return Registry.QOP_AUTH_CONF;
313 return Registry.QOP_AUTH_INT;
315 return Registry.QOP_AUTH;
318 protected String getNegotiatedStrength()
322 if (inCipher != null)
323 return Registry.STRENGTH_HIGH;
324 return Registry.STRENGTH_MEDIUM;
326 return Registry.STRENGTH_LOW;
329 protected String getNegotiatedRawSendSize()
331 return String.valueOf(rawSendSize);
334 protected String getReuse()
336 return Registry.REUSE_TRUE;
339 private byte[] sendProtocolElements(final byte[] input) throws SaslException
341 if (Configuration.DEBUG)
343 log.entering(this.getClass().getName(), "sendProtocolElements");
344 log.fine("C: " + Util.dumpString(input));
346 // Client send U, I, sid, cn
347 final InputBuffer frameIn = new InputBuffer(input);
350 U = frameIn.getText(); // Extract username
351 if (Configuration.DEBUG)
352 log.fine("Got U (username): \"" + U + "\"");
353 authorizationID = frameIn.getText(); // Extract authorisation ID
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));
366 catch (IOException x)
368 if (x instanceof SaslException)
369 throw (SaslException) x;
370 throw new AuthenticationException("sendProtocolElements()", x);
373 if (ServerStore.instance().isAlive(sid))
375 final SecurityContext ctx = ServerStore.instance().restoreSession(sid);
376 srp = SRP.instance(ctx.getMdName());
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)
389 getDefaultPRNG().nextBytes(sn);
390 setupSecurityServices(false);
391 final OutputBuffer frameOut = new OutputBuffer();
394 frameOut.setScalar(1, 0xFF);
396 frameOut.setEOS(channelBinding);
398 catch (IOException x)
400 if (x instanceof SaslException)
401 throw (SaslException) x;
402 throw new AuthenticationException("sendProtocolElements()", x);
404 final byte[] result = frameOut.encode();
405 if (Configuration.DEBUG)
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");
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);
424 serverHandler.init(mapB);
425 OutgoingMessage out = new OutgoingMessage();
427 IncomingMessage in = new IncomingMessage(out.toByteArray());
428 out = serverHandler.processMessage(in);
429 in = new IncomingMessage(out.toByteArray());
432 s = in.readMPI().toByteArray();
435 catch (KeyAgreementException x)
437 throw new SaslException("sendProtocolElements()", x);
439 // -------------------------------------------------------------------
440 if (Configuration.DEBUG)
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));
447 // The server creates an options list (L), which consists of a
448 // comma-separated list of option strings that specify the security
449 // service options the server supports.
451 if (Configuration.DEBUG)
453 log.fine("Encoding L (available options): \"" + L + "\"");
454 log.fine("Encoding sIV (server IV): " + Util.dumpString(sIV));
456 final OutputBuffer frameOut = new OutputBuffer();
459 frameOut.setScalar(1, 0x00);
466 catch (IOException x)
468 if (x instanceof SaslException)
469 throw (SaslException) x;
470 throw new AuthenticationException("sendProtocolElements()", x);
472 final byte[] result = frameOut.encode();
473 if (Configuration.DEBUG)
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");
488 private byte[] sendEvidence(final byte[] input) throws SaslException
490 if (Configuration.DEBUG)
492 log.entering(this.getClass().getName(), "sendEvidence");
493 log.fine("C: " + Util.dumpString(input));
495 // Client send A, M1, o, cIV
496 final InputBuffer frameIn = new InputBuffer(input);
500 A = frameIn.getMPI(); // Extract client's ephemeral public key
501 if (Configuration.DEBUG)
502 log.fine("Got A (client ephemeral public key): " + Util.dump(A));
503 M1 = frameIn.getOS(); // Extract evidence
504 if (Configuration.DEBUG)
505 log.fine("Got M1 (client evidence): " + Util.dumpString(M1));
506 o = frameIn.getText(); // Extract client's options list
507 if (Configuration.DEBUG)
508 log.fine("Got o (client chosen options): \"" + o + "\"");
509 cIV = frameIn.getOS(); // Extract client's IV
510 if (Configuration.DEBUG)
511 log.fine("Got cIV (client IV): " + Util.dumpString(cIV));
513 catch (IOException x)
515 if (x instanceof SaslException)
516 throw (SaslException) x;
517 throw new AuthenticationException("sendEvidence()", x);
519 // Parse client's options and set security layer variables
521 // ----------------------------------------------------------------------
524 final OutgoingMessage out = new OutgoingMessage();
526 final IncomingMessage in = new IncomingMessage(out.toByteArray());
527 serverHandler.processMessage(in);
528 K = serverHandler.getSharedSecret();
530 catch (KeyAgreementException x)
532 throw new SaslException("sendEvidence()", x);
534 // ----------------------------------------------------------------------
535 if (Configuration.DEBUG)
536 log.fine("K: " + Util.dumpString(K));
537 final byte[] expected;
540 expected = srp.generateM1(N, g, U, s, A, B, K, authorizationID, L, cn,
543 catch (UnsupportedEncodingException x)
545 throw new AuthenticationException("sendEvidence()", x);
547 // Verify client evidence
548 if (! Arrays.equals(M1, expected))
549 throw new AuthenticationException("M1 mismatch");
550 setupSecurityServices(true);
554 M2 = srp.generateM2(A, M1, K, U, authorizationID, o, sid, ttl, cIV,
555 sIV, channelBinding);
557 catch (UnsupportedEncodingException x)
559 throw new AuthenticationException("sendEvidence()", x);
561 final OutputBuffer frameOut = new OutputBuffer();
566 frameOut.setEOS(sid);
567 frameOut.setScalar(4, ttl);
568 frameOut.setEOS(channelBinding);
570 catch (IOException x)
572 if (x instanceof SaslException)
573 throw (SaslException) x;
574 throw new AuthenticationException("sendEvidence()", x);
576 final byte[] result = frameOut.encode();
577 if (Configuration.DEBUG)
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");
590 private String createL()
592 if (Configuration.DEBUG)
593 log.entering(this.getClass().getName(), "createL()");
594 String s = (String) properties.get(SRPRegistry.SRP_MANDATORY);
596 s = SRPRegistry.DEFAULT_MANDATORY;
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))
603 if (Configuration.DEBUG)
604 log.fine("Unrecognised mandatory option (" + s + "). Using default...");
605 s = SRPRegistry.DEFAULT_MANDATORY;
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(",");
621 if (! SRPRegistry.MANDATORY_NONE.equals(mandatory))
622 sb.append(SRPRegistry.OPTION_MANDATORY)
623 .append("=").append(mandatory).append(",");
627 sb.append(SRPRegistry.OPTION_REPLAY_DETECTION).append(",");
628 // if replay detection is on then force integrity protection
634 for (i = 0; i < SRPRegistry.INTEGRITY_ALGORITHMS.length; i++)
635 sb.append(SRPRegistry.OPTION_INTEGRITY).append("=")
636 .append(SRPRegistry.INTEGRITY_ALGORITHMS[i]).append(",");
641 for (i = 0; i < SRPRegistry.CONFIDENTIALITY_ALGORITHMS.length; i++)
643 cipher = CipherFactory.getInstance(SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i]);
645 sb.append(SRPRegistry.OPTION_CONFIDENTIALITY).append("=")
646 .append(SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i]).append(",");
649 final String result = sb.append(SRPRegistry.OPTION_MAX_BUFFER_SIZE)
650 .append("=").append(Registry.SASL_BUFFER_MAX_LIMIT)
652 if (Configuration.DEBUG)
653 log.exiting(this.getClass().getName(), "createL");
657 // Parse client's options and set security layer variables
658 private void parseO(final String o) throws AuthenticationException
660 this.replayDetection = false;
661 boolean integrity = false;
662 boolean confidentiality = false;
666 final StringTokenizer st = new StringTokenizer(o.toLowerCase(), ",");
667 while (st.hasMoreTokens())
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 + "="))
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++)
684 if (SRPRegistry.INTEGRITY_ALGORITHMS[i].equals(option))
686 chosenIntegrityAlgorithm = option;
692 throw new AuthenticationException("Unknown integrity algorithm: "
695 else if (option.startsWith(SRPRegistry.OPTION_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++)
705 if (SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i].equals(option))
707 chosenConfidentialityAlgorithm = option;
708 confidentiality = true;
712 if (! confidentiality)
713 throw new AuthenticationException("Unknown confidentiality algorithm: "
716 else if (option.startsWith(SRPRegistry.OPTION_MAX_BUFFER_SIZE + "="))
718 final String maxBufferSize = option.substring(option.indexOf('=') + 1);
721 rawSendSize = Integer.parseInt(maxBufferSize);
722 if (rawSendSize > Registry.SASL_BUFFER_MAX_LIMIT
724 throw new AuthenticationException(
725 "Illegal value for 'maxbuffersize' option");
727 catch (NumberFormatException x)
729 throw new AuthenticationException(
730 SRPRegistry.OPTION_MAX_BUFFER_SIZE + "=" + maxBufferSize, x);
734 // check if client did the right thing
738 throw new AuthenticationException(
739 "Missing integrity protection algorithm but replay detection is chosen");
741 if (mandatory.equals(SRPRegistry.OPTION_REPLAY_DETECTION))
743 if (! replayDetection)
744 throw new AuthenticationException(
745 "Replay detection is mandatory but was not chosen");
747 if (mandatory.equals(SRPRegistry.OPTION_INTEGRITY))
750 throw new AuthenticationException(
751 "Integrity protection is mandatory but was not chosen");
753 if (mandatory.equals(SRPRegistry.OPTION_CONFIDENTIALITY))
755 if (! confidentiality)
756 throw new AuthenticationException(
757 "Confidentiality is mandatory but was not chosen");
760 if (chosenConfidentialityAlgorithm != null)
762 final IBlockCipher cipher = CipherFactory.getInstance(chosenConfidentialityAlgorithm);
764 blockSize = cipher.defaultBlockSize();
765 else // should not happen
766 throw new AuthenticationException("Confidentiality algorithm ("
767 + chosenConfidentialityAlgorithm
768 + ") not available");
770 sIV = new byte[blockSize];
772 getDefaultPRNG().nextBytes(sIV);
775 private void setupSecurityServices(final boolean newSession)
778 complete = true; // signal end of authentication phase
781 outCounter = inCounter = 0;
782 // instantiate cipher if confidentiality protection filter is active
783 if (chosenConfidentialityAlgorithm != null)
785 if (Configuration.DEBUG)
786 log.fine("Activating confidentiality protection filter");
787 inCipher = CALG.getInstance(chosenConfidentialityAlgorithm);
788 outCipher = CALG.getInstance(chosenConfidentialityAlgorithm);
790 // instantiate hmacs if integrity protection filter is active
791 if (chosenIntegrityAlgorithm != null)
793 if (Configuration.DEBUG)
794 log.fine("Activating integrity protection filter");
795 inMac = IALG.getInstance(chosenIntegrityAlgorithm);
796 outMac = IALG.getInstance(chosenIntegrityAlgorithm);
798 // generate a new sid if at least integrity is used
799 sid = (inMac != null ? ServerStore.getNewSessionID() : new byte[0]);
801 else // same session new keys
802 K = srp.generateKn(K, cn, sn);
804 final KDF kdf = KDF.getInstance(K);
805 // initialise in/out ciphers if confidentaility protection is used
806 if (inCipher != null)
808 outCipher.init(kdf, sIV, Direction.FORWARD);
809 inCipher.init(kdf, cIV, Direction.REVERSED);
811 // initialise in/out macs if integrity protection is used
817 if (sid != null && sid.length != 0)
818 { // update the security context and save in map
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(),
836 private PRNG getDefaultPRNG()
839 prng = PRNG.getInstance();