Advertisements
RSS

Category Archives: Security

“Buffer underflow in doHandshake” SSL error in Oracle Service Bus

We are using Oracle Service Bus for SSL communication to an external party. Due to security regulations we use a proxy server configuration (note: not proxy service, but proxy server) on these specific business services.

After upgrading our OSB to 11g PS4 we wanted to use the JSSE implementation for SSL because in the near future we will need to implement SHA2 certificates. After enabling JSSE (weblogic console -> managed server -> SSL -> Advanced) the outgoing connections still seem to work. However when we send a large message (in our case > 20kb) we receive the following error in our logging:


<Debug> <Socket> <someHostname> <someManagedServer> <[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <> <3fe931....> <13...> <BEA-000400> <buffer underflow in doHandshake>

The source of all knowlegde Wikipedia tells us that:
In computing buffer underrun or buffer underflow is a state occurring when a buffer used to communicate between two devices or processes is fed with data at a lower speed than the data is being read from it. This requires the program or device reading from the buffer to pause its processing while the buffer refills. This can cause undesired and sometimes serious side effects because the data being buffered is generally not suited to stop-start access of this kind.

After enabling Weblogic SSL logging we see the below output (simplified) in the logfiles when sending a small message. The SSLEngine both shows wrap and unwrap methods.


<Debug> <SecurityCertPath> <BEA-000000> <CertPathTrustManagerUtils.doCertPathValidation: >
<Debug> <SecurityCertPath> <BEA-000000> <CertPathTrustManagerUtils.doCertPathValidation: configured to defer to the admin>
<Debug> <SecurityCertPath> <BEA-000000> <CertPathTrustManagerUtils.doCertPathValidation: outbound = true>
<Debug> <SecurityCertPath> <BEA-000000> <CertPathTrustManagerUtils.doCertPathValidation: style = BuiltinSSLValidationOnly>
<Debug> <SecurityCertPath> <BEA-000000> <CertPathTrustManagerUtils.doCertPathValidation: returning false>
<Debug> <SecurityCertPath> <BEA-000000> <CertPathTrustManagerUtils.certificateCallback: returning true because the CertPathValidators should not be called>
<Debug> <SecuritySSL> <BEA-000000> <weblogic user specified trustmanager validation status 0>
<Debug> <SecuritySSL> <BEA-000000> <SSLTrustValidator returns: 0>
<Debug> <SecuritySSL> <BEA-000000> <[Thread[[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]]...SSLENGINE: No trust failure, validateErr=0.>
<Debug> <SecuritySSL> <BEA-000000> <Performing hostname validation checks: remote.website.nl>
<Debug> <SecuritySSL> <BEA-000000> <Proxying through ourDMZproxyserver.local>
<Debug> <SecuritySSL> <BEA-000000> <[Thread[[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]]...SSLENGINE: Successfully completed post-handshake processing.>
<Debug> <SecuritySSL> <BEA-000000> <[Thread[[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]]...SSLENGINE: SSLEngine.wrap(ByteBuffer,ByteBuffer) called: result=Status = OK HandshakeStatus = NOT_HANDSHAKING bytesConsumed = 304 bytesProduced = 325.>
<Debug> <SecuritySSL> <BEA-000000> <[Thread[[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]]...SSLENGINE: SSLEngine.wrap(ByteBuffer,ByteBuffer) called: result=Status = OK HandshakeStatus = NOT_HANDSHAKING bytesConsumed = 2167 bytesProduced = 2188.>
<Debug> <SecuritySSL> <BEA-000000> <[Thread[[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]]...SSLENGINE: SSLEngine.unwrap(ByteBuffer,ByteBuffer) called: result=Status = OK HandshakeStatus = NOT_HANDSHAKING bytesConsumed = 164 bytesProduced = 143.>
<Debug> <SecuritySSL> <BEA-000000> <[Thread[[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]]...SSLENGINE: SSLEngine.unwrap(ByteBuffer,ByteBuffer) called: result=Status = OK HandshakeStatus = NOT_HANDSHAKING bytesConsumed = 1036 bytesProduced = 1015.>

When sending a larger message the logging seems identical, however the logging stops after the outbound communication (wrap method) and no inbound traphic seems to return (unwrap method).


<Debug> <SecurityCertPath> <BEA-000000> <CertPathTrustManagerUtils.doCertPathValidation: >
<Debug> <SecurityCertPath> <CertPathTrustManagerUtils.doCertPathValidation: configured to defer to the admin>
<Debug> <SecurityCertPath> <CertPathTrustManagerUtils.doCertPathValidation: outbound = true>
<Debug> <SecurityCertPath> <CertPathTrustManagerUtils.doCertPathValidation: style = BuiltinSSLValidationOnly>
<Debug> <SecurityCertPath> <CertPathTrustManagerUtils.doCertPathValidation: returning false>
<Debug> <SecurityCertPath> <CertPathTrustManagerUtils.certificateCallback: returning true because the CertPathValidators should not be called>
<Debug> <SecuritySSL> <weblogic user specified trustmanager validation status 0>
<Debug> <SecuritySSL> <SSLTrustValidator returns: 0>
<Debug> <SecuritySSL> <[Thread[[ACTIVE] ExecuteThread: '8' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]]...SSLENGINE: No trust failure, validateErr=0.>
<Debug> <SecuritySSL> <Performing hostname validation checks: remote.website.nl>
<Debug> <SecuritySSL> <Proxying through ourDMZproxyserver.local>
<Debug> <SecuritySSL> <BEA-000000> <[Thread[[ACTIVE] ExecuteThread: '8' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]]...SSLENGINE: Successfully completed post-handshake processing.>
<Debug> <SecuritySSL> <BEA-000000> <[Thread[[ACTIVE] ExecuteThread: '8' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]]...SSLENGINE: SSLEngine.wrap(ByteBuffer,ByteBuffer) called: result=Status = OK HandshakeStatus = NOT_HANDSHAKING bytesConsumed = 306 bytesProduced = 327.>
<Debug> <SecuritySSL> <BEA-000000> <[Thread[[ACTIVE] ExecuteThread: '8' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]]...SSLENGINE: SSLEngine.wrap(ByteBuffer,ByteBuffer) called: result=Status = OK HandshakeStatus = NOT_HANDSHAKING bytesConsumed = 16384 bytesProduced = 16405.>

At a very high level, the SSLEngine works like this (source: Class SSLEngine @ Oracle):

                |           ^
                |     |     |
                v     |     |
           +----+-----|-----+----+
           |          |          |
           |       SSL|Engine    |
   wrap()  |          |          |  unwrap()
           | OUTBOUND | INBOUND  |
           |          |          |
           +----+-----|-----+----+
                |     |     ^
                |     |     |
                v           |

Remember when we disable JSSE and use the Certicom implementation the process still works perfectly. So everything pointed to the direction of a combination: JSSE + large message = error. Sadly the .log and .out didn’t help in the problem solving here so experimenting with a few tuning parameters did the trick for us.

After configuring the Business Service to use Chunked Streaming Mode the problem was solved and we again succeeded in sending out messages of multiple MB’s to our external trading partners.

When I initially used Google and Oracle Knowledge base to look for the “BEA-000400 buffer underflow in doHandshake” error this was not very helpfull. So hopefully this blogpost is helpfull for others in the future when they have the same problem as us.

Advertisements
 
14 Comments

Posted by on 11-06-2012 in Oracle, OSB, Security, SSL

 

Tags: , , ,

Using UserName information in the Oracle Service Bus

I was debugging a OSB 11.1.1.5 proxy service which had a OWSM UserName token policy attached to it (read this blogpost how to configure your OSB). When I noticed the $inbound variable had some interesting information which I never noticed before.

The $inbound variable holds a big data-set regarding transport and usually a small data-set regarding security. In a “normal” unsecured proxy services this would result in something like this:

<inbound>
 <con:endpoint name="mySomething" xmlns:con="http://www.bea.com/wli/sb/context">
 <con:service>
 <con:operation>getEmployeeDetails</con:operation>
 </con:service>
<con:transport>
........
</con:transport>
 <con:security>
 <con:transportClient>
 <con:username>anonymous></con:username>
 </con:transportClient>
 </con:security>
 </con:endpoint>
</inbound>

So there is just a transportClient reference which normally just contains the value “anonymous”. Not really interesting.

However in the situation where the proxy service uses the OWSM policy it contains a new messageLevelClient element:

<inbound>
 <con:endpoint name="mySomething" xmlns:con="http://www.bea.com/wli/sb/context">
 <con:service>
 <con:operation>getEmployeeDetails</con:operation>
 </con:service>
<con:transport>
........
</con:transport>
 <con:security>
 <con:transportClient>
 <con:username>anonymous></con:username>
 </con:transportClient>
 <con:messageLevelClient>
 <con:username>weblogic</con:username>
 <con:principals>
 <con:group>AdminChannelUsers</con:group>
 <con:group>Administrators</con:group>
 <con:group>IntegrationAdministrators</con:group>
 </con:principals>
 </con:messageLevelClient>
 </con:security>
 </con:endpoint>
</inbound>

Pretty good information for tracing/logging your service calls.

 
1 Comment

Posted by on 13-01-2012 in OSB, Security, WS-Security

 

Tags: , , ,

Configuring SSL for Oracle Weblogic (and OFMW)

We have a very basic domain: 3 physical servers, 1 containing the admin server, 2 containing 2 managed servers each, running in a cluster. Nice picture to follow. :)

name of the servers: server01 (Admin) / server02 (MS1+MS2) / server03 (MS3+MS4)

Step 0 – The Weblogic Demo Certificates (the reason why)

If you ever checked your Weblogic production logs and found the Security Alert below, then your Weblogic domain has a huge gaping security hole. Even if you don’t want SSL communication for your webservices or applications. The internal (administrative) processes in your Weblogic domain still relies on the default demotrust and with this everyone can access your domain.

</pre>
&nbsp;

<Alert> <Security> <SERVER02> <rbx_dev_soa_ms01> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <BEA-090152> <Demo trusted CA certificate is being used in production mode: [
[
  Version: V3
  Subject: CN=CACERT, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
  Signature Algorithm: MD5withRSA, OID = 1.2.840.113549.1.1.4

  Key:  Sun RSA public key, 512 bits
  modulus: 95501928778692415440753....
  public exponent: 65537
  Validity: [From: Thu Mar 21 21:12:27 CET 2002,
               To: Tue Mar 22 21:12:27 CET 2022]
  Issuer: CN=CACERT, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
  SerialNumber: [    33f10648 fcde0deb 4199921f d64537f4]

Certificate Extensions: 1
[1]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
  Key_CertSign
]

]
  Algorithm: [MD5withRSA]
  Signature:
0000: 9D 26 4C 29 C8 91 C3 A7   06 C3 24 6F AE B4 F8 82  .&L)......$o....
0010: 80 4D AA CB 7C 79 46 84   81 C4 66 95 F4 1E D8 C4  .M...yF...f.....
0020: E9 B7 D9 7C E2 23 33 A4   B7 21 E0 AA 54 2B 4A FF  .....#3..!..T+J.
0030: CB 21 20 88 81 21 DB AC   90 54 D8 7D 79 63 23 3C  .! ..!...T..yc#<

] The system is vulnerable to security attacks, since it trusts certificates signed by the demo trusted CA.>

Step 1 – generate the identity java keystore

We first generate a java keystores containing a private key for each physical server, since SSL hostname verifiation is based on machine names. We use “welcome1” as password here, but make sure to choose a complex password here, use it during these steps and then lock it safely away.


keytool.exe -genkey -keysize 2048 -keyalg RSA -alias server01 -keystore server01_identity.jks

Enter keystore password: welcome1
 Re-enter new password: welcome1
 What is your first and last name?
   [Unknown]:  server01
 What is the name of your organizational unit?
   [Unknown]:
 What is the name of your organization?
   [Unknown]:  Rubix
 What is the name of your City or Locality?
   [Unknown]:
 What is the name of your State or Province?
   [Unknown]:
 What is the two-letter country code for this unit?
   [Unknown]:  NL
 Is CN=server01, OU=, O=Rubix, L=, ST=, C=NL correct?
   [no]:  yes
<br>

Step 2 – generate signing request

keytool.exe -certreq -alias server01 -file server01.csr -keystore server01_identity.jks</div>
Repeat step 1 + 2 for each physical server, replacing the -alias parameter, -keystore parameter and CN name with the correct server0* value.
 

 

Step 3 – the Certificate Authority (CA)

Now comes the tricky part that you probably need some outside forces. You will need the correct Certificate Authority to sign your certificate requests (the .CSR files you generated). You can create your own CA and self-sign them, but I would not recommend that unless you know what you are doing and understand the consequences. You could use an external Internet CA provider, but this becomes very costly and time consuming when you need such an external provider to sign every SSL enabled server in your landscape. The best situation for us would be if the current organization already has an internal CA provider, especially when the rootCA is trusted by the servers and machines in your landscape.
 
Let’s assume however that you receive the signed response, including the public keys of the rootCA and a intermediateCA. CA instances often use a intermediate CA to authorize certificates, so if they have “problems” they can withdraw this intermediate CA and don’t need to withdraw the whole RootCA making it useless.
So the situation should be that you know hold 3 PEM/DER files.
 

 

Step 4 – importing the CA response

Import the certificates in your keystore, starting with the rootCA, then the intermediateCA, then the specific server alias. Example for server01:
keytool -importcert -trustcacerts -alias rootca -file rootCA.cer -keystore server01_identity.jks

keytool -importcert -alias intermediateca -file intermediateCA.cer -keystore server01_identity.jks

keytool -importcert -alias server01 -file server01.cer -keystore server01_identity.jks
Repeat these steps for server02 and server03. So we know have 3 identity keystores for each server containing the signed private key and it’s certificate chain.
 

 

Step 5 – generate the trust java keystore

Now let’s generate a truststore for each server. Altough you can use the identical keystore for both identity and trust, it’s always a good practice to separate them. The identity keystone contains the private key and normally never changes during it’s lifetime, so you should secure it with a complex password. The trust store contains the certificates that you trust and as your middleware landscape grows, this file might grow and more administrators will need access to it.
 
Example generating the truststore for server01, repeat for 02 & 03.
 
keytool -importcert -trustcacerts -alias rootca -file rootCA.cer -keystore server01_trust.jks
keytool -importcert -alias intermediateca -file intermediateCA.cer -keystore server01_trust.jks
 

Step 6 – copy the java keystore files to each server

 Make sure that each server had the files stored on disk. We use the windows server example “c:\oracle\security” in this blogpost. So server01 should hold:
– c:\oracle\security\server01_identity.jks
– c:\oracle\security\server01_trust.jks
 

 

Step 7 – configure the Node Manager for SSL

The nodemanger by default uses the demoIdentity and demoTrust keystores.
So on each server hosting a managed server (server02 and server03) we will need to change this.
Open the nodemanager.properties and add the following lines:
 
### SSL config
KeyStores=CustomIdentityAndCustomTrust
# CustomIdentityKeyStoreType=JKS
CustomIdentityKeyStoreFileName=c://oracle//security//server01_identity.jks
CustomIdentityKeyStorePassPhrase=welcome1
CustomIdentityAlias=server01
CustomIdentityPrivateKeyPassPhrase=welcome1
# CustomTrustKeyStoreType=JKS
CustomTrustKeyStoreFileName=c://oracle//security//server01_trust.jks
Restart the NodeManager to activate the changes. The passwords in the properties file will automatically become encrypted.
 
Possible error:
For server rbx_dev_soa_ms03, the Node Manager associated with machine server03 is not reachable. All of the servers selected are currently in a state which is incompatible with this operation or are not associated with a running Node Manager or you are not authorized to perform the action requested. No action will be performed.
Possible solution:
Your AdminServer can not communicate with a node manager. Make sure it’s running, check Environment -> Machines in the Weblogic console if the machine has state reachable, check if the address configured there, and the address in the nodemanager.properties and the CN-name used in SSL have the same value, check if Weblogic and Nodemanager use the same SSL configuration (trust+identity).
 

 

Step 8 – configure Weblogic for SSL

Log in the Weblogic console, in our example: http://server01:7001/console
 
 
Step 8.1 – configure Weblogic for SSL, enable SSL
 
Log in the Weblogic console (in our case http://server01:7001/console) and make sure that each server has the SSL port enabled. You can find the setting “SSL Listen Port Enabled” for each server under “Configuration -> General”. Enable it and make sure you use a correct and free port.
 

Step 8.2 – configure Weblogic for SSL, changing keystores

For each server (Admin + MS) we have to change the KeyStore configuration.
So for each server go to: Configuration -> Keystores
 
  • Keystores -> “Change” = “Custom Identity and Custom Trust”
  • Custom Identity Keystore = c:/Oracle/security/serverXX_identity.jks
  • Custom Identity Keystore Type = JKS
  • Custom Identity Keystore Passphrase = welcome1
  • Custom Trust keystore = c:/Oracle/security/serverXX_trust.jks
  • Custom Trust Keystore Type = JKS
  • Custom Trust Keystore Passphrase = welcome1
 
 

Step 8.3 – configure Weblogic for SSL, changing identity:

For each server (Admin + MS) we have to change the SSL configuration.
So for each server go to: Configuration -> SSL
 
  • Private Key Alias = serverXX
  • Private Key Passphrase = welcome1
 

Step 9 – Weblogic start scripts:

By default Weblogic uses the DemoTrust.jks truststore. Since we changed this in the console configuration you would hope this would be enough. However the SetDomainEnv.sh / SetDomainEnv.cmd script still contains a reference. So for each server:
 
  • Go to %domain_home%/bin/
  • Open the SetDomainEnv script
  • Search the argument: -Djavax.net.ssl.trustStore=
  • Make sure the value is not referring to the demo trust.jks but “c:/oracle/security/serverXX_trust.jks
When you are finished restart your whole Weblogic environment (Admin + MS).
 

Step 10 – Configure Enterprise Manager:

This took me some research and the Oracle Forums to get it working. Navigate to the enterprise manager console (/em)
 

Step 10.1 – Security Provider Configuration:

I’m actually not really sure if this step is still necessary in 11g, but hey .. why not be sure:
 
  • Click Weblogic -> right-click domain
  • Select Security -> Security Provider Configuration -> KeyStore Configure
  • Keystore Path = c:/oracle/security/server01_identity.jks
 

Step 10.2 – SOA Infra properties

 
  • Click SOA -> right-click soa-infra
  • Select SOA Administration -> Common Properties
  • Click More SOA Infra Advanced Properties
  • Keystore Location = c:/oracle/security/serverXX_identity.jks

Step 10.3 – Credential Mapping:
The next step is to configure the credential mapping keys

  • Click Weblogic -> right-click domain name
  • Select Security -> Credentials
  • Create a Map named “SOA”
  • Click Create a key
  • Key = KeyPassword
  • User Name = KeyPassword
  • Password = welcome1
  • Click Create Key:
  • Key = KeyStorePassword
  • User Name = KeyStorePassword
  • Password = welcome1
 
Possible error:
</div>
<div>

<Warning> <oracle.as.jmx.framework.MessageLocalizationHelper> <J2EE JMX-46041> <The resource for bundle "oracle.soa.management.config.bpel.mbeans.MessageBundle_en" with key "oracle.soa.BPELConfigBean.auditFlushByteThreshold" cannot be found.>
INFO: SSLSocketFactoryManagerImpl.getKeystoreLocation SOA Keystore location: c:/oracle/security/server04_identity.jks
INFO: SSLSocketFactoryManagerImpl.getKeystorePassword Obtained null or empty keystore password
INFO: SSLSocketFactoryManagerImpl.getKeyPassword Obtained null or empty key password
INFO: SSLSocketFactoryManagerImpl.getSSLSocketFactory Could not obtain keystore location or password

</div>
<div>
 
Possible solution:
You did not configure the SOA key mapping correctly as mentioned above in 9.3

 

Conclusion:

Enabling SSL takes a lot of steps, and we didn’t even mentioned it for enabling SSL client identity in OSB (Service Key Provider) and communication with an LDAP over SSL. But there’s more to come I guess.
If you have any remarks please let me know in the comments. Hope it helps. :)
 
 

Links:

 
12 Comments

Posted by on 16-12-2011 in Security, SOA Suite, Weblogic

 

Tags: ,

Using OWSM UsernameToken for authentication and authorisation of OSB services

With the use of Oracle Web Service Manager (OWSM) we can easily configure Oracle Service Bus (OSB) services with different message security polices. This configuration can be done from Eclipse (OEPE), OSB SBConsole or the Enterprise Manager. One of the most common WS-Security mechanismes and therefor also OWSM policies is the UsernameToken where a username and password are send along with the message.

In this blog we will:

  • part I: how to enable authentication of users against the list of all known users
  • part II: how to enable authorisation of only a specific subset of users to access a service

First we configure a proxy service in OEPE with the OWSM UsernameToken policy oracle/wss_username_token_service_policy:


And make sure we process the WS-Security header:


After deployment we call the service with a request that is missing the WS-Security to test the result.


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <GreetingRequestMessage>
         <in>I say hello ...</in>
      <GreetingRequestMessage>
   </soapenv:Body>
</soapenv:Envelope>

As expected the result is an error because the OWSM policy requires a WS-Security segment in the SOAP-header which contains a username and password:


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <soapenv:Fault>
         <faultcode>soapenv:Server</faultcode>
         <faultstring>BEA-386200: General web service security error</faultstring>
         <detail>
            <con:fault xmlns:con="http://www.bea.com/wli/sb/context">
               <con:errorCode>BEA-386200</con:errorCode>
               <con:reason>General web service security error</con:reason>
               <con:location>
                  <con:path>request-pipeline</con:path>
               </con:location>
            </con:fault>
         </detail>
      </soapenv:Fault>
   </soapenv:Body>
</soapenv:Envelope>

So to make sure we can send a UsernameToken we add 2 users to the Weblogic security realm called userA and userB.

The request to the proxy service containing the WS-Security UsernameToken for userA


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header>
      <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <wsse:UsernameToken wsu:Id="UsernameToken-4" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:Username>userA</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">welcomeA1</wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
   </soapenv:Header>
   <soapenv:Body>
      <GreetingRequestMessage>
         <in>I say hello ...</in>
      </GreetingRequestMessage>
   </soapenv:Body>
</soapenv:Envelope>

This results in a successfull response from the proxy service:


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <GreetingResponseMessage>
         <out>HelloWorld</out>
      </GreetingResponseMessage>
   </soapenv:Body>
</soapenv:Envelope>

So part 1 is complete, we succesfully implemented a proxy service that requires a WS-Security UsernameToken and authenticates these users against the Weblogic security realm. But in our case we have a tight security requirement and need to make sure the user is not only authenticated, but also authorized to access this specific service.

The result from part 1 means this is not the case, both userA and userB would be able to access this service. So let’s start part 2 where we will limit the access to the proxy service to only userB. For this we have to login to the sbconsole, since the OEPE does not allow you to make Message (or Transport) Access Control settings.

  • Login the sbconsole
  • Select Project Explorer
  • Select the the proxy service
  • Go to the Security Tab

  • Click on Message Access Control option (either for the whole service or just a single operation).
  • Click on Add Condition
  • Select User from predicate list
  • Type userB at the User Argument Name
  • Click on Add and Finish
  • Click on Save and Activate to finish the OSB session
Next thing we can call the service again and this time with userB and we still receive a succesfull result.
However if we call the service again with a UsernameToken containing userA we get the following SoapFault:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <soapenv:Fault>
         <faultcode>soapenv:Server</faultcode>
         <faultstring>BEA-386102: Message-level authorization denied</faultstring>
         <detail>
            <con:fault xmlns:con="http://www.bea.com/wli/sb/context">
               <con:errorCode>BEA-386102</con:errorCode>
               <con:reason>Message-level authorization denied</con:reason>
               <con:location>
                  <con:path>request-pipeline</con:path>
               </con:location>
            </con:fault>
         </detail>
      </soapenv:Fault>
   </soapenv:Body>
</soapenv:Envelope>

Part 2 is completed and we finished with a proxy service that has both Authentication and Authorization enabled.

Remarks:

  • You can also use groups and roles (rather than users) to authorize access to services.
  • If you implement and configure an external LDAP (like Oracle Internet Directory) in Weblogic you can control ACL with groups central in your company LDAP instead of in each Weblogic security realm.
  • The SOAP fault for Message Level Authorization denied (BEA-386102) contains a faultcode value of “Server” which is not correct if you look at the w3c definition. This should be the value “Client” because: “….. the message could lack the proper authentication or payment information. It is generally an indication that the message should not be resent without change”

Update 2011-08-10:
Added 3rd remark regarding the SOAP Fault code

Update 2012-01-13:
Using the OWSM username token policies you get some additional information on runtime in you $inbound variable. See this blogpost for more details.
References:


 
26 Comments

Posted by on 09-08-2011 in OSB, WS-Security

 

Tags: , , ,

Weblogic and OSB various keystore reminders

Default Weblogic DemoIdentity and DemoTrust keystore:

I always forget the default passwords, so a quick reminder:

Location: %WL_HOME%/server/lib
File = DemoIdentity.jks

  • keystore password = DemoIdentityKeyStorePassPhrase
  • key password = DemoIdentityPassPhrase
  • keytool -list -keystore DemoIdentity.jks -storepass DemoIdentityKeyStorePassPhrase
    

File = DemoTrust.jks

  • keystore password = DemoTrustKeyStorePassPhrase
  • 	keytool -list -keystore DemoTrust.jks -storepass DemoTrustKeyStorePassPhrase
    
Generate a new private key:

Go to the security folder in your domain (the SerializedSystemIni.dat is also located here, so you already need to secure this folder):
%DOMAIN_HOME%\security

keytool -genkey -keysize 2048 -keyalg RSA -alias myhostname01 -keystore myhostname01_identity.jks

Generate a Certificate Request:

keytool -certreq -alias myhostname01 -file myhostname01.csr -keystore myhostname01_identity.jks

Send this CSR file to your Certificate Authority

Import signed response:

keytool -importcert -trustcacerts -alias rootCA -file rootCA.cer -keystore myhostname01_identity.jks -storepass mySecretPassword
keytool -importcert -alias chaincert1 -file chaincert1.cer -keystore myhostname01_identity.jks -storepass mySecretPassword
keytool -importcert -alias myhostname01 -file myhostname01.cer -keystore myhostname01_identity.jks -storepass mySecretPassword

import P12 into JKS:

keytool -v -importkeystore -srckeystore somecert.p12 -srcstoretype PKCS12 -destkeystore mytruststore.jks -deststoretype JKS

Configure Eclipse OEPE with custom keystore:

  • Right-click OSB Configuration in Project Explorer
  • Select Oracle Service Bus Configuration
  • Configure the keystore file and the storepassword
  • You can now add a ServiceKeyProvider to your project to act as a SSL-client
 
Leave a comment

Posted by on 04-08-2011 in OSB, Security, Weblogic

 

Tags: , ,

Weblogic and IIS two-way TLS/SSL issue (debugging)

I’m blogging this to help other people who might experience the same problem. On the other hand there are some loose ends where someone out there might contribute to.

So a project required SOAP/HTTP(S) requests over two-way SSL between Oracle Service Bus and a remote service running on Microsoft IIS 6.0.

Weblogic & OSB setup:
All certicates are stored in keystores and used by the nodemgr + admin + ms.
Weblogic has a PKICredentialMapper and in the SBconsole we have our ServiceKeyProvider configured. We build our proxy and business services where:
– BS is confgured with SSL and Authentication ClientCert (http transport Tab)
– PS is configured with the ServiceKeyProvider on the Security tab

Pretty default stuff, working with other backends. The callout however fails and the IIS guys claim they never receive a client-cert.

Callout from OSB:
clientIPhere, -, 1/11/2011, 15:51:18, serviceNameHere, serverNameHere, serverIPhere, 449859, 1160, 0, 403, 64, POST, /SomeService.asmx, -,

Callout from SOAPui from client workstation:
clientIPhere, -, 1/11/2011, 16:01:21, serviceNameHere, serverNameHere, serverIPhere, 187, 918, 916, 200, 0, POST, /SomeService.asmx, -,

According to this page the 403 is a forbidden error and the 0 in front of it means 0 bytes have been send from the server to the client.

So we enable Weblogic SSL debugging with the arguments: -Dssl.debug=true -Dweblogic.StdoutDebugEnabled=true

After the next callout we see this in the logging:

</soap:Body>>   *<-------- this is the last $body logging in the ProxyService before it calls the business* <Debug> <SecuritySSL> <BEA-000000> <SSLSetup: loading trusted CA certificates><Debug> <SecuritySSL> <BEA-000000> <clientInfo has new style certificate and key><Debug> <SecuritySSL> <BEA-000000> <Filtering JSSE SSLSocket><Debug> <SecuritySSL> <BEA-000000> <SSLIOContextTable.addContext(ctx): 270694655><Debug> <SecuritySSL> <BEA-000000> <SSLSocket will  be Muxing><Debug> <SecuritySSL> <BEA-000000> <write SSL_20_RECORD><Debug> <SecuritySSL> <BEA-000000> <isMuxerActivated: false><Debug> <SecuritySSL> <BEA-000000> <270694400 SSL3/TLS MAC><Debug> <SecuritySSL> <BEA-000000> <270694400 received HANDSHAKE><Debug> <SecuritySSL> <BEA-000000> <HANDSHAKEMESSAGE: ServerHello><Debug> <SecuritySSL> <BEA-000000> <HANDSHAKEMESSAGE: Certificate><Debug> <SecuritySSL> <BEA-000000> <Validating certificate 0 in the chain: Serial number: 130583870796631153730390131696172958331Issuer:C=xxxxxxxxxxNot Valid Before:Wed Oct 20 02:00:00 CEST 2010Not Valid After:Sun Oct 20 01:59:59 CEST 2013Signature Algorithm:SHA1withRSA><Debug> <SecuritySSL> <BEA-000000> <Validating certificate 1 in the chain: Serial number: 50682576685400420811231509872710703774Issuer:C=xxxxxxxNot Valid Before:Tue Jun 07 10:09:10 CEST 2005Not Valid After:Sat May 30 12:48:38 CEST 2020Signature Algorithm:SHA1withRSA><Debug> <SecuritySSL> <BEA-000000> <validationCallback: validateErr = 0><Debug> <SecuritySSL> <BEA-000000> <  cert[0] = Serial number: 130583870796631153730390131696172958331Issuer:C=xxxxxxxxxxSubject:C=xxxxxxxNot Valid Before:Wed Oct 20 02:00:00 CEST 2010Not Valid After:Sun Oct 20 01:59:59 CEST 2013Signature Algorithm:SHA1withRSA><Debug> <SecuritySSL> <BEA-000000> <  cert[1] = Serial number: 50682576685400420811231509872710703774Issuer:CxxxxxxxxNot Valid Before:Tue Jun 07 10:09:10 CEST 2005Not Valid After:Sat May 30 12:48:38 CEST 2020Signature Algorithm:SHA1withRSA><Debug> <SecuritySSL> <BEA-000000> <weblogic user specified trustmanager validation status 0><Debug> <SecuritySSL> <BEA-000000> <SSLTrustValidator returns: 0><Debug> <SecuritySSL> <BEA-000000> <Trust status (0): NONE><Debug> <SecuritySSL> <BEA-000000> <Performing hostname validation checks: www.nahetvo.nl><Debug> <SecuritySSL> <BEA-000000> <HANDSHAKEMESSAGE: ServerHelloDone><Debug> <SecuritySSL> <BEA-000000> <Ignoring not supported JCE Mac: SunJCE version 1.6 for algorithm HmacMD5><Debug> <SecuritySSL> <BEA-000000> <Will use default Mac for algorithm HmacMD5><Debug> <SecuritySSL> <BEA-000000> <Ignoring not supported JCE Mac: SunJCE version 1.6 for algorithm HmacSHA1><Debug> <SecuritySSL> <BEA-000000> <Will use default Mac for algorithm HmacSHA1><Debug> <SecuritySSL> <BEA-000000> <Will use default Mac for algorithm MD5><Debug> <SecuritySSL> <BEA-000000> <Using JCE Cipher: SunJCE version 1.6 for algorithm RC4><Debug> <SecuritySSL> <BEA-000000> <Ignoring not supported JCE Mac: SunJCE version 1.6 for algorithm HmacMD5><Debug> <SecuritySSL> <BEA-000000> <Will use default Mac for algorithm HmacMD5><Debug> <SecuritySSL> <BEA-000000> <Ignoring not supported JCE Mac: SunJCE version 1.6 for algorithm HmacSHA1><Debug> <SecuritySSL> <BEA-000000> <Will use default Mac for algorithm HmacSHA1><Debug> <SecuritySSL> <BEA-000000> <Using JCE Cipher: SunJCE version 1.6 for algorithm RSA><Debug> <SecuritySSL> <BEA-000000> <write HANDSHAKE, offset = 0, length = 134><Debug> <SecuritySSL> <BEA-000000> <write CHANGE_CIPHER_SPEC, offset = 0, length = 1><Debug> <SecuritySSL> <BEA-000000> <Using JCE Cipher: SunJCE version 1.6 for algorithm RC4><Debug> <SecuritySSL> <BEA-000000> <Ignoring not supported JCE Mac: SunJCE version 1.6 for algorithm HMACMD5><Debug> <SecuritySSL> <BEA-000000> <Will use default Mac for algorithm HMACMD5><Debug> <SecuritySSL> <BEA-000000> <Ignoring not supported JCE Mac: SunJCE version 1.6 for algorithm HmacMD5><Debug> <SecuritySSL> <BEA-000000> <Will use default Mac for algorithm HmacMD5><Debug> <SecuritySSL> <BEA-000000> <Ignoring not supported JCE Mac: SunJCE version 1.6 for algorithm HmacSHA1><Debug> <SecuritySSL> <BEA-000000> <Will use default Mac for algorithm HmacSHA1><Debug> <SecuritySSL> <BEA-000000> <write HANDSHAKE, offset = 0, length = 16><Debug> <SecuritySSL> <BEA-000000> <isMuxerActivated: false><Debug> <SecuritySSL> <BEA-000000> <270694400 SSL3/TLS MAC><Debug> <SecuritySSL> <BEA-000000> <270694400 received CHANGE_CIPHER_SPEC><Debug> <SecuritySSL> <BEA-000000> <Using JCE Cipher: SunJCE version 1.6 for algorithm RC4><Debug> <SecuritySSL> <BEA-000000> <Ignoring not supported JCE Mac: SunJCE version 1.6 for algorithm HMACMD5><Debug> <SecuritySSL> <BEA-000000> <Will use default Mac for algorithm HMACMD5><Debug> <SecuritySSL> <BEA-000000> <isMuxerActivated: false><Debug> <SecuritySSL> <BEA-000000> <270694400 SSL3/TLS MAC><Debug> <SecuritySSL> <BEA-000000> <270694400 received HANDSHAKE><Debug> <SecuritySSL> <BEA-000000> <HANDSHAKEMESSAGE: Finished><Debug> <SecuritySSL> <BEA-000000> <Ignoring not supported JCE Mac: SunJCE version 1.6 for algorithm HmacMD5><Debug> <SecuritySSL> <BEA-000000> <Will use default Mac for algorithm HmacMD5><Debug> <SecuritySSL> <BEA-000000> <Ignoring not supported JCE Mac: SunJCE version 1.6 for algorithm HmacSHA1><Debug> <SecuritySSL> <BEA-000000> <Will use default Mac for algorithm HmacSHA1><Debug> <SecuritySSL> <BEA-000000> <write APPLICATION_DATA, offset = 0, length = 321><Debug> <SecuritySSL> <BEA-000000> <write APPLICATION_DATA, offset = 0, length = 839><Debug> <SecuritySSL> <BEA-000000> <SSLIOContextTable.findContext(sock): 270693819><Debug> <SecuritySSL> <BEA-000000> <SSLIOContextTable.findContext(sock): 270693819><Debug> <SecuritySSL> <BEA-000000> <activateNoRegister()><Debug> <SecuritySSL> <BEA-000000> <SSLFilterImpl.activate(): activated: 270693844 270909954><Debug> <SecuritySSL> <BEA-000000> <270694391 read(offset=0, length=4080)><Debug> <SecuritySSL> <BEA-000000> <isMuxerActivated: true><Debug> <SecuritySSL> <BEA-000000> <hasSSLRecord()><Debug> <SecuritySSL> <BEA-000000> <hasSSLRecord returns true><Debug> <SecuritySSL> <BEA-000000> <270694400 SSL3/TLS MAC><Debug> <SecuritySSL> <BEA-000000> <270694400 received HANDSHAKE><Debug> <SecuritySSL> <BEA-000000> <NEW ALERT with Severity: WARNING, Type: 100java.lang.Exception: New alert stack        at com.certicom.tls.record.alert.Alert.<init>(Unknown Source)        at com.certicom.tls.record.handshake.HandshakeHandler.handleHandshakeMessages(Unknown Source)        at com.certicom.tls.record.MessageInterpreter.interpretContent(Unknown Source)        at com.certicom.tls.record.MessageInterpreter.decryptMessage(Unknown Source)        at com.certicom.tls.record.ReadHandler.processRecord(Unknown Source)        at com.certicom.tls.record.ReadHandler.readRecord(Unknown Source)        at com.certicom.tls.record.ReadHandler.read(Unknown Source)        at com.certicom.io.InputSSLIOStreamWrapper.read(Unknown Source)        at weblogic.socket.SSLFilterImpl.isMessageComplete(SSLFilterImpl.java:202)        at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:896)        at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:840)        at weblogic.socket.EPollSocketMuxer.dataReceived(EPollSocketMuxer.java:215)        at weblogic.socket.EPollSocketMuxer.processSockets(EPollSocketMuxer.java:177)        at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:29)        at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:42)        at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:145)        at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:117)><Debug> <SecuritySSL> <BEA-000000> <write ALERT, offset = 0, length = 2><Debug> <SecuritySSL> <BEA-000000> <isMuxerActivated: true><Debug> <SecuritySSL> <BEA-000000> <hasSSLRecord()><Debug> <SecuritySSL> <BEA-000000> <hasSSLRecord returns false 1><Debug> <SecuritySSL> <BEA-000000> <270694391 Rethrowing InterruptedIOException><Debug> <SecuritySSL> <BEA-000000> <270694391 read(offset=0, length=8192)><Debug> <SecuritySSL> <BEA-000000> <isMuxerActivated: false><Debug> <SecuritySSL> <BEA-000000> <264112838 read(offset=0, length=4080)><Debug> <SecuritySSL> <BEA-000000> <isMuxerActivated: true><Debug> <SecuritySSL> <BEA-000000> <hasSSLRecord()><Debug> <SecuritySSL> <BEA-000000> <hasSSLRecord returns true><Debug> <SecuritySSL> <BEA-000000> <264114219 SSL3/TLS MAC><Debug> <SecuritySSL> <BEA-000000> <264114219 received APPLICATION_DATA: databufferLen 0, contentLength 29><Debug> <SecuritySSL> <BEA-000000> <264112838 read databufferLen 29><Debug> <SecuritySSL> <BEA-000000> <264112838 read A returns 29><Debug> <SecuritySSL> <BEA-000000> <264112838 read(offset=29, length=4051)><Debug> <SecuritySSL> <BEA-000000> <isMuxerActivated: true><Debug> <SecuritySSL> <BEA-000000> <hasSSLRecord()><Debug> <SecuritySSL> <BEA-000000> <hasSSLRecord returns false 1><Debug> <SecuritySSL> <BEA-000000> <264112838 Rethrowing InterruptedIOException><Debug> <SecuritySSL> <BEA-000000> <write APPLICATION_DATA, offset = 0, length = 29>

