From 99986a2fdd686dedd265e5675b29f910948983a3 Mon Sep 17 00:00:00 2001 From: Scott Frederick Date: Thu, 2 Nov 2023 13:53:08 -0500 Subject: [PATCH] Polish SSL internals --- .../ssl/BundleContentProperty.java | 16 ++++++++------ .../ssl/BundleContentPropertyTests.java | 2 +- .../boot/ssl/pem/PemContent.java | 20 ++++++----------- .../boot/ssl/pem/PemContentTests.java | 22 ++++++++----------- 4 files changed, 26 insertions(+), 34 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/BundleContentProperty.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/BundleContentProperty.java index abaace466f4f..7be8e3eceb37 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/BundleContentProperty.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/BundleContentProperty.java @@ -51,11 +51,6 @@ boolean hasValue() { return StringUtils.hasText(this.value); } - private URL toUrl() throws FileNotFoundException { - Assert.state(!isPemContent(), "Value contains PEM content"); - return ResourceUtils.getURL(this.value); - } - Path toWatchPath() { return toPath(); } @@ -63,15 +58,22 @@ Path toWatchPath() { private Path toPath() { try { URL url = toUrl(); - Assert.state(isFileUrl(url), () -> "Vaule '%s' is not a file URL".formatted(url)); + Assert.state(isFileUrl(url), () -> "Value '%s' is not a file URL".formatted(url)); return Path.of(url.toURI()).toAbsolutePath(); } catch (Exception ex) { - throw new IllegalStateException("Unable to convert '%s' property to a path".formatted(this.name), ex); + throw new IllegalStateException("Unable to convert value of property '%s' to a path".formatted(this.name), + ex); } } + private URL toUrl() throws FileNotFoundException { + Assert.state(!isPemContent(), "Value contains PEM content"); + return ResourceUtils.getURL(this.value); + } + private boolean isFileUrl(URL url) { return "file".equalsIgnoreCase(url.getProtocol()); } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/BundleContentPropertyTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/BundleContentPropertyTests.java index 7ff334f08de6..72d5f6ae3190 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/BundleContentPropertyTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/BundleContentPropertyTests.java @@ -74,7 +74,7 @@ void hasValueWhenHasEmptyValueReturnsFalse() { void toWatchPathWhenNotPathThrowsException() { BundleContentProperty property = new BundleContentProperty("name", PEM_TEXT); assertThatIllegalStateException().isThrownBy(property::toWatchPath) - .withMessage("Unable to convert 'name' property to a path"); + .withMessage("Unable to convert value of property 'name' to a path"); } @Test diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemContent.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemContent.java index e6bb75a44bcd..d3013bcb6f3a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemContent.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemContent.java @@ -126,19 +126,6 @@ static PemContent load(String content) throws IOException { } } - /** - * Load {@link PemContent} from the given {@link URL}. - * @param url the URL to load content from - * @return the loaded PEM content - * @throws IOException on IO error - */ - public static PemContent load(URL url) throws IOException { - Assert.notNull(url, "Url must not be null"); - try (InputStream in = url.openStream()) { - return load(in); - } - } - /** * Load {@link PemContent} from the given {@link Path}. * @param path a path to load the content from @@ -152,6 +139,13 @@ public static PemContent load(Path path) throws IOException { } } + private static PemContent load(URL url) throws IOException { + Assert.notNull(url, "Url must not be null"); + try (InputStream in = url.openStream()) { + return load(in); + } + } + private static PemContent load(InputStream in) throws IOException { return of(StreamUtils.copyToString(in, StandardCharsets.UTF_8)); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/pem/PemContentTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/pem/PemContentTests.java index 5f65058ef1f5..fac38bc5fd50 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/pem/PemContentTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/pem/PemContentTests.java @@ -46,7 +46,7 @@ void getCertificateWhenNoCertificatesThrowsException() { @Test void getCertificateReturnsCertificates() throws Exception { - PemContent content = PemContent.load(getClass().getResource("/test-cert-chain.pem")); + PemContent content = PemContent.load(contentFromClasspath("/test-cert-chain.pem")); List certificates = content.getCertificates(); assertThat(certificates).isNotNull(); assertThat(certificates).hasSize(2); @@ -64,7 +64,7 @@ void getPrivateKeyWhenNoKeyThrowsException() { @Test void getPrivateKeyReturnsPrivateKey() throws Exception { PemContent content = PemContent - .load(getClass().getResource("/org/springframework/boot/web/server/pkcs8/dsa.key")); + .load(contentFromClasspath("/org/springframework/boot/web/server/pkcs8/dsa.key")); PrivateKey privateKey = content.getPrivateKey(); assertThat(privateKey).isNotNull(); assertThat(privateKey.getFormat()).isEqualTo("PKCS#8"); @@ -117,22 +117,14 @@ void loadWithStringWhenContentIsPemContentReturnsContent() throws Exception { @Test void loadWithStringWhenClasspathLocationReturnsContent() throws IOException { String actual = PemContent.load("classpath:test-cert.pem").toString(); - String expected = new ClassPathResource("test-cert.pem").getContentAsString(StandardCharsets.UTF_8); + String expected = contentFromClasspath("test-cert.pem"); assertThat(actual).isEqualTo(expected); } @Test void loadWithStringWhenFileLocationReturnsContent() throws IOException { String actual = PemContent.load("src/test/resources/test-cert.pem").toString(); - String expected = new ClassPathResource("test-cert.pem").getContentAsString(StandardCharsets.UTF_8); - assertThat(actual).isEqualTo(expected); - } - - @Test - void loadWithUrlReturnsContent() throws Exception { - ClassPathResource resource = new ClassPathResource("test-cert.pem"); - String expected = resource.getContentAsString(StandardCharsets.UTF_8); - String actual = PemContent.load(resource.getURL()).toString(); + String expected = contentFromClasspath("test-cert.pem"); assertThat(actual).isEqualTo(expected); } @@ -140,7 +132,7 @@ void loadWithUrlReturnsContent() throws Exception { void loadWithPathReturnsContent() throws IOException { Path path = Path.of("src/test/resources/test-cert.pem"); String actual = PemContent.load(path).toString(); - String expected = new ClassPathResource("test-cert.pem").getContentAsString(StandardCharsets.UTF_8); + String expected = contentFromClasspath("test-cert.pem"); assertThat(actual).isEqualTo(expected); } @@ -154,4 +146,8 @@ void ofReturnsContent() { assertThat(PemContent.of("test")).hasToString("test"); } + private static String contentFromClasspath(String path) throws IOException { + return new ClassPathResource(path).getContentAsString(StandardCharsets.UTF_8); + } + }