Hermes ebXML SSL Configuration


This blog item describes how I setup End-2-End security ebXML communication using the Hermes2 framework.
The ebMS client is on a Tomcat installation and it communicates with an Apache WebServer (running on Linux and redirecting ebms communication to Tomcat instance on the same server).

  • Hermes2 (client) and Tomcat installed
  • Hermes2 (server) and Tomcat installed
  • Server certificates generated (self signed)

Configuring Hermes2 (corvus webbapplication within Tomcat)

When you change the partner agreement to use the https:// protocol towards the receiver you will get the following error (look in the ebms.log of the ebMS sender).
hk.hku.cecid.ebms.spa.task.DeliveryException: Cannot send the message
    by hk.hku.cecid.piazza.commons.net.ConnectionException: Unable to send HTTP SOAP request
    by javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    by sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    by sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at hk.hku.cecid.ebms.spa.task.OutboxTask.sendMsgByHttp(OutboxTask.java:578)
    at hk.hku.cecid.ebms.spa.task.OutboxTask.execute(OutboxTask.java:440)
    at hk.hku.cecid.piazza.commons.module.ActiveThread.run(ActiveThread.java:90)
    at java.lang.Thread.run(Unknown Source)

  1. You need to edit the <CorvusWebApp>/WEB-INF/classes/hk/hku/cecid/piazza/corvus/core/conf/corvus.module.xml
    <module id="piazza.corvus" name="Piazza Corvus" version="1.0">

        <component id="logger" name="System Logger">
            <parameter name="config" value="hk/hku/cecid/piazza/corvus/core/conf/corvus.log.properties.xml" />      
            <parameter name="category" value="hk.hku.cecid.piazza" />

        <component id="properties" name="System Properties">
            <parameter name="config" value="hk/hku/cecid/piazza/corvus/core/conf/corvus.properties.xml" />

        <component id="messages" name="System Messages">
            <parameter name="config" value="hk/hku/cecid/piazza/corvus/core/conf/corvus.messages.xml" />

        <!-- Set up a SSL Trust Manager for SSL connection -->
        <component id="ssl-trust-manager" name="SSL Trust Manager">
            <parameter name="keystore-location" value="c:/program files/java/jre1.5.0_22/lib/security/cacerts" />
            <parameter name="keystore-password" value="changeit" />

        <!-- Set up a SSL Key Manager for SSL connection, it is configured in application server most case (e.g. Tomcat server.xml) -->
        <component id="ssl-key-manager" name="SSL Key Manager">
            <parameter name="keystore-location" value="d:/local/programs/hermes2/plugins/hk.hku.cecid.ebms/security/corvus.p12" />
            <parameter name="keystore-password" value="password" />
            <parameter name="key-alias" value="corvus2" />
            <parameter name="key-password" value="password" />
            <parameter name="keystore-type" value="PKCS12" />
            <parameter name="keystore-provider" value="org.bouncycastle.jce.provider.BouncyCastleProvider" />


  2. Edit the <CorvusWebApp>/WEB-INF/classes/hk/hku/cecid/piazza/corvus/core/conf/corvus.properties.xml
    <?xml version="1.0" encoding="UTF-8"?><corvus>

        <!-- Home Directory -->

        <!-- Plugin Registry -->

        <!-- Encoding settings -->
        <!-- Environment settings -->
                <javax.net.ssl.trustStore>c:/program files/java/jre1.5.0_22/lib/security/cacerts</javax.net.ssl.trustStore>

    * Be sure to use absolute paths for the keystore locations
    * The Keymanager store is used to store the Certificate for this ebMS instance
    * The Trust Manager is used to upload the Certificates this ebMS instance can trust. When sender ebMS try to establish a secure connection, the receiver ebMS will provide a public certificate to sender ebMS to identify its identity. If this certificate is self-signed, it should be added to the truststore defined on the sender side.

