you can edit this file and add those providers at the next numbers. When you obtain JCE, you are told that its providers class name is
com.sun.crypto.provider.SunJCE ; the classname of the provider in JSSE
is com.sun.net.ssl.internal.ssl.Provider
. Hence, to use these providers you add these lines to the java.security file as we did in Chapter 1:
security.provider.3=com.sun.crypto.provider.SunJCE security.provider.4=com.sun.net.ssl.internal.ssl.Provider
Note that theres no reason why the new provider classes had to be added at positions 3 and 4 −− it would have been perfectly acceptable to add the
SunJCE class as
security.provider.1 if the
sun.security.provider.Sun class were changed to
security.provider.3 or, alternately,
removed altogether. The Security
class keeps the instances of the providers in an array so that each class is found at the index specified in the java.security file. As long as the providers in the java.security file begin
with 1 and are numbered consecutively, they may appear in any order. The order of these properties is significant; when the
Security class is asked to provide a particular engine
and algorithm, it searches the listed providers in order to find the first one that can supply the desired operation. All engine classes use the security class to supply objects. When the message digest engine is asked
to provide an object capable of generating SHA message digests, the engine will ask the Security
class which provider to use. If the first provider in the list can perform SHA message digests, that provider will be
used. Otherwise, the second provider is checked, and so on, until there are no providers left and an exception is thrown or until a provider that implements the desired operation is found. Hence, the number that follows
the security.provider
string indicates the order in which providers will be searched for particular implementations.
Note that the classes that are listed in this manner must be installed into the system classpath. The security infrastructure will use only the system class loader to locate these classes, which is why they are usually
installed as an extension in JREHOMElibext. If you write your own security provider as we do in the next section, that provider must either be installed programatically or the classes that encompass the provider must
be installed as an extension.
For end users and administrators, thats all there is to adding new security providers. For developers, there is also a programmatic way in which a security provider may be added; well explore that when we discuss the
interface of the Security
class. But as we mentioned earlier, the programmatic interface provided by the two classes were about to discuss is not often needed; youd need it only if you wanted to supply your own
security provider or if you wanted to inspect or set programmatically the list of existing providers. Otherwise, the classes are interesting only because they are used by the engine classes well begin to examine in the next
chapter.
8.2 The Provider Class
The first class well examine in depth is the Provider
class java.security.Provider
. public abstract class Provider extends Properties
This class forms the basis of the security provider architecture. There is normally a standard subclass that implements a default security feature set; other classes can be installed to implement other
security algorithms.
In the core Java API, the Provider
class is abstract and there are no classes in the core Java API that extend the
Provider class. The default provider class that comes with Suns implementation of Java is the class
Sun in the
sun.security.provider package. However, since this class is in the
sun package, theres
no guarantee that it will be available with every implementation of the Java virtual machine; other Chapter 8. Security Providers
implementations may supply a different provider. In theory, this should not matter. The concepts of the security package will work according to the
specification as long as the Java implementation provides an appropriate provider class and appropriate classes to perform the operations a Java program will expect. The exact set of classes a particular program
may expect will depend, of course, on the program. In the next section, well discuss how different implementations of the
Provider class may be loaded and used during the execution of the virtual machine.
8.2.1 Using the Provider Class
The Provider
class is seldom used directly by a programmer. This class does contain a number of useful miscellaneous methods well review here; these methods are generally informational and would be used
accordingly:
public String getName Return the name of the provider.
public double getVersion Return the version number of the provider.
public String getInfo Return the info string of the provider.
public String toString Return the string specifying the provider; this is typically the providers name concatenated with the
providers version number. As an extension of the
Properties class, the
Provider class also shares its public interface. The
Provider class overrides three of those methods:
public synchronized void clear If permission is granted, clear out all entries from the provider.
public synchronized Object putObject key, Object value If permission is granted, add the given property, keyed off the given key.
public synchronized Object removeObject key If permission is granted, remove the object associated with the given key.
These methods are overridden so that the Provider
class can ensure that the program has sufficient permissions to perform the operation. These methods call the
checkSecurityAccess method of the
security manager, which in turn uses the access controller to determine if the current classes have been granted a
SecurityPermission with the appropriate name. The string used for the
clear method is
clearProviderProperties.name ; for the
put method, it is
putProviderProperty.name ;
and for the remove
method, it is removeProviderProperty.name
. The name in these strings is 128
replaced by the name of the provider itself e.g., Sun
for the standard security provider. Since the interface to this class is simple, we wont actually show how it is used, although we will use some of
these methods later in this chapter. Note also that there is no public constructor for the Provider
class −− a provider can only be constructed under special circumstances well discuss later.
8.2.2 Implementing the Provider Class
If youre going to provide your own set of classes to perform security operations, you must extend the Provider
class and register that class with the security infrastructure. In this section, well explore how to do that. Most of the time, of course, you will not implement your own
Provider class −− youll just use the
default providers or perhaps install a third−party provider using the techniques that we explore in the next section.
Although the Provider
class is abstract, none of its methods are abstract. This means that implementing a provider is, at first blush, simple: all you need do is subclass the
Provider class and provide an appropriate
constructor. The subclass must provide a constructor since there is no default constructor within the Provider
class. The only constructor available to us is: protected ProviderString name, double version, String info
Construct a provider with the given name, version number, and information string. Hence, the basic implementation of a security provider is:
public class XYZProvider extends Provider { public XYZProvider {
superXYZ, 1.0, XYZ Security Provider v1.0; }
}
Here were defining the skeleton of a provider that is going to provide certain facilities based on various algorithms of the XYZ Corporation. Throughout the remainder of this book, well be developing the classes
that apply to the XYZs cryptographic methods, but they will be examples only −− they lack the rigorous mathematical properties that these algorithms must have. In practice, you might choose to implement
algorithms that correspond to the RSA algorithms for the cryptographic engines. Good examples of implementing cryptographic algorithms can be found in Jonathan Knudsens Java Cryptography OReilly.
Note we used a default constructor in this class rather than providing a constructor similar to the one found in the
Provider class itself. The reason for this has to do with the way providers are constructed, which we
discuss at the end of this section. When you write a provider, it must provide a constructor with no arguments. This is a complete, albeit useless, implementation of a provider. In order to add some functionality to our
provider, we must put some associations into the provider. The associations will perform the mapping that we mentioned earlier; it is necessary for the provider to map the name of an engine and algorithm with the name
of a class that implements that operation. This is why the
Provider class itself is a subclass of the
Properties class −− so that we can make each of those associations into a property.
The operations that our provider will be consulted about are listed in Table 8−2. In this example, were going to be providing an SHA algorithm for performing message digests since that would be needed as part of the
signature generation algorithm we want to implement. Theres no absolute requirement for this; we could have depended on the default Sun security provider to supply this algorithm for us. On the other hand, theres no
guarantee that the default security provider will be in place when our security provider is installed, so its a good idea for a provider to include all the algorithms it will need.