In this example, we will modify the poaHello example to demonstrate use of SSL with the ORB.
The server then creates a transient POA, sslPOA
, with
SecurityPolicy
specifying INTEGRITY
quality of protection and no client
authentication. Note that even though the default CipherSuites are for
confidentiality, the group of objects served by this POA will use
integrity only cipher suites to protect communication.
package sslHello; import util.Util; import java.io.File; import java.io.FileInputStream; import org.omg.CORBA.Any; import org.omg.CORBA.ORB; import org.omg.CORBA.Policy; import org.omg.PortableServer.POA; import org.omg.PortableServer.Servant; import org.omg.PortableServer.ImplicitActivationPolicyValue; import com.sssw.jbroker.api.security.QualityOfProtection; import com.sssw.jbroker.api.security.CSIv2.ClientAuthInfo; import com.sssw.jbroker.api.security.CSIv2.SecurityPolicy; import com.sssw.jbroker.api.security.CSIv2.SecureTransportInfo; import com.sssw.jbroker.api.security.CSIv2.SecurityPolicyValue; public class Server { public static void main(String[] args) { | try { | | | | // create the jBroker ORB | | ORB orb = ORB.init(args, null); | | | | // initialize support for SSL | | SSLUtil.initializeSSL(orb, args[0], null, true); | | | | // get the root POA | | POA rootPOA = (POA) orb.resolve_initial_references("RootPOA"); | | | | // create the security policy | | SecureTransportInfo transport = new SecureTransportInfo( | | QualityOfProtection.INTEGRITY, null, 0, false, false, true); | | Any secPolicy = orb.create_any(); | | secPolicy.insert_Value(new SecurityPolicyValue(transport, null, | | false)); | | | | // create the secure POA | | POA sslPOA = rootPOA.create_POA("sslPOA", | | rootPOA.the_POAManager(), | | new Policy[] { | | | rootPOA.create_implicit_activation_policy( | | | ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION), | | | orb.create_policy(SecurityPolicy.POLICY_TYPE, secPolicy) | | }); | | | | // create a servant | | Servant hello = new HelloImpl(orb); | | | | // create a stringified object reference | | String helloIOR = orb.object_to_string( | | sslPOA.servant_to_reference(hello)); | | | | // write the stringified object reference | | Util.writeIOR(helloIOR, "ior", true); | | | | // activate the SSL POA | | sslPOA.the_POAManager().activate(); | | | | // wait for invocations | | System.out.println("waiting for invocations ..."); | | orb.run(); | | | } catch (Exception ex) { | | ex.printStackTrace(); | } } }
The IOR for the secure hello object contains an SSL component specifying integrity and establish trust in target options. The output from parseIOR:
Type Id = IDL:helloWorld/Hello:1.0 Profiles = 1 Internet Inter-ORB Protocol (IIOP) Profile: version = 1.1 host = godel port = 0 obj key = 4A424B52 00020001 16A8D28D 5B545203 JBKR........[TR. 00000001 .... components = 1 TAG_SSL_SEC_TRANS : requires: integrity, authenticate target, SSL port: 46020
The HelloImpl
class demonstrates some of the SSL specific methods that the
server can invoke on the SecurityCurrent. The server gets the
caller's IP address, negotiated cipher suite, and the client certificate chain.
Since in this example the server did not require the client to authenticate
using the PUBLIC_KEY_REALM the client certificate chain will be null.
package sslHello; import org.omg.CORBA.ORB; import com.sssw.jbroker.api.security.SecurityCurrent; public class HelloImpl extends helloWorld.HelloPOA { SecurityCurrent _securityCurrent; public HelloImpl(ORB orb) { | try { | | _securityCurrent = (SecurityCurrent) orb. | | resolve_initial_references("SecurityCurrent"); | } catch (Exception ex) { | | ex.printStackTrace(); | } | | com.sssw.jbroker.orb.RequestHandlerImpl._debug = true; } public String sayHello() { | try { | | System.out.println("Caller Address: " + | | _securityCurrent.getInetAddress()); | | | | System.out.println("Negotiated Cipher: " + | | _securityCurrent.getNegotiatedCipherSuite()); | | | | SSLUtil.printCertChain(_securityCurrent.getCertificateChain()); | | | } catch (Exception ex) { | | ex.printStackTrace(); | } | | return "Hello World!\n"; } }
The client initializes SSL with integrity CipherSuites, its certificate chain, its private key, and the trusted CAs.
The client then gets the Hello
object reference and invokes
the sayHello
method on it. The client also demonstrates the
SSL specific methods that it can call to determine the negotiated cipher
suite as well as the server's certificate chain. Note that this can be
even before any method is invoked by the client.
package sslHello; import util.Util; import org.omg.CORBA.ORB; import org.omg.CORBA.portable.ObjectImpl; import java.io.ByteArrayInputStream; import helloWorld.Hello; import helloWorld.HelloHelper; import com.sssw.jbroker.api.security.CipherSuite; import com.sssw.jbroker.api.security.SecurityCurrent; public class Client { public static void main(String[] args) { | try { | | | | // create the jBroker ORB | | ORB orb = ORB.init(args, null); | | | | // initialize SSL | | SSLUtil.initializeSSL(orb, args[0], CipherSuite. | | CIPHER_SUITES_INTEGRITY_ONLY, false); | | | | // read the stringified object reference | | String helloIOR = Util.readIOR("ior"); | | | | // narrow the stringified object | | Hello hello = HelloHelper.narrow(orb.string_to_object(helloIOR)); | | | | // get the SecurityCurrent | | SecurityCurrent secCurrent = (SecurityCurrent) orb. | | resolve_initial_references("SecurityCurrent"); | | | | // print the negotiated ciphers | | System.out.println("Negotiated Cipher: " + | | secCurrent.getNegotiatedCipherSuite((ObjectImpl) hello)); | | | | // print out the peer certificates (Java 2 only) | | SSLUtil.printCertChain(secCurrent.getCertificateChain( | | (ObjectImpl) hello)); | | | | // invoke method on the object | | System.out.println(hello.sayHello()); | | | } catch (Exception ex) { | | ex.printStackTrace(); | } } }
This is a utility class to initialize SSL. The initializeSSL
method gets the CertificateManager from the ORB, and then
sets the various pieces of data (certificates, private keys, pass phrase,
trusted CAs, and cipher suites) needed by SSL to work.
package sslHello; import com.sssw.jbroker.api.security.CipherSuite; import com.sssw.jbroker.api.security.CertificateManager; import java.io.*; import java.lang.reflect.Method; import org.omg.CORBA.ORB; import com.sssw.jbroker.api.security.CipherSuite; import com.sssw.jbroker.tools.security.PrintCert; public class SSLUtil { public static void initializeSSL(ORB orb, String dir, CipherSuite[] cipherSuites, boolean server) throws Exception { | // get the certificate Manager | CertificateManager certMgr = (CertificateManager) orb. | resolve_initial_references("CertificateManager"); | | // the dierctory with certs and keys | dir = dir + File.separator; | | // set cipher suite | certMgr.setCipherSuites(cipherSuites); | | // determine cert chain and private key files | String privKey = null, certChain = null; | if (server) { | | privKey = "data/serverKey.pkcs8"; | | certChain = "data/serverCertChain.chain"; | } else { | | privKey = "data/clientKey.pkcs8"; | | certChain = "data/clientCertChain.chain"; | } | | // set certificate chain and private key | if (privKey != null) { | | | | // load the private key | | byte[] privateKey = loadFromFile(new File(dir + privKey)); | | | | // load the certificate chain | | byte[][] serverCertChain = loadChainFromFile( | | new File(dir + certChain)); | | | | // set certificate chain and private key | | certMgr.setCertificateChain(serverCertChain, privateKey, "test"); | } | | // get the list of trusted CA certificates | File certDir = new File(dir, "certs"); | String[] certs = certDir.list(new FilenameFilter() { | | public boolean accept(File dir, String name) { | | | return name.endsWith(".cert") ? true : false; | | } | }); | | // set the trusted CAs | for (int i=0; i < certs.length; i++) | certMgr.addCACertificate(loadFromFile(new File(certDir, certs[i]))); } // print the certificate using reflection public static void printCertChain(byte[][] certs) throws Exception { | System.out.print("Peer Certificate Chain: "); | if (certs != null) { | | for (int i=0; i < certs.length; i++) { | | | if (_genCertMethod != null) { | | | | Object cert = _genCertMethod.invoke(_certFactory, | | | | new Object[] { new ByteArrayInputStream(certs[i]) }); | | | | System.out.println(cert); | | | } else PrintCert.doPrint(certs[i]); // jBroker internal API | | } | } else System.out.println("<null>"); } private static byte[][] loadChainFromFile(File file) throws IOException { | DataInputStream dis = new DataInputStream(new FileInputStream(file)); | | // get the size of the chain | int chainLen = dis.readInt(); | byte[][] chain = new byte[chainLen][]; | | // read in the individual elements | for (int i=0; i < chainLen; i++) { | | chain[i] = new byte[dis.readInt()]; | | dis.readFully(chain[i]); | } | | // return the chain | dis.close(); return chain; } private static byte[] loadFromFile(File file) throws IOException { | DataInputStream dis = new DataInputStream(new FileInputStream(file)); | byte[] bytes = new byte[dis.available()]; | dis.readFully(bytes); dis.close(); | return bytes; } // is Certificate Factory available private static Object _certFactory = null; private static Method _genCertMethod = null; static { | try { | | Class certFactoryClass = Class.forName( | | "java.security.cert.CertificateFactory"); | | Method getInstanceMethod = certFactoryClass.getDeclaredMethod( | | "getInstance", new Class[] { String.class }); | | _certFactory = getInstanceMethod.invoke(null, new Object[] { | | "X.509"}); | | _genCertMethod = _certFactory.getClass().getDeclaredMethod( | | "generateCertificate", new Class[] { InputStream.class }); | } catch (Throwable ex) {} } }
Copyright © 2000-2004, Novell, Inc. All rights reserved. |