From 2b9a4f35e2e50fca4304107b5033b6216af0124d Mon Sep 17 00:00:00 2001 From: Bartosz Gardziejewski Date: Tue, 12 Jan 2021 10:33:18 +0100 Subject: Add support for signature in PCKS7 format. Signed-off-by: Bartosz Gardziejewski Change-Id: Ic98d1b9c93c11c484c86338588922c2f347b7c02 Issue-ID: VNFSDK-714 --- .../VTPValidateCSARR130206IntegrationTest.java | 114 +++++++++++++++ .../cvc/csar/security/SignatureFactoryTest.java | 159 +++++++++++++++++++++ 2 files changed, 273 insertions(+) create mode 100644 csarvalidation/src/test/java/org/onap/cvc/csar/security/SignatureFactoryTest.java (limited to 'csarvalidation/src/test/java/org/onap/cvc') 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 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 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 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 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 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 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 + *

+ * 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. + * + */ + +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" + + "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" + + "\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))); + } + +} -- cgit 1.2.3-korg