Jboss 7 class loading for JCE provider bouncy castle

I was helping somebody on encrypting the database connection from a Jboss 7 web application.

the recommended JCE provider is bouncy castle, however, this jboss7 class loading issue should apply to any other JCE provider jar as well.

the exception is

JZ0LA: Failed to instantiate Cipher object. Transformation RSA/NONE/
OAEPWithSHA1
AndMGF1Padding is not implemented by any of the loaded JCE providers.

when using spring jdbc connection or anything alike, for example

	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close" p:driverClassName="com.sybase.jdbc3.jdbc.SybDriver"
		p:url="${db.url}" p:username="${db.username}"
		p:password="${db.password}" />

the db.url, would be alike

jdbc:sybase:Tds:server:4100/datavase?ENCRYPT_PASSWORD=true&JCE_PROVIDER_CLASS=org.bouncycastle.jce.provider.BouncyCastleProvider 

Above exception basically says, the boucy castle jar is not on classpath.

The jar, is however, already put into
application.war
—–WEB-INF
–lib
–bcprov-jdk1.6-1.4.6.jar

above settings would work in Jboss 5. However, it would fail in Jboss 7. The reason being, while Jboss 5 using hierarchy class loading, I guess it starts from the WAS class loader first, which successfully load the bouncy castle.
However, Jboss 7 is using module class loading now, other than implicity dependecies like rt.jar, javax.security etc, other dependecies, as you define it in jboss-deployment-structure.xml, else you cannot access it.

And for jboss 7, the JCE_provider attribute was passed to Jdbc3.SybDriver, however, was being called/looked for by Jboss class loader, not the war class loader.

The resolution to resolve above is, either put bc.jar as a module, as physically pointed to as a resource.
Solution 1.


<module xmlns="urn:jboss:module:1.1" name="org.bouncycastle">

    <resources>
		<resource-root path="bcprov-jdk16-1.46.jar"/>
        <!-- Insert resources here -->
    </resources>
	
	<dependencies>
    	<module name="javax.api" slot="main" export="true"/>
	</dependencies>
		

</module>
		<dependencies>
			<module name="org.osgi.core" />
			<module name="com.sun.crypto.provider" slot="main" export="true"/>  
			<module name="org.bouncycastle" slot="main" export="true"/>  
		</dependencies>
	</deployment>
</jboss-deployment-structure>

Solution 2. Not use-physical-code-source=”true” is compulsory.

 		<resources>
 			<resource-root path="WEB-INF/lib/bcprov-jdk16-1.46.jar" use-physical-code-source="true"/>
 		</resources>
	</deployment>
</jboss-deployment-structure>

Refer to https://community.jboss.org/thread/175395

https://docs.jboss.org/author/display/AS7/Class+Loading+in+AS7

FTP directories listing for local and domain acocunts

Just spotted, when accessing FTP using local and domain accounts, would result in different directories listing. For example:
sftp user@server would list differently than, sftp ‘domain\user@server’.

Good explanation here:

Account Type 	Advantages 	Disadvantages
Domain User Accounts

(Used with FTP's Basic Authentication) 	Domain accounts allow for easier access and auditing for domain resources, like content on UNC shares. 	Domain accounts obviously have more access to your network's resources.

For example, if the accounts are part of the local "Domain Users" group, they have access to everything that the group has access to.
Local User Accounts

(Used with FTP's Basic Authentication) 	Local accounts are generally better than domain accounts when you are trying to limit access to your domain, and you can still audit their activity using Windows auditing. 	Local user accounts may still have access to local system resources.

For example, if the accounts are part of the local "Users" group, they have access to everything that the group has access to.

Refer to http://blogs.msdn.com/b/robert_mcmurray/archive/2010/03/05/using-ftp-with-different-account-types.aspx

HTTPS secure for JBoss web application

Quick steps
1. generate key store file:

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

if the keystore generated is certified by CA (external/internal), browser display warning: the certificate is not signed by trusted CA.
if the keystore was generated by another domain/server, browser would warn: the certificate was for another domain

2. put the keystore file into jboss\server\default\conf

3. enable SSL connection part in server.xml, and refer to the keystore

      <!-- SSL/TLS Connector configuration using the admin devl guide keystore -->
      <Connector port="18443" address="${jboss.bind.address}"
           maxThreads="100" strategy="ms" maxHttpHeaderSize="8192"
           emptySessionPath="true"
           scheme="https" secure="true" clientAuth="false" 
           keystoreFile="${jboss.server.home.dir}/conf/sydneyweb.keystore"
           keystorePass="password" sslProtocol = "TLS" />

refer to: http://docs.jboss.org/jbossweb/latest/ssl-howto.html

http://docs.jboss.org/jbossas/guides/webguide/r2/en/html/ch9.https.sect.html

http://en.wikipedia.org/wiki/HTTP_Secure#Network_layers

Database Encyrption using JCE provider

I was pulled to help others to solve issues for database encryption projects. One project is Jaguar manager plug in for Sybase Central, the other is a JBoss 7 web application built by myself.

I will write the problem and solution for the jboss 7 application in another post.

Background:

the database server would force connections using encrypted strings. For Sydbase JDBC driver, there are two properties to set
1. encrypt_password = true
2. JCE_provider = (eg.org.bouncycastle.jce.provider.BouncyCastleProvider)

refer to http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc20155.1500/html/newfesd/newfesd95.htm

general instructions on how to use JCE library, http://www.jasypt.org/non-default-providers.html
1. put the library on $JRE_HOME/lib/ext
2. enable the provider in java.security file

however, for Sybase central v3, based on JDK 1.4, it keeps throws below exception:

JZ0LA: Failed to instantiate Cipher object. Transformation RSA/NONE/
OAEPWithSHA1
AndMGF1Padding is not implemented by any of the loaded JCE providers.

according to Sybase, this basically means, the JCE provider jar is not class path. refer to: http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc39001.0707/html/prjdbc0707/CHDGJJIG.htm.

https://groups.google.com/forum/#!topic/sybase.public.jconnect/FD0XHvdVV6I

however, the weired stuff about sybase central v3 is that, it needs bouncycastle jce provider jdk1.4 jar bcprov-jdk1.4.jar plus, it needs jce-jdk1.3.jar, which replaced the default JDK1.4 jce jars.

The 2nd jar, the jce-jdk1.3.jar, provided by BC to override the JDK jce jar, caused me three hard days to figure out. And it’s from this page:

“Choose Your Cryptographic Provider
Sun’s JDK ships with a small set of cryptographic implementations and, in fact, doesn’t provide any asymmetric algorithms, like the industry-dominant RSA algorithms. In fact, many Java cryptology experts recommend avoiding Sun’s JCE provider altogether because once the Sun provider is loaded, it prevents the use of other providers (see Professional Java Security by Jess Garms and Daniel Somerfield for more details). ”

“I fired off several e-mails to Sybase engineers, but with the holiday break I hadn’t received a response prior to my submission deadline as to why this extra .jar might be necessary. ”
http://java.sys-con.com/node/106821/print

Powerbuild Application with JCE

Jboss JAAS Kerberos LDAP security

I encountered some issue while moving one old Jboss web application, from win 2000 to windows 2008 machine.

the first exception encountered is: field is too long

javax.naming.AuthenticationException: GSSAPI [Root exception is javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Field is too long for this implementation (61))]]

