diff options
author | 2020-08-19 10:38:43 +0200 | |
---|---|---|
committer | 2020-08-27 15:02:07 +0200 | |
commit | 2512d60868bf25f91e4aa4b857d4ba373579f0fd (patch) | |
tree | e46d4010b6fc873facbf0222225eb822d3284dac /trustStoreMerger | |
parent | a1def56303f42c197156ed3862f733df32001bb7 (diff) |
Add Certification merge logic
Issue-ID: DCAEGEN2-2253
Signed-off-by: Tomasz Wrobel <tomasz.wrobel@nokia.com>
Change-Id: I4157ce71373b41d9f7ee03b76d407ec7a2b17ec3
Diffstat (limited to 'trustStoreMerger')
50 files changed, 1816 insertions, 245 deletions
diff --git a/trustStoreMerger/Dockerfile b/trustStoreMerger/Dockerfile index 63d15c42..8f0f2481 100644 --- a/trustStoreMerger/Dockerfile +++ b/trustStoreMerger/Dockerfile @@ -10,4 +10,7 @@ USER truststoreMerger:onap COPY target/oom-truststore-merger-${VERSION}.jar ./opt/onap/oom/truststoremerger/oom-truststore-merger.jar +#Run as root allow to manage certificates provided by other containers. It should be change in future +USER root + ENTRYPOINT ["java","-jar","./opt/onap/oom/truststoremerger/oom-truststore-merger.jar"] diff --git a/trustStoreMerger/pom.xml b/trustStoreMerger/pom.xml index 201365ca..fd2aff05 100644 --- a/trustStoreMerger/pom.xml +++ b/trustStoreMerger/pom.xml @@ -165,5 +165,9 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcpkix-jdk15on</artifactId> + </dependency> </dependencies> </project> diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/TrustStoreMerger.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/TrustStoreMerger.java index 98c67ba8..c8cc84df 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/TrustStoreMerger.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/TrustStoreMerger.java @@ -21,11 +21,12 @@ package org.onap.oom.truststoremerger; import org.onap.oom.truststoremerger.api.ExitStatus; import org.onap.oom.truststoremerger.api.ExitableException; -import org.onap.oom.truststoremerger.certification.file.TruststoreFile; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAlias; +import org.onap.oom.truststoremerger.certification.file.model.Truststore; import org.onap.oom.truststoremerger.certification.file.provider.FileManager; import org.onap.oom.truststoremerger.certification.file.provider.PasswordReader; -import org.onap.oom.truststoremerger.certification.file.provider.TruststoreFileFactory; -import org.onap.oom.truststoremerger.certification.file.provider.TruststoreFilesListProvider; +import org.onap.oom.truststoremerger.certification.file.TruststoreFileFactory; +import org.onap.oom.truststoremerger.certification.file.TruststoreFilesListProvider; import org.onap.oom.truststoremerger.certification.path.EnvProvider; import org.onap.oom.truststoremerger.certification.path.TruststoresPathsProvider; import org.onap.oom.truststoremerger.configuration.MergerConfiguration; @@ -33,9 +34,15 @@ import org.onap.oom.truststoremerger.configuration.MergerConfigurationFactory; import org.onap.oom.truststoremerger.certification.path.PathValidator; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; class TrustStoreMerger { + private static final Logger LOGGER = LoggerFactory.getLogger(TrustStoreMerger.class); + private static final int FIRST_TRUSTSTORE_INDEX = 0; + private static final int SECOND_TRUSTSTORE_INDEX = 1; + private final AppExitHandler appExitHandler; TrustStoreMerger(AppExitHandler appExitHandler) { @@ -47,28 +54,42 @@ class TrustStoreMerger { mergeTruststores(); appExitHandler.exit(ExitStatus.SUCCESS); } catch (ExitableException e) { + LOGGER.error("Truststore Merger fails in execution: ", e); appExitHandler.exit(e.applicationExitStatus()); } } private void mergeTruststores() throws ExitableException { MergerConfiguration configuration = loadConfiguration(); - List<TruststoreFile> truststoreFilesList = getTruststoreFilesList(configuration); + List<Truststore> truststoreFilesList = getTruststoreFilesList(configuration); + + Truststore baseFile = truststoreFilesList.get(FIRST_TRUSTSTORE_INDEX); + baseFile.createBackup(); + + for (int i = SECOND_TRUSTSTORE_INDEX; i < truststoreFilesList.size(); i++) { + List<CertificateWithAlias> certificateWrappers = truststoreFilesList.get(i).getCertificates(); + baseFile.addCertificate(certificateWrappers); + } + + baseFile.saveFile(); } private MergerConfiguration loadConfiguration() throws ExitableException { - TruststoresPathsProvider truststoresPathsProvider = new TruststoresPathsProvider(new EnvProvider(), new PathValidator()); + TruststoresPathsProvider truststoresPathsProvider = new TruststoresPathsProvider(new EnvProvider(), + new PathValidator()); MergerConfigurationFactory factory = new MergerConfigurationFactory(truststoresPathsProvider); return factory.createConfiguration(); } - private List<TruststoreFile> getTruststoreFilesList(MergerConfiguration configuration) throws ExitableException { - TruststoreFileFactory truststoreFileFactory = new TruststoreFileFactory(new FileManager(), new PasswordReader()); - TruststoreFilesListProvider truststoreFilesListProvider = new TruststoreFilesListProvider(truststoreFileFactory); + private List<Truststore> getTruststoreFilesList(MergerConfiguration configuration) throws ExitableException { + TruststoreFileFactory truststoreFileFactory = new TruststoreFileFactory(new FileManager(), + new PasswordReader()); + TruststoreFilesListProvider truststoreFilesListProvider = new TruststoreFilesListProvider( + truststoreFileFactory); return truststoreFilesListProvider - .getTruststoreFilesList( - configuration.getTruststoreFilePaths(), - configuration.getTruststoreFilePasswordPaths() - ); + .getTruststoreFilesList( + configuration.getTruststoreFilePaths(), + configuration.getTruststoreFilePasswordPaths() + ); } } diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/CertificateConstants.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/CertificateConstants.java new file mode 100644 index 00000000..68c5d13c --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/CertificateConstants.java @@ -0,0 +1,29 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.api; + +public class CertificateConstants { + + public static final String JKS_INSTANCE = "JKS"; + public static final String PKCS12_INSTANCE = "PKCS12"; + public static final String X_509_CERTIFICATE = "X.509"; + public static final String BOUNCY_CASTLE_PROVIDER = "BC"; + +} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ConfigurationEnvs.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ConfigurationEnvs.java index 13c8c726..f6f8bbba 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ConfigurationEnvs.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ConfigurationEnvs.java @@ -21,6 +21,6 @@ package org.onap.oom.truststoremerger.api; public class ConfigurationEnvs { - public static final String TRUSTSTORES_ENV = "TRUSTSTORES"; - public static final String TRUSTSTORES_PASSWORDS_ENV = "TRUSTSTORES_PASSWORDS"; + public static final String TRUSTSTORES_PATHS_ENV = "TRUSTSTORES_PATHS"; + public static final String TRUSTSTORES_PASSWORDS_PATHS_ENV = "TRUSTSTORES_PASSWORDS_PATHS"; } diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitStatus.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitStatus.java index d0c3b2f0..b9111bf9 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitStatus.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitStatus.java @@ -25,7 +25,15 @@ public enum ExitStatus { TRUSTSTORES_PATHS_PROVIDER_EXCEPTION(1, "Invalid paths in environment variables"), MERGER_CONFIGURATION_EXCEPTION(2, "Invalid merger configuration"), TRUSTSTORE_FILE_FACTORY_EXCEPTION(3, "Invalid truststore file-password pair"), - PASSWORD_READER_EXCEPTION(4, "Cannot read password from file"); + PASSWORD_READER_EXCEPTION(4, "Cannot read password from file"), + CREATE_BACKUP_EXCEPTION(5, "Cannot create backup file"), + KEYSTORE_INSTANCE_EXCEPTION(6, "Cannot initialize keystore instance"), + TRUSTSTORE_LOAD_FILE_EXCEPTION(7, "Cannot load truststore file"), + TRUSTSTORE_DATA_OPERATION_EXCEPTION(8, "Cannot operate on truststore data"), + MISSING_TRUSTSTORE_EXCEPTION(9, "Missing truststore certificates in provided file"), + ALIAS_CONFLICT_EXCEPTION(10, "Alias conflict detected"), + WRITE_TRUSTSTORE_FILE_EXCEPTION(11, "Cannot save truststore file"); + private final int value; private final String message; diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitableException.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitableException.java index 3cc46730..ec28d466 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitableException.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitableException.java @@ -35,5 +35,6 @@ public class ExitableException extends Exception { public ExitStatus applicationExitStatus() { return exitStatus; - }; + } + } diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoreFileFactory.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoreFileFactory.java new file mode 100644 index 00000000..d93409b6 --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoreFileFactory.java @@ -0,0 +1,99 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file; + +import org.onap.oom.truststoremerger.certification.file.model.JavaTruststore; +import org.onap.oom.truststoremerger.certification.file.model.PemTruststore; +import org.onap.oom.truststoremerger.certification.file.model.Truststore; + +import java.io.File; +import org.onap.oom.truststoremerger.certification.file.exception.KeystoreInstanceException; +import org.onap.oom.truststoremerger.certification.file.exception.LoadTruststoreException; +import org.onap.oom.truststoremerger.certification.file.exception.PasswordReaderException; +import org.onap.oom.truststoremerger.certification.file.exception.TruststoreFileFactoryException; +import org.onap.oom.truststoremerger.certification.file.provider.CertificateStoreControllerFactory; +import org.onap.oom.truststoremerger.certification.file.provider.FileManager; +import org.onap.oom.truststoremerger.certification.file.provider.JavaCertificateStoreController; +import org.onap.oom.truststoremerger.certification.file.provider.PasswordReader; +import org.onap.oom.truststoremerger.certification.file.provider.PemCertificateController; + +public class TruststoreFileFactory { + + private static final String JKS_EXTENSION = ".jks"; + private static final String P12_EXTENSION = ".p12"; + private static final String PEM_EXTENSION = ".pem"; + private static final String FILE_DOES_NOT_EXIST_MSG_TEMPLATE = "File: %s does not exist"; + private static final String UNKNOWN_TRUSTSTORE_TYPE_MSG_TEMPLATE = "Unknown truststore extension type: %s"; + + private final FileManager fileManager; + private final PasswordReader passwordReader; + private final CertificateStoreControllerFactory certificateStoreControllerFactory = + new CertificateStoreControllerFactory(); + + public TruststoreFileFactory(FileManager fileManager, PasswordReader passwordReader) { + this.fileManager = fileManager; + this.passwordReader = passwordReader; + } + + public Truststore create(String truststoreFilePath, String truststorePasswordPath) + throws TruststoreFileFactoryException, PasswordReaderException, KeystoreInstanceException, LoadTruststoreException { + File truststoreFile = new File(truststoreFilePath); + if (!fileManager.checkIfFileExists(truststoreFile)) { + throw new TruststoreFileFactoryException(String.format(FILE_DOES_NOT_EXIST_MSG_TEMPLATE, truststoreFile)); + } + return createTypedTruststore(truststoreFile, truststorePasswordPath); + } + + private Truststore createTypedTruststore(File truststoreFile, String truststorePasswordPath) + throws KeystoreInstanceException, PasswordReaderException, LoadTruststoreException, TruststoreFileFactoryException { + String extension = fileManager.getExtension(truststoreFile); + switch (extension) { + case JKS_EXTENSION: + return createJksTruststore(truststoreFile, truststorePasswordPath); + case P12_EXTENSION: + return createP12Truststore(truststoreFile, truststorePasswordPath); + case PEM_EXTENSION: + return createPemTruststore(truststoreFile); + default: + throw new TruststoreFileFactoryException( + String.format(UNKNOWN_TRUSTSTORE_TYPE_MSG_TEMPLATE, extension)); + } + } + + private JavaTruststore createJksTruststore(File truststoreFile, String truststorePasswordPath) + throws PasswordReaderException, LoadTruststoreException, KeystoreInstanceException { + String password = passwordReader.readPassword(new File(truststorePasswordPath)); + JavaCertificateStoreController storeController = certificateStoreControllerFactory + .createLoadedJksCertificateStoreController(truststoreFile, password); + return new JavaTruststore(truststoreFile, storeController); + } + + private JavaTruststore createP12Truststore(File truststoreFile, String truststorePasswordPath) + throws LoadTruststoreException, KeystoreInstanceException, PasswordReaderException { + String password = passwordReader.readPassword(new File(truststorePasswordPath)); + JavaCertificateStoreController storeController = certificateStoreControllerFactory + .createLoadedPkcs12CertificateStoreController(truststoreFile, password); + return new JavaTruststore(truststoreFile, storeController); + } + + private PemTruststore createPemTruststore(File truststoreFile) { + return new PemTruststore(truststoreFile, new PemCertificateController(truststoreFile)); + } +} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFilesListProvider.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoreFilesListProvider.java index 2f5356d5..92e3c2a8 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFilesListProvider.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoreFilesListProvider.java @@ -17,13 +17,16 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.truststoremerger.certification.file.provider; +package org.onap.oom.truststoremerger.certification.file; -import org.onap.oom.truststoremerger.certification.file.TruststoreFile; +import org.onap.oom.truststoremerger.certification.file.model.Truststore; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; +import org.onap.oom.truststoremerger.certification.file.exception.KeystoreInstanceException; +import org.onap.oom.truststoremerger.certification.file.exception.LoadTruststoreException; +import org.onap.oom.truststoremerger.certification.file.exception.PasswordReaderException; +import org.onap.oom.truststoremerger.certification.file.exception.TruststoreFileFactoryException; public class TruststoreFilesListProvider { @@ -33,16 +36,16 @@ public class TruststoreFilesListProvider { this.truststoreFileFactory = truststoreFileFactory; } - public List<TruststoreFile> getTruststoreFilesList(List<String> truststoreFilePaths, - List<String> truststoreFilePasswordPaths) - throws PasswordReaderException, TruststoreFileFactoryException { - List<TruststoreFile> truststoreFilesList = new ArrayList<>(); + public List<Truststore> getTruststoreFilesList(List<String> truststoreFilePaths, + List<String> truststoreFilePasswordPaths) + throws LoadTruststoreException, PasswordReaderException, TruststoreFileFactoryException, KeystoreInstanceException { + List<Truststore> truststoreFilesList = new ArrayList<>(); for (int i = 0; i < truststoreFilePaths.size(); i++) { String truststorePath = truststoreFilePaths.get(i); String passwordPath = truststoreFilePasswordPaths.get(i); - TruststoreFile truststoreFile = truststoreFileFactory.create(truststorePath, passwordPath); - truststoreFilesList.add(truststoreFile); + Truststore truststore = truststoreFileFactory.create(truststorePath, passwordPath); + truststoreFilesList.add(truststore); } return truststoreFilesList; diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoreFileWithPassword.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/AliasConflictException.java index 484f2d4f..a4102d9f 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoreFileWithPassword.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/AliasConflictException.java @@ -17,19 +17,15 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.truststoremerger.certification.file; +package org.onap.oom.truststoremerger.certification.file.exception; -import java.io.File; +import org.onap.oom.truststoremerger.api.ExitStatus; +import org.onap.oom.truststoremerger.api.ExitableException; -public abstract class TruststoreFileWithPassword extends TruststoreFile { - private String password; +public class AliasConflictException extends ExitableException { - TruststoreFileWithPassword(File truststoreFile, String password) { - super(truststoreFile); - this.password = password; + public AliasConflictException(String message) { + super(message, ExitStatus.ALIAS_CONFLICT_EXCEPTION); } - public String getPassword(){ - return password; - }; } diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/CreateBackupException.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/CreateBackupException.java new file mode 100644 index 00000000..a21f7013 --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/CreateBackupException.java @@ -0,0 +1,30 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.exception; + +import org.onap.oom.truststoremerger.api.ExitStatus; +import org.onap.oom.truststoremerger.api.ExitableException; + +public class CreateBackupException extends ExitableException { + + public CreateBackupException(Exception e) { + super(e, ExitStatus.CREATE_BACKUP_EXCEPTION); + } +} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/KeystoreInstanceException.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/KeystoreInstanceException.java new file mode 100644 index 00000000..c5bcc3ca --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/KeystoreInstanceException.java @@ -0,0 +1,30 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.exception; + +import org.onap.oom.truststoremerger.api.ExitStatus; +import org.onap.oom.truststoremerger.api.ExitableException; + +public class KeystoreInstanceException extends ExitableException { + + public KeystoreInstanceException(Throwable e) { + super(e, ExitStatus.KEYSTORE_INSTANCE_EXCEPTION); + } +} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/PemTruststore.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/LoadTruststoreException.java index ca2ac85d..b8bb53fa 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/PemTruststore.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/LoadTruststoreException.java @@ -17,21 +17,14 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.truststoremerger.certification.file; +package org.onap.oom.truststoremerger.certification.file.exception; -import java.io.File; -import java.security.cert.Certificate; -import java.util.Collections; -import java.util.List; +import org.onap.oom.truststoremerger.api.ExitStatus; +import org.onap.oom.truststoremerger.api.ExitableException; -public class PemTruststore extends TruststoreFile { +public class LoadTruststoreException extends ExitableException { - public PemTruststore(File truststoreFile) { - super(truststoreFile); - } - - @Override - public List<Certificate> getCertificates() { - return Collections.emptyList(); + public LoadTruststoreException(Throwable e) { + super(e, ExitStatus.TRUSTSTORE_LOAD_FILE_EXCEPTION); } } diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoreFile.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/MissingTruststoreException.java index 88b1b5a8..c502d6b6 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoreFile.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/MissingTruststoreException.java @@ -17,22 +17,14 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.truststoremerger.certification.file; +package org.onap.oom.truststoremerger.certification.file.exception; -import java.io.File; -import java.security.cert.Certificate; -import java.util.List; +import org.onap.oom.truststoremerger.api.ExitStatus; +import org.onap.oom.truststoremerger.api.ExitableException; -public abstract class TruststoreFile { - private File truststoreFile; +public class MissingTruststoreException extends ExitableException { - TruststoreFile(File truststoreFile) { - this.truststoreFile = truststoreFile; + public MissingTruststoreException(String message) { + super(message, ExitStatus.MISSING_TRUSTSTORE_EXCEPTION); } - - public abstract List<Certificate> getCertificates(); - - public File getTruststoreFile() { - return truststoreFile; - }; } diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/PasswordReaderException.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/PasswordReaderException.java index 2928f0c5..d601d229 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/PasswordReaderException.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/PasswordReaderException.java @@ -17,13 +17,13 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.truststoremerger.certification.file.provider; +package org.onap.oom.truststoremerger.certification.file.exception; import org.onap.oom.truststoremerger.api.ExitStatus; import org.onap.oom.truststoremerger.api.ExitableException; -class PasswordReaderException extends ExitableException { - PasswordReaderException(String message) { +public class PasswordReaderException extends ExitableException { + public PasswordReaderException(String message) { super(message, ExitStatus.PASSWORD_READER_EXCEPTION); } } diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/TruststoreDataOperationException.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/TruststoreDataOperationException.java new file mode 100644 index 00000000..cf848f79 --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/TruststoreDataOperationException.java @@ -0,0 +1,30 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.exception; + +import org.onap.oom.truststoremerger.api.ExitStatus; +import org.onap.oom.truststoremerger.api.ExitableException; + +public class TruststoreDataOperationException extends ExitableException { + + public TruststoreDataOperationException(Exception e) { + super(e, ExitStatus.TRUSTSTORE_DATA_OPERATION_EXCEPTION); + } +} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFileFactoryException.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/TruststoreFileFactoryException.java index 43342c83..18349fd4 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFileFactoryException.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/TruststoreFileFactoryException.java @@ -17,13 +17,13 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.truststoremerger.certification.file.provider; +package org.onap.oom.truststoremerger.certification.file.exception; import org.onap.oom.truststoremerger.api.ExitStatus; import org.onap.oom.truststoremerger.api.ExitableException; -class TruststoreFileFactoryException extends ExitableException { - TruststoreFileFactoryException(String message) { +public class TruststoreFileFactoryException extends ExitableException { + public TruststoreFileFactoryException(String message) { super(message, ExitStatus.TRUSTSTORE_FILE_FACTORY_EXCEPTION); } diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/WriteTruststoreFileException.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/WriteTruststoreFileException.java new file mode 100644 index 00000000..a5e02b3c --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/exception/WriteTruststoreFileException.java @@ -0,0 +1,31 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + +package org.onap.oom.truststoremerger.certification.file.exception; + +import org.onap.oom.truststoremerger.api.ExitStatus; +import org.onap.oom.truststoremerger.api.ExitableException; + +public class WriteTruststoreFileException extends ExitableException { + + public WriteTruststoreFileException(Exception e) { + super(e, ExitStatus.WRITE_TRUSTSTORE_FILE_EXCEPTION); + } +} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/model/JavaTruststore.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/model/JavaTruststore.java new file mode 100644 index 00000000..d46fba1e --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/model/JavaTruststore.java @@ -0,0 +1,58 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.model; + +import java.io.File; +import java.util.List; +import org.onap.oom.truststoremerger.api.ExitableException; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAlias; +import org.onap.oom.truststoremerger.certification.file.exception.WriteTruststoreFileException; +import org.onap.oom.truststoremerger.certification.file.provider.JavaCertificateStoreController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JavaTruststore extends Truststore { + + private static final Logger LOGGER = LoggerFactory.getLogger(JavaTruststore.class); + private final JavaCertificateStoreController storeController; + + public JavaTruststore(File truststoreFile, JavaCertificateStoreController storeController) { + super(truststoreFile); + this.storeController = storeController; + } + + @Override + public List<CertificateWithAlias> getCertificates() throws ExitableException { + LOGGER.debug("Attempt ro read certificates from file: {} ", this.getFile().getPath()); + return storeController.getNotEmptyCertificateList(); + } + + @Override + public void addCertificate(List<CertificateWithAlias> certificates) throws ExitableException { + LOGGER.debug("Attempt to add certificates for saving to file"); + storeController.addCertificates(certificates); + } + + @Override + public void saveFile() throws WriteTruststoreFileException { + LOGGER.debug("Attempt to save file: {}", this.getFile().getPath()); + storeController.saveFile(); + } +} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/model/PemTruststore.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/model/PemTruststore.java new file mode 100644 index 00000000..36195267 --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/model/PemTruststore.java @@ -0,0 +1,58 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.model; + +import java.io.File; +import java.util.List; +import org.onap.oom.truststoremerger.api.ExitableException; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAlias; +import org.onap.oom.truststoremerger.certification.file.provider.PemCertificateController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PemTruststore extends Truststore { + + private static final Logger LOGGER = LoggerFactory.getLogger(PemTruststore.class); + private final PemCertificateController pemCertificateController; + + public PemTruststore(File truststoreFile, PemCertificateController pemCertificateController) { + super(truststoreFile); + this.pemCertificateController = pemCertificateController; + } + + @Override + public List<CertificateWithAlias> getCertificates() throws ExitableException { + LOGGER.debug("Attempt ro read certificates from file: {}", this.getFile().getPath()); + return pemCertificateController.getNotEmptyCertificateList(); + } + + @Override + public void addCertificate(List<CertificateWithAlias> certificates) throws ExitableException { + LOGGER.debug("Attempt to add certificates for saving to file"); + pemCertificateController.addCertificates(certificates); + } + + @Override + public void saveFile() throws ExitableException { + LOGGER.debug("Attempt to save file: {}", this.getFile().getPath()); + pemCertificateController.saveFile(); + } + +} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/model/Truststore.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/model/Truststore.java new file mode 100644 index 00000000..153805a7 --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/model/Truststore.java @@ -0,0 +1,62 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.model; + +import java.io.File; +import java.io.FileOutputStream; +import java.nio.file.Files; +import java.util.List; +import org.onap.oom.truststoremerger.api.ExitableException; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAlias; +import org.onap.oom.truststoremerger.certification.file.exception.CreateBackupException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class Truststore { + + private static final Logger LOGGER = LoggerFactory.getLogger(Truststore.class); + private static final String BACKUP_EXTENSION = ".bak"; + private final File file; + + Truststore(File file) { + this.file = file; + } + + public abstract List<CertificateWithAlias> getCertificates() throws ExitableException; + + public abstract void addCertificate(List<CertificateWithAlias> certificates) throws ExitableException; + + public abstract void saveFile() throws ExitableException; + + public File getFile() { + return file; + } + + public void createBackup() throws CreateBackupException { + LOGGER.debug("Create backup of file: {}", file.getPath()); + String backupFilePath = file.getAbsolutePath() + BACKUP_EXTENSION; + try (FileOutputStream fileOutputStream = new FileOutputStream(backupFilePath)) { + Files.copy(file.toPath(), fileOutputStream); + } catch (Exception e) { + LOGGER.error("Cannot create backup of file: {} ", getFile().getPath()); + throw new CreateBackupException(e); + } + } +} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/CertificateController.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/CertificateController.java new file mode 100644 index 00000000..f2ed2c45 --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/CertificateController.java @@ -0,0 +1,33 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.provider; + +import java.util.List; +import org.onap.oom.truststoremerger.api.ExitableException; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAlias; + +public interface CertificateController { + + List<CertificateWithAlias> getNotEmptyCertificateList() throws ExitableException; + + void addCertificates(List<CertificateWithAlias> certificates) throws ExitableException; + + void saveFile() throws ExitableException; +} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/CertificateStoreControllerFactory.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/CertificateStoreControllerFactory.java new file mode 100644 index 00000000..66e2aed2 --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/CertificateStoreControllerFactory.java @@ -0,0 +1,61 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.provider; + +import static org.onap.oom.truststoremerger.api.CertificateConstants.JKS_INSTANCE; +import static org.onap.oom.truststoremerger.api.CertificateConstants.PKCS12_INSTANCE; + +import java.io.File; +import java.security.KeyStore; +import java.security.KeyStoreException; +import org.onap.oom.truststoremerger.certification.file.exception.KeystoreInstanceException; +import org.onap.oom.truststoremerger.certification.file.exception.LoadTruststoreException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CertificateStoreControllerFactory { + + private static final Logger LOGGER = LoggerFactory.getLogger(CertificateStoreControllerFactory.class); + + public JavaCertificateStoreController createLoadedJksCertificateStoreController(File certFile, String certPassword) + throws LoadTruststoreException, KeystoreInstanceException { + return createLoadedCertificateStoreController(certFile, certPassword, JKS_INSTANCE); + } + + public JavaCertificateStoreController createLoadedPkcs12CertificateStoreController(File certFile, String certPassword) + throws KeystoreInstanceException, LoadTruststoreException { + return createLoadedCertificateStoreController(certFile, certPassword, PKCS12_INSTANCE); + } + + private JavaCertificateStoreController createLoadedCertificateStoreController(File certFile, String certPassword, + String instanceType) + throws LoadTruststoreException, KeystoreInstanceException { + try { + JavaCertificateStoreController javaCertificateStoreController = new JavaCertificateStoreController( + KeyStore.getInstance(instanceType), certFile, certPassword); + javaCertificateStoreController.loadFile(); + return javaCertificateStoreController; + } catch (KeyStoreException e) { + LOGGER.error("Cannot initialize Java Keystore instance"); + throw new KeystoreInstanceException(e); + } + } +} + diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/FileManager.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/FileManager.java index 901c13ab..12029ade 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/FileManager.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/FileManager.java @@ -22,17 +22,18 @@ package org.onap.oom.truststoremerger.certification.file.provider; import java.io.File; public class FileManager { - private static final int NOT_FOUND_INDEX=-1; - String getExtension(File file) { + private static final int INDEX_NOT_FOUND = -1; + + public String getExtension(File file) { int extStartIndex = file.getName().lastIndexOf("."); - if (extStartIndex == NOT_FOUND_INDEX) { + if (extStartIndex == INDEX_NOT_FOUND) { return ""; } - return file.getName().substring(extStartIndex); + return file.getName().substring(extStartIndex).toLowerCase(); } - boolean checkIfFileExists(File file){ + public boolean checkIfFileExists(File file) { return file.exists(); } diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/JavaCertificateStoreController.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/JavaCertificateStoreController.java new file mode 100644 index 00000000..1c20fd38 --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/JavaCertificateStoreController.java @@ -0,0 +1,156 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.provider; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.onap.oom.truststoremerger.api.ExitableException; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAlias; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAliasFactory; +import org.onap.oom.truststoremerger.certification.file.exception.AliasConflictException; +import org.onap.oom.truststoremerger.certification.file.exception.TruststoreDataOperationException; +import org.onap.oom.truststoremerger.certification.file.exception.LoadTruststoreException; +import org.onap.oom.truststoremerger.certification.file.exception.MissingTruststoreException; +import org.onap.oom.truststoremerger.certification.file.exception.WriteTruststoreFileException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JavaCertificateStoreController implements CertificateController { + + private static final Logger LOGGER = LoggerFactory.getLogger(JavaCertificateStoreController.class); + + private final CertificateWithAliasFactory factory = new CertificateWithAliasFactory(); + private final KeyStore keyStore; + private final File storeFile; + private final String password; + + + public JavaCertificateStoreController(KeyStore keyStore, File storeFile, String password) { + this.keyStore = keyStore; + this.storeFile = storeFile; + this.password = password; + } + + public List<CertificateWithAlias> getNotEmptyCertificateList() throws ExitableException { + List<String> aliases = getTruststoreAliasesList(); + if (aliases.isEmpty()) { + throw new MissingTruststoreException("Missing certificate aliases in file: " + storeFile.getPath()); + } + return getWrappedCertificates(aliases); + } + + public void addCertificates(List<CertificateWithAlias> certificatesWithAliases) + throws ExitableException { + if (getTruststoreAliasesList().isEmpty()){ + throw new MissingTruststoreException("Missing certificate aliases in file: " + storeFile.getPath()); + } + for (CertificateWithAlias certificate : certificatesWithAliases) { + addCertificate(certificate); + } + } + + public void saveFile() throws WriteTruststoreFileException { + try (FileOutputStream outputStream = new FileOutputStream(this.storeFile)) { + keyStore.store(outputStream, this.password.toCharArray()); + } catch (Exception e) { + LOGGER.error("Cannot write truststore file"); + throw new WriteTruststoreFileException(e); + } + } + + public void loadFile() throws LoadTruststoreException { + try { + keyStore.load(new FileInputStream(this.storeFile), this.password.toCharArray()); + } catch (Exception e) { + LOGGER.error("Cannot load file: {}", this.storeFile.getPath()); + throw new LoadTruststoreException(e); + } + } + + private void addCertificate(CertificateWithAlias certificate) + throws TruststoreDataOperationException, AliasConflictException { + if (hasAliasConflict(certificate)) { + LOGGER.error("Alias conflict detected"); + throw new AliasConflictException("Alias conflict detected. Alias conflicted: " + certificate.getAlias()); + } + try { + keyStore.setCertificateEntry(certificate.getAlias(), certificate.getCertificate()); + } catch (KeyStoreException e) { + LOGGER.error("Cannot merge certificate with alias: {}", certificate.getAlias()); + throw new TruststoreDataOperationException(e); + } + } + + private boolean hasAliasConflict(CertificateWithAlias certificate) throws TruststoreDataOperationException { + try { + return keyStore.containsAlias(certificate.getAlias()); + } catch (KeyStoreException e) { + LOGGER.error("Cannot check alias conflict"); + throw new TruststoreDataOperationException(e); + } + } + + private List<CertificateWithAlias> getWrappedCertificates(List<String> aliases) + throws TruststoreDataOperationException { + + List<CertificateWithAlias> certificateWrapped = new ArrayList<>(); + + for (String alias : aliases) { + certificateWrapped.add(createWrappedCertificate(alias)); + } + return certificateWrapped; + } + + private CertificateWithAlias createWrappedCertificate(String alias) throws TruststoreDataOperationException { + try { + return factory.createCertificateWithAlias(keyStore.getCertificate(alias), alias); + } catch (KeyStoreException e) { + LOGGER.warn("Cannot get certificate with alias: {} ", alias); + throw new TruststoreDataOperationException(e); + } + } + + private List<String> getTruststoreAliasesList() throws TruststoreDataOperationException { + try { + List<String> aliases = Collections.list(keyStore.aliases()); + return getFilteredAlias(aliases); + } catch (KeyStoreException e) { + LOGGER.warn("Cannot read truststore aliases"); + throw new TruststoreDataOperationException(e); + } + } + + private List<String> getFilteredAlias(List<String> aliases) throws KeyStoreException { + List<String> filteredAlias = new ArrayList<>(); + for (String alias : aliases) { + if (keyStore.isCertificateEntry(alias)) { + filteredAlias.add(alias); + } + } + return filteredAlias; + } + +} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/PasswordReader.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/PasswordReader.java index db42f3bd..d7da53b0 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/PasswordReader.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/PasswordReader.java @@ -22,11 +22,12 @@ package org.onap.oom.truststoremerger.certification.file.provider; import java.io.File; import java.io.IOException; import java.nio.file.Files; +import org.onap.oom.truststoremerger.certification.file.exception.PasswordReaderException; public class PasswordReader { private static final String COULD_NOT_READ_PASSWORD_FROM_FILE_MSG_TEMPLATE = "Could not read password from file: %s"; - String readPassword(File file) throws PasswordReaderException { + public String readPassword(File file) throws PasswordReaderException { try { return Files.readString(file.toPath()); } catch (IOException e) { diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/PemCertificateController.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/PemCertificateController.java new file mode 100644 index 00000000..9ff42b87 --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/PemCertificateController.java @@ -0,0 +1,155 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.provider; + +import static org.onap.oom.truststoremerger.api.CertificateConstants.BOUNCY_CASTLE_PROVIDER; +import static org.onap.oom.truststoremerger.api.CertificateConstants.X_509_CERTIFICATE; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.StringWriter; +import java.security.Security; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator; +import org.bouncycastle.util.io.pem.PemObjectGenerator; +import org.bouncycastle.util.io.pem.PemWriter; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAlias; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAliasFactory; +import org.onap.oom.truststoremerger.certification.file.exception.MissingTruststoreException; +import org.onap.oom.truststoremerger.certification.file.exception.TruststoreDataOperationException; +import org.onap.oom.truststoremerger.certification.file.exception.WriteTruststoreFileException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PemCertificateController implements CertificateController { + + private static final Logger LOGGER = LoggerFactory.getLogger(PemCertificateController.class); + + private static final boolean APPEND_TO_FILE = true; + + private final CertificateWithAliasFactory factory = new CertificateWithAliasFactory(); + private final List<CertificateWithAlias> certificatesToBeSaved = new ArrayList<>(); + private final File file; + + public PemCertificateController(File file) { + this.file = file; + } + + public List<CertificateWithAlias> getNotEmptyCertificateList() + throws TruststoreDataOperationException, MissingTruststoreException { + if (isFileWithoutPemCertificate()) { + throw new MissingTruststoreException("File does not contain any certificate"); + } + List<Certificate> extractedCertificate = extractCertificatesFromFile(); + return wrapCertificates(extractedCertificate); + } + + public void addCertificates(List<CertificateWithAlias> certificates) + throws TruststoreDataOperationException, MissingTruststoreException { + if (isFileWithoutPemCertificate()) { + LOGGER.error("File does not contain any certificate. File path: {} ", this.file.getPath()); + throw new MissingTruststoreException("File does not contain any certificate"); + } + certificatesToBeSaved.addAll(certificates); + } + + public void saveFile() throws WriteTruststoreFileException, TruststoreDataOperationException { + List<Certificate> certificates = certificatesToBeSaved.stream() + .map(CertificateWithAlias::getCertificate) + .collect(Collectors.toList()); + String certificatesAsString = transformToStringInPemFormat(certificates); + appendToFile(certificatesAsString); + } + + boolean isFileWithoutPemCertificate() throws TruststoreDataOperationException { + List<Certificate> certificateList = extractCertificatesFromFile(); + return certificateList.isEmpty(); + } + + String transformToStringInPemFormat(List<Certificate> certificates) throws TruststoreDataOperationException { + StringWriter sw = new StringWriter(); + List<PemObjectGenerator> generators = transformToPemGenerators(certificates); + try (PemWriter pemWriter = new PemWriter(sw)) { + for (PemObjectGenerator generator : generators) { + pemWriter.writeObject(generator); + } + } catch (IOException e) { + LOGGER.error("Cannot convert certificates to PEM format"); + throw new TruststoreDataOperationException(e); + } + return sw.toString(); + } + + + private List<Certificate> extractCertificatesFromFile() throws TruststoreDataOperationException { + try (FileInputStream inputStream = new FileInputStream(this.file)) { + Security.addProvider(new BouncyCastleProvider()); + CertificateFactory factory = CertificateFactory.getInstance(X_509_CERTIFICATE, BOUNCY_CASTLE_PROVIDER); + return new ArrayList<>(factory.generateCertificates(inputStream)); + } catch (Exception e) { + LOGGER.error("Cannot read certificates from file: {}", this.file.getPath()); + throw new TruststoreDataOperationException(e); + } + } + + + private List<PemObjectGenerator> transformToPemGenerators(List<Certificate> certificates) + throws TruststoreDataOperationException { + List<PemObjectGenerator> generators = new ArrayList<>(); + for (Certificate certificate : certificates) { + PemObjectGenerator generator = createPemGenerator(certificate); + generators.add(generator); + } + return generators; + } + + private JcaMiscPEMGenerator createPemGenerator(Certificate certificate) + throws TruststoreDataOperationException { + try { + return new JcaMiscPEMGenerator(certificate); + } catch (IOException e) { + LOGGER.error("Cannot convert Certificate Object to PemGenerator Object"); + throw new TruststoreDataOperationException(e); + } + } + + private List<CertificateWithAlias> wrapCertificates(List<Certificate> rawCertificates) { + return rawCertificates.stream() + .map(factory::createPemCertificate) + .collect(Collectors.toList()); + } + + private void appendToFile(String certificatesAsString) throws WriteTruststoreFileException { + try { + FileOutputStream fileOutputStream = new FileOutputStream(this.file, APPEND_TO_FILE); + fileOutputStream.write(certificatesAsString.getBytes()); + } catch (Exception e) { + LOGGER.error("Cannot write certificates to file"); + throw new WriteTruststoreFileException(e); + } + } +} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFileFactory.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFileFactory.java deleted file mode 100644 index e63e7c33..00000000 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFileFactory.java +++ /dev/null @@ -1,84 +0,0 @@ -/*============LICENSE_START======================================================= - * oom-truststore-merger - * ================================================================================ - * Copyright (C) 2020 Nokia. All rights reserved. - * ================================================================================ - * Licensed 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. - * ============LICENSE_END========================================================= - */ - -package org.onap.oom.truststoremerger.certification.file.provider; - -import org.onap.oom.truststoremerger.certification.file.JksTruststore; -import org.onap.oom.truststoremerger.certification.file.P12Truststore; -import org.onap.oom.truststoremerger.certification.file.PemTruststore; -import org.onap.oom.truststoremerger.certification.file.TruststoreFile; - -import java.io.File; - -public class TruststoreFileFactory { - - private static final String JKS_EXTENSION = ".jks"; - private static final String P12_EXTENSION = ".p12"; - private static final String PEM_EXTENSION = ".pem"; - private static final String FILE_DOES_NOT_EXIST_MSG_TEMPLATE = "File: %s does not exist"; - private static final String UNKNOWN_TRUSTSTORE_TYPE_MSG_TEMPLATE = "Unknown truststore extension type: %s"; - - private final FileManager fileManager; - private final PasswordReader passwordReader; - - public TruststoreFileFactory(FileManager fileManager, PasswordReader passwordReader) { - this.fileManager = fileManager; - this.passwordReader = passwordReader; - } - - TruststoreFile create(String truststoreFilePath, String truststorePasswordPath) - throws TruststoreFileFactoryException, PasswordReaderException { - File truststoreFile = new File(truststoreFilePath); - if (!fileManager.checkIfFileExists(truststoreFile)) { - throw new TruststoreFileFactoryException(String.format(FILE_DOES_NOT_EXIST_MSG_TEMPLATE, truststoreFile)); - } - return createTypedTruststore(truststoreFile, truststorePasswordPath); - } - - private TruststoreFile createTypedTruststore(File truststoreFile, String truststorePasswordPath) - throws PasswordReaderException, TruststoreFileFactoryException { - String extension = fileManager.getExtension(truststoreFile); - switch (extension) { - case JKS_EXTENSION: - return createJksTruststore(truststoreFile, truststorePasswordPath); - case P12_EXTENSION: - return createP12Truststore(truststoreFile, truststorePasswordPath); - case PEM_EXTENSION: - return createPemTruststore(truststoreFile); - default: - throw new TruststoreFileFactoryException(String.format(UNKNOWN_TRUSTSTORE_TYPE_MSG_TEMPLATE, extension)); - } - } - - private JksTruststore createJksTruststore(File truststoreFile, String truststorePasswordPath) - throws PasswordReaderException { - String password = passwordReader.readPassword(new File(truststorePasswordPath)); - return new JksTruststore(truststoreFile, password); - } - - private P12Truststore createP12Truststore(File truststoreFile, String truststorePasswordPath) - throws PasswordReaderException { - String password = passwordReader.readPassword(new File(truststorePasswordPath)); - return new P12Truststore(truststoreFile, password); - } - - private PemTruststore createPemTruststore(File truststoreFile) { - return new PemTruststore(truststoreFile); - } -} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/P12Truststore.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/entry/CertificateWithAlias.java index 8527cce5..decc3977 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/P12Truststore.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/entry/CertificateWithAlias.java @@ -17,22 +17,25 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.truststoremerger.certification.file; +package org.onap.oom.truststoremerger.certification.file.provider.entry; -import java.io.File; import java.security.cert.Certificate; -import java.util.Collections; -import java.util.List; -public class P12Truststore extends TruststoreFileWithPassword { +public class CertificateWithAlias { - public P12Truststore(File truststoreFile, String password) { - super(truststoreFile, password); + private final Certificate certificate; + private final String alias; + + public CertificateWithAlias(Certificate certificate, String alias) { + this.certificate = certificate; + this.alias = alias; } - @Override - public List<Certificate> getCertificates() { - return Collections.emptyList(); + public String getAlias() { + return this.alias; } + public Certificate getCertificate() { + return this.certificate; + } } diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/JksTruststore.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/entry/CertificateWithAliasFactory.java index b977daee..0889650e 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/JksTruststore.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/entry/CertificateWithAliasFactory.java @@ -17,21 +17,17 @@ * ============LICENSE_END========================================================= */ -package org.onap.oom.truststoremerger.certification.file; +package org.onap.oom.truststoremerger.certification.file.provider.entry; -import java.io.File; import java.security.cert.Certificate; -import java.util.Collections; -import java.util.List; -public class JksTruststore extends TruststoreFileWithPassword { +public class CertificateWithAliasFactory { - public JksTruststore(File truststoreFile, String password) { - super(truststoreFile, password); + public CertificateWithAlias createCertificateWithAlias(Certificate certificate, String alias) { + return new CertificateWithAlias(certificate, alias); } - @Override - public List<Certificate> getCertificates() { - return Collections.emptyList(); + public CertificateWithAlias createPemCertificate(Certificate certificate) { + return new CertificateWithAlias(certificate, PemAliasGenerator.getInstance().getAlias()); } } diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/entry/PemAliasGenerator.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/entry/PemAliasGenerator.java new file mode 100644 index 00000000..56faa1f6 --- /dev/null +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/provider/entry/PemAliasGenerator.java @@ -0,0 +1,42 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.provider.entry; + + +import java.util.concurrent.atomic.AtomicInteger; + +public class PemAliasGenerator { + + private static final String PREFIX_ALIAS_NAME = "pem-trusted-certificate-"; + private static final PemAliasGenerator INSTANCE = new PemAliasGenerator(); + private static AtomicInteger counter = new AtomicInteger(0); + + private PemAliasGenerator() { + } + + public static PemAliasGenerator getInstance() { + return INSTANCE; + } + + public String getAlias() { + + return PREFIX_ALIAS_NAME + counter.getAndIncrement(); + } +} diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/path/EnvProvider.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/path/EnvProvider.java index 4bb763da..a1998b86 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/path/EnvProvider.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/path/EnvProvider.java @@ -21,9 +21,16 @@ package org.onap.oom.truststoremerger.certification.path; import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class EnvProvider { + private static final Logger LOGGER = LoggerFactory.getLogger(EnvProvider.class); + Optional<String> getEnv(String name) { + String value = System.getenv(name); + LOGGER.info("Read variable: {} , value: {}", name, value); return Optional.ofNullable(System.getenv(name)); } } diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/path/TruststoresPathsProvider.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/path/TruststoresPathsProvider.java index f8e85d49..9d86a8b9 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/path/TruststoresPathsProvider.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/path/TruststoresPathsProvider.java @@ -19,8 +19,8 @@ package org.onap.oom.truststoremerger.certification.path; -import static org.onap.oom.truststoremerger.api.ConfigurationEnvs.TRUSTSTORES_ENV; -import static org.onap.oom.truststoremerger.api.ConfigurationEnvs.TRUSTSTORES_PASSWORDS_ENV; +import static org.onap.oom.truststoremerger.api.ConfigurationEnvs.TRUSTSTORES_PATHS_ENV; +import static org.onap.oom.truststoremerger.api.ConfigurationEnvs.TRUSTSTORES_PASSWORDS_PATHS_ENV; import java.util.Arrays; import java.util.List; @@ -31,8 +31,8 @@ public class TruststoresPathsProvider { private static final String DELIMITER = ":"; private static final int NEGATIVE_SPLIT_LIMIT = -1; - private EnvProvider envProvider; - private PathValidator pathValidator; + private final EnvProvider envProvider; + private final PathValidator pathValidator; public TruststoresPathsProvider(EnvProvider envProvider, PathValidator pathValidator) { this.envProvider = envProvider; @@ -40,20 +40,20 @@ public class TruststoresPathsProvider { } public List<String> getTruststores() throws TruststoresPathsProviderException { - return envProvider.getEnv(TRUSTSTORES_ENV) + return envProvider.getEnv(TRUSTSTORES_PATHS_ENV) .filter(Predicate.not(String::isEmpty)) .map(this::splitToList) .filter(this::validateTruststores) .orElseThrow(() -> new TruststoresPathsProviderException( - TRUSTSTORES_ENV + " environment variable does not contain valid truststores paths")); + TRUSTSTORES_PATHS_ENV + " environment variable does not contain valid truststores paths")); } public List<String> getTruststoresPasswords() throws TruststoresPathsProviderException { - return envProvider.getEnv(TRUSTSTORES_PASSWORDS_ENV) + return envProvider.getEnv(TRUSTSTORES_PASSWORDS_PATHS_ENV) .map(this::splitToList) .filter(this::validateTruststoresPasswords) .orElseThrow(() -> new TruststoresPathsProviderException( - TRUSTSTORES_PASSWORDS_ENV + " environment variable does not contain valid passwords paths")); + TRUSTSTORES_PASSWORDS_PATHS_ENV + " environment variable does not contain valid passwords paths")); } private boolean validateTruststores(List<String> truststores) { diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/configuration/MergerConfigurationFactory.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/configuration/MergerConfigurationFactory.java index 7a2fdc10..acd9a840 100644 --- a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/configuration/MergerConfigurationFactory.java +++ b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/configuration/MergerConfigurationFactory.java @@ -22,8 +22,8 @@ package org.onap.oom.truststoremerger.configuration; import org.onap.oom.truststoremerger.certification.path.TruststoresPathsProvider; import org.onap.oom.truststoremerger.certification.path.TruststoresPathsProviderException; -import static org.onap.oom.truststoremerger.api.ConfigurationEnvs.TRUSTSTORES_ENV; -import static org.onap.oom.truststoremerger.api.ConfigurationEnvs.TRUSTSTORES_PASSWORDS_ENV; +import static org.onap.oom.truststoremerger.api.ConfigurationEnvs.TRUSTSTORES_PATHS_ENV; +import static org.onap.oom.truststoremerger.api.ConfigurationEnvs.TRUSTSTORES_PASSWORDS_PATHS_ENV; import java.util.List; @@ -42,8 +42,8 @@ public class MergerConfigurationFactory { if (truststores.size() != truststoresPasswords.size()) { throw new MergerConfigurationException( - "Size of " + TRUSTSTORES_ENV - + " does not match size of " + TRUSTSTORES_PASSWORDS_ENV + " environment variables"); + "Size of " + TRUSTSTORES_PATHS_ENV + + " does not match size of " + TRUSTSTORES_PASSWORDS_PATHS_ENV + " environment variables"); } return new MergerConfiguration(truststores, truststoresPasswords); diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/TestCertificateProvider.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/TestCertificateProvider.java new file mode 100644 index 00000000..c971ca17 --- /dev/null +++ b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/TestCertificateProvider.java @@ -0,0 +1,157 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import org.onap.oom.truststoremerger.certification.file.exception.KeystoreInstanceException; +import org.onap.oom.truststoremerger.certification.file.exception.LoadTruststoreException; +import org.onap.oom.truststoremerger.certification.file.model.JavaTruststore; +import org.onap.oom.truststoremerger.certification.file.model.PemTruststore; +import org.onap.oom.truststoremerger.certification.file.provider.JavaCertificateStoreController; +import org.onap.oom.truststoremerger.certification.file.provider.CertificateStoreControllerFactory; +import org.onap.oom.truststoremerger.certification.file.provider.PemCertificateController; + +public class TestCertificateProvider { + + public static final String SAMPLE_P12_TRUSTSTORE_FILE_PATH = "src/test/resources/truststore-p12.p12"; + public static final String SAMPLE_P12_TRUSTSTORE_PASSWORD = "88y9v5D8H3SG6bZWRVHDfOAo"; + public static final String TMP_P12_TRUSTSTORE_FILE_PATH = "src/test/resources/tmp-truststore-p12.p12"; + + public static final String SAMPLE_P12_KEYSTORE_FILE_PATH = "src/test/resources/keystore.p12"; + public static final String SAMPLE_P12_KEYSTORE_PASSWORD = "Foh49MJNYI7S_pEzE9gvUDSu"; + + public static final String SAMPLE_JKS_TRUSTSTORE_FILE_PATH = "src/test/resources/truststore-jks.jks"; + public static final String SAMPLE_JKS_TRUSTSTORE_UNIQUE_ALIAS_FILE_PATH = "src/test/resources/truststore-jks-uniq.jks"; + public static final String SAMPLE_JKS_TRUSTSTORE_PASSWORD = "EOyuFbuYDyq_EhpboM72RHua"; + public static final String TMP_JKS_TRUSTSTORE_FILE_PATH = "src/test/resources/tmp-truststore-jks.jks"; + + public static final String SAMPLE_PEM_TRUSTSTORE_FILE_PATH = "src/test/resources/truststore.pem"; + public static final String EMPTY_PEM_TRUSTSTORE_FILE_PATH = "src/test/resources/empty-truststore.pem"; + public static final String TMP_PEM_TRUSTSTORE_FILE_PATH = "src/test/resources/tmp-truststore.pem"; + public static final String SAMPLE_PEM_TRUSTSTORE_WITH_PRIVATE_KEY_FILE_PATH = "src/test/resources/truststore-with-private-key.pem"; + + private static final CertificateStoreControllerFactory certificateStoreControllerFactory = new CertificateStoreControllerFactory(); + + public static JavaTruststore getSampleP12Truststore() throws LoadTruststoreException, KeystoreInstanceException { + return createP12TruststoreInstance(SAMPLE_P12_TRUSTSTORE_FILE_PATH, SAMPLE_P12_TRUSTSTORE_PASSWORD); + } + + public static JavaTruststore getSampleP12Keystore() throws LoadTruststoreException, KeystoreInstanceException { + return createP12TruststoreInstance(SAMPLE_P12_KEYSTORE_FILE_PATH, SAMPLE_P12_KEYSTORE_PASSWORD); + } + + public static JavaTruststore createTmpP12TruststoreFile() + throws IOException, LoadTruststoreException, KeystoreInstanceException { + copyFile(SAMPLE_P12_TRUSTSTORE_FILE_PATH, TMP_P12_TRUSTSTORE_FILE_PATH); + return createP12TruststoreInstance(TMP_P12_TRUSTSTORE_FILE_PATH, SAMPLE_P12_TRUSTSTORE_PASSWORD); + } + + public static JavaTruststore getTmpP12TruststoreFile() throws LoadTruststoreException, KeystoreInstanceException { + return createP12TruststoreInstance(TMP_P12_TRUSTSTORE_FILE_PATH, SAMPLE_P12_TRUSTSTORE_PASSWORD); + } + + private static JavaTruststore createP12TruststoreInstance(String filePath, String password) + throws LoadTruststoreException, KeystoreInstanceException { + File certFile = getFile(filePath); + JavaCertificateStoreController storeController = certificateStoreControllerFactory + .createLoadedPkcs12CertificateStoreController(certFile, password); + return new JavaTruststore(certFile, storeController); + } + + public static PemTruststore getSamplePemTruststoreFile() { + return getPemTruststoreInstance(SAMPLE_PEM_TRUSTSTORE_FILE_PATH); + } + + public static PemTruststore getEmptyPemTruststoreFile() { + return getPemTruststoreInstance(EMPTY_PEM_TRUSTSTORE_FILE_PATH); + } + + public static PemTruststore createEmptyTmpPemTruststoreFile() throws IOException { + copyFile(EMPTY_PEM_TRUSTSTORE_FILE_PATH, TMP_PEM_TRUSTSTORE_FILE_PATH); + return getPemTruststoreInstance(TMP_PEM_TRUSTSTORE_FILE_PATH); + } + + public static PemTruststore createTmpPemTruststoreFile() throws IOException { + copyFile(SAMPLE_PEM_TRUSTSTORE_FILE_PATH, TMP_PEM_TRUSTSTORE_FILE_PATH); + return getPemTruststoreInstance(TMP_PEM_TRUSTSTORE_FILE_PATH); + } + + public static PemTruststore getTmpPemTruststoreFile() { + return getPemTruststoreInstance(TMP_PEM_TRUSTSTORE_FILE_PATH); + } + + public static PemTruststore getPemWithPrivateKeyTruststoreFile() { + return getPemTruststoreInstance(SAMPLE_PEM_TRUSTSTORE_WITH_PRIVATE_KEY_FILE_PATH); + } + + public static String getExpectedPemCertificateAsString() throws IOException { + Path samplePemFilePath = Paths.get(SAMPLE_PEM_TRUSTSTORE_FILE_PATH); + return Files.readString(samplePemFilePath); + } + + public static JavaTruststore getSampleJksTruststoreFile() + throws LoadTruststoreException, KeystoreInstanceException { + return createJKSTruststoreInstance(SAMPLE_JKS_TRUSTSTORE_FILE_PATH, SAMPLE_JKS_TRUSTSTORE_PASSWORD); + } + + public static JavaTruststore getSampleJksTruststoreFileWithUniqueAlias() + throws LoadTruststoreException, KeystoreInstanceException { + return createJKSTruststoreInstance(SAMPLE_JKS_TRUSTSTORE_UNIQUE_ALIAS_FILE_PATH, + SAMPLE_JKS_TRUSTSTORE_PASSWORD); + } + + public static JavaTruststore createTmpJksTruststoreFileWithUniqAlias() + throws IOException, LoadTruststoreException, KeystoreInstanceException { + copyFile(SAMPLE_JKS_TRUSTSTORE_UNIQUE_ALIAS_FILE_PATH, TMP_JKS_TRUSTSTORE_FILE_PATH); + return createJKSTruststoreInstance(TMP_JKS_TRUSTSTORE_FILE_PATH, SAMPLE_JKS_TRUSTSTORE_PASSWORD); + } + + public static void removeTemporaryFiles() throws IOException { + Files.deleteIfExists(Paths.get(TMP_PEM_TRUSTSTORE_FILE_PATH)); + Files.deleteIfExists(Paths.get(TMP_JKS_TRUSTSTORE_FILE_PATH)); + Files.deleteIfExists(Paths.get(TMP_P12_TRUSTSTORE_FILE_PATH)); + } + + private static JavaTruststore createJKSTruststoreInstance(String filePath, String password) + throws LoadTruststoreException, KeystoreInstanceException { + File certFile = getFile(filePath); + JavaCertificateStoreController storeController = certificateStoreControllerFactory + .createLoadedJksCertificateStoreController(certFile, password); + return new JavaTruststore(certFile, storeController); + } + + private static PemTruststore getPemTruststoreInstance(String tmpPemTruststoreFilePath) { + File file = getFile(tmpPemTruststoreFilePath); + return new PemTruststore(file, new PemCertificateController(file)); + } + + private static void copyFile(String sourcePath, String destPath) throws IOException { + Files.copy(Paths.get(sourcePath), Paths.get(destPath), StandardCopyOption.REPLACE_EXISTING); + } + + private static File getFile(String path) { + return new File(path); + } +} diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/model/JavaTruststoreTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/model/JavaTruststoreTest.java new file mode 100644 index 00000000..eccf36bc --- /dev/null +++ b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/model/JavaTruststoreTest.java @@ -0,0 +1,116 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.model; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.onap.oom.truststoremerger.api.CertificateConstants.X_509_CERTIFICATE; + +import java.io.IOException; +import java.security.cert.Certificate; +import java.util.List; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; +import org.onap.oom.truststoremerger.api.ExitableException; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAlias; +import org.onap.oom.truststoremerger.certification.file.TestCertificateProvider; + + +class JavaTruststoreTest { + public static final int FIRST_ELEMENT = 0; + private static final int EXPECTED_ONE = 1; + public static final int EXPECTED_THREE = 3; + + @Test + void jksTruststoreShouldReadCertificatesFromFile() throws ExitableException { + + //given + JavaTruststore jksTruststoreFile = TestCertificateProvider.getSampleJksTruststoreFile(); + + //when + List<CertificateWithAlias> certificates = jksTruststoreFile.getCertificates(); + Certificate certificate = certificates.get(FIRST_ELEMENT).getCertificate(); + + //then + assertThat(certificates).hasSize(EXPECTED_ONE); + assertThat(certificate.getType()).isEqualTo(X_509_CERTIFICATE); + } + + @Test + void jksTruststoreShouldAddDifferentCertificates() throws Exception { + + //given + JavaTruststore jksTruststore = TestCertificateProvider.createTmpJksTruststoreFileWithUniqAlias(); + List<CertificateWithAlias> p12certificates = TestCertificateProvider.getSampleP12Truststore() + .getCertificates(); + List<CertificateWithAlias> pemCertificates = TestCertificateProvider.getSamplePemTruststoreFile() + .getCertificates(); + + //when + jksTruststore.addCertificate(p12certificates); + jksTruststore.addCertificate(pemCertificates); + + //then + assertThat(jksTruststore.getCertificates()).hasSize(EXPECTED_THREE); + + } + + @Test + void p12TruststoreShouldReadCertificatesFromFile() throws ExitableException { + //given + JavaTruststore p12Truststore = TestCertificateProvider.getSampleP12Truststore(); + + //when + List<CertificateWithAlias> certificatesWithAliases = p12Truststore.getCertificates(); + Certificate certificate = certificatesWithAliases.get(FIRST_ELEMENT).getCertificate(); + + //then + assertThat(certificatesWithAliases).hasSize(EXPECTED_ONE); + assertThat(certificate.getType()).isEqualTo(X_509_CERTIFICATE); + } + + + @Test + void p12TruststoreShouldAddDifferentCertificates() throws Exception { + //given + JavaTruststore p12Truststore = TestCertificateProvider.createTmpP12TruststoreFile(); + List<CertificateWithAlias> jksTruststoreCertificates = TestCertificateProvider + .getSampleJksTruststoreFileWithUniqueAlias() + .getCertificates(); + List<CertificateWithAlias> pemTruststoreCertificates = TestCertificateProvider.getSamplePemTruststoreFile() + .getCertificates(); + + //when + p12Truststore.addCertificate(jksTruststoreCertificates); + p12Truststore.addCertificate(pemTruststoreCertificates); + p12Truststore.saveFile(); + + + //then + JavaTruststore p12TruststoreSaved = TestCertificateProvider.getTmpP12TruststoreFile(); + assertThat(p12TruststoreSaved.getCertificates()).hasSize(EXPECTED_THREE); + } + + + + @AfterAll + static void removeTemporaryFiles() throws IOException { + TestCertificateProvider.removeTemporaryFiles(); + } +} diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/model/PemTruststoreTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/model/PemTruststoreTest.java new file mode 100644 index 00000000..e7ffa093 --- /dev/null +++ b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/model/PemTruststoreTest.java @@ -0,0 +1,149 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.model; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.onap.oom.truststoremerger.api.CertificateConstants.X_509_CERTIFICATE; + +import java.io.IOException; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; +import org.onap.oom.truststoremerger.api.ExitableException; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAlias; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAliasFactory; +import org.onap.oom.truststoremerger.certification.file.TestCertificateProvider; +import org.onap.oom.truststoremerger.certification.file.exception.MissingTruststoreException; +import org.onap.oom.truststoremerger.certification.file.exception.TruststoreDataOperationException; +import org.onap.oom.truststoremerger.certification.file.exception.WriteTruststoreFileException; + +class PemTruststoreTest { + + public static final int EXPECTED_ONE = 1; + public static final int EXPECTED_THREE = 3; + public static final int FIRST_ELEMENT = 0; + + private final CertificateWithAliasFactory factory = new CertificateWithAliasFactory(); + + @Test + void pemTruststoreShouldReadCertificatesFromFile() throws ExitableException { + + //given + PemTruststore pemTruststore = TestCertificateProvider.getSamplePemTruststoreFile(); + + //when + List<CertificateWithAlias> certificates = pemTruststore.getCertificates(); + Certificate certificate = certificates.get(FIRST_ELEMENT).getCertificate(); + //then + + assertThat(certificates).hasSize(EXPECTED_ONE); + assertThat(certificate.getType()).isEqualTo(X_509_CERTIFICATE); + } + + @Test + void pemTruststoreShouldAddDifferentCertificates() throws IOException, ExitableException { + + //given + PemTruststore tmpPemTruststoreFile = TestCertificateProvider.createTmpPemTruststoreFile(); + List<CertificateWithAlias> jksTruststoreCertificates = TestCertificateProvider + .getSampleJksTruststoreFileWithUniqueAlias().getCertificates(); + List<CertificateWithAlias> p12TruststoreCertificates = TestCertificateProvider.getSampleP12Truststore() + .getCertificates(); + + //when + tmpPemTruststoreFile.addCertificate(jksTruststoreCertificates); + tmpPemTruststoreFile.addCertificate(p12TruststoreCertificates); + tmpPemTruststoreFile.saveFile(); + + PemTruststore tmpPemTruststoreSaved = TestCertificateProvider.getTmpPemTruststoreFile(); + List<CertificateWithAlias> addedCertificates = tmpPemTruststoreSaved.getCertificates(); + Certificate certificate = addedCertificates.get(FIRST_ELEMENT).getCertificate(); + + //then + assertThat(addedCertificates).hasSize(EXPECTED_THREE); + assertThat(certificate.getType()).isEqualTo(X_509_CERTIFICATE); + + } + + @Test + void privateKeyIsSkippedWhileReadingCertificates() throws ExitableException { + //given + PemTruststore pemTruststore = TestCertificateProvider.getPemWithPrivateKeyTruststoreFile(); + + //when + List<CertificateWithAlias> certificate = pemTruststore.getCertificates(); + //then + + assertThat(certificate).hasSize(EXPECTED_ONE); + } + + @Test + void shouldThrowExceptionWhenCannotSaveFile() throws IOException, ExitableException { + //given + PemTruststore tmpPemTruststoreFile = TestCertificateProvider.createTmpPemTruststoreFile(); + List<CertificateWithAlias> pemTruststoreCertificates = + TestCertificateProvider.getSamplePemTruststoreFile().getCertificates(); + //when + tmpPemTruststoreFile.addCertificate(pemTruststoreCertificates); + tmpPemTruststoreFile.getFile().setWritable(false); + //then + assertThatExceptionOfType(WriteTruststoreFileException.class) + .isThrownBy(tmpPemTruststoreFile::saveFile); + + } + + @Test + void shouldThrowExceptionWhenFileNotContainsCertificate() throws IOException { + //given + PemTruststore tmpPemTruststoreFile = TestCertificateProvider.createEmptyTmpPemTruststoreFile(); + //when//then + assertThatExceptionOfType(MissingTruststoreException.class) + .isThrownBy(tmpPemTruststoreFile::getCertificates); + } + + @Test + void shouldThrowExceptionWhenCannotConvertCertificateToPem() throws Exception { + //given + PemTruststore pemTruststore = TestCertificateProvider.createTmpPemTruststoreFile(); + Certificate certificate = mock(Certificate.class); + + when(certificate.getEncoded()).thenThrow(new CertificateEncodingException()); + + List<CertificateWithAlias> certificatesWithAliases = new ArrayList<>(); + certificatesWithAliases.add(factory.createPemCertificate(certificate)); + pemTruststore.addCertificate(certificatesWithAliases); + + //when //then + assertThatExceptionOfType(TruststoreDataOperationException.class) + .isThrownBy(pemTruststore::saveFile); + } + + @AfterAll + static void removeTemporaryFiles() throws IOException { + TestCertificateProvider.removeTemporaryFiles(); + } + +} diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/model/TruststoreTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/model/TruststoreTest.java new file mode 100644 index 00000000..eea1f9c7 --- /dev/null +++ b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/model/TruststoreTest.java @@ -0,0 +1,60 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.model; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; +import org.onap.oom.truststoremerger.certification.file.exception.CreateBackupException; +import org.onap.oom.truststoremerger.certification.file.provider.PemCertificateController; + +import static org.assertj.core.api.Assertions.assertThat; + +class TruststoreTest { + + private static final String PEM_FILE_PATH = "src/test/resources/truststore.pem"; + private static final String PEM_BACKUP_FILE_PATH = "src/test/resources/truststore.pem.bak"; + private static final String BACKUP_EXTENSION = ".bak"; + + + @Test + void createBackupShouldCreateFileWithExtension() throws CreateBackupException { + //given + File pemFile = new File(PEM_FILE_PATH); + Truststore truststore = new PemTruststore(pemFile, new PemCertificateController(pemFile)); + //when + truststore.createBackup(); + + //then + File backupFile = new File(PEM_BACKUP_FILE_PATH); + assertThat(backupFile.getName().endsWith(BACKUP_EXTENSION)).isTrue(); + assertThat(backupFile.isFile()).isTrue(); + } + + + @AfterAll + static void removeBackupFile() throws IOException { + Files.deleteIfExists(Paths.get(PEM_BACKUP_FILE_PATH)); + } + +} diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/FileManagerTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/FileManagerTest.java index d348dd7e..c649ba68 100644 --- a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/FileManagerTest.java +++ b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/FileManagerTest.java @@ -33,12 +33,13 @@ class FileManagerTest { @ParameterizedTest @CsvSource(value = { - "opt/app/truststore.jks:.jks", - "opt/app/truststore.p12:.p12", - "opt/app/truststore.pem:.pem", - "opt/app/truststore:''", + "opt/app/truststore.jks:.jks", + "opt/app/truststore.p12:.p12", + "opt/app/truststore.pem:.pem", + "opt/app/truststore.PEM:.pem", + "opt/app/truststore:''", }, delimiter = ':') - void shouldReturnCorrectExtension(String filePath, String expectedExtension){ + void shouldReturnCorrectExtension(String filePath, String expectedExtension) { String extension = fileManager.getExtension(new File(filePath)); assertThat(extension).isEqualTo(expectedExtension); } diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/JavaCertificateStoreControllerTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/JavaCertificateStoreControllerTest.java new file mode 100644 index 00000000..8ee77ef2 --- /dev/null +++ b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/JavaCertificateStoreControllerTest.java @@ -0,0 +1,59 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.provider; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.onap.oom.truststoremerger.certification.file.TestCertificateProvider.getSampleJksTruststoreFile; + +import java.util.List; +import org.junit.jupiter.api.Test; +import org.onap.oom.truststoremerger.api.ExitableException; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAlias; +import org.onap.oom.truststoremerger.certification.file.TestCertificateProvider; +import org.onap.oom.truststoremerger.certification.file.exception.AliasConflictException; +import org.onap.oom.truststoremerger.certification.file.exception.MissingTruststoreException; +import org.onap.oom.truststoremerger.certification.file.model.JavaTruststore; + +class JavaCertificateStoreControllerTest { + + + @Test + void throwExceptionWhenAliasConflictDetected() throws Exception { + //given + JavaTruststore p12Truststore = TestCertificateProvider.getSampleP12Truststore(); + List<CertificateWithAlias> jksTruststoreCertificates = getSampleJksTruststoreFile().getCertificates(); + + //when //then + assertThatExceptionOfType(AliasConflictException.class) + .isThrownBy(() -> p12Truststore.addCertificate(jksTruststoreCertificates)); + } + + + @Test + void throwExceptionWhenFileNotContainsTruststoreEntry() throws ExitableException { + //given + JavaTruststore p12Truststore = TestCertificateProvider.getSampleP12Keystore(); + + //when//then + assertThatExceptionOfType(MissingTruststoreException.class) + .isThrownBy(p12Truststore::getCertificates); + } + +} diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/PasswordReaderTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/PasswordReaderTest.java index 712935ac..40eda4dd 100644 --- a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/PasswordReaderTest.java +++ b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/PasswordReaderTest.java @@ -22,6 +22,7 @@ package org.onap.oom.truststoremerger.certification.file.provider; import org.junit.jupiter.api.Test; import java.io.File; +import org.onap.oom.truststoremerger.certification.file.exception.PasswordReaderException; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/PemCertificateControllerTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/PemCertificateControllerTest.java new file mode 100644 index 00000000..080fcca3 --- /dev/null +++ b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/PemCertificateControllerTest.java @@ -0,0 +1,95 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.provider; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import java.io.File; +import java.io.IOException; +import java.security.cert.Certificate; +import java.util.List; +import java.util.stream.Collectors; +import org.junit.jupiter.api.Test; +import org.onap.oom.truststoremerger.api.ExitableException; +import org.onap.oom.truststoremerger.certification.file.provider.entry.CertificateWithAlias; +import org.onap.oom.truststoremerger.certification.file.TestCertificateProvider; +import org.onap.oom.truststoremerger.certification.file.exception.MissingTruststoreException; +import org.onap.oom.truststoremerger.certification.file.exception.TruststoreDataOperationException; +import org.onap.oom.truststoremerger.certification.file.model.PemTruststore; + +class PemCertificateControllerTest { + + @Test + void getNotEmptyCertificateListShouldThrowExceptionWhenFileNotContainsCertificate() { + //given + File emptyPemFile = TestCertificateProvider.getEmptyPemTruststoreFile().getFile(); + PemCertificateController pemCertificateController = new PemCertificateController(emptyPemFile); + //when//then + assertThatExceptionOfType(MissingTruststoreException.class) + .isThrownBy(pemCertificateController::getNotEmptyCertificateList); + } + + @Test + void transformToStringInPemFormatShouldCorrectlyTransform() throws ExitableException, IOException { + //given + PemTruststore pemTruststore = TestCertificateProvider.getSamplePemTruststoreFile(); + List<CertificateWithAlias> wrappedCertificates = pemTruststore.getCertificates(); + File notEmptyPemFile = pemTruststore.getFile(); + List<Certificate> certificateList = unWrapCertificate(wrappedCertificates); + PemCertificateController pemCertificateController = new PemCertificateController(notEmptyPemFile); + String expected = TestCertificateProvider.getExpectedPemCertificateAsString(); + + //when + String certificateTransformed = pemCertificateController.transformToStringInPemFormat(certificateList); + + //then + assertThat(certificateTransformed).isEqualTo(expected); + } + + @Test + void fileNotContainsPemCertificateShouldReturnTrueIfFileNotContainsCertificate() + throws TruststoreDataOperationException { + //given + File emptyPemFile = TestCertificateProvider.getEmptyPemTruststoreFile().getFile(); + PemCertificateController pemCertificateController = new PemCertificateController(emptyPemFile); + //when//then + assertThat(pemCertificateController.isFileWithoutPemCertificate()).isTrue(); + } + + @Test + void fileNotContainsPemCertificateShouldReturnFalseIfFileContainsCertificate() + throws TruststoreDataOperationException { + //given + File notEmptyPemFile = TestCertificateProvider.getSamplePemTruststoreFile().getFile(); + PemCertificateController pemCertificateController = new PemCertificateController(notEmptyPemFile); + + //when//then + assertThat(pemCertificateController.isFileWithoutPemCertificate()).isFalse(); + } + + private List<Certificate> unWrapCertificate(List<CertificateWithAlias> certificateWithAliases) { + return certificateWithAliases + .stream() + .map(CertificateWithAlias::getCertificate) + .collect(Collectors.toList()); + } + +} diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFileFactoryTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFactoryTest.java index f00b2bc4..b2063cc3 100644 --- a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFileFactoryTest.java +++ b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFactoryTest.java @@ -24,25 +24,27 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; -import org.onap.oom.truststoremerger.certification.file.JksTruststore; -import org.onap.oom.truststoremerger.certification.file.P12Truststore; -import org.onap.oom.truststoremerger.certification.file.PemTruststore; -import org.onap.oom.truststoremerger.certification.file.TruststoreFile; +import org.onap.oom.truststoremerger.certification.file.TruststoreFileFactory; +import org.onap.oom.truststoremerger.certification.file.model.JavaTruststore; +import org.onap.oom.truststoremerger.certification.file.model.PemTruststore; +import org.onap.oom.truststoremerger.certification.file.model.Truststore; +import org.onap.oom.truststoremerger.certification.file.exception.KeystoreInstanceException; +import org.onap.oom.truststoremerger.certification.file.exception.LoadTruststoreException; import java.io.File; +import org.onap.oom.truststoremerger.certification.file.exception.PasswordReaderException; +import org.onap.oom.truststoremerger.certification.file.exception.TruststoreFileFactoryException; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @ExtendWith(MockitoExtension.class) -class TruststoreFileFactoryTest { +class TruststoreFactoryTest { private static final String TRUSTSTORE_JKS_PATH = "src/test/resources/truststore-jks.jks"; private static final String TRUSTSTORE_JKS_PASS_PATH = "src/test/resources/truststore-jks.pass"; - private static final String TRUSTSTORE_JKS_PASS = "EOyuFbuYDyq_EhpboM72RHua"; private static final String TRUSTSTORE_P12_PATH = "src/test/resources/truststore-p12.p12"; private static final String TRUSTSTORE_P12_PASS_PATH = "src/test/resources/truststore-p12.pass"; - private static final String TRUSTSTORE_P12_PASS = "88y9v5D8H3SG6bZWRVHDfOAo"; private static final String TRUSTSTORE_PEM_PATH = "src/test/resources/truststore.pem"; private static final String EMPTY_PASS_PATH = ""; private static final String TRUSTSTORE_UNKNOWN_EXTENSION_PATH = "src/test/resources/truststore-jks.unknown"; @@ -56,28 +58,28 @@ class TruststoreFileFactoryTest { } @Test - void shouldReturnCorrectJksTruststoreForJksFile() throws TruststoreFileFactoryException, PasswordReaderException { - TruststoreFile truststore = truststoreFileFactory + void shouldReturnCorrectJksTruststoreForJksFile() + throws LoadTruststoreException, PasswordReaderException, TruststoreFileFactoryException, KeystoreInstanceException { + Truststore truststore = truststoreFileFactory .create(TRUSTSTORE_JKS_PATH, TRUSTSTORE_JKS_PASS_PATH); - assertThat(truststore).isInstanceOf(JksTruststore.class); - JksTruststore jksTruststore = (JksTruststore) truststore; - assertThat(jksTruststore.getPassword()).isEqualTo(TRUSTSTORE_JKS_PASS); - assertThat(jksTruststore.getTruststoreFile()).isEqualTo(new File(TRUSTSTORE_JKS_PATH)); + assertThat(truststore).isInstanceOf(JavaTruststore.class); + JavaTruststore jksTruststore = (JavaTruststore) truststore; + assertThat(jksTruststore.getFile()).isEqualTo(new File(TRUSTSTORE_JKS_PATH)); } @Test - void shouldReturnCorrectP12TruststoreForP12File() throws TruststoreFileFactoryException, PasswordReaderException { - TruststoreFile truststore = truststoreFileFactory + void shouldReturnCorrectP12TruststoreForP12File() + throws LoadTruststoreException, PasswordReaderException, TruststoreFileFactoryException, KeystoreInstanceException { + Truststore truststore = truststoreFileFactory .create(TRUSTSTORE_P12_PATH, TRUSTSTORE_P12_PASS_PATH); - assertThat(truststore).isInstanceOf(P12Truststore.class); - P12Truststore jksTruststore = (P12Truststore) truststore; - assertThat(jksTruststore.getPassword()).isEqualTo(TRUSTSTORE_P12_PASS); + assertThat(truststore).isInstanceOf(JavaTruststore.class); } @Test - void shouldReturnCorrectPemTruststoreForPemFile() throws TruststoreFileFactoryException, PasswordReaderException { - TruststoreFile truststore = truststoreFileFactory + void shouldReturnCorrectPemTruststoreForPemFile() + throws LoadTruststoreException, PasswordReaderException, TruststoreFileFactoryException, KeystoreInstanceException { + Truststore truststore = truststoreFileFactory .create(TRUSTSTORE_PEM_PATH, EMPTY_PASS_PATH); assertThat(truststore).isInstanceOf(PemTruststore.class); diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFilesListProviderTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFilesListProviderTest.java index 034e1b32..0dadcfef 100644 --- a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFilesListProviderTest.java +++ b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/TruststoreFilesListProviderTest.java @@ -22,15 +22,19 @@ package org.onap.oom.truststoremerger.certification.file.provider; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.onap.oom.truststoremerger.certification.file.JksTruststore; -import org.onap.oom.truststoremerger.certification.file.P12Truststore; -import org.onap.oom.truststoremerger.certification.file.PemTruststore; -import org.onap.oom.truststoremerger.certification.file.TruststoreFile; -import org.onap.oom.truststoremerger.certification.file.TruststoreFileWithPassword; +import org.onap.oom.truststoremerger.certification.file.TruststoreFileFactory; +import org.onap.oom.truststoremerger.certification.file.TruststoreFilesListProvider; +import org.onap.oom.truststoremerger.certification.file.model.JavaTruststore; +import org.onap.oom.truststoremerger.certification.file.model.PemTruststore; +import org.onap.oom.truststoremerger.certification.file.model.Truststore; +import org.onap.oom.truststoremerger.certification.file.exception.KeystoreInstanceException; +import org.onap.oom.truststoremerger.certification.file.exception.LoadTruststoreException; import java.io.File; import java.util.Arrays; import java.util.List; +import org.onap.oom.truststoremerger.certification.file.exception.PasswordReaderException; +import org.onap.oom.truststoremerger.certification.file.exception.TruststoreFileFactoryException; import static org.assertj.core.api.Assertions.assertThat; @@ -38,10 +42,8 @@ class TruststoreFilesListProviderTest { private static final String TRUSTSTORE_JKS_PATH = "src/test/resources/truststore-jks.jks"; private static final String TRUSTSTORE_JKS_PASS_PATH = "src/test/resources/truststore-jks.pass"; - private static final String TRUSTSTORE_JKS_PASS = "EOyuFbuYDyq_EhpboM72RHua"; private static final String TRUSTSTORE_P12_PATH = "src/test/resources/truststore-p12.p12"; private static final String TRUSTSTORE_P12_PASS_PATH = "src/test/resources/truststore-p12.pass"; - private static final String TRUSTSTORE_P12_PASS = "88y9v5D8H3SG6bZWRVHDfOAo"; private static final String TRUSTSTORE_PEM_PATH = "src/test/resources/truststore.pem"; private static final String EMPTY_PASS_PATH = ""; @@ -54,37 +56,32 @@ class TruststoreFilesListProviderTest { } @Test - void shouldReturnTruststoreFilesList() throws PasswordReaderException, TruststoreFileFactoryException { + void shouldReturnTruststoreFilesList() + throws TruststoreFileFactoryException, PasswordReaderException, LoadTruststoreException, KeystoreInstanceException { List<String> truststorePaths = Arrays.asList(TRUSTSTORE_JKS_PATH, TRUSTSTORE_P12_PATH, TRUSTSTORE_PEM_PATH); List<String> truststorePasswordPaths = Arrays.asList(TRUSTSTORE_JKS_PASS_PATH, TRUSTSTORE_P12_PASS_PATH, EMPTY_PASS_PATH); - List<TruststoreFile> truststoreFilesList = truststoreFilesListProvider.getTruststoreFilesList(truststorePaths, truststorePasswordPaths); + List<Truststore> truststoreFilesList = truststoreFilesListProvider.getTruststoreFilesList(truststorePaths, truststorePasswordPaths); assertThat(truststoreFilesList.size()).isEqualTo(3); - assertCorrectJksTruststore(truststoreFilesList.get(0), TRUSTSTORE_JKS_PATH, TRUSTSTORE_JKS_PASS); - assertCorrectP12Truststore(truststoreFilesList.get(1), TRUSTSTORE_P12_PATH, TRUSTSTORE_P12_PASS); + assertCorrectJksTruststore(truststoreFilesList.get(0), TRUSTSTORE_JKS_PATH); + assertCorrectP12Truststore(truststoreFilesList.get(1), TRUSTSTORE_P12_PATH); assertCorrectPemTruststore(truststoreFilesList.get(2), TRUSTSTORE_PEM_PATH); } - private void assertCorrectJksTruststore(TruststoreFile truststoreFile, String truststorePath, String truststorePass) { - assertCorrectTypeAndTruststorePath(truststoreFile, truststorePath, JksTruststore.class); - assertContainsCorrectPassword(truststoreFile, truststorePass); + private void assertCorrectJksTruststore(Truststore truststore, String truststorePath) { + assertCorrectTypeAndTruststorePath(truststore, truststorePath, JavaTruststore.class); } - private void assertCorrectP12Truststore(TruststoreFile truststoreFile, String truststorePath, String truststorePass) { - assertCorrectTypeAndTruststorePath(truststoreFile, truststorePath, P12Truststore.class); - assertContainsCorrectPassword(truststoreFile, truststorePass); + private void assertCorrectP12Truststore(Truststore truststore, String truststorePath) { + assertCorrectTypeAndTruststorePath(truststore, truststorePath, JavaTruststore.class); } - private void assertCorrectPemTruststore(TruststoreFile truststoreFile, String truststorePath) { - assertCorrectTypeAndTruststorePath(truststoreFile, truststorePath, PemTruststore.class); + private void assertCorrectPemTruststore(Truststore truststore, String truststorePath) { + assertCorrectTypeAndTruststorePath(truststore, truststorePath, PemTruststore.class); } - private void assertCorrectTypeAndTruststorePath(TruststoreFile truststoreFile, String truststorePath, Class<?> truststoreType) { - assertThat(truststoreFile).isInstanceOf(truststoreType); - assertThat(truststoreFile.getTruststoreFile()).isEqualTo(new File(truststorePath)); + private void assertCorrectTypeAndTruststorePath(Truststore truststore, String truststorePath, Class<?> truststoreType) { + assertThat(truststore).isInstanceOf(truststoreType); + assertThat(truststore.getFile()).isEqualTo(new File(truststorePath)); } - private void assertContainsCorrectPassword(TruststoreFile truststoreFile, String truststorePass) { - TruststoreFileWithPassword truststoreFileWithPassword = (TruststoreFileWithPassword) truststoreFile; - assertThat(truststoreFileWithPassword.getPassword()).isEqualTo(truststorePass); - } } diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/entry/PemAliasGeneratorTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/entry/PemAliasGeneratorTest.java new file mode 100644 index 00000000..0897de29 --- /dev/null +++ b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/provider/entry/PemAliasGeneratorTest.java @@ -0,0 +1,58 @@ +/*============LICENSE_START======================================================= + * oom-truststore-merger + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.oom.truststoremerger.certification.file.provider.entry; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashSet; +import java.util.Set; +import org.junit.jupiter.api.Test; + +class PemAliasGeneratorTest { + + private final static String PREFIX_ALIAS_NAME = "pem-trusted-certificate-"; + static final int GENERATED_ALIASES_NUMBER = 100; + + @Test + void aliasHasPemPrefix() { + //given + PemAliasGenerator pemAliasGenerator = PemAliasGenerator.getInstance(); + //when + String alias = pemAliasGenerator.getAlias(); + //then + assertThat(alias.contains(PREFIX_ALIAS_NAME)).isTrue(); + } + + @Test + void generatedAliasesHaveUniqNames() { + //given + PemAliasGenerator pemAliasGenerator = PemAliasGenerator.getInstance(); + Set<String> aliases = new HashSet<>(); + + //when + for (int i = 0; i < GENERATED_ALIASES_NUMBER; i++) { + aliases.add(pemAliasGenerator.getAlias()); + } + + //then + assertThat(aliases).hasSize(GENERATED_ALIASES_NUMBER); + } + +} diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/path/TruststoresPathsProviderTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/path/TruststoresPathsProviderTest.java index 945a1077..38422d5c 100644 --- a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/path/TruststoresPathsProviderTest.java +++ b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/path/TruststoresPathsProviderTest.java @@ -30,8 +30,8 @@ import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.Mockito.when; -import static org.onap.oom.truststoremerger.api.ConfigurationEnvs.TRUSTSTORES_ENV; -import static org.onap.oom.truststoremerger.api.ConfigurationEnvs.TRUSTSTORES_PASSWORDS_ENV; +import static org.onap.oom.truststoremerger.api.ConfigurationEnvs.TRUSTSTORES_PATHS_ENV; +import static org.onap.oom.truststoremerger.api.ConfigurationEnvs.TRUSTSTORES_PASSWORDS_PATHS_ENV; @ExtendWith(MockitoExtension.class) @@ -94,11 +94,11 @@ class TruststoresPathsProviderTest { } private void mockTruststoresEnv(String truststores) { - mockEnv(truststores, TRUSTSTORES_ENV); + mockEnv(truststores, TRUSTSTORES_PATHS_ENV); } private void mockTruststoresPasswordsEnv(String truststoresPasswords) { - mockEnv(truststoresPasswords, TRUSTSTORES_PASSWORDS_ENV); + mockEnv(truststoresPasswords, TRUSTSTORES_PASSWORDS_PATHS_ENV); } private void mockEnv(String envValue, String envName) { diff --git a/trustStoreMerger/src/test/resources/empty-truststore.pem b/trustStoreMerger/src/test/resources/empty-truststore.pem new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/trustStoreMerger/src/test/resources/empty-truststore.pem @@ -0,0 +1 @@ + diff --git a/trustStoreMerger/src/test/resources/keystore.p12 b/trustStoreMerger/src/test/resources/keystore.p12 Binary files differnew file mode 100644 index 00000000..bc047a98 --- /dev/null +++ b/trustStoreMerger/src/test/resources/keystore.p12 diff --git a/trustStoreMerger/src/test/resources/truststore-jks-uniq.jks b/trustStoreMerger/src/test/resources/truststore-jks-uniq.jks Binary files differnew file mode 100644 index 00000000..76ce8bc4 --- /dev/null +++ b/trustStoreMerger/src/test/resources/truststore-jks-uniq.jks diff --git a/trustStoreMerger/src/test/resources/truststore-with-private-key.pem b/trustStoreMerger/src/test/resources/truststore-with-private-key.pem new file mode 100644 index 00000000..95179062 --- /dev/null +++ b/trustStoreMerger/src/test/resources/truststore-with-private-key.pem @@ -0,0 +1,56 @@ +-----BEGIN CERTIFICATE----- +MIIEszCCAxugAwIBAgIUE+27eIlr12tQ+AMxkJTf2Y+ycOEwDQYJKoZIhvcNAQEL +BQAwYTEjMCEGCgmSJomT8ixkAQEME2MtMDRjYmE2YjhhMDQ5ODEyNGQxFTATBgNV +BAMMDE1hbmFnZW1lbnRDQTEjMCEGA1UECgwaRUpCQ0EgQ29udGFpbmVyIFF1aWNr +c3RhcnQwHhcNMjAwNzA4MTIzODU4WhcNMzAwNzA4MTIzODU4WjBhMSMwIQYKCZIm +iZPyLGQBAQwTYy0wNGNiYTZiOGEwNDk4MTI0ZDEVMBMGA1UEAwwMTWFuYWdlbWVu +dENBMSMwIQYDVQQKDBpFSkJDQSBDb250YWluZXIgUXVpY2tzdGFydDCCAaIwDQYJ +KoZIhvcNAQEBBQADggGPADCCAYoCggGBALTlx22Ld87VO5QgkD7OJvx81a8xLRWt +b4cqmLSBRKw+jTjX4fHCtLh98hXNtYXJ9nxPa2t8MKR/I00Wf1razX1IYN9H/diV +uICjyMxDyK6nwEMpqaWiQgOQx1N4TjNhr19ULTbyFLQMVfXy1OrTsfoWQ2omvRxN +LIoVKwPHd92KG6iqJDZU14ErfA6UtypDV+4rOKQBh0JrfFI/KxKFKRH3e0oDxD8c +PIOUpYVccVv/4Gbc0ZRs8KK0uPZN73LlQccYzPrSk/VAUeuZ52Wqk6dNrq5FHSCe +EwPbx6aqgLwhTLlYAJqmYuDsGU9ZL09buCVKim1pjZiPaoaYAvv3KHdjEKAu9NxF +dezd4JZ24hqYCA7EGnKgyjHxA0SiD/B8f+aBdRGDZbMlH1gKFKivjuHSfPwRv6Op +p8ykEzk3yp0RcqSflVPg0mj+LPViYo/loLLOLybFFR7BetyFieN5QV7BKRyfc7Qi +Se6Idh1nLIrYR9ek8BDkEE9u/JiTT0gP3QIDAQABo2MwYTAPBgNVHRMBAf8EBTAD +AQH/MB8GA1UdIwQYMBaAFDYtHGSe9lYaC9+WnNT91wuiMlkjMB0GA1UdDgQWBBQ2 +LRxknvZWGgvflpzU/dcLojJZIzAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEL +BQADggGBAIcLj76GVhYSuVaWMMCVlVl8rHhYYufT9z2X7G/0D1G655/dAeAJLltL +S4T7SZI44XKfVH4ztc4TO6OEMLZzslcfDzv/tUzL4EOsXtBTpsK9JgHP2lzCE+aj +a7uxn5SGWlu0YmT/++2d+QYaVVAjqalal8NsppOYCh8GB84TXbQjOMWcR9YBozZf +DSy3/vDNMuggZfdEOMMP57M10NoOKor+8eMGB42k4NR+G2npYHZ4uh1Ifk+eoTAh +o5O0iz3+/8eMTkLavqpnfzBhWHfRTI8wUu6zgm+QI+tsqhPePRuwauD8r79JBnPW +0gayZI5jIWTwvufpweKMgLyQbiGVUDtsr2c43kJ6XHoEf0ACUzbJKtGDD3Y7H/G1 +5Q7hBWbQwhUpiVeRnofS9jHQPWu0Ueq4/784hy+yPWotBIeIWEy4KzKTS+GaRDm0 +OSYtta/BdU0iZO/PzzTC5yIzwrsaq+5Idp16mub7mCAW0B36x0Phmr0DQWpZwxmX +9envV9HcJw== +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCeCRM315FGH1Fa +nlHRo/JfNwPi+xAor+cC4b/5qEIsGI9Zwgg9rzs/k9XOyUYoWMCNzn8c3nTYhd8h +8KzPu7o5thiHsr1z6luVPf9zF6K4UJupR0Vba812n7Z8Ye/uyOBu0TeE6RGL7Vxv +2cKDBLKHIRpexhic2+NkfhZGyfU5kB6IMQBs08LC4wmiPffCWhoWcLk9QbNlJL0d +3g389oWZQ2NVD2zCvkKe4+LfaNE1Rzk+1Wb+fHhLbL/2tFi9bbM8GjzVewREZekw +vS4fD8i/Sdx85m35QqzX33b1KbUPmZummmyC37l2oihfWrNKxcpC0alYvfwypHZp +E26Xy2D/AgMBAAECggEABUJeDlyxK/k81twv8t8W4M5O5c3fIst/z5u9rMxJr3f9 +xUnsxki/mwULd39BQ3R4q/90QXyxvMbvvwxoY91mfCcwN8vd/C6Pb68JgkYGF0Yv +d/m0OC+lPc5g31DPEE5FEcsKovSyrcpvahWAIKYWXuLeIstK5GV48s4zZZWxAIJa +7IhLst4I3Y7B6vmPHCutOxL6VXPllhe1gAI/tRWH0Hpbk/KiN0jGirTWo9FrNgAZ +aRLcrS+a4sZuVZBMe7/NR4qXs+NbafFcuWcgRdgZLoktnKyWk5/WuhRXVuTY6H5B +pBgrffaab+qMDuziQ2SyHlm1eCnQGbl/++9UPAHZ6QKBgQDQIpVwqzfDsGxsBFo5 +y6wL5uWP8oiDoAkTjX41tgFy5G+ccHaIle/N8U+yrMkgW4tKKYFdREfA9eNxLbsB +Dy6MkYlbE6cWbcf42QN7/Nn0jWBVrSNBssAPdQYtCJw+07/Qn1rWVIkTNHpqvEV7 +T9+JgLtSD9d3yMEeW/wWpF0PBQKBgQDCYQEQ2iwqyMtsd5GRZFXboBWAVdjfuEd9 +7sZ3SM6z3U1fkKXImdncnihlLN2Ll7tMftGLMF8yxT4OWHPC9Tn7qnatlc3oSVIm +82Kj0S0j0dr0V4tjpxAhcfuDh1n02A+JQX1gK/rQN/H8JMqpc5FySTV3lBswTvAs +Gdk7J2tHMwKBgDeX1TS39vglCoC7lOH1Heo77TtKu930hBgd5gUwrShkDc/KVk7b +RadLek8uSbaD3Suc9HnWABhxVSPo5Bc/V96iDP8vu6SJBC3awUx/2DOzA3U+/rjQ +pu46AsFKmHlLk+OEfP3crJRdowkZarGqPvn6UY50vse27qZOSYI+usCFAoGBAJhF +fZxCDY+GtTVHhdWsEEZ45d8fYUIBDqBsyTTw6Fym5NIUcorvW2gkzehUeUm9l5CZ +WHX9ctZHBhIe4LC9gqrQIyBg1mk95wl0aLWETCRfZXM8kYmDenN441tqUOIp0CHq +F9mbGmS7LuojuE9+pVYuW6BNee8iJ6ukpDRe8P9ZAoGAHbXYDvWfNgHE4w15uCpE +riR19yvlWk9tsswdefhyIb36/2qX7+4cQLZsD9b/nVF+GVwbXFgn/qjRQyds+YUD +dpD/KciWewZRhlQvWChEH/hZrzauBnkE0qcMURW6Xf7NHn/7d+jembEc3bkyjnEI +6yNDF7D4l5W6gvqgiN5VSM8= +-----END RSA PRIVATE KEY----- |