Book Home Java Security Search this book

8.4. The Architecture of Engine Classes

In the next few chapters, we'll discuss the engine classes that are part of the core Java API. All engine classes share a similar architecture that we'll discuss here.

Most programmers are only interested in using the engine classes to perform their desired operation; each engine class has a public interface that defines the operations the engine can perform. None of this is unusual: it is the basis of programming in Java.

However, the engine classes are designed so that users can employ third-party security providers (using the architecture we've just examined). For programmers who are interested in writing such providers, the engine classes have an additional interface called the security provider interface (SPI). The SPI is a set of abstract methods that a particular engine must implement in order to fulfill its contract of providing a particular operation.

The role of the SPI has changed between Java 1.1 and Java 1.2. In 1.1, the SPI was simply a convention. There were a set of protected, usually abstract, methods in each engine that made up the SPI. By convention, these methods begin with the word "engine"; implementing a 1.1 engine is a matter of implementing each of these protected methods.

In 1.2, the interface of an engine was split between two distinct classes: the engine class itself and the SPI class. For example, in 1.2 there is an engine class called MessageDigest, and its SPI class is called MessageDigestSpi. For historic reasons, there are differences in various engine classes between the engine class itself and the SPI.

There were three engine classes in 1.1. In 1.2, the SPI class for these classes is a superclass of the engine class; e.g., the MessageDigest class extends the MessageDigestSpi class. This allows the MessageDigest class in 1.2 to have the same interface as it does in 1.1, even though the class hierarchy to which it belongs has changed.

There are six new engine classes in 1.2, and for these classes, the SPI is unrelated to the class itself; e.g., there is a KeyFactory class and a KeyFactorySpi class, both of which simply subclass the Object class. In these cases, the engine class contains an instance of the SPI that it uses to carry out its operations. Table 8-5 summarizes the nine core Java engine classes and their corresponding SPI.

Table 8-5. Engine Classes in the Core Java API

Engine

SPI Class

Engine Superclass

Class Definition

AlgorithmParameters figure

Class Definition

AlgorithmParametersSpi

Class Definition

Object

Class Definition

AlgorithmParameterGenerator figure

Class Definition

AlgorithmParameterGeneratorSpi

Class Definition

Object

Class Definition

CertificateFactory figure

Class Definition

CertificateFactorySpi

Class Definition

Object

Class Definition

KeyFactory figure

Class Definition

KeyFactorySpi

Class Definition

Object

Class Definition

KeyPairGenerator

Class Definition

KeyPairGeneratorSpi

Class Definition

KeyPairGeneratorSpi

Class Definition

KeyStore figure

Class Definition

KeyStoreSpi

Class Definition

Object

Class Definition

MessageDigest

Class Definition

MessageDigestSpi

Class Definition

MessageDigestSpi

Class Definition

SecureRandom figure

Class Definition

SecureRandomSpi

Class Definition

Object

Class Definition

Signature

Class Definition

SignatureSpi

Class Definition

SignatureSpi

What this all means is that if you want to implement a security provider under Java 1.2, you would typically extend the SPI. This allows a developer to request a particular engine and receive the correct class according to the following algorithm:

  1. The programmer requests an instance of a particular engine that implements a particular algorithm. Engine classes never have public constructors; instead, every engine has a getInstance() method that takes the name of the desired algorithm as an argument and returns an instance of the appropriate class.

  2. The Security class is asked to consult its list of providers and provide the appropriate instance. For example, when the getInstance() method of the MessageDigest class is called, the Security class may determine that the appropriate provider class is called com.xyz.XYZMessageDigest.

  3. If the retrieved class does not extend the appropriate SPI (e.g., java.security.MessageDigestSpi in this case), a NoSuchAlgorithmException is generated.

  4. An instance of the retrieved class is created and returned to the getInstance() method (which in turn returns it to the developer).

For consistency, when you implement any engine class in 1.2, it is always possible to extend the appropriate SPI. However, when you implement one of the three engines that are part of 1.1, it may make more sense to extend the engine class (e.g., the MessageDigest class) rather than the SPI (e.g., the MessageDigestSpi class). This allows the implementation to be used under both 1.1 and 1.2. An engine class that directly subclasses its SPI in 1.2 cannot be used in 1.1, while an engine class that directly subclasses a Java engine class can be used in both 1.1 and 1.2. That is the convention we'll follow in our examples.



Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.