FileDocCategorySizeDatePackage
Provider.javaAPI DocJava SE 6 API47282Tue Jun 10 00:25:46 BST 2008java.security

Provider

public abstract class Provider extends Properties
This class represents a "provider" for the Java Security API, where a provider implements some or all parts of Java Security. Services that a provider may implement include:
  • Algorithms (such as DSA, RSA, MD5 or SHA-1).
  • Key generation, conversion, and management facilities (such as for algorithm-specific keys).

Each provider has a name and a version number, and is configured in each runtime it is installed in.

See The Provider Class in the "Java Cryptography Architecture API Specification & Reference" for information about how a particular type of provider, the cryptographic service provider, works and is installed. However, please note that a provider can be used to implement any security service in Java that uses a pluggable architecture with a choice of implementations that fit underneath.

Some provider implementations may encounter unrecoverable internal errors during their operation, for example a failure to communicate with a security token. A {@link ProviderException} should be used to indicate such errors.

The service type Provider is reserved for use by the security framework. Services of this type cannot be added, removed, or modified by applications. The following attributes are automatically placed in each Provider object:
NameValue
Provider.id name String.valueOf(provider.getName())
Provider.id version String.valueOf(provider.getVersion())
Provider.id info String.valueOf(provider.getInfo())
Provider.id className provider.getClass().getName()

version
1.77, 08/07/06
author
Benjamin Renaud
author
Andreas Sterbenz

Fields Summary
static final long
serialVersionUID
private static final Debug
debug
private String
name
The provider name.
private String
info
A description of the provider and its services.
private double
version
The provider version number.
private transient Set
entrySet
private transient int
entrySetCallCount
private transient boolean
initialized
private transient boolean
legacyChanged
private transient boolean
servicesChanged
private transient Map
legacyStrings
private transient Map
serviceMap
private transient Map
legacyMap
private transient Set
serviceSet
private static final String
ALIAS_PREFIX
private static final String
ALIAS_PREFIX_LOWER
private static final int
ALIAS_LENGTH
private static volatile ServiceKey
previousKey
private static final Map
knownEngines
Constructors Summary
protected Provider(String name, double version, String info)
Constructs a provider with the specified name, version number, and information.

param
name the provider name.
param
version the provider version number.
param
info a description of the provider and its services.


                                         
           
	this.name = name;
	this.version = version;
	this.info = info;
	putId();
	initialized = true;
    
Methods Summary
private static voidaddEngine(java.lang.String name, boolean sp, java.lang.String paramName)

	EngineDescription ed = new EngineDescription(name, sp, paramName);
	// also index by canonical name to avoid toLowerCase() for some lookups
	knownEngines.put(name.toLowerCase(ENGLISH), ed);
	knownEngines.put(name, ed);
    
private voidcheck(java.lang.String directive)

	checkInitialized();
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkSecurityAccess(directive);
        }
    
private voidcheckInitialized()

	if (!initialized) {
	    throw new IllegalStateException();
	}
    
public synchronized voidclear()
Clears this provider so that it no longer contains the properties used to look up facilities implemented by the provider.

First, if there is a security manager, its checkSecurityAccess method is called with the string "clearProviderProperties."+name (where name is the provider name) to see if it's ok to clear this provider. If the default implementation of checkSecurityAccess is used (that is, that method is not overriden), then this results in a call to the security manager's checkPermission method with a SecurityPermission("clearProviderProperties."+name) permission.

