Tuesday, September 24, 2019

how to replace classes on server


Details to replace classes on server as :


Search for the 2 classes on server, and replace with the temp fix and restart the server.
 
e.g.
find . -name "TCRMPartyComponent.class" -print
 
/opt/IBM/WebSphere/AppServer9.0/profiles/Node01/installedEBAs/com.ibm.mdm.hub.server-MDM116Instance_11.6.0.8/byValue/87f44ab3-3768-47d9-9ad3-84609f960921.31/31/com/dwl/tcrm/coreParty/component/TCRMPartyComponent.class
 
find . -name "TCRMPrivacyPreferenceComponent.class" -print
 
/opt/IBM/WebSphere/AppServer9.0/profiles/Node01/installedEBAs/com.ibm.mdm.hub.server-MDM116Instance_11.6.0.8/byValue/87f44ab3-3768-47d9-9ad3-84609f960921.37/37/com/dwl/tcrm/businessServices/component/TCRMPrivacyPreferenceComponent.class
 
However, if you want to deploy it properly, follow these steps :

1) Log on to the WebSphere admin console
 
2) Export EBA from server
Applications -> Assets
com.ibm.mdm.hub.server.app-<appName>.eba

Select the Export button and export the EBA
 
2) Extract bundles from the exported EBA
com.ibm.mdm.server.party.<version_date_timestamp>.jar
com.ibm.mdm.server.bizservices.<version_date_timestamp>.jar
 
3) replace the 2 classes in the extracted bundles with those provided
bundle: com.ibm.mdm.server.party.<version_date_timestamp>.jar
com.dwl.tcrm.coreParty.component.TCRMPartyComponent.class
 
bundle: com.ibm.mdm.server.bizservices.<version_date_timestamp>.jar
com.dwl.tcrm.businessServices.component.TCRMPrivacyPreferenceComponent
 
4) extract META-INF/MANIFEST.MF from both bundles
update MANIFEST.MF Bundle-Version to higher value at date_timestamp
replace META-INF/MANIFEST.MF with updated copy
rename the 2 bundles with new date_timestamp
 
5) Navigate to Environment->OSGi bundle repositories->Internal bundle repository
 
6) Click New and then select the new com.ibm.mdm.server.party.<version_date_timestamp>.jar
 repeat for com.ibm.mdm.server.bizservices.<version_date_timestamp>.jar
 
7) Once the file has loaded click Review link then select "Synchronize changes with Nodes" and click Save followed by OK once the update has completed and then OK and the new bundle should be listed in the repository
 
8) Navigate to Applications->Application Types->Assets->com.ibm.mdm.hub.server.app-<appName>.eba
 
9) Click on "Update bundle versions in this application"
 
10) Change the com.ibm.mdm.server.party and the com.ibm.mdm.server.bizservices bundle versions into the versions loaded earlier and then click Preview followed by Create
 
11) Click the Review link then select "Synchronize changes with Nodes" and click Save followed by OK once the update has completed
 
12) Navigate to Applications->Application Types->Business-level applications->com.ibm.mdm.hub.server.app-<appName>.eba
 
13) Click the "Update to latest deployment..." button and hit OK
 
14) On the Blueprint resource references screen, select the Authentication Alias for datasources jdbc/DWLConfig and jdbc/DWLCustomer, and then Next then Next and Finish
 
15) Click the Review link then select "Synchronize changes with Nodes" and click Save followed by OK once the update has completed
 
16) Navigate to Servers->Server Types->WebSphere application servers
 
17) Select the server and click the Restart button


Monday, September 23, 2019

BTM ITxRx Exception

The cache could have residue from anything that are interfering with class loading, including wrong paths, different class names etc ...


Clearing the cache is something that is used to solve many issues that are not product defect. This includes your issue here. I think this case can be closed as there is no further action required here.


 

clearing WAS osgi cache is a known fix of this "Controller class loading issue"


Trace settings

 

*=info: com.dwl.*=warning: com.ibm.mdm.*=warning: com.ibm.mdm.server.config.*=info: com.ibm.mdm.common.brokers.*=info: com.ibm.mdm.mds.*=info: com.initiatesystems.*=info: com.dwl.base.report.mbean.TransactionDataListener=fine: WLM*=all: com.dwl.jmsadapter.mdb.*=info: com.dwl.base.requestHandler.*=info: com.ibm.ws.classloader.*=all

 


[9/11/19 13:20:20:978 EDT] 00001a91 TCRMCommonCom E  com.dwl.base.exception.DWLDataInvalidException: [1001 FVERR 1102 The following is required: ReferenceNumber][1009 FVERR 102 EndDate must be after StartDate]

The only error that is of a concerns is this ..

[9/10/19 13:34:19:054 EDT] 00001e58 DWLExceptionU E  java.lang.Exception: [Exception_DWLTxnBP_CannotLoadBeanController:] CDKCH2005E:The controller class cannot be loaded. Controller class = Controller Service not found for transaction: getPerson
   at com.dwl.base.requestHandler.DWLTxnBP.processInquiryObject(DWLTxnBP.java:400)
   at com.rbc.cdm.composite.compositeTxn.RbcBaseTxnBP.fireInquiryTransaction(RbcBaseTxnBP.java:192)
   at com.rbc.cdm.composite.compositeTxn.RbcBaseTxnBP.getPerson(RbcBaseTxnBP.java:300)
   at com.rbc.cdm.composite.compositeTxn.MaintainCDMPartyCompositeTxnBP.processRequest(MaintainCDMPartyCompositeTxnBP.java:697)
   at com.rbc.cdm.composite.compositeTxn.MaintainCDMPartyCompositeTxnBP.execute(MaintainCDMPartyCompositeTxnBP.java:185)
   at com.dwl.base.requestHandler.DWLTxnProcessor.processTx(DWLTxnProcessor.java:98)
   at com.dwl.unifi.tx.manager.CTxRxFacade.processTxNormal(CTxRxFacade.java:681)
   at com.dwl.unifi.tx.manager.CTxRxFacade.processTx(CTxRxFacade.java:544)
   at com.dwl.base.requestHandler.DWLRequestHandler.processTransaction(DWLRequestHandler.java:1276)
   at com.dwl.base.requestHandler.DWLRequestHandler.processTx(DWLRequestHandler.java:608)
   at com.dwl.base.requestHandler.DWLServiceControllerBase.processRequest(DWLServiceControllerBase.java:253)
   at com.dwl.base.requestHandler.beans.EJSLocal0SLDWLServiceController_2c54996d.processRequest(EJSLocal0SLDWLServiceController_2c54996d.java)
   at com.dwl.base.requestHandler.beans.EJSProxy$$MDMServiceControllerLocal.processRequest(Unknown Source)
   at com.dwl.jmsadapter.util.DWLCustomerApp.submit(DWLCustomerApp.java:149)
   at com.ibm.mdm.jmsadapter.util.MessageProcessingManager.submitRequest(MessageProcessingManager.java:127)
   at com.dwl.jmsadapter.mdb.MDBRequestReceiverBean.processMessage(MDBRequestReceiverBean.java:173)
   at com.dwl.jmsadapter.mdb.MDBRequestReceiverBean.onMessage(MDBRequestReceiverBean.java:128)
   at com.ibm.ejs.container.WASMessageEndpointHandler.invokeJMSMethod(WASMessageEndpointHandler.java:138)
   at com.ibm.ws.ejbcontainer.mdb.MessageEndpointHandler.invokeMdbMethod(MessageEndpointHandler.java:1146)
   at com.ibm.ws.ejbcontainer.mdb.MessageEndpointHandler.invoke(MessageEndpointHandler.java:844)
   at com.sun.proxy.$Proxy82.onMessage(Unknown Source)
   at com.ibm.mq.connector.inbound.MessageEndpointWrapper.onMessage(MessageEndpointWrapper.java:131)
   at com.ibm.mq.jms.MQSession$FacadeMessageListener.onMessage(MQSession.java:133)
   at com.ibm.msg.client.jms.internal.JmsSessionImpl.run(JmsSessionImpl.java:2913)
   at com.ibm.mq.jms.MQSession.run(MQSession.java:958)
   at com.ibm.mq.connector.inbound.ASFWorkImpl.doDelivery(ASFWorkImpl.java:111)
   at com.ibm.mq.connector.inbound.AbstractWorkImpl.run(AbstractWorkImpl.java:238)
   at com.ibm.ejs.j2c.work.WorkProxy$RunWork.run(WorkProxy.java:282)
   at java.security.AccessController.doPrivileged(AccessController.java:666)
   at javax.security.auth.Subject.doAs(Subject.java:490)
   at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:133)
   at com.ibm.ejs.j2c.work.WorkProxy$RunWork.run(WorkProxy.java:285)
   at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:63)
   at com.ibm.ejs.j2c.work.WorkProxy.run(WorkProxy.java:667)
   at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1892)

