Skip to content

Commit

Permalink
Merge pull request #81 from openpreserve/fix/dsig-validation
Browse files Browse the repository at this point in the history
FIX: Dsignature validation
  • Loading branch information
carlwilson authored Nov 8, 2023
2 parents 6f119d9 + 286d0d3 commit db5f339
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ private ValidatingParserImpl()
public ValidationReport validatePackage(final OdfPackage toValidate) {
Objects.requireNonNull(toValidate, String.format(Checks.NOT_NULL, TO_VALIDATE, "OdfPackage"));
this.results.clear();
final ValidationReport report = ValidationReport.of(toValidate.getName());
if (!toValidate.isWellFormedZip()) {
final ValidationReport report = ValidationReport.of(toValidate.getName());
report.add(toValidate.getName(), FACTORY.getError("PKG-9"));
return report;
}
Expand Down Expand Up @@ -177,6 +177,7 @@ private final List<Message> validateMimeEntry(final ZipEntry mimeEntry, final bo
if (mimeEntry.getExtra() != null && mimeEntry.getExtra().length > 0) {
messages.add(FACTORY.getError("PKG-8"));
}

return messages;
}

Expand Down Expand Up @@ -230,8 +231,10 @@ private final Map<String, List<Message>> auditZipEntries(final OdfPackage odfPac
messages.add(FACTORY.getError("PKG-1", zipEntry.getName()));
}
if (zipEntry.getName().startsWith(OdfPackages.NAME_META_INF)
&& (zipEntry.isDirectory() && !OdfPackages.NAME_META_INF.equals(zipEntry.getName()))) {
&& (!zipEntry.isDirectory() && !OdfPackages.PATH_MANIFEST.equals(zipEntry.getName())
&& !OdfPackages.isDsig(zipEntry.getName()))) {
messages.add(FACTORY.getError("PKG-3", zipEntry.getName()));
messageMap.put(zipEntry.getName(), messages);
}
if (zipEntry.isDirectory() || !isLegitimateManifestEntry(zipEntry.getName())) {
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,41 @@
import org.openpreservation.messages.Message;
import org.openpreservation.messages.MessageLog;
import org.openpreservation.messages.Messages;
import org.openpreservation.odf.document.OpenDocument;

public class ValidationReport {
final String name;
public final OpenDocument document;
public final Map<String, MessageLog> documentMessages;

private ValidationReport(final String name) {
this(name, new HashMap<>());
this(name, null);
}

private ValidationReport(final String name, final Map<String, MessageLog> documentMessages) {
private ValidationReport(final String name, final OpenDocument document) {
this(name, document, new HashMap<>());
}

private ValidationReport(final String name, final OpenDocument document, final Map<String, MessageLog> documentMessages) {
super();
this.name = name;
this.document = document;
this.documentMessages = documentMessages;
}

static final ValidationReport of(final String name) {
return new ValidationReport(name);
}
static final ValidationReport of(final String name, final OpenDocument document) {
return new ValidationReport(name, document);
}

static final ValidationReport of(final String name, final Map<String, MessageLog> documentMessages) {
return new ValidationReport(name, documentMessages);
return new ValidationReport(name, null, documentMessages);
}

static final ValidationReport of(final String name, final OpenDocument document, final Map<String, MessageLog> documentMessages) {
return new ValidationReport(name, document, documentMessages);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ DOC-4 = Invalid MIMETYPE declaration %s detected.
DOC-5 = No MIMETYPE declaration detected.
PKG-1 = All files contained in the Zip file shall be non compressed (STORED) or compressed using the “deflate” (DEFLATED) algorithm. Zip entry %s is compressed with an unknown algorithm.
PKG-2 = An OpenDocument package SHOULD contain a file "mimetype".
PKG-3 = Subdirectory %s not allowed in the "META-INF" folder.
PKG-3 = An OpenDocument package SHALL only contain the "META-INF/manifest.xml" and files containg the term "signatures" in their name in the "META-INF" folder. File %s does not meet this criteria.
PKG-4 = An OpenDocument package SHALL contain a file “META-INF/manifest.xml”.
PKG-5 = The content of the "mimetype" file SHALL be ASCII encoded.
PKG-6 = The "mimetype" file SHALL NOT be compressed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class TestFiles {
final static String THUMBNAIL_TEST_ROOT = PKG_TEST_ROOT + "thumbnail/";
final static String EMBEDDED_TEST_ROOT = PKG_TEST_ROOT + "embedded/";
final static String ENCRYPTED_TEST_ROOT = PKG_TEST_ROOT + "encrypted/";
final static String DSIG_TEST_ROOT = PKG_TEST_ROOT + "dsigs/";
final static String XML_TEST_ROOT = TEST_ROOT + "xml/";
final static String FILE_TEST_ROOT = TEST_ROOT + "files/";
public final static URL EMPTY_ODS = ClassLoader.getSystemResource(ZIP_TEST_ROOT + "empty.ods");
Expand Down Expand Up @@ -52,5 +53,7 @@ public class TestFiles {
public final static URL FAKEMIME_TEXT = ClassLoader.getSystemResource(FILE_TEST_ROOT + "mimefake.txt");
final static URL MIMESIG_ODS = ClassLoader.getSystemResource(FILE_TEST_ROOT + "mimesig-ods.txt");
final static URL MIMESIG_OTS = ClassLoader.getSystemResource(FILE_TEST_ROOT + "mimesig-ots.txt");
public final static URL DSIG_EXAMPLE = ClassLoader.getSystemResource(TEST_ROOT + "dsigs.odt");
public final static URL DSIG_INVALID = ClassLoader.getSystemResource(DSIG_TEST_ROOT + "dsigs.odt");
public final static URL DSIG_VALID = ClassLoader.getSystemResource(DSIG_TEST_ROOT + "dsigs-valid.ods");
public final static URL DSIG_BADNAME = ClassLoader.getSystemResource(DSIG_TEST_ROOT + "bad_dsig_name.ods");
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public void testHasThumbnail() throws IOException, URISyntaxException {
@Test
public void testXmlEntryPaths() throws IOException, URISyntaxException {
PackageParser parser = PackageParserImpl.getInstance();
OdfPackage pkg = parser.parsePackage(new File(TestFiles.DSIG_EXAMPLE.toURI()));
OdfPackage pkg = parser.parsePackage(new File(TestFiles.DSIG_INVALID.toURI()));
final List<String> entryPaths = Collections.unmodifiableList(pkg.getXmlEntryPaths());
assertEquals("Package should have 7 XML entries", 7, entryPaths.size());
assertTrue("Package should have a styles.xml entry", entryPaths.contains("styles.xml"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ public void testParsePackageStream() throws ParserConfigurationException, SAXExc
}

@Test
public void testDsigValidation() throws ParserConfigurationException, SAXException, IOException {
public void testDsigParsing() throws ParserConfigurationException, SAXException, IOException {
PackageParser parser = OdfPackages.getPackageParser();
InputStream is = TestFiles.DSIG_EXAMPLE.openStream();
OdfPackage pkg = parser.parsePackage(is, TestFiles.DSIG_EXAMPLE.toString());
InputStream is = TestFiles.DSIG_INVALID.openStream();
OdfPackage pkg = parser.parsePackage(is, TestFiles.DSIG_INVALID.toString());
ParseResult result = pkg.getEntryXmlParseResult("META-INF/documentsignatures.xml");
assertNotNull("Dsig file META-INF/documentsignatures.xml result should not be null" , result);
assertTrue("Package should have a well formed dsig for META-INF/documentsignatures.xml" , result.isWellFormed());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
import javax.xml.parsers.ParserConfigurationException;

import org.junit.Test;
import org.openpreservation.format.xml.ParseResult;
import org.openpreservation.odf.fmt.TestFiles;
import org.openpreservation.odf.pkg.OdfPackage;
import org.openpreservation.odf.pkg.OdfPackages;
import org.openpreservation.odf.pkg.PackageParser;
import org.xml.sax.SAXException;

public class ValidatingParserTest {
Expand Down Expand Up @@ -324,4 +327,32 @@ public void testPasswordEncrypted() throws ParserConfigurationException, SAXExce
assertFalse("ENCRYPTED_PASSWORDS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("XML-3")).count() > 0);
}

@Test
public void testDsigValid() throws ParserConfigurationException, SAXException, IOException {
ValidatingParser parser = Validators.getValidatingParser();
InputStream is = TestFiles.DSIG_VALID.openStream();
OdfPackage pkg = parser.parsePackage(is, TestFiles.DSIG_VALID.toString());
ValidationReport report = parser.validatePackage(pkg);
assertTrue("Package should be be valid" , report.isValid());
}

@Test
public void testDsigInvalid() throws ParserConfigurationException, SAXException, IOException {
ValidatingParser parser = Validators.getValidatingParser();
InputStream is = TestFiles.DSIG_INVALID.openStream();
OdfPackage pkg = parser.parsePackage(is, TestFiles.DSIG_INVALID.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("Package should be NOT be valid, dsig file has bad version" , report.isValid());
}

@Test
public void testDsigInvalidBadName() throws ParserConfigurationException, SAXException, IOException {
ValidatingParser parser = Validators.getValidatingParser();
InputStream is = TestFiles.DSIG_BADNAME.openStream();
OdfPackage pkg = parser.parsePackage(is, TestFiles.DSIG_BADNAME.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("Package should be NOT be valid, badly named META-INF file." , report.isValid());
assertEquals(1, report.getMessages().stream().filter(m -> m.getId().equals("PKG-3")).count());
}
}
Binary file not shown.
Binary file not shown.

0 comments on commit db5f339

Please sign in to comment.