Showing posts with label ssl. Show all posts
Showing posts with label ssl. Show all posts

Saturday, 25 October 2014

Export private and public keys from a PKCS12 keystore


Both keys into the same PEM file
openssl pkcs12 -in keystore.p12 -passin "pass:password" -nodes -out keypair.pem

Separate PEM files
openssl pkcs12 -in keystore.p12 -passin "pass:password" -nodes -nocerts -out private_key.pem
openssl pkcs12 -in keystore.p12 -passin "pass:password"  -nokeys -out public_key.pem 

Thursday, 19 September 2013

A very quick way to get wsadmin to reference a different SSL truststore


There may be occasion when you want to run wsadmin from a single host and connect to multiple remote Cells to gather stats or run-time data. If you do this you'll need to trust the SSL certificates of these other Cells.

All pretty straight forward but if you're OCD (like me) you won't want to add all of those signer certificates to the CellDefaultTrustStore of the environment where you're running wsadmin..... it's far too untidy.  Much better to have a custom truststore that you create yourself and add the signers to that.. nice and tidy :)

Of course you'll need to point wsadmin at this new SSL truststore and here's how to do it

  • Make a copy of wsadmin.sh - ( I just copied it to my scripts directory /opt/bpm/scripts/inventory)
  • As above for setupCmdLine.sh
  • Edit the copy of wsadmin.sh to overide the CLIENTSSL var. I advise you insert this just above the line where java get's invoked as follows ...

CLIENTSSL=-Dcom.ibm.SSL.ConfigURL=file:/opt/bpm/scripts/inventory2/props/ssl.client.props

"$JAVA_EXE" \
-Xbootclasspath/p:"$WAS_BOOTCLASSPATH" \
$EXTRA_X_ARGS \
$CONSOLE_ENCODING \
$javaOption \
$WAS_DEBUG \
"$OSGI_INSTALL" "$OSGI_CFG" \
"$CLIENTSAS" \
"$CLIENTSSL" \


The new line is the CLIENTSSL one. This points to your custom ssl.client.props file (you need to create this) which in turn points to your custom SSL truststore

Here's my ssl.client.props file

com.ibm.ssl.performURLHostNameVerification=false
com.ibm.ssl.validationEnabled=false
com.ibm.security.useFIPS=false
com.ibm.ssl.defaultCertReqAlias=default
com.ibm.ssl.defaultCertReqSubjectDN=cn=${hostname},o=IBM,c=US
com.ibm.ssl.defaultCertReqDays=365
com.ibm.ssl.defaultCertReqKeySize=1024
com.ibm.jsse2.checkRevocation=false
com.ibm.security.enableCRLDP=false
com.ibm.ssl.alias=DefaultSSLSettings
com.ibm.ssl.protocol=SSL_TLS
com.ibm.ssl.securityLevel=HIGH
com.ibm.ssl.trustManager=IbmPKIX
com.ibm.ssl.keyManager=IbmX509
com.ibm.ssl.contextProvider=IBMJSSE2
com.ibm.ssl.enableSignerExchangePrompt=gui
com.ibm.ssl.keyStoreProvider=IBMJCE
com.ibm.ssl.keyStoreFileBased=true
com.ibm.ssl.trustStore=/opt/bpm/scripts/inventory2/certs/myTrust.p12
com.ibm.ssl.trustStorePassword={xor}Not included for security reasons
com.ibm.ssl.trustStoreType=PKCS12
com.ibm.ssl.trustStoreProvider=IBMJCE
com.ibm.ssl.trustStoreFileBased=true
com.ibm.ssl.trustStoreReadOnly=false
#-------------------------------------------------------------------------
# Additional stuff for getting thin client to work
#-------------------------------------------------------------------------
ssl.SocketFactory.provider=com.ibm.websphere.ssl.protocol.SSLSocketFactory
ssl.ServerSocketFactory.provider=com.ibm.websphere.ssl.protocol.SSLServerSocketFactory



The important line is com.ibm.ssl.trustStore which points at my SSL truststore which contains signers for all of the environments I need to connect to (I imported these manually using ikeycmd)

Lastly, in setupCmdLine.sh you need to force $WAS_HOME to point at your WAS install dir (it tries to work it out intelligently based on where you're running it from but becasue you've made a copy you need to overide this) .. and you're done


Tuesday, 20 August 2013

Configure mutual auth (2-way SSL) on specific WebSphere transports



