mirror of https://github.com/grpc/grpc-java.git
xds: add CertProviderServerSslContextProvider support (#7331)
This commit is contained in:
parent
39c49b0408
commit
ee9109eced
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Copyright 2020 The gRPC 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 io.grpc.xds.internal.certprovider;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import io.envoyproxy.envoy.config.core.v3.Node;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CertificateValidationContext;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext.CombinedCertificateValidationContext;
|
||||
import io.grpc.netty.GrpcSslContexts;
|
||||
import io.grpc.xds.Bootstrapper.CertificateProviderInfo;
|
||||
import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext;
|
||||
import io.grpc.xds.internal.sds.trust.SdsTrustManagerFactory;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.cert.CertStoreException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Map;
|
||||
|
||||
/** A server SslContext provider using CertificateProviderInstance to fetch secrets. */
|
||||
final class CertProviderServerSslContextProvider extends CertProviderSslContextProvider {
|
||||
|
||||
private CertProviderServerSslContextProvider(
|
||||
Node node,
|
||||
Map<String, CertificateProviderInfo> certProviders,
|
||||
CommonTlsContext.CertificateProviderInstance certInstance,
|
||||
CommonTlsContext.CertificateProviderInstance rootCertInstance,
|
||||
CertificateValidationContext staticCertValidationContext,
|
||||
DownstreamTlsContext downstreamTlsContext,
|
||||
CertificateProviderStore certificateProviderStore) {
|
||||
super(
|
||||
node,
|
||||
certProviders,
|
||||
checkNotNull(certInstance, "Server SSL requires certInstance"),
|
||||
rootCertInstance,
|
||||
staticCertValidationContext,
|
||||
downstreamTlsContext,
|
||||
certificateProviderStore);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final SslContextBuilder getSslContextBuilder(
|
||||
CertificateValidationContext certificateValidationContextdationContext)
|
||||
throws CertStoreException, CertificateException, IOException {
|
||||
SslContextBuilder sslContextBuilder = SslContextBuilder.forServer(savedKey, savedCertChain);
|
||||
setClientAuthValues(
|
||||
sslContextBuilder,
|
||||
isMtls()
|
||||
? new SdsTrustManagerFactory(
|
||||
savedTrustedRoots.toArray(new X509Certificate[0]),
|
||||
certificateValidationContextdationContext)
|
||||
: null);
|
||||
sslContextBuilder = GrpcSslContexts.configure(sslContextBuilder);
|
||||
return sslContextBuilder;
|
||||
}
|
||||
|
||||
/** Creates CertProviderServerSslContextProvider. */
|
||||
static final class Factory {
|
||||
private static final Factory DEFAULT_INSTANCE =
|
||||
new Factory(CertificateProviderStore.getInstance());
|
||||
private final CertificateProviderStore certificateProviderStore;
|
||||
|
||||
@VisibleForTesting Factory(CertificateProviderStore certificateProviderStore) {
|
||||
this.certificateProviderStore = certificateProviderStore;
|
||||
}
|
||||
|
||||
static Factory getInstance() {
|
||||
return DEFAULT_INSTANCE;
|
||||
}
|
||||
|
||||
CertProviderServerSslContextProvider getProvider(
|
||||
DownstreamTlsContext downstreamTlsContext,
|
||||
Node node,
|
||||
Map<String, CertificateProviderInfo> certProviders) {
|
||||
checkNotNull(downstreamTlsContext, "downstreamTlsContext");
|
||||
CommonTlsContext commonTlsContext = downstreamTlsContext.getCommonTlsContext();
|
||||
CommonTlsContext.CertificateProviderInstance rootCertInstance = null;
|
||||
CertificateValidationContext staticCertValidationContext = null;
|
||||
if (commonTlsContext.hasCombinedValidationContext()) {
|
||||
CombinedCertificateValidationContext combinedValidationContext =
|
||||
commonTlsContext.getCombinedValidationContext();
|
||||
if (combinedValidationContext.hasValidationContextCertificateProviderInstance()) {
|
||||
rootCertInstance =
|
||||
combinedValidationContext.getValidationContextCertificateProviderInstance();
|
||||
}
|
||||
if (combinedValidationContext.hasDefaultValidationContext()) {
|
||||
staticCertValidationContext = combinedValidationContext.getDefaultValidationContext();
|
||||
}
|
||||
} else if (commonTlsContext.hasValidationContextCertificateProviderInstance()) {
|
||||
rootCertInstance = commonTlsContext.getValidationContextCertificateProviderInstance();
|
||||
} else if (commonTlsContext.hasValidationContext()) {
|
||||
staticCertValidationContext = commonTlsContext.getValidationContext();
|
||||
}
|
||||
CommonTlsContext.CertificateProviderInstance certInstance = null;
|
||||
if (commonTlsContext.hasTlsCertificateCertificateProviderInstance()) {
|
||||
certInstance = commonTlsContext.getTlsCertificateCertificateProviderInstance();
|
||||
}
|
||||
return new CertProviderServerSslContextProvider(
|
||||
node,
|
||||
certProviders,
|
||||
certInstance,
|
||||
rootCertInstance,
|
||||
staticCertValidationContext,
|
||||
downstreamTlsContext,
|
||||
certificateProviderStore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext;
|
|||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.SdsSecretConfig;
|
||||
import io.grpc.netty.GrpcSslContexts;
|
||||
import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext;
|
||||
import io.grpc.xds.internal.sds.trust.SdsTrustManagerFactory;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
import java.io.IOException;
|
||||
import java.security.cert.CertStoreException;
|
||||
|
|
@ -85,7 +86,11 @@ final class SdsServerSslContextProvider extends SdsSslContextProvider {
|
|||
tlsCertificate.hasPassword()
|
||||
? tlsCertificate.getPassword().getInlineString()
|
||||
: null);
|
||||
setClientAuthValues(sslContextBuilder, localCertValidationContext);
|
||||
setClientAuthValues(
|
||||
sslContextBuilder,
|
||||
localCertValidationContext != null
|
||||
? new SdsTrustManagerFactory(localCertValidationContext)
|
||||
: null);
|
||||
return sslContextBuilder;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext;
|
|||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.TlsCertificate;
|
||||
import io.grpc.netty.GrpcSslContexts;
|
||||
import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext;
|
||||
import io.grpc.xds.internal.sds.trust.SdsTrustManagerFactory;
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
import java.io.File;
|
||||
|
|
@ -108,7 +109,8 @@ final class SecretVolumeServerSslContextProvider extends SslContextProvider {
|
|||
SslContextBuilder sslContextBuilder =
|
||||
GrpcSslContexts.forServer(
|
||||
new File(certificateChain), new File(privateKey), privateKeyPassword);
|
||||
setClientAuthValues(sslContextBuilder, certContext);
|
||||
setClientAuthValues(
|
||||
sslContextBuilder, certContext != null ? new SdsTrustManagerFactory(certContext) : null);
|
||||
return sslContextBuilder.build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package io.grpc.xds.internal.sds;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CertificateValidationContext;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext;
|
||||
import io.grpc.xds.EnvoyServerProtoData.BaseTlsContext;
|
||||
import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext;
|
||||
|
|
@ -70,11 +69,11 @@ public abstract class SslContextProvider implements Closeable {
|
|||
}
|
||||
|
||||
protected void setClientAuthValues(
|
||||
SslContextBuilder sslContextBuilder, CertificateValidationContext localCertValidationContext)
|
||||
SslContextBuilder sslContextBuilder, SdsTrustManagerFactory sdsTrustManagerFactory)
|
||||
throws CertificateException, IOException, CertStoreException {
|
||||
DownstreamTlsContext downstreamTlsContext = getDownstreamTlsContext();
|
||||
if (localCertValidationContext != null) {
|
||||
sslContextBuilder.trustManager(new SdsTrustManagerFactory(localCertValidationContext));
|
||||
if (sdsTrustManagerFactory != null) {
|
||||
sslContextBuilder.trustManager(sdsTrustManagerFactory);
|
||||
sslContextBuilder.clientAuth(
|
||||
downstreamTlsContext.isRequireClientCertificate()
|
||||
? ClientAuth.REQUIRE
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import static io.grpc.xds.internal.sds.CommonTlsContextTestsUtil.SERVER_1_PEM_FI
|
|||
import static io.grpc.xds.internal.sds.CommonTlsContextTestsUtil.doChecksOnSslContext;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import io.envoyproxy.envoy.config.core.v3.DataSource;
|
||||
|
|
@ -270,7 +271,7 @@ public class CertProviderClientSslContextProviderTest {
|
|||
|
||||
static class QueuedExecutor implements Executor {
|
||||
/** A list of Runnables to be run in order. */
|
||||
private final Queue<Runnable> runQueue = new ConcurrentLinkedQueue<>();
|
||||
@VisibleForTesting final Queue<Runnable> runQueue = new ConcurrentLinkedQueue<>();
|
||||
|
||||
@Override
|
||||
public synchronized void execute(Runnable r) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* Copyright 2020 The gRPC 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 io.grpc.xds.internal.certprovider;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static io.grpc.xds.internal.certprovider.CertProviderClientSslContextProviderTest.QueuedExecutor;
|
||||
import static io.grpc.xds.internal.certprovider.CommonCertProviderTestUtils.getCertFromResourceName;
|
||||
import static io.grpc.xds.internal.sds.CommonTlsContextTestsUtil.CA_PEM_FILE;
|
||||
import static io.grpc.xds.internal.sds.CommonTlsContextTestsUtil.CLIENT_PEM_FILE;
|
||||
import static io.grpc.xds.internal.sds.CommonTlsContextTestsUtil.SERVER_0_KEY_FILE;
|
||||
import static io.grpc.xds.internal.sds.CommonTlsContextTestsUtil.SERVER_0_PEM_FILE;
|
||||
import static io.grpc.xds.internal.sds.CommonTlsContextTestsUtil.SERVER_1_KEY_FILE;
|
||||
import static io.grpc.xds.internal.sds.CommonTlsContextTestsUtil.SERVER_1_PEM_FILE;
|
||||
import static io.grpc.xds.internal.sds.CommonTlsContextTestsUtil.doChecksOnSslContext;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import io.envoyproxy.envoy.config.core.v3.DataSource;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CertificateValidationContext;
|
||||
import io.grpc.xds.Bootstrapper;
|
||||
import io.grpc.xds.EnvoyServerProtoData;
|
||||
import io.grpc.xds.internal.sds.CommonTlsContextTestsUtil;
|
||||
import io.grpc.xds.internal.sds.CommonTlsContextTestsUtil.TestCallback;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link CertProviderServerSslContextProvider}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class CertProviderServerSslContextProviderTest {
|
||||
|
||||
CertificateProviderRegistry certificateProviderRegistry;
|
||||
CertificateProviderStore certificateProviderStore;
|
||||
private CertProviderServerSslContextProvider.Factory certProviderServerSslContextProviderFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
certificateProviderRegistry = new CertificateProviderRegistry();
|
||||
certificateProviderStore = new CertificateProviderStore(certificateProviderRegistry);
|
||||
certProviderServerSslContextProviderFactory =
|
||||
new CertProviderServerSslContextProvider.Factory(certificateProviderStore);
|
||||
}
|
||||
|
||||
/** Helper method to build CertProviderServerSslContextProvider. */
|
||||
private CertProviderServerSslContextProvider getSslContextProvider(
|
||||
String certInstanceName,
|
||||
String rootInstanceName,
|
||||
Bootstrapper.BootstrapInfo bootstrapInfo,
|
||||
Iterable<String> alpnProtocols,
|
||||
CertificateValidationContext staticCertValidationContext,
|
||||
boolean requireClientCert) {
|
||||
EnvoyServerProtoData.DownstreamTlsContext downstreamTlsContext =
|
||||
CommonTlsContextTestsUtil.buildDownstreamTlsContextForCertProviderInstance(
|
||||
certInstanceName,
|
||||
"cert-default",
|
||||
rootInstanceName,
|
||||
"root-default",
|
||||
alpnProtocols,
|
||||
staticCertValidationContext,
|
||||
requireClientCert);
|
||||
return certProviderServerSslContextProviderFactory.getProvider(
|
||||
downstreamTlsContext,
|
||||
bootstrapInfo.getNode().toEnvoyProtoNode(),
|
||||
bootstrapInfo.getCertProviders());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderForServer_mtls() throws Exception {
|
||||
final CertificateProvider.DistributorWatcher[] watcherCaptor =
|
||||
new CertificateProvider.DistributorWatcher[1];
|
||||
TestCertificateProvider.createAndRegisterProviderProvider(
|
||||
certificateProviderRegistry, watcherCaptor, "testca", 0);
|
||||
CertProviderServerSslContextProvider provider =
|
||||
getSslContextProvider(
|
||||
"gcp_id",
|
||||
"gcp_id",
|
||||
CommonCertProviderTestUtils.getTestBootstrapInfo(),
|
||||
/* alpnProtocols= */ null,
|
||||
/* staticCertValidationContext= */ null,
|
||||
/* requireClientCert= */ true);
|
||||
|
||||
assertThat(provider.savedKey).isNull();
|
||||
assertThat(provider.savedCertChain).isNull();
|
||||
assertThat(provider.savedTrustedRoots).isNull();
|
||||
assertThat(provider.getSslContext()).isNull();
|
||||
|
||||
// now generate cert update
|
||||
watcherCaptor[0].updateCertificate(
|
||||
CommonCertProviderTestUtils.getPrivateKey(SERVER_0_KEY_FILE),
|
||||
ImmutableList.of(getCertFromResourceName(SERVER_0_PEM_FILE)));
|
||||
assertThat(provider.savedKey).isNotNull();
|
||||
assertThat(provider.savedCertChain).isNotNull();
|
||||
assertThat(provider.getSslContext()).isNull();
|
||||
|
||||
// now generate root cert update
|
||||
watcherCaptor[0].updateTrustedRoots(ImmutableList.of(getCertFromResourceName(CA_PEM_FILE)));
|
||||
assertThat(provider.getSslContext()).isNotNull();
|
||||
assertThat(provider.savedKey).isNull();
|
||||
assertThat(provider.savedCertChain).isNull();
|
||||
assertThat(provider.savedTrustedRoots).isNull();
|
||||
|
||||
TestCallback testCallback =
|
||||
CommonTlsContextTestsUtil.getValueThruCallback(provider);
|
||||
|
||||
doChecksOnSslContext(true, testCallback.updatedSslContext, /* expectedApnProtos= */ null);
|
||||
TestCallback testCallback1 =
|
||||
CommonTlsContextTestsUtil.getValueThruCallback(provider);
|
||||
assertThat(testCallback1.updatedSslContext).isSameInstanceAs(testCallback.updatedSslContext);
|
||||
|
||||
// just do root cert update: sslContext should still be the same
|
||||
watcherCaptor[0].updateTrustedRoots(
|
||||
ImmutableList.of(getCertFromResourceName(CLIENT_PEM_FILE)));
|
||||
assertThat(provider.savedKey).isNull();
|
||||
assertThat(provider.savedCertChain).isNull();
|
||||
assertThat(provider.savedTrustedRoots).isNotNull();
|
||||
testCallback1 = CommonTlsContextTestsUtil.getValueThruCallback(provider);
|
||||
assertThat(testCallback1.updatedSslContext).isSameInstanceAs(testCallback.updatedSslContext);
|
||||
|
||||
// now update id cert: sslContext should be updated i.e.different from the previous one
|
||||
watcherCaptor[0].updateCertificate(
|
||||
CommonCertProviderTestUtils.getPrivateKey(SERVER_1_KEY_FILE),
|
||||
ImmutableList.of(getCertFromResourceName(SERVER_1_PEM_FILE)));
|
||||
assertThat(provider.savedKey).isNull();
|
||||
assertThat(provider.savedCertChain).isNull();
|
||||
assertThat(provider.savedTrustedRoots).isNull();
|
||||
assertThat(provider.getSslContext()).isNotNull();
|
||||
testCallback1 = CommonTlsContextTestsUtil.getValueThruCallback(provider);
|
||||
assertThat(testCallback1.updatedSslContext).isNotSameInstanceAs(testCallback.updatedSslContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderForServer_queueExecutor() throws Exception {
|
||||
final CertificateProvider.DistributorWatcher[] watcherCaptor =
|
||||
new CertificateProvider.DistributorWatcher[1];
|
||||
TestCertificateProvider.createAndRegisterProviderProvider(
|
||||
certificateProviderRegistry, watcherCaptor, "testca", 0);
|
||||
CertProviderServerSslContextProvider provider =
|
||||
getSslContextProvider(
|
||||
"gcp_id",
|
||||
"gcp_id",
|
||||
CommonCertProviderTestUtils.getTestBootstrapInfo(),
|
||||
/* alpnProtocols= */ null,
|
||||
/* staticCertValidationContext= */ null,
|
||||
/* requireClientCert= */ true);
|
||||
QueuedExecutor queuedExecutor = new QueuedExecutor();
|
||||
|
||||
TestCallback testCallback =
|
||||
CommonTlsContextTestsUtil.getValueThruCallback(provider, queuedExecutor);
|
||||
assertThat(queuedExecutor.runQueue).isEmpty();
|
||||
|
||||
// now generate cert update
|
||||
watcherCaptor[0].updateCertificate(
|
||||
CommonCertProviderTestUtils.getPrivateKey(SERVER_0_KEY_FILE),
|
||||
ImmutableList.of(getCertFromResourceName(SERVER_0_PEM_FILE)));
|
||||
assertThat(queuedExecutor.runQueue).isEmpty(); // still empty
|
||||
|
||||
// now generate root cert update
|
||||
watcherCaptor[0].updateTrustedRoots(ImmutableList.of(getCertFromResourceName(CA_PEM_FILE)));
|
||||
assertThat(queuedExecutor.runQueue).hasSize(1);
|
||||
queuedExecutor.drain();
|
||||
|
||||
doChecksOnSslContext(true, testCallback.updatedSslContext, /* expectedApnProtos= */ null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderForServer_tls() throws Exception {
|
||||
final CertificateProvider.DistributorWatcher[] watcherCaptor =
|
||||
new CertificateProvider.DistributorWatcher[1];
|
||||
TestCertificateProvider.createAndRegisterProviderProvider(
|
||||
certificateProviderRegistry, watcherCaptor, "testca", 0);
|
||||
CertProviderServerSslContextProvider provider =
|
||||
getSslContextProvider(
|
||||
"gcp_id",
|
||||
/* rootInstanceName= */ null,
|
||||
CommonCertProviderTestUtils.getTestBootstrapInfo(),
|
||||
/* alpnProtocols= */ null,
|
||||
/* staticCertValidationContext= */ null,
|
||||
/* requireClientCert= */ false);
|
||||
|
||||
assertThat(provider.savedKey).isNull();
|
||||
assertThat(provider.savedCertChain).isNull();
|
||||
assertThat(provider.savedTrustedRoots).isNull();
|
||||
assertThat(provider.getSslContext()).isNull();
|
||||
|
||||
// now generate cert update
|
||||
watcherCaptor[0].updateCertificate(
|
||||
CommonCertProviderTestUtils.getPrivateKey(SERVER_0_KEY_FILE),
|
||||
ImmutableList.of(getCertFromResourceName(SERVER_0_PEM_FILE)));
|
||||
|
||||
assertThat(provider.getSslContext()).isNotNull();
|
||||
assertThat(provider.savedKey).isNull();
|
||||
assertThat(provider.savedCertChain).isNull();
|
||||
assertThat(provider.savedTrustedRoots).isNull();
|
||||
|
||||
TestCallback testCallback =
|
||||
CommonTlsContextTestsUtil.getValueThruCallback(provider);
|
||||
|
||||
doChecksOnSslContext(true, testCallback.updatedSslContext, /* expectedApnProtos= */ null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderForServer_sslContextException_onError() throws Exception {
|
||||
CertificateValidationContext staticCertValidationContext =
|
||||
CertificateValidationContext.newBuilder()
|
||||
.setTrustedCa(DataSource.newBuilder().setInlineString("foo"))
|
||||
.build();
|
||||
|
||||
final CertificateProvider.DistributorWatcher[] watcherCaptor =
|
||||
new CertificateProvider.DistributorWatcher[1];
|
||||
TestCertificateProvider.createAndRegisterProviderProvider(
|
||||
certificateProviderRegistry, watcherCaptor, "testca", 0);
|
||||
CertProviderServerSslContextProvider provider =
|
||||
getSslContextProvider(
|
||||
/* certInstanceName= */ "gcp_id",
|
||||
/* rootInstanceName= */ "gcp_id",
|
||||
CommonCertProviderTestUtils.getTestBootstrapInfo(),
|
||||
/* alpnProtocols= */null,
|
||||
staticCertValidationContext,
|
||||
/* requireClientCert= */ true);
|
||||
|
||||
// now generate cert update
|
||||
watcherCaptor[0].updateCertificate(
|
||||
CommonCertProviderTestUtils.getPrivateKey(SERVER_0_KEY_FILE),
|
||||
ImmutableList.of(getCertFromResourceName(SERVER_0_PEM_FILE)));
|
||||
|
||||
TestCallback testCallback = new TestCallback(MoreExecutors.directExecutor());
|
||||
provider.addCallback(testCallback);
|
||||
try {
|
||||
watcherCaptor[0].updateTrustedRoots(ImmutableList.of(getCertFromResourceName(CA_PEM_FILE)));
|
||||
fail("exception expected");
|
||||
} catch (RuntimeException expected) {
|
||||
assertThat(expected)
|
||||
.hasMessageThat()
|
||||
.contains("only static certificateValidationContext expected");
|
||||
}
|
||||
assertThat(testCallback.updatedThrowable).isNotNull();
|
||||
assertThat(testCallback.updatedThrowable)
|
||||
.hasCauseThat()
|
||||
.hasMessageThat()
|
||||
.contains("only static certificateValidationContext expected");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderForServer_certInstanceNull_expectError() throws Exception {
|
||||
final CertificateProvider.DistributorWatcher[] watcherCaptor =
|
||||
new CertificateProvider.DistributorWatcher[1];
|
||||
TestCertificateProvider.createAndRegisterProviderProvider(
|
||||
certificateProviderRegistry, watcherCaptor, "testca", 0);
|
||||
try {
|
||||
getSslContextProvider(
|
||||
/* certInstanceName= */ null,
|
||||
/* rootInstanceName= */ null,
|
||||
CommonCertProviderTestUtils.getTestBootstrapInfo(),
|
||||
/* alpnProtocols= */ null,
|
||||
/* staticCertValidationContext= */ null,
|
||||
/* requireClientCert= */ false);
|
||||
fail("exception expected");
|
||||
} catch (NullPointerException expected) {
|
||||
assertThat(expected).hasMessageThat().contains("Server SSL requires certInstance");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -533,6 +533,27 @@ public class CommonTlsContextTestsUtil {
|
|||
staticCertValidationContext));
|
||||
}
|
||||
|
||||
/** Helper method to build DownstreamTlsContext for CertProvider tests. */
|
||||
public static EnvoyServerProtoData.DownstreamTlsContext
|
||||
buildDownstreamTlsContextForCertProviderInstance(
|
||||
@Nullable String certInstanceName,
|
||||
@Nullable String certName,
|
||||
@Nullable String rootInstanceName,
|
||||
@Nullable String rootCertName,
|
||||
Iterable<String> alpnProtocols,
|
||||
CertificateValidationContext staticCertValidationContext,
|
||||
boolean requireClientCert) {
|
||||
return buildInternalDownstreamTlsContext(
|
||||
buildCommonTlsContextForCertProviderInstance(
|
||||
certInstanceName,
|
||||
certName,
|
||||
rootInstanceName,
|
||||
rootCertName,
|
||||
alpnProtocols,
|
||||
staticCertValidationContext), requireClientCert);
|
||||
}
|
||||
|
||||
|
||||
/** Perform some simple checks on sslContext. */
|
||||
public static void doChecksOnSslContext(boolean server, SslContext sslContext,
|
||||
List<String> expectedApnProtos) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue