November 13, 2014

How to modify the friendly name attribute in a SSL certifcate

Recently I have been investigating the cause of the exception which started to show up after switching to a new SSL certifacate:
Exception in thread "main" org.apache.ws.security.WSSecurityException: General security error (No certificates for user john were found for signature)
at org.apache.ws.security.message.WSSecSignature.prepare(WSSecSignature.java:314)
at org.apache.ws.security.message.WSSecSignature.build(WSSecSignature.java:755)
the code responsibile for the above exception:
1| WSSecSignature builder = new WSSecSignature();
2| builder.setUserInfo("john", "secret");
3| builder.build(document, crypto, secHeader);
where:
  • builder is an instance of org.apache.ws.security.message.WSSecSignature
  • crypto is an instance of org.apache.ws.security.components.crypto.Crypto
  • document is an instance of org.w3c.dom.Document
  • secHeader is an instance of org.apache.ws.security.message.WSSecHeader

The crucial line in the above snippet is line 2, where the username (john) and password (secret) are provided. The username must match the friendly name attribute in the certificate.

To check if a certificate contains the friendly name attribute run:
openssl pkcs12 -info -nodes -in cert.p12
For the new certificate I got:
MAC Iteration 2048
MAC verified OK
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
Bag Attributes
    localKeyID: B4 CA ...
subject=/C=PL/O=organization/CN=name
issuer=/C=PL/O=organization/CN=user
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
Bag Attributes
    localKeyID: B4 CA ...
Key Attributes: 
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
The cause of the issue was the friendly name attribute missing in the new certificate.

I did some Googling and I came across this great page that contains a list of steps how to modify a certficate:

  1. export the certifcate
  2. openssl pkcs12 -info -nodes -in cert.p12 > cert.p12.pem
    
  3. extract the private key
    • copy cert.p12.pem to key.pem
    • delete the private key from cert.p12.pem
    • delete everything from key.pem except the private key
  4. extract the user certificate
    • copy cert.p12.pem to mycert.pem
    • delete the user certificate from cert.p12.pem
    • delete everything from mycert.pem except the user certificate
  5. modify cert.p12.pem
    • add a new attribute friendlyName
  6. run:
  7. openssl pkcs12 -export -in mycert.pem -inkey key.pem -name user -out cert.p12.new 
    
VoilĂ ! inside cert.p12.new there is the new certificate with the friendly name attribute set.
openssl pkcs12 -info -nodes -in cert.p12.new
returns now:
MAC Iteration 2048
MAC verified OK
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
Bag Attributes
    friendlyName: user
    localKeyID: B4 CA ...
subject=/C=PL/O=organization/CN=name
issuer=/C=PL/O=organization/CN=user
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
Bag Attributes
    friendlyName: user
    localKeyID: B4 CA ...
Key Attributes: 
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----

February 8, 2014

SVNKit - Check if the given file has the executable flag set

Earlier today I had to code up with code checking if the given SVN url points to a file that has the executable flag set. As Google was not able to find any complete solution using the SVNkit library, here it is:
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNProperties;
import org.tmatesoft.svn.core.SVNProperty;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.BasicAuthenticationManager;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
import org.tmatesoft.svn.core.internal.util.SVNURLUtil;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;

public class SvnClient {
  private String username;
  private String password;
  
  public SvnClient(String username, String password) {
    super();
    this.username = username;
    this.password = password;
  }

  protected SVNRepository connectToRepo(String url) {
    // For using over http:// and https://
    DAVRepositoryFactory.setup();
        
    try {
      final SVNURL svnUrl = SVNURL.parseURIEncoded(url);

      final SVNRepository repository = SVNRepositoryFactory
        .create(svnUrl);
      
      final ISVNAuthenticationManager authManager = 
        new BasicAuthenticationManager(username, password);
      repository.setAuthenticationManager(authManager);
          
      repository.testConnection();
          
      return repository;
    } catch (SVNException e) {
      throw new RuntimeException("Error while connecting to SVN, url "
        + url, e); 
    }        
  }

  public boolean hasExecutableFlagSet(String url, long revision) {
    final SVNRepository repository = connectToRepo(url);
    try {     
      SVNURL repositoryRoot = repository.getRepositoryRoot(true);
      final String fileRelativeURL = "/" + 
        SVNURLUtil.getRelativeURL(repositoryRoot, 
          SVNURL.parseURIEncoded(url), false);
      
      final SVNProperties properties = new SVNProperties();
            
      repository.getFile(fileRelativeURL, revision, properties, null);

      String value = properties.getStringValue(
        SVNProperty.EXECUTABLE);
      
      return value != null;
    } catch(SVNException e) {
      throw new RuntimeException("Error while checking if object "
        + "has the executable flag set, "
        + "url " + url + ", revision " + revision, e);
    } finally {
      repository.closeSession();
    }
  }
  
}

January 12, 2014

Tricky Java job interview questions #1 - discarded exceptions

In May last year I have joined Stackoverflow and started following Java questions. After a few months of actively participating in Stackoverflow, answering questions and learning from others' answers I must say that Stackoverflow is a great source of knowledge. Yes, there are a lot of very simple questions, but among them there are also challenges.

During the last few months I have seen numerous very interesting, and tricky, questions, questions that might be used on Java job interviews. Without further ado, let us start with question #1: What will be the result of executing the following code:

try {
    try {
        System.out.print("1");
        throw new Exception("a");
    } catch (Exception e) {
        System.out.print("2");
        throw new Exception("b");
    } finally {
        System.out.print("3");
        throw new Exception("c");
    }
} catch (Exception e) {
    System.out.print(e.getMessage());
}

Answer: 123c

Explanation: When a finally block throws an Exception (Exception("c")) then the exception thrown in the try block (Exception("b")) is discarded
From the Java Language Specification 14.20.2.:
If execution of the try block completes abruptly for any other reason R, then the finally block is executed, and then there is a choice:
  • If the finally block completes normally, then the try statement completes abruptly for reason R.
  • If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).


Inspired by this Stackoverflow question.

December 20, 2013

JAXB automatically will NOT marshal fields with non-public getter/setter pairs

Recently I have been investigating why JAXB does not marshal one of the classes in the application I was working on. This class had its setters marked as protected, while all the other classes had public setters. As it has turned out this discrepancy was responsible for the issue.

JAXB by default marshals only fields that have a corresponding setter/getter pair marked as public.

So when you want to marshal such class:
@XmlRootElement
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    private Integer id;
    private String name;
 
    public Integer getId() {
        return id;
    }
    protected void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    protected void setName(String name) {
        this.name = name;
    } 
}
you have to append the following annotation:
@XmlAccessorType(XmlAccessType.FIELD)

May 17, 2013

Checked or unchecked exception in Java - decide on the method responsible for performing the check approach

While reading Martin Fowler's book "Refactoring" I came across below paragraph suggesting when choose a checked and when an unchecked exception.

class Account... 
  int withdraw(int amount) {
      if (amount > _balance) return -1;
      else { _balance -= amount; return 0; 
  } 
  private int _balance;
}
To change this code to use an exception I first need to decide whether to use a checked or unchecked exception. The decision hinges on whether it is the responsibility of the caller to test the balance before withdrawing or whether it is the responsibility of the withdraw routine to make the check. If testing the balance is the caller's responsibility, it is a programming error to call withdraw with an amount greater than the balance. Because it is a programming error—that is, a bug—I should use an unchecked exception. If testing the balance is the withdraw routine's responsibility, I must declare the exception in the interface. That way I signal the caller to expect the exception and to take appropriate measures.

I think this is a great guideline, helping in this very, very, very frequent dilemma in the Java world.

I have entitled this approach decide on the method responsible for performing the check approach, it can be summarized as:

  • If it is the caller method should perform a check prior calling the called method (e.g. making sure the arguments are not not null) then if such check has not been done it is clearly a programming error and then the called method should thrown an unchecked exception.
  • It is the called method responsibility to make the check, because only this method can know how to perform such check then the exception thrown from the called method should be checked.

I have done some research checking how the above approach to the checked vs unchecked exception dilemma is applied in the Java world.

  1. java.io.File throws an unchecked NullPointerException when null is passed as the filename to the constructor
  2. public File(String pathname) {
      if (pathname == null) {
        throw new NullPointerException();
      }
      this.path = fs.normalize(pathname);
      this.prefixLength = fs.prefixLength(this.path);
    }
    

    It is the responsibility of the caller to make sure the mandatory arguments provided to the constructor are not nulls.

  3. java.io.File throws java.lang.IllegalArgumentException when an incorrect URL is passed to the constructor
  4. public File(URI uri) {
      if (!uri.isAbsolute())
        throw new IllegalArgumentException("URI is not absolute");
      if (uri.isOpaque())
        throw new IllegalArgumentException("URI is not hierarchical");
      String scheme = uri.getScheme();
      if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
        throw new IllegalArgumentException("URI scheme is not \"file\"");
      if (uri.getAuthority() != null)
        throw new IllegalArgumentException("URI has an authority component");
      if (uri.getFragment() != null)
        throw new IllegalArgumentException("URI has a fragment component");
      if (uri.getQuery() != null)
        throw new IllegalArgumentException("URI has a query component");
      String p = uri.getPath();
      if (p.equals(""))
        throw new IllegalArgumentException("URI path component is empty");
      /// ...
    }
    

    Same story here, it is the caller who is responsible for making sure the provided arguments are correct.

  5. java.util.zip.InflaterInputStream throws a checked java.util.zip.DataFormatException when read() encounters a problem reading the ZIP file
  6. public int read(byte[] b, int off, int len) throws IOException {
      try {
        // ...
      } catch (DataFormatException e) {
        String s = e.getMessage();
        throw new ZipException(s != null ? s : "Invalid ZLIB data format");
      }
    }
    

    It is the responsibility of this (called) method to not only read a zip file but also to validate if the zip file is correct. If it is not valid, what is possible, the calling method should be notified about that.

  7. A checked java.rmi.AlreadyBoundException is thrown when a name provided to java.rmi.Naming.bind() is already bound
  8. public static void bind(String name, Remote obj) throws AlreadyBoundException // ...
    

    The responsibility of checking if the given name is already bound or not might be pushed onto the calling method as there is a method to check if the provided name is bound or not (Naming.lookup()). However it is possible that the name that has been checked to be available has been bound by another process/thread between the call to the lookup and bind method. Therefore a situation when this exception is thrown seems to be perfectly natural and should not be treated as a development bug on the caller side.

  9. A programming error of calling operations on a closed stream results does not result in an unchecked exception but in a checked java.io.IOException
  10. I is it important to keep in mind that this approach is only a guideline, which means there are cases when it is not followed, even in the JDK source code.

    Below code snippet from StringReader:
    public int read() throws IOException {
      synchronized (lock) {
        ensureOpen();
        if (next >= length)
          return -1;
        return str.charAt(next++);
      }
    }
    
    private void ensureOpen() throws IOException {
      if (str == null)
        throw new IOException("Stream closed");
    }
    

    Causes below code to throw a checked IOException:

    StringReader reader = new StringReader("aa");
    
    reader.read();  
    reader.close();  
    reader.read();
    

    While it is clear that is the programmer's responsiblity to make sure that he is not calling any operations on an already closed stream.

    Exactly the same exception is also thrown in the following IO classes:
    • BufferedInputStream
    • BufferedReader
    • BufferedWriter
    • CharArrayReader
    • PrintStream
    • PrintWriter

May 3, 2013

Why I love MacOS - reason #1 - renice

I have been reading a PDF file and had a movie played in the background from a VOD service (plus of course a dozen of other applications that I never quit Skype, Chrome, iTerm, numerous services etc.). Every single time I was scrolling down the PDF file the movie hanged for a half a second. As you can imagine this was extremely annoying.

So I have increased the VOD process priority by changing its nice value and after that was able to continue doing these two tasks smoothly.

This is what I did

  • found the PID of the process playing VOD with "top -o cpu"
  • invoked "sudo renice -15 -p PID"

May 2, 2013

Bash script to get a diff with all the changes from the provided SVN branch

Despite there are numerous user friendly and feature-rich tools for doing code reviews, Crucible being the first one that comes to my mind, when I have to focus solely on the changes I personally prefer to resort to old-school vim with just syntax highlighting.

If you have the same preference, below is a short bash script that might be useful to you, given an SVN branch it will output all the changes from this branch.


#!/bin/bash
test $# -ne 1 && echo "Usage: $0 SVN_URL" && exit 1

svn="$1"
log=`mktemp svn_log.XXXXX`

svn log --stop-on-copy "$svn" > $log
first="`grep '^r[0-9]* | .* | .* |' $log | cut -c2- | cut -d\  -f1 | head -1`"
last="`grep '^r[0-9]* | .* | .* |' $log | cut -c2- | cut -d\  -f1 | tail -1`"

rm $log

svn diff -x "-w --ignore-eol-style" -r "${first}:${last}" $svn

So if you run this script against e.g. https://svn.apache.org/repos/asf/wicket/branches/wicket-1.5.0 you will get:

Index: wicket-guice/pom.xml
===================================================================
--- wicket-guice/pom.xml (revision 1164579)
+++ wicket-guice/pom.xml (revision 1164571)
@@ -23,7 +23,7 @@
  <parent>
   <groupId>org.apache.wicket</groupId>
   <artifactId>wicket-parent</artifactId>
-  <version>1.5.0</version>
+  <version>1.5-RC7</version>
   <relativePath>../pom.xml</relativePath>
  </parent>

Index: wicket-datetime/pom.xml
===================================================================
--- wicket-datetime/pom.xml (revision 1164579)
+++ wicket-datetime/pom.xml (revision 1164571)
@@ -21,7 +21,7 @@
...