package org.bouncycastle.jsse.provider.test;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.Principal;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509ExtendedKeyManager;
import javax.security.auth.x500.X500Principal;
import junit.framework.TestCase;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;
public class KeyManagerFactoryTest
extends TestCase
{
private static final char[] PASSWORD = "fred".toCharArray();
protected void setUp()
{
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null)
{
Security.addProvider(new BouncyCastleProvider());
}
if (Security.getProvider(BouncyCastleJsseProvider.PROVIDER_NAME) == null)
{
Security.addProvider(new BouncyCastleJsseProvider());
}
}
public void testBasicRSA()
throws Exception
{
KeyManagerFactory fact = KeyManagerFactory.getInstance("PKIX", BouncyCastleJsseProvider.PROVIDER_NAME);
KeyStore ks = getRsaKeyStore(true);
fact.init(ks, PASSWORD);
KeyManager[] managers = fact.getKeyManagers();
X509ExtendedKeyManager manager = (X509ExtendedKeyManager)managers[0];
String alias = manager.chooseServerAlias("RSA", null, null);
assertNotNull(alias);
assertNotNull(manager.getCertificateChain(alias));
assertNotNull(manager.getPrivateKey(alias));
alias = manager.chooseServerAlias("RSA", new Principal[] { new X500Principal("CN=TLS Test") }, null);
assertNull(alias);
alias = manager.chooseServerAlias("RSA", new Principal[] { new X500Principal("CN=TLS Test CA") }, null);
assertNotNull(alias);
assertNotNull(manager.getCertificateChain(alias));
assertNotNull(manager.getPrivateKey(alias));
}
public void testBasicEC()
throws Exception
{
KeyManagerFactory fact = KeyManagerFactory.getInstance("PKIX", BouncyCastleJsseProvider.PROVIDER_NAME);
KeyStore ks = getEcKeyStore(false);
fact.init(ks, PASSWORD);
KeyManager[] managers = fact.getKeyManagers();
X509ExtendedKeyManager manager = (X509ExtendedKeyManager)managers[0];
String alias = manager.chooseServerAlias("ECDHE_ECDSA", null, null);
assertNotNull(alias);
assertNotNull(manager.getCertificateChain(alias));
assertNotNull(manager.getPrivateKey(alias));
alias = manager.chooseServerAlias("ECDHE_ECDSA", new Principal[] { new X500Principal("CN=TLS Test") }, null);
assertNull(alias);
alias = manager.chooseServerAlias("ECDHE_ECDSA", new Principal[] { new X500Principal("CN=TLS Test CA") }, null);
assertNotNull(alias);
assertNotNull(manager.getCertificateChain(alias));
assertNotNull(manager.getPrivateKey(alias));
}
private KeyStore getRsaKeyStore(boolean encryption)
throws Exception
{
KeyStore ks = KeyStore.getInstance("JKS");
KeyPair rPair = TestUtils.generateRSAKeyPair();
KeyPair iPair = TestUtils.generateRSAKeyPair();
KeyPair ePair = TestUtils.generateRSAKeyPair();
X509Certificate rCert = TestUtils.generateRootCert(rPair);
X509Certificate iCert = TestUtils.generateIntermediateCert(iPair.getPublic(), new X500Name("CN=TLS Test CA"), rPair.getPrivate(), rCert);
X509Certificate eCert;
if (encryption)
{
eCert = TestUtils.generateEndEntityCertEnc(ePair.getPublic(), new X500Name("CN=TLS Test"), iPair.getPrivate(), iCert);
}
else
{
eCert = TestUtils.generateEndEntityCertSign(ePair.getPublic(), new X500Name("CN=TLS Test"), iPair.getPrivate(), iCert);
}
ks.load(null, PASSWORD);
ks.setKeyEntry("test", ePair.getPrivate(), PASSWORD, new Certificate[] { eCert, iCert });
ks.setCertificateEntry("root", rCert);
return ks;
}
private KeyStore getEcKeyStore(boolean agreement)
throws Exception
{
KeyStore ks = KeyStore.getInstance("JKS");
KeyPair rPair = TestUtils.generateECKeyPair();
KeyPair iPair = TestUtils.generateECKeyPair();
KeyPair ePair = TestUtils.generateECKeyPair();
X509Certificate rCert = TestUtils.generateRootCert(rPair);
X509Certificate iCert = TestUtils.generateIntermediateCert(iPair.getPublic(), new X500Name("CN=TLS Test CA"), rPair.getPrivate(), rCert);
X509Certificate eCert;
if (agreement)
{
eCert = TestUtils.generateEndEntityCertAgree(ePair.getPublic(), new X500Name("CN=TLS Test"), iPair.getPrivate(), iCert);
}
else
{
eCert = TestUtils.generateEndEntityCertSign(ePair.getPublic(), new X500Name("CN=TLS Test"), iPair.getPrivate(), iCert);
}
ks.load(null, PASSWORD);
ks.setKeyEntry("test", ePair.getPrivate(), PASSWORD, new Certificate[] { eCert, iCert });
ks.setCertificateEntry("root", rCert);
return ks;
}
public void testRSAServer()
throws Exception
{
KeyStore ks = getRsaKeyStore(true);
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(null, PASSWORD);
trustStore.setCertificateEntry("server", ks.getCertificate("root"));
SSLUtils.startServer(ks, PASSWORD, trustStore, false, 8886);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX", BouncyCastleJsseProvider.PROVIDER_NAME);
trustManagerFactory.init(trustStore);
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, trustManagerFactory.getTrustManagers(), null);
SSLSocketFactory f = context.getSocketFactory();
SSLSocket c = (SSLSocket)f.createSocket("localhost", 8886);
c.setUseClientMode(true);
SSLUtils.restrictKeyExchange(c, "RSA");
c.getOutputStream().write('!');
c.getInputStream().read();
}
public void testRSAServerWithClientAuth()
throws Exception
{
KeyStore clientKS = getRsaKeyStore(false);
KeyStore serverKS = getRsaKeyStore(true);
KeyStore serverTS = KeyStore.getInstance("JKS");
serverTS.load(null, PASSWORD);
serverTS.setCertificateEntry("clientRoot", clientKS.getCertificate("root"));
SSLUtils.startServer(serverKS, PASSWORD, serverTS, true, 8887);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("PKIX", BouncyCastleJsseProvider.PROVIDER_NAME);
keyManagerFactory.init(clientKS, PASSWORD);
KeyStore clientTS = KeyStore.getInstance("JKS");
clientTS.load(null, PASSWORD);
clientTS.setCertificateEntry("serverRoot", serverKS.getCertificate("root"));
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX", BouncyCastleJsseProvider.PROVIDER_NAME);
trustManagerFactory.init(clientTS);
SSLContext context = SSLContext.getInstance("TLS");
context.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
SSLSocketFactory f = context.getSocketFactory();
SSLSocket c = (SSLSocket)f.createSocket("localhost", 8887);
c.setUseClientMode(true);
SSLUtils.restrictKeyExchange(c, "RSA");
c.getOutputStream().write('!');
c.getInputStream().read();
}
}