Thursday, April 30, 2015

add company self-signed rootca certificate to JBoss default truststore (JRE's rootca)

Java SE 7 certificate keystore

trusted keystore (hosting trusted certificates) are located in file cacerts in folders

  • C:\Program Files\Java\jdk1.7.0_75\jre\lib\security
  • C:\Program Files\Java\jre7\lib\security



Java Control Panel, which is used to control how Java and JavaFX applications that are embedded in a browser or are launched from a browser run on your computer.

In Windows 7, user level keystores managed by JCP are located in C:\Users\XYZ\AppData\LocalLow\Sun\Java\Deployment\security and has no password.


C:\Users\XYZ\AppData\LocalLow\Sun\Java\Deployment\security>dir
 Volume in drive C has no label.
 Volume Serial Number is 48D8-D804

 Directory of C:\Users\XYZ\AppData\LocalLow\Sun\Java\Deployment\security

04/13/2015  12:31 PM    <DIR>          .
04/13/2015  12:31 PM    <DIR>          ..
01/20/2015  02:12 PM                44 baseline.versions
08/09/2013  11:10 AM             2,837 blacklist.dynamic
03/12/2013  09:39 AM                18 blacklisted.certs
04/13/2015  12:12 PM                47 exception.sites
04/13/2015  12:31 PM               905 trusted.cacerts
04/13/2015  12:32 PM             1,908 trusted.certs
04/13/2015  12:30 PM             1,031 trusted.jssecerts
04/30/2015  11:26 AM                 1 update.securitypack.timestamp
04/30/2015  09:39 AM                 1 update.timestamp
               9 File(s)          6,792 bytes
               2 Dir(s)  166,788,972,544 bytes free

Scenario:
  • IE 10 browser
  • Java applet signed by self-signed certificate (dev_cert)
  • Java applet connects to another web resource via https (certificate is issued by self-signed company root ca)


For browser to trust the signed applet, (ie, to trust applet signer's certificate dev_cert), import dev_cert into Signer CA (via Java Control Panel). The certificate will be imported into trusted.cacerts keystore.

Restart browser, hit applet page, we'll see the signer is recognized.



Issue:


Fixed by adding these lines to manifest:
Trusted-Library: true
Caller-Allowable-Codebase: *
Now manifest looks like this:
Manifest-Version: 1.0
Trusted-Library: true
Application-Library-Allowable-Codebase: *
Application-Name: ...
Permissions: all-permissions
Caller-Allowable-Codebase: localhost
Main-Class: ...
Codebase: *


Caller-Allowable-Codebase: localhost
Allow javascript downloaded from localhost to access applet.


When Java SE 7 is installed on a Windows system, it maintains 3 trusted certificate keystore files:
1. System-Level Signer CA Keystore:
Location: "\Program Files\java\jre7\lib\security\cacerts"
Password: "changeit"
Contents: All signer CA certificates known at the time of Java release
2. System-Level Secure Site CA Keystore:
Location: "\Program Files\java\jre7\lib\security\jssecacerts"
Password: "changeit"
Contents: Empty by default.
3. User-Level Certificate Keystore\
Location:
   "\Users\xyz\AppData\LocalLow\sun\Java\Deployment\security\trusted.certs"
Password: ""
Contents: Empty by default

Issue:
Allow access to the following application from this web site?
Fix:
https://www.java.com/en/download/help/javascript_applet.xml



By default, JBossAS 7.1 uses JRE's truststore, my EJB service needs to connect to remote exchange server via https (the exchange server's https certificate is issued by company's self-signed rootca).

To make JBossAS7.1 trust company's self-signed rootca, do
// change to C:\Program Files\Java\jdk1.7.0_75\jre\lib\security
keytool -import -alias company_rootca -file C:\DEVEL\company_rootca.cer.p12 -keystore cacerts -storepass changeit



Resources:
http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/security/manifest.html#permissions

Wednesday, April 29, 2015

config JBossAS 7.1 to use customized truststore

From JBoss AS 7.1, my ejb service needs to send out email to exchange server via Microsoft EWS Java API.

EWS Java API maven dependency as
<dependency>
 <groupId>com.microsoft.ews-java-api</groupId>
 <artifactId>ews-java-api</artifactId>
 <version>2.0-SNAPSHOT</version>
</dependency>

Our exchange server endpoint is exposed via https, whose certificate is self-signed by company's root CA (the root ca is also self-signed).

At runtime, when the EJB trying to connect to exchange server (via https), since JBoss doesn't trust company's root ca, we got error as


...
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
 at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196) [rt.jar:1.7.0_75]
 at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268) [rt.jar:1.7.0_75]
 at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380) [rt.jar:1.7.0_75]
 ... 171 more

To fix this, I need to config JBoss to trust company's root ca, so that also trust the https certificate the root ca signed. Since my dev JBoss has no truststore configured yet, I add following system properties to server's standalone-full.xml file in C:\DEVEL\APPS\jboss-as-7.1.3.Final\standalone\configuration. The updated  standalone-full.xml as


        <extension module="org.jboss.as.webservices"/>
        <extension module="org.jboss.as.weld"/>
    </extensions>

    <system-properties>
        <property name="javax.net.ssl.trustStore" value="c:\\Users\\jwang.tek\\.keystore "/>
        <property name="javax.net.ssl.trustStorePassword" value="dev1234"/>
    </system-properties>


    <management>
        <security-realms>

Note: the system-properties needs to be right after extension tag.

Restart JBoss AS server, connect via cli, I can see the added system properties as


C:\DEVEL\APPS\jboss-as-7.1.3.Final\bin>jboss-cli.bat --connect
[standalone@localhost:9999 /] /system-property=foo:read-resource
{
    "outcome" => "failed",
    "failure-description" => "JBAS014807: Management resource '[(\"system-property\" => \"foo\")]' not found",
    "rolled-back" => true
}
[standalone@localhost:9999 /] /system-property=javax.net.ssl.trustStore:read-resource
{
    "outcome" => "success",
    "result" => {"value" => "c:\\\\Users\\\\jwang.tek\\\\.keystore "}
}
[standalone@localhost:9999 /]

Done. JBoss started fine, hit EJB service and sending email to exchange server works fine.


Use jboss pre-deployed module in maven ejb project


Use jboss pre-deployed module in maven ejb project

Goal

From my EJB maven project, I want to use commons-io and org.jgroups libraries,  both of the jars have already been pre-deployed as modules in JBossAS 7.1.3 runtime.
 I use these jars as provided dependency to avoid packing redundant jars inside ejb project as lib jars.

JBoss AS 7.1.3 already has commons-io and org.jgroups deployed as module

...\jboss-as-7.1.3.Final\modules\org\apache\commons\io\main
commons-io-2.1.jar
...\jboss-as-7.1.3.Final\modules\org\jgroups\main
jgroups-3.0.14.Final.jar

Steps

in ejb project pom.xml, add
// add commons-io and org.jgroups dependency with provided scope (so the jar won't be deployed alone with project archive as lib jars). This also makes the Eclipse IDE happy
...

<dependency>
 <groupId>commons-io</groupId>
 <artifactId>commons-io</artifactId>
 <version>2.1</version>
 <scope>provided</scope>
</dependency>

<dependency>
 <groupId>org.jgroups</groupId>
 <artifactId>jgroups</artifactId>
 <version>3.0.14.Final</version>
 <scope>provided</scope>
</dependency>
...
// once packaged, the ejb jar won't have  commons-io and org.jgroups in its lib directory. For server deployment, we then need to config project packaging plugin to add dependency to manifestEntries in ejb's MANIFEST.MF to use commons-io and org.jgroups as jboss pre-deployed module. Update ejb maven plugin to add dependency to manifestEntries as below
...

<plugin>
 <artifactId>maven-ejb-plugin</artifactId>
 <version>${version.ejb.plugin}</version>
 <configuration>
  <!-- Tell Maven we are using EJB 3.1 -->
  <ejbVersion>3.1</ejbVersion>
  <archive>
     <manifestEntries>
     <Dependencies>org.apache.commons.io, org.jgroups</Dependencies>
     </manifestEntries>  
  </archive>                    
 </configuration>
</plugin>
...

The generated MANIFEST.MF will have line as

Dependencies: org.apache.commons.io, org.jgroups

done. build project and deploy to JBoss.

Monday, April 13, 2015

Self-signed Certificate & Java Security Warning & Browser

dev setup:


  • html page XYZ hosting Java Applet ABC
  • Java Applet ABC signed by mykey
  • mykey - self-issued pivate key

security warning - untrusted applet signer


When loading html page, we got security warning as below:

Reason:  The applet is signed using self-issued key (for dev only)


To resolve:
Export signer pubkey certificate (its private key is used to sign applet ABC)
C:\> keytool -export -keystore c:\Users\*****\.keystore -alias mykey -file C:\Users\*****\workspace\POC\jwangdev.cer.p12
Enter keystore password: dev1234

Import singer certificate into “Signer CA” via Java Control Panel.
Java Control Panel -> Security -> Manage Cerficates… -> choose “Signer CA” -> import C:\Users\*****\workspace\POC\jwangdev.cer.p12


restart browser. done.

applet security warning - untrusted https certificate issuer

reason:
From the signed applet ABC, we have https connection to https://localhost:8443 (a dev jboss server with default self-signed https certificate for "localhost"). When applet tries to make such https connection, we have security warning window as below: 

To suppress the above warning window:

Add “C:\Users\*****\workspace\POC\ dev_jboss_cert.cer.p12” certificate to “Secure Site” via Java Control Panel. 

restart browser. done.