Oracle9i CORBA Developer's Guide and Reference
Release 1 (9.0.1)

Part Number A90187-01
Go To Documentation Library
Home
Go To Product List
Book List
Go To Table Of Contents
Contents
Go To Index
Index

Master Index

Feedback

Go to previous page Go to next page

6
IIOP Security

Security involves data integrity, authentication, and authorization.

The following sections explain these subjects in detail:

Overview

As discussed in the Oracle9i Java Developer's Guide, there are several security issues you must think about for your application. The Oracle9i Java Developer's Guide divides security into network connection, database contents, and JVM security issues. All these factors pertain to IIOP. However, IIOP has specific implementation issues for both the networking and the JVM security, as listed below:

This section describes fully the network connection security issues that IIOP applications must consider.

Data Integrity

Do you want your transport line to be encrypted? Do you want data integrity and confidentiality? If you believe that the physical connection can be tampered with, you can consider encrypting all transmissions by using the secure socket layer (SSL) encryption technology. However, because adding encryption to your transmission affects your connection performance, if you do not have any transport security issues, you should transmit unencrypted.

Figure 6-1 Data Integrity Decision Tree


Text description of secure5.gif follows
Text description of the illustration secure5.gif

Using the Secure Socket Layer

The Oracle9i CORBA and EJB implementations rely on the Secure Socket Layer (SSL) for data integrity and authentication. SSL is a secure networking protocol, originally defined by Netscape Communications, Inc. Oracle9i supports SSL over the IIOP protocol used for the ORB.

When a connection is requested between a client and the server, the SSL layer within both parties negotiate during the connection handshake to verify if the connection is allowed. The connection is verified at several levels:

  1. The SSL version on both the client and the server must agree for the transport to be guaranteed for data integrity.

  2. If server-side authentication with certificates is requested, the certificates provided by the server are verified by the client at the SSL layer. This means that the server is guaranteed to be itself. That is, it is not a third party pretending to be the server.

  3. If client-side authentication with certificates is requested, the certificates provided by the client are verified at the SSL layer. The server receives the client's certificates for authentication or authorization of the client.


    Note:

    Normally, client-side authentication means only that the server verifies that the client is not an impersonator and is trusted. However, when you specify SSL_CLIENT_AUTH, you are requesting both server-side and client-side authentication.  


The SSL layer performs authentication between the peers. After the handshake, you can be assured that the peers are authenticated to be who they say they are. You can perform additional tests on their certificate chain to authorize that this user can access your application. See "Authorization" for how to go beyond authentication.


Note:

If you decide to use SSL, your client must import the following JAR files:

  • If your client uses JDK 1.1, import jssl-1_1.jar and javax-ssl-1_1.jar.

  • If your client uses Java 2, import jssl-1_2.jar and javax-ssl-1_2.jar.

 

SSL Version Negotiation

SSL makes sure that both the client and server side agree on an SSL protocol version number. The values that you can specify are as follows:

In the database, the default is "Undetermined". The database does not support 2.0 or 3.0 with 2.0 Hello. Thus, you can use only the Undetermined or 3.0 setting for the client.

Table 6-1 shows which handshakes resolve to depending on SSL version settings on both the client and the server. The star sign "X" indicates cases where the handshake fails. Table 6-1 SSL Version Numbers

  Server Setting 
Client Setting 
Undetermined
 
3.0 W/2.0 Hello
(Not Supported)
 
3.0  2.0 (Not
Supported)
 

Undetermined  

3.0 

3.0 W/2.0 Hello
(not supported) 

3.0  

3.0 

3.0 

2.0 (not supported) 

Authentication

Authentication is the process by which one party supplies to a requesting party information that identifies itself. This information guarantees that the originator is not an imposter. In the client/server distributed environment, authentication can be required from the client or the server:

Client-Side Authentication

The Oracle data server is a secure server: a client application cannot access data stored in the database without first being authenticated by the database server. Oracle9i CORBA server objects and Enterprise JavaBeans execute in the database server. For a client to activate such an object and invoke methods on it, the client must authenticate itself to the server. The client authenticates itself when a CORBA or EJB object starts a new session. The following are examples of how each IIOP client must authenticate itself to the database:

