diff options
32 files changed, 1286 insertions, 61 deletions
diff --git a/certServiceClient/pom.xml b/certServiceClient/pom.xml index 9e828839..4b7c0cf9 100644 --- a/certServiceClient/pom.xml +++ b/certServiceClient/pom.xml @@ -146,16 +146,16 @@ <artifactId>bcpkix-jdk15on</artifactId> </dependency> <dependency> - <groupId>org.assertj</groupId> - <artifactId>assertj-core</artifactId> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> </dependency> <dependency> - <groupId>org.junit.jupiter</groupId> - <artifactId>junit-jupiter-engine</artifactId> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> - <artifactId>junit-jupiter-api</artifactId> + <artifactId>junit-jupiter</artifactId> </dependency> <dependency> <groupId>org.mockito</groupId> diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/CertServiceClient.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/CertServiceClient.java index 59d0c032..d3d7f26d 100644 --- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/CertServiceClient.java +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/CertServiceClient.java @@ -19,9 +19,14 @@ package org.onap.aaf.certservice.client; +import java.security.KeyPair; import org.onap.aaf.certservice.client.api.ExitableException; +import org.onap.aaf.certservice.client.certification.PrivateKeyToPemEncoder; import org.onap.aaf.certservice.client.certification.CsrFactory; import org.onap.aaf.certservice.client.certification.KeyPairFactory; +import org.onap.aaf.certservice.client.certification.conversion.KeystoreTruststoreCreator; +import org.onap.aaf.certservice.client.certification.conversion.KeystoreTruststoreCreatorFactory; +import org.onap.aaf.certservice.client.common.Base64Encoder; import org.onap.aaf.certservice.client.configuration.EnvsForClient; import org.onap.aaf.certservice.client.configuration.EnvsForCsr; import org.onap.aaf.certservice.client.configuration.factory.ClientConfigurationFactory; @@ -32,14 +37,12 @@ import org.onap.aaf.certservice.client.httpclient.CloseableHttpClientProvider; import org.onap.aaf.certservice.client.httpclient.HttpClient; import org.onap.aaf.certservice.client.httpclient.model.CertServiceResponse; -import java.security.KeyPair; - import static org.onap.aaf.certservice.client.api.ExitCode.SUCCESS_EXIT_CODE; import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.KEY_SIZE; import static org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants.RSA_ENCRYPTION_ALGORITHM; -import static org.onap.aaf.certservice.client.common.Base64Coder.encode; public class CertServiceClient { + private AppExitHandler appExitHandler; public CertServiceClient(AppExitHandler appExitHandler) { @@ -48,21 +51,28 @@ public class CertServiceClient { public void run() { KeyPairFactory keyPairFactory = new KeyPairFactory(RSA_ENCRYPTION_ALGORITHM, KEY_SIZE); + PrivateKeyToPemEncoder pkEncoder = new PrivateKeyToPemEncoder(); + Base64Encoder base64Encoder = new Base64Encoder(); try { ClientConfiguration clientConfiguration = new ClientConfigurationFactory(new EnvsForClient()).create(); CsrConfiguration csrConfiguration = new CsrConfigurationFactory(new EnvsForCsr()).create(); KeyPair keyPair = keyPairFactory.create(); CsrFactory csrFactory = new CsrFactory(csrConfiguration); - CloseableHttpClientProvider provider = new CloseableHttpClientProvider(clientConfiguration.getRequestTimeout()); + CloseableHttpClientProvider provider = new CloseableHttpClientProvider( + clientConfiguration.getRequestTimeout()); HttpClient httpClient = new HttpClient(provider, clientConfiguration.getUrlToCertService()); CertServiceResponse certServiceData = httpClient.retrieveCertServiceData( clientConfiguration.getCaName(), - csrFactory.createEncodedCsr(keyPair), - encode(keyPair.getPrivate().toString())); + base64Encoder.encode(csrFactory.createCsrInPem(keyPair)), + base64Encoder.encode(pkEncoder.encodePrivateKeyToPem(keyPair.getPrivate()))); + KeystoreTruststoreCreator filesCreator = new KeystoreTruststoreCreatorFactory( + clientConfiguration.getCertsOutputPath()).create(); + filesCreator.createKeystore(certServiceData.getCertificateChain(), keyPair.getPrivate()); + filesCreator.createTruststore(certServiceData.getTrustedCertificates()); } catch (ExitableException e) { appExitHandler.exit(e.applicationExitCode()); } diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitCode.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitCode.java index b72a0e2d..670cbe90 100644 --- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitCode.java +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/api/ExitCode.java @@ -25,7 +25,9 @@ public enum ExitCode { KEY_PAIR_GENERATION_EXCEPTION(3), CSR_GENERATION_EXCEPTION(4), CERT_SERVICE_API_CONNECTION_EXCEPTION(5), - HTTP_CLIENT_EXCEPTION(6); + HTTP_CLIENT_EXCEPTION(6), + PKCS12_CONVERSION_EXCEPTION(7), + PK_TO_PEM_ENCODING_EXCEPTION(8); private final int value; diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/CsrFactory.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/CsrFactory.java index f936636a..83fa6d44 100644 --- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/CsrFactory.java +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/CsrFactory.java @@ -66,12 +66,12 @@ public class CsrFactory { } - public String createEncodedCsr(KeyPair keyPair) throws CsrGenerationException { + public String createCsrInPem(KeyPair keyPair) throws CsrGenerationException { PKCS10CertificationRequest request; String csrParameters = getMandatoryParameters().append(getOptionalParameters()).toString(); X500Principal subject = new X500Principal(csrParameters); request = createPKCS10Csr(subject, keyPair); - return encodeToBase64(convertPKC10CsrToPem(request)); + return convertPKC10CsrToPem(request); } @@ -151,8 +151,4 @@ public class CsrFactory { private static Boolean isParameterPresent(String parameter) { return parameter != null && !"".equals(parameter); } - - private static String encodeToBase64(String csrInPem) { - return Base64.getEncoder().encodeToString(csrInPem.getBytes(StandardCharsets.UTF_8)); - } } diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoder.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoder.java new file mode 100644 index 00000000..77995958 --- /dev/null +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoder.java @@ -0,0 +1,51 @@ +/* + * ============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification; + + + +import java.io.IOException; +import java.io.StringWriter; +import java.security.PrivateKey; + +import org.bouncycastle.openssl.jcajce.JcaPEMWriter; +import org.bouncycastle.util.io.pem.PemObject; +import org.onap.aaf.certservice.client.certification.exception.PkEncodingException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PrivateKeyToPemEncoder { + + public static final String PEM_OBJECT_TYPE = "RSA PRIVATE KEY"; + private final Logger LOGGER = LoggerFactory.getLogger(PrivateKeyToPemEncoder.class); + + public String encodePrivateKeyToPem(PrivateKey pk) throws PkEncodingException { + LOGGER.info("Encoding PrivateKey to PEM"); + StringWriter stringWriter = new StringWriter(); + try (JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter)) { + pemWriter.writeObject(new PemObject(PEM_OBJECT_TYPE, pk.getEncoded())); + } catch (IOException e) { + LOGGER.error("Exception occurred during encoding PrivateKey to PEM", e); + throw new PkEncodingException(e); + } + return stringWriter.toString(); + } +} diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreator.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreator.java new file mode 100644 index 00000000..6dc2ef87 --- /dev/null +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreator.java @@ -0,0 +1,55 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification.conversion; + +import java.security.PrivateKey; +import java.util.List; +import org.onap.aaf.certservice.client.certification.exception.PemToPKCS12ConverterException; + +public class KeystoreTruststoreCreator { + + private static final String CERTIFICATE_ALIAS = "certificate"; + private static final String TRUSTED_CERTIFICATE_ALIAS = "trusted-certificate-"; + private static final int PASSWORD_LENGTH = 24; + private final RandomPasswordGenerator generator; + private final PemToPKCS12Converter converter; + private final PKCS12FilesCreator creator; + + public KeystoreTruststoreCreator(PKCS12FilesCreator creator, RandomPasswordGenerator generator, + PemToPKCS12Converter converter) { + this.generator = generator; + this.converter = converter; + this.creator = creator; + } + + public void createKeystore(List<String> data, PrivateKey privateKey) + throws PemToPKCS12ConverterException { + Password password = generator.generate(PASSWORD_LENGTH); + creator.saveKeystoreData(converter.convertKeystore(data, password, CERTIFICATE_ALIAS, privateKey), + password.getPassword()); + } + + public void createTruststore(List<String> data) + throws PemToPKCS12ConverterException { + Password password = generator.generate(PASSWORD_LENGTH); + creator.saveTruststoreData(converter.convertTruststore(data, password, TRUSTED_CERTIFICATE_ALIAS), + password.getPassword()); + } +} diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorFactory.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorFactory.java new file mode 100644 index 00000000..8c719535 --- /dev/null +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorFactory.java @@ -0,0 +1,35 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification.conversion; + +public class KeystoreTruststoreCreatorFactory { + private final String outputPath; + + public KeystoreTruststoreCreatorFactory(String outputPath) { + this.outputPath = outputPath; + } + + public KeystoreTruststoreCreator create() { + return new KeystoreTruststoreCreator( + new PKCS12FilesCreator(outputPath), + new RandomPasswordGenerator(), + new PemToPKCS12Converter()); + } +} diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreator.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreator.java new file mode 100644 index 00000000..d8c41bfd --- /dev/null +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreator.java @@ -0,0 +1,73 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification.conversion; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Path; + +import org.onap.aaf.certservice.client.certification.exception.PemToPKCS12ConverterException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class PKCS12FilesCreator { + + private static final String KEYSTORE_JKS = "keystore.jks"; + private static final String KEYSTORE_PASS = "keystore.pass"; + private static final String TRUSTSTORE_JKS = "truststore.jks"; + private static final String TRUSTSTORE_PASS = "truststore.pass"; + private final String keystoreJksPath; + private final String keystorePassPath; + private final String truststoreJksPath; + private final String truststorePassPath; + private final Logger LOGGER = LoggerFactory.getLogger(PKCS12FilesCreator.class); + + + PKCS12FilesCreator(String path) { + keystoreJksPath = Path.of(path, KEYSTORE_JKS).toString(); + keystorePassPath = Path.of(path, KEYSTORE_PASS).toString(); + truststoreJksPath = Path.of(path, TRUSTSTORE_JKS).toString(); + truststorePassPath = Path.of(path, TRUSTSTORE_PASS).toString(); + } + + void saveKeystoreData(byte[] keystoreData, String keystorePassword) throws PemToPKCS12ConverterException { + LOGGER.debug("Creating PKCS12 keystore files and saving data. Keystore path: {}", keystoreJksPath); + + saveDataToLocation(keystoreData, keystoreJksPath); + saveDataToLocation(keystorePassword.getBytes(), keystorePassPath); + } + + void saveTruststoreData(byte[] truststoreData, String truststorePassword) + throws PemToPKCS12ConverterException { + LOGGER.debug("Creating PKCS12 truststore files and saving data. Truststore path: {}", truststoreJksPath); + + saveDataToLocation(truststoreData, truststoreJksPath); + saveDataToLocation(truststorePassword.getBytes(), truststorePassPath); + } + + private void saveDataToLocation(byte[] data, String path) throws PemToPKCS12ConverterException { + try (FileOutputStream fos = new FileOutputStream(path)) { + fos.write(data); + } catch (IOException e) { + LOGGER.error("PKCS12 files creation failed", e); + throw new PemToPKCS12ConverterException(e); + } + } +} diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/Password.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/Password.java new file mode 100644 index 00000000..f0ee419c --- /dev/null +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/Password.java @@ -0,0 +1,42 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification.conversion; + +class Password { + private final static String PASSWORD_PATTERN = "[\\w$#]{16,}"; + private final String password; + + Password(String password) { + this.password = password; + } + + String getPassword() { + return password; + } + + char[] toCharArray() { + return password.toCharArray(); + } + + boolean isCorrectPasswordPattern() { + return password.matches(PASSWORD_PATTERN); + } +} diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12Converter.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12Converter.java new file mode 100644 index 00000000..eab9bf7c --- /dev/null +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12Converter.java @@ -0,0 +1,133 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification.conversion; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.StringReader; +import java.security.KeyStore; +import java.security.KeyStore.LoadStoreParameter; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.util.List; +import java.util.Optional; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openssl.PEMParser; +import org.onap.aaf.certservice.client.certification.exception.PemToPKCS12ConverterException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class PemToPKCS12Converter { + + private final static String PKCS12 = "PKCS12"; + private final static String PASSWORD_ERROR_MSG = "Password should be min. 16 chars long and should contain only alphanumeric characters and special characters like Underscore (_), Dollar ($) and Pound (#)"; + private final LoadStoreParameter EMPTY_KEYSTORE_CONFIGURATION = null; + private final Logger LOGGER = LoggerFactory.getLogger(PemToPKCS12Converter.class); + + byte[] convertKeystore(List<String> certificateChain, Password password, String alias, PrivateKey privateKey) + throws PemToPKCS12ConverterException { + LOGGER.debug("Converting PEM certificates to PKCS12 keystore."); + return convert(certificateChain, password, certs -> getKeyStore(alias, password, certs, privateKey)); + } + + byte[] convertTruststore(List<String> trustAnchors, Password password, String alias) + throws PemToPKCS12ConverterException { + LOGGER.debug("Converting PEM certificates to PKCS12 truststore."); + return convert(trustAnchors, password, certs -> getTrustStore(alias, certs)); + } + + private byte[] convert(List<String> certificates, Password password, StoreEntryOperation operation) + throws PemToPKCS12ConverterException { + checkPassword(password); + final Certificate[] X509Certificates = convertToCertificateArray(certificates); + return getKeyStoreBytes(password, operation, X509Certificates); + } + + private void checkPassword(Password password) throws PemToPKCS12ConverterException { + if (!password.isCorrectPasswordPattern()) { + LOGGER.error(PASSWORD_ERROR_MSG); + throw new PemToPKCS12ConverterException(PASSWORD_ERROR_MSG); + } + } + + private byte[] getKeyStoreBytes(Password password, StoreEntryOperation op, Certificate[] x509Certificates) + throws PemToPKCS12ConverterException { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + KeyStore ks = op.getStore(x509Certificates); + ks.store(bos, password.toCharArray()); + return bos.toByteArray(); + } catch (IOException | CertificateException | NoSuchAlgorithmException | KeyStoreException e) { + LOGGER.error("Pem to PKCS12 converter failed", e); + throw new PemToPKCS12ConverterException(e); + } + } + + private KeyStore getKeyStore(String alias, Password password, Certificate[] certificates, PrivateKey privateKey) + throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException { + KeyStore ks = getKeyStoreInstance(); + ks.setKeyEntry(alias, privateKey, password.toCharArray(), certificates); + return ks; + } + + private KeyStore getTrustStore(String alias, Certificate[] certificates) + throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException { + KeyStore ks = getKeyStoreInstance(); + long i = 1L; + for (Certificate c : certificates) { + ks.setCertificateEntry(alias + i++, c); + } + return ks; + } + + private KeyStore getKeyStoreInstance() + throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException { + KeyStore ks = KeyStore.getInstance(PKCS12); + ks.load(EMPTY_KEYSTORE_CONFIGURATION); + return ks; + } + + private Certificate[] convertToCertificateArray(List<String> certificates) + throws PemToPKCS12ConverterException { + Certificate[] parsedCertificates = new Certificate[certificates.size()]; + for (String certificate : certificates) { + parsedCertificates[certificates.indexOf(certificate)] = parseCertificate(certificate); + } + return parsedCertificates; + } + + private Certificate parseCertificate(String certificate) throws PemToPKCS12ConverterException { + try (PEMParser pem = new PEMParser(new StringReader(certificate))) { + X509CertificateHolder certHolder = Optional.ofNullable((X509CertificateHolder) pem.readObject()) + .orElseThrow( + () -> new PemToPKCS12ConverterException("The certificate couldn't be parsed correctly. " + certificate)); + return new JcaX509CertificateConverter() + .setProvider(new BouncyCastleProvider()) + .getCertificate(certHolder); + } catch (IOException | CertificateException e) { + LOGGER.error("Certificates conversion failed", e); + throw new PemToPKCS12ConverterException(e); + } + } +} diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGenerator.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGenerator.java new file mode 100644 index 00000000..5db7b26f --- /dev/null +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGenerator.java @@ -0,0 +1,47 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification.conversion; + +import java.security.SecureRandom; +import org.apache.commons.lang3.RandomStringUtils; + +class RandomPasswordGenerator { + + private static final String ALPHA = "abcdefghijklmnopqrstuvwxyz"; + private static final String NUMBERS = "0123456789"; + private static final String SPECIAL_CHARS = "_$#"; + private static final char[] SET_OF_CHARS = (ALPHA + ALPHA.toUpperCase() + NUMBERS + SPECIAL_CHARS).toCharArray(); + private static final char START_POSITION_IN_ASCII_CHARS = 0; + private static final char END_POSITION_IN_ASCII_CHARS = 0; + private static final boolean USE_LETTERS_ONLY = false; + private static final boolean USE_NUMBERS_ONLY = false; + + Password generate(int passwordLength) { + return new Password(RandomStringUtils.random( + passwordLength, + START_POSITION_IN_ASCII_CHARS, + END_POSITION_IN_ASCII_CHARS, + USE_LETTERS_ONLY, + USE_NUMBERS_ONLY, + SET_OF_CHARS, + new SecureRandom())); + } +} + diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/StoreEntryOperation.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/StoreEntryOperation.java new file mode 100644 index 00000000..6ee7817b --- /dev/null +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/conversion/StoreEntryOperation.java @@ -0,0 +1,34 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification.conversion; + +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; + +@FunctionalInterface +public interface StoreEntryOperation { + + KeyStore getStore(Certificate[] certificates) + throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException; +} diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PemToPKCS12ConverterException.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PemToPKCS12ConverterException.java new file mode 100644 index 00000000..87020d6f --- /dev/null +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PemToPKCS12ConverterException.java @@ -0,0 +1,39 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification.exception; + +import org.onap.aaf.certservice.client.api.ExitCode; +import org.onap.aaf.certservice.client.api.ExitableException; + +public class PemToPKCS12ConverterException extends ExitableException { + private static final ExitCode EXIT_CODE = ExitCode.PKCS12_CONVERSION_EXCEPTION; + + public PemToPKCS12ConverterException(Throwable e) { + super(e); + } + public PemToPKCS12ConverterException(String message) { + super(message); + } + + @Override + public int applicationExitCode() { + return EXIT_CODE.getValue(); + } +} diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PkEncodingException.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PkEncodingException.java new file mode 100644 index 00000000..596a6a44 --- /dev/null +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/certification/exception/PkEncodingException.java @@ -0,0 +1,35 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification.exception; + +import org.onap.aaf.certservice.client.api.ExitCode; +import org.onap.aaf.certservice.client.api.ExitableException; + +public class PkEncodingException extends ExitableException { + private static final ExitCode EXIT_CODE = ExitCode.PK_TO_PEM_ENCODING_EXCEPTION; + + public PkEncodingException(Throwable e) { + super(e); + } + + public int applicationExitCode() { + return EXIT_CODE.getValue(); + } +} diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/common/Base64Coder.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/common/Base64Encoder.java index c066187d..1f90db1b 100644 --- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/common/Base64Coder.java +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/common/Base64Encoder.java @@ -1,5 +1,4 @@ -/* - * ============LICENSE_START======================================================= +/*============LICENSE_START======================================================= * aaf-certservice-client * ================================================================================ * Copyright (C) 2020 Nokia. All rights reserved. @@ -22,8 +21,8 @@ package org.onap.aaf.certservice.client.common; import org.bouncycastle.util.encoders.Base64; -public class Base64Coder { - public static String encode(String string){ +public class Base64Encoder { + public String encode(String string){ return new String(Base64.encode(string.getBytes())); } -} +}
\ No newline at end of file diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtils.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtils.java index e65d688d..b0405274 100644 --- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtils.java +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtils.java @@ -27,7 +27,7 @@ public final class EnvValidationUtils { private EnvValidationUtils() {} public static Boolean isPathValid(String path) { - return path.matches("^/|(/[a-zA-Z0-9_-]+)+$"); + return path.matches("^/|(/[a-zA-Z0-9_-]+)+/?$"); } public static Boolean isAlphaNumeric(String caName) { diff --git a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/ClientConfigurationFactory.java b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/ClientConfigurationFactory.java index b7ee5d32..3bd15288 100644 --- a/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/ClientConfigurationFactory.java +++ b/certServiceClient/src/main/java/org/onap/aaf/certservice/client/configuration/factory/ClientConfigurationFactory.java @@ -20,14 +20,15 @@ package org.onap.aaf.certservice.client.configuration.factory; + + +import java.util.Optional; import org.onap.aaf.certservice.client.configuration.ClientConfigurationEnvs; import org.onap.aaf.certservice.client.configuration.EnvValidationUtils; import org.onap.aaf.certservice.client.configuration.EnvsForClient; import org.onap.aaf.certservice.client.configuration.exception.ClientConfigurationException; import org.onap.aaf.certservice.client.configuration.model.ClientConfiguration; -import java.util.Optional; - public class ClientConfigurationFactory implements AbstractConfigurationFactory<ClientConfiguration> { private final EnvsForClient envsForClient; diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/CsrFactoryTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/CsrFactoryTest.java index 16b5e03b..809a91f2 100644 --- a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/CsrFactoryTest.java +++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/CsrFactoryTest.java @@ -52,7 +52,7 @@ public class CsrFactoryTest { when(config.getOrganizationUnit()).thenReturn("ONAP"); when(config.getState()).thenReturn("California"); - assertThat(new CsrFactory(config).createEncodedCsr(keyPair)).isNotEmpty(); + assertThat(new CsrFactory(config).createCsrInPem(keyPair)).isNotEmpty(); } } diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoderTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoderTest.java new file mode 100644 index 00000000..def9c1d5 --- /dev/null +++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/PrivateKeyToPemEncoderTest.java @@ -0,0 +1,66 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification; + + +import org.bouncycastle.util.io.pem.PemObject; +import org.bouncycastle.util.io.pem.PemReader; +import org.junit.jupiter.api.Test; +import org.onap.aaf.certservice.client.certification.exception.PkEncodingException; + +import java.io.IOException; +import java.io.StringReader; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; + +import static org.assertj.core.api.Assertions.assertThat; + +class PrivateKeyToPemEncoderTest { + + private static final String ENCRYPTION_ALGORITHM = "RSA"; + private static final String RESOURCES_DIR = "src/test/resources/"; + private static final String PRIVATE_KEY_PEM_PATH = RESOURCES_DIR + "rsaPrivateKeyPem"; + + @Test + public void shouldReturnProperlyEncodedPrivateKey() throws InvalidKeySpecException, NoSuchAlgorithmException, PkEncodingException, IOException { + //given + String expectedPem = Files.readString(Paths.get(PRIVATE_KEY_PEM_PATH)); + PrivateKeyToPemEncoder testedPkEncoder = new PrivateKeyToPemEncoder(); + //when + PrivateKey privateKey = extractPrivateKeyFromPem(expectedPem); + String resultPkInPem = testedPkEncoder.encodePrivateKeyToPem(privateKey); + //then + assertThat(resultPkInPem).isEqualTo(expectedPem); + } + + private PrivateKey extractPrivateKeyFromPem(String pem) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException { + PemReader pemReader = new PemReader(new StringReader(pem)); + PemObject pemObject = pemReader.readPemObject(); + pemReader.close(); + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(pemObject.getContent()); + KeyFactory kf = KeyFactory.getInstance(ENCRYPTION_ALGORITHM); + return kf.generatePrivate(spec); + } +}
\ No newline at end of file diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorTest.java new file mode 100644 index 00000000..04bccf0b --- /dev/null +++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/KeystoreTruststoreCreatorTest.java @@ -0,0 +1,80 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification.conversion; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.security.PrivateKey; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.onap.aaf.certservice.client.certification.exception.PemToPKCS12ConverterException; + +class KeystoreTruststoreCreatorTest { + + private PKCS12FilesCreator filesCreator = mock(PKCS12FilesCreator.class); + private RandomPasswordGenerator passwordGenerator = mock(RandomPasswordGenerator.class); + private PemToPKCS12Converter converter = mock(PemToPKCS12Converter.class); + private PrivateKey privateKey = mock(PrivateKey.class); + + @Test + void createKeystoreShouldCallRequiredMethods() throws PemToPKCS12ConverterException { + // given + final Password password = new Password("d9D_u8LooYaXH4G48DtN#vw0"); + final List<String> certificates = List.of("a", "b"); + final int passwordLength = 24; + final String alias = "certificate"; + final byte[] keystoreBytes = "this is a keystore test".getBytes(); + KeystoreTruststoreCreator creator = new KeystoreTruststoreCreator(filesCreator, passwordGenerator, converter); + + // when + when(passwordGenerator.generate(passwordLength)).thenReturn(password); + when(converter.convertKeystore(certificates, password, alias, privateKey)).thenReturn(keystoreBytes); + creator.createKeystore(certificates, privateKey); + + // then + verify(passwordGenerator, times(1)).generate(passwordLength); + verify(converter, times(1)).convertKeystore(certificates, password, alias, privateKey); + verify(filesCreator, times(1)).saveKeystoreData(keystoreBytes, password.getPassword()); + } + + @Test + void createTruststoreShouldCallRequiredMethods() throws PemToPKCS12ConverterException { + // given + final Password password = new Password("d9D_u8LooYaXH4G48DtN#vw0"); + final List<String> certificates = List.of("a", "b"); + final int passwordLength = 24; + final String alias = "trusted-certificate-"; + final byte[] truststoreBytes = "this is a truststore test".getBytes(); + KeystoreTruststoreCreator creator = new KeystoreTruststoreCreator(filesCreator, passwordGenerator, converter); + + // when + when(passwordGenerator.generate(passwordLength)).thenReturn(password); + when(converter.convertTruststore(certificates, password, alias)).thenReturn(truststoreBytes); + creator.createTruststore(certificates); + + // then + verify(passwordGenerator, times(1)).generate(passwordLength); + verify(converter, times(1)).convertTruststore(certificates, password, alias); + verify(filesCreator, times(1)).saveTruststoreData(truststoreBytes, password.getPassword()); + } +}
\ No newline at end of file diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreatorTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreatorTest.java new file mode 100644 index 00000000..8e6e03c6 --- /dev/null +++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PKCS12FilesCreatorTest.java @@ -0,0 +1,111 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification.conversion; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.aaf.certservice.client.certification.exception.PemToPKCS12ConverterException; + +class PKCS12FilesCreatorTest { + + private static final String RESOURCES_PATH = "src/test/resources"; + private static final String OUTPUT_PATH = RESOURCES_PATH + "/generatedFiles/"; + private static final String KEYSTORE_PATH = OUTPUT_PATH + "keystore.jks"; + private static final String KEYSTORE_PASS_PATH = OUTPUT_PATH + "keystore.pass"; + private static final String TRUSTSTORE_PATH = OUTPUT_PATH + "truststore.jks"; + private static final String TRUSTSTORE_PASS_PATH = OUTPUT_PATH + "truststore.pass"; + private static final String ERROR_MESSAGE = "java.io.FileNotFoundException: src/test/resources/generatedFiles/thisPathDoesNotExist/keystore.jks (No such file or directory)"; + + private File outputDirectory = new File(OUTPUT_PATH); + + @BeforeEach + void createDirectory() { + outputDirectory.mkdir(); + } + + @AfterEach + void cleanUpFiles() { + List.of(outputDirectory.listFiles()).forEach(f -> f.delete()); + outputDirectory.delete(); + } + + @Test + void saveKeystoreDataShouldCreateFilesWithDataInGivenLocation() throws PemToPKCS12ConverterException, IOException { + // given + final byte[] data = new byte[]{-128, 1, 127}; + final String password = "onap123"; + File keystore = new File(KEYSTORE_PATH); + File keystorePass = new File(KEYSTORE_PASS_PATH); + PKCS12FilesCreator filesCreator = new PKCS12FilesCreator(OUTPUT_PATH); + + // when + filesCreator.saveKeystoreData(data, password); + + // then + assertTrue(keystore.exists()); + assertTrue(keystorePass.exists()); + assertArrayEquals(data, Files.readAllBytes(Path.of(KEYSTORE_PATH))); + assertEquals(password, Files.readString(Path.of(KEYSTORE_PASS_PATH), StandardCharsets.UTF_8)); + } + + @Test + void saveTruststoreDataShouldCreateFilesWithDataInGivenLocation() + throws PemToPKCS12ConverterException, IOException { + // given + final byte[] data = new byte[]{-128, 1, 2, 3, 127}; + final String password = "nokia321"; + File truststore = new File(TRUSTSTORE_PATH); + File truststorePass = new File(TRUSTSTORE_PASS_PATH); + PKCS12FilesCreator filesCreator = new PKCS12FilesCreator(OUTPUT_PATH); + + // when + filesCreator.saveTruststoreData(data, password); + + // then + assertTrue(truststore.exists()); + assertTrue(truststorePass.exists()); + assertArrayEquals(data, Files.readAllBytes(Path.of(TRUSTSTORE_PATH))); + assertEquals(password, Files.readString(Path.of(TRUSTSTORE_PASS_PATH), StandardCharsets.UTF_8)); + } + + @Test + void saveKeystoreDataShouldThrowPemToPKCS12ConverterExceptionWhenOutputDirectoryDoesNotExist() { + // given + final byte[] data = new byte[]{-128, 1, 2, 3, 0}; + final String password = "123aikon"; + PKCS12FilesCreator filesCreator = new PKCS12FilesCreator(OUTPUT_PATH + "thisPathDoesNotExist/"); + + // when then + assertThatThrownBy(() -> filesCreator.saveKeystoreData(data, password)) + .isInstanceOf(PemToPKCS12ConverterException.class).hasMessage(ERROR_MESSAGE); + } +}
\ No newline at end of file diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12ConverterTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12ConverterTest.java new file mode 100644 index 00000000..35043409 --- /dev/null +++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/PemToPKCS12ConverterTest.java @@ -0,0 +1,197 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification.conversion; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants; +import org.onap.aaf.certservice.client.certification.exception.PemToPKCS12ConverterException; + +class PemToPKCS12ConverterTest { + + private static final String RESOURCES_PATH = "src/test/resources"; + private static final String CERT1_PATH = RESOURCES_PATH + "/cert1.pem"; + private static final String CERT2_PATH = RESOURCES_PATH + "/cert2.pem"; + private static final String KEY_PATH = RESOURCES_PATH + "/privateKey"; + private static final String EXPECTED_KEYSTORE_PATH = RESOURCES_PATH + "/expectedKeystore.jks"; + private static final String EXPECTED_TRUSTSTORE_PATH = RESOURCES_PATH + "/expectedTruststore.jks"; + private static final String PKCS12 = "PKCS12"; + private static final String PKCS8 = "PKCS#8"; + private static final String KEY_ERROR_MSG = "java.security.KeyStoreException: Key protection algorithm not found: java.lang.NullPointerException"; + private static final String CERTIFICATES_ERROR_MSG = "The certificate couldn't be parsed correctly. certificate1"; + private static final String PASSWORD_ERROR_MSG = "Password should be min. 16 chars long and should contain only alphanumeric characters and special characters like Underscore (_), Dollar ($) and Pound (#)"; + private static byte[] key; + private PrivateKey privateKey = mock(PrivateKey.class); + + @BeforeAll + static void setUpForAll() throws IOException { + key = Files.readAllBytes(Path.of(KEY_PATH)); + } + + @Test + void convertKeystoreShouldReturnKeystoreWithGivenPrivateKeyAndCertificateChain() + throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, PemToPKCS12ConverterException { + // given + final String alias = "keystore-entry"; + final Password password = new Password("d9D_u8LooYaXH4G48DtN#vw0"); + final List<String> certificateChain = getCertificates(); + final PemToPKCS12Converter converter = new PemToPKCS12Converter(); + final KeyStore expectedKeyStore = KeyStore.getInstance(PKCS12); + expectedKeyStore.load(new ByteArrayInputStream(Files.readAllBytes(Path.of(EXPECTED_KEYSTORE_PATH))), + password.toCharArray()); + final Certificate[] expectedChain = expectedKeyStore.getCertificateChain(alias); + privateKeyMockSetup(); + + // when + final byte[] result = converter.convertKeystore(certificateChain, password, alias, privateKey); + + // then + final KeyStore actualKeyStore = KeyStore.getInstance(PKCS12); + actualKeyStore.load(new ByteArrayInputStream(result), password.toCharArray()); + final Certificate[] actualChain = actualKeyStore.getCertificateChain(alias); + + assertArrayEquals(key, actualKeyStore.getKey(alias, password.toCharArray()).getEncoded()); + assertEquals(2, expectedChain.length); + assertArrayEquals(expectedChain, actualChain); + } + + @Test + void convertKeystoreShouldThrowPemToPKCS12ConverterExceptionBecauseOfWrongPassword() throws IOException { + // given + final String alias = "keystore-entry"; + final Password password = new Password("apple"); + final List<String> certificateChain = getCertificates(); + final PemToPKCS12Converter converter = new PemToPKCS12Converter(); + privateKeyMockSetup(); + + // when + Exception exception = assertThrows(PemToPKCS12ConverterException.class, () -> + converter.convertKeystore(certificateChain, password, alias, privateKey) + ); + + // then + assertEquals(PASSWORD_ERROR_MSG, exception.getMessage()); + } + + @Test + void convertTruststoreShouldReturnTruststoreWithGivenCertificatesArray() + throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, PemToPKCS12ConverterException { + + // given + final PemToPKCS12Converter converter = new PemToPKCS12Converter(); + final String alias = "trusted-certificate-"; + final String alias1 = alias + 1; + final String alias2 = alias + 2; + final Password password = new Password("9z6oFx1epRSCuBWU4Er8i_0y"); + final List<String> trustedCertificates = getCertificates(); + final KeyStore expectedTrustStore = KeyStore.getInstance(PKCS12); + expectedTrustStore.load(new ByteArrayInputStream(Files.readAllBytes(Path.of(EXPECTED_TRUSTSTORE_PATH))), + password.toCharArray()); + + // when + final byte[] result = converter.convertTruststore(trustedCertificates, password, alias); + + // then + final KeyStore actualKeyStore = KeyStore.getInstance(PKCS12); + actualKeyStore.load(new ByteArrayInputStream(result), password.toCharArray()); + + assertTrue(actualKeyStore.containsAlias(alias1)); + assertTrue(actualKeyStore.containsAlias(alias2)); + assertEquals(expectedTrustStore.getCertificate(alias1), actualKeyStore.getCertificate(alias1)); + assertEquals(expectedTrustStore.getCertificate(alias2), actualKeyStore.getCertificate(alias2)); + } + + @Test + void convertTruststoreShouldThrowPemToPKCS12ConverterExceptionBecauseOfWrongPassword() throws IOException { + // given + final String alias = "trusted-certificate-"; + final Password password = new Password("nokia"); + final List<String> trustedCertificates = getCertificates(); + final PemToPKCS12Converter converter = new PemToPKCS12Converter(); + + // when then + assertThatThrownBy(() -> + converter.convertTruststore(trustedCertificates, password, alias)) + .isInstanceOf(PemToPKCS12ConverterException.class).hasMessage(PASSWORD_ERROR_MSG); + } + + @Test + void convertKeystoreShouldThrowPemToPKCS12ConverterExceptionBecauseOfWrongPrivateKey() throws IOException { + // given + final String alias = "keystore-entry"; + final Password password = new Password("d9D_u8LooYaXH4G48DtN#vw0"); + final List<String> certificateChain = getCertificates(); + final PemToPKCS12Converter converter = new PemToPKCS12Converter(); + + // when then + assertThatThrownBy(() -> converter.convertKeystore(certificateChain, password, alias, privateKey)) + .isInstanceOf(PemToPKCS12ConverterException.class).hasMessage(KEY_ERROR_MSG); + } + + @Test + void convertKeystoreShouldThrowPemToPKCS12ConverterExceptionBecauseOfWrongCertificates() { + // given + final String alias = "keystore-entry"; + final Password password = new Password("d9D_u8LooYaXH4G48DtN#vw0"); + final List<String> certificateChain = List.of("certificate1", "certificate2"); + final PemToPKCS12Converter converter = new PemToPKCS12Converter(); + privateKeyMockSetup(); + + // when then + assertThatThrownBy(() -> converter.convertKeystore(certificateChain, password, alias, privateKey)) + .isInstanceOf(PemToPKCS12ConverterException.class).hasMessage(CERTIFICATES_ERROR_MSG); + } + + private void privateKeyMockSetup() { + when(privateKey.getEncoded()).thenReturn(key); + when(privateKey.getAlgorithm()).thenReturn(EncryptionAlgorithmConstants.RSA_ENCRYPTION_ALGORITHM); + when(privateKey.getFormat()).thenReturn(PKCS8); + } + + private List<String> getCertificates() throws IOException { + return List.of( + Files.readString( + Path.of(CERT1_PATH), StandardCharsets.UTF_8), + Files.readString( + Path.of(CERT2_PATH), StandardCharsets.UTF_8) + ); + } +}
\ No newline at end of file diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGeneratorTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGeneratorTest.java new file mode 100644 index 00000000..169ce98a --- /dev/null +++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/certification/conversion/RandomPasswordGeneratorTest.java @@ -0,0 +1,32 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.certification.conversion; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + +class RandomPasswordGeneratorTest { + + @Test + void shouldGenerateRandomPasswordOfGivenLengthMatchingThePattern() { + Password password = new RandomPasswordGenerator().generate(24); + assertTrue(password.isCorrectPasswordPattern()); + } +}
\ No newline at end of file diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtilsTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtilsTest.java new file mode 100644 index 00000000..8f4fe6a3 --- /dev/null +++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/EnvValidationUtilsTest.java @@ -0,0 +1,41 @@ +/*============LICENSE_START======================================================= + * aaf-certservice-client + * ================================================================================ + * 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.aaf.certservice.client.configuration; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class EnvValidationUtilsTest { + + @ParameterizedTest + @ValueSource(strings = {"/var/log", "/", "/var/log/", "/second_var", "/second-var"}) + public void shouldAcceptValidPath(String path){ + assertTrue(EnvValidationUtils.isPathValid(path)); + } + + @ParameterizedTest + @ValueSource(strings = {"/var/log?", "", "var_", "var", "//", "/var//log"}) + public void shouldRejectInvalidPath(String path){ + assertFalse(EnvValidationUtils.isPathValid(path)); + } +}
\ No newline at end of file diff --git a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/CsrConfigurationFactoryTest.java b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/CsrConfigurationFactoryTest.java index 707094c0..bb566e81 100644 --- a/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/CsrConfigurationFactoryTest.java +++ b/certServiceClient/src/test/java/org/onap/aaf/certservice/client/configuration/model/CsrConfigurationFactoryTest.java @@ -20,13 +20,17 @@ package org.onap.aaf.certservice.client.configuration.model; +import org.assertj.core.api.Condition; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.onap.aaf.certservice.client.api.ExitCode; import org.onap.aaf.certservice.client.configuration.CsrConfigurationEnvs; import org.onap.aaf.certservice.client.configuration.EnvsForCsr; import org.onap.aaf.certservice.client.configuration.exception.CsrConfigurationException; import org.onap.aaf.certservice.client.configuration.factory.CsrConfigurationFactory; import java.util.Optional; +import java.util.function.Predicate; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -43,23 +47,30 @@ public class CsrConfigurationFactoryTest { private final String ORGANIZATION_UNIT_VALID = "ONAP"; private final String STATE_VALID = "California"; private final String COMMON_NAME_INVALID = "onap.org*&"; + private final String COUNTRY_INVALID = "PLA"; + private final String ORGANIZATION_INVALID = "Linux?Foundation"; private EnvsForCsr envsForCsr = mock(EnvsForCsr.class); - + private CsrConfigurationFactory testedFactory; + private Condition<CsrConfigurationException> expectedExitCodeCondition = new Condition<>("Correct exit code"){ + @Override + public boolean matches(CsrConfigurationException e) { + return e.applicationExitCode() == ExitCode.CSR_CONFIGURATION_EXCEPTION.getValue(); + } + }; + + @BeforeEach + void setUp() { + testedFactory = new CsrConfigurationFactory(envsForCsr); + } @Test - void create_shouldReturnSuccessWhenAllVariablesAreSetAndValid() throws CsrConfigurationException { + void shouldReturnCorrectConfiguration_WhenAllVariablesAreSetAndValid() throws CsrConfigurationException { // given - when(envsForCsr.getCommonName()).thenReturn(Optional.of(COMMON_NAME_VALID)); - when(envsForCsr.getSubjectAlternativesName()).thenReturn(Optional.of(SANS_VALID)); - when(envsForCsr.getCountry()).thenReturn(Optional.of(COUNTRY_VALID)); - when(envsForCsr.getLocation()).thenReturn(Optional.of(LOCATION_VALID)); - when(envsForCsr.getOrganization()).thenReturn(Optional.of(ORGANIZATION_VALID)); - when(envsForCsr.getOrganizationUnit()).thenReturn(Optional.of(ORGANIZATION_UNIT_VALID)); - when(envsForCsr.getState()).thenReturn(Optional.of(STATE_VALID)); + mockEnvsWithAllValidParameters(); // when - CsrConfiguration configuration = new CsrConfigurationFactory(envsForCsr).create(); + CsrConfiguration configuration = testedFactory.create(); // then assertThat(configuration.getCommonName()).isEqualTo(COMMON_NAME_VALID); @@ -72,15 +83,12 @@ public class CsrConfigurationFactoryTest { } @Test - void create_shouldReturnSuccessWhenNotRequiredVariablesAreNotSet() throws CsrConfigurationException { + void shouldReturnCorrectConfiguration_WhenNotRequiredVariablesAreNotSet() throws CsrConfigurationException { // given - when(envsForCsr.getCommonName()).thenReturn(Optional.of(COMMON_NAME_VALID)); - when(envsForCsr.getState()).thenReturn(Optional.of(STATE_VALID)); - when(envsForCsr.getCountry()).thenReturn(Optional.of(COUNTRY_VALID)); - when(envsForCsr.getOrganization()).thenReturn(Optional.of(ORGANIZATION_VALID)); + mockEnvsWithValidRequiredParameters(); // when - CsrConfiguration configuration = new CsrConfigurationFactory(envsForCsr).create(); + CsrConfiguration configuration = testedFactory.create(); // then assertThat(configuration.getCommonName()).isEqualTo(COMMON_NAME_VALID); @@ -91,22 +99,89 @@ public class CsrConfigurationFactoryTest { @Test - void create_shouldReturnCsrConfigurationExceptionWhenCommonNameContainsSpecialCharacters() { + void shouldThrowCsrConfigurationException_WhenCommonNameInvalid() { // given - when(envsForCsr.getCommonName()).thenReturn(Optional.of(COMMON_NAME_INVALID)); + mockEnvsWithInvalidCommonName(); + + // when/then + assertThatExceptionOfType(CsrConfigurationException.class) + .isThrownBy(testedFactory::create) + .withMessageContaining(CsrConfigurationEnvs.COMMON_NAME + " is invalid.") + .has(expectedExitCodeCondition); + } + + @Test + void shouldThrowCsrConfigurationException_WhenOrganizationInvalid() { + // given + mockEnvsWithInvalidOrganization(); + + // when/then + assertThatExceptionOfType(CsrConfigurationException.class) + .isThrownBy(testedFactory::create) + .withMessageContaining(CsrConfigurationEnvs.ORGANIZATION + " is invalid.") + .has(expectedExitCodeCondition); + + } + + @Test + void shouldThrowCsrConfigurationException_WhenCountryInvalid() { + // given + mockEnvsWithInvalidCountry(); + + // when/then + assertThatExceptionOfType(CsrConfigurationException.class) + .isThrownBy(testedFactory::create) + .withMessageContaining(CsrConfigurationEnvs.COUNTRY + " is invalid.") + .has(expectedExitCodeCondition); + + } + + @Test + void shouldThrowCsrConfigurationExceptionWhenStateInvalid() { + // given + mockEnvsWithInvalidState(); + // when/then + assertThatExceptionOfType(CsrConfigurationException.class) + .isThrownBy(testedFactory::create) + .withMessageContaining(CsrConfigurationEnvs.STATE + " is invalid.") + .has(expectedExitCodeCondition); + } + + private void mockEnvsWithAllValidParameters() { + mockEnvsWithValidRequiredParameters(); + mockEnvsWithValidOptionalParameters(); + } + + private void mockEnvsWithValidOptionalParameters() { + when(envsForCsr.getOrganizationUnit()).thenReturn(Optional.of(ORGANIZATION_UNIT_VALID)); + when(envsForCsr.getLocation()).thenReturn(Optional.of(LOCATION_VALID)); when(envsForCsr.getSubjectAlternativesName()).thenReturn(Optional.of(SANS_VALID)); + } + + private void mockEnvsWithValidRequiredParameters() { + when(envsForCsr.getCommonName()).thenReturn(Optional.of(COMMON_NAME_VALID)); when(envsForCsr.getCountry()).thenReturn(Optional.of(COUNTRY_VALID)); - when(envsForCsr.getLocation()).thenReturn(Optional.of(LOCATION_VALID)); when(envsForCsr.getOrganization()).thenReturn(Optional.of(ORGANIZATION_VALID)); - when(envsForCsr.getOrganizationUnit()).thenReturn(Optional.of(ORGANIZATION_UNIT_VALID)); - when(envsForCsr.getState()).thenReturn(Optional.of(SANS_VALID)); + when(envsForCsr.getState()).thenReturn(Optional.of(STATE_VALID)); + } - // when - CsrConfigurationFactory configurationFactory = new CsrConfigurationFactory(envsForCsr); + private void mockEnvsWithInvalidCommonName() { + mockEnvsWithAllValidParameters(); + when(envsForCsr.getCommonName()).thenReturn(Optional.of(COMMON_NAME_INVALID)); + } - // when/then - assertThatExceptionOfType(CsrConfigurationException.class) - .isThrownBy(configurationFactory::create) - .withMessageContaining(CsrConfigurationEnvs.COMMON_NAME + " is invalid."); + private void mockEnvsWithInvalidCountry() { + mockEnvsWithAllValidParameters(); + when(envsForCsr.getCountry()).thenReturn(Optional.of(COUNTRY_INVALID)); + } + + private void mockEnvsWithInvalidOrganization() { + mockEnvsWithAllValidParameters(); + when(envsForCsr.getOrganization()).thenReturn(Optional.of(ORGANIZATION_INVALID)); + } + + private void mockEnvsWithInvalidState() { + mockEnvsWithAllValidParameters(); + when(envsForCsr.getState()).thenReturn(Optional.empty()); } } diff --git a/certServiceClient/src/test/resources/cert1.pem b/certServiceClient/src/test/resources/cert1.pem new file mode 100644 index 00000000..cd5f3841 --- /dev/null +++ b/certServiceClient/src/test/resources/cert1.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDjDCCAnSgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwgYQxCzAJBgNVBAYTAlVT +MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkw +FwYDVQQKDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMR4wHAYDVQQD +DBVpbnRlcm1lZGlhdGUub25hcC5vcmcwHhcNMjAwMjEyMDk1MTI2WhcNMjIxMTA4 +MDk1MTI2WjB7MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG +A1UEBwwNU2FuLUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjEN +MAsGA1UECwwET05BUDEVMBMGA1UEAwwMdmlkLm9uYXAub3JnMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+GIRzJzUOh0gtc+wzFJEdTnn+q5F10L0Yhr +G1xKdjPieHIFGsoiXwcuCU8arNSqlz7ocx62KQRkcA8y6edlOAsYtdOEJvqEI9vc +eyTB/HYsbzw3URPGch4AmibrQkKU9QvGwouHtHn4R2Ft2Y0tfEqv9hxj9v4njq4A +EiDLAFLl5FmVyCZu/MtKngSgu1smcaFKTYySPMxytgJZexoa/ALZyyE0gRhsvwHm +NLGCPt1bmE/PEGZybsCqliyTO0S56ncD55The7+D/UDS4kE1Wg0svlWon/YsE6QW +B3oeJDX7Kr8ebDTIAErevIAD7Sm4ee5se2zxYrsYlj0MzHZtvwIDAQABoxAwDjAM +BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCvQ1pTvjON6vSlcJRKSY4r +8q7L4/9ZaVXWJAjzEYJtPIqsgGiPWz0vGfgklowU6tZxp9zRZFXfMil+mPQSe+yo +ULrZSQ/z48YHPueE/BNO/nT4aaVBEhPLR5aVwC7uQVX8H+m1V1UGT8lk9vdI9rej +CI9l524sLCpdE4dFXiWK2XHEZ0Vfylk221u3IYEogVVA+UMX7BFPSsOnI2vtYK/i +lwZtlri8LtTusNe4oiTkYyq+RSyDhtAswg8ANgvfHolhCHoLFj6w1IkG88UCmbwN +d7BoGMy06y5MJxyXEZG0vR7eNeLey0TIh+rAszAFPsIQvrOHW+HuA+WLQAj1mhnm +-----END CERTIFICATE----- diff --git a/certServiceClient/src/test/resources/cert2.pem b/certServiceClient/src/test/resources/cert2.pem new file mode 100644 index 00000000..92ebc821 --- /dev/null +++ b/certServiceClient/src/test/resources/cert2.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDqTCCApGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZcxCzAJBgNVBAYTAlVT +MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkw +FwYDVQQKDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMREwDwYDVQQD +DAhvbmFwLm9yZzEeMBwGCSqGSIb3DQEJARYPdGVzdGVyQG9uYXAub3JnMB4XDTIw +MDIxMjA5NDAxMloXDTIyMTEwODA5NDAxMlowgYQxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkwFwYDVQQK +DBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMR4wHAYDVQQDDBVpbnRl +cm1lZGlhdGUub25hcC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC1oOYMZ6G+2DGDAizYnzdCNiogivlht1s4oqgem7fM1XFPxD2p31ATIibOdqr/ +gv1qemO9Q4r1xn6w1Ufq7T1K7PjnMzdSeTqZefurE2JM/HHx2QvW4TjMlz2ILgaD +L1LN60kmMQSOi5VxKJpsrCQxbOsxhvefd212gny5AZMcjJe23kUd9OxUrtvpdLEv +wI3vFEvT7oRUnEUg/XNz7qeg33vf1C39yMR+6O4s6oevgsEebVKjb+yOoS6zzGtz +72wZjm07C54ZlO+4Uy+QAlMjRiU3mgWkKbkOy+4CvwehjhpTikdBs2DX39ZLGHhn +L/0a2NYtGulp9XEqmTvRoI+PAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggEBADcitdJ6YswiV8jAD9GK0gf3+zqcGegt4kt+79JXlXYbb1sY +q3o6prcB7nSUoClgF2xUPCslFGpM0Er9FCSFElQM/ru0l/KVmJS6kSpwEHvsYIH3 +q5anta+Pyk8JSQWAAw+qrind0uBQMnhR8Tn13tgV+Kjvg/xlH/nZIEdN5YtLB1cA +beVsZRyRfVL9DeZU8s/MZ5wC3kgcEp5A4m5lg7HyBxBdqhzFcDr6xiy6OGqW8Yep +xrwfc8Fw8a/lOv4U+tBeGNKPQDYaL9hh+oM+qMkNXsHXDqdJsuEGJtU4i3Wcwzoc +XGN5NWV//4bP+NFmwgcn7AYCdRvz04A8GU/0Cwg= +-----END CERTIFICATE----- diff --git a/certServiceClient/src/test/resources/expectedKeystore.jks b/certServiceClient/src/test/resources/expectedKeystore.jks Binary files differnew file mode 100644 index 00000000..95359b0e --- /dev/null +++ b/certServiceClient/src/test/resources/expectedKeystore.jks diff --git a/certServiceClient/src/test/resources/expectedTruststore.jks b/certServiceClient/src/test/resources/expectedTruststore.jks Binary files differnew file mode 100644 index 00000000..ab7d93d9 --- /dev/null +++ b/certServiceClient/src/test/resources/expectedTruststore.jks diff --git a/certServiceClient/src/test/resources/privateKey b/certServiceClient/src/test/resources/privateKey Binary files differnew file mode 100644 index 00000000..463a27d3 --- /dev/null +++ b/certServiceClient/src/test/resources/privateKey diff --git a/certServiceClient/src/test/resources/rsaPrivateKeyPem b/certServiceClient/src/test/resources/rsaPrivateKeyPem new file mode 100644 index 00000000..a99cc3c8 --- /dev/null +++ b/certServiceClient/src/test/resources/rsaPrivateKeyPem @@ -0,0 +1,28 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCwooLW/yfXHIGs +djOW6zCM6mzGq4ZkFr0LMVBE+Y9dckGsYJzCrfC4pQtFjcvTlwalu6/YOgieR/zY +bgVF7Ic0IYV+BssO+t6Zx2xYli4NIGc5kJgDrKtR6lWvH8AMnQEr+QiDElLBWobU ++QGn5v8A528Ow5yD1fmxKTqqvWS4v1rOShGCIdse5ViraGjnMFxOV6u6pGqa17v7 +dTh0XIUyF/o3aSbmBHXkmvQ4pu/K1ncsF2zHIqUWAc7j8y1u5uE5o8b+dUzkcS4t +QKfjFKP81I7XQNmpGZ8REzWyaYVk3RrMCju6iVgdKrs198Wif0b7wGswFv4BFhOp +2jceFUwfAgMBAAECggEABjDb9x8gTVjRbrMB4eNCY14ADAKNBksJuy+ySYiZrsPH +a3xDYktoaYBXYcuzfioH8J0gb6qxDKMnSIqqoqXEo14daKpiSZcfYDJuKLiyyoD9 +PTZFLbPKmWdmM2ogeBC0rs7eroFg5yf+G87ScQkWnPh/mvveK3y/cKcqSDu1IQh8 +3b8KQshC5g4iBqCfOMW3ASF03M4zmM3brKMWsdsAWEbFHQ34H10FXTHrAINpWIZK +s2NL3z9tK6hXrwlZdKH6R/JWczSO7O5MBjLfeXZK7q3Tw4qtFWWjcNwfPlUZKMAS +3fZFamFwY//qW+0yuCO59o70d9Pjm6p0DWsfOs9t8QKBgQD1iRdGV4xZXZT9Q4Wh +LQMnChjuNHcmhdBYbmC03j3AffQwkQ1dKt++9uWYdy9dO9v1w7aygAMQI36jkDvR +UJ1Rnmt9gQpeOL/wHP3R0uHbTtxLeGnX3Oo1Yx7Wfl98rq4mmBxjO5Lgft/6kTgz +XgeiNDWi53KwDEOoFaZhWihZ6QKBgQC4Ka5Hc9wXD/5utpvNs5ut+9zjY0kx6kr8 +SyDZExbVR1ohtvSQ2sd2JvZPyFS0VbvYfFPhyCYcWW9LDEX168CZT5aHgcNop1Iu +Szq8nYrljFa5Ibdlpf0qxC6JgObC2XytUR0O7BaXHBWpl0/wLpLTcfU2wTDLRoH8 +JLu7P3MoxwKBgQCI9DWqQ60CL8Op3J7NvviyLtynCVaogx0qJi8E062oD9lDubS1 +kfOJZde8ykX+ACR5mffu6p5KwzGg9BOZdhi57N5R+8cXtRnCSbl97t2R4RPZeMm4 +4P02WBpcU9LZDeoPlurGovUTCVHPRm8Nn9YsMGj2e5ip/71BJQpP5OT6+QKBgQCP +NYJb+AG3QW22hHQmArxWEFxVyrh5g1sqU/XIOCryUVkKjK4kEq02+NdjdUJBNcYs +c4n7MlxIgVelQXcJ5HlR/uzslQDy2eJzM3cKg2wmUvqBXnGyLuDvJ72UmdNYxC1K +zZ/OIdLzURibV5oHCQCOQrjQCm06NasQ+zOtSYrwswKBgQCUHhgxynFNyidxPFzX +V0X5xCbJ3jvJNjZFRsItQ97vEAkfJqxCnOZKMti0JWSlLBEViaKnqaA+ZE/SeJ/k +Jut5h9gu4QIdeF4mf9v3tjuEQP7RaMCD6xnFZnebkQf6wlZz5VaXME4ICpi1Cnk7 +DySS9CMoRnwdwY7hAbfPtupKDA== +-----END RSA PRIVATE KEY----- @@ -53,6 +53,7 @@ <springdoc-openapi-maven-plugin.version>0.2</springdoc-openapi-maven-plugin.version> <gson.version>2.8.6</gson.version> <httpcomponents.version>4.5.6</httpcomponents.version> + <commons-lang3.version>3.9</commons-lang3.version> <commons-io.version>2.6</commons-io.version> <docker-maven-plugin.version>0.33.0</docker-maven-plugin.version> <junit.version>5.5.2</junit.version> @@ -235,6 +236,11 @@ <version>${httpcomponents.version}</version> </dependency> <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <version>${commons-lang3.version}</version> + </dependency> + <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>${commons-io.version}</version> @@ -257,13 +263,7 @@ </dependency> <dependency> <groupId>org.junit.jupiter</groupId> - <artifactId>junit-jupiter-engine</artifactId> - <version>${junit.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.junit.jupiter</groupId> - <artifactId>junit-jupiter-api</artifactId> + <artifactId>junit-jupiter</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> |