From b2f9dc5d3bc02564b4d952caa0bf2ccd20dfc6af Mon Sep 17 00:00:00 2001 From: kooper Date: Tue, 2 Apr 2019 09:22:01 +0000 Subject: [PATCH] Verify signature Change-Id: I8fc5d50d74d3dd8031c96ee16708489dc7c789b8 Issue-ID: SDC-2163 Signed-off-by: kooper --- onboarding/pom.xml | 1 + .../vendor-software-products-rest-services/pom.xml | 18 ++ .../sdcrests/vsp/rest/data/PackageArchive.java | 160 ++++++++++++ .../OrchestrationTemplateCandidateException.java | 27 +++ .../OrchestrationTemplateCandidateImpl.java | 55 ++++- .../sdcrests/vsp/rest/data/PackageArchiveTest.java | 99 ++++++++ .../OrchestrationTemplateCandidateImplTest.java | 121 +++++++++ .../src/test/resources/vspmanager.csar/notCsar.txt | 0 .../signing/2-empty-directories-in-root.zip | Bin 0 -> 290 bytes ...pty-files-1-directory-with-contents-in-root.zip | Bin 0 -> 558 bytes .../2-empty-files-1-empty-directory-in-root.zip | Bin 0 -> 420 bytes .../vspmanager.csar/signing/2-files-in-root.zip | Bin 0 -> 286 bytes .../signing/csar-and-cms-in-root.zip | Bin 0 -> 304 bytes .../signing/signed-package-tampered-data.zip | Bin 0 -> 4242 bytes .../vspmanager.csar/signing/signed-package.zip | Bin 0 -> 4242 bytes .../pom.xml | 5 + .../security/SecurityManager.java | 269 ++++++++++++++++++--- .../security/SecurityManagerException.java | 27 ++- .../security/SecurityManagerTest.java | 108 +++++++-- .../cert/2-file-signed-package/dummyPnfv3.cms | 34 +++ .../cert/2-file-signed-package/dummyPnfv3.csar | Bin 0 -> 3866 bytes .../cert/3-file-signed-package/dummyPnfv3.cert | 20 ++ .../cert/3-file-signed-package/dummyPnfv3.cms | 17 ++ .../cert/3-file-signed-package/dummyPnfv3.csar | Bin 0 -> 3866 bytes .../src/test/resources/cert/root.cert | 22 ++ .../cert/tampered-signed-package/dummyPnfv3.cms | 34 +++ .../cert/tampered-signed-package/dummyPnfv3.csar | Bin 0 -> 3877 bytes .../org/openecomp/sdc/common/errors/Messages.java | 3 +- 28 files changed, 956 insertions(+), 64 deletions(-) create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/data/PackageArchive.java create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateException.java create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/data/PackageArchiveTest.java create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImplTest.java create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/notCsar.txt create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/2-empty-directories-in-root.zip create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/2-empty-files-1-directory-with-contents-in-root.zip create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/2-empty-files-1-empty-directory-in-root.zip create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/2-files-in-root.zip create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/csar-and-cms-in-root.zip create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/signed-package-tampered-data.zip create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/signed-package.zip create mode 100644 openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/2-file-signed-package/dummyPnfv3.cms create mode 100644 openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/2-file-signed-package/dummyPnfv3.csar create mode 100644 openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/3-file-signed-package/dummyPnfv3.cert create mode 100644 openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/3-file-signed-package/dummyPnfv3.cms create mode 100644 openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/3-file-signed-package/dummyPnfv3.csar create mode 100644 openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/root.cert create mode 100644 openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/tampered-signed-package/dummyPnfv3.cms create mode 100644 openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/tampered-signed-package/dummyPnfv3.csar diff --git a/onboarding/pom.xml b/onboarding/pom.xml index 25db1ac9de..35be7440fc 100644 --- a/onboarding/pom.xml +++ b/onboarding/pom.xml @@ -125,6 +125,7 @@ 1.0.0 ${project.version} 2.4.1.Final + 1.61 diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/pom.xml b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/pom.xml index 26a7c15ff2..b1cee443a8 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/pom.xml +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/pom.xml @@ -130,6 +130,24 @@ unique-type-rest-types ${project.version} + + org.powermock + powermock-module-junit4-common + ${powermock.version} + test + + + org.powermock + powermock-api-mockito2 + ${powermock.version} + test + + + org.powermock + powermock-module-junit4 + ${powermock.version} + test + diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/data/PackageArchive.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/data/PackageArchive.java new file mode 100644 index 0000000000..bf029fb29e --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/data/PackageArchive.java @@ -0,0 +1,160 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019, Nordix Foundation. 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.openecomp.sdcrests.vsp.rest.data; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.openecomp.core.utilities.file.FileContentHandler; +import org.openecomp.sdc.common.utils.CommonUtil; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.openecomp.sdc.vendorsoftwareproduct.security.SecurityManager; +import org.openecomp.sdc.vendorsoftwareproduct.security.SecurityManagerException; + +import java.io.IOException; +import java.security.cert.CertificateException; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * Class responsible for processing zip archive and verify if this package corresponds + * SOL004 option 2 signed package format, verifies the cms signature if package is signed + */ +public class PackageArchive { + private static final Logger LOG = LoggerFactory.getLogger(PackageArchive.class); + private static final String[] ALLOWED_ARCHIVE_EXTENSIONS = {"csar", "zip"}; + private static final String[] ALLOWED_SIGNATURE_EXTENSIONS = {"cms"}; + private static final String[] ALLOWED_CERTIFICATE_EXTENSIONS = {"cert"}; + private static final int NUMBER_OF_FILES_FOR_SIGNATURE_WITH_CERT_INSIDE = 2; + private static final int NUMBER_OF_FILES_FOR_SIGNATURE_WITHOUT_CERT_INSIDE = 3; + private final SecurityManager securityManager; + private final byte[] outerPackageFileBytes; + private Pair> handlerPair; + + public PackageArchive(Attachment uploadedFile) { + this(uploadedFile.getObject(byte[].class)); + } + + public PackageArchive(byte[] outerPackageFileBytes) { + this.outerPackageFileBytes = outerPackageFileBytes; + this.securityManager = SecurityManager.getInstance(); + try { + handlerPair = CommonUtil.getFileContentMapFromOrchestrationCandidateZip( + outerPackageFileBytes); + } catch (IOException exception) { + LOG.error("Error reading files inside archive", exception); + } + } + + /** + * Checks if package matches required format {package.csar/zip, package.cms, package.cert(optional)} + * + * @return true if structure matches sol004 option 2 structure + */ + public boolean isSigned() { + return isPackageSizeMatches() && getSignatureFileName().isPresent(); + } + + /** + * Gets csar/zip package name with extension only if package is signed + * + * @return csar package name + */ + public Optional getArchiveFileName() { + if (isSigned()) { + return getFileByExtension(ALLOWED_ARCHIVE_EXTENSIONS); + } + return Optional.empty(); + } + + /** + * Gets csar/zip package content from zip archive + * @return csar package content + * @throws SecurityManagerException + */ + public byte[] getPackageFileContents() throws SecurityManagerException { + try { + if (isSignatureValid()) { + return handlerPair.getKey().getFiles().get(getArchiveFileName().orElseThrow(CertificateException::new)); + } + } catch (CertificateException exception) { + LOG.info("Error verifying signature " + exception); + } + return outerPackageFileBytes; + } + + /** + * Validates package signature against trusted certificates + * @return true if signature verified + * @throws SecurityManagerException + */ + public boolean isSignatureValid() throws SecurityManagerException { + Map files = handlerPair.getLeft().getFiles(); + Optional signatureFileName = getSignatureFileName(); + Optional archiveFileName = getArchiveFileName(); + if (files.isEmpty() || !signatureFileName.isPresent() || !archiveFileName.isPresent()) { + return false; + } + Optional certificateFile = getCertificateFileName(); + if(certificateFile.isPresent()){ + return securityManager.verifySignedData(files.get(signatureFileName.get()), + files.get(certificateFile.get()), files.get(archiveFileName.get())); + }else { + return securityManager.verifySignedData(files.get(signatureFileName.get()), + null, files.get(archiveFileName.get())); + } + } + + private boolean isPackageSizeMatches() { + return handlerPair.getRight().isEmpty() + && (handlerPair.getLeft().getFiles().size() == NUMBER_OF_FILES_FOR_SIGNATURE_WITH_CERT_INSIDE + || handlerPair.getLeft().getFiles().size() == NUMBER_OF_FILES_FOR_SIGNATURE_WITHOUT_CERT_INSIDE); + } + + private Optional getSignatureFileName() { + return getFileByExtension(ALLOWED_SIGNATURE_EXTENSIONS); + } + + private Optional getFileByExtension(String[] extensions) { + for (String fileName : handlerPair.getLeft().getFileList()) { + for (String extension : extensions) { + if (extension.equalsIgnoreCase(FilenameUtils.getExtension(fileName))) { + return Optional.of(fileName); + } + } + } + return Optional.empty(); + } + + private Optional getCertificateFileName() { + Optional certFileName = getFileByExtension(ALLOWED_CERTIFICATE_EXTENSIONS); + if(!certFileName.isPresent()){ + return Optional.empty(); + } + String certNameWithoutExtension = FilenameUtils.removeExtension(certFileName.get()); + if (certNameWithoutExtension.equals(FilenameUtils.removeExtension(getArchiveFileName().orElse("")))) { + return certFileName; + } + //cert file name should be the same as package name, e.g. vnfpackage.scar-->vnfpackage.cert + return Optional.empty(); + } +} diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateException.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateException.java new file mode 100644 index 0000000000..a7e65a7e6f --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateException.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019, Nordix Foundation. 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.openecomp.sdcrests.vsp.rest.services; + +public class OrchestrationTemplateCandidateException extends Exception{ + + public OrchestrationTemplateCandidateException(String message, Throwable t){ + super(message, t); + } +} diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImpl.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImpl.java index bdc422d580..4978b3fb34 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImpl.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImpl.java @@ -25,6 +25,7 @@ import org.openecomp.sdc.activitylog.ActivityLogManagerFactory; import org.openecomp.sdc.activitylog.dao.type.ActivityLogEntity; import org.openecomp.sdc.activitylog.dao.type.ActivityType; import org.openecomp.sdc.common.errors.Messages; +import org.openecomp.sdc.common.utils.SdcCommon; import org.openecomp.sdc.datatypes.error.ErrorLevel; import org.openecomp.sdc.datatypes.error.ErrorMessage; import org.openecomp.sdc.logging.api.Logger; @@ -33,6 +34,7 @@ import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateMan import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManagerFactory; import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager; import org.openecomp.sdc.vendorsoftwareproduct.VspManagerFactory; +import org.openecomp.sdc.vendorsoftwareproduct.security.SecurityManagerException; import org.openecomp.sdc.vendorsoftwareproduct.types.OrchestrationTemplateActionResponse; import org.openecomp.sdc.vendorsoftwareproduct.types.UploadFileResponse; import org.openecomp.sdc.vendorsoftwareproduct.types.ValidationResponse; @@ -43,6 +45,7 @@ import org.openecomp.sdcrests.vendorsoftwareproducts.types.OrchestrationTemplate import org.openecomp.sdcrests.vendorsoftwareproducts.types.UploadFileResponseDto; import org.openecomp.sdcrests.vendorsoftwareproducts.types.ValidationResponseDto; import org.openecomp.sdcrests.vsp.rest.OrchestrationTemplateCandidate; +import org.openecomp.sdcrests.vsp.rest.data.PackageArchive; import org.openecomp.sdcrests.vsp.rest.mapping.MapFilesDataStructureToDto; import org.openecomp.sdcrests.vsp.rest.mapping.MapUploadFileResponseToUploadFileResponseDto; import org.openecomp.sdcrests.vsp.rest.mapping.MapValidationResponseToDto; @@ -51,9 +54,13 @@ import org.springframework.stereotype.Service; import javax.inject.Named; import javax.ws.rs.core.Response; +import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStream; import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Optional; import static org.openecomp.core.utilities.file.FileUtils.getFileExtension; @@ -75,18 +82,46 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate @Override public Response upload(String vspId, String versionId, Attachment fileToUpload, String user) { + PackageArchive archive = new PackageArchive(fileToUpload.getObject(byte[].class)); + UploadFileResponseDto uploadFileResponseDto; + try { + if (archive.isSigned() && !archive.isSignatureValid()) { + ErrorMessage errorMessage = new ErrorMessage(ErrorLevel.ERROR, + getErrorWithParameters(Messages.FAILED_TO_VERIFY_SIGNATURE.getErrorMessage(), "")); + LOGGER.error(errorMessage.getMessage()); + uploadFileResponseDto = buildUploadResponseWithError(errorMessage); + //returning OK as SDC UI won't show error message if NOT OK error code. + return Response.ok(uploadFileResponseDto).build(); + } - String filename = fileToUpload.getContentDisposition().getParameter("filename"); - UploadFileResponse uploadFileResponse = candidateManager - .upload(vspId, new Version(versionId), fileToUpload.getObject(InputStream.class), - getFileExtension(filename), getNetworkPackageName(filename)); - - UploadFileResponseDto uploadFileResponseDto = new MapUploadFileResponseToUploadFileResponseDto() - .applyMapping(uploadFileResponse, UploadFileResponseDto.class); - + String filename = archive.getArchiveFileName().orElse(fileToUpload.getContentDisposition().getFilename()); + UploadFileResponse uploadFileResponse = candidateManager + .upload(vspId, new Version(versionId), new ByteArrayInputStream(archive.getPackageFileContents()), + getFileExtension(filename), getNetworkPackageName(filename)); + + uploadFileResponseDto = new MapUploadFileResponseToUploadFileResponseDto() + .applyMapping(uploadFileResponse, UploadFileResponseDto.class); + } catch (SecurityManagerException e) { + ErrorMessage errorMessage = new ErrorMessage(ErrorLevel.ERROR, + getErrorWithParameters(e.getMessage(), "")); + LOGGER.error(errorMessage.getMessage(), e); + uploadFileResponseDto = buildUploadResponseWithError(errorMessage); + //returning OK as SDC UI won't show error message if NOT OK error code. + return Response.ok(uploadFileResponseDto).build(); + } return Response.ok(uploadFileResponseDto).build(); } + private UploadFileResponseDto buildUploadResponseWithError(ErrorMessage errorMessage) { + UploadFileResponseDto uploadFileResponseDto = new UploadFileResponseDto(); + Map> errorMap = new HashMap<>(); + List errorMessages = new ArrayList<>(); + errorMessages.add(errorMessage); + errorMap.put(SdcCommon.UPLOAD_FILE, errorMessages); + uploadFileResponseDto.setErrors(errorMap); + return uploadFileResponseDto; + } + @Override public Response get(String vspId, String versionId, String user) throws IOException { Optional> zipFile = candidateManager.get(vspId, new Version(versionId)); @@ -146,7 +181,7 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate String errorWithParameters = ErrorMessagesFormatBuilder .getErrorWithParameters(Messages.MAPPING_OBJECTS_FAILURE.getErrorMessage(), fileDataStructureDto.toString(), fileDataStructure.toString()); - throw new Exception(errorWithParameters, exception); + throw new OrchestrationTemplateCandidateException(errorWithParameters, exception); } ValidationResponse response = candidateManager .updateFilesDataStructure(vspId, new Version(versionId), fileDataStructure); diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/data/PackageArchiveTest.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/data/PackageArchiveTest.java new file mode 100644 index 0000000000..6458a65d17 --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/data/PackageArchiveTest.java @@ -0,0 +1,99 @@ +package org.openecomp.sdcrests.vsp.rest.data; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.openecomp.sdc.vendorsoftwareproduct.security.SecurityManager; +import org.openecomp.sdc.vendorsoftwareproduct.security.SecurityManagerException; +import org.powermock.reflect.Whitebox; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.when; + +public class PackageArchiveTest { + private static final String BASE_DIR = "/vspmanager.csar/"; + + @Mock + SecurityManager manager; + + @Before + public void setUp(){ + initMocks(this); + } + + + @Test + public void isSignedTestCheckingWrongFile() throws IOException, + URISyntaxException { + PackageArchive packageArchive = getArchive("notCsar.txt"); + assertFalse("2 or 3 files expected for signed package present or signature valid for " + + "empty file", packageArchive.isSigned()); + } + + @Test + public void isSignedTestWrongPackageStructure2EmptyDirInRoot() throws IOException, + URISyntaxException { + PackageArchive packageArchive = getArchive("signing/2-empty-directories-in-root.zip"); + assertFalse(packageArchive.isSigned()); + } + + @Test + public void isSignedTestWrongPackageStructure2EmptyFilesAndEmptyDirInRoot() throws IOException, + URISyntaxException { + PackageArchive packageArchive = getArchive("signing/2-empty-files-1-empty-directory-in-root.zip"); + assertFalse(packageArchive.isSigned()); + } + + @Test + public void isSignedTestWrongPackageStructure2EmptyFilesAndDirWithContentInRoot() throws IOException, + URISyntaxException { + PackageArchive packageArchive = getArchive("signing/2-empty-files-1-directory-with-contents-in-root.zip"); + assertFalse(packageArchive.isSigned()); + } + + @Test + public void isSignedTestCorrectStructureNoSignature() throws IOException, + URISyntaxException { + PackageArchive packageArchive = getArchive("signing/2-files-in-root.zip"); + assertFalse(packageArchive.isSigned()); + } + + @Test + public void isSignedTestCorrectStructureAndSignatureExists() throws IOException, + URISyntaxException { + PackageArchive packageArchive = getArchive("signing/csar-and-cms-in-root.zip"); + assertTrue(packageArchive.isSigned()); + } + + @Test + public void isSignatureValidTestCorrectStructureAndValidSignatureExists() throws IOException, + URISyntaxException, SecurityManagerException { + PackageArchive packageArchive = getArchive("signing/signed-package.zip"); + Whitebox.setInternalState(packageArchive, "securityManager", manager); + when(manager.verifySignedData(any(), any(), any())).thenReturn(true); + assertTrue("Signature invalid for signed package", + packageArchive.isSignatureValid()); + } + + @Test(expected = SecurityManagerException.class) + public void isSignatureValidTestCorrectStructureAndNotValidSignatureExists() throws IOException, + URISyntaxException, SecurityManagerException { + PackageArchive packageArchive = getArchive("signing/signed-package-tampered-data.zip"); + Whitebox.setInternalState(packageArchive, "securityManager", manager); + when(manager.verifySignedData(any(), any(), any())).thenThrow(new SecurityManagerException("error!")); + packageArchive.isSignatureValid(); + } + + private PackageArchive getArchive(String path) throws URISyntaxException, IOException { + return new PackageArchive(Files.readAllBytes(Paths.get( + PackageArchiveTest.class.getResource(BASE_DIR + path).toURI()))); + } +} diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImplTest.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImplTest.java new file mode 100644 index 0000000000..2dc6cd737c --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImplTest.java @@ -0,0 +1,121 @@ +package org.openecomp.sdcrests.vsp.rest.services; + +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum; +import org.openecomp.sdc.activitylog.ActivityLogManager; +import org.openecomp.sdc.activitylog.ActivityLogManagerFactory; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManager; +import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManagerFactory; +import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager; +import org.openecomp.sdc.vendorsoftwareproduct.VspManagerFactory; +import org.openecomp.sdc.vendorsoftwareproduct.security.SecurityManagerException; +import org.openecomp.sdc.vendorsoftwareproduct.types.UploadFileResponse; +import org.openecomp.sdcrests.vendorsoftwareproducts.types.UploadFileResponseDto; +import org.openecomp.sdcrests.vsp.rest.data.PackageArchive; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import javax.ws.rs.core.Response; + +import java.util.Optional; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertFalse; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.powermock.api.mockito.PowerMockito.mock; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; +import static org.powermock.api.mockito.PowerMockito.whenNew; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({VspManagerFactory.class, ActivityLogManagerFactory.class, + OrchestrationTemplateCandidateManagerFactory.class, OrchestrationTemplateCandidateImpl.class}) +public class OrchestrationTemplateCandidateImplTest { + + Logger logger = LoggerFactory.getLogger(OrchestrationTemplateCandidateImplTest.class); + @Mock + private OrchestrationTemplateCandidateManager candidateManager; + @Mock + private VendorSoftwareProductManager vendorSoftwareProductManager; + @Mock + private PackageArchive packageArchive; + @Mock + private VspManagerFactory vspManagerFactory; + @Mock + private ActivityLogManager activityLogManager; + @Mock + private ActivityLogManagerFactory activityLogManagerFactory; + @Mock + OrchestrationTemplateCandidateManagerFactory orchestrationTemplateCandidateManagerFactory; + + private OrchestrationTemplateCandidateImpl orchestrationTemplateCandidate; + + @Before + public void setUp(){ + try { + initMocks(this); + packageArchive = mock(PackageArchive.class); + mockStatic(VspManagerFactory.class); + when(VspManagerFactory.getInstance()).thenReturn(vspManagerFactory); + when(vspManagerFactory.createInterface()).thenReturn(vendorSoftwareProductManager); + mockStatic(ActivityLogManagerFactory.class); + when(ActivityLogManagerFactory.getInstance()).thenReturn(activityLogManagerFactory); + when(activityLogManagerFactory.createInterface()).thenReturn(activityLogManager); + whenNew(PackageArchive.class).withAnyArguments().thenReturn(packageArchive); + mockStatic(OrchestrationTemplateCandidateManagerFactory.class); + when(OrchestrationTemplateCandidateManagerFactory.getInstance()).thenReturn(orchestrationTemplateCandidateManagerFactory); + when(orchestrationTemplateCandidateManagerFactory.createInterface()).thenReturn(candidateManager); + when(packageArchive.getArchiveFileName()).thenReturn(Optional.of("test")); + when(packageArchive.getPackageFileContents()).thenReturn(new byte[0]); + UploadFileResponse uploadFileResponse = new UploadFileResponse(); + uploadFileResponse.setOnboardingType(OnboardingTypesEnum.ZIP); + uploadFileResponse.setNetworkPackageName("test"); + when(candidateManager.upload(any(), any(), any(), any(), any())).thenReturn(uploadFileResponse); + }catch (Exception e){ + logger.error(e.getMessage(), e); + } + } + + @Test + public void uploadSignedTest() throws SecurityManagerException { + when(packageArchive.isSigned()).thenReturn(true); + when(packageArchive.isSignatureValid()).thenReturn(true); + orchestrationTemplateCandidate = new OrchestrationTemplateCandidateImpl(); + Attachment attachment = mock(Attachment.class); + when(attachment.getContentDisposition()).thenReturn(new ContentDisposition("test")); + Response response = orchestrationTemplateCandidate.upload("1", "1", attachment, "1"); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + + } + + @Test + public void uploadNotSignedTest(){ + when(packageArchive.isSigned()).thenReturn(false); + orchestrationTemplateCandidate = new OrchestrationTemplateCandidateImpl(); + Attachment attachment = mock(Attachment.class); + when(attachment.getContentDisposition()).thenReturn(new ContentDisposition("test")); + Response response = orchestrationTemplateCandidate.upload("1", "1", attachment, "1"); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + + } + + @Test + public void uploadSignNotValidTest() throws SecurityManagerException { + when(packageArchive.isSigned()).thenReturn(true); + when(packageArchive.isSignatureValid()).thenReturn(false); + orchestrationTemplateCandidate = new OrchestrationTemplateCandidateImpl(); + Attachment attachment = mock(Attachment.class); + when(attachment.getContentDisposition()).thenReturn(new ContentDisposition("test")); + Response response = orchestrationTemplateCandidate.upload("1", "1", attachment, "1"); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + assertFalse(((UploadFileResponseDto)response.getEntity()).getErrors().isEmpty()); + + } +} diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/notCsar.txt b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/notCsar.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/2-empty-directories-in-root.zip b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/2-empty-directories-in-root.zip new file mode 100644 index 0000000000000000000000000000000000000000..d0f1fd09dc7201d9c0a601866b338f597329d3c3 GIT binary patch literal 290 zcmWIWW@h1H00HMk<$hoWlwf9%VMt8W4-MgDV6K}oEv6NSODnh;7+IcmFf*_){9<4T zfNS=`qB$uEqPYjCaUwR&j7)OOxa^jIx41-wNKz1!IO0MU6b761SM literal 0 HcmV?d00001 diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/2-empty-files-1-directory-with-contents-in-root.zip b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/2-empty-files-1-directory-with-contents-in-root.zip new file mode 100644 index 0000000000000000000000000000000000000000..0f10af262feab68feecad4674c45e1e0f1fd0baa GIT binary patch literal 558 zcmWIWW@h1H00HMk<$hoWlwf9%VMt8W4-MgDV6K}oEv6NSODnh;7+IcmFf*_){9<4T zfNSPjjH;Ols5vn?lE8Yu&zu&cIt!0pv(>12Ss{*2NdapQ zUotHw0f;fIW@M6M#^q}XsQ(2R-a3Mq;4ol?gaICdFhc-l5Cg-KMq8jkpzr{i0}2m3 z=3s^fvN@GNb3kDOGzSzmc+9~J8Dw*|LOccvC!kTFaKbQ(l?|u{7|$#WDvS&aUqBoN E0Eum0y8r+H literal 0 HcmV?d00001 diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/2-empty-files-1-empty-directory-in-root.zip b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/2-empty-files-1-empty-directory-in-root.zip new file mode 100644 index 0000000000000000000000000000000000000000..6ded8b1d5784f657f7d66843a789943f4dd0aab0 GIT binary patch literal 420 zcmWIWW@h1H00HMk<$hoWlwf9%VMt8W4-MgDV6K}oEv6NSODnh;7+IcmFf*_){9<4T zfNSPjjH;Ols5vn?lE8Yu&zu&cItz@$6Bv#_7=-Bsm_ZB-OB!u~27x>TGza7%Jmz3}2icrTpgADV0nGt<4#ON) RHjtB!YurT~$UG4wJr$uZ-ySpx2mC5<2^$Q`T@ci=Gx(-p|(*Z|D|xd~_vR`;;7 Qfox&|!U;gS0>ohe0C7<(*Z=?k literal 0 HcmV?d00001 diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/csar-and-cms-in-root.zip b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/csar-and-cms-in-root.zip new file mode 100644 index 0000000000000000000000000000000000000000..07331466dfb81b698f177232be718bde1a0c38e7 GIT binary patch literal 304 zcmWIWW@h1H00H%-<$hoWlwfC&VMt8WOD;|<3Ju|8V16}oS_}x6R&X;gvOMcxW?*6X z#lR2%H$W5305+fjNlALixy4}p?|^zi7(+iJlN>WHCrH3uw4@Qlggb~8;vhVRVLAud cFh`(aFvkJS!s;+qHjtG}KsXafgY9Pk03TpB<^TWy literal 0 HcmV?d00001 diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/signed-package-tampered-data.zip b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/signed-package-tampered-data.zip new file mode 100644 index 0000000000000000000000000000000000000000..0cfb9e02650ccca9c7e389d2e8d3103a9eb47f5a GIT binary patch literal 4242 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 B(E9)Y literal 0 HcmV?d00001 diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/signed-package.zip b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/resources/vspmanager.csar/signing/signed-package.zip new file mode 100644 index 0000000000000000000000000000000000000000..a64ddd9be2f4906bbe84f30992720cbb0b294e67 GIT binary patch literal 4242 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 C609Kr literal 0 HcmV?d00001 diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/pom.xml b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/pom.xml index 66f04f1ba7..74a691b373 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/pom.xml +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/pom.xml @@ -203,6 +203,11 @@ openecomp-tosca-converter-core ${project.version} + + org.bouncycastle + bcpkix-jdk15on + ${bouncycastle.version} + junit junit diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/security/SecurityManager.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/security/SecurityManager.java index d2da7ef20f..7b1890dcaa 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/security/SecurityManager.java +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/security/SecurityManager.java @@ -20,83 +20,292 @@ package org.openecomp.sdc.vendorsoftwareproduct.security; import com.google.common.collect.ImmutableSet; +import org.bouncycastle.asn1.cms.ContentInfo; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cms.CMSException; +import org.bouncycastle.cms.CMSProcessableByteArray; +import org.bouncycastle.cms.CMSSignedData; +import org.bouncycastle.cms.CMSTypedData; +import org.bouncycastle.cms.SignerInformation; +import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openssl.PEMParser; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.util.Store; import org.openecomp.sdc.logging.api.Logger; import org.openecomp.sdc.logging.api.LoggerFactory; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.security.GeneralSecurityException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PublicKey; +import java.security.Security; +import java.security.SignatureException; +import java.security.cert.CertPathBuilder; +import java.security.cert.CertStore; import java.security.cert.Certificate; import java.security.cert.CertificateException; +import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateFactory; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.CollectionCertStoreParameters; +import java.security.cert.PKIXBuilderParameters; +import java.security.cert.PKIXCertPathBuilderResult; +import java.security.cert.TrustAnchor; +import java.security.cert.X509CertSelector; +import java.security.cert.X509Certificate; +import java.util.Collection; import java.util.HashSet; import java.util.Set; /** - * This is temporary solution. When AAF provides functionality for verifying certificates, this class should be reviewed - * Class is responsible for providing root certificates from configured location in onboarding container. + * This is temporary solution. When AAF provides functionality for verifying trustedCertificates, this class should be reviewed + * Class is responsible for providing root trustedCertificates from configured location in onboarding container. */ public class SecurityManager { - private static final String CERTIFICATE_DEFAULT_LOCATION = "/root/cert"; + private static final String CERTIFICATE_DEFAULT_LOCATION = "cert"; + private static final SecurityManager INSTANCE = new SecurityManager(); private Logger logger = LoggerFactory.getLogger(SecurityManager.class); - private Set certificates = new HashSet<>(); + private Set trustedCertificates = new HashSet<>(); private File certificateDirectory; + static { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + } - public SecurityManager(){ + private SecurityManager() { certificateDirectory = this.getcertDirectory(); } - private void processCertificateDir() { - if(!certificateDirectory.exists() || !certificateDirectory.isDirectory()){ + public static SecurityManager getInstance(){ + return INSTANCE; + } + + /** + * + * Checks the configured location for available trustedCertificates + * + * @return set of trustedCertificates + * @throws SecurityManagerException + */ + public Set getTrustedCertificates() throws SecurityManagerException { + //if file number in certificate directory changed reload certs + String[] certFiles = certificateDirectory.list(); + if (certFiles == null) { + logger.error("Certificate directory is empty!"); + return ImmutableSet.copyOf(new HashSet<>()); + } + if (trustedCertificates.size() != certFiles.length) { + trustedCertificates = new HashSet<>(); + processCertificateDir(); + } + return ImmutableSet.copyOf(trustedCertificates); + } + + /** + * Cleans certificate collection + */ + public void cleanTrustedCertificates(){ + trustedCertificates.clear(); + } + + /** + * + * Verifies if packaged signed with trusted certificate + * + * @param messageSyntaxSignature - signature data in cms format + * @param packageCert - package certificate if not part of cms signature, can be null + * @param innerPackageFile data package signed with cms signature + * @return true if signature verified + * @throws SecurityManagerException + */ + public boolean verifySignedData(final byte[] messageSyntaxSignature, final byte[] packageCert, + final byte[] innerPackageFile) throws SecurityManagerException{ + try (ByteArrayInputStream signatureStream = new ByteArrayInputStream(messageSyntaxSignature)) { + Object parsedObject = new PEMParser(new InputStreamReader(signatureStream)).readObject(); + if (!(parsedObject instanceof ContentInfo)) { + throw new SecurityManagerException("Signature is not recognized"); + } + ContentInfo signature = ContentInfo.getInstance(parsedObject); + CMSTypedData signedContent = new CMSProcessableByteArray(innerPackageFile); + CMSSignedData signedData = new CMSSignedData(signedContent, signature); + + Collection signers = signedData.getSignerInfos().getSigners(); + SignerInformation firstSigner = signers.iterator().next(); + Store certificates = signedData.getCertificates(); + X509Certificate cert; + if (packageCert == null) { + Collection firstSignerCertificates = certificates.getMatches(firstSigner.getSID()); + if(!firstSignerCertificates.iterator().hasNext()){ + throw new SecurityManagerException("No certificate found in cms signature that should contain one!"); + } + X509CertificateHolder firstSignerFirstCertificate = firstSignerCertificates.iterator().next(); + cert = loadCertificate(firstSignerFirstCertificate.getEncoded()); + } else { + cert = loadCertificate(packageCert); + } + + PKIXCertPathBuilderResult result = verifyCertificate(cert, getTrustedCertificates()); + + if (result == null) { + return false; + } + + return firstSigner.verify(new JcaSimpleSignerInfoVerifierBuilder().build(cert)); + } catch (OperatorCreationException | IOException | CMSException e) { + logger.error(e.getMessage(), e); + throw new SecurityManagerException("Unexpected error occurred during signature validation!", e); + } catch (GeneralSecurityException e){ + throw new SecurityManagerException("Could not verify signature!", e); + } + } + + private void processCertificateDir() throws SecurityManagerException { + if (!certificateDirectory.exists() || !certificateDirectory.isDirectory()) { logger.error("Issue with certificate directory, check if exists!"); return; } - File [] files = certificateDirectory.listFiles(); - if(files == null){ + File[] files = certificateDirectory.listFiles(); + if (files == null) { logger.error("Certificate directory is empty!"); return; } - for(File f : files) { - certificates.add(loadCertificate(f)); + for (File f : files) { + trustedCertificates.add(loadCertificate(f)); } } private File getcertDirectory() { String certDirLocation = System.getenv("SDC_CERT_DIR"); - if(certDirLocation == null){ + if (certDirLocation == null) { certDirLocation = CERTIFICATE_DEFAULT_LOCATION; } return new File(certDirLocation); } - private Certificate loadCertificate(File certFile){ - try (InputStream fileInputStream = new FileInputStream(certFile)){ + private X509Certificate loadCertificate(File certFile) throws SecurityManagerException { + try (InputStream fileInputStream = new FileInputStream(certFile)) { CertificateFactory factory = CertificateFactory.getInstance("X.509"); - return factory.generateCertificate(fileInputStream); - } catch (CertificateException|IOException e) { + return (X509Certificate) factory.generateCertificate(fileInputStream); + } catch (CertificateException | IOException e) { throw new SecurityManagerException("Error during loading Certificate file!", e); } } - /** - * Checks the configured location for available certificates - * @return set of certificates - */ - public Set getCertificates() { - //if file number in certificate directory changed reload certs - String[] certFiles = certificateDirectory.list(); - if(certFiles == null){ - logger.error("Certificate directory is empty!"); - return ImmutableSet.copyOf(new HashSet<>()); + private X509Certificate loadCertificate(byte[] certFile) throws SecurityManagerException { + try (InputStream in = new ByteArrayInputStream(certFile)) { + CertificateFactory factory = CertificateFactory.getInstance("X.509"); + return (X509Certificate) factory.generateCertificate(in); + } catch (CertificateException | IOException e) { + throw new SecurityManagerException("Error during loading Certificate from bytes!", e); } - if(certificates.size() != certFiles.length){ - certificates = new HashSet<>(); - processCertificateDir(); + } + + private PKIXCertPathBuilderResult verifyCertificate(X509Certificate cert, + Set additionalCerts) throws GeneralSecurityException, SecurityManagerException { + if (null == cert) { + throw new SecurityManagerException("The certificate is empty!"); + } + + if (isExpired(cert)) { + throw new SecurityManagerException("The certificate expired on: " + cert.getNotAfter()); + } + + if (isSelfSigned(cert)) { + throw new SecurityManagerException("The certificate is self-signed."); + } + + Set trustedRootCerts = new HashSet<>(); + Set intermediateCerts = new HashSet<>(); + for (X509Certificate additionalCert : additionalCerts) { + if (isSelfSigned(additionalCert)) { + trustedRootCerts.add(additionalCert); + } else { + intermediateCerts.add(additionalCert); + } + } + + return verifyCertificate(cert, trustedRootCerts, intermediateCerts); + } + + private PKIXCertPathBuilderResult verifyCertificate(X509Certificate cert, + Set allTrustedRootCerts, + Set allIntermediateCerts) + throws GeneralSecurityException { + + // Create the selector that specifies the starting certificate + X509CertSelector selector = new X509CertSelector(); + selector.setCertificate(cert); + + // Create the trust anchors (set of root CA certificates) + Set trustAnchors = new HashSet<>(); + for (X509Certificate trustedRootCert : allTrustedRootCerts) { + trustAnchors.add(new TrustAnchor(trustedRootCert, null)); + } + + // Configure the PKIX certificate builder algorithm parameters + PKIXBuilderParameters pkixParams; + try { + pkixParams = new PKIXBuilderParameters(trustAnchors, selector); + } catch (InvalidAlgorithmParameterException ex) { + throw new InvalidAlgorithmParameterException("No root CA has been found for this certificate", ex); + } + + // Not supporting CRL checks for now + pkixParams.setRevocationEnabled(false); + + Set certSet = new HashSet<>(); + certSet.add(cert); + pkixParams.addCertStore(createCertStore(certSet)); + pkixParams.addCertStore(createCertStore(allIntermediateCerts)); + pkixParams.addCertStore(createCertStore(allTrustedRootCerts)); + + CertPathBuilder builder = CertPathBuilder.getInstance(CertPathBuilder.getDefaultType(), BouncyCastleProvider.PROVIDER_NAME); + return (PKIXCertPathBuilderResult) builder.build(pkixParams); + } + + private CertStore createCertStore(Set certificateSet) throws InvalidAlgorithmParameterException, + NoSuchAlgorithmException, NoSuchProviderException { + return CertStore.getInstance("Collection", new CollectionCertStoreParameters(certificateSet), BouncyCastleProvider.PROVIDER_NAME); + } + + private boolean isExpired(X509Certificate cert) { + try { + cert.checkValidity(); + } catch (CertificateExpiredException e) { + logger.error(e.getMessage(), e); + return true; + } catch (CertificateNotYetValidException e) { + logger.error(e.getMessage(), e); + return false; + } + return false; + } + + private boolean isSelfSigned(Certificate cert) + throws CertificateException, NoSuchAlgorithmException, + NoSuchProviderException { + try { + // Try to verify certificate signature with its own public key + PublicKey key = cert.getPublicKey(); + cert.verify(key); + return true; + } catch (SignatureException | InvalidKeyException e) { + logger.error(e.getMessage(), e); + //not self-signed + return false; } - return ImmutableSet.copyOf(certificates); } } diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/security/SecurityManagerException.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/security/SecurityManagerException.java index 5c5a23a5f8..cdba2f8f0b 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/security/SecurityManagerException.java +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/security/SecurityManagerException.java @@ -1,8 +1,31 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019, Nordix Foundation. 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.openecomp.sdc.vendorsoftwareproduct.security; -public class SecurityManagerException extends RuntimeException { +public class SecurityManagerException extends Exception { - public SecurityManagerException(String s, Throwable t) { + public SecurityManagerException(String s) { super(s); } + + public SecurityManagerException(String s, Throwable t) { + super(s, t); + } } diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/security/SecurityManagerTest.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/security/SecurityManagerTest.java index c693015791..eea8a3a186 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/security/SecurityManagerTest.java +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/security/SecurityManagerTest.java @@ -6,11 +6,15 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import java.io.File; import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Paths; import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertTrue; @@ -18,67 +22,129 @@ import static org.mockito.ArgumentMatchers.eq; @RunWith(PowerMockRunner.class) @PrepareForTest(SecurityManager.class) +@PowerMockIgnore("javax.security.auth.x500.X500Principal") public class SecurityManagerTest { - File certDir; + private File certDir; + private SecurityManager securityManager; @Before - public void setUp(){ + public void setUp() throws IOException { certDir = new File("/tmp/cert"); + if(certDir.exists()){ + tearDown(); + } certDir.mkdirs(); PowerMockito.mockStatic(System.class); PowerMockito.when(System.getenv(eq("SDC_CERT_DIR"))).thenReturn(certDir.getPath()); + securityManager = SecurityManager.getInstance(); } @After - public void tearDown(){ - certDir.delete(); + public void tearDown() throws IOException { + if(certDir.exists()) { + FileUtils.deleteDirectory(certDir); + } + securityManager.cleanTrustedCertificates(); } @Test - public void testGetCertificates() throws IOException { + public void testGetCertificates() throws IOException, SecurityManagerException { File origFile = new File("src/test/resources/cert/root-certificate.pem"); File newFile = new File("/tmp/cert/root-certificate.pem"); newFile.createNewFile(); FileUtils.copyFile(origFile, newFile); - SecurityManager securityManager = new SecurityManager(); - assertEquals(1, securityManager.getCertificates().size()); + assertEquals(1, securityManager.getTrustedCertificates().size()); newFile.delete(); - assertEquals(0, securityManager.getCertificates().size()); + assertEquals(0, securityManager.getTrustedCertificates().size()); } @Test - public void testGetCertificatesNoDirectory() throws IOException { + public void testGetCertificatesNoDirectory() throws IOException, SecurityManagerException { certDir.delete(); - SecurityManager securityManager = new SecurityManager(); - assertEquals(0, securityManager.getCertificates().size()); + assertEquals(0, securityManager.getTrustedCertificates().size()); } @Test(expected = SecurityManagerException.class) - public void testGetCertificatesException() throws IOException { + public void testGetCertificatesException() throws IOException, SecurityManagerException { File newFile = new File("/tmp/cert/root-certificate.pem"); newFile.createNewFile(); - SecurityManager securityManager = new SecurityManager(); - assertEquals(1, securityManager.getCertificates().size()); + assertEquals(1, securityManager.getTrustedCertificates().size()); newFile.delete(); - assertEquals(0, securityManager.getCertificates().size()); + assertEquals(0, securityManager.getTrustedCertificates().size()); } @Test - public void testGetCertificatesUpdated() throws IOException { + public void testGetCertificatesUpdated() throws IOException, SecurityManagerException { File origFile = new File("src/test/resources/cert/root-certificate.pem"); File newFile = new File("/tmp/cert/root-certificate.pem"); newFile.createNewFile(); FileUtils.copyFile(origFile, newFile); - SecurityManager securityManager = new SecurityManager(); - assertTrue(securityManager.getCertificates().size() == 1); + assertTrue(securityManager.getTrustedCertificates().size() == 1); File otherOrigFile = new File("src/test/resources/cert/package-certificate.pem"); File otherNewFile = new File("/tmp/cert/package-certificate.pem"); newFile.createNewFile(); FileUtils.copyFile(otherOrigFile, otherNewFile); - assertEquals(2, securityManager.getCertificates().size()); + assertEquals(2, securityManager.getTrustedCertificates().size()); otherNewFile.delete(); - assertEquals(1, securityManager.getCertificates().size()); + assertEquals(1, securityManager.getTrustedCertificates().size()); newFile.delete(); - assertEquals(0, securityManager.getCertificates().size()); + assertEquals(0, securityManager.getTrustedCertificates().size()); + } + + @Test + public void verifySignedDataTestCertIncludedIntoSignature() throws IOException, URISyntaxException, SecurityManagerException { + File origFile = new File("src/test/resources/cert/root.cert"); + File newFile = new File("/tmp/cert/root.cert"); + newFile.createNewFile(); + FileUtils.copyFile(origFile, newFile); + byte[] signature = Files.readAllBytes(Paths.get(getClass().getResource("/cert/2-file-signed-package/dummyPnfv3.cms").toURI())); + byte[] archive = Files.readAllBytes(Paths.get(getClass().getResource("/cert/2-file-signed-package/dummyPnfv3.csar").toURI())); + assertTrue(securityManager.verifySignedData(signature, null, archive)); + } + + @Test(expected = SecurityManagerException.class) + public void verifySignedDataTestCertNotIncludedIntoSignatureButExpected() throws IOException, URISyntaxException, SecurityManagerException { + File origFile = new File("src/test/resources/cert/root.cert"); + File newFile = new File("/tmp/cert/root.cert"); + newFile.createNewFile(); + FileUtils.copyFile(origFile, newFile); + byte[] signature = Files.readAllBytes(Paths.get(getClass().getResource("/cert/3-file-signed-package/dummyPnfv3.cms").toURI())); + byte[] archive = Files.readAllBytes(Paths.get(getClass().getResource("/cert/2-file-signed-package/dummyPnfv3.csar").toURI())); + securityManager.verifySignedData(signature, null, archive); + } + + @Test + public void verifySignedDataTestCertNotIncludedIntoSignature() throws IOException, URISyntaxException, SecurityManagerException { + File origFile = new File("src/test/resources/cert/root.cert"); + File newFile = new File("/tmp/cert/root.cert"); + newFile.createNewFile(); + FileUtils.copyFile(origFile, newFile); + byte[] signature = Files.readAllBytes(Paths.get(getClass().getResource("/cert/3-file-signed-package/dummyPnfv3.cms").toURI())); + byte[] archive = Files.readAllBytes(Paths.get(getClass().getResource("/cert/3-file-signed-package/dummyPnfv3.csar").toURI())); + byte[] cert = Files.readAllBytes(Paths.get(getClass().getResource("/cert/3-file-signed-package/dummyPnfv3.cert").toURI())); + assertTrue(securityManager.verifySignedData(signature, cert, archive)); + } + + @Test(expected = SecurityManagerException.class) + public void verifySignedDataTestWrongCertificate() throws IOException, URISyntaxException, SecurityManagerException { + File origFile = new File("src/test/resources/cert/root-certificate.pem"); + File newFile = new File("/tmp/cert/root-certificate.cert"); + newFile.createNewFile(); + FileUtils.copyFile(origFile, newFile); + byte[] signature = Files.readAllBytes(Paths.get(getClass().getResource("/cert/3-file-signed-package/dummyPnfv3.cms").toURI())); + byte[] archive = Files.readAllBytes(Paths.get(getClass().getResource("/cert/3-file-signed-package/dummyPnfv3.csar").toURI())); + byte[] cert = Files.readAllBytes(Paths.get(getClass().getResource("/cert/3-file-signed-package/dummyPnfv3.cert").toURI())); + securityManager.verifySignedData(signature, cert, archive); + } + + @Test(expected = SecurityManagerException.class) + public void verifySignedDataTestChangedArchive() throws IOException, URISyntaxException, SecurityManagerException { + File origFile = new File("src/test/resources/cert/root.cert"); + File newFile = new File("/tmp/cert/root.cert"); + newFile.createNewFile(); + FileUtils.copyFile(origFile, newFile); + byte[] signature = Files.readAllBytes(Paths.get(getClass().getResource("/cert/tampered-signed-package/dummyPnfv3.cms").toURI())); + byte[] archive = Files.readAllBytes(Paths.get(getClass().getResource("/cert/tampered-signed-package/dummyPnfv3.csar").toURI())); + securityManager.verifySignedData(signature, null, archive); } } diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/2-file-signed-package/dummyPnfv3.cms b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/2-file-signed-package/dummyPnfv3.cms new file mode 100644 index 0000000000..fca5faca8e --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/2-file-signed-package/dummyPnfv3.cms @@ -0,0 +1,34 @@ +-----BEGIN CMS----- +MIIF9AYJKoZIhvcNAQcCoIIF5TCCBeECAQExDTALBglghkgBZQMEAgEwCwYJKoZI +hvcNAQcBoIIDPjCCAzowggIiAgkAmTZc6pj8rWYwDQYJKoZIhvcNAQELBQAwXzEL +MAkGA1UEBhMCSUUxEjAQBgNVBAgMCVdlc3RtZWF0aDEQMA4GA1UEBwwHQXRobG9u +ZTEMMAoGA1UECgwDRVNZMQ8wDQYDVQQLDAZUZWNobm8xCzAJBgNVBAMMAlNTMB4X +DTE5MDMyODEzMDQ0NloXDTE5MDQyNzEzMDQ0NlowXzELMAkGA1UEBhMCSUUxEjAQ +BgNVBAgMCVdlc3RtZWF0aDEQMA4GA1UEBwwHQXRobG9uZTEMMAoGA1UECgwDRVNZ +MQ8wDQYDVQQLDAZUZWNobm8xCzAJBgNVBAMMAlNTMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAqzpc/mRJZe5fxh9yo2ZmFCrNCynrbtLujp2GJwW40Nh0 +89jUBb49zFRwHrUUTlmIZRMrW8XDopX1LDajE+pzNxv+skdpZaPHhEjYcqbFIL1I +KiWxo1PTBi/9KgSFlzc5eewolrwV+NX76p2+xkLDwt6rnZy8UiubVH7U4mUnPtxy +Wx/W7uVGaZDKo0g2PNcFayRcL5skbm0Una2TjjAunwGP3FkxKigw+LukLE+w2fvE +C7b8ndIk10WER9rCIeMCf1571Ub8WJzR/80PfhJxbxoroRaiGESFh3kNNfqanLcS +Q4I9KHWeijOhSW0pHkqL2KPAee35FtfEUpL5aN0OcwIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQBlm8RMspc6cwcktqJXDLZLZiHSoapQqcq3TI3dkhU2uEFTstnxnXa3 +r4eTVF8tre2BjvxJtgmM7qMnoDTFo+uUjkvuBBalLARbQM+gF6PAeRLYRHMLSkN/ +yOfnyQ3ypYAQMpEHVG0Er6B5+KbQwFr2G0XBW0zE8au9oGzqBUNg7e0O22AyXqQk +uhHzXXVhz6sWxJVv51gjPoWtr/1YbsGmJPimFIuz9GvrZD1MKGQ4sotZvRkfofHz +ePg0y8taAcdXHJwfmAeiJdc0S9SsYxKLAz1OB+n4oQTsk+31cnKflp+wVfeNyaRP +sdFf4KLicluzbwIRJ/x0h2r/lTorGGUcMYICfDCCAngCAQEwbDBfMQswCQYDVQQG +EwJJRTESMBAGA1UECAwJV2VzdG1lYXRoMRAwDgYDVQQHDAdBdGhsb25lMQwwCgYD +VQQKDANFU1kxDzANBgNVBAsMBlRlY2hubzELMAkGA1UEAwwCU1MCCQCZNlzqmPyt +ZjALBglghkgBZQMEAgGggeQwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkq +hkiG9w0BCQUxDxcNMTkwMzI4MTMwODUwWjAvBgkqhkiG9w0BCQQxIgQg9ya6QcX9 +J6hp+zfK1gceoLlpApp92mfxGoX3eZ1dMUwweQYJKoZIhvcNAQkPMWwwajALBglg +hkgBZQMEASowCwYJYIZIAWUDBAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzAO +BggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcN +AwICASgwDQYJKoZIhvcNAQEBBQAEggEAAmmSdu8W5zr8DVrkASlujCCSLwKq1XE+ +knlrR84UkkpRz8SacfxtoQL2/T6H0LyOnlJTOGQj3M8w2CaYKKWamnp/2jLZFvUn +aaPbCdKeKvwPiL99iBIqXWcHXJKk5Ch3fIfcWyAfl48HAB7MFE3TlKk0qUQVXlZP +7/c4PGaqtbfB7pDuJx6k+Bd2dqG4Xe8RDdvKDEK33HzkAZ72ZPuEL3Zw77eeWZS6 +vyAQTxEkFKERiC1AkmGUdAfTolzYGn1LlTcqb1P59nzs/AZ16JKx6ZITumhaSG6Q +JvkvodxD99bhOh3pHaLkTkkcLxEEE9OscYEtWvIdIGyfjrpGIFP31g== +-----END CMS----- diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/2-file-signed-package/dummyPnfv3.csar b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/2-file-signed-package/dummyPnfv3.csar new file mode 100644 index 0000000000000000000000000000000000000000..2c626ed90bf7a27e47a62df575104f704973abbc GIT binary patch literal 3866 zcmb7{4^&fi6vy8fC@O#ENpYYR&?NQ1bYK{o8V)TFY_9mD{L%5)-o~^2!R;YVkEfGS zQDLcR4oE}nR0lyp)6xU}B^Ah1W9@@2~5UmpG#4{V}^p>?E&vCdY3bMPsEk<&%#_e79==>-Om94ltk%h6Ai0?w;K1PgmY3s(xz0( zvYysZX_T?RKr$4o+5L$k@U1&HcI8(Q0)p7@Ll7Y#f+sJdZqN2JN@0ZP&2Kxk*IsMd z-xU(J@ZzOU7Pim5_4Q@n-LyO>R~X%Vvhm0(oyV3bIub;=LuLPJ>g+o+mNy^HomBgC z;?#z}Zuu%RcXnsezkl3tJ}xmnOel`IGT%ObS&#Dj>LJyp;?jt)9?4^q7wd%apGW$X zMM~mUMIYZ_x5}mz9a?hnM&lm?A6m0otD-+D%H4Ipa!Krhr8yH*2hIl`?^Pa6KksjE zo8J6WVBCThdrDA1MTueCX-Vki&P|%NYb_;HuDwyNdLlS#UH#c(_Zp`U<|)#dIEBx# zzW1W5uf{K)lQp5k(fnORUvcl#-;~|Ws|-}sO~`+t=FXUm)B|e!#vA>)UCC2RcMP6m zW;KYr?yPDMhg~|=pZCS=cdvAp-@37CaGd+P4QcEP3kze2t}Ng0{>NCG|)KOmee>(tzxak+ zHkA%EZvAw5@U)wkDnbu#PQ4xE*H@-<6ft`<;;Ux`+1mU5j#--id{E-ueeYMiRJ*_J z!LIu?)VhjA`=&>YJ3MdJIBIOu!V~khKKpBL`8j$0nb-^D*p!e)@lm}rextnLY~h{a z=+f)0PnH<(`|ee#+h?W^%{{$jQLmpWS>UsnaCR?$uE4H@FWB|)<(@L*iSXgS2naEu zum2!`I_MA}+a3I8OWy&9z!}@yEJCqioEhNlj?J1(ILQ8%RWGb@2)Gs(!Jl6U1VyZ7 zfv{S(r`=9?rUOg31HxOyl-4KmV$I?1QL5g8HtPdxI+FO zgKios6bkVwJGUB~@Z1)W06sd9o$;Vb4xf*>GXCy^2vC{K1A(;(;kXwEPpp99xfU11 z-$3No;8&g}^&_^&yT0|{J<6S$jGfa|Itp&StKjSG+NNXb6b5858t(z1@T+&RUK zE^$SNni2 ztv84RYnScETXt|j%AU*)ST1A@w*wp9<%27PrhsN$v_)moqdp^#N2 U`;7r{z`inxIOtCh8N;9c17W5MvH$=8 literal 0 HcmV?d00001 diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/3-file-signed-package/dummyPnfv3.cert b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/3-file-signed-package/dummyPnfv3.cert new file mode 100644 index 0000000000..d7da41db94 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/3-file-signed-package/dummyPnfv3.cert @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDOjCCAiICCQCZNlzqmPytZjANBgkqhkiG9w0BAQsFADBfMQswCQYDVQQGEwJJ +RTESMBAGA1UECAwJV2VzdG1lYXRoMRAwDgYDVQQHDAdBdGhsb25lMQwwCgYDVQQK +DANFU1kxDzANBgNVBAsMBlRlY2hubzELMAkGA1UEAwwCU1MwHhcNMTkwMzI4MTMw +NDQ2WhcNMTkwNDI3MTMwNDQ2WjBfMQswCQYDVQQGEwJJRTESMBAGA1UECAwJV2Vz +dG1lYXRoMRAwDgYDVQQHDAdBdGhsb25lMQwwCgYDVQQKDANFU1kxDzANBgNVBAsM +BlRlY2hubzELMAkGA1UEAwwCU1MwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCrOlz+ZEll7l/GH3KjZmYUKs0LKetu0u6OnYYnBbjQ2HTz2NQFvj3MVHAe +tRROWYhlEytbxcOilfUsNqMT6nM3G/6yR2llo8eESNhypsUgvUgqJbGjU9MGL/0q +BIWXNzl57CiWvBX41fvqnb7GQsPC3qudnLxSK5tUftTiZSc+3HJbH9bu5UZpkMqj +SDY81wVrJFwvmyRubRSdrZOOMC6fAY/cWTEqKDD4u6QsT7DZ+8QLtvyd0iTXRYRH +2sIh4wJ/XnvVRvxYnNH/zQ9+EnFvGiuhFqIYRIWHeQ01+pqctxJDgj0odZ6KM6FJ +bSkeSovYo8B57fkW18RSkvlo3Q5zAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAGWb +xEyylzpzByS2olcMtktmIdKhqlCpyrdMjd2SFTa4QVOy2fGddrevh5NUXy2t7YGO +/Em2CYzuoyegNMWj65SOS+4EFqUsBFtAz6AXo8B5EthEcwtKQ3/I5+fJDfKlgBAy +kQdUbQSvoHn4ptDAWvYbRcFbTMTxq72gbOoFQ2Dt7Q7bYDJepCS6EfNddWHPqxbE +lW/nWCM+ha2v/VhuwaYk+KYUi7P0a+tkPUwoZDiyi1m9GR+h8fN4+DTLy1oBx1cc +nB+YB6Il1zRL1KxjEosDPU4H6fihBOyT7fVycp+Wn7BV943JpE+x0V/gouJyW7Nv +AhEn/HSHav+VOisYZRw= +-----END CERTIFICATE----- diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/3-file-signed-package/dummyPnfv3.cms b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/3-file-signed-package/dummyPnfv3.cms new file mode 100644 index 0000000000..eeee6a977b --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/3-file-signed-package/dummyPnfv3.cms @@ -0,0 +1,17 @@ +-----BEGIN CMS----- +MIICsgYJKoZIhvcNAQcCoIICozCCAp8CAQExDTALBglghkgBZQMEAgEwCwYJKoZI +hvcNAQcBMYICfDCCAngCAQEwbDBfMQswCQYDVQQGEwJJRTESMBAGA1UECAwJV2Vz +dG1lYXRoMRAwDgYDVQQHDAdBdGhsb25lMQwwCgYDVQQKDANFU1kxDzANBgNVBAsM +BlRlY2hubzELMAkGA1UEAwwCU1MCCQCZNlzqmPytZjALBglghkgBZQMEAgGggeQw +GAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzI4 +MTMxMDI2WjAvBgkqhkiG9w0BCQQxIgQg9ya6QcX9J6hp+zfK1gceoLlpApp92mfx +GoX3eZ1dMUwweQYJKoZIhvcNAQkPMWwwajALBglghkgBZQMEASowCwYJYIZIAWUD +BAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzAOBggqhkiG9w0DAgICAIAwDQYI +KoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwDQYJKoZIhvcNAQEB +BQAEggEAGGYZ4DsMUDzjMVpJU9zwLzTtxO1wCnouTVw8FJT2utGnUds+OexbKQoj +pCCfuAL1k9UaP3uyNXOjuMx8tzlQY0gZJzaKpYJ7vh0q6P9IZs0hjcvEXPhRTI/y +vI8mHP3WIXwuh36ehRmqALnGbBcOj46k578gAf/p1hHD3/ceQfB1MSkSVMwvf+yP +3YwJyvKHYYlGaaAbSjnIK+7g2tuRIvFdXGk30CU2mnldvb3JltfxB5MkZgEM6hPz +ZhjgNDtmFDZzoblEOCvFJnpXg2IF7bAPjObNaPd20ZRvRSRhQODktT5EHARRT53Y +p+03N4IUz89hw/roOnq0nlbetQSKvg== +-----END CMS----- diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/3-file-signed-package/dummyPnfv3.csar b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/3-file-signed-package/dummyPnfv3.csar new file mode 100644 index 0000000000000000000000000000000000000000..2c626ed90bf7a27e47a62df575104f704973abbc GIT binary patch literal 3866 zcmb7{4^&fi6vy8fC@O#ENpYYR&?NQ1bYK{o8V)TFY_9mD{L%5)-o~^2!R;YVkEfGS zQDLcR4oE}nR0lyp)6xU}B^Ah1W9@@2~5UmpG#4{V}^p>?E&vCdY3bMPsEk<&%#_e79==>-Om94ltk%h6Ai0?w;K1PgmY3s(xz0( zvYysZX_T?RKr$4o+5L$k@U1&HcI8(Q0)p7@Ll7Y#f+sJdZqN2JN@0ZP&2Kxk*IsMd z-xU(J@ZzOU7Pim5_4Q@n-LyO>R~X%Vvhm0(oyV3bIub;=LuLPJ>g+o+mNy^HomBgC z;?#z}Zuu%RcXnsezkl3tJ}xmnOel`IGT%ObS&#Dj>LJyp;?jt)9?4^q7wd%apGW$X zMM~mUMIYZ_x5}mz9a?hnM&lm?A6m0otD-+D%H4Ipa!Krhr8yH*2hIl`?^Pa6KksjE zo8J6WVBCThdrDA1MTueCX-Vki&P|%NYb_;HuDwyNdLlS#UH#c(_Zp`U<|)#dIEBx# zzW1W5uf{K)lQp5k(fnORUvcl#-;~|Ws|-}sO~`+t=FXUm)B|e!#vA>)UCC2RcMP6m zW;KYr?yPDMhg~|=pZCS=cdvAp-@37CaGd+P4QcEP3kze2t}Ng0{>NCG|)KOmee>(tzxak+ zHkA%EZvAw5@U)wkDnbu#PQ4xE*H@-<6ft`<;;Ux`+1mU5j#--id{E-ueeYMiRJ*_J z!LIu?)VhjA`=&>YJ3MdJIBIOu!V~khKKpBL`8j$0nb-^D*p!e)@lm}rextnLY~h{a z=+f)0PnH<(`|ee#+h?W^%{{$jQLmpWS>UsnaCR?$uE4H@FWB|)<(@L*iSXgS2naEu zum2!`I_MA}+a3I8OWy&9z!}@yEJCqioEhNlj?J1(ILQ8%RWGb@2)Gs(!Jl6U1VyZ7 zfv{S(r`=9?rUOg31HxOyl-4KmV$I?1QL5g8HtPdxI+FO zgKios6bkVwJGUB~@Z1)W06sd9o$;Vb4xf*>GXCy^2vC{K1A(;(;kXwEPpp99xfU11 z-$3No;8&g}^&_^&yT0|{J<6S$jGfa|Itp&StKjSG+NNXb6b5858t(z1@T+&RUK zE^$SNni2 ztv84RYnScETXt|j%AU*)ST1A@w*wp9<%27PrhsN$v_)moqdp^#N2 U`;7r{z`inxIOtCh8N;9c17W5MvH$=8 literal 0 HcmV?d00001 diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/root.cert b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/root.cert new file mode 100644 index 0000000000..767804ede4 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/root.cert @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIJANxs5zQCT2zPMA0GCSqGSIb3DQEBCwUAMF8xCzAJBgNV +BAYTAklFMRIwEAYDVQQIDAlXZXN0bWVhdGgxEDAOBgNVBAcMB0F0aGxvbmUxDDAK +BgNVBAoMA0VTWTEPMA0GA1UECwwGVGVjaG5vMQswCQYDVQQDDAJTUzAeFw0xOTAz +MjgxMzAyMDVaFw0xOTA0MjcxMzAyMDVaMF8xCzAJBgNVBAYTAklFMRIwEAYDVQQI +DAlXZXN0bWVhdGgxEDAOBgNVBAcMB0F0aGxvbmUxDDAKBgNVBAoMA0VTWTEPMA0G +A1UECwwGVGVjaG5vMQswCQYDVQQDDAJTUzCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALwd8mRaVTPIiyJEGuscMulTg7EyQGUcVgRUJDrcEsubK9vgDEqh +0BTps1xO01LX7RaXSe4KWTcsJG41QsdX9lo94VoYZFfR0tVKCkPjWoaynl0cZEAZ +r6vADWwQkWWi1Czwr9fTX9NBu68IexLATuS387gafonlzvpa4TLVwi69ogNlVa91 +pKkeZCBWbhgDgYDz5pEbKPJ6TRab/sFxZOx/HBIM9i7INvwNhdnZF77eZVgNUX2z +XKFcXOklmY9gEr9HQtsFIyTxlOdL2DF7JspgN0Yfb6hqAKE/sfOgQ6h3A+n4AuA1 +gtgC6k0OVps2ZM3jlmpYatKorz22zp3nhzECAwEAAaNTMFEwHQYDVR0OBBYEFGci +Qjw5QhCSvwl86i6weBl++bQvMB8GA1UdIwQYMBaAFGciQjw5QhCSvwl86i6weBl+ ++bQvMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHtMPlNaUJPy +IXBOjROu0LlRXWJ/u7TVLaLaLnok5Sy/9QAz/FBKzOvMP1cmavsZiZC/9ISEaWFv +KlTOeZrhUl7WGk8pJPkkfATxt7HtRxO/c0RNrJin1AWWjQnUxjCB+nuqKS2h/itG +fHyHzzB3kjzxaK73kVuh8fzdxRDkg6QgLyW83BJ8T/U/VOuM3HRNIF86cazgae7E +7c9SrnXZ67IS7w3gxm/L/k5Rpd4XuuumaDuDz3NhGj1HFh323x11jheMmfl559SK +qU5NIC2qwKYGhzDojgLUJeL9g52DeS4eZ3DmINFRK2g0UMrHrypKq5aQ2v1kac6X +Io5o3F3L2DE= +-----END CERTIFICATE----- diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/tampered-signed-package/dummyPnfv3.cms b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/tampered-signed-package/dummyPnfv3.cms new file mode 100644 index 0000000000..fca5faca8e --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/tampered-signed-package/dummyPnfv3.cms @@ -0,0 +1,34 @@ +-----BEGIN CMS----- +MIIF9AYJKoZIhvcNAQcCoIIF5TCCBeECAQExDTALBglghkgBZQMEAgEwCwYJKoZI +hvcNAQcBoIIDPjCCAzowggIiAgkAmTZc6pj8rWYwDQYJKoZIhvcNAQELBQAwXzEL +MAkGA1UEBhMCSUUxEjAQBgNVBAgMCVdlc3RtZWF0aDEQMA4GA1UEBwwHQXRobG9u +ZTEMMAoGA1UECgwDRVNZMQ8wDQYDVQQLDAZUZWNobm8xCzAJBgNVBAMMAlNTMB4X +DTE5MDMyODEzMDQ0NloXDTE5MDQyNzEzMDQ0NlowXzELMAkGA1UEBhMCSUUxEjAQ +BgNVBAgMCVdlc3RtZWF0aDEQMA4GA1UEBwwHQXRobG9uZTEMMAoGA1UECgwDRVNZ +MQ8wDQYDVQQLDAZUZWNobm8xCzAJBgNVBAMMAlNTMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAqzpc/mRJZe5fxh9yo2ZmFCrNCynrbtLujp2GJwW40Nh0 +89jUBb49zFRwHrUUTlmIZRMrW8XDopX1LDajE+pzNxv+skdpZaPHhEjYcqbFIL1I +KiWxo1PTBi/9KgSFlzc5eewolrwV+NX76p2+xkLDwt6rnZy8UiubVH7U4mUnPtxy +Wx/W7uVGaZDKo0g2PNcFayRcL5skbm0Una2TjjAunwGP3FkxKigw+LukLE+w2fvE +C7b8ndIk10WER9rCIeMCf1571Ub8WJzR/80PfhJxbxoroRaiGESFh3kNNfqanLcS +Q4I9KHWeijOhSW0pHkqL2KPAee35FtfEUpL5aN0OcwIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQBlm8RMspc6cwcktqJXDLZLZiHSoapQqcq3TI3dkhU2uEFTstnxnXa3 +r4eTVF8tre2BjvxJtgmM7qMnoDTFo+uUjkvuBBalLARbQM+gF6PAeRLYRHMLSkN/ +yOfnyQ3ypYAQMpEHVG0Er6B5+KbQwFr2G0XBW0zE8au9oGzqBUNg7e0O22AyXqQk +uhHzXXVhz6sWxJVv51gjPoWtr/1YbsGmJPimFIuz9GvrZD1MKGQ4sotZvRkfofHz +ePg0y8taAcdXHJwfmAeiJdc0S9SsYxKLAz1OB+n4oQTsk+31cnKflp+wVfeNyaRP +sdFf4KLicluzbwIRJ/x0h2r/lTorGGUcMYICfDCCAngCAQEwbDBfMQswCQYDVQQG +EwJJRTESMBAGA1UECAwJV2VzdG1lYXRoMRAwDgYDVQQHDAdBdGhsb25lMQwwCgYD +VQQKDANFU1kxDzANBgNVBAsMBlRlY2hubzELMAkGA1UEAwwCU1MCCQCZNlzqmPyt +ZjALBglghkgBZQMEAgGggeQwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkq +hkiG9w0BCQUxDxcNMTkwMzI4MTMwODUwWjAvBgkqhkiG9w0BCQQxIgQg9ya6QcX9 +J6hp+zfK1gceoLlpApp92mfxGoX3eZ1dMUwweQYJKoZIhvcNAQkPMWwwajALBglg +hkgBZQMEASowCwYJYIZIAWUDBAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzAO +BggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcN +AwICASgwDQYJKoZIhvcNAQEBBQAEggEAAmmSdu8W5zr8DVrkASlujCCSLwKq1XE+ +knlrR84UkkpRz8SacfxtoQL2/T6H0LyOnlJTOGQj3M8w2CaYKKWamnp/2jLZFvUn +aaPbCdKeKvwPiL99iBIqXWcHXJKk5Ch3fIfcWyAfl48HAB7MFE3TlKk0qUQVXlZP +7/c4PGaqtbfB7pDuJx6k+Bd2dqG4Xe8RDdvKDEK33HzkAZ72ZPuEL3Zw77eeWZS6 +vyAQTxEkFKERiC1AkmGUdAfTolzYGn1LlTcqb1P59nzs/AZ16JKx6ZITumhaSG6Q +JvkvodxD99bhOh3pHaLkTkkcLxEEE9OscYEtWvIdIGyfjrpGIFP31g== +-----END CMS----- diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/tampered-signed-package/dummyPnfv3.csar b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/cert/tampered-signed-package/dummyPnfv3.csar new file mode 100644 index 0000000000000000000000000000000000000000..81cb1f72d2a52888180a3ad68675e8c322f5e99e GIT binary patch literal 3877 zcmb7{4OCNQ7{~7zB=R{=3Iol6CaDLe1H-_taAifQlpNi zX8D;QX^55`1O-h?5BQx5&*#xVA$QAIkVMNb)MJJPXbl9n0TIB#3# ztppnfg9U2{BKZv_O!OZ+UniAXqtvLRnj2Te0H;1|4Smb)6vRFqs&Jrvnh#*!x3B%cL z0j}a5u3&x)YI|+i{jtOOzy1=O{u~G2yn70xR``tg78q1Ulb*CEMu(|l?}{B_SFxEg z$<@VLB?SxCb<%3qw}Hp-v5?kKCXBeWkXdHWd04Ht$ju6qwulxg%o-O+!`jLOWl`qA z0&*lIG=~Wa0-!WXr8Q__7VuJIuN1IWN=U6ClQON;DyS?2^ma|fBH1FN39m-qlFYLP)7CGzkmHo5YrrrPgn(t1nIKO}! z*L14!=$jqK=S$j?c?ARI|0wFpw&yHpI#MvY_Q%w*4S(MEmF8~m%+>z-NyEj&)TBr* zKmJBaS<3t_>37uwvNfgF=*TX?vt#C{xJjSK_>{*85|_lCSXE{gg_j(jd-+b|Z+#z` z^IEFnJ}xQP@uYHY!i;(OqcZz02A}Ab9?QPyU)DOI>4)IN8O>!GAwd-zb(_x!BCd6; zQ7m6>+8BQ8on5l=p|LCK&mDidl>CQ5U!(+!x#T3iV*G z-g-7_>2YhUB0&lZG^yL+V~;?Ua62O)kv z>@!dD*Xoq(0jFVa1}_eXUP-JgK2pRLtHxA$H`E>61rNBQDH3 zIepX1KX>msFRnkEaETm|5!T2*rWPix78ji>epni3z1{NsM*S1tJu-RQr0judXXeiC z_LHS^eC802>UD21uqxpTRy};V8c6^VW&aO{;1lZlZ9&u_8wc6W&_9}c4%#?&-&}8P z3Hgp%w}1UahHplb!a?ge2n0oF7$B^h;h4vrUmooT@gv(B_QHGc z9>=)%JRDQu4KvsQaoU6Am)c?WkVRAn4YqkteG<{4z^B*2t6DpJUKTLxmw=qIYH4G1cIN znHzW<_~<}(;?pWIw}z?AefB{FsBESO0%H=waj*5CTnOE>EiTA?UP3r1sDy!YOiwt$ zf7!u&NMKu>z@D6foJR!-p8^6tapB%=8A}iMg0e@}THb!n*{2A{BZuu>;PejDb(Q7a z)4Tl3SHre5v!Zl$DDo_l(ysEA60fVfILlExc4dTGusr=lA z9UPFcJGULC3t8QR;6_*a;0WPqBtifvWScv{H6Y=r(hFOwl|TbRAuCJwdj|Lc^U7%A LkUv3?_Pc)pfv^>> literal 0 HcmV?d00001 diff --git a/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java b/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java index 2111f6d547..7b8fda8c49 100644 --- a/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java +++ b/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java @@ -188,7 +188,8 @@ public enum Messages { /* Notifications */ FAILED_TO_MARK_NOTIFICATION_AS_READ("Failed to mark notifications as read"), - FAILED_TO_UPDATE_LAST_SEEN_NOTIFICATION("Failed to update last seen notification for user %s"); + FAILED_TO_UPDATE_LAST_SEEN_NOTIFICATION("Failed to update last seen notification for user %s"), + FAILED_TO_VERIFY_SIGNATURE("Cannot verify signature of signed archive!"); private String errorMessage; -- 2.16.6