The client authenticates itself by providing one of the following types:

Authentication type  Definition 

Certificates 

You can provide the user certificate, the Certificate Authority certificate (or a chain that contains both, including other identifying certificates), and a private key. 

Username and
password combination 

You can provide the username and password through either credentials or the login protocol. In addition, you can pass a database role to the server, along with the username and password. 

The type of client-side authentication can be determined by the server's configuration. If, within the SQLNET.ORA file, the SSL_CLIENT_AUTHENTICATION parameter is TRUE, then the client must provide certificate-based authentication. If the SSL_CLIENT_AUTHENTICATION parameter is FALSE, the client authenticates itself with a username/password combination. If the SSL_CLIENT_AUTHENTICATION parameter is TRUE and the client provides a username/password, the connection handshake will fail.

The following table gives a brief overview of the options that the client has for authentication.

As the table demonstrates, most of the authentication options include setting an appropriate value in JNDI properties.

Using JNDI for Authentication

To set up client-side authentication using JNDI, set the javax.naming.Context.SECURITY_AUTHENTICATION attribute to one of the following values:

Within each of these options, you choose to do one or more of the following:

Client authentication 

  • authenticate itself to the server using login protocol

  • authenticate itself to the server using straight username and password

  • authenticate itself to the server using SSL certificates

 

Server authentication 

  • authenticate itself to the client using SSL certificates

 

For information on how to implement each of these methods for client or server authentication, see the following sections:

Providing Username and Password for Client-Side Authentication

The client authenticates itself to the database server either through a username/password or by supplying appropriate certificates. The username/password can be supplied either through Oracle's login protocol, or credentials over the SSL transport connection.

Username Sent by Setting JNDI Properties for the Login Protocol

A client can use the login protocol to authenticate itself to the Oracle9i data server. You can use the login protocol either with or without SSL encryption, because a secure handshaking encryption protocol is built in to the login protocol.

If your application requires an SSL connection for client-server data security, specify the SSL_LOGIN service context value for the SECURITY_AUTHENTICATION property that is passed when the JNDI initial context is obtained. The following example defines the connection to be SSL-enabled for the login protocol. Notice that the username and password are set.