Just before the dump we see a: Warning, Type 100. The TLS protocol states informs us that this alert 100 would mean NO_RENEGOTIATION:

A.3. Alert messages

    enum { warning(1), fatal(2), (255) } AlertLevel;

        enum {            close_notify(0),            unexpected_message(10),            bad_record_mac(20),            decryption_failed(21),            record_overflow(22),            decompression_failure(30),            handshake_failure(40),            bad_certificate(42),            unsupported_certificate(43),            certificate_revoked(44),            certificate_expired(45),            certificate_unknown(46),            illegal_parameter(47),            unknown_ca(48),            access_denied(49),            decode_error(50),            decrypt_error(51),            export_restriction(60),            protocol_version(70),            insufficient_security(71),            internal_error(80),            user_canceled(90),            no_renegotiation(100),            (255)        } AlertDescription;

    struct {        AlertLevel level;        AlertDescription description;    } Alert;

So we use Wireshark which is one of the coolest free software tools out there. And even better, did I mention it’s free? With a Wireshark capture you can get a lot of information about the connection.

Essentially, what is going on here can be summarized as:

– Step 4: The client makes a hello request
– Step 8: The server responds with its certificate
– Step 10: The client key is send to server
– Step 11+12: Clients send a change of cipher spec and handshake message
– Step 14: Server send a change of cipher spec and handshake message
– Step 19: We see another server triggered handshake message followed by
– Step 20: Encrypted Alert

