Book Home Java Security Search this book

8.3. The Security Class

The Security class (java.security.Security) is responsible for managing the set of provider classes that a Java program can use, and forms the last link in the architecture of the security provider. This class is final, and all its methods are static (except for its constructor, which is private). Like the System and Math classes, then, the Security class can never be created or subclassed; it exists simply to provide a placeholder for methods that deal with the java.security package.

Earlier, we explained how to add entries to the java.security file to add new providers to the security architecture. The same feat can be accomplished programmatically via these methods of the Security class:

public static int addProvider(Provider provider)

Add a new provider into the list of providers. The provider is added to the end of the internal array of providers.

public static int insertProviderAt(Provider provider, int position)

Add a new provider into the internal array of providers. The provider is added at the specified position; other providers have their index changed if necessary to make room for this provider. Position counting begins at 1.

The notion that these classes are kept in an indexed array is important; when the Security class is asked to provide a particular algorithm for an operation, the array is searched sequentially for a provider that can provide the requested algorithm for the requested operation.

As an example, let's use a modification of the XYZProvider class that we outlined earlier. This class comes with a set of classes to perform generation of key pairs, and it can generate key pairs according to two algorithms: DSA and XYZ. The XYZProvider class, according to an entry added to the java.security file, has been added at position 2. Additionally, let's say that our Java program has installed an additional provider class at position 3 called the FooProvider that can generate key pairs and digital signatures according to a single algorithm known as Foo. This leaves us with the set of provider classes listed in Table 8-3.

Table 8-3. Sample Security Providers

Sun Provider

XYZ Provider

Foo Provider

Class Definition

Signature Engines
    DSA

Class Definition

Signature Engines
    XYZ
    DSA

Class Definition

Signature Engines
    Foo

Class Definition

Message Digest Engines
    MD5

Class Definition

Message Digest Engines
    XYZ
    SHA

Class Definition

Message Digest Engines
    None

Class Definition

Key Pair Engines
    DSA

Class Definition

Key Pair Engines
    XYZ
    DSA

Class Definition

Key Pair Engines
    Foo

Now when our Java program needs to generate a key pair, the security provider is consulted as to which classes will implement the key pair generation we want. If we need to generate a DSA key, the security provider returns to us a class associated with the Sun provider class, since the Sun provider, at position 1, is the first class that says that it can perform DSA key generation. If we had reversed the order of indices in the java.security file so that the Sun provider was at position 2 and the XYZ provider was at position 1, a class associated with the XYZ provider would have been returned instead. Similarly, when we request a Foo key pair, a class associated with the Foo provider is returned to us, regardless of what index it occurs at, since that is the only provider class that knows how to perform Foo key generation.

Remember that this is a two-step process. The security class receives a string (like KeyPairGenerator.DSA) and locates a class that provides that service (such as sun.security.provider.Sun). The Sun class, as a provider class, does not actually know how to generate keys (or do anything else)--it only knows what classes in the Sun security package know how to generate keys. Then the security class must ask the provider itself for the name of the class that actually implements the desired operation. That process is handled by an internal method of the Security class--we'll use that method implicitly over the next few chapters when we retrieve objects that implement a particular engine and algorithm. Before we do that, though, we'll finish looking at the interface of the Security class.

There are a number of other methods in the Security class that provide basic information about the configuration of the security provider.

public static void removeProvider(String name)

Remove the named provider from the list of provider classes. The remaining providers move up in the array of providers if necessary. If the named provider is not in the list, this method silently returns (i.e., no exception is thrown).

public static Provider[] getProviders()

Return a copy of the array of providers on which the Security class operates. Note that this is a copy of the array; reordering its elements has no effect on the Security class.

public static Provider getProvider(String name)

Return the provider with the given name. If the named provider is not in the list held by the Security class, this method returns null.

public static String getProperty(String key)

Get the property of the Security class with the associated key. The properties held in the Security class are the properties that were read from the java.security file. In typical usage, one of the properties is security.provider.1 (as well as any other providers listed in the java.security file). Note, however, that properties of this sort may not reflect the actual order of the provider classes: when the addProvider(), insertProviderAt(), and removeProvider() methods are called, the order of the providers changes. These changes are not reflected in the internal property list.

The java.security file has a number of other properties within it; these other properties may also be retrieved via this method.

public static String setProperty(String key)

Set the property of the security class with the associated key.

public static String getAlgorithmProperty(String algName, String propName)figure

