/* DigiDoc4J library * * This software is released under either the GNU Library General Public * License (see LICENSE.LGPL). * * Note that the only valid version of the LGPL license as far as this * project is concerned is the original GNU Library General Public License * Version 2.1, February 1999 */ package org.digidoc4j.main; import static org.apache.commons.lang.StringUtils.endsWithIgnoreCase; import static org.apache.commons.lang.StringUtils.equalsIgnoreCase; import static org.digidoc4j.Container.DocumentType.BDOC; import static org.digidoc4j.Container.DocumentType.DDOC; import java.io.File; import org.apache.commons.cli.CommandLine; import org.digidoc4j.Container; import org.digidoc4j.ContainerBuilder; import org.digidoc4j.ContainerOpener; import org.digidoc4j.DataFile; import org.digidoc4j.EncryptionAlgorithm; import org.digidoc4j.Signature; import org.digidoc4j.SignatureBuilder; import org.digidoc4j.SignatureProfile; import org.digidoc4j.SignatureToken; import org.digidoc4j.signers.PKCS11SignatureToken; import org.digidoc4j.signers.PKCS12SignatureToken; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ContainerManipulator { private final static Logger logger = LoggerFactory.getLogger(ContainerManipulator.class); private static final String EXTRACT_CMD = "extract"; private CommandLine commandLine; private boolean fileHasChanged; public ContainerManipulator(CommandLine commandLine) { this.commandLine = commandLine; } public void processContainer(Container container) { logger.debug("Processing container"); manipulateContainer(container); signContainer(container); verifyContainer(container); } public Container openContainer(String containerPath) { Container.DocumentType type = getContainerType(commandLine); if (new File(containerPath).exists() || commandLine.hasOption("verify") || commandLine.hasOption("remove")) { logger.debug("Opening container " + containerPath); return ContainerOpener.open(containerPath); } else { logger.debug("Creating new " + type + "container " + containerPath); return ContainerBuilder.aContainer(type.name()).build(); } } public void saveContainer(Container container, String containerPath) { if (fileHasChanged) { container.saveAsFile(containerPath); if (new File(containerPath).exists()) { logger.debug("Container has been successfully saved to " + containerPath); } else { logger.warn("Container was NOT saved to " + containerPath); } } } private void manipulateContainer(Container container) { if (commandLine.hasOption("add")) { String[] optionValues = commandLine.getOptionValues("add"); container.addDataFile(optionValues[0], optionValues[1]); fileHasChanged = true; } if (commandLine.hasOption("remove")) { container.removeDataFile(commandLine.getOptionValue("remove")); fileHasChanged = true; } if (commandLine.hasOption(EXTRACT_CMD)) { logger.debug("Extracting data file"); extractDataFile(container); } } public Container.DocumentType getContainerType(CommandLine commandLine) { if (equalsIgnoreCase(commandLine.getOptionValue("type"), "BDOC")) return BDOC; if (equalsIgnoreCase(commandLine.getOptionValue("type"), "DDOC")) return DDOC; if (endsWithIgnoreCase(commandLine.getOptionValue("in"), ".bdoc")) return BDOC; if (endsWithIgnoreCase(commandLine.getOptionValue("in"), ".ddoc")) return DDOC; return BDOC; } private void extractDataFile(Container container) { String[] optionValues = commandLine.getOptionValues(EXTRACT_CMD); String fileNameToExtract = optionValues[0]; String extractPath = optionValues[1]; boolean fileFound = false; for (DataFile dataFile : container.getDataFiles()) { if (equalsIgnoreCase(fileNameToExtract, dataFile.getName())) { logger.info("Extracting " + dataFile.getName() + " to " + extractPath); dataFile.saveAs(extractPath); fileFound = true; } } if (!fileFound) { throw new DigiDoc4JUtilityException(4, "Data file " + fileNameToExtract + " was not found in the container"); } } private void signContainer(Container container) { SignatureBuilder signatureBuilder = SignatureBuilder.aSignature(container); updateProfile(signatureBuilder); updateEncryptionAlgorithm(signatureBuilder); signWithPkcs12(container, signatureBuilder); signWithPkcs11(container, signatureBuilder); } private void updateProfile(SignatureBuilder signatureBuilder) { if (commandLine.hasOption("profile")) { String profile = commandLine.getOptionValue("profile"); try { SignatureProfile signatureProfile = SignatureProfile.valueOf(profile); signatureBuilder.withSignatureProfile(signatureProfile); } catch (IllegalArgumentException e) { System.out.println("Signature profile \"" + profile + "\" is unknown and will be ignored"); } } } private void updateEncryptionAlgorithm(SignatureBuilder signatureBuilder) { if (commandLine.hasOption("encryption")) { String encryption = commandLine.getOptionValue("encryption"); EncryptionAlgorithm encryptionAlgorithm = EncryptionAlgorithm.valueOf(encryption); signatureBuilder.withEncryptionAlgorithm(encryptionAlgorithm); } } private void signWithPkcs12(Container container, SignatureBuilder signatureBuilder) { if (commandLine.hasOption("pkcs12")) { String[] optionValues = commandLine.getOptionValues("pkcs12"); SignatureToken pkcs12Signer = new PKCS12SignatureToken(optionValues[0], optionValues[1].toCharArray()); Signature signature = invokeSigning(signatureBuilder, pkcs12Signer); container.addSignature(signature); fileHasChanged = true; } } private void signWithPkcs11(Container container, SignatureBuilder signatureBuilder) { if (commandLine.hasOption("pkcs11")) { String[] optionValues = commandLine.getOptionValues("pkcs11"); String pkcs11ModulePath = optionValues[0]; char[] pin = optionValues[1].toCharArray(); int slotIndex = Integer.parseInt(optionValues[2]); SignatureToken pkcs11Signer = new PKCS11SignatureToken(pkcs11ModulePath, pin, slotIndex); Signature signature = invokeSigning(signatureBuilder, pkcs11Signer); container.addSignature(signature); fileHasChanged = true; } } private Signature invokeSigning(SignatureBuilder signatureBuilder, SignatureToken signatureToken) { return signatureBuilder. withSignatureToken(signatureToken). invokeSigning(); } private void verifyContainer(Container container) { if (commandLine.hasOption("verify")) { ContainerVerifier verifier = new ContainerVerifier(commandLine); verifier.verify(container); } } }