Oracle9i CORBA Developer's Guide and Reference Release 1 (9.0.1) Part Number A90187-01 |
|
Security involves data integrity, authentication, and authorization.
The following sections explain these subjects in detail:
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:
loadjava
tool. See the loadjava
discussion in the Oracle9i Java Developer's Guide for information on granting execution rights when loading the CORBA classes.
- Session authorization--The session is authorized to the user. In this case, the client is authorized to access the server through validating either the username or certificate provided.
- User authorization--The client or server can perform authorization on a provided certificate. This type of authorization can be performed only when the client or server authenticates itself by providing a certificate.
This section describes fully the network connection security issues that IIOP applications must consider.
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.
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:
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.
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:
SSL_UNDETERMINED
. This is the default setting.
SSL_30
.
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.
environment.put("CLIENT_SSL_VERSION", ServiceCtx.SSL_30);
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:
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:
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.
To set up client-side authentication using JNDI, set the javax.naming.Context.SECURITY_AUTHENTICATION
attribute to one of the following values:
ServiceCtx.NON_SSL_LOGIN
--A plain IIOP connection is used. Because SSL is not used, all data flowing over the line is not encrypted. Thus, to protect the password, the client uses the login protocol to authenticate itself. In addition, the server does not provide SSL certificates to the client to identify itself.
ServiceCtx.SSL_LOGIN
--An SSL-enabled IIOP connection is used. All data flowing over the transport is encrypted. If you do not want to provide a certificate for the client authentication, use the login protocol to provide the username and password.
Because this is an SSL connection, the server sends its certificate identity to the client. The client is responsible for verifying the server's certificate, if interested, for server authentication. Optionally, the client can set up trust points for the server's certificate to be verified against.
ServiceCtx.SSL_CREDENTIAL
--An SSL-enabled IIOP connection is used. All data flowing over the transport is encrypted. The client provides the username and password without using the login protocol for client authentication to the server. The username and password are automatically passed to the server in a security context, on the first message.
The server provides its certificate identity to the client. The client is responsible for verifying the server's certificate, if interested, for server authentication.
ServiceCtx.SSL_CLIENT_AUTH
--An SSL-enabled IIOP connection is used. All data flowing over the transport is encrypted. The client provides appropriate certificates for client-side authentication to the server. In addition, the server provides its certificate identity to the client. If interested, the client is responsible for authorizing the server's certificate.
$ORACLE_HOME/javavm/demo/examples/corba/session/sharedsession
example for more information. The username and password in the initial context environment are automatically passed as parameters to the login object's authenticate()
method.
Within each of these options, you choose to do one or more of the following:
Client authentication |
|
Server authentication |
For information on how to implement each of these methods for client or server authentication, see the following sections:
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.
SECURITY_AUTHENTICATION
to ServiceCtx.SSL_LOGIN
or ServiceCtx.NON_SSL_LOGIN
.
SECURITY_AUTHENTICATION
to serviceCtx.SSL_CREDENTIAL
.
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:
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.
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();
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.
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:
// 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);
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.
You set up the client for certificate authentication through one of the following methods:
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.
After you create a valid wallet, bring up the Wallet Manager and perform the following:
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.
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 |
|
Key for decrypting the private key |
|
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.S
SL_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");
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
.
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.
final private static StringtestCert_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);
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
if client-side authentication is required, and the client does not want to use JNDI properties for setting certificates.
AuroraCertficateManager
if it is executing a callout or a callback. The typical server-side authentication for a simple client/server exchange is taken care of by the database wallet. However, if this server intends to act as a client by executing a callout or callback, it needs to set certificates identifying itself; it cannot use the database certificate that is contained in the wallet.
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.
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. |
This method is invoked by servers that wish to require certificates from client applications. This method is not intended for use by client applications.
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. |
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. |
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. |
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 |
This example does the following:
AuroraCertificateManager
.
setCertificateChain
.
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");
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.
The following sections describe this in more detail:
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. |
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.
AuroraCertificateManager
, as discussed in "Using Certificates for Client Authentication".
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.
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:
Text description of the illustration secure3.gif
The following code shows the client code that performs (a) and (d) steps above. The first half of the client code sets up a username and password for authenticating itself to the database. It retrieves the server object. However, before it invokes the server's method, the last half of the code sets up the client callback object by setting certificates, initializing the BOA, and instantiating the callback object. Finally, the server method is invoked.
public static void main (String[] args) throws Exception { String serviceURL = args [0]; String objectName = args [1]; String user = args [2]; String password = args [3]; //set up username/password for authentication to database. Set up //security to be SSL_LOGIN - login authentication for client and server-side //authentication. Hashtable env = new Hashtable (); env.put (Context.URL_PKG_PREFIXES, "oracle.aurora.jndi"); env.put (Context.SECURITY_PRINCIPAL,user
); env.put (Context.SECURITY_CREDENTIALS,password
); env.put (Context.SECURITY_AUTHENTICATION, ServiceCtx.SSL_LOGIN
); Context ic = new InitialContext (env); // Get the server object before preparing the client object. // You have to do it in this order to get the ORB initialized correctly Server server = (Server)ic.lookup (serviceURL + objectName); // Create the client object and export it to the ORB in the client // First, set up the ORB properties for the callback object java.util.Properties props = new java.util.Properties(); props.put("ORBservices", "oracle.aurora.ssl
"); BASE64Decoder decoder = new BASE64Decoder(); // Initialize the ORB. com.visigenic.vbroker.orb.ORB orb = (com.visigenic.vbroker.orb.ORB)oracle.aurora.jndi.orb_dep.Orb.init(args, props);
// Get the certificate manager AuroraCertificateManager certificateManager =
AuroraCertificateManagerHelper.narrow( orb.resolve_initial_references("AuroraSSLCertificateManager
")); // Set up client callbackcertificate chain
, ordered from user to CA. 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 client callback object's private key. byte[] encryptedPrivateKey=decoder.decodeBuffer(encryptedPrivateKey_base64);cm.setEncryptedPrivateKey(encryptedPrivateKey, "welcome12");
// Initialize the BOA with SSLorg.omg.CORBA.BOA boa = orb.BOA_init("AuroraSSLTSession", null);
//Instantiate the client callback object ClientImpl client = new ClientImpl (); //register callback object with BOA boa.obj_is_ready (client); // Invoke the server method, passing the client to call us back System.out.println (server.hello (client));
Text description of the illustration secure4.gif
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".
The following server code does the following:
AuroraCertificateManager
AuroraCertificateManager
methods.
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
(); }
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.
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:
AuroraCertificateManager.addTrustedCertificate
method. See Example 6-4 on how to set a single trustpoint through JNDI.
AuroraCertificateManager.addTrustedCertificate
method.
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.
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);
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.
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:
getPeerDERCertChain
--Obtain the peer's certificate chain, which enables you to verify that the peer is authorized to access your application methods.
getNegotiatedProtocolVersion
--Obtain the SSL protocol version being used by the connection, to verify the versioning.
getNegotiatedCipherSuite
--Obtain the cipher suite used to encrypt messages passed over the connection, to verify that the encryption is strong enough for your purposes.
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.
The following describes the methods contained within AuroraCurrent
. See Example 6-5 for a code example of these methods.
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:
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.
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:
This example shows how to authorize a peer by retrieving the certificate information, using the AuroraCurrent
object.
AuroraCurrent
object, invoke the ORB.resolve_initial_references
method with AuroraSSLCurrent
as the argument.
AuroraCurrent
methods: getNegotiatedCipherSuite
, getNegotiatedProtocolVersion
, and getPeerDERCertChain
.
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 currentAuroraCurrent
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; }
|
Copyright © 1996-2001, Oracle Corporation. All Rights Reserved. |
|