From b7ccb75d02b8c30c8e2a631ca7feea7dcda97160 Mon Sep 17 00:00:00 2001 From: Alex Rudyy Date: Tue, 3 Feb 2015 15:02:36 +0000 Subject: QPID-6354: Fix validation of certificates and private keys for non java keystores/truststores git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1656751 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/java/broker-core/pom.xml | 3 + .../qpid/server/security/NonJavaKeyStoreImpl.java | 13 +- .../server/security/NonJavaTrustStoreImpl.java | 9 +- .../qpid/server/security/NonJavaKeyStoreTest.java | 220 +++++++++++++++++++++ .../server/security/NonJavaTrustStoreTest.java | 92 +++++++++ 5 files changed, 325 insertions(+), 12 deletions(-) create mode 100644 qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaKeyStoreTest.java create mode 100644 qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaTrustStoreTest.java (limited to 'qpid/java') diff --git a/qpid/java/broker-core/pom.xml b/qpid/java/broker-core/pom.xml index 68301f07bd..516ac9a4c4 100644 --- a/qpid/java/broker-core/pom.xml +++ b/qpid/java/broker-core/pom.xml @@ -150,6 +150,9 @@ ${basedir}/src/test/resources + + ${basedir}/../test-profiles/test_resources/ssl + diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java index 6231413dd7..f6298ab383 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java @@ -248,16 +248,16 @@ public class NonJavaKeyStoreImpl extends AbstractConfiguredObject _broker = mock(Broker.class); + private final TaskExecutor _taskExecutor = CurrentThreadTaskExecutor.newStartedInstance(); + private final SecurityManager _securityManager = mock(SecurityManager.class); + private final Model _model = BrokerModel.getInstance(); + private final ConfiguredObjectFactory _factory = _model.getObjectFactory(); + private List _testResources; + + @Override + public void setUp() throws Exception + { + super.setUp(); + + when(_broker.getTaskExecutor()).thenReturn(_taskExecutor); + when(_broker.getModel()).thenReturn(_model); + when(_broker.getSecurityManager()).thenReturn(_securityManager); + _testResources = new ArrayList<>(); + } + + @Override + public void tearDown() throws Exception + { + try + { + super.tearDown(); + } + finally + { + for (File resource: _testResources) + { + try + { + resource.delete(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + } + } + + private File[] extractResourcesFromTestKeyStore(boolean pem) throws Exception + { + java.security.KeyStore ks = java.security.KeyStore.getInstance(java.security.KeyStore.getDefaultType()); + try(InputStream is = getClass().getResourceAsStream("/java_broker_keystore.jks")) + { + ks.load(is, KEYSTORE_PASSWORD.toCharArray() ); + } + + + File privateKeyFile = TestFileUtils.createTempFile(this, ".private-key.der"); + try(FileOutputStream kos = new FileOutputStream(privateKeyFile)) + { + Key pvt = ks.getKey("java-broker", KEYSTORE_PASSWORD.toCharArray()); + if (pem) + { + kos.write("-----BEGIN PRIVATE KEY-----\n".getBytes()); + kos.write(Base64.encodeBase64(pvt.getEncoded(), true)); + kos.write("\n-----END PRIVATE KEY-----".getBytes()); + } + else + { + kos.write(pvt.getEncoded()); + } + kos.flush(); + } + + File certificateFile = TestFileUtils.createTempFile(this, ".certificate.der"); + + try(FileOutputStream cos = new FileOutputStream(certificateFile)) + { + Certificate pub = ks.getCertificate("rootca"); + if (pem) + { + cos.write("-----BEGIN CERTIFICATE-----\n".getBytes()); + cos.write(Base64.encodeBase64(pub.getEncoded(), true)); + cos.write("\n-----END CERTIFICATE-----".getBytes()); + } + else + { + cos.write(pub.getEncoded()); + } + cos.flush(); + } + + return new File[]{privateKeyFile,certificateFile}; + } + + public void testCreationOfTrustStoreFromValidPrivateKeyAndCertificateInDERFormat() throws Exception + { + runTestCreationOfTrustStoreFromValidPrivateKeyAndCertificateInDerFormat(false); + } + + public void testCreationOfTrustStoreFromValidPrivateKeyAndCertificateInPEMFormat() throws Exception + { + runTestCreationOfTrustStoreFromValidPrivateKeyAndCertificateInDerFormat(true); + } + + private void runTestCreationOfTrustStoreFromValidPrivateKeyAndCertificateInDerFormat(boolean isPEM)throws Exception + { + File[] resources = extractResourcesFromTestKeyStore(isPEM); + _testResources.addAll(Arrays.asList(resources)); + + Map attributes = new HashMap<>(); + attributes.put(NonJavaKeyStore.NAME, "myTestTrustStore"); + attributes.put("privateKeyUrl", resources[0].toURI().toURL().toExternalForm()); + attributes.put("certificateUrl", resources[1].toURI().toURL().toExternalForm()); + attributes.put(NonJavaKeyStore.TYPE, "NonJavaKeyStore"); + + NonJavaKeyStoreImpl fileTrustStore = + (NonJavaKeyStoreImpl) _factory.create(KeyStore.class, attributes, _broker); + + KeyManager[] keyManagers = fileTrustStore.getKeyManagers(); + assertNotNull(keyManagers); + assertEquals("Unexpected number of key managers", 1, keyManagers.length); + assertNotNull("Key manager is null", keyManagers[0]); + } + + public void testCreationOfTrustStoreFromValidPrivateKeyAndInvalidCertificate()throws Exception + { + File[] resources = extractResourcesFromTestKeyStore(true); + _testResources.addAll(Arrays.asList(resources)); + + File invalidCertificate = TestFileUtils.createTempFile(this, ".invalid.cert", "content"); + _testResources.add(invalidCertificate); + + Map attributes = new HashMap<>(); + attributes.put(NonJavaKeyStore.NAME, "myTestTrustStore"); + attributes.put("privateKeyUrl", resources[0].toURI().toURL().toExternalForm()); + attributes.put("certificateUrl", invalidCertificate.toURI().toURL().toExternalForm()); + attributes.put(NonJavaKeyStore.TYPE, "NonJavaKeyStore"); + + try + { + _factory.create(KeyStore.class, attributes, _broker); + fail("Created key store from invalid certificate"); + } + catch(IllegalConfigurationException e) + { + // pass + } + } + + public void testCreationOfTrustStoreFromInvalidPrivateKeyAndValidCertificate()throws Exception + { + File[] resources = extractResourcesFromTestKeyStore(true); + _testResources.addAll(Arrays.asList(resources)); + + File invalidPrivateKey = TestFileUtils.createTempFile(this, ".invalid.pk", "content"); + _testResources.add(invalidPrivateKey); + + Map attributes = new HashMap<>(); + attributes.put(NonJavaKeyStore.NAME, "myTestTrustStore"); + attributes.put("privateKeyUrl", invalidPrivateKey.toURI().toURL().toExternalForm()); + attributes.put("certificateUrl", resources[1].toURI().toURL().toExternalForm()); + attributes.put(NonJavaKeyStore.TYPE, "NonJavaKeyStore"); + + try + { + _factory.create(KeyStore.class, attributes, _broker); + fail("Created key store from invalid certificate"); + } + catch(IllegalConfigurationException e) + { + // pass + } + } +} diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaTrustStoreTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaTrustStoreTest.java new file mode 100644 index 0000000000..798d9fcbe5 --- /dev/null +++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/NonJavaTrustStoreTest.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.qpid.server.security; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import javax.net.ssl.TrustManager; +import java.util.HashMap; +import java.util.Map; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.ConfiguredObjectFactory; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.test.utils.QpidTestCase; + + +public class NonJavaTrustStoreTest extends QpidTestCase +{ + private final Broker _broker = mock(Broker.class); + private final TaskExecutor _taskExecutor = CurrentThreadTaskExecutor.newStartedInstance(); + private final SecurityManager _securityManager = mock(SecurityManager.class); + private final Model _model = BrokerModel.getInstance(); + private final ConfiguredObjectFactory _factory = _model.getObjectFactory(); + + @Override + public void setUp() throws Exception + { + super.setUp(); + + when(_broker.getTaskExecutor()).thenReturn(_taskExecutor); + when(_broker.getModel()).thenReturn(_model); + when(_broker.getSecurityManager()).thenReturn(_securityManager); + } + + public void testCreationOfTrustStoreFromValidCertificate() throws Exception + { + Map attributes = new HashMap<>(); + attributes.put(NonJavaTrustStore.NAME, "myTestTrustStore"); + attributes.put("certificatesUrl", getClass().getResource("/java_broker.crt").toExternalForm()); + attributes.put(NonJavaTrustStore.TYPE, "NonJavaTrustStore"); + + NonJavaTrustStoreImpl fileTrustStore = + (NonJavaTrustStoreImpl) _factory.create(TrustStore.class, attributes, _broker); + + TrustManager[] trustManagers = fileTrustStore.getTrustManagers(); + assertNotNull(trustManagers); + assertEquals("Unexpected number of trust managers", 1, trustManagers.length); + assertNotNull("Trust manager unexpected null", trustManagers[0]); + } + + public void testCreationOfTrustStoreFromNonCertificate() throws Exception + { + Map attributes = new HashMap<>(); + attributes.put(NonJavaTrustStore.NAME, "myTestTrustStore"); + attributes.put("certificatesUrl", getClass().getResource("/java_broker.req").toExternalForm()); + attributes.put(NonJavaTrustStore.TYPE, "NonJavaTrustStore"); + + try + { + _factory.create(TrustStore.class, attributes, _broker); + fail("Trust store is created from certificate request file"); + } + catch (IllegalConfigurationException e) + { + // pass + } + } + +} -- cgit v1.2.1