Add factory methods to create an SslManagerBundle from trust managers
Add two methods to create an SslManagerBundle from a given TrustManagerFactory or from a single or multiple TrustManagers. Both those methods use the default KeyManagerFactory. Closes gh-43064
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.ssl;
|
||||
|
||||
import java.security.KeyStore;
|
||||
import java.security.Provider;
|
||||
|
||||
import javax.net.ssl.ManagerFactoryParameters;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.TrustManagerFactorySpi;
|
||||
|
||||
import org.springframework.boot.SpringBootVersion;
|
||||
|
||||
/**
|
||||
* {@link TrustManagerFactory} which uses a fixed set of {@link TrustManager
|
||||
* TrustManagers}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
final class FixedTrustManagerFactory extends TrustManagerFactory {
|
||||
|
||||
private static final Provider PROVIDER = new Provider("FixedTrustManagerFactory", SpringBootVersion.getVersion(),
|
||||
"") {
|
||||
};
|
||||
|
||||
private FixedTrustManagerFactory(FixedTrustManagersSpi spi, String algorithm) {
|
||||
super(spi, PROVIDER, algorithm);
|
||||
}
|
||||
|
||||
static FixedTrustManagerFactory of(TrustManagerFactory trustManagerFactory, TrustManager... trustManagers) {
|
||||
return new FixedTrustManagerFactory(new FixedTrustManagersSpi(trustManagers),
|
||||
trustManagerFactory.getAlgorithm());
|
||||
}
|
||||
|
||||
private static final class FixedTrustManagersSpi extends TrustManagerFactorySpi {
|
||||
|
||||
private final TrustManager[] trustManagers;
|
||||
|
||||
private FixedTrustManagersSpi(TrustManager[] trustManagers) {
|
||||
this.trustManagers = trustManagers;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineInit(KeyStore ks) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineInit(ManagerFactoryParameters spec) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TrustManager[] engineGetTrustManagers() {
|
||||
return this.trustManagers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
package org.springframework.boot.ssl;
|
||||
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
@@ -30,6 +35,7 @@ import org.springframework.util.Assert;
|
||||
* {@link SslStoreBundle}.
|
||||
*
|
||||
* @author Scott Frederick
|
||||
* @author Moritz Halbritter
|
||||
* @since 3.1.0
|
||||
* @see SslStoreBundle
|
||||
* @see SslBundle#getManagers()
|
||||
@@ -118,4 +124,59 @@ public interface SslManagerBundle {
|
||||
return new DefaultSslManagerBundle(storeBundle, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new {@link SslManagerBundle} using the given
|
||||
* {@link TrustManagerFactory} and the default {@link KeyManagerFactory}.
|
||||
* @param trustManagerFactory the trust manager factory
|
||||
* @return a new {@link SslManagerBundle} instance
|
||||
* @since 3.5.0
|
||||
*/
|
||||
static SslManagerBundle from(TrustManagerFactory trustManagerFactory) {
|
||||
Assert.notNull(trustManagerFactory, "TrustManagerFactory must not be null");
|
||||
KeyManagerFactory defaultKeyManagerFactory = createDefaultKeyManagerFactory();
|
||||
return of(defaultKeyManagerFactory, trustManagerFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new {@link SslManagerBundle} using the given
|
||||
* {@link TrustManager TrustManagers} and the default {@link KeyManagerFactory}.
|
||||
* @param trustManagers the trust managers to use
|
||||
* @return a new {@link SslManagerBundle} instance
|
||||
* @since 3.5.0
|
||||
*/
|
||||
static SslManagerBundle from(TrustManager... trustManagers) {
|
||||
Assert.notNull(trustManagers, "TrustManagers must not be null");
|
||||
KeyManagerFactory defaultKeyManagerFactory = createDefaultKeyManagerFactory();
|
||||
TrustManagerFactory defaultTrustManagerFactory = createDefaultTrustManagerFactory();
|
||||
return of(defaultKeyManagerFactory, FixedTrustManagerFactory.of(defaultTrustManagerFactory, trustManagers));
|
||||
}
|
||||
|
||||
private static TrustManagerFactory createDefaultTrustManagerFactory() {
|
||||
String defaultAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
|
||||
TrustManagerFactory trustManagerFactory;
|
||||
try {
|
||||
trustManagerFactory = TrustManagerFactory.getInstance(defaultAlgorithm);
|
||||
trustManagerFactory.init((KeyStore) null);
|
||||
}
|
||||
catch (NoSuchAlgorithmException | KeyStoreException ex) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to create TrustManagerFactory for default '%s' algorithm".formatted(defaultAlgorithm), ex);
|
||||
}
|
||||
return trustManagerFactory;
|
||||
}
|
||||
|
||||
private static KeyManagerFactory createDefaultKeyManagerFactory() {
|
||||
String defaultAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
|
||||
KeyManagerFactory keyManagerFactory;
|
||||
try {
|
||||
keyManagerFactory = KeyManagerFactory.getInstance(defaultAlgorithm);
|
||||
keyManagerFactory.init(null, null);
|
||||
}
|
||||
catch (NoSuchAlgorithmException | KeyStoreException | UnrecoverableKeyException ex) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to create KeyManagerFactory for default '%s' algorithm".formatted(defaultAlgorithm), ex);
|
||||
}
|
||||
return keyManagerFactory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.ssl;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link FixedTrustManagerFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class FixedTrustManagerFactoryTests {
|
||||
|
||||
@Test
|
||||
void shouldReturnTrustmanagers() throws Exception {
|
||||
TrustManager trustManager1 = mock(TrustManager.class);
|
||||
TrustManager trustManager2 = mock(TrustManager.class);
|
||||
FixedTrustManagerFactory factory = FixedTrustManagerFactory.of(getDefaultTrustManagerFactory(), trustManager1,
|
||||
trustManager2);
|
||||
assertThat(factory.getTrustManagers()).containsExactly(trustManager1, trustManager2);
|
||||
}
|
||||
|
||||
private static TrustManagerFactory getDefaultTrustManagerFactory() throws NoSuchAlgorithmException {
|
||||
return TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package org.springframework.boot.ssl;
|
||||
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -31,12 +32,13 @@ import static org.mockito.Mockito.mock;
|
||||
* Tests for {@link SslManagerBundle}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class SslManagerBundleTests {
|
||||
|
||||
private KeyManagerFactory keyManagerFactory = mock(KeyManagerFactory.class);
|
||||
private final KeyManagerFactory keyManagerFactory = mock(KeyManagerFactory.class);
|
||||
|
||||
private TrustManagerFactory trustManagerFactory = mock(TrustManagerFactory.class);
|
||||
private final TrustManagerFactory trustManagerFactory = mock(TrustManagerFactory.class);
|
||||
|
||||
@Test
|
||||
void getKeyManagersDelegatesToFactory() {
|
||||
@@ -85,4 +87,20 @@ class SslManagerBundleTests {
|
||||
assertThat(bundle).isInstanceOf(DefaultSslManagerBundle.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnTrustManagerFactory() {
|
||||
SslManagerBundle bundle = SslManagerBundle.from(this.trustManagerFactory);
|
||||
assertThat(bundle.getKeyManagerFactory()).isNotNull();
|
||||
assertThat(bundle.getTrustManagerFactory()).isSameAs(this.trustManagerFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnTrustManagers() {
|
||||
TrustManager trustManager1 = mock(TrustManager.class);
|
||||
TrustManager trustManager2 = mock(TrustManager.class);
|
||||
SslManagerBundle bundle = SslManagerBundle.from(trustManager1, trustManager2);
|
||||
assertThat(bundle.getKeyManagerFactory()).isNotNull();
|
||||
assertThat(bundle.getTrustManagerFactory().getTrustManagers()).containsExactly(trustManager1, trustManager2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user