Since we are looking for something interesting, this Encrypted Alert is it. The problem here is that you can see an Alert but cant see the exact alert type.

I was hoping for a CERT_CHAIN_UNTRUSTED or BAD_CERTIFICATE since that would give me a good direction. But it looks like Weblogic logging shows an alert 100 (no_renegotiation) and we had to go with that.

no_renegotiation:
Sent by the client in response to a hello request or by the server in response to a client hello after initial handshaking. Either of these would normally lead to renegotiation; when that is not appropriate, the recipient should respond with this alert; at that point, the original requester can decide whether to proceed with the connection. One case where this would be appropriate would be where a server has spawned a process to satisfy a request; the process might receive security parameters
(key length, authentication, etc.) at startup and it might be difficult to communicate changes to these parameters after that point. This message is always a warning.

I’m still not fully convinced of a no_renegotiation. Because for the client to trigger a renegotiation, it should send a new Client Hello message (in the encrypted channel, like any other handshaking message) which then the server responds with a Server Hello, and negotiation goes exactly as above. Other case when the server initiates a renegotiation it will send the client a Hello Request message on which he client simply sends a new Client Hello, exactly as above, and the process goes as usual. In the wireshark captures this behavious is not visible.

<update.2011-01-27>
I found this Wireshark capture in a document called “Renegotiating TLS” by Ray and Dispensa which shows the process of renegotiation.