Tuesday, September 17, 2019

maxRetryLimit - Check for Retry

The MDM CONFIGELEMENT setting /IBM/MessagingAdapter/Exception/maxRetryLimit controls the number of retries:

 

https://www.ibm.com/support/knowledgecenter/en/SSWSR9_11.6.0/com.ibm.mdmhs.dev.platform.doc/references/r_CMproperties.html

/IBM/MessagingAdapter/Exception/maxRetryLimit

·         Description: Determines how many times the Messaging Adapter attempts to reprocess a failed inbound request message by invoking DWLServiceController.

·         Default value3

·         Dynamic: true

·          

If you want to see it in action, you will have to turn on INFO level logging for

com.dwl.jmsadapter.mdb.MDBRequestReceiverBean class

 

as the logging code is below

 

                               

                        

 

if(currentRetryCount <= getMaxRetryLimit(manager.getControl()) && manager.shouldRetry(e)) {

                               

                        

 

if (logger.isInfoEnabled()) {

                                

                        

 

logger.info(ResourceBundleHelper.resolve(

                               

                        

 

ResourceBundleNames.MESSAGING_ADAPTER_STRINGS,

                               

                        

 

INFO_DWLJMSMessageProcessor_MessageRetry,

                               

                        

 

new Object[] {manager.getMessageId(), currentRetryCount}));

                               

                        

 

}

                                

                        

 

processMessage(manager, currentRetryCount);

                               

                        

 

}

                       

 

There are no such settings for the retry interval setting in MDM.  Updating the CONFIGELEMENT and using the retryErrorCodeList' seems like the only option within MDM.  You can most likely do it programmatically outside of MDM, for example like in the earlier article I sent you, Identifying database deadlocks and retrying transactions.  However, there is no other settings within MDM to control for the number of retries or a delay between retries.  

 

_______________________________________________________________________

If you received this email in error, please advise the sender (by return email or otherwise) immediately. You have consented to receive the attached electronically at the above-noted email address; please retain a copy of this confirmation for future reference.

Si vous recevez ce courriel par erreur, veuillez en aviser l'expéditeur immédiatement, par retour de courriel ou par un autre moyen. Vous avez accepté de recevoir le(s) document(s) ci-joint(s) par voie électronique à l'adresse courriel indiquée ci-dessus; veuillez conserver une copie de cette confirmation pour les fins de reference future.

Thursday, August 22, 2019

Error Retry on Queue

The Batch framework allows retry of errors, is there a similar setting for Queue's for FAIL transactions?

In order to see the retry in the logs we need to enable Step #1

1.       Log onto WAS Console: Goto Troubleshooting-> Logs and Trace-> Server1-> Change Log Level Detail and add the bolded text.
*=info: com.dwl.*=warning: com.ibm.mdm.*=warning: com.ibm.mdm.server.config.*=info: com.ibm.mdm.common.brokers.*=info: com.ibm.mdm.mds.*=info: com.initiatesystems.*=info: com.dwl.base.report.mbean.TransactionDataListener=fine: com.dwl.jmsadapter.mdb.*=info
  
2.       SQL
UPDATE CONFIGELEMENT SET VALUE = ' SQLCODE=-911,SQLCODE=-913,ORA-00370,ORA-02049,ORA-00060,SQLCODE=-968,SQLCODE=-803, SQLCODE=-723'
, LAST_UPDATE_DT = CURRENT_TIMESTAMP WHERE NAME = '/IBM/DWLCommonServices/ErrorHandling/retryErrorStringList';

UPDATE CONFIGELEMENT SET VALUE = '12,2037,4930, 109,10506,49359',
LAST_UPDATE_DT = CURRENT_TIMESTAMP WHERE NAME = '/IBM/DWLCommonServices/ErrorHandling/retryErrorCodeList';


Once we set the error codes the retry should work automatically, do we have a setting to enable retries? This is a CM configuration, use sql to update it. 
If I add the log statement in WAS console then this retry information will be logged in trace.log? This should appear in SystemOut.log, not sure it will appear in trace.log. 

Reference:  

/IBM/MessagingAdapter/Exception/maxRetryLimit

·         Description: Determines how many times the Messaging Adapter attempts to reprocess a failed inbound request message by invoking DWLServiceController.
·         Default value3
·         Dynamic: true
If you want to see it in action, you will have to turn on INFO level logging for
com.dwl.jmsadapter.mdb.MDBRequestReceiverBean class

as the logging code is below

                               
                        

if(currentRetryCount <= getMaxRetryLimit(manager.getControl()) && manager.shouldRetry(e)) {
                                
                        

if (logger.isInfoEnabled()) {
                               
                        

logger.info(ResourceBundleHelper.resolve(
                               
                        

ResourceBundleNames.MESSAGING_ADAPTER_STRINGS,
                               
                        

INFO_DWLJMSMessageProcessor_MessageRetry,
                               
                        

new Object[] {manager.getMessageId(), currentRetryCount}));
                                
                        

}
                               
                        

processMessage(manager, currentRetryCount);
                               
                        

}
                       

Reprocessing inbound messages in case of an error
When there is an error processing an inbound request message, Messaging Adapter can re-invoke the DWLServiceController to reprocess the request. You can define the error conditions that trigger the Messaging Adapter to re-invoke the DWLServiceController using the following properties in the Configuration and Management component:
/IBM/DWLCommonServices/ErrorHandling/retryErrorStringList
/IBM/DWLCommonServices/ErrorHandling/retryErrorCodeList

Error Retry on Queue


Here is the SQL to run for retry:

UPDATE CONFIGELEMENT SET VALUE = ' SQLCODE=-911,SQLCODE=-913,ORA-00370,ORA-02049,ORA-00060,SQLCODE=-968,SQLCODE=-803, SQLCODE=-723'
, LAST_UPDATE_DT = CURRENT_TIMESTAMP WHERE NAME = '/IBM/DWLCommonServices/ErrorHandling/retryErrorStringList';

UPDATE CONFIGELEMENT SET VALUE = '12,2037,4930, 109,10506,49359',
LAST_UPDATE_DT = CURRENT_TIMESTAMP WHERE NAME = '/IBM/DWLCommonServices/ErrorHandling/retryErrorCodeList';

Summary of error response for defects which have been configured for retry:
1:
      <DWLError>
        <ComponentType>1012</ComponentType>
        <ErrorMessage>The following is required: PersonName</ErrorMessage>
        <ErrorType>FVERR</ErrorType>
        <LanguageCode>100</LanguageCode>
        <ReasonCode>2037</ReasonCode>
        <Severity>0</Severity>
        <Throwable>com.dwl.tcrm.exception.TCRMDataInvalidException: com.dwl.base.exception.DWLDataInvalidException: [1012 FVERR 2037 The following is required: PersonName]</Throwable>
      </DWLError>
