113 lines
4.7 KiB
Java
113 lines
4.7 KiB
Java
package de.mlessmann.certassist;
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
|
|
import de.mlessmann.certassist.keystore.KeyStoreManager;
|
|
import de.mlessmann.certassist.openssl.CertificateProvider;
|
|
import de.mlessmann.certassist.openssl.CertificateUsage;
|
|
import de.mlessmann.certassist.openssl.InMemoryCertificatePasswordProvider;
|
|
import de.mlessmann.certassist.openssl.OpenSSLService;
|
|
import de.mlessmann.certassist.service.ExecutableResolver;
|
|
import java.io.IOException;
|
|
import java.net.ServerSocket;
|
|
import java.nio.file.Path;
|
|
import java.security.SecureRandom;
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
import javax.net.ssl.KeyManagerFactory;
|
|
import javax.net.ssl.SSLContext;
|
|
import javax.net.ssl.TrustManagerFactory;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.mockito.Mockito;
|
|
|
|
public class TestKeystoreCreation {
|
|
|
|
private static final String STORE_PASSPHRASE = "changeit";
|
|
private static final SecureRandom TEST_RANDOM = new SecureRandom();
|
|
private final CertificateUsage dummyCert = new CertificateUsage() {
|
|
@Override
|
|
public String fingerprint() {
|
|
return TestOpenSSLService.TEST_CERT_FINGERPRINT;
|
|
}
|
|
|
|
@Override
|
|
public Path certificatePath() {
|
|
return TestOpenSSLService.TEST_CERT_PATH.resolve("x509forImport.pem");
|
|
}
|
|
|
|
@Override
|
|
public Path certificateKeyPath() {
|
|
return TestOpenSSLService.TEST_CERT_PATH.resolve("x509forImport.key.pem");
|
|
}
|
|
|
|
@Override
|
|
public Path fullchainPath() {
|
|
return TestOpenSSLService.TEST_CERT_PATH.resolve("x509forImport.fullchain.pem");
|
|
}
|
|
};
|
|
|
|
@Test
|
|
void testTruststore() throws Exception {
|
|
var passwordProvider = new InMemoryCertificatePasswordProvider();
|
|
passwordProvider.setPasswordFor(dummyCert.fingerprint(), TestOpenSSLService.TEST_CERT_PASSPHRASE);
|
|
|
|
var certificateProvider = Mockito.mock(CertificateProvider.class);
|
|
var opensslCertCreator = new OpenSSLService(new ExecutableResolver(), passwordProvider, certificateProvider);
|
|
var keyStoreManager = new KeyStoreManager(opensslCertCreator, passwordProvider);
|
|
AtomicBoolean serverAccepted = new AtomicBoolean(false);
|
|
AtomicBoolean clientAccepted = new AtomicBoolean(false);
|
|
|
|
try (
|
|
var tmpTruststore = keyStoreManager.createTruststore(STORE_PASSPHRASE, dummyCert);
|
|
var tmpKeyStore = keyStoreManager.createKeyStore(STORE_PASSPHRASE, dummyCert)
|
|
) {
|
|
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
|
|
KeyManagerFactory.getDefaultAlgorithm()
|
|
);
|
|
keyManagerFactory.init(tmpTruststore.readAsKeystore(STORE_PASSPHRASE), STORE_PASSPHRASE.toCharArray());
|
|
|
|
SSLContext tlsSrvContext = SSLContext.getInstance("TLS");
|
|
tlsSrvContext.init(keyManagerFactory.getKeyManagers(), null, TEST_RANDOM);
|
|
|
|
ServerSocket serverSocket = tlsSrvContext.getServerSocketFactory().createServerSocket(0);
|
|
var serverThread = Thread.startVirtualThread(() -> {
|
|
try {
|
|
var remote = serverSocket.accept();
|
|
serverAccepted.set(true);
|
|
try {
|
|
Thread.sleep(2_000);
|
|
} catch (InterruptedException e) {
|
|
// nothing
|
|
}
|
|
remote.close();
|
|
} catch (IOException e) {
|
|
throw new IllegalStateException("Failed to create server socket!", e);
|
|
}
|
|
});
|
|
|
|
var trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
|
trustManagerFactory.init(tmpTruststore.readAsKeystore(STORE_PASSPHRASE));
|
|
|
|
SSLContext tlsContext = SSLContext.getInstance("TLS");
|
|
tlsContext.init(null, trustManagerFactory.getTrustManagers(), TEST_RANDOM);
|
|
|
|
var clientThread = Thread.startVirtualThread(() -> {
|
|
try {
|
|
var socket = tlsContext.getSocketFactory().createSocket("127.0.0.1", serverSocket.getLocalPort());
|
|
clientAccepted.set(true);
|
|
socket.close();
|
|
} catch (IOException e) {
|
|
throw new IllegalStateException("Failed to create client socket!", e);
|
|
}
|
|
});
|
|
|
|
serverThread.join();
|
|
clientThread.join();
|
|
if (!serverSocket.isClosed()) {
|
|
serverSocket.close();
|
|
}
|
|
|
|
assertThat(serverAccepted.get()).withFailMessage("Server did not accept connection!").isTrue();
|
|
assertThat(clientAccepted.get()).withFailMessage("Client did not accept connection!").isTrue();
|
|
}
|
|
}
|
|
}
|