Author: rgodfrey
Date: Sat Nov 21 22:25:52 2015
New Revision: 1715586

URL: http://svn.apache.org/viewvc?rev=1715586&view=rev
Log:
QPID-6876 : Provide a mechanism to extract the certificate of an auto generated 
self signed key

Modified:
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStore.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStoreImpl.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/autogeneratedselfsigned/show.js
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/store/autogeneratedselfsigned/add.html
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/store/autogeneratedselfsigned/show.html

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStore.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStore.java?rev=1715586&r1=1715585&r2=1715586&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStore.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStore.java
 Sat Nov 21 22:25:52 2015
@@ -20,11 +20,16 @@
  */
 package org.apache.qpid.server.security;
 
+import java.util.Collection;
+
+import org.apache.qpid.server.logging.LogRecord;
+import org.apache.qpid.server.model.Content;
 import org.apache.qpid.server.model.DerivedAttribute;
 import org.apache.qpid.server.model.KeyStore;
 import org.apache.qpid.server.model.ManagedAttribute;
 import org.apache.qpid.server.model.ManagedObject;
 import org.apache.qpid.server.model.ManagedOperation;
+import org.apache.qpid.server.model.Param;
 
 @ManagedObject( category = false, type = "AutoGeneratedSelfSigned" )
 public interface AutoGeneratedSelfSignedKeyStore<X extends 
AutoGeneratedSelfSignedKeyStore<X>> extends KeyStore<X>
@@ -51,4 +56,12 @@ public interface AutoGeneratedSelfSigned
 
     @ManagedOperation
     void regenerateCertificate();
