Monday, December 22, 2008

How to solve the certification path error

Exception trace:

javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://localhost:7443/WSRM/WsrmServerService?wsdl. It failed with:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:162)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:144)
at com.sun.xml.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:264)
at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:227)
at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:175)
at com.sun.xml.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:104)
at javax.xml.ws.Service.(Service.java:56)
at gov.cdc.wsigrid.wsrm.WsrmServerService.(WsrmServerService.java:46)
at gov.cdc.wsigrid.wsrm.WsrmClientServlet.processRequest(WsrmClientServlet.java:205)
at gov.cdc.wsigrid.wsrm.WsrmClientServlet.doPost(WsrmClientServlet.java:279)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1591)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1035)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:124)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)

Solution:
This is caused by the ssl communication. The client need to import the public key of the server.
To solve the problem, refer to the post "How to establish client SSL connection".
e.g.
openssl s_client -connect localhost:7443
$JAVA_HOME/bin/keytool -import -alias tomcat_client -keystore $JAVA_HOME/jre/lib/security/cacerts -file pubcert.pem

Friday, December 12, 2008

How to setup tomcat SSL client

1. Retrieve public key from the server certificate

openssl s_client -connect server_host_name:8443

ouput look like this
--------------------------------------------------------------
CONNECTED(00000003)
depth=0 /C=US/ST=GA/L=Atlanta/O=cdc/OU=cdc/CN=Charlie
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=US/ST=GA/L=Atlanta/O=cdc/OU=cdc/CN=Charlie
verify return:1
---
Certificate chain
0 s:/C=US/ST=GA/L=Atlanta/O=cdc/OU=cdc/CN=Charlie
i:/C=US/ST=GA/L=Atlanta/O=cdc/OU=cdc/CN=Charlie
---
Server certificate
-----BEGIN CERTIFICATE-----
MIICKzCCAZSgAwIBAgIESUKsLDANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJV
UzELMAkGA1UECBMCR0ExEDAOBgNVBAcTB0F0bGFudGExDDAKBgNVBAoTA2NkYzEM
MAoGA1UECxMDY2RjMRAwDgYDVQQDEwdDaGFybGllMB4XDTA4MTIxMjE4MjM0MFoX
DTA5MDMxMjE4MjM0MFowWjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkdBMRAwDgYD
VQQHEwdBdGxhbnRhMQwwCgYDVQQKEwNjZGMxDDAKBgNVBAsTA2NkYzEQMA4GA1UE
AxMHQ2hhcmxpZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAnee+j8Fj5TTC
BQMVRLRWnv9zTPhJYaMYFDkZqu3PmqIdv3Nc6aNsSKwqcJG5TaM9dFhiZdhF5Glk
XaEx9ERU4fNh7NLxBHBl0g7CsjssDnLJBB/CzrDkqYUKy3+yE+cSyiOznpkYsOmH
SZYRaDNVJ7MsLQM7Tyyvks911E8ULwUCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBb
7txpYmEzQxYUX9RrckDcbcznMjao2ND89P+Ifs/3g4mWxvQz6bTBFngjihfaayzK
Zr6kYQDzgHWYa4TaRLGWL17FTrgk8obZuY84+TMCsQPOi4bim26sGDk6Kzkj1pmG
F7NBC/FSKiJDsH7M5uJLYeFNYDulP5GvfHBS//OpAg==
-----END CERTIFICATE-----
subject=/C=US/ST=GA/L=Atlanta/O=cdc/OU=cdc/CN=Charlie
issuer=/C=US/ST=GA/L=Atlanta/O=cdc/OU=cdc/CN=Charlie
---
----------------------------------------------------
save the text including -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- into a file, e.g. named pubkey.pem

2. import the sever ssl pubkey into JDK default cacerts file
in JDK1.6 the cacerts file is in $JAVA_HOME/jre/lib/security/cacerts
----------------------------------------------------------------------------------
$JAVA_HOME/bin/keytool -import -alias tomcat -keystore $JAVA_HOME/jre/lib/security/cacerts -file pubcert.pem
--------------------------------------------------------------
3. In development only, add the following code in your main java client program to overcome the
javax.xml.ws.WebServiceException: java.io.IOException: HTTPS
hostname wrong: should be
static {
//WORKAROUND. TO BE REMOVED.


javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){

public boolean verify(String |hostname|,
javax.net.ssl.SSLSession sslSession) {
if (hostname.equals("mytargethostname")) {
return true;
}
return false;
}
});


}

