Methods Summary |
---|
public static int | addProvider(java.security.Provider provider)Adds a provider to the next position available.
First, if there is a security manager, its
checkSecurityAccess
method is called with the string
"insertProvider."+provider.getName()
to see if it's ok to add a new provider.
If the default implementation of checkSecurityAccess
is used (i.e., that method is not overriden), then this will result in
a call to the security manager's checkPermission method
with a
SecurityPermission("insertProvider."+provider.getName())
permission.
/*
* We can't assign a position here because the statically
* registered providers may not have been installed yet.
* insertProviderAt() will fix that value after it has
* loaded the static providers.
*/
return insertProviderAt(provider, 0);
|
private static void | check(java.lang.String directive)
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkSecurityAccess(directive);
}
|
public static java.lang.String | getAlgorithmProperty(java.lang.String algName, java.lang.String propName)Gets a specified property for an algorithm. The algorithm name
should be a standard name. See Appendix A in the
Java Cryptography Architecture API Specification & Reference
for information about standard algorithm names.
One possible use is by specialized algorithm parsers, which may map
classes to algorithms which they understand (much like Key parsers
do).
ProviderProperty entry = getProviderProperty("Alg." + propName
+ "." + algName);
if (entry != null) {
return entry.className;
} else {
return null;
}
|
public static java.util.Set | getAlgorithms(java.lang.String serviceName)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 or if serviceName is null. For a complete list
of Java cryptographic services, please see the
Java
Cryptography Architecture API Specification & Reference.
Note: the returned set is immutable.
if ((serviceName == null) || (serviceName.length() == 0) ||
(serviceName.endsWith("."))) {
return Collections.EMPTY_SET;
}
HashSet result = new HashSet();
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);
|
private static java.util.LinkedHashSet | getAllQualifyingCandidates(java.lang.String filterKey, java.lang.String filterValue, java.security.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];
return getProvidersNotUsingCache(serviceName, algName, attrName,
filterValue, allProviders);
|
static java.lang.String[] | getFilterComponents(java.lang.String filterKey, java.lang.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;
|
static java.lang.Object[] | getImpl(java.lang.String algorithm, java.lang.String type, java.lang.String provider)
if (provider == null) {
return GetInstance.getInstance
(type, getSpiClass(type), algorithm).toArray();
} else {
return GetInstance.getInstance
(type, getSpiClass(type), algorithm, provider).toArray();
}
|
static java.lang.Object[] | getImpl(java.lang.String algorithm, java.lang.String type, java.lang.String provider, java.lang.Object params)
if (provider == null) {
return GetInstance.getInstance
(type, getSpiClass(type), algorithm, params).toArray();
} else {
return GetInstance.getInstance
(type, getSpiClass(type), algorithm, params, provider).toArray();
}
|
static java.lang.Object[] | getImpl(java.lang.String algorithm, java.lang.String type, java.security.Provider provider)
return GetInstance.getInstance
(type, getSpiClass(type), algorithm, provider).toArray();
|
static java.lang.Object[] | getImpl(java.lang.String algorithm, java.lang.String type, java.security.Provider provider, java.lang.Object params)
return GetInstance.getInstance
(type, getSpiClass(type), algorithm, params, provider).toArray();
|
public static java.lang.String | getProperty(java.lang.String key)Gets a security property value.
First, if there is a security manager, its
checkPermission method is called with a
java.security.SecurityPermission("getProperty."+key)
permission to see if it's ok to retrieve the specified
security property value..
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SecurityPermission("getProperty."+
key));
}
String name = props.getProperty(key);
if (name != null)
name = name.trim(); // could be a class name with trailing ws
return name;
|
public static java.security.Provider | getProvider(java.lang.String name)Returns the provider installed with the specified name, if
any. Returns null if no provider with the specified name is
installed or if name is null.
return Providers.getProviderList().getProvider(name);
|
private static java.security.Security$ProviderProperty | getProviderProperty(java.lang.String key)Looks up providers, and returns the property (and its associated
provider) mapping the key, if any.
The order in which the providers are looked up is the
provider-preference order, as specificed in the security
properties file.
ProviderProperty entry = null;
List providers = Providers.getProviderList().providers();
for (int i = 0; i < providers.size(); i++) {
String matchKey = null;
Provider prov = (Provider)providers.get(i);
String prop = prov.getProperty(key);
if (prop == null) {
// Is there a match if we do a case-insensitive property name
// comparison? Let's try ...
for (Enumeration e = prov.keys();
e.hasMoreElements() && prop == null; ) {
matchKey = (String)e.nextElement();
if (key.equalsIgnoreCase(matchKey)) {
prop = prov.getProperty(matchKey);
break;
}
}
}
if (prop != null) {
ProviderProperty newEntry = new ProviderProperty();
newEntry.className = prop;
newEntry.provider = prov;
return newEntry;
}
}
return entry;
|
private static java.lang.String | getProviderProperty(java.lang.String key, java.security.Provider provider)Returns the property (if any) mapping the key for the given provider.
String prop = provider.getProperty(key);
if (prop == null) {
// Is there a match if we do a case-insensitive property name
// comparison? Let's try ...
for (Enumeration e = provider.keys();
e.hasMoreElements() && prop == null; ) {
String matchKey = (String)e.nextElement();
if (key.equalsIgnoreCase(matchKey)) {
prop = provider.getProperty(matchKey);
break;
}
}
}
return prop;
|
public static java.security.Provider[] | getProviders()Returns an array containing all the installed providers. The order of
the providers in the array is their preference order.
return Providers.getFullProviderList().toArray();
|
public static java.security.Provider[] | getProviders(java.lang.String filter)Returns an array containing all installed providers that satisfy the
specified selection criterion, or null if no such providers have been
installed. The returned providers are ordered
according to their preference order.
A cryptographic service is always associated with a particular
algorithm or type. For example, a digital signature service is
always associated with a particular algorithm (e.g., DSA),
and a CertificateFactory service is always associated with
a particular certificate type (e.g., X.509).
The selection criterion must be specified in one of the following two
formats:
- <crypto_service>.<algorithm_or_type>
The
cryptographic service name must not contain any dots.
A
provider satisfies the specified selection criterion iff the provider
implements the
specified algorithm or type for the specified cryptographic service.
For example, "CertificateFactory.X.509"
would be satisfied by any provider that supplied
a CertificateFactory implementation for X.509 certificates.
- <crypto_service>.<algorithm_or_type>
<attribute_name>:< attribute_value>
The cryptographic service name must not contain any dots. There
must be one or more space charaters between the the
<algorithm_or_type> and the <attribute_name>.
A provider satisfies this selection criterion iff the
provider implements the specified algorithm or type for the specified
cryptographic service and its implementation meets the
constraint expressed by the specified attribute name/value pair.
For example, "Signature.SHA1withDSA KeySize:1024" would be
satisfied by any provider that implemented
the SHA1withDSA signature algorithm with a keysize of 1024 (or larger).
See Appendix A in the
Java Cryptogaphy Architecture API Specification & Reference
for information about standard cryptographic service names, standard
algorithm names and standard attribute names.
String key = null;
String value = null;
int index = filter.indexOf(':");
if (index == -1) {
key = filter;
value = "";
} else {
key = filter.substring(0, index);
value = filter.substring(index + 1);
}
Hashtable hashtableFilter = new Hashtable(1);
hashtableFilter.put(key, value);
return (getProviders(hashtableFilter));
|
public static java.security.Provider[] | getProviders(java.util.Map filter)Returns an array containing all installed providers that satisfy the
specified* selection criteria, or null if no such providers have been
installed. The returned providers are ordered
according to their preference order.
The selection criteria are represented by a map.
Each map entry represents a selection criterion.
A provider is selected iff it satisfies all selection
criteria. The key for any entry in such a map must be in one of the
following two formats:
- <crypto_service>.<algorithm_or_type>
The cryptographic service name must not contain any dots.
The value associated with the key must be an empty string.
A provider
satisfies this selection criterion iff the provider implements the
specified algorithm or type for the specified cryptographic service.
- <crypto_service>.<algorithm_or_type> <attribute_name>
The cryptographic service name must not contain any dots. There
must be one or more space charaters between the <algorithm_or_type>
and the <attribute_name>.
The value associated with the key must be a non-empty string.
A provider satisfies this selection criterion iff the
provider implements the specified algorithm or type for the specified
cryptographic service and its implementation meets the
constraint expressed by the specified attribute name/value pair.
See Appendix A in the
Java Cryptogaphy Architecture API Specification & Reference
for information about standard cryptographic service names, standard
algorithm names and standard attribute names.
// Get all installed providers first.
// Then only return those providers who satisfy the selection criteria.
Provider[] allProviders = Security.getProviders();
Set keySet = filter.keySet();
LinkedHashSet candidates = new LinkedHashSet(5);
// Returns all installed providers
// if the selection criteria is null.
if ((keySet == null) || (allProviders == null)) {
return allProviders;
}
boolean firstSearch = true;
// For each selection criterion, remove providers
// which don't satisfy the criterion from the candidate set.
for (Iterator ite = keySet.iterator(); ite.hasNext(); ) {
String key = (String)ite.next();
String value = (String)filter.get(key);
LinkedHashSet newCandidates = getAllQualifyingCandidates(key, value,
allProviders);
if (firstSearch) {
candidates = newCandidates;
firstSearch = false;
}
if ((newCandidates != null) && !newCandidates.isEmpty()) {
// For each provider in the candidates set, if it
// isn't in the newCandidate set, we should remove
// it from the candidate set.
for (Iterator cansIte = candidates.iterator();
cansIte.hasNext(); ) {
Provider prov = (Provider)cansIte.next();
if (!newCandidates.contains(prov)) {
cansIte.remove();
}
}
} else {
candidates = null;
break;
}
}
if ((candidates == null) || (candidates.isEmpty()))
return null;
Object[] candidatesArray = candidates.toArray();
Provider[] result = new Provider[candidatesArray.length];
for (int i = 0; i < result.length; i++) {
result[i] = (Provider)candidatesArray[i];
}
return result;
|
private static java.util.LinkedHashSet | getProvidersNotUsingCache(java.lang.String serviceName, java.lang.String algName, java.lang.String attrName, java.lang.String filterValue, java.security.Provider[] allProviders)
LinkedHashSet 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;
|
private static java.lang.Class | getSpiClass(java.lang.String type)Return the Class object for the given engine type
(e.g. "MessageDigest"). Works for Spis in the java.security package
only.
Class clazz = spiMap.get(type);
if (clazz != null) {
return clazz;
}
try {
clazz = Class.forName("java.security." + type + "Spi");
spiMap.put(type, clazz);
return clazz;
} catch (ClassNotFoundException e) {
throw (Error)new AssertionError("Spi class not found").initCause(e);
}
|
private static void | initialize()
// doPrivileged here because there are multiple
// things in initialize that might require privs.
// (the FileInputStream call and the File.exists call,
// the securityPropFile call, etc)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
initialize();
return null;
}
});
props = new Properties();
boolean loadedProps = false;
boolean overrideAll = false;
// first load the system properties file
// to determine the value of security.overridePropertiesFile
File propFile = securityPropFile("java.security");
if (propFile.exists()) {
try {
FileInputStream fis = new FileInputStream(propFile);
InputStream is = new BufferedInputStream(fis);
props.load(is);
is.close();
loadedProps = true;
if (sdebug != null) {
sdebug.println("reading security properties file: " +
propFile);
}
} catch (IOException e) {
if (sdebug != null) {
sdebug.println("unable to load security properties from " +
propFile);
e.printStackTrace();
}
}
}
if ("true".equalsIgnoreCase(props.getProperty
("security.overridePropertiesFile"))) {
String extraPropFile = System.getProperty
("java.security.properties");
if (extraPropFile != null && extraPropFile.startsWith("=")) {
overrideAll = true;
extraPropFile = extraPropFile.substring(1);
}
if (overrideAll) {
props = new Properties();
if (sdebug != null) {
sdebug.println
("overriding other security properties files!");
}
}
// now load the user-specified file so its values
// will win if they conflict with the earlier values
if (extraPropFile != null) {
try {
URL propURL;
extraPropFile = PropertyExpander.expand(extraPropFile);
propFile = new File(extraPropFile);
if (propFile.exists()) {
propURL = new URL
("file:" + propFile.getCanonicalPath());
} else {
propURL = new URL(extraPropFile);
}
BufferedInputStream bis = new BufferedInputStream
(propURL.openStream());
props.load(bis);
bis.close();
loadedProps = true;
if (sdebug != null) {
sdebug.println("reading security properties file: " +
propURL);
if (overrideAll) {
sdebug.println
("overriding other security properties files!");
}
}
} catch (Exception e) {
if (sdebug != null) {
sdebug.println
("unable to load security properties from " +
extraPropFile);
e.printStackTrace();
}
}
}
}
if (!loadedProps) {
initializeStatic();
if (sdebug != null) {
sdebug.println("unable to load security properties " +
"-- using defaults");
}
}
|
private static void | initializeStatic()
props.put("security.provider.1", "sun.security.provider.Sun");
props.put("security.provider.2", "sun.security.rsa.SunRsaSign");
props.put("security.provider.3", "com.sun.net.ssl.internal.ssl.Provider");
props.put("security.provider.4", "com.sun.crypto.provider.SunJCE");
props.put("security.provider.5", "sun.security.jgss.SunProvider");
props.put("security.provider.6", "com.sun.security.sasl.Provider");
|
public static synchronized int | insertProviderAt(java.security.Provider provider, int position)Adds a new provider, at a specified position. The position is
the preference order in which providers are searched for
requested algorithms. Note that it is not guaranteed that this
preference will be respected. The position is 1-based, that is,
1 is most preferred, followed by 2, and so on.
If the given provider is installed at the requested position,
the provider that used to be at that position, and all providers
with a position greater than position , are shifted up
one position (towards the end of the list of installed providers).
A provider cannot be added if it is already installed.
First, if there is a security manager, its
checkSecurityAccess
method is called with the string
"insertProvider."+provider.getName()
to see if it's ok to add a new provider.
If the default implementation of checkSecurityAccess
is used (i.e., that method is not overriden), then this will result in
a call to the security manager's checkPermission method
with a
SecurityPermission("insertProvider."+provider.getName())
permission.
String providerName = provider.getName();
check("insertProvider." + providerName);
ProviderList list = Providers.getFullProviderList();
ProviderList newList = ProviderList.insertAt(list, provider, position - 1);
if (list == newList) {
return -1;
}
Providers.setProviderList(newList);
return newList.getIndex(providerName) + 1;
|
private static void | invalidateSMCache(java.lang.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 boolean | isConstraintSatisfied(java.lang.String attribute, java.lang.String value, java.lang.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 = Integer.parseInt(value);
int maxSize = Integer.parseInt(prop);
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;
|
private static boolean | isCriterionSatisfied(java.security.Provider prov, java.lang.String serviceName, java.lang.String algName, java.lang.String attrName, java.lang.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);
}
|
private static boolean | isStandardAttr(java.lang.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;
|
public static synchronized void | removeProvider(java.lang.String name)Removes the provider with the specified name.
When the specified provider is removed, all providers located
at a position greater than where the specified provider was are shifted
down one position (towards the head of the list of installed
providers).
This method returns silently if the provider is not installed or
if name is null.
First, if there is a security manager, its
checkSecurityAccess
method is called with the string "removeProvider."+name
to see if it's ok to remove the provider.
If the default implementation of checkSecurityAccess
is used (i.e., that method is not overriden), then this will result in
a call to the security manager's checkPermission method
with a SecurityPermission("removeProvider."+name)
permission.
check("removeProvider." + name);
ProviderList list = Providers.getFullProviderList();
ProviderList newList = ProviderList.remove(list, name);
Providers.setProviderList(newList);
|
private static java.io.File | securityPropFile(java.lang.String filename)
// maybe check for a system property which will specify where to
// look. Someday.
String sep = File.separator;
return new File(System.getProperty("java.home") + sep + "lib" + sep +
"security" + sep + filename);
|
public static void | setProperty(java.lang.String key, java.lang.String datum)Sets a security property value.
First, if there is a security manager, its
checkPermission method is called with a
java.security.SecurityPermission("setProperty."+key)
permission to see if it's ok to set the specified
security property value.
check("setProperty."+key);
props.put(key, datum);
invalidateSMCache(key); /* See below. */
|