Support supplying key and certificate to Docker as data
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/61fb3ec1 Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/61fb3ec1 Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/61fb3ec1 Branch: refs/heads/master Commit: 61fb3ec14581a8a91bb35d45536d61968d13c973 Parents: 42d0576 Author: Andrew Donald Kennedy <[email protected]> Authored: Wed May 18 11:28:58 2016 +0100 Committer: Andrea Turli <[email protected]> Committed: Mon May 23 17:52:24 2016 +0200 ---------------------------------------------------------------------- .../org/jclouds/docker/DockerApiMetadata.java | 6 ++- .../suppliers/DockerSSLContextSupplier.java | 18 +++++-- .../DockerUntrustedSSLContextSupplier.java | 12 +++-- .../docker/suppliers/SSLContextBuilder.java | 57 ++++++++++++++------ 4 files changed, 67 insertions(+), 26 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/61fb3ec1/apis/docker/src/main/java/org/jclouds/docker/DockerApiMetadata.java ---------------------------------------------------------------------- diff --git a/apis/docker/src/main/java/org/jclouds/docker/DockerApiMetadata.java b/apis/docker/src/main/java/org/jclouds/docker/DockerApiMetadata.java index 9089fd0..453f393 100644 --- a/apis/docker/src/main/java/org/jclouds/docker/DockerApiMetadata.java +++ b/apis/docker/src/main/java/org/jclouds/docker/DockerApiMetadata.java @@ -38,6 +38,7 @@ import com.google.inject.Module; public class DockerApiMetadata extends BaseHttpApiMetadata<DockerApi> { public static final String DOCKER_CA_CERT_PATH = "docker.cacert.path"; + public static final String DOCKER_CA_CERT_DATA = "docker.cacert.data"; @Override public Builder toBuilder() { @@ -58,6 +59,7 @@ public class DockerApiMetadata extends BaseHttpApiMetadata<DockerApi> { properties.setProperty(ComputeServiceProperties.IMAGE_LOGIN_USER, "root:password"); properties.setProperty(TEMPLATE, "osFamily=UBUNTU,os64Bit=true"); properties.setProperty(DOCKER_CA_CERT_PATH, ""); + properties.setProperty(DOCKER_CA_CERT_DATA, ""); return properties; } @@ -67,8 +69,8 @@ public class DockerApiMetadata extends BaseHttpApiMetadata<DockerApi> { super(DockerApi.class); id("docker") .name("Docker API") - .identityName("Path to certificate .pem file") - .credentialName("Path to key .pem file") + .identityName("Path or data for certificate .pem file") + .credentialName("Path or data for key .pem file") .documentation(URI.create("https://docs.docker.com/reference/api/docker_remote_api/")) .version("1.21") .defaultEndpoint("https://127.0.0.1:2376") http://git-wip-us.apache.org/repos/asf/jclouds/blob/61fb3ec1/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerSSLContextSupplier.java ---------------------------------------------------------------------- diff --git a/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerSSLContextSupplier.java b/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerSSLContextSupplier.java index ed901f3..326528a 100644 --- a/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerSSLContextSupplier.java +++ b/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerSSLContextSupplier.java @@ -18,6 +18,7 @@ package org.jclouds.docker.suppliers; import com.google.common.base.Strings; import com.google.common.base.Supplier; + import org.jclouds.docker.DockerApiMetadata; import org.jclouds.domain.Credentials; import org.jclouds.location.Provider; @@ -26,22 +27,25 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import javax.net.ssl.SSLContext; + import java.io.IOException; import java.security.GeneralSecurityException; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Throwables.propagate; +import static org.jclouds.docker.suppliers.SSLContextBuilder.isClientKeyAndCertificateData; @Singleton public class DockerSSLContextSupplier implements Supplier<SSLContext> { private final Supplier<Credentials> creds; private final String caCertPath; - + private final String caCertData; @Inject - DockerSSLContextSupplier(@Provider Supplier<Credentials> creds, @Named(DockerApiMetadata.DOCKER_CA_CERT_PATH) String caCertPath) { + DockerSSLContextSupplier(@Provider Supplier<Credentials> creds, @Named(DockerApiMetadata.DOCKER_CA_CERT_PATH) String caCertPath, @Named(DockerApiMetadata.DOCKER_CA_CERT_DATA) String caCertData) { this.creds = creds; this.caCertPath = caCertPath; + this.caCertData = caCertData; } @Override @@ -49,9 +53,15 @@ public class DockerSSLContextSupplier implements Supplier<SSLContext> { Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null"); try { SSLContextBuilder builder = new SSLContextBuilder(); - builder.clientKeyAndCertificate(currentCreds.credential, currentCreds.identity); + if (isClientKeyAndCertificateData(currentCreds.credential, currentCreds.identity)) { + builder.clientKeyAndCertificateData(currentCreds.credential, currentCreds.identity); + } else { + builder.clientKeyAndCertificatePaths(currentCreds.credential, currentCreds.identity); + } if (!Strings.isNullOrEmpty(caCertPath)) { - builder.caCertificate(caCertPath); + builder.caCertificatePath(caCertPath); + } else if (!Strings.isNullOrEmpty(caCertData)) { + builder.caCertificateData(caCertData); } return builder.build(); } catch (GeneralSecurityException e) { http://git-wip-us.apache.org/repos/asf/jclouds/blob/61fb3ec1/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerUntrustedSSLContextSupplier.java ---------------------------------------------------------------------- diff --git a/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerUntrustedSSLContextSupplier.java b/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerUntrustedSSLContextSupplier.java index 880a48a..f972bb4 100644 --- a/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerUntrustedSSLContextSupplier.java +++ b/apis/docker/src/main/java/org/jclouds/docker/suppliers/DockerUntrustedSSLContextSupplier.java @@ -17,6 +17,7 @@ package org.jclouds.docker.suppliers; import com.google.common.base.Supplier; + import org.jclouds.domain.Credentials; import org.jclouds.http.config.SSLModule; import org.jclouds.location.Provider; @@ -30,6 +31,7 @@ import java.io.IOException; import java.security.GeneralSecurityException; import static com.google.common.base.Throwables.propagate; +import static org.jclouds.docker.suppliers.SSLContextBuilder.isClientKeyAndCertificateData; @Singleton public class DockerUntrustedSSLContextSupplier implements Supplier<SSLContext> { @@ -45,13 +47,13 @@ public class DockerUntrustedSSLContextSupplier implements Supplier<SSLContext> { @Override public SSLContext get() { - Credentials currentCreds = creds.get(); + Credentials currentCreds = checkNotNull(creds.get(), "credential supplier returned null"); try { SSLContextBuilder builder = new SSLContextBuilder(); - // check if identity and credential are files, to set up sslContext - if (currentCreds != null && new File(currentCreds.identity).isFile() - && new File(currentCreds.credential).isFile()) { - builder.clientKeyAndCertificate(currentCreds.credential, currentCreds.identity); + if (isClientKeyAndCertificateData(currentCreds.credential, currentCreds.identity)) { + builder.clientKeyAndCertificateData(currentCreds.credential, currentCreds.identity); + } else if (new File(currentCreds.identity).isFile() && new File(currentCreds.credential).isFile()) { + builder.clientKeyAndCertificatePaths(currentCreds.credential, currentCreds.identity); } builder.trustManager(insecureTrustManager); return builder.build(); http://git-wip-us.apache.org/repos/asf/jclouds/blob/61fb3ec1/apis/docker/src/main/java/org/jclouds/docker/suppliers/SSLContextBuilder.java ---------------------------------------------------------------------- diff --git a/apis/docker/src/main/java/org/jclouds/docker/suppliers/SSLContextBuilder.java b/apis/docker/src/main/java/org/jclouds/docker/suppliers/SSLContextBuilder.java index 6030def..cc1025b 100644 --- a/apis/docker/src/main/java/org/jclouds/docker/suppliers/SSLContextBuilder.java +++ b/apis/docker/src/main/java/org/jclouds/docker/suppliers/SSLContextBuilder.java @@ -18,10 +18,13 @@ package org.jclouds.docker.suppliers; import com.google.common.base.Charsets; import com.google.common.io.Files; + import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; + +import org.jclouds.crypto.Pems; import org.jclouds.util.Closeables2; import javax.net.ssl.KeyManager; @@ -29,6 +32,7 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509ExtendedKeyManager; + import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; @@ -54,22 +58,48 @@ public class SSLContextBuilder { private KeyManager[] keyManagers; private TrustManager[] trustManagers; + public static final boolean isClientKeyAndCertificateData(String key, String cert) { + return (key.startsWith(Pems.PUBLIC_X509_MARKER) || key.startsWith(Pems.PUBLIC_PKCS1_MARKER)) && + cert.startsWith(Pems.CERTIFICATE_X509_MARKER); + } + public SSLContextBuilder() { } - public SSLContextBuilder clientKeyAndCertificate(String keyPath, String certPath) throws IOException, CertificateException { + public SSLContextBuilder clientKeyAndCertificatePaths(String keyPath, String certPath) throws IOException, CertificateException { X509Certificate certificate = getCertificate(loadFile(certPath)); PrivateKey privateKey = getKey(loadFile(keyPath)); - keyManagers = new KeyManager[]{new InMemoryKeyManager(certificate, privateKey)}; + keyManager(new InMemoryKeyManager(certificate, privateKey)); + return this; + } + + public SSLContextBuilder clientKeyAndCertificateData(String keyData, String certData) throws CertificateException { + X509Certificate certificate = getCertificate(certData); + PrivateKey privateKey = getKey(keyData); + keyManager(new InMemoryKeyManager(certificate, privateKey)); + return this; + } + + public SSLContextBuilder caCertificatePath(String caCertPath) { + try { + trustManagers = getTrustManagerWithCaCert(loadFile(caCertPath)); + } catch (IOException e) { + throw propagate(e); + } return this; } - public SSLContextBuilder caCertificate(String caCertPath){ + public SSLContextBuilder caCertificateData(String caCertPath) { trustManagers = getTrustManagerWithCaCert(caCertPath); return this; } + public SSLContextBuilder keyManager(KeyManager keyManager) { + keyManagers = new KeyManager[] { keyManager }; + return this; + } + public SSLContextBuilder trustManager(TrustManager trustManager) { - trustManagers = new TrustManager[]{trustManager}; + trustManagers = new TrustManager[] { trustManager }; return this; } @@ -79,9 +109,9 @@ public class SSLContextBuilder { return sslContext; } - private TrustManager[] getTrustManagerWithCaCert(String caCertPath) { + private TrustManager[] getTrustManagerWithCaCert(String caCertData) { try { - X509Certificate caCert = getCertificate(loadFile(caCertPath)); + X509Certificate caCert = getCertificate(caCertData); KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null, null); trustStore.setCertificateEntry("ca", caCert); @@ -132,32 +162,29 @@ public class SSLContextBuilder { private final PrivateKey privateKey; - public InMemoryKeyManager(final X509Certificate certificate, final PrivateKey privateKey) - throws IOException, CertificateException { + public InMemoryKeyManager(final X509Certificate certificate, final PrivateKey privateKey) throws CertificateException { this.certificate = certificate; this.privateKey = privateKey; } @Override - public String chooseClientAlias(final String[] keyType, final Principal[] issuers, - final Socket socket) { + public String chooseClientAlias(final String[] keyType, final Principal[] issuers, final Socket socket) { return DEFAULT_ALIAS; } @Override - public String chooseServerAlias(final String keyType, final Principal[] issuers, - final Socket socket) { + public String chooseServerAlias(final String keyType, final Principal[] issuers, final Socket socket) { return DEFAULT_ALIAS; } @Override public X509Certificate[] getCertificateChain(final String alias) { - return new X509Certificate[]{certificate}; + return new X509Certificate[] { certificate }; } @Override public String[] getClientAliases(final String keyType, final Principal[] issuers) { - return new String[]{DEFAULT_ALIAS}; + return new String[] { DEFAULT_ALIAS }; } @Override @@ -167,7 +194,7 @@ public class SSLContextBuilder { @Override public String[] getServerAliases(final String keyType, final Principal[] issuers) { - return new String[]{DEFAULT_ALIAS}; + return new String[] { DEFAULT_ALIAS }; } }