When you send a message again now to the https endpoint I got the error:
hk.hku.cecid.ebms.spa.task.DeliveryException: Cannot send the message
    by hk.hku.cecid.piazza.commons.net.ConnectionException: Unable to send HTTP SOAP request
    by javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: Certificate chain not trusted
    by java.security.cert.CertificateException: Certificate chain not trusted
    at hk.hku.cecid.ebms.spa.task.OutboxTask.sendMsgByHttp(OutboxTask.java:578)
    at hk.hku.cecid.ebms.spa.task.OutboxTask.execute(OutboxTask.java:440)
    at hk.hku.cecid.piazza.commons.module.ActiveThread.run(ActiveThread.java:90)
    at java.lang.Thread.run(Unknown Source)

This is because I did not import the certificate of the Receiver yet into the Java TrustStore as defined above (In this case the server certificate was self signed).
  1. Import the server certificate in the trust store (be sure the certificate is X.501):
    keytool -import -alias tomcat -keystore <your_keystore_filename> -trustcacerts -file <your_certificate_filename>

When I imported the server.crt and ca.crt (both generated on the Linux server with OpenSSL).

SSL: Tomcat and Apache some handy links


I know there has been written a lot already about SSL configuration on Tomcat and Apache, but for my own registration I store some links I used to setup SSL.
It also contains some handy commands I used to generate certificates.


Client Certificate Authentication with Apache
Apache webserver and SSL configuration

Nice overview of SSL and OpenSSL

OpenSSL and PKCS#12 FQA

Description of Java keytool
Most common keytool commands

Configuration of Hermes2 (ebXML framework) with SSL

Configuration of SSL in Tomcat


In cryptography, X.509 is an ITU-T standard for a public key infrastructure (PKI) for single sign-on (SSO) and Privilege Management Infrastructure (PMI). X.509 specifies, amongst other things, standard formats for public key certificates, certificate revocation lists, attribute certificates, and a certification path validation algorithm.

PKCS#12 is a standard for storing private keys and certificates securely. It defines a file format commonly used to store X.509 private keys with accompanying public key certificates, protected with a password-based symmetric key, and is the successor to PFX from Microsoft. PFX has received heavy criticism of being one of the most complex cryptographic protocols, but nevertheless remains the only standard way today to store private keys and certificates in a single encrypted file.
Note: There are other PKCS standards described here.

OpenSSL is an open source implementation of the SSL and TLS protocols. The core library (written in the C programming language) implements the basic cryptographic functions and provides various utility functions.

In cryptography, RSA (which stands for Rivest, Shamir and Adleman who first publicly described it) is an algorithm for public-key cryptography. It is the first algorithm known to be suitable for signing as well as encryption, and was one of the first great advances in public key cryptography. RSA is widely used in electronic commerce protocols, and is believed to be secure given sufficiently long keys and the use of up-to-date implementations.


How to explain Cordys BPM?

Today I got a question from Anita one of my Twitter followers:

"Most people just dont get the whole application, BPM, layered language, how do you explain Cordys to people?"

So to get a discussion going i post this question to my Blog so that we can discuss here !

A few questions come to me:
  • What do people don't get? The layering? The BPM language? Or the step towards Cordys?

The whole thing about BPM is that you get a flexible business architecture that is abstracting the business processes from the technical implementation.
This way you get technical flexibility as well as business flexibility. BPM brings business and IT together !

Cordys BOP4 is a platform that supports this notion of layering and processes with a service oriented architecture.
It follows the principles as set by Thomas Erl's SOA Principles.
Within the SOA patterns there is also the layering pattern:

This is about layering your Services into three abstraction layers. Thomas talks about
  • Task Services - A business service with a functional boundary directly associated with a specific parent business task or process.
  • Entity Services - A service centric service that bases its functional context and boundary one a related business entity.
  • Utility Services - Services that provide cross-cutting functionality, also known as application services or technology services.

When we talk about SOA layering you also see the 5-layering architecture. In those layering the presentation layer and application/data layer is added.

Within the Cordys BOP4 platform this is mapped to:
  • Visual Layer - XForms, WebBased GUI
  • Business Process Layer - BPM processes modelled with BPMN and exposed as WebServices
  • Business Service Layer - Entity Services modelled with BPMN and exposed as WebServices
  • Technical Service Layer - Application Connectors, like FTP, File and Database connectors, exposed as WebServices.
  • External Systems - These are the external systems that are used within the SOA/BPM architecture.

The WebServices is the Standardized Service Contract SOA Principle used within Cordys.

Can't wait to here your comments !


Cordys: Authenticator is not instantiated via the properties

I was testing Basic Authentication with soapUI and got the following error:

"Authenticator is not instantiated via the properties".

<soapenv:Envelope xmlns:def="http://schemas.cordys.com/default" xmlns:mes="http://www.cvz.nl/csp/message" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

         <faultcode xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/">ns0:Client</faultcode>
         <faultstring xml:lang="en-US">User validation failed for: '5517'.</faultstring>
            <cordys:FaultDetails xmlns:cordys="http://schemas.cordys.com/General/1.0/">
            <cordys:FaultRelatedException xmlns:cordys="http://schemas.cordys.com/General/1.0/">com.eibus.security.identity.IdentityValidationException: Could not authenticate username '5517': Authenticator is not instantiated via the properties constructor
    at com.eibus.security.identity.WSSecurityUsernameTokenIdentityType.validate(WSSecurityUsernameTokenIdentityType.java:71)
    at com.eibus.soap.SOAPTransaction.&lt;init>(SOAPTransaction.java:349)
    at com.eibus.soap.SOAPTransaction.&lt;init>(SOAPTransaction.java:175)
    at com.eibus.soap.Processor.onReceive(Processor.java:956)
    at com.eibus.soap.Processor.onReceive(Processor.java:929)
    at com.eibus.connector.nom.Connector.onReceive(Connector.java:417)
    at com.eibus.transport.Middleware$NonTransactionalWorkerThreadBody.run(Middleware.java:1722)
    at com.eibus.util.threadpool.WorkerThread.run(WorkerThread.java:64)
Caused by: com.eibus.security.authentication.InvalidAuthenticatorException: Authenticator is not instantiated via the properties constructor
    at com.eibus.security.authentication.AuthenticatorFactory.getAuthenticator(AuthenticatorFactory.java:76)
    at com.eibus.security.identity.WSSecurityUsernameTokenIdentityType.validate(WSSecurityUsernameTokenIdentityType.java:63)
    ... 7 more</cordys:FaultRelatedException>

The first thing that came to mind was that the Service Group was not configured yet for CARS authentication, so i did:

  1. Open LDAP Explorer --> Expand the Organization where the service is deployed --> Expand 'soap nodes' --> Open the properties of the Service Group of that WebService Container
  2. Select ... (button) behind  'bussoapnodeconfiguration' to open the XML Editor with the Service Group configuration.
  3. Add the next line underneath <configuration>:  <authenticator implementation="com.eibus.security.authentication.CARSAuthenticator" />

I restarted the Service Container and the problem was solved.


Cordys: Contract First design


One of the principles of Service Design is Contract First. With this principle you first design the service contract of the service and then implement it. This blog item will show a small example within Cordys BOP4.

Contract First

First I will create a simple HRM Employee service first. The WSDL can be found here

Before you can use this WSDL you have to import the WSDL.
  1. Create a Project with com/examples Folders

  1. Create new Web Service document in com/examples Folder

  1. Select Import WSDL and name the service, click Next

  1. Now you have to fill in the URL of the WSDL. I have installed Cordys on my Windows machine and put my EmployeeService within the <CordysInstallDir>/Web directory. This way the WSDL is accessable through a URL. Select Show Services to view the service defined within the WSDL. Check Interface WSDL, because it is just the interface and not the implementation we are importing.
  1. Now you are able to use this as a basis to define a Contract Based Business Process Model. Create a new Business Process Model within the same Folder with the following Properties. You must check Contract and select the Interface just imported in the previous step.

  1. When you press OK, a skeleton Process is generated for you with Process messages.

Regards, Roger


SOA Business Events


I read a nice article here on the SOA Magazine site about "SOA: Dealing with events". This blog item discusses some of the points made and the practical consequences it has (in my opinion).

What is an event?

The first fundamental question you have to ask yourself is "what a business event" actually is.
The writer talks about "a significant or meaningful change in state", "a higher level semantic form" and "meaningfull" for the business. Technical local events are not considered business events.
I think this is the same discussion you always have about what a "Service" is. So this always remains a point of discussion.
A technical event can also be very usefull when for example systems are going down. This shall have impact on other parts of the business and maybe should trigger the business.

Key Concepts

Autonomous messages

The clue of the statement the writer makes here is: "each message contains just enough information to represent a unit of work.
This is about the fine or coarse grained events. Just like the design decisions about the finegrainedness of the service operations, this also holds for the business events.
So maybe you should also consider several events that represent the same event only that the information differs, for example EmployeeAdded with just employee number or EmployeeAdded with more information.

Pub/Sub for Lossely coupling

The writer states here: "The only requirement is a well-defined message semantic format, which can be implemented as plain old XML-based (POX) payload. "
I think (as pointed out earlier) this can be a challenge of its own.

Another statement: "Furthermore, due to the overall reduced dependencies, changes to each connected system can be deployed more independently (and thus more frequently) with minimal impact to other systems. "
This also holds for request-response systems when you adhere to the service interface. Also there each system (service) can be deployed independently as long as it adheres to the interface.

The example given is about the Web application generating an event that the registration of a new Employee is finished. I would say that the business event is the Employee has been registered within the HRM system.
There may be aother ways to register a new employee, should each client generate such an event?

Aspects of implementation

I like the statement of the writer that request/response and event driven architecture style are complementary, i totally agree on that, and would otherwise make the statement myself.

Event Normalization and Taxonomy
Just like a CDM of ojects used within Services a CDM has to be made for Events as well. This also holds for the granularity of the events and the governance of the Events.

Process Design and Modeling
I like the rule of thumb: "As a rule of thumb, the Synchronous Request-Driven pattern is appropriate when the event source (or client) depends on the receiver (or server) to perform and complete a function as a component of its own process execution and is typically focused on reusing business logic. On the other hand, the Asynchronous Event-Driven pattern is appropriate when connected systems are largely autonomous, not having any physical or logical dependencies; typically focused on data integration. "

The weriter states: "event-based security can be simpler as connected systems can leverage a point-to-point, trust-based security model and context, compared to the end-to-end security contexts used in multistep request-driven distributed transactions. "
But you also need end-to-end security for Events. Furthermore when the security requirements are different between parts of the enterprise this can also be more complex.


A good article that shows which elements and challenges you will face when (also) implementing event based SOA.


Cordys: Configuring Apache and BOP4 for SSL


This blog item will show an example how to configure secure SSL with Apache 2.2.x and Cordys BOP4 (CU9) (on Windows).

Creating Test Certificate