In this example I've set up 2 way SSL for WC_default_secure inbound on the AppTarget and WebApp cluster members

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
# Add MutualAuthSSLSettings at Cell level and client auth to True 
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
cell = AdminConfig.list('Cell') 
cellName = AdminConfig.showAttribute(cell, 'name') 
print "Creating new SSLConfiguration  at Cell scope with name of MutualAuthSSLSettings" 
AdminTask.createSSLConfig('[-alias MutualAuthSSLSettings -type JSSE -scopeName (cell):'+cellName+' -keyStoreName CellDefaultKeyStore -keyStoreScopeName (cell):'+cellName+' -trustStoreName CellDefaultTrustStore -trustStoreScopeName (cell):'+cellName+' -serverKeyAlias default -clientKeyAlias default ]') 

print "Setting MutualAuthSSLSettings for client auth = 'required'" 
AdminTask.modifySSLConfig('[-alias MutualAuthSSLSettings -scopeName (cell):'+cellName+' -keyStoreName CellDefaultKeyStore -keyStoreScopeName (cell):'+cellName+' -trustStoreName CellDefaultKeyStore -trustStoreScopeName (cell):'+cellName+' -jsseProvider IBMJSSE2 -sslProtocol SSL_TLS -clientAuthentication true -securityLevel HIGH -enabledCiphers ]') 

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
# Now iterate around each server and set WC_default_secure 
# inbound to use the new MutualAuthSSLSettings 
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
nodes = AdminConfig.list('Node') 
for node in nodes.splitlines(): 
        nodeName =  AdminConfig.showAttribute(node, 'name') 

        servers = AdminConfig.list('Server', node) 
        for server in servers.splitlines(): 
                serverName =  AdminConfig.showAttribute(server, 'name') 
                if(serverName.find('AppTarget') != -1): 
                        print "Setting "+serverName+" WC_default_secure_inbound to use MutualAuthSSLSettings" 
                        AdminTask.createSSLConfigGroup('[-name WC_defaulthost_secure -scopeName (cell):'+cellName+':(node):'+nodeName+':(server):'+serverName+':(endpoint):WC_defaulthost_secure -direction inbound -certificateAlias default -sslConfigAliasName MutualAuthSSLSettings -sslConfigScopeName (cell):'+cellName+' ]') 
                elif(serverName.find('WebApp') != -1): 
                        print "Setting "+serverName+" WC_default_secure_inbound to use MutualAuthSSLSettings" 
                        AdminTask.createSSLConfigGroup('[-name WC_defaulthost_secure -scopeName (cell):'+cellName+':(node):'+nodeName+':(server):'+serverName+':(endpoint):WC_defaulthost_secure -direction inbound -certificateAlias default -sslConfigAliasName MutualAuthSSLSettings -sslConfigScopeName (cell):'+cellName+' ]') 
        print 

Tuesday, 9 July 2013

How to tell if a keystore entry is a keypair or just a public


Here's how to tell if a certificate store entry is a personal cert (i.e a public/ private keypair) or just a signer (i.e. a public key)

You could just use a GUI like iKeyman, but if you're stuck without an X server here's the command line version using keytool

A keypair output is as follows (the important part for this particular question is highlighted in red)

java/jre/bin/keytool -list -v -alias test1 -keystore /tmp/foo.jks -storepass password


Alias name: test1
Creation date: 09-Jul-2013
Entry type: keyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=test1
Issuer: CN=test1
Serial number: 51dc2cee
Valid from: 09/07/13 16:31 until: 09/07/14 16:31
Certificate fingerprints:
         MD5:  C1:52:E0:CF:46:88:16:19:EC:7D:EF:0F:D7:6C:BA:6F
         SHA1: 17:73:9E:2F:F6:DC:F0:55:72:5F:06:71:83:64:30:AE:AC:20:BD:7A


and now for a signer
java/jre/bin/keytool -list -v  -alias ldap_signer -keystore ~/ihs/Plugins/etc/plugin-key.kdb -storepass WebAS -storetype kdb

Alias name: ldap_signer
Creation date: null
Entry type: trustedCertEntry
Owner: CN=ldapeu2.uk.db.com, OU=Directory Services, O=Deutsche Bank, L=London, ST=England, C=GB
Issuer: CN=foo, OU=Directory Services, O=Tangerine Labs, L=London, ST=England, C=UK
Serial number: dd
Valid from: 07/06/10 15:45 until: 04/06/20 15:45
Certificate fingerprints:
         MD5:  92:75:9A:29:36:9C:10:10:64:DF:0F:2B:2F:DD:A5:25
         SHA1: B6:5C:3E:23:F8:C2:B0:B8:D7:99:E3:1F:CE:83:12:53:03:33:FA:CC

