Table of Contents Previous Next PDF


Writing a CORBA Application That Implements Security

Writing a CORBA Application That Implements Security
This topic includes the following sections:
Notes:
Technical support for third party CORBA Java ORBs should be provided by their respective vendors. Oracle Tuxedo does not provide any technical support or documentation for third party CORBA Java ORBs.
Using the Bootstrapping Mechanism
Note:
The Bootstrap object in the Oracle Tuxedo CORBA environment has been enhanced so that users can specify that all communication to a given IIOP Listener/Handler be protected. The Bootstrap object supports corbaloc and corbalocs Uniform Resource Locator (URL) address formats to be used when specifying the location of the IIOP Listener/Handler. The type of security provided depends on the format of URL used to specify the location of the IIOP Listener/Handler.
As with the Host and Port address format, you use the URL address formats to specify the location of the IIOP Listener/Handler, but the bootstrapping process behaves differently. When using the corbaloc or corbalocs URL address format, the initial connection to the IIOP Listener/Handler is deferred until either:
The principal uses password authentication with either the Tobj::PrincipalAuthenticator::logon or the SecurityLevel2::PrincipalAuthenticator::authenticate methods.
The principal calls the Tobj_Bootstrap::resolve_initial_references method using an object ID value other than SecurityCurrent.
Using the corbalocs URL address format indicates that the SSL protocol is used to protect at least the integrity of the connection between the principal and the IIOP Listener/Handler.
Table 9‑1 highlights the differences between the two URL address formats.
 
A principal can secure the bootstrapping process by using the authenticate() method of the SecurityLevel2::PrincipalAuthenticator interface and the invocation_options_required() method of the SecurityLeve12::Credentials interface to specify that certificate authentication is to be used.
Both the corbaloc and corbalocs URL address formats provide stringified object references that are easily manipulated in both TCP/IP and Domain Name System (DNS) environments. The corbaloc and corbalocs URL address formats contain a DNS-style host name or an IP address and port.
The URL address formats follow and extend the definition of object URLs adopted by the Object Management Group (OMG) as part of the Interoperable Naming Service submission. The Oracle Tuxedo software also extends the URL format described in the OMG Interoperable Naming Service submission to support a secure form that is modeled after the URL for secure HTTP, as well as to support functionality in previous releases of the WebLogic Enterprise product.
Listing 9‑1 contains examples of the new URL address formats.
Listing 9‑1 Examples of the corbaloc and corbalocs URL Address Formats
corbaloc://555xyz.com:1024,corbaloc://555backup.com:1022,
corbaloc://555last.com:1999
corbalocs://555xyz.com:1024,(corbalocs://555backup.com:1022|corbalocs://555last.com:1999)
corbaloc://555xyz.com:1111
corbalocs://24.128.122.32:1011, corbalocs://24.128.122.34
 
As an enhancement to the URL syntax described in the OMG Interoperable Naming Service submission, the Oracle Tuxedo product extends the syntax to support a list of multiple URLs, each with a different scheme. Listing 9‑2 contains examples of specifying multiple URLs.
Listing 9‑2 Examples of Specifying Multiple URL Address Formats
corbalocs://555xyz.com:1024,corbaloc://555xyz.com:1111
corbalocs://ctxobj.com:3434,corbalocs://mthd.com:3434,corbaloc://force.com:1111
 
