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 };
         }
     }
 

Reply via email to