Use self signed certificate when running the proxy locally

This allows us to not obtain a certificate and encrypt it with KMS when running the proxy locally during development.

Also updated FOSS build dagger version.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=191746309
This commit is contained in:
jianglai 2018-04-05 08:37:27 -07:00 committed by Ben McIlwain
parent ea891001d9
commit 18a145eef1
10 changed files with 157 additions and 117 deletions

View file

@ -19,10 +19,12 @@ import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableList;
import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
import google.registry.proxy.ProxyModule.PemBytes;
import google.registry.proxy.ProxyConfig.Environment;
import google.registry.util.FormattingLogger;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
@ -32,6 +34,7 @@ import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.function.Function;
import javax.inject.Named;
import javax.inject.Qualifier;
import javax.inject.Singleton;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
@ -44,18 +47,32 @@ import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
/**
* Dagger module that provides bindings needed to inject EPP SSL certificate chain and private key.
*
* <p>The certificates and private key are stored in a .pem file that is encrypted by Cloud KMS. The
* .pem file can be generated by concatenating the .crt certificate files on the chain and the .key
* private file.
* <p>The production certificates and private key are stored in a .pem file that is encrypted by
* Cloud KMS. The .pem file can be generated by concatenating the .crt certificate files on the
* chain and the .key private file.
*
* <p>The certificates in the .pem file must be stored in order, where the next certificate's
* subject is the previous certificate's issuer.
* <p>The production certificates in the .pem file must be stored in order, where the next
* certificate's subject is the previous certificate's issuer.
*
* <p>When running the proxy locally or in test, a self signed certificate is used.
*
* @see <a href="https://cloud.google.com/kms/">Cloud Key Management Service</a>
*/
@Module
public class CertificateModule {
/** Dagger qualifier to provide bindings related to EPP certificates */
@Qualifier
public @interface EppCertificates {}
/** Dagger qualifier to provide bindings when running locally. */
@Qualifier
public @interface Local {}
/** Dagger qualifier to provide bindings when running in production. */
@Qualifier
public @interface Prod {}
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
static {
@ -79,12 +96,56 @@ public class CertificateModule {
.collect(toImmutableList());
}
@Singleton
@Provides
@EppCertificates
static X509Certificate[] provideCertificates(
Environment env,
@Local Lazy<X509Certificate[]> localCertificates,
@Prod Lazy<X509Certificate[]> prodCertificates) {
return (env == Environment.LOCAL) ? localCertificates.get() : prodCertificates.get();
}
@Singleton
@Provides
@EppCertificates
static PrivateKey providePrivateKey(
Environment env,
@Local Lazy<PrivateKey> localPrivateKey,
@Prod Lazy<PrivateKey> prodPrivateKey) {
return (env == Environment.LOCAL) ? localPrivateKey.get() : prodPrivateKey.get();
}
@Singleton
@Provides
static SelfSignedCertificate provideSelfSignedCertificate() {
try {
return new SelfSignedCertificate();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Singleton
@Provides
@Local
static PrivateKey provideLocalPrivateKey(SelfSignedCertificate ssc) {
return ssc.key();
}
@Singleton
@Provides
@Local
static X509Certificate[] provideLocalCertificates(SelfSignedCertificate ssc) {
return new X509Certificate[] {ssc.cert()};
}
@Singleton
@Provides
@Named("pemObjects")
static ImmutableList<Object> providePemObjects(PemBytes pemBytes) {
static ImmutableList<Object> providePemObjects(@Named("pemBytes") byte[] pemBytes) {
PEMParser pemParser =
new PEMParser(new InputStreamReader(new ByteArrayInputStream(pemBytes.getBytes()), UTF_8));
new PEMParser(new InputStreamReader(new ByteArrayInputStream(pemBytes), UTF_8));
ImmutableList.Builder<Object> listBuilder = new ImmutableList.Builder<>();
Object obj;
// PEMParser returns an object (private key, certificate, etc) each time readObject() is called,
@ -107,7 +168,8 @@ public class CertificateModule {
@Singleton
@Provides
static PrivateKey providePrivateKey(@Named("pemObjects") ImmutableList<Object> pemObjects) {
@Prod
static PrivateKey provideProdPrivateKey(@Named("pemObjects") ImmutableList<Object> pemObjects) {
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
Function<PEMKeyPair, PrivateKey> privateKeyConverter =
pemKeyPair -> {
@ -129,8 +191,8 @@ public class CertificateModule {
@Singleton
@Provides
@Named("eppServerCertificates")
static X509Certificate[] provideCertificates(
@Prod
static X509Certificate[] provideProdCertificates(
@Named("pemObjects") ImmutableList<Object> pemObject) {
JcaX509CertificateConverter converter = new JcaX509CertificateConverter().setProvider("BC");
Function<X509CertificateHolder, X509Certificate> certificateConverter =