In the examples in Listing 9‑2, if the parser reaches the URL corbaloc://force.com:1111, it resets its internal state as if it had never attempted secure connections, and then begins attempting unprotected connections. This situation occurs if the client application has not set any SSL parameters on the Credentials object.
The following sections describe the behavior when using the different address formats of the Bootstrap object.
Using the Host and Port Address Format
If a CORBA client application uses the Host and Port address format of the Bootstrap object, the constructor method of the Bootstrap object constructs an object reference using the specified host name and port number. The invocation to the IIOP Listener/Handler is made without the protections offered by the SSL protocol.
The client application can still authenticate using password authentication. However, since the bootstrapping process is performed over an unprotected and unverified link, all communications are vulnerable to the following security attacks:
Note:
Using the corbaloc URL Address Format
By default, the invocation on the IIOP Listener/Handler is unprotected when using the corbaloc URL address format and password authentication. Therefore, all communications are vulnerable to the following security attacks:
You can protect the bootstrapping process when using the corbaloc URL address format by using the SecurityLevel2::PrincipalAuthenticator::authenticate() method, specifying that certificate authentication is to be used, and setting the invocation_methods_required method on the Credentials object.
Note:
If the IIOP Listener/Handler is configured for the SSL protocol but not configured for certificate authentication and the corbaloc URL address format is used, the invocation on the specified CORBA object results in an INVALID_DOMAIN exception.
Oracle recommends that existing CORBA applications migrate to the corbaloc URL address format instead of using the Host and Port Address format.
Using the corbalocs URL Address Format
The corbalocs URL address format is the recommended format to use to ensure that communications between principals and the IIOP Listener/Handler are protected. The corbalocs URL address format functions in the same way as the corbaloc URL address format, except the SSL protocol is used to protect all communications with the IIOP Listener/Handler or the CORBA C++ ORB regardless of the type of authentication used.
When the defaults are used with the corbalocs URL address format, communications are vulnerable only to Denial of Service security attacks. Using the SSL protocol and certificate authentication guards against Sniffer, Tamper, and Replay attacks. In addition, the validation check of the host specified in the digital certificate guards against Man-in-the-Middle attacks.
To use the corbalocs URL address format, the IIOP Listener/Handler or the CORBA C++ ORB must be configured to enable the use of the SSL protocol. For more information about configuring the IIOP Listener/Handler or the CORBA C++ ORB for the SSL protocol, see “Configuring the SSL Protocol” on page 6‑1.
Using Password Authentication
This section describes implementing password authentication in a CORBA applications.
The Security Sample Application
The Security sample application demonstrates password authentication. The Security sample application requires each student using the application to have an ID and a password. The Security sample application works in the following manner:
1.
2.
The server application implements a get_student_details() method on the Registrar object to return information about a student. After the user is authenticated and the logon is complete, the get_student_details() method accesses the student information in the database to obtain the student information needed by the client logon method.
3.
Figure 9‑1 illustrates the Security sample application.
Figure 9‑1 Security Sample Application
 
 
The source files for the Security sample application are located in the \samples\corba\university directory in the Oracle Tuxedo software. For information about building and running the Security sample application, see the Guide to the CORBA University Sample Applications.
Writing the Client Application
When using password authentication, write client application code that does the following:
1.
2.
3.
C++—SecurityLevel2::PrincipalAuthenticator::authenticate() using Tobj::TuxedoSecurity
C++—Tobj::PrincipalAuthenticator::logon()
The SecurityLevel2::PrincipalAuthenticator interface is defined in the CORBAservices Security Service specification. This interface contains two methods that are used to accomplish the authentication of the principal. There are two methods because authentication of principals may require more than one step. The authenticate() method allows the caller to authenticate and optionally select attributes for the principal of this session.
The CORBA environment extends the PrincipalAuthenticator object with functionality to support similar security to that found in the ATMI environment in the Oracle Tuxedo product. The enhanced functionality is provided by the Tobj::PrincipalAuthenticator interface.
The methods defined for the Tobj::PrincipalAuthenticator interface provide a focused, simplified form of the equivalent CORBA-defined interface. You can use either the CORBA-defined or the Oracle Tuxedo extensions when developing a CORBA application.
The Tobj::PrincipalAuthenticator interface provides the same functionality as the SecurityLevel2::PrincipalAuthenticator interface. However, unlike the SecurityLevel2::PrincipalAuthenticator::authenticate() method, the logon() method of the Tobj::PrincipalAuthenticator interface does not return a Credentials object. As a result, CORBA applications that need to use more than one principal identity are required to call the Current::get_credentials() method immediately after the logon() method to retrieve the Credentials object as a result of the logon. Retrieval of the Credentials object directly after a logon method should be protected with serialized access.
Note:
The following sections contain C++ code examples that illustrate implementing password authentication. For a Visual Basic code example, see “Automation Security Reference” on page 16‑1.
C++ Code Example That Uses the SecurityLevel2::PrincipalAuthenticator::authenticate() Method
Listing 9‑3 contains C++ code that performs password authentication using the SecurityLevel2::PrincipalAuthenticator::authenticate()method.
Listing 9‑3 C++ Client Application That Uses the SecurityLevel2::PrincipalAuthenticator::authenticate() Method
...
//Create Bootstrap object
     Tobj_Bootstrap* bootstrap = new Tobj_Bootstrap(orb,
                      corbalocs://sling.com:2143);
//Get SecurityCurrent object
CORBA::Object_var var_security_current_oref =
     bootstrap.resolve_initial_references(“SecurityCurrent”);
SecurityLevel2::Current_var var_security_current_ref =
     SecurityLevel2::Current::_narrow(var_security_current_oref.in());
//Get the PrincipalAuthenticator
SecurityLevel2::PrincipalAuthenticator_var var_principal_authenticator =
     var_security_current_oref->principal_authenticator();

const char * user_name = “john”
const char * client_name = “university”;
char system_password[31] = {‘\0’};
char user_password[31] = {‘\0’};

Tobj::PrincipalAuthenticator_ptr var_bea_principal_authenticator =
           Tobj::PrincipalAuthenticator::_narrow(var_bea_principal_authenticator.in());

//Determine the security level
Tobj::AuthType auth_type = var_bea_principal_authenticator->get_auth_type();
switch (auth_type)
{
   case Tobj::TOBJ_NOAUTH;
   break;

   case Tobj::TOBJ_SYSAUTH
   strcpy(system_password, “sys_pw”);

   case Tobj::TOBJ_APPAUTH
   strcpy(system_password, “sys_pw”);
   strcpy(user_password, “john_pw”);
   break;
}
if (auth_type != Tobj::TOBJ_NOAUTH)

{
   SecurityLevel2::Credentials_var               creds;
     Security::Opaque_var                        auth_data;
     Security::AttributeList_var                 privileges;
     Security::Opaque_var                        cont_data;
     Security::Opaque_var                        auth_spec_data;

var_bea_principalauthenticator->build_auth_data(user_name,
                                                client_name,
                                                system_password,
                                                user_password,
                                                NULL,
                                                auth_data,
                                                privileges);
Security::AuthenticationStatus status =
      var_bea_principalauthenticator->authenticate(
                                                   Tobj::TuxedoSecurity,
                                                   user_name,
                                                   auth_data,
                                                   privileges,
                                                   creds,
                                                   cont_data, auth_spec_data);

if (status != Security::SecAuthSuccess)
 {
    //Failed authentication
    return;
 }
}
// Proceed with application
...
 
C++ Code Example That Uses the Tobj::PrincipalAuthenticator::logon() Method
Listing 9‑4 contains C++ code that performs password authentication using the Tobj::PrincipalAuthenticator::logon()method.
Listing 9‑4 C++ Client Application That Uses the Tobj::PrincipalAuthenticator::logon() Method
...
CORBA::Object_var var_security_current_oref =
     bootstrap.resolve_initial_references(“SecurityCurrent”);
SecurityLevel2::Current_var var_security_current_ref =
     SecurityLevel2::Current::_narrow(var_security_current_oref.in());
//Get the PrincipalAuthenticator
SecurityLevel2::PrincipalAuthenticator_var var_principal_authenticator_oref =
     var_security_current_oref->principal_authenticator();

//Narrow the PrincipalAuthenticator
Tobj::PrincipalAuthenticator_var var_bea_principal_authenticator =
     Tobj::PrincipalAuthenticator::_narrow
                                       var_principal_authenticator_oref.in());

