/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE file at the root of the source * tree and available online at * * https://github.com/keeps/roda */ package org.roda.core.plugins.plugins.characterization; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.security.GeneralSecurityException; import java.security.SignatureException; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.roda.core.data.common.RodaConstants; import org.roda.core.data.exceptions.AuthorizationDeniedException; import org.roda.core.data.exceptions.GenericException; import org.roda.core.data.exceptions.NotFoundException; import org.roda.core.data.exceptions.RequestNotValidException; import org.roda.core.data.v2.ip.File; import org.roda.core.model.ModelService; import org.roda.core.storage.ContentPayload; import org.roda.core.storage.fs.FSPathContentPayload; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.itextpdf.text.DocumentException; public class DigitalSignaturePluginUtils { private static final Logger LOGGER = LoggerFactory.getLogger(DigitalSignaturePluginUtils.class); protected static final String PDF_FORMAT = "pdf"; protected static final String OOXML_FORMAT = "ooxml"; protected static final String ODF_FORMAT = "odf"; private DigitalSignaturePluginUtils() { // do nothing } public static String runDigitalSignatureVerify(Path input, String fileFormat, String mimetype) { String generalFileFormat = SignatureUtils.canHaveEmbeddedSignature(fileFormat, mimetype); try { if (PDF_FORMAT.equals(generalFileFormat)) { return PDFSignatureUtils.runDigitalSignatureVerify(input); } else if (OOXML_FORMAT.equals(generalFileFormat)) { return OOXMLSignatureUtils.runDigitalSignatureVerify(input); } else if (ODF_FORMAT.equals(generalFileFormat)) { return ODFSignatureUtils.runDigitalSignatureVerify(input); } } catch (IOException | GeneralSecurityException e) { LOGGER.warn("Problems running digital signature verification, reason: {}", e.getMessage()); } return "Not a supported format"; } public static int runDigitalSignatureExtraction(ModelService model, File file, Path input, String fileFormat, String mimetype) { List<Path> extractResult = new ArrayList<>(); try { String generalFileFormat = SignatureUtils.canHaveEmbeddedSignature(fileFormat, mimetype); if (PDF_FORMAT.equals(generalFileFormat)) { extractResult = PDFSignatureUtils.runDigitalSignatureExtract(input); if (!extractResult.isEmpty()) { ContentPayload mainPayload = new FSPathContentPayload(extractResult.get(0)); ContentPayload contentsPayload = new FSPathContentPayload(extractResult.get(1)); model.createOrUpdateOtherMetadata(file.getAipId(), file.getRepresentationId(), file.getPath(), file.getId().substring(0, file.getId().lastIndexOf('.')), ".xml", RodaConstants.OTHER_METADATA_TYPE_DIGITAL_SIGNATURE, mainPayload, true); if (extractResult.get(1).toFile().length() > 0) { model.createOrUpdateOtherMetadata(file.getAipId(), file.getRepresentationId(), file.getPath(), file.getId().substring(0, file.getId().lastIndexOf('.')), ".pkcs7", RodaConstants.OTHER_METADATA_TYPE_DIGITAL_SIGNATURE, contentsPayload, true); } } } else if (OOXML_FORMAT.equals(generalFileFormat)) { Map<Path, String> extractMap = OOXMLSignatureUtils.runDigitalSignatureExtract(input); extractResult = new ArrayList<>(extractMap.keySet()); for (Path p : extractResult) { ContentPayload mainPayload = new FSPathContentPayload(p); model.createOrUpdateOtherMetadata(file.getAipId(), file.getRepresentationId(), file.getPath(), file.getId().substring(0, file.getId().lastIndexOf('.')) + "_" + extractMap.get(p), ".xml", RodaConstants.OTHER_METADATA_TYPE_DIGITAL_SIGNATURE, mainPayload, true); } } else if (ODF_FORMAT.equals(generalFileFormat)) { extractResult = ODFSignatureUtils.runDigitalSignatureExtract(input); if (!extractResult.isEmpty()) { ContentPayload mainPayload = new FSPathContentPayload(extractResult.get(0)); model.createOrUpdateOtherMetadata(file.getAipId(), file.getRepresentationId(), file.getPath(), file.getId().substring(0, file.getId().lastIndexOf('.')), ".xml", RodaConstants.OTHER_METADATA_TYPE_DIGITAL_SIGNATURE, mainPayload, true); } } } catch (IOException | RequestNotValidException | GenericException | NotFoundException | AuthorizationDeniedException | SignatureException e) { LOGGER.warn("Problems running a document digital signature extraction, reason: {}", e.getMessage()); } return extractResult.size(); } public static Path runDigitalSignatureStrip(Path input, String fileFormat, String mimetype) { try { Path output = Files.createTempFile("stripped", "." + fileFormat); String generalFileFormat = SignatureUtils.canHaveEmbeddedSignature(fileFormat, mimetype); if (PDF_FORMAT.equals(generalFileFormat)) { PDFSignatureUtils.runDigitalSignatureStrip(input, output); } else if (OOXML_FORMAT.equals(generalFileFormat)) { OOXMLSignatureUtils.runDigitalSignatureStrip(input, output); } else if (ODF_FORMAT.equals(generalFileFormat)) { ODFSignatureUtils.runDigitalSignatureStrip(input, output); } return output; } catch (IOException | InvalidFormatException | DocumentException e) { LOGGER.warn("Problems running a document signature stripping, reason: {}", e.getMessage()); return null; } } }