summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartosz Gardziejewski <bartosz.gardziejewski@nokia.com>2021-01-12 10:33:18 +0100
committerBartosz Gardziejewski <bartosz.gardziejewski@nokia.com>2021-01-13 09:14:31 +0100
commit2b9a4f35e2e50fca4304107b5033b6216af0124d (patch)
tree554c86f5ddadd2610f5ac554770dede4b3d2b7b8
parent6aab2c816dad5fa8dda7c1fb4597ad5433c6181c (diff)
Add support for signature in PCKS7 format.
Signed-off-by: Bartosz Gardziejewski <bartosz.gardziejewski@nokia.com> Change-Id: Ic98d1b9c93c11c484c86338588922c2f347b7c02 Issue-ID: VNFSDK-714
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/r130206/CsarSourceSecurityValidator.java2
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/r130206/Error.java4
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/security/CmsSignatureDataFactory.java25
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/security/SignatureFactory.java60
-rw-r--r--csarvalidation/src/test/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206IntegrationTest.java114
-rw-r--r--csarvalidation/src/test/java/org/onap/cvc/csar/security/SignatureFactoryTest.java159
-rw-r--r--csarvalidation/src/test/java/org/onap/functional/PnfValidationFunctionalTest.java16
-rw-r--r--csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-cms-invalid-with-signature-of-individual-artifact-p7.csarbin0 -> 28210 bytes
-rw-r--r--csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-cms-valid-with-signature-of-individual-artifact-p7-DER.csarbin0 -> 28105 bytes
-rw-r--r--csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-cms-valid-with-signature-of-individual-artifact-p7.csarbin0 -> 28274 bytes
-rw-r--r--csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-tosca-individual-p7-signature-common-cert-invalid.csarbin0 -> 26695 bytes
-rw-r--r--csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-tosca-individual-p7-signature-common-cert-valid.csarbin0 -> 26707 bytes
-rw-r--r--csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-tosca-multiple-individual-signature.csarbin10824 -> 12975 bytes
-rw-r--r--csarvalidation/src/test/resources/security/signature/testEncodedSignature.sig.p7cbin0 -> 1515 bytes
-rw-r--r--csarvalidation/src/test/resources/security/signature/testSignature.sig.cms34
-rw-r--r--csarvalidation/src/test/resources/security/signature/testSignature.sig.p7b34
16 files changed, 421 insertions, 27 deletions
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/r130206/CsarSourceSecurityValidator.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/r130206/CsarSourceSecurityValidator.java
index 282b37d..8710c36 100644
--- a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/r130206/CsarSourceSecurityValidator.java
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/r130206/CsarSourceSecurityValidator.java
@@ -33,7 +33,7 @@ import java.util.List;
public class CsarSourceSecurityValidator {
public static final String SIGNATURE_FILE_TYPE = "signature";
- private static final String[] ARTIFACT_SIGNATURE_EXTENSIONS = {".sig.cms"};
+ private static final String[] ARTIFACT_SIGNATURE_EXTENSIONS = {".sig.cms",".sig.p7b",".sig.p7c"};
public static final String CERTIFICATE_FILE_TYPE = "certificate";
private static final String[] ARTIFACT_CERTIFICATE_EXTENSIONS = {".cert"};
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/r130206/Error.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/r130206/Error.java
index 72b036f..f74b6a5 100644
--- a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/r130206/Error.java
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/r130206/Error.java
@@ -170,9 +170,9 @@ public class Error {
public static class CSARErrorFailToLoadArtifactSignature extends CSARArchive.CSARError {
- public CSARErrorFailToLoadArtifactSignature(String path, String cms) {
+ public CSARErrorFailToLoadArtifactSignature(String source, String signature) {
super("0x4019");
- this.message = String.format("Fail to load signature '%s', for source '%s'!", path, cms);
+ this.message = String.format("Fail to load signature '%s', for source '%s'!", signature, source);
}
}
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/security/CmsSignatureDataFactory.java b/csarvalidation/src/main/java/org/onap/cvc/csar/security/CmsSignatureDataFactory.java
index 2744bc6..834f0ad 100644
--- a/csarvalidation/src/main/java/org/onap/cvc/csar/security/CmsSignatureDataFactory.java
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/security/CmsSignatureDataFactory.java
@@ -24,23 +24,21 @@ import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.SignerInformation;
-import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.util.Store;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Optional;
public class CmsSignatureDataFactory {
+ private final SignatureFactory signatureFactory = new SignatureFactory();
+
public CmsSignatureData createForFirstSigner(final byte[] cmsSignature, final byte[] fileContent)
- throws CmsSignatureLoadingException{
+ throws CmsSignatureLoadingException {
- try (ByteArrayInputStream cmsSignatureStream = new ByteArrayInputStream(cmsSignature)) {
- CMSSignedData signedData = getCMSSignedData(fileContent, cmsSignatureStream);
+ try {
+ CMSSignedData signedData = getCMSSignedData(fileContent, cmsSignature);
Collection<SignerInformation> signers = signedData.getSignerInfos().getSigners();
Store<X509CertificateHolder> certificates = signedData.getCertificates();
SignerInformation firstSigner = getFirstSigner(signers);
@@ -73,19 +71,10 @@ public class CmsSignatureDataFactory {
return cert;
}
-
- private CMSSignedData getCMSSignedData(byte[] innerPackageFileCSAR, ByteArrayInputStream signatureStream) throws IOException, CmsSignatureLoadingException, CMSException {
- ContentInfo signature = produceSignature(signatureStream);
+ private CMSSignedData getCMSSignedData(byte[] innerPackageFileCSAR, byte[] signatureStream) throws IOException, CmsSignatureLoadingException, CMSException {
+ ContentInfo signature = signatureFactory.createSignature(signatureStream);
CMSTypedData signedContent = new CMSProcessableByteArray(innerPackageFileCSAR);
return new CMSSignedData(signedContent, signature);
}
- private ContentInfo produceSignature(ByteArrayInputStream signatureStream) throws IOException, CmsSignatureLoadingException {
- Object parsedObject = new PEMParser(new InputStreamReader(signatureStream, Charset.defaultCharset())).readObject();
- if (!(parsedObject instanceof ContentInfo)) {
- throw new CmsSignatureLoadingException("Signature is not recognized!");
- }
- return ContentInfo.getInstance(parsedObject);
- }
-
}
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/security/SignatureFactory.java b/csarvalidation/src/main/java/org/onap/cvc/csar/security/SignatureFactory.java
new file mode 100644
index 0000000..00e9fce
--- /dev/null
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/security/SignatureFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2021 Nokia
+ * <p>
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ *
+ */
+
+package org.onap.cvc.csar.security;
+
+import org.apache.commons.codec.binary.Base64;
+import org.bouncycastle.asn1.cms.ContentInfo;
+import org.bouncycastle.openssl.PEMParser;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+public class SignatureFactory {
+
+ public static final String PEM_SIGNATURE_BEGIN_TAG = "-----BEGIN CMS-----";
+ public static final String PEM_SIGNATURE_END_TAG = "-----END CMS-----";
+
+ public ContentInfo createSignature(byte[] signatureStream) throws IOException, CmsSignatureLoadingException {
+ byte[] pemSignatureStream = convertSignatureToPemIfInDerFormat(signatureStream);
+ try(ByteArrayInputStream signatureInput = new ByteArrayInputStream(pemSignatureStream)) {
+ Object parsedObject = new PEMParser(new InputStreamReader(signatureInput)).readPemObject().getContent();
+ return ContentInfo.getInstance(parsedObject);
+ } catch (Exception e) {
+ throw new CmsSignatureLoadingException("Signature is not recognized!", e);
+ }
+ }
+
+ private byte[] convertSignatureToPemIfInDerFormat(byte[] signatureStream) throws IOException {
+ byte[] encodedSignatureStream = signatureStream.clone();
+ if (!Base64.isBase64(signatureStream)) {
+ encodedSignatureStream = Base64.encodeBase64(encodedSignatureStream);
+ encodedSignatureStream = wrapWithPemTags(encodedSignatureStream);
+ }
+ return encodedSignatureStream;
+ }
+
+ private byte[] wrapWithPemTags(byte[] encodedSignatureStream) throws IOException {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
+ outputStream.write( (PEM_SIGNATURE_BEGIN_TAG + "\n").getBytes() );
+ outputStream.write( encodedSignatureStream );
+ outputStream.write( ("\n" + PEM_SIGNATURE_END_TAG).getBytes() );
+ return outputStream.toByteArray();
+ }
+}
diff --git a/csarvalidation/src/test/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206IntegrationTest.java b/csarvalidation/src/test/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206IntegrationTest.java
index 4d6adc4..0015c02 100644
--- a/csarvalidation/src/test/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206IntegrationTest.java
+++ b/csarvalidation/src/test/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206IntegrationTest.java
@@ -29,6 +29,8 @@ import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.onap.cvc.csar.cc.sol004.IntegrationTestUtils.configureTestCase;
import static org.onap.cvc.csar.cc.sol004.IntegrationTestUtils.convertToMessagesList;
+import static org.onap.functional.CsarValidationUtility.CERTIFICATION_RULE;
+import static org.onap.functional.CsarValidationUtility.createExpectedError;
public class VTPValidateCSARR130206IntegrationTest {
@@ -630,7 +632,119 @@ public class VTPValidateCSARR130206IntegrationTest {
);
}
+ @Test
+ public void shouldReturnNoErrorWhenIndividualArtifactHaveP7Signature() throws Exception {
+
+ // given
+ configureTestCaseForRule130206("pnf/r130206/csar-cert-in-cms-valid-with-signature-of-individual-artifact-p7.csar");
+
+ // when
+ testCase.execute();
+
+ // then
+ List<CSARArchive.CSARError> errors = testCase.getErrors();
+
+ assertThat(convertToMessagesList(errors)).containsExactlyInAnyOrder(
+ "Manifest file has invalid signature!"
+ );
+ }
+
+ @Test
+ public void shouldReturnNoErrorWhenIndividualArtifactHaveP7SignatureInDERFormat() throws Exception {
+
+ // given
+ configureTestCaseForRule130206("pnf/r130206/csar-cert-in-cms-valid-with-signature-of-individual-artifact-p7-DER.csar");
+
+ // when
+ testCase.execute();
+
+ // then
+ List<CSARArchive.CSARError> errors = testCase.getErrors();
+
+ assertThat(convertToMessagesList(errors)).containsExactlyInAnyOrder(
+ "Manifest file has invalid signature!"
+ );
+ }
+
+ @Test
+ public void shouldReturnNoErrorWhenIndividualArtifactHaveP7SignatureAndUsesCommonCert() throws Exception {
+
+ // given
+ configureTestCaseForRule130206("pnf/r130206/csar-cert-in-tosca-individual-p7-signature-common-cert-valid.csar");
+
+ // when
+ testCase.execute();
+
+ // then
+ List<CSARArchive.CSARError> errors = testCase.getErrors();
+
+ assertThat(convertToMessagesList(errors)).containsExactlyInAnyOrder(
+ "Manifest file has invalid signature!"
+ );
+ }
+
+ @Test
+ public void shouldReturnErrorWhenIndividualArtifactHaveInvalidP7Signature() throws Exception {
+
+ // given
+ configureTestCaseForRule130206("pnf/r130206/csar-cert-in-cms-invalid-with-signature-of-individual-artifact-p7.csar");
+
+ // when
+ testCase.execute();
+
+ // then
+ List<CSARArchive.CSARError> errors = testCase.getErrors();
+
+ assertThat(convertToMessagesList(errors)).containsExactlyInAnyOrder(
+ "Source 'Files/Yang_module/mynetconf.yang' has incorrect signature!",
+ "Manifest file has invalid signature!"
+ );
+ }
+
+ @Test
+ public void shouldReturnErrorWhenIndividualArtifactHaveInvalidP7SignatureAndUsesCommonCert() throws Exception {
+
+ // given
+ configureTestCaseForRule130206("pnf/r130206/csar-cert-in-tosca-individual-p7-signature-common-cert-invalid.csar");
+
+ // when
+ testCase.execute();
+
+ // then
+ List<CSARArchive.CSARError> errors = testCase.getErrors();
+
+ assertThat(convertToMessagesList(errors)).containsExactlyInAnyOrder(
+ "Source 'Files/Yang_module/mynetconf.yang' has incorrect signature!",
+ "Manifest file has invalid signature!"
+ );
+ }
+
+ @Test
+ public void shouldReturnMultipleErrorsWhenMultipleIndividualArtifactsHaveInvalidSecurityData() throws Exception {
+
+ // given
+ configureTestCaseForRule130206("pnf/r130206/csar-cert-in-tosca-multiple-individual-signature.csar");
+
+ // when
+ testCase.execute();
+
+ // then
+ List<CSARArchive.CSARError> errors = testCase.getErrors();
+ assertThat(convertToMessagesList(errors)).containsExactlyInAnyOrder(
+ "Source 'Artifacts/Deployment/Events/RadioNode_Pnf_v1.yaml' has wrong hash!",
+ "Source 'Artifacts/Deployment/Events/RadioNode_Pnf_v2.yaml' has incorrect signature!",
+ "Source 'Artifacts/Deployment/Measurements/PM_Dictionary.yml' has 'signature' tag, pointing to non existing file!. Pointed file 'Artifacts/Deployment/Measurements/PM_Dictionary.sig.cms'",
+ "Source 'Artifacts/Deployment/Yang_module/yang-module1.yang' has 'signature' file with wrong name, signature name: 'yang-module.sig.cms'.Signature should have same name as source file!",
+ "Source 'Artifacts/Deployment/Yang_module/yang-module1.yang' has 'certificate' file with wrong name, signature name: 'yang-module.cert'.Signature should have same name as source file!",
+ "Source 'Artifacts/Other/my_script.csh' has incorrect signature!",
+ "Source 'Artifacts/Informational/user_guide.txt' has 'signature' file located in wrong directory, directory: 'Artifacts/user_guide.sig.cms'.Signature should be in same directory as source file!",
+ "Source 'Artifacts/Informational/user_guide.txt' has 'certificate' file located in wrong directory, directory: 'Artifacts/user_guide.cert'.Signature should be in same directory as source file!",
+ "Manifest file has invalid signature!"
+ );
+ }
+
private void configureTestCaseForRule130206(String filePath) throws OnapCommandException, URISyntaxException {
configureTestCase(testCase, filePath, VTP_VALIDATE_SCHEMA, IS_PNF);
}
+
}
diff --git a/csarvalidation/src/test/java/org/onap/cvc/csar/security/SignatureFactoryTest.java b/csarvalidation/src/test/java/org/onap/cvc/csar/security/SignatureFactoryTest.java
new file mode 100644
index 0000000..baa88c0
--- /dev/null
+++ b/csarvalidation/src/test/java/org/onap/cvc/csar/security/SignatureFactoryTest.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2021 Nokia
+ * <p>
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ *
+ */
+
+package org.onap.cvc.csar.security;
+
+import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.cms.ContentInfo;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Base64;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class SignatureFactoryTest {
+
+ private final static String testPemSignature = "" +
+ "-----BEGIN CMS-----\n" +
+ "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" +
+ "dDrh3CbBGa9nLr6i1jOOp1TxYM8/e2kYbVIl" +
+ "\n-----END CMS-----";
+
+ private final static String testPkcs7Signature = "" +
+ "-----BEGIN PKCS7-----\n" +
+ "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" +
+ "dDrh3CbBGa9nLr6i1jOOp1TxYM8/e2kYbVIl" +
+ "\n-----END PKCS7-----";
+
+ private SignatureFactory signatureFactory;
+
+ @Before
+ public void setUp(){
+ signatureFactory = new SignatureFactory();
+ }
+
+ @Test
+ public void shouldCreateContentInfoWithProperContentForPEM() throws IOException, CmsSignatureLoadingException {
+
+ // when
+ ContentInfo contentInfo = signatureFactory.createSignature(testPemSignature.getBytes());
+
+ // then
+ final String contentInfoSignature = getContentInfoSignatureAsPem(contentInfo);
+ assertThat(testPemSignature).contains(contentInfoSignature);
+ }
+
+ @Test
+ public void shouldCreateContentInfoWithProperContentForPKCS7() throws IOException, CmsSignatureLoadingException {
+
+ // when
+ ContentInfo contentInfo = signatureFactory.createSignature(testPkcs7Signature.getBytes());
+
+ // then
+ final String contentInfoSignature = getContentInfoSignatureAsPem(contentInfo);
+ assertThat(testPkcs7Signature).contains(contentInfoSignature);
+ }
+
+ @Test
+ public void shouldCreateContentInfoWithProperContentForDecodedPKCS7() throws IOException, CmsSignatureLoadingException {
+ // given
+ InputStream signatureAsStream = loadFileFromResources("./security/signature/testEncodedSignature.sig.p7c");
+
+ // when
+ ContentInfo contentInfo = signatureFactory.createSignature(signatureAsStream.readAllBytes());
+
+ // then
+ final String contentInfoSignature = getContentInfoSignatureAsPem(contentInfo);
+ assertThat(testPkcs7Signature).contains(contentInfoSignature);
+ }
+
+ private InputStream loadFileFromResources(String fileFromResources) throws IOException{
+ InputStream resourceAsStream = SignatureFactoryTest.class.getClassLoader().getResourceAsStream(fileFromResources);
+ if(resourceAsStream==null) {
+ throw new IOException(String.format("fail to load file: %s from resourcer", fileFromResources));
+ }
+ return resourceAsStream;
+ }
+
+ private String getContentInfoSignatureAsPem(ContentInfo contentInfo) throws IOException {
+ return new String(Base64.getEncoder().encode(contentInfo.toASN1Primitive().getEncoded(ASN1Encoding.DER)));
+ }
+
+}
diff --git a/csarvalidation/src/test/java/org/onap/functional/PnfValidationFunctionalTest.java b/csarvalidation/src/test/java/org/onap/functional/PnfValidationFunctionalTest.java
index 2038eca..2477377 100644
--- a/csarvalidation/src/test/java/org/onap/functional/PnfValidationFunctionalTest.java
+++ b/csarvalidation/src/test/java/org/onap/functional/PnfValidationFunctionalTest.java
@@ -258,10 +258,10 @@ public class PnfValidationFunctionalTest {
assertThat(ruleValidationResult.warnings).isEmpty();
if (ruleValidationResult.vnfreqName.equals(CERTIFICATION_RULE)) {
assertThat(ruleValidationResult.errors)
- .containsAll(expectedCertificationErrors);
+ .containsExactlyInAnyOrderElementsOf(expectedCertificationErrors);
} else if (ruleValidationResult.vnfreqName.equals(MANIFEST_FILE_RULE)) {
assertThat(ruleValidationResult.errors)
- .containsAll(expectedManifestErrors);
+ .containsExactlyInAnyOrderElementsOf(expectedManifestErrors);
} else {
assertThat(ruleValidationResult.errors).isEmpty();
}
@@ -274,6 +274,10 @@ public class PnfValidationFunctionalTest {
// given
List<OnapCliValidationResponseWrapper.ValidationResultWrapper.ValidationErrorWrapper> expectedCertificationErrors =
List.of(
+ createExpectedError(CERTIFICATION_RULE, "0x4004",
+ "Source 'Artifacts/Deployment/Events/RadioNode_Pnf_v1.yaml' has wrong hash!"),
+ createExpectedError(CERTIFICATION_RULE, "0x4020",
+ "Source 'Artifacts/Deployment/Events/RadioNode_Pnf_v2.yaml' has incorrect signature!"),
createExpectedError(CERTIFICATION_RULE, "0x4018",
"Source 'Artifacts/Deployment/Measurements/PM_Dictionary.yml' has 'signature' tag, pointing to non existing file!. Pointed file 'Artifacts/Deployment/Measurements/PM_Dictionary.sig.cms'"),
createExpectedError(CERTIFICATION_RULE, "0x4023",
@@ -338,19 +342,19 @@ public class PnfValidationFunctionalTest {
switch (ruleValidationResult.vnfreqName) {
case CERTIFICATION_RULE:
assertThat(ruleValidationResult.errors)
- .containsAll(expectedCertificationErrors);
+ .containsExactlyInAnyOrderElementsOf(expectedCertificationErrors);
break;
case MANIFEST_FILE_RULE:
assertThat(ruleValidationResult.errors)
- .containsAll(expectedManifestErrors);
+ .containsExactlyInAnyOrderElementsOf(expectedManifestErrors);
break;
case PM_DICTIONARY_YAML_RULE:
assertThat(ruleValidationResult.errors)
- .containsAll(expectedPnfDictionaryErrors);
+ .containsExactlyInAnyOrderElementsOf(expectedPnfDictionaryErrors);
break;
case NON_MANO_FILES_RULE:
assertThat(ruleValidationResult.errors)
- .containsAll(expectedNonManoFilesErrors);
+ .containsExactlyInAnyOrderElementsOf(expectedNonManoFilesErrors);
break;
default:
assertThat(ruleValidationResult.errors).isEmpty();
diff --git a/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-cms-invalid-with-signature-of-individual-artifact-p7.csar b/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-cms-invalid-with-signature-of-individual-artifact-p7.csar
new file mode 100644
index 0000000..2b1b48b
--- /dev/null
+++ b/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-cms-invalid-with-signature-of-individual-artifact-p7.csar
Binary files differ
diff --git a/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-cms-valid-with-signature-of-individual-artifact-p7-DER.csar b/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-cms-valid-with-signature-of-individual-artifact-p7-DER.csar
new file mode 100644
index 0000000..5277099
--- /dev/null
+++ b/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-cms-valid-with-signature-of-individual-artifact-p7-DER.csar
Binary files differ
diff --git a/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-cms-valid-with-signature-of-individual-artifact-p7.csar b/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-cms-valid-with-signature-of-individual-artifact-p7.csar
new file mode 100644
index 0000000..4f55629
--- /dev/null
+++ b/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-cms-valid-with-signature-of-individual-artifact-p7.csar
Binary files differ
diff --git a/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-tosca-individual-p7-signature-common-cert-invalid.csar b/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-tosca-individual-p7-signature-common-cert-invalid.csar
new file mode 100644
index 0000000..ad9df38
--- /dev/null
+++ b/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-tosca-individual-p7-signature-common-cert-invalid.csar
Binary files differ
diff --git a/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-tosca-individual-p7-signature-common-cert-valid.csar b/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-tosca-individual-p7-signature-common-cert-valid.csar
new file mode 100644
index 0000000..cbf02d2
--- /dev/null
+++ b/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-tosca-individual-p7-signature-common-cert-valid.csar
Binary files differ
diff --git a/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-tosca-multiple-individual-signature.csar b/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-tosca-multiple-individual-signature.csar
index c2560bd..1b25855 100644
--- a/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-tosca-multiple-individual-signature.csar
+++ b/csarvalidation/src/test/resources/pnf/r130206/csar-cert-in-tosca-multiple-individual-signature.csar
Binary files differ
diff --git a/csarvalidation/src/test/resources/security/signature/testEncodedSignature.sig.p7c b/csarvalidation/src/test/resources/security/signature/testEncodedSignature.sig.p7c
new file mode 100644
index 0000000..3709390
--- /dev/null
+++ b/csarvalidation/src/test/resources/security/signature/testEncodedSignature.sig.p7c
Binary files differ
diff --git a/csarvalidation/src/test/resources/security/signature/testSignature.sig.cms b/csarvalidation/src/test/resources/security/signature/testSignature.sig.cms
new file mode 100644
index 0000000..30612a4
--- /dev/null
+++ b/csarvalidation/src/test/resources/security/signature/testSignature.sig.cms
@@ -0,0 +1,34 @@
+-----BEGIN CMS-----
+MIIF5wYJKoZIhvcNAQcCoIIF2DCCBdQCAQExDTALBglghkgBZQMEAgEwCwYJKoZI
+hvcNAQcBoIIDMjCCAy4wggIWAhR5r1QBcQCve4lQft5zSZ4MPH5XHjANBgkqhkiG
+9w0BAQsFADBTMQswCQYDVQQGEwJQTDEMMAoGA1UECAwDc2lsMQwwCgYDVQQHDAN3
+cmMxDjAMBgNVBAoMBU5PS0lBMRgwFgYDVQQDDA9ub2tpYS50ZXN0LmNlcnQwHhcN
+MjAxMjA4MTMyNDIxWhcNMjEwMTA3MTMyNDIxWjBUMQswCQYDVQQGEwJQTDEMMAoG
+A1UECAwDc2lsMQwwCgYDVQQHDAN3cmMxDjAMBgNVBAoMBU5PS0lBMRkwFwYDVQQD
+DBBub2tpYS50ZXN0LmludGVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAv7XBTY4K7Szn8XNZerp3un5WXIuPjrLBo9mBFbnWwURKURDwbFkwxQwARvFW
+xFylVAQ7kESQYtJFvcdNar1yDLHdi7ntf1s/AHZkPOp9OVDWUQTemVqE9JJDLK9c
+lOpwwujfdDbpdYIaE3ih13Fu4gGqQJVlRiQQLuximC6MCNmdQwo1OSV04acPmxVB
++1raz5p3jy52PG1VYLvn4qU4TDMGy3Cb9Eu2ihVL0zK3mdgpt4K5JFJFbmDWlFo2
+jfiqGrPrpR8Sg6ZHKOAvRHpOl5yggZwpxChCNH/tor7mgC3HGs+y425t4z1tiPXJ
+K3RYr4yS+2VwgxHwkpZnQ35UhwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCqnrll
+bkLUh1tfxuC1pe8op5IwlfWZghhs6zyLpSZ6MC6BRRn0Lr/rkCmn3s6NNEB8UJIo
+Gw+DDhlk4tuFWdPOKaTtoJwNPqeE0Eq+QO4OKatM4aqFGRgjF5kLDgHj7AeKVTi2
+TfkB1m8BDFjbLqTVAfHQ8zqHJ5OpFCioyjOjztKKTpt/6CrPBIoctBL2hM5pBFTb
+a0sZlgQ/zFHjJVx+hvWpb9cNPMA7w2eANiXCOMsdL8BMTGk+hl3G/tw7b1G/Afnm
+ksmw124CsbXY02axtt52Jg6nJZqq+TcU4ApwREtOOu7t+emqSCXuAY45loqiquyD
+tTtEe+VmMdvBq6BqMYICezCCAncCAQEwazBTMQswCQYDVQQGEwJQTDEMMAoGA1UE
+CAwDc2lsMQwwCgYDVQQHDAN3cmMxDjAMBgNVBAoMBU5PS0lBMRgwFgYDVQQDDA9u
+b2tpYS50ZXN0LmNlcnQCFHmvVAFxAK97iVB+3nNJngw8flceMAsGCWCGSAFlAwQC
+AaCB5DAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0y
+MDEyMDgxMzI3MTNaMC8GCSqGSIb3DQEJBDEiBCAaebVqT67TRo7xFd6IJsRmRHVp
+TmogPE1ZYjerP1mxxzB5BgkqhkiG9w0BCQ8xbDBqMAsGCWCGSAFlAwQBKjALBglg
+hkgBZQMEARYwCwYJYIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMCAgIA
+gDANBggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDANBgkqhkiG
+9w0BAQEFAASCAQABt5I0W3LQW6/8qmWthZvtXoAKpwXN8cc6A/wEPJvoUwQHh70c
+iKlUYwKTcc+BhEyTzuMbuLRi5IPGFpbf1pSbORLiAuvkcrRWfKfzMchTR+X1tAzk
+NwxLneezzT4iaYWBADx5nWpTYYY3yb1MOQPtFN1lWYbkaRzDXYb1/vUI+3CmnnE5
+l+iZV+TcfA9wZkyZ9yCRPaLIrMbbc5u4RaPw2Wuu0HQz2oOPAYRyrxIaUM4qbVsd
+xr/KJgulSI4ZITM+jbG0HQE1qmZAZSD+TGXsxfz4zFvsoSZ/ZoDwOf1Dn6Yp6Vhp
+dDrh3CbBGa9nLr6i1jOOp1TxYM8/e2kYbVIl
+-----END CMS-----
diff --git a/csarvalidation/src/test/resources/security/signature/testSignature.sig.p7b b/csarvalidation/src/test/resources/security/signature/testSignature.sig.p7b
new file mode 100644
index 0000000..2e00705
--- /dev/null
+++ b/csarvalidation/src/test/resources/security/signature/testSignature.sig.p7b
@@ -0,0 +1,34 @@
+-----BEGIN PKCS7-----
+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
+dDrh3CbBGa9nLr6i1jOOp1TxYM8/e2kYbVIl
+-----END PKCS7-----