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());
183 when(commonConfigurationManager.getConfigValue(eq("externalCsarStore"), eq("uploadPartSize"), any())).thenReturn(50_000_000);
185 prepareCertFiles("/cert/rootCA.cert", cerDirPath + "root.cert");
186 byte[] fileToUploadBytes = readAllBytes("/cert/2-file-signed-package/2-file-signed-package.zip");
187 when(getObjectArgsBuilder
191 ).thenReturn(getObjectArgs);
193 when(minioClient.getObject(any(GetObjectArgs.class)))
194 .thenReturn(new GetObjectResponse(null, "bucket", "", "objectName",
195 new BufferedInputStream(new ByteArrayInputStream(fileToUploadBytes))));
197 final var onboardingPackageProcessor = new OnboardingPackageProcessor("2-file-signed-package.zip", fileToUploadBytes,
198 new CnfPackageValidator(), new MinIoArtifactInfo("bucket", "objectName"));
199 final OnboardPackageInfo onboardPackageInfo = onboardingPackageProcessor.getOnboardPackageInfo().orElse(null);
201 assertTrue(securityManager
202 .verifyPackageSignedData((OnboardSignedPackage) onboardPackageInfo.getOriginalOnboardPackage(),
203 onboardPackageInfo.getArtifactInfo()));
209 void verifySignedDataTestCertNotIncludedIntoSignatureButExpected() throws IOException, URISyntaxException, SecurityManagerException {
210 Assertions.assertThrows(SecurityManagerException.class, () -> {
211 prepareCertFiles("/cert/root.cert", cerDirPath + "root.cert");
212 byte[] signature = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cms");
213 byte[] archive = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.csar");
214 securityManager.verifySignedData(signature, null, archive);
220 void verifySignedDataTestCertNotIncludedIntoSignature() throws IOException, URISyntaxException, SecurityManagerException {
221 prepareCertFiles("/cert/rootCA.cert", cerDirPath + "root.cert");
222 byte[] signature = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cms");
223 byte[] archive = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.csar");
224 byte[] cert = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cert");
225 assertTrue(securityManager.verifySignedData(signature, cert, archive));
229 void verifySignedDataTestCertNotIncludedIntoSignatureArtifactStorageManagerIsEnabled() throws Exception {
231 final Map<String, Object> endpoint = new HashMap<>();
232 endpoint.put("host", "localhost");
233 endpoint.put("port", 9000);
234 final Map<String, Object> credentials = new HashMap<>();
235 credentials.put("accessKey", "login");
236 credentials.put("secretKey", "password");
238 try (MockedStatic<CommonConfigurationManager> utilities = Mockito.mockStatic(CommonConfigurationManager.class)) {
239 utilities.when(CommonConfigurationManager::getInstance).thenReturn(commonConfigurationManager);
240 try (MockedStatic<MinioClient> minioUtilities = Mockito.mockStatic(MinioClient.class)) {
241 minioUtilities.when(MinioClient::builder).thenReturn(builderMinio);
243 .endpoint(anyString(), anyInt(), anyBoolean())
244 .credentials(anyString(), anyString())
246 ).thenReturn(minioClient);
248 when(commonConfigurationManager.getConfigValue("externalCsarStore", "endpoint", null)).thenReturn(endpoint);
249 when(commonConfigurationManager.getConfigValue("externalCsarStore", "credentials", null)).thenReturn(credentials);
250 when(commonConfigurationManager.getConfigValue("externalCsarStore", "tempPath", null)).thenReturn("tempPath");
251 when(commonConfigurationManager.getConfigValue(eq("externalCsarStore"), eq("storageType"), any())).thenReturn(MINIO.name());
252 when(commonConfigurationManager.getConfigValue(eq("externalCsarStore"), eq("uploadPartSize"), any())).thenReturn(50_000_000);
254 prepareCertFiles("/cert/rootCA.cert", cerDirPath + "root.cert");
255 byte[] fileToUploadBytes = readAllBytes("/cert/3-file-signed-package/3-file-signed-package.zip");
256 when(getObjectArgsBuilder
260 ).thenReturn(getObjectArgs);
262 when(minioClient.getObject(any(GetObjectArgs.class)))
263 .thenReturn(new GetObjectResponse(null, "bucket", "", "objectName",
264 new BufferedInputStream(new ByteArrayInputStream(fileToUploadBytes))));
266 final var onboardingPackageProcessor = new OnboardingPackageProcessor("3-file-signed-package.zip", fileToUploadBytes,
267 new CnfPackageValidator(), new MinIoArtifactInfo("bucket", "objectName"));
268 final OnboardPackageInfo onboardPackageInfo = onboardingPackageProcessor.getOnboardPackageInfo().orElse(null);
270 assertTrue(securityManager
271 .verifyPackageSignedData((OnboardSignedPackage) onboardPackageInfo.getOriginalOnboardPackage(),
272 onboardPackageInfo.getArtifactInfo()));
278 void verifySignedDataTestCertIntermediateNotIncludedIntoSignature() throws IOException, URISyntaxException, SecurityManagerException {
279 prepareCertFiles("/cert/rootCA.cert", cerDirPath + "root.cert");
280 prepareCertFiles("/cert/package2.cert", cerDirPath + "signing-ca2.crt");
281 byte[] signature = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cms");
282 byte[] archive = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.csar");
283 byte[] cert = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cert");
284 assertTrue(securityManager.verifySignedData(signature, cert, archive));
288 void verifySignedDataTestCertWrongIntermediate() throws IOException, URISyntaxException, SecurityManagerException {
289 Assertions.assertThrows(SecurityManagerException.class, () -> {
290 prepareCertFiles("/cert/root.cert", cerDirPath + "root.cert");
291 prepareCertFiles("/cert/signing-ca1.crt", cerDirPath + "signing-ca1.crt");
292 byte[] signature = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cms");
293 byte[] archive = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.csar");
294 byte[] cert = readAllBytes("/cert/3-file-signed-package/dummyPnfv4-no-intermediate.cert");
295 securityManager.verifySignedData(signature, cert, archive);
301 void verifySignedDataTestCertIncludedIntoSignatureWithWrongIntermediateInDirectory()
302 throws IOException, URISyntaxException, SecurityManagerException {
303 prepareCertFiles("/cert/rootCA.cert", cerDirPath + "root.cert");
304 prepareCertFiles("/cert/signing-ca1.crt", cerDirPath + "signing-ca1.crt");
305 byte[] signature = readAllBytes("/cert/2-file-signed-package/dummyPnfv4.cms");
306 byte[] archive = readAllBytes("/cert/2-file-signed-package/dummyPnfv4.csar");
307 assertTrue(securityManager.verifySignedData(signature, null, archive));
311 void verifySignedDataTestCertWrongIntermediateInDirectory() throws IOException, URISyntaxException, SecurityManagerException {
312 prepareCertFiles("/cert/rootCA.cert", cerDirPath + "root.cert");
313 prepareCertFiles("/cert/signing-ca1.crt", cerDirPath + "signing-ca1.crt");
314 byte[] signature = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cms");
315 byte[] archive = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.csar");
316 byte[] cert = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cert");
317 assertTrue(securityManager.verifySignedData(signature, cert, archive));
321 void verifySignedDataTestWrongCertificate() throws IOException, URISyntaxException, SecurityManagerException {
322 Assertions.assertThrows(SecurityManagerException.class, () -> {
323 prepareCertFiles("/cert/root-certificate.pem", cerDirPath + "root-certificate.cert");
324 byte[] signature = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cms");
325 byte[] archive = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.csar");
326 byte[] cert = readAllBytes("/cert/3-file-signed-package/dummyPnfv4.cert");
327 securityManager.verifySignedData(signature, cert, archive);
333 void verifySignedDataTestChangedArchive() throws IOException, URISyntaxException, SecurityManagerException {
334 Assertions.assertThrows(SecurityManagerException.class, () -> {
335 prepareCertFiles("/cert/root.cert", cerDirPath + "root.cert");
336 byte[] signature = readAllBytes("/cert/tampered-signed-package/dummyPnfv4.cms");
337 byte[] archive = readAllBytes("/cert/tampered-signed-package/dummyPnfv4.csar");
338 securityManager.verifySignedData(signature, null, archive);