Skip to content

Commit

Permalink
Merge pull request #6028 from hwupathum/keystore-refactor
Browse files Browse the repository at this point in the history
Unifying keystore related functionalities into one place
  • Loading branch information
UdeshAthukorala authored Oct 25, 2024
2 parents 49d3018 + 565230f commit b6ef275
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 322 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.utils</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.security.mgt.stub</artifactId>
Expand Down Expand Up @@ -89,6 +93,7 @@
org.wso2.carbon.registry.core.*; version="${carbon.kernel.registry.imp.pkg.version}",
org.wso2.carbon.security.mgt.stub.*;
version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.utils.*; version="${carbon.kernel.package.import.version.range}",
org.wso2.carbon.identity.sts.common.stub.config.*;
version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.user.mgt.stub.types.carbon; version="${carbon.identity.package.import.version.range}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,8 @@ private byte[] getBytesFromFile(File file) throws java.lang.Exception {
public boolean isPrivateKeyStore(byte[] content, String password, String type)
throws java.lang.Exception {

try {
boolean isPrivateStore = false;
ByteArrayInputStream stream = new ByteArrayInputStream(content);
boolean isPrivateStore = false;
try (ByteArrayInputStream stream = new ByteArrayInputStream(content)) {
KeyStore store = KeystoreUtils.getKeystoreInstance(type);
store.load(stream, password.toCharArray());
Enumeration<String> aliases = store.aliases();
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
package org.wso2.carbon.security.keystore;

import org.apache.commons.lang.StringUtils;
import org.wso2.carbon.CarbonException;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.RegistryType;
import org.wso2.carbon.core.util.KeyStoreManager;
import org.wso2.carbon.core.util.KeyStoreUtil;
import org.wso2.carbon.identity.base.IdentityException;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
Expand Down Expand Up @@ -128,8 +130,8 @@ public X509Certificate getClientCertificate(String tenantDomain, String alias) t

KeyStore trustStore = null;
try {
trustStore = getKeyStoreAdmin(tenantDomain).getTrustStore();
} catch (SecurityConfigException e) {
trustStore = getKeyStoreManager(tenantDomain).getTrustStore();
} catch (CarbonException e) {
throw handleServerException(ERROR_CODE_RETRIEVE_CLIENT_TRUSTSTORE, tenantDomain, e);
}

Expand Down Expand Up @@ -161,7 +163,7 @@ public void addCertificate(String tenantDomain, String alias, String certificate
String certAlias;
boolean isAliasExists;
try {
keyStore = keyStoreAdmin.getKeyStore(keyStoreName);
keyStore = getKeyStoreManager(tenantDomain).getKeyStore(keyStoreName);
isAliasExists = keyStore.containsAlias(alias);
certAlias = keyStore.getCertificateAlias(cert);
} catch (Exception e) {
Expand Down Expand Up @@ -295,6 +297,11 @@ private KeyStoreAdmin getKeyStoreAdmin(String tenantDomain) {
(Registry) CarbonContext.getThreadLocalCarbonContext().getRegistry(RegistryType.SYSTEM_GOVERNANCE));
}

private KeyStoreManager getKeyStoreManager(String tenantDomain) {

return KeyStoreManager.getInstance(IdentityTenantUtil.getTenantId(tenantDomain));
}

private boolean isSuperTenant(String tenantDomain) {

return IdentityTenantUtil.getTenantId(tenantDomain) == MultitenantConstants.SUPER_TENANT_ID;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@

package org.wso2.carbon.security.keystore.service;

import org.apache.axiom.om.util.Base64;
import org.wso2.carbon.CarbonException;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.core.AbstractAdmin;
import org.wso2.carbon.core.util.KeyStoreManager;
import org.wso2.carbon.security.SecurityConfigException;
import org.wso2.carbon.security.keystore.KeyStoreAdmin;

Expand All @@ -38,9 +41,14 @@ public KeyStoreData[] getKeyStores() throws SecurityConfigException {
@Override
public void addKeyStore(String fileData, String filename, String password, String provider,
String type, String pvtkeyPass) throws SecurityConfigException {
KeyStoreAdmin admin = new KeyStoreAdmin(CarbonContext.getThreadLocalCarbonContext().getTenantId(),
getGovernanceSystemRegistry());
admin.addKeyStore(fileData, filename, password, provider, type, pvtkeyPass);

KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(
CarbonContext.getThreadLocalCarbonContext().getTenantId());
try {
keyStoreManager.addKeyStore(Base64.decode(fileData), filename, password, provider, type, pvtkeyPass);
} catch (SecurityException e) {
throw new SecurityConfigException(e.getMessage());
}
}

@Override
Expand All @@ -53,10 +61,14 @@ public void addTrustStore(String fileData, String filename, String password, Str

@Override
public void deleteStore(String keyStoreName) throws SecurityConfigException {
KeyStoreAdmin admin = new KeyStoreAdmin(CarbonContext.getThreadLocalCarbonContext().getTenantId(),
getGovernanceSystemRegistry());
admin.deleteStore(keyStoreName);

KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(
CarbonContext.getThreadLocalCarbonContext().getTenantId());
try {
keyStoreManager.deleteStore(keyStoreName);
} catch (SecurityException e) {
throw new SecurityConfigException(e.getMessage());
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import org.wso2.carbon.CarbonException;
import org.wso2.carbon.base.CarbonBaseConstants;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.core.RegistryResources;
import org.wso2.carbon.core.util.CryptoUtil;
import org.wso2.carbon.core.util.KeyStoreManager;
import org.wso2.carbon.core.util.KeyStoreUtil;
Expand All @@ -47,63 +49,53 @@
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertThrows;

@Listeners(MockitoTestNGListener.class)
public class KeyStoreAdminTest extends IdentityBaseTest {

public static final String SERVER_TRUSTSTORE_FILE = "Security.TrustStore.Location";
public static final String SERVER_TRUSTSTORE_PASSWORD = "Security.TrustStore.Password";
private static final String KEYSTORE_NAME = "wso2carbon.jks";
private static final String KEYSTORE_TYPE = "JKS";
private static final String KEYSTORE_PASSWORD = "wso2carbon";
@Mock
ServerConfiguration serverConfiguration;
private ServerConfiguration serverConfiguration;
@Mock
KeyStoreManager keyStoreManager;
private KeyStoreManager keyStoreManager;
@Mock
Registry registry;
private Registry registry;
@Mock
private CryptoUtil cryptoUtil;
@Mock
private Resource resource;
private KeyStoreAdmin keyStoreAdmin;
private int tenantID = -1234;
private final int tenantID = -1234;

@BeforeClass
public void setup() {
public void setup() throws Exception {

System.setProperty(
CarbonBaseConstants.CARBON_HOME,
Paths.get(System.getProperty("user.dir"), "src", "test", "resources").toString()
);

}

@Test(description = "Add KeyStore test")
public void testAddKeyStore() throws Exception {

byte[] keyStoreContent = readBytesFromFile(createPath(KEYSTORE_NAME).toString());

try (MockedStatic<ServerConfiguration> serverConfiguration = mockStatic(ServerConfiguration.class);
MockedStatic<CryptoUtil>cryptoUtilMockedStatic = mockStatic(CryptoUtil.class);
try (MockedStatic<KeyStoreManager> keyStoreManager = mockStatic(KeyStoreManager.class);
MockedStatic<KeyStoreUtil> keyStoreUtil = mockStatic(KeyStoreUtil.class)) {

keyStoreUtil.when(() -> KeyStoreUtil.isPrimaryStore(any())).thenReturn(false);
serverConfiguration.when(ServerConfiguration::getInstance).thenReturn(this.serverConfiguration);
when(this.serverConfiguration.getFirstProperty(SERVER_TRUSTSTORE_FILE)).thenReturn(createPath(KEYSTORE_NAME).toString());
when(this.serverConfiguration.getFirstProperty(SERVER_TRUSTSTORE_PASSWORD)).thenReturn(KEYSTORE_PASSWORD);

// Mocking Registry interactions
when(registry.newResource()).thenReturn(resource);

// Mocking password encryption
cryptoUtilMockedStatic.when(CryptoUtil::getDefaultCryptoUtil).thenReturn(cryptoUtil);
when(cryptoUtil.encryptAndBase64Encode(any())).thenReturn("encryptedPassword");
keyStoreManager.when(() -> KeyStoreManager.getInstance(anyInt())).thenReturn(this.keyStoreManager);

keyStoreUtil.when(() -> KeyStoreUtil.isPrimaryStore(any())).thenReturn(false);
keyStoreUtil.when(() -> KeyStoreUtil.isTrustStore(any())).thenReturn(false);

keyStoreAdmin = new KeyStoreAdmin(tenantID, registry);
keyStoreAdmin.addKeyStore(keyStoreContent, "new_keystore.jks", KEYSTORE_PASSWORD, " ", "JKS", KEYSTORE_PASSWORD);
Expand All @@ -114,42 +106,30 @@ public void testAddKeyStore() throws Exception {
public void testAddTrustStore() throws Exception {

byte[] keyStoreContent = readBytesFromFile(createPath(KEYSTORE_NAME).toString());
keyStoreAdmin = new KeyStoreAdmin(tenantID, registry);

try (MockedStatic<ServerConfiguration> serverConfiguration = mockStatic(ServerConfiguration.class);
MockedStatic<CryptoUtil>cryptoUtilMockedStatic = mockStatic(CryptoUtil.class);
try (MockedStatic<KeyStoreManager> keyStoreManager = mockStatic(KeyStoreManager.class);
MockedStatic<KeyStoreUtil> keyStoreUtil = mockStatic(KeyStoreUtil.class)) {

keyStoreUtil.when(() -> KeyStoreUtil.isPrimaryStore(any())).thenReturn(false);

serverConfiguration.when(ServerConfiguration::getInstance).thenReturn(this.serverConfiguration);

// Mocking Registry interactions
when(registry.newResource()).thenReturn(resource);

// Mocking password encryption
cryptoUtilMockedStatic.when(CryptoUtil::getDefaultCryptoUtil).thenReturn(cryptoUtil);
when(cryptoUtil.encryptAndBase64Encode(any())).thenReturn("encryptedPassword");
keyStoreManager.when(() -> KeyStoreManager.getInstance(anyInt())).thenReturn(this.keyStoreManager);

keyStoreUtil.when(() -> KeyStoreUtil.isPrimaryStore(any())).thenReturn(false);
keyStoreUtil.when(() -> KeyStoreUtil.isTrustStore(any())).thenReturn(true);

keyStoreAdmin = new KeyStoreAdmin(tenantID, registry);
keyStoreAdmin.addTrustStore(keyStoreContent, "new_truststore.jks", KEYSTORE_PASSWORD, " ", "JKS");
}
}

@Test(description = "Test case to verify successful retrieval of TrustStore")
public void testGetTrustStoreSuccess() throws Exception {

keyStoreAdmin = new KeyStoreAdmin(tenantID, registry);

// Mock ServerConfiguration static calls
try (MockedStatic<ServerConfiguration> serverConfiguration = mockStatic(ServerConfiguration.class)) {
try (MockedStatic<KeyStoreManager> keyStoreManager = mockStatic(KeyStoreManager.class)) {

// Mocking configuration properties
serverConfiguration.when(ServerConfiguration::getInstance).thenReturn(this.serverConfiguration);
when(this.serverConfiguration.getFirstProperty(SERVER_TRUSTSTORE_FILE)).thenReturn(createPath(KEYSTORE_NAME).toString());
when(this.serverConfiguration.getFirstProperty(SERVER_TRUSTSTORE_PASSWORD)).thenReturn(KEYSTORE_PASSWORD);
when(this.serverConfiguration.getFirstProperty(KeyStoreAdmin.SERVER_TRUSTSTORE_TYPE)).thenReturn(KEYSTORE_TYPE);
keyStoreManager.when(() -> KeyStoreManager.getInstance(tenantID)).thenReturn(this.keyStoreManager);
when(this.keyStoreManager.getTrustStore())
.thenReturn(getKeyStoreFromFile(KEYSTORE_NAME, KEYSTORE_PASSWORD));

keyStoreAdmin = new KeyStoreAdmin(tenantID, registry);
KeyStore result = keyStoreAdmin.getTrustStore();

assertNotNull(result);
Expand All @@ -159,24 +139,55 @@ public void testGetTrustStoreSuccess() throws Exception {
@Test(description = "Test case to verify that an exception is thrown when getting TrustStore")
public void testGetTrustStoreException() throws Exception {

keyStoreAdmin = new KeyStoreAdmin(tenantID, registry);

// Mock ServerConfiguration static calls
try (MockedStatic<ServerConfiguration> serverConfiguration = mockStatic(ServerConfiguration.class)) {
try (MockedStatic<KeyStoreManager> keyStoreManager = mockStatic(KeyStoreManager.class)) {

// Mocking configuration properties
serverConfiguration.when(ServerConfiguration::getInstance).thenReturn(this.serverConfiguration);
when(this.serverConfiguration.getFirstProperty(SERVER_TRUSTSTORE_FILE)).thenReturn(createPath(KEYSTORE_NAME).toString());
when(this.serverConfiguration.getFirstProperty(KeyStoreAdmin.SERVER_TRUSTSTORE_TYPE)).thenReturn("PKCS12");
when(this.serverConfiguration.getFirstProperty("JCEProvider")).thenReturn("BC");
keyStoreManager.when(() -> KeyStoreManager.getInstance(anyInt())).thenReturn(this.keyStoreManager);
when(this.keyStoreManager.getTrustStore())
.thenThrow(new CarbonException("Error occurred while retrieving TrustStore"));

keyStoreAdmin = new KeyStoreAdmin(tenantID, registry);
// Execute method under test
assertThrows(SecurityConfigException.class, () -> {
keyStoreAdmin.getTrustStore();
});
}
}

@Test(description = "Delete KeyStore test", dependsOnMethods = "testAddKeyStore")
public void testDeleteKeyStore() throws Exception {

try (MockedStatic<KeyStoreManager> keyStoreManager = mockStatic(KeyStoreManager.class);
MockedStatic<KeyStoreUtil> keyStoreUtil = mockStatic(KeyStoreUtil.class)) {

keyStoreManager.when(() -> KeyStoreManager.getInstance(anyInt())).thenReturn(this.keyStoreManager);

keyStoreUtil.when(() -> KeyStoreUtil.isPrimaryStore(anyString())).thenReturn(false);
keyStoreUtil.when(() -> KeyStoreUtil.isTrustStore(anyString())).thenReturn(false);

keyStoreAdmin = new KeyStoreAdmin(tenantID, registry);
keyStoreAdmin.deleteStore("new_keystore.jks");
verify(this.keyStoreManager).deleteStore("new_keystore.jks");
}
}

@Test(description = "Delete TrustStore test", dependsOnMethods = "testAddTrustStore")
public void testDeleteTrustStore() throws Exception {

try (MockedStatic<KeyStoreManager> keyStoreManager = mockStatic(KeyStoreManager.class);
MockedStatic<KeyStoreUtil> keyStoreUtil = mockStatic(KeyStoreUtil.class)) {

keyStoreManager.when(() -> KeyStoreManager.getInstance(anyInt())).thenReturn(this.keyStoreManager);

keyStoreUtil.when(() -> KeyStoreUtil.isPrimaryStore(anyString())).thenReturn(false);
keyStoreUtil.when(() -> KeyStoreUtil.isTrustStore(anyString())).thenReturn(false);

keyStoreAdmin = new KeyStoreAdmin(tenantID, registry);
keyStoreAdmin.deleteStore("new_truststore.jks");
verify(this.keyStoreManager).deleteStore("new_truststore.jks");
}
}



@Test
Expand All @@ -185,16 +196,16 @@ public void testGetPaginatedKeystoreInfo() throws Exception {
try (MockedStatic<ServerConfiguration> serverConfiguration = mockStatic(ServerConfiguration.class);
MockedStatic<KeyStoreManager> keyStoreManager = mockStatic(KeyStoreManager.class);
MockedStatic<KeyStoreUtil> keyStoreUtil = mockStatic(KeyStoreUtil.class)) {
serverConfiguration.when(ServerConfiguration::getInstance).thenReturn(this.serverConfiguration);

keyStoreManager.when(() -> KeyStoreManager.getInstance(anyInt())).thenReturn(this.keyStoreManager);
when(this.serverConfiguration.getFirstProperty(SERVER_TRUSTSTORE_FILE)).thenReturn(createPath(KEYSTORE_NAME).toString());
when(this.serverConfiguration.getFirstProperty(SERVER_TRUSTSTORE_PASSWORD)).thenReturn(KEYSTORE_PASSWORD);
serverConfiguration.when(ServerConfiguration::getInstance).thenReturn(this.serverConfiguration);
when(this.serverConfiguration.getFirstProperty(
RegistryResources.SecurityManagement.SERVER_PRIMARY_KEYSTORE_TYPE)).thenReturn(KEYSTORE_TYPE);

keyStoreUtil.when(() -> KeyStoreUtil.isPrimaryStore(any())).thenReturn(true);

keyStoreManager.when(() -> KeyStoreManager.getInstance(tenantID)).thenReturn(this.keyStoreManager);
when(this.keyStoreManager.getPrimaryKeyStore()).thenReturn(getKeyStoreFromFile(KEYSTORE_NAME, KEYSTORE_PASSWORD));
when(this.keyStoreManager.getKeyStore(anyString()))
.thenReturn(getKeyStoreFromFile(KEYSTORE_NAME, KEYSTORE_PASSWORD));

keyStoreAdmin = new KeyStoreAdmin(tenantID, registry);
PaginatedKeyStoreData result = keyStoreAdmin.getPaginatedKeystoreInfo(KEYSTORE_NAME, 10);
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1866,7 +1866,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<!-- Carbon kernel version -->
<carbon.kernel.version>4.10.22</carbon.kernel.version>
<carbon.kernel.version>4.10.24</carbon.kernel.version>
<carbon.kernel.feature.version>4.7.0</carbon.kernel.feature.version>
<carbon.kernel.package.import.version.range>[4.5.0, 5.0.0)</carbon.kernel.package.import.version.range>
<carbon.kernel.registry.imp.pkg.version>[1.0.1, 2.0.0)</carbon.kernel.registry.imp.pkg.version>
Expand Down

0 comments on commit b6ef275

Please sign in to comment.