+
+    @ManagedOperation(nonModifying = true, description = "Extract a Java 
KeyStore containing the certificate for the autogenerated key.  The KeyStore 
can be used as a trust store by a JAva client connecting to the broker")
+    Content getClientTrustStore(@Param(name="password", defaultValue = "", 
description = "The password to use to secure the keystore (by default the empt 
string is used).") String password);
+
+    @ManagedOperation(nonModifying = true, description = "Extract a PEM file 
containing the certificate for the autogenerated key.")
+    Content getCertificate();
+
+
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStoreImpl.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStoreImpl.java?rev=1715586&r1=1715585&r2=1715586&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStoreImpl.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStoreImpl.java
 Sat Nov 21 22:25:52 2015
@@ -22,6 +22,9 @@ package org.apache.qpid.server.security;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -31,9 +34,12 @@ import java.net.NetworkInterface;
 import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
 import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.SecureRandom;
+import java.security.cert.Certificate;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
@@ -50,6 +56,7 @@ import java.util.Set;
 
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManagerFactory;
 import javax.xml.bind.DatatypeConverter;
 
 import com.google.common.util.concurrent.Futures;
@@ -60,10 +67,13 @@ import org.apache.qpid.server.logging.Ev
 import org.apache.qpid.server.logging.messages.KeyStoreMessages;
 import org.apache.qpid.server.model.AbstractConfiguredObject;
 import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Content;
+import org.apache.qpid.server.model.CustomRestHeaders;
 import org.apache.qpid.server.model.IntegrityViolationException;
 import org.apache.qpid.server.model.ManagedAttributeField;
 import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
 import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.RestContentHeader;
 import org.apache.qpid.server.model.State;
 import org.apache.qpid.server.model.StateTransition;
 import org.apache.qpid.transport.network.security.ssl.SSLUtil;
@@ -411,4 +421,128 @@ public class AutoGeneratedSelfSignedKeyS
         generatePrivateKeyAndCertificate();
         saveDerivedAttributesIfNecessary();
     }
+
+    @Override
+    public Content getClientTrustStore(String password)
+    {
+
+        try
+        {
+            KeyStore inMemoryKeyStore =
+                    KeyStore.getInstance(KeyStore.getDefaultType());
+
+            inMemoryKeyStore.load(null, null);
+            inMemoryKeyStore.setCertificateEntry(getName(), _certificate);
+
+            return new TrustStoreContent(inMemoryKeyStore, getName(), password 
== null ? new char[0] : password.toCharArray());
+        }
+        catch (CertificateException | NoSuchAlgorithmException | IOException | 
KeyStoreException e)
+        {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+
+    @Override
+    public Content getCertificate()
+    {
+        try
+        {
+            return new CertificateContent(_certificate, getName());
+        }
+        catch (CertificateEncodingException e)
+        {
+            throw new IllegalArgumentException("Cannot decode encode the 
certificate");
+        }
+
+    }
+
+    private static class TrustStoreContent implements Content, 
CustomRestHeaders
+    {
+        private final KeyStore _keyStore;
+        private final char[] _password;
+        private final String _disposition;
+
+        public TrustStoreContent(final KeyStore inMemoryKeyStore,
+                                 final String name, final char[] password)
+        {
+            _keyStore = inMemoryKeyStore;
+            _password = password;
+            _disposition = "attachment; filename=\"" + name + ".jks\"";
+        }
+
+        @Override
+        public void write(final OutputStream outputStream) throws IOException
+        {
+            try
+            {
+                _keyStore.store(outputStream, _password);
+            }
+            catch (KeyStoreException | NoSuchAlgorithmException | 
CertificateException e)
+            {
+                throw new IllegalArgumentException(e);
+            }
+        }
+
+        @RestContentHeader("Content-Type")
+        public String getContentType()
+        {
+            return "application/octet-stream";
+        }
+
+        @RestContentHeader("Content-Disposition")
+        public String getContentDisposition()
+        {
+            return _disposition;
+        }
+
+    }
+
+    private static class CertificateContent implements Content, 
CustomRestHeaders
+    {
+
+        private final String _disposition;
+        private final String _certString;
+
+        public CertificateContent(final X509Certificate certificate, final 
String name)
+                throws CertificateEncodingException
+        {
+            _disposition = "attachment; filename=\"" + name + ".pem\"";
+            StringBuffer certStringBuffer = new StringBuffer("-----BEGIN 
CERTIFICATE-----\n");
+            String cert = 
DatatypeConverter.printBase64Binary(certificate.getEncoded());
+            int offset = 0;
+            while(cert.length()-offset > 64)
+            {
+                certStringBuffer.append(cert.substring(offset, offset+64));
+                offset+=64;
+                certStringBuffer.append("\n");
+            }
+            certStringBuffer.append(cert.substring(offset));
+            certStringBuffer.append("\n-----END CERTIFICATE-----\n");
+            _certString = certStringBuffer.toString();
+        }
+
+        @Override
+        public void write(final OutputStream outputStream) throws IOException
+        {
+            Writer w = new OutputStreamWriter(outputStream);
+            w.write(_certString);
+            w.flush();
+        }
+
+        @RestContentHeader("Content-Type")
+        public String getContentType()
+        {
+            return "text/plain";
+        }
+
+        @RestContentHeader("Content-Disposition")
+        public String getContentDisposition()
+        {
+            return _disposition;
+        }
+
+    }
+
+
 }

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/autogeneratedselfsigned/show.js
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/autogeneratedselfsigned/show.js?rev=1715586&r1=1715585&r2=1715586&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/autogeneratedselfsigned/show.js
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/store/autogeneratedselfsigned/show.js
 Sat Nov 21 22:25:52 2015
@@ -17,26 +17,64 @@
  * under the License.
  */
 
-define(["qpid/common/util", "dojo/domReady!"],
-  function (util)
+define(["qpid/common/util",
+        "dojo/query",
+        "dijit/registry",
+        "dojo/_base/connect",
+        "dojo/_base/event",
+        "dojo/domReady!"],
+  function (util, query, registry, connect, event)
   {
 
     function AutoGeneratedSelfSignedKeyStoreProvider(data)
     {
         this.fields = [];
+        this.management = data.parent.management;
+        this.modelObj = data.parent.modelObj;
         var attributes = 
data.parent.management.metadata.getMetaData("KeyStore", 
"AutoGeneratedSelfSigned").attributes;
         for(var name in attributes)
         {
             this.fields.push(name);
         }
-        util.buildUI(data.containerNode, data.parent, 
"store/autogeneratedselfsigned/show.html", this.fields, this);
+        var that = this;
+
+        util.buildUI(data.containerNode, data.parent, 
"store/autogeneratedselfsigned/show.html", this.fields, this, function() {
+            var getCertificateButton = query(".getCertificateButton", 
data.containerNode)[0];
+            var getCertificateWidget = registry.byNode(getCertificateButton);
+            connect.connect(getCertificateWidget, "onClick",
+                function (evt) {
+                    event.stop(evt);
+                    that.getCertificate();
+                });
+            var getClientTrustStoreButton = 
query(".getClientTrustStoreButton", data.containerNode)[0];
+            var getClientTrustStoreWidget = 
registry.byNode(getClientTrustStoreButton);
+            connect.connect(getClientTrustStoreWidget, "onClick",
+                function (evt) {
+                    event.stop(evt);
+                    that.getClientTrustStore();
+                });
+        });
     }
 
     AutoGeneratedSelfSignedKeyStoreProvider.prototype.update = function(data)
+                                                                {
+                                                                    
util.updateUI(data, this.fields, this);
+                                                                };
+
+    AutoGeneratedSelfSignedKeyStoreProvider.prototype.getCertificate = 
function()
     {
-        util.updateUI(data, this.fields, this);
-    }
+        var modelObj = this.modelObj;
+        this.management.download({ parent: modelObj, name: "getCertificate", 
type: modelObj.type})
+    };
+
+
+    AutoGeneratedSelfSignedKeyStoreProvider.prototype.getClientTrustStore = 
function()
+    {
+        var modelObj = this.modelObj;
+        this.management.download({ parent: modelObj, name: 
"getClientTrustStore", type: modelObj.type})
+    };
+
 
-    return AutoGeneratedSelfSignedKeyStoreProvider;
+      return AutoGeneratedSelfSignedKeyStoreProvider;
   }
 );

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/store/autogeneratedselfsigned/add.html
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/store/autogeneratedselfsigned/add.html?rev=1715586&r1=1715585&r2=1715586&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/store/autogeneratedselfsigned/add.html
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/store/autogeneratedselfsigned/add.html
 Sat Nov 21 22:25:52 2015
@@ -46,7 +46,7 @@
             </div>
         </div>
         <div class="clear">
-            <div class="formLabel-labelCell tableContainer-labelCell 
clear">Signature algorithm:</div>
+            <div class="formLabel-labelCell tableContainer-labelCell 
clear">Key Length:</div>
             <div class="formLabel-controlCell tableContainer-valueCell">
                 <input type="text" id="addStore.keyLength"
                        data-dojo-type="dijit/form/ValidationTextBox"
@@ -58,7 +58,7 @@
             </div>
         </div>
         <div class="clear">
-            <div class="formLabel-labelCell tableContainer-labelCell 
clear">Signature algorithm:</div>
+            <div class="formLabel-labelCell tableContainer-labelCell 
clear">Duration:</div>
             <div class="formLabel-controlCell tableContainer-valueCell">
                 <input type="text" id="addStore.durationInMonths"
                        data-dojo-type="dijit/form/ValidationTextBox"

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/store/autogeneratedselfsigned/show.html
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/store/autogeneratedselfsigned/show.html?rev=1715586&r1=1715585&r2=1715586&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/store/autogeneratedselfsigned/show.html
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/store/autogeneratedselfsigned/show.html
 Sat Nov 21 22:25:52 2015
@@ -35,5 +35,9 @@
         <div><span class="durationInMonths" ></span></div>
     </div>
     <div class="clear"></div>
+    <div class="dijitDialogPaneActionBar">
+        <button data-dojo-type="dijit.form.Button" 
class="getCertificateButton" type="button">Download Certificate</button>
+        <button data-dojo-type="dijit.form.Button" 
class="getClientTrustStoreButton" type="button">Download Client Trust 
Store</button>
+    </div>
 </div>
 



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to