You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rg...@apache.org on 2014/07/30 16:33:34 UTC

svn commit: r1614667 - in /qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server: model/TrustStore.java security/FileTrustStore.java security/NonJavaTrustStore.java security/NonJavaTrustStoreImpl.java

Author: rgodfrey
Date: Wed Jul 30 14:33:33 2014
New Revision: 1614667

URL: http://svn.apache.org/r1614667
Log:
QPID-5946 : [Java Broker] Add alternative TrusStore implementation that can use standard crt files rather than jks files

Added:
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStore.java
      - copied, changed from r1614652, qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStore.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java
      - copied, changed from r1614652, qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java
Modified:
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/TrustStore.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/TrustStore.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/TrustStore.java?rev=1614667&r1=1614666&r2=1614667&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/TrustStore.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/TrustStore.java Wed Jul 30 14:33:33 2014
@@ -26,12 +26,6 @@ import javax.net.ssl.TrustManager;
 @ManagedObject( defaultType = "FileTrustStore" )
 public interface TrustStore<X extends TrustStore<X>> extends ConfiguredObject<X>
 {
-    @ManagedAttribute( secure = true, mandatory = true)
-    public String getPassword();
-
-    public void setPassword(String password);
-
     public TrustManager[] getTrustManagers() throws GeneralSecurityException;
 
-
 }

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java?rev=1614667&r1=1614666&r2=1614667&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStore.java Wed Jul 30 14:33:33 2014
@@ -71,4 +71,6 @@ public interface FileTrustStore<X extend
 
     @ManagedAttribute( secure = true, mandatory = true )
     String getPassword();
+
+    void setPassword(String password);
 }

Copied: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStore.java (from r1614652, qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStore.java)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStore.java?p2=qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStore.java&p1=qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStore.java&r1=1614652&r2=1614667&rev=1614667&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStore.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStore.java Wed Jul 30 14:33:33 2014
@@ -20,30 +20,31 @@
  */
 package org.apache.qpid.server.security;
 
+import java.util.List;
+import java.util.Map;
+
 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.TrustStore;
 
-@ManagedObject( category = false, type = "NonJavaKeyStore" )
-public interface NonJavaKeyStore<X extends NonJavaKeyStore<X>> extends KeyStore<X>
+@ManagedObject( category = false, type = "NonJavaTrustStore" )
+public interface NonJavaTrustStore<X extends NonJavaTrustStore<X>> extends TrustStore<X>
 {
 
-    @ManagedAttribute( mandatory = true, secure = true )
-    String getPrivateKeyUrl();
-
     @ManagedAttribute( mandatory = true )
-    String getCertificateUrl();
+    String getCertificatesUrl();
 
-    @ManagedAttribute
-    String getIntermediateCertificateUrl();
+    enum CertificateDetails
+    {
+        SUBJECT_NAME,
+        ISSUER_NAME,
+        VALID_START,
+        VALID_END
 
-    @DerivedAttribute
-    String getSubjectName();
+    }
 
     @DerivedAttribute
-    public long getCertificateValidEnd();
+    List<Map<CertificateDetails,Object>> getCertificateDetails();
 
-    @DerivedAttribute
-    public long getCertificateValidStart();
 }