Thursday, 4 July 2013

Use wsadmin to monitoring WebSphere App Server SSL certificate expiry

A Jython script to check all certificates that are stored in keystores under Cell management. At my client's site I added IHS, Plugin and CACerts keystores to the Cell so that they too can be checked.
If you have access to an SMTP service this script will send an email when a cert is due to expire in less than X days. I run this from a bourne wrapper (I'll place the code for this at the end of this post) which also sends an email if it can't run the AdminTask methods it needs to for any reason.

Here's the Jython code

# --------------------------------------------------------------------------------
# checkCertificates.py
# Author: Bob Clarke (IBM)
# Date: 19/06/2013
# --------------------------------------------------------------------------------

# --------------------------------------------------------------------------------
# Setup
# --------------------------------------------------------------------------------
import re
import sys
import time
import os
import javaos
from java.text import SimpleDateFormat ;
dateFormat = SimpleDateFormat("dd-MMM-yyyy");
emailRecipients = "bob.clarke@stack1.com"
emailContent = "props/email.content"
smtpUrl = "smtp=smtp://smtphub.stack1.com"

# --------------------------------------------------------------------------------
# Define Subroutines 
# --------------------------------------------------------------------------------
def dateDiff(keystoreName, issuedTo, expString, scopeName):
        todayString =  time.strftime("%d-%b-%Y", time.gmtime())
        todayDate = dateFormat.parse(todayString)
        expiryDate = dateFormat.parse(expString)
        e = expiryDate.getTime()
        t = todayDate.getTime()
        d = e - t
        days = d / (1000 * 60 * 60 * 24)
        print "\tExpires "+expString
        if(days < 31):
                if(re.search("blueworks",  issuedTo)):
                        print "\tIgnoring BlueworksLive cert"
                else:
                        print "\tALERT - this certificate will expire in "+str(days)+" days"
                        file = open('props/email.content','w')
                        file.write('ACTION REQUIRED : The following certificate will expire in '+str(days)+' days\n\n')
                        file.write('- Environment '+env+'\n\n')
                        file.write('- Expiry Date '+expString+'\n\n')
                        file.write('- '+str(issuedTo)+'\n\n')
                        file.write('- Keystore name '+str(keystoreName)+'\n\n')
                        file.write('- Keystore scope '+str(scopeName)+'\n')
                        file.close()
                        sendEmail()

def sendEmail():
        os.system('cat '+emailContent+' | mailx -v -s "Certificate expiry notice for '+env+'" -S '+smtpUrl+' -S from="smtp@stack1.com" '+emailRecipients+' >> logs/smtp.log 2>&1')

# ---------------------------------------------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------------------------------------------

env = sys.argv[0]
print
print 'Obtaining keystore information for '+env

# Iterate through all keystores, print each cert with expiry dates and ask user if they want to replace
for ks in AdminTask.listKeyStores('[-all true -keyStoreUsage SSLKeys ]').splitlines():
        keystoreName =  AdminConfig.showAttribute(ks, 'name')
        ms = AdminConfig.showAttribute(ks, 'managementScope')
        scopeName = AdminConfig.showAttribute(ms, 'scopeName')

        print '\n## START '+keystoreName +' in scope '+scopeName+'##'

        print '\n\t## START personal certificates ##'
        personalCertsFound=0
        for cert in AdminTask.listPersonalCertificates('[-keyStoreName '+keystoreName+' -keyStoreScope '+scopeName+']').splitlines():
                personalCertsFound=1
                issuedTo=""
                for property in re.split("\] \[", cert):
                        if(re.search("\[\[",  property)):
                                tmp = property
                                property = re.split("\[\[",tmp)[1]
                        if(re.search("] ]",  property)):
                                tmp = property
                                property = re.split("] ]",tmp)[0]
                        if(re.search("alias", property)):
                                alias = re.split("\s+", property)[1]
                                print "\n\t"+property
                        if(re.search("issuedTo", property)):
                                issuedTo=property
                                print "\t"+property
                        if(re.search("issuedBy", property)):
                                print "\t"+property
                        if(re.search("validity", property)):
                                expString = property.split()[5].split('.]')[0]
                                #dateDiff(expString)
                                dateDiff(keystoreName, issuedTo, expString, scopeName)


        if(personalCertsFound==0):
                print '\tNo personal certificates found in '+keystoreName+' in scope '+scopeName
        print '\n\t## END personal certificates ##'

        print '\n\t## START signer certificates ##'
        signerCertsFound=0
        for cert in AdminTask.listSignerCertificates('[-keyStoreName '+keystoreName+' -keyStoreScope '+scopeName+']').splitlines():
                signerCertsFound=1
                issuedTo=""
                for property in re.split("\] \[", cert):
                        if(re.search("\[\[",  property)):
                                tmp = property
                                property = re.split("\[\[",tmp)[1]
                        if(re.search("] ]",  property)):
                                tmp = property
                                property = re.split("] ]",tmp)[0]
                        if(re.search("alias", property)):
                                alias = re.split("\s+", property)[1]
                                print "\n\t"+property
                        if(re.search("issuedTo", property)):
                                issuedTo=property
                                print "\t"+property
                        if(re.search("issuedBy", property)):
                                print "\t"+property
                        if(re.search("validity", property)):
                                expString = property.split()[5].split('.]')[0]
                                #dateDiff(expString)
                                dateDiff(keystoreName, issuedTo, expString, scopeName)

        if(signerCertsFound==0):
                print '\tNo signer certificates found in '+keystoreName+' in scope '+scopeName
        print '\n\t## END signer certificates ##'

        print '\n## END '+keystoreName +' in scope '+scopeName+'##'



And here's the wrapper script to run it. NOTE: This uses a cutdown version of wadmin.sh (which I've renamed to wsAdminLite.sh - see this post) which I will describe in an upcoming post. They key advantage of this for me is that I was able to point the wsadmin client at my own keystore in which I'd loaded the cell signers for each environment rather than loading all of these (untidily) into the Cell default trust store of another WAS environment.
You'll notice that this script writes a new soap.client.props for each environment, in this way you can XOR encode each password (better than plain text).


