org.bouncycastle.jsse.provider.ProvX509Key Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bctls-fips Show documentation
Show all versions of bctls-fips Show documentation
The Bouncy Castle Java APIs for the TLS, including a JSSE provider. The APIs are designed primarily to be used in conjunction with the BC FIPS provider. The APIs may also be used with other providers although if being used in a FIPS context it is the responsibility of the user to ensure that any other providers used are FIPS certified and used appropriately.
package org.bouncycastle.jsse.provider;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.X509KeyManager;
import org.bouncycastle.jsse.BCX509Key;
import org.bouncycastle.tls.TlsUtils;
class ProvX509Key
implements BCX509Key
{
private static final Logger LOG = Logger.getLogger(ProvX509Key.class.getName());
static ProvX509Key from(X509KeyManager x509KeyManager, String keyType, String alias)
{
if (null == x509KeyManager)
{
throw new NullPointerException("'x509KeyManager' cannot be null");
}
if (null == keyType || null == alias)
{
return null;
}
X509Certificate[] certificateChain = getCertificateChain(x509KeyManager, alias);
if (null == certificateChain)
{
return null;
}
PrivateKey privateKey = getPrivateKey(x509KeyManager, alias);
if (null == privateKey)
{
return null;
}
return new ProvX509Key(keyType, privateKey, certificateChain);
}
static ProvX509Key validate(X509KeyManager x509KeyManager, boolean forServer, String keyType, String alias,
TransportData transportData)
{
if (null == x509KeyManager)
{
throw new NullPointerException("'x509KeyManager' cannot be null");
}
if (null == keyType || null == alias)
{
return null;
}
X509Certificate[] certificateChain = getCertificateChain(x509KeyManager, alias);
if (null == certificateChain)
{
return null;
}
/*
* We have several reports of custom key managers that don't properly check the key type, instead just
* returning a fixed alias. Therefore we perform a sanity check here that should allow such key
* managers a better chance of working correctly.
*/
if (!ProvX509KeyManager.isSuitableKeyType(forServer, keyType, certificateChain[0], transportData))
{
if (LOG.isLoggable(Level.FINER))
{
LOG.finer("Rejecting alias '" + alias + "': not suitable for key type '" + keyType + "'");
}
return null;
}
PrivateKey privateKey = getPrivateKey(x509KeyManager, alias);
if (null == privateKey)
{
return null;
}
return new ProvX509Key(keyType, privateKey, certificateChain);
}
private static X509Certificate[] getCertificateChain(X509KeyManager x509KeyManager, String alias)
{
X509Certificate[] certificateChain = x509KeyManager.getCertificateChain(alias);
if (TlsUtils.isNullOrEmpty(certificateChain))
{
LOG.finer("Rejecting alias '" + alias + "': no certificate chain");
return null;
}
certificateChain = certificateChain.clone();
if (JsseUtils.containsNull(certificateChain))
{
LOG.finer("Rejecting alias '" + alias + "': invalid certificate chain");
return null;
}
return certificateChain;
}
private static PrivateKey getPrivateKey(X509KeyManager x509KeyManager, String alias)
{
PrivateKey privateKey = x509KeyManager.getPrivateKey(alias);
if (null == privateKey)
{
LOG.finer("Rejecting alias '" + alias + "': no private key");
return null;
}
return privateKey;
}
private final String keyType;
private final PrivateKey privateKey;
private final X509Certificate[] certificateChain;
ProvX509Key(String keyType, PrivateKey privateKey, X509Certificate[] certificateChain)
{
this.keyType = keyType;
this.privateKey = privateKey;
this.certificateChain = certificateChain;
}
public X509Certificate[] getCertificateChain()
{
return certificateChain.clone();
}
public String getKeyType()
{
return keyType;
}
public PrivateKey getPrivateKey()
{
return privateKey;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy