Search this blog ...

Tuesday, July 17, 2012

File Download Java Servlet example - 2GB overflow workaround

I discovered a few days back an issue with our product on HTTP downloads > 2GB.  It appears to be a simple overflow on the HttpServletResponse.setContentLength method. You can probably excuse the API designers circa 1997 assuming a 32-bit signed Integer with max value 231-1 (2147483647 bytes) would be sufficient.  The Gigabit ethernet standard did not come for another year (1998)!

Here is the exception seen when you provide a long value greater than 2147483647 bytes to the setContentLength(int) method:

java.net.ProtocolException: Exceeded stated content-length of: '-XXXX' bytes
        at weblogic.servlet.internal.ServletOutputStreamImpl.checkCL(ServletOutputStreamImpl.java:200)

Below is a sample download servlet with workaround for the 2gb limitation.  It has been tested on Firefox 3.6 against WebLogic Server 10.3.6 with a 2.2GB download and worked perfectly.


import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class DownloadServlet
  extends HttpServlet
{
  @SuppressWarnings("compatibility:1533750721037291976")
  private static final long serialVersionUID = 1L;

  protected void doGet(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, IOException
  {
    doPost(request, response);
  }

  protected void doPost(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, IOException
  {
    // if no file parameter specified, download hosts file
    String file = request.getParameter("file");
    file = (file == null || file.length() == 0) ? "/etc/hosts" : file;

    File fileObj = new File(file);
    if ((!fileObj.exists()) || (!fileObj.isFile()) || (!fileObj.canRead()))
    {
      throw new IOException("'file' '" + file + "' cannot be read.");
    }

    ServletContext context = getServletConfig().getServletContext();

    String mimetype = context.getMimeType(file);
    response.setContentType(mimetype == null ? "application/octet-stream" :
        mimetype);

    long length = fileObj.length();
    if (length <= Integer.MAX_VALUE)
    {
      response.setContentLength((int)length);
    }
    else
    {
      response.addHeader("Content-Length", Long.toString(length));
    }

    response.setHeader("Content-Disposition",
        "attachment; filename=\"" + fileObj.getName() + "\"");

    ServletOutputStream out = response.getOutputStream();
    InputStream in = null;
    byte[] buffer = new byte[32768];
    try
    {
      in = new FileInputStream(fileObj);

      int bytesRead;
      while ((bytesRead = in.read(buffer)) >= 0)
      {
        out.write(buffer, 0, bytesRead);
      }
    }
    finally
    {
      if (in != null)
      {
        in.close();
      }
    }
  }
}

Saturday, July 7, 2012

WebLogic HTTPS One-Way SSL Tutorial

One-way SSL is the mode which most "storefronts" run on the internet so as to be able to accept credit card details and the like without the customer’s details being sent effectively in the clear from a packet-capture perspective.  In this mode, the server must present a valid public certificate to the client, but the client is not required to present a certificate to the server.

Two-way SSL is far less common on the internet and is often leveraged for client certificate-based authentication.

In terms of configuring WebLogic Server to support one-way SSL, it is just a matter of setting up an identity keystore containing a valid private key and associated public certificate signed by a certificate authority.  If the client has no knowledge/trust of the certificate authority that signed the server’s public certificate, the client must manually import/accept the CA’s public certificate.

WebLogic in fact ships with two demo keystores for testing purposes containing X509 artifacts, namely DemoIdentity.jks and DemoTrust.jks (both found in $WL_HOME/server/lib). The latter is intended for Two-Way SSL purposes, though is also frequently supplied to java clients that may want to connect to the WebLogic instance due to it containing the CN=CertGenCAB… WebLogic demo CA public certificate that issued the certificate in the DemoIdentity keystore.

keytool -list -v -keystore $WL_HOME/server/lib/DemoIdentity.jks -storepass DemoIdentityKeyStorePassPhrase

Keystore type: JKS
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: demoidentity
Creation date: Jun 30, 2012
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=xxxxxxxxxx, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Issuer: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Serial number: 75e1d5b02ee5b71fd3b1431f483f49f1
Valid from: Fri Jun 29 06:45:36 PDT 2012 until: Wed Jun 30 06:45:36 PDT 2027
Certificate fingerprints:
         MD5:  BB:49:16:85:4E:84:66:09:8A:68:83:A4:A7:06:AB:80
         SHA1: 1F:67:9C:78:C7:64:B4:0B:2F:A7:AA:B2:69:70:9D:47:47:D5:A0:A8
         Signature algorithm name: MD5withRSA
         Version: 1

...

keytool -list -keystore $WL_HOME/server/lib/DemoTrust.jks -storepass DemoTrustKeyStorePassPhrase

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 4 entries

certgenca, Mar 22, 2002, trustedCertEntry,
Certificate fingerprint (MD5): 8E:AB:55:50:A4:BC:06:F3:FE:C6:A9:72:1F:4F:D3:89
wlsdemocanew2, Jan 24, 2003, trustedCertEntry,
Certificate fingerprint (MD5): 5B:10:D5:3C:C8:53:ED:75:43:58:BF:D5:E5:96:1A:CF
wlsdemocanew1, Jan 24, 2003, trustedCertEntry,
Certificate fingerprint (MD5): A1:17:A1:73:9B:70:21:B9:72:85:4D:83:01:69:C8:37
wlscertgencab, Jan 24, 2003, trustedCertEntry,
Certificate fingerprint (MD5): A2:18:4C:E0:1C:AB:82:A7:65:86:86:03:D0:B3:D8:FE

The WebLogic demo CA public certificate that issued the certificate in the DemoIdentity keystore …

keytool -printcert -file $WL_HOME/server/lib/CertGenCA.der

Owner: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Issuer: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Serial number: 234b5559d1fa0f3ff5c82bdfed032a87
Valid from: Thu Oct 24 08:54:45 PDT 2002 until: Tue Oct 25 08:54:45 PDT 2022
Certificate fingerprints:
         MD5:  A2:18:4C:E0:1C:AB:82:A7:65:86:86:03:D0:B3:D8:FE
         SHA1: F8:5D:49:A4:12:54:78:C7:BA:42:A7:14:3E:06:F5:1E:A0:D4:C6:59
         Signature algorithm name: MD5withRSA
         Version: 3

...

In order to leverage the above keystores, it is just a matter of connecting to the Administration Console, then expand Environment and select Servers.
Choose the server for which you want to configure the identity and trust keystores, and select Configuration > Keystores. 
You would then fill in the relevant fields (keystore fully qualified path, type (JKS), and keystore access password). e.g.

Identity store location: /u01/app/oracle/product/Middleware/wlserver_10.3/server/lib/DemoIdentity.jks
Identity store type: JKS
Identity store password: DemoIdentityKeyStorePassPhrase

Trust store location: /u01/app/oracle/product/Middleware/wlserver_10.3/server/lib/DemoTrust.jks
Trust store type: JKS
Trust store password: DemoTrustKeyStorePassPhrase

Next, you need to enable the SSL Listen Port for the server:

Home >Summary of Servers >XXX > General
SSL Listen Port: Enabled (Check)
SSL Listen Port: XXXX

Finally, you need to tell WebLogic the alias and password in order to access the private key from the Identity Store:

Home >Summary of Servers >XXX > SSL
Identity and Trust Locations: Keystores
Private Key Alias: demoidentity
Private Key Passphrase: DemoIdentityPassPhrase

Note - you are likely to find that the Demo Identity and Demo Trust keystores are preconfigured out of the box!


For production setups, you should be generating your own key of required strength, and get the associated public certificate signed by a “real” certificate authority.  A “real” certificate authority could be hosted locally given a private client base, or it could be one of the main internet players (verisign and co) if the instance was to be accessed by the general public.

The steps below are a hybrid approach that leverage production techniques, but using the demo WebLogic certificate authority and openssl to perform the signing.

First, lets create our identity keystore along with a new keypair ...

KEYSTORE_FILE=$WL_HOME/server/lib/identity.jks
KEYSTORE_PASSWORD=welcome1
KEY_ALIAS=identity
KEY_PASSWORD=welcome1

keytool -genkeypair -v -keystore "$KEYSTORE_FILE" -storepass "$KEYSTORE_PASSWORD" -keyalg RSA -keysize 1024 -validity 365 -keypass "$KEY_PASSWORD" -alias "$KEY_ALIAS" -dname "CN=`hostname -f`"

Generating 1,024 bit RSA key pair and self-signed certificate (SHA1withRSA) with a validity of 365 days
        for: CN=xxxxxxxxxx.xx.xxxxxx.com
[Storing /u01/app/oracle/product/Middleware/wlserver_10.3/server/lib/identity.jks]

The above certificate is currently self-signed (such that, issuer = subject , private key signed its associated public certificate)

For a production server we want to get our public certificate signed by a valid certificate authority (CA).
As we are just testing, we will use the WebLogic demo CA instead.

We first need to get a certificate signing request ready ...

KEYSTORE_FILE=$WL_HOME/server/lib/identity.jks
KEYSTORE_PASSWORD=welcome1
KEY_ALIAS=identity
SIGNING_REQ_FILE="$WL_HOME/server/lib/identity_cert_signing_request.pem"

keytool -certreq -v -keystore "$KEYSTORE_FILE" -storepass "$KEYSTORE_PASSWORD" -alias "$KEY_ALIAS" -file "$SIGNING_REQ_FILE"

Certification request stored in file </u01/app/oracle/product/Middleware/wlserver_10.3/server/lib/identity_cert_signing_request.pem>
Submit this to your CA

cat "$SIGNING_REQ_FILE"

-----BEGIN NEW CERTIFICATE REQUEST-----
MIIBYjCBzAIBADAjMSEwHwYDVQQDExhhZGMyMTAwODY2LnVzLm9yYWNsZS5jb20wgZ8wDQYJKoZI
hvcNAQEBBQADgY0AMIGJAoGBAIOiOavPqXv3JDjYCsHyTmfprmSACDpF5dpozI2i2U8YVJaDYHtK
PYPdKu+KG7hpmxHlI6nHF2aqTid0sYqZjQDeYj16dHyLR6kh0SnAj3fA+I7ev9SFffyQ4cdpHwfV
1jfEkyPwNSQxz5X4UiRyd3bwCXI4rEPSjRUVpjPC8Q9LAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
gQAcieNA+waTBjDHRIrxDw+hSwjiB5OYaA6+smiEO8WYwNQkJifsr9OEc7SKeHmM2pAKGDUl9bKO
GHkv9FEKShNbAFXIRl0mItTwhIAkmqxKxZBv7HKmdM+lah5jpOQWmH1W4NRPbbGs/bdgYXHwEeYs
yCuaZsp90G73MxlPMgebFw==
-----END NEW CERTIFICATE REQUEST-----

Now we need to get the certificate signed.  As mentioned previously, we will use the WebLogic demo CA along with the openssl tool to generate the signed certificate.

We first need to convert the WebLogic demo CA private key from DER to PEM format in order to use the openssl tool.
The private key as shown below is encrypted ....

openssl asn1parse -inform DER -in CertGenCAKey.der

    0:d=0  hl=4 l= 384 cons: SEQUENCE         
    4:d=1  hl=2 l=  26 cons: SEQUENCE         
    6:d=2  hl=2 l=   9 prim: OBJECT            :pbeWithMD5AndDES-CBC
   17:d=2  hl=2 l=  13 cons: SEQUENCE         
   19:d=3  hl=2 l=   8 prim: OCTET STRING      [HEX DUMP]:0011223344556677
   29:d=3  hl=2 l=   1 prim: INTEGER           :05
   32:d=1  hl=4 l= 352 prim: OCTET STRING      [HEX

DUMP]:2A89DCA6697D9F...

16

The private key is protected by password based encryption - employing DES secret-key encryption in cipher-block chaining mode, where the secret key is derived from a password with the MD5 message-digest algorithm.

The password used for encryption of this key is "password"

Let's convert the key from DER format to PEM format supplying the encryption password …

CA_KEY_DER="$WL_HOME/server/lib/CertGenCAKey.der"
CA_KEY_PEM="$WL_HOME/server/lib/CertGenCAKey.pem"

openssl pkcs8 -inform DER -in "$CA_KEY_DER" -passin pass:password -outform PEM -out "$CA_KEY_PEM"

cat "$CA_KEY_PEM"

-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBAK+kgUpzTgIJnC8rktjUQsYUy3X9JJP8OZokh0Pm2KH3bOK49CNI
/EmCFs1v2Gy2sOfWVP2HPY7uTEI1Yli3slsCAwEAAQJAM8oRxV4SVk93GgGDHyQX
PEjNZVDrBCeO5IB40fCzV64b33n7nCnrnemS8eJwvOs6+4dN4CpogCWKrMKkdRdS
gQIhAN56PT3B7/jS2D6HVgXATF+ThJ2HkbL7CDMPVkJE00sLAiEAyhussDRxqESf
w+EibP34Effs6LJP73BeI43yIgq6R/ECIF75HfWkOdYl5AxlZ9KSscfHSMCa5Bbc
1TY+4NrvWKfbAiEAmnpEp/mt1dt98g4mbgBAmBtT7Rg9mNneWnaoV/SzJUECICjQ
Lsm4mCSPorIOlGsk2TQPH0MzJsk4TziNnsB08jBO
-----END RSA PRIVATE KEY-----


We also need the CA’s public certificate in PEM format …

CA_CERT_DER="$WL_HOME/server/lib/CertGenCA.der"
CA_CERT_PEM="$WL_HOME/server/lib/CertGenCA.pem"

openssl x509 -inform DER -in "$CA_CERT_DER" -outform PEM -out "$CA_CERT_PEM"

cat "$CA_CERT_PEM"

-----BEGIN CERTIFICATE-----
MIICGDCCAcKgAwIBAgIQI0tVWdH6Dz/1yCvf7QMqhzANBgkqhkiG9w0BAQQFADB5
MQswCQYDVQQGEwJVUzEQMA4GA1UECBMHTXlTdGF0ZTEPMA0GA1UEBxMGTXlUb3du
MRcwFQYDVQQKEw5NeU9yZ2FuaXphdGlvbjEZMBcGA1UECxMQRk9SIFRFU1RJTkcg
T05MWTETMBEGA1UEAxMKQ2VydEdlbkNBQjAeFw0wMjEwMjQxNTU0NDVaFw0yMjEw
MjUxNTU0NDVaMHkxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdNeVN0YXRlMQ8wDQYD
VQQHEwZNeVRvd24xFzAVBgNVBAoTDk15T3JnYW5pemF0aW9uMRkwFwYDVQQLExBG
T1IgVEVTVElORyBPTkxZMRMwEQYDVQQDEwpDZXJ0R2VuQ0FCMFwwDQYJKoZIhvcN
AQEBBQADSwAwSAJBAK+kgUpzTgIJnC8rktjUQsYUy3X9JJP8OZokh0Pm2KH3bOK4
9CNI/EmCFs1v2Gy2sOfWVP2HPY7uTEI1Yli3slsCAwEAAaMmMCQwDgYDVR0PAQH/
BAQDAgIEMBIGA1UdEwEB/wQIMAYBAf8CAQEwDQYJKoZIhvcNAQEEBQADQQBCOCsQ
9QWvGvAikjBBOjrTFqZBNJYJsv5+mVZ90pVwmzEDihw8dbI3ubMYz5saXkKSy3rc
SvJK9nZJkHvb88hZ
-----END CERTIFICATE-----

Once we have our CA key and certificate in PEM format, lets do the certificate signing ...

CA_KEY_PEM="$WL_HOME/server/lib/CertGenCAKey.pem"
CA_CERT_PEM="$WL_HOME/server/lib/CertGenCA.pem"
CA_SERIAL_FILE="$WL_HOME/server/lib/CA.srl"
SIGNING_REQ_FILE="$WL_HOME/server/lib/identity_cert_signing_request.pem"
SIGNED_CERT="$WL_HOME/server/lib/identity_cert_signed.pem"

openssl x509 -req -days 365 -in "$SIGNING_REQ_FILE" -inform PEM -CA "$CA_CERT_PEM" -CAkey "$CA_KEY_PEM" -out "$SIGNED_CERT" -outform PEM -CAcreateserial -CAserial "$CA_SERIAL_FILE"

Signature ok
subject=/CN=xxxxxxxxxx.xx.xxxxxx.com
Getting CA Private Key

keytool -printcert -file "$SIGNED_CERT"

Owner: CN=xxxxxxxxxx.xx.xxxxxx.com
Issuer: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Serial number: d80dbb0b65dcc3b8
Valid from: Fri Jul 06 20:41:08 PDT 2012 until: Sat Jul 06 20:41:08 PDT 2013
Certificate fingerprints:
         MD5:  2E:2A:00:AD:A9:38:E9:FA:B7:C6:A8:85:33:74:72:B3
         SHA1: 27:0D:9C:A9:39:37:92:E3:68:A2:61:E8:65:D3:3F:B9:D1:86:A8:E2
         Signature algorithm name: SHA1withRSA
         Version: 1

As can be seen above, the issuer and owner are now different.  The certificate is no longer self-signed, but rather signed by our CA.
Now we are ready to imported the signed public certificate back in to our identity keystore ...

KEYSTORE_FILE=$WL_HOME/server/lib/identity.jks
KEYSTORE_PASSWORD=welcome1
KEY_ALIAS=identity
SIGNED_CERT="$WL_HOME/server/lib/identity_cert_signed.pem"

keytool -import -v -keystore "$KEYSTORE_FILE" -storepass "$KEYSTORE_PASSWORD" -alias "$KEY_ALIAS" -file "$SIGNED_CERT"

You should see the following error when you perform the above command:

keytool error: java.lang.Exception: Failed to establish chain from reply

keytool prevents us from importing a certificate should it not be able to verify the full signing chain. As we leveraged the WebLogic demo CA, we need to import the CA's public certificate in to our keystore as a trusted certificate authority prior to importing our signed certificate.

KEYSTORE_FILE=$WL_HOME/server/lib/identity.jks
KEYSTORE_PASSWORD=welcome1
CA_ALIAS=wlsdemoca
CA_CERT_PEM="$WL_HOME/server/lib/CertGenCA.pem"

keytool -import -v -keystore "$KEYSTORE_FILE" -storepass "$KEYSTORE_PASSWORD" -trustcacerts -alias "$CA_ALIAS" -file "$CA_CERT_PEM"

Owner: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Issuer: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Serial number: 234b5559d1fa0f3ff5c82bdfed032a87
Valid from: Thu Oct 24 08:54:45 PDT 2002 until: Tue Oct 25 08:54:45 PDT 2022
Certificate fingerprints:
         MD5:  A2:18:4C:E0:1C:AB:82:A7:65:86:86:03:D0:B3:D8:FE
         SHA1: F8:5D:49:A4:12:54:78:C7:BA:42:A7:14:3E:06:F5:1E:A0:D4:C6:59
         Signature algorithm name: MD5withRSA
         Version: 3

...

Trust this certificate? [no]:  y
Certificate was added to keystore
[Storing /u01/app/oracle/product/Middleware/wlserver_10.3/server/lib/identity.jks]

Add the "-noprompt" option to prevent the “Trust this certificate” prompt.

Now lets retry our request to import the signed certificate ...

KEYSTORE_FILE=$WL_HOME/server/lib/identity.jks
KEYSTORE_PASSWORD=welcome1
KEY_ALIAS=identity
SIGNED_CERT="$WL_HOME/server/lib/identity_cert_signed.pem"

keytool -import -v -keystore "$KEYSTORE_FILE" -storepass "$KEYSTORE_PASSWORD" -alias "$KEY_ALIAS" -file "$SIGNED_CERT" -noprompt

Certificate reply was installed in keystore
[Storing /u01/app/oracle/product/Middleware/wlserver_10.3/server/lib/identity.jks]

Let's verify the keystore contents ...

KEYSTORE_FILE=$WL_HOME/server/lib/identity.jks
KEYSTORE_PASSWORD=welcome1

keytool -list -v -keystore "$KEYSTORE_FILE" -storepass "$KEYSTORE_PASSWORD"

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

Alias name: identity
Creation date: Jul 6, 2012
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=xxxxxxxxxx.xx.xxxxxx.com
Issuer: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Serial number: d80dbb0b65dcc3b8
Valid from: Fri Jul 06 20:41:08 PDT 2012 until: Sat Jul 06 20:41:08 PDT 2013
Certificate fingerprints:
         MD5:  2E:2A:00:AD:A9:38:E9:FA:B7:C6:A8:85:33:74:72:B3
         SHA1: 27:0D:9C:A9:39:37:92:E3:68:A2:61:E8:65:D3:3F:B9:D1:86:A8:E2
         Signature algorithm name: SHA1withRSA
         Version: 1
Certificate[2]:
Owner: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Issuer: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Serial number: 234b5559d1fa0f3ff5c82bdfed032a87
Valid from: Thu Oct 24 08:54:45 PDT 2002 until: Tue Oct 25 08:54:45 PDT 2022
Certificate fingerprints:
         MD5:  A2:18:4C:E0:1C:AB:82:A7:65:86:86:03:D0:B3:D8:FE
         SHA1: F8:5D:49:A4:12:54:78:C7:BA:42:A7:14:3E:06:F5:1E:A0:D4:C6:59
         Signature algorithm name: MD5withRSA
         Version: 3

...

*******************************************
*******************************************

Alias name: wlsdemoca
Creation date: Jul 6, 2012
Entry type: trustedCertEntry

Owner: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Issuer: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Serial number: 234b5559d1fa0f3ff5c82bdfed032a87
Valid from: Thu Oct 24 08:54:45 PDT 2002 until: Tue Oct 25 08:54:45 PDT 2022
Certificate fingerprints:
         MD5:  A2:18:4C:E0:1C:AB:82:A7:65:86:86:03:D0:B3:D8:FE
         SHA1: F8:5D:49:A4:12:54:78:C7:BA:42:A7:14:3E:06:F5:1E:A0:D4:C6:59
         Signature algorithm name: MD5withRSA
         Version: 3

...

Next we go to the Administration Console and ensure for our Server that:

  1. “Custom Identity and Java Standard Trust” keystore configuration option is chosen
  2. The custom identity keystore path, type, and password is correctly set
  3. Java standard trust store password is set (“changeit”)
  4. The private key alias and password is set
  5. The SSL listen port is set

Identity store location: /u01/app/oracle/product/Middleware/wlserver_10.3/server/lib/identity.jks
Identity store type: JKS
Identity store password: welcome1

Identity and Trust Locations: Keystores
Private Key Alias: identity
Private Key Passphrase: welcome1

As far as the trust keystore is concerned (and given we are leveraging one-way SSL), we just set the instance to utilize the standard trust keystore supplied with the JDK ($JAVA_HOME/jre/lib/security/cacerts   - password “changeit”).


Clients that will be connecting to our SSL protected server will likely have to import our CA’s public certificate in to their local trust keystore (cacerts etc) given that we are using a demo CA with a certificate chain unlikely to be known/resolvable.

Failure to do this from a Java client will likely lead to an exception such as:

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

As an alternative to using the JDK’s standard trust keystore, another option is create a separate keystore with just the CA’s public certificate chain.  You then provide explicit SSL trust store system properties on the java command line:

KEYSTORE_FILE=$WL_HOME/server/lib/trust.jks
KEYSTORE_PASSWORD=welcome1
CA_ALIAS=wlsdemoca
CA_CERT_PEM="$WL_HOME/server/lib/CertGenCA.pem"

keytool -import -v -keystore "$KEYSTORE_FILE" -storepass "$KEYSTORE_PASSWORD" -trustcacerts -alias "$CA_ALIAS" -file "$CA_CERT_PEM" -noprompt

Certificate was added to keystore
[Storing /u01/app/oracle/product/Middleware/wlserver_10.3/server/lib/trust.jks]

Let's verify the keystore contents ...

KEYSTORE_FILE=$WL_HOME/server/lib/trust.jks
KEYSTORE_PASSWORD=welcome1
keytool -list -v -keystore "$KEYSTORE_FILE" -storepass "$KEYSTORE_PASSWORD"

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: wlsdemoca
Creation date: Jul 9, 2012
Entry type: trustedCertEntry

Owner: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Issuer: CN=CertGenCAB, OU=FOR TESTING ONLY, O=MyOrganization, L=MyTown, ST=MyState, C=US
Serial number: 234b5559d1fa0f3ff5c82bdfed032a87
Valid from: Thu Oct 24 08:54:45 PDT 2002 until: Tue Oct 25 08:54:45 PDT 2022
Certificate fingerprints:
         MD5:  A2:18:4C:E0:1C:AB:82:A7:65:86:86:03:D0:B3:D8:FE
         SHA1: F8:5D:49:A4:12:54:78:C7:BA:42:A7:14:3E:06:F5:1E:A0:D4:C6:59
         Signature algorithm name: MD5withRSA
         Version: 3

...

Invoke Java with explicit SSL trust store elements set ...

SSL_TRUST_STORE="-Djavax.net.ssl.trustStore=$WL_HOME/server/lib/trust.jks"
SSL_TRUST_PASSWORD="-Djavax.net.ssl.trustStorePassword=welcome1"

$JAVA_HOME/bin/java "${SSL_TRUST_STORE}" "${SSL_TRUST_PASSWORD}" -cp ... XXX