2:
                        <DWLError>
                                <ComponentType>111</ComponentType>
                                <ErrorMessage>Duplicate primary key already exists.</ErrorMessage>
                                <ErrorType>DKERR</ErrorType>
                                <LanguageCode>100</LanguageCode>
                                <ReasonCode>12</ReasonCode>
                                <Severity>0</Severity>
                                <Throwable>com.dwl.tcrm.exception.TCRMDuplicateKeyException: [Exception_Common_DuplicateKey:] CDKCS0001E:The object cannot be created due to duplicate primary key. Primary key = null; object = com.dwl.tcrm.coreParty.component.TCRMSuspectBObj; exception = DB2 SQL Error: SQLCODE=-803, SQLSTATE=23505, SQLERRMC=3;RYY4.SUSPECT, DRIVER=3.72.52</Throwable>
                        </DWLError>
3:
<DWLError>
        <ComponentType>108</ComponentType>
        <ErrorMessage>BTM ITxRxException occurred in Request and Response Framework.</ErrorMessage>
        <ErrorType>READERR</ErrorType>
        <LanguageCode>100</LanguageCode>
        <ReasonCode>4930</ReasonCode>
        <Severity>0</Severity>
        <Throwable>com.dwl.base.exception.DWLBaseException</Throwable>
      </DWLError>
4:
<DWLError>
        <ComponentType>904</ComponentType>
        <ErrorMessage>The following transaction failed: updateLobRelationship</ErrorMessage>
        <ErrorType>UPDERR</ErrorType>
        <LanguageCode>100</LanguageCode>
        <ReasonCode>10506</ReasonCode>
        <Severity>0</Severity>
        <Throwable>com.ibm.pdq.runtime.exception.DataRuntimeException: [pdq][10103][3.200.75] An error prevented the update operation from completing successfully.;  Caused by: com.ibm.db2.jcc.am.SqlException: DB2 SQL Error: SQLCODE=-723, SQLSTATE=09000, SQLERRMC=RYY4.U_LEBREL;-803;23505;1|RYY4.H_LOBREL, DRIVER=3.72.52</Throwable>
      </DWLError>

5:
<DWLError>
                                                                <ComponentType>99</ComponentType>
                                                                <ErrorMessage>[Exception_Shared_LastUpdateDtNotMatched:] CDKCH2001E:Another transaction has updated the database record you are trying to update. Cannot update record at this time, please try again.</ErrorMessage>
                                                                <ErrorType>UPDERR</ErrorType>
                                                                <LanguageCode>100</LanguageCode>
                                                                <ReasonCode>109</ReasonCode>
                                                                <Severity>0</Severity>
                                                                <Throwable>java.lang.RuntimeException: com.dwl.base.exception.LastUpdateDateException: class com.dwl.tcrm.businessServices.entityObject.EObjLobRelationship | 879956570600676001</Throwable>
                                                </DWLError>
6:
<DWLError>
                                                                <ComponentType>4405</ComponentType>
                                                                <ErrorMessage>Suspect search adapter execution failed.</ErrorMessage>
                                                                <ErrorType>DIERR</ErrorType>
                                                                <LanguageCode>100</LanguageCode>
                                                                <ReasonCode>49359</ReasonCode>
                                                                <Severity>0</Severity>
                                                                <Throwable>java.lang.NullPointerException</Throwable>
                                                </DWLError>


Trace log Setup instructions


Please follow the steps below:
      1.  Log in to WAS console
      2.  Goto Troubleshooting -> Logs and Trace -> server1
3.  Set the file size to 20 MB and number of historical files to 20

Friday, July 4, 2008

Creating your own Certificate Authority using OpenSSL

It took me a long time to put all this together, but now it seems extremely simple. I hope it comes in handy to others who are trying to setup a private CA.

