ORBAsec SL3 adds authentication and encryption to Adiron's AdironORB, a source-available ORB, and IONA's ORBacus for Java ORB.
ORBAsec SL3 brings you both TLS/SSL and both Windows 2000 Kerberos and MIT Kerberos interoperability.
ORBAsec SL3 also brings you Kerberos User-to-User protocol that allows you to set up servers based on Kerberos login credentials.
ORBAsec SL3 gives you the OMG and EJB standard CSIv2 protocol which allows you to perform identity delegation over these cryptographic technologies to enhance your secure capabilities.
ORBAsec SL3 is an ongoing implementation of the Common Secure Interoperability Version 2 (CSIv2) Protocol
ORBAsec SL3 implements the Authorization Token Layer Acquisition Service (ATLAS) part of the CSIv2 protocol.
The documentation presented in this HTML directory is the preliminary documentation for an Application Programming Interface (API) for enabling the use of the OMG CSIv2 Protocol in CORBA applications. The API presented here is not the standard CORBA Security Level 2 API. The standard CORBA Security Level 2 API is extremely insufficient for enabling the use of the CSIv2 Protocol. Instead, Adiron has created a brand new API.
This new API is based on a mathematical model and calculus regarding Principals, which can be found in the following paper: Authentication in Distributed Systems: Theory and Practice by Lampson, Abadi, and Burrows.
A Principal is an entity that is either a person, a server, etc. that is referred to by a name. A principal may be authenticated by virtue of cryptographic means, such as the use of SSL/TLS, or other authentication mechanism. A principal may be anonymous.
We have named this new API SecurityLevel3 under "adiron.com". This API is a much more robust API than OMG's Security Level 2 API, and has well defined semantics. We will, in time, push to have the OMG standardize on much of this API, as it does have a basis in mathematics, and therefore, gives credibility to a security API.
Both of these layers interact in such a way to give security contexts that can be lasting over connections, or as good as only one request over a long-standing connection.
The Transport Layer is basically Common Security Interoperability Version 1. Version 1 handled security down at the transport layer, i.e. closely wrapped around TCP/IP. It covers the secure establishment of the connection from client to server.
In a regular ORB, the transport layer is the ORB protocol, General Inter-ORB Protocol (GIOP) over TCP/IP. This protocol is commonly known as IIOP. In CSIv1, IIOP and two other protocols exist, SSLIOP and SECIOP. SSLIOP defines the transport layer as using SSL (now known as TLS) over TCP/IP. So, GIOP over TLS over TCP/IP is known as SSLIOP. The OMG defines its own SSL-like transport protocol for dealing with General Security Services API (GSS-API) from the IETF. This protocol is known as SECP. GIOP over SECP over TCP/IP is known as SECIOP.
Before messages start flowing freely over the communication channel between ORBs, the secure TLS, or SECP endpoints negotiate the channel protection, such as encryption and integrity checking. They also exchange enough information to authenticate the endpoints to one another, by virtue of exchanging cryptographic keys and signatures.
The CSIv2 layer is run on top of the transport layer and its information is carried in the Service Context of GIOP Request and Reply messages. The CSIv2 layer is composed of three parts.
Each of these layers is actually a piece of a single CSI GIOP Service Context Element that flows with a request. They work together and combine to tell the server who and with what privileges the GIOP request is being made.
The Client Authentication Layer provides an extra layer of authentication. Is provides for the delivery of an authentication token, or cookie, to the server. This cookie merely tells the server that its holder is in possession of proven authentication and identity information. The reason for the existence of this layer is that TLS does not require a client to authenticate to a server. For example, to authenticate at the transport layer in TLS requires the client to possess an X.509 certificate. The Client may only have a notion of using a username and a password. ORBAsec SL3 supports a Username/Password scheme at this layer.
The Identity Assertion Layer allows a client to merely state that the request being made is on some other entity's behalf. An application using this feature is usually an intermediate server. For instance, let's say Bob, has gotten a request from an authenticated client, Alice, using TLS. Bob needs to contact another CORBA object, Carol, and make a request, not as Bob, but as the original client, Alice. There is an agreement between the intermediate server, Bob, and the final target, Carol, such that Bob will simply state under which principal the request is being made. Carol will act accordingly based on that information. Carol interprets this information as "Bob says Alice is making this request".
The Authorization Layer is a layer that enables the delivery of an authorization token from the client to the server. This layer implements a push model for authorization. The client, Alice, may get and cache her authorization information as not to overburden a heavy server, Bob, the task of looking up Alice's credentials for each request. This token might contain such things as a verifiable certificate claiming that Alice has certain privileges on which Bob may make trust decisions. ORBAsec SL3 uses the standard Authorization Token Layer Acquisition Service (ATLAS) to implement both ends of the authorization layer.
The Security Level 3 API is the heart of ORBAsec SL3's CSIv2 implementation. It carries common data structures, such as PrincipalName, PrinAttribute, Principal, and other such data structures that implement a model of principals closely resembling the mathematical model and calculus found in the following paper: Authentication in Distributed Systems: Theory and Practice by Lampson, Abadi, and Burrows.
The Security Level 3 API can be said to be divided up into three separate yet intertwined models.
The Administrative model contains interfaces that deal with the maintenance of the Security Level 3 entities. There is a SecurityManager, CredentialsCurator, CredentialsAcquirer, and helper objects. The Credentials Model, entities of which emanate from the objects in the Administrative model, handle the establishment of secure associations between clients and targets, and abstract away the use of cryptographic protocols. The Principals Model consists of structured data types, used in the Credentials model entities, to represent the principals involved in secure associations.
The SecurityManager
is the Security Level 3 Service object that is retrieved from the ORB using the
resolve_initial_references("SecurityLevel3:SecurityManager") call.
The Security Manager, containing a reference to
the CredentialsCurator,
has some operations for creating security relevant policies, and an operation
to discover the credentials of a target object.
The CredentialsCurator is an object that creates credentials, by way of CredentialsAcquirer objects, and maintains lists of active credentials for the ORB's security service. It creates Credentials that operate the CSIv2 Layer and the Transport Security Layer together, as if they were married. The acquisition of Credentials is a complex business. Many parameters go into acquiring credentials, such as transport security options: port numbers, IP addresses, X.509 Private keys and certificates, etc., and CSI options, such as a TrustDecider, and Username/Password processors, and authorization processors, i.e. ATLAS.
To help with this business of Credentials Acquisition, ORBAsec SL3 has created the SL3 Argument Factory, which is located in the SL3AQArgs module. This object handles the building of the acquisition argument that is given to the Credentials Curator to create Credentials, through the use of an ArgBuilder objects. These objects are extended by interfaces in other modules that create options specific for their purposes, such as using TLS with Java KeyStores, or Kerberos with the JAAS framework.
The SecurityCurrent is a Current object that is used on the server side. It contains operations that retrieve a representation of the client's credentials during the execution of a request.
In the Security Level 3 Principals model, a Principal comes in three types. A SimplePrincipal merely states a request, i.e. (A says r). A QuotingPrincipal merely states another principal is making a request, i.e. (A says B says r), and is usually denoted with a vertical bar, as in (A|B) for "A quotes B". And finally, a ProxyPrincipal is almost the same as a QuotingPrincipal, however, it is a little stronger than a QuotingPrincipal in that B may have given A something to use, such as an authenticator, or a certificate claiming that if (A says B says r) then A is allowed to speak on behalf of B. The difference is subtle.
All the Principals are valuetypes with simplistic factory operations. They can be shipped across to other objects, such as Access Decision objects, etc, for analysis, access control, auditing, etc. This model is the data model of ORBAsec SL3.
The implementation of the Security Level 3 API actually uses an extended Transport Security API in dealing with the transport. The Transport Security API is also extended so that it may be replaceable. Replaceability allows other secure transports, i.e. other than TLS, to be implemented and installed into ORBAsec SL3, such as SECIOP-GSS-KerberosV5.
The first thing you need to do to get started with ORBAsec SL3 with AdironORB is to initialize the ORB with ORBAsec SL3's initializers. There are two different ways to initialize the ORB with ORBAsec SL3, one if your application is going to be pure client, and the other if your application is going to be a server. This means without bringing up the Root POA (Portable Object Adapter) and one if you are going to be a server, i.e. reference the Root POA.
Client initialization is performed as follows:
java.util.Properties props = System.getProperties();
props.put("org.omg.CORBA.ORBClass", "com.adiron.orb.core.ORB");
props.put("org.omg.CORBA.ORBSingletonClass",
"com.adiron.orb.core.ORBSingleton");
props.put("org.adiron.orb.server.enable","false");
props.put("org.adiron.orb.ORBInitializerClass",
"com.adiron.orbasec.sl3.AdironORBInitializer");
props.put("org.omg.PortableInterceptor.ORBInitializerClass." +
"com.adiron.orbasec.sl3.SL3Initializer_AdironORB", "");
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, props);
The first two properties select the ORB you will be working with, which is
AdironORB. The next property, org.adiron.orb.server.enable,
determines whether the ORB will be used for server applications.
For a client application, this property is set to false.
The next property, org.adiron.orb.ORBInitializerClass,
specifying the AdironORB internal initializer, is set to
com.adiron.orbasec.sl3.AdironORBInitializer for using
ORBAsec SL3's secure network communications.
The last property, starting with
org.omg.PortableInterceptor.ORBInitializerClass, installs
ORBAsec SL3 into the Adiron ORB by way of Portable Interceptors.
Server initialization is basically the same except that we change the value
of the org.adiron.orb.server.enable property to true.
Server initialization is performed as follows:
java.util.Properties props = System.getProperties();
props.put("org.omg.CORBA.ORBClass", "com.adiron.orb.core.ORB");
props.put("org.omg.CORBA.ORBSingletonClass",
"com.adiron.orb.core.ORBSingleton");
props.put("org.adiron.orb.server.enable","true");
props.put("org.adiron.orb.ORBInitializerClass",
"com.adiron.orbasec.sl3.AdironORBInitializer");
props.put("org.omg.PortableInterceptor.ORBInitializerClass." +
"com.adiron.orbasec.sl3.SL3Initializer_AdironORB", "");
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, props);
You need the server initialization if you are going to access the
Root POA using the orb.resolve_initial_references("RootPOA")
call and perform object._this(orb) calls, which "registers"
an object implementation with the ORB's POAs.
Client initialization is performed as follows:
java.util.Properties props = System.getProperties();
props.put("org.omg.CORBA.ORBClass", "com.ooc.CORBA.ORB");
props.put("org.omg.CORBA.ORBSingletonClass",
"com.ooc.CORBA.ORBSingleton");
props.put("ooc.oci.plugin.iiop","com.adiron.orbasec.sl3.IIOP");
props.put("org.omg.PortableInterceptor.ORBInitializerClass." +
"com.adiron.orbasec.sl3.ClientInitializer", "");
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, props);
The first two properties select the ORB you will be working with, which is
ORBacus. The next property, ooc.oci.plugin.iiop, specifying
the IIOP plug-in class, is set to com.adiron.orbasec.sl3.IIOP
for using ORBAsec SL3's secure network communications instead of ORBacus'
"insecure" IIOP communications. The next property installs ORBAsec SL3 into
the ORBacus ORB by way of Portable Interceptors, which is an ORB initialization
interceptor. We use the class com.adiron.orbasec.sl3.ClientInitializer
to initialize a client.
Server initialization is basically the same except that we use
a different initializer, com.adiron.orbasec.sl3.ServerInitializer.
Server initialization is performed as follows:
java.util.Properties props = System.getProperties();
props.put("org.omg.CORBA.ORBClass", "com.ooc.CORBA.ORB");
props.put("org.omg.CORBA.ORBSingletonClass",
"com.ooc.CORBA.ORBSingleton");
props.put("ooc.oci.plugin.iiop","com.adiron.orbasec.sl3.IIOP");
props.put("org.omg.PortableInterceptor.ORBInitializerClass." +
"com.adiron.orbasec.sl3.ServerInitializer", "");
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, props);
You need the server initialization if you are going to access the
Root POA using the orb.resolve_initial_references("RootPOA")
call and perform object._this(orb) calls, which "registers"
an object implementation with the ORB's POAs.
props.put("ooc.orb.init_iiop","none"); props.put("ooc.oci.plugin.iiop","com.adiron.orbasec.sl3.IIOP");The basic procedure for using Security Level 3 API to create CSIv2 enabled Credentials or Transport Security API to create CSIv1 transport Credentials is similar, but creating CSIv2 enabled credentials involves more steps.
The acquisition process for creating CSIv1 transport Credentials is as follows:
resolve_initial_references("TransportSecurity:SecurityManager").resolve_initial_references("SL3TLS:ArgumentFactory").get_credentials on the Credential Acquirer object to get the
Transport Security Credentials object.The acquisition process for creating CSIv2 Credentials is as follows:
resolve_initial_references("SecurityLevel3:SecurityManager").resolve_initial_references("SL3TLS:ArgumentFactory").resolve_initial_references("SL3CSI:ArgumentFactory").get_credentials on the Credentials Acquirer object to
get the Security Level 3 Credentials object.We illustrate one specific method of acquiring Security Level 3 (i.e. CSIv2) with TLS for a Server, by the Java code below:
public com.adiron.SecurityLevel3.OwnCredentials
createDefaultSL3TLSCredentials(org.omg.CORBA.ORB orb)
throws org.omg.CORBA.UserException
{
//
// Resolve the Security Level 3 Security Manager
//
com.adiron.SecurityLevel3.SecurityManager secManager =
com.adiron.SecurityLevel3.SecurityManagerHelper.narrow(
orb.resolve_initial_references(
"SecurityLevel3:SecurityManager"));
//
// Get the Credentials Curator from the Security Manager
//
com.adiron.SecurityLevel3.CredentialsCurator curator =
secManager.credentials_curator();
//
// Resolve the TLS Transport Argument Factory
//
com.adiron.SL3TLS.ArgumentFactory argFac =
com.adiron.SL3TLS.ArgumentFactoryHelper.narrow(
orb.resolve_initial_references("SL3TLS:ArgumentFactory") );
//
// Get a TLS KeyStore based Transport Argument Builder for a Server.
//
com.adiron.SL3TLS.TLSKeyStoreArgBuilder tlsArgBuilder =
argFac.createTLSKeyStoreArgBuilder(
com.adiron.TransportSecurity.CU_AcceptOnly.value );
//
// Add TLS KeyStore parameters for initializing TLS Transport
// Security Credentials.
//
// The TCPIP (socket) parameters will be left to the defaults.
//
tlsArgBuilder.addTLSKeyStoreWithStorePass(
"FILE:demo.keystore", // keystore URL
"IAIKKeyStore", // storetype
"mystorepass", // storetpye
"marge", // keyalias
"mypassword", // keypass
new String[] {"SpringfieldCA"} // trusted_cert_names
);
//
// Resolve the CSI Argument Factory
//
com.adiron.SL3CSI.ArgumentFactory csiArgFac =
com.adiron.SL3CSI.ArgumentFactoryHelper.narrow(
orb.resolve_initial_references("SL3CSI:ArgumentFactory") );
//
// Get an Argument Builder for Security Level 3 Credentials for a Server
//
com.adiron.SL3CSI.CSIArgBuilder csiArgBuilder =
csiArgFac.createCSIArgBuilder(
com.adiron.SecurityLevel3.CU_AcceptOnly.value );
//
// Add the Transport Argument to the CSI Argument Builder
//
csiArgBuilder.addTransportCredentialsAQArgs(
com.adiron.SL3TLS.MID_TLS.value,
com.adiron.SL3TLS.AQM_TLSArgs.value,
tlsArgBuilder.reapAQArg() );
//
// Reap the CSI Acquisition Argument from the Builder
// and acquire the credentials.
//
com.adiron.SecurityLevel3.CredentialsAcquirer acquirer =
curator.acquire_credentials(
com.adiron.SL3CSI.AQM_CSIArgs.value,
csiArgBuilder.reapAQArg() );
//
// Get the Credentials. True means put them on the
// default own credentials list for accepting invocations.
//
com.adiron.SecurityLevel3.OwnCredentials own =
acquirer.get_credentials(true);
return own;
}
There are many other options to acquiring credentials. Please check each
Argument Builder's documentation. The Argument Builders reside in the
following modules:
Please review the demonstration programs in the "sl3/demo" directory and the test programs in the "sl3/test" directory to get a feel for acquiring the appropriate credentials for your application. The demonstration (sl3/demo) directories show a number of different scenarios: