2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.vendorsoftwareproduct.security;
23 import static junit.framework.TestCase.assertEquals;
24 import static junit.framework.TestCase.assertTrue;
25 import static org.mockito.ArgumentMatchers.any;
26 import static org.mockito.ArgumentMatchers.anyBoolean;
27 import static org.mockito.ArgumentMatchers.anyInt;
28 import static org.mockito.ArgumentMatchers.anyString;
29 import static org.mockito.ArgumentMatchers.eq;
30 import static org.mockito.Mockito.when;
31 import static org.mockito.MockitoAnnotations.openMocks;
32 import static org.openecomp.sdc.be.csar.storage.StorageFactory.StorageType.MINIO;
34 import io.minio.GetObjectArgs;
35 import io.minio.GetObjectResponse;
36 import io.minio.MinioClient;
37 import java.io.BufferedInputStream;
38 import java.io.ByteArrayInputStream;
40 import java.io.IOException;
41 import java.net.URISyntaxException;
42 import java.nio.file.Files;
43 import java.nio.file.Paths;
44 import java.util.HashMap;
46 import org.apache.commons.io.FileUtils;
47 import org.junit.jupiter.api.AfterEach;
48 import org.junit.jupiter.api.Assertions;
49 import org.junit.jupiter.api.BeforeEach;
50 import org.junit.jupiter.api.Test;
51 import org.junit.jupiter.api.extension.ExtendWith;
52 import org.mockito.Answers;
53 import org.mockito.Mock;
54 import org.mockito.MockedStatic;
55 import org.mockito.Mockito;
56 import org.mockito.junit.jupiter.MockitoExtension;
57 import org.openecomp.sdc.be.csar.storage.MinIoArtifactInfo;
58 import org.openecomp.sdc.common.CommonConfigurationManager;
59 import org.openecomp.sdc.vendorsoftwareproduct.impl.onboarding.OnboardingPackageProcessor;
60 import org.openecomp.sdc.vendorsoftwareproduct.impl.onboarding.validation.CnfPackageValidator;
61 import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardPackageInfo;
62 import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardSignedPackage;
64 @ExtendWith(MockitoExtension.class)
65 class SecurityManagerTest {
68 private String cerDirPath = "/tmp/cert/";
69 private SecurityManager securityManager;
71 private CommonConfigurationManager commonConfigurationManager;
73 private MinioClient minioClient;
74 @Mock(answer = Answers.RETURNS_DEEP_STUBS)
75 private MinioClient.Builder builderMinio;
76 @Mock(answer = Answers.RETURNS_DEEP_STUBS)
77 private GetObjectArgs.Builder getObjectArgsBuilder;
79 private GetObjectArgs getObjectArgs;
81 private File prepareCertFiles(String origFilePath, String newFilePath) throws IOException, URISyntaxException {
82 File origFile = new File(getClass().getResource(origFilePath).toURI());
83 File newFile = new File(newFilePath);
84 newFile.createNewFile();
85 FileUtils.copyFile(origFile, newFile);
89 private byte[] readAllBytes(String path) throws URISyntaxException, IOException {
90 return Files.readAllBytes(Paths.get(getClass().getResource(path).toURI()));
94 public void setUp() throws IOException {
96 certDir = new File(cerDirPath);
97 if (certDir.exists()) {
101 securityManager = new SecurityManager(certDir.getPath());
106 public void tearDown() throws IOException {
107 if (certDir.exists()) {
108 FileUtils.deleteDirectory(certDir);
110 securityManager.cleanTrustedCertificates();
114 void testGetCertificates() throws IOException, SecurityManagerException, URISyntaxException {
115 File newFile = prepareCertFiles("/cert/root-certificate.pem", cerDirPath + "/root-certificate.pem");
116 assertEquals(1, securityManager.getTrustedCertificates().size());
118 assertEquals(0, securityManager.getTrustedCertificates().size());
122 void testGetCertificatesNoDirectory() throws IOException, SecurityManagerException {
124 assertEquals(0, securityManager.getTrustedCertificates().size());
128 void testGetCertificatesException() throws IOException, SecurityManagerException {
129 File newFile = new File(cerDirPath + "root-certificate.pem");
130 newFile.createNewFile();
131 Assertions.assertThrows(SecurityManagerException.class, () -> {
132 assertEquals(1, securityManager.getTrustedCertificates().size());
135 assertEquals(0, securityManager.getTrustedCertificates().size());
140 void testGetCertificatesUpdated() throws IOException, SecurityManagerException, URISyntaxException {
141 File newFile = prepareCertFiles("/cert/root-certificate.pem", cerDirPath + "root-certificate.pem");
142 assertEquals(1, securityManager.getTrustedCertificates().size());
143 File otherNewFile = prepareCertFiles("/cert/package-certificate.pem", cerDirPath + "package-certificate.pem");
144 assertEquals(2, securityManager.getTrustedCertificates().size());
145 otherNewFile.delete();
146 assertEquals(1, securityManager.getTrustedCertificates().size());
148 assertEquals(0, securityManager.getTrustedCertificates().size());
152 void verifySignedDataTestCertIncludedIntoSignature() throws IOException, URISyntaxException, SecurityManagerException {
153 prepareCertFiles("/cert/rootCA.cert", cerDirPath + "root.cert");
154 byte[] signature = readAllBytes("/cert/2-file-signed-package/dummyPnfv4.cms");
155 byte[] archive = readAllBytes("/cert/2-file-signed-package/dummyPnfv4.csar");
156 assertTrue(securityManager.verifySignedData(signature, null, archive));
160 void verifySignedDataTestCertIncludedIntoSignatureArtifactStorageManagerIsEnabled() throws Exception {
162 final Map<String, Object> endpoint = new HashMap<>();
163 endpoint.put("host", "localhost");
164 endpoint.put("port", 9000);
165 final Map<String, Object> credentials = new HashMap<>();
166 credentials.put("accessKey", "login");
167 credentials.put("secretKey", "password");
169 try (MockedStatic<CommonConfigurationManager> utilities = Mockito.mockStatic(CommonConfigurationManager.class)) {
170 utilities.when(CommonConfigurationManager::getInstance).thenReturn(commonConfigurationManager);
171 try (MockedStatic<MinioClient> minioUtilities = Mockito.mockStatic(MinioClient.class)) {
172 minioUtilities.when(MinioClient::builder).thenReturn(builderMinio);
174 .endpoint(anyString(), anyInt(), anyBoolean())
175 .credentials(anyString(), anyString())
177 ).thenReturn(minioClient);
179 when(commonConfigurationManager.getConfigValue("externalCsarStore", "endpoint", null)).thenReturn(endpoint);
180 when(commonConfigurationManager.getConfigValue("externalCsarStore", "credentials", null)).thenReturn(credentials);
181 when(commonConfigurationManager.getConfigValue("externalCsarStore", "tempPath", null)).thenReturn("cert/2-file-signed-package");
182 when(commonConfigurationManager.getConfigValue(eq("externalCsarStore"), eq("storageType"), any())).thenReturn(MINIO.name());
184 prepareCertFiles("/cert/rootCA.cert", cerDirPath + "root.cert");
185 byte[] fileToUploadBytes = readAllBytes("/cert/2-file-signed-package/2-file-signed-package.zip");
186 when(getObjectArgsBuilder
190 ).thenReturn(getObjectArgs);
192 when(minioClient.getObject(any(GetObjectArgs.class)))
193 .thenReturn(new GetObjectResponse(null, "bucket", "", "objectName",
194 new BufferedInputStream(new ByteArrayInputStream(fileToUploadBytes))));
196 final var onboardingPackageProcessor = new OnboardingPackageProcessor("2-file-signed-package.zip", fileToUploadBytes,
197 new CnfPackageValidator(), new MinIoArtifactInfo("bucket", "objectName"));
198 final OnboardPackageInfo onboardPackageInfo = onboardingPackageProcessor.getOnboardPackageInfo().orElse(null);
200 assertTrue(securityManager
201 .verifyPackageSignedData((OnboardSignedPackage) onboardPackageInfo.getOriginalOnboardPackage(),
202 onboardPackageInfo.getArtifactInfo()));
208 void verifySignedDataTestCertNotIncludedIntoSignatureButExpected() throws IOException, URISyntaxException, SecurityManagerException {
209 Assertions.assertThrows(SecurityManagerException.class, () -> {
210 prepareCertFiles("/cert/root.cert", cerDirPath + "root.cert");
211 byte[] signature = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cms");
212 byte[] archive = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.csar");
213 securityManager.verifySignedData(signature, null, archive);
219 void verifySignedDataTestCertNotIncludedIntoSignature() throws IOException, URISyntaxException, SecurityManagerException {
220 prepareCertFiles("/cert/rootCA.cert", cerDirPath + "root.cert");
221 byte[] signature = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cms");
222 byte[] archive = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.csar");
223 byte[] cert = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cert");
224 assertTrue(securityManager.verifySignedData(signature, cert, archive));
228 void verifySignedDataTestCertNotIncludedIntoSignatureArtifactStorageManagerIsEnabled() throws Exception {
230 final Map<String, Object> endpoint = new HashMap<>();
231 endpoint.put("host", "localhost");
232 endpoint.put("port", 9000);
233 final Map<String, Object> credentials = new HashMap<>();
234 credentials.put("accessKey", "login");
235 credentials.put("secretKey", "password");
237 try (MockedStatic<CommonConfigurationManager> utilities = Mockito.mockStatic(CommonConfigurationManager.class)) {
238 utilities.when(CommonConfigurationManager::getInstance).thenReturn(commonConfigurationManager);
239 try (MockedStatic<MinioClient> minioUtilities = Mockito.mockStatic(MinioClient.class)) {
240 minioUtilities.when(MinioClient::builder).thenReturn(builderMinio);
242 .endpoint(anyString(), anyInt(), anyBoolean())
243 .credentials(anyString(), anyString())
245 ).thenReturn(minioClient);
247 when(commonConfigurationManager.getConfigValue("externalCsarStore", "endpoint", null)).thenReturn(endpoint);
248 when(commonConfigurationManager.getConfigValue("externalCsarStore", "credentials", null)).thenReturn(credentials);
249 when(commonConfigurationManager.getConfigValue("externalCsarStore", "tempPath", null)).thenReturn("tempPath");
250 when(commonConfigurationManager.getConfigValue(eq("externalCsarStore"), eq("storageType"), any())).thenReturn(MINIO.name());
252 prepareCertFiles("/cert/rootCA.cert", cerDirPath + "root.cert");
253 byte[] fileToUploadBytes = readAllBytes("/cert/3-file-signed-package/3-file-signed-package.zip");
254 when(getObjectArgsBuilder
258 ).thenReturn(getObjectArgs);
260 when(minioClient.getObject(any(GetObjectArgs.class)))
261 .thenReturn(new GetObjectResponse(null, "bucket", "", "objectName",
262 new BufferedInputStream(new ByteArrayInputStream(fileToUploadBytes))));
264 final var onboardingPackageProcessor = new OnboardingPackageProcessor("3-file-signed-package.zip", fileToUploadBytes,
265 new CnfPackageValidator(), new MinIoArtifactInfo("bucket", "objectName"));
266 final OnboardPackageInfo onboardPackageInfo = onboardingPackageProcessor.getOnboardPackageInfo().orElse(null);
268 assertTrue(securityManager
269 .verifyPackageSignedData((OnboardSignedPackage) onboardPackageInfo.getOriginalOnboardPackage(),
270 onboardPackageInfo.getArtifactInfo()));
276 void verifySignedDataTestCertIntermediateNotIncludedIntoSignature() throws IOException, URISyntaxException, SecurityManagerException {
277 prepareCertFiles("/cert/rootCA.cert", cerDirPath + "root.cert");
278 prepareCertFiles("/cert/package2.cert", cerDirPath + "signing-ca2.crt");
279 byte[] signature = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cms");
280 byte[] archive = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.csar");
281 byte[] cert = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cert");
282 assertTrue(securityManager.verifySignedData(signature, cert, archive));
286 void verifySignedDataTestCertWrongIntermediate() throws IOException, URISyntaxException, SecurityManagerException {
287 Assertions.assertThrows(SecurityManagerException.class, () -> {
288 prepareCertFiles("/cert/root.cert", cerDirPath + "root.cert");
289 prepareCertFiles("/cert/signing-ca1.crt", cerDirPath + "signing-ca1.crt");
290 byte[] signature = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cms");
291 byte[] archive = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.csar");
292 byte[] cert = readAllBytes("/cert/3-file-signed-package/dummyPnfv4-no-intermediate.cert");
293 securityManager.verifySignedData(signature, cert, archive);
299 void verifySignedDataTestCertIncludedIntoSignatureWithWrongIntermediateInDirectory()
300 throws IOException, URISyntaxException, SecurityManagerException {
301 prepareCertFiles("/cert/rootCA.cert", cerDirPath + "root.cert");
302 prepareCertFiles("/cert/signing-ca1.crt", cerDirPath + "signing-ca1.crt");
303 byte[] signature = readAllBytes("/cert/2-file-signed-package/dummyPnfv4.cms");
304 byte[] archive = readAllBytes("/cert/2-file-signed-package/dummyPnfv4.csar");
305 assertTrue(securityManager.verifySignedData(signature, null, archive));
309 void verifySignedDataTestCertWrongIntermediateInDirectory() throws IOException, URISyntaxException, SecurityManagerException {
310 prepareCertFiles("/cert/rootCA.cert", cerDirPath + "root.cert");
311 prepareCertFiles("/cert/signing-ca1.crt", cerDirPath + "signing-ca1.crt");
312 byte[] signature = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cms");
313 byte[] archive = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.csar");
314 byte[] cert = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cert");
315 assertTrue(securityManager.verifySignedData(signature, cert, archive));
319 void verifySignedDataTestWrongCertificate() throws IOException, URISyntaxException, SecurityManagerException {
320 Assertions.assertThrows(SecurityManagerException.class, () -> {
321 prepareCertFiles("/cert/root-certificate.pem", cerDirPath + "root-certificate.cert");
322 byte[] signature = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cms");
323 byte[] archive = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.csar");
324 byte[] cert = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cert");
325 securityManager.verifySignedData(signature, cert, archive);
331 void verifySignedDataTestChangedArchive() throws IOException, URISyntaxException, SecurityManagerException {
332 Assertions.assertThrows(SecurityManagerException.class, () -> {
333 prepareCertFiles("/cert/root.cert", cerDirPath + "root.cert");
334 byte[] signature = readAllBytes("/cert/tampered-signed-package/dummyPnfv4.cms");
335 byte[] archive = readAllBytes("/cert/tampered-signed-package/dummyPnfv4.csar");
336 securityManager.verifySignedData(signature, null, archive);