From 8db4db6563a98c4fac3e833707ab2b14098657d5 Mon Sep 17 00:00:00 2001 From: Lianhao Lu Date: Fri, 22 Nov 2019 10:11:45 +0800 Subject: Support non DOS/Windows format CSAR manifest file When recreating the csar manifest file during signature verification, we should use the same newline charater as the original file instead of using the DOS/Windows newline charater to avoid false positive signature verfication failure. Issue-ID: VNFSDK-520 Signed-off-by: Lianhao Lu Change-Id: I7bdf0a7f6b46c7def0a92d7ec7f245e268355959 --- .../cvc/csar/cc/sol004/VTPValidateCSARR130206.java | 8 ++-- .../onap/cvc/csar/parser/ManifestFileModel.java | 10 +++++ .../onap/cvc/csar/parser/ManifestFileSplitter.java | 51 ++++++++++++++++++++-- .../cvc/csar/parser/ManifestFileSplitterTest.java | 23 ++++++++-- .../cvc/csar/parser/MainServiceTemplate.windows.mf | 10 +++++ 5 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 csarvalidation/src/test/resources/cvc/csar/parser/MainServiceTemplate.windows.mf diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206.java index 16b6942..701c524 100644 --- a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206.java +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206.java @@ -254,15 +254,17 @@ class ManifestFileSignatureValidator { boolean isValid(File manifestFile) { try { ManifestFileModel mf = manifestFileSplitter.split(manifestFile); - return cmsSignatureValidator.verifySignedData(toBytes(mf.getCMS()), Optional.empty(), toBytes(mf.getData())); + return cmsSignatureValidator.verifySignedData(toBytes(mf.getCMS(), mf.getNewLine()), + Optional.empty(), + toBytes(mf.getData(), mf.getNewLine())); } catch (CmsSignatureValidatorException e) { LOG.error("Unable to verify signed data!", e); return false; } } - private byte[] toBytes(List data) { - final String updatedData = data.stream().map(it -> it + "\r\n").collect(Collectors.joining()); + private byte[] toBytes(List data, String newLine) { + final String updatedData = data.stream().map(it -> it + newLine).collect(Collectors.joining()); return updatedData.getBytes(Charset.defaultCharset()); } } diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestFileModel.java b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestFileModel.java index f6b42fd..ee7ade9 100644 --- a/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestFileModel.java +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestFileModel.java @@ -23,10 +23,16 @@ import java.util.List; public class ManifestFileModel { private final List data; private final List cms; + private final String newLine; public ManifestFileModel(List data, List cms) { + this(data, cms, "\n"); + } + + public ManifestFileModel(List data, List cms, String newLine) { this.data = data; this.cms = cms; + this.newLine = newLine; } public List getData() { @@ -36,4 +42,8 @@ public class ManifestFileModel { public List getCMS() { return Collections.unmodifiableList(cms); } + + public String getNewLine() { + return newLine; + } } diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestFileSplitter.java b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestFileSplitter.java index d780e67..f8d920c 100644 --- a/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestFileSplitter.java +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/parser/ManifestFileSplitter.java @@ -21,8 +21,11 @@ package org.onap.cvc.csar.parser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.BufferedReader; import java.io.File; +import java.io.FileReader; import java.io.IOException; +import java.io.Reader; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -30,6 +33,48 @@ import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; +class FileFormat { + public enum FileType { WINDOWS, UNIX, MAC, UNKNOWN } + + private static final char CR = '\r'; + private static final char LF = '\n'; + + private FileFormat() { + } + + public static FileType discover(String fileName) throws IOException { + + try (Reader reader = new BufferedReader(new FileReader(fileName))) { + return discover(reader); + } + } + + public static String getNewLine(String fileName) throws IOException { + switch(discover(fileName)) { + case WINDOWS: return String.valueOf(CR) + String.valueOf(LF); + case MAC: return String.valueOf(CR); + default: return String.valueOf(LF); + } + } + + private static FileType discover(Reader reader) throws IOException { + int c; + while ((c = reader.read()) != -1) { + switch(c) { + case LF: return FileType.UNIX; + case CR: { + if (reader.read() == LF) + return FileType.WINDOWS; + else + return FileType.MAC; + } + default: continue; + } + } + return FileType.UNKNOWN; + } +} + public class ManifestFileSplitter { private static final Logger LOG = LoggerFactory.getLogger(ManifestFileSplitter.class); @@ -41,7 +86,7 @@ public class ManifestFileSplitter { try (Stream stream = Files.lines(Paths.get(fileName))) { List lines = stream.collect(Collectors.toList()); - return createManifestFileModel(data, cms, lines); + return createManifestFileModel(data, cms, lines, FileFormat.getNewLine(fileName)); } catch (IOException e) { LOG.error("Unable to process manifest file!", e); @@ -49,7 +94,7 @@ public class ManifestFileSplitter { } } - private ManifestFileModel createManifestFileModel(List data, List cms, List lines) { + private ManifestFileModel createManifestFileModel(List data, List cms, List lines, String newLine) { boolean isCmsSection = false; for (String line : lines) { @@ -63,6 +108,6 @@ public class ManifestFileSplitter { data.add(line); } } - return new ManifestFileModel(data, cms); + return new ManifestFileModel(data, cms, newLine); } } diff --git a/csarvalidation/src/test/java/org/onap/cvc/csar/parser/ManifestFileSplitterTest.java b/csarvalidation/src/test/java/org/onap/cvc/csar/parser/ManifestFileSplitterTest.java index b530691..11cddbe 100644 --- a/csarvalidation/src/test/java/org/onap/cvc/csar/parser/ManifestFileSplitterTest.java +++ b/csarvalidation/src/test/java/org/onap/cvc/csar/parser/ManifestFileSplitterTest.java @@ -21,19 +21,27 @@ import org.assertj.core.api.Assertions; import org.junit.Test; import java.io.File; +import java.net.URISyntaxException; + +import static org.onap.cvc.csar.cc.sol004.IntegrationTestUtils.absoluteFilePath; /* How to sing files see to README.txt file into test/resources folder */ public class ManifestFileSplitterTest { - @Test - public void shouldSplitManifestFileOnDataPartAndCMS() { - File file = new File("./src/test/resources/cvc/csar/parser/MainServiceTemplate.mf"); + private ManifestFileModel getModel(String resourceFilePath) throws URISyntaxException { + File file = new File(absoluteFilePath(resourceFilePath)); ManifestFileSplitter manifestFileSplitter = new ManifestFileSplitter(); + return manifestFileSplitter.split(file); + } - ManifestFileModel manifestFileModel = manifestFileSplitter.split(file); + @Test + public void shouldSplitManifestFileOnDataPartAndCMS() throws URISyntaxException { + String resource = "cvc/csar/parser/MainServiceTemplate.mf"; + ManifestFileModel manifestFileModel = getModel(resource); + Assertions.assertThat(manifestFileModel.getNewLine()).isEqualTo("\n"); Assertions.assertThat(manifestFileModel.getData()).contains("metadata:", " pnfd_name: RadioNode", " pnfd_provider: Ericsson", @@ -47,4 +55,11 @@ public class ManifestFileSplitterTest { "-----END CMS-----" ); } + + @Test + public void shouldBeWindowsStyle() throws URISyntaxException { + String resource = "cvc/csar/parser/MainServiceTemplate.windows.mf"; + ManifestFileModel manifestFileModel = getModel(resource); + Assertions.assertThat(manifestFileModel.getNewLine()).isEqualTo("\r\n"); + } } diff --git a/csarvalidation/src/test/resources/cvc/csar/parser/MainServiceTemplate.windows.mf b/csarvalidation/src/test/resources/cvc/csar/parser/MainServiceTemplate.windows.mf new file mode 100644 index 0000000..5703942 --- /dev/null +++ b/csarvalidation/src/test/resources/cvc/csar/parser/MainServiceTemplate.windows.mf @@ -0,0 +1,10 @@ +metadata: + pnfd_name: RadioNode + pnfd_provider: Ericsson + pnfd_archive_version: 1.0 + pnfd_release_date_time: 2019-01-14T11:25:00+00:00 + +-----BEGIN CMS----- +MIIGDAYJKoZIhvcNAQcCoIIF/TCCBfkCAQExDTALBglghkgBZQMEAgEwCwYJKoZI +hvcNAQcBoIIDRTCCA0EwggIpAhRJ6KO7OFR2BuRDZwcd2TT4/wrEqDANBgkqhkiG +-----END CMS----- -- cgit 1.2.3-korg