this was due to the krb5.conf, the transport is restricted to UDP, refer to
http://docs.oracle.com/cd/E19253-01/816-4557/trouble-1/index.html

 Field is too long for this implementation
Cause:

The message size that was being sent by a Kerberized application was too long. This error could be generated if the transport protocol is UDP. which has a default maximum message size 65535 bytes. In addition, there are limits on individual fields within a protocol message that is sent by the Kerberos service.
Solution:

Verify that you have not restricted the transport to UDP in the KDC server's /etc/krb5/kdc.conf file.

krb5.conf

 

udp_preference_limit = 1 should be added to krb5.conf

[libdefaults]
        default_realm = NA.BLKINT.COM
 udp_preference_limit = 1

the 2nd exception is:Mechanism level: The ticket isn’t for us

17:25:05,531 INFO  [LDAPRealm] No entry in cache for IP, will go fetch DCs w/ subj: AUPMVAPP025/45.145.68.150
17:25:10,048 INFO  [LDAPRealm] Using site: Melbourne
17:25:10,048 INFO  [LDAPRealm] Using Domain Controller: [aupmscdc001.na.blkint.com.]
17:25:10,688 WARN  [JAASRealm] Login exception authenticating username "shenmuk"
javax.security.auth.login.LoginException: Could not establish a connection with AD: java.lang.RuntimeException: Couldn't talk to LDAP: java.lang.RuntimeException: javax.naming.AuthenticationException: GSSAPI [Root exception is javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: The ticket isn't for us (35))]]
	at com.bglobal.commons.security.ldap.NoAuthLDAPLoginModule.commit(NoAuthLDAPLoginModule.java:50)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at javax.security.auth.login.LoginContext.invoke(LoginContext.java:769)
	at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
	at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
	at javax.security.auth.login.LoginContext.login(LoginContext.java:580)
	at org.apache.catalina.realm.JAASRealm.authenticate(JAASRealm.java:373)
	at org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:256)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:391)
	at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
	at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
	at java.lang.Thread.run(Thread.java:595)

the cause is, refer to https://forums.oracle.com/thread/1527734, http://docs.oracle.com/cd/E19253-01/816-4557/trouble-1/index.html

Possible Cause and Resolution

o The server has received a ticket that was meant for a different realm.

Resolution

Verify that DNS is set up correctly. Verify that packets are correctly routed across the network.

the krb5.conf needed to be updated, as there is a SPACE, after realms ”
[realms]
NA.BLKINT.COM = {
kdc = dc-na-ewd (SPACE_HERE)
}”

or change to another realm
[realms]
NA.BLKINT.COM = {
#### kdc = dc-na-ewd
kdc = dir-ad
}

Overall, how JBoss JASS Kerberos/LDAP security works:
1. jboss-web.xml: point to the domain

<jboss-web>
	<security-domain flushOnSessionInvalidation="true">java:/jaas/BAM</security-domain>

2. auth.conf: configure the domain, use which log in module

BAM {
  com.sun.security.auth.module.Krb5LoginModule required useTicketCache=false;
  com.bglobal.commons.security.ldap.NoAuthLDAPLoginModule required;
};

2. and context.xml


  <Context>
      <Realm className="org.apache.catalina.realm.JAASRealm"                 
                appName="BAM"         
               roleClassNames="com.bglobal.commons.security.ldap.LDAPGroup"
               userClassNames="com.bglobal.commons.security.identities.BGIUserId"
                      debug="99"/>
</Context>
      
    

3. web.xml: configure which roles for which access

<login-config>
<security-constraint>

refer to: https://github.com/zanata/zanata-server/wiki/JAAS-Authentication
http://www.kerberos.org/software/tutorial.html
https://community.jboss.org/wiki/DRAFTUsingJBossNegotiationOnAS7