📄 security.java
字号:
* * <p>First, if there is a security manager, its * <code>checkPermission</code> method is called with a * <code>java.security.SecurityPermission("setProperty."+key)</code> * permission to see if it's ok to set the specified * security property value. * * @param key the name of the property to be set. * * @param datum the value of the property to be set. * * @throws SecurityException * if a security manager exists and its <code>{@link * java.lang.SecurityManager#checkPermission}</code> method * denies access to set the specified security property value * * @see #getProperty * @see java.security.SecurityPermission */ public static void setProperty(String key, String datum) { check("setProperty."+key); props.put(key, datum); invalidateSMCache(key); /* See below. */ } /* * Implementation detail: If the property we just set in * setProperty() was either "package.access" or * "package.definition", we need to signal to the SecurityManager * class that the value has just changed, and that it should * invalidate it's local cache values. * * Rather than create a new API entry for this function, * we use reflection to set a private variable. */ private static void invalidateSMCache(String key) { final boolean pa = key.equals("package.access"); final boolean pd = key.equals("package.definition"); if (pa || pd) { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { /* Get the class via the bootstrap class loader. */ Class cl = Class.forName( "java.lang.SecurityManager", false, null); Field f = null; boolean accessible = false; if (pa) { f = cl.getDeclaredField("packageAccessValid"); accessible = f.isAccessible(); f.setAccessible(true); } else { f = cl.getDeclaredField("packageDefinitionValid"); accessible = f.isAccessible(); f.setAccessible(true); } f.setBoolean(f, false); f.setAccessible(accessible); } catch (Exception e1) { /* If we couldn't get the class, it hasn't * been loaded yet. If there is no such * field, we shouldn't try to set it. There * shouldn't be a security execption, as we * are loaded by boot class loader, and we * are inside a doPrivileged() here. * * NOOP: don't do anything... */ } return null; } /* run */ }); /* PrivilegedAction */ } /* if */ } private static void check(String directive) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkSecurityAccess(directive); } } /** * Print an error message that may be significant to a user. */ static void error(String msg) { if (debug) { System.err.println(msg); } } /** * Print an error message that may be significant to a user. */ static void error(String msg, Throwable t) { error(msg); if (debug) { t.printStackTrace(); } } /** * Print an debugging message that may be significant to a developer. */ static void debug(String msg) { if (debug) { System.err.println(msg); } } /** * Print an debugging message that may be significant to a developer. */ static void debug(String msg, Throwable t) { if (debug) { t.printStackTrace(); System.err.println(msg); } } /* * Returns all providers who satisfy the specified * criterion. */ private static LinkedHashSet getAllQualifyingCandidates(String filterKey, String filterValue, Provider[] allProviders) { String[] filterComponents = getFilterComponents(filterKey, filterValue); // The first component is the service name. // The second is the algorithm name. // If the third isn't null, that is the attrinute name. String serviceName = filterComponents[0]; String algName = filterComponents[1]; String attrName = filterComponents[2]; // Check whether we can find anything in the cache String cacheKey = serviceName + '.' + algName; LinkedHashSet candidates = (LinkedHashSet)searchResultsCache.get(cacheKey); // If there is no entry for the cacheKey in the cache, // let's build an entry for it first. LinkedHashSet forCache = getProvidersNotUsingCache(serviceName, algName, null, null, null, allProviders); if ((forCache == null) || (forCache.isEmpty())) { return null; } else { searchResultsCache.put(cacheKey, forCache); if (attrName == null) { return forCache; } return getProvidersNotUsingCache(serviceName, algName, attrName, filterValue, candidates, allProviders); } } private static LinkedHashSet getProvidersNotUsingCache(String serviceName, String algName, String attrName, String filterValue, LinkedHashSet candidates, Provider[] allProviders) { if ((attrName != null) && (candidates != null) && (!candidates.isEmpty())) { for (Iterator cansIte = candidates.iterator(); cansIte.hasNext(); ) { Provider prov = (Provider)cansIte.next(); if (!isCriterionSatisfied(prov, serviceName, algName, attrName, filterValue)) { cansIte.remove(); } } } if ((candidates == null) || (candidates.isEmpty())) { if (candidates == null) candidates = new LinkedHashSet(5); for (int i = 0; i < allProviders.length; i++) { if (isCriterionSatisfied(allProviders[i], serviceName, algName, attrName, filterValue)) { candidates.add(allProviders[i]); } } } return candidates; } /* * Returns true if the given provider satisfies * the selection criterion key:value. */ private static boolean isCriterionSatisfied(Provider prov, String serviceName, String algName, String attrName, String filterValue) { String key = serviceName + '.' + algName; if (attrName != null) { key += ' ' + attrName; } // Check whether the provider has a property // whose key is the same as the given key. String propValue = getProviderProperty(key, prov); if (propValue == null) { // Check whether we have an alias instead // of a standard name in the key. String standardName = getProviderProperty("Alg.Alias." + serviceName + "." + algName, prov); if (standardName != null) { key = serviceName + "." + standardName; if (attrName != null) { key += ' ' + attrName; } propValue = getProviderProperty(key, prov); } if (propValue == null) { // The provider doesn't have the given // key in its property list. return false; } } // If the key is in the format of: // <crypto_service>.<algorithm_or_type>, // there is no need to check the value. if (attrName == null) { return true; } // If we get here, the key must be in the // format of <crypto_service>.<algorithm_or_provider> <attribute_name>. if (isStandardAttr(attrName)) { return isConstraintSatisfied(attrName, filterValue, propValue); } else { return filterValue.equalsIgnoreCase(propValue); } } /* * Returns true if the attribute is a standard attribute; * otherwise, returns false. */ private static boolean isStandardAttr(String attribute) { // For now, we just have two standard attributes: KeySize and ImplementedIn. if (attribute.equalsIgnoreCase("KeySize")) return true; if (attribute.equalsIgnoreCase("ImplementedIn")) return true; return false; } /* * Returns true if the requested attribute value is supported; * otherwise, returns false. */ private static boolean isConstraintSatisfied(String attribute, String value, String prop) { // For KeySize, prop is the max key size the // provider supports for a specific <crypto_service>.<algorithm>. if (attribute.equalsIgnoreCase("KeySize")) { int requestedSize = (new Integer(value)).intValue(); int maxSize = (new Integer(prop)).intValue(); if (requestedSize <= maxSize) { return true; } else { return false; } } // For Type, prop is the type of the implementation // for a specific <crypto service>.<algorithm>. if (attribute.equalsIgnoreCase("ImplementedIn")) { return value.equalsIgnoreCase(prop); } return false; } static String[] getFilterComponents(String filterKey, String filterValue) { int algIndex = filterKey.indexOf('.'); if (algIndex < 0) { // There must be a dot in the filter, and the dot // shouldn't be at the beginning of this string. throw new InvalidParameterException("Invalid filter"); } String serviceName = filterKey.substring(0, algIndex); String algName = null; String attrName = null; if (filterValue.length() == 0) { // The filterValue is an empty string. So the filterKey // should be in the format of <crypto_service>.<algorithm_or_type>. algName = filterKey.substring(algIndex + 1).trim(); if (algName.length() == 0) { // There must be a algorithm or type name. throw new InvalidParameterException("Invalid filter"); } } else { // The filterValue is a non-empty string. So the filterKey must be // in the format of // <crypto_service>.<algorithm_or_type> <attribute_name> int attrIndex = filterKey.indexOf(' '); if (attrIndex == -1) { // There is no attribute name in the filter. throw new InvalidParameterException("Invalid filter"); } else { attrName = filterKey.substring(attrIndex + 1).trim(); if (attrName.length() == 0) { // There is no attribute name in the filter. throw new InvalidParameterException("Invalid filter"); } } // There must be an algorithm name in the filter. if ((attrIndex < algIndex) || (algIndex == attrIndex - 1)) { throw new InvalidParameterException("Invalid filter"); } else { algName = filterKey.substring(algIndex + 1, attrIndex); } } String[] result = new String[3]; result[0] = serviceName; result[1] = algName; result[2] = attrName; return result; } /** * Returns a Set of Strings containing the names of all available * algorithms or types for the specified Java cryptographic service * (e.g., Signature, MessageDigest, Cipher, Mac, KeyStore). Returns * an empty Set if there is no provider that supports the * specified service. For a complete list of Java cryptographic * services, please see the * <a href="../../../guide/security/CryptoSpec.html">Java * Cryptography Architecture API Specification & Reference</a>. * Note: the returned set is immutable. * * @param serviceName the name of the Java cryptographic * service (e.g., Signature, MessageDigest, Cipher, Mac, KeyStore). * Note: this parameter is case-insensitive. * * NOTE: <B>java.security.Signature, java.security.KeyStore</B> are found * in J2ME CDC profiles such as J2ME Foundation Profile. <B> Cipher, * Mac </B> are found in J2ME CDC optional packages such as J2ME Security * Optional Package. * * @return a Set of Strings containing the names of all available * algorithms or types for the specified Java cryptographic service * or an empty set if no provider supports the specified service. * * @since 1.4 **/ public static Set getAlgorithms(String serviceName) { HashSet result = new HashSet(); if ((serviceName == null) || (serviceName.length() == 0) || (serviceName.endsWith("."))) { return result; } Provider[] providers = Security.getProviders(); for (int i = 0; i < providers.length; i++) { // Check the keys for each provider. for (Enumeration e = providers[i].keys(); e.hasMoreElements(); ) { String currentKey = ((String)e.nextElement()).toUpperCase(); if (currentKey.startsWith(serviceName.toUpperCase())) { // We should skip the currentKey if it contains a // whitespace. The reason is: such an entry in the // provider property contains attributes for the // implementation of an algorithm. We are only interested // in entries which lead to the implementation // classes. if (currentKey.indexOf(" ") < 0) { result.add(currentKey.substring(serviceName.length() + 1)); } } } } return Collections.unmodifiableSet(result); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -