PEM certificates for https auth

167 views
Skip to first unread message

Simone Tripodi

unread,
Feb 7, 2012, 3:05:25 PM2/7/12
to asynchttpclient
Salut a tout le monde,

I'm happily using AHC in my application, unfortunately I am
experiencing difficulties (due to my lack of knowledge as well)
authenticating the client to the server using pem certificates.

The scenario is in a scientific environment, where sysadmins provide
to scientists PEM certificates to authenticate to server and download
satellite data. Scientists are used to access to them using curl in
the following way:

curl -k --sslv3 --cert ~/.globus/xxx-cert.pem --key ~/.globus/xxx-
key.pem https://xxx.xxx.esa.int/store0901/eo/ASA_WSM_1P/2008/10/ASA_WSM_1PNPDE20081018_180853_000003432073_00070_34693_8521.N1

My question is: how can I replicate this command as well using AHC? I
found in the tests a keystore sample, but IIUC it requires
transforming the certificates to .der and importing them in the
keystore - that would be a limit in my usecase.

Does anyone have a suggestion?

Many thanks in advance, all the best!
-Simo

Benjamin Hanzelmann

unread,
Feb 7, 2012, 6:18:28 PM2/7/12
to asyncht...@googlegroups.com

You can construct an in-memory keystore from the PEM certificate and
use that keystore for AHC. Let's see if I have enough code snippets
around to explain...

// read in PEM file and parse with commons-ssl PKCS8Key
// (ca.juliusdavies:not-yet-commons-ssl:0.3.11)
RandomAccessFile in = null;
byte[] b = new byte[(int) certFile.length()];
in = new RandomAccessFile( certFile, "r" );
in.readFully( b );
char[] password = hints.get( "password" ).toString().toCharArray();
PKCS8Key key = new PKCS8Key( b, password );

// create empty key store
store = KeyStore.getInstance( KeyStore.getDefaultType() );
store.load( null, password );

// cert chain is not important if you override the default
KeyManager and/or
// TrustManager implementation, IIRC store.setKeyEntry( alias,
key.getPrivateKey(), password, new DefaultCertificate[0] );

// initialize key and trust managers -> default behavior
// password for key and store have to be the same IIRC
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
"SunX509" );
keyManagerFactory.init( store, password );
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm() );
tmf.init( store );

// override key and trust managers with desired behavior - for example
// * 'trust everything the server gives us' ->
TrustManager#checkServerTrusted
// * 'always return a preset alias to use for auth' ->
X509ExtendedKeyManager#chooseClientAlias,
X509ExtendedKeyManager#chooseEngineClientAlias
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
TrustManager[] trustManagers = tmf.getTrustManagers();
for ( int i = 0; i < keyManagers.length; i++ )
{
if ( keyManagers[i] instanceof X509ExtendedKeyManager )
{
AHCKeyManager ahcKeyManager = new AHCKeyManager(
(X509ExtendedKeyManager) keyManagers[i] );
keyManagers[i] = ahcKeyManager;
}
}

for ( int i = 0; i < trustManagers.length; i++ )
{
if ( tm instanceof X509TrustManager )
{
AHCTrustManager ahcTrustManager = new AHCTrustManager(
manager, (X509TrustManager) trustManagers[i] );
trustManagers[i] = ahcTrustManager;
}
}

// construct SSLContext and feed to AHC config
SSLContext context = SSLContext.getInstance( "TLS" );
context.init( keyManagers, trustManagers, null );
ahcCfgBuilder.setSSLContext(context);

(also in a gist for future reference: https://gist.github.com/1762446)

Ben

Simone Tripodi

unread,
Feb 8, 2012, 2:17:44 AM2/8/12
to asyncht...@googlegroups.com
Hi Benjamin,

I'm speechless, thanks *a lot* for your kind advice!!!

I will give a try and provide feedbacks, thanks once again!!!
All the best,
-Simo

http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/

> --
> You received this message because you are subscribed to the Google Groups "asynchttpclient" group.
> To post to this group, send email to asyncht...@googlegroups.com.
> To unsubscribe from this group, send email to asynchttpclie...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/asynchttpclient?hl=en.
>

Simone Tripodi

unread,
Feb 9, 2012, 8:38:50 AM2/9/12
to asyncht...@googlegroups.com
Hi again Benjamin,

thanks once again for the help! In the not-yet-commons-ssl I found an
interesting class, org.apache.commons.ssl.KeyMaterial that easily
allows creating empty KeyStore with SSL key/certificate

So, that is my working code:

+-------------------------------------------------------------------+
final KeyStore store = new KeyMaterial( certFile, keyFile, password
).getKeyStore();
store.load( null, password );

final KeyManagerFactory keyManagerFactory =


KeyManagerFactory.getInstance( "SunX509" );
keyManagerFactory.init( store, password );

SSLContext context = SSLContext.getInstance( "TLS" );
context.init( keyManagerFactory.getKeyManagers(), new TrustManager[] {
new DummyTrustManager() }, null );

ahcCfgBuilder.setSSLContext( context );
+-------------------------------------------------------------------+

where the DummyTrustManager is the one implemented in the SSL test.

Thanks again for the priceless help!!!
All the best,
-Simo

Reply all
Reply to author
Forward
0 new messages