There are three parts:
a) Creating a Certificate Authority
b) Setting up the Server(Tomcat)
c) Setting up the client

This article does not cover certificate revocation.

a) Creating a Certificate Authority

There are two ways to do this
- Using scripts provided by OpenSSL
- Using OpenSSL commands and creating your own directory structure

We will use the second method. So lets get started. Make sure you have downloaded and installed OpenSSL

1) Create a new Directory structure

MyCompanyCA\private

2) Goto the MyCompanyCA directory, create an RSA keypair for the CA using OpenSSL:

% openssl genrsa -des3 -out private/CA_key.pem 2048

Note down password you entered above for CA PASSWORD here _________________

3) Next, create, from the private key, the public-key certificate for your CA. To generate this self-signed certificate, use the following command:

% openssl req -new -key private/CA_key.pem -x509 -days 365 -out CA_cert.cer

This creates a public-key certificate from the private key you generated earlier. The -x509 switch indicates that we wish to generate this X.509 certificate, and the -days switch gives our generated certificate an expiration date. Since we are generating this public-key certificate for the first time, the command asks a number of questions, intended to populate the necessary X.500 information:

% openssl req -new -key private/CA_key.pem -x509 -days 365 -out CA_cert.cer
Enter pass phrase for private/CA_key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CA
State or Province Name (full name) [Some-State]:Ontario
Locality Name (eg, city) []:Toronto
Organization Name (eg, company) [Internet Widgits Pty Ltd]:MyCompany Info Inc.
Organizational Unit Name (eg, section) []:SECURITY Team
Common Name (eg, YOUR name) []: Certificate Authority Created by Ash Srivastava
Email Address []: asrivastava@MyCompanyinfo.com

Note: the public-key certificate should be the only file from the two that you just generated that you should share with anyone.
That’s all you need, your CA is now setup.

b) Setting up the Server(Tomcat)

1) Goto your local tomcat directory(Ex: Tomcat 5.5)
2) Generate a private key and CSR(Certificate Signing request) using the Java keytool application. To generate an RSA keypair using keytool, use the following command:

% keytool -genkey -v -alias tomcat -keyalg RSA -keysize 2048 -keystore my_keystore.jks

This command generates an RSA keypair of size 2,048 bits, following the OpenSSL example above. However, keytool will, at the same time, also generate a Java keystore (JKS) format keystore file in which the keypair, along with a self-signed public-key certificate, is placed, giving it a shorter alias of "tomcat." Since keytool creates the X.509 certificate in this step, it asks the user for the necessary X.500 information:

% keytool -genkey -v -alias tomcat -keyalg RSA -keysize 2048 -keystore my_keystore.jks
Enter keystore password: password
What is your first and last name?
[Unknown]: localhost
What is the name of your organizational unit?
[Unknown]: SECURITY team
What is the name of your organization?
[Unknown]: MyCompany Info Inc.
What is the name of your City or Locality?
[Unknown]: Toronto
What is the name of your State or Province?
[Unknown]: Ontario
What is the two-letter country code for this unit?
[Unknown]: CA
Is CN=localhost, OU=SECURITY team, O= MyCompany Info Inc., L=Toronto, ST=Ontario, C=CA correct?
[no]: yes
Generating 2,048 bit RSA key pair and self-signed certificate (MD5WithRSA)
for: CN=localhost, OU=SECURITY team, O= MyCompany Info Inc., L=Toronto, ST=Ontario, C=CA
Enter key password for
(RETURN if same as keystore password):
[Saving my_keystore.jks]

The CN should exactly be the name of the host which this certificate will identify i.e in my case localhost. Note down password you entered above for server keystore PASSWORD here _________________

3) To generate the CSR from our new keypair using keytool, you can use the following command:

% keytool -certreq -v -alias tomcat -keystore my_keystore.jks -file tomcat_request.csr
You can now submit the resulting file to the CA for certificate issuance.