const char * user_name = “john”
const char * client_name = “university”;
char system_password[31] = {‘\0’};
char user_password[31] = {‘\0’};

//Determine the security level
Tobj::AuthType auth_type = var_bea_principal_authenticator->get_auth_type();
switch (auth_type)
{
   case Tobj::TOBJ_NOAUTH;
   break;

   case Tobj::TOBJ_SYSAUTH
   strcpy(system_password, “sys_pw”);

   case Tobj::TOBJ_APPAUTH
    strcpy(system_password, “sys_pw”);
    strcpy(user_password, “john_pw”);
    break;
}
if (auth_type != Tobj::TOBJ_NOAUTH)

{
    SecurityLevel2::Credentials_var              creds;
     Security::Opaque_var                        auth_data;
     Security::AttributeList_var                 privileges;
     Security::Opaque_var                        cont_data;
     Security::Opaque_var                        auth_spec_data;

//Determine the security level
Tobj::AuthType auth_type = var_bea_principal_authenticator->get_auth_type();
Security::AuthenticationStatus status = var_bea_principal_authenticator->logon(
                                                   user_name,
                                                   client_name,
                                                   system_password,
                                                   user_password,
                                                   0);

if (status != Security::SecAuthSuccess)
{
    //Failed authentication
    return;
 }
}
// Proceed with application
...
// Log off
                                        try
         {
           logoff();
         }