throws
SecurityException if a security manager exists and its {@link java.lang.SecurityManager#checkSecurityAccess} method denies access to clear this provider
since
1.2

	check("clearProviderProperties."+name);
	if (debug != null) {
	    debug.println("Remove " + name + " provider properties");
	}
	implClear();
    
public java.util.Enumerationelements()

	checkInitialized();
	return super.elements();
    
private voidensureLegacyParsed()
Ensure all the legacy String properties are fully parsed into service objects.

	if ((legacyChanged == false) || (legacyStrings == null)) {
	    return;
	}
	serviceSet = null;
	if (legacyMap == null) {
	    legacyMap = new LinkedHashMap<ServiceKey,Service>();
	} else {
	    legacyMap.clear();
	}
	for (Map.Entry<String,String> entry : legacyStrings.entrySet()) {
	    parseLegacyPut(entry.getKey(), entry.getValue());
	}
	removeInvalidServices(legacyMap);
	legacyChanged = false;
    
public synchronized java.util.SetentrySet()
Returns an unmodifiable Set view of the property entries contained in this Provider.

see
java.util.Map.Entry
since
1.2

	checkInitialized();
	if (entrySet == null) {
	    if (entrySetCallCount++ == 0)  // Initial call
		entrySet = Collections.unmodifiableMap(this).entrySet();
	    else
		return super.entrySet();   // Recursive call
	}
	
	// This exception will be thrown if the implementation of 
	// Collections.unmodifiableMap.entrySet() is changed such that it
	// no longer calls entrySet() on the backing Map.  (Provider's
	// entrySet implementation depends on this "implementation detail",
	// which is unlikely to change.
	if (entrySetCallCount != 2)
	    throw new RuntimeException("Internal error.");
	
	return entrySet;
    
public java.lang.Objectget(java.lang.Object key)

	checkInitialized();
	return super.get(key);
    
private static java.lang.StringgetEngineName(java.lang.String s)

	knownEngines = new HashMap<String,EngineDescription>();
	// JCA
	addEngine("AlgorithmParameterGenerator",	false, null);
	addEngine("AlgorithmParameters",		false, null);
	addEngine("KeyFactory",				false, null);
	addEngine("KeyPairGenerator",			false, null);
	addEngine("KeyStore",				false, null);
	addEngine("MessageDigest",			false, null);
	addEngine("SecureRandom",			false, null);
	addEngine("Signature",				true,  null);
	addEngine("CertificateFactory",			false, null);
	addEngine("CertPathBuilder",			false, null);
	addEngine("CertPathValidator",			false, null);
	addEngine("CertStore",				false,
			    "java.security.cert.CertStoreParameters");
	// JCE
	addEngine("Cipher",				true,  null);
	addEngine("ExemptionMechanism",			false, null);
	addEngine("Mac",				true,  null);
	addEngine("KeyAgreement",			true,  null);
	addEngine("KeyGenerator",			false, null);
	addEngine("SecretKeyFactory",			false, null);
	// JSSE
	addEngine("KeyManagerFactory",			false, null);
	addEngine("SSLContext",				false, null);
	addEngine("TrustManagerFactory",		false, null);
	// JGSS
	addEngine("GssApiMechanism",			false, null);
	// SASL
	addEngine("SaslClientFactory",			false, null);
	addEngine("SaslServerFactory",			false, null);
	// POLICY
	addEngine("Policy",				false,
			    "java.security.Policy$Parameters");
	// CONFIGURATION
	addEngine("Configuration",			false,
			    "javax.security.auth.login.Configuration$Parameters");
	// XML DSig
	addEngine("XMLSignatureFactory",		false, null);
	addEngine("KeyInfoFactory",			false, null);
	addEngine("TransformService",			false, null);
	// Smart Card I/O
	addEngine("TerminalFactory",			false,
			    "java.lang.Object");
    
	// try original case first, usually correct
	EngineDescription e = knownEngines.get(s);
	if (e == null) {
	    e = knownEngines.get(s.toLowerCase(ENGLISH));
	}
	return (e == null) ? s : e.name;
    
public java.lang.StringgetInfo()
Returns a human-readable description of the provider and its services. This may return an HTML page, with relevant links.

return
a description of the provider and its services.

	return info;
    
public java.lang.StringgetName()
Returns the name of this provider.

return
the name of this provider.

	return name;
    
public java.lang.StringgetProperty(java.lang.String key)

	checkInitialized();
	return super.getProperty(key);
    
public synchronized java.security.Provider$ServicegetService(java.lang.String type, java.lang.String algorithm)
Get the service describing this Provider's implementation of the specified type of this algorithm or alias. If no such implementation exists, this method returns null. If there are two matching services, one added to this provider using {@link #putService putService()} and one added via {@link #put put()}, the service added via {@link #putService putService()} is returned.

param
type the type of {@link Service service} requested (for example, MessageDigest)
param
algorithm the case insensitive algorithm name (or alternate alias) of the service requested (for example, SHA-1)
return
the service describing this Provider's matching service or null if no such service exists
throws
NullPointerException if type or algorithm is null
since
1.5

	checkInitialized();
	// avoid allocating a new key object if possible
	ServiceKey key = previousKey;
	if (key.matches(type, algorithm) == false) {
	    key = new ServiceKey(type, algorithm, false);
	    previousKey = key;
	}
	if (serviceMap != null) {
	    Service service = serviceMap.get(key);
	    if (service != null) {
		return service;
	    }
	}
	ensureLegacyParsed();
	return (legacyMap != null) ? legacyMap.get(key) : null;
    
public synchronized java.util.SetgetServices()
Get an unmodifiable Set of all services supported by this Provider.

return
an unmodifiable Set of all services supported by this Provider
since
1.5

    
                                 
        
	checkInitialized();
	if (legacyChanged || servicesChanged) {
	    serviceSet = null;
	}
	if (serviceSet == null) {
	    ensureLegacyParsed();
	    Set<Service> set = new LinkedHashSet<Service>();
	    if (serviceMap != null) {
		set.addAll(serviceMap.values());
	    }
	    if (legacyMap != null) {
		set.addAll(legacyMap.values());
	    }
	    serviceSet = Collections.unmodifiableSet(set);
	    servicesChanged = false;
	}
	return serviceSet;
    
private java.lang.String[]getTypeAndAlgorithm(java.lang.String key)

	int i = key.indexOf(".");
	if (i < 1) {
	    if (debug != null) {
		debug.println("Ignoring invalid entry in provider "
			+ name + ":" + key);
	    }
	    return null;
	}
	String type = key.substring(0, i);
	String alg = key.substring(i + 1);
	return new String[] {type, alg};
    
public doublegetVersion()
Returns the version number for this provider.

return
the version number for this provider.

	return version;
    
private voidimplClear()

	if (legacyStrings != null) {
	    legacyStrings.clear();
	}
	if (legacyMap != null) {
	    legacyMap.clear();
	}
	if (serviceMap != null) {
	    serviceMap.clear();
	}
	legacyChanged = false;
	servicesChanged = false;
	serviceSet = null;
	super.clear();
	putId();
    
private java.lang.ObjectimplPut(java.lang.Object key, java.lang.Object value)

	if ((key instanceof String) && (value instanceof String)) {
	    String keyString = (String)key;
	    if (keyString.startsWith("Provider.")) {
		return null;
	    }
	    legacyChanged = true;
	    if (legacyStrings == null) {
		legacyStrings = new LinkedHashMap<String,String>();
	    }
	    legacyStrings.put(keyString, (String)value);
	}
	return super.put(key, value);
    
private voidimplPutAll(java.util.Map t)
Copies all of the mappings from the specified Map to this provider. Internal method to be called AFTER the security check has been performed.

	for (Map.Entry e : ((Map<?,?>)t).entrySet()) {
	    implPut(e.getKey(), e.getValue());
	}
    
private java.lang.ObjectimplRemove(java.lang.Object key)

	if (key instanceof String) {
	    String keyString = (String)key;
	    if (keyString.startsWith("Provider.")) {
		return null;
	    }
	    legacyChanged = true;
	    if (legacyStrings == null) {
		legacyStrings = new LinkedHashMap<String,String>();
	    }
	    legacyStrings.remove(keyString);
	}
	return super.remove(key);
    
private voidimplRemoveService(java.security.Provider$Service s)

	if ((s == null) || (serviceMap == null)) {
	    return;
	}
	String type = s.getType();
	String algorithm = s.getAlgorithm();
	ServiceKey key = new ServiceKey(type, algorithm, false);
	Service oldService = serviceMap.get(key);
	if (s != oldService) {
	    return;
	}
	servicesChanged = true;
	serviceMap.remove(key);
	for (String alias : s.getAliases()) {
	    serviceMap.remove(new ServiceKey(type, alias, false));
	}
	removePropertyStrings(s);
    
public java.util.SetkeySet()
Returns an unmodifiable Set view of the property keys contained in this provider.

since
1.2

	checkInitialized();
	return Collections.unmodifiableSet(super.keySet());
    
public java.util.Enumerationkeys()

	checkInitialized();
	return super.keys();
    
public synchronized voidload(java.io.InputStream inStream)
Reads a property list (key and element pairs) from the input stream.

param
inStream the input stream.
exception
IOException if an error occurred when reading from the input stream.
see
java.util.Properties#load

	check("putProviderProperty."+name);
        if (debug != null) {
            debug.println("Load " + name + " provider properties");
        }
	Properties tempProperties = new Properties();
	tempProperties.load(inStream);
	implPutAll(tempProperties);
    
private voidparseLegacyPut(java.lang.String name, java.lang.String value)

    
          
	if (name.toLowerCase(ENGLISH).startsWith(ALIAS_PREFIX_LOWER)) {
	    // e.g. put("Alg.Alias.MessageDigest.SHA", "SHA-1");
	    // aliasKey ~ MessageDigest.SHA
	    String stdAlg = value;
	    String aliasKey = name.substring(ALIAS_LENGTH);
	    String[] typeAndAlg = getTypeAndAlgorithm(aliasKey);
	    if (typeAndAlg == null) {
		return;
	    }
	    String type = getEngineName(typeAndAlg[0]);
	    String aliasAlg = typeAndAlg[1].intern();
	    ServiceKey key = new ServiceKey(type, stdAlg, true);
	    Service s = (Service)legacyMap.get(key);
	    if (s == null) {
		s = new Service(this);
		s.type = type;
		s.algorithm = stdAlg;
		legacyMap.put(key, s);
	    }
	    legacyMap.put(new ServiceKey(type, aliasAlg, true), s);
	    s.addAlias(aliasAlg);
	} else {
	    String[] typeAndAlg = getTypeAndAlgorithm(name);
	    if (typeAndAlg == null) {
		return;
	    }
	    int i = typeAndAlg[1].indexOf(' ");
	    if (i == -1) {
		// e.g. put("MessageDigest.SHA-1", "sun.security.provider.SHA");
		String type = getEngineName(typeAndAlg[0]);
		String stdAlg = typeAndAlg[1].intern();
		String className = value;
		ServiceKey key = new ServiceKey(type, stdAlg, true);
		Service s = (Service)legacyMap.get(key);
		if (s == null) {
		    s = new Service(this);
		    s.type = type;
		    s.algorithm = stdAlg;
		    legacyMap.put(key, s);
		}
		s.className = className;
	    } else { // attribute
		// e.g. put("MessageDigest.SHA-1 ImplementedIn", "Software");
		String attributeValue = value;
		String type = getEngineName(typeAndAlg[0]);
		String attributeString = typeAndAlg[1];
		String stdAlg = attributeString.substring(0, i).intern();
		String attributeName = attributeString.substring(i + 1);
		// kill additional spaces
		while (attributeName.startsWith(" ")) {
		    attributeName = attributeName.substring(1);
		}
		attributeName = attributeName.intern();
		ServiceKey key = new ServiceKey(type, stdAlg, true);
		Service s = (Service)legacyMap.get(key);
		if (s == null) {
		    s = new Service(this);
		    s.type = type;
		    s.algorithm = stdAlg;
		    legacyMap.put(key, s);
		}
		s.addAttribute(attributeName, attributeValue);
	    }
	}
    
public synchronized java.lang.Objectput(java.lang.Object key, java.lang.Object value)
Sets the key property to have the specified value.

First, if there is a security manager, its checkSecurityAccess method is called with the string "putProviderProperty."+name, where name is the provider name, to see if it's ok to set this provider's property values. If the default implementation of checkSecurityAccess is used (that is, that method is not overriden), then this results in a call to the security manager's checkPermission method with a SecurityPermission("putProviderProperty."+name) permission.

param
key the property key.
param
value the property value.
return
the previous value of the specified property (key), or null if it did not have one.
throws
SecurityException if a security manager exists and its {@link java.lang.SecurityManager#checkSecurityAccess} method denies access to set property values.
since
1.2

	check("putProviderProperty."+name);
        if (debug != null) {
            debug.println("Set " + name + " provider property [" + 
			  key + "/" + value +"]");
        }
	return implPut(key, value);
    
public synchronized voidputAll(java.util.Map t)
Copies all of the mappings from the specified Map to this provider. These mappings will replace any properties that this provider had for any of the keys currently in the specified Map.

since
1.2

	check("putProviderProperty."+name);
        if (debug != null) {
            debug.println("Put all " + name + " provider properties");
        }
	implPutAll(t);
    
private voidputId()

	// note: name and info may be null
	super.put("Provider.id name", String.valueOf(name));
	super.put("Provider.id version", String.valueOf(version));
	super.put("Provider.id info", String.valueOf(info));
	super.put("Provider.id className", this.getClass().getName());
    
private voidputPropertyStrings(java.security.Provider$Service s)
Put the string properties for this Service in this Provider's Hashtable.

	String type = s.getType();
	String algorithm = s.getAlgorithm();
	// use super() to avoid permission check and other processing
	super.put(type + "." + algorithm, s.getClassName());
	for (String alias : s.getAliases()) {
	    super.put(ALIAS_PREFIX + type + "." + alias, algorithm);
	}
	for (Map.Entry<UString,String> entry : s.attributes.entrySet()) {
	    String key = type + "." + algorithm + " " + entry.getKey();
	    super.put(key, entry.getValue());
	}
    
protected synchronized voidputService(java.security.Provider$Service s)
Add a service. If a service of the same type with the same algorithm name exists and it was added using {@link #putService putService()}, it is replaced by the new service. This method also places information about this service in the provider's Hashtable values in the format described in the Java Cryptography Architecture API Specification & Reference .

Also, if there is a security manager, its checkSecurityAccess method is called with the string "putProviderProperty."+name, where name is the provider name, to see if it's ok to set this provider's property values. If the default implementation of checkSecurityAccess is used (that is, that method is not overriden), then this results in a call to the security manager's checkPermission method with a SecurityPermission("putProviderProperty."+name) permission.

param
s the Service to add
throws
SecurityException if a security manager exists and its {@link java.lang.SecurityManager#checkSecurityAccess} method denies access to set property values.
throws
NullPointerException if s is null
since
1.5

	check("putProviderProperty." + name);
	if (debug != null) {
            debug.println(name + ".putService(): " + s);
	}
	if (s == null) {
	    throw new NullPointerException();
	}
	if (s.getProvider() != this) {
	    throw new IllegalArgumentException
		    ("service.getProvider() must match this Provider object");
	}
	if (serviceMap == null) {
	    serviceMap = new LinkedHashMap<ServiceKey,Service>();
	}
	servicesChanged = true;
	String type = s.getType();
	String algorithm = s.getAlgorithm();
	ServiceKey key = new ServiceKey(type, algorithm, true);
	// remove existing service
	implRemoveService(serviceMap.get(key));
	serviceMap.put(key, s);
	for (String alias : s.getAliases()) {
	    serviceMap.put(new ServiceKey(type, alias, true), s);
	}
	putPropertyStrings(s);
    
private voidreadObject(java.io.ObjectInputStream in)

	Map<Object,Object> copy = new HashMap<Object,Object>();
	for (Map.Entry<Object,Object> entry : super.entrySet()) {
	    copy.put(entry.getKey(), entry.getValue());
	}
	defaults = null;
	in.defaultReadObject();
	implClear();
	initialized = true;
	putAll(copy);
    
public synchronized java.lang.Objectremove(java.lang.Object key)
Removes the key property (and its corresponding value).

First, if there is a security manager, its checkSecurityAccess method is called with the string "removeProviderProperty."+name, where name is the provider name, to see if it's ok to remove this provider's properties. If the default implementation of checkSecurityAccess is used (that is, that method is not overriden), then this results in a call to the security manager's checkPermission method with a SecurityPermission("removeProviderProperty."+name) permission.

param
key the key for the property to be removed.
return
the value to which the key had been mapped, or null if the key did not have a mapping.
throws
SecurityException if a security manager exists and its {@link java.lang.SecurityManager#checkSecurityAccess} method denies access to remove this provider's properties.
since
1.2

	check("removeProviderProperty."+name);
        if (debug != null) {
            debug.println("Remove " + name + " provider property " + key);
        }
	return implRemove(key);
    
private voidremoveInvalidServices(java.util.Map map)
Remove all invalid services from the Map. Invalid services can only occur if the legacy properties are inconsistent or incomplete.

	for (Iterator t = map.entrySet().iterator(); t.hasNext(); ) {
	    Map.Entry entry = (Map.Entry)t.next();
	    Service s = (Service)entry.getValue();
	    if (s.isValid() == false) {
		t.remove();
	    }
	}
    
private voidremovePropertyStrings(java.security.Provider$Service s)
Remove the string properties for this Service from this Provider's Hashtable.

	String type = s.getType();
	String algorithm = s.getAlgorithm();
	// use super() to avoid permission check and other processing
	super.remove(type + "." + algorithm);
	for (String alias : s.getAliases()) {
	    super.remove(ALIAS_PREFIX + type + "." + alias);
	}
	for (Map.Entry<UString,String> entry : s.attributes.entrySet()) {
	    String key = type + "." + algorithm + " " + entry.getKey();
	    super.remove(key);
	}
    
protected synchronized voidremoveService(java.security.Provider$Service s)
Remove a service previously added using {@link #putService putService()}. The specified service is removed from this provider. It will no longer be returned by {@link #getService getService()} and its information will be removed from this provider's Hashtable.

Also, if there is a security manager, its checkSecurityAccess method is called with the string "removeProviderProperty."+name, where name is the provider name, to see if it's ok to remove this provider's properties. If the default implementation of checkSecurityAccess is used (that is, that method is not overriden), then this results in a call to the security manager's checkPermission method with a SecurityPermission("removeProviderProperty."+name) permission.

param
s the Service to be removed
throws
SecurityException if a security manager exists and its {@link java.lang.SecurityManager#checkSecurityAccess} method denies access to remove this provider's properties.
throws
NullPointerException if s is null
since
1.5

	check("removeProviderProperty." + name);
        if (debug != null) {
            debug.println(name + ".removeService(): " + s);
        }
	if (s == null) {
	    throw new NullPointerException();
	}
	implRemoveService(s);
    
public java.lang.StringtoString()
Returns a string with the name and the version number of this provider.

return
the string with the name and the version number for this provider.

	return name + " version " + version;
    
public java.util.Collectionvalues()
Returns an unmodifiable Collection view of the property values contained in this provider.

since
1.2

	checkInitialized();
	return Collections.unmodifiableCollection(super.values());