For Programmers: Free Programming Magazines  


Home > Archive > Java Security > July 2004 > Re: Java Secure Socket Extension (JSSE): multiple key entries in key









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Re: Java Secure Socket Extension (JSSE): multiple key entries in key
bigroddy

2004-07-30, 8:56 am

Hello,

I know that's really bad. The API states that you have to init the
KeyManangerFactory like that "init(KeyStore_ks, char[]_password)" and the
password in use have to be the one for all keys with the same certificate
chain. And there is no way to select a specific key to use.

I've made a "big workaround" creating my one KeyManager class and skipping
the usage of the Jsse KeyManagerFactory.

And that's the way:
1. KeyManager class

public class OwnKeyManager
implements X509KeyManager
{
/** The parent X509KeyManager */
private final X509KeyManager mManager;
/** The KeyStore this KeyManager uses */
private final KeyStore mKeyStore;
private final String mKeyAlias;
private final String mKeyPassword;


/**
* Constructor.
*
* @param parent the parent X509KeyManager
* @param keystore the KeyStore in use
* @param keyAlias the alias for key in use
* @param keyPassword the password used for alias
*/
public OwnKeyManager (
X509KeyManager parent, KeyStore keystore,
String keyAlias, String keyPassword)
{
mManager = parent;
mKeyStore = keystore;
mKeyAlias = keyAlias;
mKeyPassword = keyPassword;
}

/**
* Gets the one alias set in constructor.
* Currently, keyType and issuers are both ignored.
*
* @param keyType the type of private key
* @param issuers the CA certificates we are narrowing
* @return the client aliases
*/
public String[] getClientAliases (
String keyType, Principal[] issuers)
{
return new String[] {mKeyAlias};
}

/**
* Gets the list of server aliases for the SSLServerSockets. Not used.
*
* @param keyType the type of private key
* @param issuers the CA certificates we are narrowing
* @return the server aliases
*/
public String[] getServerAliases (
String keyType, Principal[] issuers)
{
return mManager.getServerAliases(keyType, issuers);
}

/**
* Gets the Certificate chain for a particular alias.
*
* @param alias the client alias
* @return the CertificateChain value
*/
public X509Certificate[] getCertificateChain (
String alias)
{
assertAlias(alias);
Certificate[] chain = null;
try
{
chain = mKeyStore.getCertificateChain(alias);
}
catch (KeyStoreException kse)
{
final OwnRuntimeException cre
= new OwnRuntimeException(RteErrorCode.INTERNAL_ERROR,
kse);
cre.setTechnicalDescription(
"Unable to obtain certificate chain for alias "
+ "<" + alias + ">");
throw cre;
}
final X509Certificate[] certChain = new
X509Certificate[chain.length];
for (int i = 0; i < chain.length; i++)
{
certChain[i] = (X509Certificate) chain[i];
}
return certChain;
}

/**
* Gets the Private Key for a particular alias.
*
* @param alias the client alias
* @return the PrivateKey
*/
public PrivateKey getPrivateKey (String alias)
{
assertAlias(alias);
try
{
return (PrivateKey) mKeyStore.getKey(
alias, mKeyPassword.toCharArray());
}
catch (GeneralSecurityException gse)
{
final OwnRuntimeException cre
= new OwnRuntimeException(RteErrorCode.INTERNAL_ERROR,
gse);
cre.setTechnicalDescription(
"Unable to obtain private key for alias "
+ "<" + alias + ">");
throw cre;
}
}

/**
* Gets the alias set in constructor.
*
* @see
javax.net.ssl.X509KeyManager#chooseClientAlias(java.lang.String[],
java.security.Principal[], java.net.Socket)
*/
public String chooseClientAlias (
String[] keyType, Principal[] issuers, Socket socket)
{
return mKeyAlias;
}

/**
* Choose the server alias for the SSLServerSockets.
* This is not used.
* @see
javax.net.ssl.X509KeyManager#chooseServerAlias(java.lang.String,
java.security.Principal[], java.net.Socket)
*/
public String chooseServerAlias (
String keyType, Principal[] issuers, Socket socket)
{
return mManager.chooseServerAlias(keyType, issuers, socket);
}

/**
* Asserts that the given alias is the one set for constructor.
* @param alias the alias to assert
*/
private void assertAlias (String alias)
{
if (!alias.equals(mKeyAlias))
{
final OwnRuntimeException cre
= new OwnRuntimeException(RteErrorCode.INTERNAL_ERROR);
cre.setTechnicalDescription(
"Unexpected alias <" + alias + ">");
throw cre;
}
}
}

This OwnKeyManager returns a specific key for callback "chooseClientAlias"
and the private key you want in "getPrivateKey".

2. Use the OwnKeyManager to init SSLContext
Init the SSLContext like that:
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(getKeyManagers(), getTrustManagers(), null);

and set the TrustManager the normal way:
private TrustManager[] getTrustManagers ()
throws GeneralSecurityException
{
final TrustManagerFactory tmf
= TrustManagerFactory.getInstance(mFactoryName);
tmf.init(mKeyStore);
return tmf.getTrustManagers();
}

and here's the trick ...set the KeyManagers like here:
private KeyManager[] getKeyManagers ()
throws GeneralSecurityException
{
final OwnKeyManager manager
= new OwnKeyManager(null, mKeyStore, mKeyAlias,
mKeyPassword);
final KeyManager[] managers = {manager};
return managers;
}

This works only on client side cause we have not set a KeyManager used
inside OwnKeyManager.chooseServerAlias etc.

ok.
hope that works for you.

Rod.

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com