Data AccessCore JavaApp FrameworksViewTestingBuildingDeploymentDev ToolsSecurityOpinions
Showing posts with label J2EE Core. Show all posts
Showing posts with label J2EE Core. Show all posts

Thursday, November 3, 2011

javax.net.ssl.SSLException: Received fatal alert: unexpected_message

If you are attempting to establish an SSL Connection as a client to a server and getting this error at the very end of the SSL Handshake, then check the server settings for client authentication.

Client Authentication is the ability of a webserver to verify the client, whether it be a browser or other application.

Setting client authentication does reduce the level of security enabled, so this decision should be made based on your needs and threat model.

If you do require client authentication, there are two great articles below:


If you have any JSSE/OpenSSL questions, feel free to comment and I'll try and get back to you.

SSL Connections over a proxy using JSSE

The Java Secure Socket Extension (JSSE) enables secure Internet communications. It provides a framework and an implementation for a Java version of the SSL and TLS protocols and includes functionality for data encryption, server authentication, message integrity, and optional client authentication. Using JSSE, developers can provide for the secure passage of data between a client and a server running any application protocol, such as Hypertext Transfer Protocol (HTTP), Telnet, or FTP, over TCP/IP.

The https protocol is similar to http, but https first establishes a secure channel via SSL/TLS sockets and then verifies the identity of the peer before requesting/receiving data. javax.net.ssl.HttpsURLConnection extends the java.net.HttpsURLConnection class, and adds support for https-specific features. Upon obtaining a HttpsURLConnection, you can configure a number of http/https parameters before actually initiating the network connection via the method URLConnection.connect.

In some situations, it is desirable to specify the SSLSocketFactory that an HttpsURLConnection instance uses. For example, you may wish to tunnel through a proxy type which is NOT supported by the default implementation. The new SSLSocketFactory could return sockets that have already performed all necessary tunneling, thus allowing HttpsURLConnection to use additional proxies.

Post your issue below, and I'll try and answer your JSSE questions.


References:
  1. JSSE Reference Guide for Java SE6
  2. JSSE Reference Guide for Java SE6 - Hostname Verifier
  3. javadoc: javax.net.ssl.SSLSocketFactory
  4. javadoc: javax.net.ssl.HttpsURLConnection
  5. javadoc: java.net.URLConnection
  6. javadoc: java.net.URL.openConnection()

Saturday, December 5, 2009

Data Access: Plain JDBC vs. ORM

I start this discussion, to try and organize some thoughts and comparisons on data access code, written in plain old JDBC (or Java Database Connectivity) vs. utilizing an ORM Framework (or Object Relational Management Framework), such as Hibernate or iBatis.

A developer's goal when writing data access code is to properly contain the responsibilities of all data access operations. Leaking data access operations into the application is referred to as leakage of data-access details and has some adverse affects when the application has to adapt to changes on the data side.

Let's take a look at a method that uses raw JDBC:
public class UserRegistrationJDBC {

   private javax.sql.DataSource dataSource;

   public int getUserRegistrationCount() throws MyDataAccessException {

      java.sql.Connection connection = null;
      java.sql.Statement statement = null;
      java.sql.ResultSet resultSet = null;
      try{
         connection = dataSource.getConnection();
         statement = connection.createStatement();
         resultSet = statement.executeQuery(
            "SELECT COUNT(*) FROM USER_REGISTRATION");

         rs.next();
         return rs.getInt(1);
      }catch(java.sql.SQLException sqle){
         throw new MyDataAccessException(e);
      }finally{
         if(resultSet != null){ 
            try{ resultSet.close() }
            catch (java.sql.SQLException sqle){ sqle.printStackTrace(); }
         }
         if(statement != null){ 
            try{ statement.close() }
            catch (java.sql.SQLException sqle){ sqle.printStackTrace(); }
         }
         if(connection != null){ 
            try{ connection.close() }
            catch (java.sql.SQLException sqle){ sqle.printStackTrace(); }
         }
      }
   }
}

Let's look at some technical details of this data access code:

  • The call to getConnection() on the javax.sql.DataSource object can be problematic because it obtains its own database connection. There may be an instance when this call depends entirely on the underlying DataSource object. Not too bad, but it does restrict the application on how it can organize database transactions.
  • The call to createStatement() is problematic as well. All sql should be rendered using a java.sql.PreparedStatement() for improved performance via caching. While this is more of a practice and learned through experience, using raw JDBC leaves the programmer open to these types of mistakes.
  • Catching a java.sql.SQLException is required by the JDBC API as it is it's only exception type and typically reveals little about the root cause of your error. Wrapping it with the unchecked exception MyDataAccessException, adds little value, only that your calling code does not have to catch it. Your application code now is restricted in how it can deal with specific data access errors.
  • The finally block contains the closing of all resources used in the method, which makes it impossible for other methods to reuse it.
Some of the concerns also exist when using ORM tools, however, are often less visible.

Poor handling of the concerns above can lead to:
  • Resource exhaustion - loss of connection availability and loss of memory from improperly closed result sets and statements
  • Poor performance - due to Statement vs. PreparedStatement as mentioned above.
  • Inappropriate connection life cycles - any operation where more than one SQL statement is executed can reuse connections and other resources for more appropriate life cycles. Even with connection pools, we should be careful not to spend CPU cycles and memory on obtaining and releasing connections.

To elaborate even further the inappropriate connection life cycles point, consider where a user registration is added with a payment for the registration. We would want to ensure that all the data access operations occurred or none at all. In a more appropriate world, we want to demarcate these operations at a transaction level, enabling the reuse of all related resources.

The goal of many ORM's are to handle the concerns above with:
  • Transaction Demarcation - a mechanism to declare when transactions start and end.
  • Transaction Management API - an API to keep contracts clear and concise on transactions
It should be obvious, that writing a Transaction Management API is out of scope for most developers and only an adequately defined API can guarantee that applications remain flexible and adaptive.

In my next article, I'll present ways on how Spring provides a constructive and flexible programming model which addresses the concerns above and much more.

Tuesday, April 14, 2009

Check if a file contains a string

I recently wrote some java code to check if a file contains a string.


public class FileUtilities {


/**
* Returns true if the file exists and contains aString, false otherwise.
* @param file
* @param aString
* @return
* @throws FileNotFoundException
*/
public static boolean fileContainsString(File file, String aString) throws FileNotFoundException{

FileInputStream fis = null;
BufferedReader in = null;

try{
fis = new FileInputStream(file);
in = new BufferedReader(new InputStreamReader(fis));

String currentLine = "";
while ((currentLine = in.readLine()) != null) {
if(currentLine.indexOf(aString) > 0) return true;
}

}catch(IOException ioe){
ioe.printStackTrace();
}finally{
try{
if(in != null) in.close();
if(fis != null) fis.close();
}catch(IOException ioe){ }
}
return false;
}
}