#!/bin/sh
# -----------------------------------------------------------------------------
# run.sh
# Author: Bob Clarke (IBM)
# Date: 01/07/2013
# -----------------------------------------------------------------------------
wsaCmd="./wsAdminLite.sh -lang jython"
envProps="props/env.props"
soapProps="props/soap.client.props"
run_log="logs/run.log"
emailRecipients="bob.clarke@stack1.com"
pwd=`pwd`
timestamp=`date "+%d/%m/%y %H:%M:%S"`
scripthost=`hostname`

cat $envProps | grep -v '^#' | while read line
do
        # Parse props
        env=`echo $line | awk -F: '{print $1}'`
        host=`echo $line | awk -F: '{print $2}'`
        port=`echo $line | awk -F: '{print $3}'`
        user=`echo $line | awk -F: '{print $4}'`
        pw=`echo $line | awk -F: '{print $5}'`

        # Write soap.client.props
        echo "com.ibm.SOAP.loginUserid=admin" > ${soapProps}
        echo "com.ibm.SOAP.loginPassword={xor}"${pw} >> ${soapProps}
        echo "com.ibm.ssl.alias=DefaultSSLSettings" >> ${soapProps}

        echo >> $run_log
        echo ENV is $env >> $run_log
        echo Timestamp is $timestamp >> $run_log
        echo "Running: $wsaCmd -host $host -port $port -f checkCertificates.py $env using $soapProps" >> $run_log
        out=`$wsaCmd -host $host -port $port -f checkCertificates.py $env`
        echo "Command output is: $out" >> $run_log

        # Check if we successfully connected to the deployment manager and obtained cert details
        echo $out | grep "END signer certificates" 2>&1 > /dev/null
        if [ $? -ne 0 ]; then
                echo
                echo "It seems the attempt to run checkCertificates.py on environment (${env}) has failed"
                echo "Invocation of checkCertificates.py on host (${scripthost}) to check certificates on environment (${env}) has failed, please check ${pwd}/${run_log}" | mailx -v -s "ACTION REQUIRED :Certificate check for $env has failed" -S smtp=smtp://smtphub.stack1.com -S from="smtp@stack1.com" $emailRecipients >> logs/smtp.log 2>&1
                echo
        fi
done


