📄 srpserver.java
字号:
final byte[] expected; try { expected = srp.generateM1(N, g, U, s, A, B, K, authorizationID, L, cn, cCB); } catch (UnsupportedEncodingException x) { throw new AuthenticationException("sendEvidence()", x); } // Verify client evidence if (!Arrays.equals(M1, expected)) { throw new AuthenticationException("M1 mismatch"); } setupSecurityServices(true); final byte[] M2; try { M2 = srp.generateM2(A, M1, K, U, authorizationID, o, sid, ttl, cIV, sIV, channelBinding); } catch (UnsupportedEncodingException x) { throw new AuthenticationException("sendEvidence()", x); } final OutputBuffer frameOut = new OutputBuffer(); try { frameOut.setOS(M2); frameOut.setOS(sIV); frameOut.setEOS(sid); frameOut.setScalar(4, ttl); frameOut.setEOS(channelBinding); } catch (IOException x) { if (x instanceof SaslException) { throw (SaslException) x; } throw new AuthenticationException("sendEvidence()", x); } final byte[] result = frameOut.encode(); if (DEBUG && debuglevel > 2) debug(INFO, "S: " + Util.dumpString(result)); if (DEBUG && debuglevel > 2) debug(INFO, " M2 = " + Util.dumpString(M2)); if (DEBUG && debuglevel > 2) debug(INFO, " sIV = " + Util.dumpString(sIV)); if (DEBUG && debuglevel > 2) debug(INFO, " sid = " + new String(sid)); if (DEBUG && debuglevel > 2) debug(INFO, " ttl = " + ttl); if (DEBUG && debuglevel > 2) debug(INFO, " sCB = " + Util.dumpString(channelBinding)); if (DEBUG && debuglevel > 8) debug(TRACE, "<== sendEvidence()"); return result; } private String createL() { if (DEBUG && debuglevel > 8) debug(TRACE, "==> createL()"); String s = (String) properties.get(SRPRegistry.SRP_MANDATORY); if (s == null) { s = SRPRegistry.DEFAULT_MANDATORY; } if (!SRPRegistry.MANDATORY_NONE.equals(s) && !SRPRegistry.OPTION_REPLAY_DETECTION.equals(s) && !SRPRegistry.OPTION_INTEGRITY.equals(s) && !SRPRegistry.OPTION_CONFIDENTIALITY.equals(s)) { if (DEBUG && debuglevel > 4) debug(WARN, "Unrecognised mandatory option (" + s + "). Using default..."); s = SRPRegistry.DEFAULT_MANDATORY; } mandatory = s; s = (String) properties.get(SRPRegistry.SRP_CONFIDENTIALITY); final boolean confidentiality = (s == null ? SRPRegistry.DEFAULT_CONFIDENTIALITY : Boolean.valueOf(s).booleanValue()); s = (String) properties.get(SRPRegistry.SRP_INTEGRITY_PROTECTION); boolean integrity = (s == null ? SRPRegistry.DEFAULT_INTEGRITY : Boolean.valueOf(s).booleanValue()); s = (String) properties.get(SRPRegistry.SRP_REPLAY_DETECTION); final boolean replayDetection = (s == null ? SRPRegistry.DEFAULT_REPLAY_DETECTION : Boolean.valueOf(s).booleanValue()); final StringBuffer sb = new StringBuffer(); sb.append(SRPRegistry.OPTION_SRP_DIGEST).append("=").append( srp.getAlgorithm()).append( ","); if (!SRPRegistry.MANDATORY_NONE.equals(mandatory)) { sb.append(SRPRegistry.OPTION_MANDATORY).append("=").append(mandatory).append( ","); } if (replayDetection) { sb.append(SRPRegistry.OPTION_REPLAY_DETECTION).append(","); // if replay detection is on then force integrity protection integrity = true; } int i; if (integrity) { for (i = 0; i < SRPRegistry.INTEGRITY_ALGORITHMS.length; i++) { sb.append(SRPRegistry.OPTION_INTEGRITY).append("=").append( SRPRegistry.INTEGRITY_ALGORITHMS[i]).append( ","); } } if (confidentiality) { IBlockCipher cipher; for (i = 0; i < SRPRegistry.CONFIDENTIALITY_ALGORITHMS.length; i++) { cipher = CipherFactory.getInstance(SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i]); if (cipher != null) { sb.append(SRPRegistry.OPTION_CONFIDENTIALITY).append("=").append( SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i]).append( ","); } } } final String result = sb.append(SRPRegistry.OPTION_MAX_BUFFER_SIZE).append( "=").append( Registry.SASL_BUFFER_MAX_LIMIT).toString(); if (DEBUG && debuglevel > 8) debug(TRACE, "<== createL()"); return result; } // Parse client's options and set security layer variables private void parseO(final String o) throws AuthenticationException { this.replayDetection = false; boolean integrity = false; boolean confidentiality = false; String option; int i; final StringTokenizer st = new StringTokenizer(o.toLowerCase(), ","); while (st.hasMoreTokens()) { option = st.nextToken(); if (DEBUG && debuglevel > 6) debug(TRACE, "option: <" + option + ">"); if (option.equals(SRPRegistry.OPTION_REPLAY_DETECTION)) { replayDetection = true; } else if (option.startsWith(SRPRegistry.OPTION_INTEGRITY + "=")) { if (integrity) { throw new AuthenticationException( "Only one integrity algorithm may be chosen"); } else { option = option.substring(option.indexOf('=') + 1); if (DEBUG && debuglevel > 6) debug(TRACE, "algorithm: <" + option + ">"); for (i = 0; i < SRPRegistry.INTEGRITY_ALGORITHMS.length; i++) { if (SRPRegistry.INTEGRITY_ALGORITHMS[i].equals(option)) { chosenIntegrityAlgorithm = option; integrity = true; break; } } if (!integrity) { throw new AuthenticationException( "Unknown integrity algorithm: " + option); } } } else if (option.startsWith(SRPRegistry.OPTION_CONFIDENTIALITY + "=")) { if (confidentiality) { throw new AuthenticationException( "Only one confidentiality algorithm may be chosen"); } else { option = option.substring(option.indexOf('=') + 1); if (DEBUG && debuglevel > 6) debug(TRACE, "algorithm: <" + option + ">"); for (i = 0; i < SRPRegistry.CONFIDENTIALITY_ALGORITHMS.length; i++) { if (SRPRegistry.CONFIDENTIALITY_ALGORITHMS[i].equals(option)) { chosenConfidentialityAlgorithm = option; confidentiality = true; break; } } if (!confidentiality) { throw new AuthenticationException( "Unknown confidentiality algorithm: " + option); } } } else if (option.startsWith(SRPRegistry.OPTION_MAX_BUFFER_SIZE + "=")) { final String maxBufferSize = option.substring(option.indexOf('=') + 1); try { rawSendSize = Integer.parseInt(maxBufferSize); if (rawSendSize > Registry.SASL_BUFFER_MAX_LIMIT || rawSendSize < 1) throw new AuthenticationException( "Illegal value for 'maxbuffersize' option"); } catch (NumberFormatException x) { throw new AuthenticationException( SRPRegistry.OPTION_MAX_BUFFER_SIZE + "=" + String.valueOf(maxBufferSize), x); } } } // check if client did the right thing if (replayDetection) { if (!integrity) { throw new AuthenticationException( "Missing integrity protection algorithm " + "but replay detection is chosen"); } } if (mandatory.equals(SRPRegistry.OPTION_REPLAY_DETECTION)) { if (!replayDetection) { throw new AuthenticationException( "Replay detection is mandatory but was not chosen"); } } if (mandatory.equals(SRPRegistry.OPTION_INTEGRITY)) { if (!integrity) { throw new AuthenticationException( "Integrity protection is mandatory but was not chosen"); } } if (mandatory.equals(SRPRegistry.OPTION_CONFIDENTIALITY)) { if (!confidentiality) { throw new AuthenticationException( "Confidentiality is mandatory but was not chosen"); } } int blockSize = 0; if (chosenConfidentialityAlgorithm != null) { final IBlockCipher cipher = CipherFactory.getInstance(chosenConfidentialityAlgorithm); if (cipher != null) { blockSize = cipher.defaultBlockSize(); } else { // should not happen throw new AuthenticationException("Confidentiality algorithm (" + chosenConfidentialityAlgorithm + ") not available"); } } sIV = new byte[blockSize]; if (blockSize > 0) getDefaultPRNG().nextBytes(sIV); } private void setupSecurityServices(final boolean newSession) throws SaslException { complete = true; // signal end of authentication phase if (newSession) { outCounter = inCounter = 0; // instantiate cipher if confidentiality protection filter is active if (chosenConfidentialityAlgorithm != null) { if (DEBUG && debuglevel > 2) debug(INFO, "Activating confidentiality protection filter"); inCipher = CALG.getInstance(chosenConfidentialityAlgorithm); outCipher = CALG.getInstance(chosenConfidentialityAlgorithm); } // instantiate hmacs if integrity protection filter is active if (chosenIntegrityAlgorithm != null) { if (DEBUG && debuglevel > 2) debug(INFO, "Activating integrity protection filter"); inMac = IALG.getInstance(chosenIntegrityAlgorithm); outMac = IALG.getInstance(chosenIntegrityAlgorithm); } // generate a new sid if at least integrity is used sid = (inMac != null ? ServerStore.getNewSessionID() : new byte[0]); } else { // same session new keys K = srp.generateKn(K, cn, sn); } final KDF kdf = KDF.getInstance(K); // initialise in/out ciphers if confidentaility protection is used if (inCipher != null) { outCipher.init(kdf, sIV, Direction.FORWARD); inCipher.init(kdf, cIV, Direction.REVERSED); } // initialise in/out macs if integrity protection is used if (inMac != null) { outMac.init(kdf); inMac.init(kdf); } if (sid != null && sid.length != 0) { // update the security context and save in map if (DEBUG && debuglevel > 2) debug(INFO, "Updating security context for sid = " + new String(sid)); ServerStore.instance().cacheSession( ttl, new SecurityContext( srp.getAlgorithm(), sid, K, cIV, sIV, replayDetection, inCounter, outCounter, inMac, outMac, inCipher, outCipher)); } } private PRNG getDefaultPRNG() { if (prng == null) prng = PRNG.getInstance(); return prng; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -