Browse Source

Add reload integration tests

pull/15301/head
Andrii Landiak 7 months ago
parent
commit
1317a44639
  1. 349
      common/coap-server/src/test/java/org/thingsboard/server/coapserver/CoapDtlsCertificateReloadIntegrationTest.java
  2. 276
      common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/MqttSslCertificateReloadIntegrationTest.java

349
common/coap-server/src/test/java/org/thingsboard/server/coapserver/CoapDtlsCertificateReloadIntegrationTest.java

@ -0,0 +1,349 @@
/**
* Copyright © 2016-2026 The Thingsboard Authors
*
* 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.
*/
package org.thingsboard.server.coapserver;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
import org.eclipse.californium.core.CoapClient;
import org.eclipse.californium.core.CoapResource;
import org.eclipse.californium.core.CoapResponse;
import org.eclipse.californium.core.CoapServer;
import org.eclipse.californium.core.coap.CoAP;
import org.eclipse.californium.core.config.CoapConfig;
import org.eclipse.californium.core.network.CoapEndpoint;
import org.eclipse.californium.core.server.resources.CoapExchange;
import org.eclipse.californium.elements.config.Configuration;
import org.eclipse.californium.elements.util.SslContextUtil;
import org.eclipse.californium.scandium.DTLSConnector;
import org.eclipse.californium.scandium.config.DtlsConfig;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.californium.scandium.dtls.CertificateType;
import org.eclipse.californium.scandium.dtls.x509.SingleCertificateProvider;
import org.eclipse.californium.scandium.dtls.x509.StaticNewAdvancedCertificateVerifier;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.thingsboard.server.common.transport.config.ssl.KeystoreSslCredentials;
import org.thingsboard.server.common.transport.config.ssl.PemSslCredentials;
import org.thingsboard.server.common.transport.config.ssl.SslCredentials;
import org.thingsboard.server.common.transport.config.ssl.SslCredentialsConfig;
import org.thingsboard.server.common.transport.config.ssl.SslCredentialsType;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_CLIENT_AUTHENTICATION_MODE;
import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_RETRANSMISSION_TIMEOUT;
import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_ROLE;
import static org.eclipse.californium.scandium.config.DtlsConfig.DtlsRole.SERVER_ONLY;
public class CoapDtlsCertificateReloadIntegrationTest {
private static final String TEST_RESOURCE_PATH = "test";
private static final String TEST_PAYLOAD = "hello-dtls";
@TempDir
Path tempDir;
private CoapServer coapServer;
@AfterEach
public void teardown() {
if (coapServer != null) {
coapServer.destroy();
}
}
@Test
public void givenDtlsServer_whenCertFileChangedAndReloadTriggered_thenNewEndpointServesNewCert() throws Exception {
KeyPair keyPairA = generateKeyPair();
X509Certificate certA = generateSelfSignedCert(keyPairA, "CN=ServerA");
KeyPair keyPairB = generateKeyPair();
X509Certificate certB = generateSelfSignedCert(keyPairB, "CN=ServerB");
Path certFile = tempDir.resolve("server-cert.pem");
Path keyFile = tempDir.resolve("server-key.pem");
writeCertPem(certFile, certA);
writeKeyPem(keyFile, keyPairA);
SslCredentialsConfig credentialsConfig = createSslCredentialsConfig(certFile, keyFile);
Configuration config = createServerConfig();
coapServer = new CoapServer(config);
coapServer.add(new TestResource());
int dtlsPort = findAvailablePort();
CoapEndpoint endpointA = buildDtlsEndpointFromCredentials(config, credentialsConfig.getCredentials(), dtlsPort);
coapServer.addEndpoint(endpointA);
coapServer.start();
CoapResponse responseA = doDtlsRequest(dtlsPort, certA);
assertThat(responseA).isNotNull();
assertThat(responseA.getCode()).isEqualTo(CoAP.ResponseCode.CONTENT);
assertThat(responseA.getResponseText()).isEqualTo(TEST_PAYLOAD);
writeCertPem(certFile, certB);
writeKeyPem(keyFile, keyPairB);
credentialsConfig.onCertificateFileChanged();
coapServer.getEndpoints().remove(endpointA);
endpointA.stop();
CoapEndpoint endpointB = buildDtlsEndpointFromCredentials(config, credentialsConfig.getCredentials(), dtlsPort);
coapServer.addEndpoint(endpointB);
endpointB.start();
endpointA.destroy();
CoapResponse responseB = doDtlsRequest(dtlsPort, certB);
assertThat(responseB).isNotNull();
assertThat(responseB.getCode()).isEqualTo(CoAP.ResponseCode.CONTENT);
assertThat(responseB.getResponseText()).isEqualTo(TEST_PAYLOAD);
}
@Test
public void givenDtlsServer_whenCertReloaded_thenOldCertClientFails() throws Exception {
KeyPair keyPairA = generateKeyPair();
X509Certificate certA = generateSelfSignedCert(keyPairA, "CN=ServerA");
KeyPair keyPairB = generateKeyPair();
X509Certificate certB = generateSelfSignedCert(keyPairB, "CN=ServerB");
Path certFile = tempDir.resolve("server-cert.pem");
Path keyFile = tempDir.resolve("server-key.pem");
writeCertPem(certFile, certA);
writeKeyPem(keyFile, keyPairA);
SslCredentialsConfig credentialsConfig = createSslCredentialsConfig(certFile, keyFile);
Configuration config = createServerConfig();
coapServer = new CoapServer(config);
coapServer.add(new TestResource());
int dtlsPort = findAvailablePort();
CoapEndpoint endpointA = buildDtlsEndpointFromCredentials(config, credentialsConfig.getCredentials(), dtlsPort);
coapServer.addEndpoint(endpointA);
coapServer.start();
CoapResponse responseA = doDtlsRequest(dtlsPort, certA);
assertThat(responseA).isNotNull();
writeCertPem(certFile, certB);
writeKeyPem(keyFile, keyPairB);
credentialsConfig.onCertificateFileChanged();
coapServer.getEndpoints().remove(endpointA);
endpointA.stop();
CoapEndpoint endpointB = buildDtlsEndpointFromCredentials(config, credentialsConfig.getCredentials(), dtlsPort);
coapServer.addEndpoint(endpointB);
endpointB.start();
endpointA.destroy();
CoapResponse failedResponse = doDtlsRequest(dtlsPort, certA);
assertThat(failedResponse).isNull();
CoapResponse responseB = doDtlsRequest(dtlsPort, certB);
assertThat(responseB).isNotNull();
assertThat(responseB.getCode()).isEqualTo(CoAP.ResponseCode.CONTENT);
}
@Test
public void givenDtlsServer_whenReloadWithSameCert_thenConnectionStillWorks() throws Exception {
KeyPair keyPair = generateKeyPair();
X509Certificate cert = generateSelfSignedCert(keyPair, "CN=Server");
Path certFile = tempDir.resolve("server-cert.pem");
Path keyFile = tempDir.resolve("server-key.pem");
writeCertPem(certFile, cert);
writeKeyPem(keyFile, keyPair);
SslCredentialsConfig credentialsConfig = createSslCredentialsConfig(certFile, keyFile);
Configuration config = createServerConfig();
coapServer = new CoapServer(config);
coapServer.add(new TestResource());
int dtlsPort = findAvailablePort();
CoapEndpoint endpoint1 = buildDtlsEndpointFromCredentials(config, credentialsConfig.getCredentials(), dtlsPort);
coapServer.addEndpoint(endpoint1);
coapServer.start();
CoapResponse response1 = doDtlsRequest(dtlsPort, cert);
assertThat(response1).isNotNull();
assertThat(response1.getCode()).isEqualTo(CoAP.ResponseCode.CONTENT);
credentialsConfig.onCertificateFileChanged();
coapServer.getEndpoints().remove(endpoint1);
endpoint1.stop();
CoapEndpoint endpoint2 = buildDtlsEndpointFromCredentials(config, credentialsConfig.getCredentials(), dtlsPort);
coapServer.addEndpoint(endpoint2);
endpoint2.start();
endpoint1.destroy();
CoapResponse response2 = doDtlsRequest(dtlsPort, cert);
assertThat(response2).isNotNull();
assertThat(response2.getCode()).isEqualTo(CoAP.ResponseCode.CONTENT);
}
private SslCredentialsConfig createSslCredentialsConfig(Path certFile, Path keyFile) {
PemSslCredentials pem = new PemSslCredentials();
pem.setCertFile(certFile.toAbsolutePath().toString());
pem.setKeyFile(keyFile.toAbsolutePath().toString());
SslCredentialsConfig config = new SslCredentialsConfig("CoAP DTLS Test", false);
config.setEnabled(true);
config.setType(SslCredentialsType.PEM);
config.setPem(pem);
config.setKeystore(new KeystoreSslCredentials());
config.init();
return config;
}
private CoapEndpoint buildDtlsEndpointFromCredentials(Configuration config, SslCredentials credentials, int port) {
DtlsConnectorConfig.Builder dtlsBuilder = new DtlsConnectorConfig.Builder(config);
dtlsBuilder.setAddress(new InetSocketAddress(InetAddress.getLoopbackAddress(), port));
dtlsBuilder.set(DTLS_ROLE, SERVER_ONLY);
dtlsBuilder.set(DTLS_RETRANSMISSION_TIMEOUT, 3000, MILLISECONDS);
dtlsBuilder.set(DTLS_CLIENT_AUTHENTICATION_MODE,
org.eclipse.californium.elements.config.CertificateAuthenticationMode.WANTED);
SslContextUtil.Credentials serverCreds = new SslContextUtil.Credentials(
credentials.getPrivateKey(), null, credentials.getCertificateChain());
dtlsBuilder.setCertificateIdentityProvider(
new SingleCertificateProvider(serverCreds.getPrivateKey(), serverCreds.getCertificateChain(),
Collections.singletonList(CertificateType.X_509)));
dtlsBuilder.setAdvancedCertificateVerifier(
StaticNewAdvancedCertificateVerifier.builder()
.setTrustAllCertificates()
.build());
DTLSConnector connector = new DTLSConnector(dtlsBuilder.build());
CoapEndpoint.Builder endpointBuilder = new CoapEndpoint.Builder();
endpointBuilder.setConfiguration(config);
endpointBuilder.setConnector(connector);
return endpointBuilder.build();
}
private KeyPair generateKeyPair() throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
kpg.initialize(256);
return kpg.generateKeyPair();
}
private X509Certificate generateSelfSignedCert(KeyPair kp, String subjectDn) throws Exception {
X500Name subject = new X500Name(subjectDn);
Date now = new Date();
Date expiry = new Date(now.getTime() + TimeUnit.DAYS.toMillis(1));
return new JcaX509CertificateConverter().getCertificate(
new JcaX509v3CertificateBuilder(
subject, BigInteger.valueOf(System.nanoTime()), now, expiry,
subject, kp.getPublic())
.build(new JcaContentSignerBuilder("SHA256withECDSA").build(kp.getPrivate())));
}
private void writeCertPem(Path path, X509Certificate cert) throws Exception {
try (PemWriter writer = new PemWriter(new OutputStreamWriter(Files.newOutputStream(path)))) {
writer.writeObject(new PemObject("CERTIFICATE", cert.getEncoded()));
}
}
private void writeKeyPem(Path path, KeyPair keyPair) throws Exception {
try (PemWriter writer = new PemWriter(new OutputStreamWriter(Files.newOutputStream(path)))) {
writer.writeObject(new PemObject("PRIVATE KEY", keyPair.getPrivate().getEncoded()));
}
}
private Configuration createServerConfig() {
Configuration config = new Configuration();
config.set(CoapConfig.MAX_RETRANSMIT, 2);
config.set(CoapConfig.RESPONSE_MATCHING, CoapConfig.MatcherMode.RELAXED);
return config;
}
private CoapResponse doDtlsRequest(int port, X509Certificate trustedCert) {
try {
Configuration clientConfig = new Configuration();
clientConfig.set(CoapConfig.MAX_RETRANSMIT, 1);
clientConfig.set(DtlsConfig.DTLS_ROLE, DtlsConfig.DtlsRole.CLIENT_ONLY);
clientConfig.set(DtlsConfig.DTLS_RETRANSMISSION_TIMEOUT, 2000, MILLISECONDS);
clientConfig.set(DtlsConfig.DTLS_USE_HELLO_VERIFY_REQUEST, false);
clientConfig.set(DtlsConfig.DTLS_VERIFY_SERVER_CERTIFICATES_SUBJECT, false);
DtlsConnectorConfig.Builder clientDtls = new DtlsConnectorConfig.Builder(clientConfig);
clientDtls.setAdvancedCertificateVerifier(
StaticNewAdvancedCertificateVerifier.builder()
.setTrustedCertificates(trustedCert)
.build());
DTLSConnector clientConnector = new DTLSConnector(clientDtls.build());
CoapEndpoint clientEndpoint = new CoapEndpoint.Builder()
.setConfiguration(clientConfig)
.setConnector(clientConnector)
.build();
CoapClient client = new CoapClient("coaps://127.0.0.1:" + port + "/" + TEST_RESOURCE_PATH);
client.setEndpoint(clientEndpoint);
client.setTimeout((long) 5000);
try {
clientEndpoint.start();
return client.get();
} finally {
client.shutdown();
clientEndpoint.destroy();
}
} catch (Exception e) {
return null;
}
}
private int findAvailablePort() throws Exception {
try (java.net.DatagramSocket socket = new java.net.DatagramSocket(0)) {
return socket.getLocalPort();
}
}
private static class TestResource extends CoapResource {
TestResource() {
super(TEST_RESOURCE_PATH);
}
@Override
public void handleGET(CoapExchange exchange) {
exchange.respond(CoAP.ResponseCode.CONTENT, TEST_PAYLOAD);
}
}
}

