Creating a Mock Google Apps API Certificate

The Setup

In this post we’ll discuss how to create a self-signed Google Apps API certificate for use in automated testing.

We do many types of software and system testing in the Custom Development practice at IDMWORKS, from Unit tests to Integration tests, System and Smoke tests. These are created using tools such as JUnit and RSpec and automated using systems such as Jenkins.

One of the techniques we employ is mocking HTTP responses from 3rd-party APIs. This allows us the flexibility of targeting either the real API or mocking the results while using the same bed of test cases and code.

The Challenge

One of the 3rd-party APIs that we ran into trouble mocking at the HTTP level was Google Apps. Their Client Library expects a certificate to be supplied for communication with their API. In our case, when mocking the HTTP responses we did not want to provide a real certificate for a Google Apps service account. Rather, we wanted to simply use a self-signed Google Apps API certificate.

While generating a self-signed p12 file is fairly straight forward using OpenSSL, getting the steps to work with the Google Apps Client Library took a bit of trial and some spelunking in the Google Apps Client Library for Java source code.

The error we initially ran into with a self-signed certificate was:

javax.crypto.BadPaddingException: Given final block not properly padded

A bit of research led to the conclusion that the password being used to encrypt private keys was not correct. Indeed we were testing with a blank password in the self-signed cert. Luckily the source code for the Google Apps Client Library is Open Source, so a bit of digging lead to the following code:

 * Sets the private key to use with the service account flow or {@code null} for none.

* Overriding is only supported for the purpose of calling the super implementation and changing * the return type, but nothing else. *

* * @param p12File input stream to the p12 file (closed at the end of this method in a finally * block) */ public Builder setServiceAccountPrivateKeyFromP12File(File p12File) throws GeneralSecurityException, IOException { serviceAccountPrivateKey = SecurityUtils.loadPrivateKeyFromKeyStore( SecurityUtils.getPkcs12KeyStore(), new FileInputStream(p12File), "notasecret", "privatekey", "notasecret"); return this; }

By referencing the SecurityUtils.loadPrivateKeyFromKeyStore online documentation, we can see that the Google Apps Client Library expects the certificate to use the password “notasecret” and the alias “privatekey”.

The Solution

Armed with that knowledge, the final set of steps for creating the self-signed Google Apps API certificate is found below:

# put a self-signed Google Apps cert in place
openssl req 
    -newkey rsa:4096 
    -days 365 
    -subj "/" 
    -keyout googleapps_mock.key 
    -out googleapps_mock.crt

openssl pkcs12 -export -in googleapps_mock.crt -inkey googleapps_mock.key -out googleapps_mock.p12 -name privatekey -passout pass:notasecret

This will create and export a self-signed p12 file that can be successfully loaded by the Google Apps Client Library. Good luck and happy testing!