From 535a04fa05f739ec16dd81666e3b0f82dfbd442d Mon Sep 17 00:00:00 2001 From: tknall Date: Wed, 9 Jan 2013 15:41:29 +0000 Subject: pdf-as-lib maven project files moved to pdf-as-lib git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/pdf-as/trunk@926 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../at/gv/egiz/pdfas/impl/api/PdfAsObject.java | 865 +++++++++++++++++++++ 1 file changed, 865 insertions(+) create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java (limited to 'pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java') diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java new file mode 100644 index 0000000..eda94c0 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java @@ -0,0 +1,865 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a + * joint initiative of the Federal Chancellery Austria and Graz University of + * Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egiz.pdfas.impl.api; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.Vector; + +import org.apache.commons.lang.math.NumberUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.api.PdfAs; +import at.gv.egiz.pdfas.api.analyze.AnalyzeParameters; +import at.gv.egiz.pdfas.api.analyze.AnalyzeResult; +import at.gv.egiz.pdfas.api.commons.Constants; +import at.gv.egiz.pdfas.api.commons.DynamicSignatureLifetimeEnum; +import at.gv.egiz.pdfas.api.commons.DynamicSignatureProfile; +import at.gv.egiz.pdfas.api.commons.DynamicSignatureProfileImpl; +import at.gv.egiz.pdfas.api.commons.SignatureInformation; +import at.gv.egiz.pdfas.api.exceptions.PdfAsException; +import at.gv.egiz.pdfas.api.sign.SignParameters; +import at.gv.egiz.pdfas.api.sign.SignResult; +import at.gv.egiz.pdfas.api.sign.SignatureDetailInformation; +import at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters; +import at.gv.egiz.pdfas.api.verify.VerifyAfterReconstructXMLDsigParameters; +import at.gv.egiz.pdfas.api.verify.VerifyParameters; +import at.gv.egiz.pdfas.api.verify.VerifyResult; +import at.gv.egiz.pdfas.api.verify.VerifyResults; +import at.gv.egiz.pdfas.api.xmldsig.ExtendedSignatureInformation; +import at.gv.egiz.pdfas.api.xmldsig.ReconstructXMLDsigAfterAnalysisParameters; +import at.gv.egiz.pdfas.api.xmldsig.ReconstructXMLDsigParameters; +import at.gv.egiz.pdfas.api.xmldsig.ReconstructXMLDsigResult; +import at.gv.egiz.pdfas.api.xmldsig.XMLDsigData; +import at.gv.egiz.pdfas.commandline.CommandlineConnectorChooser; +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.gv.egiz.pdfas.exceptions.framework.PlaceholderExtractionException; +import at.gv.egiz.pdfas.framework.ConnectorParameters; +import at.gv.egiz.pdfas.framework.DataSourceHolder; +import at.gv.egiz.pdfas.framework.config.SettingsHelper; +import at.gv.egiz.pdfas.framework.input.ExtractionStage; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.signator.Signator; +import at.gv.egiz.pdfas.framework.signator.SignatorInformation; +import at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters; +import at.gv.egiz.pdfas.impl.api.analyze.AnalyzeResultImpl; +import at.gv.egiz.pdfas.impl.api.commons.DataSinkAdapter; +import at.gv.egiz.pdfas.impl.api.commons.PdfDataSourceAdapter; +import at.gv.egiz.pdfas.impl.api.commons.SignatureInformationAdapter; +import at.gv.egiz.pdfas.impl.api.commons.SignatureProfileImpl; +import at.gv.egiz.pdfas.impl.api.commons.TextDataSourceAdapter; +import at.gv.egiz.pdfas.impl.api.sign.ActualSignaturePositionAdapter; +import at.gv.egiz.pdfas.impl.api.sign.SignResultImpl; +import at.gv.egiz.pdfas.impl.api.sign.SignatureDetailInformationImpl; +import at.gv.egiz.pdfas.impl.api.verify.VerifyResultAdapter; +import at.gv.egiz.pdfas.impl.api.verify.VerifyResultsImpl; +import at.gv.egiz.pdfas.impl.input.DelimitedPdfDataSource; +import at.gv.egiz.pdfas.impl.vfilter.VerificationFilterParametersImpl; +import at.gv.egiz.pdfas.impl.xmldsig.XMLDsigReconstructor; +import at.gv.egiz.pdfas.placeholder.SignaturePlaceholderContext; +import at.gv.egiz.pdfas.placeholder.SignaturePlaceholderData; +import at.gv.egiz.pdfas.placeholder.SignaturePlaceholderExtractor; +import at.gv.egiz.pdfas.utils.ConfigUtils; +import at.knowcenter.wag.egov.egiz.PdfAS; +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.cfg.OverridePropertyHolder; +import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; +import at.knowcenter.wag.egov.egiz.exceptions.OutOfMemoryException; +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; +import at.knowcenter.wag.egov.egiz.exceptions.SignatorFactoryException; +import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; +import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; +import at.knowcenter.wag.egov.egiz.pdf.AdobeSignatureHelper; +import at.knowcenter.wag.egov.egiz.pdf.BinarySignatureHolder; +import at.knowcenter.wag.egov.egiz.pdf.NoSignatureHolder; +import at.knowcenter.wag.egov.egiz.pdf.ObjectExtractor; +import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; +import at.knowcenter.wag.egov.egiz.pdf.TablePos; +import at.knowcenter.wag.egov.egiz.pdf.TextualSignatureHolder; +import at.knowcenter.wag.egov.egiz.sig.SignatureData; +import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl; +import at.knowcenter.wag.egov.egiz.sig.SignatureResponse; +import at.knowcenter.wag.egov.egiz.sig.SignatureTypeDefinition; +import at.knowcenter.wag.egov.egiz.sig.SignatureTypes; +import at.knowcenter.wag.egov.egiz.sig.connectors.Connector; +import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject; + +/** + * Implementation of the {@link PdfAs} interface. + * + * @author wprinz + */ +public class PdfAsObject implements PdfAs +{ +//23.11.2010 changed by exthex - added methods for reconstructXMLDsig + + /** + * The log. + */ + private static Log log = LogFactory.getLog(PdfAsObject.class); + + private static final String ENABLE_PLACEHOLDER_SEARCH_KEY = "enable_placeholder_search"; + + /** + * Configuration key for minimal signature block width threshold. Any width below this certain value will lead to a warning log entry." + */ + private static final String SIGNATURE_BLOCK_WIDTH_THRESHOLD_FOR_WARNING_KEY = "signature_block_width_warning_threshold"; + + /** + * Minimal signature block width. If a width below that value is defined (by parameter, by placeholder or by configuration) a warning log entry is created. + */ + public static final float DEFAULT_SIGNATURE_BLOCK_WIDTH_THRESHOLD = 150; + + + /** + * This constructor is for internal use only - use + * {@link at.gv.egiz.pdfas.PdfAsFactory} instead. + * Note: IAIK JCE and IAIK ECC security providers are automatically registered. + * + * @param workDirectory + * The work directory. + * @throws PdfAsException + * Thrown, if the configuration cannot be processed. + */ + public PdfAsObject(File workDirectory) throws PdfAsException + { + this(workDirectory, SettingsReader.REGISTER_IAIK_PROVIDERS_ON_DEFAULT); + } + + /** + * This constructor is for internal use only - use + * {@link at.gv.egiz.pdfas.PdfAsFactory} instead. + * + * @param workDirectory + * The work directory. + * @param registerProvider true: automatically registers IAIK JCE and ECC Provider; + * false: providers will NOT be automatically registered, providers + * needed have to be registered by the API user + * @throws PdfAsException + * Thrown, if the configuration cannot be processed. + */ + public PdfAsObject(File workDirectory, boolean registerProvider) throws PdfAsException + { + String path = workDirectory != null ? workDirectory.getPath() : null; + SettingsReader.initialize(path, path); + reloadConfig(registerProvider); + } + + /** + * This constructor is for internal use only - use + * {@link at.gv.egiz.pdfas.PdfAsFactory} instead. + * Note: IAIK JCE and IAIK ECC security providers are automatically registered. + * + * @throws PdfAsException + * Thrown, if the configuration cannot be processed. + */ + public PdfAsObject() throws PdfAsException + { + this(null); + } + + /** + * @see at.gv.egiz.pdfas.api.PdfAs#reloadConfig() + */ + public void reloadConfig() throws PdfAsException + { + ConfigUtils.initializeLogger(); + SettingsReader.createInstance(); + SignatureTypes.createInstance(); + } + + /** + * @param registerProvider true: automatically registers IAIK JCE and ECC Provider; + * false: providers will NOT be automatically registered, providers + * needed have to be registered by the API user + * @see at.gv.egiz.pdfas.api.PdfAs#reloadConfig() + */ + private void reloadConfig(boolean registerProvider) throws PdfAsException + { + ConfigUtils.initializeLogger(); + SettingsReader.createInstance(registerProvider); + SignatureTypes.createInstance(); + } + + /** + * @see at.gv.egiz.pdfas.api.PdfAs#getProfileInformation() + */ + public List getProfileInformation() throws PdfAsException + { + log.debug("Collecting profile information."); + final String MOA_SIGN_KEY_IDENTIFIER_KEY = "moa.sign.KeyIdentifier"; + + SettingsReader settings = SettingsReader.getInstance(); + final String defaultMoaKeyIdentifiert = settings.getSetting(MOA_SIGN_KEY_IDENTIFIER_KEY, null); + + SignatureTypes types = SignatureTypes.getInstance(); + List profiles = types.getSignatureTypeDefinitions(); + + List profileInformation = new ArrayList(profiles.size()); + + String default_type = settings.getValueFromKey(SignatureTypes.DEFAULT_TYPE); + + Iterator it = profiles.iterator(); + while (it.hasNext()) + { + SignatureTypeDefinition profile = (SignatureTypeDefinition) it.next(); + + final String profileId = profile.getType(); + log.debug("Processing profile \"" + profileId + "\"."); + final String moaKeyIdentifier = settings.getSetting("sig_obj." + profileId + "." + MOA_SIGN_KEY_IDENTIFIER_KEY, defaultMoaKeyIdentifiert); + final String profileDescription = settings.getSetting("sig_obj." + profileId + "." + SignatureTypes.SIG_DESCR, null); + + boolean isDefault = (default_type != null && default_type.equals(profileId)); + // modified by tknall + SignatureProfileImpl signatureProfile = new SignatureProfileImpl(profileId, profileDescription, moaKeyIdentifier, isDefault); + + // start - added by tknall + + // signature entries relevant to the search algorithm + Properties signatureEntries = new Properties(); + + // search for table entries + String parentPropertyKey = "sig_obj." + profileId + ".table"; + log.debug("Looking for subkeys of \"" + parentPropertyKey + "\"."); + Vector keysVector = settings.getSettingKeys(parentPropertyKey); + if (keysVector != null) { + Iterator keyIt = keysVector.iterator(); + while (keyIt.hasNext()) { + String subKey = (String) keyIt.next(); + if (subKey != null && subKey.length() > 0) { + String fullKey = parentPropertyKey + "." + subKey; + String value = settings.getValueFromKey(fullKey); + int lastIndex = fullKey.lastIndexOf("."); + if (lastIndex != -1) { + String endsWith = fullKey.substring(lastIndex + 1); + if (value != null && value.length() > 0) { + if (NumberUtils.isDigits(endsWith)) { + signatureEntries.setProperty(fullKey, value); + } else { + log.debug("Ignoring table entry \"" + fullKey + "\" because it does not end with a digit. Therefore it is not relevant for the seach algorithm."); + } + } else { + log.warn("Problem detected with key \"" + fullKey + "\". The value is empty."); + } + } + } + } + } + + // search for table entries + parentPropertyKey = "sig_obj." + profileId + ".key"; + log.debug("Looking for subkeys of \"" + parentPropertyKey + "\"."); + keysVector = settings.getSettingKeys(parentPropertyKey); + if (keysVector != null) { + Iterator keyIt = keysVector.iterator(); + while (keyIt.hasNext()) { + String subKey = (String) keyIt.next(); + if (subKey != null && subKey.length() > 0) { + String fullKey = parentPropertyKey + "." + subKey; + String value = settings.getValueFromKey(fullKey); + if (value != null && value.length() > 0) { + signatureEntries.setProperty(fullKey, value); + } else { + log.warn("Problem detected with key \"" + fullKey + "\". The value is empty."); + } + } + } + } + + // set properties + signatureProfile.setSignatureBlockEntries(signatureEntries); + + // stop - added by tknall + + profileInformation.add(signatureProfile); + } + + return profileInformation; + } + + /** + * @see at.gv.egiz.pdfas.api.PdfAs#sign(at.gv.egiz.pdfas.api.sign.SignParameters) + */ + public SignResult sign(SignParameters signParameters) throws PdfAsException + { + CheckHelper.checkSignParameters(signParameters, false); + + try { + SignatureDetailInformation signatorInfo = prepareSign(signParameters); + + return sign(signParameters, signatorInfo); + + } catch (java.lang.OutOfMemoryError e) { + throw new OutOfMemoryException(ErrorCode.OUT_OF_MEMORY_ERROR, "Insufficient memory allocated to virtual machine. Start Java with parameters \"-Xms128m -Xmx786m -XX:MaxPermSize=256m\".", e); + } + + } + + /** + * @see at.gv.egiz.pdfas.api.PdfAs#verify(at.gv.egiz.pdfas.api.verify.VerifyParameters) + */ + public VerifyResults verify(VerifyParameters verifyParameters) throws PdfAsException + { + CheckHelper.checkVerifyParameters(verifyParameters); + + AnalyzeParameters ap = new AnalyzeParameters(); + fillAnalyzeParametersWithVerifyParameters(ap, verifyParameters); + AnalyzeResult analyzeResult = analyze(ap); + + if (verifyParameters.getSignatureToVerify() != Constants.VERIFY_ALL) + { + if (verifyParameters.getSignatureToVerify() >= analyzeResult.getSignatures().size()) + { + throw new SignatureException(312, "The selected signature to be verified doesn't exist. " + verifyParameters.getSignatureToVerify()); + } + + Object stv = analyzeResult.getSignatures().get(verifyParameters.getSignatureToVerify()); + List selectedSignature = new ArrayList(1); + selectedSignature.add(stv); + analyzeResult = new AnalyzeResultImpl(selectedSignature); + } + + VerifyAfterAnalysisParameters vaap = new VerifyAfterAnalysisParameters(); + vaap.setAnalyzeResult(analyzeResult); + fillVerifyAfterAnalysisParametersWithVerifyParameters(vaap, verifyParameters); + VerifyResults res = verify(vaap); + + return res; + + } + + + /** + * Copies all adequate parameters from the {@link VerifyParameters} to the + * {@link AnalyzeParameters}. + * + * @param ap + * The {@link AnalyzeParameters}. + * @param vp + * The {@link VerifyParameters}. + */ + protected void fillAnalyzeParametersWithVerifyParameters(AnalyzeParameters ap, VerifyParameters vp) + { + ap.setDocument(vp.getDocument()); + ap.setVerifyMode(vp.getVerifyMode()); + ap.setReturnNonTextualObjects(vp.isReturnNonTextualObjects()); + } + + protected void fillAnalyzeParametersWithReconstructXMLDsigParameters(AnalyzeParameters ap, ReconstructXMLDsigParameters rxp) + { + ap.setDocument(rxp.getDocument()); + ap.setVerifyMode(rxp.getVerifyMode()); + ap.setReturnNonTextualObjects(rxp.isReturnNonTextualObjects()); + } + + /** + * Copies all adequate parameters from the {@link VerifyParameters} to the + * {@link VerifyAfterAnalysisParameters}. + * + * @param vaap + * The {@link VerifyAfterAnalysisParameters}. + * @param vp + * The {@link VerifyParameters}. + */ + protected void fillVerifyAfterAnalysisParametersWithVerifyParameters(VerifyAfterAnalysisParameters vaap, VerifyParameters vp) + { + vaap.setSignatureDevice(vp.getSignatureDevice()); + vaap.setVerificationTime(vp.getVerificationTime()); + vaap.setReturnHashInputData(vp.isReturnHashInputData()); + } + + + protected void fillReconstructXMLDsigAfterAnalysisParametersWithVerifyAfterAnalysisParameters( + ReconstructXMLDsigAfterAnalysisParameters reconstructParams, + VerifyAfterAnalysisParameters verifyAfterAnalysisParameters) { + reconstructParams.setAnalyzeResult(verifyAfterAnalysisParameters.getAnalyzeResult()); + reconstructParams.setSignatureDevice(verifyAfterAnalysisParameters.getSignatureDevice()); + } + + /** + * @see at.gv.egiz.pdfas.api.PdfAs#analyze(at.gv.egiz.pdfas.api.analyze.AnalyzeParameters) + */ + public AnalyzeResult analyze(AnalyzeParameters analyzeParameters) throws PdfAsException + { + CheckHelper.checkAnalyzeParameters(analyzeParameters); + + VerificationFilterParameters parametersConfig = SettingsHelper.readVerificationFilterParametersFromSettings(); + boolean binaryOnly = parametersConfig.extractBinarySignaturesOnly(); + if (analyzeParameters.getVerifyMode().equals(Constants.VERIFY_MODE_BINARY_ONLY)) + { + binaryOnly = true; + } + boolean assumeOnlySB = parametersConfig.assumeOnlySignatureUpdateBlocks(); + if (analyzeParameters.getVerifyMode().equals(Constants.VERIFY_MODE_SEMI_CONSERVATIVE)) + { + assumeOnlySB = true; + } + if (analyzeParameters.getVerifyMode().equals(Constants.VERIFY_MODE_FULL_CONSERVATIVE)) + { + assumeOnlySB = false; + } + VerificationFilterParameters parameters = new VerificationFilterParametersImpl(binaryOnly, assumeOnlySB, parametersConfig.scanForOldSignatures()); + + at.gv.egiz.pdfas.framework.input.DataSource inputDataSource = null; + if (analyzeParameters.getDocument().getMimeType().equals("application/pdf")) + { + inputDataSource = new PdfDataSourceAdapter(analyzeParameters.getDocument()); + } + else + { + try + { + inputDataSource = new TextDataSourceAdapter(analyzeParameters.getDocument()); + } + catch (UnsupportedEncodingException e) + { + throw new PresentableException(ErrorCode.DOCUMENT_CANNOT_BE_READ, "The characterEncoding is not supported." + analyzeParameters.getDocument().getCharacterEncoding(), e); + } + } + assert inputDataSource != null; + + try { + ExtractionStage es = new ExtractionStage(); + DataSourceHolder dsh = new DataSourceHolder(inputDataSource); + List signature_holders = es.extractSignatureHolders(dsh, parameters); + + + // List sigInfs = new ArrayList(signature_holders.size()); + List sigInfs = new ArrayList(); + List noSigs = new ArrayList(); + Iterator it = signature_holders.iterator(); + while (it.hasNext()) + { + SignatureHolder sh = (SignatureHolder)it.next(); + + if(sh instanceof NoSignatureHolder) { + noSigs.add(sh); + } else { + + SignatureInformation si = new SignatureInformationAdapter(sh); + sigInfs.add(si); + if (analyzeParameters.isReturnNonTextualObjects()) { + si.setNonTextualObjects(doExtractNonTexualObjects(sh, (PdfDataSource) dsh.getDataSource())); + } + + } + } + return new AnalyzeResultImpl(sigInfs, noSigs, parameters.hasBeenCorrected()); + } catch (java.lang.OutOfMemoryError e) { + throw new OutOfMemoryException(ErrorCode.OUT_OF_MEMORY_ERROR, "Insufficient memory allocated to virtual machine. Start Java with parameters \"-Xms128m -Xmx786m -XX:MaxPermSize=256m\".", e); + } + + } + + private List doExtractNonTexualObjects(SignatureHolder sh, PdfDataSource pdfDataSource) { + if (sh == null) return null; + if (sh instanceof BinarySignatureHolder) { + BinarySignatureHolder bsh = (BinarySignatureHolder)sh; + return ObjectExtractor.extractNonTextInfo(bsh.getSignedPdf()); + } else if (sh instanceof TextualSignatureHolder) { + TextualSignatureHolder tsh = (TextualSignatureHolder)sh; + if (tsh.getUiBlockEndPos() == 0) { + log.warn("uiblockendpos not available. Extract objects from final pdf document"); + return ObjectExtractor.extractNonTextInfo(pdfDataSource); + } + DelimitedPdfDataSource dpds = new DelimitedPdfDataSource(pdfDataSource, tsh.getUiBlockEndPos()); + return ObjectExtractor.extractNonTextInfo(dpds); + } else { + return null; + } + } + +/** + * @see at.gv.egiz.pdfas.api.PdfAs#verify(at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters) + */ + public VerifyResults verify(VerifyAfterAnalysisParameters verifyAfterAnalysisParameters) throws PdfAsException + { + CheckHelper.checkVerifyAfterAnalysisParameters(verifyAfterAnalysisParameters); + + List signatures = verifyAfterAnalysisParameters.getAnalyzeResult().getSignatures(); + + // added by tknall + if (signatures == null || signatures.isEmpty()) { + throw new PDFDocumentException(ErrorCode.DOCUMENT_NOT_SIGNED, "PDF document not signed."); //$NON-NLS-1$ + } + + ReconstructXMLDsigAfterAnalysisParameters rxaap = new ReconstructXMLDsigAfterAnalysisParameters(); + fillReconstructXMLDsigAfterAnalysisParametersWithVerifyAfterAnalysisParameters(rxaap, verifyAfterAnalysisParameters); + ReconstructXMLDsigResult reconstructResult = reconstructXMLDSIG(rxaap); + + VerifyAfterReconstructXMLDsigParameters varxp = new VerifyAfterReconstructXMLDsigParameters(); + fillVerifyAfterReconstructXMLDsigParametersWithVerifyAfterAnalysisParameters(varxp, verifyAfterAnalysisParameters); + varxp.setReconstructXMLDsigResult(reconstructResult); + + return verify(varxp); + + } + + protected void fillVerifyAfterReconstructXMLDsigParametersWithVerifyAfterAnalysisParameters( + VerifyAfterReconstructXMLDsigParameters varxp, + VerifyAfterAnalysisParameters verifyAfterAnalysisParameters) { + varxp.setReturnHashInputData(verifyAfterAnalysisParameters.isReturnHashInputData()); + varxp.setSignatureDevice(verifyAfterAnalysisParameters.getSignatureDevice()); + varxp.setVerificationTime(verifyAfterAnalysisParameters.getVerificationTime()); + varxp.setVerifySignatureIndex(verifyAfterAnalysisParameters.getVerifySignatureIndex()); + } + + /** + * @see PdfAs#reconstructXMLDSIG(ReconstructXMLDsigParameters) + */ + public ReconstructXMLDsigResult reconstructXMLDSIG( + ReconstructXMLDsigParameters reconstructXMLDsigParameters) + throws PdfAsException { + + AnalyzeParameters analyzeParameters = new AnalyzeParameters(); + fillAnalyzeParametersWithReconstructXMLDsigParameters(analyzeParameters, reconstructXMLDsigParameters); + AnalyzeResult ar = analyze(analyzeParameters); + + ReconstructXMLDsigAfterAnalysisParameters rxaap = new ReconstructXMLDsigAfterAnalysisParameters(); + rxaap.setSignatureDevice(reconstructXMLDsigParameters.getSignatureDevice()); + rxaap.setAnalyzeResult(ar); + + return reconstructXMLDSIG(rxaap); + } + + /** + * @see PdfAs#reconstructXMLDSIG(ReconstructXMLDsigAfterAnalysisParameters) + */ + public ReconstructXMLDsigResult reconstructXMLDSIG( + ReconstructXMLDsigAfterAnalysisParameters reconstructXMLDsigParameters) + throws PdfAsException { + + AnalyzeResult ar = reconstructXMLDsigParameters.getAnalyzeResult(); + List extendedSignatureInfos = new Vector(); + for (int i = 0; i < ar.getSignatures().size(); i++) + { + SignatureInformation si = (SignatureInformation)ar.getSignatures().get(i); + XMLDsigData dsigData; + try { + dsigData = XMLDsigReconstructor.reconstruct(si, reconstructXMLDsigParameters.getSignatureDevice()); + extendedSignatureInfos.add(new ExtendedSignatureInformation(si, dsigData)); + } catch (ConnectorException e) { + // don't care for connector exceptions because of mutli signs. they are handled during verify + extendedSignatureInfos.add(new ExtendedSignatureInformation(si, null)); + } + + } + return new ReconstructXMLDsigResult(extendedSignatureInfos, reconstructXMLDsigParameters.getSignatureDevice()); + } + + /** + * @see PdfAs#verify(VerifyAfterReconstructXMLDsigParameters) + */ + public VerifyResults verify( + VerifyAfterReconstructXMLDsigParameters verifyAfterReconstructXMLDsigParameters) + throws PdfAsException { + + try { + List extSignatures = verifyAfterReconstructXMLDsigParameters.getReconstructXMLDsigResult().getExtendedSignatures(); + String signatureDevice = verifyAfterReconstructXMLDsigParameters.getSignatureDevice(); + if (signatureDevice == null){ + signatureDevice = verifyAfterReconstructXMLDsigParameters.getReconstructXMLDsigResult().getDevice(); + } + List results = PdfAS.verifyExtendedSignatureHolders(extSignatures, + signatureDevice, + verifyAfterReconstructXMLDsigParameters.isReturnHashInputData(), + verifyAfterReconstructXMLDsigParameters.getVerificationTime(), verifyAfterReconstructXMLDsigParameters.getVerifySignatureIndex()); + + List vrs = new ArrayList(results.size()); + + int verifySignatureIndex = verifyAfterReconstructXMLDsigParameters.getVerifySignatureIndex(); + if (verifySignatureIndex < 0) + { + for (int i = 0; i < extSignatures.size(); i++) + { + SignatureResponse response = (SignatureResponse) results.get(i); + ExtendedSignatureInformation extSigInfo = (ExtendedSignatureInformation)extSignatures.get(i); + SignatureHolder holder = (SignatureHolder) extSigInfo.getSignatureInformation().getInternalSignatureInformation(); + + VerifyResult vr = new VerifyResultAdapter(response, holder, verifyAfterReconstructXMLDsigParameters.getVerificationTime(), extSigInfo.getXmlDsigData()); + vr.setNonTextualObjects( extSigInfo.getSignatureInformation().getNonTextualObjects()); + + vrs.add(vr); + } + }else{ + SignatureResponse response = (SignatureResponse) results.get(0); + ExtendedSignatureInformation extSigInfo = (ExtendedSignatureInformation)extSignatures.get(verifySignatureIndex); + SignatureHolder holder = (SignatureHolder) extSigInfo.getSignatureInformation().getInternalSignatureInformation(); + + VerifyResult vr = new VerifyResultAdapter(response, holder, verifyAfterReconstructXMLDsigParameters.getVerificationTime(), extSigInfo.getXmlDsigData()); + vr.setNonTextualObjects( extSigInfo.getSignatureInformation().getNonTextualObjects()); + + vrs.add(vr); + } + + VerifyResultsImpl verifyResults = new VerifyResultsImpl(vrs); + return verifyResults; + } catch (java.lang.OutOfMemoryError e) { + throw new OutOfMemoryException(ErrorCode.OUT_OF_MEMORY_ERROR, "Insufficient memory allocated to virtual machine. Start Java with parameters \"-Xms128m -Xmx786m -XX:MaxPermSize=256m\".", e); + } + } + + public DynamicSignatureProfile createDynamicSignatureProfile(String parentProfile, DynamicSignatureLifetimeEnum mode) { + return DynamicSignatureProfileImpl.createFromParent(null, parentProfile, mode); + } + + public DynamicSignatureProfile createEmptyDynamicSignatureProfile(DynamicSignatureLifetimeEnum mode) { + return DynamicSignatureProfileImpl.createEmptyProfile(null, mode); + } + + public DynamicSignatureProfile loadDynamicSignatureProfile(String name) { + return DynamicSignatureProfileImpl.loadProfile(name); + } + + public DynamicSignatureProfile createDynamicSignatureProfile(String myUniqueName, + String parentProfile, DynamicSignatureLifetimeEnum mode) { + return DynamicSignatureProfileImpl.createFromParent(myUniqueName, parentProfile, mode); + } + + public DynamicSignatureProfile createEmptyDynamicSignatureProfile(String myUniqueName, + DynamicSignatureLifetimeEnum mode) { + return DynamicSignatureProfileImpl.createEmptyProfile(myUniqueName, mode); + } + + /** + * @see PdfAs#prepareSign(SignParameters) + */ + public SignatureDetailInformation prepareSign(SignParameters signParameters) throws PdfAsException { + CheckHelper.checkSignParameters(signParameters, true); + + if (signParameters.getProfileOverrideProperties() != null) { + OverridePropertyHolder.setOverrideProps(signParameters.getProfileOverrideProperties()); + } + + signParameters.setDocument(PdfAS.applyStrictMode(signParameters.getDocument())); + + SettingsReader settings = SettingsReader.getInstance(); + String defaultProfile = settings.getValueFromKey(SignatureTypes.DEFAULT_TYPE); + + SignaturePlaceholderData spd = getSignaturePlaceholder(signParameters, defaultProfile); + if (spd != null){ + if (spd.getProfile() != null) + signParameters.setSignatureProfileId(spd.getProfile()); + if (spd.getType() != null) + signParameters.setSignatureType(spd.getType()); + if (spd.getKey() != null) + signParameters.setSignatureKeyIdentifier(spd.getKey()); + // check again, we might have destroyed something + CheckHelper.checkSignParameters(signParameters, true); + } + + if (signParameters.getSignatureProfileId() == null) + { + signParameters.setSignatureProfileId(defaultProfile); + } + + boolean fromPlaceholder = false; + boolean fromSignParameters = false; + boolean fromConfig = false; + TablePos pos = null; + if (spd != null && spd.getTablePos() != null){ + // position and width is determined by placeholder image + fromPlaceholder = true; + pos = spd.getTablePos(); + } else { + // position and width is determined by api sign parameters + pos = PosHelper.formTablePos(signParameters.getSignaturePositioning()); + if (pos != null) { + fromSignParameters = true; + } + } + + TablePos effectivePos = pos; + if (effectivePos == null) { + String pos_string = settings.getSetting(SignatureTypes.SIG_OBJ + signParameters.getSignatureProfileId() + ".pos", null); + if (pos_string != null) { + // position and width is determined by profile configuration + effectivePos = PdfAS.parsePositionFromPosString(pos_string); + fromConfig = true; + } + } + if (effectivePos != null) { + // check if width is lower than the smallest meaningful width + String thresholdString = AdobeSignatureHelper.getDefaultableConfigProperty(signParameters.getSignatureProfileId(), SIGNATURE_BLOCK_WIDTH_THRESHOLD_FOR_WARNING_KEY, String.valueOf(DEFAULT_SIGNATURE_BLOCK_WIDTH_THRESHOLD)); + float threshold = DEFAULT_SIGNATURE_BLOCK_WIDTH_THRESHOLD; + try { + threshold = Float.parseFloat(thresholdString); + } catch (NumberFormatException e) { + if (log.isDebugEnabled()) { + log.debug("Unable to parse threshold value (\"" + thresholdString + "\") of configuration value \"" + SIGNATURE_BLOCK_WIDTH_THRESHOLD_FOR_WARNING_KEY + "\". Using default value: " + DEFAULT_SIGNATURE_BLOCK_WIDTH_THRESHOLD); + } + } + if (!effectivePos.isWauto() && effectivePos.getWidth() < threshold) { + String msg = "The {0} for the signature block is very small ({1}). The signature block might not get placed correcty."; + String[] arguments = new String[]{ "given width", "" + effectivePos.getWidth()}; + // very small, warn user + if (fromPlaceholder) { + arguments[0] = "width given by the placeholder image"; + } else if (fromSignParameters) { + arguments[0] = "width defined by the sign parameters"; + } else if (fromConfig) { + arguments[0] = "width defined by the profile " + signParameters.getSignatureProfileId(); + } + log.warn(MessageFormat.format(msg, arguments)); + } + } + + Signator signator = createSignator(signParameters.getSignatureType()); + + SignatorInformation signatorInfo = signator.prepareSign( + new PdfDataSourceAdapter(signParameters.getDocument()), + signParameters.getSignatureProfileId(), + pos, + signParameters.getTimeStamperImpl()); + + SignatureDetailInformationImpl ret = new SignatureDetailInformationImpl(); + ret.setSignatorInformation(signatorInfo); + return ret; + + } + + private SignaturePlaceholderData getSignaturePlaceholder(SignParameters signParameters, + String defaultProfile) throws SettingsException, PDFDocumentException, PlaceholderExtractionException { + SignaturePlaceholderData spd = null; + SignaturePlaceholderContext.setSignaturePlaceholderData(null); + + SettingsReader settings = SettingsReader.getInstance(); + + // check sig_obj.PROFILEID.enable_placeholder_search + String profile = signParameters.getSignatureProfileId(); + if (profile == null) + profile = defaultProfile; + String key = SignatureTypes.SIG_OBJ + profile + "." + ENABLE_PLACEHOLDER_SEARCH_KEY; + String configFileActivedString = settings.getValueFromKey(key); + + if (configFileActivedString == null){ + // check global enable_placeholder_search + configFileActivedString = settings.getValueFromKey(ENABLE_PLACEHOLDER_SEARCH_KEY); + } + + Boolean configFileActived = null; + if (configFileActivedString != null) + configFileActived = Boolean.valueOf(configFileActivedString); + + Boolean signParamsActivated = signParameters.isCheckForPlaceholder(); + + boolean enableSearch; + + if (signParamsActivated != null) + { + enableSearch = signParamsActivated.booleanValue(); + } else { + if (configFileActived != null) + enableSearch = configFileActived.booleanValue(); + else + enableSearch = false; + } + + if (enableSearch) + { + spd = SignaturePlaceholderExtractor.extract( + signParameters.getDocument().createInputStream(), + signParameters.getPlaceholderId(), + signParameters.getPlaceholderMatchMode()); + } + return spd; + } + + private Signator createSignator(String signatureType) throws SignatorFactoryException { + PdfASID signatorId = null; + if (signatureType.equals(Constants.SIGNATURE_TYPE_BINARY)) + { + signatorId = SignatorFactory.MOST_RECENT_BINARY_SIGNATOR_ID; + } + if (signatureType.equals(Constants.SIGNATURE_TYPE_TEXTUAL)) + { + signatorId = SignatorFactory.MOST_RECENT_TEXTUAL_SIGNATOR_ID; + } + if (signatureType.equals(Constants.SIGNATURE_TYPE_DETACHEDTEXTUAL)) + { + signatorId = SignatorFactory.MOST_RECENT_DETACHEDTEXT_SIGNATOR_ID; + } + + return at.gv.egiz.pdfas.framework.SignatorFactory.createSignator(signatorId); + + } + + public SignResult sign(SignParameters signParameters, SignatureDetailInformation signatorInfo) + throws PdfAsException { + CheckHelper.checkSignParametersForSignAfterPrepare(signParameters, false); + + if (signParameters.getProfileOverrideProperties() != null) { + OverridePropertyHolder.setOverrideProps(signParameters.getProfileOverrideProperties()); + } + + String connectorId = CommandlineConnectorChooser.chooseCommandlineConnectorForSign(signParameters.getSignatureDevice()); + + ConnectorParameters cp = new ConnectorParameters(); + cp.setProfileId(signParameters.getSignatureProfileId()); + cp.setSignatureKeyIdentifier(signParameters.getSignatureKeyIdentifier()); + Connector c = at.gv.egiz.pdfas.framework.ConnectorFactory.createConnector(connectorId, cp); + + SignatureData sd = new SignatureDataImpl(new PdfDataSourceAdapter(signatorInfo.getSignatureData()), signatorInfo.getSignatureData().getMimeType()); + SignSignatureObject sso = PdfAS.sign(sd, c, signParameters.getTimeStamperImpl()); + ((SignatureDetailInformationImpl)signatorInfo).setSignSignatureObject(sso); + + return finishSign(signParameters, signatorInfo); + } + + public SignResult finishSign(SignParameters signParameters, SignatureDetailInformation signatureDetailInformation) + throws PdfAsException { + try { + CheckHelper.checkSignParametersForSignAfterPrepare(signParameters, true); + CheckHelper.checkSignatureDetailInformation(signatureDetailInformation); + + if (signParameters.getProfileOverrideProperties() != null) { + OverridePropertyHolder.setOverrideProps(signParameters.getProfileOverrideProperties()); + } + + Signator signator = createSignator(signParameters.getSignatureType()); + + SignatorInformation signatorInfo = ((SignatureDetailInformationImpl)signatureDetailInformation).getSignatorInfo(); + signator.finishSign(signatorInfo, new DataSinkAdapter(signParameters.getOutput())); + + return new SignResultImpl( + signParameters.getOutput(), + signatorInfo.getSignSignatureObject().getX509Certificate(), + new ActualSignaturePositionAdapter(signatorInfo.getActualTablePos()), + signatorInfo.getNonTextualObjects()); + } finally { + OverridePropertyHolder.removeProperties(); + DynamicSignatureProfileImpl.disposeLocalProfile(); + } + } + +} -- cgit v1.2.3