Skip to content

Commit

Permalink
xds: add CertProviderServerSslContextProvider support (#7331)
Browse files Browse the repository at this point in the history
  • Loading branch information
sanjaypujare committed Aug 18, 2020
1 parent 39c49b0 commit ee9109e
Show file tree
Hide file tree
Showing 7 changed files with 439 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
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;
Expand Down Expand Up @@ -85,7 +86,11 @@ protected final SslContextBuilder getSslContextBuilder(
tlsCertificate.hasPassword()
? tlsCertificate.getPassword().getInlineString()
: null);
setClientAuthValues(sslContextBuilder, localCertValidationContext);
setClientAuthValues(
sslContextBuilder,
localCertValidationContext != null
? new SdsTrustManagerFactory(localCertValidationContext)
: null);
return sslContextBuilder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
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;
Expand Down Expand Up @@ -108,7 +109,8 @@ SslContext buildSslContextFromSecrets()
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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
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;
Expand Down Expand Up @@ -70,11 +69,11 @@ protected CommonTlsContext getCommonTlsContext() {
}

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
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;
Expand Down Expand Up @@ -270,7 +271,7 @@ public void testProviderForClient_rootInstanceNull_expectError() throws Exceptio

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) {
Expand Down

0 comments on commit ee9109e

Please sign in to comment.