afc43967c983a186097baf7688d21c73243a8218
[sdc.git] / openecomp-be / backend / openecomp-sdc-vendor-software-product-manager / src / test / java / org / openecomp / sdc / vendorsoftwareproduct / security / SecurityManagerTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20
21 package org.openecomp.sdc.vendorsoftwareproduct.security;
22
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;
33
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;
39 import java.io.File;
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;
45 import java.util.Map;
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;
63
64 @ExtendWith(MockitoExtension.class)
65 class SecurityManagerTest {
66
67     private File certDir;
68     private String cerDirPath = "/tmp/cert/";
69     private SecurityManager securityManager;
70     @Mock
71     private CommonConfigurationManager commonConfigurationManager;
72     @Mock
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;
78     @Mock
79     private GetObjectArgs getObjectArgs;
80
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);
86         return newFile;
87     }
88
89     private byte[] readAllBytes(String path) throws URISyntaxException, IOException {
90         return Files.readAllBytes(Paths.get(getClass().getResource(path).toURI()));
91     }
92
93     @BeforeEach
94     public void setUp() throws IOException {
95         openMocks(this);
96         certDir = new File(cerDirPath);
97         if (certDir.exists()) {
98             tearDown();
99         }
100         certDir.mkdirs();
101         securityManager = new SecurityManager(certDir.getPath());
102
103     }
104
105     @AfterEach
106     public void tearDown() throws IOException {
107         if (certDir.exists()) {
108             FileUtils.deleteDirectory(certDir);
109         }
110         securityManager.cleanTrustedCertificates();
111     }
112
113     @Test
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());
117         newFile.delete();
118         assertEquals(0, securityManager.getTrustedCertificates().size());
119     }
120
121     @Test
122     void testGetCertificatesNoDirectory() throws IOException, SecurityManagerException {
123         certDir.delete();
124         assertEquals(0, securityManager.getTrustedCertificates().size());
125     }
126
127     @Test
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());
133         });
134         newFile.delete();
135         assertEquals(0, securityManager.getTrustedCertificates().size());
136
137     }
138
139     @Test
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());
147         newFile.delete();
148         assertEquals(0, securityManager.getTrustedCertificates().size());
149     }
150
151     @Test
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));
157     }
158
159     @Test
160     void verifySignedDataTestCertIncludedIntoSignatureArtifactStorageManagerIsEnabled() throws Exception {
161
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");
168
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);
173                 when(builderMinio
174                     .endpoint(anyString(), anyInt(), anyBoolean())
175                     .credentials(anyString(), anyString())
176                     .build()
177                 ).thenReturn(minioClient);
178
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
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
187                     .bucket(anyString())
188                     .object(anyString())
189                     .build()
190                 ).thenReturn(getObjectArgs);
191
192                 when(minioClient.getObject(any(GetObjectArgs.class)))
193                     .thenReturn(new GetObjectResponse(null, "bucket", "", "objectName",
194                         new BufferedInputStream(new ByteArrayInputStream(fileToUploadBytes))));
195
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);
199
200                 assertTrue(securityManager
201                     .verifyPackageSignedData((OnboardSignedPackage) onboardPackageInfo.getOriginalOnboardPackage(),
202                         onboardPackageInfo.getArtifactInfo()));
203             }
204         }
205     }
206
207     @Test
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);
214         });
215
216     }
217
218     @Test
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));
225     }
226
227     @Test
228     void verifySignedDataTestCertNotIncludedIntoSignatureArtifactStorageManagerIsEnabled() throws Exception {
229
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");
236
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);
241                 when(builderMinio
242                     .endpoint(anyString(), anyInt(), anyBoolean())
243                     .credentials(anyString(), anyString())
244                     .build()
245                 ).thenReturn(minioClient);
246
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());
251
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
255                     .bucket(anyString())
256                     .object(anyString())
257                     .build()
258                 ).thenReturn(getObjectArgs);
259
260                 when(minioClient.getObject(any(GetObjectArgs.class)))
261                     .thenReturn(new GetObjectResponse(null, "bucket", "", "objectName",
262                         new BufferedInputStream(new ByteArrayInputStream(fileToUploadBytes))));
263
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);
267
268                 assertTrue(securityManager
269                     .verifyPackageSignedData((OnboardSignedPackage) onboardPackageInfo.getOriginalOnboardPackage(),
270                         onboardPackageInfo.getArtifactInfo()));
271             }
272         }
273     }
274
275     @Test
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));
283     }
284
285     @Test
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);
294         });
295
296     }
297
298     @Test
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));
306     }
307
308     @Test
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));
316     }
317
318     @Test
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);
326         });
327
328     }
329
330     @Test
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);
337         });
338
339     }
340 }