4) Using the private key/public-key certificate you generated earlier for the CA, you can sign the certificate contained in the CSR using OpenSSL. Copy tomcat_request.csr to MyCompanyCA directory, the goto MyCompanyCA directory and type the following:

% openssl x509 -req -days 365 -in tomcat_request.csr -CA CA_cert.cer -CAkey private/CA_key.pem -CAcreateserial -out tomcat.cer

This command issues a new certificate, signed by your CA, with a validity period of one year. The use of the -CAcreateserial switch enables the unique assignment of serial numbers to our issued certificates. Since this is the first certificate issued by your CA, a new file is created (demoCA/CA_cert.srl) containing the number "02," which is the next serial number to be used when the next certificate is issued (serial number "01" was used by the first certificate). Thus, when issuing subsequent certificates, you would use the following command:

% openssl x509 -req -days 365 -in new_request.csr -CA demoCA/CA_cert.cer -CAkey demoCA/private/CA_key.pem -CAserial demoDA/CA_cert.srl -out new_certificate.cer

Once your CA has issued the certificate, you can send it back to the requester for use. It's also important to keep a copy of the certificate around, just in case you need to revoke it later.

5) Send tomcat.cer and CA_cert.cer to the server and paste tomcat.cer to the server directory. (Ex: Tomcat 5.5).

Rename my_keystore.jks to keystore.key

Now add CA_cert.cer to the truststore and tomcat.cer to the keystore.

The keystoreFile is a collection of X.509 certificates one of which Tomcat will use to identify itself to Browsers. This certificate contains the DNS name of the server on which Tomcat is running which the HTTP client will have used as the servername part of the URL. It is possible to use a file that contains multiple certificates (in which case Tomcat will use the certificate stored under the alias "Tomcat" or, if that is not found, will use the first certificate it finds that also has an associated private key). However, to assure that no mistakes are made it is sensible practice to use a file that has only the one host certificate, plus of course its private key and chain of parent Certificate Authorities.

The truststoreFile is a collection of X.509 certificates representing Certificate Authorities from which Tomcat is willing to accept User certificates. Since the keystoreFile contains the CA that issued the certificate identifying the server, the truststoreFile and keystoreFile could be the same in a CAS configuration where the URL (actually the port) that uses X.509 authentication is not the well know widely recognized URL for interactive (userid/password form) login, and therefore the only CA that it trusts is the institutional internal CA.
The JKS (Java Key Store) file format is maintained by a tool provided by Sun in the /bin subdirectory of the Java Development Kit (JDK) distribution of your current version of Java. It is documented in http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/keytool.html.

Add CA_cert.cer to the truststore
% keytool --import -alias CA -keystore trustStore.jks -file CA_cert.cer
Enter keystore password: tomcat
Owner: EMAILADDRESS=asrivastava@MyCompanyinfo.com, CN=Certificate Authority Created by Ash Srivastava, OU=SECURITY Team, O=MyCompany Info Inc., L=Toronto, ST=Ontario, C=CA
Issuer: EMAILADDRESS=asrivastava@MyCompanyinfo.com, CN=Certificate Authority Created by Ash Srivastava, OU=SECURITY Team, O=MyCompany Info Inc., L=Toronto, ST=Ontario, C=CA
Serial number: 0
Valid from: Wed Jul 02 16:10:50 EDT 2008 until: Thu Jul 02 16:10:50 EDT 2009
Certificate fingerprints:
MD5: 22:15:FB:7D:3D:22:40:3E:BC:EE:FD:33:92:BF:E6:8F
SHA1: 8A:EC:45:37:8D:1F:F0:E7:B4:20:69:B9:DC:93:AC:C6:46:04:7E:7E
Trust this certificate? [no]: yes
Certificate was added to keystore

Note down password you entered above for server truststore PASSWORD here___________