</update.2011-01-27>

So as a fix we tried switching over from JRockit to Sun JDK, tried some arguments but in the end rolled everything back since 1 simple options seem to solve the issue:

With older version of Weblogic you can use these arguments for the jvm:
-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol
-Dssl.SocketFactory.provider=com.sun.net.ssl.internal.SSLSocketFactoryImpl
-DUseSunHttpHandler=true
-Dweblogic.wsee.client.ssl.usejdk=true (for webservice clients)

With the latest versions of Weblogic there is a “Use JSEE SSL” setting. The setting is located on the SSL (advanced) tab of the managed server.

So now our Wireshark capture looks like this:

The difference looks to occur after the server sends an encrypted handshake (ERR-capture step 19 & OK-capture step 42). In the OK-capture you can see the client sending an encrypted handshake after that (step 43), however the ERR-capture results in a Alert (step 20).

Focusing on the Weblogic logging and the NO_RENEGOTIATION message a guess would be that the different client implementations handle these renegotiations differently.

The Oracle Support Knowledge base mentions something like this (ID 1078957.1). The trace mentioned there isn’t identical as our error, however the solution seems to point in the same direction.


ERROR = HANDSHAKE_FAILURE
CAUSE = This may happen when the WebLogic server connects a remote Microsoft server.
SOLUTION =
This happened before the client got the ServerHello message. The Microsoft Server was refusing the handshake because the cipher suites given to the remote server were not 128 bits – the remote server wasn’t allowing anything lower. If the client license is changed on the WebLogic Server side, it will then work.

