1 /*============LICENSE_START=======================================================
2 * aaf-certservice-client
3 * ================================================================================
4 * Copyright (C) 2020 Nokia. All rights reserved.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 * ============LICENSE_END=========================================================
20 package org.onap.aaf.certservice.client.certification.conversion;
22 import org.junit.jupiter.api.BeforeAll;
23 import org.junit.jupiter.api.Test;
24 import org.junit.jupiter.params.ParameterizedTest;
25 import org.junit.jupiter.params.provider.ValueSource;
26 import org.onap.aaf.certservice.client.certification.EncryptionAlgorithmConstants;
27 import org.onap.aaf.certservice.client.certification.exception.PemConversionException;
29 import java.io.ByteArrayInputStream;
30 import java.io.IOException;
31 import java.nio.charset.StandardCharsets;
32 import java.nio.file.Files;
33 import java.nio.file.Path;
34 import java.security.KeyStore;
35 import java.security.KeyStoreException;
36 import java.security.NoSuchAlgorithmException;
37 import java.security.PrivateKey;
38 import java.security.UnrecoverableKeyException;
39 import java.security.cert.Certificate;
40 import java.security.cert.CertificateException;
41 import java.util.List;
43 import static org.assertj.core.api.Assertions.assertThatThrownBy;
44 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
45 import static org.junit.jupiter.api.Assertions.assertEquals;
46 import static org.junit.jupiter.api.Assertions.assertThrows;
47 import static org.junit.jupiter.api.Assertions.assertTrue;
48 import static org.mockito.Mockito.mock;
49 import static org.mockito.Mockito.when;
51 class PemConverterTest {
53 private static final String RESOURCES_PATH = "src/test/resources";
54 private static final String CERT1_PATH = RESOURCES_PATH + "/cert1.pem";
55 private static final String CERT2_PATH = RESOURCES_PATH + "/cert2.pem";
56 private static final String KEY_PATH = RESOURCES_PATH + "/privateKey";
57 private static final String EXPECTED_KEYSTORE_PATH = RESOURCES_PATH + "/expectedKeystore.jks";
58 private static final String EXPECTED_TRUSTSTORE_PATH = RESOURCES_PATH + "/expectedTruststore.jks";
59 private static final String PKCS12 = "PKCS12";
60 private static final String PKCS8 = "PKCS#8";
61 private static final String JKS = "JKS";
62 private static final String KEY_ERROR_MSG = "java.security.KeyStoreException: Key protection algorithm not found: java.lang.NullPointerException";
63 private static final String CERTIFICATES_ERROR_MSG = "The certificate couldn't be parsed correctly. certificate1";
64 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 (#)";
65 private static byte[] key;
66 private PrivateKey privateKey = mock(PrivateKey.class);
69 static void setUpForAll() throws IOException {
70 key = Files.readAllBytes(Path.of(KEY_PATH));
74 @ValueSource(strings = {PKCS12, JKS})
75 void convertKeystoreShouldReturnKeystoreWithGivenPrivateKeyAndCertificateChain(String conversionTarget)
76 throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, PemConversionException {
78 final String alias = "keystore-entry";
79 final Password password = new Password("d9D_u8LooYaXH4G48DtN#vw0");
80 final List<String> certificateChain = getCertificates();
81 final PemConverter converter = new PemConverter(conversionTarget);
82 final KeyStore expectedKeyStore = KeyStore.getInstance(conversionTarget);
83 expectedKeyStore.load(new ByteArrayInputStream(Files.readAllBytes(Path.of(EXPECTED_KEYSTORE_PATH))),
84 password.toCharArray());
85 final Certificate[] expectedChain = expectedKeyStore.getCertificateChain(alias);
86 privateKeyMockSetup();
89 final byte[] result = converter.convertKeystore(certificateChain, password, alias, privateKey);
92 final KeyStore actualKeyStore = KeyStore.getInstance(conversionTarget);
93 actualKeyStore.load(new ByteArrayInputStream(result), password.toCharArray());
94 final Certificate[] actualChain = actualKeyStore.getCertificateChain(alias);
96 assertArrayEquals(key, actualKeyStore.getKey(alias, password.toCharArray()).getEncoded());
97 assertEquals(2, expectedChain.length);
98 assertArrayEquals(expectedChain, actualChain);
102 @ValueSource(strings = {PKCS12, JKS})
103 void convertKeystoreShouldThrowPemConverterExceptionBecauseOfWrongPassword(String conversionTarget) throws IOException {
105 final String alias = "keystore-entry";
106 final Password password = new Password("apple");
107 final List<String> certificateChain = getCertificates();
108 final PemConverter converter = new PemConverter(conversionTarget);
109 privateKeyMockSetup();
112 Exception exception = assertThrows(PemConversionException.class, () ->
113 converter.convertKeystore(certificateChain, password, alias, privateKey)
117 assertEquals(PASSWORD_ERROR_MSG, exception.getMessage());
121 @ValueSource(strings = {PKCS12, JKS})
122 void convertTruststoreShouldReturnTruststoreWithGivenCertificatesArray(String conversionTarget)
123 throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, PemConversionException {
126 final PemConverter converter = new PemConverter(conversionTarget);
127 final String alias = "trusted-certificate-";
128 final String alias1 = alias + 1;
129 final String alias2 = alias + 2;
130 final Password password = new Password("9z6oFx1epRSCuBWU4Er8i_0y");
131 final List<String> trustedCertificates = getCertificates();
132 final KeyStore expectedTrustStore = KeyStore.getInstance(conversionTarget);
133 expectedTrustStore.load(new ByteArrayInputStream(Files.readAllBytes(Path.of(EXPECTED_TRUSTSTORE_PATH))),
134 password.toCharArray());
137 final byte[] result = converter.convertTruststore(trustedCertificates, password, alias);
140 final KeyStore actualKeyStore = KeyStore.getInstance(conversionTarget);
141 actualKeyStore.load(new ByteArrayInputStream(result), password.toCharArray());
143 assertTrue(actualKeyStore.containsAlias(alias1));
144 assertTrue(actualKeyStore.containsAlias(alias2));
145 assertEquals(expectedTrustStore.getCertificate(alias1), actualKeyStore.getCertificate(alias1));
146 assertEquals(expectedTrustStore.getCertificate(alias2), actualKeyStore.getCertificate(alias2));
150 @ValueSource(strings = {PKCS12, JKS})
151 void convertTruststoreShouldThrowPemConverterExceptionBecauseOfWrongPassword(String conversionTarget) throws IOException {
153 final String alias = "trusted-certificate-";
154 final Password password = new Password("nokia");
155 final List<String> trustedCertificates = getCertificates();
156 final PemConverter converter = new PemConverter(conversionTarget);
159 assertThatThrownBy(() ->
160 converter.convertTruststore(trustedCertificates, password, alias))
161 .isInstanceOf(PemConversionException.class).hasMessage(PASSWORD_ERROR_MSG);
165 void convertKeystoreShouldThrowPemConverterExceptionBecauseOfWrongPrivateKey() throws IOException {
167 final String alias = "keystore-entry";
168 final Password password = new Password("d9D_u8LooYaXH4G48DtN#vw0");
169 final List<String> certificateChain = getCertificates();
170 final PemConverter converter = new PemConverter(PKCS12);
173 assertThatThrownBy(() -> converter.convertKeystore(certificateChain, password, alias, privateKey))
174 .isInstanceOf(PemConversionException.class).hasMessage(KEY_ERROR_MSG);
178 @ValueSource(strings = {PKCS12, JKS})
179 void convertKeystoreShouldThrowPemConverterExceptionBecauseOfWrongCertificates(String conversionTarget) {
181 final String alias = "keystore-entry";
182 final Password password = new Password("d9D_u8LooYaXH4G48DtN#vw0");
183 final List<String> certificateChain = List.of("certificate1", "certificate2");
184 final PemConverter converter = new PemConverter(conversionTarget);
185 privateKeyMockSetup();
188 assertThatThrownBy(() -> converter.convertKeystore(certificateChain, password, alias, privateKey))
189 .isInstanceOf(PemConversionException.class).hasMessage(CERTIFICATES_ERROR_MSG);
192 private void privateKeyMockSetup() {
193 when(privateKey.getEncoded()).thenReturn(key);
194 when(privateKey.getAlgorithm()).thenReturn(EncryptionAlgorithmConstants.RSA_ENCRYPTION_ALGORITHM);
195 when(privateKey.getFormat()).thenReturn(PKCS8);
198 private List<String> getCertificates() throws IOException {
201 Path.of(CERT1_PATH), StandardCharsets.UTF_8),
203 Path.of(CERT2_PATH), StandardCharsets.UTF_8)