Add tomcat.cer to the keystore
% keytool -import -trustcacerts -alias tomcat -file tomcat.cer -keystore keystore.key
You will be asked to provide the server keystore password here

6) Go in server.xml for tomcat and enable SSL by commenting out the 8080 connector and enabling the SSL connector and add the keystore and truststore location

server.xml's SSL section should look like the following:

connector port="8443" maxhttpheadersize="8192" maxthreads="150" minsparethreads="25" maxsparethreads="75" enablelookups="false" disableuploadtimeout="true" acceptcount="100" scheme="https" secure="true" clientauth="true" sslprotocol="TLS" keystorefile="keystore.key" keystorepass="tomcat" truststorefile="trustStore.jks" truststorepass="tomcat"

The clientAuth="want" tells Tomcat to request that the Browser provide a User certificate if one is available. If you want to force the use of User certificates, replace "want" with "true". If you specify "want" and the browser does not have a certificate, then the Webflow configuration described below will forward the request to the userid/password form.

Congratulations your server is setup now.

c) Setting up the client

1) Add CA_cert.cer to your browsers Trust Store
In Firefox, Tools->Options->View Certificates->Authorities Tab->Import
In IE, Tools->Internet options->Content tab->Certificates Button->Trusted root Certification Authorities tab -> Import

2) The client should install openSSL and should generate their private key and a CSR. Create a folder caller ClientCertificate on client computer. Go in that folder and first, you need to generate an RSA private key for the new server:

% openssl genrsa -des3 -out ash.pem 2048

Note down password you entered above for client private key PASSWORD here_________
Just as in the CA example above, this command generates a new RSA private key protected by a DES3 password.

Since you want your CA to issue the public-key certificate, enabling distributed trust by other members of the PKI, you now need to generate a certificate signing request (CSR) from your private key. Using OpenSSL, you can do so with the following command:

% openssl req -new -key ash.pem -out ash_request.csr
It is this CSR file that you can now submit to the CA for public-key certificate issuance.

3) Send ash_rquest.csr to your CA and run the following command in your CA_cert.cer directory

% openssl x509 -req -days 365 -in ash_request.csr -CA CA_cert.cer -CAkey private/CA_key.pem -CAcreateserial -out ash.cer

You will required to enter the CA private key password. Send ash.cer and CA_cer back to the client

4) Now you have ash.pem, ash.cer and CA_cert.cer in your ClientCertificate Directory
To add the client certificate to the browser it has to be in .p12 format. The following command creates a single PKCS#12 file from client certificate, its key and issuer's (CA's) certificate. -name and -caname specify PKCS#12 friendly names for client's cert and CA's cert respectively.

> openssl pkcs12 -export -in ash.cer -inkey ash.pem -certfile CA_cert.cer -out ash.p12 -name "Ash Client Cert 001" -caname "MyCompany CA"

So you have created ash.p12 file which you can go and add to you browser to identify yourself to the server.

In Firefox, Tools->Options->View Certificates->Your Certificate Tab->Import
In IE, Tools->Internet options->Content tab->Certificates Button-> Personal Tab -> Import
Now go to the server and the browser will present you with the certificate you will like to use to represent yourself to the server.

d) Extracting X509 variables from the certificate and using it in a web app.

In the servlet doPost method add the following,

java.security.cert.X509Certificate[] certs = (java.security.cert.X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
HTMLWriter.writeSSLInfo(response,certs);

Simply extract and dispay it on the page

public static void writeSSLInfo(HttpServletResponse response,
X509Certificate[] certs) throws IOException {

response.setContentType("text/html");
PrintWriter writer = response.getWriter();

writeCommonHead(writer, "Authenticate");
for (int i=0; i < style="font-weight: bold;">References
1. http://www.linux.com/feature/38315
2. http://www.ja-sig.org/wiki/display/CASUM/X.509+Certificates
3. http://www.digicert.com/ssl-certificate-installation-tomcat.htm
4. http://www.orenosv.com/orenosp/certmemo_en.txt