Skip Headers
Oracle® Fusion Middleware Application Security Guide
11g Release 1 (11.1.1)

Part Number E10043-12
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
PDF · Mobi · ePub

27 Developing with the Keystore Service

This chapter explains how to utilize the Keystore Service when developing applications.

27.1 About the Keystore Service API

A keystore is used for secure storage of and access to keys and certificates. The Keystore Service API is used to access and perform operations on the keystores.

The Keystore Service:

Critical (create, update, delete) functions provided by the Keystore Service API include:

Operations on a KeyStore are secured by KeyStoreAccessPermission, which implements the fine-grained access control model utilized by the Keystore Service.

27.2 Overview of Application Development with the Keystore Service

Knowledge of the following areas is helpful in getting your applications to work with the Keystore Service:

27.3 Setting the Java Security Policy Permission

The Oracle Platform Security Services keystore provider is set when the server is started. When the provider is file-based, the data is stored in system-jazn-data.xml.

Keystore Service supports securing keys:

Notes:

  • To properly access the Keystore Service APIs, you need to grant Java permissions in the policy store.

  • The code invoking Keystore Service APIs needs code source permission. The permissions are typically for specific code jars and not for the complete application.

This section provides guidelines for permission grants to keystore objects, along with several examples:

Note:

In the examples, the application jar file name is AppName.jar.

27.3.1 Guidelines for Granting Permissions

The Keystore Service relies on Java permissions to grant permissions to keystore or key objects. It is highly recommended that only the requisite permissions be granted, and no more.

WARNING:

It is risky and inadvisable to grant unnecessary permissions, particularly permissions to all application stripes and/or keystores.

27.3.2 Permissions Grant Example 1

The Keystore Service stores objects in a hierarchy:

application stripe -> keystore(s) -> key(s)/certificate(s)

See Also:

Section 11.1.1 for details about the object hierarchy in the Keystore Service.

This example grants permissions for a specific application stripe and a specific keystore name within that stripe.

<jazn-policy>
    <grant>
        <grantee>
            <principals>...</principals>
            <!-- This is the location of the jar -->
            <!-- as loaded with the run-time -->
            <codesource>
      <url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
            </codesource>
        </grantee>
        <permissions>
            <permission>
               <class>oracle.security.jps.service.keystore.
                      KeyStoreAccessPermission</class>
               <name>stripeName=keystoreapp,keystoreName=ks1,alias=*</name>
              <!-- All actions are granted -->
              <actions>*</actions>
            </permission>
        </permissions>
    </grant>
</jazn-policy>

where:

  • stripeName is the name of the application stripe (typically the name of the application) for which you want to grant these permissions (read, write, update, and delete permissions denoted by the wildcarded actions).

  • keystoreName is the key store name in use.

  • alias indicates the key alias within the key store.

    Note:

    The wildcard indicates the application is granted permission for all aliases.

27.3.3 Permissions Grant Example 2

In this example, permissions are granted for a specific application stripe name and all its keystores.

<jazn-policy>
    <grant>
        <grantee>
            <principals>...</principals>
            <codesource>
      <url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
            </codesource>
        </grantee>
        <permissions>
           <permission>
              <class>oracle.security.jps.service.keystore.
                     KeyStoreAccessPermission</class>
              <name>stripeName=keystoreapp,keystoreName=*,alias=*</name>
              <!-- Certain actions are explicitly specified -->
              <!-- Compare to wild-card grant in previous example -->
              <actions>read,write,update,delete</actions>
        </permission>
        </permissions>
    </grant>
</jazn-policy>

27.3.4 Permissions Grant Example 3

In this example, read permissions are granted for a specific key alias within an application stripe name and a keystore.

<jazn-policy>
    <grant>
        <grantee>
            <principals>...</principals>
            <codesource>
      <url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
            </codesource>
        </grantee>
        <permissions>
           <permission>
              <class>oracle.security.jps.service.keystore.
                     KeyStoreAccessPermission</class>
              <name>stripeName=keystoreapp,keystoreName=ks1,alias=orakey</name>
              <actions>read</actions>
        </permission>
        </permissions>
    </grant>
</jazn-policy>

27.4 Configuring the Keystore Service

You need to define the Keystore Service instance in a configuration file which contains information about the location of the keystore and the provider classes. Configuration files are located in:

$DOMAIN_HOME/config/fmwconfig

and are named as follows:

27.5 Steps for Using the Keystore Service API

You can use the Keystore Service within Oracle WebLogic Server or in a standalone environment.

27.5.1 Using the Keystore Service API in a Standalone Environment

The steps for using the API in a standalone environment are:

  1. Set up the classpath. Ensure that the jps-manifest.jar file is in your classpath. For details, see Required JAR in Classpath in Section 1.5.3, "Scenario 3: Securing a Java SE Application".

  2. Set up the policy; to provide access to the Keystore Service APIs, you need to configure the access permissions in the reference policy store. For examples, see Section 27.3, "Setting the Java Security Policy Permission".

  3. Run the application.

Command-line options include:

  • -Doracle.security.jps.config
    

    specifies the full path to the configuration file

  • -Djava.security.policy
    

    specifies the location of the OPSS/Oracle WebLogic Server policy file

  • -Djava.security.debug=all
    

    is helpful for debugging purposes

27.5.2 Using the Keystore Service API in Oracle WebLogic Server

Take these steps to use the API in an Oracle WebLogic Server environment:

  1. Out-of-the-box, the keystore service provider section of the jps-config.xml file is configured in the following directory:

    $DOMAIN_HOME/config/fmwconfig
    

    If needed, reassociate to an LDAP or database store.

  2. Set up the policy. To provide access to the Keystore Service APIs, you need to configure the access permissions in the reference policy store. For examples, see Section 27.3, "Setting the Java Security Policy Permission".

  3. Start Oracle WebLogic Server.

  4. Deploy and test the application.

27.6 Example of Keystore Service API Usage

This section provides an example of using the key store service APIs. It contains these topics:

27.6.1 Java Program for Keystore Service Operations

The following Java code demonstrates common Keystore Service operations:

import oracle.security.jps.JpsContext;
import oracle.security.jps.JpsContextFactory;
import oracle.security.jps.JpsException;
import oracle.security.jps.internal.policystore.JavaPolicyProvider;
import oracle.security.jps.service.keystore.KeyStoreProperties;
import oracle.security.jps.service.keystore.KeyStoreService;
import oracle.security.jps.service.keystore.KeyStoreServiceException;
 
import java.security.AccessController;
import java.security.PrivilegedAction;
 
public class KeyStoreTest {
 
    static {
        java.security.Policy.setPolicy(new JavaPolicyProvider());
    }
 
    private static KeyStoreService ks = null;
 
 
    public KeyStoreTest() {
        super();
    }
 
    /*
     * This method performs a non-privileged operation. Either all code
     * in the call stack must have KeyStoreAccessPermission
     * OR
     * the caller must have the KeyStoreAccessPermission only and
     * invoke this operation in doPrivileged block
     */
    public static void doKeyStoreOperation() {
        doOperation();
    }

     /*
     * Since this method performs a privileged operation, only current class or
     * jar containing this class needs KeyStoreAccessPermission
     */
    public static void doPrivilegedKeyStoreOperation() {
        AccessController.doPrivileged(new PrivilegedAction<String>() {
            public String run() {
                doOperation();
                return "done";
            }
        });
    }
 
    private static void doOperation() {
        try {
            ks.deleteKeyStore("keystoreapp", "ks1", null);
        } catch(KeyStoreServiceException e) {
            e.printStackTrace();
        }

     /*
     * Since this method performs a privileged operation, only current class or
     * jar containing this class needs KeyStoreAccessPermission
     */
    public static void doPrivilegedKeyStoreOperation() {
        AccessController.doPrivileged(new PrivilegedAction<String>() {
            public String run() {
                doOperation();
                return "done";
            }
        });
    }
 
    private static void doOperation() {
        try {
            ks.deleteKeyStore("keystoreapp", "ks1", null);
        } catch(KeyStoreServiceException e) {
            e.printStackTrace();
        }

 public static void main(String args[]) throws Exception {
 
        try {
 
            JpsContext ctx = JpsContextFactory.getContextFactory().getContext();
            ks = ctx.getServiceInstance(KeyStoreService.class);
            
            // #1 - this call is in a doPrivileged block
            // #1 - this should succeed.
            doPrivilegedKeyStoreOperation();
 
            // #2 - this will also pass since granted all application
            // code necessary permission
            // NOTE: Since this call is not in a doPrivileged block,
            // this call would have failed if KeyStoreAccessPermission
            // wasn't granted to this class.
 
            /*
            doKeyStoreOperation();
            */
            
        } catch (JpsException je) {
            je.printStackTrace();
        }
 
    }
}

27.6.2 Policy Store Setup

For illustration, the example uses an xml-based policy store file (system-jazn-data.xml) which has the appropriate permissions needed to access the given key store from the store. The file defines the permissions for different combinations of application stripe and key store name. Other combinations, or attempts to access the store beyond the permissions defined here, will be disallowed.

Note:

The default policy store to which this grant is added is $DOMAIN_HOME/config/fmwconfig/system-jazn-data.xml.

Here the system property projectsrc.home is set to point to the directory containing the Java SE application, and clientApp.jar is the application jar file which is present in sub-directory dist.

The corresponding policy grant looks like this:

<grant>
   <grantee>
      <codesource>
         <url>file:${projectsrc.home}/dist/clientApp.jar</url>
      </codesource>
   </grantee>
   <permissions>
      <permission>
         <class>oracle.security.jps.service.keystore.KeyStoreAccessPermission
         </class>
         <name>stripeName=keystoreapp,keystoreName=ks1,alias=*</name>
         <actions>*</actions>
      </permission>
   </permissions>
</grant>

27.6.3 Configuration File

Here is a sample configuration file (jps-config-jse.xml). The keystore.file.path property of the keystore service shows the directory containing the keystores.xml file:

Note:

For the complete configuration file see the default file shipped with the distribution at $DOMAIN_HOME/config/fmwconfig/jps-config-jse.xml.

<jpsConfig>
 ...
    <serviceInstances>
        <serviceInstance name="keystore_file_instance"
                         provider="keystore_file_provider">
            <property name="keystore.file.path" value="store" />
            <property name="keystore.provider.type" value="file" />
        </serviceInstance>
    </serviceInstances>
 ...
</jpsConfig>

27.6.4 About Using the Keystore Service in the Java SE Environment

In the Java SE environment, the following calls are equivalent:

KeyStoreService store = JpsServiceLocator.getServiceLocator().lookup(KeyStoreService.class);

and:

KeyStoreService store = JpsContextFactory.getContextFactory().getContext().getServiceInstance

(KeyStoreService.class); 

27.7 Best Practices

In a clustered environment, use the Keystore Service Mbean API over the Keystore Service API to create, retrieve, update, and delete keys for an application.

If you are simply reading keys, however, either API can be used.