Our issue however is not identical (i think), because I can see that the client (weblogic) sends 19 cipher specs (among them TLS_RSA_WITH_RC4_128_MD5) and that the server agrees with this specific 00 44

TLS_RSA_WITH_NULL_MD5 = { 0x00,0x01 }TLS_RSA_WITH_NULL_SHA = { 0x00,0x02 }TLS_RSA_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x03 }TLS_RSA_WITH_RC4_128_MD5 = { 0x00,0x04 }TLS_RSA_WITH_RC4_128_SHA = { 0x00,0x05 }TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00,0x06 }TLS_RSA_WITH_IDEA_CBC_SHA = { 0x00,0x07 }TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x08 }TLS_RSA_WITH_DES_CBC_SHA = { 0x00,0x09 }TLS_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x0A }TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA = { 0x00,0x62 }TLS_RSA_EXPORT1024_WITH_RC4_56_SHA = { 0x00,0x64 }TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x0B }TLS_DH_DSS_WITH_DES_CBC_SHA = { 0x00,0x0C }TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x0D }TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x0E }TLS_DH_RSA_WITH_DES_CBC_SHA = { 0x00,0x0F }TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x10 }TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x11 }TLS_DHE_DSS_WITH_DES_CBC_SHA = { 0x00,0x12 }TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x13 }TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x14 }TLS_DHE_RSA_WITH_DES_CBC_SHA = { 0x00,0x15 }TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x16 }TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA= { 0x00,0x63 }TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA = { 0x00,0x65 }TLS_DHE_DSS_WITH_RC4_128_SHA = { 0x00,0x66 }TLS_DHE_DSS_WITH_NULL_SHA = { 0x00,0x67 }TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x17 }TLS_DH_anon_WITH_RC4_128_MD5 = { 0x00,0x18 }TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x19 }TLS_DH_anon_WITH_DES_CBC_SHA = { 0x00,0x1A }TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = { 0x00,0x1B }

