diff --git a/managed/src/main/java/com/yugabyte/yw/common/WSClientRefresher.java b/managed/src/main/java/com/yugabyte/yw/common/WSClientRefresher.java index bf15a6fea7e4..7dd71524dacb 100644 --- a/managed/src/main/java/com/yugabyte/yw/common/WSClientRefresher.java +++ b/managed/src/main/java/com/yugabyte/yw/common/WSClientRefresher.java @@ -79,6 +79,7 @@ private WSClient newClient(String ybWsConfigPath) { if (!ybaStoreConfig.isEmpty() && customCAStoreManager.isEnabled()) { // Add JRE default cert paths as well in this case. ybaStoreConfig.add(customCAStoreManager.getJavaDefaultConfig()); + ybaStoreConfig.addAll(customCAStoreManager.getYBAJavaKeyStoreConfig()); Config customWsConfig = ConfigFactory.empty() @@ -89,7 +90,7 @@ private WSClient newClient(String ybWsConfigPath) { ybWsOverrides = customWsConfig.getValue("play.ws"); } - log.info( + log.debug( "Creating ws client with config override: {}", ybWsOverrides.render(ConfigRenderOptions.concise())); diff --git a/managed/src/main/java/com/yugabyte/yw/common/certmgmt/CertificateHelper.java b/managed/src/main/java/com/yugabyte/yw/common/certmgmt/CertificateHelper.java index 30ab9ac25332..ff1c45f580f0 100644 --- a/managed/src/main/java/com/yugabyte/yw/common/certmgmt/CertificateHelper.java +++ b/managed/src/main/java/com/yugabyte/yw/common/certmgmt/CertificateHelper.java @@ -767,11 +767,16 @@ public static void writeCertBundleToCertPath(List certs, String public static void writeCertBundleToCertPath( List certs, String certPath, boolean syncToDB) { + writeCertBundleToCertPath(certs, certPath, syncToDB, false); + } + + public static void writeCertBundleToCertPath( + List certs, String certPath, boolean syncToDB, boolean append) { File certFile = new File(certPath); // Create directory to store the certFile. certFile.getParentFile().mkdirs(); log.info("Dumping certs at path: {}", certPath); - try (JcaPEMWriter certWriter = new JcaPEMWriter(new FileWriter(certFile))) { + try (JcaPEMWriter certWriter = new JcaPEMWriter(new FileWriter(certFile, append))) { for (X509Certificate cert : certs) { log.info(getCertificateProperties(cert)); certWriter.writeObject(cert); diff --git a/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/CustomCAStoreManager.java b/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/CustomCAStoreManager.java index 0995571c1747..ca1f8cef793f 100644 --- a/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/CustomCAStoreManager.java +++ b/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/CustomCAStoreManager.java @@ -258,6 +258,7 @@ public boolean deleteCA(UUID customerId, UUID certId, String storagePath) { String trustStoreHome = getTruststoreHome(storagePath); String certPath = getCustomCACertsPath(trustStoreHome, certId); + boolean deleted = false; boolean suppressErrors = false; char[] truststorePassword = getTruststorePassword(); @@ -275,6 +276,9 @@ public boolean deleteCA(UUID customerId, UUID certId, String storagePath) { } catch (Exception e) { log.error("CA certificate delete is incomplete due to: ", e); // Rollback DB. + CustomCaCertificateInfo origCert = CustomCaCertificateInfo.get(customerId, certId, false); + // We need to ensure paths is not messed up in the custom cert table. + cert.setContents(origCert.getContents()); cert.activate(); try { suppressErrors = true; @@ -340,6 +344,27 @@ public List> getPemStoreConfig() { // -------------- PKCS12 CA trust-store specific methods ------------ + public List> getYBAJavaKeyStoreConfig() { + String storagePath = AppConfigHelper.getStoragePath(); + String trustStoreHome = getTruststoreHome(storagePath); + List ybaJavaKeyStoreConfig = new ArrayList<>(); + + if (Files.exists(Paths.get(trustStoreHome))) { + String javaTrustStorePathStr = pkcs12TrustStoreManager.getYbaTrustStorePath(trustStoreHome); + Path javaTrustStorePath = Paths.get(javaTrustStorePathStr); + if (Files.exists(javaTrustStorePath)) { + Map trustStoreMap = new HashMap<>(); + trustStoreMap.put("path", javaTrustStorePathStr); + trustStoreMap.put("type", pkcs12TrustStoreManager.getYbaTrustStoreType()); + trustStoreMap.put("password", new String(getTruststorePassword())); + ybaJavaKeyStoreConfig.add(trustStoreMap); + } + } + + log.debug("YBA's custom java trust store config is {}", ybaJavaKeyStoreConfig); + return ybaJavaKeyStoreConfig; + } + private KeyStore getYbaKeyStore() { String storagePath = AppConfigHelper.getStoragePath(); String trustStoreHome = getTruststoreHome(storagePath); diff --git a/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/PemTrustStoreManager.java b/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/PemTrustStoreManager.java index 138b226f0cf0..c4feb7ffa927 100644 --- a/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/PemTrustStoreManager.java +++ b/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/PemTrustStoreManager.java @@ -9,6 +9,7 @@ import com.google.inject.Singleton; import com.yugabyte.yw.common.PlatformServiceException; import com.yugabyte.yw.common.certmgmt.CertificateHelper; +import com.yugabyte.yw.models.CustomCaCertificateInfo; import com.yugabyte.yw.models.FileData; import java.io.File; import java.io.FileInputStream; @@ -24,8 +25,11 @@ import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; +import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; import org.bouncycastle.openssl.jcajce.JcaPEMWriter; /** Relates to YBA's PEM trust store */ @@ -44,9 +48,9 @@ public boolean addCertificate( throws KeyStoreException, CertificateException, IOException, PlatformServiceException { log.debug("Trying to update YBA's PEM truststore ..."); - Certificate newCert = null; - newCert = getX509Certificate(certPath); - if (newCert == null) { + List newCerts = null; + newCerts = getX509Certificate(certPath); + if (CollectionUtils.isEmpty(newCerts)) { throw new PlatformServiceException( BAD_REQUEST, String.format("No new CA certificate exists at %s", certPath)); } @@ -60,21 +64,35 @@ public boolean addCertificate( log.debug("Created an empty YBA PEM trust-store"); } else { List trustCerts = getCertsInTrustStore(trustStorePath, trustStorePassword); + List addedCertChain = new ArrayList(newCerts); if (trustCerts != null) { // Check if such an alias already exists. - boolean exists = trustCerts.contains(newCert); - if (exists && !suppressErrors) { - String msg = "CA certificate with same content already exists"; - log.error(msg); - throw new PlatformServiceException(BAD_REQUEST, msg); + for (int i = 0; i < addedCertChain.size(); i++) { + Certificate newCert = addedCertChain.get(i); + boolean exists = trustCerts.contains(newCert); + if (!exists) { + break; + } + // In case of certificate chain, we can have the same root/intermediate + // cert present in the chain. Throw error in case all of these exists. + if (exists && !suppressErrors && addedCertChain.size() - 1 == i) { + String msg = "CA certificate with same content already exists"; + log.error(msg); + throw new PlatformServiceException(BAD_REQUEST, msg); + } else if (exists && addedCertChain.size() != i) { + newCerts.remove(i); + } } } } // Update the trust store in file system. - boolean append = true; - CertificateHelper.writeCertFileContentToCertPath( - (X509Certificate) newCert, trustStorePath, false, append); + List x509Certificates = + newCerts.stream() + .filter(certificate -> certificate instanceof X509Certificate) + .map(certificate -> (X509Certificate) certificate) + .collect(Collectors.toList()); + CertificateHelper.writeCertBundleToCertPath(x509Certificates, trustStorePath, false, true); log.debug("Truststore '{}' now has the cert {}", trustStorePath, certAlias); // Backup up YBA's PEM trust store in DB. @@ -99,18 +117,25 @@ public void replaceCertificate( List trustCerts = getCertificates(trustStorePath); // Check if such a cert already exists. - Certificate oldCert = getX509Certificate(oldCertPath); - boolean exists = trustCerts.remove(oldCert); - if (!exists && !suppressErrors) { - String msg = String.format("Certificate '%s' doesn't exist to update", certAlias); - log.error(msg); - throw new PlatformServiceException(BAD_REQUEST, msg); + List oldCerts = getX509Certificate(oldCertPath); + boolean exists = false; + for (Certificate oldCert : oldCerts) { + if (isCertificateUsedInOtherChain(oldCert)) { + log.debug("Certificate {} is part of a chain, skipping replacement.", certAlias); + continue; + } + exists = trustCerts.remove(oldCert); + if (!exists && !suppressErrors) { + String msg = String.format("Certificate '%s' doesn't exist to update", certAlias); + log.error(msg); + throw new PlatformServiceException(BAD_REQUEST, msg); + } } // Update the trust store. if (exists) { - Certificate newCert = getX509Certificate(newCertPath); - trustCerts.add(newCert); + List newCerts = getX509Certificate(newCertPath); + trustCerts.addAll(newCerts); saveTo(trustStorePath, trustCerts); log.info("Truststore '{}' updated with new cert at alias '{}'", trustStorePath, certAlias); } @@ -144,11 +169,30 @@ public void remove( log.info("Removing cert {} from PEM truststore ...", certAlias); String trustStorePath = getTrustStorePath(trustStoreHome, TRUSTSTORE_FILE_NAME); List trustCerts = getCertificates(trustStorePath); - // Check if such an alias already exists. - Certificate certToRemove = getX509Certificate(certPath); - boolean exists = - Iterators.removeAll(trustCerts.iterator(), Collections.singletonList(certToRemove)); + List certToRemove = getX509Certificate(certPath); + int certToRemoveCount = certToRemove.size(); + // Iterate through each certificate in certToRemove and check if it's used in any chain + boolean exists = false; + Iterator certIterator = certToRemove.iterator(); + while (certIterator.hasNext()) { + Certificate cert = certIterator.next(); + if (isCertificateUsedInOtherChain(cert)) { + // Certificate is part of a chain, do not remove it + log.debug("Certificate {} is part of a chain, skipping removal.", certAlias); + certToRemoveCount -= 1; + certIterator.remove(); + } else { + // Certificate is not part of a chain + exists = true; + } + } + + if (certToRemoveCount == 0) { + log.debug( + "Skipping removal of cert from PEM truststore, as the cert is part of other trust chain"); + return; + } if (!exists && !suppressErrors) { String msg = String.format("Certificate '%s' does not exist to delete", certAlias); @@ -157,14 +201,15 @@ public void remove( } // Delete from the trust-store. - if (exists) { + if (!certToRemove.isEmpty()) { + Iterators.removeAll(trustCerts.iterator(), certToRemove); saveTo(trustStorePath, trustCerts); log.debug("Certificate {} is now deleted from trust-store {}", certAlias, trustStorePath); } log.info("custom CA certs deleted from YBA's PEM truststore"); } - private List getCertsInTrustStore(String trustStorePath, char[] trustStorePassword) { + public List getCertsInTrustStore(String trustStorePath, char[] trustStorePassword) { if (trustStorePath == null) { throw new PlatformServiceException( INTERNAL_SERVER_ERROR, "Cannot get CA certificates from empty path"); @@ -223,4 +268,21 @@ public boolean isTrustStoreEmpty(String storePathStr, char[] trustStorePassword) throw new PlatformServiceException(INTERNAL_SERVER_ERROR, msg); } } + + private boolean isCertificateUsedInOtherChain(Certificate cert) + throws CertificateException, IOException { + // Retrieve all the certificates from `custom_ca_certificate_info` schema. + // In case the passed cert is substring in more than 1 cert than it is used + // as part of other cert chain as well. + // We will skip removing it from the trust-store. + int certChainCount = 0; + List customCACertificates = CustomCaCertificateInfo.getAll(false); + for (CustomCaCertificateInfo customCA : customCACertificates) { + List certChain = getX509Certificate(customCA.getContents()); + if (certChain.contains(cert)) { + certChainCount++; + } + } + return certChainCount > 1; + } } diff --git a/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/Pkcs12TrustStoreManager.java b/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/Pkcs12TrustStoreManager.java index d5eb80f363f9..1c4b5d0dc980 100644 --- a/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/Pkcs12TrustStoreManager.java +++ b/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/Pkcs12TrustStoreManager.java @@ -81,8 +81,11 @@ public boolean addCertificate( throw new PlatformServiceException(BAD_REQUEST, errMsg); } - Certificate certificate = getX509Certificate(certPath); - trustStore.setCertificateEntry(certAlias, certificate); + List certificates = getX509Certificate(certPath); + for (int i = 0; i < certificates.size(); i++) { + String alias = certAlias + "-" + i; + trustStore.setCertificateEntry(alias, certificates.get(i)); + } // Update the trust store in file-system. saveTrustStore(trustStorePath, trustStore, trustStorePassword); log.debug("Truststore '{}' now has a certificate with alias '{}'", trustStorePath, certAlias); @@ -113,17 +116,31 @@ public void replaceCertificate( throw new PlatformServiceException(INTERNAL_SERVER_ERROR, errMsg); } - // Check if such an alias already exists. - if (!trustStore.containsAlias(certAlias) && !suppressErrors) { - String errMsg = String.format("Cert by name '%s' does not exist to update", certAlias); - log.error(errMsg); - // Purge newCertPath which got created. - throw new PlatformServiceException(BAD_REQUEST, errMsg); + List oldCertificates = getX509Certificate(oldCertPath); + List newCertificates = getX509Certificate(newCertPath); + for (int i = 0; i < oldCertificates.size(); i++) { + // Check if such an alias already exists. + String alias = certAlias + "-" + i; + if (!trustStore.containsAlias(alias) && !suppressErrors) { + String errMsg = String.format("Cert by name '%s' does not exist to update", alias); + log.error(errMsg); + // Purge newCertPath which got created. + throw new PlatformServiceException(BAD_REQUEST, errMsg); + } + } + + if (newCertificates.size() < oldCertificates.size()) { + for (int i = newCertificates.size(); i < oldCertificates.size(); i++) { + String alias = certAlias + "-" + i; + trustStore.deleteEntry(alias); + } } // Update the trust store. - Certificate newCertificate = getX509Certificate(newCertPath); - trustStore.setCertificateEntry(certAlias, newCertificate); + for (int i = 0; i < newCertificates.size(); i++) { + String alias = certAlias + "-" + i; + trustStore.setCertificateEntry(alias, newCertificates.get(i)); + } saveTrustStore(trustStorePath, trustStore, trustStorePassword); // Backup up YBA's pkcs12 trust store in DB. @@ -183,22 +200,26 @@ public void remove( String trustStoreHome, char[] trustStorePassword, boolean suppressErrors) - throws KeyStoreException { + throws KeyStoreException, IOException, CertificateException { log.info("Removing cert {} from YBA's pkcs12 truststore ...", certAlias); String trustStorePath = getTrustStorePath(trustStoreHome, TRUSTSTORE_FILE_NAME); KeyStore trustStore = getTrustStore(trustStorePath, trustStorePassword, false); + List certificates = getX509Certificate(certPath); + for (int i = 0; i < certificates.size(); i++) { + String alias = certAlias + "-" + i; + + // Check if such an alias already exists. + if (!trustStore.containsAlias(alias) && !suppressErrors) { + String errMsg = String.format("CA certificate '%s' does not exist to delete", alias); + log.error(errMsg); + throw new PlatformServiceException(BAD_REQUEST, errMsg); + } - // Check if such an alias already exists. - if (!trustStore.containsAlias(certAlias) && !suppressErrors) { - String errMsg = String.format("CA certificate '%s' does not exist to delete", certAlias); - log.error(errMsg); - throw new PlatformServiceException(BAD_REQUEST, errMsg); - } - - // Delete from the trust store. - if (trustStore.containsAlias(certAlias)) { - trustStore.deleteEntry(certAlias); + // Delete from the trust store. + if (trustStore.containsAlias(alias)) { + trustStore.deleteEntry(alias); + } } saveTrustStore(trustStorePath, trustStore, trustStorePassword); log.debug("Truststore '{}' now does not have a CA certificate '{}'", trustStorePath, certAlias); diff --git a/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/TrustStoreManager.java b/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/TrustStoreManager.java index cd27204a5df6..88287454a8f1 100644 --- a/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/TrustStoreManager.java +++ b/managed/src/main/java/com/yugabyte/yw/common/certmgmt/castore/TrustStoreManager.java @@ -9,17 +9,25 @@ import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; +import java.util.ArrayList; +import java.util.List; public interface TrustStoreManager { default String getTrustStorePath(String trustStoreHome, String trustStoreFileName) { return String.format("%s/%s", trustStoreHome, trustStoreFileName); } - default Certificate getX509Certificate(String certPath) throws CertificateException, IOException { + default List getX509Certificate(String certPath) + throws CertificateException, IOException { + List certificates = new ArrayList<>(); try (FileInputStream certStream = new FileInputStream(certPath)) { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); - Certificate certificate = certificateFactory.generateCertificate(certStream); - return certificate; + + while (certStream.available() > 0) { + Certificate certificate = certificateFactory.generateCertificate(certStream); + certificates.add(certificate); + } + return certificates; } } diff --git a/managed/src/main/java/db/migration/default_/postgres/V274__AddRuntimeCertsToCAStore.java b/managed/src/main/java/db/migration/default_/postgres/V274__AddRuntimeCertsToCAStore.java index 3ad06e757906..97721a9f57b3 100644 --- a/managed/src/main/java/db/migration/default_/postgres/V274__AddRuntimeCertsToCAStore.java +++ b/managed/src/main/java/db/migration/default_/postgres/V274__AddRuntimeCertsToCAStore.java @@ -8,6 +8,7 @@ import com.typesafe.config.ConfigValue; import com.yugabyte.yw.common.AppConfigHelper; import com.yugabyte.yw.common.certmgmt.CertificateHelper; +import com.yugabyte.yw.common.utils.FileUtils; import java.io.File; import java.io.FileOutputStream; import java.nio.file.Files; @@ -25,6 +26,7 @@ import java.util.Map; import java.util.UUID; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; import org.flywaydb.core.api.migration.BaseJavaMigration; import org.flywaydb.core.api.migration.Context; @@ -53,8 +55,16 @@ public class V274__AddRuntimeCertsToCAStore extends BaseJavaMigration { @Override public void migrate(Context context) throws Exception { - for (String confPath : WS_CONF_PATH) { - migrate_conf(context, confPath); + try { + for (String confPath : WS_CONF_PATH) { + migrate_conf(context, confPath); + } + } catch (Exception e) { + // In case the migration fails for some reason, need to ensure that we do + // cleanup of the relevant files that might be created. + File trustStoreDirectory = new File(trustHome); + FileUtils.deleteDirectory(trustStoreDirectory); + throw e; } } @@ -120,26 +130,37 @@ public boolean addCAsToTruststore( if (customerResult.next()) { customerUuid = UUID.fromString(customerResult.getString("uuid")); } - X509Certificate x509Cert = null; + List x509Certs = null; int numCerts = allCerts.size(); for (int count = 0; count < numCerts; count++) { try { - x509Cert = CertificateHelper.convertStringToX509Cert(allCerts.get(count)); + String inputCert = allCerts.get(count); + String[] lines = inputCert.split("\n"); + StringBuilder result = new StringBuilder(); + + // Iterate through the lines and remove leading white spaces + for (String line : lines) { + String trimmedLine = line.trim(); // Remove leading and trailing white spaces + if (!trimmedLine.isEmpty()) { + result.append(trimmedLine).append("\n"); + } + } + x509Certs = CertificateHelper.convertStringToX509CertList(result.toString()); } catch (CertificateException e) { log.warn("Certificate exception occurred, ignoring it.", e); return false; } - UUID certUuid = UUID.randomUUID(); Date createDate = new Timestamp(new Date().getTime()); - Date startDate = x509Cert.getNotBefore(); - Date expiryDate = x509Cert.getNotAfter(); + Pair dates = CertificateHelper.extractDatesFromCertBundle(x509Certs); + Date startDate = dates.getLeft(); + Date expiryDate = dates.getRight(); String certPath = String.format("%s/certs/trust-store/%s/ca.crt", storagePath, certUuid); File certFile = new File(certPath); certFile.getParentFile().mkdirs(); // Create file data in certPath, using syncToDb as false as it has runtime config use. - CertificateHelper.writeCertFileContentToCertPath(x509Cert, certPath, false); + CertificateHelper.writeCertBundleToCertPath(x509Certs, certPath, false); String filePath = String.format("/certs/trust-store/%s/ca.crt", certUuid); String encodedCert = Base64.getEncoder().encodeToString(allCerts.get(count).getBytes()); String fileCreateSql = @@ -162,10 +183,13 @@ public boolean addCAsToTruststore( connection.createStatement().executeUpdate(createSql); // Add the CA in the Pkcs12 format truststore. - ybaJavaStore.setCertificateEntry(certName, x509Cert); + for (int i = 0; i < x509Certs.size(); i++) { + String alias = certName + "-" + i; // Unique alias for each certificate in the chain + ybaJavaStore.setCertificateEntry(alias, x509Certs.get(i)); + } // Add the PEM store file in the file-system. - CertificateHelper.writeCertFileContentToCertPath(x509Cert, pemStorePath, false, true); + CertificateHelper.writeCertBundleToCertPath(x509Certs, pemStorePath, false, true); log.debug("Truststore '{}' now has the cert {}", pemStorePath, certName); } diff --git a/managed/src/test/java/com/yugabyte/yw/common/certmgmt/PemTrustStoreManagerTest.java b/managed/src/test/java/com/yugabyte/yw/common/certmgmt/PemTrustStoreManagerTest.java new file mode 100644 index 000000000000..d1ecb96f7a4f --- /dev/null +++ b/managed/src/test/java/com/yugabyte/yw/common/certmgmt/PemTrustStoreManagerTest.java @@ -0,0 +1,438 @@ +/* + * Copyright 2023 YugaByte, Inc. and Contributors + * + * Licensed under the Polyform Free Trial License 1.0.0 (the "License"); you + * may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * https://github.com/YugaByte/yugabyte-db/blob/master/licenses/ + * POLYFORM-FREE-TRIAL-LICENSE-1.0.0.txt + */ + +package com.yugabyte.yw.common.certmgmt; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.yugabyte.yw.common.FakeDBApplication; +import com.yugabyte.yw.common.ModelFactory; +import com.yugabyte.yw.common.PlatformServiceException; +import com.yugabyte.yw.common.certmgmt.castore.PemTrustStoreManager; +import com.yugabyte.yw.models.CustomCaCertificateInfo; +import com.yugabyte.yw.models.Customer; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.security.KeyStoreException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.junit.MockitoJUnitRunner; + +@Slf4j +@RunWith(MockitoJUnitRunner.class) +public class PemTrustStoreManagerTest extends FakeDBApplication { + + static String TMP_PEM_STORE = "/tmp/certmgmt/"; + static String PEM_TRUST_STORE_FILE; + + @InjectMocks PemTrustStoreManager pemTrustStoreManager; + private Customer defaultCustomer; + + @Before + public void setUp() throws IOException { + defaultCustomer = ModelFactory.testCustomer(); + TMP_PEM_STORE += defaultCustomer.getUuid().toString(); + PEM_TRUST_STORE_FILE = TMP_PEM_STORE + "/" + PemTrustStoreManager.TRUSTSTORE_FILE_NAME; + new File(TMP_PEM_STORE).mkdirs(); + new File(PEM_TRUST_STORE_FILE).createNewFile(); + } + + @After + public void tearDown() throws IOException { + FileUtils.deleteDirectory(new File(TMP_PEM_STORE)); + } + + public String getCertificateChain2Content() { + String certChain = + "-----BEGIN CERTIFICATE-----\n" + + "MIICQzCCAawCCQDhN1VLJiS5JDANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJJ\n" + + "TjELMAkGA1UECAwCS0ExEjAQBgNVBAcMCUJlbmdhbHVydTELMAkGA1UECgwCWUIx\n" + + "DDAKBgNVBAsMA0RldjEbMBkGA1UEAwwSQ2xpZW50IENlcnRpZmljYXRlMB4XDTIz\n" + + "MTAwNjExMTM0NFoXDTMzMTAwMzExMTM0NFowZjELMAkGA1UEBhMCSU4xCzAJBgNV\n" + + "BAgMAktBMRIwEAYDVQQHDAlCZW5nYWx1cnUxCzAJBgNVBAoMAllCMQwwCgYDVQQL\n" + + "DANEZXYxGzAZBgNVBAMMEkNsaWVudCBDZXJ0aWZpY2F0ZTCBnzANBgkqhkiG9w0B\n" + + "AQEFAAOBjQAwgYkCgYEA037hWIlJsttsV10ZIGDi0bzUdjouSirqhvjNxUZUEo0t\n" + + "CNupAdjp5M+vyJj2xnAI8DziUslpYovFpPtuwPCuB4MzqO95xVLGLhszH9cQidua\n" + + "Qu+cgFN9JqgrmHUuQJOkTZlPYAEwkE2lqFBvdhXgqICmbgOXgFVHpa8YB8f4U8UC\n" + + "AwEAATANBgkqhkiG9w0BAQsFAAOBgQBmr3fX12cDXaqLMDOqvs8VsAKS7YdOS4K8\n" + + "5RxupmOaoiw0pV2RMY0KSl6VXgcROBlGWo7WCUVVMXq6xw1mrV/RigoV8T+jZ6SQ\n" + + "MvDXgw80Ykm1o+U5tvL6xQ33jTZrlPUDEEHjMq8SRmSzBbLs/G34cuFbnFFCm8h4\n" + + "m4ZyRf8Nlw==\n" + + "-----END CERTIFICATE-----\n" + + "\n" + + "-----BEGIN CERTIFICATE-----\n" + + "MIIDFTCCAn6gAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwZjELMAkGA1UEBhMCSU4x\n" + + "CzAJBgNVBAgMAktBMRIwEAYDVQQHDAlCZW5nYWx1cnUxCzAJBgNVBAoMAllCMQww\n" + + "CgYDVQQLDANEZXYxGzAZBgNVBAMMEkNsaWVudCBDZXJ0aWZpY2F0ZTAeFw0yMzEw\n" + + "MDYxMTE0MDFaFw0yNDEwMDUxMTE0MDFaMGYxCzAJBgNVBAYTAklOMQswCQYDVQQI\n" + + "DAJLQTESMBAGA1UEBwwJQmVuZ2FsdXJ1MQswCQYDVQQKDAJZQjEMMAoGA1UECwwD\n" + + "RGV2MRswGQYDVQQDDBJDbGllbnQgQ2VydGlmaWNhdGUwgZ8wDQYJKoZIhvcNAQEB\n" + + "BQADgY0AMIGJAoGBALUPV0LrhSq7cDPJuQnt/9k26rZuhDLYsy8mjP4yHV+S3T4x\n" + + "TmVi3Q9VTQc16WBjGp31SLci9ZpCC79GdhmG8TuzzXe89udmvyfS24Tqxl/2jyZm\n" + + "ABUHx/v/6Uvd3Q/GkUTkoyFAPb69Ra9ZbCCNIY7p08zM2U3ILsNJMJRJZnefAgMB\n" + + "AAGjgdEwgc4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAaYwHQYDVR0OBBYEFBTQ\n" + + "4JZlqLnFw7mZpgEl7UBlujG1MIGABgNVHSMEeTB3oWqkaDBmMQswCQYDVQQGEwJJ\n" + + "TjELMAkGA1UECAwCS0ExEjAQBgNVBAcMCUJlbmdhbHVydTELMAkGA1UECgwCWUIx\n" + + "DDAKBgNVBAsMA0RldjEbMBkGA1UEAwwSQ2xpZW50IENlcnRpZmljYXRlggkA4TdV\n" + + "SyYkuSQwDwYDVR0RBAgwBocEChcQETANBgkqhkiG9w0BAQsFAAOBgQBlBoNDnIfT\n" + + "nGw0TJSsR5MXXgnckHldUlsuA+T3UWlzG8KDlVY4F2pGm0fvPqN6YPpABjeB+ue9\n" + + "W7SYPqMflpbEqAHTnC8poID91x7xx9FQzLqwOx8/fmsNZSXscJoPWRxOvqPMoEuh\n" + + "iIHq0hzJqeG6abe076ILpUX7xhVZ9OZ6dQ==\n" + + "-----END CERTIFICATE-----\n"; + + return certChain; + } + + public void addCertificateToYBA(String certPath, String certContent) throws IOException { + File file = new File(certPath); + file.createNewFile(); + FileWriter writer = new FileWriter(file); + writer.write(certContent); + writer.close(); + } + + public String getCertificateChain1Content() { + String certificates = + "-----BEGIN CERTIFICATE-----\n" + + "MIICQzCCAawCCQDhN1VLJiS5JDANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJJ\n" + + "TjELMAkGA1UECAwCS0ExEjAQBgNVBAcMCUJlbmdhbHVydTELMAkGA1UECgwCWUIx\n" + + "DDAKBgNVBAsMA0RldjEbMBkGA1UEAwwSQ2xpZW50IENlcnRpZmljYXRlMB4XDTIz\n" + + "MTAwNjExMTM0NFoXDTMzMTAwMzExMTM0NFowZjELMAkGA1UEBhMCSU4xCzAJBgNV\n" + + "BAgMAktBMRIwEAYDVQQHDAlCZW5nYWx1cnUxCzAJBgNVBAoMAllCMQwwCgYDVQQL\n" + + "DANEZXYxGzAZBgNVBAMMEkNsaWVudCBDZXJ0aWZpY2F0ZTCBnzANBgkqhkiG9w0B\n" + + "AQEFAAOBjQAwgYkCgYEA037hWIlJsttsV10ZIGDi0bzUdjouSirqhvjNxUZUEo0t\n" + + "CNupAdjp5M+vyJj2xnAI8DziUslpYovFpPtuwPCuB4MzqO95xVLGLhszH9cQidua\n" + + "Qu+cgFN9JqgrmHUuQJOkTZlPYAEwkE2lqFBvdhXgqICmbgOXgFVHpa8YB8f4U8UC\n" + + "AwEAATANBgkqhkiG9w0BAQsFAAOBgQBmr3fX12cDXaqLMDOqvs8VsAKS7YdOS4K8\n" + + "5RxupmOaoiw0pV2RMY0KSl6VXgcROBlGWo7WCUVVMXq6xw1mrV/RigoV8T+jZ6SQ\n" + + "MvDXgw80Ykm1o+U5tvL6xQ33jTZrlPUDEEHjMq8SRmSzBbLs/G34cuFbnFFCm8h4\n" + + "m4ZyRf8Nlw==\n" + + "-----END CERTIFICATE-----\n" + + "-----BEGIN CERTIFICATE-----\n" + + "MIIDFTCCAn6gAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwZjELMAkGA1UEBhMCSU4x\n" + + "CzAJBgNVBAgMAktBMRIwEAYDVQQHDAlCZW5nYWx1cnUxCzAJBgNVBAoMAllCMQww\n" + + "CgYDVQQLDANEZXYxGzAZBgNVBAMMEkNsaWVudCBDZXJ0aWZpY2F0ZTAeFw0yMzEw\n" + + "MTAwNTIzMzdaFw0yNDEwMDkwNTIzMzdaMGYxCzAJBgNVBAYTAklOMQswCQYDVQQI\n" + + "DAJLQTESMBAGA1UEBwwJQmVuZ2FsdXJ1MQswCQYDVQQKDAJZQjEMMAoGA1UECwwD\n" + + "RGV2MRswGQYDVQQDDBJDbGllbnQgQ2VydGlmaWNhdGUwgZ8wDQYJKoZIhvcNAQEB\n" + + "BQADgY0AMIGJAoGBAPacLQJ5kyDi37F8WAVrBgcyx+UvLR9hdmWhq+h4AyXO/Ibq\n" + + "vpocAQRXoRC8eguXDSwNNVCYzz1QqyxyYY29XHiy5Fk2ZrMdg0bHArNoOWEcxQe0\n" + + "kmH6y7yG7Y07FE11GVMMyzs/gaVv1NQGjt8IhZ7ZPpkx9X6/uoV07emWwFZNAgMB\n" + + "AAGjgdEwgc4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAaYwHQYDVR0OBBYEFNPK\n" + + "51Qbc/iCTki7ZECdR8vqoSiwMIGABgNVHSMEeTB3oWqkaDBmMQswCQYDVQQGEwJJ\n" + + "TjELMAkGA1UECAwCS0ExEjAQBgNVBAcMCUJlbmdhbHVydTELMAkGA1UECgwCWUIx\n" + + "DDAKBgNVBAsMA0RldjEbMBkGA1UEAwwSQ2xpZW50IENlcnRpZmljYXRlggkA4TdV\n" + + "SyYkuSQwDwYDVR0RBAgwBocEChcQETANBgkqhkiG9w0BAQsFAAOBgQDOg9EyCo6c\n" + + "Lg1+RDsztb+MBEYzL+X1ADNFEICLW7w7uboMow/CFIeT1wr0jdJj52a28ypJxX7v\n" + + "gN4HytXW/d7uoi0Z7XWpDliZ1/+o+71vNKIxqWh00bGqFbxYMl0Pt08YWy4RcAYQ\n" + + "TKb1mt19gJKGdjJDQz6lDSg20OqehrZmsQ==\n" + + "-----END CERTIFICATE-----\n"; + + return certificates; + } + + public String getCertificateContent() { + String certificate = + "-----BEGIN CERTIFICATE-----\n" + + "MIIDBTCCAe2gAwIBAgIQKvGH5iWg47RCxMcw/B3HfDANBgkqhkiG9w0BAQsFADAV\n" + + "MRMwEQYDVQQDEwppdGVzdC1sZGFwMB4XDTIzMDIxMzA5MDkzMloXDTMzMDIxMzA5\n" + + "MTkzMlowFTETMBEGA1UEAxMKaXRlc3QtbGRhcDCCASIwDQYJKoZIhvcNAQEBBQAD\n" + + "ggEPADCCAQoCggEBAM0GyAjTfFqpN9+bTiUBo4sY3v3yhyc6cfbS8K8Pt3t2D7nW\n" + + "0VnmLZOc1h7XmHv9aq67c5mjiC4q1O1zbVRh/3MofyzLywmCxfZSt8DjynN+FAxA\n" + + "g46fa+8NdQMAKbmRWG+05j1AhY6LZJr6h2J126n45BjZGZCsfnrSnHyAlIe8ZTvA\n" + + "H17WG0GKoCC84H43MYyunyaXmQZ7ImR7+lAhtIXtg9l7mNLHZTjZTI40iFxQV4T9\n" + + "M+Antrhs5E5HGoaKagHqbxk2U+sW9KFn1+bo9UpgUlVZDtKkHsLzXZO/ilXXhgyL\n" + + "HxJlxP8ed0qEoaLg3wFK3GJrzFmy4p33BXZBVzUCAwEAAaNRME8wCwYDVR0PBAQD\n" + + "AgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFAd4BgRooit2x4eJeukQXi+u\n" + + "no3XMBAGCSsGAQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBCwUAA4IBAQCZA6FfNJKo\n" + + "GlbxErYUSQc0BmlVTDP3TxriCKPzPaxl6WZ/p3bFkg8HvXLOySzl/kEAEe4KWe56\n" + + "751Iz0vuGRihPqQgkikjfPtvIuLVSytHx19a/sDTZUCQM7qyhWHtYyL7FTxtXMDG\n" + + "8nyrBRax1CNEDW/l0uwyxndopshFxaPvlLsz2SLVcP8g07DWpT9m0d+PnjHBI1Vl\n" + + "B9LKHhpy27wUjYCctLO4BzEP9URJGGgpSI4YEoJIx3HHCSZcjtFxc9zHSeDU7EdY\n" + + "1JKjULlmEPHyte03hkKh+8Ylcn/jo1UsVgbmnJpvQPhWGeI76TtnoM33LgZpnPLW\n" + + "IgS49841p/6U\n" + + "-----END CERTIFICATE-----\n"; + + return certificate; + } + + public String getCertificateChain3Content() { + String certChain = + "-----BEGIN CERTIFICATE-----\n" + + "MIIFZDCCA0ygAwIBAgIIDrYWUG22FM8wDQYJKoZIhvcNAQELBQAwMzESMBAGA1UE\n" + + "AwwJRklDQSBSb290MRAwDgYDVQQKDAdGTVIgTExDMQswCQYDVQQGEwJVUzAeFw0x\n" + + "NjA3MTkyMjAyNTVaFw00NjA3MTkyMjAyNTVaMDMxEjAQBgNVBAMMCUZJQ0EgUm9v\n" + + "dDEQMA4GA1UECgwHRk1SIExMQzELMAkGA1UEBhMCVVMwggIiMA0GCSqGSIb3DQEB\n" + + "AQUAA4ICDwAwggIKAoICAQDBQ6PhzyH9OqT05jxb7oVP0n+XsHqw3FUw7OhuVqTs\n" + + "FAYlMX8wVIsjsS/ozXMV26337yl5S7x62j9/e5KxGT6b2J1Xqfok2NUnx3pMk9/o\n" + + "Dl9+ifrUF0RPw94bxVJCx3DhAjDxiSPJs9XXlJ8+tSUzPpr+ZK+PvyvunWwB3Jr2\n" + + "ZBalKYQfSa6DWz5pIjcf+UwvMaW+NUMewOhcrWP55DTfVH3vfxh6OQkr/xWHYIYq\n" + + "TFEBg4ctEW6vYiPi7SEn27wDVRHn1E1Tno9Eq/a+2INQq1JLVMV7NnkDAx+r+Rbw\n" + + "h11lj6rkW3CKCpSv6Pu6EO03BSdResi0VzHCoa2EgrStSmjJq+DeVRQt8Bz0bP0D\n" + + "ap/u16lxKZCRzs0LE8LDKMa4D/vRZfvPAnmsWwDRvW5JieUbBLWGO7AungJqirWb\n" + + "EGqfHXVQfMWsFADROnWJpUJfvlVZ5DC4Cf9ewc8NZb5SZM0yml8KMngoPBJ1vpe4\n" + + "dgWGGeygzTEHn15Ux9GKrXQ2xye4mQIK2okFuOIQZSPJDqcR3k6Rl+Ilm5KGfqO3\n" + + "vpiKSdvmlcNhwGqKNUhDt8yUMr/9zSJV6Hxx8StAzqoX4f5RWnRiH90uSqTTS+Ui\n" + + "QVPiQoSAvwkDgADYGbj8EBZhppqgCUw14I91vF8KUGQc2HcHYCjl8tP/PB8biupz\n" + + "5wIDAQABo3wwejAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN6nbJ4lvQ8K\n" + + "vWTSssDiysj/k3zEMBcGA1UdIAQQMA4wDAYKKwYBBAGKFB4BATAdBgNVHQ4EFgQU\n" + + "3qdsniW9Dwq9ZNKywOLKyP+TfMQwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB\n" + + "CwUAA4ICAQBrx1a+3wzbfqai4xrctuXkqxyAYl0BIYAli9uZA1f9+q92nOZ2ZFc9\n" + + "6BzZGZeUtxlMd5mAVW+zC2lSKn9xWfZWA7rrpCPiMprXfJdQGA+HZ/w2hNtruCPv\n" + + "tSZ/DkiQFz2DBYEnQOdPvYWZGCIcdA2IEtd/fLgSbENXBr2hoX0vHR7YnV3OExk6\n" + + "9IJjYij1CY3IGXt0Zy1eI2APYuTGogAcYwhMvK/XDhNa2oYf0T++7UbzXzkq3Zy0\n" + + "KxnOd1X3bsXjdZYGgTPPjycLTzbLxvbz14YlnoGHD0filMtfHHH0wG1lDieIU+lk\n" + + "OL8Ff8Bk71khoP9qNgkS8CkjazUaW2PczjL4yczs+jvNB69h718Sg4xS7sV8/VC9\n" + + "lmeT/glZNFhTZKNbK3LSMoumk4ElUw7MeWCuKqPD4OB5WHKMrcj0WtnZJYgagaco\n" + + "RfpRSrd7CI9iD9yu2P173En8uzgMZA2/pMDf8gH6m3b5sz5td7nzdTaXVYQjkYBq\n" + + "t8bZFHvD3hgsIeEcQ9v9XunEYVpCac6LcUDxL33c3+e4s419LrLkgQMnoFYBBezy\n" + + "0TR5XPOoWin1SVgZ29WlIz432VJpw4mnrKdW5k4LcbdHRQ9E4ORNEJC2OesRAyBW\n" + + "C5MpsYpIhsgPPL1y7HS9r83MXWReheDyOEl5SnNYMjrcOib086vCag==\n" + + "-----END CERTIFICATE-----\n" + + "\n" + + "-----BEGIN CERTIFICATE-----\n" + + "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\n" + + "LIqYphQ=\n" + + "-----END CERTIFICATE-----\n" + + "\n" + + "-----BEGIN CERTIFICATE-----\n" + + "MIIF1jCCA76gAwIBAgIIIv77qJI0sdUwDQYJKoZIhvcNAQELBQAwOzEaMBgGA1UE\n" + + "AwwRRklDQSBJbnRlcm1lZGlhdGUxEDAOBgNVBAoMB0ZNUiBMTEMxCzAJBgNVBAYT\n" + + "AlVTMB4XDTE2MDcyODIxMjY1MVoXDTM2MDcyODIxMjY1MVowOTEYMBYGA1UEAwwP\n" + + "RklDQSBJc3N1aW5nIEUxMRAwDgYDVQQKDAdGTVIgTExDMQswCQYDVQQGEwJVUzCC\n" + + "AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOsnvfnZ8QICs84YDxo0DxJV\n" + + "2ZNY7CXGVOgSk+LBJdA0U9ebSenSJWUtTNznCHt5w8t/8IzTQoVuo6HfKoHynzMw\n" + + "Pe20rPQAS7Ot62ZchqrkZsnbcEjcYY1fBDWiIRqeFj53V0kCTXFq8qi9AszB/Nyu\n" + + "vt0tZMJ4Sl6TzM9B076IRtGrLtpkWMJ3TBjnpPLUKwbDqv0vg78prPEx8DoL9Dmv\n" + + "5gF8vjuyXS5KFvOREj3CAw6rW2cW0hzZV1nItAorxoeH9T3SzniH3KLMcm7KmJOi\n" + + "24xzZivETJzYypYphd6eaZ3BZg+k9CyLbbWB2QVX1/rFZAZj0cQrkkr1JqYBBvrW\n" + + "Vb1jU2zUGPlisYX+ecGZ91a2MTSGIPZPCkbq/HtwCOualwhwJV2Olu1o3PrPquI5\n" + + "FV6Q60y+icKC27Y/CKOlt4DAcNY8WK/Kgtn1IEL2AX82wlEIPnY4YtH2RHj3EG/e\n" + + "Xy9L89CITLX8EwvpkkW9KwZDT84rgrT6GVc3vD7bOMsBNhF7Lwj4Kofnc1ay/xaG\n" + + "zWphyIWBrgfD+nc+bl7zBVzILSBsnRZiMhtJfjiEDY3FiOKKuO8kn606jMntF4VW\n" + + "L8tISmTfSMEKIUU4nUjlSYPeVaOTdQnp5g6wU6YQ3soh2i97umtWPXCMnMz51VM5\n" + + "JxL3mIuWy4NxOaU8V6f3AgMBAAGjgd8wgdwwDwYDVR0TAQH/BAUwAwEB/zAfBgNV\n" + + "HSMEGDAWgBRlQY+gJG5kUFspTXIyACy+8qV+OTA/BggrBgEFBQcBAQQzMDEwLwYI\n" + + "KwYBBQUHMAGGI2h0dHA6Ly9lamJjYXZhbC5mbXIuY29tL3N0YXR1cy9vY3NwMDgG\n" + + "A1UdHwQxMC8wLaAroCmGJ2h0dHA6Ly9lamJjYXZhbC5mbXIuY29tL2NybC9maWNh\n" + + "aW50LmNybDAdBgNVHQ4EFgQUAfJmhr3/kwKCRJoLd04vP8EaiU8wDgYDVR0PAQH/\n" + + "BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBT7580KPs/Xg6t5NiAnerWb6KnlHPk\n" + + "Gr2VgO4pmEDl1tBb/bbSWRQ1ByrYQspu+ZQqo5n4A4WkTYVQvhX8bqiDepig633S\n" + + "gybX2q51RWYWgKph8cbvYAtHattqLUhlmkNqMepT/3Wx7vIACAmWloZNWB20EynI\n" + + "fJUm0p1cCnJoJLaWHikq70IZX1ly3M0oSyaz5ezEHQXgpPbezQXDdtQxdoEVsrnu\n" + + "iuccjGIMyFsQwCFFia7tmx+adwrfG1/yKhvn/L6+pcMGA47fPGIppDYT47dlILJk\n" + + "zavVaik1JaoEOyMMJN6iJsypSgey7GV6KfXyclBeBU1RO0A5gPfg5pD8aZ6QPnnZ\n" + + "K1WiiCSi2vcbdLExB0rS/I/J5xBtrMGRknfYkB+VQ2Hly8+5LP1lf0cThybO0Xal\n" + + "v0Zejsg8zGXiHD5T62clfn4vrtt5D1227hc58lol1ZgdTNUd2nRwWahOTlkj3lib\n" + + "WVBbCHlAH7sVhNSX3bd0KPXzy8CWnwrwbJMeqp6lKVwjcORve4RWaugyrwkqvtXa\n" + + "dxFODwJU6TEk11yV1y+tnX4BngJouz4PoiSopdqRr92tlK2fu9lMkCmMjCZ/38tR\n" + + "37eaos6RAqVKLWGfYkwwMumwVJt889LuYgC8sKNt9pPyj/LVoHoIddUJs3Jjhfi8\n" + + "iDUYpcRmFIuvRQ==\n" + + "-----END CERTIFICATE-----\n"; + + return certChain; + } + + @Test + public void addCertificateChainToTrustStore() + throws KeyStoreException, CertificateException, IOException, PlatformServiceException { + // Add a new certificate to the YBA's PEM trust store. + UUID certUUID = UUID.randomUUID(); + String certDirectory = TMP_PEM_STORE + certUUID.toString(); + new File(certDirectory).mkdirs(); + String certPath = certDirectory + "/ca.crt"; + String certificateContent = getCertificateChain1Content(); + addCertificateToYBA(certPath, certificateContent); + + pemTrustStoreManager.addCertificate(certPath, "test-cert", TMP_PEM_STORE, null, false); + + List pemTrustStoreCertificates = + pemTrustStoreManager.getCertsInTrustStore(PEM_TRUST_STORE_FILE, null); + assertEquals(2, pemTrustStoreCertificates.size()); + + certUUID = UUID.randomUUID(); + certDirectory = TMP_PEM_STORE + certUUID.toString(); + new File(certDirectory).mkdirs(); + certPath = certDirectory + "/ca.crt"; + certificateContent = getCertificateChain2Content(); + addCertificateToYBA(certPath, certificateContent); + pemTrustStoreManager.addCertificate(certPath, "test-cert-1", TMP_PEM_STORE, null, false); + pemTrustStoreCertificates = + pemTrustStoreManager.getCertsInTrustStore(PEM_TRUST_STORE_FILE, null); + assertEquals(3, pemTrustStoreCertificates.size()); + } + + @Test + public void addCertificateToTrustStore() + throws KeyStoreException, CertificateException, IOException, PlatformServiceException { + UUID certUUID = UUID.randomUUID(); + String certDirectory = TMP_PEM_STORE + certUUID.toString(); + new File(certDirectory).mkdirs(); + String certPath = certDirectory + "/ca.crt"; + + String certificateContent = getCertificateContent(); + addCertificateToYBA(certPath, certificateContent); + pemTrustStoreManager.addCertificate(certPath, "test-cert", TMP_PEM_STORE, null, false); + + List pemTrustStoreCertificates = + pemTrustStoreManager.getCertsInTrustStore(PEM_TRUST_STORE_FILE, null); + assertEquals(1, pemTrustStoreCertificates.size()); + } + + @Test + public void removeCertificateChainFromTrustStore() + throws KeyStoreException, CertificateException, IOException, PlatformServiceException { + UUID certUUID = UUID.randomUUID(); + String certDirectory = TMP_PEM_STORE + certUUID.toString(); + new File(certDirectory).mkdirs(); + String certPath = certDirectory + "/ca.crt"; + + String certificateContent = getCertificateChain1Content(); + CustomCaCertificateInfo.create( + defaultCustomer.getUuid(), certUUID, "test-cert", certPath, new Date(), new Date(), true); + addCertificateToYBA(certPath, certificateContent); + pemTrustStoreManager.addCertificate(certPath, "test-cert", TMP_PEM_STORE, null, false); + + List pemTrustStoreCertificates = + pemTrustStoreManager.getCertsInTrustStore(PEM_TRUST_STORE_FILE, null); + assertEquals(2, pemTrustStoreCertificates.size()); + + certUUID = UUID.randomUUID(); + certDirectory = TMP_PEM_STORE + certUUID.toString(); + new File(certDirectory).mkdirs(); + certPath = certDirectory + "/ca.crt"; + certificateContent = getCertificateChain2Content(); + CustomCaCertificateInfo.create( + defaultCustomer.getUuid(), certUUID, "test-cert-1", certPath, new Date(), new Date(), true); + addCertificateToYBA(certPath, certificateContent); + + pemTrustStoreManager.addCertificate(certPath, "test-cert-1", TMP_PEM_STORE, null, false); + pemTrustStoreCertificates = + pemTrustStoreManager.getCertsInTrustStore(PEM_TRUST_STORE_FILE, null); + assertEquals(3, pemTrustStoreCertificates.size()); + + pemTrustStoreManager.remove(certPath, "test-cert", TMP_PEM_STORE, null, false); + pemTrustStoreCertificates = + pemTrustStoreManager.getCertsInTrustStore(PEM_TRUST_STORE_FILE, null); + assertEquals(2, pemTrustStoreCertificates.size()); + } + + @Test + public void replaceCertificateChainInTrustStore() + throws KeyStoreException, CertificateException, IOException, PlatformServiceException { + UUID certUUID = UUID.randomUUID(); + String certDirectory = TMP_PEM_STORE + certUUID.toString(); + new File(certDirectory).mkdirs(); + String oldCertPath = certDirectory + "/ca.crt"; + + String certificateContent = getCertificateChain1Content(); + CustomCaCertificateInfo.create( + defaultCustomer.getUuid(), + certUUID, + "test-cert", + oldCertPath, + new Date(), + new Date(), + true); + addCertificateToYBA(oldCertPath, certificateContent); + pemTrustStoreManager.addCertificate(oldCertPath, "test-cert", TMP_PEM_STORE, null, false); + + List pemTrustStoreCertificates = + pemTrustStoreManager.getCertsInTrustStore(PEM_TRUST_STORE_FILE, null); + assertEquals(2, pemTrustStoreCertificates.size()); + + certUUID = UUID.randomUUID(); + certDirectory = TMP_PEM_STORE + certUUID.toString(); + new File(certDirectory).mkdirs(); + String certPath = certDirectory + "/ca.crt"; + certificateContent = getCertificateChain2Content(); + CustomCaCertificateInfo.create( + defaultCustomer.getUuid(), certUUID, "test-cert-1", certPath, new Date(), new Date(), true); + addCertificateToYBA(certPath, certificateContent); + + pemTrustStoreManager.addCertificate(certPath, "test-cert-1", TMP_PEM_STORE, null, false); + pemTrustStoreCertificates = + pemTrustStoreManager.getCertsInTrustStore(PEM_TRUST_STORE_FILE, null); + assertEquals(3, pemTrustStoreCertificates.size()); + + certUUID = UUID.randomUUID(); + certDirectory = TMP_PEM_STORE + certUUID.toString(); + new File(certDirectory).mkdirs(); + String newCertPath = certDirectory + "/ca.crt"; + certificateContent = getCertificateChain3Content(); + addCertificateToYBA(newCertPath, certificateContent); + + pemTrustStoreManager.replaceCertificate( + certPath, newCertPath, "test-cert-1", TMP_PEM_STORE, null, false); + CustomCaCertificateInfo.create( + defaultCustomer.getUuid(), + certUUID, + "test-cert-1", + newCertPath, + new Date(), + new Date(), + true); + + pemTrustStoreCertificates = + pemTrustStoreManager.getCertsInTrustStore(PEM_TRUST_STORE_FILE, null); + List allCerts = pemTrustStoreManager.getX509Certificate(newCertPath); + allCerts.addAll(pemTrustStoreManager.getX509Certificate(oldCertPath)); + assertEquals(5, allCerts.size()); + for (Certificate cert : allCerts) { + if (!pemTrustStoreCertificates.contains(cert)) { + fail(); + } + } + assertEquals(5, pemTrustStoreCertificates.size()); + } +}