...
 
Using Certificate Authentication
This section describes implementing certificate authentication in CORBA applications.
The Secure Simpapp Sample Application
The Secure Simpapp sample application uses the existing Simpapp sample application and modifies the code and configuration files to support secure communications through the SSL protocol and certificate authentication.
The server application in the Secure Simpapp sample application provides an implementation of a CORBA object that has the following two methods:
The upper method accepts a string from the client application and converts the string to uppercase letters.
The lower method accepts a string from the client application and converts the string to lowercase letters.
The Simpapp sample application was modified in the following ways to support certificate authentication and the SSL protocol:
In the ISL section of the UBBCONFIG file, the -a, -S, -z, and -Z options of the ISL command are specified to configure the IIOP Listener/Handler for the SSL protocol.
In the ISL section of the UBBCONFIG file, the SEC_PRINCIPAL_NAME, the SEC_PRINCIPAL_LOCATION, and the SEC_PRINCIPAL_PASSVAR parameters are defined to specify proof material for the IIOP Listener/Handler.
The code for the CORBA client application uses the authenticate() method of the SecurityLevel2:PrincipalAuthenticator interface to authenticate the principal and obtain credentials for the principals.
The source files for the C++ Secure Simpapp sample application are located in the \samples\corba\simpappSSL directory of the Oracle Tuxedo software. For instructions for building and running the Secure Simpapp sample application, see “Building and Running the CORBA Sample Applications” on page 10‑1.
Writing the CORBA Client Application
When using certificate authentication, write CORBA client application code that does the following:
1.
2.
3.
Uses the authenticate() method of the SecurityLevel2:PrincipalAuthenticator interface to authenticate the principals and obtain credentials for the principals. When using certificate authentication, specify Tobj::CertificateBased for the method argument and the pass phrase for the private key as the auth_data argument for Security::Opaque.
The following sections contain C++ code examples that illustrate implementing certificate authentication.
C++ Code Example of Certificate Authentication
Listing 9‑5 illustrates using certificate authentication in a CORBA C++ client application.
Listing 9‑5 CORBA C++ Client Application That Uses Certificate Authentication
....
// Initialize the ORB
CORBA::ORB_var v_orb = CORBA::ORB_init(argc, argv, "");
// Create the bootstrap object
Tobj_Bootstrap bootstrap(v_orb.in(), corbalocs://sling.com:2143);
// Resolve SecurityCurrent
CORBA::Object_ptr seccurobj =
        bootstrap.resolve_initial_references("SecurityCurrent");
SecurityLevel2::Current_ptr seccur =
        SecurityLevel2::Current::_narrow(seccurobj);
// Perform certificate-based authentication
       SecurityLevel2::Credentials_ptr the_creds;
       Security::AttributeList_var privileges;
        Security::Opaque_var continuation_data;
        Security::Opaque_var auth_specific_data;
        Security::Opaque_var response_data;
//Principal email address
        char emailAddress[] = “milozzi@bigcompany.com;”
// Pass phrase for principal’s digital certificate
        char password[] = “asdawrewe98infldi7;”
// Convert the certificate private key password to opaque
        unsigned long password_len = strlen(password);
         Security::Opaque ssl_auth_data(password_len);
// Authenticate principal certificate with principal authenticator
          for(int i = 0; (unsigned long) i < password_len; i++)
          ssl_auth_data[i] = password[i];
          Security::AuthenticationStatus auth_status;
          SecurityLevel2::PrincipalAuthenticator_var PA =
                           seccur->principal_authenticator();
          auth_status = PA->authenticate(Tobj::CertificateBased,
                                        emailAddress,
                                        ssl_auth_data,
                                        privileges,
                                        the_creds,
                                        continuation_data,
                                          auth_specific_data);
              while(auth_status == Security::SecAuthContinue) {
              auth_status = PA->continue_authentication(
                                        response_data,
                                        the_creds,
                                        continuation_data,
                                          auth_specific_data);
              }
...
 
 
Using the Interoperable Naming Service Mechanism
Note:
To use the Interoperable Naming Service mechanism to access the Oracle Tuxedo domain with the proper credentials, perform the following steps:
1.
Use the ORB::resolve_initial_references() operation to get a SecurityLevel2::PrincipalAuthenticator object for the Oracle Tuxedo domain. The SecurityLevel2::PrincipalAuthenticator object adheres to the standard CORBAservices Security Service instead of the proprietary Oracle delegated interfaces and contains methods for the purpose of authenticating principals.
2.
Use the authenticate() method of the SecurityLevel2::PrincipalAuthenticator object to log on to the Oracle Tuxedo domain and authenticate the client ORB to the Oracle Tuxedo domain. If security credentials are required to access the Oracle Tuxedo domain, the authenticate() method will return a status indicating that continued authentication is required.
3.
Use the continue_authentication() method of the SecurityLevel2::PrincipalAuthenticator object to pass encyrpted logon and credential information to the Oracle Tuxedo domain.
For more information about using the CORBA Interoperable Naming Service (INS) mechanism, see the CORBA Bootstrap Object Programming Reference for the SecurityLevel2::PrincipalAuthenticator interface.
Protecting the Client Credentials
The following information provides a sample that protects the client credentials before performing the step of continuing authentication.
The following example assumes a Java client using J2SE v 1.4, accessing an Oracle Tuxedo application.
1.
Add $TUXDIR/udataobj/java/jdk/tuxsecenv.jar to your CLASSPATH.
2.
In your client code, call com.bea.protectLogonData() before you call the PrincipalAuthenticator continue_authentication() method.
3.
The following is sample code that shows a protectLogonData() call. This code depends on Java classes that are generated from these IDL files in $TUXDIR/include: security.idl, lcs.idl, ns.idl, tobj.idl.
Listing 9-6 Sample Client Code Using CORBA INS
  try {
      // Initialize the ORB.

      ORB orb = ORB.init(args, null);

      // Authentication

      org.omg.CORBA.Object sec_obj =
        orb.resolve_initial_references("PrincipalAuthenticator");

      org.omg.SecurityLevel2.PrincipalAuthenticator pa =
      org.omg.SecurityLevel2.PrincipalAuthenticatorHelper.narrow(sec_obj);

      String userName = "geni";
      String clientName = "SimpleClient";

      org.omg.Security.SecAttribute[] privilege =
        new org.omg.Security.SecAttribute[1];

      org.omg.SecurityLevel2.CredentialsHolder myCreds =
        new org.omg.SecurityLevel2.CredentialsHolder();

      org.omg.Security.OpaqueHolder cont_data = // continuation data
        new org.omg.Security.OpaqueHolder();

      org.omg.Security.OpaqueHolder auth_data = // auth specific data
        new org.omg.Security.OpaqueHolder();

      org.omg.Security.AuthenticationStatus status = pa.authenticate(
          1,
         userName,
         clientName.getBytes(),
         privilege,
         myCreds,
         cont_data,
         auth_data
         );

      if (status.value() == 2) {

        // further authentication required

        org.omg.SecurityLevel2.Credentials creds = myCreds.value;
        String secUid = new String(cont_data.value);

      org.omg.Security.OpaqueHolder cont_data_2 =
        new org.omg.Security.OpaqueHolder();
      org.omg.Security.OpaqueHolder auth_data_2 =
        new org.omg.Security.OpaqueHolder();
      org.omg.Security.OpaqueHolder opqholder =
        new org.omg.Security.OpaqueHolder();
      byte[] ba0 = new byte[0];

        String userPasswd = new String("abc123");
        String domainPasswd = new String("abc123");

       // encrypt the logon data
       com.bea.LogonData td = new com.bea.LogonData();
        int rc = td.protectLogonData(
           userName,
           clientName,
           domainPasswd,
           userPasswd,
           secUid,
           ba0,
           opqholder
           );

        // continue authentication
        status = pa.continue_authentication(
           opqholder.value,
           creds,
           cont_data_2,
           auth_data_2
           );
      }
      else {
        System.out.println("No security required");
      }
    .
    .
    .
 
Using the Invocations_Options_Required() Method
When using certificate authentication, it may be necessary for a principal to explicitly define the security attributes it requires. For example, a bank application may have specific security requirements it needs to meet before the bank application can transfer data to a database. The invocation_options_required() method of the SecurityLevel2::Credentials interface allows the principal to explicitly control the security characteristics of the SSL connection. When using the corbaloc URL address format, you can secure the bootstrapping process by using the authenticate()and invocation_options_required() methods of the SecurityLevel2::Credentials interface.
To use the invocation_options_required() method, complete the following steps:
1.
Write application code that uses the authenticate() method of the SecurityLevel2::PrincipalAuthenticator object to specify certificate authentication is being used.
2.
Use the invocation_options_required() method to specify the security attributes the principal requires. See the description of the invocation_options_required() method in the “C++ Security Reference” on page 14‑1 and “Java Security Reference” on page 15‑1 for a complete list of security options.
Listing 9‑7 provides a C++ example that uses the invocation_options_required() method.
Listing 9‑7 C++ Example That Uses the invocation_options_required() Method
// Initialize the ORB
CORBA::ORB_var v_orb = CORBA::ORB_init(argc, argv, "");
// Create the bootstrap object
Tobj_Bootstrap bootstrap(v_orb.in(), corbalocs://sling.com:2143);
// Resolve SecurityCurrent
CORBA::Object_ptr seccurobj =
        bootstrap.resolve_initial_references("SecurityCurrent");
SecurityLevel2::Current_ptr seccur =
        SecurityLevel2::Current::_narrow(seccurobj);
// Perform certificate-based authentication
        SecurityLevel2::Credentials_ptr the_creds;
Security::AttributeList_var privileges;
        Security::Opaque_var continuation_data;
        Security::Opaque_var auth_specific_data;
        Security::Opaque_var response_data;
//Principal email address
        char emailAddress[] = “milozzi@bigcompany.com;”
// Pass phrase for principal’s digital certificate
        char password[] = “asdawrewe98infldi7;”
// Convert the certificate private key password to opaque
        unsigned long password_len = strlen(password);
        Security::Opaque ssl_auth_data(password_len);
// Authenticate principal certificate with principal authenticator
          for(int i = 0; (unsigned long) i < password_len; i++)
          ssl_auth_data[i] = password[i];
          Security::AuthenticationStatus auth_status;
          SecurityLevel2::PrincipalAuthenticator_var PA =
                           seccur->principal_authenticator();
         
 auth_status = PA->authenticate(Tobj::CertificateBased,
                                         emailAddress,
                                         ssl_auth_data,
                                         privileges,
                                         the_creds,
                                         continuation_data,
                                          auth_specific_data);
          the_creds->invocation_options_required(
                               Security::Integrity|
                               Security::DetectReplay|
                               Security::DetectMisordering|
                               Security::EstablishTrustInTarget|
                               Security::EstalishTrustInClient|
                               Security::SimpleDelegation);
          while(auth_status == Security::SecAuthContinue) {
                auth_status = PA->continue_authentication(
                                         response_data,
                                         the_creds,
                                         continuation_data,
                                            auth_specific_data);
              }
 

Copyright © 1994, 2017, Oracle and/or its affiliates. All rights reserved.