/**
* VMware Continuent Tungsten Replicator
* Copyright (C) 2007-2015 VMware, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Initial developer(s): Ludovic Launer
* Contributor(s):
*/
package com.continuent.tungsten.common.sockets;
import java.net.Socket;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.text.MessageFormat;
import javax.net.ssl.X509KeyManager;
import org.apache.log4j.Logger;
import com.continuent.tungsten.common.security.SecurityHelper;
/**
* Implements a class handle selecting multiple aliases from an X509KeyManager.
* The author gratefully acknowledges the blog article by Alexandre Saudate for
* providing guidance for the implementation.
*
* @see <a href=
* "http://alesaudate.wordpress.com/2010/08/09/how-to-dynamically-select-a-certificate-alias-when-invoking-web-services/">
* How to dynamically select a certificate alias when invoking web
* services</a>
*/
public class AliasSelectorKeyManager implements X509KeyManager
{
private static final Logger logger = Logger
.getLogger(AliasSelectorKeyManager.class);
private X509KeyManager sourceKeyManager = null;
private String alias;
public AliasSelectorKeyManager(X509KeyManager keyManager, String alias)
{
this.sourceKeyManager = keyManager;
this.alias = alias;
}
@Override
public String chooseClientAlias(String[] keyType, Principal[] issuers,
Socket socket)
{
return sourceKeyManager.chooseClientAlias(keyType, issuers, socket);
}
@Override
public String chooseServerAlias(String keyType, Principal[] issuers,
Socket socket)
{
if (this.alias == null)
return sourceKeyManager.chooseServerAlias(keyType, issuers, socket);
else
{
boolean aliasFound = false;
String[] validAliases = sourceKeyManager.getClientAliases(keyType,
issuers);
if (validAliases != null)
{
for (int j = 0; j < validAliases.length && !aliasFound; j++)
{
if (validAliases[j].equals(alias))
aliasFound = true;
}
}
if (aliasFound)
{
if (logger.isTraceEnabled())
logger.trace(MessageFormat.format(
"Alias Found !: {0} for keyType: {1} in keystore: {2}",
this.alias, keyType,
SecurityHelper.getKeyStoreLocation()));
return alias;
}
else
{
String keyStoreLocation = SecurityHelper.getKeyStoreLocation();
// Not finding the alias is not an error at this stage, it only
// means that we could not find the alias for a given keyType
// (i.e.:EC_EC), it may exist for the desired keyType (i.e.:RSA)
logger.trace(MessageFormat.format(
"Could not find alias: {0} for keyType: {1} in keystore: {2}",
this.alias, keyType, keyStoreLocation));
}
}
return null;
}
public X509Certificate[] getCertificateChain(String alias)
{
return sourceKeyManager.getCertificateChain(alias);
}
public String[] getClientAliases(String keyType, Principal[] issuers)
{
return sourceKeyManager.getClientAliases(keyType, issuers);
}
public PrivateKey getPrivateKey(String alias)
{
return sourceKeyManager.getPrivateKey(alias);
}
public String[] getServerAliases(String keyType, Principal[] issuers)
{
return sourceKeyManager.getServerAliases(keyType, issuers);
}
}