276
common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/MqttSslCertificateReloadIntegrationTest.java

@ -0,0 +1,276 @@
/**
* Copyright © 2016-2026 The Thingsboard Authors
*
* 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.
*/
package org.thingsboard.server.transport.mqtt;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;
import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.transport.config.ssl.PemSslCredentials;
import org.thingsboard.server.common.transport.config.ssl.SslCredentialsConfig;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.net.InetAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(MockitoExtension.class)
public class MqttSslCertificateReloadIntegrationTest {
@TempDir
Path tempDir;
@Mock
private TransportService transportService;
@Test
public void givenMqttSslProvider_whenCertFileChangedAndReloadTriggered_thenNewConnectionSeesNewCert() throws Exception {
KeyPair keyPairA = generateKeyPair();
X509Certificate certA = generateSelfSignedCert(keyPairA, "CN=CertA");
KeyPair keyPairB = generateKeyPair();
X509Certificate certB = generateSelfSignedCert(keyPairB, "CN=CertB");
Path certFile = tempDir.resolve("server-cert.pem");
Path keyFile = tempDir.resolve("server-key.pem");
writeCertPem(certFile, certA);
writeKeyPem(keyFile, keyPairA);
SslCredentialsConfig credentialsConfig = createSslCredentialsConfig(certFile, keyFile);
MqttSslHandlerProvider provider = createMqttSslHandlerProvider(credentialsConfig);
SSLContext ctxA = getProviderSslContext(provider);
X509Certificate servedA;
try (SSLServerSocket ss = createServerSocket(ctxA)) {
servedA = doHandshakeAndGetServerCert(ss);
}
assertThat(servedA.getSubjectX500Principal()).isEqualTo(certA.getSubjectX500Principal());
writeCertPem(certFile, certB);
writeKeyPem(keyFile, keyPairB);
credentialsConfig.onCertificateFileChanged();
SSLContext ctxB = getProviderSslContext(provider);
assertThat(ctxB).isNotSameAs(ctxA);
X509Certificate servedB;
try (SSLServerSocket ss = createServerSocket(ctxB)) {
servedB = doHandshakeAndGetServerCert(ss);
}
assertThat(servedB.getSubjectX500Principal()).isEqualTo(certB.getSubjectX500Principal());
assertThat(servedB.getSubjectX500Principal()).isNotEqualTo(servedA.getSubjectX500Principal());
}
@Test
public void givenMqttSslProvider_whenReloadCalledWithSameFiles_thenSslContextIsRecreated() throws Exception {
KeyPair keyPair = generateKeyPair();
X509Certificate cert = generateSelfSignedCert(keyPair, "CN=SameCert");
Path certFile = tempDir.resolve("server-cert.pem");
Path keyFile = tempDir.resolve("server-key.pem");
writeCertPem(certFile, cert);
writeKeyPem(keyFile, keyPair);
SslCredentialsConfig credentialsConfig = createSslCredentialsConfig(certFile, keyFile);
MqttSslHandlerProvider provider = createMqttSslHandlerProvider(credentialsConfig);
SSLContext ctx1 = getProviderSslContext(provider);
assertThat(ctx1).isNotNull();
credentialsConfig.onCertificateFileChanged();
SSLContext ctx2 = getProviderSslContext(provider);
assertThat(ctx2).isNotSameAs(ctx1);
X509Certificate served;
try (SSLServerSocket ss = createServerSocket(ctx2)) {
served = doHandshakeAndGetServerCert(ss);
}
assertThat(served.getSubjectX500Principal()).isEqualTo(cert.getSubjectX500Principal());
}
@Test
public void givenMqttSslProvider_whenMultipleReloads_thenEachProducesNewContext() throws Exception {
KeyPair keyPairA = generateKeyPair();
X509Certificate certA = generateSelfSignedCert(keyPairA, "CN=CertA");
KeyPair keyPairB = generateKeyPair();
X509Certificate certB = generateSelfSignedCert(keyPairB, "CN=CertB");
KeyPair keyPairC = generateKeyPair();
X509Certificate certC = generateSelfSignedCert(keyPairC, "CN=CertC");
Path certFile = tempDir.resolve("server-cert.pem");
Path keyFile = tempDir.resolve("server-key.pem");
writeCertPem(certFile, certA);
writeKeyPem(keyFile, keyPairA);
SslCredentialsConfig credentialsConfig = createSslCredentialsConfig(certFile, keyFile);
MqttSslHandlerProvider provider = createMqttSslHandlerProvider(credentialsConfig);
SSLContext ctx1 = getProviderSslContext(provider);
writeCertPem(certFile, certB);
writeKeyPem(keyFile, keyPairB);
credentialsConfig.onCertificateFileChanged();
SSLContext ctx2 = getProviderSslContext(provider);
writeCertPem(certFile, certC);
writeKeyPem(keyFile, keyPairC);
credentialsConfig.onCertificateFileChanged();
SSLContext ctx3 = getProviderSslContext(provider);
assertThat(ctx1).isNotSameAs(ctx2);
assertThat(ctx2).isNotSameAs(ctx3);
X509Certificate served;
try (SSLServerSocket ss = createServerSocket(ctx3)) {
served = doHandshakeAndGetServerCert(ss);
}
assertThat(served.getSubjectX500Principal()).isEqualTo(certC.getSubjectX500Principal());
}
private SslCredentialsConfig createSslCredentialsConfig(Path certFile, Path keyFile) throws Exception {
PemSslCredentials pem = new PemSslCredentials();
pem.setCertFile(certFile.toAbsolutePath().toString());
pem.setKeyFile(keyFile.toAbsolutePath().toString());
SslCredentialsConfig config = new SslCredentialsConfig("MQTT SSL Test", false);
config.setEnabled(true);
config.setType(org.thingsboard.server.common.transport.config.ssl.SslCredentialsType.PEM);
config.setPem(pem);
config.setKeystore(new org.thingsboard.server.common.transport.config.ssl.KeystoreSslCredentials());
config.init();
return config;
}
private MqttSslHandlerProvider createMqttSslHandlerProvider(SslCredentialsConfig credentialsConfig) {
MqttSslHandlerProvider provider = new MqttSslHandlerProvider();
ReflectionTestUtils.setField(provider, "sslProtocol", "TLSv1.2");
ReflectionTestUtils.setField(provider, "mqttSslCredentialsConfig", credentialsConfig);
ReflectionTestUtils.setField(provider, "transportService", transportService);
provider.afterSingletonsInstantiated();
return provider;
}
/**
* Triggers SSLContext creation through the provider's getSslHandler() path,
* then extracts the cached SSLContext for direct server socket use.
*/
private SSLContext getProviderSslContext(MqttSslHandlerProvider provider) {
provider.getSslHandler();
return (SSLContext) ReflectionTestUtils.getField(provider, "sslContext");
}
private KeyPair generateKeyPair() throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
return kpg.generateKeyPair();
}
private X509Certificate generateSelfSignedCert(KeyPair kp, String subjectDn) throws Exception {
X500Name subject = new X500Name(subjectDn);
Date now = new Date();
Date expiry = new Date(now.getTime() + TimeUnit.DAYS.toMillis(1));
return new JcaX509CertificateConverter().getCertificate(
new JcaX509v3CertificateBuilder(
subject, BigInteger.valueOf(System.nanoTime()), now, expiry,
subject, kp.getPublic())
.build(new JcaContentSignerBuilder("SHA256withRSA").build(kp.getPrivate())));
}
private void writeCertPem(Path path, X509Certificate cert) throws Exception {
try (PemWriter writer = new PemWriter(new OutputStreamWriter(Files.newOutputStream(path)))) {
writer.writeObject(new PemObject("CERTIFICATE", cert.getEncoded()));
}
}
private void writeKeyPem(Path path, KeyPair keyPair) throws Exception {
try (PemWriter writer = new PemWriter(new OutputStreamWriter(Files.newOutputStream(path)))) {
writer.writeObject(new PemObject("PRIVATE KEY", keyPair.getPrivate().getEncoded()));
}
}
private SSLServerSocket createServerSocket(SSLContext ctx) throws Exception {
return (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(0, 1, InetAddress.getLoopbackAddress());
}
private X509Certificate doHandshakeAndGetServerCert(SSLServerSocket serverSocket) throws Exception {
Thread acceptor = new Thread(() -> {
try (var conn = serverSocket.accept()) {
conn.getInputStream().read();
} catch (Exception ignored) {}
});
acceptor.setDaemon(true);
acceptor.start();
SSLContext clientCtx = SSLContext.getInstance("TLSv1.2");
clientCtx.init(null, new TrustManager[]{new TrustAllManager()}, null);
try (SSLSocket client = (SSLSocket) clientCtx.getSocketFactory()
.createSocket(InetAddress.getLoopbackAddress(), serverSocket.getLocalPort())) {
client.setSoTimeout(5000);
client.startHandshake();
Certificate[] peerCerts = client.getSession().getPeerCertificates();
assertThat(peerCerts).isNotEmpty();
return (X509Certificate) peerCerts[0];
} finally {
acceptor.join(5000);
}
}
private static class TrustAllManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
}
Loading…
Cancel
Save