4. Restart the app server

How to setup tomcat SSL server and client

  1. Create a certificate keystore by executing the following command:

    Windows:

    %JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA

    Unix:

    $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
    and specify a password value of "changeit". the keystore file is named as .keystore located in the user's home directory.

  2. Uncomment the "SSL HTTP/1.1 Connector" entry in $CATALINA_BASE/conf/server.xml and tweak as necessary
  3. ---------------------------------------------------------------------------------- maxThreads="150" scheme="https" secure="true"
    clientAuth="false" sslProtocol="TLS" />

How to solve javax.net.ssl.SSLHandshakeException?

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:441)
at javax.mail.Service.connect(Service.java:233)
at javax.mail.Service.connect(Service.java:134)

--------------------------------------------------------
The problem is that our webapp is now acting as a SSL client, and as a client, it needs to obtain and 'trust' the server's public key.
-----------------------------------------------------

The fix

Obtain the server's public key.

To quote Microsoft; "consult your system administrator". The public/private key pair will live somewhere on the server. The public key should be located and copied to the server hosting JIRA/Confluence. For example:

scp root@mail.yourcompany.com:/etc/ssl/certs/imapd.pem .

If you have openssl installed locally, the key can be retrieved with a command like:

jturner@teacup:~$ openssl s_client -connect imap.atlassian.com:imaps
CONNECTED(00000003)
depth=0 /C=AU/ST=NSW/L=Sydney/O=Atlassian/CN=imap.atlassian.com/emailAddress=info@atlassian.com
.....
.....
Server certificate
-----BEGIN CERTIFICATE-----
MIICiTCCAfKgAwIBAgIBADANBgkqhkiG9w0BAQQFADB/MQswCQYDVQQGEwJBVTEM
MAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxEjAQBgNVBAoTCUF0bGFzc2lh
bjEaMBgGA1UEAxMRY3ZzLmF0bGFzc2lhbi5jb20xITAfBgkqhkiG9w0BCQEWEmlu
Zm9AYXRsYXNzaWFuLmNvbTAeFw0wNTA5MjMwNjUyNTNaFw0wNjA5MjMwNjUyNTNa
MH8xCzAJBgNVBAYTAkFVMQwwCgYDVQQIEwNOU1cxDzANBgNVBAcTBlN5ZG5leTES
MBAGA1UEChMJQXRsYXNzaWFuMRowGAYDVQQDExFjdnMuYXRsYXNzaWFuLmNvbTEh
MB8GCSqGSIb3DQEJARYSaW5mb0BhdGxhc3NpYW4uY29tMIGfMA0GCSqGSIb3DQEB
AQUAA4GNADCBiQKBgQDhwAgx/gDgKe9tBjUCj7JtVkwQSzj2Dq0PHiJu1AWUYWFW
ivbBWaWSYbt/w9vIRSL8OlGVOLnlFOH5o7QIpIBZvd3xBMv6DxMijM86/hu8QTPt
KcMuqBTGpu1T846SzNncj883wSE1hXxezCgEFCsqyC7dVX4l0Ay6zgzkt2wc3QID
AQABoxUwEzARBglghkgBhvhCAQEEBAMCBkAwDQYJKoZIhvcNAQEEBQADgYEAJOgg
O4brCcQa3IgONo8UmLcHo6Rq+Py6ZA3ueUegy/uyQ358JUeL4kktXuYL9gAPCuMc
hsC1iyaOrWY/S9S67w2ZWqc+uYX9ophFHkxK1r3YiaiMpEzMyB12VWSrOITcR0LV
7NTWfxfPLUpkDbj+Mw/66QJkI0lqBvcKn3KXI74=
-----END CERTIFICATE-----

Cut and paste the certificate (including BEGIN and END lines) into a local file (eg. imapd.pem).

Import the public key.

To do this, you need to use the keytool program that comes with Java. If you haven't already, add $JAVA_HOME/bin to your PATH, and then run the following:

jturner@teacup:~$ sudo keytool -import -alias mail.yourcompany.com -keystore $JAVA_HOME/jre/lib/security/cacerts -file imapd.pem
Enter keystore password: changeit
Owner: EMAILADDRESS=info@atlassian.com, CN=atlassian.com, O=Atlassian, L=Sydney, ST=NSW, C=AU
Issuer: EMAILADDRESS=info@atlassian.com, CN=atlassian.com, O=Atlassian, L=Sydney, ST=NSW, C=AU
Serial number: 0
Valid from: Fri Feb 11 14:09:05 EST 2005 until: Sat Feb 11 14:09:05 EST 2006
Certificate fingerprints:
MD5: CB:AE:7D:5D:1A:08:06:77:93:3B:0F:53:BB:40:C0:D4
SHA1: 7C:02:44:0D:A9:8F:F9:FB:BB:7B:C6:F1:52:DE:CA:00:17:D9:3A:A0
Trust this certificate? [no]: yes
Certificate was added to keystore

This will import the public key (imapd.pem) into Java's default keystore, and marks it as trusted.

On Windows the command is similar, eg.:

C:\Program Files\Java\jre1.6.0_05>bin\keytool -import -file c:\certs\imapd.pem -alias mail.yourcompany.com -keystore lib\security\cacerts
Enter keystore password:
Owner: CN=*.atlassian.com, OU=IT, O=ATLASSIAN SOFTWARE SYSTEMS PROPRIETARY LIMITED, L=Sydney, ST=NSW, C=au
Issuer: CN=DigiCert Global CA, OU=www.digicert.com, O=DigiCert Inc, C=US
Serial number: a2d7047dc5d47ba988c9685e1efb860
Valid from: Thu Jan 10 11:00:00 EST 2008 until: Fri Jan 14 10:59:59 EST 2011
Certificate fingerprints:
MD5: 9D:B4:9F:3D:0A:DE:6A:BD:BC:3D:95:BE:60:BD:70:02
SHA1: 67:C6:E9:C8:3F:F1:7A:3C:66:E2:CE:62:78:A1:66:84:35:5E:62:1E
Signature algorithm name: SHA1withRSA
Version: 3
.....

Trust this certificate? [no]: yes
Certificate was added to keystore

C:\Program Files\Java\jre1.6.0_05>

Restart the app server

How to solve the https SSL client authentication ava.security.cert.CertificateException: No name matching problem

javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://localhost:8443/WSRM/WsrmServerService?wsdl. It failed with:
java.security.cert.CertificateException: No name matching localhost found.
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:162)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:144)
at com.sun.xml.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:264)
at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:227)
at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:175)
at com.sun.xml.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:104)
at javax.xml.ws.Service.(Service.java:56)
--------------------------------------------------------

Transport Security (SSL) Workaround

This note applies to cases where https is the transport protocol used between a WSIT client and a secure web service using transport binding, and you are referencing localhost when creating the client.


Note: If you use the fully-qualified hostname (FQHN) in the URL for the service WSDL when you are adding the web service client to the client application, this workaround is not required. It is only required when you specify localhost in the URL for the service WSDL.


During development (not production) it is sometimes convenient to use certificates whose CN (Common Name) does not match the host name in the URL.

A developer would want to use a CN which is different from the host name in the URL in WSIT when using https addresses in Dispatch clients and during wsimport. The below mentioned workaround is only for the Dispatch clients, which are also used in WS-Trust to communicate with STS. This has to be done even if the client's main service is not on https, but only the STS is on https.

Java by default verifies that the certificate CN (Common Name) is the same as host name in the URL. If the CN in the certificate is not the same as the host name, your web service client fails with the following exception:

javax.xml.ws.WebServiceException: java.io.IOException: HTTPS
hostname wrong: should be

The recommended way to overcome this issue is to generate the server certificate with the Common Name (CN) matching the host name.

To workaround this only during development, in your client code, you can set the default host name verifier to a custom host name verifier which does a custom check. An example is given below. It is sometimes necessary to include this in the static block of your main Java class as shown below to set this verifier before any connections are made to the server.

static {
//WORKAROUND. TO BE REMOVED.


javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){

public boolean verify(String |hostname|,
javax.net.ssl.SSLSession sslSession) {
if (hostname.equals("mytargethostname")) {
return true;
}
return false;
}
});
}

Monday, December 8, 2008

How to change the JVM used by netbeans

In the $NETNEANS_HOME/etc directory, edit the netbeans.conf file, put
repoint the netbeans_jdkhome="/usr/local/JDK/jdk" to your new JDK directory. (e.g. new 1.6 JAVA_HOME)

wsdl file WEB-INF/wsdl/wscoor.wsdl does not exist for webservice Cordinator

Need to use JDK 1.6, it arises from jar conflict. Using JDK 1.6 will resolve this.

Where is javax.xml.ws.Holder class?

the javax.xml.ws.Holer class is in lib/common/endorsed/webservices-api.jar