Copied: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java (from r1614652, qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java?p2=qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java&p1=qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java&r1=1614652&r2=1614667&rev=1614667&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java Wed Jul 30 14:33:33 2014
@@ -20,28 +20,20 @@
  */
 package org.apache.qpid.server.security;
 
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.StringReader;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
 import java.security.AccessControlException;
 import java.security.GeneralSecurityException;
-import java.security.KeyFactory;
-import java.security.PrivateKey;
-import java.security.SecureRandom;
+import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
-import java.security.spec.PKCS8EncodedKeySpec;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
+import java.util.EnumMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -49,9 +41,9 @@ import java.util.Set;
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.xml.bind.DatatypeConverter;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.security.auth.x500.X500Principal;
 
 import org.apache.log4j.Logger;
 
@@ -70,112 +62,106 @@ import org.apache.qpid.server.security.a
 import org.apache.qpid.server.util.urlstreamhandler.data.Handler;
 
 @ManagedObject( category = false )
-public class NonJavaKeyStoreImpl extends AbstractConfiguredObject<NonJavaKeyStoreImpl> implements NonJavaKeyStore<NonJavaKeyStoreImpl>
+public class NonJavaTrustStoreImpl
+        extends AbstractConfiguredObject<NonJavaTrustStoreImpl> implements NonJavaTrustStore<NonJavaTrustStoreImpl>
 {
-    private static final Logger LOGGER = Logger.getLogger(NonJavaKeyStoreImpl.class);
+    private static final Logger LOGGER = Logger.getLogger(NonJavaTrustStoreImpl.class);
 
     private final Broker<?> _broker;
 
-    @ManagedAttributeField( afterSet = "updateKeyManagers" )
-    private String _privateKeyUrl;
-    @ManagedAttributeField( afterSet = "updateKeyManagers" )
-    private String _certificateUrl;
-    @ManagedAttributeField( afterSet = "updateKeyManagers" )
-    private String _intermediateCertificateUrl;
+    @ManagedAttributeField( afterSet = "updateTrustManagers" )
+    private String _certificatesUrl;
+
+    private volatile TrustManager[] _trustManagers = new TrustManager[0];
 
-    private volatile KeyManager[] _keyManagers = new KeyManager[0];
 
-    private static final SecureRandom RANDOM = new SecureRandom();
 
     static
     {
         Handler.register();
     }
 
-    private X509Certificate _certificate;
+    private X509Certificate[] _certificates;
 
     @ManagedObjectFactoryConstructor
-    public NonJavaKeyStoreImpl(final Map<String, Object> attributes, Broker<?> broker)
+    public NonJavaTrustStoreImpl(final Map<String, Object> attributes, Broker<?> broker)
     {
         super(parentsMap(broker), attributes);
         _broker = broker;
     }
 
     @Override
-    public String getPrivateKeyUrl()
+    public String getCertificatesUrl()
     {
-        return _privateKeyUrl;
+        return _certificatesUrl;
     }
 
+
     @Override
-    public String getCertificateUrl()
+    public List<Map<CertificateDetails,Object>> getCertificateDetails()
     {
-        return _certificateUrl;
+        List<Map<CertificateDetails,Object>> certificateDetails = new ArrayList<>();
+        for(X509Certificate certificate : _certificates)
+        {
+            Map<CertificateDetails,Object> details = new EnumMap<>(CertificateDetails.class);
+
+            details.put(CertificateDetails.SUBJECT_NAME, getNameFromCertificate(certificate));
+            details.put(CertificateDetails.ISSUER_NAME, certificate.getIssuerX500Principal().getName());
+            details.put(CertificateDetails.VALID_START, certificate.getNotBefore());
+            details.put(CertificateDetails.VALID_END, certificate.getNotAfter());
+            certificateDetails.add(details);
+        }
+        return certificateDetails;
     }
 
-    @Override
-    public String getIntermediateCertificateUrl()
+    private String getNameFromCertificate(final X509Certificate certificate)
     {
-        return _intermediateCertificateUrl;
+        String name;
+        X500Principal subjectX500Principal = certificate.getSubjectX500Principal();
+        name = getCommonNameFromPrincipal(subjectX500Principal);
+
+        return name;
     }
 
-    @Override
-    public String getSubjectName()
+    private String getCommonNameFromPrincipal(final X500Principal subjectX500Principal)
     {
-        if(_certificate != null)
+        String name;
+        String dn = subjectX500Principal.getName();
+        try
         {
-            try
+            LdapName ldapDN = new LdapName(dn);
+            name = dn;
+            for (Rdn rdn : ldapDN.getRdns())
             {
-                String dn = _certificate.getSubjectX500Principal().getName();
-                LdapName ldapDN = new LdapName(dn);
-                String name = dn;
-                for (Rdn rdn : ldapDN.getRdns())
+                if (rdn.getType().equalsIgnoreCase("CN"))
                 {
-                    if (rdn.getType().equalsIgnoreCase("CN"))
-                    {
-                        name = String.valueOf(rdn.getValue());
-                        break;
-                    }
+                    name = String.valueOf(rdn.getValue());
+                    break;
                 }
-                return name;
-            }
-            catch (InvalidNameException e)
-            {
-                LOGGER.error("Error getting subject name from certificate");
-                return null;
             }
+
         }
-        else
+        catch (InvalidNameException e)
         {
-            return null;
+            LOGGER.error("Error getting subject name from certificate");
+            name =  null;
         }
-    }
-
-    @Override
-    public long getCertificateValidEnd()
-    {
-        return _certificate == null ? 0 : _certificate.getNotAfter().getTime();
-    }
-
-    @Override
-    public long getCertificateValidStart()
-    {
-        return _certificate == null ? 0 : _certificate.getNotBefore().getTime();
+        return name;
     }
 
 
     @Override
-    public KeyManager[] getKeyManagers() throws GeneralSecurityException
+    public TrustManager[] getTrustManagers() throws GeneralSecurityException
     {
 
-        return _keyManagers;
+        return _trustManagers;
     }
 
     @Override
     public void onValidate()
     {
         super.onValidate();
-        validateKeyStoreAttributes(this);
+        validateTrustStoreAttributes(this);
     }
 
     @Override
@@ -247,24 +233,19 @@ public class NonJavaKeyStoreImpl extends
     protected void validateChange(final ConfiguredObject<?> proxyForValidation, final Set<String> changedAttributes)
     {
         super.validateChange(proxyForValidation, changedAttributes);
-        NonJavaKeyStore changedStore = (NonJavaKeyStore) proxyForValidation;
+        NonJavaTrustStore changedStore = (NonJavaTrustStore) proxyForValidation;
         if (changedAttributes.contains(NAME) && !getName().equals(changedStore.getName()))
         {
             throw new IllegalConfigurationException("Changing the key store name is not allowed");
         }
-        validateKeyStoreAttributes(changedStore);
+        validateTrustStoreAttributes(changedStore);
     }
 
-    private void validateKeyStoreAttributes(NonJavaKeyStore<?> keyStore)
+    private void validateTrustStoreAttributes(NonJavaTrustStore<?> keyStore)
     {
         try
         {
-            getUrlFromString(keyStore.getPrivateKeyUrl()).openStream();
-            getUrlFromString(keyStore.getCertificateUrl()).openStream();
-            if(keyStore.getIntermediateCertificateUrl() != null)
-            {
-                getUrlFromString(keyStore.getIntermediateCertificateUrl()).openStream();
-            }
+            getUrlFromString(keyStore.getCertificatesUrl()).openStream();
         }
         catch (IOException e)
         {
@@ -273,42 +254,35 @@ public class NonJavaKeyStoreImpl extends
     }
 
     @SuppressWarnings("unused")
-    private void updateKeyManagers()
+    private void updateTrustManagers()
     {
         try
         {
-            if (_privateKeyUrl != null && _certificateUrl != null)
+            if (_certificatesUrl != null)
             {
-                PrivateKey privateKey = readPrivateKey(getUrlFromString(_privateKeyUrl));
-                X509Certificate[] certs = readCertificates(getUrlFromString(_certificateUrl));
-                if(_intermediateCertificateUrl != null)
+                X509Certificate[] certs = readCertificates(getUrlFromString(_certificatesUrl));
+                java.security.KeyStore inMemoryKeyStore = java.security.KeyStore.getInstance(java.security.KeyStore.getDefaultType());
+
+                inMemoryKeyStore.load(null, null);
+                int i = 1;
+                for(Certificate cert : certs)
                 {
-                    List<X509Certificate> allCerts = new ArrayList<>(Arrays.asList(certs));
-                    allCerts.addAll(Arrays.asList(readCertificates(getUrlFromString(_intermediateCertificateUrl))));
-                    certs = allCerts.toArray(new X509Certificate[allCerts.size()]);
+                    inMemoryKeyStore.setCertificateEntry(String.valueOf(i++), cert);
                 }
 
-                java.security.KeyStore inMemoryKeyStore = java.security.KeyStore.getInstance(java.security.KeyStore.getDefaultType());
 
-                byte[] bytes = new byte[64];
-                char[] chars = new char[64];
-                RANDOM.nextBytes(bytes);
-                StandardCharsets.US_ASCII.decode(ByteBuffer.wrap(bytes)).get(chars);
-                inMemoryKeyStore.load(null, chars);
-                inMemoryKeyStore.setKeyEntry("1", privateKey, chars, certs);
 
-
-                KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-                kmf.init(inMemoryKeyStore, chars);
-                _keyManagers = kmf.getKeyManagers();
-                _certificate = certs[0];
+                TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+                tmf.init(inMemoryKeyStore);
+                _trustManagers = tmf.getTrustManagers();
+                _certificates = certs;
             }
 
         }
         catch (IOException | GeneralSecurityException e)
         {
             LOGGER.error("Error attempting to create KeyStore from private key and certificates", e);
-            _keyManagers = new KeyManager[0];
+            _trustManagers = new TrustManager[0];
         }
     }
 
@@ -351,54 +325,4 @@ public class NonJavaKeyStoreImpl extends
         return crt.toArray(new X509Certificate[crt.size()]);
     }
 
-    private static PrivateKey readPrivateKey(final URL url)
-            throws IOException, GeneralSecurityException
-    {
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        try (InputStream urlStream = url.openStream())
-        {
-            byte[] tmp = new byte[1024];
-            int read;
-            while((read = urlStream.read(tmp)) != -1)
-            {
-                buffer.write(tmp,0,read);
-            }
-        }
-
-        byte[] content = buffer.toByteArray();
-        String contentAsString = new String(content, StandardCharsets.US_ASCII);
-        if(contentAsString.contains("-----BEGIN ") && contentAsString.contains(" PRIVATE KEY-----"))
-        {
-            BufferedReader lineReader = new BufferedReader(new StringReader(contentAsString));
-
-            String line;
-            do
-            {
-                line = lineReader.readLine();
-            } while(line != null && !(line.startsWith("-----BEGIN ") && line.endsWith(" PRIVATE KEY-----")));
-
-            if(line != null)
-            {
-                StringBuilder keyBuilder = new StringBuilder();
-
-                while((line = lineReader.readLine()) != null)
-                {
-                    if(line.startsWith("-----END ") && line.endsWith(" PRIVATE KEY-----"))
-                    {
-                        break;
-                    }
-                    keyBuilder.append(line);
-                }
-
-                content = DatatypeConverter.parseBase64Binary(keyBuilder.toString());
-            }
-        }
-        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(content);
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        PrivateKey key = kf.generatePrivate(keySpec);
-        return key;
-    }
-
-
-
 }



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