First we will create a test certificate with Apache.
  1. Copy the <Apache>/conf/openssl.cnf to a temportary directory (<temp>)
  2. Because the EventService of Cordys uses the IP address as an alternate domain, you have to change the openssl.cnf file in the <temp> directory.
    Add the following line behind [ v3_req ]:
    subjectAltName=DNS: www.example.com,DNS:
    (Change localhost and IP address accordingly)
  3. First we will create the RSA Private Key:
    <Apache>/bin/openssl genrsa -des3 -out server.key 1024
  4. Now we must generate a Certificate Signed Request (CSR).
    During the generation of the CSR, you will be prompted for several pieces of information. These are the X.509 attributes of the certificate. One of the prompts will be for "Common Name (e.g., YOUR name)". It is important that this field be filled in with the fully qualified domain name of the server to be protected by SSL.
    <Apache>/bin/openssl req -config <temp>/openssl.cnf -new -key server.key -out server.csr
    Country Name (2 letter code) [GB]:NL
    State or Province Name (full name) [Berkshire]:Holland
    Locality Name (eg, city) [Newbury]:Geldrop
    Organization Name (eg, company) [My Company Ltd]:Roger
    Organizational Unit Name (eg, section) []:IT
    Common Name (eg, your name or your server's hostname) []:www.example.com
    Email Address []:rvdkimmenade
    Please enter the following 'extra' attributes to be sent with your certificate request
    A challenge password []: An optional company name []:

  5. We have to remove the Passphrase from the key because it is inconvenient to type the passphrase each time Apache is restarted:
    copy server.key server.key.org
    openssl rsa -in server.key.org -out server.key
  6. Normally you would sent the CSR to a Certificate Authority to sign the request, but for this example we will sign it ourself.
    <Apache>/bin/openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
  7. Now the private key and the certificate need to be copied to Apache:
    copy <apache>\bin/server.crt <apache>\conf\server.crt
    copy <apache>\bin\server.key <apache>\conf\server.key
    Notice that these settings of the public- and private key are in the httpd-ssl.conf file.

Changing Apache settings

Now that the certificate is created we start to change the Apache settings (<Apache</conf/httpd.conf file).
  1. Uncomment or add:
    LoadModule ssl_module modules/mod_ssl.so
  2. Uncomment or add:
    Include conf/extra/httpd-ssl.conf
  3. Comment #listen 80
  4. Comment:
    #<IfModule ssl_module>
    # SSLRandomSeed startup builtin # SSLRandomSeed connect builtin # </IfModule>
  5. The SSL configurations are within the <Apache>/conf/extra/httpd-ssl.conf file and are good already.
  6. In the <Cordys>\components\webgateway\Apache\cordys_apache.conf replace the following line:
    <Directory "<Cordys>/Web">
       AllowOverride All   
       AuthName "Cordys"   

       AuthType Basic   
       #SSPIAuth On   
       #SSPIAuthoritative On   
       Allow from all   
       #Require valid-user   
       Anonymous anonymous

    <Directory "d:\local\programs\Cordys\defaultInst\Web">
       Anonymous_NoUserID on   
       Anonymous_VerifyEmail off   
       Anonymous_MustGiveEmail off   
       Anonymous_LogEmail off   
       Anonymous anonymous   
       Allow from all
  7. Restart the Apache server.
  8. (This step can be ommitted be is just present for information) For client authentication (tow-way SSL) add the following line to cordys_apache.conf:
    <Directory  "<Cordys>\Web">
       SSLVerifyClient require   
       SSLVerifyDepth 2   
       SSLCACertificatePath conf/ssl/   
       AllowOverride All   
       Allow from all    
    Note: The <Apache>/conf/ssl directory has to be present/created

Now you are able to connect through the https protocol.


Configuring Security with Cordys is easy or ..


The last week we had to implement some Authorization functionality on Cordys BOP4 (CU9) services. During this journey I discovered that there were several ways in defining the security and this makes it very complex (if you’re a first user just like me). So this blog item describes some ways to define the security and my experiences.

Ways to Identify

Cordys supports several ways to identify users:
  1. No identification is used, in this case this is mapped to an “anonymous” authenticated user within Cordys.
  2. Cordys. The credentials are put in the soap header request and are mapped to a Cordys user.
  3. WS-Security SAML. This can be used for single-sign-on
  4. WS-Security User name token. The user puts its identity (user and password, clear text or encrypted are possible) within the soap header

This blog item uses the last with clear text user and password.

You can set Cordys identification within the LDAP Explorer:
  1. Open LDAP Explorer
  2. Goto Organization (HRM) > soap nodes > AddEmployee
  3. On the right window, select “...” at the bussoapnodeconfiguration
  4. Add <authenticator implementation="com.eibus.security.authentication.CARSAuthenticator" />


Access Control lists are used to define security at several levels. These levels can be:
* Service Group. This is best used when webservices are bundled and all of them should have the same restrictions. * Webservice interface. This is best used when the several interfaces need different restrictions. * Webservice operation. The restriction can also be set op webservice operation level.

In this example we use the unconditional ACL in which the security setting is put stactically on an object.

Defining security

This example uses the service as build within my previous post.
When you try to call this service from soapui:
<soapenv:Envelope xmlns:emp="http://www.examples.com/employee/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
          <emp:LastName>van de Kimmenade</emp:LastName>
you will get a soap fault that contains: <faultstring xml:lang="en-US">Anonymous access is denied for the method 'Employee'.</faultstring>

First we create a Role and a new User with no roles attached
  1. Create Users Folder
  2. Create HRMEmployee Role within this Folder
  1. Publish the Users
  2. Goto User Manager
    Note: This is also the place to remove roles and users, because when removed from the workspace and republish does not give the wanted effect. They are still within the LDAP (CARS). So remove them from within the User Manager.
  3. Create a New User with no roles attached

Next we define the security on the AddEmployee service that the HRMEmployee Role is permitted to execute the webservice.
  1. Goto Workspace > AddEmployee Service > EmployeeBinding
  2. Right click Define Runtime Security
  3. Add HRMEmployee Role, Save and Publish
  1. When you run the service from within soapUI again you get the error:
    Access is denied for the method 'Employee'. This is because you did not give the new User the needed Role, so that is what you do next. Note: You can add the WS-Security name token within the Aut tab and then right click Add
    WSS Username Token, remove soapenv:mustUnderstand="1" and Nonce and Create elements.
  2. Goto User Manager > Users Roles > Assign HRMEmployee to New User
  3. Execute the service request again from soapUI and the service should execute

User Manager

When you goto the User Manager and select Roles - Roles you will see the Organization Roles.
Right-click on HRMEmployee > Security on you will see the defined ACL on the Role:

When you click on the “Key” you will see the actual ACL:

You see that the state is “open”. In case the webservice should be blocked it would be “blocked”.

Note that this is also the place to remove the binding of the Role to the webservice !!
When you remove the Runtime Security on the AddEmployee Service and republish again the service is still accessible by the New User. I think this is a bug within Cordys.

Define on Service Group level

You can also set the security on Service Group level in which case all services within that group have the same security settings.
  1. Goto System Resource Manager
  2. Show All Service Groups
  3. Right click Define Security
  1. Add HRMEmployee , Allow, and click OK

Note: If you goto the User Manager > Roles - Roles and Select HRMEmployee and right click Security you will see that two ACL sets are defined on this Role:


Book review request

Today I received a request to review a new book on SOA:
 Service Oriented Architecture: An integration blueprint

I feel honoured of course and in a few weeks I will receive a hard copy of the book.
Looking forward to it and I will keep you up-to-date about my review !

Regards, Roger


Cordys: Using custom Java within your Message Map


Sometimes it is needed to add a custom Java call within your Message Map or Data Transformation.
This blog item describes how to do this for a Message Map. In this example I wrote a decode/encode methods for base64Binary.

Java Code

First you have to write your Java code. This can be done in any environment you like. Generate the .jar file.
Here's my Java code:

package com.util;

import com.eibus.util.system.Native;

public class Base64Util {
 public static String decodeFromBase64(String input){
            String result = new String(Native.decodeBinBase64(input.getBytes(), input.length()));
            return result;

 public static String encodeToBase64(String input){
                String result = new String(Native.encodeBinBase64(input.getBytes(), input.length()));
                return result;

Import within BOP4

The next step you need to do is to import your .jar library within Cordys.
  1. Create a Folder where you want to import the .jar file (for example InstallDir)
  2. Create some subFolders underneath it for the Qualified Name
  3. Set the Start Qualified Name

  1. Upload the .jar file by selecting Upload Document .. on the subfolder where you want your library

  1. Select the base64Util.jar file and click Finish

Use within Message Map

Now you are able to use the method within a Message Map of a Business Process.
  1. Create Business Process

  1. Use within the Message Map

Service Container classpath

The last thing you need to do is to change the classpath of the service container the process is running in.
  1. Goto System Manager
  2. Goto the Business Process Management container in which the business process is running
  3. Select Properties
  4. Select JRE Configuration Tab
  5. Enter the class path of the jar file. This is the Cordys installation directory + Qualified Name as defined in "Import within BOP4" part.