Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ARTEMIS-5340 ensure PEM provider is truly optional #5547

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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.activemq.artemis.core.remoting.impl.ssl;

import java.security.Security;

public class PemSupport {

public static void loadProvider() {
Security.insertProviderAt(new de.dentrassi.crypto.pem.PemKeyStoreProvider(), Integer.parseInt(System.getProperty("artemis.pemProvider.insertAt", "0")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -352,11 +352,14 @@ public static KeyStore loadKeystore(final String keystoreProvider,
return ks;
}

public static void checkPemProviderLoaded(String keystoreType) {
/**
* This method calls out to a separate class in order to avoid a hard dependency on the provider's implementation.
* This allows folks who don't use PEM to avoid using the corresponding dependency.
*/
public static void checkPemProviderLoaded(String keystoreType) throws Exception {
if (keystoreType != null && keystoreType.startsWith("PEM")) {
if (Security.getProvider("PEM") == null) {
Security.insertProviderAt(new de.dentrassi.crypto.pem.PemKeyStoreProvider(),
Integer.parseInt(System.getProperty("artemis.pemProvider.insertAt", "0")));
PemSupport.loadProvider();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* 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.activemq.artemis.core.remoting.impl.netty;

import de.dentrassi.crypto.pem.PemKeyStoreProvider;
import org.apache.activemq.artemis.core.remoting.impl.ssl.SSLSupport;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

/**
* Order is important here because we don't want to load the PEM provider class before we test that it isn't loaded.
*/
@TestMethodOrder(OrderAnnotation.class)
public class PemProviderTest {

// use a literal to avoid implicitly loading the actual package/class
static final String PEM_PROVIDER_PACKAGE = "de.dentrassi.crypto.pem";

@Test
@Order(1)
public void testPemProviderNotLoadedOnSSLSupportStaticUse() {
// ensure the PEM provider isn't already loaded (e.g. by another test)
assertNull(ClassLoader.getSystemClassLoader().getDefinedPackage(PEM_PROVIDER_PACKAGE));

// use a static method from SSLSupport to force the JVM to load it as well as any hard dependencies it has
SSLSupport.parseCommaSeparatedListIntoArray("");

assertNull(ClassLoader.getSystemClassLoader().getDefinedPackage(PEM_PROVIDER_PACKAGE));
}

@Test
@Order(2)
public void testPemProviderNotLoadedOnLoadingNonPemKeystore() throws Exception {
// ensure the PEM provider isn't already loaded (e.g. by another test)
assertNull(ClassLoader.getSystemClassLoader().getDefinedPackage(PEM_PROVIDER_PACKAGE));

SSLSupport.loadKeystore(null, "JKS", "", "");

assertNull(ClassLoader.getSystemClassLoader().getDefinedPackage(PEM_PROVIDER_PACKAGE));
}

@Test
@Order(3)
public void testPemProviderLoadedOnLoadingPemKeystore() throws Exception {
// ensure the PEM provider isn't already loaded (e.g. by another test)
assertNull(ClassLoader.getSystemClassLoader().getDefinedPackage(PEM_PROVIDER_PACKAGE));

SSLSupport.loadKeystore(null, "PEM", "", "");

assertNotNull(ClassLoader.getSystemClassLoader().getDefinedPackage(PEM_PROVIDER_PACKAGE));
}

/**
* This test simply verifies that we're using the right literal for the PEM provider implementation.
*/
@Test
@Order(4)
public void testPemProviderPackageName() {
assertEquals(PEM_PROVIDER_PACKAGE, PemKeyStoreProvider.class.getPackageName());
}
}