Components of the Architecture

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.