Monday, November 1, 2010

Encrypt the response with a certificate taken from the request

Sometimes it is not possible to share public keys among all clients but still necessary to provide some level of message security. In this case it's possible to validate an incoming request and use a certificate from the request to encrypt a response. I'll show how to create the proxy workflow for the SOA Expressway providing such functionality.

First of all we'll start a backend web-service which will do a real work. I usually use jax-ws to create simple web-services. The code for simple web-service is listed below.
package example;
import javax.jws.*;
import javax.jws.soap.*;

public class Hello {
public String hello(String name) {
return "hello " + name;
public static void main(String args[]) {
+ args[0]+"/hello",new Hello());
System.out.println("Web Service listening on "
+ args[0]);

We will compile this file with an apt tool and run it with command
$ java example/Hello 9876
Web Service listening on 9876

Service is started and accepting requests on address http://localhost:9876/hello

Now we are ready to create the SOA Expressway application to offload security operations for our HelloWorld web-service.

Create a new Intel SOA Expressway Project in the Services Designer.

Create a new Synchronous SOA Expressway Workflow in this project.

Select the Invoke operation on a right palette and drop it between the Receive and the Reply. This operation will call the backend web-service.

Click on the "Invoke" operation and select the "Use Existing WSDL" checkbox to make this "Invoke" WSDL-oriented activity.
Import the backed web-service WSDL with the "Import WSDL..." button and import WSDL of the jax-ws backend web service.

Bind the "Invoke" activity to the "hello" operation.

We've done with the operation "Invoke" and now we need to setup the "Receive" operation to receive requests for the backend server.
Click on the "Receive" operation select "Use existing WSDL" and select the "hello" operation.

To setup the dataflow click on the "Invoke" activity and select for the "1. parameters" dropdown value "$Receive.parameters" to pass a data from the "Receive" activity into the "Invoke" activity then click on the "Reply" activity and select the value "$Invoke.parameters" for the "1. parameters" dropdown to send a server's response back to the client.

The simple proxy application is ready and we can go on with security features.
We'll need two security policies, first for a request verification and second for a response encryption.

Create a new WS-Security Policy with the name "verify" and an operation type "Verify".

On the Settings tab of the verification.wsSecurity policy select accepted methods. Set the "Save resolved key information" checkbox, this key will be later used for the response encryption. Select "X509 Certificate Source: incoming message".

Create a new WS-Security policy with the name "encrypt" and an operation type "Encrypt". On "Settings" tab select suitable algorithms and "X509 certificate Source: Verify operation" to use the certificate from the request for the encryption.

Policies are ready now and we need to bind them to "Receive" and "Reply" activities respectively.
Click on the "Receive" activity, then select "WS-Security" tab and add the verify.wsSecurity policy to the list.

Click on the "Reply" activity, select the "WS-Security" tab, add the encrypt.wsSecurity policy to the list and select "Receive > verify.wsSecirity" as "Encryption key: X509 certificate" value.

Our workflow is complete now, we can export it and deploy it into the SOA Expressway server. Once workflow is deployed and started it will be able to both verify requests and encrypt responses.

Tuesday, July 13, 2010

Intel SOA Expressway Service Gateway and WebLogic 11g Application server message exchange with SignatureConfirmation

Intel SOA Expressway is often used as a security gateway in B2B or app-to-app integration scenarios. Therefore Intel SOA Expressway has to interoperate with different WSDL/WS-Policy/WS-Security capabilities of ESBs and Application Servers. In this writeup I am going to discuss SOAE's security interoperability with Oracle 11g Application Server

Both Oracle WebLogic and Intel SOA Expressway support an extensive set of WS-Security standards, in this post I'll show how to make Oracle WebLogic produce messages with signature confirmations and how to make Intel SOA Expressway validate signature confirmations. We'll create a web-service application for WebLogic and configure security gateway application for Intel SOA Expressway.

Let's start with WebLogic, it supports JSR-181 and extends it with some weblogic-specific annotations.
/* file - src/wl/example/ */
package wl.example;
import javax.jws.*;
import weblogic.jws.Policy;

public class Hello {
public String world(String s) {
return "Hello " + s + " I hear you!";

Service logic is contained in the java source above but security is offloaded into the Policy file 'wspolicy.xml' listed below.

<!-- file src/wl/example/wspolicy.xml -->
<sp:Wss11 xmlns:sp="">

The policy is pretty simple, it forces both ends to sign messages and to use signature confirmations.

Here is build.xml to build the deploy-able war-file for weblogic
<!-- file build.xml -->
<project name="webservice" default='compile'>
<property name='src' value='src'/>
<property name='bin' value='bin'/>
<property name='wl-server-lib' value='../lib'/>
<path id='web-logic'>
<pathelement location="${wl-server-lib}/com.bea.core.annogen_1.0.0.0.jar"/>

<taskdef name="jwsc" classpathref='web-logic'
<target name="prepare">
<mkdir dir='${bin}'/>

<target name="compile" depends='prepare'>
<jwsc srcdir='${src}' destdir='${bin}'>
<jws file='wl/example/'/>

<target name="clean">
<delete dir='${bin}'/>

Key-pair and certificate installation process for weblogic is described here.

After compilation and deployment the web-service WSDL will be available at url http://weblogic:weblogic_port/Hello/Hello?WSDL. For further imports we will save this wsdl into a file 'hello.wsdl'.

WebLogic web-service is up and running now, we have the wsdl saved into file, so we are ready to create an Intel SOA Expressway proxy application.

First, create a new Empty SOAE Project in Intel Services Designed. In the empty project, create a new Workflow using template "Web Services proxy SOAE Workflow".

Pass hello.wsdl to the service proxy creation wizard

and click the "Finish" button. The proxy application is ready now, but it doesn't do any security governance. Our application needs to:

  • sign messages before sending them to WebLogic service

  • verify signatures in WebLogic responses

  • verify signature confirmations of WebLogic responses

We need to create a separate ws policy for each of these activities.

First we will create a policy with the name "sign" and operation type "Sign". The wspolicy.xml declares the TripleDesRsa15 algorithm suite, which means we should use the rsaWithSha1 signature generation method and sha1 digest generation method. The X509 key-pair token name should be specified for the sign operation ('client' for example). We also need to set "Save signature confirmation data" checkbox to use this data later, for signature confirmation.

Second operation in the order of the application is Verify. Create a policy with the name "verify_signature" and operation type "Verify". Verification should use the same set of algorithms as signing, but it's important to use a Certificate from the security configuration with the name 'server' and to specify web service authentication policy which will control the verification process.

The last and the the most simple policy is the signature verification policy. Create a ws-security policy with the name 'verify_confirmation' and operation type 'Verify Signature Confirmations'.

Policies are ready now and we can apply them to the request and response of the Invoke activity.

Proxy workflow is complete. We can deploy it in Intel SOA Expressway.
In the Intel SOA Expressway management Console, we create a new configuration and security package. In the security package, we deploy a client key-pair, server certificate and certificate authority (ca) and create a Web Service Authentication policy with name 'proxy_policy' referring to the trusted ca group 'ca'.

Deploy the application into the application configuration and assign the security package to the uploaded application. Activate configuration. The proxy application is started now. We can send test request to check workflow functionality.

WebLogic will refuse a non-signed request.

$ curl -v --data-binary @req -H 'content-type: text/xml' http://weblogic:7003/Hello/Hello
* About to connect() to weblogic port 7003
* Trying connected
* Connected to weblogic ( port 7003
> POST /Hello/Hello HTTP/1.1
> User-Agent: curl/7.15.5 (i386-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: client_host:7003
> Accept: */*
> content-type: text/xml
> Content-Length: 183
> <SOAP:Envelope xmlns:SOAP="">
> <SOAP:Body>
> <ns2:world xmlns:ns2="http://wl/example">
> <ns2:s>test</ns2:s>
> </ns2:world>
> </SOAP:Body>
> </SOAP:Envelope>
< HTTP/1.1 500 Internal Server Error
< Date: Wed, 14 Jul 2010 08:46:53 GMT
< Transfer-Encoding: chunked
< Content-Type: text/xml; charset=utf-8
< X-Powered-By: Servlet/2.5 JSP/2.1
* Connection #0 to host weblogic left intact
* Closing connection #0
<env:Envelope xmlns:env="">
<env:Fault xmlns:wsse="">
No id attribute on element

But SOAE will accept plain request, sign it and forward to weblogic, receive response verify it and send plain response back to client.

$ curl -v --data-binary @req -H 'content-type: text/xml' http://soae_server:7003/Hello/Hello
* About to connect() to soae_server port 7003
* Trying connected
* Connected to soae_server ( port 7003
> POST /Hello/Hello HTTP/1.1
> User-Agent: curl/7.15.5 (i386-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: client_host:7003
> Accept: */*
> content-type: text/xml
> Content-Length: 183
> <SOAP:Envelope xmlns:SOAP="">
> <SOAP:Body>
> <ns2:world xmlns:ns2="http://wl/example">
> <ns2:s>test</ns2:s>
> </ns2:world>
> </SOAP:Body></SOAP:Envelope>
< HTTP/1.1 200 OK
< Content-Type: text/xml;charset=utf-8
< Content-Length: 534
<?xml version="1.0" encoding="utf-8"?>
Connection #0 to host pblcbrxw028 left intact
* Closing connection #0
<env:Envelope xmlns:env="">
<env:Body wsu:Id="Body_HytYHeKjNiBvJUva">
<m:worldResponse xmlns:m="http://wl/example">
<m:return>Hello test I hear you!</m:return>

Thursday, June 10, 2010

How to create security tokens for testing purposes?

As part of my work responsibilities I pretty often install different WS-Security implementations to check if they are interoperable or not. If you already have secured client end server the only thing which is necessary is set of security tokens. There are different ways to create security tokens, one of them is openssl tool. OpenSSL is de-facto standard it's usually preinstalled on Unix/Linux systems and could be installed on Windows as well. I use following script to create certificates and keypairs



#create Certificate Authority Key
openssl genrsa -out ca_key.pem $KEYLENGTH
#create Certificate Authoruty Certificate
echo -e "RU\nSpb\nCA\nFAKE CA\nTesters\nCA_example_host\n\n" | \
/usr/bin/openssl req -config $CA_CFG \
-new -x509 -key ca_key.pem -out ca_cert.cer -days $DAYS

for host in $HOSTS
#create key
openssl genrsa -out ${host}_key.pem $KEYLENGTH
#create certificate request, $host is used for CN
echo -e "RU\nSpb\nFAKE Organization\nFAKE Unit\nTesters\n$host\n\n\n\n\n" | \
/usr/bin/openssl req -config $CA_CFG -extensions \
v3_ca -new -key ${host}_key.pem -out ${host}_req.pem -days $DAYS
#create certificate from request
openssl x509 -req -in ${host}_req.pem -out ${host}_cert.cer \
-CA ca_cert.cer -extfile $CA_CFG -extensions v3_ca \
-CAkey ca_key.pem -CAcreateserial -days $DAYS
# delete certificate request
rm ${host}_req.pem
#pack key-pair into pfx file with password $PASS
openssl pkcs12 -export -out ${host}.pfx -passout pass:$PASS \
-inkey ${host}_key.pem -in ${host}_cert.cer
#delete non-encrypted key
rm ${host}_key.pem

This script creates key and self-signed certificate for certificate authority. For each command-line argument script creates key-pair with certificate signed by previously created certificate authority. Certificates are stored in .cer files, keypaires are stored in .pfx files. .cer and.pfx files could be imported into Windows keystore just with doubleckick on .cer/.pfx file and these files could be imported into java keystore with following commands

keytool -importcert -keystore store.jks -storepass password -file certificate.cer
keytool -importkeystore -destkeystore store.jks -deststorepass password \
-srckeystore keypair.pfx -srcstoretype PKCS12 -srcstorepass password

Monday, June 7, 2010

Interop: Microsoft WCF & Intel SOA Expressway

Intel SOA Expressway and Microsoft WCF are supporting wide variety of Web Services standards, both of them supports WS-Security. In this article will be shown how to create and deploy SOA Expressway application to send encrypted and signed requests to WCF-hosted Web-Service.
We will create securing-proxy application for "Intel SOA Expressway". This application will receive plain requests sign/encrypt them and forward secured message to WCF-service, then it will receive encrypted WCF-service response decrypt/verify it and forward plain response to client.

Code of WCF service is listed below

using System;
using System.Configuration;
using System.ServiceModel;
using System.Net.Security;

namespace example {
public interface Example {
string hello(string s);

public class ExampleService : Example {
public string hello(string s) {return "Hello " + s + "!";}
public static void Main() {
using (ServiceHost serviceHost =
new ServiceHost(typeof(ExampleService))) {

Configuration for WCF service
<?xml version="1.0" encoding="utf-8" ?><!--service.exe.config-->
<binding name="free">
<security mode="Message">
<add baseAddress="http://hostname:1234/hello"/>
<endpoint address=""
<endpoint address="mex"
contract="IMetadataExchange" />
<behavior name="behavior">
<serviceMetadata httpGetEnabled="True"
<serviceDebug includeExceptionDetailInFaults="True" />
<serviceCertificate storeLocation='CurrentUser'
<authentication trustedStoreLocation='CurrentUser'

We'll need set of security tokens

  • ca_cert.cer - Certificate Authority certificate

  • client_cert.cer - client certificate

  • client.pfx - client key-pair

  • server_cert.cer - server certificate

  • server.pfx - server key-pair

SOA Expressway acts as secured-client it will use

  • ca_cert.cer - to verify response

  • client.pfx - to sign request and to decrypt response

  • server_cert.cer - to encrypt request and verify response

WCF-service acts as secured-server it will use

  • ca_cert.cer - to verify request

  • server.pfx - to sign response and to decrypt request

  • client_cert.cer - to encrypt response and to verify request

First of all we need to get WSDL of Web-Service.
Deploy security tokens into windows keystore (just doubleclick and import them) and compile service.cs with csc.exe, put service.exe.config in directory with service.exe, then
start service.exe; WSDL will become accessible via URL http://hostname:1234/hello?wsdl

Start Intel Services Designer and create new Intel SOA Expressway Project

Create new synchronous workflow

Click on Receive action and select "Use existing WSDL". Click on "Import WSDL" button, select "URL", type "http://hostname:1234/hello?wsdl" and click "Download" button

Workflow's Receive action is bound to service's WSDL. Now we need to create back-end service invocation action. Take "Invoke" action from palette and drop it between Receive and Reply.

Set "Use existing WSDL" checkbox in Properties of Invoke and select "hello" operation

Set Request Message Data parameters field of Invoke action to "$Receive.parameters" to forward client request to back-end server

Click on Reply and set Response Message Data parameters to "$invoke.parameters" to forward response of back-end server to client

Now our workflow is able to receive plain message from client, forward it to back-end server, receive WCF service's response and forward it to client. But WCF service will reject plain messages, so we need to sign/encrypt requests and decrypt/verify responses.
Web-Service is secured with EncryptAndSign protection level it means both request and responses should be Signed then Encrypted together with signature. WCF service uses Basic128Rsa15 algorithmSuite it means it will use aes128 for symmetric encryption, Rsa15 for asymmetric encryption and SHA1 for digest calculation.

We need to create four policies to implement these four actions (sign/encrypt/decrypt/verify)

Create new WS-Security policy with operation type "Sign" and name it "sign"

On "Settings" tab of "sign.wsSecurity" set

  • Signature generation method = rsaWithSha1

  • Digest generation method = sha1

  • Token name = client

WCF doesn't accept messages without singed timestamp, set "Include WS-Security Timestamp in generated signature" checkbox on targets tab of "sign.wsSecurity"

Create new WS-Security policy with operation type "Encrypt" and name it "encrypt". On "Settings" tab of "encrypt.wsSecurity" set

  • Data encryption generation method = aes128

  • Key encryption generation method = rsaV1.5

  • KeyInfo type = SKI

  • Token name = server

By default "Encrypt" policy encrypts only SOAP:Body, but WCF requires signatures to be encrypted as well. On tab "Targets" add namespace "" with prefix "dsig" and add XPath Target Expression /soap:Envelope/soap:Header/wsse:Security/dsig:Signature with Include Tags = Yes

Create new WS-Security policy with operation type "Decrypt" and name it "decrypt". On "Settings" tab of "decrypt.wsSecurity" set

  • Data encryption methods accepted - AES-128

  • Key encryption methods accepted - RSA V1.5

  • Token name - client

Create new WS-Security policy with operation type "Verify" and name it "verify". On "Settings" tab of "verify.wsSecurity" set

  • Signature methods accepted - RSA with SHA1

  • Digest method accepted - SHA1 (160-bit)

  • Canonicalization methods accepted -

  • X509 Certificate Token name - server

  • Authentication Policy Token name - policy

WS-Security policies are ready, now we need to apply them to Invoke action. Open Process.bpel, click on Invoke action then on WS-Security tab of Invoke properties and add sign.wsSecurity, encrypt.wsSecurity to "WS-Security policies for request" table and decrypt.wsSecurrity, verify.wsSecurity to "WS-Security policies for response" table. Order of policies is important, policies are applied to message in same order as they are listed in table.

Workflow is complete now and can be exported for further deployment.

Login to SOAE and go to Configuration tab. Create configuration with name "WCF-example".

Click on "Security Packages" in left column and create new security package with name "example-sec-conf", it will be used to deploy security tokens.

  • Put client.pfx into "Asymmetric Key Pair" section of security configuration with name "client"

  • Put server_cert.cer into "Certificate" section of security configuration with name "server"

  • Put ca_cert.cer into "Trusted CA Group" section of security configuration with name "example-ca"

  • Create new "Web Service Authentication Policy" in security configuration with name "policy" and Trusted CA Group = "example-ca"

Security configuration is ready now, click "OK" to save it, then click on Applications->Upload Application in left column to deploy workflow. Upload application bundle (wcf_example.tgz) and link it to Security Configuration "example-sec-conf"

If Intel SOA Expressway in installed on same machine with WCF Service it's necessary to alter port of Input Server, because default listen port is taken from WSDL is 1234 which is already busy by WCF-service. To alter listen port, click on "Input Servers" in left column, then click on "Edit" in column "Actions", set port 1235 for example.

Click "OK" to save Input Server changes.

Application is deployed and linked to security configuration with necessary tokens. Click "Activate" to save and activate this configuration. After activation Intel SOA Expressway is ready to process request. Let's test it with simple request sent by curl:

[pbtbskaplou /home/bskaplou ]$ cat req
<s:Envelope xmlns:s="">
<s:Body><hello xmlns=""><s>test</s></hello></s:Body>
[pbtbskaplou /home/bskaplou/ ]$ curl -v --data-binary @req -H 'content-type: text/xml' \
-H 'soapaction: ""' \
* About to connect() to pblcbrxw028 port 1235
* Trying connected
* Connected to pblcbrxw028 ( port 1235
> POST /hello HTTP/1.1
> User-Agent: curl/7.15.5
> Host: hostname:1235
> Accept: */*
> content-type: text/xml
> soapaction: ""
> Content-Length: 149
> <s:Envelope xmlns:s="">
<s:Body><hello xmlns="">
< HTTP/1.1 200 OK
< Content-Type: text/xml;charset=utf-8
< Content-Length: 390
<?xml version="1.0" encoding="utf-8"?>
Connection #0 to host hostname left intact
* Closing connection #0
<SOAP:Envelope xmlns:SOAP="">
<helloResult>Hello test!</helloResult></helloResponse></SOAP:Body></SOAP:Envelope>

We've successfully received response from SOA Expressway.