So our problems seems to be solved by using the Sun SSL implementation instead of the default Certicom one.

However that still leaves questions unanswered for me as:
– how come that other 2-way SSL trusts succeed with the default, but in this case with IIS6.0 as a service provider fails
– where does the 2-way SSL trust exactly fail, and how can I pinpoint this with tools like Wireshark ?
– what is the exact difference between Certicom and Sun’s implementation off TLS 1.0 ?

 
11 Comments

Posted by on 13-01-2011 in Oracle, OSB, Security, Weblogic

 

Tags: , , ,

Oracle Service Bus and Siebel UserNameToken

In this case we need to publish messages from the OSB 10.3.1 to Siebel 8.1.1.2 where Siebel supports different options for authentication of incoming HTTP webservice requests.

  • passing the user name and password in the URL (basic authentication)
  • A sort of custom Siebel Soap Header token like:
<soap:Header>
     <UsernameToken xmlns="http://siebel.com/webservices">user</UsernameToken>
     <PasswordText xmlns="http://siebel.com/webservices">hello123</PasswordText>
     <SessionType xmlns="http://siebel.com/webservices">None</SessionType>
</soap:Header>
  • And last but not least; Siebel claims to support the WS-Security UserName Token mechanism. However Siebel only supports the PasswordText option so the password will still be send in clear text.