.... and here's an example env.props file


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# NOTE: The first column is a simple flag that is passed
# to wsadmin so that it can print out a meaningful
# string to describe the environment being checked
# It's up to the person who edits this file to ensure it's accurate
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
PNL_PERF002:jupiter.stack1.com:11005:admin:gfe8Shm1sPSjy
PNL_DEV001:pluto.stack1.com:8887:admin:HQ8SbhdsS8y
PNL_PROC_CENTRE:saturn.stack1.com::12005:admin:Lhjhju98zxubW==
PNL_SIT001:mars.stack1.com::8879:admin:HQ8Sjkj654kjk==
PNL_PERF001:venus.stack1.com::11005:admin:t65hhjtPS8y=

Monday, 17 June 2013

KDB keystores and default certificates


It's a little strange, and I need to think about this a little more when I get time....
But, with KDB keystores, you need to set a default certificate which the server will serve up when a client hits it

/opt/ihs/java/jre/bin/ikeycmd -cert -setdefault -label <mylabel>  -db <mystore> -pw <mypass>

If you don't do this you'll get the following error from openssl

4266:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:596:

Wednesday, 15 May 2013

A note about the browser based Process Inspector and SSL trust


It's worth noting that when you use the browser based Lombardi Process Inspector...



.... an outbound  connection is made from an AppTarget cluster member JVM to the endpoint specified in 100Custom.xml (or 99Local.xml depending on how proper you're being).   In many cases I've seen this endpoint left as the relevant WAS node ... but with me being OCD I made this endpoint the Load Balancer so that things were load balanced. Under these circumstances the public certificate issued by the webservers that sit behind the load balancer (unless of course you terminate SSL on the load balancer itself in which case you'd need to trust this instead)  wouldn't be trusted by the WAS Cell, so you'll need to import it into the relevant trust store. I import into the CellDefaultTrustStore because I like the convenience.

If you don't trust the cert you'll see things like javax.net.ssl.SSLPeerUnverifiedException and javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated in the AppTarget logs



Tuesday, 16 April 2013

Setting default cert for KDB keystores

This has caught me out a couple of times so I thought I'd better write it down ...

KDB keystores need you to set a default private key to issue, otherwise when a client sends an SSL HELLO, the handshake fails even if there is only one keypair in the keystore

A classic place to experience this is in the plugin keystore if you have 2-way SSL enabled between the web server and app server, you'll especially see this if  WAS has auto renewed the certificate and your web servers are managed by the Cell. Under this scenario WAS renews the cert in plugin keystore but does not set a default.

To remedy, use the setdefault option of ikeycmd

For example...
/opt/bpm/ihs8/java/jre/bin/ikeycmd -cert -setdefault -label frbpmwebdev.gslb.db.com -db /opt/bpm/ihs8/ssl/dev_ihskeystore.kdb -pw *******

Thursday, 31 January 2013

Using ikeycmd with spaces in the -label parameter


This one gave me loads of bother.. but I worked it out eventually :-)

Here's the problem..
Normally, when you want to look at the details of a keystore entry you run 

/opt/ihs/java/jre/bin/ikeycmd  -cert -details -label myLabel -db /tmp/myKeystore.kdb -pw myPasword

However, if somebody has imported a cert without specifying a label, the DN will be used as a default label, which invariably contains spaces. 'OK' you might thing, 'a couple of quotes will do nicely' ... not true!. I tried every combination of quotes, brackets and backslashes know to man or martian and none of them worked.

In the end, this article gave me the vital clue http://publib.boulder.ibm.com/httpserv/ihsdiag/gather_certificate_doc.html (search for the word parameter within) and running the java command directly as opposed to via the wrapper script (which is all ikeycmd is) did the trick.. see example below


/opt/ihs/java/jre/bin/java -ms8m com.ibm.gsk.ikeyman.ikeycmd  -cert -details -label 'CN=bobclarke.co.uk, OU=PKI, O=London Town C=GB' -db /tmp/myKeystore.kdb

NOTE: you still need to put single quotes around the label 

Sunday, 2 December 2012

Process Inspector and SSL trust


I had the whole SSL trust model sorted when I was running BPM 7.5.0, I even had Client auth set up and for this to work properly the Application Server had to trust the IHS plug-in.

Imagine my suprise then after I upgraded to BPM 7.5.1,  navigated to the ProcessAdmin screen, pressed the new "Process Inspector" button and realised (after checking the application server logs) that the Application server was complaining that it didn't trust the webserver cert!!!!... that's right, not the plug-in cert but the webserver cert!  .

The only explanation was that the App Server must be making a call (i.e as an SSL client) to the webserver. A quick check using Wireshark confirmed this.

So.. you need to make sure your WAS Cell trusts the webserver certificate (or it's signer chain)

My assumption at this moment is that a Dojo server side component is responsible for the call, and it's getting the webserver hostname / ipaddress from the clientside Dojo running "on the glass"

Friday, 9 November 2012

Using ikeycmd

Create a keystore 
/opt/bpm/ihs/java/jre/bin/ikeycmd -keydb -create -db /opt/ihs/ssl/ihskeystore.kdb -pw mypassword -type cms -expire 3650 –stash 

Export a keypair and directly import into another keystore 
/opt/ihs/java/jre/bin/ikeycmd -cert -import -db /tmp/certs/myKeyPair.jks -pw mypassword -label key -type jks -target /opt/ihs/ssl/ihskeystore.kdb -target_pw mytargetpassword -target_type cms

List keystore entries
/opt/ihs/java/jre/bin/ikeycmd -cert -list -type jks -db /tmp/certs/myKeyPair.jks -pw mypassword 

List keystore entry details
/opt/ihs/java/jre/bin/ikeycmd -cert -details -label myLabel -type jks -db /tmp/certs/myKeyPair.jks -pw mypassword 

Tuesday, 6 November 2012

Use of CACerts in BPM v751

Some facts...

1 : Process centre uses CAcerts to look up a trusted certificate 

2: RAL client uses CACerts but only when it needs to send a client cert to AppTarget when it asks for one (i.e .when it has Mutual auth enabled)

3: If you have your webserver specifying that mutual auth is optional it's happy to let you in without you sending a cert. But if you send one and it's not trusted you'll get a handshake error
It sounds obvious but it scuppered me for a while ... if you have your webserver specifying that mutual auth is optional it's happy to let you in without you sending a cert. But if you send do one and it's not trusted you'll get a handshake errror. In my case the SSL client was WAS and default the nodeDefaultSSLSettings are configured with a client cert alias on NONE. I changed this to default when I was debugging a differernt issue and didn't change it back again. This led to the Process Server heartbeat failling becasue it started sending a non trusted cert to the process centre webserver where previosuly I hadn't sent anything

Be careful when configuring mutual auth IHS to Optional

A process server contacting a process centre via a web server with Mutual auth set to optional 
When messing around with nodedefault settings in WAS I had set  default client certificate alias of default (previously it had been none) 
This mean that now, WAS would send a client cert to IHS because IHS would optionally accept this. however, the cert sent was of course not trusted 
Had me going for a couple of hours, finally realised the issue and confirmed by looking in error_log

View certificate chains with Open SSL

openssl s_client -showcerts -connect <host>:<port>

Check certificate expiry as follows

 openssl s_client -connect google.com:443 < /dev/null | openssl x509 -text | grep "Not After"

Monday, 5 November 2012

WebSphere RAL in BPM Advanced uses CACerts

I found this out when I enabled mutual authentication on the AppTarget cluster in a 4 cluster BPM advanced (751) setup...

I had enabled SSL client authentication for the inbound WC ports on my AppTarget JVM's (it's a long story so I wont go into why I did this).... this meant that anything sending a request to AppTargets WC ports would be asked for a client certificate.

RAL (Remote Artifact Loader) does just this... it's used by BPC explorer (which in my case was running on the Support Cluster) to gather info about a running BPC process running on the AppTarget cluster. (note: RAL traffic cant be pushed through a reverse proxy by design because all URI's are the same regardless of the server component being contacted.. weird design!).

So, in this scenario, with client auth enabled on AppTarget as described, any RAL requests would need to authenticate with a client certificate. So, you would be right to think this would already be taken care of by the fact that NodeDefaultKeyStore contains everything the RAL needs. However, you would be wrong.. it turns out that RAL uses CAcerts for this, and therefore, when you tried to get into about a running process (ir tried to start a new process for that matter) the request would fail.

I'm sure there's a way to force WAS to use the right keystores and truststores... but until I or someone else works out what is is.... you can copy the relevant keypairs around using the ikeycmd commands below

$WAS_HOME/java/jre/bin/ikeycmd -cert -export -label default -type pkcs12
-db $WAS_HOME/profiles/<profile>/config/cells/<cell>/nodes/<node>/key.p12
-pw <password> -target_pw <target password> -target_type jks -target
$WAS_HOME/java/jre/lib/security/cacerts

By the way, the Lombardi Process Centre also uses CACerts for trust when deploying to a Process Server. Ironically enough the Lombardi Process Server is better behaved and does not use CACerts when trusting the Process Centre web sending it's heartbeat.. it uses CellDefaultTruststore as one would expect.