Hashtable env = new Hashtable();
env.put(javax.naming.Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
env.put(javax.naming.Context.SECURITY_PRINCIPAL, username);
env.put(javax.naming.Context.SECURITY_CREDENTIALS, password);
env.put(javax.naming.Context.SECURITY_AUTHENTICATION, ServiceCtx.SSL_LOGIN);
Context ic = new InitialContext(env);
...

If your application does not use an SSL connection, specify NON_SSL_LOGIN within the SECURITY_AUTHENTICATION parameter as shown below:


Note:

The login handshaking is secured by encryption, but the remainder of the client-server interaction is not secure. 


env.put(javax.naming.Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN);

When you specify values for all four JNDI Context variables--URL_PKG_PREFIXES, SECURITY_PRINCIPAL, SECURITY_CREDENTIALS, and SECURITY_AUTHENTICATION--the first invocation of the Context.lookup()method performs a login automatically.

If the client setting up the connection is not using JNDI lookup() because it already has an IOR, the user that gave it the IOR for the object should have also passed in a Login object that exists in the same session as the active object. You must provide the username and password in the authenticate method of the Login object before invoking the methods on the active object.

Logging In and Out of the Oracle9i Session

If the session owner wishes to exit the session, the owner can use the logout method of the LogoutServer object, which is pre-published as "/etc/logout". You use the LogoutServer object to exit the session. Only the session owner is allowed to logout. Any other owner receives a NO_PERMISSION exception.

The LogoutServer object is analogous to the LoginServer object, which is pre-published as "/etc/login". You can use the LoginServer object to retrieve the Login object, which is used to authenticate to the server. This is an alternative method to using the Login object within the JNDI lookup.

The following example shows how a client can authenticate using the LoginServer object and can exit the session through the LogoutServer object.

import oracle.aurora.AuroraServices.LoginServer;
import oracle.aurora.AuroraServices.LogoutServer;
...
// To log in using the LoginServer object
LoginServer loginServer = (LoginServer)ic.lookup(serviceURL + "/etc/login");
Login login = new Login(loginServer);
System.out.println("Logging in ..");
login.authenticate(user, password, null);
...
//To logout using the LogoutServer
LogoutServer logout = (LogoutServer)ic.lookup(serviceURL + "/etc/logout");
logout.logout();

Username Sent Implicitly by Using Credentials

Using the ServiceCtx.SSL_CREDENTIAL authentication type means that the username, password, and, potentially, a role are passed to the server on the first request. Because this information is passed over an SSL connection, the password is encrypted by the transfer protocol, and there is no need for the handshaking that the Login protocol uses. This is slightly more efficient and is recommended for SSL connections.

Username Sent by Explicitly Activating a Login Object

You can explicitly create and populate a Login object for the database login. Typically, you would do this if you wanted to create and use more than a single session from a client. The following example shows a client creating and logging on to two different sessions. To do this, you must perform the following steps:

  1. Create the initial context.

  2. Perform a look up on a URL for the destination database.

  3. On this database service context, create two subcontexts--one for each session.

  4. Login to each session using a Login object, providing a username and password.


    Note:

    The username and password for both sessions are identical, because the destination database is the same database. If the client connects to two different databases, the username and password may need to be different for logging on. 


    // Prepare a simplified Initial Context as we are going to do
    // everything by hand Hashtable env = new Hashtable (); env.put (Context.URL_PKG_PREFIXES, "oracle.aurora.jndi"); Context ic = new InitialContext (env); // Get a SessionCtx that represents a database instance ServiceCtx service = (ServiceCtx)ic.lookup (serviceURL); // Create and authenticate a first session in the instance. SessionCtx session1 = (SessionCtx)service.createSubcontext (":session1"); LoginServer login_server1 = (LoginServer)session1.activate ("etc/login"); Login login1 = new Login (login_server1); login1.authenticate (user, password, null); // Create and authenticate a second session in the instance. SessionCtx session2 = (SessionCtx)service.createSubcontext (":session2"); LoginServer login_server2 = (LoginServer)session2.activate ("etc/login"); Login login2 = new Login (login_server2); login2.authenticate (user, password, null); // Activate one Hello object in each session Hello hello1 = (Hello)session1.activate (objectName); Hello hello2 = (Hello)session2.activate (objectName);

    Using Certificates for Client Authentication

    Client authentication through certificates requires the client sending a certificate or certificate chain to the server; the server verifies that the client is truly who the client said it was and that it is trusted.


    Note:

    All certificates, trustpoints, and the private key should be in base-64 encoded format.  


    You set up the client for certificate authentication through one of the following methods:

    Specifying Certificates in a File

    You can set up a file that contains the user certificate, the issuer certificate, the entire certificate chain, an encrypted private key, and the trustpoints. Once created, you can specify that the client use the file during connection handshake for client authentication.

    1. Create the client certificate file--Create this file through an export feature in the Wallet Manager. The Oracle Wallet Manager has an option that creates this file. You must populate a wallet using the Wallet Manager before requesting that the file is created.

      After you create a valid wallet, bring up the Wallet Manager and perform the following:

      • From the menu bar pull down, click on Operations > Export Wallet.

      • Within the filename field, enter the name that you want the certificate file to be known as.

      This creates a base-64 encoded file that contains all certificates, keys, and trustpoints that you added within your wallet. For information on how to create the wallet, see the Oracle Advanced Security Administrator's Guide.

    2. Specify the client certificates file for the connection--Within the client code, set the SECURITY_AUTHENTICATION property to ServiceCtx.SSL_CLIENT_AUTH. Provide the appropriate certificates and trustpoints for the server to authenticate against. Specify the filename and decrypting key in the JNDI properties, as follows:

      Values  Set in JNDI Property 

      Name of the certificate file 

      SECURITY_PRINCIPAL 

      Key for decrypting the private key 

      SECURITY_CREDENTIAL  

    The following code is an example of how to set up the JNDI properties to define the client certificate file:

    Hashtable env = new Hashtable();
    env.put(javax.naming.Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
    env.put(javax.naming.Context.SECURITY_PRINCIPAL, <filename>);
    env.put(javax.naming.Context.SECURITY_CREDENTIAL, <decrypting_key>);
    env.put(javax.naming.Context.SECURITY_AUTHENTICATION, 
    ServiceCtx.SSL_CLIENT_AUTH); Context ic = new InitialContext(env); ...

    For example, if your decrypting key is welcome12 and the certificate file is credsFile, the following two lines would specify these values within the JNDI context:

    env.put(Context.SECURITY_CREDENTIALS, "welcome12");
    env.put(Context.SECURITY_PRINCIPAL, "credsFile");
    

Specifying Certificates in Individual JNDI Properties

You can provide each certificate, private key, and trust point programmatically, by setting each item individually within JNDI properties. Once you populate the JNDI properties with the user certificate, issuer (Certificate Authority) certificate, encrypted private key, and trust points, they are used during connection handshake for authentication. To identify client-side authentication, set the SECURITY_AUTHENTICATION property to serviceCtx.SSL_CLIENT_AUTH.


Note:

Only a single issuer certificate can be set through JNDI properties. 


You can choose any method for setting up your certificates within the JNDI properties. All authorization information values must be set up before initializing the context.

The following example declares the certificates as a static variable. However, this is just one of many options. Your certificate must be base-64 encoded. For example, in the following code, the testCert_base64 is a base-64 encoded client certificate declared as a static variable. The other variables for CA certificate, private key, and so on, are not shown, but they are defined similarly.


Note:

When you are setting individual certificates as static variables, note that certificates for Oracle9i parties do not have any separators. However, if you are setting a certificate for a Visigenic ORB (as the client callback object does in a callback scenario), the certificate must be delineated by "BEGIN CERTIFICATE" and "END CERTIFICATE" identifying lines. See the Visigenic documentation for the format of these strings. 


final private static String testCert_base64 =
  "MIICejCCAeOgAwIBAgICAmowDQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMCVVMx" +
  "DzANBgNVBAoTBk9yYWNsZTEoMCYGA1UECxMfRW50ZXJwcmlzZSBBcHBsaWNhdGlv" +
  "biBTZXJ2aWNlczEhMB8GA1UEAxMYRUFTUUEgQ2VydGlmaWNhdGUgU2VydmVyMB4X" +
  "DTk5MDgxNzE2MjIxMloXDTAwMDIxMzE2MjIxMlowgYUxCzAJBgNVBAYTAlVTMRsw" +
  "GQYDVQQKExJPcmFjbGUgQ29ycG9yYXRpb24xPDA6BgNVBAsUMyoqIFNlY3VyaXR5" +
  "IFRFU1RJTkcgQU5EIEVWQUxVQVRJT04gT05MWSB2ZXJzaW9uMiAqKjEbMBkGA1UE" +
  "AxQSdGVzdEB1cy5vcmFjbGUuY29tMHwwDQYJKoZIhvcNAQEBBQADawAwaAJhANG1" +
  "Kk2K7uOOtI/UBYrmTe89LVRrG83Eb0/wY3xWGelkBeEUTwW57a26u2M9LZAfmT91" +
  "e8Afksqc4qQW23Sjxyo4ObQK3Kth6y1NJgovBgfMu1YGtDHaSn2VEg8p58g+nwID" +
  "AQABozYwNDARBglghkgBhvhCAQEEBAMCAMAwHwYDVR0jBBgwFoAUDCHwEuJfIFXD" +
  "a7tuYNO8bOw1EYwwDQYJKoZIhvcNAQEEBQADgYEARC5rWKge5trqgZ18onldinCg" +
  "Fof6D/qFT9b6Cex5JK3a2dEekg/P/KqDINyifIZL0DV7z/XCK6PQDLwYcVqSSK/m" +
  "487qjdH+zM5X+1DaJ+ROhqOOX54UpiAhAleRMdLT5KuXV6AtAx6Q2mc8k9bzFzwq" +
  "eR3uI+i5Tn0dKgxhCZU=\n";

Hashtable env = new Hashtable();
env.put(Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
env.put(Context.SECURITY_AUTHENTICATION, ServiceCtx.SSL_CLIENT_AUTH);
//decrypting key
env.put(Context.SECURITY_CREDENTIALS, "welcome12");

// you may also set the certificates individually, as shown bellow.
//User certificate
env.put(ServiceCtx.SECURITY_USER_CERT, testCert_base64);
//Certificate Authority's certificate
env.put(ServiceCtx.SECURITY_CA_CERT, caCert_base64);
//Private key
env.put(ServiceCtx.SECURITY_ENCRYPTED_PKEY, encryptedPrivateKey_base64);
// setup the trust point
env.put(ServiceCtx.SECURITY_TRUSTED_CERT, trustedCert);

Context ic = new InitialContext(env);

Specifying Certificates Using AuroraCertificateManager

CORBA clients that do not use JNDI can use AuroraCertificateManager for setting the user and issuer certificates, the encrypted private key, and the trust points.

AuroraCertificateManager maintains certificates for your application. For the certificates to be passed on the SSL handshake for the connection, you must set the certificates before an SSL connection is made. Setting up a certificate in this manner is required only if the following is true:

AuroraCertificateManager Class

The methods offered by this object allow you to:

Invoking the ORB.resolve_initial_references method with the parameter SSLCertificateManager will return an object that can be narrowed to a AuroraCertificateManager. Example 6-1 shows a code example of the following methods.

addTrustedCertificate

This method adds the specified certificate as a trusted certificate. The certificate must be in DER encoded format. The client adds trustpoints through this method for server-side authentication.

When your client wants to authenticate a server, the server sends its certificate chain to the client. You might not want to check every certificate in the chain. For example, you have a chain composed of the following certificates: Certificate Authority, enterprise, business unit, a company site, and a user. If you trust the company site, you would check the user's certificate, but you might stop checking the chain when you get to the company site's certificate, because you accept the certificates above the company sites in the hierarchical chain.

Syntax

void addTrustedCertificate(byte[] derCert);

Parameter  Description 

derCert 

The DER encoded byte array containing the certificate. 

requestClientCertificate

This method is invoked by servers that wish to require certificates from client applications. This method is not intended for use by client applications.


Note:

The requestClientCertificate method is not currently required, because the SQLNET.ORA and LISTENER.ORA configuration parameter SSL_CLIENT_AUTHENTICATION performs its function. 


Syntax

void requestClientCertificate(boolean need);

Parameter  Description 

need 

If true, the client must send a certificate for authentication. If false, no certificate is requested from the client. 

setCertificateChain

This method sets the certificate chain for your client application or server object and can be invoked by clients or by servers. The certificate chain always starts with the Certificate Authority certificate. Each subsequent certificate is for the issuer of the preceding certificate. The last certificate in the chain is the certificate for the user or process.

Syntax

void setCertificateChain(byte[][] derCertChain)

Parameter  Description 

derCertChain 

A byte array containing an array of certificates. 

setEncryptedPrivateKey

This method sets the private key for your client application or server object. You must specify the key in PKCS5 or PKCS8 format.

Syntax

void setEncryptedPrivateKey(byte[] key, String password);

Parameter  Description 

key 

The byte array that contains the encrypted private key. 

password 

A string containing a password for decrypting the private key. 

setProtocolVersion

This method sets the SSL protocol version that can be used for the connection. A 2.0 Client trying to establish an SSL connection with a 3.0 Server will fail and the converse. We recommend using Version_Undetermined, because it lets the peers establish an SSL connection whether they are using the same protocol version or not. SSL_Version_Undetermined is the default value.

Syntax

void setProtocolVersion(int protocolVersion);

Parameter  Description 

protocolVersion 

The protocol version being specified. The value you supply is defined in oracle.security.SSL.OracleSSLProtocolVersion. This class defines the following values:

  • SSL_Version_Undetermined: Version is undetermined. This is used to connect to SSL 2.0 and SSL 3.0 peers. This is the default version.

  • SSL_Version_3_0_With_2_0_Hello: Not supported.

  • SSL_Version_3_0: Used to connect to 3.0 peers only.

  • SSL_Version_2_0: Not supported.

 

Example 6-1 Setting SSL Security Information Using AuroraCertificateManager

This example does the following:

  1. Retrieves the AuroraCertificateManager.

  2. Initializes this client's SSL information:

    1. Sets the certificate chain through setCertificateChain.

    2. Sets the trustpoint through addTrustedCertificate.

    3. Sets the private key through setEncryptedPrivateKey.

      // Get the certificate manager
      AuroraCertificateManager cm = AuroraCertificateManagerHelper.narrow(
      	orb.resolve_initial_references("AuroraSSLCertificateManager"));
      
      BASE64Decoder decoder = new BASE64Decoder();
      byte[] userCert = decoder.decodeBuffer(testCert_base64);
      byte[] caCert = decoder.decodeBuffer(caCert_base64);
      
      // Set my certificate chain, ordered from CA to user.
      byte[][] certificates = {
              caCert, userCert
      };
      cm.setCertificateChain(certificates);
      cm.addTrustedCertificate(caCert);
      
      // Set my private key.
      byte[] encryptedPrivateKey =
      decoder.decodeBuffer(encryptedPrivateKey_base64);
      
      cm.setEncryptedPrivateKey(encryptedPrivateKey, "welcome12");
      

Server-Side Authentication

The server can require a different type of authentication, depending on its role. If you are utilizing the database as a server in a typical client/server environment, you use certificates that are set within a wallet for the database for server-side authentication. However, if you are using the server to callout to another object or callback to an object on the client, the server is now acting as a client and so requires its own identifying certificates. That is, in a callout or callback scenario, the server cannot use the wallet generated for database server-side authentication.

Server activity  Authentication method 

Typical client/server 

Use database wallet generated by Oracle Wallet Manager. 

Callout to another object 

Set identifying certificates, using either JNDI properties or AuroraCurrentManager class. 

Callback to client object 

Set identifying certificates, using AuroraCurrentManager class. 

The following sections describe this in more detail:

Typical Client/Server

Server-side authentication takes place when the server provides certificates for authentication to the client. When requested, the server will authenticate itself to the client, also known as server-side authentication, by providing certificates to the client. The SSL layer authenticates both peers during the connection handshake. The client requests server-side authentication by setting any of the SSL_* values in the JNDI property. See "Using JNDI for Authentication" for more information on these JNDI values.

For server-side authentication, you must set up a database wallet with the appropriate certificates, using the Wallet Manager. See the Oracle Advanced Security Administrator's Guide for information on how to create a wallet.


Note:

If the client wants to verify the server against trustpoints or authorize the server, it is up to the client to set up its trustpoints and parse the server's certificates for authorization. See "Authorization" for more information. 


Callouts using Security

A callout is when a Java object loaded within the database invokes a method within another Java object. If the original call from the client required a certain level of security--certificate-based or username/password security--the server object is also required to provide the same level of security information for itself before invoking the method on the second server object.

Figure 6-2 Server callout requires security


Text description of securea.gif follows
Text description of the illustration securea.gif

Callbacks using Security

A callback is when the client passes the server object an object reference to an object that exists on the client. As shown in Figure 6-3, the server object receives the object reference and invokes methods. This effectively calls out of the server and back to an object located in the client. See "Debugging Techniques" for more information on callbacks.

Figure 6-3 Server Callout Requires Security


Text description of secure2.gif follows
Text description of the illustration secure2.gif

The type of security you can use for callbacks is certificate-based security over SSL. When you add SSL security to callbacks, you can have one of two situations:

  1. Server-side authentication only.


    Text description of secure3.gif follows
    Text description of the illustration secure3.gif

    1. The client is not required to authenticate itself with a certificate. However, it must still authenticate itself to the database using a username/password combination.

    2. The server, because server-side authentication is always required with SSL, authenticates itself to the client by providing certificates contained in the database wallet.

    3. When the server calls back to the client, it acts as a client; thus, it is not required to provide certificates for authentication.

    4. The called object, although contained in the client, is the server object in the callback scenario. Thus, because server-side authentication rules hold, the callback object must provide certificates to authenticate itself.

Example 6-2 Callback Code With Server-side Authentication Only

  • Client-side and server-side authentication.


    Text description of secure4.gif follows
    Text description of the illustration secure4.gif

    1. The client is required to authenticate itself with a certificate.

    2. The server, because server-side authentication is always required with SSL, authenticates itself to the client by providing certificates contained in the database wallet.

    3. When the server calls back to the client, it acts as a client; thus, it is required to provide its own certificates for authentication.

    4. The called object, although contained in the client, is the server object in the callback scenario. Thus, because server-side authentication rules hold, the callback object must provide certificates to authenticate itself.

      The code for the client shown in Example 6-2 is the same for this scenario, except 
      that instead of providing a username and password, the client provides certificates. 
      
      Because client-side authentication is required and because the server is acting as a 
      client, the server code sets up identifying certificates for itself before invoking the 
      callback object. The server must create and send its own certificates; it cannot 
      forward on the client's certificates for authentication. You set up your server object 
      certificates using either the appropriate JNDI properties or the 
      AuroraCertificateManager as discussed in "Using Certificates for Client 
      Authentication". 
      

    Example 6-3 Server Code in Callback with Client-side Authentication

    The following server code does the following:

    1. Retrieves the Oracle9i ORB reference by invoking the init method.

    2. Retrieves the AuroraCertificateManager

    3. Sets certificates and key through AuroraCertificateManager methods.

    4. Invokes the client callback method, hello.

      public String hello (Client client) {
      BASE64Decoder decoder = new BASE64Decoder();
      com.visigenic.vbroker.orb.ORB orb = (com.visigenic.vbroker.orb.ORB)
                               oracle.aurora.jndi.orb_dep.Orb.init();
      
      try  {
      // Get the certificate manager
           AuroraCertificateManager cm = AuroraCertificateManagerHelper.narrow(
                 orb.resolve_initial_references("AuroraSSLCertificateManager"));
      
            byte[] userCert = decoder.decodeBuffer(testCert_base64); 
            byte[] caCert = decoder.decodeBuffer(caCert_base64);
      
          // Set my certificate chain, ordered from CA to user.
            byte[][] certificates = { caCert, userCert };
            cm.setCertificateChain(certificates);
      
            // Set my private key.
            byte[] encryptedPrivateKey =
      decoder.decodeBuffer(encryptedPrivateKey_base64); cm.setEncryptedPrivateKey(encryptedPrivateKey, "welcome12"); } catch (Exception e) { e.printStackTrace(); throw new org.omg.CORBA.INITIALIZE( "Couldn't initialize SSL context"); } return "I Called back and got: " + client.helloBack (); }

    Authorization

    The SSL layer authenticates the peers during the connect handshake. After the handshake, you can be assured that the peers are authenticated to be who they said they are. In addition, because the server has specified, within an Oracle wallet, its trustpoints, the SSL adapter on the server will authorize the client. However, the client has the option of how much authorization is done against the server.

    Setting Up Trust Points

    The server automatically has trustpoints established through the installed Oracle Wallet. The trustpoints in the wallet are used to verify the client's certificates. However, if the client wants to verify the server's certificates against certain trustpoints, it can set up these trustpoints, as follows:

    If the client does not set up trust points, it does not hinder the authorization. That is, Oracle9i assumes that the client trusts the server.

    Example 6-4 Verifying Trustpoints

    The following example shows how the client sets up its trustpoints through JNDI. The JNDI SECURITY_TRUSTED_CERT property can take only a single certificate.

    // setup the trust point
    env.put(ServiceCtx.SECURITY_TRUSTED_CERT, trustedCert);
    

    Parsing Through the Server's Certificate Chain

    The client retrieves the certificates to perform any authorization checks. In the past, you could retrieve the single issuer certificate. Now, you receive the entire issuer certificate chain. You must parse the certificate chain for the information that you need. You can parse the chain through the AuroraCurrent object.


    Note:

    You must configure the database and listener to be SSL-enabled, as described in Chapter 3, "Configuring IIOP Applications". 



    Note:

    JDK 1.1 certificate classes were contained within javax.security.cert. In JDK 1.2, these classes have been moved to java.security.cert


    AuroraCurrent contains three methods for retrieving and managing the certificate chain. For creating and parsing the certificate chain, you can use the X509Cert class methods. For information on this class, see the Sun Microsystems JDK documentation. Note that the X509Cert class manipulates the certificate chain differently in JDK 1.1 than in Java 2.

    The AuroraCurrent class methods are as follows:

    When the handshake occurs, the protocol version and the type of encryption used is negotiated. The type of encryption can be full or limited encryption, which complies with the United States legal restrictions. After the handshake completes, the AuroraCurrent can retrieve what was resolved in the negotiation.

    AuroraCurrent Class

    The following describes the methods contained within AuroraCurrent. See Example 6-5 for a code example of these methods.

    getNegotiatedCipherSuite

    This method obtains the type of encryption negotiated in the handshake with the peer.

    Syntax

    String getNegotiatedCipherSuite(org.omg.CORBA.Object peer);
    

    Parameter  Description 

    peer  

    the peer from which you obtain the negotiated cipher 

    Returns

    This method returns a string with one of the following values:

    Export ciphers:

    Domestic ciphers:

    getPeerDERCertificateChain

    This method obtains the peer's certificate chain. After retrieving the chain, you can parse through the certificates within the chain, to authorize the peer to your application.

    Syntax

    byte [] [] getPeerDERCertificateChain(org.omg.CORBA.Object peer);
    

    Parameter  Description 

    peer  

    the peer from which you obtain its certificate chain 

    Returns

    This method returns a byte array that contains an array of certificates.

    getNegotiatedProtocolVersion

    This method obtains the negotiated SSL protocol version of a peer.

    Syntax

    String getNegoriatedProtocolVersion(org.omg.CORBA.Object peer);
    

    Parameter  Description 

    peer  

    the peer from which you obtain the negotiated protocol version 

    Returns

    This method returns a string with one of the following values:

    Example 6-5 Retrieving a Peer's SSL Information for Authorization

    This example shows how to authorize a peer by retrieving the certificate information, using the AuroraCurrent object.

    1. To retrieve an AuroraCurrent object, invoke the ORB.resolve_initial_references method with AuroraSSLCurrent as the argument.

    2. Retrieve the SSL information from the peer through AuroraCurrent methods: getNegotiatedCipherSuite, getNegotiatedProtocolVersion, and getPeerDERCertChain.

    3. Authorize the peer. You can authorize the peer based on its certificate chain.


      Note:

      This example uses the x509Certificate class methods for parsing the certificate chain and is specific to Java 2. If you are using Java 1.1, you must use the x509Certificate class methods specific to Java 1.1. 


      static boolean verifyPeerCert(org.omg.CORBA.Object obj) throws Exception
       {
         org.omg.CORBA.ORB orb = oracle.aurora.jndi.orb_dep.Orb.init();
      
         // Get the SSL current
         AuroraCurrent current = AuroraCurrentHelper.narrow
             (orb.resolve_initial_references("AuroraSSLCurrent"));
      
         // Check the cipher
         System.out.println("Negotiated Cipher:  " +
                            current.getNegotiatedCipherSuite(obj));
         // Check the protocol version
         System.out.println("Protocol Version:   " +
                            current.getNegotiatedProtocolVersion(obj));
         // Check the peer's certificate
         System.out.println("Peer's certificate chain : ");
         byte [] [] certChain = current.getPeerDERCertChain(obj);
      
         //Parse through the certificate chain using the X509Certificate methods
         System.out.println("length : " + certChain.length);
         System.out.println("Certificates: ");
         CertificateFactory cf = CertificateFactory.getInstance("X.509");
      
         //For each certificate in the chain
         for(int i = 0; i < certChain.length; i++) {
           ByteArrayInputStream bais = new ByteArrayInputStream(certChain[i]);
           Certificate  xcert = cf.generateCertificate(bais);
           System.out.println(xcert);
           if(xcert instanceof X509Certificate)
           {
             X509Certificate x509Cert = (X509Certificate)xcert;
             String globalUser = x509Cert.getSubjectDN().getName();
             System.out.println("DN out of the cert : " + globalUser);
           }
         }
      
         return true;
       }
      


      Note:

      The x509Certificate class is a Java 2 class. See the Sun Microsystems documentation for more information. In addition, you can find information in the javadoc for javax.net.ssl



  • Go to previous page Go to next page
    Oracle
    Copyright © 1996-2001, Oracle Corporation.

    All Rights Reserved.
    Go To Documentation Library
    Home
    Go To Product List
    Book List
    Go To Table Of Contents
    Contents
    Go To Index
    Index

    Master Index

    Feedback