We concluded that the URL or the custom header option was not acceptable due to the customers security requirements. The only acceptable solution for them would be the WS-security UsernameToken. Within the OSB this can be arranged by using a WS-policy and a Service Account and connect them to the outgoing business service. Since the password will still be in cleartext, we will use SSL to protect the password on it’s journey over the dark trenches of our WAN.

So here we start off:

1st the Siebel configuration for inbound services. Make sure the authentication type is set to username/password clear text.


2nd the WS-policy used (very basic):


<wsp:Policy wsu:Id="WS-Policy-Siebel"
  xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
  xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
  xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <wssp:Identity xmlns:wssp="http://www.bea.com/wls90/security/policy">
    <wssp:SupportedTokens>
      <wssp:SecurityToken TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken">
        <wssp:UsePassword Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"/>
      </wssp:SecurityToken>
    </wssp:SupportedTokens>
  </wssp:Identity>
</wsp:Policy>

Attach the policy to the OSB business service together with the service account and go !!! 
With tcpmon we catch the SOAP-header and it looks like:

<soapenv:Header>
  <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
    <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="unt_hzo9Xh2IiCqSYGaH">
      <wsse:Username>SADMIN</wsse:Username>
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">SADMIN</wsse:Password>
    </wsse:UsernameToken>
  </wsse:Security>
