From 67a6cbfe23391dfc256c55b4080e58b6fbfc3e91 Mon Sep 17 00:00:00 2001 From: JiaLin Date: Sun, 26 Jul 2020 02:01:59 +0800 Subject: [PATCH] change format for check style --- spring-cloud-config-client-tls-tests/pom.xml | 31 ++- .../cloud/config/client/AppRunner.java | 183 ++++++------- .../cloud/config/client/BaseCertTest.java | 123 +++++---- .../cloud/config/client/ConfigClientTest.java | 236 ++++++++--------- .../cloud/config/client/KeyAndCert.java | 131 ++++----- .../cloud/config/client/KeyTool.java | 158 +++++------ .../config/client/TlsConfigClientRunner.java | 75 +++--- .../config/client/TlsConfigServerRunner.java | 59 +++-- .../test/config/application.properties | 2 +- .../config/client/ConfigClientProperties.java | 250 +++++++++--------- .../ConfigServicePropertySourceLocator.java | 40 +-- 11 files changed, 670 insertions(+), 618 deletions(-) diff --git a/spring-cloud-config-client-tls-tests/pom.xml b/spring-cloud-config-client-tls-tests/pom.xml index e442991f..40ab9edd 100644 --- a/spring-cloud-config-client-tls-tests/pom.xml +++ b/spring-cloud-config-client-tls-tests/pom.xml @@ -20,30 +20,37 @@ This project is a Spring configuration client. ]]> + + + 2.4.0-M1 + - - org.springframework.cloud - spring-cloud-config-client - ${project.version} - org.springframework.cloud spring-cloud-config-server ${project.version} + + org.springframework.cloud + spring-cloud-config-client + ${project.version} + + org.springframework.boot - spring-boot-configuration-processor - true + spring-boot + ${spring.boot.version} org.springframework.boot spring-boot-autoconfigure + ${spring.boot.version} org.springframework.boot spring-boot-starter-logging + ${spring.boot.version} true @@ -70,11 +77,13 @@ org.springframework.boot spring-boot-starter-actuator + ${spring.boot.version} true org.springframework.boot spring-boot-starter-aop + ${spring.boot.version} true @@ -84,23 +93,21 @@ org.springframework.boot spring-boot-autoconfigure-processor + ${spring.boot.version} true org.springframework.boot spring-boot-starter-test + ${spring.boot.version} test + org.junit.vintage junit-vintage-engine test - - org.springframework.cloud - spring-cloud-test-support - test - org.bouncycastle bcpkix-jdk15on diff --git a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/AppRunner.java b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/AppRunner.java index 2c9d950a..b7b719c3 100644 --- a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/AppRunner.java +++ b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/AppRunner.java @@ -28,95 +28,98 @@ import org.springframework.util.SocketUtils; public class AppRunner implements AutoCloseable { - private Class appClass; - private Map props; - - private ConfigurableApplicationContext app; - - public AppRunner(Class appClass) { - this.appClass = appClass; - props = new LinkedHashMap<>(); - } - - public void property(String key, String value) { - props.put(key, value); - } - - public void start() { - if (app == null) { - SpringApplicationBuilder builder = new SpringApplicationBuilder(appClass); - builder.properties("spring.jmx.enabled=false"); - builder.properties(String.format("server.port=%d", availabeTcpPort())); - builder.properties(props()); - - app = builder.build().run(); - } - } - - private int availabeTcpPort() { - return SocketUtils.findAvailableTcpPort(); - } - - private String [] props() { - List result = new ArrayList<>(); - - for (String key : props.keySet()) { - String value = props.get(key); - result.add(String.format("%s=%s", key, value)); - } - - return result.toArray(new String [0]); - } - - public void stop() { - if (app != null) { - app.stop(); - app = null; - } - } - - public ConfigurableApplicationContext app() { - return app; - } - - public String getProperty(String key) { - return app.getEnvironment().getProperty(key); - } - - public T getBean(Class type) { - return app.getBean(type); - } - - public ApplicationContext parent() { - return app.getParent(); - } - - public Map getParentBeans(Class type) { - return parent().getBeansOfType(type); - } - - public int port() { - if (app == null) { - throw new RuntimeException("App is not running."); - } - return app.getEnvironment().getProperty("server.port", Integer.class, -1); - } - - public String root() { - if (app == null) { - throw new RuntimeException("App is not running."); - } - - String protocol = tlsEnabled() ? "https" : "http"; - return String.format("%s://localhost:%d/", protocol, port()); - } - - private boolean tlsEnabled() { - return app.getEnvironment().getProperty("server.ssl.enabled", Boolean.class, false); - } + private Class appClass; + + private Map props; + + private ConfigurableApplicationContext app; + + public AppRunner(Class appClass) { + this.appClass = appClass; + props = new LinkedHashMap<>(); + } + + public void property(String key, String value) { + props.put(key, value); + } + + public void start() { + if (app == null) { + SpringApplicationBuilder builder = new SpringApplicationBuilder(appClass); + builder.properties("spring.jmx.enabled=false"); + builder.properties(String.format("server.port=%d", availabeTcpPort())); + builder.properties(props()); + + app = builder.build().run(); + } + } + + private int availabeTcpPort() { + return SocketUtils.findAvailableTcpPort(); + } + + private String[] props() { + List result = new ArrayList<>(); + + for (String key : props.keySet()) { + String value = props.get(key); + result.add(String.format("%s=%s", key, value)); + } + + return result.toArray(new String[0]); + } + + public void stop() { + if (app != null) { + app.stop(); + app = null; + } + } + + public ConfigurableApplicationContext app() { + return app; + } + + public String getProperty(String key) { + return app.getEnvironment().getProperty(key); + } + + public T getBean(Class type) { + return app.getBean(type); + } + + public ApplicationContext parent() { + return app.getParent(); + } + + public Map getParentBeans(Class type) { + return parent().getBeansOfType(type); + } + + public int port() { + if (app == null) { + throw new RuntimeException("App is not running."); + } + return app.getEnvironment().getProperty("server.port", Integer.class, -1); + } + + public String root() { + if (app == null) { + throw new RuntimeException("App is not running."); + } + + String protocol = tlsEnabled() ? "https" : "http"; + return String.format("%s://localhost:%d/", protocol, port()); + } + + private boolean tlsEnabled() { + return app.getEnvironment().getProperty("server.ssl.enabled", Boolean.class, + false); + } + + @Override + public void close() { + stop(); + } - @Override - public void close() { - stop(); - } } diff --git a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/BaseCertTest.java b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/BaseCertTest.java index 2d252118..bf0a555e 100644 --- a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/BaseCertTest.java +++ b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/BaseCertTest.java @@ -24,61 +24,70 @@ import java.security.KeyStore; import org.junit.BeforeClass; public class BaseCertTest { - - protected static final String KEY_STORE_PASSWORD = "test-key-store-password"; - protected static final String KEY_PASSWORD = "test-key-password"; - protected static final String WRONG_PASSWORD = "test-wrong-password"; - - protected static File caCert; - protected static File wrongCaCert; - - protected static File serverCert; - protected static File clientCert; - protected static File wrongClientCert; - - @BeforeClass - public static void createCertificates() throws Exception { - KeyTool tool = new KeyTool(); - - KeyAndCert ca = tool.createCA("MyCA"); - KeyAndCert server = ca.sign("server"); - KeyAndCert client = ca.sign("client"); - - caCert = saveCert(ca); - serverCert = saveKeyAndCert(server); - clientCert = saveKeyAndCert(client); - - KeyAndCert wrongCa = tool.createCA("WrongCA"); - KeyAndCert wrongClient = wrongCa.sign("client"); - - wrongCaCert = saveCert(wrongCa); - wrongClientCert = saveKeyAndCert(wrongClient); - - System.setProperty("javax.net.ssl.trustStore", caCert.getAbsolutePath()); - System.setProperty("javax.net.ssl.trustStorePassword", KEY_STORE_PASSWORD); - } - - private static File saveKeyAndCert(KeyAndCert keyCert) throws Exception { - return saveKeyStore(keyCert.subject(), () -> keyCert.storeKeyAndCert(KEY_PASSWORD)); - } - - private static File saveCert(KeyAndCert keyCert) throws Exception { - return saveKeyStore(keyCert.subject(), () -> keyCert.storeCert()); - } - - private static File saveKeyStore(String prefix, KeyStoreSupplier func) throws Exception { - File result = File.createTempFile(prefix, ".p12"); - result.deleteOnExit(); - - try (OutputStream output = new FileOutputStream(result)) { - KeyStore store = func.createKeyStore(); - store.store(output, KEY_STORE_PASSWORD.toCharArray()); - } - return result; - } - - interface KeyStoreSupplier { - - public KeyStore createKeyStore() throws Exception; - } + + protected static final String KEY_STORE_PASSWORD = "test-key-store-password"; + + protected static final String KEY_PASSWORD = "test-key-password"; + + protected static final String WRONG_PASSWORD = "test-wrong-password"; + + protected static File caCert; + + protected static File wrongCaCert; + + protected static File serverCert; + + protected static File clientCert; + + protected static File wrongClientCert; + + @BeforeClass + public static void createCertificates() throws Exception { + KeyTool tool = new KeyTool(); + + KeyAndCert ca = tool.createCA("MyCA"); + KeyAndCert server = ca.sign("server"); + KeyAndCert client = ca.sign("client"); + + caCert = saveCert(ca); + serverCert = saveKeyAndCert(server); + clientCert = saveKeyAndCert(client); + + KeyAndCert wrongCa = tool.createCA("WrongCA"); + KeyAndCert wrongClient = wrongCa.sign("client"); + + wrongCaCert = saveCert(wrongCa); + wrongClientCert = saveKeyAndCert(wrongClient); + + System.setProperty("javax.net.ssl.trustStore", caCert.getAbsolutePath()); + System.setProperty("javax.net.ssl.trustStorePassword", KEY_STORE_PASSWORD); + } + + private static File saveKeyAndCert(KeyAndCert keyCert) throws Exception { + return saveKeyStore(keyCert.subject(), + () -> keyCert.storeKeyAndCert(KEY_PASSWORD)); + } + + private static File saveCert(KeyAndCert keyCert) throws Exception { + return saveKeyStore(keyCert.subject(), () -> keyCert.storeCert()); + } + + private static File saveKeyStore(String prefix, KeyStoreSupplier func) + throws Exception { + File result = File.createTempFile(prefix, ".p12"); + result.deleteOnExit(); + + try (OutputStream output = new FileOutputStream(result)) { + KeyStore store = func.createKeyStore(); + store.store(output, KEY_STORE_PASSWORD.toCharArray()); + } + return result; + } + + interface KeyStoreSupplier { + + KeyStore createKeyStore() throws Exception; + + } + } diff --git a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/ConfigClientTest.java b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/ConfigClientTest.java index bdfafa07..38f35ee1 100644 --- a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/ConfigClientTest.java +++ b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/ConfigClientTest.java @@ -16,134 +16,130 @@ package org.springframework.cloud.config.client; -import static org.junit.Assert.*; - import java.io.File; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; + import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.cloud.config.server.EnableConfigServer; +import static org.assertj.core.api.Assertions.assertThat; + public class ConfigClientTest extends BaseCertTest { - - private static TlsConfigServerRunner server; - - @BeforeClass - public static void setupAll() throws Exception { - startConfigServer(); - } - - @AfterClass - public static void tearDownAll() { - stopConfigServer(); - } - - private static void startConfigServer() { - server = new TlsConfigServerRunner(TestConfigServer.class); - server.enableTls(); - server.setKeyStore(serverCert, KEY_STORE_PASSWORD, "server", KEY_PASSWORD); - server.setTrustStore(caCert, KEY_STORE_PASSWORD); - - server.start(); - } - - private static void stopConfigServer() { - server.stop(); - } - - @Test - public void clientCertCanWork() { - try (TlsConfigClientRunner client = createConfigClient()) { - enableTlsClient(client); - client.start(); - assertEquals("dumb-value", client.getProperty("dumb.key")); - } - } - - @Test - public void tlsClientCanBeDisabled() { - try (TlsConfigClientRunner client = createConfigClient()) { - enableTlsClient(client); - client.property("spring.cloud.config.enabled", "false"); - client.start(); - assertNull(client.getProperty("dumb.key")); - } - } - - @Test - public void noCertCannotWork() { - try (TlsConfigClientRunner client = createConfigClient()) { - client.disableTls(); - client.start(); - assertNull(client.getProperty("dumb.key")); - } - } - - @Test - public void wrongCertCannotWork() { - try (TlsConfigClientRunner client = createConfigClient()) { - enableTlsClient(client); - client.setKeyStore(wrongClientCert); - client.start(); - assertNull(client.getProperty("dumb.key")); - } - } - - @Test(expected = IllegalStateException.class) - public void wrongPasswordCauseFailure() { - TlsConfigClientRunner client = createConfigClient(); - enableTlsClient(client); - client.setKeyStore(clientCert, WRONG_PASSWORD, WRONG_PASSWORD); - client.start(); - } - - @Test(expected = IllegalStateException.class) - public void nonExistKeyStoreCauseFailure() { - TlsConfigClientRunner client = createConfigClient(); - enableTlsClient(client); - client.setKeyStore(new File("nonExistFile")); - client.start(); - } - - @Test - public void wrongTrustStoreCannotWork() { - try (TlsConfigClientRunner client = createConfigClient()) { - enableTlsClient(client); - client.setTrustStore(wrongCaCert); - client.start(); - assertNull(client.getProperty("dumb.key")); - } - } - - @Test - public void onlyOneLocator() { - try (TlsConfigClientRunner client = createConfigClient()) { - enableTlsClient(client); - client.start(); - - assertEquals(1, client.getParentBeans(ConfigServicePropertySourceLocator.class).size()); - } - } - - private TlsConfigClientRunner createConfigClient() { - return new TlsConfigClientRunner(TestApp.class, server); - } - - private void enableTlsClient(TlsConfigClientRunner runner) { - runner.enableTls(); - runner.setKeyStore(clientCert, KEY_STORE_PASSWORD, KEY_PASSWORD); - runner.setTrustStore(caCert, KEY_STORE_PASSWORD); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - public static class TestApp {} - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableConfigServer - public static class TestConfigServer {} + + private static TlsConfigServerRunner server; + + @BeforeClass + public static void setupAll() throws Exception { + startConfigServer(); + } + + @AfterClass + public static void tearDownAll() { + stopConfigServer(); + } + + private static void startConfigServer() { + server = new TlsConfigServerRunner(TestConfigServer.class); + server.enableTls(); + server.setKeyStore(serverCert, KEY_STORE_PASSWORD, "server", KEY_PASSWORD); + server.setTrustStore(caCert, KEY_STORE_PASSWORD); + + server.start(); + } + + private static void stopConfigServer() { + server.stop(); + } + + @Test + public void clientCertCanWork() { + try (TlsConfigClientRunner client = createConfigClient()) { + enableTlsClient(client); + client.start(); + assertThat(client.getProperty("dumb.key")).isEqualTo("dumb-value"); + } + } + + @Test + public void tlsClientCanBeDisabled() { + try (TlsConfigClientRunner client = createConfigClient()) { + enableTlsClient(client); + client.property("spring.cloud.config.enabled", "false"); + client.start(); + assertThat(client.getProperty("dumb.key")).isNull(); + } + } + + @Test + public void noCertCannotWork() { + try (TlsConfigClientRunner client = createConfigClient()) { + client.disableTls(); + client.start(); + assertThat(client.getProperty("dumb.key")).isNull(); + } + } + + @Test + public void wrongCertCannotWork() { + try (TlsConfigClientRunner client = createConfigClient()) { + enableTlsClient(client); + client.setKeyStore(wrongClientCert); + client.start(); + assertThat(client.getProperty("dumb.key")).isNull(); + } + } + + @Test(expected = IllegalStateException.class) + public void wrongPasswordCauseFailure() { + TlsConfigClientRunner client = createConfigClient(); + enableTlsClient(client); + client.setKeyStore(clientCert, WRONG_PASSWORD, WRONG_PASSWORD); + client.start(); + } + + @Test(expected = IllegalStateException.class) + public void nonExistKeyStoreCauseFailure() { + TlsConfigClientRunner client = createConfigClient(); + enableTlsClient(client); + client.setKeyStore(new File("nonExistFile")); + client.start(); + } + + @Test + public void wrongTrustStoreCannotWork() { + try (TlsConfigClientRunner client = createConfigClient()) { + enableTlsClient(client); + client.setTrustStore(wrongCaCert); + client.start(); + assertThat(client.getProperty("dumb.key")).isNull(); + } + } + + private TlsConfigClientRunner createConfigClient() { + return new TlsConfigClientRunner(TestApp.class, server); + } + + private void enableTlsClient(TlsConfigClientRunner runner) { + runner.enableTls(); + runner.setKeyStore(clientCert, KEY_STORE_PASSWORD, KEY_PASSWORD); + runner.setTrustStore(caCert, KEY_STORE_PASSWORD); + } + + @SpringBootConfiguration + @EnableAutoConfiguration + public static class TestApp { + + } + + @SpringBootConfiguration + @EnableAutoConfiguration + @EnableConfigServer + public static class TestConfigServer { + + } + } diff --git a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/KeyAndCert.java b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/KeyAndCert.java index 218a5eb2..4c58a125 100644 --- a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/KeyAndCert.java +++ b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/KeyAndCert.java @@ -24,68 +24,71 @@ import java.security.cert.Certificate; import java.security.cert.X509Certificate; public class KeyAndCert { - - private KeyPair keyPair; - private X509Certificate certificate; - - public KeyAndCert(KeyPair keyPair, X509Certificate certificate) { - this.keyPair = keyPair; - this.certificate = certificate; - } - - public KeyPair keyPair() { - return keyPair; - } - - public PublicKey publicKey() { - return keyPair.getPublic(); - } - - public PrivateKey privateKey() { - return keyPair.getPrivate(); - } - - public X509Certificate certificate() { - return certificate; - } - - public String subject() { - String dn = certificate.getSubjectDN().getName(); - int index = dn.indexOf('='); - return dn.substring(index + 1); - } - - public KeyAndCert sign(String subject) throws Exception { - KeyTool tool = new KeyTool(); - return tool.signCertificate(subject, this); - } - - public KeyAndCert sign(KeyPair keyPair, String subject) throws Exception { - KeyTool tool = new KeyTool(); - return tool.signCertificate(keyPair, subject, this); - } - - public KeyStore storeKeyAndCert(String keyPassword) throws Exception { - KeyStore result = KeyStore.getInstance("PKCS12"); - result.load(null); - - result.setKeyEntry(subject(), keyPair.getPrivate(), keyPassword.toCharArray(), certChain()); - return result; - } - - private Certificate [] certChain() { - return new Certificate [] {certificate()}; - } - - public KeyStore storeCert() throws Exception { - return storeCert("PKCS12"); - } - - public KeyStore storeCert(String storeType) throws Exception { - KeyStore result = KeyStore.getInstance(storeType); - result.load(null); - - result.setCertificateEntry(subject(), certificate()); - return result; - } + + private KeyPair keyPair; + + private X509Certificate certificate; + + public KeyAndCert(KeyPair keyPair, X509Certificate certificate) { + this.keyPair = keyPair; + this.certificate = certificate; + } + + public KeyPair keyPair() { + return keyPair; + } + + public PublicKey publicKey() { + return keyPair.getPublic(); + } + + public PrivateKey privateKey() { + return keyPair.getPrivate(); + } + + public X509Certificate certificate() { + return certificate; + } + + public String subject() { + String dn = certificate.getSubjectDN().getName(); + int index = dn.indexOf('='); + return dn.substring(index + 1); + } + + public KeyAndCert sign(String subject) throws Exception { + KeyTool tool = new KeyTool(); + return tool.signCertificate(subject, this); + } + + public KeyAndCert sign(KeyPair keyPair, String subject) throws Exception { + KeyTool tool = new KeyTool(); + return tool.signCertificate(keyPair, subject, this); + } + + public KeyStore storeKeyAndCert(String keyPassword) throws Exception { + KeyStore result = KeyStore.getInstance("PKCS12"); + result.load(null); + + result.setKeyEntry(subject(), keyPair.getPrivate(), keyPassword.toCharArray(), + certChain()); + return result; + } + + private Certificate[] certChain() { + return new Certificate[] { certificate() }; + } + + public KeyStore storeCert() throws Exception { + return storeCert("PKCS12"); + } + + public KeyStore storeCert(String storeType) throws Exception { + KeyStore result = KeyStore.getInstance(storeType); + result.load(null); + + result.setCertificateEntry(subject(), certificate()); + return result; + } + } diff --git a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/KeyTool.java b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/KeyTool.java index fd13c701..1ee56ea3 100644 --- a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/KeyTool.java +++ b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/KeyTool.java @@ -39,78 +39,88 @@ import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; public class KeyTool { - - private static final long ONE_DAY = 1000L * 60L * 60L * 24L; - private static final long TEN_YEARS = ONE_DAY * 365L * 10L; - - public KeyAndCert createCA(String ca) throws Exception { - KeyPair keyPair = createKeyPair(); - X509Certificate certificate = createCert(keyPair, ca); - return new KeyAndCert(keyPair, certificate); - } - - public KeyAndCert signCertificate(String subject, KeyAndCert signer) throws Exception { - return signCertificate(createKeyPair(), subject, signer); - } - - public KeyAndCert signCertificate(KeyPair keyPair, String subject, KeyAndCert signer) throws Exception { - X509Certificate certificate = createCert(keyPair.getPublic(), signer.privateKey(), signer.subject(), subject); - KeyAndCert result = new KeyAndCert(keyPair, certificate); - - return result; - } - - public KeyPair createKeyPair() throws Exception { - return createKeyPair(1024); - } - - public KeyPair createKeyPair(int keySize) throws Exception { - KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA"); - gen.initialize(keySize, new SecureRandom()); - return gen.generateKeyPair(); - } - - public X509Certificate createCert(KeyPair keyPair, String ca) throws Exception { - JcaX509v3CertificateBuilder builder = certBuilder(keyPair.getPublic(), ca, ca); - builder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.keyCertSign)); - builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(true)); - - return signCert(builder, keyPair.getPrivate()); - } - - public X509Certificate createCert(PublicKey publicKey, PrivateKey privateKey, String issuer, String subject) throws Exception { - JcaX509v3CertificateBuilder builder = certBuilder(publicKey, issuer, subject); - builder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature)); - builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(false)); - - GeneralName [] names = new GeneralName [] { new GeneralName(GeneralName.dNSName, "localhost") }; - builder.addExtension(Extension.subjectAlternativeName, false, GeneralNames.getInstance(new DERSequence(names))); - - return signCert(builder, privateKey); - } - - private JcaX509v3CertificateBuilder certBuilder(PublicKey publicKey, String issuer, String subject) { - X500Name issuerName = new X500Name(String.format("dc=%s", issuer)); - X500Name subjectName = new X500Name(String.format("dc=%s", subject)); - - long now = System.currentTimeMillis(); - BigInteger serialNum = BigInteger.valueOf(now); - Date notBefore = new Date(now - ONE_DAY); - Date notAfter = new Date(now + TEN_YEARS); - - return new JcaX509v3CertificateBuilder( - issuerName, - serialNum, - notBefore, - notAfter, - subjectName, - publicKey); - } - - private X509Certificate signCert(JcaX509v3CertificateBuilder builder, PrivateKey privateKey) throws Exception { - ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA").build(privateKey); - X509CertificateHolder holder = builder.build(signer); - - return new JcaX509CertificateConverter().getCertificate(holder); - } + + private static final long ONE_DAY = 1000L * 60L * 60L * 24L; + + private static final long TEN_YEARS = ONE_DAY * 365L * 10L; + + public KeyAndCert createCA(String ca) throws Exception { + KeyPair keyPair = createKeyPair(); + X509Certificate certificate = createCert(keyPair, ca); + return new KeyAndCert(keyPair, certificate); + } + + public KeyAndCert signCertificate(String subject, KeyAndCert signer) + throws Exception { + return signCertificate(createKeyPair(), subject, signer); + } + + public KeyAndCert signCertificate(KeyPair keyPair, String subject, KeyAndCert signer) + throws Exception { + X509Certificate certificate = createCert(keyPair.getPublic(), signer.privateKey(), + signer.subject(), subject); + KeyAndCert result = new KeyAndCert(keyPair, certificate); + + return result; + } + + public KeyPair createKeyPair() throws Exception { + return createKeyPair(1024); + } + + public KeyPair createKeyPair(int keySize) throws Exception { + KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA"); + gen.initialize(keySize, new SecureRandom()); + return gen.generateKeyPair(); + } + + public X509Certificate createCert(KeyPair keyPair, String ca) throws Exception { + JcaX509v3CertificateBuilder builder = certBuilder(keyPair.getPublic(), ca, ca); + builder.addExtension(Extension.keyUsage, true, + new KeyUsage(KeyUsage.keyCertSign)); + builder.addExtension(Extension.basicConstraints, false, + new BasicConstraints(true)); + + return signCert(builder, keyPair.getPrivate()); + } + + public X509Certificate createCert(PublicKey publicKey, PrivateKey privateKey, + String issuer, String subject) throws Exception { + JcaX509v3CertificateBuilder builder = certBuilder(publicKey, issuer, subject); + builder.addExtension(Extension.keyUsage, true, + new KeyUsage(KeyUsage.digitalSignature)); + builder.addExtension(Extension.basicConstraints, false, + new BasicConstraints(false)); + + GeneralName[] names = new GeneralName[] { + new GeneralName(GeneralName.dNSName, "localhost") }; + builder.addExtension(Extension.subjectAlternativeName, false, + GeneralNames.getInstance(new DERSequence(names))); + + return signCert(builder, privateKey); + } + + private JcaX509v3CertificateBuilder certBuilder(PublicKey publicKey, String issuer, + String subject) { + X500Name issuerName = new X500Name(String.format("dc=%s", issuer)); + X500Name subjectName = new X500Name(String.format("dc=%s", subject)); + + long now = System.currentTimeMillis(); + BigInteger serialNum = BigInteger.valueOf(now); + Date notBefore = new Date(now - ONE_DAY); + Date notAfter = new Date(now + TEN_YEARS); + + return new JcaX509v3CertificateBuilder(issuerName, serialNum, notBefore, notAfter, + subjectName, publicKey); + } + + private X509Certificate signCert(JcaX509v3CertificateBuilder builder, + PrivateKey privateKey) throws Exception { + ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA") + .build(privateKey); + X509CertificateHolder holder = builder.build(signer); + + return new JcaX509CertificateConverter().getCertificate(holder); + } + } diff --git a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/TlsConfigClientRunner.java b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/TlsConfigClientRunner.java index c1ef9446..d5ea3f88 100644 --- a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/TlsConfigClientRunner.java +++ b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/TlsConfigClientRunner.java @@ -20,41 +20,42 @@ import java.io.File; public class TlsConfigClientRunner extends AppRunner { - public TlsConfigClientRunner(Class appClass, AppRunner server) { - super(appClass); - - property("spring.cloud.config.uri", server.root()); - property("spring.cloud.config.enabled", "true"); - } - - public void enableTls() { - property("spring.cloud.config.tls.enabled", "true"); - } - - public void disableTls() { - property("spring.cloud.config.tls.enabled", "false"); - } - - public void setKeyStore(File keyStore, String keyStorePassword, String keyPassword) { - property("spring.cloud.config.tls.key-store", pathOf(keyStore)); - property("spring.cloud.config.tls.key-store-password", keyStorePassword); - property("spring.cloud.config.tls.key-password", keyPassword); - } - - public void setKeyStore(File keyStore) { - property("spring.cloud.config.tls.key-store", pathOf(keyStore)); - } - - public void setTrustStore(File trustStore, String password) { - property("spring.cloud.config.tls.trust-store", pathOf(trustStore)); - property("spring.cloud.config.tls.trust-store-password", password); - } - - public void setTrustStore(File trustStore) { - property("spring.cloud.config.tls.trust-store", pathOf(trustStore)); - } - - private String pathOf(File file) { - return String.format("file:%s", file.getAbsolutePath()); - } + public TlsConfigClientRunner(Class appClass, AppRunner server) { + super(appClass); + + property("spring.cloud.config.uri", server.root()); + property("spring.cloud.config.enabled", "true"); + } + + public void enableTls() { + property("spring.cloud.config.tls.enabled", "true"); + } + + public void disableTls() { + property("spring.cloud.config.tls.enabled", "false"); + } + + public void setKeyStore(File keyStore, String keyStorePassword, String keyPassword) { + property("spring.cloud.config.tls.key-store", pathOf(keyStore)); + property("spring.cloud.config.tls.key-store-password", keyStorePassword); + property("spring.cloud.config.tls.key-password", keyPassword); + } + + public void setKeyStore(File keyStore) { + property("spring.cloud.config.tls.key-store", pathOf(keyStore)); + } + + public void setTrustStore(File trustStore, String password) { + property("spring.cloud.config.tls.trust-store", pathOf(trustStore)); + property("spring.cloud.config.tls.trust-store-password", password); + } + + public void setTrustStore(File trustStore) { + property("spring.cloud.config.tls.trust-store", pathOf(trustStore)); + } + + private String pathOf(File file) { + return String.format("file:%s", file.getAbsolutePath()); + } + } diff --git a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/TlsConfigServerRunner.java b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/TlsConfigServerRunner.java index 8d435240..c585bf8d 100644 --- a/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/TlsConfigServerRunner.java +++ b/spring-cloud-config-client-tls-tests/src/test/java/org/springframework/cloud/config/client/TlsConfigServerRunner.java @@ -20,32 +20,35 @@ import java.io.File; public class TlsConfigServerRunner extends AppRunner { - public TlsConfigServerRunner(Class appClass) { - super(appClass); - property("spring.profiles.active", "native"); - property("spring.cloud.config.server.native.search-locations", "classpath:/test/config"); - } - - public void enableTls() { - property("server.ssl.enabled", "true"); - property("server.ssl.client-auth", "need"); - } - - public void setKeyStore(File keyStore, String keyStorePassword, String key, String keyPassword) { - property("server.ssl.key-store", pathOf(keyStore)); - property("server.ssl.key-store-type", "PKCS12"); - property("server.ssl.key-store-password", keyStorePassword); - property("server.ssl.key-alias", key); - property("server.ssl.key-password", keyPassword); - } - - public void setTrustStore(File trustStore, String password) { - property("server.ssl.trust-store", pathOf(trustStore)); - property("server.ssl.trust-store-type", "PKCS12"); - property("server.ssl.trust-store-password", password); - } - - private String pathOf(File file) { - return String.format("file:%s", file.getAbsolutePath()); - } + public TlsConfigServerRunner(Class appClass) { + super(appClass); + property("spring.profiles.active", "native"); + property("spring.cloud.config.server.native.search-locations", + "classpath:/test/config"); + } + + public void enableTls() { + property("server.ssl.enabled", "true"); + property("server.ssl.client-auth", "need"); + } + + public void setKeyStore(File keyStore, String keyStorePassword, String key, + String keyPassword) { + property("server.ssl.key-store", pathOf(keyStore)); + property("server.ssl.key-store-type", "PKCS12"); + property("server.ssl.key-store-password", keyStorePassword); + property("server.ssl.key-alias", key); + property("server.ssl.key-password", keyPassword); + } + + public void setTrustStore(File trustStore, String password) { + property("server.ssl.trust-store", pathOf(trustStore)); + property("server.ssl.trust-store-type", "PKCS12"); + property("server.ssl.trust-store-password", password); + } + + private String pathOf(File file) { + return String.format("file:%s", file.getAbsolutePath()); + } + } diff --git a/spring-cloud-config-client-tls-tests/src/test/resources/test/config/application.properties b/spring-cloud-config-client-tls-tests/src/test/resources/test/config/application.properties index c5344796..2f4082ae 100644 --- a/spring-cloud-config-client-tls-tests/src/test/resources/test/config/application.properties +++ b/spring-cloud-config-client-tls-tests/src/test/resources/test/config/application.properties @@ -1 +1 @@ -dumb.key=dumb-value \ No newline at end of file +dumb.key=dumb-value diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientProperties.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientProperties.java index d6c84bbe..c23617e0 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientProperties.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientProperties.java @@ -33,6 +33,7 @@ import javax.annotation.PostConstruct; import javax.net.ssl.SSLContext; import org.apache.http.ssl.SSLContextBuilder; + import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -110,9 +111,9 @@ public class ConfigClientProperties { * Discovery properties. */ private Discovery discovery = new Discovery(); - + /** - * TLS properties + * TLS properties. */ private TLS tls = new TLS(); @@ -232,7 +233,7 @@ public class ConfigClientProperties { public void setTls(TLS tls) { this.tls = tls; } - + @PostConstruct public void checkTlsStoreType() { tls.checkStoreType(); @@ -444,37 +445,43 @@ public class ConfigClientProperties { } } - + /** - * TLS properties + * TLS properties. */ public static class TLS { - - private static final String DEFAULT_STORE_TYPE = "PKCS12"; - private static final Map EXTENSION_STORE_TYPES = extTypes(); - - private boolean enabled; + + private static final String DEFAULT_STORE_TYPE = "PKCS12"; + + private static final Map EXTENSION_STORE_TYPES = extTypes(); + + private boolean enabled; private Resource keyStore; - private String keyStoreType; - private String keyStorePassword = ""; - private String keyPassword = ""; - private Resource trustStore; - private String trustStoreType; - private String trustStorePassword = ""; - - private static Map extTypes() { - Map result = new HashMap<>(); + private String keyStoreType; - result.put("p12", "PKCS12"); - result.put("pfx", "PKCS12"); - result.put("jks", "JKS"); + private String keyStorePassword = ""; - return Collections.unmodifiableMap(result); - } - - public boolean isEnabled() { + private String keyPassword = ""; + + private Resource trustStore; + + private String trustStoreType; + + private String trustStorePassword = ""; + + private static Map extTypes() { + Map result = new HashMap<>(); + + result.put("p12", "PKCS12"); + result.put("pfx", "PKCS12"); + result.put("jks", "JKS"); + + return Collections.unmodifiableMap(result); + } + + public boolean isEnabled() { return enabled; } @@ -537,113 +544,120 @@ public class ConfigClientProperties { public void setTrustStorePassword(String trustStorePassword) { this.trustStorePassword = trustStorePassword; } - - public char[] keyStorePassword() { - return keyStorePassword.toCharArray(); - } - - public char[] keyPassword() { - return keyPassword.toCharArray(); - } - + + public char[] keyStorePassword() { + return keyStorePassword.toCharArray(); + } + + public char[] keyPassword() { + return keyPassword.toCharArray(); + } + public char[] trustStorePassword() { - return trustStorePassword.toCharArray(); - } - - public void checkStoreType() { - if (keyStore != null && keyStoreType == null) { - keyStoreType = storeTypeOf(keyStore); - } - if (trustStore != null && trustStoreType == null) { - trustStoreType = storeTypeOf(trustStore); - } - } + return trustStorePassword.toCharArray(); + } - private String storeTypeOf(Resource resource) { - String extension = fileExtensionOf(resource); - String type = EXTENSION_STORE_TYPES.get(extension); + public void checkStoreType() { + if (keyStore != null && keyStoreType == null) { + keyStoreType = storeTypeOf(keyStore); + } + if (trustStore != null && trustStoreType == null) { + trustStoreType = storeTypeOf(trustStore); + } + } - return (type == null) ? DEFAULT_STORE_TYPE : type; - } + private String storeTypeOf(Resource resource) { + String extension = fileExtensionOf(resource); + String type = EXTENSION_STORE_TYPES.get(extension); - private String fileExtensionOf(Resource resource) { - String name = resource.getFilename(); - int index = name.lastIndexOf('.'); + return (type == null) ? DEFAULT_STORE_TYPE : type; + } - return index < 0 ? "" : name.substring(index + 1).toLowerCase(); - } - - public SSLContext createSSLContext() throws GeneralSecurityException, IOException { - SSLContextBuilder builder = new SSLContextBuilder(); - char[] keyPassword = keyPassword(); - KeyStore keyStore = createKeyStore(); + private String fileExtensionOf(Resource resource) { + String name = resource.getFilename(); + int index = name.lastIndexOf('.'); - try { - builder.loadKeyMaterial(keyStore, keyPassword); - } catch (UnrecoverableKeyException e) { - if (keyPassword.length == 0) { - // Retry if empty password, see https://rt.openssl.org/Ticket/Display.html?id=1497&user=guest&pass=guest - builder.loadKeyMaterial(keyStore, new char[]{'\0'}); - } else { - throw e; - } - } + return index < 0 ? "" : name.substring(index + 1).toLowerCase(); + } - KeyStore trust = createTrustStore(); - if (trust != null) { - builder.loadTrustMaterial(trust, null); - } + public SSLContext createSSLContext() + throws GeneralSecurityException, IOException { + SSLContextBuilder builder = new SSLContextBuilder(); + char[] keyPassword = keyPassword(); + KeyStore keyStore = createKeyStore(); - return builder.build(); - } + try { + builder.loadKeyMaterial(keyStore, keyPassword); + } + catch (UnrecoverableKeyException e) { + if (keyPassword.length == 0) { + // Retry if empty password, see + // https://rt.openssl.org/Ticket/Display.html?id=1497&user=guest&pass=guest + builder.loadKeyMaterial(keyStore, new char[] { '\0' }); + } + else { + throw e; + } + } - private KeyStore createKeyStore() throws GeneralSecurityException, IOException { - if (keyStore == null) { - throw new KeyStoreException("Keystore not specified."); - } - if (!keyStore.exists()) { - throw new KeyStoreException("Keystore not exists: " + keyStore); - } + KeyStore trust = createTrustStore(); + if (trust != null) { + builder.loadTrustMaterial(trust, null); + } - KeyStore result = KeyStore.getInstance(keyStoreType); - char[] keyStorePassword = keyStorePassword(); + return builder.build(); + } - try { - loadKeyStore(result, keyStore, keyStorePassword); - } catch (IOException e) { - // Retry if empty password, see https://rt.openssl.org/Ticket/Display.html?id=1497&user=guest&pass=guest - if (keyStorePassword.length == 0) { - loadKeyStore(result, keyStore, new char[]{'\0'}); - } else { - throw e; - } - } + private KeyStore createKeyStore() throws GeneralSecurityException, IOException { + if (keyStore == null) { + throw new KeyStoreException("Keystore not specified."); + } + if (!keyStore.exists()) { + throw new KeyStoreException("Keystore not exists: " + keyStore); + } - return result; - } + KeyStore result = KeyStore.getInstance(keyStoreType); + char[] keyStorePassword = keyStorePassword(); - private static void loadKeyStore(KeyStore keyStore, Resource keyStoreResource, char[] keyStorePassword) - throws IOException, GeneralSecurityException - { - try (InputStream inputStream = keyStoreResource.getInputStream()) { - keyStore.load(inputStream, keyStorePassword); - } - } + try { + loadKeyStore(result, keyStore, keyStorePassword); + } + catch (IOException e) { + // Retry if empty password, see + // https://rt.openssl.org/Ticket/Display.html?id=1497&user=guest&pass=guest + if (keyStorePassword.length == 0) { + loadKeyStore(result, keyStore, new char[] { '\0' }); + } + else { + throw e; + } + } - private KeyStore createTrustStore() throws GeneralSecurityException, IOException { - if (trustStore == null) { - return null; - } - if (!trustStore.exists()) { - throw new KeyStoreException("KeyStore not exists: " + trustStore); - } + return result; + } + + private static void loadKeyStore(KeyStore keyStore, Resource keyStoreResource, + char[] keyStorePassword) throws IOException, GeneralSecurityException { + try (InputStream inputStream = keyStoreResource.getInputStream()) { + keyStore.load(inputStream, keyStorePassword); + } + } + + private KeyStore createTrustStore() throws GeneralSecurityException, IOException { + if (trustStore == null) { + return null; + } + if (!trustStore.exists()) { + throw new KeyStoreException("KeyStore not exists: " + trustStore); + } + + KeyStore result = KeyStore.getInstance(trustStoreType); + try (InputStream input = trustStore.getInputStream()) { + result.load(input, trustStorePassword()); + } + return result; + } - KeyStore result = KeyStore.getInstance(trustStoreType); - try (InputStream input = trustStore.getInputStream()) { - result.load(input, trustStorePassword()); - } - return result; - } } } diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServicePropertySourceLocator.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServicePropertySourceLocator.java index 171cc246..ecd1808a 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServicePropertySourceLocator.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServicePropertySourceLocator.java @@ -33,6 +33,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.client.HttpClient; import org.apache.http.impl.client.HttpClients; + import org.springframework.boot.env.OriginTrackedMapPropertySource; import org.springframework.boot.origin.Origin; import org.springframework.boot.origin.OriginTrackedValue; @@ -308,7 +309,7 @@ public class ConfigServicePropertySourceLocator implements PropertySourceLocator if (client.getRequestConnectTimeout() < 0) { throw new IllegalStateException("Invalid Value for Connect Timeout set."); } - + ClientHttpRequestFactory requestFactory = createHttpRquestFactory(client); RestTemplate template = new RestTemplate(requestFactory); Map headers = new HashMap<>(client.getHeaders()); @@ -322,28 +323,33 @@ public class ConfigServicePropertySourceLocator implements PropertySourceLocator return template; } - - private ClientHttpRequestFactory createHttpRquestFactory(ConfigClientProperties client) { + + private ClientHttpRequestFactory createHttpRquestFactory( + ConfigClientProperties client) { if (client.getTls().isEnabled()) { try { - SSLContext sslContext = client.getTls().createSSLContext(); - HttpClient httpClient = HttpClients.custom().setSSLContext(sslContext).build(); - HttpComponentsClientHttpRequestFactory result = new HttpComponentsClientHttpRequestFactory(httpClient); - - result.setReadTimeout(client.getRequestReadTimeout()); - result.setConnectTimeout(client.getRequestConnectTimeout()); - return result; - - } catch (GeneralSecurityException | IOException ex) { + SSLContext sslContext = client.getTls().createSSLContext(); + HttpClient httpClient = HttpClients.custom().setSSLContext(sslContext) + .build(); + HttpComponentsClientHttpRequestFactory result = new HttpComponentsClientHttpRequestFactory( + httpClient); + + result.setReadTimeout(client.getRequestReadTimeout()); + result.setConnectTimeout(client.getRequestConnectTimeout()); + return result; + + } + catch (GeneralSecurityException | IOException ex) { logger.error(ex); - throw new IllegalStateException("Failed to create config client with TLS.", ex); + throw new IllegalStateException( + "Failed to create config client with TLS.", ex); } } - + SimpleClientHttpRequestFactory result = new SimpleClientHttpRequestFactory(); - result.setReadTimeout(client.getRequestReadTimeout()); - result.setConnectTimeout(client.getRequestConnectTimeout()); - return result; + result.setReadTimeout(client.getRequestReadTimeout()); + result.setConnectTimeout(client.getRequestConnectTimeout()); + return result; } private void addAuthorizationToken(ConfigClientProperties configClientProperties,