Search all the providers for a property in the form Alg.propName.algName and return the first match it finds. For example, if a provider had set the Alg.NativeImplementation.XYZ property to the string "false," a call to getAlgorithmName("XYZ","NativeImplementation") returns the string "false" (which is why earlier we used a string value in the provider class).

Here's a simple example, then, of how to see a list of all the security providers in a particular virtual machine:

Class Definition

public class ExamineSecurity {
	public static void main(String args[]) {
		try {
			Provider p[] = Security.getProviders();
			for (int i = 0; i < p.length; i++) {
				System.out.println(p[i]);
				for (Enumeration e = p[i].keys(); e.hasMoreElements();)
					System.out.println("\t" + e.nextElement());
			}
		}
		catch (Exception e) {
			System.out.println(e);
		}
	}
}

If we run this program with the 1.2 Sun security provider, we get this output:

Class Definition

SUN version 1.2
        Alg.Alias.MessageDigest.SHA
        Alg.Alias.Signature.SHAwithDSA
        Alg.Alias.Signature.1.3.14.3.2.13
        Alg.Alias.Signature.OID.1.2.840.10040.4.3
        Alg.Alias.Signature.SHA-1/DSA
        Alg.Alias.Signature.DSS
        Alg.Alias.Signature.SHA1withDSA
        Alg.Alias.Signature.OID.1.3.14.3.2.13
        AlgorithmParameters.DSA
        KeyFactory.DSA
        Alg.Alias.Signature.1.2.840.10040.4.3
        Alg.Alias.MessageDigest.SHA1
        AlgorithmParameterGenerator.DSA
        Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1
        MessageDigest.MD5
        Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1
        MessageDigest.SHA-1
        Alg.Alias.KeyPairGenerator.OID.1.3.14.3.2.12
        Signature.DSA
        Alg.Alias.KeyPairGenerator.1.3.14.3.2.12
        Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1
        Alg.Alias.Signature.1.3.14.3.2.27
        Alg.Alias.Signature.SHA/DSA
        KeyPairGenerator.DSA
        Alg.Alias.Signature.SHA1/DSA
        Alg.Alias.Signature.OID.1.3.14.3.2.27
        Alg.Alias.AlgorithmParameters.1.3.14.3.2.12
		KeyStore.JKS
		CertificateFactory.X509
		Alg.Alias.CertificateFactory.X.509
		SecureRandom.SHA1PRNG

Two things are readily apparent from this example. First, the strings that contain only an engine name and an algorithm implement the expected operations that we listed in Table 8-1. Second, as we mentioned in the section on the Provider class, security providers often leverage the fact that the Provider class is a subclass of the Properties class to provide properties that may make sense only to other classes that are part of the provider package. Hence, the signature algorithm 1.3.14.3.2.13 may make sense to one of the classes in the Sun security provider, but it is not a string that will necessarily make sense to other developers. In fact, those aliases--including the ones that are prefaced by OID--do have meanings within the cryptography standards world, but for our purposes we'll stick with the standard algorithm names that we listed earlier.

8.3.1. The Security Class and the Security Manager

All the public methods of the Security class call the checkSecurityAccess() method of the security manager. This gives the security manager the opportunity to intervene before an untrusted class affects the security policy of the virtual machine.

Recall that the checkSecurityAccess() method accepts a single string parameter. In the case of the methods in the Security class, the call that is made looks like this:

Class Definition

public static Provider getProvider(String name) {
	SecurityManager sec = System.getSecurityManager();
	if (sec != null)
		sec.checkSecurityAccess("java");
	... continue to find the provider ...
}

The string parameter that is sent to the checkSecurityAccess() method has changed between releases of Java; the various methods and the strings they pass to the security manager are listed in Table 8-4.

Table 8-4. Security Checks of the Security Class

Method

1.2 Parameter

1.1 Parameter

Class Definition

insertProviderAt()

Class Definition

insertProvider. + provider.getName()

Class Definition

java

Class Definition

removeProvider()

Class Definition

removeProvider. + provider.getName()

Class Definition

java

Class Definition

getProviders()

-- not called --

Class Definition

java

Class Definition

getProvider()

-- not called --

Class Definition

java

Class Definition

getProperty()

Class Definition

getProperty. + key

Class Definition

java

Class Definition

setProperty()

Class Definition

setProperty. + key

Class Definition

java

In typical usage in 1.1, the security manager ignores this string altogether and simply allows all trusted classes to call these methods and prevents all untrusted classes from calling these methods. In 1.2, the security manager constructs a security permission for the given name and calls the access controller to see if the given permission has been granted.



Library Navigation Links

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