</soapenv:Header>

Bummer, we get our 1st error. Well let’s say that good things always take some extra effort.
The error response from Siebel:
<Body>
  <Fault>
    <faultcode>SOAP-ENV:MustUnderstand</faultcode>
    <faultstring>Unable to process SOAP Header child element 'wsse:Security' with 'mustUnderstand="1"'((SBL-EAI-08000)</faultstring>
      <detail>
          <siebelf:siebdetail xmlns:siebelf="http://www.siebel.com/ws/fault">
          <siebelf:logfilename>EAIObjMgr_nld_0014_14680077.log</siebelf:logfilename>
          <siebelf:errorstack>
          <siebelf:error>
          <siebelf:errorcode>SBL-EAI-08000</siebelf:errorcode>
          <siebelf:errorsymbol/>
          <siebelf:errormsg>Unable to process SOAP Header child element 'wsse:Security' with 'mustUnderstand="1"'((SBL-EAI-08000)</siebelf:errormsg>
          </siebelf:error>
          </siebelf:errorstack>
          </siebelf:siebdetail>
      </detail>
    </Fault>
</Body>

The error might let you think that Siebel simply fails on the mustUnderstand attribute which would force it to understand the SOAP header. However this is not the whole case.

After some debugging and using the Assign action in the OSB to manually build the SOAP-header with the WS-security definition it was possible to send out a UserName token Siebel accepted.

After this my conclusion is that Siebel apparently expects another wsse namespace then the OSB is generating.

Siebel requires the old wsse IBM/Microsoft/VeriSign definition of http://schemas.xmlsoap.org/ws/2002/04/secext&#8221; while the OSB uses the newer namespace http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&#8221; which was changed to match the OASIS specifications after their approval of WS-security as a standard in 2004.

After contact with Oracle Support I received confirmation from the Siebel Team that this is a limitation from Siebel, as it is not accepting the latest WS-Security definition. The option they give you is that for now it’s the caller’s responsibility to change the header to conform to the namespace Siebel is expecting.

So a new challenge for the OSB. The project looks something like this:

The solution for it is the fn-bea:lookupBasicCredentials function. We use an Assign Action to get the expression
fn-bea:lookupBasicCredentials(‘myRubixProject/security/SA.Siebel.MyRubixProject’)
result in a variable named $varBasicCredentials with the following content:

<con:UsernamePasswordCredential xmlns:con="http://www.bea.com/wli/sb/services/security/config">
  <con:username>SADMIN</con:username>
  <con:password>SADMIN</con:password>
 </con:UsernamePasswordCredential></pre>
We edit the Replace action to use the username and password elements.
<pre class="brush: xml"><soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext" soapenv:mustUnderstand="1">
   <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsse:Username>{$varBasicCredentials/con:username/text()}</wsse:Username>
     <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">{$varBasicCredentials/con:password/text()}</wsse:Password>
    </wsse:UsernameToken>
   </wsse:Security>
 </soapenv:Header>

Don’t forget to add the con namespace to the Replace action.

Finally, succes at last !!! :)
Off course this is just a workaround to make sure that Siebel and OSB speak te same “namespace language”. Let’s hope that Siebel 11g fixes this. After all, when it runs on Weblogic it must be good ;-)

Special thanks to Anuj Dwivedi for pointing me out the posibilities of the  fn-bea:lookupBasicCredentials function

 
Leave a comment

Posted by on 01-04-2010 in Oracle, OSB, Siebel, WS-Security, XQuery

 

Tags: , , ,