Categories:
Audio (13)
Biotech (29)
Bytecode (36)
Database (77)
Framework (7)
Game (7)
General (507)
Graphics (53)
I/O (35)
IDE (2)
JAR Tools (101)
JavaBeans (21)
JDBC (121)
JDK (426)
JSP (20)
Logging (108)
Mail (58)
Messaging (8)
Network (84)
PDF (97)
Report (7)
Scripting (84)
Security (32)
Server (121)
Servlet (26)
SOAP (24)
Testing (54)
Web (15)
XML (309)
Collections:
Other Resources:
JDK 11 java.security.sasl.jmod - Security SASL Module
JDK 11 java.security.sasl.jmod is the JMOD file for JDK 11 Security SASL (Simple Authentication and Security Layer) module.
JDK 11 Security SASL module compiled class files are stored in \fyicenter\jdk-11.0.1\jmods\java.security.sasl.jmod.
JDK 11 Security SASL module compiled class files are also linked and stored in the \fyicenter\jdk-11.0.1\lib\modules JImage file.
JDK 11 Security SASL module source code files are stored in \fyicenter\jdk-11.0.1\lib\src.zip\java.security.sasl.
You can click and view the content of each source code file in the list below.
✍: FYIcenter
⏎ com/sun/security/sasl/digest/DigestMD5Server.java
/* * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package com.sun.security.sasl.digest; import java.security.NoSuchAlgorithmException; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.StringTokenizer; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Arrays; import java.util.logging.Level; import javax.security.sasl.*; import javax.security.auth.callback.*; /** * An implementation of the DIGEST-MD5 server SASL mechanism. * (<a href="http://www.ietf.org/rfc/rfc2831.txt">RFC 2831</a>) * <p> * The DIGEST-MD5 SASL mechanism specifies two modes of authentication. * <ul><li>Initial Authentication * <li>Subsequent Authentication - optional, (currently not supported) * </ul> * * Required callbacks: * - RealmCallback * used as key by handler to fetch password * - NameCallback * used as key by handler to fetch password * - PasswordCallback * handler must enter password for username/realm supplied * - AuthorizeCallback * handler must verify that authid/authzids are allowed and set * authorized ID to be the canonicalized authzid (if applicable). * * Environment properties that affect the implementation: * javax.security.sasl.qop: * specifies list of qops; default is "auth"; typically, caller should set * this to "auth, auth-int, auth-conf". * javax.security.sasl.strength * specifies low/medium/high strength of encryption; default is all available * ciphers [high,medium,low]; high means des3 or rc4 (128); medium des or * rc4-56; low is rc4-40. * javax.security.sasl.maxbuf * specifies max receive buf size; default is 65536 * javax.security.sasl.sendmaxbuffer * specifies max send buf size; default is 65536 (min of this and client's max * recv size) * * com.sun.security.sasl.digest.utf8: * "true" means to use UTF-8 charset; "false" to use ISO-8859-1 encoding; * default is "true". * com.sun.security.sasl.digest.realm: * space-separated list of realms; default is server name (fqdn parameter) * * @author Rosanna Lee */ final class DigestMD5Server extends DigestMD5Base implements SaslServer { private static final String MY_CLASS_NAME = DigestMD5Server.class.getName(); private static final String UTF8_DIRECTIVE = "charset=utf-8,"; private static final String ALGORITHM_DIRECTIVE = "algorithm=md5-sess"; /* * Always expect nonce count value to be 1 because we support only * initial authentication. */ private static final int NONCE_COUNT_VALUE = 1; /* "true" means use UTF8; "false" ISO 8859-1; default is "true" */ private static final String UTF8_PROPERTY = "com.sun.security.sasl.digest.utf8"; /* List of space-separated realms used for authentication */ private static final String REALM_PROPERTY = "com.sun.security.sasl.digest.realm"; /* Directives encountered in responses sent by the client. */ private static final String[] DIRECTIVE_KEY = { "username", // exactly once "realm", // exactly once if sent by server "nonce", // exactly once "cnonce", // exactly once "nonce-count", // atmost once; default is 00000001 "qop", // atmost once; default is "auth" "digest-uri", // atmost once; (default?) "response", // exactly once "maxbuf", // atmost once; default is 65536 "charset", // atmost once; default is ISO-8859-1 "cipher", // exactly once if qop is "auth-conf" "authzid", // atmost once; default is none "auth-param", // >= 0 times (ignored) }; /* Indices into DIRECTIVE_KEY */ private static final int USERNAME = 0; private static final int REALM = 1; private static final int NONCE = 2; private static final int CNONCE = 3; private static final int NONCE_COUNT = 4; private static final int QOP = 5; private static final int DIGEST_URI = 6; private static final int RESPONSE = 7; private static final int MAXBUF = 8; private static final int CHARSET = 9; private static final int CIPHER = 10; private static final int AUTHZID = 11; private static final int AUTH_PARAM = 12; /* Server-generated/supplied information */ private String specifiedQops; private byte[] myCiphers; private List<String> serverRealms; DigestMD5Server(String protocol, String serverName, Map<String, ?> props, CallbackHandler cbh) throws SaslException { super(props, MY_CLASS_NAME, 1, protocol + "/" + (serverName==null?"*":serverName), cbh); serverRealms = new ArrayList<String>(); useUTF8 = true; // default if (props != null) { specifiedQops = (String) props.get(Sasl.QOP); if ("false".equals((String) props.get(UTF8_PROPERTY))) { useUTF8 = false; logger.log(Level.FINE, "DIGEST80:Server supports ISO-Latin-1"); } String realms = (String) props.get(REALM_PROPERTY); if (realms != null) { StringTokenizer parser = new StringTokenizer(realms, ", \t\n"); int tokenCount = parser.countTokens(); String token = null; for (int i = 0; i < tokenCount; i++) { token = parser.nextToken(); logger.log(Level.FINE, "DIGEST81:Server supports realm {0}", token); serverRealms.add(token); } } } encoding = (useUTF8 ? "UTF8" : "8859_1"); // By default, use server name as realm if (serverRealms.isEmpty()) { if (serverName == null) { throw new SaslException( "A realm must be provided in props or serverName"); } else { serverRealms.add(serverName); } } } public byte[] evaluateResponse(byte[] response) throws SaslException { if (response.length > MAX_RESPONSE_LENGTH) { throw new SaslException( "DIGEST-MD5: Invalid digest response length. Got: " + response.length + " Expected < " + MAX_RESPONSE_LENGTH); } byte[] challenge; switch (step) { case 1: if (response.length != 0) { throw new SaslException( "DIGEST-MD5 must not have an initial response"); } /* Generate first challenge */ String supportedCiphers = null; if ((allQop&PRIVACY_PROTECTION) != 0) { myCiphers = getPlatformCiphers(); StringBuilder sb = new StringBuilder(); // myCipher[i] is a byte that indicates whether CIPHER_TOKENS[i] // is supported for (int i = 0; i < CIPHER_TOKENS.length; i++) { if (myCiphers[i] != 0) { if (sb.length() > 0) { sb.append(','); } sb.append(CIPHER_TOKENS[i]); } } supportedCiphers = sb.toString(); } try { challenge = generateChallenge(serverRealms, specifiedQops, supportedCiphers); step = 3; return challenge; } catch (UnsupportedEncodingException e) { throw new SaslException( "DIGEST-MD5: Error encoding challenge", e); } catch (IOException e) { throw new SaslException( "DIGEST-MD5: Error generating challenge", e); } // Step 2 is performed by client case 3: /* Validates client's response and generate challenge: * response-auth = "rspauth" "=" response-value */ try { byte[][] responseVal = parseDirectives(response, DIRECTIVE_KEY, null, REALM); challenge = validateClientResponse(responseVal); } catch (SaslException e) { throw e; } catch (UnsupportedEncodingException e) { throw new SaslException( "DIGEST-MD5: Error validating client response", e); } finally { step = 0; // Set to invalid state } completed = true; /* Initialize SecurityCtx implementation */ if (integrity && privacy) { secCtx = new DigestPrivacy(false /* not client */); } else if (integrity) { secCtx = new DigestIntegrity(false /* not client */); } return challenge; default: // No other possible state throw new SaslException("DIGEST-MD5: Server at illegal state"); } } /** * Generates challenge to be sent to client. * digest-challenge = * 1#( realm | nonce | qop-options | stale | maxbuf | charset * algorithm | cipher-opts | auth-param ) * * realm = "realm" "=" <"> realm-value <"> * realm-value = qdstr-val * nonce = "nonce" "=" <"> nonce-value <"> * nonce-value = qdstr-val * qop-options = "qop" "=" <"> qop-list <"> * qop-list = 1#qop-value * qop-value = "auth" | "auth-int" | "auth-conf" | * token * stale = "stale" "=" "true" * maxbuf = "maxbuf" "=" maxbuf-value * maxbuf-value = 1*DIGIT * charset = "charset" "=" "utf-8" * algorithm = "algorithm" "=" "md5-sess" * cipher-opts = "cipher" "=" <"> 1#cipher-value <"> * cipher-value = "3des" | "des" | "rc4-40" | "rc4" | * "rc4-56" | token * auth-param = token "=" ( token | quoted-string ) */ private byte[] generateChallenge(List<String> realms, String qopStr, String cipherStr) throws UnsupportedEncodingException, IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); // Realms (>= 0) for (int i = 0; realms != null && i < realms.size(); i++) { out.write("realm=\"".getBytes(encoding)); writeQuotedStringValue(out, realms.get(i).getBytes(encoding)); out.write('"'); out.write(','); } // Nonce - required (1) out.write(("nonce=\"").getBytes(encoding)); nonce = generateNonce(); writeQuotedStringValue(out, nonce); out.write('"'); out.write(','); // QOP - optional (1) [default: auth] // qop="auth,auth-conf,auth-int" if (qopStr != null) { out.write(("qop=\"").getBytes(encoding)); // Check for quotes in case of non-standard qop options writeQuotedStringValue(out, qopStr.getBytes(encoding)); out.write('"'); out.write(','); } // maxbuf - optional (1) [default: 65536] if (recvMaxBufSize != DEFAULT_MAXBUF) { out.write(("maxbuf=\"" + recvMaxBufSize + "\",").getBytes(encoding)); } // charset - optional (1) [default: ISO 8859_1] if (useUTF8) { out.write(UTF8_DIRECTIVE.getBytes(encoding)); } if (cipherStr != null) { out.write("cipher=\"".getBytes(encoding)); // Check for quotes in case of custom ciphers writeQuotedStringValue(out, cipherStr.getBytes(encoding)); out.write('"'); out.write(','); } // algorithm - required (1) out.write(ALGORITHM_DIRECTIVE.getBytes(encoding)); return out.toByteArray(); } /** * Validates client's response. * digest-response = 1#( username | realm | nonce | cnonce | * nonce-count | qop | digest-uri | response | * maxbuf | charset | cipher | authzid | * auth-param ) * * username = "username" "=" <"> username-value <"> * username-value = qdstr-val * cnonce = "cnonce" "=" <"> cnonce-value <"> * cnonce-value = qdstr-val * nonce-count = "nc" "=" nc-value * nc-value = 8LHEX * qop = "qop" "=" qop-value * digest-uri = "digest-uri" "=" <"> digest-uri-value <"> * digest-uri-value = serv-type "/" host [ "/" serv-name ] * serv-type = 1*ALPHA * host = 1*( ALPHA | DIGIT | "-" | "." ) * serv-name = host * response = "response" "=" response-value * response-value = 32LHEX * LHEX = "0" | "1" | "2" | "3" | * "4" | "5" | "6" | "7" | * "8" | "9" | "a" | "b" | * "c" | "d" | "e" | "f" * cipher = "cipher" "=" cipher-value * authzid = "authzid" "=" <"> authzid-value <"> * authzid-value = qdstr-val * sets: * negotiatedQop * negotiatedCipher * negotiatedRealm * negotiatedStrength * digestUri (checked and set to clients to account for case diffs) * sendMaxBufSize * authzid (gotten from callback) * @return response-value ('rspauth') for client to validate */ private byte[] validateClientResponse(byte[][] responseVal) throws SaslException, UnsupportedEncodingException { /* CHARSET: optional atmost once */ if (responseVal[CHARSET] != null) { // The client should send this directive only if the server has // indicated it supports UTF-8. if (!useUTF8 || !"utf-8".equals(new String(responseVal[CHARSET], encoding))) { throw new SaslException("DIGEST-MD5: digest response format " + "violation. Incompatible charset value: " + new String(responseVal[CHARSET])); } } // maxbuf: atmost once int clntMaxBufSize = (responseVal[MAXBUF] == null) ? DEFAULT_MAXBUF : Integer.parseInt(new String(responseVal[MAXBUF], encoding)); // Max send buf size is min of client's max recv buf size and // server's max send buf size sendMaxBufSize = ((sendMaxBufSize == 0) ? clntMaxBufSize : Math.min(sendMaxBufSize, clntMaxBufSize)); /* username: exactly once */ String username; if (responseVal[USERNAME] != null) { username = new String(responseVal[USERNAME], encoding); logger.log(Level.FINE, "DIGEST82:Username: {0}", username); } else { throw new SaslException("DIGEST-MD5: digest response format " + "violation. Missing username."); } /* realm: exactly once if sent by server */ negotiatedRealm = ((responseVal[REALM] != null) ? new String(responseVal[REALM], encoding) : ""); logger.log(Level.FINE, "DIGEST83:Client negotiated realm: {0}", negotiatedRealm); if (!serverRealms.contains(negotiatedRealm)) { // Server had sent at least one realm // Check that response is one of these throw new SaslException("DIGEST-MD5: digest response format " + "violation. Nonexistent realm: " + negotiatedRealm); } // Else, client specified realm was one of server's or server had none /* nonce: exactly once */ if (responseVal[NONCE] == null) { throw new SaslException("DIGEST-MD5: digest response format " + "violation. Missing nonce."); } byte[] nonceFromClient = responseVal[NONCE]; if (!Arrays.equals(nonceFromClient, nonce)) { throw new SaslException("DIGEST-MD5: digest response format " + "violation. Mismatched nonce."); } /* cnonce: exactly once */ if (responseVal[CNONCE] == null) { throw new SaslException("DIGEST-MD5: digest response format " + "violation. Missing cnonce."); } byte[] cnonce = responseVal[CNONCE]; /* nonce-count: atmost once */ if (responseVal[NONCE_COUNT] != null && NONCE_COUNT_VALUE != Integer.parseInt( new String(responseVal[NONCE_COUNT], encoding), 16)) { throw new SaslException("DIGEST-MD5: digest response format " + "violation. Nonce count does not match: " + new String(responseVal[NONCE_COUNT])); } /* qop: atmost once; default is "auth" */ negotiatedQop = ((responseVal[QOP] != null) ? new String(responseVal[QOP], encoding) : "auth"); logger.log(Level.FINE, "DIGEST84:Client negotiated qop: {0}", negotiatedQop); // Check that QOP is one sent by server byte cQop; switch (negotiatedQop) { case "auth": cQop = NO_PROTECTION; break; case "auth-int": cQop = INTEGRITY_ONLY_PROTECTION; integrity = true; rawSendSize = sendMaxBufSize - 16; break; case "auth-conf": cQop = PRIVACY_PROTECTION; integrity = privacy = true; rawSendSize = sendMaxBufSize - 26; break; default: throw new SaslException("DIGEST-MD5: digest response format " + "violation. Invalid QOP: " + negotiatedQop); } if ((cQop&allQop) == 0) { throw new SaslException("DIGEST-MD5: server does not support " + " qop: " + negotiatedQop); } if (privacy) { negotiatedCipher = ((responseVal[CIPHER] != null) ? new String(responseVal[CIPHER], encoding) : null); if (negotiatedCipher == null) { throw new SaslException("DIGEST-MD5: digest response format " + "violation. No cipher specified."); } int foundCipher = -1; logger.log(Level.FINE, "DIGEST85:Client negotiated cipher: {0}", negotiatedCipher); // Check that cipher is one that we offered for (int j = 0; j < CIPHER_TOKENS.length; j++) { if (negotiatedCipher.equals(CIPHER_TOKENS[j]) && myCiphers[j] != 0) { foundCipher = j; break; } } if (foundCipher == -1) { throw new SaslException("DIGEST-MD5: server does not " + "support cipher: " + negotiatedCipher); } // Set negotiatedStrength if ((CIPHER_MASKS[foundCipher]&HIGH_STRENGTH) != 0) { negotiatedStrength = "high"; } else if ((CIPHER_MASKS[foundCipher]&MEDIUM_STRENGTH) != 0) { negotiatedStrength = "medium"; } else { // assume default low negotiatedStrength = "low"; } logger.log(Level.FINE, "DIGEST86:Negotiated strength: {0}", negotiatedStrength); } // atmost once String digestUriFromResponse = ((responseVal[DIGEST_URI]) != null ? new String(responseVal[DIGEST_URI], encoding) : null); if (digestUriFromResponse != null) { logger.log(Level.FINE, "DIGEST87:digest URI: {0}", digestUriFromResponse); } // serv-type "/" host [ "/" serv-name ] // e.g.: smtp/mail3.example.com/example.com // e.g.: ftp/ftp.example.com // e.g.: ldap/ldapserver.example.com // host should match one of service's configured service names // Check against digest URI that mech was created with if (uriMatches(digestUri, digestUriFromResponse)) { digestUri = digestUriFromResponse; // account for case-sensitive diffs } else { throw new SaslException("DIGEST-MD5: digest response format " + "violation. Mismatched URI: " + digestUriFromResponse + "; expecting: " + digestUri); } // response: exactly once byte[] responseFromClient = responseVal[RESPONSE]; if (responseFromClient == null) { throw new SaslException("DIGEST-MD5: digest response format " + " violation. Missing response."); } // authzid: atmost once byte[] authzidBytes; String authzidFromClient = ((authzidBytes=responseVal[AUTHZID]) != null? new String(authzidBytes, encoding) : username); if (authzidBytes != null) { logger.log(Level.FINE, "DIGEST88:Authzid: {0}", new String(authzidBytes)); } // Ignore auth-param // Get password need to generate verifying response char[] passwd; try { // Realm and Name callbacks are used to provide info RealmCallback rcb = new RealmCallback("DIGEST-MD5 realm: ", negotiatedRealm); NameCallback ncb = new NameCallback("DIGEST-MD5 authentication ID: ", username); // PasswordCallback is used to collect info PasswordCallback pcb = new PasswordCallback("DIGEST-MD5 password: ", false); cbh.handle(new Callback[] {rcb, ncb, pcb}); passwd = pcb.getPassword(); pcb.clearPassword(); } catch (UnsupportedCallbackException e) { throw new SaslException( "DIGEST-MD5: Cannot perform callback to acquire password", e); } catch (IOException e) { throw new SaslException( "DIGEST-MD5: IO error acquiring password", e); } if (passwd == null) { throw new SaslException( "DIGEST-MD5: cannot acquire password for " + username + " in realm : " + negotiatedRealm); } try { // Validate response value sent by client byte[] expectedResponse; try { expectedResponse = generateResponseValue("AUTHENTICATE", digestUri, negotiatedQop, username, negotiatedRealm, passwd, nonce /* use own nonce */, cnonce, NONCE_COUNT_VALUE, authzidBytes); } catch (NoSuchAlgorithmException e) { throw new SaslException( "DIGEST-MD5: problem duplicating client response", e); } catch (IOException e) { throw new SaslException( "DIGEST-MD5: problem duplicating client response", e); } if (!Arrays.equals(responseFromClient, expectedResponse)) { throw new SaslException("DIGEST-MD5: digest response format " + "violation. Mismatched response."); } // Ensure that authzid mapping is OK try { AuthorizeCallback acb = new AuthorizeCallback(username, authzidFromClient); cbh.handle(new Callback[]{acb}); if (acb.isAuthorized()) { authzid = acb.getAuthorizedID(); } else { throw new SaslException("DIGEST-MD5: " + username + " is not authorized to act as " + authzidFromClient); } } catch (SaslException e) { throw e; } catch (UnsupportedCallbackException e) { throw new SaslException( "DIGEST-MD5: Cannot perform callback to check authzid", e); } catch (IOException e) { throw new SaslException( "DIGEST-MD5: IO error checking authzid", e); } return generateResponseAuth(username, passwd, cnonce, NONCE_COUNT_VALUE, authzidBytes); } finally { // Clear password for (int i = 0; i < passwd.length; i++) { passwd[i] = 0; } } } private static boolean uriMatches(String thisUri, String incomingUri) { // Full match if (thisUri.equalsIgnoreCase(incomingUri)) { return true; } // Unbound match if (thisUri.endsWith("/*")) { int protoAndSlash = thisUri.length() - 1; String thisProtoAndSlash = thisUri.substring(0, protoAndSlash); String incomingProtoAndSlash = incomingUri.substring(0, protoAndSlash); return thisProtoAndSlash.equalsIgnoreCase(incomingProtoAndSlash); } return false; } /** * Server sends a message formatted as follows: * response-auth = "rspauth" "=" response-value * where response-value is calculated as above, using the values sent in * step two, except that if qop is "auth", then A2 is * * A2 = { ":", digest-uri-value } * * And if qop is "auth-int" or "auth-conf" then A2 is * * A2 = { ":", digest-uri-value, ":00000000000000000000000000000000" } * * Clears password afterwards. */ private byte[] generateResponseAuth(String username, char[] passwd, byte[] cnonce, int nonceCount, byte[] authzidBytes) throws SaslException { // Construct response value try { byte[] responseValue = generateResponseValue("", digestUri, negotiatedQop, username, negotiatedRealm, passwd, nonce, cnonce, nonceCount, authzidBytes); byte[] challenge = new byte[responseValue.length + 8]; System.arraycopy("rspauth=".getBytes(encoding), 0, challenge, 0, 8); System.arraycopy(responseValue, 0, challenge, 8, responseValue.length ); return challenge; } catch (NoSuchAlgorithmException e) { throw new SaslException("DIGEST-MD5: problem generating response", e); } catch (IOException e) { throw new SaslException("DIGEST-MD5: problem generating response", e); } } public String getAuthorizationID() { if (completed) { return authzid; } else { throw new IllegalStateException( "DIGEST-MD5 server negotiation not complete"); } } }
⏎ com/sun/security/sasl/digest/DigestMD5Server.java
Or download all of them as a single archive file:
File name: java.security.sasl-11.0.1-src.zip File size: 76634 bytes Release date: 2018-11-04 Download
⇒ JDK 11 java.smartcardio.jmod - Smart Card IO Module
2020-09-15, 12865👍, 0💬
Popular Posts:
Where Can I see Java Source Code files for Xerces Java 2.11.2? Here are Java Source Code files for X...
XStream is a simple library to serialize objects to XML and back again. JAR File Size and Download L...
ASM is an all purpose Java bytecode manipulation and analysis framework. It can be used to modify ex...
What Is HttpComponents httpcore-4.2.2.jar? HttpComponents httpcore-4.2.2.jar is the JAR file for Apa...
How to perform XML Schema validation with dom\Writer.java provided in the Apache Xerces package? You...