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
new file mode 100644
index 0000000000..abaace466f
--- /dev/null
+++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/BundleContentProperty.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2012-2023 the original author or 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
+ *
+ * https://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.springframework.boot.autoconfigure.ssl;
+
+import java.io.FileNotFoundException;
+import java.net.URL;
+import java.nio.file.Path;
+
+import org.springframework.boot.ssl.pem.PemContent;
+import org.springframework.util.Assert;
+import org.springframework.util.ResourceUtils;
+import org.springframework.util.StringUtils;
+
+/**
+ * Helper utility to manage a single bundle content configuration property. May possibly
+ * contain PEM content, a location or a directory search pattern.
+ *
+ * @param name the configuration property name (excluding any prefix)
+ * @param value the configuration property value
+ * @author Phillip Webb
+ */
+record BundleContentProperty(String name, String value) {
+
+ /**
+ * Return if the property value is PEM content.
+ * @return if the value is PEM content
+ */
+ boolean isPemContent() {
+ return PemContent.isPresentInText(this.value);
+ }
+
+ /**
+ * Return if there is any property value present.
+ * @return if the value is present
+ */
+ 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();
+ }
+
+ private Path toPath() {
+ try {
+ URL url = toUrl();
+ Assert.state(isFileUrl(url), () -> "Vaule '%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);
+ }
+ }
+
+ private boolean isFileUrl(URL url) {
+ return "file".equalsIgnoreCase(url.getProtocol());
+ }
+}
diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PemSslBundleProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PemSslBundleProperties.java
index 7870c6b059..beb58d87dc 100644
--- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PemSslBundleProperties.java
+++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PemSslBundleProperties.java
@@ -58,7 +58,7 @@ public class PemSslBundleProperties extends SslBundleProperties {
private String type;
/**
- * Location or content of the certificate in PEM format.
+ * Location or content of the certificate or certificate chain in PEM format.
*/
private String certificate;
diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PropertiesSslBundle.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PropertiesSslBundle.java
index 39512f2b3e..d8cfd084ab 100644
--- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PropertiesSslBundle.java
+++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PropertiesSslBundle.java
@@ -99,7 +99,35 @@ public final class PropertiesSslBundle implements SslBundle {
* @return an {@link SslBundle} instance
*/
public static SslBundle get(PemSslBundleProperties properties) {
- return new PropertiesSslBundle(asSslStoreBundle(properties), properties);
+ try {
+ PemSslStore keyStore = getPemSslStore("keystore", properties.getKeystore());
+ if (keyStore != null) {
+ keyStore = keyStore.withAlias(properties.getKey().getAlias())
+ .withPassword(properties.getKey().getPassword());
+ }
+ PemSslStore trustStore = getPemSslStore("truststore", properties.getTruststore());
+ SslStoreBundle storeBundle = new PemSslStoreBundle(keyStore, trustStore);
+ return new PropertiesSslBundle(storeBundle, properties);
+ }
+ catch (IOException ex) {
+ throw new UncheckedIOException(ex);
+ }
+ }
+
+ private static PemSslStore getPemSslStore(String propertyName, PemSslBundleProperties.Store properties)
+ throws IOException {
+ PemSslStore pemSslStore = PemSslStore.load(asPemSslStoreDetails(properties));
+ if (properties.isVerifyKeys()) {
+ CertificateMatcher certificateMatcher = new CertificateMatcher(pemSslStore.privateKey());
+ Assert.state(certificateMatcher.matchesAny(pemSslStore.certificates()),
+ "Private key matches none of the certificates in the chain");
+ }
+ return pemSslStore;
+ }
+
+ private static PemSslStoreDetails asPemSslStoreDetails(PemSslBundleProperties.Store properties) {
+ return new PemSslStoreDetails(properties.getType(), properties.getCertificate(), properties.getPrivateKey(),
+ properties.getPrivateKeyPassword());
}
/**
@@ -108,38 +136,8 @@ public final class PropertiesSslBundle implements SslBundle {
* @return an {@link SslBundle} instance
*/
public static SslBundle get(JksSslBundleProperties properties) {
- return new PropertiesSslBundle(asSslStoreBundle(properties), properties);
- }
-
- private static SslStoreBundle asSslStoreBundle(PemSslBundleProperties properties) {
- PemSslStore keyStore = asPemSslStore(properties.getKeystore());
- if (keyStore != null) {
- keyStore = keyStore.withAlias(properties.getKey().getAlias())
- .withPassword(properties.getKey().getPassword());
- }
- PemSslStore trustStore = asPemSslStore(properties.getTruststore());
- return new PemSslStoreBundle(keyStore, trustStore);
- }
-
- private static PemSslStore asPemSslStore(PemSslBundleProperties.Store properties) {
- try {
- PemSslStoreDetails details = asStoreDetails(properties);
- PemSslStore pemSslStore = PemSslStore.load(details);
- if (properties.isVerifyKeys()) {
- CertificateMatcher certificateMatcher = new CertificateMatcher(pemSslStore.privateKey());
- Assert.state(certificateMatcher.matchesAny(pemSslStore.certificates()),
- "Private key matches none of the certificates in the chain");
- }
- return pemSslStore;
- }
- catch (IOException ex) {
- throw new UncheckedIOException(ex);
- }
- }
-
- private static PemSslStoreDetails asStoreDetails(PemSslBundleProperties.Store properties) {
- return new PemSslStoreDetails(properties.getType(), properties.getCertificate(), properties.getPrivateKey(),
- properties.getPrivateKeyPassword());
+ SslStoreBundle storeBundle = asSslStoreBundle(properties);
+ return new PropertiesSslBundle(storeBundle, properties);
}
private static SslStoreBundle asSslStoreBundle(JksSslBundleProperties properties) {
diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/SslPropertiesBundleRegistrar.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/SslPropertiesBundleRegistrar.java
index 810ff772a3..583702c82c 100644
--- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/SslPropertiesBundleRegistrar.java
+++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/SslPropertiesBundleRegistrar.java
@@ -16,20 +16,17 @@
package org.springframework.boot.autoconfigure.ssl;
-import java.net.URL;
import java.nio.file.Path;
-import java.util.LinkedHashSet;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
-import java.util.regex.Pattern;
+import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.ssl.SslBundleRegistry;
-import org.springframework.util.Assert;
-import org.springframework.util.ResourceUtils;
-import org.springframework.util.StringUtils;
/**
* A {@link SslBundleRegistrar} that registers SSL bundles based
@@ -41,8 +38,6 @@ import org.springframework.util.StringUtils;
*/
class SslPropertiesBundleRegistrar implements SslBundleRegistrar {
- private static final Pattern PEM_CONTENT = Pattern.compile("-+BEGIN\\s+[^-]*-+", Pattern.CASE_INSENSITIVE);
-
private final SslProperties.Bundles properties;
private final FileWatcher fileWatcher;
@@ -54,70 +49,58 @@ class SslPropertiesBundleRegistrar implements SslBundleRegistrar {
@Override
public void registerBundles(SslBundleRegistry registry) {
- registerBundles(registry, this.properties.getPem(), PropertiesSslBundle::get, this::getLocations);
- registerBundles(registry, this.properties.getJks(), PropertiesSslBundle::get, this::getLocations);
+ registerBundles(registry, this.properties.getPem(), PropertiesSslBundle::get, this::watchedPemPaths);
+ registerBundles(registry, this.properties.getJks(), PropertiesSslBundle::get, this::watchedJksPaths);
}
private
void registerBundles(SslBundleRegistry registry, Map properties,
- Function bundleFactory, Function
> locationsSupplier) {
+ Function
bundleFactory, Function
> watchedPaths) {
properties.forEach((bundleName, bundleProperties) -> {
- SslBundle bundle = bundleFactory.apply(bundleProperties);
- registry.registerBundle(bundleName, bundle);
- if (bundleProperties.isReloadOnUpdate()) {
- Set paths = locationsSupplier.apply(bundleProperties)
- .stream()
- .filter(Location::hasValue)
- .map((location) -> toPath(bundleName, location))
- .collect(Collectors.toSet());
- this.fileWatcher.watch(paths,
- () -> registry.updateBundle(bundleName, bundleFactory.apply(bundleProperties)));
+ Supplier bundleSupplier = () -> bundleFactory.apply(bundleProperties);
+ try {
+ registry.registerBundle(bundleName, bundleSupplier.get());
+ if (bundleProperties.isReloadOnUpdate()) {
+ Supplier> pathsSupplier = () -> watchedPaths.apply(bundleProperties);
+ watchForUpdates(registry, bundleName, pathsSupplier, bundleSupplier);
+ }
+ }
+ catch (IllegalStateException ex) {
+ throw new IllegalStateException("Unable to register SSL bundle '%s'".formatted(bundleName), ex);
}
});
}
- private Set getLocations(JksSslBundleProperties properties) {
- JksSslBundleProperties.Store keystore = properties.getKeystore();
- JksSslBundleProperties.Store truststore = properties.getTruststore();
- Set locations = new LinkedHashSet<>();
- locations.add(new Location("keystore.location", keystore.getLocation()));
- locations.add(new Location("truststore.location", truststore.getLocation()));
- return locations;
- }
-
- private Set getLocations(PemSslBundleProperties properties) {
- PemSslBundleProperties.Store keystore = properties.getKeystore();
- PemSslBundleProperties.Store truststore = properties.getTruststore();
- Set locations = new LinkedHashSet<>();
- locations.add(new Location("keystore.private-key", keystore.getPrivateKey()));
- locations.add(new Location("keystore.certificate", keystore.getCertificate()));
- locations.add(new Location("truststore.private-key", truststore.getPrivateKey()));
- locations.add(new Location("truststore.certificate", truststore.getCertificate()));
- return locations;
- }
-
- private Path toPath(String bundleName, Location watchableLocation) {
- String value = watchableLocation.value();
- String field = watchableLocation.field();
- Assert.state(!PEM_CONTENT.matcher(value).find(),
- () -> "SSL bundle '%s' '%s' is not a URL and can't be watched".formatted(bundleName, field));
+ private void watchForUpdates(SslBundleRegistry registry, String bundleName, Supplier> pathsSupplier,
+ Supplier bundleSupplier) {
try {
- URL url = ResourceUtils.getURL(value);
- Assert.state("file".equalsIgnoreCase(url.getProtocol()),
- () -> "SSL bundle '%s' '%s' URL '%s' doesn't point to a file".formatted(bundleName, field, url));
- return Path.of(url.toURI()).toAbsolutePath();
+ this.fileWatcher.watch(pathsSupplier.get(), () -> registry.updateBundle(bundleName, bundleSupplier.get()));
}
- catch (Exception ex) {
- throw new RuntimeException(
- "SSL bundle '%s' '%s' location '%s' cannot be watched".formatted(bundleName, field, value), ex);
+ catch (RuntimeException ex) {
+ throw new IllegalStateException("Unable to watch for reload on update", ex);
}
}
- private record Location(String field, String value) {
+ private Set watchedJksPaths(JksSslBundleProperties properties) {
+ List watched = new ArrayList<>();
+ watched.add(new BundleContentProperty("keystore.location", properties.getKeystore().getLocation()));
+ watched.add(new BundleContentProperty("truststore.location", properties.getTruststore().getLocation()));
+ return watchedPaths(watched);
+ }
- boolean hasValue() {
- return StringUtils.hasText(this.value);
- }
+ private Set watchedPemPaths(PemSslBundleProperties properties) {
+ List watched = new ArrayList<>();
+ watched.add(new BundleContentProperty("keystore.private-key", properties.getKeystore().getPrivateKey()));
+ watched.add(new BundleContentProperty("keystore.certificate", properties.getKeystore().getCertificate()));
+ watched.add(new BundleContentProperty("truststore.private-key", properties.getTruststore().getPrivateKey()));
+ watched.add(new BundleContentProperty("truststore.certificate", properties.getTruststore().getCertificate()));
+ return watchedPaths(watched);
+ }
+ private Set watchedPaths(List properties) {
+ return properties.stream()
+ .filter(BundleContentProperty::hasValue)
+ .map(BundleContentProperty::toWatchPath)
+ .collect(Collectors.toSet());
}
}
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
new file mode 100644
index 0000000000..7ff334f08d
--- /dev/null
+++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/BundleContentPropertyTests.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2012-2023 the original author or 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
+ *
+ * https://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.springframework.boot.autoconfigure.ssl;
+
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
+
+/**
+ * Tests for {@link BundleContentProperty}.
+ *
+ * @author Moritz Halbritter
+ * @author Phillip Webb
+ */
+class BundleContentPropertyTests {
+
+ private static final String PEM_TEXT = """
+ -----BEGIN CERTIFICATE-----
+ -----END CERTIFICATE-----
+ """;
+
+ @TempDir
+ Path temp;
+
+ @Test
+ void isPemContentWhenValueIsPemTextReturnsTrue() {
+ BundleContentProperty property = new BundleContentProperty("name", PEM_TEXT);
+ assertThat(property.isPemContent()).isTrue();
+ }
+
+ @Test
+ void isPemContentWhenValueIsNotPemTextReturnsFalse() {
+ BundleContentProperty property = new BundleContentProperty("name", "file.pem");
+ assertThat(property.isPemContent()).isFalse();
+ }
+
+ @Test
+ void hasValueWhenHasValueReturnsTrue() {
+ BundleContentProperty property = new BundleContentProperty("name", "file.pem");
+ assertThat(property.hasValue()).isTrue();
+ }
+
+ @Test
+ void hasValueWhenHasNullValueReturnsFalse() {
+ BundleContentProperty property = new BundleContentProperty("name", null);
+ assertThat(property.hasValue()).isFalse();
+ }
+
+ @Test
+ void hasValueWhenHasEmptyValueReturnsFalse() {
+ BundleContentProperty property = new BundleContentProperty("name", "");
+ assertThat(property.hasValue()).isFalse();
+ }
+
+ @Test
+ void toWatchPathWhenNotPathThrowsException() {
+ BundleContentProperty property = new BundleContentProperty("name", PEM_TEXT);
+ assertThatIllegalStateException().isThrownBy(property::toWatchPath)
+ .withMessage("Unable to convert 'name' property to a path");
+ }
+
+ @Test
+ void toWatchPathWhenPathReturnsPath() {
+ Path file = this.temp.toAbsolutePath().resolve("file.txt");
+ BundleContentProperty property = new BundleContentProperty("name", file.toString());
+ assertThat(property.toWatchPath()).isEqualTo(file);
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/SslPropertiesBundleRegistrarTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/SslPropertiesBundleRegistrarTests.java
index 2410b8bbaa..759bb47460 100644
--- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/SslPropertiesBundleRegistrarTests.java
+++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/SslPropertiesBundleRegistrarTests.java
@@ -106,7 +106,9 @@ class SslPropertiesBundleRegistrarTests {
""".strip());
this.properties.getBundle().getPem().put("bundle1", pem);
assertThatIllegalStateException().isThrownBy(() -> this.registrar.registerBundles(this.registry))
- .withMessage("SSL bundle 'bundle1' 'keystore.certificate' is not a URL and can't be watched");
+ .withMessageContaining("Unable to register SSL bundle 'bundle1'")
+ .havingCause()
+ .withMessage("Unable to watch for reload on update");
}
@Test
@@ -121,7 +123,9 @@ class SslPropertiesBundleRegistrarTests {
""".strip());
this.properties.getBundle().getPem().put("bundle1", pem);
assertThatIllegalStateException().isThrownBy(() -> this.registrar.registerBundles(this.registry))
- .withMessage("SSL bundle 'bundle1' 'keystore.private-key' is not a URL and can't be watched");
+ .withMessageContaining("Unable to register SSL bundle 'bundle1'")
+ .havingCause()
+ .withMessage("Unable to watch for reload on update");
}
@Test
@@ -145,7 +149,9 @@ class SslPropertiesBundleRegistrarTests {
""".strip());
this.properties.getBundle().getPem().put("bundle1", pem);
assertThatIllegalStateException().isThrownBy(() -> this.registrar.registerBundles(this.registry))
- .withMessage("SSL bundle 'bundle1' 'truststore.certificate' is not a URL and can't be watched");
+ .withMessageContaining("Unable to register SSL bundle 'bundle1'")
+ .havingCause()
+ .withMessage("Unable to watch for reload on update");
}
@Test
@@ -160,7 +166,9 @@ class SslPropertiesBundleRegistrarTests {
""".strip());
this.properties.getBundle().getPem().put("bundle1", pem);
assertThatIllegalStateException().isThrownBy(() -> this.registrar.registerBundles(this.registry))
- .withMessage("SSL bundle 'bundle1' 'truststore.private-key' is not a URL and can't be watched");
+ .withMessageContaining("Unable to register SSL bundle 'bundle1'")
+ .havingCause()
+ .withMessage("Unable to watch for reload on update");
}
private void pathEndingWith(Set paths, String... suffixes) {
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 280e7094df..364a3f745a 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
@@ -105,8 +105,8 @@ public final class PemContent {
}
/**
- * Load {@link PemContent} from the given content (either the PEM content itself or
- * something that can be loaded by {@link ResourceUtils#getURL}).
+ * Load {@link PemContent} from the given content (either the PEM content itself or a
+ * reference to the resource to load).
* @param content the content to load
* @return a new {@link PemContent} instance
* @throws IOException on IO error
diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemSslStoreDetails.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemSslStoreDetails.java
index 57d6d5db60..8f97b2b55a 100644
--- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemSslStoreDetails.java
+++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemSslStoreDetails.java
@@ -18,7 +18,6 @@ package org.springframework.boot.ssl.pem;
import java.security.KeyStore;
-import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
/**
@@ -30,12 +29,12 @@ import org.springframework.util.StringUtils;
* @param password the password used
* {@link KeyStore#setKeyEntry(String, java.security.Key, char[], java.security.cert.Certificate[])
* setting key entries} in the {@link KeyStore}
- * @param certificates the certificates content (either the PEM content itself or
- * something that can be loaded by {@link ResourceUtils#getURL}). When a
- * {@link #privateKey() private key} is present this value is treated as a certificate
- * chain, otherwise it is treated a list of certificates that should all be registered.
- * @param privateKey the private key content (either the PEM content itself or something
- * that can be loaded by {@link ResourceUtils#getURL})
+ * @param certificates the certificates content (either the PEM content itself or or a
+ * reference to the resource to load). When a {@link #privateKey() private key} is present
+ * this value is treated as a certificate chain, otherwise it is treated a list of
+ * certificates that should all be registered.
+ * @param privateKey the private key content (either the PEM content itself or a reference
+ * to the resource to load)
* @param privateKeyPassword a password used to decrypt an encrypted private key
* @author Scott Frederick
* @author Phillip Webb
@@ -53,10 +52,10 @@ public record PemSslStoreDetails(String type, String alias, String password, Str
* @param password the password used
* {@link KeyStore#setKeyEntry(String, java.security.Key, char[], java.security.cert.Certificate[])
* setting key entries} in the {@link KeyStore}
- * @param certificates the certificate content (either the PEM content itself or
- * something that can be loaded by {@link ResourceUtils#getURL})
- * @param privateKey the private key content (either the PEM content itself or
- * something that can be loaded by {@link ResourceUtils#getURL})
+ * @param certificates the certificate content (either the PEM content itself or a
+ * reference to the resource to load)
+ * @param privateKey the private key content (either the PEM content itself or a
+ * reference to the resource to load)
* @param privateKeyPassword a password used to decrypt an encrypted private key
* @since 3.2.0
*/
@@ -67,10 +66,10 @@ public record PemSslStoreDetails(String type, String alias, String password, Str
* Create a new {@link PemSslStoreDetails} instance.
* @param type the key store type, for example {@code JKS} or {@code PKCS11}. A
* {@code null} value will use {@link KeyStore#getDefaultType()}).
- * @param certificate the certificate content (either the PEM content itself or
- * something that can be loaded by {@link ResourceUtils#getURL})
- * @param privateKey the private key content (either the PEM content itself or
- * something that can be loaded by {@link ResourceUtils#getURL})
+ * @param certificate the certificate content (either the PEM content itself or a
+ * reference to the resource to load)
+ * @param privateKey the private key content (either the PEM content itself or a
+ * reference to the resource to load)
* @param privateKeyPassword a password used to decrypt an encrypted private key
*/
public PemSslStoreDetails(String type, String certificate, String privateKey, String privateKeyPassword) {
@@ -81,10 +80,10 @@ public record PemSslStoreDetails(String type, String alias, String password, Str
* Create a new {@link PemSslStoreDetails} instance.
* @param type the key store type, for example {@code JKS} or {@code PKCS11}. A
* {@code null} value will use {@link KeyStore#getDefaultType()}).
- * @param certificate the certificate content (either the PEM content itself or
- * something that can be loaded by {@link ResourceUtils#getURL})
- * @param privateKey the private key content (either the PEM content itself or
- * something that can be loaded by {@link ResourceUtils#getURL})
+ * @param certificate the certificate content (either the PEM content itself or a
+ * reference to the resource to load)
+ * @param privateKey the private key content (either the PEM content itself or a
+ * reference to the resource to load)
*/
public PemSslStoreDetails(String type, String certificate, String privateKey) {
this(type, certificate, privateKey, null);
@@ -155,8 +154,8 @@ public record PemSslStoreDetails(String type, String alias, String password, Str
* certificate. Note: This method doesn't actually check if the provided value
* only contains a single certificate. It is functionally equivalent to
* {@link #forCertificates(String)}.
- * @param certificate the certificate content (either the PEM content itself or
- * something that can be loaded by {@link ResourceUtils#getURL})
+ * @param certificate the certificate content (either the PEM content itself or a
+ * reference to the resource to load)
* @return a new {@link PemSslStoreDetails} instance.
*/
public static PemSslStoreDetails forCertificate(String certificate) {
@@ -166,8 +165,8 @@ public record PemSslStoreDetails(String type, String alias, String password, Str
/**
* Factory method to create a new {@link PemSslStoreDetails} instance for the given
* certificates.
- * @param certificates the certificates content (either the PEM content itself or
- * something that can be loaded by {@link ResourceUtils#getURL})
+ * @param certificates the certificates content (either the PEM content itself or a
+ * reference to the resource to load)
* @return a new {@link PemSslStoreDetails} instance.
* @since 3.2.0
*/