mirror of https://github.com/grpc/grpc-java.git
xds: add inline bytes support to CertificationValidationContext we use in SdsTrustManagerFactory (#6429)
This commit is contained in:
parent
48929c4d50
commit
80c78ddede
|
|
@ -20,6 +20,7 @@ import java.io.BufferedInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
|
|
@ -44,16 +45,19 @@ final class CertificateUtils {
|
||||||
*
|
*
|
||||||
* @param file a {@link File} containing the cert data
|
* @param file a {@link File} containing the cert data
|
||||||
*/
|
*/
|
||||||
static synchronized X509Certificate[] toX509Certificates(File file)
|
static X509Certificate[] toX509Certificates(File file) throws CertificateException, IOException {
|
||||||
|
FileInputStream fis = new FileInputStream(file);
|
||||||
|
return toX509Certificates(new BufferedInputStream(fis));
|
||||||
|
}
|
||||||
|
|
||||||
|
static synchronized X509Certificate[] toX509Certificates(InputStream inputStream)
|
||||||
throws CertificateException, IOException {
|
throws CertificateException, IOException {
|
||||||
initInstance();
|
initInstance();
|
||||||
FileInputStream fis = new FileInputStream(file);
|
|
||||||
BufferedInputStream bis = new BufferedInputStream(fis);
|
|
||||||
try {
|
try {
|
||||||
Collection<? extends Certificate> certs = factory.generateCertificates(bis);
|
Collection<? extends Certificate> certs = factory.generateCertificates(inputStream);
|
||||||
return certs.toArray(new X509Certificate[0]);
|
return certs.toArray(new X509Certificate[0]);
|
||||||
} finally {
|
} finally {
|
||||||
bis.close();
|
inputStream.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package io.grpc.xds.sds.trust;
|
package io.grpc.xds.sds.trust;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
|
|
@ -54,19 +53,27 @@ public final class SdsTrustManagerFactory extends SimpleTrustManagerFactory {
|
||||||
public SdsTrustManagerFactory(CertificateValidationContext certificateValidationContext)
|
public SdsTrustManagerFactory(CertificateValidationContext certificateValidationContext)
|
||||||
throws CertificateException, IOException, CertStoreException {
|
throws CertificateException, IOException, CertStoreException {
|
||||||
checkNotNull(certificateValidationContext, "certificateValidationContext");
|
checkNotNull(certificateValidationContext, "certificateValidationContext");
|
||||||
String certsFile = getTrustedCaFromCertContext(certificateValidationContext);
|
|
||||||
checkState(!Strings.isNullOrEmpty(certsFile),
|
|
||||||
"trustedCa.file-name in certificateValidationContext cannot be empty");
|
|
||||||
createSdsX509TrustManager(
|
createSdsX509TrustManager(
|
||||||
CertificateUtils.toX509Certificates(new File(certsFile)), certificateValidationContext);
|
getTrustedCaFromCertContext(certificateValidationContext), certificateValidationContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getTrustedCaFromCertContext(
|
private static X509Certificate[] getTrustedCaFromCertContext(
|
||||||
CertificateValidationContext certificateValidationContext) {
|
CertificateValidationContext certificateValidationContext)
|
||||||
checkArgument(
|
throws CertificateException, IOException {
|
||||||
certificateValidationContext.getTrustedCa().getSpecifierCase() == SpecifierCase.FILENAME,
|
final SpecifierCase specifierCase =
|
||||||
"filename expected");
|
certificateValidationContext.getTrustedCa().getSpecifierCase();
|
||||||
return certificateValidationContext.getTrustedCa().getFilename();
|
if (specifierCase == SpecifierCase.FILENAME) {
|
||||||
|
String certsFile = certificateValidationContext.getTrustedCa().getFilename();
|
||||||
|
checkState(
|
||||||
|
!Strings.isNullOrEmpty(certsFile),
|
||||||
|
"trustedCa.file-name in certificateValidationContext cannot be empty");
|
||||||
|
return CertificateUtils.toX509Certificates(new File(certsFile));
|
||||||
|
} else if (specifierCase == SpecifierCase.INLINE_BYTES) {
|
||||||
|
return CertificateUtils.toX509Certificates(
|
||||||
|
certificateValidationContext.getTrustedCa().getInlineBytes().newInput());
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Not supported: " + specifierCase);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createSdsX509TrustManager(
|
private void createSdsX509TrustManager(
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package io.grpc.xds.sds.trust;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
import io.envoyproxy.envoy.api.v2.auth.CertificateValidationContext;
|
import io.envoyproxy.envoy.api.v2.auth.CertificateValidationContext;
|
||||||
import io.envoyproxy.envoy.api.v2.core.DataSource;
|
import io.envoyproxy.envoy.api.v2.core.DataSource;
|
||||||
import io.grpc.internal.testing.TestUtils;
|
import io.grpc.internal.testing.TestUtils;
|
||||||
|
|
@ -69,6 +70,26 @@ public class SdsTrustManagerFactoryTest {
|
||||||
.isEqualTo(CertificateUtils.toX509Certificates(TestUtils.loadCert(CA_PEM_FILE))[0]);
|
.isEqualTo(CertificateUtils.toX509Certificates(TestUtils.loadCert(CA_PEM_FILE))[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void constructor_fromInlineBytes()
|
||||||
|
throws CertificateException, IOException, CertStoreException {
|
||||||
|
SdsTrustManagerFactory factory =
|
||||||
|
new SdsTrustManagerFactory(getCertContextFromPathAsInlineBytes(CA_PEM_FILE));
|
||||||
|
assertThat(factory).isNotNull();
|
||||||
|
TrustManager[] tms = factory.getTrustManagers();
|
||||||
|
assertThat(tms).isNotNull();
|
||||||
|
assertThat(tms).hasLength(1);
|
||||||
|
TrustManager myTm = tms[0];
|
||||||
|
assertThat(myTm).isInstanceOf(SdsX509TrustManager.class);
|
||||||
|
SdsX509TrustManager sdsX509TrustManager = (SdsX509TrustManager) myTm;
|
||||||
|
X509Certificate[] acceptedIssuers = sdsX509TrustManager.getAcceptedIssuers();
|
||||||
|
assertThat(acceptedIssuers).isNotNull();
|
||||||
|
assertThat(acceptedIssuers).hasLength(1);
|
||||||
|
X509Certificate caCert = acceptedIssuers[0];
|
||||||
|
assertThat(caCert)
|
||||||
|
.isEqualTo(CertificateUtils.toX509Certificates(TestUtils.loadCert(CA_PEM_FILE))[0]);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void checkServerTrusted_goodCert()
|
public void checkServerTrusted_goodCert()
|
||||||
throws CertificateException, IOException, CertStoreException {
|
throws CertificateException, IOException, CertStoreException {
|
||||||
|
|
@ -135,4 +156,14 @@ public class SdsTrustManagerFactoryTest {
|
||||||
DataSource.newBuilder().setFilename(TestUtils.loadCert(pemFilePath).getAbsolutePath()))
|
DataSource.newBuilder().setFilename(TestUtils.loadCert(pemFilePath).getAbsolutePath()))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** constructs CertificateValidationContext from pemFilePath and sets contents as inline-bytes. */
|
||||||
|
private static final CertificateValidationContext getCertContextFromPathAsInlineBytes(
|
||||||
|
String pemFilePath) throws IOException, CertificateException {
|
||||||
|
X509Certificate x509Cert = TestUtils.loadX509Cert(pemFilePath);
|
||||||
|
return CertificateValidationContext.newBuilder()
|
||||||
|
.setTrustedCa(
|
||||||
|
DataSource.newBuilder().setInlineBytes(ByteString.copyFrom(x509Cert.getEncoded())))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue