From 3d982813b34f6f230baf4a467cdc37ec92a77595 Mon Sep 17 00:00:00 2001 From: netconomy Date: Fri, 17 Aug 2007 06:10:56 +0000 Subject: Performance git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@167 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../commandline/CommandlineConnectorChooser.java | 167 +++++ .../at/gv/egiz/pdfas/exceptions/ErrorCode.java | 49 ++ .../gv/egiz/pdfas/exceptions/ErrorCodeHelper.java | 43 ++ .../external/ExternalErrorException.java | 43 ++ .../exceptions/framework/SignatorException.java | 40 ++ .../framework/VerificationFilterException.java | 40 ++ .../framework/VerificatorFactoryException.java | 49 ++ .../exceptions/pdf/KZSettingNotFoundException.java | 27 + .../exceptions/pdf/TextExtractionException.java | 18 + .../exceptions/web/SessionExpiredException.java | 48 ++ .../gv/egiz/pdfas/framework/ConnectorFactory.java | 83 +++ .../at/gv/egiz/pdfas/framework/DataManager.java | 35 + .../at/gv/egiz/pdfas/framework/DataStrategy.java | 37 ++ .../gv/egiz/pdfas/framework/SignatorFactory.java | 100 +++ .../pdfas/framework/SignatureHolderHelper.java | 34 + .../egiz/pdfas/framework/VerificatorFactory.java | 45 ++ .../pdfas/framework/config/SettingsHelper.java | 37 ++ .../gv/egiz/pdfas/framework/input/DataSource.java | 35 + .../pdfas/framework/input/ExtractionStage.java | 66 ++ .../egiz/pdfas/framework/input/PdfDataSource.java | 21 + .../egiz/pdfas/framework/input/TextDataSource.java | 19 + .../gv/egiz/pdfas/framework/output/DataSink.java | 15 + .../sigdevice/SequentialSignatureDevice.java | 25 + .../pdfas/framework/sigdevice/SignatureDevice.java | 16 + .../gv/egiz/pdfas/framework/signator/Signator.java | 56 ++ .../framework/signator/SignatorInformation.java | 43 ++ .../pdfas/framework/verificator/Verificator.java | 53 ++ .../framework/vfilter/VerificationFilter.java | 52 ++ .../vfilter/VerificationFilterParameters.java | 76 +++ .../impl/input/ByteArrayPdfDataSourceImpl.java | 56 ++ .../impl/input/CompoundPdfDataSourceImpl.java | 47 ++ .../pdfas/impl/input/DelimitedInputStream.java | 105 +++ .../pdfas/impl/input/DelimitedPdfDataSource.java | 44 ++ .../at/gv/egiz/pdfas/impl/input/FileBased.java | 20 + .../impl/input/FileBasedPdfDataSourceImpl.java | 103 +++ .../impl/input/FileBasedTextDataSourceImpl.java | 124 ++++ .../pdfas/impl/input/IncrementalUpdateParser.java | 49 ++ .../egiz/pdfas/impl/input/TextDataSourceImpl.java | 82 +++ .../pdfas/impl/input/helper/DataSourceHelper.java | 92 +++ .../egiz/pdfas/impl/output/ByteArrayDataSink.java | 83 +++ .../egiz/pdfas/impl/output/FileBasedDataSink.java | 126 ++++ .../impl/signator/IncrementalUpdateHelper.java | 45 ++ .../impl/signator/SignatorInformationImpl.java | 20 + .../signator/binary/BinarySignatorInformation.java | 51 ++ .../impl/signator/binary/BinarySignator_1_0_0.java | 326 +++++++++ .../impl/signator/binary/BinarySignator_1_1_0.java | 69 ++ .../detached/DetachedTextualSignator_1_0_0.java | 142 ++++ .../textual/TextualSignatorInformation.java | 45 ++ .../signator/textual/TextualSignator_1_0_0.java | 149 +++++ .../signator/textual/TextualSignator_1_1_0.java | 45 ++ .../binary/BinaryVerificator_1_0_0.java | 399 +++++++++++ .../binary/BinaryVerificator_1_1_0.java | 24 + .../at/gv/egiz/pdfas/impl/vfilter/Partition.java | 9 + .../pdfas/impl/vfilter/VerificationFilterImpl.java | 575 ++++++++++++++++ .../vfilter/VerificationFilterParametersImpl.java | 67 ++ .../helper/VerificationFilterBinaryHelper.java | 152 +++++ .../vfilter/helper/VerificationFilterHelper.java | 142 ++++ .../helper/VerificationFilterTextHelper.java | 15 + .../impl/vfilter/partition/BinaryPartition.java | 19 + .../impl/vfilter/partition/TextPartition.java | 20 + .../egiz/pdfas/performance/PerformanceCounter.java | 62 ++ .../pdfas/performance/PerformanceCounters.java | 22 + .../egiz/pdfas/performance/PerformanceTimer.java | 48 ++ .../java/at/gv/egiz/pdfas/utils/DataHashUtils.java | 136 ++++ .../java/at/gv/egiz/pdfas/utils/StreamUtils.java | 42 ++ .../gv/egiz/pdfas/web/CurrentLocalOperation.java | 87 +++ .../gv/egiz/pdfas/web/SignSessionInformation.java | 140 ++++ .../egiz/pdfas/web/VerifySessionInformation.java | 195 ++++++ .../at/gv/egiz/pdfas/web/helper/SessionHelper.java | 48 ++ .../egiz/pdfas/web/helper/SignServletHelper.java | 229 +++++++ .../at/gv/egiz/pdfas/web/helper/TempDirHelper.java | 242 +++++++ .../java/at/knowcenter/wag/egov/egiz/PdfAS.java | 737 ++++++++++----------- .../java/at/knowcenter/wag/egov/egiz/PdfASID.java | 30 + .../knowcenter/wag/egov/egiz/cfg/ConfigLogger.java | 2 + .../wag/egov/egiz/cfg/SettingsReader.java | 24 +- .../knowcenter/wag/egov/egiz/commandline/Main.java | 421 +++++++----- .../egov/egiz/exceptions/ConnectorException.java | 10 +- .../egiz/exceptions/ConnectorFactoryException.java | 22 +- .../egov/egiz/exceptions/ErrorCodeException.java | 10 +- .../egov/egiz/exceptions/InvalidIDException.java | 5 - .../egov/egiz/exceptions/NormalizeException.java | 30 +- .../egov/egiz/exceptions/PDFDocumentException.java | 11 +- .../egov/egiz/exceptions/PlaceholderException.java | 4 +- .../egov/egiz/exceptions/PresentableException.java | 23 +- .../egiz/exceptions/SettingNotFoundException.java | 25 +- .../egov/egiz/exceptions/SettingsException.java | 15 +- .../egiz/exceptions/SignatorFactoryException.java | 4 +- .../egov/egiz/exceptions/SignatureException.java | 7 +- .../egiz/exceptions/SignatureTypesException.java | 34 +- .../wag/egov/egiz/exceptions/WebException.java | 56 +- .../wag/egov/egiz/framework/Signator.java | 3 +- .../wag/egov/egiz/framework/SignatorFactory.java | 2 +- .../egov/egiz/framework/VerificationFilter.java | 58 +- .../wag/egov/egiz/framework/Verificator.java | 2 + .../framework/signators/BinarySignator_1_0_0.java | 78 ++- .../framework/signators/BinarySignator_1_1_0.java | 11 +- .../signators/DetachedSignator_1_0_0.java | 20 +- .../signators/DetachedfTextualSignator_1_0_0.java | 20 +- .../framework/signators/TextualSignator_1_0_0.java | 23 +- .../verificators/BinaryVerificator_1_0_0.java | 50 +- .../verificators/BinaryVerificator_1_1_0.java | 24 + .../verificators/TextualVerificator_1_0_0.java | 7 +- .../verificators/TextualVerificator_pdfasold.java | 3 +- .../wag/egov/egiz/pdf/AbsoluteTextSignature.java | 4 +- .../wag/egov/egiz/pdf/BinarySignature.java | 463 +++++++------ .../wag/egov/egiz/pdf/BinarySignatureHolder.java | 165 +++-- .../egiz/pdf/IncrementalUpdateInformation.java | 10 +- .../at/knowcenter/wag/egov/egiz/pdf/PDFPage.java | 6 +- .../wag/egov/egiz/pdf/PDFSignatureCreation.java | 20 +- .../wag/egov/egiz/pdf/PDFSignatureObjectIText.java | 3 +- .../knowcenter/wag/egov/egiz/pdf/PDFUtilities.java | 10 +- .../wag/egov/egiz/pdf/SignatureHolder.java | 36 +- .../wag/egov/egiz/pdf/TextualSignature.java | 26 +- .../wag/egov/egiz/pdf/TextualSignatureHolder.java | 74 ++- .../wag/egov/egiz/sig/ConnectorFactory.java | 2 + .../wag/egov/egiz/sig/LocalConnector.java | 6 +- .../wag/egov/egiz/sig/SignatureData.java | 10 +- .../wag/egov/egiz/sig/SignatureDataImpl.java | 55 +- .../wag/egov/egiz/sig/SignatureObject.java | 8 +- .../wag/egov/egiz/sig/connectors/BKUConnector.java | 35 +- .../egiz/sig/connectors/BKUPostConnection.java | 4 +- .../egov/egiz/sig/connectors/ConnectorChooser.java | 154 ++--- .../wag/egov/egiz/sig/connectors/MOAConnector.java | 18 +- .../egov/egiz/sig/connectors/bku/BKUHelper.java | 21 +- .../egiz/sig/connectors/bku/BKUPostConnection.java | 27 +- .../sig/connectors/bku/DetachedBKUConnector.java | 15 +- .../bku/EnvelopedBase64BKUConnector.java | 8 +- .../bku/OldEnvelopingBase64BKUConnector.java | 6 +- .../connectors/moa/DetachedLocRefMOAConnector.java | 69 +- .../moa/EnvelopingBase64MOAConnector.java | 7 - .../egiz/sig/connectors/moa/MOASoapConnection.java | 2 +- .../sig/sigid/DetachedLocRefMOAIdFormatter.java | 1 - .../wag/egov/egiz/tools/CodingHelper.java | 12 + .../knowcenter/wag/egov/egiz/tools/Normalizer.java | 14 +- .../egov/egiz/web/AsynchronousDataResponder.java | 240 +++---- .../egiz/web/AsynchronousRedirectResponder.java | 314 ++++----- .../wag/egov/egiz/web/LocalRequestHelper.java | 324 +++++---- .../egov/egiz/web/PdfASServletContextListener.java | 18 +- .../wag/egov/egiz/web/SessionInformation.java | 21 +- .../wag/egov/egiz/web/servlets/DataURLServlet.java | 253 ++++--- .../web/servlets/RetrieveSignatureDataServlet.java | 133 ++-- .../egov/egiz/web/servlets/SignPreviewServlet.java | 39 +- .../wag/egov/egiz/web/servlets/SignServlet.java | 373 ++++------- .../egiz/web/servlets/VerifyPreviewServlet.java | 155 +++-- .../wag/egov/egiz/web/servlets/VerifyServlet.java | 143 ++-- .../wag/exactparser/parsing/PDFUtils.java | 2 +- 146 files changed, 8587 insertions(+), 2358 deletions(-) create mode 100644 src/main/java/at/gv/egiz/pdfas/commandline/CommandlineConnectorChooser.java create mode 100644 src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java create mode 100644 src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCodeHelper.java create mode 100644 src/main/java/at/gv/egiz/pdfas/exceptions/external/ExternalErrorException.java create mode 100644 src/main/java/at/gv/egiz/pdfas/exceptions/framework/SignatorException.java create mode 100644 src/main/java/at/gv/egiz/pdfas/exceptions/framework/VerificationFilterException.java create mode 100644 src/main/java/at/gv/egiz/pdfas/exceptions/framework/VerificatorFactoryException.java create mode 100644 src/main/java/at/gv/egiz/pdfas/exceptions/pdf/KZSettingNotFoundException.java create mode 100644 src/main/java/at/gv/egiz/pdfas/exceptions/pdf/TextExtractionException.java create mode 100644 src/main/java/at/gv/egiz/pdfas/exceptions/web/SessionExpiredException.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/ConnectorFactory.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/DataManager.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/DataStrategy.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/SignatorFactory.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/SignatureHolderHelper.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/VerificatorFactory.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/config/SettingsHelper.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/input/DataSource.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/input/ExtractionStage.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/input/PdfDataSource.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/input/TextDataSource.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/output/DataSink.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/sigdevice/SequentialSignatureDevice.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/sigdevice/SignatureDevice.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/signator/Signator.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/signator/SignatorInformation.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/verificator/Verificator.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/vfilter/VerificationFilter.java create mode 100644 src/main/java/at/gv/egiz/pdfas/framework/vfilter/VerificationFilterParameters.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/input/ByteArrayPdfDataSourceImpl.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/input/CompoundPdfDataSourceImpl.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/input/DelimitedInputStream.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/input/DelimitedPdfDataSource.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/input/FileBased.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/input/FileBasedPdfDataSourceImpl.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/input/FileBasedTextDataSourceImpl.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/input/IncrementalUpdateParser.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/input/TextDataSourceImpl.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/input/helper/DataSourceHelper.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/output/ByteArrayDataSink.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/output/FileBasedDataSink.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/signator/IncrementalUpdateHelper.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/signator/SignatorInformationImpl.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignatorInformation.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_1_0.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/signator/textual/TextualSignatorInformation.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/signator/textual/TextualSignator_1_0_0.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/signator/textual/TextualSignator_1_1_0.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/verificator/binary/BinaryVerificator_1_0_0.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/verificator/binary/BinaryVerificator_1_1_0.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/vfilter/Partition.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterParametersImpl.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterHelper.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterTextHelper.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/vfilter/partition/BinaryPartition.java create mode 100644 src/main/java/at/gv/egiz/pdfas/impl/vfilter/partition/TextPartition.java create mode 100644 src/main/java/at/gv/egiz/pdfas/performance/PerformanceCounter.java create mode 100644 src/main/java/at/gv/egiz/pdfas/performance/PerformanceCounters.java create mode 100644 src/main/java/at/gv/egiz/pdfas/performance/PerformanceTimer.java create mode 100644 src/main/java/at/gv/egiz/pdfas/utils/DataHashUtils.java create mode 100644 src/main/java/at/gv/egiz/pdfas/utils/StreamUtils.java create mode 100644 src/main/java/at/gv/egiz/pdfas/web/CurrentLocalOperation.java create mode 100644 src/main/java/at/gv/egiz/pdfas/web/SignSessionInformation.java create mode 100644 src/main/java/at/gv/egiz/pdfas/web/VerifySessionInformation.java create mode 100644 src/main/java/at/gv/egiz/pdfas/web/helper/SessionHelper.java create mode 100644 src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java create mode 100644 src/main/java/at/gv/egiz/pdfas/web/helper/TempDirHelper.java create mode 100644 src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/BinaryVerificator_1_1_0.java (limited to 'src/main/java/at') diff --git a/src/main/java/at/gv/egiz/pdfas/commandline/CommandlineConnectorChooser.java b/src/main/java/at/gv/egiz/pdfas/commandline/CommandlineConnectorChooser.java new file mode 100644 index 0000000..2bc6a58 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/commandline/CommandlineConnectorChooser.java @@ -0,0 +1,167 @@ +/** + * + */ +package at.gv.egiz.pdfas.commandline; + +import at.gv.egiz.pdfas.framework.ConnectorFactory; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; +import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; +import at.knowcenter.wag.egov.egiz.sig.sigid.HotfixIdFormatter; + +/** + * Encapsulates the logic of choosing the correct connector for the commandline + * that can later be created using the ConnectorFactory. + * + * @author wprinz + */ +public class CommandlineConnectorChooser +{ + /** + * The log. + */ + private static Log log = LogFactory.getLog(CommandlineConnectorChooser.class); + + protected static final String BKU = "bku"; //$NON-NLS-1$ + + protected static final String MOA = "moa"; //$NON-NLS-1$ + + public static boolean needsSigId (String connectorId) + { + return !ConnectorFactory.isMOA(connectorId); + } + + public static String chooseCommandlineConnectorForSign(String connectorType) throws ConnectorException + { + log.debug("Choosing Connector for commandline signation..."); + + log.debug("connector type = " + connectorType); + + if (connectorType.equals(BKU)) + { + log.debug("sig_app is BKU ==> DetachedMultipartBKUConnector"); //$NON-NLS-1$ + + return ConnectorFactory.DETACHED_MULTIPART_BKU_CONNECTOR; + } + if (connectorType.equals(MOA)) + { + // TODO MOA detached signing is not allowed at the commandline + log.warn("Detached MOA is not supported on the commandline. -> choosing Base64 temporarily."); + return ConnectorFactory.ENVELOPING_BASE64_MOA_CONNECTOR; + } + + throw new ConnectorException(300, "Unknown connector type '" + connectorType + "' specified."); + } + + public static String chooseCommandlineConnectorForVerify(String connectorType, PdfASID sig_kz, String sig_id, String profile) throws ConnectorException + { + log.debug("Choosing Connector for Commandline verification..."); + + log.debug("connector type = " + connectorType); + log.debug("sig_kz = " + sig_kz); //$NON-NLS-1$ + log.debug("sig_id = " + sig_id); //$NON-NLS-1$ + + if (sig_kz == null) + { + log.debug("sig_kz is null -> chose an old enveloped base64 connector"); //$NON-NLS-1$ + + return chooseEnvelopingBase64ConnectorOld(connectorType); + } + + log.debug("sig_kz is not null -> one of the newer signatures"); + + if (sig_kz.getVersion().equals(SignatorFactory.VERSION_1_0_0)) + { + log.debug("Version is 1.0.0 -> Base64 Signatur (old or Hotfix)."); + + if (sig_id == null) + { + log.debug("sig_id is null, which means that it is a MOA signature -> choose a hotfix base64 connector (thus it is moa - it doesn't matter)."); + + return chooseEnvelopingBase64ConnectorHotfix(connectorType); + } + + String[] sig_id_parts = sig_id.split("@"); + if (sig_id_parts.length == 2) + { + log.debug("sig_id has 2 @-separated parts -> choosing old base64 connector"); + + return chooseEnvelopingBase64ConnectorOld(connectorType); + } + if (sig_id_parts[0].equals(HotfixIdFormatter.SIG_ID_PREFIX)) + { + log.debug("sig_id prefix is hotfix -> choosing hotfix base64 connector"); + + return chooseEnvelopingBase64ConnectorHotfix(connectorType); + } + + throw new ConnectorException(300, "The SIG_KZ version is 1.0.0, but SIG_ID is neither MOA nor Old base64 nor Hotfix base64 ???'"); + } + if (sig_kz.getVersion().equals(SignatorFactory.VERSION_1_1_0)) + { + log.debug("Version is 1.1.0 -> chose a detached connector."); + + return chooseDetachedMultipartConnector(connectorType); + } + + throw new ConnectorException(310, "The SIG_KZ version '" + sig_kz.getVersion() + "' is unknown."); + } + + protected static String chooseEnvelopingBase64ConnectorOld(String sig_app) throws ConnectorException + { + if (sig_app.equals(BKU)) + { + log.debug("sig_app is BKU ==> OldEnvelopingBase64BKUConnector"); //$NON-NLS-1$ + + return ConnectorFactory.OLD_ENVELOPING_BASE64_BKU_CONNECTOR; + } + if (sig_app.equals(MOA)) + { + log.debug("sig_app is MOA ==> EnvelopingBase64MOAConnector"); //$NON-NLS-1$ + + return ConnectorFactory.ENVELOPING_BASE64_MOA_CONNECTOR; + } + throw new ConnectorException(310, "Unknown sig_app '" + sig_app + "'."); //$NON-NLS-1$ //$NON-NLS-2$ + + } + + protected static String chooseEnvelopingBase64ConnectorHotfix(String sig_app) throws ConnectorException + { + if (sig_app.equals(BKU)) + { + log.debug("sig_app is BKU ==> EnvelopingBase64BKUConnector"); //$NON-NLS-1$ + + return ConnectorFactory.ENVELOPING_BASE64_BKU_CONNECTOR; + } + if (sig_app.equals(MOA)) + { + log.debug("sig_app is MOA ==> EnvelopingBase64MOAConnector"); //$NON-NLS-1$ + + return ConnectorFactory.ENVELOPING_BASE64_MOA_CONNECTOR; + } + throw new ConnectorException(310, "Unknown sig_app '" + sig_app + "'."); //$NON-NLS-1$ //$NON-NLS-2$ + } + + protected static String chooseDetachedMultipartConnector(String sig_app) throws ConnectorException + { + if (sig_app.equals(BKU)) + { + log.debug("sig_app is BKU ==> DetachedMultipartBKUConnector"); //$NON-NLS-1$ + + return ConnectorFactory.DETACHED_MULTIPART_BKU_CONNECTOR; + } + if (sig_app.equals(MOA)) + { + log.debug("sig_app is MOA ==> DetachedMOAConnector"); //$NON-NLS-1$ + + String msg = "A Detached signature cannot be verified with the MOA connector (yet)."; //$NON-NLS-1$ + log.error(msg); + throw new ConnectorException(370, msg); + } + throw new ConnectorException(310, "Unknown sig_app '" + sig_app + "'."); //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java b/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java new file mode 100644 index 0000000..dda4919 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java @@ -0,0 +1,49 @@ +/** + * + */ +package at.gv.egiz.pdfas.exceptions; + +/** + * Contains constants for the error codes. + * + *

+ * In Java 1.5 this would be an enum. + *

+ * + * @author wprinz + */ +public final class ErrorCode +{ + public static final int EXTERNAL_ERROR = 0; + + public static final int SETTING_NOT_FOUND = 100; + public static final int SETTINGS_EXCEPTION = 101; + public static final int KZ_SETTING_NOT_FOUND = 102; + + public static final int DOCUMENT_CANNOT_BE_READ = 201; + public static final int TEXT_EXTRACTION_EXCEPTION = 202; + public static final int CANNOT_WRITE_PDF = 205; + public static final int DOCUMENT_NOT_SIGNED = 206; + public static final int SIGNATURE_TYPES_EXCEPTION = 223; + + public static final int SIGNATURE_COULDNT_BE_CREATED = 300; + public static final int SIGNED_TEXT_EMPTY = 301; + public static final int PROFILE_NOT_DEFINED = 302; + public static final int SERIAL_NUMBER_INVALID = 303; + public static final int SIG_CERTIFICATE_CANNOT_BE_READ = 304; + + public static final int COULDNT_VERIFY = 310; + + public static final int NOT_SEMANTICALLY_EQUAL = 314; + + public static final int WEB_EXCEPTION = 330; + + + public static final int NORMALIZER_EXCEPTION = 400; + + public static final int SESSION_EXPIRED = 600; + + public static final int PLACEHOLDER_EXCEPTION = 700; + + +} diff --git a/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCodeHelper.java b/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCodeHelper.java new file mode 100644 index 0000000..4144a10 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCodeHelper.java @@ -0,0 +1,43 @@ +/** + * + */ +package at.gv.egiz.pdfas.exceptions; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; +import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException; +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; + +/** + * @author wprinz + * + */ +public class ErrorCodeHelper +{ + /** + * The log. + */ + private static final Log log = LogFactory.getLog(ErrorCodeHelper.class); + + public static String getMessageForErrorCode(int errorCode) + { + try + { + SettingsReader settings = SettingsReader.getInstance(); + String message = settings.getSetting("error.code." + errorCode); + return message; + } + catch (SettingsException e) + { + log.warn(e); + } + catch (SettingNotFoundException e) + { + log.warn(e); + } + return null; + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/exceptions/external/ExternalErrorException.java b/src/main/java/at/gv/egiz/pdfas/exceptions/external/ExternalErrorException.java new file mode 100644 index 0000000..4e12ced --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/exceptions/external/ExternalErrorException.java @@ -0,0 +1,43 @@ +package at.gv.egiz.pdfas.exceptions.external; + +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; + +public class ExternalErrorException extends ConnectorException +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = 2108427722915583885L; + + protected String externalErrorCode; + + protected String externalErrorMessage; + + public ExternalErrorException(String externalErrorCode, String externalErrorMessage) + { + super(ErrorCode.EXTERNAL_ERROR, "External Error " + externalErrorCode + ": " + externalErrorMessage); + + this.externalErrorCode = externalErrorCode; + this.externalErrorMessage = externalErrorMessage; + } + + /** + * @return the externalErrorCode + */ + public String getExternalErrorCode() + { + return externalErrorCode; + } + + /** + * @return the externalErrorMessage + */ + public String getExternalErrorMessage() + { + return externalErrorMessage; + } + + +} diff --git a/src/main/java/at/gv/egiz/pdfas/exceptions/framework/SignatorException.java b/src/main/java/at/gv/egiz/pdfas/exceptions/framework/SignatorException.java new file mode 100644 index 0000000..84868d8 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/exceptions/framework/SignatorException.java @@ -0,0 +1,40 @@ +/** + * + */ +package at.gv.egiz.pdfas.exceptions.framework; + +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; + + +/** + * Exception thrown by the Signators. + * @author wprinz + */ +public class SignatorException extends PresentableException +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = 5051232904560832089L; + + public SignatorException(int error_code, String message, Throwable cause) + { + super(error_code, message, cause); + } + + public SignatorException(int error_code, String message) + { + super(error_code, message); + } + + public SignatorException(int error_code, Throwable cause) + { + super(error_code, cause); + } + + public SignatorException(PresentableException pe) + { + super(pe.getErrorCode(), pe); + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/exceptions/framework/VerificationFilterException.java b/src/main/java/at/gv/egiz/pdfas/exceptions/framework/VerificationFilterException.java new file mode 100644 index 0000000..5569e5d --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/exceptions/framework/VerificationFilterException.java @@ -0,0 +1,40 @@ +/** + * + */ +package at.gv.egiz.pdfas.exceptions.framework; + +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; + +/** + * Wrapper exception for the VerificationFilter. + * + * @author wprinz + */ +public class VerificationFilterException extends PresentableException +{ + /** + * SVUID. + */ + private static final long serialVersionUID = -3863253910537746742L; + + public VerificationFilterException(int errorCode, String message, Throwable cause) + { + super(errorCode, message, cause); + } + + public VerificationFilterException(int errorCode, String message) + { + super(errorCode, message); + } + + public VerificationFilterException(int errorCode, Throwable cause) + { + super(errorCode, cause); + } + + public VerificationFilterException(PresentableException cause) + { + super(cause.getErrorCode(), cause); + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/exceptions/framework/VerificatorFactoryException.java b/src/main/java/at/gv/egiz/pdfas/exceptions/framework/VerificatorFactoryException.java new file mode 100644 index 0000000..4721cdb --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/exceptions/framework/VerificatorFactoryException.java @@ -0,0 +1,49 @@ +/** + * + */ +package at.gv.egiz.pdfas.exceptions.framework; + +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; + +/** + * @author wprinz + * + */ +public class VerificatorFactoryException extends PresentableException +{ + + /** + * + */ + private static final long serialVersionUID = 8765156531863056335L; + + /** + * @param errorCode + * @param message + */ + public VerificatorFactoryException(String message) + { + super(ErrorCode.COULDNT_VERIFY, message); + } + + /** + * @param errorCode + * @param message + * @param cause + */ + public VerificatorFactoryException(String message, Throwable cause) + { + super(ErrorCode.COULDNT_VERIFY, message, cause); + } + + /** + * @param errorCode + * @param cause + */ + public VerificatorFactoryException(Throwable cause) + { + super(ErrorCode.COULDNT_VERIFY, cause); + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/exceptions/pdf/KZSettingNotFoundException.java b/src/main/java/at/gv/egiz/pdfas/exceptions/pdf/KZSettingNotFoundException.java new file mode 100644 index 0000000..816a2c1 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/exceptions/pdf/KZSettingNotFoundException.java @@ -0,0 +1,27 @@ +/** + * + */ +package at.gv.egiz.pdfas.exceptions.pdf; + +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException; + +/** + * @author wprinz + * + */ +public class KZSettingNotFoundException extends SettingNotFoundException +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = 2516636821733440462L; + + public KZSettingNotFoundException(String message) + { + super(ErrorCode.KZ_SETTING_NOT_FOUND, message); + } + + +} diff --git a/src/main/java/at/gv/egiz/pdfas/exceptions/pdf/TextExtractionException.java b/src/main/java/at/gv/egiz/pdfas/exceptions/pdf/TextExtractionException.java new file mode 100644 index 0000000..1f54bb5 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/exceptions/pdf/TextExtractionException.java @@ -0,0 +1,18 @@ +package at.gv.egiz.pdfas.exceptions.pdf; + +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; + +public class TextExtractionException extends PresentableException +{ + /** + * SVUID. + */ + private static final long serialVersionUID = 2798763345488999563L; + + public TextExtractionException(Throwable cause) + { + super(ErrorCode.TEXT_EXTRACTION_EXCEPTION, cause); + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/exceptions/web/SessionExpiredException.java b/src/main/java/at/gv/egiz/pdfas/exceptions/web/SessionExpiredException.java new file mode 100644 index 0000000..bb55293 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/exceptions/web/SessionExpiredException.java @@ -0,0 +1,48 @@ +/** + * + */ +package at.gv.egiz.pdfas.exceptions.web; + +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; + +/** + * @author wprinz + * + */ +public class SessionExpiredException extends PresentableException +{ + /** + * SVUID. + */ + private static final long serialVersionUID = -1877790545371341233L; + + /** + * @param errorCode + * @param message + */ + public SessionExpiredException(String message) + { + super(ErrorCode.SESSION_EXPIRED, message); + } + + /** + * @param errorCode + * @param message + * @param cause + */ + public SessionExpiredException(String message, Throwable cause) + { + super(ErrorCode.SESSION_EXPIRED, message, cause); + } + + /** + * @param errorCode + * @param cause + */ + public SessionExpiredException(Throwable cause) + { + super(ErrorCode.SESSION_EXPIRED, cause); + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/ConnectorFactory.java b/src/main/java/at/gv/egiz/pdfas/framework/ConnectorFactory.java new file mode 100644 index 0000000..65c5af7 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/ConnectorFactory.java @@ -0,0 +1,83 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework; + +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorFactoryException; +import at.knowcenter.wag.egov.egiz.sig.connectors.Connector; +import at.knowcenter.wag.egov.egiz.sig.connectors.bku.EnvelopedBase64BKUConnector; +import at.knowcenter.wag.egov.egiz.sig.connectors.bku.MultipartDetachedBKUConnector; +import at.knowcenter.wag.egov.egiz.sig.connectors.bku.OldEnvelopingBase64BKUConnector; +import at.knowcenter.wag.egov.egiz.sig.connectors.moa.DetachedLocRefMOAConnector; +import at.knowcenter.wag.egov.egiz.sig.connectors.moa.EnvelopingBase64MOAConnector; + +/** + * @author wprinz + */ +public class ConnectorFactory +{ + // TODO the functionality of the connector should be split into template + // handling and the actualy hardware access + + public static String DETACHED_MULTIPART_BKU_CONNECTOR = "DetachedMultipartBKUConnector"; + + public static String ENVELOPING_BASE64_BKU_CONNECTOR = "EnvelopingBase64BKUConnector"; + + public static String OLD_ENVELOPING_BASE64_BKU_CONNECTOR = "OldEnvelopingBase64BKUConnector"; + + public static String DETACHED_LOCREF_MOA_CONNECTOR = "DetachedLocRefMOAConnector"; + + public static String ENVELOPING_BASE64_MOA_CONNECTOR = "EnvelopingBase64MOAConnector"; + + + + public static Connector createConnector (String connectorId, String profile, String locRef) throws ConnectorFactoryException, ConnectorException + { + if (connectorId.equals(DETACHED_MULTIPART_BKU_CONNECTOR)) + { + return new MultipartDetachedBKUConnector(profile); + } + + if (connectorId.equals(ENVELOPING_BASE64_BKU_CONNECTOR)) + { + return new EnvelopedBase64BKUConnector(profile); + } + + if (connectorId.equals(OLD_ENVELOPING_BASE64_BKU_CONNECTOR)) + { + return new OldEnvelopingBase64BKUConnector(profile); + } + + if (connectorId.equals(DETACHED_LOCREF_MOA_CONNECTOR)) + { + return new DetachedLocRefMOAConnector(profile, locRef); + } + + if (connectorId.equals(ENVELOPING_BASE64_MOA_CONNECTOR)) + { + return new EnvelopingBase64MOAConnector(profile); + } + + throw new ConnectorFactoryException("The connector Id " + connectorId + " couldn't be found by the ConnectorFactory."); + } + + public static boolean isMOA (String connectorId) + { + if (connectorId.equals(DETACHED_LOCREF_MOA_CONNECTOR) || connectorId.equals(ENVELOPING_BASE64_MOA_CONNECTOR)) + { + return true; + } + + return false; + } + +// public static Connector createConnectorForCommandline (String connectorId) throws ConnectorFactoryException +// { +// } +// +// public static Connector createConnectorForCommandline (String connectorId) throws ConnectorFactoryException +// { +// } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/DataManager.java b/src/main/java/at/gv/egiz/pdfas/framework/DataManager.java new file mode 100644 index 0000000..1640b07 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/DataManager.java @@ -0,0 +1,35 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework; + +/** + * The DataManager is a mediator for all components that need to allocate large + * data elements. + * + *

+ * The DataManager uses a certain DataStrategy to perform the actual tasks. The + * strategy may be different in different environments. E.g. The commandline may + * implement a strategy to keep all data in memory, whereas the web might + * implement one that puts as many data onto the disk as possible to save + * memory. + *

+ * + * @author wprinz + * + */ +public class DataManager +{ + protected static DataStrategy dataStrategy = null; + + public static void initialize(DataStrategy ds) + { + dataStrategy = ds; + } + + public static DataStrategy getDataStrategy() + { + return dataStrategy; + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/DataStrategy.java b/src/main/java/at/gv/egiz/pdfas/framework/DataStrategy.java new file mode 100644 index 0000000..22f9676 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/DataStrategy.java @@ -0,0 +1,37 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework; + +import java.io.InputStream; + +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.input.TextDataSource; +import at.gv.egiz.pdfas.framework.output.DataSink; + +/** + * Factory for creating DataSources. + * + * @author wprinz + */ +public interface DataStrategy +{ + + public TextDataSource createTextDataSource (String text); + + public PdfDataSource createPdfDataSource (InputStream is); + + public PdfDataSource createPdfDataSource (DataSource other, int length); + + /** + * @deprecated - use streaming. + * @param pdf + * @return + */ + public PdfDataSource createPdfDataSource (byte [] pdf); + + public void destroyDataSource (DataSource dataSource); + + public DataSink createDataSink (); +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/SignatorFactory.java b/src/main/java/at/gv/egiz/pdfas/framework/SignatorFactory.java new file mode 100644 index 0000000..d4ecc26 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/SignatorFactory.java @@ -0,0 +1,100 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework; + +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.exceptions.SignatorFactoryException; +import at.gv.egiz.pdfas.impl.signator.binary.BinarySignator_1_0_0; +import at.gv.egiz.pdfas.impl.signator.binary.BinarySignator_1_1_0; +import at.gv.egiz.pdfas.impl.signator.detached.DetachedTextualSignator_1_0_0; +import at.gv.egiz.pdfas.impl.signator.textual.TextualSignator_1_0_0; +import at.gv.egiz.pdfas.impl.signator.textual.TextualSignator_1_1_0; +import at.gv.egiz.pdfas.framework.signator.Signator; + +/** + * @author wprinz + * + */ +public class SignatorFactory +{ + /** + * The Vendor. + */ + public static final String VENDOR = "bka.gv.at"; //$NON-NLS-1$ + + /** + * The binary Signator algorithm. + */ + public static final String TYPE_BINARY = "binaer"; //$NON-NLS-1$ + + /** + * The textual Signator algorithm. + */ + public static final String TYPE_TEXTUAL = "text"; //$NON-NLS-1$ + + /** + * Detached Signator. + */ + public static final String TYPE_DETACHED_TEXTUAL = "detachedtext"; //$NON-NLS-1$ + + /** + * This application's current algorithm versions. + */ + public static final String VERSION_1_0_0 = "v1.0.0"; //$NON-NLS-1$ + + /** + * This application's current algorithm versions. + */ + public static final String VERSION_1_1_0 = "v1.1.0"; //$NON-NLS-1$ + + + public static Signator createSignator (PdfASID id) throws SignatorFactoryException + { + if (!id.getVendor().equals(VENDOR)) + { + throw new SignatorFactoryException("The vendor '" + id.getVendor() + "' is unrecognized by this SignatorFactory. (id='" + id + "')"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + if (id.getType().equals(TYPE_BINARY)) + { + if (id.getVersion().equals(VERSION_1_0_0)) + { + return new BinarySignator_1_0_0(); + } + if (id.getVersion().equals(VERSION_1_1_0)) + { + return new BinarySignator_1_1_0(); + } + + throw new SignatorFactoryException("The version '" + id.getVersion() + "' of type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + if (id.getType().equals(TYPE_TEXTUAL)) + { + if (id.getVersion().equals(VERSION_1_0_0)) + { + return new TextualSignator_1_0_0(); + } + if (id.getVersion().equals(VERSION_1_1_0)) + { + return new TextualSignator_1_1_0(); + } + + throw new SignatorFactoryException("The version '" + id.getVersion() + "' of type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + if (id.getType().equals(TYPE_DETACHED_TEXTUAL)) + { + if (id.getVersion().equals(VERSION_1_0_0)) + { + return new DetachedTextualSignator_1_0_0(); + } + + throw new SignatorFactoryException("The version '" + id.getVersion() + "' of type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + throw new SignatorFactoryException("The type '" + id.getType() + "' is not supported by this SignatorFactory. (id='" + id + "')"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/SignatureHolderHelper.java b/src/main/java/at/gv/egiz/pdfas/framework/SignatureHolderHelper.java new file mode 100644 index 0000000..ab77092 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/SignatureHolderHelper.java @@ -0,0 +1,34 @@ +package at.gv.egiz.pdfas.framework; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import at.knowcenter.wag.egov.egiz.pdf.EGIZDate; +import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; + +public final class SignatureHolderHelper +{ + + /** + * Sorts the List of SignatureHolders by date. + * + * @param signatureHolders + * The List of SignatureHolders. + */ + public static void sortByDate(List signatureHolders) + { + Collections.sort(signatureHolders, new Comparator() { + public int compare(Object o1, Object o2) + { + SignatureHolder sh1 = (SignatureHolder) o1; + SignatureHolder sh2 = (SignatureHolder) o2; + + EGIZDate date1 = EGIZDate.parseFromString(sh1.getSignatureObject().getSignationDate()); + EGIZDate date2 = EGIZDate.parseFromString(sh2.getSignatureObject().getSignationDate()); + + return date1.compareTo(date2); + } + }); + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/VerificatorFactory.java b/src/main/java/at/gv/egiz/pdfas/framework/VerificatorFactory.java new file mode 100644 index 0000000..f77ca23 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/VerificatorFactory.java @@ -0,0 +1,45 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework; + +import at.gv.egiz.pdfas.exceptions.framework.VerificatorFactoryException; +import at.gv.egiz.pdfas.framework.verificator.Verificator; +import at.gv.egiz.pdfas.impl.verificator.binary.BinaryVerificator_1_0_0; +import at.gv.egiz.pdfas.impl.verificator.binary.BinaryVerificator_1_1_0; +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; + +/** + * @author wprinz + * + */ +public class VerificatorFactory +{ + + public static Verificator createVerificator(PdfASID kz) throws VerificatorFactoryException + { + if (kz.getType().equals(SignatorFactory.TYPE_BINARY)) + { + return createBinaryVerificator(kz); + } + + return null; + } + + public static Verificator createBinaryVerificator(PdfASID kz) throws VerificatorFactoryException + { + assert kz.getType().equals(SignatorFactory.TYPE_BINARY); + + if (kz.equals(BinaryVerificator_1_0_0.MY_ID)) + { + return new BinaryVerificator_1_0_0(); + } + if (kz.equals(BinaryVerificator_1_1_0.MY_ID)) + { + return new BinaryVerificator_1_1_0(); + } + + throw new VerificatorFactoryException("kz is not a known binary signator " + kz); + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/config/SettingsHelper.java b/src/main/java/at/gv/egiz/pdfas/framework/config/SettingsHelper.java new file mode 100644 index 0000000..6f67d1d --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/config/SettingsHelper.java @@ -0,0 +1,37 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework.config; + +import at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters; +import at.gv.egiz.pdfas.impl.vfilter.VerificationFilterParametersImpl; +import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; + +/** + * Contains helpful Settings functions. + * @author wprinz + */ +public final class SettingsHelper +{ + public static VerificationFilterParameters readVerificationFilterParametersFromSettings() throws SettingsException + { + boolean binaryOnly = getFlag("binary_only"); + boolean assumeOnlySB = getFlag("assume_only_signauture_blocks"); + boolean checkOld = getFlag("check_old_textual_sigs"); + + VerificationFilterParameters vfp = new VerificationFilterParametersImpl(binaryOnly, assumeOnlySB, checkOld); + return vfp; + } + + protected static boolean getFlag (String settingsKey) throws SettingsException + { + String flag = SettingsReader.getInstance().getSetting(settingsKey, "false"); + boolean b = true; + if (flag.equals("false")) + { + b = false; + } + return b; + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/input/DataSource.java b/src/main/java/at/gv/egiz/pdfas/framework/input/DataSource.java new file mode 100644 index 0000000..265cb0c --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/input/DataSource.java @@ -0,0 +1,35 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework.input; + +import java.io.InputStream; + +/** + * The input document data source. + * + *

+ * Usually this is a PdfDataSource, but it may be a TextDataSource as well. + *

+ * + * @author wprinz + * + */ +public interface DataSource +{ + /** + * Creates a new InputStream that allows to read out the document's binary + * data from the beginning. + * + * @return Returns the InputStream with the binary data. + */ + public InputStream createInputStream(); + + /** + * Returns the length (number of bytes) of the stream. + * + * @return Returns the length (number of bytes) of the stream. + */ + public int getLength(); + +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/input/ExtractionStage.java b/src/main/java/at/gv/egiz/pdfas/framework/input/ExtractionStage.java new file mode 100644 index 0000000..36d9bd8 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/input/ExtractionStage.java @@ -0,0 +1,66 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework.input; + +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.gv.egiz.pdfas.exceptions.framework.VerificationFilterException; +import at.gv.egiz.pdfas.framework.vfilter.VerificationFilter; +import at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters; +import at.gv.egiz.pdfas.impl.input.IncrementalUpdateParser; +import at.gv.egiz.pdfas.impl.vfilter.VerificationFilterImpl; +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; + +/** + * Extracts all signatures from a given input DataSource. + * + * @author wprinz + */ +public class ExtractionStage +{ + /** + * The log. + */ + private static final Log log = LogFactory.getLog(ExtractionStage.class); + + public List extractSignatureHolders(final DataSource dataSource, VerificationFilterParameters parameters) throws PresentableException + { + if (dataSource instanceof PdfDataSource) + { + PdfDataSource pdfDataSource = (PdfDataSource) dataSource; + + List blocks = parsePdfIntoBlocks(pdfDataSource); + + VerificationFilter vf = new VerificationFilterImpl(); + List signatures = vf.extractSignatureHolders(pdfDataSource, blocks, parameters); + + return signatures; + } + + if (dataSource instanceof TextDataSource) + { + TextDataSource textDataSource = (TextDataSource) dataSource; + + VerificationFilter vf = new VerificationFilterImpl(); + List signatures = vf.extractSignaturHolders(textDataSource, parameters); + + return signatures; + } + + String msg = "The input DataSource is neither pdf nor text. class.name = " + dataSource.getClass().getName(); + log.error(msg); + throw new VerificationFilterException(ErrorCode.DOCUMENT_CANNOT_BE_READ, msg); + } + + protected List parsePdfIntoBlocks(PdfDataSource pdfDataSource) throws PDFDocumentException + { + List blocks = IncrementalUpdateParser.parsePdfIntoIUBlocks(pdfDataSource); + return blocks; + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/input/PdfDataSource.java b/src/main/java/at/gv/egiz/pdfas/framework/input/PdfDataSource.java new file mode 100644 index 0000000..b03a67e --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/input/PdfDataSource.java @@ -0,0 +1,21 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework.input; + + +/** + * Represents the binary data of a PDF document. + * + *

+ * This interface allows Pdf data to be handled in an abstract way so that the + * storage (byta array, disk etc.) of pdf documents can be separated from the + * algorithms. + *

+ * + * @author wprinz + */ +public interface PdfDataSource extends DataSource +{ + // jsut a marker interface +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/input/TextDataSource.java b/src/main/java/at/gv/egiz/pdfas/framework/input/TextDataSource.java new file mode 100644 index 0000000..c5fd4b1 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/input/TextDataSource.java @@ -0,0 +1,19 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework.input; + +/** + * Represents a free-text input text to be processed. + * + * @author wprinz + */ +public interface TextDataSource extends DataSource +{ + /** + * Returns the text to be processed. + * @return Returns the text to be processed. + */ + public String getText(); + +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/output/DataSink.java b/src/main/java/at/gv/egiz/pdfas/framework/output/DataSink.java new file mode 100644 index 0000000..d7d0cc4 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/output/DataSink.java @@ -0,0 +1,15 @@ +package at.gv.egiz.pdfas.framework.output; + +import java.io.OutputStream; + +/** + * Output document data sink. + * + * @author wprinz + */ +public interface DataSink +{ + public OutputStream createOutputStream(String mimeType); + + public OutputStream createOutputStream(String mimeType, String characterEncoding); +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/sigdevice/SequentialSignatureDevice.java b/src/main/java/at/gv/egiz/pdfas/framework/sigdevice/SequentialSignatureDevice.java new file mode 100644 index 0000000..70a28db --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/sigdevice/SequentialSignatureDevice.java @@ -0,0 +1,25 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework.sigdevice; + +/** + * A SignatureDevice that can be accessed in a sequential manner. + * + *

+ * A sequential device handles all necessary steps in sequence. E.g. all the + * data is transformed into a http request and sent to a server. The server + * processes the request and answers. The response from the server is then + * analyzed and returned. + *

+ * + * @author wprinz + */ +public interface SequentialSignatureDevice extends SignatureDevice +{ + // This is just a concept how it could be realized in future. + public void sign(); + + public void verify(); + +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/sigdevice/SignatureDevice.java b/src/main/java/at/gv/egiz/pdfas/framework/sigdevice/SignatureDevice.java new file mode 100644 index 0000000..735dd3c --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/sigdevice/SignatureDevice.java @@ -0,0 +1,16 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework.sigdevice; + +/** + * Performs the task of passing the signature XML and data from the application + * to an external signature device and return the response in an form that the + * application can use. + * + * @author wprinz + */ +public interface SignatureDevice +{ + // Marker interface +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/signator/Signator.java b/src/main/java/at/gv/egiz/pdfas/framework/signator/Signator.java new file mode 100644 index 0000000..e77ed08 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/signator/Signator.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2006 by Know-Center, Graz, Austria + * + * This software is the confidential and proprietary information of Know-Center, + * Graz, Austria. You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Know-Center. + * + * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF + * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY + * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. + * + * $Id: Signator.java,v 1.1 2006/08/25 17:07:21 wprinz Exp $ + */ +package at.gv.egiz.pdfas.framework.signator; + +import at.gv.egiz.pdfas.exceptions.framework.SignatorException; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.output.DataSink; +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.framework.SignResult; +import at.knowcenter.wag.egov.egiz.pdf.TablePos; + +/** + * The basic interface for signator algorithms. + * + * @author wprinz + */ +public interface Signator +{ + /** + * Returns the PdfASID of this Connector. + * + *

+ * This should always return the MY_ID static field of the connector. Dont't + * forget to override this. + *

+ *

+ * Within connector code always use this method so that code reuse through + * derivation can take place correctly. + *

+ * + * @return Returns the PdfASID of this Connector. + */ + public PdfASID getMyId(); + + + public SignatorInformation prepareSign(PdfDataSource pdfDataSource, + String profile, TablePos pos, boolean has_SIG_ID) throws SignatorException; + + + public void finishSign(SignatorInformation signatorInformation, DataSink dataSink) throws SignatorException; +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/signator/SignatorInformation.java b/src/main/java/at/gv/egiz/pdfas/framework/signator/SignatorInformation.java new file mode 100644 index 0000000..da81e87 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/signator/SignatorInformation.java @@ -0,0 +1,43 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework.signator; + +import at.knowcenter.wag.egov.egiz.sig.SignatureData; +import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject; + +/** + * Encapsulates the Signator dependant information that needs to be passed from + * prepareSign to finishSign. + * + *

+ * This supersedes the IncrementalUpdateInformation. + *

+ * + * @author wprinz + */ +public interface SignatorInformation +{ + /** + * Returns the SignatureData to be signed. + *

+ * This is passed on to the Connector and signature device for signing. + *

+ * + * @return Returns the SignatureData to be signed. + */ + public SignatureData getSignatureData(); + + /** + * Sets the SignSignatureObject with the signature data. + * + *

+ * This is called by the framework to provide the finishSign with the + * signature data. + *

+ * + * @param signSignatureObject + * The SignSignatureObject. + */ + public void setSignSignatureObject(SignSignatureObject signSignatureObject); +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/verificator/Verificator.java b/src/main/java/at/gv/egiz/pdfas/framework/verificator/Verificator.java new file mode 100644 index 0000000..b134d64 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/verificator/Verificator.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2006 by Know-Center, Graz, Austria + * + * This software is the confidential and proprietary information of Know-Center, + * Graz, Austria. You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Know-Center. + * + * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF + * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY + * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. + * + * $Id: Verificator.java,v 1.1 2006/08/25 17:07:21 wprinz Exp $ + */ +package at.gv.egiz.pdfas.framework.verificator; + +import java.util.List; + +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; +import at.knowcenter.wag.exactparser.parsing.results.FooterParseResult; + + +/** + * Given an Incremental Update Block and the corresponding PDF, a verificator + * extracts all Signatures of its type and returns them as valitatable + * SignatureHolders. + * + * @author wprinz + */ +public interface Verificator +{ + /** + * Parses the given document/Block for signatures of this type. + * + * @param pdf + * The whole pdf document. A Verificator must only access the + * document up to its given block (block.next_index) and must not + * modify any byte in the pdf array. + * @param block + * The incremental update block. + * @param start_of_whole_block + * The start of the incremental update block (the end of the previous + * block) - If 0, this is the first block (the original Document). + * @return Returns the List of SignatureHolder objects found for this block. + */ + public List parseBlock(PdfDataSource pdfDataSource, byte [] pdf, final FooterParseResult block, + int start_of_whole_block) throws PresentableException; + +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/vfilter/VerificationFilter.java b/src/main/java/at/gv/egiz/pdfas/framework/vfilter/VerificationFilter.java new file mode 100644 index 0000000..1633b09 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/vfilter/VerificationFilter.java @@ -0,0 +1,52 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework.vfilter; + +import java.util.List; + +import at.gv.egiz.pdfas.exceptions.framework.VerificationFilterException; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.input.TextDataSource; + +/** + * Extracts all signatures from a given PDF document or text. + * + * @see VerificationFilterParameters + * + * @author wprinz + */ +public interface VerificationFilter +{ + + /** + * Extracts the signatures from the given PDF. + * + * @param pdf + * The PDF. + * @param blocks + * The List of Incremental Update blocks. Usually this comes from a + * preprocessing step. + * @param parameters + * The algorithm parameters. + * @return Returns a List of SignatureHolders containing the signatures. May + * be empty in case no signatures have been found. + * @throws VerificationFilterException + * Thrown if something goes wrong. + */ + public List extractSignatureHolders(PdfDataSource pdf, List blocks, VerificationFilterParameters parameters) throws VerificationFilterException; + + /** + * Extracts the text signatures from the given free-text. + * + * @param text + * The free-text. + * @param parameters + * The algorithm parameters. + * @return Returns a List of SignatureHolders containing the signatures. May + * be empty in case no signatures have been found. + * @throws VerificationFilterException + * Thrown if something goes wrong. + */ + public List extractSignaturHolders(TextDataSource text, VerificationFilterParameters parameters) throws VerificationFilterException; +} diff --git a/src/main/java/at/gv/egiz/pdfas/framework/vfilter/VerificationFilterParameters.java b/src/main/java/at/gv/egiz/pdfas/framework/vfilter/VerificationFilterParameters.java new file mode 100644 index 0000000..c518fef --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/vfilter/VerificationFilterParameters.java @@ -0,0 +1,76 @@ +/** + * + */ +package at.gv.egiz.pdfas.framework.vfilter; + +/** + * The parameters of the VerificationFilter algorithm. + * + * @author wprinz + */ +public interface VerificationFilterParameters +{ + + /** + * Tells the VerificationFilter to extract binary signatures only. + * + *

+ * Not scanning for textual signatures allows the algorithm to skip text + * extraction and signature extraction, which are both time and memory + * intensive processes. + *

+ * + * @return Returns true if the VerificationFilter should extract binary + * signatures only. + */ + public boolean extractBinarySignaturesOnly(); + + /** + * Tells the VerificationFilter to assume that there are only singatures (and + * their Incremental Update blocks) younger than the original document. + * + *

+ * This is equivalent to saying that the document was not updated using an + * Incremental update block other than a signature after being singed. The + * incremental update blocks after the original document contain only + * signatures (either text or binary). + *

+ *

+ * This is equivalent to saying that there exists no Incremental Update block + * that would render a text signature before it invalid. + *

+ *

+ * Under this assumption, the process of finding all text signatures + * simplifies to one text extraction of the whole document and one signature + * extraction. This is of course a massive performance gain. + *

+ *

+ * Actually the algorithm performs a text extraction of the whole document not + * including trailing binary signature Incremental Update blocks. This means + * that if a the last n Incremental Update blocks of a document are binary, + * there is no use extract text from them. + *

+ *

+ * Note that if there are Incremental Update blocks with text after a + * signature thus this assumption does not hold the signatures older than this + * block will break. + *

+ * + * @return Returns true if the Verification filter should assume that there + * are only signature blocks after the original document. + */ + public boolean assumeOnlySignatureUpdateBlocks(); + + /** + * Tells the VerificationFilter so scan for old signatures in the rest text. + * + *

+ * The rest text is the text of the oldest text signature or the original + * document text if there is no text signature. + *

+ * + * @return Returns true if the VerificationFilter should scan for old text + * signatures in the rest text. + */ + public boolean scanForOldSignatures(); +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/input/ByteArrayPdfDataSourceImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/input/ByteArrayPdfDataSourceImpl.java new file mode 100644 index 0000000..0d27781 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/input/ByteArrayPdfDataSourceImpl.java @@ -0,0 +1,56 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.input; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import at.gv.egiz.pdfas.performance.PerformanceCounters; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; + +/** + * Implements a PdfDataSource that holds the whole PDF document in a byte array. + * + *

+ * Note that holding the data in a byte array is very memory consuming for large + * documents. + *

+ * + * @author wprinz + */ +public class ByteArrayPdfDataSourceImpl implements PdfDataSource +{ + protected byte[] pdf = null; + + protected int length = -1; + + public ByteArrayPdfDataSourceImpl(byte[] pdf) + { + PerformanceCounters.byteArrays.increment(); + + this.pdf = pdf; + this.length = pdf.length; + } + + public ByteArrayPdfDataSourceImpl(byte[] pdf, int length) + { + PerformanceCounters.byteArrays.increment(); + + this.pdf = pdf; + this.length = length; + } + + + public InputStream createInputStream() + { + ByteArrayInputStream bais = new ByteArrayInputStream(this.pdf, 0, this.length); + return bais; + } + + public int getLength() + { + return this.length; + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/input/CompoundPdfDataSourceImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/input/CompoundPdfDataSourceImpl.java new file mode 100644 index 0000000..f77d6be --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/input/CompoundPdfDataSourceImpl.java @@ -0,0 +1,47 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.input; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.SequenceInputStream; + +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; + +/** + * @author wprinz + * + */ +public class CompoundPdfDataSourceImpl implements PdfDataSource +{ + protected DataSource originalDataSource = null; + + protected byte[] appendix = null; + + public CompoundPdfDataSourceImpl (PdfDataSource original, byte [] appendix) + { + this.originalDataSource = original; + this.appendix = appendix; + } + + /** + * @see at.gv.egiz.pdfas.framework.input.DataSource#createInputStream() + */ + public InputStream createInputStream() + { + ByteArrayInputStream bais = new ByteArrayInputStream(this.appendix); + SequenceInputStream sis = new SequenceInputStream(this.originalDataSource.createInputStream(), bais); + return sis; + } + + /** + * @see at.gv.egiz.pdfas.framework.input.DataSource#getLength() + */ + public int getLength() + { + return this.originalDataSource.getLength() + this.appendix.length; + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/input/DelimitedInputStream.java b/src/main/java/at/gv/egiz/pdfas/impl/input/DelimitedInputStream.java new file mode 100644 index 0000000..4be9ec5 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/input/DelimitedInputStream.java @@ -0,0 +1,105 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.input; + +import java.io.IOException; +import java.io.InputStream; + +/** + * An input stream that has a delimited length. + * + * @author wprinz + */ +public class DelimitedInputStream extends InputStream +{ + /** + * The underlying InputStream. + */ + protected InputStream is = null; + + /** + * The number of bytes that can be read from the stream. + */ + protected int bytes_to_read = -1; + + /** + * Constructs the DelimitedInputStream from which a maximum of length bytes + * can be read. + */ + public DelimitedInputStream(InputStream is, int length) + { + this.is = is; + this.bytes_to_read = length; + } + + /** + * @see java.io.InputStream#read() + */ + public int read() throws IOException + { + if (this.bytes_to_read <= 0) + { + return -1; + } + int read = this.is.read(); + if (read > 0) + { + this.bytes_to_read--; + } + return read; + } + + /** + * @see java.io.InputStream#read(byte[], int, int) + */ + public int read(byte[] b, int off, int len) throws IOException + { + int btr = Math.min(len, this.bytes_to_read); + int read = this.is.read(b, off, btr); + if (read > 0) + { + this.bytes_to_read -= read; + } + return read; + } + + /** + * @see java.io.InputStream#read(byte[]) + */ + public int read(byte[] b) throws IOException + { + return read(b, 0, b.length); + } + + /** + * @see java.io.InputStream#skip(long) + */ + public long skip(long n) throws IOException + { + long bts = Math.min(n, this.bytes_to_read); + long skipped = this.is.skip(bts); + if (skipped > 0) + { + this.bytes_to_read -= skipped; + } + return skipped; + } + + /** + * @see java.io.InputStream#close() + */ + public void close() throws IOException + { + this.is.close(); + } + + /** + * @see java.io.InputStream#available() + */ + public int available() throws IOException + { + int avail = this.is.available(); + return Math.min(this.bytes_to_read, avail); + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/input/DelimitedPdfDataSource.java b/src/main/java/at/gv/egiz/pdfas/impl/input/DelimitedPdfDataSource.java new file mode 100644 index 0000000..6c67be2 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/input/DelimitedPdfDataSource.java @@ -0,0 +1,44 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.input; + +import java.io.InputStream; + +import at.gv.egiz.pdfas.framework.input.PdfDataSource; + +/** + * @author wprinz + * + */ +public class DelimitedPdfDataSource implements PdfDataSource +{ + + protected PdfDataSource dataSource = null; + protected int len = -1; + + public DelimitedPdfDataSource (PdfDataSource original, int length) + { + this.dataSource = original; + this.len = length; + } + + /** + * @see at.gv.egiz.pdfas.framework.input.DataSource#createInputStream() + */ + public InputStream createInputStream() + { + InputStream originalIS = this.dataSource.createInputStream(); + DelimitedInputStream dis = new DelimitedInputStream(originalIS, this.len); + return dis; + } + + /** + * @see at.gv.egiz.pdfas.framework.input.DataSource#getLength() + */ + public int getLength() + { + return this.len; + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/input/FileBased.java b/src/main/java/at/gv/egiz/pdfas/impl/input/FileBased.java new file mode 100644 index 0000000..54f8842 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/input/FileBased.java @@ -0,0 +1,20 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.input; + +import java.io.File; + +/** + * Interface that reveals the underlying data file. + * + * @author wprinz + */ +public interface FileBased +{ + /** + * Returns the underlying data file. + * @return Returns the underlying data file. + */ + public File getFile(); +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/input/FileBasedPdfDataSourceImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/input/FileBasedPdfDataSourceImpl.java new file mode 100644 index 0000000..8453192 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/input/FileBasedPdfDataSourceImpl.java @@ -0,0 +1,103 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.input; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.framework.input.PdfDataSource; + +/** + * @author wprinz + * + */ +public class FileBasedPdfDataSourceImpl implements PdfDataSource, FileBased +{ + /** + * The log. + */ + private static final Log log = LogFactory.getLog(FileBasedPdfDataSourceImpl.class); + + /** + * The underlying file. + */ + protected File inputFile = null; + + protected int length = -1; + + /** + * Constructor that creates this PdfDataSource backed by a file in the file + * system. + * + * @param file + * The input File. + * @param length + * The length of the InputStream. The is the maximum number of bytes + * that can be read from the stream. + * @throws IOException + * Thrown if the file cannot be read properly. + */ + public FileBasedPdfDataSourceImpl(File file, int length) throws IOException + { + + if (!file.exists()) + { + throw new FileNotFoundException("The file '" + file + "' does not exist."); + } + // for some reason the isFile is not always correct... + // if (file.isFile()) + // { + // throw new IOException("The file '" + file + "' is not a normal file."); + // } + if (!file.canRead()) + { + throw new IOException("The file '" + file + "' cannot be read."); + } + + this.inputFile = file; + this.length = length; + } + + /** + * @see at.gv.egiz.pdfas.impl.input.FileBased#getFile() + */ + public File getFile() + { + return this.inputFile; + } + + /** + * @see at.gv.egiz.pdfas.framework.input.PdfDataSource#createInputStream() + */ + public InputStream createInputStream() + { + try + { + FileInputStream fis = new FileInputStream(getFile()); + DelimitedInputStream dis = new DelimitedInputStream(fis, getLength()); + return dis; + } + catch (IOException e) + { + log.error("Couldn't create InputStream for file " + getFile() + ". Returning null."); + log.error(e); + + return null; + } + } + + /** + * @see at.gv.egiz.pdfas.framework.input.PdfDataSource#getLength() + */ + public int getLength() + { + return this.length; + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/input/FileBasedTextDataSourceImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/input/FileBasedTextDataSourceImpl.java new file mode 100644 index 0000000..6f6c7b4 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/input/FileBasedTextDataSourceImpl.java @@ -0,0 +1,124 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.input; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.framework.input.TextDataSource; + +/** + * @author wprinz + * + */ +public class FileBasedTextDataSourceImpl implements TextDataSource, FileBased +{ + /** + * The log. + */ + private static final Log log = LogFactory.getLog(FileBasedTextDataSourceImpl.class); + + protected File file = null; + + protected String characterEncoding = null; + + public FileBasedTextDataSourceImpl(File file, String characterEncoding) throws IOException + { + if (!file.exists()) + { + throw new FileNotFoundException("The file '" + file + "' does not exist."); + } + if (!file.canRead()) + { + throw new IOException("The file '" + file + "' cannot be read."); + } + + this.file = file; + this.characterEncoding = characterEncoding; + } + + /** + * @see at.gv.egiz.pdfas.impl.input.FileBased#getFile() + */ + public File getFile() + { + return this.file; + } + + /** + * Returns the character encoding. + * + * @return Returns the character encoding. + */ + public String getCharacterEncoding() + { + return this.characterEncoding; + } + + /** + * @see at.gv.egiz.pdfas.framework.input.TextDataSource#getText() + */ + public String getText() + { + try + { + InputStream is = createInputStream(); + byte[] data = new byte[getLength()]; + int read = 0; + int n = 0; + while ((n = is.read(data, read, data.length - read)) > 0) + { + read += n; + } + is.close(); + + String text = new String(data, getCharacterEncoding()); + + data = null; + + return text; + } + catch (IOException e) + { + log.error("Couldn't read text for file " + getFile() + ". Returning null."); + log.error(e); + + return null; + } + } + + /** + * @see at.gv.egiz.pdfas.framework.input.DataSource#createInputStream() + */ + public InputStream createInputStream() + { + try + { + FileInputStream fis = new FileInputStream(getFile()); + return fis; + } + catch (IOException e) + { + log.error("Couldn't create InputStream for file " + getFile() + ". Returning null."); + log.error(e); + + return null; + } + } + + /** + * @see at.gv.egiz.pdfas.framework.input.DataSource#getLength() + */ + public int getLength() + { + return (int) getFile().length(); + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/input/IncrementalUpdateParser.java b/src/main/java/at/gv/egiz/pdfas/impl/input/IncrementalUpdateParser.java new file mode 100644 index 0000000..b4c2bef --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/input/IncrementalUpdateParser.java @@ -0,0 +1,49 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.input; + +import java.util.List; + +import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper; +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; +import at.knowcenter.wag.exactparser.ParseDocument; + +/** + * Parses the given PDF document into a list of Incremental Update blocks. + * @author wprinz + */ +public class IncrementalUpdateParser +{ + /** + * The log. + */ + private static final Log log = LogFactory.getLog(IncrementalUpdateParser.class); + + public static List parsePdfIntoIUBlocks (PdfDataSource pdfDataSource) throws PDFDocumentException + { + log.trace("parsePdfIntoIUBlocks:"); + + List blocks = null; + try + { + byte [] pdf = DataSourceHelper.convertDataSourceToByteArray(pdfDataSource); + blocks = ParseDocument.parseDocument(pdf); + } + catch (Exception e) + { + log.error("Error while parsing Document into IU blocks.", e); + throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e); + } + + log.trace("parsePdfIntoIUBlocks finished."); + return blocks; + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/input/TextDataSourceImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/input/TextDataSourceImpl.java new file mode 100644 index 0000000..b259a3e --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/input/TextDataSourceImpl.java @@ -0,0 +1,82 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.input; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +import at.gv.egiz.pdfas.framework.input.TextDataSource; + +/** + * A TextDataSource that keeps the text in memory. + * + *

+ * Keeping the text in memory is fast as long as the text is short, but may + * result in bad memory performance when the text is longer. Use a FileBased + * TextDataSource instead if memory is an issue. + *

+ * + * @author wprinz + */ +public class TextDataSourceImpl implements TextDataSource +{ + /** + * The text. + */ + protected String text = null; + + /** + * Constructor that sets the text. + * + * @param text + * The text. + */ + public TextDataSourceImpl(String text) + { + this.text = text; + } + + /** + * @see at.gv.egiz.pdfas.framework.input.TextDataSource#getText() + */ + public String getText() + { + return this.text; + } + + /** + * @see at.gv.egiz.pdfas.framework.input.DataSource#createInputStream() + */ + public InputStream createInputStream() + { + try + { + byte[] data = getText().getBytes("UTF-8"); + // PERF: if memory is an issue (e.g. in web), use a FileBased TextDataSource instead. + return new ByteArrayInputStream(data); + } + catch (UnsupportedEncodingException e) + { + throw new RuntimeException(e); + } + } + + /** + * @see at.gv.egiz.pdfas.framework.input.DataSource#getLength() + */ + public int getLength() + { + try + { + byte[] data = getText().getBytes("UTF-8"); + return data.length; + } + catch (UnsupportedEncodingException e) + { + throw new RuntimeException(e); + } + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/input/helper/DataSourceHelper.java b/src/main/java/at/gv/egiz/pdfas/impl/input/helper/DataSourceHelper.java new file mode 100644 index 0000000..1e2ffdc --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/input/helper/DataSourceHelper.java @@ -0,0 +1,92 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.input.helper; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import at.gv.egiz.pdfas.performance.PerformanceCounters; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * @author wprinz + * + */ +public class DataSourceHelper +{ + /** + * The log. + */ + private static final Log log = LogFactory.getLog(DataSourceHelper.class); + + /** + * Converts a PdfDataSource to a byte array. + * + *

+ * Note that this function is very memory intensive. Use the Streams whereever + * possible. + *

+ * + * @deprecated + * + * @param pdfDataSource + * @return + * @throws IOException + */ + public static byte[] convertDataSourceToByteArray(DataSource pdfDataSource) + { + try + { + PerformanceCounters.byteArrays.increment(); + + byte[] data = new byte[pdfDataSource.getLength()]; + + int bytes_written = 0; + + InputStream is = pdfDataSource.createInputStream(); + int n = 0; + while ((n = is.read(data, bytes_written, data.length - bytes_written)) > 0) + { + bytes_written += n; + } + is.close(); + + assert bytes_written == data.length; + + return data; + } + catch (IOException e) + { + log.error(e); + throw new RuntimeException(e); + } + } + + public static void debugDataSourceToFile(DataSource dataSource, File file) + { + try + { + InputStream is = dataSource.createInputStream(); + FileOutputStream fos = new FileOutputStream(file); + byte[] data = new byte[2048]; + int n = -1; + while ((n = is.read(data)) > 0) + { + fos.write(data, 0, n); + } + is.close(); + fos.close(); + } + catch (IOException e) + { + log.error(e); + } + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/output/ByteArrayDataSink.java b/src/main/java/at/gv/egiz/pdfas/impl/output/ByteArrayDataSink.java new file mode 100644 index 0000000..f3d1283 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/output/ByteArrayDataSink.java @@ -0,0 +1,83 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.output; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.framework.output.DataSink; +import at.gv.egiz.pdfas.performance.PerformanceCounters; + +/** + * @author wprinz + * + */ +public class ByteArrayDataSink implements DataSink +{ + /** + * The log. + */ + private static final Log log = LogFactory.getLog(ByteArrayDataSink.class); + + protected String mimeType = null; + protected String characterEncoding = null; + + protected ByteArrayOutputStream baos = null; + + + public ByteArrayDataSink() + { + PerformanceCounters.byteArrays.increment(); + } + + /** + * @see at.gv.egiz.pdfas.framework.output.DataSink#createOutputStream(java.lang.String) + */ + public OutputStream createOutputStream(String mimeType) + { + return createOutputStream(mimeType, null); + } + + /** + * @see at.gv.egiz.pdfas.framework.output.DataSink#createOutputStream(java.lang.String, java.lang.String) + */ + public OutputStream createOutputStream(String mimeType, String characterEncoding) + { + if (this.baos != null) + { + log.warn("An output stream is created twice. The old one will be rendered useless."); + } + this.baos = new ByteArrayOutputStream(4096); + return this.baos; + } + + /** + * Returns the byte array. + * @return Returns the byte array. + */ + public byte [] getByteArray () + { + return this.baos.toByteArray(); + } + + /** + * @return the mimeType + */ + public String getMimeType() + { + return this.mimeType; + } + + /** + * @return the characterEncoding + */ + public String getCharacterEncoding() + { + return this.characterEncoding; + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/output/FileBasedDataSink.java b/src/main/java/at/gv/egiz/pdfas/impl/output/FileBasedDataSink.java new file mode 100644 index 0000000..4e1e3b7 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/output/FileBasedDataSink.java @@ -0,0 +1,126 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.output; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import at.gv.egiz.pdfas.framework.output.DataSink; +import at.gv.egiz.pdfas.impl.input.FileBased; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * @author wprinz + * + */ +public class FileBasedDataSink implements DataSink, FileBased +{ + /** + * The log. + */ + private static final Log log = LogFactory.getLog(FileBasedDataSink.class); + + protected String mimeType = null; + protected String characterEncoding = null; + + /** + * The output file. + */ + protected File outputFile = null; + + /** + * Creates a file based PdfDataSink. + * + * @param file + * The file. + * @throws IOException + * F.e. + */ + public FileBasedDataSink(File file) throws IOException + { + if (!file.exists()) + { + file.createNewFile(); + } + if (!file.isFile()) + { + throw new IOException("The file '" + file + "' is not a normal file."); + } + if (!file.canWrite()) + { + throw new IOException("The file '" + file + "' cannot be written."); + } + + this.outputFile = file; + } + + /** + * @see at.gv.egiz.pdfas.impl.input.FileBased#getFile() + */ + public File getFile() + { + return this.outputFile; + } + + + + protected OutputStream createOutputStream() + { + try + { + FileOutputStream fos = new FileOutputStream(getFile()); + return fos; + } + catch (IOException e) + { + log.error("Couldn't create OutputStream for file " + getFile() + ". Returning null."); + log.error(e); + + return null; + + } + } + + /** + * @see at.gv.egiz.pdfas.framework.output.DataSink#createOutputStream(java.lang.String) + */ + public OutputStream createOutputStream(String mimeType) + { + return createOutputStream(mimeType, null); + } + + /** + * @see at.gv.egiz.pdfas.framework.output.DataSink#createOutputStream(java.lang.String, java.lang.String) + */ + public OutputStream createOutputStream(String mimeType, String characterEncoding) + { + this.mimeType = mimeType; + this.characterEncoding = characterEncoding; + + return createOutputStream(); + } + + /** + * @return the mimeType + */ + public String getMimeType() + { + return mimeType; + } + + /** + * @return the characterEncoding + */ + public String getCharacterEncoding() + { + return characterEncoding; + } + + + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/signator/IncrementalUpdateHelper.java b/src/main/java/at/gv/egiz/pdfas/impl/signator/IncrementalUpdateHelper.java new file mode 100644 index 0000000..a95cdc6 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/signator/IncrementalUpdateHelper.java @@ -0,0 +1,45 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.signator; + +import java.util.List; + +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.output.DataSink; +import at.gv.egiz.pdfas.impl.output.ByteArrayDataSink; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; +import at.knowcenter.wag.egov.egiz.pdf.BinarySignature; +import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation; +import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; + +import com.lowagie.text.pdf.PdfPTable; + +/** + * @author wprinz + */ +public final class IncrementalUpdateHelper +{ + public static IncrementalUpdateInformation writeIncrementalUpdate(PdfDataSource pdfDataSource, PdfPTable pdf_table, PositioningInstruction pi, List variable_field_definitions, + List all_field_definitions) throws PresentableException + { + // PERF: binary sig needs the signed_pdf as byte array + ByteArrayDataSink bads = new ByteArrayDataSink(); + IncrementalUpdateInformation iui = BinarySignature.writeIncrementalUpdate(pdfDataSource, bads, pdf_table, pi, variable_field_definitions, all_field_definitions); + iui.signed_pdf = bads.getByteArray(); + bads = null; + + return iui; + } + + public static void writeIncrementalUpdateToDataSink(PdfDataSource pdfDataSource, DataSink dataSink, PdfPTable pdf_table, PositioningInstruction pi) throws PresentableException + { + writeIncrementalUpdateToDataSink(pdfDataSource, dataSink, pdf_table, pi, null, null); + } + + public static void writeIncrementalUpdateToDataSink(PdfDataSource pdfDataSource, DataSink dataSink, PdfPTable pdf_table, PositioningInstruction pi, List variable_field_definitions, + List all_field_definitions) throws PresentableException + { + BinarySignature.writeIncrementalUpdate(pdfDataSource, dataSink, pdf_table, pi, variable_field_definitions, all_field_definitions); + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/signator/SignatorInformationImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/signator/SignatorInformationImpl.java new file mode 100644 index 0000000..d07dc6a --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/signator/SignatorInformationImpl.java @@ -0,0 +1,20 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.signator; + +import at.knowcenter.wag.egov.egiz.sig.SignatureData; +import at.gv.egiz.pdfas.framework.signator.SignatorInformation; + +/** + * @author wprinz + */ +public abstract class SignatorInformationImpl implements SignatorInformation +{ + + /** + * @see at.gv.egiz.pdfas.framework.signator.SignatorInformation#getSignatureData() + */ + public abstract SignatureData getSignatureData(); + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignatorInformation.java b/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignatorInformation.java new file mode 100644 index 0000000..916abf4 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignatorInformation.java @@ -0,0 +1,51 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.signator.binary; + +import java.util.List; + +import at.knowcenter.wag.egov.egiz.sig.SignatureData; +import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.signator.SignatorInformation; + +/** + * @author wprinz + * + */ +public class BinarySignatorInformation implements SignatorInformation +{ + protected PdfDataSource originalDocument = null; + + protected byte [] incrementalUpdateBlock = null; + + protected SignatureData signatureData = null; + + protected List replaces = null; + + protected int cert_start = -1; + protected int cert_length = -1; + + protected int enc_start = -1; + protected int enc_length = -1; + + protected SignSignatureObject signSignatureObject = null; + + /** + * @see at.gv.egiz.pdfas.framework.signator.SignatorInformation#getSignatureData() + */ + public SignatureData getSignatureData() + { + return this.signatureData; + } + + /** + * @see at.gv.egiz.pdfas.framework.signator.SignatorInformation#setSignSignatureObject(at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject) + */ + public void setSignSignatureObject(SignSignatureObject signSignatureObject) + { + this.signSignatureObject = signSignatureObject; + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java b/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java new file mode 100644 index 0000000..6c6ba29 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java @@ -0,0 +1,326 @@ +/** + * Copyright (c) 2006 by Know-Center, Graz, Austria + * + * This software is the confidential and proprietary information of Know-Center, + * Graz, Austria. You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Know-Center. + * + * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF + * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY + * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. + * + * $Id: BinarySignator_1_0_0.java,v 1.1 2006/08/25 17:07:35 wprinz Exp $ + */ +package at.gv.egiz.pdfas.impl.signator.binary; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.gv.egiz.pdfas.exceptions.framework.SignatorException; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.output.DataSink; +import at.gv.egiz.pdfas.framework.signator.Signator; +import at.gv.egiz.pdfas.framework.signator.SignatorInformation; +import at.gv.egiz.pdfas.impl.input.CompoundPdfDataSourceImpl; +import at.gv.egiz.pdfas.impl.signator.IncrementalUpdateHelper; +import at.knowcenter.wag.egov.egiz.PdfAS; +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; +import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; +import at.knowcenter.wag.egov.egiz.pdf.BinarySignature; +import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation; +import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; +import at.knowcenter.wag.egov.egiz.pdf.ReplaceInfo; +import at.knowcenter.wag.egov.egiz.pdf.StringInfo; +import at.knowcenter.wag.egov.egiz.pdf.TablePos; +import at.knowcenter.wag.egov.egiz.sig.SignatureData; +import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl; +import at.knowcenter.wag.egov.egiz.sig.SignatureFieldDefinition; +import at.knowcenter.wag.egov.egiz.sig.SignatureObject; +import at.knowcenter.wag.egov.egiz.sig.SignatureTypes; +import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObjectHelper; +import at.knowcenter.wag.exactparser.ByteArrayUtils; + +import com.lowagie.text.pdf.PdfPTable; + +/** + * Signs the document binary. + * + *

+ * In prepareSign, an Incremental Update is created that contains the Signature + * block and the egiz dictionary. For formatting the layout, variable values are + * filled with placeholders. After the layout has been fixed, all variable + * fields (all holes in the byte ranges) are replaced with 0. This document is + * then base64 encoded and signed. + *

+ *

+ * In finishSign, the variable fields (values, /Cert) are replaced with the + * values according to the encoding. + *

+ * + * @author wprinz + */ +public class BinarySignator_1_0_0 implements Signator +{ + /** + * The Pdf-AS ID of this Signator. + */ + public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_BINARY, SignatorFactory.VERSION_1_0_0); + + /** + * @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId() + */ + public PdfASID getMyId() + { + return MY_ID; + } + + /** + * Default constructor. + */ + public BinarySignator_1_0_0() + { + // Default constructor. + } + + /** + * @see at.gv.egiz.pdfas.framework.signator.Signator#prepareSign(at.gv.egiz.pdfas.framework.input.PdfDataSource, + * java.lang.String, at.knowcenter.wag.egov.egiz.pdf.TablePos, boolean) + */ + public SignatorInformation prepareSign(PdfDataSource pdfDataSource, String profile, TablePos pos, boolean has_SIG_ID) throws SignatorException + { + try + { + SignatureObject signature_object = PdfAS.createSignatureObjectFromType(profile); + signature_object.fillValues((char) BinarySignature.LAYOUT_PLACEHOLDER, has_SIG_ID); + + signature_object.setKZ(getMyId()); + + PdfPTable pdf_table = PdfAS.createPdfPTableFromSignatureObject(signature_object); + + PositioningInstruction pi = PdfAS.determineTablePositioning(pos, profile, pdfDataSource, pdf_table); + + List all_field_definitions = signature_object.getSignatureTypeDefinition().getFieldDefinitions(); + List variable_field_definitions = new ArrayList(); + for (int i = 0; i < all_field_definitions.size(); i++) + { + SignatureFieldDefinition sfd = (SignatureFieldDefinition) all_field_definitions.get(i); + if (sfd.placeholder_length > 0) + { + if (sfd.field_name.equals(SignatureTypes.SIG_ID) && has_SIG_ID == false) + { + continue; + } + variable_field_definitions.add(sfd); + } + } + + IncrementalUpdateInformation iui = IncrementalUpdateHelper.writeIncrementalUpdate(pdfDataSource, pdf_table, pi, variable_field_definitions, all_field_definitions); + + String temp_string = iui.temp_ir_number + " " + iui.temp_ir_generation + " obj"; //$NON-NLS-1$//$NON-NLS-2$ + byte[] temp_bytes = temp_string.getBytes("US-ASCII"); //$NON-NLS-1$ + int temp_start = ByteArrayUtils.lastIndexOf(iui.signed_pdf, temp_bytes); + byte[] stream_bytes = new byte[] { '>', '>', 's', 't', 'r', 'e', 'a', 'm', 0x0A }; + int stream_start = ByteArrayUtils.indexOf(iui.signed_pdf, temp_start, stream_bytes); + iui.content_stream_start = stream_start + stream_bytes.length; + + // update the stream indices + Iterator it = iui.replaces.iterator(); + while (it.hasNext()) + { + ReplaceInfo ri = (ReplaceInfo) it.next(); + + Iterator sit = ri.replaces.iterator(); + while (sit.hasNext()) + { + StringInfo si = (StringInfo) sit.next(); + si.string_start += iui.content_stream_start; + } + } + // update KZ list indices: + it = iui.kz_list.iterator(); + while (it.hasNext()) + { + StringInfo si = (StringInfo) it.next(); + si.string_start += iui.content_stream_start; + } + + BinarySignature.markByteRanges(iui); + + // byte [] old_signed_pdf = iui.signed_pdf; + iui.signed_pdf = BinarySignature.prepareDataToSign(iui.signed_pdf, iui.byte_ranges); + + BinarySignatorInformation bsi = compressIUI(iui); + return bsi; + + } + catch (UnsupportedEncodingException e) + { + throw new SignatorException(201, e); + } + catch (PDFDocumentException e) + { + throw new SignatorException(e.getErrorCode(), e); + } + catch (PresentableException e) + { + throw new SignatorException(201, e); + } + } + + /** + * @see at.gv.egiz.pdfas.framework.signator.Signator#finishSign(at.gv.egiz.pdfas.framework.signator.SignatorInformation, + * at.gv.egiz.pdfas.framework.output.DataSink) + */ + public void finishSign(SignatorInformation signatorInformation, DataSink dataSink) throws SignatorException + { + try + { + IncrementalUpdateInformation iui = uncompressIUI((BinarySignatorInformation) signatorInformation); + + // PERF: need to keep the whole pdf in mem for processing + + // PdfAS.prefixID(iui.signed_signature_object, PdfAS.BINARY_ID); + fillReplacesWithValues(iui); + + BinarySignature.replaceCertificate(iui); + BinarySignature.replacePlaceholders(iui); + + OutputStream os = dataSink.createOutputStream(PdfAS.PDF_MIME_TYPE); + os.write(iui.signed_pdf); + os.close(); + + //SignResult sign_result = new SignResult(PdfAS.PDF_MIME_TYPE, iui.signed_pdf); + //return sign_result; + } + catch (PDFDocumentException e) + { + throw new SignatorException(e.getErrorCode(), e); + } + catch (IOException e) + { + throw new SignatorException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e); + } + } + + /** + * Reads the signature values from the signed signature object and fills the + * corresponding value in the Replaces array. + * + * @param iui + * The IncrementalUpdateInformation. + */ + protected void fillReplacesWithValues(IncrementalUpdateInformation iui) + { + Iterator it = iui.replaces.iterator(); + while (it.hasNext()) + { + ReplaceInfo ri = (ReplaceInfo) it.next(); + + ri.value = SignSignatureObjectHelper.retrieveStringValueFromSignatureObject(iui.signed_signature_object, ri.sfd.field_name); + } + } + + /** + * Forms the SignatureData to be used for signing. + * + * @param iui + * The IncrementalUpdateInformation. + * @return Returns the SignatureData to be used for signing. + */ + protected SignatureData formSignatureData(IncrementalUpdateInformation iui) + { + // String document_text = + // BinarySignature.retrieveSignableTextFromData(iui.signed_pdf, + // iui.signed_pdf.length); // signed_pdf.length); + // + // byte[] data; + // try + // { + // data = document_text.getBytes("UTF-8"); //$NON-NLS-1$ + // } + // catch (UnsupportedEncodingException e) + // { + // throw new RuntimeException("Very strange: UTF-8 character encoding not + // supported.", e); //$NON-NLS-1$ + // } + DataSource ds = new CompoundPdfDataSourceImpl(iui.original_document, iui.sign_iui_block); + SignatureData signature_data = new SignatureDataImpl(ds, PdfAS.PDF_MIME_TYPE); + + return signature_data; + } + + protected BinarySignatorInformation compressIUI(IncrementalUpdateInformation iui) + { + iui.sign_iui_block = new byte[iui.signed_pdf.length - iui.original_document.getLength()]; + System.arraycopy(iui.signed_pdf, iui.original_document.getLength(), iui.sign_iui_block, 0, iui.sign_iui_block.length); + + iui.signature_data = formSignatureData(iui); + + // remove the signed pdf from memory + iui.signed_pdf = null; + + BinarySignatorInformation bsi = new BinarySignatorInformation(); + bsi.originalDocument = iui.original_document; + bsi.incrementalUpdateBlock = iui.sign_iui_block; + bsi.signatureData = iui.signature_data; + bsi.replaces = iui.replaces; + bsi.cert_start = iui.cert_start; + bsi.cert_length = iui.cert_length; + bsi.enc_start = iui.enc_start; + bsi.enc_length = iui.enc_length; + + return bsi; + } + + protected IncrementalUpdateInformation uncompressIUI(BinarySignatorInformation bsi) + { + IncrementalUpdateInformation iui = new IncrementalUpdateInformation(); + + iui.original_document = bsi.originalDocument; + iui.sign_iui_block = bsi.incrementalUpdateBlock; + iui.signature_data = bsi.signatureData; + iui.replaces = bsi.replaces; + iui.cert_start = bsi.cert_start; + iui.cert_length = bsi.cert_length; + iui.enc_start = bsi.enc_start; + iui.enc_length = bsi.enc_length; + + iui.signed_signature_object = bsi.signSignatureObject; + + restoreSignedPdf(iui); + + return iui; + } + + protected void restoreSignedPdf(IncrementalUpdateInformation iui) + { + iui.signed_pdf = new byte[iui.original_document.getLength() + iui.sign_iui_block.length]; + + try + { + InputStream is = iui.original_document.createInputStream(); + is.read(iui.signed_pdf, 0, iui.original_document.getLength()); + is.close(); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + + System.arraycopy(iui.sign_iui_block, 0, iui.signed_pdf, iui.original_document.getLength(), iui.sign_iui_block.length); + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_1_0.java b/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_1_0.java new file mode 100644 index 0000000..7ab62fc --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_1_0.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2006 by Know-Center, Graz, Austria + * + * This software is the confidential and proprietary information of Know-Center, + * Graz, Austria. You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Know-Center. + * + * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF + * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY + * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. + * + * $Id: BinarySignator_1_0_0.java,v 1.1 2006/08/25 17:07:35 wprinz Exp $ + */ +package at.gv.egiz.pdfas.impl.signator.binary; + +import at.gv.egiz.pdfas.impl.input.CompoundPdfDataSourceImpl; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.knowcenter.wag.egov.egiz.PdfAS; +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; +import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation; +import at.knowcenter.wag.egov.egiz.sig.SignatureData; +import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl; + +/** + * Signs the document binary. + * + *

+ * This just differs from version 1.0.0 in the fact that the signature data is + * the actual binary PDF instead of a Base64 encoding. + *

+ * + * @see BinarySignator_1_0_0 + * + * @author wprinz + */ +public class BinarySignator_1_1_0 extends BinarySignator_1_0_0 +{ + /** + * The Pdf-AS ID of this Signator. + */ + public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_BINARY, SignatorFactory.VERSION_1_1_0); + + /** + * @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId() + */ + public PdfASID getMyId() + { + return MY_ID; + } + + /** + * Overrides the SignatureData generation of the BinarySignator 1.0.0 so that + * the SignatureData is the actual binary PDF instead of a Base64 encoding. + * + * @see at.knowcenter.wag.egov.egiz.framework.signators.BinarySignator_1_0_0#formSignatureData(at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation) + */ + protected SignatureData formSignatureData(IncrementalUpdateInformation iui) + { + DataSource ds = new CompoundPdfDataSourceImpl(iui.original_document, iui.sign_iui_block); + SignatureData signature_data = new SignatureDataImpl(ds, PdfAS.PDF_MIME_TYPE); + + return signature_data; + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java b/src/main/java/at/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java new file mode 100644 index 0000000..6a242b6 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2006 by Know-Center, Graz, Austria + * + * This software is the confidential and proprietary information of Know-Center, + * Graz, Austria. You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Know-Center. + * + * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF + * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY + * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. + * + * $Id: TextualSignator_1_0_0.java,v 1.3 2006/10/31 08:07:50 wprinz Exp $ + */ +package at.gv.egiz.pdfas.impl.signator.detached; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; + +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.gv.egiz.pdfas.exceptions.framework.SignatorException; +import at.gv.egiz.pdfas.framework.SignatorFactory; +import at.gv.egiz.pdfas.framework.output.DataSink; +import at.gv.egiz.pdfas.framework.signator.SignatorInformation; +import at.gv.egiz.pdfas.impl.signator.textual.TextualSignatorInformation; +import at.gv.egiz.pdfas.impl.signator.textual.TextualSignator_1_0_0; +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection; + +/** + * Signs a document textually. + * + *

+ * In prepareSign, the document text is extracted and normalized. + *

+ *

+ * In finishSign, the signed SignatureObject is transformed into a Signature + * block, which is then written as an Incremental Update. + *

+ * + * @author wprinz + */ +public class DetachedTextualSignator_1_0_0 extends TextualSignator_1_0_0 +{ + /** + * The Mime Type. + */ + public static final String MIME_TYPE = "text/xml"; //$NON-NLS-1$ + + /** + * The Pdf-AS ID of this Signator. + */ + public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_DETACHED_TEXTUAL, SignatorFactory.VERSION_1_0_0); + + /** + * @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId() + */ + public PdfASID getMyId() + { + return MY_ID; + } + + // /** + // *

+ // * The parameter has_SIG_ID is not used by this Signator because it doesn't + // * pre-format the signature block. + // *

+ // * + // * @see at.knowcenter.wag.egov.egiz.framework.Signator#prepareSign(byte[], + // * String, TablePos, boolean) + // */ + // public IncrementalUpdateInformation prepareSign(PdfDataSource pdf, + // String signature_type, TablePos pos, boolean has_SIG_ID) throws + // PresentableException + // { + // IncrementalUpdateInformation iui = new IncrementalUpdateInformation(); + // iui.original_document = pdf; + // iui.signature_type = signature_type; + // iui.pos = pos; + // + // String document_text = + // PdfAS.extractNormalizedTextTextual(pdf.createInputStream()); + // // logger_.debug("signed_text = " + document_text); + // + // DataSource ds = new TextDataSourceImpl(document_text); + // iui.signature_data = new SignatureDataImpl(ds, MIME_TYPE, "UTF-8"); + // //$NON-NLS-1$ //$NON-NLS-2$ + // + // return iui; + // } + // + // /** + // * @see + // at.knowcenter.wag.egov.egiz.framework.Signator#finishSign(at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation) + // */ + // public SignResult finishSign(IncrementalUpdateInformation iui) throws + // PresentableException + // { + // try + // { + // String response = + // iui.signed_signature_object.response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY); + // byte[] response_bytes = response.getBytes("UTF-8"); //$NON-NLS-1$ + // + // SignResult sign_result = new SignResult(MIME_TYPE, response_bytes); + // return sign_result; + // } + // catch (UnsupportedEncodingException e) + // { + // e.printStackTrace(); + // throw new PDFDocumentException(300, e); + // } + // } + + /** + * @see at.gv.egiz.pdfas.impl.signator.textual.TextualSignator_1_0_0#finishSign(at.gv.egiz.pdfas.framework.signator.SignatorInformation, + * at.gv.egiz.pdfas.framework.output.DataSink) + */ + public void finishSign(SignatorInformation signatorInformation, DataSink dataSink) throws SignatorException + { + try + { + TextualSignatorInformation tsi = (TextualSignatorInformation) signatorInformation; + + String response = tsi.signSignatureObject.response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY); + + OutputStream os = dataSink.createOutputStream(MIME_TYPE, "UTF-8"); + OutputStreamWriter osw = new OutputStreamWriter(os); + osw.write(response); + osw.close(); + } + catch (IOException e) + { + throw new SignatorException(ErrorCode.SIGNATURE_COULDNT_BE_CREATED, e); + } + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/signator/textual/TextualSignatorInformation.java b/src/main/java/at/gv/egiz/pdfas/impl/signator/textual/TextualSignatorInformation.java new file mode 100644 index 0000000..c5b18ff --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/signator/textual/TextualSignatorInformation.java @@ -0,0 +1,45 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.signator.textual; + +import at.knowcenter.wag.egov.egiz.pdf.TablePos; +import at.knowcenter.wag.egov.egiz.sig.SignatureData; +import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.signator.SignatorInformation; + +/** + * @author wprinz + * + */ +public class TextualSignatorInformation implements SignatorInformation +{ + protected PdfDataSource originalDocument = null; + + protected SignatureData signatureData = null; + + protected String profile = null; + + protected TablePos pos = null; + + public SignSignatureObject signSignatureObject = null; + + /** + * @see at.gv.egiz.pdfas.framework.signator.SignatorInformation#getSignatureData() + */ + public SignatureData getSignatureData() + { + return this.signatureData; + } + + /** + * + * @see at.gv.egiz.pdfas.framework.signator.SignatorInformation#setSignSignatureObject(at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject) + */ + public void setSignSignatureObject(SignSignatureObject signSignatureObject) + { + this.signSignatureObject = signSignatureObject; + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/signator/textual/TextualSignator_1_0_0.java b/src/main/java/at/gv/egiz/pdfas/impl/signator/textual/TextualSignator_1_0_0.java new file mode 100644 index 0000000..b0494c8 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/signator/textual/TextualSignator_1_0_0.java @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2006 by Know-Center, Graz, Austria + * + * This software is the confidential and proprietary information of Know-Center, + * Graz, Austria. You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Know-Center. + * + * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF + * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY + * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. + * + * $Id: TextualSignator_1_0_0.java,v 1.3 2006/10/31 08:07:50 wprinz Exp $ + */ +package at.gv.egiz.pdfas.impl.signator.textual; + +import at.gv.egiz.pdfas.exceptions.framework.SignatorException; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.output.DataSink; +import at.gv.egiz.pdfas.framework.signator.Signator; +import at.gv.egiz.pdfas.framework.signator.SignatorInformation; +import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl; +import at.gv.egiz.pdfas.impl.signator.IncrementalUpdateHelper; +import at.knowcenter.wag.egov.egiz.PdfAS; +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; +import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; +import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; +import at.knowcenter.wag.egov.egiz.pdf.TablePos; +import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl; +import at.knowcenter.wag.egov.egiz.sig.SignatureObject; +import at.knowcenter.wag.egov.egiz.sig.signatureobject.SignatureObjectHelper; + +import com.lowagie.text.pdf.PdfPTable; + +/** + * Signs a document textually. + * + *

+ * In prepareSign, the document text is extracted and normalized. + *

+ *

+ * In finishSign, the signed SignatureObject is transformed into a Signature + * block, which is then written as an Incremental Update. + *

+ * + * @author wprinz + */ +public class TextualSignator_1_0_0 implements Signator +{ + /** + * The Pdf-AS ID of this Signator. + */ + public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_TEXTUAL, SignatorFactory.VERSION_1_0_0); + + /** + * @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId() + */ + public PdfASID getMyId() + { + return MY_ID; + } + + /** + * Default constructor. + */ + public TextualSignator_1_0_0() + { + // Default constructor. + } + + /** + *

+ * The parameter has_SIG_ID is not used by this Signator because it doesn't + * pre-format the signature block. + *

+ * + * @see at.gv.egiz.pdfas.framework.signator.Signator#prepareSign(at.gv.egiz.pdfas.framework.input.PdfDataSource, + * java.lang.String, at.knowcenter.wag.egov.egiz.pdf.TablePos, boolean) + */ + public SignatorInformation prepareSign(PdfDataSource pdfDataSource, String profile, TablePos pos, boolean has_SIG_ID) throws SignatorException + { + try + { + TextualSignatorInformation tsi = new TextualSignatorInformation(); + tsi.originalDocument = pdfDataSource; + tsi.profile = profile; + tsi.pos = pos; + + String document_text = PdfAS.extractNormalizedTextTextual(pdfDataSource.createInputStream()); + // logger_.debug("signed_text = " + document_text); + + DataSource ds = new TextDataSourceImpl(document_text); + tsi.signatureData = new SignatureDataImpl(ds, "text/plain", "UTF-8"); + + return tsi; + } + catch (PresentableException pe) + { + throw new SignatorException(pe); + } + } + + /** + * @see at.gv.egiz.pdfas.framework.signator.Signator#finishSign(at.gv.egiz.pdfas.framework.signator.SignatorInformation, + * at.gv.egiz.pdfas.framework.output.DataSink) + */ + public void finishSign(SignatorInformation signatorInformation, DataSink dataSink) throws SignatorException + { + try + { + TextualSignatorInformation tsi = (TextualSignatorInformation) signatorInformation; + + // PdfAS.prefixID(iui.signed_signature_object, PdfAS.TEXT_ID); + + // iui.signed_signature_object.kz = getMyId().toString(); + tsi.signSignatureObject.kz = getMyId().toString(); + // TODO what is this for? + + SignatureObject so = SignatureObjectHelper.convertSignSignatureObjectToSignatureObject(tsi.signSignatureObject, tsi.profile); + + PdfPTable pdf_table = PdfAS.createPdfPTableFromSignatureObject(so); + + PositioningInstruction pi = PdfAS.determineTablePositioning(tsi.pos, tsi.profile, tsi.originalDocument, pdf_table); + + IncrementalUpdateHelper.writeIncrementalUpdateToDataSink(tsi.originalDocument, dataSink, pdf_table, pi); + +// OutputStream os = dataSink.createOutputStream(PdfAS.PDF_MIME_TYPE); +// os.write(signed_iui.signed_pdf); +// os.close(); + +// SignResult sign_result = new SignResult(PdfAS.PDF_MIME_TYPE, signed_iui.signed_pdf); +// return sign_result; + } + catch (PresentableException pe) + { + throw new SignatorException(pe); + } +// catch (IOException e) +// { +// throw new SignatorException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e); +// } + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/signator/textual/TextualSignator_1_1_0.java b/src/main/java/at/gv/egiz/pdfas/impl/signator/textual/TextualSignator_1_1_0.java new file mode 100644 index 0000000..68cd3a1 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/signator/textual/TextualSignator_1_1_0.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2006 by Know-Center, Graz, Austria + * + * This software is the confidential and proprietary information of Know-Center, + * Graz, Austria. You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Know-Center. + * + * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF + * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY + * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. + * + * $Id: TextualSignator_1_0_0.java,v 1.3 2006/10/31 08:07:50 wprinz Exp $ + */ +package at.gv.egiz.pdfas.impl.signator.textual; + +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; + +/** + * Signs a document textually. + * + * @see TextualSignator_1_0_0 + * + * @author wprinz + */ +public class TextualSignator_1_1_0 extends TextualSignator_1_0_0 +{ + /** + * The Pdf-AS ID of this Signator. + */ + public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_TEXTUAL, SignatorFactory.VERSION_1_1_0); + + /** + * @see at.knowcenter.wag.egov.egiz.framework.Signator#getMyId() + */ + public PdfASID getMyId() + { + return MY_ID; + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/verificator/binary/BinaryVerificator_1_0_0.java b/src/main/java/at/gv/egiz/pdfas/impl/verificator/binary/BinaryVerificator_1_0_0.java new file mode 100644 index 0000000..b52e97f --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/verificator/binary/BinaryVerificator_1_0_0.java @@ -0,0 +1,399 @@ +/** + * Copyright (c) 2006 by Know-Center, Graz, Austria + * + * This software is the confidential and proprietary information of Know-Center, + * Graz, Austria. You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Know-Center. + * + * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF + * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY + * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. + * + * $Id: BinaryVerificator_1_0_0.java,v 1.3 2006/10/11 08:03:22 wprinz Exp $ + */ +package at.gv.egiz.pdfas.impl.verificator.binary; + +import java.io.ByteArrayOutputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.verificator.Verificator; +import at.gv.egiz.pdfas.impl.input.ByteArrayPdfDataSourceImpl; +import at.gv.egiz.pdfas.impl.input.CompoundPdfDataSourceImpl; +import at.gv.egiz.pdfas.impl.input.DelimitedPdfDataSource; +import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper; + +import org.apache.log4j.Logger; + +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger; +import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; +import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; +import at.knowcenter.wag.egov.egiz.framework.VerificationFilter; +import at.knowcenter.wag.egov.egiz.pdf.BinaryBlockInfo; +import at.knowcenter.wag.egov.egiz.pdf.BinarySignature; +import at.knowcenter.wag.egov.egiz.pdf.BinarySignatureHolder; +import at.knowcenter.wag.egov.egiz.pdf.Placeholder; +import at.knowcenter.wag.egov.egiz.pdf.ReplaceInfo; +import at.knowcenter.wag.egov.egiz.pdf.StringInfo; +import at.knowcenter.wag.egov.egiz.sig.SignatureObject; +import at.knowcenter.wag.egov.egiz.sig.SignatureTypes; +import at.knowcenter.wag.exactparser.parsing.IndirectObjectReference; +import at.knowcenter.wag.exactparser.parsing.PDFUtils; +import at.knowcenter.wag.exactparser.parsing.results.ArrayParseResult; +import at.knowcenter.wag.exactparser.parsing.results.DictionaryParseResult; +import at.knowcenter.wag.exactparser.parsing.results.FooterParseResult; +import at.knowcenter.wag.exactparser.parsing.results.IndirectObjectReferenceParseResult; +import at.knowcenter.wag.exactparser.parsing.results.LiteralStringParseResult; +import at.knowcenter.wag.exactparser.parsing.results.NameParseResult; +import at.knowcenter.wag.exactparser.parsing.results.NumberParseResult; +import at.knowcenter.wag.exactparser.parsing.results.ObjectParseResult; +import at.knowcenter.wag.exactparser.parsing.results.ParseResult; + +/** + * The BinaryVerificator parses the EGIT Dictionary and extracts the signature + * holder from it. + * + * @author wprinz + */ +public class BinaryVerificator_1_0_0 implements Verificator +{ + /** + * The Pdf-AS ID of this Verificator. + */ + public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_BINARY, SignatorFactory.VERSION_1_0_0); + + /** + * Use this to override the MY_ID field. + * + * @return Returns the Id of this Verificator. + */ + protected PdfASID getMyId() + { + return MY_ID; + } + + /** + * The /ODS key in the EGIZ Dict. + */ + public static final byte[] EGIZ_ODS_NAME = new byte[] { 'O', 'D', 'S' }; + + /** + * The /ID key in the EGIZ Dict. + */ + public static final byte[] EGIZ_KZ_NAME = VerificationFilter.EGIZ_KZ_NAME; + + /** + * The /ByteRange key in the EGIZ Dict. + */ + public static final byte[] EGIZ_BYTE_RANGE_NAME = new byte[] { 'B', 'y', 't', 'e', 'R', 'a', 'n', 'g', 'e' }; + + /** + * The /replaces key in the EGIZ Dict. + */ + public static final byte[] EGIZ_REPLACES_NAME = new byte[] { 'r', 'e', 'p', 'l', 'a', 'c', 'e', 's' }; + + /** + * The /encodings key in the EGIZ Dict. + */ + public static final byte[] EGIZ_ENCODINGS_NAME = new byte[] { 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g', 's' }; + + /** + * The /Cert key in the EGIZ Dict. + */ + public static final byte[] EGIZ_CERT_NAME = new byte[] { 'C', 'e', 'r', 't' }; + + /** + * The logger definition. + */ + private static final Logger logger_ = ConfigLogger.getLogger(BinaryVerificator_1_0_0.class); + + /** + * Default constructor. + */ + public BinaryVerificator_1_0_0() + { + // Default constructor. + } + + /** + * @see at.gv.egiz.pdfas.framework.verificator.Verificator#parseBlock(at.gv.egiz.pdfas.framework.input.PdfDataSource, + * byte[], + * at.knowcenter.wag.exactparser.parsing.results.FooterParseResult, int) + */ + public List parseBlock(PdfDataSource pdfDataSource, byte [] pdf, FooterParseResult block, int start_of_whole_block) throws PresentableException + { + // PERF: BinaryVerificator needs byte array. + + int egiz_index = PDFUtils.indexOfName(pdf, block.tpr.dpr.names, VerificationFilter.EGIZ_DICT_NAME); + if (egiz_index < 0) + { + throw new PDFDocumentException(ErrorCode.COULDNT_VERIFY, "egiz_index = " + egiz_index); + } + + IndirectObjectReferenceParseResult egiz_dict_iorpr = (IndirectObjectReferenceParseResult) block.tpr.dpr.values.get(egiz_index); + + IndirectObjectReference ior = egiz_dict_iorpr.ior; + + final int egiz_dict_offset = PDFUtils.getObjectOffsetFromXRefByIndirectObjectReference(block.xpr, ior); + + ObjectParseResult obj = PDFUtils.parseObject(pdf, egiz_dict_offset); + DictionaryParseResult egiz_dict = (DictionaryParseResult) obj.object; + + NumberParseResult ods_npr = (NumberParseResult) getRequiredValueOfKey(pdf, egiz_dict, EGIZ_ODS_NAME); + + ArrayParseResult kz_apr = (ArrayParseResult) getRequiredValueOfKey(pdf, egiz_dict, EGIZ_KZ_NAME); + PdfASID kz = null; + String kz_string = VerificationFilter.restoreKZ(pdf, kz_apr); + kz = new PdfASID(kz_string); + if (!kz_string.equals(getMyId().toString())) + { + logger_.warn("Warning: Kennzeichnung not recognized:" + kz_string); + } + + ArrayParseResult byte_ranges_apr = (ArrayParseResult) getRequiredValueOfKey(pdf, egiz_dict, EGIZ_BYTE_RANGE_NAME); + + ArrayParseResult replaces_apr = (ArrayParseResult) getRequiredValueOfKey(pdf, egiz_dict, EGIZ_REPLACES_NAME); + + ArrayParseResult encodings_apr = (ArrayParseResult) getRequiredValueOfKey(pdf, egiz_dict, EGIZ_ENCODINGS_NAME); + + ArrayParseResult cert_apr = (ArrayParseResult) getValueOfKey(pdf, egiz_dict, EGIZ_CERT_NAME); + byte[] cert = null; + if (cert_apr != null && !cert_apr.elements.isEmpty()) + { + LiteralStringParseResult lspr = (LiteralStringParseResult) cert_apr.elements.get(0); + int str_length = lspr.content_end_index - lspr.content_start_index; + byte[] encoded = new byte[str_length]; + System.arraycopy(pdf, lspr.content_start_index, encoded, 0, encoded.length); + + cert = Placeholder.unescapePDFString(encoded); + } + + int num_byte_ranges = byte_ranges_apr.elements.size() / 2; + List byte_ranges = new ArrayList(); + for (int i = 0; i < num_byte_ranges; i++) + { + NumberParseResult start_npr = (NumberParseResult) byte_ranges_apr.elements.get(2 * i); + NumberParseResult length_npr = (NumberParseResult) byte_ranges_apr.elements.get(2 * i + 1); + + StringInfo si = new StringInfo(); + si.string_start = start_npr.number; + si.string_length = length_npr.number; + byte_ranges.add(si); + } + + StringInfo sis[] = new StringInfo[num_byte_ranges - 1]; + for (int i = 0; i < num_byte_ranges - 1; i++) + { + StringInfo prev = (StringInfo) byte_ranges.get(i); + StringInfo next = (StringInfo) byte_ranges.get(i + 1); + + StringInfo hole = new StringInfo(); + hole.string_start = prev.string_start + prev.string_length; + hole.string_length = next.string_start - hole.string_start; + + sis[i] = hole; + } + + int n = replaces_apr.elements.size(); + byte[][] brevs = new byte[n][]; + for (int i = 0; i < n; i++) + { + NameParseResult lspr = (NameParseResult) replaces_apr.elements.get(i); + + byte[] brev = new byte[3]; + System.arraycopy(pdf, lspr.name_start_index, brev, 0, brev.length); + + brevs[i] = brev; // SignatureTypes.convertBrevToType(brev); + } + + n = encodings_apr.elements.size(); + byte[][] encodings = new byte[n][]; + for (int i = 0; i < n; i++) + { + NameParseResult lspr = (NameParseResult) encodings_apr.elements.get(i); + + byte[] enc = new byte[3]; + System.arraycopy(pdf, lspr.name_start_index, enc, 0, enc.length); + encodings[i] = enc; + } + + BinaryBlockInfo bbi = new BinaryBlockInfo(); + bbi.replaces = BinarySignature.reconstructReplaces(pdf, brevs, sis, encodings); + bbi.signed_size = ods_npr.number; + + // BinaryBlockInfo bbi = BinarySignature.retrieveEgizDictInformation(pdf, + // ior.object_number, ior.generation_number, egiz_dict_offset); + + // byte[] original_pdf = BinarySignature.restoreEgizDictInformation(pdf, + // bbi); + + byte[] signed_pdf = BinarySignature.prepareDataToSign(pdf, byte_ranges); + // String signed_text = + // BinarySignature.retrieveSignableTextFromData(signed_pdf, + // signed_pdf.length); // has been moved into the BinarySignatureHolder + + SignatureObject signature_object = new SignatureObject(); + String default_type = SettingsReader.getInstance().getValueFromKey(SignatureTypes.DEFAULT_TYPE); + signature_object.setSigType(default_type); + signature_object.initByType(); + + signature_object.setKZ(kz); + + if (cert != null) + { + try + { + // ByteArrayInputStream bais = new ByteArrayInputStream(cert); + // CertificateFactory cf = CertificateFactory.getInstance("X.509"); + // X509Certificate certificate = (X509Certificate) + // cf.generateCertificate(bais); + + // trim zero bytes. - the base 64 cert must not have zero bytes. + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + for (int i = 0; i < cert.length; i++) + { + if (cert[i] != 0) + { + baos.write(cert[i]); + } + } + byte[] b64 = baos.toByteArray(); + + signature_object.storeNewCertificateInLocalStore(b64); + } + catch (Exception e) + { + e.printStackTrace(); + } + + } + + Iterator rit = bbi.replaces.iterator(); + while (rit.hasNext()) + { + ReplaceInfo ri = (ReplaceInfo) rit.next(); + + String type = SignatureTypes.convertBrevToType(ri.brev); + + // signature_object.setSigValue(ri.type, ri.value); + if (type.equals(SignatureTypes.SIG_DATE)) + { + signature_object.setSignationDate(ri.value); + continue; + } + + if (type.equals(SignatureTypes.SIG_ISSUER)) + { + signature_object.setSignationIssuer(ri.value); + continue; + } + + if (type.equals(SignatureTypes.SIG_VALUE)) + { + signature_object.setSignationValue(ri.value); + continue; + } + + if (type.equals(SignatureTypes.SIG_NUMBER)) + { + signature_object.setSignationSerialNumber(ri.value); + continue; + } + + if (type.equals(SignatureTypes.SIG_ID)) + { + signature_object.setSignationIDs(ri.value); + continue; + } + } + + int iu_length = signed_pdf.length - start_of_whole_block; + byte [] iu_block = new byte [iu_length]; + System.arraycopy(signed_pdf, start_of_whole_block, iu_block, 0, iu_length); + + DelimitedPdfDataSource dpds = new DelimitedPdfDataSource(pdfDataSource, start_of_whole_block); + PdfDataSource ds = new CompoundPdfDataSourceImpl(dpds, iu_block); + + //PdfDataSource dsByteArray = new ByteArrayPdfDataSourceImpl(signed_pdf, signed_pdf.length); + + BinarySignatureHolder signature_holder = new BinarySignatureHolder(ds, signature_object); + + List holders = new ArrayList(); + holders.add(signature_holder); + return holders; + } + + /** + * Retrieves the value of the key from the dictionary. + * + * @param pdf + * The PDF. + * @param egiz_dict + * The dictionary. + * @param name + * The name of the key. + * @return Returns the value of the key. An exception is thrown if the key + * doesn't exist. + * @throws PDFDocumentException + * Thrown, if the key doesn't exist in the dictionary. + */ + protected ParseResult getRequiredValueOfKey(byte[] pdf, DictionaryParseResult egiz_dict, byte[] name) throws PDFDocumentException + { + final int index = PDFUtils.indexOfName(pdf, egiz_dict.names, name); + checkIndex(index); + ParseResult value = (ParseResult) egiz_dict.values.get(index); + return value; + } + + /** + * Throws an excaption, if the index is lower than 0. + * + * @param name_index + * The index. + * @throws PDFDocumentException + * Thrown, if the index is lower than 0. + */ + protected void checkIndex(int name_index) throws PDFDocumentException + { + if (name_index < 0) + { + throw new PDFDocumentException(ErrorCode.COULDNT_VERIFY, "The name wasn't found in the egiz dict."); + } + } + + /** + * Retrieves the value of the key from the dictionary. + * + * @param pdf + * The PDF. + * @param egiz_dict + * The dictionary. + * @param name + * The name of the key. + * @return Returns the key's value, or null if the dictionary didn't contain + * that key. + */ + protected ParseResult getValueOfKey(byte[] pdf, DictionaryParseResult egiz_dict, byte[] name) + { + final int index = PDFUtils.indexOfName(pdf, egiz_dict.names, name); + if (index < 0) + { + return null; + } + ParseResult value = (ParseResult) egiz_dict.values.get(index); + return value; + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/verificator/binary/BinaryVerificator_1_1_0.java b/src/main/java/at/gv/egiz/pdfas/impl/verificator/binary/BinaryVerificator_1_1_0.java new file mode 100644 index 0000000..a78c4a8 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/verificator/binary/BinaryVerificator_1_1_0.java @@ -0,0 +1,24 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.verificator.binary; + +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; + +/** + * @author wprinz + * + */ +public class BinaryVerificator_1_1_0 extends BinaryVerificator_1_0_0 +{ + public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_BINARY, SignatorFactory.VERSION_1_1_0); + + /** + * @see at.knowcenter.wag.egov.egiz.framework.verificators.BinaryVerificator_1_0_0#getMyId() + */ + protected PdfASID getMyId() + { + return MY_ID; + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/Partition.java b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/Partition.java new file mode 100644 index 0000000..6fe90e5 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/Partition.java @@ -0,0 +1,9 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.vfilter; + +public interface Partition +{ + public boolean isTextPartition(); +} \ No newline at end of file diff --git a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java new file mode 100644 index 0000000..981b868 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java @@ -0,0 +1,575 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.vfilter; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.exceptions.framework.VerificationFilterException; +import at.gv.egiz.pdfas.framework.SignatureHolderHelper; +import at.gv.egiz.pdfas.framework.VerificatorFactory; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.input.TextDataSource; +import at.gv.egiz.pdfas.framework.verificator.Verificator; +import at.gv.egiz.pdfas.framework.vfilter.VerificationFilter; +import at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters; +import at.gv.egiz.pdfas.impl.input.DelimitedInputStream; +import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper; +import at.gv.egiz.pdfas.impl.vfilter.helper.VerificationFilterBinaryHelper; +import at.gv.egiz.pdfas.impl.vfilter.helper.VerificationFilterHelper; +import at.gv.egiz.pdfas.impl.vfilter.partition.BinaryPartition; +import at.gv.egiz.pdfas.impl.vfilter.partition.TextPartition; +import at.knowcenter.wag.egov.egiz.PdfAS; +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.exceptions.NormalizeException; +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; +import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; +import at.knowcenter.wag.egov.egiz.exceptions.SignatureTypesException; +import at.knowcenter.wag.egov.egiz.pdf.AbsoluteTextSignature; +import at.knowcenter.wag.egov.egiz.pdf.EGIZDate; +import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; +import at.knowcenter.wag.egov.egiz.pdf.TextualSignatureHolder; +import at.knowcenter.wag.exactparser.parsing.results.FooterParseResult; + +/** + * @author wprinz + */ +public class VerificationFilterImpl implements VerificationFilter +{ + + /** + * The log. + */ + private static final Log log = LogFactory.getLog(VerificationFilterImpl.class); + + /** + * @see at.gv.egiz.pdfas.framework.vfilter.VerificationFilter#extractSignatureHolders(at.gv.egiz.pdfas.framework.input.PdfDataSource, + * java.util.List, + * at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters) + */ + public List extractSignatureHolders(final PdfDataSource pdf, List blocks, final VerificationFilterParameters parameters) throws VerificationFilterException + { + log.trace("extractSignaturHolders:"); + + if (log.isDebugEnabled()) + { + log.debug("Original IU blocks: " + blocks.size()); + debugIUBlocks(blocks); + } + + unrollLinearization(blocks); + + if (log.isDebugEnabled()) + { + log.debug("IU blocks without linearization: " + blocks.size()); + debugIUBlocks(blocks); + } + + List signatureHolderChain = null; + + if (parameters.extractBinarySignaturesOnly()) + { + log.debug("Extracting only binary signatures. Binary-only mode."); + + signatureHolderChain = performBinaryOnly(pdf, blocks); + } + else + { + List partitions = VerificationFilterHelper.partition(pdf, blocks); + if (log.isDebugEnabled()) + { + debugPartitions(partitions); + } + + if (parameters.assumeOnlySignatureUpdateBlocks()) + { + log.debug("Assuming that there are only signature Incremental Update blocks. Semi-conservative mode."); + + signatureHolderChain = performSemiConservative(pdf, parameters.scanForOldSignatures(), blocks, partitions); + } + else + { + log.debug("Scanning complete document. Conservative mode."); + + signatureHolderChain = performFullConservative(pdf, parameters.scanForOldSignatures(), blocks, partitions); + } + + } + + log.trace("extractSignaturHolders finished."); + return signatureHolderChain; + } + + /** + * @see at.gv.egiz.pdfas.framework.vfilter.VerificationFilter#extractSignaturHolders(at.gv.egiz.pdfas.framework.input.TextDataSource, + * at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters) + */ + public List extractSignaturHolders(TextDataSource text, VerificationFilterParameters parameters) throws VerificationFilterException + { + if (parameters.extractBinarySignaturesOnly()) + { + log + .warn("A free text signature extraction was issued although the VerificationFilter was configured to detect only binary signatures (binary-only mode). The result is of course that no signatures can be found."); + + return new ArrayList(); + } + + String freetext = text.getText(); + String normalizedText = normalizeText(freetext); + + List foundSignatures = null; + if (parameters.scanForOldSignatures()) + { + log.debug("Extracting old and new signatures from text."); + + foundSignatures = extractNewAndOldSignaturesFromText(normalizedText); + } + else + { + log.debug("Extracting new signatures from text (not extracting old ones)."); + + foundSignatures = extractNewSignaturesFromText(normalizedText); + } + + List textOnlySignatures = filterOutBinarySignatures(foundSignatures); + + return textOnlySignatures; + } + + protected String normalizeText(String freetext) throws VerificationFilterException + { + try + { + return PdfAS.normalizeText(freetext); + } + catch (NormalizeException e) + { + throw new VerificationFilterException(e); + } + } + + /** + * Removes the linearization footer from the list of update blocks. + * + * @param blocks + * The list of FooterParseResult objects in \prev order. + */ + protected void unrollLinearization(List blocks) + { + int linearization_index = -1; + for (int i = 0; i < blocks.size(); i++) + { + FooterParseResult bpr = (FooterParseResult) blocks.get(i); + + if (bpr.sxpr.xref_index == 0) + { + if (linearization_index >= 0) + { + throw new RuntimeException("There is more than one linearization block! index = " + i); + } + linearization_index = i; + } + } + + if (linearization_index >= 0) + { + // logger_.debug("The document is linearized - unrolling + // linearization block " + linearization_index); + blocks.remove(linearization_index); + } + } + + protected List performBinaryOnly(PdfDataSource pdf, List blocks) throws VerificationFilterException + { + return extractBinarySignaturesOnly(pdf, blocks); + } + + protected List performSemiConservative(PdfDataSource pdf, boolean scanForOldSignatures, List blocks, List partitions) throws VerificationFilterException + { + List binarySignatures = extractBinarySignaturesOnly(pdf, blocks); + + TextPartition lastTextPartition = VerificationFilterHelper.findLastTextPartition(partitions); + List extractedSignatures = null; + if (scanForOldSignatures) + { + SignaturesAndOld sao = extractSignaturesFromPartitionAndOld(pdf, lastTextPartition); + extractedSignatures = sao.newSignatures; + if (sao.oldSignature != null) + { + extractedSignatures.add(0, sao.oldSignature); + } + } + else + { + extractedSignatures = extractSignaturesFromPartition(pdf, lastTextPartition); + } + + List signatureHolderChain = intermingleSignatures(binarySignatures, extractedSignatures); + + return signatureHolderChain; + } + + protected List performFullConservative(PdfDataSource pdf, boolean scanForOldSignatures, List blocks, List partitions) throws VerificationFilterException + { + List binarySignatures = extractBinarySignaturesOnly(pdf, blocks); + + SignatureHolder oldSignature = null; + + List partitionResults = new ArrayList(partitions.size()); + for (int i = 0; i < partitions.size(); i++) + { + Partition p = (Partition) partitions.get(i); + + if (p instanceof TextPartition) + { + TextPartition tp = (TextPartition) p; + + List partitionResult = null; + + boolean scanThisPartitionForOldSignature = (i == 0) && scanForOldSignatures; + if (scanThisPartitionForOldSignature) + { + SignaturesAndOld sao = extractSignaturesFromPartitionAndOld(pdf, tp); + partitionResult = sao.newSignatures; + oldSignature = sao.oldSignature; + } + else + { + partitionResult = extractSignaturesFromPartition(pdf, tp); + } + + partitionResults.add(partitionResult); + } + } + + List extractedSignatures = new ArrayList(); + Iterator it = partitionResults.iterator(); + List prevPartitionResult = null; + while (it.hasNext()) + { + List partitionResult = (List) it.next(); + + if (prevPartitionResult == null) + { + extractedSignatures.addAll(partitionResult); + } + else + { + assert partitionResult.size() >= prevPartitionResult.size(); + + for (int i = prevPartitionResult.size(); i < partitionResult.size(); i++) + { + SignatureHolder sh = (SignatureHolder) partitionResult.get(i); + extractedSignatures.add(sh); + } + } + + prevPartitionResult = partitionResult; + } + + List signatureHolderChain = intermingleSignatures(binarySignatures, extractedSignatures); + + if (oldSignature != null) + { + signatureHolderChain.add(0, oldSignature); + } + + return signatureHolderChain; + } + + protected String extractText(PdfDataSource pdf, int endOfDocument) throws PresentableException + { + DelimitedInputStream dis = new DelimitedInputStream(pdf.createInputStream(), endOfDocument); + return PdfAS.extractNormalizedTextTextual(dis); + } + + protected List extractNewSignaturesFromText(String text) throws VerificationFilterException + { + try + { + return AbsoluteTextSignature.extractSignatureHoldersFromText(text); + } + catch (PresentableException e) + { + throw new VerificationFilterException(e); + } + } + + protected List extractNewAndOldSignaturesFromText(String text) throws VerificationFilterException + { + SignaturesAndOld sao = extractSignaturesAndOld(text); + if (sao.oldSignature != null) + { + sao.newSignatures.add(0, sao.oldSignature); + } + + return sao.newSignatures; + } + + protected List extractOldSignaturesFromText(String text) throws PresentableException + { + return PdfAS.extractSignatureHoldersTextual(text, true); + } + + protected List intermingleSignatures(List binarySignatures, List extractedSignatures) + { + List textualSignatures = filterOutBinarySignatures(extractedSignatures); + + List intermingled = new ArrayList(binarySignatures.size() + textualSignatures.size()); + intermingled.addAll(binarySignatures); + intermingled.addAll(textualSignatures); + + sortSignatures(intermingled); + + return intermingled; + } + + protected List filterOutBinarySignatures(List signatures) + { + List textOnly = new ArrayList(signatures.size()); + + Iterator it = signatures.iterator(); + while (it.hasNext()) + { + SignatureHolder sh = (SignatureHolder) it.next(); + if (sh.getSignatureObject().isTextual()) + { + textOnly.add(sh); + } + } + + return textOnly; + } + + protected void sortSignatures(List signatures) + { + SignatureHolderHelper.sortByDate(signatures); + } + + protected void debugIUBlocks(List blocks) + { + Iterator it = blocks.iterator(); + while (it.hasNext()) + { + FooterParseResult fpr = (FooterParseResult) it.next(); + log.debug("footer: " + fpr.start_index + " to " + fpr.next_index + ", has predecessor = " + fpr.tpr.has_predecessor); + } + } + + protected void debugPartitions(List partitions) + { + Iterator it = partitions.iterator(); + while (it.hasNext()) + { + Object o = it.next(); + assert o instanceof Partition; + + List blocks = null; + if (o instanceof TextPartition) + { + TextPartition tp = (TextPartition) o; + + blocks = tp.blocks; + + log.debug("text partition with " + tp.blocks.size() + " blocks:"); + } + else + { + BinaryPartition bp = (BinaryPartition) o; + + blocks = bp.blocks; + + log.debug("binary partition: with " + bp.blocks.size() + " blocks:"); + + } + debugIUBlocks(blocks); + log.debug("partition finished."); + } + } + + /** + * Extracts the binary singatures from the given PDF. + * + *

+ * IU blocks without an egiz dict are not considered. + *

+ * + * @param pdf + * @param blocks + * @return Returns the List of signature holders. + * @throws PresentableException + */ + protected List extractBinarySignaturesOnly(PdfDataSource pdf, List blocks) throws VerificationFilterException + { + try + { + // PERF: extract binary signatures needs byte array + byte[] data = DataSourceHelper.convertDataSourceToByteArray(pdf); + + List binarySignatures = new ArrayList(blocks.size()); + + Iterator it = blocks.iterator(); + int prev_end = 0; + while (it.hasNext()) + { + FooterParseResult fpr = (FooterParseResult) it.next(); + assert fpr.next_index > prev_end; + + if (VerificationFilterBinaryHelper.containsEGIZDict(data, fpr)) + { + PdfASID kz = VerificationFilterBinaryHelper.extractKZFromEGIZBlock(data, fpr); + + Verificator verificator = VerificatorFactory.createBinaryVerificator(kz); + List binary_holders = verificator.parseBlock(pdf, data, fpr, prev_end); + + binarySignatures.addAll(binary_holders); + } + + prev_end = fpr.next_index; + } + + return binarySignatures; + } + catch (PresentableException e) + { + throw new VerificationFilterException(e); + } + } + + protected List extractSignatures(PdfDataSource pdf, int endOfDocument) throws VerificationFilterException + { + try + { + log.debug("Extracting text from 0 to " + endOfDocument + " (total document size = " + pdf.getLength() + "):"); + String extractedText = extractText(pdf, endOfDocument); + log.debug("Extracting text finished."); + + log.debug("Extracting signatures:"); + List extractedSignatures = extractNewSignaturesFromText(extractedText); + log.debug("Extracting signatures finished."); + + return extractedSignatures; + } + catch (PresentableException e) + { + throw new VerificationFilterException(e); + } + } + + protected String determineRestText(List newSignatures, String extractedText) + { + if (newSignatures.isEmpty()) + { + return extractedText; + } + + // note that even if the oldest signature is a binary signature, + // the rest text is the text of this binary signature, which was extracted + // like a text signature. + TextualSignatureHolder oldestSignature = (TextualSignatureHolder) newSignatures.get(0); + return oldestSignature.getSignedText(); + } + + protected List extractSignaturesFromPartition(PdfDataSource pdf, Partition partition) throws VerificationFilterException + { + assert partition.isTextPartition(); + + int endOfDocument = VerificationFilterHelper.getEndOfPartition(partition); + return extractSignatures(pdf, endOfDocument); + } + + protected SignaturesAndOld extractSignaturesFromPartitionAndOld(PdfDataSource pdf, Partition partition) throws VerificationFilterException + { + assert partition.isTextPartition(); + + try + { + int endOfDocument = VerificationFilterHelper.getEndOfPartition(partition); + + log.debug("Extracting text from 0 to " + endOfDocument + " (total document size = " + pdf.getLength() + "):"); + String extractedText = extractText(pdf, endOfDocument); + log.debug("Extracting text finished."); + + SignaturesAndOld sao = extractSignaturesAndOld(extractedText); + + return sao; + } + catch (PresentableException e) + { + throw new VerificationFilterException(e); + } + } + + protected static class SignaturesAndOld + { + public List newSignatures = null; + + public SignatureHolder oldSignature = null; + } + + protected SignaturesAndOld extractSignaturesAndOld(String text) throws VerificationFilterException + { + try + { + log.debug("Extracting signatures:"); + List extractedSignatures = extractNewSignaturesFromText(text); + log.debug("Extracting signatures finished."); + + log.debug("Extracting old signatures:"); + SignatureHolder oldSignature = extractOldSignature(text, extractedSignatures); + log.debug("Extracting old signatures finished."); + + SignaturesAndOld sao = new SignaturesAndOld(); + sao.newSignatures = extractedSignatures; + sao.oldSignature = oldSignature; + + return sao; + } + catch (PresentableException e) + { + throw new VerificationFilterException(e); + } + } + + /** + * Extracts the old signature from the text, but only if it is older than the + * oldest signature of the new signatueres. + * + * @param extractedText + * @param newSignatures + * @return + * @throws PDFDocumentException + * @throws SignatureException + * @throws NormalizeException + * @throws SignatureTypesException + */ + protected SignatureHolder extractOldSignature(String extractedText, List newSignatures) throws PDFDocumentException, SignatureException, NormalizeException, SignatureTypesException + { + SignatureHolder oldSignature = null; + + String restText = determineRestText(newSignatures, extractedText); + + List oldSignatures = PdfAS.extractSignatureHoldersTextual(restText, true); + if (!oldSignatures.isEmpty()) + { + oldSignature = (SignatureHolder) oldSignatures.get(0); + if (!newSignatures.isEmpty()) + { + SignatureHolder oldestNewSignature = (SignatureHolder) newSignatures.get(0); + EGIZDate oldDate = EGIZDate.parseFromString(oldSignature.getSignatureObject().getSignationDate()); + EGIZDate newDate = EGIZDate.parseFromString(oldestNewSignature.getSignatureObject().getSignationDate()); + if (newDate.compareTo(oldDate) <= 0) + { + oldSignature = null; + } + } + } + return oldSignature; + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterParametersImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterParametersImpl.java new file mode 100644 index 0000000..292e816 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterParametersImpl.java @@ -0,0 +1,67 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.vfilter; + +import java.io.Serializable; + +import at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters; + +/** + * @author wprinz + * + */ +public class VerificationFilterParametersImpl implements VerificationFilterParameters, Serializable +{ + /** + * SVUID. + */ + private static final long serialVersionUID = -7118403150485416046L; + + protected boolean extractBinarySignaturesOnly = false; + + protected boolean assumeOnlySignatureUpdateBlocks = false; + + protected boolean scanForOldSignatures = true; + + public VerificationFilterParametersImpl(boolean extractBinarySignaturesOnly, boolean assumeOnlySignatureUpdateBlocks, boolean scanForOldSignatures) + { + this.extractBinarySignaturesOnly = extractBinarySignaturesOnly; + this.assumeOnlySignatureUpdateBlocks = assumeOnlySignatureUpdateBlocks; + this.scanForOldSignatures = scanForOldSignatures; + } + + /** + * @see at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters#extractBinarySignaturesOnly() + */ + public boolean extractBinarySignaturesOnly() + { + return this.extractBinarySignaturesOnly; + } + + /** + * @see at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters#assumeOnlySignatureUpdateBlocks() + */ + public boolean assumeOnlySignatureUpdateBlocks() + { + return this.assumeOnlySignatureUpdateBlocks; + } + + + /** + * @see at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters#scanForOldSignatures() + */ + public boolean scanForOldSignatures() + { + return this.scanForOldSignatures; + } + + /** + * @see java.lang.Object#toString() + */ + // @override + public String toString() + { + return "{VerificationFilterParametersImpl: extractBinarySignaturesOnly = " + extractBinarySignaturesOnly() + ", assumeOnlySignatureUpdateBlocks = " + assumeOnlySignatureUpdateBlocks() + "}"; + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java new file mode 100644 index 0000000..b7f36d1 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java @@ -0,0 +1,152 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.vfilter.helper; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import at.gv.egiz.pdfas.exceptions.ErrorCode; + +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.exceptions.InvalidIDException; +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; +import at.knowcenter.wag.egov.egiz.pdf.BinarySignature; +import at.knowcenter.wag.egov.egiz.pdf.Placeholder; +import at.knowcenter.wag.egov.egiz.pdf.StringInfo; +import at.knowcenter.wag.exactparser.parsing.IndirectObjectReference; +import at.knowcenter.wag.exactparser.parsing.PDFUtils; +import at.knowcenter.wag.exactparser.parsing.results.ArrayParseResult; +import at.knowcenter.wag.exactparser.parsing.results.DictionaryParseResult; +import at.knowcenter.wag.exactparser.parsing.results.FooterParseResult; +import at.knowcenter.wag.exactparser.parsing.results.IndirectObjectReferenceParseResult; +import at.knowcenter.wag.exactparser.parsing.results.NumberParseResult; +import at.knowcenter.wag.exactparser.parsing.results.ObjectParseResult; + +/** + * Contains helpful methods used by the VerificationFilter to analyze the PDF for binary signatures. + * + * @author wprinz + */ +public final class VerificationFilterBinaryHelper +{ + /** + * The name of the egiz dict key. + */ + public static final byte[] EGIZ_DICT_NAME = { 'E', 'G', 'I', 'Z', 'S', 'i', 'g', 'D', 'i', 'c', 't' }; + + /** + * The name of the ID (SIG_KZ) property in the egiz dict. + */ + public static final byte[] EGIZ_KZ_NAME = { 'I', 'D' }; + + /** + * Tells, if the given incremental update block contains a binary signature. + * + *

+ * According to definition, if a block is a binary block, it must/cannot + * contain other signatures than this one. + *

+ * + * @param block + * The incremental update block. + * @return Returns true, if this block is a binary signature block, false + * otherwise. + */ + public static boolean containsEGIZDict(final byte[] pdf, final FooterParseResult block) + { + int dict_index = PDFUtils.indexOfName(pdf, block.tpr.dpr.names, EGIZ_DICT_NAME); + if (dict_index <= 0) + { + return false; + } + + return true; + } + + /** + * Extracts the PDF AS ID of the egiz block. + * + * @param pdf + * The pdf. + * @param block + * The IU block. + * @return Returns the extracted PDF AS ID. + * @throws PDFDocumentException + * Forwarded exception. + * @throws InvalidIDException + * Forwarded exception. + */ + public static PdfASID extractKZFromEGIZBlock(final byte[] pdf, final FooterParseResult block) throws PDFDocumentException, InvalidIDException + { + int egiz_index = PDFUtils.indexOfName(pdf, block.tpr.dpr.names, EGIZ_DICT_NAME); + if (egiz_index < 0) + { + throw new PDFDocumentException(301, "egiz_index = " + egiz_index); + } + + IndirectObjectReferenceParseResult egiz_dict_iorpr = (IndirectObjectReferenceParseResult) block.tpr.dpr.values.get(egiz_index); + // logger_.debug("egiz_dict_ir = " + egiz_dict_iorpr.ior.object_number + // + " " + egiz_dict_iorpr.ior.generation_number); + + IndirectObjectReference ior = egiz_dict_iorpr.ior; + + final int egiz_dict_offset = PDFUtils.getObjectOffsetFromXRefByIndirectObjectReference(block.xpr, ior); + // logger_.debug("egiz_dict_offset = " + egiz_dict_offset); + + ObjectParseResult obj = PDFUtils.parseObject(pdf, egiz_dict_offset); + DictionaryParseResult egiz_dict = (DictionaryParseResult) obj.object; + + int kz_index = PDFUtils.indexOfName(pdf, egiz_dict.names, EGIZ_KZ_NAME); + if (kz_index < 0) + { + throw new PDFDocumentException(301, "kz_index = " + kz_index); + } + ArrayParseResult kz_apr = (ArrayParseResult) egiz_dict.values.get(kz_index); + + String kz_string = restoreKZ(pdf, kz_apr); + PdfASID kz = new PdfASID(kz_string); + + return kz; + } + + /** + * Restores the Kennzeichnung String from an Array. + * + * @param pdf + * The PDF. + * @param kz_apr + * The Array, as parsed from the EGIZ Dict. + * @return Returns the restored KZ. + * @throws PDFDocumentException + * Forwarded exception. + */ + public static String restoreKZ(byte[] pdf, ArrayParseResult kz_apr) throws PDFDocumentException + { + try + { + List partition = new ArrayList(); + + for (int i = 0; i < kz_apr.elements.size() / 2; i++) + { + NumberParseResult start_npr = (NumberParseResult) kz_apr.elements.get(i * 2); + NumberParseResult length_npr = (NumberParseResult) kz_apr.elements.get(i * 2 + 1); + + StringInfo si = new StringInfo(); + si.string_start = start_npr.number; + si.string_length = length_npr.number; + + partition.add(si); + } + + String KZ = Placeholder.reconstructStringFromPartition(pdf, partition, BinarySignature.ENCODING_WIN); + return KZ; + } + catch (IOException e1) + { + throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e1); + } + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterHelper.java b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterHelper.java new file mode 100644 index 0000000..67af129 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterHelper.java @@ -0,0 +1,142 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.vfilter.helper; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import at.gv.egiz.pdfas.exceptions.framework.VerificationFilterException; +import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper; +import at.gv.egiz.pdfas.impl.vfilter.Partition; +import at.gv.egiz.pdfas.impl.vfilter.partition.BinaryPartition; +import at.gv.egiz.pdfas.impl.vfilter.partition.TextPartition; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.knowcenter.wag.exactparser.parsing.results.FooterParseResult; + +/** + * Contains helpful methods used by the VerificationFilter. + * + * @author wprinz + */ +public final class VerificationFilterHelper +{ + /** + * Partitions the list of Incremental Update blocks into text and binary + * partitions. + * + *

+ * A partition is a sequence of Incremental Update blocks of the same type. + *

+ *

+ * An Incremental Update block is considered to have the type "binary" if it + * contains an egiz dictionary. A block not containing an egiz dictionary is + * considert to have the type "text". + *

+ * + * @param pdf + * The PDF. + * @param blocks + * The Incremental Update blocks. + * @return Returns the partitioning of the blocks. + * @throws VerificationFilterException + * Thrown if something goes wrong. + */ + public static List partition(PdfDataSource pdf, List blocks) throws VerificationFilterException + { + List partitions = new ArrayList(blocks.size()); + + Iterator it = blocks.iterator(); + while (it.hasNext()) + { + FooterParseResult fpr = (FooterParseResult) it.next(); + + byte[] data = DataSourceHelper.convertDataSourceToByteArray(pdf); + if (VerificationFilterBinaryHelper.containsEGIZDict(data, fpr)) + { + BinaryPartition bp = null; + if (partitions.isEmpty() || ((Partition) partitions.get(partitions.size() - 1)).isTextPartition()) + { + bp = new BinaryPartition(); + bp.blocks = new ArrayList(blocks.size()); + partitions.add(bp); + } + else + { + bp = (BinaryPartition) partitions.get(partitions.size() - 1); + } + assert bp != null; + + bp.blocks.add(fpr); + } + else + { + TextPartition tp = null; + if (partitions.isEmpty() || !((Partition) partitions.get(partitions.size() - 1)).isTextPartition()) + { + tp = new TextPartition(); + tp.blocks = new ArrayList(blocks.size()); + partitions.add(tp); + } + else + { + tp = (TextPartition) partitions.get(partitions.size() - 1); + } + assert tp != null; + + tp.blocks.add(fpr); + } + } + + assert partitions.size() >= 1 : "There must be at least one partition"; + + return partitions; + } + + /** + * Determines the end of the given partiton. + * + * @param partition + * The partition. + * @return Returns the end index of the given partition. + */ + public static int getEndOfPartition(Partition partition) + { + List blocks = null; + if (partition instanceof TextPartition) + { + blocks = ((TextPartition) partition).blocks; + } + else + { + blocks = ((BinaryPartition) partition).blocks; + } + + return ((FooterParseResult) blocks.get(blocks.size() - 1)).next_index; + } + + /** + * Finds the last text partition in the given list of partitions. + * + * @param partitions + * The partitions. + * @return Returns the last TextPartition. + */ + public static TextPartition findLastTextPartition(List partitions) + { + Partition lastTextPartition = (Partition) partitions.get(partitions.size() - 1); + + if (!lastTextPartition.isTextPartition()) + { + assert partitions.size() > 1 : "The only one partition cannot be a binary partition - where is the original document?"; + Partition previousToLastPartition = (Partition) partitions.get(partitions.size() - 2); + assert previousToLastPartition.isTextPartition() : "The previous to last partition must be a text partition or something is wrong with the partitioning algorithm."; + + lastTextPartition = previousToLastPartition; + } + + return (TextPartition) lastTextPartition; + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterTextHelper.java b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterTextHelper.java new file mode 100644 index 0000000..f9a79b0 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterTextHelper.java @@ -0,0 +1,15 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.vfilter.helper; + +/** + * Contains helpful methods used by the VerificationFilter to analyze text and + * find text signatures. + * + * @author wprinz + */ +public final class VerificationFilterTextHelper +{ + +} diff --git a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/partition/BinaryPartition.java b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/partition/BinaryPartition.java new file mode 100644 index 0000000..520f3b1 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/partition/BinaryPartition.java @@ -0,0 +1,19 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.vfilter.partition; + +import java.util.List; + +import at.gv.egiz.pdfas.impl.vfilter.Partition; + + +public class BinaryPartition implements Partition +{ + public List blocks = null; + + public boolean isTextPartition() + { + return false; + } +} \ No newline at end of file diff --git a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/partition/TextPartition.java b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/partition/TextPartition.java new file mode 100644 index 0000000..bf17633 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/partition/TextPartition.java @@ -0,0 +1,20 @@ +/** + * + */ +package at.gv.egiz.pdfas.impl.vfilter.partition; + +import java.util.List; + +import at.gv.egiz.pdfas.impl.vfilter.Partition; + + +public class TextPartition implements Partition +{ + public List blocks = null; + + public boolean isTextPartition() + { + return true; + } + +} \ No newline at end of file diff --git a/src/main/java/at/gv/egiz/pdfas/performance/PerformanceCounter.java b/src/main/java/at/gv/egiz/pdfas/performance/PerformanceCounter.java new file mode 100644 index 0000000..2d9b461 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/performance/PerformanceCounter.java @@ -0,0 +1,62 @@ +/** + * + */ +package at.gv.egiz.pdfas.performance; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * @author wprinz + */ +public class PerformanceCounter +{ + /** + * The log. + */ + private static Log log = LogFactory.getLog(PerformanceCounter.class); + + protected String name = null; + + protected long counter = 0; + + public PerformanceCounter(String name) + { + this.name = name; + reset(); + } + + public PerformanceCounter(Class clazz) + { + this(clazz.getName()); + } + + public void increment() + { + this.counter++; + log.trace(this.name + ": incremented to " + this.counter); + } + + public void reset() + { + this.counter = 0; + log.trace(this.name + ": reset to 0"); + } + + /** + * @return the name + */ + public String getName() + { + return this.name; + } + + /** + * @return the counter + */ + public long getCounter() + { + return this.counter; + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/performance/PerformanceCounters.java b/src/main/java/at/gv/egiz/pdfas/performance/PerformanceCounters.java new file mode 100644 index 0000000..6251c55 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/performance/PerformanceCounters.java @@ -0,0 +1,22 @@ +/** + * + */ +package at.gv.egiz.pdfas.performance; + +/** + * Contains various global PerformanceCounters that provide information about the system. + * + * @author wprinz + */ +public final class PerformanceCounters +{ + /** + * Keeps track of the number of text extractions done so far. + */ + public static PerformanceCounter textExtractions = new PerformanceCounter("TextExtractions"); + + /** + * Keeps track of the number of large byte array allocations. + */ + public static PerformanceCounter byteArrays = new PerformanceCounter("ByteArrays"); +} diff --git a/src/main/java/at/gv/egiz/pdfas/performance/PerformanceTimer.java b/src/main/java/at/gv/egiz/pdfas/performance/PerformanceTimer.java new file mode 100644 index 0000000..6ebb9be --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/performance/PerformanceTimer.java @@ -0,0 +1,48 @@ +/** + * + */ +package at.gv.egiz.pdfas.performance; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * @author wprinz + * + */ +public class PerformanceTimer +{ + /** + * The log. + */ + private static Log log = LogFactory.getLog(PerformanceTimer.class); + + protected String name = null; + + protected long startTime = -1; + + protected long stopTime = -1; + + public PerformanceTimer(String name) + { + this.name = name; + } + + public void start() + { + this.startTime = System.currentTimeMillis(); + log.trace(this.name + ": started at " + this.startTime); + } + + public void stop() + { + this.stopTime = System.currentTimeMillis(); + log.trace(this.name + ": stopped at " + this.stopTime); + log.trace(this.name + ": time elapsed = " + getTimeElapsed()); + } + + public long getTimeElapsed() + { + return this.stopTime - this.startTime; + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/utils/DataHashUtils.java b/src/main/java/at/gv/egiz/pdfas/utils/DataHashUtils.java new file mode 100644 index 0000000..19d7b33 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/utils/DataHashUtils.java @@ -0,0 +1,136 @@ +/** + * + */ +package at.gv.egiz.pdfas.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.security.DigestInputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import org.apache.commons.codec.binary.Base64; + +import at.knowcenter.wag.egov.egiz.pdf.BinarySignatureHolder; +import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; +import at.knowcenter.wag.egov.egiz.pdf.TextualSignatureHolder; + +/** + * Contains helpful methods for building data hashed. + * + *

+ * Data hashes are useful for summarizing the signed data of signatures for + * debugging and testing purposes. Do not use these hashes for signatures. + *

+ *

+ * A data hash is always a Base64 encoded String. + *

+ * + * @author wprinz + * + */ +public final class DataHashUtils +{ + + /** + * + * @param text + * @return + */ + public static String buildDataHash(String text) + { + try + { + MessageDigest md = getMessageDigest(); + // probable performance leak for very large texts + md.update(text.getBytes("UTF-8")); + byte[] rawDigest = md.digest(); + + return encodeDigest(rawDigest); + } + catch (UnsupportedEncodingException e) + { + throw new RuntimeException(e); + } + } + + public static String buildDataHash(byte[] data) + { + MessageDigest md = getMessageDigest(); + md.update(data); + byte[] rawDigest = md.digest(); + + return encodeDigest(rawDigest); + } + + public static String buildDataHash(InputStream is) + { + try + { + MessageDigest md = getMessageDigest(); + + DigestInputStream dis = new DigestInputStream(is, md); + + byte[] temp = new byte[1024]; + int i = 0; + while (dis.read(temp) >= 0) + { + // this just keeps the compiler from optimizing this loop away + i++; + } + dis.close(); + + byte[] rawDigest = md.digest(); + + return encodeDigest(rawDigest); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + + public static String buildDataHash(SignatureHolder sh) + { + if (sh instanceof TextualSignatureHolder) + { + TextualSignatureHolder tsh = (TextualSignatureHolder) sh; + String signedText = tsh.getSignedText(); + return buildDataHash(signedText); + } + + { + BinarySignatureHolder bsh = (BinarySignatureHolder) sh; + InputStream is = bsh.getSignedPdf().createInputStream(); + return buildDataHash(is); + } + } + + protected static MessageDigest getMessageDigest() + { + try + { + MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); + return sha1; + } + catch (NoSuchAlgorithmException e) + { + throw new RuntimeException(e); + } + } + + protected static String encodeDigest(byte[] rawDigest) + { + try + { + byte[] encoded = Base64.encodeBase64(rawDigest); + String str = new String(encoded, "US-ASCII"); + return str; + } + catch (UnsupportedEncodingException e) + { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/utils/StreamUtils.java b/src/main/java/at/gv/egiz/pdfas/utils/StreamUtils.java new file mode 100644 index 0000000..acf7e75 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/utils/StreamUtils.java @@ -0,0 +1,42 @@ +package at.gv.egiz.pdfas.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class StreamUtils +{ + + public static void writeInputStreamToOutputStream (InputStream is, OutputStream os) throws IOException + { + byte [] buffer = new byte [2048]; + + int read = -1; + while ((read = is.read(buffer)) > 0) + { + os.write(buffer, 0, read); + } + is.close(); + os.close(); + } + + // The InputStream should be self- delimited. +// public static void writeInputStreamToOutputStream(InputStream is, OutputStream os, int length) throws IOException +// { +// byte [] buffer = new byte [2048]; +// +// int bytes_to_write = length; +// +// int read = -1; +// while ((read = is.read(buffer, 0, (bytes_to_write >= buffer.length) ? buffer.length : bytes_to_write)) > 0) +// { +// os.write(buffer, 0, read); +// bytes_to_write -= read; +// } +// is.close(); +// os.close(); +// +// assert bytes_to_write == 0; +// } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/web/CurrentLocalOperation.java b/src/main/java/at/gv/egiz/pdfas/web/CurrentLocalOperation.java new file mode 100644 index 0000000..83d214c --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/web/CurrentLocalOperation.java @@ -0,0 +1,87 @@ +/** + * + */ +package at.gv.egiz.pdfas.web; + +import java.util.List; +import java.util.Properties; + +import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; +import at.knowcenter.wag.egov.egiz.web.LocalRequest; + +/** + * Encapsulates a local operation. + * + *

+ * A local operation is a sequence of successive local verifications. + *

+ *

+ * This is held on the VerifySessionInformation so that the DataURLServlet and RetrieveSignatureDataServlet + * can provide their data to the local service easily. + *

+ * + * @author wprinz + */ +public class CurrentLocalOperation +{ + + /** + * The signature holders to be verified in the current local operation. + */ + public List holders_to_be_verified; + + + /** + * An array of local requests to be processed. + */ + public LocalRequest[] requests = null; + + /** + * An array of response strings of the local requests. + */ + public Properties[] response_properties = null; + + /** + * The index of the holder/request to be processed. + */ + public int current_operation = 0; + +// /** +// * Tells, if the current local request has been finished. +// */ +// public boolean finished = false; + + /** + * @see at.gv.egiz.pdfas.web.LocalOperation#isFinished() + */ + public boolean isFinished() + { + return this.current_operation >= this.requests.length; + } + + /** + * @see at.gv.egiz.pdfas.web.LocalOperation#getCurrentLocalRequest() + */ + public LocalRequest getCurrentLocalRequest() + { + return this.requests[this.current_operation]; + } + + /** + * @see at.gv.egiz.pdfas.web.LocalOperation#getCurrentSignatureHolder() + */ + public SignatureHolder getCurrentSignatureHolder() + { + return (SignatureHolder) this.holders_to_be_verified.get(this.current_operation); + } + + /** + * @see at.gv.egiz.pdfas.web.LocalOperation#finishCurrentOperation(java.util.Properties) + */ + public void finishCurrentOperation(Properties response_properties) + { + this.response_properties[this.current_operation] = response_properties; + + this.current_operation++; + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/web/SignSessionInformation.java b/src/main/java/at/gv/egiz/pdfas/web/SignSessionInformation.java new file mode 100644 index 0000000..459a104 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/web/SignSessionInformation.java @@ -0,0 +1,140 @@ +/** + * + */ +package at.gv.egiz.pdfas.web; + +import java.io.Serializable; +import java.util.Properties; + +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; + +import at.gv.egiz.pdfas.impl.input.FileBasedPdfDataSourceImpl; +import at.gv.egiz.pdfas.impl.output.FileBasedDataSink; +import at.gv.egiz.pdfas.web.helper.TempDirHelper; +import at.gv.egiz.pdfas.framework.signator.SignatorInformation; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.knowcenter.wag.egov.egiz.pdf.TablePos; +import at.knowcenter.wag.egov.egiz.web.ExternAppInformation; +import at.knowcenter.wag.egov.egiz.web.LocalRequest; + +/** + * @author wprinz + * + */ +public class SignSessionInformation implements HttpSessionBindingListener, Serializable +{ + /** + * SVUID. + */ + private static final long serialVersionUID = 2739944460007369626L; + + /** + * The log. + */ + private static Log log = LogFactory.getLog(SignSessionInformation.class); + + /** + * The connector. + */ + public String connector = null; + + /** + * For local requests, tells the application (sign, verify). + */ + public String application = null; + + /** + * Tells the operation mode (binary, textual). + */ + public String mode = null; + + /** + * The original, uploaded pdf. + */ + public FileBasedPdfDataSourceImpl pdfDataSource = null; + + /** + * The type/profile of the signature. + */ + public String type = null; + + /** + * The suggested filename. + */ + public String filename; + + /** + * Tells, if the file download should be done inline or as attachment. + */ + public boolean download_inline; + + /** + * Object containing information about the calling webapplication. + * + * @author: Thomas Zefferer + */ + public ExternAppInformation exappinf; + + /** + * Information about the signature position + * + * @author: Thomas Zefferer + */ + public TablePos pos; + + /** + * The SignatorInformation. + */ + public SignatorInformation si = null; + + /** + * The DataSink to write the output data to. + */ + public FileBasedDataSink output = null; + + /** + * The local request to be sent to the device. + */ + public LocalRequest localRequest = null; + + /** + * The response properties of the local request. + */ + public Properties response_properties = null; + + /** + * Tells if the sign request has been processed and the signed document is + * available in the DataSink. + */ + public boolean outputAvailable = false; + + + /** + * @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent) + */ + public void valueBound(HttpSessionBindingEvent event) + { + log.debug("Bound SignSessionInformation to session."); + } + + /** + * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent) + */ + public void valueUnbound(HttpSessionBindingEvent event) + { + log.debug("Unbound SignSessionInformation from session."); + + if (this.pdfDataSource != null) + { + TempDirHelper.deleteDataSourceIfFileBased(this.pdfDataSource); + } + if (this.output != null) + { + TempDirHelper.deleteDataSinkIfFileBased(this.output); + } + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/web/VerifySessionInformation.java b/src/main/java/at/gv/egiz/pdfas/web/VerifySessionInformation.java new file mode 100644 index 0000000..e998ded --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/web/VerifySessionInformation.java @@ -0,0 +1,195 @@ +/** + * Copyright (c) 2006 by Know-Center, Graz, Austria + * + * This software is the confidential and proprietary information of Know-Center, + * Graz, Austria. You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Know-Center. + * + * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF + * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY + * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. + * + * $Id: SessionInformation.java,v 1.2 2006/08/25 17:06:11 wprinz Exp $ + */ +package at.gv.egiz.pdfas.web; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.web.helper.TempDirHelper; +import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; +import at.knowcenter.wag.egov.egiz.pdf.TablePos; +import at.knowcenter.wag.egov.egiz.web.ExternAppInformation; + +/** + * This class is a collection of various session parameters that are passed + * between the servlets and jsps. + * + *

+ * The SessionInformation class contains type safe references to the objects. + *

+ * + * @author wprinz + */ +public class VerifySessionInformation implements HttpSessionBindingListener, Serializable +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = -7413884936584659150L; + + /** + * The log. + */ + private static Log log = LogFactory.getLog(VerifySessionInformation.class); + + /** + * The connector. + */ + public String connector = null; + + /** + * For local requests, tells the application (sign, verify). + */ + public String application = null; + + /** + * Tells the operation mode (binary, textual). + */ + public String mode = null; + + /** + * The original, uploaded pdf. + */ + //public FileBasedPdfDataSourceImpl pdfDataSource = null; + public DataSource inputDataSource = null; + + /** + * The type/profile of the signature. + */ + public String type = null; + +// /** +// * The user name. +// */ +// public String user_name = null; +// +// /** +// * The password. +// */ +// public String user_password = null; + + /** + * All SignatureHolders extracted from the document. + */ + public List signature_holders; + + /** + * Keeps track of the currently running local operation. + * + *

+ * Only valid during local verify. + *

+ */ + public CurrentLocalOperation currentLocalOperation = null; + + /** + * This is used only for MOA loc-ref web verify. + */ + public SignatureHolder moa_holder; + + +// /** +// * The incremental update information that has been extracted from the given +// * PDF document. +// */ +// public IncrementalUpdateInformation iui; + +// public SignatorInformation si = null; + +// public FileBasedDataSink output = null; + + +// /** +// * Copy of signature holders. It's needed by BKU when we try to verify single by single +// * signature. +// */ +// public List copy_of_signature_holders; + +// /** +// * The suggested filename. +// */ +// public String filename; +// +// /** +// * Tells, if the file download should be done inline or as attachment. +// */ +// public boolean download_inline; + +//// /** +//// * The sign result to be passed back to the user. +//// */ +//// public SignResult sign_result; +// +// public boolean isSignFinished = false; + + + + /** + * Object containing information about the calling webapplication. + * @author: Thomas Zefferer + */ + public ExternAppInformation exappinf; + + /** + * Information about the signature position + * @author: Thomas Zefferer + */ + public TablePos pos ; + + + + /** + * @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent) + */ + public void valueBound(HttpSessionBindingEvent event) + { + log.debug("Bound SignSessionInformation to session."); + } + + /** + * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent) + */ + public void valueUnbound(HttpSessionBindingEvent event) + { + log.debug("Unbound SignSessionInformation from session."); + + if (this.inputDataSource != null) + { + TempDirHelper.deleteDataSourceIfFileBased(this.inputDataSource); + } + if (this.signature_holders != null) + { + Iterator it = this.signature_holders.iterator(); + while (it.hasNext()) + { + SignatureHolder sh = (SignatureHolder) it.next(); + TempDirHelper.deleteDataSourceIfFileBased(sh.getDataSource()); + } + } + } + +} diff --git a/src/main/java/at/gv/egiz/pdfas/web/helper/SessionHelper.java b/src/main/java/at/gv/egiz/pdfas/web/helper/SessionHelper.java new file mode 100644 index 0000000..5752838 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/web/helper/SessionHelper.java @@ -0,0 +1,48 @@ +/** + * + */ +package at.gv.egiz.pdfas.web.helper; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.exceptions.web.SessionExpiredException; +import at.knowcenter.wag.egov.egiz.web.SessionAttributes; + +/** + * @author wprinz + * + */ +public class SessionHelper +{ + /** + * The log. + */ + private static Log log = LogFactory.getLog(SessionHelper.class); + + public static Object getSession(HttpServletRequest request) throws SessionExpiredException + { + + HttpSession session = request.getSession(false); + if (session == null) + { + String msg = "There is no session associated with this request."; //$NON-NLS-1$ + log.error(msg); + throw new SessionExpiredException(msg); + } + + Object sessionObject = session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); + if (sessionObject == null) + { + String msg = "The session is not found or no longer valid."; //$NON-NLS-1$ + log.error(msg); + throw new SessionExpiredException(msg); + } + + return sessionObject; + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java b/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java new file mode 100644 index 0000000..55e0051 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java @@ -0,0 +1,229 @@ +/** + * + */ +package at.gv.egiz.pdfas.web.helper; + +import java.io.IOException; +import java.net.URL; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.framework.SignatorFactory; +import at.gv.egiz.pdfas.framework.signator.Signator; +import at.gv.egiz.pdfas.web.SignSessionInformation; +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; +import at.knowcenter.wag.egov.egiz.framework.signators.DetachedSignator_1_0_0; +import at.knowcenter.wag.egov.egiz.sig.ConnectorFactory; +import at.knowcenter.wag.egov.egiz.sig.connectors.Connector; +import at.knowcenter.wag.egov.egiz.sig.connectors.ConnectorChooser; +import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject; +import at.knowcenter.wag.egov.egiz.web.FormFields; +import at.knowcenter.wag.egov.egiz.web.LocalRequestHelper; + +/** + * @author wprinz + * + */ +public class SignServletHelper +{ + /** + * The log. + */ + private static Log log = LogFactory.getLog(SignServletHelper.class); + + protected static void dispatch(HttpServletRequest request, HttpServletResponse response, String resource, ServletContext context) throws ServletException, IOException + { + response.setContentType("text/html"); + response.setCharacterEncoding("UTF-8"); + + RequestDispatcher disp = context.getRequestDispatcher(resource); + disp.forward(request, response); + } + + + /** + * Prepares the sign. + * + *

+ * This prepares the data for both being signed or being previewed. + *

+ * + * @param si + * The SessionInformation to be prepared. + * @throws PresentableException + * f.e. + */ + public static void prepareSign(SignSessionInformation si) throws PresentableException + { + log.debug("prepareSign:"); //$NON-NLS-1$ + + PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); + Signator signator = SignatorFactory.createSignator(algorithm); + + // tzefferer: modified + // si.iui = signator.prepareSign(si.pdf, si.type, null, + // ConnectorFactory.needsSIG_ID(si.connector)); + si.si = signator.prepareSign(si.pdfDataSource, si.type, si.pos, ConnectorFactory.needsSIG_ID(si.connector)); + // end modify + log.debug("prepareSign finished."); //$NON-NLS-1$ + } + + /** + * Finishes the sign. + * + *

+ * For non local connectors this concludes the sign process, signs the + * document and returns the result. For local connectors this initializes the + * local sign process and redirects to following servlets. + *

+ * + * @param si + * The SessionInformation. + * @param request + * The servlet request for dispatching. + * @param response + * The servlet response for dispatching. + * @param context + * The servlet context for dispatching. + * @throws PresentableException + * f.e. + * @throws IOException + * f. e. + * @throws ServletException + * f. e. + */ + public static void finishSign(SignSessionInformation si, HttpServletRequest request, HttpServletResponse response, ServletContext context) throws PresentableException, IOException, ServletException + { + log.debug("finishSign:"); //$NON-NLS-1$ + + log.debug("connector = " + si.connector); //$NON-NLS-1$ + if (ConnectorFactory.isConnectorLocal(si.connector)) + { + log.debug("Connector is local -> dispatching to local processing."); //$NON-NLS-1$ + + String dispatch_to = LocalRequestHelper.processLocalSign(si, request, response); + dispatch(request, response, dispatch_to, context); + return; + } + log.debug("Connector is not local -> finishing the sign."); //$NON-NLS-1$ + + PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); + Signator signator = SignatorFactory.createSignator(algorithm); + + log.debug("RequestURL = " + request.getRequestURL()); + log.debug("ContextPath = " + request.getContextPath()); + String host = request.getServerName(); + URL signature_data_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/RetrieveSignatureData"); + String signature_data_url = response.encodeURL(signature_data_URL.toString()); + + Connector c = ConnectorChooser.chooseWebConnectorForSign(si.connector, si.type, signature_data_url); + SignSignatureObject signSignatureObject = c.doSign(si.si.getSignatureData()); + + si.si.setSignSignatureObject(signSignatureObject); + + si.output = TempDirHelper.createTempDataSink(si.filename + "_signed.pdf"); + signator.finishSign(si.si, si.output); + + returnSignResponse(si, response); + + log.debug("finishSign finished."); //$NON-NLS-1$ + } + + /** + * Returns the data in the SignResult with proper content disposition. + * + * @param si + * SessionInformation. + * @param response + * The servlet response. + * @throws IOException + * The IO Exception. + */ + public static void returnSignResponse(SignSessionInformation si, HttpServletResponse response) throws IOException + { +// SignResult sign_result = si.sign_result; + + String file_name = formatFileNameForSignResult(si.filename, si.output.getMimeType()); + + // tzefferer: added condition + if (si.exappinf == null) + { + + // The name parameter is actually deprecated in favour of + // Content-Disposition filename + // Unfortunately Acrobat reader does recognize neither of these parameters + // with its inline save-as. It always takes the page name. + response.setContentType(si.output.getMimeType() + "; name=\"" + file_name + "\""); + if (si.download_inline) + { + response.addHeader("Content-Disposition", "inline; filename=\"" + file_name + "\""); + } + else + { + response.addHeader("Content-Disposition", "attachment; filename=\"" + file_name + "\""); + } + + TempDirHelper.writeDataSinkToHttpResponse(si.output, response); + //response.getOutputStream().write(sign_result.getData()); + + // tzefferer: added else-block + } + else + { + // TODO @tzefferer: what is this code? + throw new RuntimeException("This has to be refactored."); +// SignResult sr = si.sign_result; +// byte[] signed_pdf = sr.getData(); +// PDFContainer entry = new PDFContainer(signed_pdf, si.exappinf.pdf_id); +// ProvidePDFServlet.signedDocuments.add(entry); +// +// // notify webapp... +// String invoke_url = si.exappinf.invoke_url; +// +// String providePDFServlet = "ProvidePDF"; +// String pdf_id = String.valueOf(si.exappinf.pdf_id); +// String session_id = si.exappinf.session_id; +// +// // build URL +// int ind = invoke_url.indexOf("?"); +// String query = invoke_url.substring(0, ind) + ";jsessionid=" + session_id + invoke_url.substring(ind) + "&" + FormFields.FIELD_PDF_URL + "=" + providePDFServlet + "&" + FormFields.FIELD_PDF_ID +// + "=" + pdf_id + "&" + FormFields.FIELD_FILE_LENGTH + "=" + signed_pdf.length; +// +// response.sendRedirect(query); + + } + + } + + /** + * Formats the file name according to the SignResult. + * + * @param file_name + * The file name. + * @param sign_result + * The sign result. + * @return Returns the formatted file name. + */ + public static String formatFileNameForSignResult(String file_name, String mimeType) + { + String output = file_name + "_signed"; + if (mimeType.equals(DetachedSignator_1_0_0.MIME_TYPE)) + { + output += ".xml"; + } + else + { + output += ".pdf"; + } + + return output; + } +} diff --git a/src/main/java/at/gv/egiz/pdfas/web/helper/TempDirHelper.java b/src/main/java/at/gv/egiz/pdfas/web/helper/TempDirHelper.java new file mode 100644 index 0000000..9f2b6fb --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/web/helper/TempDirHelper.java @@ -0,0 +1,242 @@ +/** + * + */ +package at.gv.egiz.pdfas.web.helper; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.TextDataSource; +import at.gv.egiz.pdfas.framework.output.DataSink; +import at.gv.egiz.pdfas.impl.input.FileBased; +import at.gv.egiz.pdfas.impl.input.FileBasedPdfDataSourceImpl; +import at.gv.egiz.pdfas.impl.input.FileBasedTextDataSourceImpl; +import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl; +import at.gv.egiz.pdfas.impl.output.FileBasedDataSink; +import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; +import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; +import at.knowcenter.wag.egov.egiz.pdf.TextualSignatureHolder; + +/** + * @author wprinz + * + */ +public class TempDirHelper +{ + /** + * The log. + */ + private static Log log = LogFactory.getLog(TempDirHelper.class); + + protected static long runningIndex = 0; + + public static void storeTextSignatureHoldersIfApplicable(List shs, String fileNameSuffix) throws IOException + { + Iterator it = shs.iterator(); + while (it.hasNext()) + { + SignatureHolder sh = (SignatureHolder) it.next(); + if (sh instanceof TextualSignatureHolder) + { + TextualSignatureHolder tsh = (TextualSignatureHolder) sh; + if (!(tsh.getDataSource() instanceof FileBased)) + { + TextDataSource tds = (TextDataSource) tsh.getDataSource(); + if (isReasonableToStore(tds.getText().length())) + { + TextDataSource fbtds = placeTextIntoTempDir(tds.getText(), fileNameSuffix); + tsh.exchangeDataSource(fbtds); + } + } + } + } + } + + /** + * Places the text into the temp dir if reasonable. + * + *

+ * Reasonable means that the text is longer than a certain threshold. + * Otherwise a short text is simply held in memory. + *

+ * + * @param text + * The text to be stored. + * @param fileNameSuffix + * A file name suffix so that the temp file gets a more "readable" + * name. + * @return Returns the TextDataSource. + * @throws IOException + * F.e. + */ + public static TextDataSource placeTextIntoTempDir(String text, String fileNameSuffix) throws IOException + { + if (isReasonableToStore(text.length())) + { + String fileName = formatFileName(fileNameSuffix); + + File tmpFile = createTempFileInDir(fileName); + + FileOutputStream fos = new FileOutputStream(tmpFile); + OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); + osw.write(text); + osw.close(); + + FileBasedTextDataSourceImpl textDataSource = new FileBasedTextDataSourceImpl(tmpFile, "UTF-8"); + return textDataSource; + } + else + { + return new TextDataSourceImpl(text); + } + } + + /** + * Tells, if it is reasonable to store the text of the given length onto the + * disk. + * + * @param textLength + * The length of the text under question. + * @return Returns true if the text should be stored on the disk. + */ + public static boolean isReasonableToStore(int textLength) + { + return textLength >= 10000; + } + + public static FileBasedPdfDataSourceImpl placePdfIntoTempDir(InputStream pdfInput, String fileNameSuffix) throws IOException + { + File pdfFile = placeInputIntoTempDirFile(pdfInput, fileNameSuffix); + + FileBasedPdfDataSourceImpl pdfDataSource = new FileBasedPdfDataSourceImpl(pdfFile, (int) pdfFile.length()); + return pdfDataSource; + } + + protected static File placeInputIntoTempDirFile(InputStream input, String fileNameSuffix) throws IOException + { + String fileName = formatFileName(fileNameSuffix); + + File tmpFile = createTempFileInDir(fileName); + + FileOutputStream fos = new FileOutputStream(tmpFile); + + byte[] buffer = new byte[2048]; + int read = -1; + while ((read = input.read(buffer)) > 0) + { + fos.write(buffer, 0, read); + } + fos.close(); + input.close(); + + return tmpFile; + } + + protected static String formatFileName(String fileNameSuffix) + { + String fileName = "tmp" + formatIndex(runningIndex) + "_" + fileNameSuffix; + runningIndex++; + + return fileName; + } + + protected static String formatIndex(long index) + { + NumberFormat nf = new DecimalFormat("00000000"); + + return nf.format(index); + } + + protected static File createTempFileInDir(String fileName) throws IOException + { + File tempDir = new File(new File(SettingsReader.RESOURCES_PATH), "pdfastmp"); + + File tmpFile = new File(tempDir, fileName); + + tmpFile.createNewFile(); + + tmpFile.deleteOnExit(); + + return tmpFile; + } + + public static FileBasedDataSink createTempDataSink(String fileNameSuffix) throws IOException + { + String fileName = formatFileName(fileNameSuffix); + + File tmpFile = createTempFileInDir(fileName); + + FileBasedDataSink fbds = new FileBasedDataSink(tmpFile); + + return fbds; + } + + public static void writeDataSinkToHttpResponse(FileBasedDataSink fbds, HttpServletResponse response) throws IOException + { + + response.setContentType(fbds.getMimeType()); + response.setCharacterEncoding(fbds.getCharacterEncoding()); + + OutputStream os = response.getOutputStream(); + + byte[] buffer = new byte[2048]; + FileInputStream fis = new FileInputStream(fbds.getFile()); + int n = -1; + while ((n = fis.read(buffer)) > 0) + { + os.write(buffer, 0, n); + } + fis.close(); + os.close(); + } + + /** + * Deletes the underlying file of the FileBased DataSource. + * + *

+ * If the DataSource is not FileBased, nothing is done. + *

+ *

+ * This is usually used by the application to delete temporary files. + *

+ * + * @param dataSource + */ + public static void deleteDataSourceIfFileBased(DataSource dataSource) + { + if (dataSource instanceof FileBased) + { + FileBased fb = (FileBased) dataSource; + log.debug("Deleting temp file " + fb.getFile()); + boolean deleted = fb.getFile().delete(); + log.debug("deleted = " + deleted); + } + } + + public static void deleteDataSinkIfFileBased(DataSink dataSink) + { + if (dataSink instanceof FileBased) + { + FileBased fb = (FileBased) dataSink; + log.debug("Deleting temp file " + fb.getFile()); + boolean deleted = fb.getFile().delete(); + log.debug("deleted = " + deleted); + } + } + +} diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java index 0576781..e2505ea 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java @@ -19,19 +19,31 @@ package at.knowcenter.wag.egov.egiz; import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Array; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Vector; +import at.gv.egiz.pdfas.commandline.CommandlineConnectorChooser; +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.gv.egiz.pdfas.impl.input.DelimitedInputStream; +import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl; +import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.input.TextDataSource; +import at.gv.egiz.pdfas.framework.output.DataSink; +import at.gv.egiz.pdfas.framework.signator.SignatorInformation; +import at.gv.egiz.pdfas.web.VerifySessionInformation; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorFactoryException; import at.knowcenter.wag.egov.egiz.exceptions.NormalizeException; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; @@ -40,11 +52,7 @@ import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; import at.knowcenter.wag.egov.egiz.exceptions.SignatureTypesException; import at.knowcenter.wag.egov.egiz.framework.FoundBlock; import at.knowcenter.wag.egov.egiz.framework.FoundKey; -import at.knowcenter.wag.egov.egiz.framework.SignResult; -import at.knowcenter.wag.egov.egiz.framework.Signator; -import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; -import at.knowcenter.wag.egov.egiz.framework.VerificationFilter; -import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation; +import at.knowcenter.wag.egov.egiz.pdf.BinarySignatureHolder; import at.knowcenter.wag.egov.egiz.pdf.PDFSignatureCreation; import at.knowcenter.wag.egov.egiz.pdf.PDFSignatureObject; import at.knowcenter.wag.egov.egiz.pdf.PDFUtilities; @@ -64,9 +72,7 @@ import at.knowcenter.wag.egov.egiz.sig.connectors.Connector; import at.knowcenter.wag.egov.egiz.sig.connectors.ConnectorChooser; import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject; import at.knowcenter.wag.egov.egiz.sig.signatureobject.SignatureObjectHelper; -import at.knowcenter.wag.egov.egiz.tools.CodingHelper; import at.knowcenter.wag.egov.egiz.tools.Normalizer; -import at.knowcenter.wag.egov.egiz.web.SessionInformation; import at.knowcenter.wag.exactparser.ParseDocument; import at.knowcenter.wag.exactparser.parsing.PDFUtils; import at.knowcenter.wag.exactparser.parsing.results.HeaderParseResult; @@ -135,17 +141,26 @@ public abstract class PdfAS /** * Checks the version of the given PDF to be 1.4 or lower. * - * @param pdf + *

+ * This scans the first 1000 bytes of the PDF for the pdf Header. + *

+ * + * @param pdfDataSource * The PDF. * @return Returns true, if the given PDF is strict 1.4, false otherwise. * @throws PDFDocumentException * Forwarded exception. */ - public static boolean isPdf14(byte[] pdf) throws PDFDocumentException + public static boolean isPdf14(PdfDataSource pdfDataSource) throws PDFDocumentException { try { - HeaderParseResult hpr = PDFUtils.parseHeader(pdf, 0); + byte[] firstBytes = new byte[1000]; + InputStream is = pdfDataSource.createInputStream(); + is.read(firstBytes); + is.close(); + + HeaderParseResult hpr = PDFUtils.parseHeader(firstBytes, 0); if (hpr.major <= 1 && hpr.minor <= 4) { @@ -168,21 +183,22 @@ public abstract class PdfAS * parsability. *

* - * @param pdf + * @param pdfDataSource * The pdf to be checked against strict mode. * @throws PDFDocumentException */ - public static void applyStrictMode(byte[] pdf) throws PDFDocumentException + public static void applyStrictMode(PdfDataSource pdfDataSource) throws PDFDocumentException { if (isStrictPdfChecking()) { - if (!isPdf14(pdf)) + if (!isPdf14(pdfDataSource)) { throw new PDFDocumentException(201, "StrictMode: The pdf version is not 1.4 or lower."); } } try { + byte[] pdf = DataSourceHelper.convertDataSourceToByteArray(pdfDataSource); ParseDocument.parseDocument(pdf); } catch (Exception e) @@ -192,56 +208,60 @@ public abstract class PdfAS } } - /** - * Verifies the given PDF document. - * - * @param pdf - * The PDF document. - * @param connector - * The connector. - * @return Returns the List of results. - * @throws PresentableException - * Forwarded exception. - */ - public static List verifyPdf(final byte[] pdf, final String connector) throws PresentableException - { - VerificationFilter vf = new VerificationFilter(); - List signature_holders = vf.extractSignaturesFromPdf(pdf); - if (signature_holders.isEmpty()) - { - throw new PDFDocumentException(206); - } - - List results = verifySignatureHolders(signature_holders, connector); - - return results; - } - - /** - * Verifies the given text that is supposed to be extracted from a PDF - * document using text extraction mechanisms. - * - * @param text - * The text to be verified. - * @param connector - * The connecor. - * @return Returns the List of results. - * @throws PresentableException - * Forwarded exception. - */ - public static List verifyText(final String text, final String connector) throws PresentableException - { - VerificationFilter vf = new VerificationFilter(); - List signature_holders = vf.extractSignaturesFromPlainText(text); - if (signature_holders.isEmpty()) - { - throw new PDFDocumentException(206); - } - - List results = verifySignatureHolders(signature_holders, connector); - - return results; - } + // TODO: unused method - remove + // /** + // * Verifies the given PDF document. + // * + // * @param pdf + // * The PDF document. + // * @param connector + // * The connector. + // * @return Returns the List of results. + // * @throws PresentableException + // * Forwarded exception. + // */ + // public static List verifyPdf(final byte[] pdf, final String connector) + // throws PresentableException + // { + // VerificationFilter vf = new VerificationFilter(); + // List signature_holders = vf.extractSignaturesFromPdf(pdf); + // if (signature_holders.isEmpty()) + // { + // throw new PDFDocumentException(206); + // } + // + // List results = verifySignatureHolders(signature_holders, connector); + // + // return results; + // } + + // TODO: unused method - remove + // /** + // * Verifies the given text that is supposed to be extracted from a PDF + // * document using text extraction mechanisms. + // * + // * @param text + // * The text to be verified. + // * @param connector + // * The connecor. + // * @return Returns the List of results. + // * @throws PresentableException + // * Forwarded exception. + // */ + // public static List verifyText(final String text, final String connector) + // throws PresentableException + // { + // VerificationFilter vf = new VerificationFilter(); + // List signature_holders = vf.extractSignaturesFromPlainText(text); + // if (signature_holders.isEmpty()) + // { + // throw new PDFDocumentException(206); + // } + // + // List results = verifySignatureHolders(signature_holders, connector); + // + // return results; + // } /** * Extracts all signature blocks from the given raw text using textual mode. @@ -256,15 +276,14 @@ public abstract class PdfAS * @throws SignatureTypesException * @throws NormalizeException */ - public static List extractSignatureHoldersTextual(String raw_text, - boolean old_style) throws PDFDocumentException, SignatureException, SignatureTypesException, NormalizeException + public static List extractSignatureHoldersTextual(String raw_text, boolean old_style) throws PDFDocumentException, SignatureException, SignatureTypesException, NormalizeException { List signature_holders = new ArrayList(); String text = raw_text; for (;;) { - SignatureHolder holder = extractSignatureHolderTextual(text, old_style); + TextualSignatureHolder holder = extractSignatureHolderTextual(text, old_style); if (holder == null) { break; @@ -291,8 +310,7 @@ public abstract class PdfAS * @throws SignatureTypesException * @throws NormalizeException */ - public static SignatureHolder extractSignatureHolderTextual(String raw_text, - boolean old_style) throws SignatureException, SignatureTypesException, NormalizeException + public static TextualSignatureHolder extractSignatureHolderTextual(String raw_text, boolean old_style) throws SignatureException, SignatureTypesException, NormalizeException { SignatureTypes sig_types = SignatureTypes.getInstance(); List signatureTypes_ = sig_types.getSignatureTypeDefinitions(); @@ -339,7 +357,7 @@ public abstract class PdfAS if (!semantic_equality) { - throw new SignatureException(314); + throw new SignatureException(ErrorCode.NOT_SEMANTICALLY_EQUAL, "The found blocks are not semantically equal."); } if (!minimum_blocks.isEmpty()) @@ -368,7 +386,7 @@ public abstract class PdfAS // this normalization is required to get rid of possible trailing // newlines. String normalized_text = normalizeText(signed_text); - SignatureHolder holder = new TextualSignatureHolder(normalized_text, signatureObject_); + TextualSignatureHolder holder = new TextualSignatureHolder(normalized_text, signatureObject_); return holder; } @@ -388,8 +406,7 @@ public abstract class PdfAS * @return Returns a List of the found keys of the block, or null, if the * block could not be found. */ - public static List findBlockInText(String text, - SignatureTypeDefinition sig_type_def, boolean old_style) + public static List findBlockInText(String text, SignatureTypeDefinition sig_type_def, boolean old_style) { Vector keys = sig_type_def.getRevertSortedKeys(); Vector captions = sig_type_def.getRevertSortedCaptions(); @@ -472,8 +489,7 @@ public abstract class PdfAS { // sort the found_keys according to their start pos reversely. - Collections.sort(found_keys, new Comparator() - { + Collections.sort(found_keys, new Comparator() { public int compare(Object arg0, Object arg1) { FoundKey fk0 = (FoundKey) arg0; @@ -496,8 +512,7 @@ public abstract class PdfAS { // sort the found_keys according to their start pos. - Collections.sort(found_keys, new Comparator() - { + Collections.sort(found_keys, new Comparator() { public int compare(Object arg0, Object arg1) { FoundKey fk0 = (FoundKey) arg0; @@ -524,8 +539,7 @@ public abstract class PdfAS * Tells, if SIG_KZ should be ignored, or not. * @return Returns true, if the keys are correct. */ - public static boolean checkThatOrderIsCorrectAndCorrectFoundKeys( - List found_keys, List profile_keys, boolean old_style) + public static boolean checkThatOrderIsCorrectAndCorrectFoundKeys(List found_keys, List profile_keys, boolean old_style) { int found_index = 0; @@ -700,8 +714,7 @@ public abstract class PdfAS * Flag that tells, if KZ is not required. * @return Returns true, if all required keys were found. */ - public static boolean checkFoundRequiredKeys(List found_keys, - boolean old_style) + public static boolean checkFoundRequiredKeys(List found_keys, boolean old_style) { if (!containsFoundKey(found_keys, SignatureTypes.SIG_DATE)) { @@ -726,23 +739,7 @@ public abstract class PdfAS return true; } - /** - * Verifies the List of SignatureHolders using the given connector. - * - * @param signature_holders - * The List of SignatureHolder objects to be verified. - * @param connector - * The connector. - * @return Returns the List of SignatureResponse objects. - * @throws PDFDocumentException - * F.e. - * @throws NormalizeException - * F.e. - * @throws SignatureException - * F.e. - */ - public static List verifySignatureHolders(List signature_holders, - String connector) throws PDFDocumentException, NormalizeException, SignatureException + public static List verifySignatureHolders(List signature_holders, String connectorType) throws PDFDocumentException, NormalizeException, SignatureException, ConnectorException, ConnectorFactoryException { List results = new ArrayList(); for (int i = 0; i < signature_holders.size(); i++) @@ -759,7 +756,7 @@ public abstract class PdfAS // (holder.signature_object.isTextual() ? "textual" : "binary")); // logger_.debug(holder.signature_object.toString()); - SignatureResponse result = verify(holder, connector); + SignatureResponse result = verify(holder, connectorType); results.add(result); // logger_.debug(); @@ -773,38 +770,24 @@ public abstract class PdfAS } return results; } - - // TODO the choosing algorithm should be extracted into a visitor or factory design pattern. + public static List verifySignatureHoldersWeb(List signature_holders, - //String connector, String loc_ref) throws PDFDocumentException, NormalizeException, SignatureException - SessionInformation si, String loc_ref) throws PDFDocumentException, NormalizeException, SignatureException + VerifySessionInformation si, String loc_ref) throws PDFDocumentException, NormalizeException, SignatureException, ConnectorException { - List results = new ArrayList(); - - si.current_operation = 0; - - if(signature_holders.size() == 1) - { - List temp_holders = new ArrayList(si.signature_holders); - si.signature_holders = signature_holders; - SignatureHolder tmp_holder = (SignatureHolder) signature_holders.get(0); - SignatureResponse res = verifyWeb(tmp_holder, si.connector, loc_ref); - results.add(res); - si.signature_holders = temp_holders; - - return results; - } - - for (int i = 0; i < signature_holders.size(); i++) + List results = new ArrayList(); + + for (int i = 0; i < signature_holders.size(); i++) { SignatureHolder holder = (SignatureHolder) signature_holders.get(i); + // store the current holder on the session so that moa can obtain + // it from the RetrieveSignatureDataServlet. + si.moa_holder = holder; + SignatureResponse result = verifyWeb(holder, si.connector, loc_ref); results.add(result); - - si.current_operation++; } - + return results; } @@ -822,77 +805,67 @@ public abstract class PdfAS * F.e. * @throws SignatureException * F.e. + * @throws ConnectorException + * @throws ConnectorFactoryException */ - public static SignatureResponse verify(SignatureHolder signature_holder, - String connector) throws NormalizeException, PDFDocumentException, SignatureException + public static SignatureResponse verify(SignatureHolder signature_holder, String connectorType) throws NormalizeException, PDFDocumentException, SignatureException, ConnectorException, ConnectorFactoryException { - String text_to_be_verified = signature_holder.getSignedText(); + // String text_to_be_verified = signature_holder.getSignedText(); // logger_.debug("verify text_to_be_verified"+text_to_be_verified); SignatureObject so_to_be_verified = signature_holder.getSignatureObject(); - if (text_to_be_verified == null) - { - throw new SignatureException(311, "Document can not be verified because the text to be verified is either null."); - } - if (text_to_be_verified.length() <= 0) - { - throw new SignatureException(311, "Document can not be verified because the length of the text to be verified is 0. (length = " + text_to_be_verified.length() + ")"); - } + // if (text_to_be_verified == null) + // { + // throw new SignatureException(311, "Document can not be verified because + // the text to be verified is either null."); + // } + // if (text_to_be_verified.length() <= 0) + // { + // throw new SignatureException(311, "Document can not be verified because + // the length of the text to be verified is 0. (length = " + + // text_to_be_verified.length() + ")"); + // } if (so_to_be_verified == null) { throw new SignatureException(312, "Document can not be verified because no signature object are set."); } - - // fixed by tknall - if (so_to_be_verified.getX509Cert() == null) { - throw new SignatureException(313, "Document certificate is not defined."); - } - // FIXME this has to be made better - SignatureData sd = null; - if (so_to_be_verified.isBinary()) + // fixed by tknall + if (so_to_be_verified.getX509Cert() == null) { - byte[] data = CodingHelper.decodeBase64(text_to_be_verified); - sd = new SignatureDataImpl(data, "application/pdf"); - } - else - { - try - { - sd = new SignatureDataImpl(text_to_be_verified.getBytes("UTF-8"), "text/plain", "UTF-8"); - } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException("Very Strange: UTF-8 character encoding not supported???"); - } + throw new SignatureException(313, "Document certificate is not defined."); } SignSignatureObject so = SignatureObjectHelper.convertSignatureObjectToSignSignatureObject(so_to_be_verified); - + SignatureData sd = convertSignatureHolderToSignatureData(signature_holder); + String profile = so_to_be_verified.getSignatureTypeDefinition().getType(); - Connector c = ConnectorChooser.chooseCommandlineConnectorForVerify(connector, so_to_be_verified.getKZ(), so.id, profile); +// Connector c = ConnectorChooser.chooseCommandlineConnectorForVerify(connector, so_to_be_verified.getKZ(), so.id, profile); + String connectorId = CommandlineConnectorChooser.chooseCommandlineConnectorForVerify(connectorType, so_to_be_verified.getKZ(), so.id, profile); + Connector c = at.gv.egiz.pdfas.framework.ConnectorFactory.createConnector(connectorId, profile, null); return c.doVerify(sd, so); } - // TODO make this better using the visitor DP. - public static SignatureResponse verifyWeb(SignatureHolder signature_holder, - String connector, String loc_ref) throws NormalizeException, PDFDocumentException, SignatureException + public static SignatureResponse verifyWeb(SignatureHolder signature_holder, String connector, String loc_ref) throws NormalizeException, PDFDocumentException, SignatureException, ConnectorException { - String text_to_be_verified = signature_holder.getSignedText(); + // String text_to_be_verified = signature_holder.getSignedText(); // logger_.debug("verify text_to_be_verified"+text_to_be_verified); SignatureObject so_to_be_verified = signature_holder.getSignatureObject(); - if (text_to_be_verified == null) - { - throw new SignatureException(311, "Document can not be verified because the text to be verified is either null."); - } - if (text_to_be_verified.length() <= 0) - { - throw new SignatureException(311, "Document can not be verified because the length of the text to be verified is 0. (length = " + text_to_be_verified.length() + ")"); - } + // if (text_to_be_verified == null) + // { + // throw new SignatureException(311, "Document can not be verified because + // the text to be verified is either null."); + // } + // if (text_to_be_verified.length() <= 0) + // { + // throw new SignatureException(311, "Document can not be verified because + // the length of the text to be verified is 0. (length = " + + // text_to_be_verified.length() + ")"); + // } if (so_to_be_verified == null) { @@ -900,30 +873,14 @@ public abstract class PdfAS } // added by tknall - if (so_to_be_verified.getX509Cert() == null) { - throw new SignatureException(313, "Document certificate is not defined."); - } - - // FIXME this has to be made better - SignatureData sd = null; - if (so_to_be_verified.isBinary()) + if (so_to_be_verified.getX509Cert() == null) { - byte[] data = CodingHelper.decodeBase64(text_to_be_verified); - sd = new SignatureDataImpl(data, "application/pdf"); - } - else - { - try - { - sd = new SignatureDataImpl(text_to_be_verified.getBytes("UTF-8"), "text/plain", "UTF-8"); - } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException("Very Strange: UTF-8 character encoding not supported???"); - } + throw new SignatureException(313, "Document certificate is not defined."); } + SignSignatureObject so = SignatureObjectHelper.convertSignatureObjectToSignSignatureObject(so_to_be_verified); + SignatureData sd = convertSignatureHolderToSignatureData(signature_holder); String profile = so_to_be_verified.getSignatureTypeDefinition().getType(); Connector c = ConnectorChooser.chooseWebConnectorForVerify(connector, so_to_be_verified.getKZ(), so.id, profile, loc_ref); @@ -931,6 +888,23 @@ public abstract class PdfAS return c.doVerify(sd, so); } + + public static SignatureData convertSignatureHolderToSignatureData(SignatureHolder signature_holder) + { + SignatureData sd = null; + if (signature_holder instanceof BinarySignatureHolder) + { + BinarySignatureHolder bsh = (BinarySignatureHolder) signature_holder; + sd = new SignatureDataImpl(bsh.getDataSource(), "application/pdf"); + } + else + { + TextualSignatureHolder tsh = (TextualSignatureHolder)signature_holder; + sd = new SignatureDataImpl(tsh.getDataSource(), "text/plain", "UTF-8"); + } + return sd; + } + /** * Signs the given text with the provided connector using the given signature * type. @@ -946,18 +920,20 @@ public abstract class PdfAS * F.e. * @throws PDFDocumentException * F.e. + * @throws ConnectorException */ - public static SignSignatureObject sign(final SignatureData data_to_sign, - final Connector connector) throws SignatureException, PDFDocumentException + public static SignSignatureObject sign(final SignatureData data_to_sign, final Connector connector) throws SignatureException, PDFDocumentException, ConnectorException { - if (data_to_sign == null || data_to_sign.getData() == null) - { - throw new SignatureException(301, "Signature can not be produced. Data is null."); //$NON-NLS-1$ - } - if (data_to_sign.getData().length <= 0) - { - throw new SignatureException(301, "Signature can not be produced. Data is empty. (length = " + data_to_sign.getData().length + ")"); //$NON-NLS-1$ //$NON-NLS-2$ - } +// if (data_to_sign == null || data_to_sign.getData() == null) +// { +// throw new SignatureException(301, "Signature can not be produced. Data is null."); //$NON-NLS-1$ +// } + // if (data_to_sign.getData().length <= 0) + // { + // throw new SignatureException(301, "Signature can not be produced. Data is + // empty. (length = " + data_to_sign.getData().length + ")"); //$NON-NLS-1$ + // //$NON-NLS-2$ + // } SignSignatureObject signed_signature_object = connector.doSign(data_to_sign); return signed_signature_object; @@ -975,8 +951,7 @@ public abstract class PdfAS * @throws SignatureTypesException * f.e. */ - public static SignatureObject createSignatureObjectFromType( - final String signature_type) throws SignatureException, SignatureTypesException + public static SignatureObject createSignatureObjectFromType(final String signature_type) throws SignatureException, SignatureTypesException { SignatureObject sig_obj = new SignatureObject(); sig_obj.setSigType(signature_type); @@ -985,45 +960,53 @@ public abstract class PdfAS return sig_obj; } - /** - * Signs the document using the given algorithm. - * - * @param algorithm - * The Signator algorithm to be used. - * @param pdf - * The PDF. - * @param signature_type - * The signature type. - * @param connector - * The connector. - * @param user_name - * The user name. - * @param user_password - * The password. - * @param pos - * The absolute position. If null, the position is either taken from - * the profile or computed automatically. - * @return Returns the SignResult. - * @throws PresentableException - * F.e. - */ - public static SignResult sign(PdfASID algorithm, final byte[] pdf, - final String signature_type, final String connector, - final String user_name, final String user_password, TablePos pos) throws PresentableException +// /** +// * @deprecated moved to Main.processSign use signCommandline instead +// * @param pdfDataSource +// * @param dataSink +// * @param signatorId +// * @param connectorType +// * @param profile +// * @param pos +// * @throws PresentableException +// */ +// public static void sign(PdfDataSource pdfDataSource, DataSink dataSink, PdfASID signatorId, final String connectorType, final String profile, TablePos pos) throws PresentableException +// { +//// //Signator signator = SignatorFactory.createSignator(algorithm); +//// at.gv.egiz.pdfas.framework.signator.Signator signator = at.gv.egiz.pdfas.framework.SignatorFactory.createSignator(algorithm); +//// +//// //IncrementalUpdateInformation iui = signator.prepareSign(pdfDataSource, signature_type, pos, ConnectorFactory.needsSIG_ID(connector)); +//// SignatorInformation si = signator.prepareSign(pdfDataSource, signature_type, pos, ConnectorFactory.needsSIG_ID(connector)); +// +// // Connector c = ConnectorChooser.chooseCommandlineConnectorForSign(connector, signature_type); +// +//// SignSignatureObject sso = sign(si.getSignatureData(), c); +//// +//// si.setSignSignatureObject(sso); +//// +//// signator.finishSign(si, dataSink); +// +// String connectorId = CommandlineConnectorChooser.chooseCommandlineConnectorForSign(connectorType); +// +// signCommandline(pdfDataSource, dataSink, signatorId, connectorId, profile, pos); +// } + + public static void signCommandline(PdfDataSource pdfDataSource, DataSink dataSink, PdfASID signatorId, String connectorId, final String profile, TablePos pos) throws PresentableException { - Signator signator = SignatorFactory.createSignator(algorithm); - - IncrementalUpdateInformation iui = signator.prepareSign(pdf, signature_type, pos, ConnectorFactory.needsSIG_ID(connector)); + at.gv.egiz.pdfas.framework.signator.Signator signator = at.gv.egiz.pdfas.framework.SignatorFactory.createSignator(signatorId); - Connector c = ConnectorChooser.chooseCommandlineConnectorForSign(connector, signature_type); + Connector c = at.gv.egiz.pdfas.framework.ConnectorFactory.createConnector(connectorId, profile, null); - iui.signed_signature_object = sign(iui.signature_data, c); + // SignatorInformation si = signator.prepareSign(pdfDataSource, profile, pos, ConnectorFactory.needsSIG_ID(connector)); + SignatorInformation si = signator.prepareSign(pdfDataSource, profile, pos, CommandlineConnectorChooser.needsSigId(connectorId)); - SignResult sign_result = signator.finishSign(iui); + SignSignatureObject sso = sign(si.getSignatureData(), c); + + si.setSignSignatureObject(sso); - return sign_result; + signator.finishSign(si, dataSink); } - + /** * Extracts and normalizes the text from the pdf. * @@ -1033,40 +1016,52 @@ public abstract class PdfAS * @throws PresentableException * F.e. */ - public static String extractNormalizedTextTextual(final byte[] pdf) throws PresentableException +// public static String extractNormalizedTextTextual(final byte[] pdf) throws PresentableException +// { +// // ByteArrayInputStream bais = new ByteArrayInputStream(pdf); +// // String raw_document_text = TextualSignature.extractTextTextual(bais); +// // +// // String document_text = normalizeText(raw_document_text); +// +// return extractNormalizedTextTextual(pdf, pdf.length); +// } + + public static String extractNormalizedTextTextual(InputStream pdfInputStream) throws PresentableException { - // ByteArrayInputStream bais = new ByteArrayInputStream(pdf); - // String raw_document_text = TextualSignature.extractTextTextual(bais); - // - // String document_text = normalizeText(raw_document_text); - - return extractNormalizedTextTextual(pdf, pdf.length); + String raw_document_text = TextualSignature.extractTextTextual(pdfInputStream); + String document_text = normalizeText(raw_document_text); + return document_text; } - - /** - * Extracts and normalizes the text from the pdf. - * - * @param pdf - * The PDF document. - * @param length - * The length of the PDF document. The decument is considered to be - * that long even if the byte array is longer. - * @return Returns the text String. - * @throws PresentableException - * F.e. - */ - public static String extractNormalizedTextTextual(final byte[] pdf, - final int length) throws PresentableException + public static String extractNormalizedTextTextual(InputStream pdfInputStream, int length) throws PresentableException { - ByteArrayInputStream bais = new ByteArrayInputStream(pdf, 0, length); - String raw_document_text = TextualSignature.extractTextTextual(bais); - // logger_.info("extractNormalizedTextTextual - // raw_document_text="+raw_document_text); + DelimitedInputStream dis = new DelimitedInputStream(pdfInputStream, length); + String raw_document_text = TextualSignature.extractTextTextual(dis); String document_text = normalizeText(raw_document_text); - // logger_.info("extractNormalizedTextTextual document_text - // ="+document_text); - return document_text; + return document_text; } +// /** +// * Extracts and normalizes the text from the pdf. +// * +// * @param pdf +// * The PDF document. +// * @param length +// * The length of the PDF document. The decument is considered to be +// * that long even if the byte array is longer. +// * @return Returns the text String. +// * @throws PresentableException +// * F.e. +// */ +// public static String extractNormalizedTextTextual(final byte[] pdf, final int length) throws PresentableException +// { +// ByteArrayInputStream bais = new ByteArrayInputStream(pdf, 0, length); +// String raw_document_text = TextualSignature.extractTextTextual(bais); +// // logger_.info("extractNormalizedTextTextual +// // raw_document_text="+raw_document_text); +// String document_text = normalizeText(raw_document_text); +// // logger_.info("extractNormalizedTextTextual document_text +// // ="+document_text); +// return document_text; +// } /** * Normalizes the given text. @@ -1095,8 +1090,7 @@ public abstract class PdfAS * @throws SignatureException * F.e. */ - public static PdfPTable createPdfPTableFromSignatureObject( - final SignatureObject signature_object) throws PDFDocumentException, SignatureException + public static PdfPTable createPdfPTableFromSignatureObject(final SignatureObject signature_object) throws PDFDocumentException, SignatureException { PDFSignatureCreation creation = new PDFSignatureCreation(signature_object); PDFSignatureObject pdf_sig_obj = creation.getPDFSignatureObject(); @@ -1124,8 +1118,7 @@ public abstract class PdfAS * @throws SettingsException * F.e. */ - public static PositioningInstruction determineTablePositioning(TablePos pos, - String signature_type, byte[] pdf, PdfPTable pdf_table) throws PDFDocumentException, SettingsException + public static PositioningInstruction determineTablePositioning(TablePos pos, String signature_type, PdfDataSource pdfDataSource, PdfPTable pdf_table) throws PDFDocumentException, SettingsException { if (pos == null) { @@ -1142,7 +1135,7 @@ public abstract class PdfAS pos = new TablePos(); } // System.out.println("Tablepos="+pos); - return PdfAS.adjustSignatureTableandCalculatePosition(pdf, pdf_table, pos); + return PdfAS.adjustSignatureTableandCalculatePosition(pdfDataSource, pdf_table, pos); } /** @@ -1157,12 +1150,11 @@ public abstract class PdfAS * @throws PDFDocumentException * F.e. */ - public static PositioningInstruction adjustSignatureTableandCalculatePosition( - final byte[] pdf, PdfPTable pdf_table, TablePos pos) throws PDFDocumentException + public static PositioningInstruction adjustSignatureTableandCalculatePosition(final PdfDataSource pdfDataSource, PdfPTable pdf_table, TablePos pos) throws PDFDocumentException { // first check pageinstruction in TablePos-object // new,auto,absolut - PdfReader reader = readInPdfDocument(pdf); + PdfReader reader = readInPdfDocument(pdfDataSource); // get pages of currentdocument int doc_pages = reader.getNumberOfPages(); int page = doc_pages; @@ -1235,7 +1227,7 @@ public abstract class PdfAS // up to here no checks have to be made if Tablesize and Pagesize are fit // Now we have to getfreespace in page and reguard footerline float footer_line = pos.getFooterLine(); - float pre_page_length = PDFUtilities.calculatePageLength(pdf, page - 1, page_height - footer_line, page_rotation); + float pre_page_length = PDFUtilities.calculatePageLength(pdfDataSource, page - 1, page_height - footer_line, page_rotation); if (pre_page_length == Float.NEGATIVE_INFINITY) { // we do have an empty page or nothing in area above footerline @@ -1275,103 +1267,101 @@ public abstract class PdfAS return new PositioningInstruction(make_new_page, page, pos_x, pos_y); } - /** - * Sets the width of the table according to the layout of the document and - * calculates the y position where the PDFPTable should be placed. - * - * @deprecated - * @param pdf - * The PDF document. - * @param pdf_table - * The PDFPTable to be placed. - * @return Returns the position where the PDFPTable should be placed. - * @throws PDFDocumentException - * F.e. - */ - public static PositioningInstruction adjustTableAndCalculatePosition( - final byte[] pdf, PdfPTable pdf_table) throws PDFDocumentException - { - boolean make_new_page = false; - - PdfReader reader = readInPdfDocument(pdf); - - int page = reader.getNumberOfPages(); - Rectangle psize = reader.getPageSizeWithRotation(page); - float page_width = psize.width(); - float page_height = psize.height(); - - final float width = page_width - SIGNATURE_BORDER; - pdf_table.setTotalWidth(width); - pdf_table.setLockedWidth(true); - - final float pos_x = SIGNATURE_BORDER / 2; - - final float table_height = pdf_table.getTotalHeight(); - final float page_length = PDFUtilities.calculateLastPageLength(pdf, page_height); - float pos_y = page_height - page_length - SIGNATURE_MARGIN; - - if (pos_y <= table_height) - { - make_new_page = true; - page++; - - pos_y = page_height - SIGNATURE_BORDER / 2; - } - - return new PositioningInstruction(make_new_page, page, pos_x, pos_y); - } - - /** - * Sets the width of the table according to the layout of the document and - * calculates the y position where the PDFPTable should be placed. - * - *

- * This algorithm tries to position the table between the end of the text and - * the footer line. - *

- * - * @deprecated - * @param pdf - * The PDF document. - * @param pdf_table - * The PDFPTable to be placed. - * @return Returns the position where the PDFPTable should be placed. - * @throws PDFDocumentException - * F.e. - */ - public static PositioningInstruction adjustTableAndCalculatePositionRegardingFooter( - final byte[] pdf, PdfPTable pdf_table, float footer_line) throws PDFDocumentException - { - boolean make_new_page = false; - - PdfReader reader = readInPdfDocument(pdf); - - int page = reader.getNumberOfPages(); - Rectangle psize = reader.getPageSizeWithRotation(page); - float page_width = psize.width(); - float page_height = psize.height(); - - final float width = page_width - SIGNATURE_BORDER; - pdf_table.setTotalWidth(width); - pdf_table.setLockedWidth(true); - - final float pos_x = SIGNATURE_BORDER / 2; - - final float table_height = pdf_table.getTotalHeight(); - - final float page_length = PDFUtilities.calculateLastPageLength(pdf, page_height - footer_line); - float pos_y = page_height - page_length - SIGNATURE_MARGIN; - - if (pos_y - footer_line <= table_height) - { - make_new_page = true; - page++; - - pos_y = page_height - SIGNATURE_BORDER / 2; - } - - return new PositioningInstruction(make_new_page, page, pos_x, pos_y); - } +// /** +// * Sets the width of the table according to the layout of the document and +// * calculates the y position where the PDFPTable should be placed. +// * +// * @deprecated +// * @param pdf +// * The PDF document. +// * @param pdf_table +// * The PDFPTable to be placed. +// * @return Returns the position where the PDFPTable should be placed. +// * @throws PDFDocumentException +// * F.e. +// */ +// public static PositioningInstruction adjustTableAndCalculatePosition(final byte[] pdf, PdfPTable pdf_table) throws PDFDocumentException +// { +// boolean make_new_page = false; +// +// PdfReader reader = readInPdfDocument(pdf); +// +// int page = reader.getNumberOfPages(); +// Rectangle psize = reader.getPageSizeWithRotation(page); +// float page_width = psize.width(); +// float page_height = psize.height(); +// +// final float width = page_width - SIGNATURE_BORDER; +// pdf_table.setTotalWidth(width); +// pdf_table.setLockedWidth(true); +// +// final float pos_x = SIGNATURE_BORDER / 2; +// +// final float table_height = pdf_table.getTotalHeight(); +// final float page_length = PDFUtilities.calculateLastPageLength(pdf, page_height); +// float pos_y = page_height - page_length - SIGNATURE_MARGIN; +// +// if (pos_y <= table_height) +// { +// make_new_page = true; +// page++; +// +// pos_y = page_height - SIGNATURE_BORDER / 2; +// } +// +// return new PositioningInstruction(make_new_page, page, pos_x, pos_y); +// } + +// /** +// * Sets the width of the table according to the layout of the document and +// * calculates the y position where the PDFPTable should be placed. +// * +// *

+// * This algorithm tries to position the table between the end of the text and +// * the footer line. +// *

+// * +// * @deprecated +// * @param pdf +// * The PDF document. +// * @param pdf_table +// * The PDFPTable to be placed. +// * @return Returns the position where the PDFPTable should be placed. +// * @throws PDFDocumentException +// * F.e. +// */ +// public static PositioningInstruction adjustTableAndCalculatePositionRegardingFooter(final byte[] pdf, PdfPTable pdf_table, float footer_line) throws PDFDocumentException +// { +// boolean make_new_page = false; +// +// PdfReader reader = readInPdfDocument(pdf); +// +// int page = reader.getNumberOfPages(); +// Rectangle psize = reader.getPageSizeWithRotation(page); +// float page_width = psize.width(); +// float page_height = psize.height(); +// +// final float width = page_width - SIGNATURE_BORDER; +// pdf_table.setTotalWidth(width); +// pdf_table.setLockedWidth(true); +// +// final float pos_x = SIGNATURE_BORDER / 2; +// +// final float table_height = pdf_table.getTotalHeight(); +// +// final float page_length = PDFUtilities.calculateLastPageLength(pdf, page_height - footer_line); +// float pos_y = page_height - page_length - SIGNATURE_MARGIN; +// +// if (pos_y - footer_line <= table_height) +// { +// make_new_page = true; +// page++; +// +// pos_y = page_height - SIGNATURE_BORDER / 2; +// } +// +// return new PositioningInstruction(make_new_page, page, pos_x, pos_y); +// } /** * Creates an iText Reader that parses the document. @@ -1386,11 +1376,14 @@ public abstract class PdfAS * @throws PDFDocumentException * F.e. */ - public static PdfReader readInPdfDocument(final byte[] pdf) throws PDFDocumentException + public static PdfReader readInPdfDocument(final PdfDataSource pdfDataSource) throws PDFDocumentException { try { - return new PdfReader(pdf); + InputStream is = pdfDataSource.createInputStream(); + PdfReader reader = new PdfReader(is); + is.close(); + return reader; } catch (IOException e) { diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/PdfASID.java b/src/main/java/at/knowcenter/wag/egov/egiz/PdfASID.java index 0193368..0409bb7 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/PdfASID.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/PdfASID.java @@ -161,6 +161,36 @@ public class PdfASID implements Serializable { return this.version; } + + + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + //@override + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + if (!(obj instanceof PdfASID)) + { + return false; + } + + PdfASID other = (PdfASID) obj; + + return this.toString().equals(other.toString()); + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() + { + return toString().hashCode(); + } /** * @see java.lang.Object#toString() diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/cfg/ConfigLogger.java b/src/main/java/at/knowcenter/wag/egov/egiz/cfg/ConfigLogger.java index 3b32c22..e0a8a3d 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/cfg/ConfigLogger.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/cfg/ConfigLogger.java @@ -27,6 +27,8 @@ import org.apache.log4j.Logger; /** * This logger class is the main logger class for the pdf-as project. It holds static logger * instances with could be configured the level with one method. + * + * @deprecated use commons.logging instead */ public class ConfigLogger { diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/cfg/SettingsReader.java b/src/main/java/at/knowcenter/wag/egov/egiz/cfg/SettingsReader.java index 96286ad..a158729 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/cfg/SettingsReader.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/cfg/SettingsReader.java @@ -18,17 +18,17 @@ package at.knowcenter.wag.egov.egiz.cfg; -import java.io.FileInputStream; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.Serializable; -import java.util.Vector; import java.util.ArrayList; import java.util.Enumeration; import java.util.Properties; +import java.util.Vector; -import org.apache.log4j.Level; -import org.apache.log4j.Logger; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException; import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; @@ -120,7 +120,7 @@ import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; * * @author wlackner */ -public class SettingsReader implements Settings, Serializable +public class SettingsReader implements Serializable { /** @@ -252,9 +252,9 @@ public class SettingsReader implements Settings, Serializable private PropertyTree pTree_ = new PropertyTree(); /** - * The logger definition. + * The log. */ - private static final Logger logger_ = ConfigLogger.getLogger(SettingsReader.class); + private static final Log logger_ = LogFactory.getLog(SettingsReader.class); /** * Make this constructor private. Use the method @@ -321,7 +321,7 @@ public class SettingsReader implements Settings, Serializable } catch (IOException e) { - throw new SettingsException(e); + throw new SettingsException("Couldn't load settings from file " + settingsFile, e); } } @@ -385,11 +385,11 @@ public class SettingsReader implements Settings, Serializable if (result == null) { String log_message = "Configuration key not found: '" + key + "'! Check '" + settingsFile_ + "' file."; - if (logger_.isEnabledFor(Level.WARN)) + if (logger_.isWarnEnabled()) { logger_.warn(log_message); } - SettingNotFoundException snf = new SettingNotFoundException(100, log_message); + SettingNotFoundException snf = new SettingNotFoundException(log_message); throw snf; } // if (logger_.isDebugEnabled()) @@ -524,14 +524,14 @@ public class SettingsReader implements Settings, Serializable } catch (NumberFormatException e) { - if (logger_.isEnabledFor(Level.WARN)) + if (logger_.isWarnEnabled()) { logger_.warn("Can not convert " + value + " to int."); } } catch (SettingNotFoundException e) { - if (logger_.isEnabledFor(Level.WARN)) + if (logger_.isWarnEnabled()) { logger_.warn("Setting " + key + " not found, return default value:" + defaultValue); } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java b/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java index 65c30b9..ee12fff 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java @@ -19,34 +19,44 @@ package at.knowcenter.wag.egov.egiz.commandline; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; +import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import org.apache.log4j.Logger; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.log4j.PropertyConfigurator; +import at.gv.egiz.pdfas.commandline.CommandlineConnectorChooser; +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.gv.egiz.pdfas.exceptions.ErrorCodeHelper; +import at.gv.egiz.pdfas.exceptions.external.ExternalErrorException; +import at.gv.egiz.pdfas.framework.config.SettingsHelper; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.ExtractionStage; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.output.DataSink; +import at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters; +import at.gv.egiz.pdfas.impl.input.FileBasedPdfDataSourceImpl; +import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl; +import at.gv.egiz.pdfas.impl.output.FileBasedDataSink; +import at.gv.egiz.pdfas.impl.vfilter.VerificationFilterParametersImpl; import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.PdfASID; -import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.ConnectorFactoryException; -import at.knowcenter.wag.egov.egiz.exceptions.ErrorCodeException; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; import at.knowcenter.wag.egov.egiz.exceptions.PlaceholderException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException; import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; import at.knowcenter.wag.egov.egiz.exceptions.SignatureTypesException; -import at.knowcenter.wag.egov.egiz.framework.SignResult; import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; -import at.knowcenter.wag.egov.egiz.framework.VerificationFilter; import at.knowcenter.wag.egov.egiz.framework.signators.BinarySignator_1_0_0; -import at.knowcenter.wag.egov.egiz.framework.signators.DetachedSignator_1_0_0; import at.knowcenter.wag.egov.egiz.framework.signators.TextualSignator_1_0_0; import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; import at.knowcenter.wag.egov.egiz.pdf.TablePos; @@ -132,12 +142,12 @@ public abstract class Main /** * The application mode verify */ - public static final String VALUE_SIGNATURE_MODE_DETACHED_TEXt = "detachedtextual"; + public static final String VALUE_SIGNATURE_MODE_DETACHED_TEXT = "detachedtextual"; /** - * The logger definition. + * The log. */ - private static final Logger logger_ = ConfigLogger.getLogger(Main.class); + private static final Log logger_ = LogFactory.getLog(Main.class); /** * Main program entry point. @@ -152,9 +162,7 @@ public abstract class Main SettingsReader.initializeForCommandLine(); PropertyConfigurator.configure(SettingsReader.CONFIG_PATH + "log4j.properties"); - - try - { + // printUsage(System.out); String mode = null; @@ -170,7 +178,10 @@ public abstract class Main String input = null; String output = null; - + + try + { + // for (int i = 0; i < args.length; i++) // { // logger_.debug("arg[" + i + "] = " + args[i]); @@ -378,21 +389,31 @@ public abstract class Main return; } + if (mode.equals(VALUE_MODE_SIGN) && output == null) + { + output = generateOutputFileNameFromInput(input, signature_mode); + } + else + { + output = null; + } + carryOutCommand(mode, signature_mode, connector, signature_type, user_name, user_password, verify_which, input, output, pos_string); } catch (PresentableException e) { - if (e instanceof ErrorCodeException) - { - ErrorCodeException ece = (ErrorCodeException) e; - printErrorCodeException(ece); - } - else + printPresentableException(e); + + if (output != null) { - System.err.println("PresentableException:"); - System.err.println(e.getMessage()); - logger_.debug(e.toString()); + logger_.debug("Deleting output file on error."); + File oFile = new File(output); + boolean deleted = oFile.delete(); + if (!deleted) + { + logger_.error("Couldn't delete output file " + output); + } } } finally @@ -401,186 +422,226 @@ public abstract class Main } } - /** - * Carries out the actual command given via the commandline parameters. - * - *

- * This is simply the procedure that is executed after the commandline - * parameters have been parsed successfully. - *

- * - * @param mode - * The operation mode (e.g. "sign", "verify"). - * @param signature_mode - * The signature mode (e.g. "binary", "textual"). - * @param connector - * The connector (e.g. "bku", "a1"). - * @param signature_type - * The signature type/profile. For signing only. - * @param user_name - * The user name. For signing only. - * @param user_password - * The user password. For signing only. - * @param verify_which - * The number of the signature to be verified. For verifying only. - * @param input - * The input file name. - * @param output - * The output file name. - * @throws PresentableException - */ - protected static void carryOutCommand(final String mode, - final String signature_mode, final String connector, - final String signature_type, final String user_name, - final String user_password, final int verify_which, final String input, - String output, final String pos_string) throws PresentableException + protected static void carryOutCommand(final String mode, final String signature_mode, final String connector, final String signature_type, final String user_name, final String user_password, + final int verify_which, final String input, String output, final String pos_string) throws PresentableException + { + // File file = new File(input); + // + // byte[] input_bytes = null; + // try + // { + // FileInputStream fis = new FileInputStream(file); + // input_bytes = new byte[(int) file.length()]; + // fis.read(input_bytes); + // fis.close(); + // } + // catch (IOException e) + // { + // throw new PDFDocumentException(201); + // } + + PrintWriter messageOutput = new PrintWriter(System.out); + + if (mode.equals(VALUE_MODE_SIGN)) + { + carryOutSign(input, connector, signature_mode, signature_type, pos_string, user_name, user_password, output, messageOutput); + } + else + { + carryOutVerify(input, connector, verify_which, messageOutput); + } + messageOutput.close(); + } + + public static void carryOutSign(String input, String connector, String signature_mode, String signature_type, String pos_string, String user_name, String user_password, String output, + PrintWriter messageOutput) throws PresentableException { - File file = new File(input); + messageOutput.println("Signing..."); - byte[] input_bytes = null; + PdfDataSource pdfDataSource; try { - FileInputStream fis = new FileInputStream(file); - input_bytes = new byte[(int) file.length()]; - fis.read(input_bytes); - fis.close(); + File file = new File(input); + pdfDataSource = new FileBasedPdfDataSourceImpl(file, (int)file.length()); } catch (IOException e) { - throw new PDFDocumentException(201); + throw new PDFDocumentException(201, e); } - if (mode.equals(VALUE_MODE_SIGN)) + FileBasedDataSink dataSink = null; + try { - System.out.println("Signing..."); + File outputFile = new File(output); + dataSink = new FileBasedDataSink(outputFile); + } + catch (IOException e) + { + throw new PDFDocumentException(ErrorCode.CANNOT_WRITE_PDF, e); + } - PdfAS.applyStrictMode(input_bytes); + processSign(pdfDataSource, connector, signature_mode, signature_type, pos_string, dataSink); - TablePos pos = null; - if (pos_string != null) + messageOutput.println("Signing was successful."); + } + + public static void carryOutVerify(String input, String connector, int verify_which, PrintWriter messageOutput) throws PresentableException + { + messageOutput.println("Verifying..."); + + DataSource dataSource = null; + try + { + File file = new File(input); + String extension = VerifyServlet.extractExtension(input); + if (extension != null && extension.equals("txt")) { try { - pos = PdfAS.parsePositionFromPosString(pos_string); + FileInputStream fis = new FileInputStream(file); + byte[] input_bytes = new byte[(int) file.length()]; + fis.read(input_bytes); + fis.close(); + + String text = new String(input_bytes, "UTF-8"); + dataSource = new TextDataSourceImpl(text); } - catch (PDFDocumentException e) + catch (UnsupportedEncodingException e) { - printUnrecognizedValue(PARAMETER_POS, pos_string); - return; - + throw new RuntimeException("Very strange: UTF-8 character encoding not supported.", e); } } - - PdfASID algorithm = translateSignatureModeToPdfASID(signature_mode); - - // TODO MOA detached signing is not allowed at the commandline - logger_.debug("Suggested sign algorithm = " + algorithm); - if (connector.equals("moa")) + else { - // TODO: possible new implementation of moa where is commandline call supported - // it should be checked in config file is it allowed to use MOA detached from command line. - String msg = "Hinweis: Der MOA Detached Connector ist für die Kommandozeile nicht geeignet. Die Signatur wird daher im alten Base64 enveloping Format ausgeführt."; - System.out.println(msg); - logger_.warn(msg); - - if (signature_mode.equals(VALUE_SIGNATURE_MODE_BINARY)) - { - algorithm = BinarySignator_1_0_0.MY_ID; - } - if (signature_mode.equals(VALUE_SIGNATURE_MODE_TEXTUAL)) - { - algorithm = TextualSignator_1_0_0.MY_ID; - } + dataSource = new FileBasedPdfDataSourceImpl(file, (int)file.length()); } - logger_.debug("Finally used sign algorithm = " + algorithm); + } + catch (IOException e) + { + throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e); + } + + List results = processVerify(dataSource, connector, verify_which); - SignResult sign_result = PdfAS.sign(algorithm, input_bytes, signature_type, connector, user_name, user_password, pos); + messageOutput.println("Verification results:"); + formatVerifyResults(results, messageOutput); + } + + public static void processSign(PdfDataSource pdfDataSource, String connector, String signature_mode, String signature_type, String pos_string, DataSink dataSink) throws PresentableException + { + PdfAS.applyStrictMode(pdfDataSource); + TablePos pos = null; + if (pos_string != null) + { try { - if (output == null) - { - output = generateOutputFileNameFromInput(input, sign_result); - } - - FileOutputStream fos = new FileOutputStream(output); - fos.write(sign_result.getData()); - fos.close(); + pos = PdfAS.parsePositionFromPosString(pos_string); } - catch (IOException e) + catch (PDFDocumentException e) { - throw new PDFDocumentException(205); - } + printUnrecognizedValue(PARAMETER_POS, pos_string); + return; - System.out.println("Signing was successful."); + } } - else - { - System.out.println("Verifying..."); - - VerificationFilter vf = new VerificationFilter(); - List signature_holders = null; + PdfASID signatorId = translateSignatureModeToPdfASID(signature_mode); - String extension = VerifyServlet.extractExtension(input); - if (extension != null && extension.equals("txt")) + // TODO MOA detached signing is not allowed at the commandline + logger_.debug("Suggested sign algorithm = " + signatorId); + if (connector.equals("moa")) + { + // TODO: possible new implementation of moa where is commandline call + // supported + // it should be checked in config file is it allowed to use MOA detached + // from command line. + String msg = "Hinweis: Der MOA Detached Connector ist für die Kommandozeile nicht geeignet. Die Signatur wird daher im alten Base64 enveloping Format ausgeführt."; + System.out.println(msg); + logger_.warn(msg); + + if (signature_mode.equals(VALUE_SIGNATURE_MODE_BINARY)) { - try - { - String text = new String(input_bytes, "UTF-8"); - signature_holders = vf.extractSignaturesFromPlainText(text); - } - catch (UnsupportedEncodingException e) - { - throw new PresentableException(e); - } + signatorId = BinarySignator_1_0_0.MY_ID; } - else + if (signature_mode.equals(VALUE_SIGNATURE_MODE_TEXTUAL)) { - signature_holders = vf.extractSignaturesFromPdf(input_bytes); + signatorId = TextualSignator_1_0_0.MY_ID; } + } + logger_.debug("Finally used sign algorithm = " + signatorId); + + String connectorId = CommandlineConnectorChooser.chooseCommandlineConnectorForSign(connector); - if (signature_holders.isEmpty()) - { - throw new PDFDocumentException(206); - } + PdfAS.signCommandline(pdfDataSource, dataSink, signatorId, connectorId, signature_type, pos); - List holders_to_verify = signature_holders; +// PdfAS.sign(algorithm, pdfDataSource, dataSink, signature_type, connector, pos); + } + + public static List processVerify(DataSource dataSource, String connector, int verify_which) throws PresentableException + { + VerificationFilterParameters parameters = SettingsHelper.readVerificationFilterParametersFromSettings(); + ExtractionStage es = new ExtractionStage(); - // verify_which - optional argument in command line/web - if (verify_which >= 0) - { - if (verify_which >= signature_holders.size()) - { - throw new SignatureException(312, "The selected signature to be verified doesn't exist."); - } + List signature_holders = es.extractSignatureHolders(dataSource, parameters); - SignatureHolder holder = (SignatureHolder) signature_holders.get(verify_which); - holders_to_verify = new ArrayList(); - holders_to_verify.add(holder); + if (signature_holders.isEmpty()) + { + throw new PDFDocumentException(ErrorCode.DOCUMENT_NOT_SIGNED, "Document is unsigned."); + } + + List holders_to_verify = signature_holders; + + // verify_which - optional argument in command line/web + if (verify_which >= 0) + { + if (verify_which >= signature_holders.size()) + { + throw new SignatureException(312, "The selected signature to be verified doesn't exist."); } - List results = PdfAS.verifySignatureHolders(holders_to_verify, connector); - System.out.println("Verification results:"); - formatVerifyResults(results, System.out); + SignatureHolder holder = (SignatureHolder) signature_holders.get(verify_which); + holders_to_verify = new ArrayList(); + holders_to_verify.add(holder); } + + List results = PdfAS.verifySignatureHolders(holders_to_verify, connector); + + return results; } - /** - * Generates a suitable output file name for the output regarding the type of - * the sign_result. - * - * @param input - * The input file name. - * @param sign_result - * The sign result. - * @return Returns the output file name. - */ - protected static String generateOutputFileNameFromInput(String input, - SignResult sign_result) + // TODO old method - remove + // /** + // * Generates a suitable output file name for the output regarding the type + // of + // * the sign_result. + // * + // * @param input + // * The input file name. + // * @param sign_result + // * The sign result. + // * @return Returns the output file name. + // */ + // protected static String generateOutputFileNameFromInput(String input, + // SignResult sign_result) + // { + // String output = input + "_out"; + // if (sign_result.getMimeType().equals(DetachedSignator_1_0_0.MIME_TYPE)) + // { + // output += ".xml"; + // } + // else + // { + // output += ".pdf"; + // } + // + // return output; + // } + + protected static String generateOutputFileNameFromInput(String input, String sig_mode) { String output = input + "_out"; - if (sign_result.getMimeType().equals(DetachedSignator_1_0_0.MIME_TYPE)) + if (sig_mode.equals("detached")) { output += ".xml"; } @@ -628,8 +689,7 @@ public abstract class Main * @throws PresentableException * Forwarded exception. */ - protected static void printUnrecognizedValue(final String parameter, - final String value) throws PresentableException + protected static void printUnrecognizedValue(final String parameter, final String value) throws PresentableException { System.err.println("The parameter " + parameter + " doesn't recognize the provided value '" + value + "'."); printUsage(System.out); @@ -643,8 +703,7 @@ public abstract class Main * @throws PresentableException * Forwarded exception. */ - protected static void printUnrecognizedAdditionalCommandlineArgument( - final String argument) throws PresentableException + protected static void printUnrecognizedAdditionalCommandlineArgument(final String argument) throws PresentableException { System.err.println("Unrecognized additional commandline argument '" + argument + "'."); printUsage(System.out); @@ -660,8 +719,7 @@ public abstract class Main * @throws PresentableException * Forwarded exception. */ - protected static void printMissingParameter(final String missing_term, - final String parameter) throws PresentableException + protected static void printMissingParameter(final String missing_term, final String parameter) throws PresentableException { printMissing(missing_term + " ('" + parameter + "' parameter)"); } @@ -686,23 +744,32 @@ public abstract class Main * @param ece * The ErrorCodeException to be printed. */ - protected static void printErrorCodeException(final ErrorCodeException ece) + protected static void printPresentableException(final PresentableException e) { - if (ece instanceof PlaceholderException) + if (e.getErrorCode() == ErrorCode.PLACEHOLDER_EXCEPTION) { - PlaceholderException phe = (PlaceholderException) ece; + PlaceholderException phe = null; + if (e instanceof PlaceholderException) + { + phe = (PlaceholderException) e; + } + else + { + phe = (PlaceholderException) e.getCause(); + } System.err.println("Der Platzhalter des Feldes " + phe.getField() + " ist um " + phe.getMissing() + " Bytes zu kurz. "); } - System.err.println("Fehler " + ece.getErrorCode() + ": " + ece.getErrorCodeMessage()); + System.err.println("Fehler " + e.getErrorCode() + ": " + ErrorCodeHelper.getMessageForErrorCode(e.getErrorCode())); - if (ece.hasExternalErrorMessage()) + if (e instanceof ExternalErrorException) { - System.err.println("Externer Fehlergrund: " + ece.getExternalErrorCode() + ": " + ece.getExternalErrorMessage()); + ExternalErrorException eee = (ExternalErrorException) e; + System.err.println("Externer Fehlergrund: " + eee.getExternalErrorCode() + ": " + eee.getExternalErrorMessage()); } - logger_.debug(ece.toString()); + logger_.debug(e); } /** @@ -753,8 +820,8 @@ public abstract class Main writer.println(" " + PARAMETER_SIGNATURE_MODE + " <" + VALUE_SIGNATURE_MODE_BINARY + "|" + VALUE_SIGNATURE_MODE_TEXTUAL + ">"); writer.println(" " + VALUE_SIGNATURE_MODE_BINARY + " ... signs the complete binary document"); writer.println(" " + VALUE_SIGNATURE_MODE_TEXTUAL + " ... signs only the textual portion of the document"); - writer.println(" " + VALUE_SIGNATURE_MODE_DETACHED + " ... signs the document using the binary mode and returns the xml signature of it."); - writer.println(" " + VALUE_SIGNATURE_MODE_DETACHED_TEXt + " ... signs the document using the textual mode and returns the xml signature of it."); + //writer.println(" " + VALUE_SIGNATURE_MODE_DETACHED + " ... signs the document using the binary mode and returns the xml signature of it."); + writer.println(" " + VALUE_SIGNATURE_MODE_DETACHED_TEXT + " ... signs the document using the textual mode and returns the xml signature of it."); writer.print(" " + PARAMETER_SIGNATURE_TYPE + " <"); SignatureTypes sig_types = SignatureTypes.getInstance(); @@ -831,7 +898,8 @@ public abstract class Main */ protected static boolean checkSignatureMode(String signature_mode) { - return signature_mode.equals(VALUE_SIGNATURE_MODE_BINARY) || signature_mode.equals(VALUE_SIGNATURE_MODE_TEXTUAL) || signature_mode.equals(VALUE_SIGNATURE_MODE_DETACHED) || signature_mode.equals(VALUE_SIGNATURE_MODE_DETACHED_TEXt); + return signature_mode.equals(VALUE_SIGNATURE_MODE_BINARY) || signature_mode.equals(VALUE_SIGNATURE_MODE_TEXTUAL) || signature_mode.equals(VALUE_SIGNATURE_MODE_DETACHED) + || signature_mode.equals(VALUE_SIGNATURE_MODE_DETACHED_TEXT); } /** @@ -892,7 +960,7 @@ public abstract class Main { return SignatorFactory.MOST_RECENT_DETACHED_SIGNATOR_ID; } - if (signature_mode.equals(VALUE_SIGNATURE_MODE_DETACHED_TEXt)) + if (signature_mode.equals(VALUE_SIGNATURE_MODE_DETACHED_TEXT)) { return SignatorFactory.MOST_RECENT_DETACHEDTEXT_SIGNATOR_ID; } @@ -909,7 +977,7 @@ public abstract class Main * @throws SettingNotFoundException * Forwarded exception. */ - protected static void formatVerifyResults(List results, PrintStream writer) throws SettingNotFoundException + protected static void formatVerifyResults(List results, PrintWriter writer) throws SettingNotFoundException { Iterator it = results.iterator(); while (it.hasNext()) @@ -934,8 +1002,7 @@ public abstract class Main * @throws SettingNotFoundException * Forwarded exception. */ - public static void formatSignatureResponse(SignatureResponse result, - PrintStream writer) throws SettingNotFoundException + public static void formatSignatureResponse(SignatureResponse result, PrintWriter writer) throws SettingNotFoundException { writer.println(" Zertifikat:"); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/ConnectorException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/ConnectorException.java index e660bb7..34c27b2 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/ConnectorException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/ConnectorException.java @@ -9,7 +9,7 @@ package at.knowcenter.wag.egov.egiz.exceptions; * * @author wprinz */ -public class ConnectorException extends SignatureException +public class ConnectorException extends PresentableException { /** @@ -45,12 +45,8 @@ public class ConnectorException extends SignatureException super(error_code, cause); } - /** - * @param error_code - */ - public ConnectorException(int error_code) + public ConnectorException(PresentableException cause) { - super(error_code); + super(cause.getErrorCode(), cause); } - } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/ConnectorFactoryException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/ConnectorFactoryException.java index 733ccb6..924400f 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/ConnectorFactoryException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/ConnectorFactoryException.java @@ -17,6 +17,8 @@ */ package at.knowcenter.wag.egov.egiz.exceptions; +import at.gv.egiz.pdfas.exceptions.ErrorCode; + /** * This exception is thrown when the connector factory encounters an error * during providing a connector. @@ -41,24 +43,24 @@ public class ConnectorFactoryException extends PresentableException */ public ConnectorFactoryException(String message) { - super(message); + super(ErrorCode.SETTINGS_EXCEPTION, message); } - /** - * @param message - * @param cause - */ - public ConnectorFactoryException(String message, Throwable cause) - { - super(message, cause); - } +// /** +// * @param message +// * @param cause +// */ +// public ConnectorFactoryException(String message, Throwable cause) +// { +// super(message, cause); +// } /** * @param cause */ public ConnectorFactoryException(Throwable cause) { - super(cause); + super(ErrorCode.SETTINGS_EXCEPTION, cause); } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/ErrorCodeException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/ErrorCodeException.java index 42fe597..ec21fb5 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/ErrorCodeException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/ErrorCodeException.java @@ -44,6 +44,8 @@ import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; * @author wlackner * @author wprinz (enforced error code) * + * @deprecated + * * @see at.knowcenter.wag.egov.egiz.cfg.SettingsReader */ public class ErrorCodeException extends PresentableException @@ -96,7 +98,7 @@ public class ErrorCodeException extends PresentableException */ public ErrorCodeException(final int error_code) { - super("error code " + error_code); + super(error_code, "just an error code"); this.error_code_ = error_code; loadSettings(); } @@ -112,7 +114,7 @@ public class ErrorCodeException extends PresentableException */ public ErrorCodeException(final int error_code, String message) { - super("error code " + error_code + ": " + message); + super(error_code, message); this.error_code_ = error_code; loadSettings(); } @@ -130,7 +132,7 @@ public class ErrorCodeException extends PresentableException */ public ErrorCodeException(final int error_code, String message, Throwable cause) { - super("error code " + error_code + ": " + message, cause); + super(error_code, message, cause); this.error_code_ = error_code; loadSettings(); } @@ -146,7 +148,7 @@ public class ErrorCodeException extends PresentableException */ public ErrorCodeException(final int error_code, Throwable cause) { - super("error code " + error_code, cause); + super(error_code, cause); this.error_code_ = error_code; loadSettings(); } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/InvalidIDException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/InvalidIDException.java index 33d189b..15f30ca 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/InvalidIDException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/InvalidIDException.java @@ -44,9 +44,4 @@ public class InvalidIDException extends SignatureException super(error_code, cause); } - public InvalidIDException(int error_code) - { - super(error_code); - } - } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/NormalizeException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/NormalizeException.java index 3675edb..2dd6cd4 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/NormalizeException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/NormalizeException.java @@ -19,13 +19,15 @@ */ package at.knowcenter.wag.egov.egiz.exceptions; +import at.gv.egiz.pdfas.exceptions.ErrorCode; + /** * This exception is thrown by the processing a normalizer. * * @author wlackner */ -public class NormalizeException extends ErrorCodeException { +public class NormalizeException extends PresentableException { /** * SVUID. @@ -37,36 +39,18 @@ public class NormalizeException extends ErrorCodeException { * @param message * @param cause */ - public NormalizeException(int error_code, String message, Throwable cause) + public NormalizeException(String message, Throwable cause) { - super(error_code, message, cause); + super(ErrorCode.NORMALIZER_EXCEPTION, message, cause); } /** * @param error_code * @param message */ - public NormalizeException(int error_code, String message) - { - super(error_code, message); - } - - /** - * @param error_code - * @param cause - */ - public NormalizeException(int error_code, Throwable cause) - { - super(error_code, cause); - } - - /** - * @param error_code - */ - public NormalizeException(int error_code) + public NormalizeException(String message) { - super(error_code); + super(ErrorCode.NORMALIZER_EXCEPTION, message); } - } \ No newline at end of file diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/PDFDocumentException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/PDFDocumentException.java index a0cf56a..f7fd09d 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/PDFDocumentException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/PDFDocumentException.java @@ -22,11 +22,11 @@ package at.knowcenter.wag.egov.egiz.exceptions; * * @author wlackner */ -public class PDFDocumentException extends ErrorCodeException +public class PDFDocumentException extends PresentableException { /** - * + * SVUID. */ private static final long serialVersionUID = -4595955288382226408L; @@ -58,12 +58,5 @@ public class PDFDocumentException extends ErrorCodeException super(error_code, cause); } - /** - * @param error_code - */ - public PDFDocumentException(int error_code) - { - super(error_code); - } } \ No newline at end of file diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/PlaceholderException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/PlaceholderException.java index 1c82c3c..7fdc06b 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/PlaceholderException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/PlaceholderException.java @@ -17,6 +17,8 @@ */ package at.knowcenter.wag.egov.egiz.exceptions; +import at.gv.egiz.pdfas.exceptions.ErrorCode; + /** * @author wprinz */ @@ -33,7 +35,7 @@ public class PlaceholderException extends PDFDocumentException public PlaceholderException(String field, int missing) { - super(700, field + ":" + missing); + super(ErrorCode.PLACEHOLDER_EXCEPTION, field + ":" + missing); this.field = field; this.missing = missing; diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/PresentableException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/PresentableException.java index ab87002..218109d 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/PresentableException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/PresentableException.java @@ -36,30 +36,47 @@ public class PresentableException extends Exception * SVUID. */ private static final long serialVersionUID = -102406558526000792L; + + protected int errorCode = -1; /** * @param message */ - public PresentableException(String message) + public PresentableException(int errorCode, String message) { super(message); + + this.errorCode = errorCode; } /** * @param message * @param cause */ - public PresentableException(String message, Throwable cause) + public PresentableException(int errorCode, String message, Throwable cause) { super(message, cause); + + this.errorCode = errorCode; } /** * @param cause */ - public PresentableException(Throwable cause) + public PresentableException(int errorCode, Throwable cause) { super(cause); + + this.errorCode = errorCode; + } + + /** + * Returns the error code of this exception. + * @return Returns the error code of this exception. + */ + public int getErrorCode () + { + return this.errorCode; } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SettingNotFoundException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SettingNotFoundException.java index 02a3b5b..b117fdb 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SettingNotFoundException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SettingNotFoundException.java @@ -17,13 +17,15 @@ */ package at.knowcenter.wag.egov.egiz.exceptions; +import at.gv.egiz.pdfas.exceptions.ErrorCode; + /** * This exception is thrown by the SettingsReader if a property key is not * found. * * @author wlackner */ -public class SettingNotFoundException extends ErrorCodeException +public class SettingNotFoundException extends PresentableException { /** @@ -36,35 +38,32 @@ public class SettingNotFoundException extends ErrorCodeException * @param message * @param cause */ - public SettingNotFoundException(int error_code, String message, Throwable cause) + public SettingNotFoundException(String message, Throwable cause) { - super(error_code, message, cause); + super(ErrorCode.SETTING_NOT_FOUND, message, cause); } /** * @param error_code * @param message */ - public SettingNotFoundException(int error_code, String message) + public SettingNotFoundException(String message) { - super(error_code, message); + super(ErrorCode.SETTING_NOT_FOUND, message); } /** * @param error_code * @param cause */ - public SettingNotFoundException(int error_code, Throwable cause) + public SettingNotFoundException(Throwable cause) { - super(error_code, cause); + super(ErrorCode.SETTING_NOT_FOUND, cause); } - - /** - * @param error_code - */ - public SettingNotFoundException(int error_code) + + protected SettingNotFoundException(int errorCode, String message) { - super(error_code); + super(errorCode, message); } } \ No newline at end of file diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SettingsException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SettingsException.java index c53e6f2..d781577 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SettingsException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SettingsException.java @@ -17,6 +17,8 @@ */ package at.knowcenter.wag.egov.egiz.exceptions; +import at.gv.egiz.pdfas.exceptions.ErrorCode; + /** * Thrown when the settings couldn't be loaded. * @@ -40,7 +42,7 @@ public class SettingsException extends PresentableException */ public SettingsException(String message) { - super(message); + super(ErrorCode.SETTINGS_EXCEPTION, message); } /** @@ -49,15 +51,6 @@ public class SettingsException extends PresentableException */ public SettingsException(String message, Throwable cause) { - super(message, cause); - } - - /** - * @param cause - */ - public SettingsException(Throwable cause) - { - super(cause); + super(ErrorCode.SETTINGS_EXCEPTION, message, cause); } - } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SignatorFactoryException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SignatorFactoryException.java index dea7cfc..53a88de 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SignatorFactoryException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SignatorFactoryException.java @@ -17,6 +17,8 @@ */ package at.knowcenter.wag.egov.egiz.exceptions; +import at.gv.egiz.pdfas.exceptions.ErrorCode; + /** * Exception coming out of the SignatorFactory. * @author wprinz @@ -31,7 +33,7 @@ public class SignatorFactoryException extends PresentableException public SignatorFactoryException(String message) { - super(message); + super(ErrorCode.SETTINGS_EXCEPTION, message); } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SignatureException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SignatureException.java index f036f49..dc69722 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SignatureException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SignatureException.java @@ -25,7 +25,7 @@ package at.knowcenter.wag.egov.egiz.exceptions; * * @author wlackner */ -public class SignatureException extends ErrorCodeException { +public class SignatureException extends PresentableException { /** * SVUID. @@ -62,10 +62,11 @@ public class SignatureException extends ErrorCodeException { /** * @param error_code + * @param cause */ - public SignatureException(int error_code) + public SignatureException(PresentableException cause) { - super(error_code); + super(cause.getErrorCode(), cause); } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SignatureTypesException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SignatureTypesException.java index 4f51418..d8f46db 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SignatureTypesException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/SignatureTypesException.java @@ -17,8 +17,11 @@ */ package at.knowcenter.wag.egov.egiz.exceptions; +import at.gv.egiz.pdfas.exceptions.ErrorCode; + /** * Exception for Signature Type problems. + * * @author wprinz */ public class SignatureTypesException extends PresentableException @@ -34,24 +37,31 @@ public class SignatureTypesException extends PresentableException */ public SignatureTypesException(String message) { - super(message); + super(ErrorCode.SIGNATURE_TYPES_EXCEPTION, message); } - /** - * @param message - * @param cause - */ - public SignatureTypesException(String message, Throwable cause) - { - super(message, cause); - } +// /** +// * @param message +// * @param cause +// */ +// public SignatureTypesException(String message, Throwable cause) +// { +// super(ErrorCode.SIGNATURE_TYPES_EXCEPTION, message, cause); +// } + + // /** + // * @param cause + // */ + // public SignatureTypesException(Throwable cause) + // { + // super(ErrorCode.SIGNATURE_TYPES_EXCEPTION, cause); + // } /** * @param cause */ - public SignatureTypesException(Throwable cause) + public SignatureTypesException(PresentableException cause) { - super(cause); + super(cause.getErrorCode(), cause); } - } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/WebException.java b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/WebException.java index 5f72211..7d06b6a 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/WebException.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/exceptions/WebException.java @@ -19,54 +19,48 @@ */ package at.knowcenter.wag.egov.egiz.exceptions; +import at.gv.egiz.pdfas.exceptions.ErrorCode; + /** * Exception for web problems. * @author wlackner */ -public class WebException extends ErrorCodeException { +public class WebException extends PresentableException { /** * SVUID. */ private static final long serialVersionUID = 4329890155872840492L; +// /** +// * @param error_code +// * @param message +// * @param cause +// */ +// public WebException(int error_code, String message, Throwable cause) +// { +// super(error_code, message, cause); +// } +// +// /** +// * @param error_code +// * @param message +// */ +// public WebException(int error_code, String message) +// { +// super(error_code, message); +// } +// + /** * @param error_code - * @param message * @param cause */ - public WebException(int error_code, String message, Throwable cause) + public WebException(Throwable cause) { - super(error_code, message, cause); + super(ErrorCode.WEB_EXCEPTION, cause); } - /** - * @param error_code - * @param message - */ - public WebException(int error_code, String message) - { - super(error_code, message); - } - - /** - * @param error_code - * @param cause - */ - public WebException(int error_code, Throwable cause) - { - super(error_code, cause); - } - - /** - * @param error_code - */ - public WebException(int error_code) - { - super(error_code); - } - - } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/Signator.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/Signator.java index 8d1688c..2d90005 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/Signator.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/Signator.java @@ -17,6 +17,7 @@ */ package at.knowcenter.wag.egov.egiz.framework; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; import at.knowcenter.wag.egov.egiz.PdfASID; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; @@ -64,7 +65,7 @@ public interface Signator * @throws PresentableException * Forwarded exception. */ - public IncrementalUpdateInformation prepareSign(byte[] pdf, + public IncrementalUpdateInformation prepareSign(PdfDataSource pdfDataSource, String signature_type, TablePos pos, boolean has_SIG_ID) throws PresentableException; /** diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/SignatorFactory.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/SignatorFactory.java index c26055f..01155a8 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/SignatorFactory.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/SignatorFactory.java @@ -82,7 +82,7 @@ public abstract class SignatorFactory /** * The most recent test algorithm this application provides. */ - public static final PdfASID MOST_RECENT_DETACHED_SIGNATOR_ID = DetachedSignator_1_0_0.MY_ID; + public static final PdfASID MOST_RECENT_DETACHED_SIGNATOR_ID = DetachedfTextualSignator_1_0_0.MY_ID; /** * The most recent test algorithm this application provides. diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/VerificationFilter.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/VerificationFilter.java index da5a8dc..2631028 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/VerificationFilter.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/VerificationFilter.java @@ -17,6 +17,7 @@ */ package at.knowcenter.wag.egov.egiz.framework; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -24,6 +25,8 @@ import java.io.PrintStream; import java.util.ArrayList; import java.util.List; +import at.gv.egiz.pdfas.exceptions.ErrorCode; + import org.apache.log4j.Logger; import at.knowcenter.wag.egov.egiz.PdfAS; @@ -43,6 +46,7 @@ import at.knowcenter.wag.egov.egiz.pdf.BinarySignature; import at.knowcenter.wag.egov.egiz.pdf.Placeholder; import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; import at.knowcenter.wag.egov.egiz.pdf.StringInfo; +import at.knowcenter.wag.egov.egiz.pdf.TextualSignatureHolder; import at.knowcenter.wag.exactparser.ParseDocument; import at.knowcenter.wag.exactparser.parsing.IndirectObjectReference; import at.knowcenter.wag.exactparser.parsing.PDFUtils; @@ -64,6 +68,8 @@ import at.knowcenter.wag.exactparser.parsing.results.ObjectParseResult; * in the document. *

* + * @deprecated use the new at.gv.egiz.framework instead + * * @author wprinz * @author amavriqi */ @@ -105,6 +111,7 @@ public class VerificationFilter return extractSignaturesFromPdf(pdf, false); } + //@deprecated public List extractSignaturesFromPdf(final byte[] pdf, boolean ignorePostSignModificationsRestriction) throws PresentableException { @@ -178,7 +185,7 @@ public class VerificationFilter } else { - // FIXME make better + // TODO: make better - already deprecated //amavriqi: skip checking for old sigs becouse of performance issues String old_text_sigs = SettingsReader.getInstance().getSetting("check_old_textual_sigs", "false"); @@ -201,7 +208,7 @@ public class VerificationFilter current_block_contains_signature = true; } - // FIXME make better + // TODO: make better - already deprecated //amavriqi: only if old textual signatures are checked for if(old_text_sigs.equalsIgnoreCase("true")){ if (prev_end == 0) @@ -209,7 +216,7 @@ public class VerificationFilter String rest_text = null; if (!text_holders.isEmpty()) { - SignatureHolder first_holder = (SignatureHolder) text_holders.get(0); + TextualSignatureHolder first_holder = (TextualSignatureHolder) text_holders.get(0); rest_text = first_holder.getSignedText(); } else @@ -218,7 +225,7 @@ public class VerificationFilter logger_.debug("Incemental block" + prev_end + " and there are " + text_holders.size() + " text holders"); logger_.debug("Checking for older textual Signatures"); logger_.debug("Extracting text to " + bpr.next_index); - rest_text = PdfAS.extractNormalizedTextTextual(pdf, bpr.next_index); + rest_text = PdfAS.extractNormalizedTextTextual(new ByteArrayInputStream(pdf), bpr.next_index); } List old_holders = PdfAS.extractSignatureHoldersTextual(rest_text, true); @@ -371,7 +378,7 @@ public class VerificationFilter String rest_text = normalized_text; if (!text_holders.isEmpty()) { - SignatureHolder holder = (SignatureHolder) text_holders.get(0); + TextualSignatureHolder holder = (TextualSignatureHolder) text_holders.get(0); rest_text = holder.getSignedText(); } @@ -492,7 +499,7 @@ public class VerificationFilter } catch (IOException e1) { - throw new PDFDocumentException(201); + throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e1); } } @@ -530,23 +537,24 @@ public class VerificationFilter } - public static void main(String[] args) throws IOException, PresentableException - { - SettingsReader.initializeForCommandLine(); - - File in = new File(args[0]); - FileInputStream fis = new FileInputStream(in); - byte[] pdf = new byte[(int) in.length()]; - fis.read(pdf); - fis.close(); - - String text = PdfAS.extractNormalizedTextTextual(pdf, pdf.length);; - - VerificationFilter vf = new VerificationFilter(); - //List found = vf.extractSignaturesFromPdf(pdf); - - List found = vf.extractSignaturesFromPlainText(text); - - printFoundHolders("Final Holders", found, System.out); - } + // TODO old code - remove +// public static void main(String[] args) throws IOException, PresentableException +// { +// SettingsReader.initializeForCommandLine(); +// +// File in = new File(args[0]); +// FileInputStream fis = new FileInputStream(in); +// byte[] pdf = new byte[(int) in.length()]; +// fis.read(pdf); +// fis.close(); +// +// String text = PdfAS.extractNormalizedTextTextual(pdf, pdf.length);; +// +// VerificationFilter vf = new VerificationFilter(); +// //List found = vf.extractSignaturesFromPdf(pdf); +// +// List found = vf.extractSignaturesFromPlainText(text); +// +// printFoundHolders("Final Holders", found, System.out); +// } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/Verificator.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/Verificator.java index b17fc79..e70c44a 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/Verificator.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/Verificator.java @@ -28,6 +28,8 @@ import at.knowcenter.wag.exactparser.parsing.results.FooterParseResult; * extracts all Signatures of its type and returns them as valitatable * SignatureHolders. * + * @deprecated replaced by the one in framework + * * @author wprinz */ public interface Verificator diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java index 2c5ecf5..0ecff57 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java @@ -17,11 +17,17 @@ */ package at.knowcenter.wag.egov.egiz.framework.signators; +import java.io.IOException; +import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import at.gv.egiz.pdfas.impl.input.CompoundPdfDataSourceImpl; +import at.gv.egiz.pdfas.impl.signator.IncrementalUpdateHelper; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.PdfASID; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; @@ -60,6 +66,8 @@ import com.lowagie.text.pdf.PdfPTable; * values according to the encoding. *

* + * @deprecated movet to nc-framework + * * @author wprinz */ public class BinarySignator_1_0_0 implements Signator @@ -89,8 +97,7 @@ public class BinarySignator_1_0_0 implements Signator * @see at.knowcenter.wag.egov.egiz.framework.Signator#prepareSign(byte[], * String, TablePos, boolean) */ - public IncrementalUpdateInformation prepareSign(byte[] pdf, - String signature_type, TablePos pos, boolean has_SIG_ID) throws PresentableException + public IncrementalUpdateInformation prepareSign(PdfDataSource pdf, String signature_type, TablePos pos, boolean has_SIG_ID) throws PresentableException { try { @@ -117,13 +124,12 @@ public class BinarySignator_1_0_0 implements Signator variable_field_definitions.add(sfd); } } - IncrementalUpdateInformation iui = BinarySignature.writeIncrementalUpdate(pdf, pdf_table, pi, variable_field_definitions, all_field_definitions); + IncrementalUpdateInformation iui = IncrementalUpdateHelper.writeIncrementalUpdate(pdf, pdf_table, pi, variable_field_definitions, all_field_definitions); String temp_string = iui.temp_ir_number + " " + iui.temp_ir_generation + " obj"; //$NON-NLS-1$//$NON-NLS-2$ byte[] temp_bytes = temp_string.getBytes("US-ASCII"); //$NON-NLS-1$ int temp_start = ByteArrayUtils.lastIndexOf(iui.signed_pdf, temp_bytes); - byte[] stream_bytes = new byte[] { '>', '>', 's', 't', 'r', 'e', 'a', - 'm', 0x0A }; + byte[] stream_bytes = new byte[] { '>', '>', 's', 't', 'r', 'e', 'a', 'm', 0x0A }; int stream_start = ByteArrayUtils.indexOf(iui.signed_pdf, temp_start, stream_bytes); iui.content_stream_start = stream_start + stream_bytes.length; @@ -153,6 +159,8 @@ public class BinarySignator_1_0_0 implements Signator // byte [] old_signed_pdf = iui.signed_pdf; iui.signed_pdf = BinarySignature.prepareDataToSign(iui.signed_pdf, iui.byte_ranges); + reduceToIUBlock(iui); + iui.signature_data = formSignatureData(iui); return iui; @@ -170,8 +178,11 @@ public class BinarySignator_1_0_0 implements Signator */ public SignResult finishSign(IncrementalUpdateInformation iui) throws PresentableException { + restoreSignedPdf(iui); + // PdfAS.prefixID(iui.signed_signature_object, PdfAS.BINARY_ID); fillReplacesWithValues(iui); + BinarySignature.replaceCertificate(iui); BinarySignature.replacePlaceholders(iui); @@ -192,11 +203,38 @@ public class BinarySignator_1_0_0 implements Signator while (it.hasNext()) { ReplaceInfo ri = (ReplaceInfo) it.next(); - + ri.value = SignSignatureObjectHelper.retrieveStringValueFromSignatureObject(iui.signed_signature_object, ri.sfd.field_name); } } + protected void reduceToIUBlock(IncrementalUpdateInformation iui) + { + byte[] iu_block = new byte[iui.signed_pdf.length - iui.original_document.getLength()]; + System.arraycopy(iui.signed_pdf, iui.original_document.getLength(), iu_block, 0, iu_block.length); + + iui.signed_pdf = null; + iui.sign_iui_block = iu_block; + } + + protected void restoreSignedPdf(IncrementalUpdateInformation iui) + { + iui.signed_pdf = new byte[iui.original_document.getLength() + iui.sign_iui_block.length]; + + try + { + InputStream is = iui.original_document.createInputStream(); + is.read(iui.signed_pdf, 0, iui.original_document.getLength()); + is.close(); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + + System.arraycopy(iui.sign_iui_block, 0, iui.signed_pdf, iui.original_document.getLength(), iui.sign_iui_block.length); + } + /** * Forms the SignatureData to be used for signing. * @@ -206,18 +244,22 @@ public class BinarySignator_1_0_0 implements Signator */ protected SignatureData formSignatureData(IncrementalUpdateInformation iui) { - String document_text = BinarySignature.retrieveSignableTextFromData(iui.signed_pdf, iui.signed_pdf.length); // signed_pdf.length); - - byte[] data; - try - { - data = document_text.getBytes("UTF-8"); //$NON-NLS-1$ - } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException("Very strange: UTF-8 character encoding not supported.", e); //$NON-NLS-1$ - } - SignatureData signature_data = new SignatureDataImpl(data, PdfAS.PDF_MIME_TYPE); + // String document_text = + // BinarySignature.retrieveSignableTextFromData(iui.signed_pdf, + // iui.signed_pdf.length); // signed_pdf.length); + // + // byte[] data; + // try + // { + // data = document_text.getBytes("UTF-8"); //$NON-NLS-1$ + // } + // catch (UnsupportedEncodingException e) + // { + // throw new RuntimeException("Very strange: UTF-8 character encoding not + // supported.", e); //$NON-NLS-1$ + // } + DataSource ds = new CompoundPdfDataSourceImpl(iui.original_document, iui.sign_iui_block); + SignatureData signature_data = new SignatureDataImpl(ds, PdfAS.PDF_MIME_TYPE); return signature_data; } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_1_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_1_0.java index 174f0b6..b6e18ed 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_1_0.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_1_0.java @@ -17,6 +17,12 @@ */ package at.knowcenter.wag.egov.egiz.framework.signators; +import java.io.ByteArrayInputStream; + +import at.gv.egiz.pdfas.impl.input.ByteArrayPdfDataSourceImpl; +import at.gv.egiz.pdfas.impl.input.CompoundPdfDataSourceImpl; +import at.gv.egiz.pdfas.framework.input.DataSource; + import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.PdfASID; import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; @@ -34,6 +40,8 @@ import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl; * * @see BinarySignator_1_0_0 * + * @deprecated moved to nc-framework + * * @author wprinz */ public class BinarySignator_1_1_0 extends BinarySignator_1_0_0 @@ -59,7 +67,8 @@ public class BinarySignator_1_1_0 extends BinarySignator_1_0_0 */ protected SignatureData formSignatureData(IncrementalUpdateInformation iui) { - SignatureData signature_data = new SignatureDataImpl(iui.signed_pdf, PdfAS.PDF_MIME_TYPE); + DataSource ds = new CompoundPdfDataSourceImpl(iui.original_document, iui.sign_iui_block); + SignatureData signature_data = new SignatureDataImpl(ds, PdfAS.PDF_MIME_TYPE); return signature_data; } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java index 5d0fd65..4ef1e15 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedSignator_1_0_0.java @@ -17,8 +17,14 @@ */ package at.knowcenter.wag.egov.egiz.framework.signators; +import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; +import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl; +import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; + import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.PdfASID; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; @@ -73,7 +79,7 @@ public class DetachedSignator_1_0_0 implements Signator * @see at.knowcenter.wag.egov.egiz.framework.Signator#prepareSign(byte[], * String, TablePos, boolean) */ - public IncrementalUpdateInformation prepareSign(byte[] pdf, + public IncrementalUpdateInformation prepareSign(PdfDataSource pdf, String signature_type, TablePos pos, boolean has_SIG_ID) throws PresentableException { IncrementalUpdateInformation iui = new IncrementalUpdateInformation(); @@ -81,17 +87,11 @@ public class DetachedSignator_1_0_0 implements Signator iui.signature_type = signature_type; iui.pos = pos; - String document_text = PdfAS.extractNormalizedTextTextual(pdf); + String document_text = PdfAS.extractNormalizedTextTextual(pdf.createInputStream()); // logger_.debug("signed_text = " + document_text); - try - { - iui.signature_data = new SignatureDataImpl(document_text.getBytes("UTF-8"), MIME_TYPE, "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$ - } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException("Very strange: UTF-8 character encoding not supported???"); //$NON-NLS-1$ - } + DataSource ds = new TextDataSourceImpl(document_text); + iui.signature_data = new SignatureDataImpl(ds, MIME_TYPE, "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$ return iui; } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java index 93f10ff..d7c79ea 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/DetachedfTextualSignator_1_0_0.java @@ -17,8 +17,14 @@ */ package at.knowcenter.wag.egov.egiz.framework.signators; +import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; +import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl; +import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; + import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.PdfASID; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; @@ -81,7 +87,7 @@ public class DetachedfTextualSignator_1_0_0 implements Signator * @see at.knowcenter.wag.egov.egiz.framework.Signator#prepareSign(byte[], * String, TablePos, boolean) */ - public IncrementalUpdateInformation prepareSign(byte[] pdf, + public IncrementalUpdateInformation prepareSign(PdfDataSource pdf, String signature_type, TablePos pos, boolean has_SIG_ID) throws PresentableException { IncrementalUpdateInformation iui = new IncrementalUpdateInformation(); @@ -89,17 +95,11 @@ public class DetachedfTextualSignator_1_0_0 implements Signator iui.signature_type = signature_type; iui.pos = pos; - String document_text = PdfAS.extractNormalizedTextTextual(pdf); + String document_text = PdfAS.extractNormalizedTextTextual(pdf.createInputStream()); // logger_.debug("signed_text = " + document_text); - try - { - iui.signature_data = new SignatureDataImpl(document_text.getBytes("UTF-8"), MIME_TYPE, "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$ - } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException("Very strange: UTF-8 character encoding not supported???"); //$NON-NLS-1$ - } + DataSource ds = new TextDataSourceImpl(document_text); + iui.signature_data = new SignatureDataImpl(ds, MIME_TYPE, "UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$ return iui; } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java index 7fe9e4f..33de15e 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java @@ -17,15 +17,16 @@ */ package at.knowcenter.wag.egov.egiz.framework.signators; -import java.io.UnsupportedEncodingException; - +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl; +import at.gv.egiz.pdfas.impl.signator.IncrementalUpdateHelper; import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.PdfASID; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; import at.knowcenter.wag.egov.egiz.framework.SignResult; import at.knowcenter.wag.egov.egiz.framework.Signator; import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; -import at.knowcenter.wag.egov.egiz.pdf.BinarySignature; import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation; import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; import at.knowcenter.wag.egov.egiz.pdf.TablePos; @@ -80,7 +81,7 @@ public class TextualSignator_1_0_0 implements Signator * @see at.knowcenter.wag.egov.egiz.framework.Signator#prepareSign(byte[], * String, TablePos, boolean) */ - public IncrementalUpdateInformation prepareSign(byte[] pdf, + public IncrementalUpdateInformation prepareSign(PdfDataSource pdf, String signature_type, TablePos pos, boolean has_SIG_ID) throws PresentableException { IncrementalUpdateInformation iui = new IncrementalUpdateInformation(); @@ -88,17 +89,11 @@ public class TextualSignator_1_0_0 implements Signator iui.signature_type = signature_type; iui.pos = pos; - String document_text = PdfAS.extractNormalizedTextTextual(pdf); + String document_text = PdfAS.extractNormalizedTextTextual(pdf.createInputStream()); // logger_.debug("signed_text = " + document_text); - try - { - iui.signature_data = new SignatureDataImpl(document_text.getBytes("UTF-8"), "text/plain", "UTF-8"); - } - catch (UnsupportedEncodingException e) - { - throw new RuntimeException("Very strange: UTF-8 character encoding not supported???"); //$NON-NLS-1$ - } + DataSource ds = new TextDataSourceImpl(document_text); + iui.signature_data = new SignatureDataImpl(ds, "text/plain", "UTF-8"); return iui; } @@ -118,7 +113,7 @@ public class TextualSignator_1_0_0 implements Signator PositioningInstruction pi = PdfAS.determineTablePositioning(iui.pos, iui.signature_type, iui.original_document, pdf_table); - IncrementalUpdateInformation signed_iui = BinarySignature.writeIncrementalUpdate(iui.original_document, pdf_table, pi, null, null); + IncrementalUpdateInformation signed_iui = IncrementalUpdateHelper.writeIncrementalUpdate(iui.original_document, pdf_table, pi, null, null); SignResult sign_result = new SignResult(PdfAS.PDF_MIME_TYPE, signed_iui.signed_pdf); return sign_result; diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/BinaryVerificator_1_0_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/BinaryVerificator_1_0_0.java index 469fcee..b389a25 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/BinaryVerificator_1_0_0.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/BinaryVerificator_1_0_0.java @@ -22,6 +22,10 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.impl.input.ByteArrayPdfDataSourceImpl; + import org.apache.log4j.Logger; import at.knowcenter.wag.egov.egiz.PdfASID; @@ -52,11 +56,12 @@ import at.knowcenter.wag.exactparser.parsing.results.NumberParseResult; import at.knowcenter.wag.exactparser.parsing.results.ObjectParseResult; import at.knowcenter.wag.exactparser.parsing.results.ParseResult; - /** * The BinaryVerificator parses the EGIT Dictionary and extracts the signature * holder from it. * + * @deprecated moved to the new framework + * * @author wprinz */ public class BinaryVerificator_1_0_0 implements Verificator @@ -66,6 +71,16 @@ public class BinaryVerificator_1_0_0 implements Verificator */ public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_BINARY, SignatorFactory.VERSION_1_0_0); + /** + * Use this to override the MY_ID field. + * + * @return Returns the Id of this Verificator. + */ + protected PdfASID getMyId() + { + return MY_ID; + } + /** * The /ODS key in the EGIZ Dict. */ @@ -79,20 +94,17 @@ public class BinaryVerificator_1_0_0 implements Verificator /** * The /ByteRange key in the EGIZ Dict. */ - public static final byte[] EGIZ_BYTE_RANGE_NAME = new byte[] { 'B', 'y', 't', - 'e', 'R', 'a', 'n', 'g', 'e' }; + public static final byte[] EGIZ_BYTE_RANGE_NAME = new byte[] { 'B', 'y', 't', 'e', 'R', 'a', 'n', 'g', 'e' }; /** * The /replaces key in the EGIZ Dict. */ - public static final byte[] EGIZ_REPLACES_NAME = new byte[] { 'r', 'e', 'p', - 'l', 'a', 'c', 'e', 's' }; + public static final byte[] EGIZ_REPLACES_NAME = new byte[] { 'r', 'e', 'p', 'l', 'a', 'c', 'e', 's' }; /** * The /encodings key in the EGIZ Dict. */ - public static final byte[] EGIZ_ENCODINGS_NAME = new byte[] { 'e', 'n', 'c', - 'o', 'd', 'i', 'n', 'g', 's' }; + public static final byte[] EGIZ_ENCODINGS_NAME = new byte[] { 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g', 's' }; /** * The /Cert key in the EGIZ Dict. @@ -116,13 +128,12 @@ public class BinaryVerificator_1_0_0 implements Verificator * @see at.knowcenter.wag.egov.egiz.framework.Verificator#parseBlock(byte[], * at.knowcenter.wag.exactparser.parsing.results.FooterParseResult, int) */ - public List parseBlock(byte[] pdf, FooterParseResult block, - int start_of_whole_block) throws PresentableException + public List parseBlock(byte[] pdf, FooterParseResult block, int start_of_whole_block) throws PresentableException { int egiz_index = PDFUtils.indexOfName(pdf, block.tpr.dpr.names, VerificationFilter.EGIZ_DICT_NAME); if (egiz_index < 0) { - throw new PDFDocumentException(301, "egiz_index = " + egiz_index); + throw new PDFDocumentException(ErrorCode.COULDNT_VERIFY, "egiz_index = " + egiz_index); } IndirectObjectReferenceParseResult egiz_dict_iorpr = (IndirectObjectReferenceParseResult) block.tpr.dpr.values.get(egiz_index); @@ -140,7 +151,7 @@ public class BinaryVerificator_1_0_0 implements Verificator PdfASID kz = null; String kz_string = VerificationFilter.restoreKZ(pdf, kz_apr); kz = new PdfASID(kz_string); - if (!kz_string.equals(MY_ID.toString())) + if (!kz_string.equals(getMyId().toString())) { logger_.warn("Warning: Kennzeichnung not recognized:" + kz_string); } @@ -223,7 +234,9 @@ public class BinaryVerificator_1_0_0 implements Verificator // bbi); byte[] signed_pdf = BinarySignature.prepareDataToSign(pdf, byte_ranges); - //String signed_text = BinarySignature.retrieveSignableTextFromData(signed_pdf, signed_pdf.length); // has been moved into the BinarySignatureHolder + // String signed_text = + // BinarySignature.retrieveSignableTextFromData(signed_pdf, + // signed_pdf.length); // has been moved into the BinarySignatureHolder SignatureObject signature_object = new SignatureObject(); String default_type = SettingsReader.getInstance().getValueFromKey(SignatureTypes.DEFAULT_TYPE); @@ -300,8 +313,9 @@ public class BinaryVerificator_1_0_0 implements Verificator } } - // FIXME make better - BinarySignatureHolder signature_holder = new BinarySignatureHolder(signed_pdf, signed_pdf.length, signature_object); + // FIXME This blows up the session !!!!! + PdfDataSource ds = new ByteArrayPdfDataSourceImpl(signed_pdf, signed_pdf.length); + BinarySignatureHolder signature_holder = new BinarySignatureHolder(ds, signature_object); List holders = new ArrayList(); holders.add(signature_holder); @@ -322,8 +336,7 @@ public class BinaryVerificator_1_0_0 implements Verificator * @throws PDFDocumentException * Thrown, if the key doesn't exist in the dictionary. */ - protected ParseResult getRequiredValueOfKey(byte[] pdf, - DictionaryParseResult egiz_dict, byte[] name) throws PDFDocumentException + protected ParseResult getRequiredValueOfKey(byte[] pdf, DictionaryParseResult egiz_dict, byte[] name) throws PDFDocumentException { final int index = PDFUtils.indexOfName(pdf, egiz_dict.names, name); checkIndex(index); @@ -343,7 +356,7 @@ public class BinaryVerificator_1_0_0 implements Verificator { if (name_index < 0) { - throw new PDFDocumentException(301, "The name wasn't found in the egiz dict."); + throw new PDFDocumentException(ErrorCode.COULDNT_VERIFY, "The name wasn't found in the egiz dict."); } } @@ -359,8 +372,7 @@ public class BinaryVerificator_1_0_0 implements Verificator * @return Returns the key's value, or null if the dictionary didn't contain * that key. */ - protected ParseResult getValueOfKey(byte[] pdf, - DictionaryParseResult egiz_dict, byte[] name) + protected ParseResult getValueOfKey(byte[] pdf, DictionaryParseResult egiz_dict, byte[] name) { final int index = PDFUtils.indexOfName(pdf, egiz_dict.names, name); if (index < 0) diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/BinaryVerificator_1_1_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/BinaryVerificator_1_1_0.java new file mode 100644 index 0000000..efbc4f8 --- /dev/null +++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/BinaryVerificator_1_1_0.java @@ -0,0 +1,24 @@ +/** + * + */ +package at.knowcenter.wag.egov.egiz.framework.verificators; + +import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; + +/** + * @author wprinz + * + */ +public class BinaryVerificator_1_1_0 extends BinaryVerificator_1_0_0 +{ + public static final PdfASID MY_ID = new PdfASID(SignatorFactory.VENDOR, SignatorFactory.TYPE_BINARY, SignatorFactory.VERSION_1_1_0); + + /** + * @see at.knowcenter.wag.egov.egiz.framework.verificators.BinaryVerificator_1_0_0#getMyId() + */ + protected PdfASID getMyId() + { + return MY_ID; + } +} diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/TextualVerificator_1_0_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/TextualVerificator_1_0_0.java index fccdfd0..176c0f0 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/TextualVerificator_1_0_0.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/TextualVerificator_1_0_0.java @@ -17,6 +17,7 @@ */ package at.knowcenter.wag.egov.egiz.framework.verificators; +import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.List; @@ -49,6 +50,8 @@ import at.knowcenter.wag.exactparser.parsing.results.FooterParseResult; * Note that it will not find old style blocks as they don't have the SIG_KZ. *

* + * @deprecated moved to the new framework + * * @author wprinz */ public class TextualVerificator_1_0_0 implements Verificator @@ -78,7 +81,7 @@ public class TextualVerificator_1_0_0 implements Verificator public List parseBlock(byte[] pdf, FooterParseResult block, int start_of_whole_block) throws PresentableException { - String block_text = PdfAS.extractNormalizedTextTextual(pdf, block.next_index); + String block_text = PdfAS.extractNormalizedTextTextual(new ByteArrayInputStream(pdf), block.next_index); logger_.debug("Scanning block:"); //List signature_holders = PdfAS.extractSignatureHoldersTextual(block_text, false); @@ -97,7 +100,7 @@ public class TextualVerificator_1_0_0 implements Verificator { text_holder_candidates = new ArrayList(); - String prev_text = PdfAS.extractNormalizedTextTextual(pdf, start_of_whole_block); + String prev_text = PdfAS.extractNormalizedTextTextual(new ByteArrayInputStream(pdf), start_of_whole_block); logger_.debug("Scanning prev block:"); //List prev_signature_holders = PdfAS.extractSignatureHoldersTextual(prev_text, false); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/TextualVerificator_pdfasold.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/TextualVerificator_pdfasold.java index 5008ed3..ea84e7e 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/TextualVerificator_pdfasold.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/verificators/TextualVerificator_pdfasold.java @@ -17,6 +17,7 @@ */ package at.knowcenter.wag.egov.egiz.framework.verificators; +import java.io.ByteArrayInputStream; import java.util.List; import org.apache.log4j.Logger; @@ -60,7 +61,7 @@ public class TextualVerificator_pdfasold implements Verificator throw new PDFDocumentException(201, "The PDF-AS-old Verificator can only be applied on original documents."); } - String normalized_text = PdfAS.extractNormalizedTextTextual(pdf, block.next_index); + String normalized_text = PdfAS.extractNormalizedTextTextual(new ByteArrayInputStream(pdf), block.next_index); logger_.debug("Scanning block:"); List signature_holders = PdfAS.extractSignatureHoldersTextual(normalized_text, true); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java index a5d1be8..4219475 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java @@ -75,7 +75,7 @@ public class AbsoluteTextSignature String current_text = text; for (;;) { - SignatureHolder signature_holder = extractLatestBlock(current_text); + TextualSignatureHolder signature_holder = extractLatestBlock(current_text); if (signature_holder == null) { break; @@ -99,7 +99,7 @@ public class AbsoluteTextSignature * @throws SignatureTypesException * F.e. */ - public static SignatureHolder extractLatestBlock(String text) throws SignatureException, SignatureTypesException + public static TextualSignatureHolder extractLatestBlock(String text) throws SignatureException, SignatureTypesException { FoundBlock latest_block = findLatestBlock(text); if (latest_block == null) diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java index fb93fbd..d253393 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java @@ -24,6 +24,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -35,17 +36,16 @@ import java.util.Comparator; import java.util.Iterator; import java.util.List; +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.gv.egiz.pdfas.exceptions.pdf.KZSettingNotFoundException; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.output.DataSink; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; import at.knowcenter.wag.egov.egiz.exceptions.PlaceholderException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException; -import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; -import at.knowcenter.wag.egov.egiz.exceptions.SignatureTypesException; -import at.knowcenter.wag.egov.egiz.sig.SignatureBlock; import at.knowcenter.wag.egov.egiz.sig.SignatureFieldDefinition; -import at.knowcenter.wag.egov.egiz.sig.SignatureObject; import at.knowcenter.wag.egov.egiz.sig.SignatureTypes; -import at.knowcenter.wag.egov.egiz.sig.X509Cert; import at.knowcenter.wag.egov.egiz.tools.CodingHelper; import at.knowcenter.wag.exactparser.ByteArrayUtils; @@ -288,8 +288,7 @@ public abstract class BinarySignature * @return Returns the indirect reference of the Egiz Dictionary, or null, if * none exists. */ - public static PdfIndirectReference getEgizDictIndRefFromReader( - PdfReader reader) + public static PdfIndirectReference getEgizDictIndRefFromReader(PdfReader reader) { PdfDictionary catalog = reader.getCatalog(); PdfIndirectReference dict_ir = (PdfIndirectReference) catalog.get(EGIZ_DICT_NAME); @@ -369,12 +368,11 @@ public abstract class BinarySignature * The original document size. * @return Returns the signable text. */ - public static String retrieveSignableTextFromData(final byte[] data, - final int ods) + public static String retrieveSignableTextFromData(final byte[] data, final int ods) { // byte[] digest = buildDigest(data, ods); String raw_text = CodingHelper.encodeBase64(data);// digest); // data); - + return raw_text; } @@ -387,8 +385,7 @@ public abstract class BinarySignature * The byte ranges. * @return Returns the filled text. */ - public static byte[] prepareDataToSign(final byte[] data, - final List byte_ranges) + public static byte[] prepareDataToSign(final byte[] data, final List byte_ranges) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); Iterator it = byte_ranges.iterator(); @@ -411,174 +408,176 @@ public abstract class BinarySignature return data_to_sign; } - /** - * Extracts the binary 'text' of a document. - * - *

- * If the document contains an Egiz Dictionary, which means that it is already - * signed, the binary text is the Base64 coded string of the original document - * followed by the Ascii representation of the signature block. - *

- *

- * If the document does not contain an Egiz Dictionary, which means that it is - * unsigned, only the binary Base64 coded original document is returned as - * binary text. - *

- *

- * This function is intented for being used instead of the "text extraction" - * mechanism used in the plain text Egiz project. - *

- * - * @param doc - * The file. - * @return Returns the binary text of the document. - * @throws PDFDocumentException - * Forwarded exception. - */ - public static String extractTextBinary(File doc) throws PDFDocumentException - { - try - { - FileInputStream fis = new FileInputStream(doc); - return extractTextBinary(fis); - } - catch (FileNotFoundException e) - { - throw new PDFDocumentException(202, e); - } - } - - /** - * Extracts the text binary. - * - * @param is - * @return Returns the binary text. - * @throws PDFDocumentException - */ - public static String extractTextBinary(InputStream is) throws PDFDocumentException - { - try - { - // for some stupid reason this produces a read error if the is comes from - // a - // multipart servlet form..??? - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int i = -1; - int acc = 0; - byte[] b = new byte[1000]; - while ((i = is.read(b)) > 0) - { - acc += i; - System.out.print(" " + i); - baos.write(b, 0, i); - } - System.out.println("acc = " + acc); - byte[] pdf = baos.toByteArray(); - - return extractTextBinary(pdf); - } - catch (IOException e) - { - throw new PDFDocumentException(202, e); - } - } - - /** - * Extracts the signable text from a binary pdf document. - * - *

- * The signable text is the text that will be signed or verified afterwards. - *

- * - * @param pdf - * The pdf document. - * @return Returns the extracted text String. - * @throws PDFDocumentException - * Forwarded exception. - */ - public static String extractTextBinary(final byte[] pdf) throws PDFDocumentException - { - try - { - PdfReader reader = new PdfReader(new ByteArrayInputStream(pdf)); - PdfDictionary egiz_dict = getEgizDictFromReader(reader); - if (egiz_dict == null) - { - System.out.println("NO Egiz Dict found - whole doc = original doc"); - - int ods = pdf.length; - return retrieveSignableTextFromData(pdf, ods); - } - - String sig_text = extractSignatureTextOnly(egiz_dict); - - int ods = getOriginalDocumentSizeFromEgizDict(egiz_dict); - - String raw_text = retrieveSignableTextFromData(pdf, ods); - raw_text += "\n"; - raw_text += sig_text; - - return raw_text; - } - catch (IOException e) - { - throw new PDFDocumentException(202, e); - } - } - - /** - * Retrieves the List of SignatureHolders containing the information of all - * digital signatures of the given document. - * - *

- * If the List of SignatureHolders is empty, the document is not signed - * anyways. - *

- * - * @param pdf - * The complete pdf document. - * @return Returns the List of SignatureHolders. - * @throws PDFDocumentException - * @throws SignatureTypesException - * @throws SignatureException - */ - public static List extractSignatureHoldersBinary(final byte[] pdf) throws PDFDocumentException, SignatureTypesException, SignatureException - { - try - { - PdfReader reader = new PdfReader(new ByteArrayInputStream(pdf)); - List chain = getEgizDictChainFromReader(reader); - - List signatures = new ArrayList(); - Iterator it = chain.iterator(); - while (it.hasNext()) - { - PdfDictionary dict = (PdfDictionary) it.next(); - - int ods = getOriginalDocumentSizeFromEgizDict(dict); - String signature_text = extractSignatureTextOnly(dict); - - SignatureTypes sig_types = SignatureTypes.getInstance(); - List types = sig_types.getSignatureTypeDefinitions(); - SignatureBlock sig_block = new SignatureBlock(types); - boolean could_separate = sig_block.separateBlockFromRawText(signature_text, false); - - if (could_separate) - { - SignatureObject sig_object = sig_block.getSignatureObject(); - - SignatureHolder holder = new BinarySignatureHolder(pdf, ods, sig_object); - signatures.add(holder); - } - } - - return signatures; - } - catch (IOException e) - { - throw new PDFDocumentException(201, e); - } - } + // TODO old code - remove + // /** + // * Extracts the binary 'text' of a document. + // * + // *

+ // * If the document contains an Egiz Dictionary, which means that it is already + // * signed, the binary text is the Base64 coded string of the original document + // * followed by the Ascii representation of the signature block. + // *

+ // *

+ // * If the document does not contain an Egiz Dictionary, which means that it is + // * unsigned, only the binary Base64 coded original document is returned as + // * binary text. + // *

+ // *

+ // * This function is intented for being used instead of the "text extraction" + // * mechanism used in the plain text Egiz project. + // *

+ // * + // * @param doc + // * The file. + // * @return Returns the binary text of the document. + // * @throws PDFDocumentException + // * Forwarded exception. + // */ + // public static String extractTextBinary(File doc) throws PDFDocumentException + // { + // try + // { + // FileInputStream fis = new FileInputStream(doc); + // return extractTextBinary(fis); + // } + // catch (FileNotFoundException e) + // { + // throw new PDFDocumentException(202, e); + // } + // } + // + // /** + // * Extracts the text binary. + // * + // * @param is + // * @return Returns the binary text. + // * @throws PDFDocumentException + // */ + // public static String extractTextBinary(InputStream is) throws PDFDocumentException + // { + // try + // { + // // for some stupid reason this produces a read error if the is comes from + // // a + // // multipart servlet form..??? + // ByteArrayOutputStream baos = new ByteArrayOutputStream(); + // int i = -1; + // int acc = 0; + // byte[] b = new byte[1000]; + // while ((i = is.read(b)) > 0) + // { + // acc += i; + // System.out.print(" " + i); + // baos.write(b, 0, i); + // } + // System.out.println("acc = " + acc); + // byte[] pdf = baos.toByteArray(); + // + // return extractTextBinary(pdf); + // } + // catch (IOException e) + // { + // throw new PDFDocumentException(202, e); + // } + // } + // + // /** + // * Extracts the signable text from a binary pdf document. + // * + // *

+ // * The signable text is the text that will be signed or verified afterwards. + // *

+ // * + // * @param pdf + // * The pdf document. + // * @return Returns the extracted text String. + // * @throws PDFDocumentException + // * Forwarded exception. + // */ + // public static String extractTextBinary(final byte[] pdf) throws PDFDocumentException + // { + // try + // { + // PdfReader reader = new PdfReader(new ByteArrayInputStream(pdf)); + // PdfDictionary egiz_dict = getEgizDictFromReader(reader); + // if (egiz_dict == null) + // { + // System.out.println("NO Egiz Dict found - whole doc = original doc"); + // + // int ods = pdf.length; + // return retrieveSignableTextFromData(pdf, ods); + // } + // + // String sig_text = extractSignatureTextOnly(egiz_dict); + // + // int ods = getOriginalDocumentSizeFromEgizDict(egiz_dict); + // + // String raw_text = retrieveSignableTextFromData(pdf, ods); + // raw_text += "\n"; + // raw_text += sig_text; + // + // return raw_text; + // } + // catch (IOException e) + // { + // throw new PDFDocumentException(202, e); + // } + // } + + // TODO obsolete code - remove + // /** + // * Retrieves the List of SignatureHolders containing the information of all + // * digital signatures of the given document. + // * + // *

+ // * If the List of SignatureHolders is empty, the document is not signed + // * anyways. + // *

+ // * + // * @param pdf + // * The complete pdf document. + // * @return Returns the List of SignatureHolders. + // * @throws PDFDocumentException + // * @throws SignatureTypesException + // * @throws SignatureException + // */ + // public static List extractSignatureHoldersBinary(final byte[] pdf) throws PDFDocumentException, SignatureTypesException, SignatureException + // { + // try + // { + // PdfReader reader = new PdfReader(new ByteArrayInputStream(pdf)); + // List chain = getEgizDictChainFromReader(reader); + // + // List signatures = new ArrayList(); + // Iterator it = chain.iterator(); + // while (it.hasNext()) + // { + // PdfDictionary dict = (PdfDictionary) it.next(); + // + // int ods = getOriginalDocumentSizeFromEgizDict(dict); + // String signature_text = extractSignatureTextOnly(dict); + // + // SignatureTypes sig_types = SignatureTypes.getInstance(); + // List types = sig_types.getSignatureTypeDefinitions(); + // SignatureBlock sig_block = new SignatureBlock(types); + // boolean could_separate = sig_block.separateBlockFromRawText(signature_text, false); + // + // if (could_separate) + // { + // SignatureObject sig_object = sig_block.getSignatureObject(); + // + // SignatureHolder holder = new BinarySignatureHolder(pdf, ods, sig_object); + // signatures.add(holder); + // } + // } + // + // return signatures; + // } + // catch (IOException e) + // { + // throw new PDFDocumentException(201, e); + // } + // } // /** // * Signs a document with the given signature table using the Incremental @@ -677,22 +676,26 @@ public abstract class BinarySignature * @throws PresentableException * Forwarded exception. */ - public static IncrementalUpdateInformation writeIncrementalUpdate( - byte[] original_document, PdfPTable pdf_table, PositioningInstruction pi, + public static IncrementalUpdateInformation writeIncrementalUpdate(PdfDataSource original_document, DataSink written_pdf, PdfPTable pdf_table, PositioningInstruction pi, List variable_field_definitions, List all_field_definitions) throws PresentableException { try { IncrementalUpdateInformation iui = new IncrementalUpdateInformation(); iui.original_document = original_document; - iui.start_index = original_document.length; + iui.start_index = original_document.getLength(); Document.compress = false; // System.out.println("wprinz: STAMPING PDF"); - PdfReader reader = new PdfReader(original_document); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); + InputStream is = original_document.createInputStream(); + PdfReader reader = new PdfReader(is); + is.close(); + + OutputStream baos = written_pdf.createOutputStream("application/pdf"); + // ByteArrayOutputStream baos = new ByteArrayOutputStream(); + // IMPORTANT: append the new content to the original document using // incremental updated // The stamper allows this by setting append = true @@ -786,19 +789,21 @@ public abstract class BinarySignature stamper.close(); // System.out.println("wprinz: STAMPING FINISHED"); - iui.signed_pdf = baos.toByteArray(); + // just to make sure the stream is really closed + baos.close(); + // iui.signed_pdf = baos.toByteArray(); return iui; } catch (IOException e) { e.printStackTrace(); - throw new PresentableException(e); + throw new PresentableException(ErrorCode.CANNOT_WRITE_PDF, e); } catch (DocumentException e) { e.printStackTrace(); - throw new PresentableException(e); + throw new PresentableException(ErrorCode.CANNOT_WRITE_PDF, e); } } @@ -816,9 +821,8 @@ public abstract class BinarySignature * @throws IOException * @throws SettingNotFoundException */ - protected static void createEgizDict(PdfStamper stamper, - PdfTemplate table_template, IncrementalUpdateInformation iui, - List variable_field_definitions, List all_field_definitions) throws IOException, SettingNotFoundException + protected static void createEgizDict(PdfStamper stamper, PdfTemplate table_template, IncrementalUpdateInformation iui, List variable_field_definitions, List all_field_definitions) + throws IOException, SettingNotFoundException { // iui.temp_ir = table_template.getIndirectReference(); iui.temp_ir_number = table_template.getIndirectReference().getNumber(); @@ -1302,8 +1306,7 @@ public abstract class BinarySignature * @return Returns the list of ReplaceInfo objects specifying the variable * areas. */ - protected static List determineReplacesInContentStream(final byte[] pdf, - int begin, int end, List field_definitions) + protected static List determineReplacesInContentStream(final byte[] pdf, int begin, int end, List field_definitions) { List replaces = new ArrayList(); try @@ -1343,8 +1346,7 @@ public abstract class BinarySignature } // sort replaces - Collections.sort(replaces, new Comparator() - { + Collections.sort(replaces, new Comparator() { public int compare(Object arg0, Object arg1) { ReplaceInfo ri0 = (ReplaceInfo) arg0; @@ -1373,8 +1375,7 @@ public abstract class BinarySignature * @throws SettingNotFoundException * F.e. */ - protected static List determineKZ(final byte[] pdf, int begin, int end, - List field_definitions) throws SettingNotFoundException + protected static List determineKZ(final byte[] pdf, int begin, int end, List field_definitions) throws SettingNotFoundException { try { @@ -1414,7 +1415,7 @@ public abstract class BinarySignature { e.printStackTrace(); } - throw new SettingNotFoundException(102, "Field " + SignatureTypes.SIG_KZ + " not found."); + throw new KZSettingNotFoundException("Field " + SignatureTypes.SIG_KZ + " not found."); } /** @@ -1508,8 +1509,7 @@ public abstract class BinarySignature return true; } - protected static boolean startsWithCaption(StringInfo si, - List field_definitions) + protected static boolean startsWithCaption(StringInfo si, List field_definitions) { try { @@ -1568,8 +1568,7 @@ public abstract class BinarySignature * @param placeholder * The placeholder the string should be filled with. */ - public static void restorePlaceholder(final byte[] pdf, StringInfo si, - final byte placeholder) + public static void restorePlaceholder(final byte[] pdf, StringInfo si, final byte placeholder) { byte[] ph = new byte[si.string_length]; for (int i = 0; i < ph.length; i++) @@ -1592,8 +1591,7 @@ public abstract class BinarySignature * values. * @throws PDFDocumentException */ - public static List reconstructReplaces(final byte[] pdf, byte[][] brevs, - StringInfo[] sis, byte[][] encodings) throws PDFDocumentException + public static List reconstructReplaces(final byte[] pdf, byte[][] brevs, StringInfo[] sis, byte[][] encodings) throws PDFDocumentException { try { @@ -1654,8 +1652,7 @@ public abstract class BinarySignature * The number of digits. * @return Returns the read number. */ - public static int readNumber(final byte[] pdf, final int start_index, - final int num_digits) + public static int readNumber(final byte[] pdf, final int start_index, final int num_digits) { try { @@ -1685,8 +1682,7 @@ public abstract class BinarySignature * @param num_digits * The number of digits. */ - public static void replaceNumber(final byte[] pdf, final int start_index, - final int number, final int num_digits) + public static void replaceNumber(final byte[] pdf, final int start_index, final int number, final int num_digits) { try { @@ -1717,30 +1713,31 @@ public abstract class BinarySignature } } - /** - * For debugging purposes. - * - * @param args - * @throws IOException - */ - public static void main(String[] args) throws IOException - { - File signed_doc = new File("C:/wprinz/temp.pdf"); - - PdfReader reader = new PdfReader(new FileInputStream(signed_doc)); - PdfDictionary egiz_dict = getEgizDictFromReader(reader); - if (egiz_dict == null) - { - System.out.println("NO Egiz Dict"); - return; - } - - String sig_text = extractSignatureTextOnly(egiz_dict); - System.out.println("Sig Text:"); - System.out.println(sig_text); - - int ods = getOriginalDocumentSizeFromEgizDict(egiz_dict); - System.out.println("Original Document Size = " + ods); - } + // TODO old code - remove + // /** + // * For debugging purposes. + // * + // * @param args + // * @throws IOException + // */ + // public static void main(String[] args) throws IOException + // { + // File signed_doc = new File("C:/wprinz/temp.pdf"); + // + // PdfReader reader = new PdfReader(new FileInputStream(signed_doc)); + // PdfDictionary egiz_dict = getEgizDictFromReader(reader); + // if (egiz_dict == null) + // { + // System.out.println("NO Egiz Dict"); + // return; + // } + // + // String sig_text = extractSignatureTextOnly(egiz_dict); + // System.out.println("Sig Text:"); + // System.out.println(sig_text); + // + // int ods = getOriginalDocumentSizeFromEgizDict(egiz_dict); + // System.out.println("Original Document Size = " + ods); + // } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignatureHolder.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignatureHolder.java index 1f522ff..8d42370 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignatureHolder.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignatureHolder.java @@ -19,6 +19,10 @@ package at.knowcenter.wag.egov.egiz.pdf; import java.io.Serializable; +import at.gv.egiz.pdfas.impl.input.ByteArrayPdfDataSourceImpl; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; + import at.knowcenter.wag.egov.egiz.sig.SignatureObject; /** @@ -44,48 +48,58 @@ public class BinarySignatureHolder implements Serializable, SignatureHolder */ private static final long serialVersionUID = -7208103904479272760L; - /** - * The whole pdf this holder was extracted from. - */ - private byte[] signed_pdf = null; - - /** - * The number of bytes that give the signed document. - */ - private int signed_pdf_length = -1; - - /** - * The signed text of this object. - * - *

- * This is the value that will be signed by the Connector. - *

- */ - private String signed_text = null; +// /** +// * The whole pdf this holder was extracted from. +// */ +// private byte[] signed_pdf = null; + + private PdfDataSource pdfDataSource = null; + +// /** +// * The number of bytes that give the signed document. +// */ +// private int signed_pdf_length = -1; + +// /** +// * The signed text of this object. +// * +// *

+// * This is the value that will be signed by the Connector. +// *

+// */ +// private String signed_text = null; /** * The signature object. */ private SignatureObject signature_object = null; - /** - * Constructor that takes the pdf and the SignatureObject as parameters. - * - * @param pdf - * The pdf data. - * @param length - * The length (number of bytes) of the pdf data to be used for being - * converted into "signed text". - * @param so - * The signed signature object. - */ - public BinarySignatureHolder(final byte[] pdf, final int length, SignatureObject so) +// /** +// * Constructor that takes the pdf and the SignatureObject as parameters. +// * +// * @param pdf +// * The pdf data. +// * @param length +// * The length (number of bytes) of the pdf data to be used for being +// * converted into "signed text". +// * @param so +// * The signed signature object. +// */ +// public BinarySignatureHolder(final byte[] pdf, final int length, SignatureObject so) +// { +//// this.signed_pdf = pdf; +// this.pdfDataSource = new ByteArrayPdfDataSourceImpl(pdf); +// // streaming byte array +// this.signed_pdf_length = length; +// this.signature_object = so; +// +//// this.signed_text = null; +// } + + public BinarySignatureHolder(PdfDataSource pdf, SignatureObject so) { - this.signed_pdf = pdf; - this.signed_pdf_length = length; + this.pdfDataSource = pdf; this.signature_object = so; - - this.signed_text = null; } /** @@ -93,11 +107,12 @@ public class BinarySignatureHolder implements Serializable, SignatureHolder */ public String getSignedText() { - if (this.signed_text == null) - { - computeSignedText(); - } - return this.signed_text; + throw new RuntimeException("BinarySignatureHolder must not return text."); +// if (this.signed_text == null) +// { +// computeSignedText(); +// } +// return this.signed_text; } /** @@ -107,40 +122,56 @@ public class BinarySignatureHolder implements Serializable, SignatureHolder { return this.signature_object; } - + /** - * Computes or recomputes the signed text from the underlying binary data. - * - *

- * This usually encodes the binary data of given length in Base64. - *

- * - *

- * This is usually called automatically when the signed text is first - * requested. - *

+ * @see at.knowcenter.wag.egov.egiz.pdf.SignatureHolder#getDataSource() */ - protected void computeSignedText() + public DataSource getDataSource() { - this.signed_text = BinarySignature.retrieveSignableTextFromData(this.signed_pdf, this.signed_pdf_length); + return getSignedPdf(); } - - /** - * Returns the signed_pdf. - * @return Returns the signed_pdf. - */ - public byte[] getSignedPdf() + + + + // TODO obsolete funtction - remove; +// /** +// * Computes or recomputes the signed text from the underlying binary data. +// * +// *

+// * This usually encodes the binary data of given length in Base64. +// *

+// * +// *

+// * This is usually called automatically when the signed text is first +// * requested. +// *

+// */ +// protected void computeSignedText() +// { +// this.signed_text = BinarySignature.retrieveSignableTextFromData(this.signed_pdf, this.signed_pdf_length); +// } + +// /** +// * Returns the signed_pdf. +// * @return Returns the signed_pdf. +// */ +// public byte[] getSignedPdf() +// { +// return this.signed_pdf; +// } + + public PdfDataSource getSignedPdf () { - return this.signed_pdf; + return this.pdfDataSource; } - /** - * Returns the signed_pdf_length. - * @return Returns the signed_pdf_length. - */ - public int getSignedPdfLength() - { - return this.signed_pdf_length; - } +// /** +// * Returns the signed_pdf_length. +// * @return Returns the signed_pdf_length. +// */ +// public int getSignedPdfLength() +// { +// return this.signed_pdf_length; +// } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java index 76c59c3..fc446f9 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/IncrementalUpdateInformation.java @@ -20,6 +20,9 @@ package at.knowcenter.wag.egov.egiz.pdf; import java.io.Serializable; import java.util.List; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.output.DataSink; + import at.knowcenter.wag.egov.egiz.sig.SignatureData; import at.knowcenter.wag.egov.egiz.sig.SignatureObject; import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject; @@ -48,7 +51,8 @@ public class IncrementalUpdateInformation implements Serializable /** * The original PDF document. */ - public byte[] original_document = null; + //public byte[] original_document = null; + public PdfDataSource original_document = null; /** * The Singature type to be created. @@ -63,6 +67,10 @@ public class IncrementalUpdateInformation implements Serializable *

*/ public byte[] signed_pdf = null; + // this is only valid during prepare + + // holds the variable iui data for bin sigs. + public byte [] sign_iui_block = null; /** * The start index of this incremental update block. diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java index 666ee52..0bae3d2 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java @@ -355,7 +355,7 @@ public class PDFPage extends PDFTextStripper if (current_y > this.footer_line) { - logger_.debug("character is below footer_line. footer_line = " + this.footer_line + ", text.character=" + character + ", y=" + current_y); + //logger_.debug("character is below footer_line. footer_line = " + this.footer_line + ", text.character=" + character + ", y=" + current_y); return; } @@ -363,11 +363,11 @@ public class PDFPage extends PDFTextStripper if (!character.equals(" ") && current_y > this.max_character_ypos) { this.max_character_ypos = current_y; - logger_.debug("text.character=" + character + ", y=" + current_y); + //logger_.debug("text.character=" + character + ", y=" + current_y); // System.err.println(character + "|" + current_y); } - logger_.debug("text.character=" + character + ", y=" + current_y); + //logger_.debug("text.character=" + character + ", y=" + current_y); // System.err.println(character + "|" + current_y); } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureCreation.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureCreation.java index 453103b..fd885fc 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureCreation.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureCreation.java @@ -79,12 +79,12 @@ public class PDFSignatureCreation { * @throws PDFDocumentException ErrorCode:101 */ public PDFSignatureCreation(SignatureObject sigObject) throws PDFDocumentException { - try { +// try { loadSettings(); - } catch (PDFDocumentException e) { - e.setErrorCode(101); - throw e; - } +// } catch (PDFDocumentException e) { +// e.setErrorCode(101); +// throw e; +// } sigObject_ = sigObject; } @@ -157,12 +157,12 @@ public class PDFSignatureCreation { */ public PDFSignatureObject getPDFSignatureObject() throws PDFDocumentException { if (pdfSigObject_ == null) { - try { +// try { pdfSigObject_ = createPDFSignatureObject(); - } catch (PDFDocumentException e) { - e.setErrorCode(203); - throw e; - } +// } catch (PDFDocumentException e) { +// e.setErrorCode(203); +// throw e; +// } pdfSigObject_.setSignatorObject(sigObject_); } return pdfSigObject_; diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureObjectIText.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureObjectIText.java index 56b5f86..6c609ae 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureObjectIText.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureObjectIText.java @@ -28,7 +28,6 @@ import org.apache.log4j.Logger; import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; -import at.knowcenter.wag.egov.egiz.exceptions.ErrorCodeException; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; import at.knowcenter.wag.egov.egiz.sig.SignatureObject; @@ -342,7 +341,7 @@ public class PDFSignatureObjectIText implements PDFSignatureObject } if (logger_.isEnabledFor(Level.ERROR)) { - logger_.error("Error Code:222 " + ErrorCodeException.getErrorCodeMessage(222) + ". IOException:" + e.getMessage()); + logger_.error("Error Code: 222, IOException:" + e.getMessage()); } PDFDocumentException pde = new PDFDocumentException(222, "PDF table can not created: Image can not loaded"); throw pde; diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java index 8c15d21..e19c244 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java @@ -22,6 +22,8 @@ import java.io.File; import java.io.IOException; import java.util.List; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; + import org.pdfbox.pdfparser.PDFParser; import org.pdfbox.pdmodel.PDDocument; import org.pdfbox.pdmodel.PDPage; @@ -39,13 +41,15 @@ import com.lowagie.text.DocumentException; */ public abstract class PDFUtilities { - public static float calculatePageLength(final byte[] pdf,int page ,float footer_line, int pagerotation) throws PDFDocumentException + public static float calculatePageLength(final PdfDataSource pdfDataSource,int page ,float footer_line, int pagerotation) throws PDFDocumentException { try { - ByteArrayInputStream original_bais = new ByteArrayInputStream(pdf); - byte [] normalized_pdf = TextualSignature.normalizePDF(original_bais); + //ByteArrayInputStream original_bais = new ByteArrayInputStream(pdf); + //byte [] normalized_pdf = TextualSignature.normalizePDF(original_bais); + byte [] normalized_pdf = TextualSignature.normalizePDF(pdfDataSource.createInputStream()); + // PERF: The whole PDF normalization process is costy ByteArrayInputStream bais = new ByteArrayInputStream(normalized_pdf); PDFParser parser = new PDFParser(bais); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/SignatureHolder.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/SignatureHolder.java index d7fcce9..aa8da2c 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/SignatureHolder.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/SignatureHolder.java @@ -17,6 +17,7 @@ */ package at.knowcenter.wag.egov.egiz.pdf; +import at.gv.egiz.pdfas.framework.input.DataSource; import at.knowcenter.wag.egov.egiz.sig.SignatureObject; /** @@ -36,21 +37,21 @@ import at.knowcenter.wag.egov.egiz.sig.SignatureObject; public interface SignatureHolder { - /** - * Returns the signed text (verification) or the to-be-signed signable text - * (signation). - * - *

- * Note that this text must be the one that was actually signed. This text is - * directly passed to the connector for signation/verification. No - * normalization or modification will be / must be done to this text between - * reading out from the signature holder and passing the text to the - * connector. - *

- * - * @return Returns the signed text or the to-be-signed signable text. - */ - public String getSignedText(); +// /** +// * Returns the signed text (verification) or the to-be-signed signable text +// * (signation). +// * +// *

+// * Note that this text must be the one that was actually signed. This text is +// * directly passed to the connector for signation/verification. No +// * normalization or modification will be / must be done to this text between +// * reading out from the signature holder and passing the text to the +// * connector. +// *

+// * +// * @return Returns the signed text or the to-be-signed signable text. +// */ +// public String getSignedText(); /** * @@ -59,4 +60,9 @@ public interface SignatureHolder */ public SignatureObject getSignatureObject(); + /** + * Returns the DataSource providing the data. + * @return + */ + public DataSource getDataSource(); } \ No newline at end of file diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignature.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignature.java index a52d6dd..668bbcb 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignature.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignature.java @@ -23,6 +23,9 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import at.gv.egiz.pdfas.performance.PerformanceCounters; +import at.gv.egiz.pdfas.exceptions.pdf.TextExtractionException; + import org.apache.log4j.Logger; import org.pdfbox.pdfparser.PDFParser; import org.pdfbox.pdmodel.PDDocument; @@ -31,7 +34,6 @@ import org.pdfbox.util.PDFTextStripper; import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; -import at.knowcenter.wag.egov.egiz.framework.signators.TextualSignator_1_0_0; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; @@ -52,6 +54,7 @@ public class TextualSignature * The logger definition. */ private static final Logger logger_ = ConfigLogger.getLogger(TextualSignature.class); + /** * Extracts the document text from a given pdf. * @@ -61,8 +64,10 @@ public class TextualSignature * @throws PresentableException * Forwarded exception. */ - public static String extractTextTextual(InputStream pdf_stream) throws PresentableException + public static String extractTextTextual(InputStream pdf_stream) throws TextExtractionException { + PerformanceCounters.textExtractions.increment(); + try { int first_page_rotation = 0; @@ -79,8 +84,10 @@ public class TextualSignature //iText PdfReader reader = new PdfReader(pdf_stream); + pdf_stream.close(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); + // PERF: PDF normalization needs byte array - this is costy + ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); // For some reason the Reader -> ImportPage -> Writer mechanism produces // problems en mass. @@ -136,7 +143,7 @@ public class TextualSignature // } baos.close(); - byte[] normalizedPDF = baos.toByteArray(); + byte[] normalizedPDF = baos.toByteArray(); ByteArrayInputStream bais = new ByteArrayInputStream(normalizedPDF); //PDFBox-parser @@ -164,9 +171,13 @@ public class TextualSignature return text; } - catch (Exception e) + catch (IOException e) + { + throw new TextExtractionException(e); + } + catch (DocumentException e) { - throw new PresentableException(e); + throw new TextExtractionException(e); } } @@ -195,6 +206,9 @@ public class TextualSignature { //iText PdfReader reader = new PdfReader(input_pdf); + input_pdf.close(); + + // PERF: PDF Normalization needs byte array ByteArrayOutputStream baos = new ByteArrayOutputStream(); // For some reason the Reader -> ImportPage -> Writer mechanism produces // problems en mass. diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignatureHolder.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignatureHolder.java index fd56125..0971f90 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignatureHolder.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignatureHolder.java @@ -19,6 +19,9 @@ package at.knowcenter.wag.egov.egiz.pdf; import java.io.Serializable; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.TextDataSource; +import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl; import at.knowcenter.wag.egov.egiz.sig.SignatureObject; /** @@ -35,34 +38,44 @@ public class TextualSignatureHolder implements Serializable, SignatureHolder */ private static final long serialVersionUID = -7208103904479272760L; - /** - * The signed text of this object. - * - *

- * This is the value that will be signed by the Connector. - *

- */ - private String signed_text = null; +// /** +// * The signed text of this object. +// * +// *

+// * This is the value that will be signed by the Connector. +// *

+// */ +// private String signed_text = null; /** * The signature object. */ private SignatureObject signature_object = null; + + private TextDataSource textDataSource = null; public TextualSignatureHolder(String text, SignatureObject so) { - this.signed_text = text; + //this.signed_text = text; this.signature_object = so; + this.textDataSource = new TextDataSourceImpl(text); } - /** - * @see at.knowcenter.wag.egov.egiz.pdf.SignatureHolder#getSignedText() - */ - public String getSignedText() + public TextualSignatureHolder(TextDataSource text, SignatureObject so) { - return this.signed_text; + //this.signed_text = text; + this.signature_object = so; + this.textDataSource = text; } +// /** +// * @see at.knowcenter.wag.egov.egiz.pdf.SignatureHolder#getSignedText() +// */ +// public String getSignedText() +// { +// return this.signed_text; +// } + /** * @see at.knowcenter.wag.egov.egiz.pdf.SignatureHolder#getSignatureObject() */ @@ -70,4 +83,37 @@ public class TextualSignatureHolder implements Serializable, SignatureHolder { return this.signature_object; } + + /** + * @see at.knowcenter.wag.egov.egiz.pdf.SignatureHolder#getDataSource() + */ + public DataSource getDataSource() + { + return this.textDataSource; + } + + /** + * This is used to replace the DataSource. + * + *

+ * After processing the text, data sources containing large texts are usually replaced by a FileBased ones to save memory. + *

+ * + * @param tds + */ + public void exchangeDataSource(TextDataSource tds) + { + this.textDataSource = tds; + } + + /** + * This is just a shortcut to getDataSource().getText() + * @return Returns the text of this data source. + */ + public String getSignedText() + { + return this.textDataSource.getText(); + } + + } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/ConnectorFactory.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/ConnectorFactory.java index 690a913..9d744e1 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/ConnectorFactory.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/ConnectorFactory.java @@ -34,6 +34,8 @@ import at.knowcenter.wag.egov.egiz.sig.connectors.MOAConnector; * This is a factory for creating the appropriate connector according to the * connector identifier. * + * @deprecated this code is far too complicated + * * @see at.knowcenter.wag.egov.egiz.sig.ConnectorInformation * @author wprinz */ diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/LocalConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/LocalConnector.java index 65c79a9..3b647a0 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/LocalConnector.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/LocalConnector.java @@ -39,6 +39,8 @@ import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; * whereas the connection to the local service is made from the local client. *

* + * @deprecated use the new connectory instead + * * @author wprinz */ public interface LocalConnector extends Connector @@ -82,7 +84,7 @@ public interface LocalConnector extends Connector * @throws SignatureException * F.e. */ - // TODO hotfix + // TODO hotfix - already deprecated public SignatureObject analyzeSignResponse(Properties response_properties, String signature_type) throws SignatureException; @@ -93,7 +95,7 @@ public interface LocalConnector extends Connector * @throws SignatureException * F.e. */ - // TODO hotfix + // TODO hotfix - already deprecated public SignatureResponse analyzeVerifyResponse(Properties response_properties) throws SignatureException; /** diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureData.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureData.java index 015831e..8c9ab12 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureData.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureData.java @@ -3,6 +3,8 @@ */ package at.knowcenter.wag.egov.egiz.sig; +import at.gv.egiz.pdfas.framework.input.DataSource; + /** * This encapsuilates the content data to be signed or verified. * @@ -20,14 +22,12 @@ package at.knowcenter.wag.egov.egiz.sig; */ public interface SignatureData { - - // TODO Performance: make this to an InputStream /** - * Returns the data to be signed or verified. + * Returns the DataSource that provides the data for this SignatureData. * - * @return Returns the data to be signed or verified. + * @return Returns the DataSource. */ - public byte[] getData(); + public DataSource getDataSource(); /** * Returns the mime type of the data. diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureDataImpl.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureDataImpl.java index 5b9304d..320c511 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureDataImpl.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureDataImpl.java @@ -5,6 +5,8 @@ package at.knowcenter.wag.egov.egiz.sig; import java.io.Serializable; +import at.gv.egiz.pdfas.framework.input.DataSource; + /** * Generic implementation of the SignatureData interface for being used by * signators and verificators. @@ -21,8 +23,8 @@ public class SignatureDataImpl implements SignatureData, Serializable /** * The signature data. */ - protected byte[] data = null; - + protected DataSource data = null; + /** * The mime type of the data. */ @@ -46,43 +48,50 @@ public class SignatureDataImpl implements SignatureData, Serializable * @param mime_type * The mime type of the data. */ - public SignatureDataImpl(byte[] data, String mime_type) + public SignatureDataImpl(DataSource data, String mime_type) { this.data = data; this.mimeType = mime_type; this.characterEncoding = null; } - /** - * Constructor that fills the SignatureData. - * - *

- * Use this constructor for textual data as it allows to provide the character - * encoding. - *

- * - * @param data - * The signature data. - * @param mime_type - * The mime type of the data. - * @param character_encoding - * The character encoding of the data if appropriate, or null if not. - */ - public SignatureDataImpl(byte[] data, String mime_type, String character_encoding) +// /** +// * Constructor that fills the SignatureData. +// * +// *

+// * Use this constructor for textual data as it allows to provide the character +// * encoding. +// *

+// * +// * @param data +// * The signature data. +// * @param mime_type +// * The mime type of the data. +// * @param character_encoding +// * The character encoding of the data if appropriate, or null if not. +// */ +// public SignatureDataImpl(byte[] data, String mime_type, String character_encoding) +// { +// this.data = data; +// this.mimeType = mime_type; +// this.characterEncoding = character_encoding; +// } + public SignatureDataImpl(DataSource data, String mime_type, String character_encoding) { this.data = data; this.mimeType = mime_type; this.characterEncoding = character_encoding; } - + /** - * @see at.knowcenter.wag.egov.egiz.sig.SignatureData#getData() + * @see at.knowcenter.wag.egov.egiz.sig.SignatureData#getDataSource() */ - public byte[] getData() + public DataSource getDataSource() { return this.data; } - + + /** * @see at.knowcenter.wag.egov.egiz.sig.SignatureData#getMimeType() */ diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java index a48893c..52c986a 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java @@ -252,9 +252,7 @@ public class SignatureObject implements Serializable { String log_message = "Can not load pdf signature settings. Cause:\n" + e.getMessage(); logger_.error(log_message); - SignatureException se = new SignatureException(101, log_message, e); - se.setErrorCode(101); - throw se; + throw new SignatureException(101, log_message, e); } } // pTree_ = settings_.getPTree(); @@ -829,7 +827,7 @@ public class SignatureObject implements Serializable public static boolean decideNewEtsiByBKUVersion(String productVersion) { boolean new_etsi = true; - // TODO make better + // TODO hotfix if (productVersion.startsWith("2.5") || productVersion.startsWith("2.4") || productVersion.startsWith("2.3") || productVersion.startsWith("2.2") || productVersion.startsWith("2.1") || productVersion.startsWith("1") || productVersion.startsWith("0")) { new_etsi = false; @@ -1540,7 +1538,7 @@ public class SignatureObject implements Serializable } catch (NormalizeException e) { - throw new SignatureTypesException("Can not set normalizer Version:" + value); + throw new SignatureTypesException(e); } } // value = new String(CodingHelper.encodeUTF8(value)); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java index d6301a9..75e4c31 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java @@ -22,6 +22,8 @@ import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; +import at.gv.egiz.pdfas.exceptions.external.ExternalErrorException; + import org.apache.log4j.Level; import org.apache.log4j.Logger; @@ -41,6 +43,8 @@ import at.knowcenter.wag.egov.egiz.tools.FileHelper; /** * Connector for communicating with BKU. * + * @deprecated use the new connectors. + * * @author wlackner * @author wprinz */ @@ -270,7 +274,7 @@ public class BKUConnector implements LocalConnector ids[3] = extractId(xmlResponse, "etsi-data-reference-"); ids[4] = extractId(xmlResponse, "etsi-data-object-"); - //TODO hotfix + //TODO hotfix - already deprecated String final_ids =SignatureObject.formatSigIds(response_properties, ids); //sigObj.setSignationIDs(ids); sigObj.setSignationIDs(final_ids); @@ -291,11 +295,11 @@ public class BKUConnector implements LocalConnector int start_idx = text.indexOf(name) + name.length(); int end_idx = text.indexOf("\"", start_idx); - // TODO hotfix! + // TODO hotfix! - already deprecated final int quot_end_idx = end_idx; final int squot_end_idx = text.indexOf("'", start_idx); end_idx = Math.min(quot_end_idx, squot_end_idx); - // TODO hotfix end! + // TODO hotfix end! - already deprecated id = text.substring(start_idx, end_idx); if (logger_.isDebugEnabled()) @@ -342,7 +346,7 @@ public class BKUConnector implements LocalConnector logger_.debug("ids_string = " + ids_string); String[] ids = SignatureObject.parseSigIds(ids_string); - // TODO hotfix + // TODO hotfix - already deprecated final boolean neue_bku = ids[5] != null; logger_.debug("ids[5] = " + ids[5]); logger_.debug("neue_bku = " + neue_bku); @@ -391,7 +395,7 @@ public class BKUConnector implements LocalConnector ver_temp_str = ver_temp_str.replaceFirst("TemplateQualifyingPropertiesReplace", sig_prop_str); byte[] sig_prop_code = CodingHelper.buildDigest(sig_prop_str.getBytes("UTF-8")); - // TODO hotfix + // TODO hotfix - already deprecated if (neue_bku) { final String ETSI_SIGNED_PROPERTIES_START_TAG = ""); Matcher erm_m_s = erm_p_s.matcher(response_string); Matcher erm_m_e = erm_p_e.matcher(response_string); - SignatureException se = new SignatureException(0, "BKUSigExc"); String error_code = response_string.substring(erc_m_s.end(), erc_m_e.start()); - se.setExternalErrorCode(error_code); + String error_mess = null; if (erm_m_s.find() && erm_m_e.find()) { - String error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start()); - se.setExternalErrorMessage(error_mess); + error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start()); } - throw se; + throw new SignatureException(new ExternalErrorException(error_code, error_mess)); } else { @@ -781,18 +783,17 @@ public class BKUConnector implements LocalConnector Pattern erm_p_e = Pattern.compile(""); Matcher erm_m_s = erm_p_s.matcher(response_string); Matcher erm_m_e = erm_p_e.matcher(response_string); - SignatureException se = new SignatureException(0, "BKUSigExc"); + String error_code = null; if (erc_m_s.find() && erc_m_e.find()) { - String error_code = response_string.substring(erc_m_s.end(), erc_m_e.start()); - se.setExternalErrorCode(error_code); + error_code = response_string.substring(erc_m_s.end(), erc_m_e.start()); } + String error_mess = null; if (erm_m_s.find() && erm_m_e.find()) { - String error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start()); - se.setExternalErrorMessage(error_mess); + error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start()); } - throw se; + throw new SignatureException(new ExternalErrorException(error_code, error_mess)); } else { diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUPostConnection.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUPostConnection.java index 1ddef5f..a1ebe31 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUPostConnection.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUPostConnection.java @@ -118,7 +118,9 @@ public abstract class BKUPostConnection // TODO hotfix public static void parseBKUVersion(String header_value, Properties properties) { - Pattern pattern = Pattern.compile("^citizen-card-environment/(\\d+\\.\\d+) (.+)/(\\d+\\.\\d+\\.\\d+)$"); + // dummy bku header starts with Apache Coyote... + //Pattern pattern = Pattern.compile("^citizen-card-environment/(\\d+\\.\\d+) (.+)/(\\d+\\.\\d+\\.\\d+)$"); + Pattern pattern = Pattern.compile("^.*citizen-card-environment/(\\d+\\.\\d+) (.+)/(\\d+\\.\\d+\\.\\d+)$"); Matcher m = pattern.matcher(header_value); m.matches(); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/ConnectorChooser.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/ConnectorChooser.java index 4dcd1b5..dd22b1d 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/ConnectorChooser.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/ConnectorChooser.java @@ -21,6 +21,8 @@ import at.knowcenter.wag.egov.egiz.sig.sigid.HotfixIdFormatter; * Helper class that provides static methods that help the application to * "choose" the right connector for a given task. * + * @deprecated functionality split to ConnectorChooser implementations in framework commandline and web + * * @author wprinz */ public final class ConnectorChooser @@ -62,28 +64,28 @@ public final class ConnectorChooser return new DetachedLocRefMOAConnector(profile, loc_ref_url); } - public static Connector chooseCommandlineConnectorForSign(String connector, - String profile) throws ConnectorException - { - log.debug("Choosing Connector for commandline signation..."); - - log.debug("connector type = " + connector); - - if (connector.equals(BKU)) - { - log.debug("sig_app is BKU ==> MultipartDetachedBKUConnector"); //$NON-NLS-1$ - - return new MultipartDetachedBKUConnector(profile); - } - if (connector.equals(MOA)) - { - // TODO MOA detached signing is not allowed at the commandline - log.warn("Detached MOA is not supported on the commandline. -> choosing Base64 temporarily."); - return new EnvelopingBase64MOAConnector(profile); - } - - throw new ConnectorException(300, "Unknown connector type '" + connector + "' specified."); - } +// public static Connector chooseCommandlineConnectorForSign(String connector, +// String profile) throws ConnectorException +// { +// log.debug("Choosing Connector for commandline signation..."); +// +// log.debug("connector type = " + connector); +// +// if (connector.equals(BKU)) +// { +// log.debug("sig_app is BKU ==> MultipartDetachedBKUConnector"); //$NON-NLS-1$ +// +// return new MultipartDetachedBKUConnector(profile); +// } +// if (connector.equals(MOA)) +// { +// // TODO MOA detached signing is not allowed at the commandline +// log.warn("Detached MOA is not supported on the commandline. -> choosing Base64 temporarily."); +// return new EnvelopingBase64MOAConnector(profile); +// } +// +// throw new ConnectorException(300, "Unknown connector type '" + connector + "' specified."); +// } public static LocalConnector chooseLocalConnectorForVerify(String connector, PdfASID sig_kz, String sig_id, String profile, String loc_ref_url) throws ConnectorException @@ -177,60 +179,60 @@ public final class ConnectorChooser throw new ConnectorException(310, "The SIG_KZ version '" + sig_kz.getVersion() + "' is unknown."); } - public static Connector chooseCommandlineConnectorForVerify(String connector, - PdfASID sig_kz, String sig_id, String profile) throws ConnectorException - { - log.debug("Choosing Connector for Commandline verification..."); - - log.debug("connector type = " + connector); - log.debug("sig_kz = " + sig_kz); //$NON-NLS-1$ - log.debug("sig_id = " + sig_id); //$NON-NLS-1$ - - if (sig_kz == null) - { - log.debug("sig_kz is null -> chose an old enveloped base64 connector"); //$NON-NLS-1$ - - return chooseEnvelopedBase64ConnectorOld(profile, connector); - } - - log.debug("sig_kz is not null -> one of the newer signatures"); - - if (sig_kz.getVersion().equals(SignatorFactory.VERSION_1_0_0)) - { - log.debug("Version is 1.0.0 -> Base64 Signatur (old or Hotfix)."); - - if (sig_id == null) - { - log.debug("sig_id is null, which means that it is a MOA signature -> choose a hotfix base64 connector (thus it is moa - it doesn't matter)."); - - return chooseEnvelopedBase64ConnectorHotfix(profile, connector); - } - - String[] sig_id_parts = sig_id.split("@"); - if (sig_id_parts.length == 2) - { - log.debug("sig_id has 2 @-separated parts -> choosing old base64 connector"); - - return chooseEnvelopedBase64ConnectorOld(profile, connector); - } - if (sig_id_parts[0].equals(HotfixIdFormatter.SIG_ID_PREFIX)) - { - log.debug("sig_id prefix is hotfix -> choosing hotfix base64 connector"); - - return chooseEnvelopedBase64ConnectorHotfix(profile, connector); - } - - throw new ConnectorException(300, "The SIG_KZ version is 1.0.0, but SIG_ID is neither MOA nor Old base64 nor Hotfix base64 ???'"); - } - if (sig_kz.getVersion().equals(SignatorFactory.VERSION_1_1_0)) - { - log.debug("Version is 1.1.0 -> chose a detached connector."); - - return chooseDetachedMultipartConnector(profile, connector); - } - - throw new ConnectorException(310, "The SIG_KZ version '" + sig_kz.getVersion() + "' is unknown."); - } +// public static Connector chooseCommandlineConnectorForVerify(String connector, +// PdfASID sig_kz, String sig_id, String profile) throws ConnectorException +// { +// log.debug("Choosing Connector for Commandline verification..."); +// +// log.debug("connector type = " + connector); +// log.debug("sig_kz = " + sig_kz); //$NON-NLS-1$ +// log.debug("sig_id = " + sig_id); //$NON-NLS-1$ +// +// if (sig_kz == null) +// { +// log.debug("sig_kz is null -> chose an old enveloped base64 connector"); //$NON-NLS-1$ +// +// return chooseEnvelopedBase64ConnectorOld(profile, connector); +// } +// +// log.debug("sig_kz is not null -> one of the newer signatures"); +// +// if (sig_kz.getVersion().equals(SignatorFactory.VERSION_1_0_0)) +// { +// log.debug("Version is 1.0.0 -> Base64 Signatur (old or Hotfix)."); +// +// if (sig_id == null) +// { +// log.debug("sig_id is null, which means that it is a MOA signature -> choose a hotfix base64 connector (thus it is moa - it doesn't matter)."); +// +// return chooseEnvelopedBase64ConnectorHotfix(profile, connector); +// } +// +// String[] sig_id_parts = sig_id.split("@"); +// if (sig_id_parts.length == 2) +// { +// log.debug("sig_id has 2 @-separated parts -> choosing old base64 connector"); +// +// return chooseEnvelopedBase64ConnectorOld(profile, connector); +// } +// if (sig_id_parts[0].equals(HotfixIdFormatter.SIG_ID_PREFIX)) +// { +// log.debug("sig_id prefix is hotfix -> choosing hotfix base64 connector"); +// +// return chooseEnvelopedBase64ConnectorHotfix(profile, connector); +// } +// +// throw new ConnectorException(300, "The SIG_KZ version is 1.0.0, but SIG_ID is neither MOA nor Old base64 nor Hotfix base64 ???'"); +// } +// if (sig_kz.getVersion().equals(SignatorFactory.VERSION_1_1_0)) +// { +// log.debug("Version is 1.1.0 -> chose a detached connector."); +// +// return chooseDetachedMultipartConnector(profile, connector); +// } +// +// throw new ConnectorException(310, "The SIG_KZ version '" + sig_kz.getVersion() + "' is unknown."); +// } protected static final String BKU = "bku"; //$NON-NLS-1$ diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/MOAConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/MOAConnector.java index 3c53b54..4dd3d5e 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/MOAConnector.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/MOAConnector.java @@ -31,6 +31,8 @@ import javax.xml.rpc.Call; import javax.xml.rpc.Service; import javax.xml.rpc.ServiceFactory; +import at.gv.egiz.pdfas.exceptions.external.ExternalErrorException; + import org.apache.axis.message.SOAPBodyElement; import org.apache.log4j.Level; import org.apache.log4j.Logger; @@ -55,6 +57,7 @@ import at.knowcenter.wag.egov.egiz.tools.FileHelper; /** * Connector to access the MOA service. * + * @deprecated * @author wlackner * @author wprinz */ @@ -252,10 +255,7 @@ public class MOAConnector implements Connector error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start()); logger_.debug(error_mess); } - SignatureException se = new SignatureException(0, "MOASigExc ext error code = " + error_code + ", err_mess = " + error_mess); - se.setExternalErrorCode(error_code); - se.setExternalErrorMessage(error_mess); - throw se; + throw new SignatureException(new ExternalErrorException(error_code, error_mess)); } else { @@ -581,15 +581,13 @@ public class MOAConnector implements Connector Pattern erm_p_e = Pattern.compile(""); Matcher erm_m_s = erm_p_s.matcher(response_string); Matcher erm_m_e = erm_p_e.matcher(response_string); - SignatureException se = new SignatureException(0, "MOASigExc2"); String error_code = response_string.substring(erc_m_s.end(), erc_m_e.start()); - se.setExternalErrorCode(error_code); + String error_mess = null; if (erm_m_s.find() && erm_m_e.find()) { - String error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start()); - se.setExternalErrorMessage(error_mess); + error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start()); } - throw se; + throw new SignatureException(new ExternalErrorException(error_code, error_mess)); } else { @@ -868,7 +866,7 @@ public class MOAConnector implements Connector } catch (Exception e) { - throw new WebException(330, e); + throw new WebException(e); } // serialize signature only diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUHelper.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUHelper.java index c05c688..5e3033e 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUHelper.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUHelper.java @@ -2,6 +2,7 @@ package at.knowcenter.wag.egov.egiz.sig.connectors.bku; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; @@ -9,6 +10,9 @@ import java.security.cert.X509Certificate; import java.util.regex.Matcher; import java.util.regex.Pattern; +import at.gv.egiz.pdfas.exceptions.external.ExternalErrorException; +import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -47,7 +51,10 @@ public final class BKUHelper */ public static String prepareBase64Content(SignatureData data) { - String base64 = CodingHelper.encodeBase64(data.getData()); + // PERF: base64 encoding needs byte array + byte [] d = DataSourceHelper.convertDataSourceToByteArray(data.getDataSource()); + + String base64 = CodingHelper.encodeBase64(d); if (data.getMimeType().equals("application/pdf")) //$NON-NLS-1$ { log.debug("The data is application/pdf - so the binary data is Base64 encoded."); //$NON-NLS-1$ @@ -69,7 +76,9 @@ public final class BKUHelper */ public static byte[] prepareEnvelopingData(SignatureData data) { - byte[] enc = data.getData(); + // PERF: prepareEnvelopingData needs byte array + byte[] enc = DataSourceHelper.convertDataSourceToByteArray(data.getDataSource()); + if (data.getMimeType().equals("application/pdf")) //$NON-NLS-1$ { log.debug("The data is application/pdf - so the binary data is Base64 encoded."); //$NON-NLS-1$ @@ -111,15 +120,13 @@ public final class BKUHelper Pattern erm_p_e = Pattern.compile(""); //$NON-NLS-1$ Matcher erm_m_s = erm_p_s.matcher(response_string); Matcher erm_m_e = erm_p_e.matcher(response_string); - ConnectorException se = new ConnectorException(0, "BKUSigExc"); //$NON-NLS-1$ String error_code = response_string.substring(erc_m_s.end(), erc_m_e.start()); - se.setExternalErrorCode(error_code); + String error_mess = null; if (erm_m_s.find() && erm_m_e.find()) { - String error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start()); - se.setExternalErrorMessage(error_mess); + error_mess = response_string.substring(erm_m_s.end(), erm_m_e.start()); } - throw se; + throw new ExternalErrorException(error_code, error_mess); } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUPostConnection.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUPostConnection.java index 321287d..02013a5 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUPostConnection.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/BKUPostConnection.java @@ -4,16 +4,17 @@ package at.knowcenter.wag.egov.egiz.sig.connectors.bku; import java.io.IOException; +import java.io.InputStream; import java.util.Properties; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource; import org.apache.commons.httpclient.methods.multipart.FilePart; import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; import org.apache.commons.httpclient.methods.multipart.Part; +import org.apache.commons.httpclient.methods.multipart.PartSource; import org.apache.commons.httpclient.methods.multipart.StringPart; import org.apache.commons.httpclient.params.HttpMethodParams; import org.apache.commons.logging.Log; @@ -55,7 +56,7 @@ public final class BKUPostConnection * @throws IOException */ public static Properties doPostRequestMultipart(String url, String request, - SignatureData data) throws HttpException, IOException + final SignatureData data) throws HttpException, IOException { log.debug("doPostRequestMultipart:"); //$NON-NLS-1$ @@ -68,9 +69,25 @@ public final class BKUPostConnection // xmlpart.setContentType("text/xml"); // xmlpart.setTransferEncoding(null); - String filename = data.getMimeType().equals("application/pdf") ? "myfile.pdf" : "myfile.txt"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - ByteArrayPartSource baps = new ByteArrayPartSource(filename, data.getData()); - FilePart filepart = new FilePart("fileupload", baps); //$NON-NLS-1$ + final String filename = data.getMimeType().equals("application/pdf") ? "myfile.pdf" : "myfile.txt"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + PartSource ps = new PartSource() { + public InputStream createInputStream() throws IOException + { + return data.getDataSource().createInputStream(); + } + + public String getFileName() + { + return filename; + } + + public long getLength() + { + return data.getDataSource().getLength(); + } + }; + //ByteArrayPartSource baps = new ByteArrayPartSource(filename, data.getData()); + FilePart filepart = new FilePart("fileupload", ps); //$NON-NLS-1$ filepart.setContentType(data.getMimeType()); // this is optional // filepart.setCharSet(data.getCharacterEncoding()); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedBKUConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedBKUConnector.java index 410c46e..c84ce8a 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedBKUConnector.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedBKUConnector.java @@ -10,6 +10,7 @@ import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import at.gv.egiz.pdfas.exceptions.ErrorCode; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; @@ -231,7 +232,6 @@ public class DetachedBKUConnector implements Connector, LocalConnector SignSignatureObject sso = analyzeSignResponse(response_properties); - // TODO this could be made more generic sso.response_properties = response_properties; log.debug("doSign finished."); //$NON-NLS-1$ @@ -256,7 +256,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector String verify_request_xml = prepareVerifyRequest(data, so); log.debug("verify_request_xml = " + verify_request_xml); //$NON-NLS-1$ - // TODO debug + // TODO debug - remove // try // { // FileOutputStream fos = new @@ -351,8 +351,9 @@ public class DetachedBKUConnector implements Connector, LocalConnector // data digest replace { - byte[] data_value = data.getData(); - byte[] data_value_hash = CodingHelper.buildDigest(data_value); +// byte[] data_value = data.getData(); +// byte[] data_value_hash = CodingHelper.buildDigest(data_value); + byte[] data_value_hash = CodingHelper.buildDigest(data.getDataSource()); String object_data_hash = CodingHelper.encodeBase64(data_value_hash); verify_xml = verify_xml.replaceFirst(TemplateReplaces.DIGEST_VALUE_SIGNED_DATA_REPLACE, object_data_hash); @@ -583,8 +584,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector if (this.verify_request_template == null) { - // TODO make this a settings exception - throw new ConnectorException(300, "Can not read the verify xml request template"); //$NON-NLS-1$ + throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify xml request template"); //$NON-NLS-1$ } // load template key file @@ -599,8 +599,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector if (this.verify_template == null) { - // TODO make this a settings exception - throw new ConnectorException(300, "Can not read the verify template"); //$NON-NLS-1$ + throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify template"); //$NON-NLS-1$ } this.verify_url = getConnectorValueFromProfile(settings, profile, VERIFY_URL_KEY); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/EnvelopedBase64BKUConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/EnvelopedBase64BKUConnector.java index 4983da7..82ec9bd 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/EnvelopedBase64BKUConnector.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/EnvelopedBase64BKUConnector.java @@ -10,6 +10,7 @@ import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import at.gv.egiz.pdfas.exceptions.ErrorCode; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; @@ -83,7 +84,6 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector // DebugHelper.debugStringToFile(response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY), "BKU_EnvB64_sign_response.xml"); //$NON-NLS-1$ SignSignatureObject sso = analyzeSignResponse(response_properties); - // TODO this could be made more generic sso.response_properties = response_properties; log.debug("doSign finished."); //$NON-NLS-1$ @@ -487,16 +487,14 @@ public class EnvelopedBase64BKUConnector implements Connector, LocalConnector this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename)); if (this.verify_request_template == null) { - // TODO make this a settings exception - throw new ConnectorException(300, "Can not read the verify xml request template"); //$NON-NLS-1$ + throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify xml request template"); //$NON-NLS-1$ } String verify_filename = getConnectorValueFromProfile(settings, profile, VERIFY_TEMPLATE_KEY); this.verify_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_filename)); if (this.verify_template == null) { - // TODO make this a settings exception - throw new ConnectorException(300, "Can not read the verify template"); //$NON-NLS-1$ + throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify template"); //$NON-NLS-1$ } this.verify_url = getConnectorValueFromProfile(settings, profile, VERIFY_URL_KEY); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/OldEnvelopingBase64BKUConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/OldEnvelopingBase64BKUConnector.java index d1fffb1..586879a 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/OldEnvelopingBase64BKUConnector.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/OldEnvelopingBase64BKUConnector.java @@ -8,6 +8,7 @@ import java.io.UnsupportedEncodingException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import at.gv.egiz.pdfas.exceptions.ErrorCode; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; @@ -95,15 +96,14 @@ public class OldEnvelopingBase64BKUConnector extends EnvelopedBase64BKUConnector } catch (SettingsException e) { - throw new ConnectorException(300, e); + throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, e); } String verify_filename = getConnectorValueFromProfile(settings, profile, VERIFY_TEMPLATE_KEY); this.verify_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_filename)); if (this.verify_template == null) { - // TODO make this a settings exception - throw new ConnectorException(300, "Can not read the verify template"); //$NON-NLS-1$ + throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify template"); //$NON-NLS-1$ } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/DetachedLocRefMOAConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/DetachedLocRefMOAConnector.java index 31b62f0..3bf0719 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/DetachedLocRefMOAConnector.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/DetachedLocRefMOAConnector.java @@ -9,6 +9,7 @@ import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import at.gv.egiz.pdfas.exceptions.ErrorCode; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; @@ -38,7 +39,6 @@ public class DetachedLocRefMOAConnector implements Connector * The SIG_ID prefix. */ // public static final String SIG_ID_PREFIX = "etsi-bku-detached@"; //$NON-NLS-1$ - /** * The log. */ @@ -128,7 +128,6 @@ public class DetachedLocRefMOAConnector implements Connector // DebugHelper.debugStringToFile(response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY), "MOA_DetLocRef_sign_response.xml"); //$NON-NLS-1$ SignSignatureObject sso = analyzeSignResponse(response_properties); - // TODO this could be made more generic sso.response_properties = response_properties; log.debug("doSign finished."); //$NON-NLS-1$ @@ -187,7 +186,7 @@ public class DetachedLocRefMOAConnector implements Connector verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.LOC_REF_CONTENT_REPLACE, this.environment.getSignatureDataUrl()); log.debug("\r\n\r\n" + verify_request_xml + "\r\n\r\n"); - + return verify_request_xml; } @@ -234,8 +233,9 @@ public class DetachedLocRefMOAConnector implements Connector // data digest replace { - byte[] data_value = data.getData(); - byte[] data_value_hash = CodingHelper.buildDigest(data_value); +// byte[] data_value = data.getData(); +// byte[] data_value_hash = CodingHelper.buildDigest(data_value); + byte[] data_value_hash = CodingHelper.buildDigest(data.getDataSource()); String object_data_hash = CodingHelper.encodeBase64(data_value_hash); verify_xml = verify_xml.replaceFirst(TemplateReplaces.DIGEST_VALUE_SIGNED_DATA_REPLACE, object_data_hash); @@ -289,8 +289,7 @@ public class DetachedLocRefMOAConnector implements Connector } } - protected Properties sendRequest(String url, String mode, - String request_string) throws ConnectorException + protected Properties sendRequest(String url, String mode, String request_string) throws ConnectorException { try { @@ -324,21 +323,21 @@ public class DetachedLocRefMOAConnector implements Connector * The configuration key of the sign URL. */ protected static final String SIGN_URL_KEY = "moa.sign.url"; //$NON-NLS-1$ - + /** * MOA template file prefix */ protected static final String TEMPLATE_FILE_PREFIX = "./templates/moa."; - + /** * signing file template sufix */ protected static final String SIGN_TEMPLATE_FILE_SUFIX = ".sign.xml"; - + /** * verifing template file sufix */ - protected static final String VERIFY_REQUEST_TEMPLATE_FILE_SUFIX = ".verify.request.xml"; + protected static final String VERIFY_REQUEST_TEMPLATE_FILE_SUFIX = ".verify.request.xml"; /** * verifing file template key sufix @@ -374,7 +373,7 @@ public class DetachedLocRefMOAConnector implements Connector * The configuration key for the RSA cert alg property. */ protected static final String RSA_CERT_ALG_KEY = "cert.alg.rsa"; //$NON-NLS-1$ - + protected String profile = null; protected String signature_data_url = null; @@ -410,7 +409,7 @@ public class DetachedLocRefMOAConnector implements Connector public Environment(String profile, String signature_data_url) throws ConnectorException { this.profile = profile; - + this.signature_data_url = signature_data_url; SettingsReader settings = null; @@ -424,33 +423,32 @@ public class DetachedLocRefMOAConnector implements Connector } this.sign_key_identifier = getConnectorValueFromProfile(settings, profile, SIGN_KEY_IDENTIFIER_KEY); - + String sign_request_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.moa.algorithm.id") + SIGN_TEMPLATE_FILE_SUFIX; - + // try to load template from file this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename)); - - if(this.sign_request_template == null) + + if (this.sign_request_template == null) { - sign_request_filename = getConnectorValueFromProfile(settings, profile, SIGN_REQUEST_TEMPLATE_KEY); - this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename)); + sign_request_filename = getConnectorValueFromProfile(settings, profile, SIGN_REQUEST_TEMPLATE_KEY); + this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename)); } //this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename)); if (this.sign_request_template == null) { - // TODO make this a settings exception - throw new ConnectorException(300, "Can not read the create xml request template"); //$NON-NLS-1$ + throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the create xml request template"); //$NON-NLS-1$ } this.sign_url = getConnectorValueFromProfile(settings, profile, SIGN_URL_KEY); - + String verify_request_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.moa.algorithm.id") + VERIFY_REQUEST_TEMPLATE_FILE_SUFIX; - + // try to load template file for verifing this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename)); - - if(this.verify_request_template == null) + + if (this.verify_request_template == null) { verify_request_filename = getConnectorValueFromProfile(settings, profile, VERIFY_REQUEST_TEMPLATE_KEY); this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename)); @@ -458,24 +456,22 @@ public class DetachedLocRefMOAConnector implements Connector if (this.verify_request_template == null) { - // TODO make this a settings exception - throw new ConnectorException(300, "Can not read the verify xml request template"); //$NON-NLS-1$ + throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify xml request template"); //$NON-NLS-1$ } - + // load template key file String verify_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.moa.algorithm.id") + VERIFY_TEMPLATE_SUFIX; this.verify_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_filename)); - - if(this.verify_template == null) + + if (this.verify_template == null) { - verify_filename = getConnectorValueFromProfile(settings, profile, VERIFY_TEMPLATE_KEY); - this.verify_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_filename)); + verify_filename = getConnectorValueFromProfile(settings, profile, VERIFY_TEMPLATE_KEY); + this.verify_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_filename)); } if (this.verify_template == null) { - // TODO make this a settings exception - throw new ConnectorException(300, "Can not read the verify template"); //$NON-NLS-1$ + throw new ConnectorException(ErrorCode.SETTING_NOT_FOUND, "Can not read the verify template"); //$NON-NLS-1$ } this.verify_url = getConnectorValueFromProfile(settings, profile, VERIFY_URL_KEY); @@ -488,8 +484,6 @@ public class DetachedLocRefMOAConnector implements Connector } - - public String getProfile() { return this.profile; @@ -607,8 +601,7 @@ public class DetachedLocRefMOAConnector implements Connector * The configuration key. * @return Returns the configuration entry. */ - public static String getConnectorValueFromProfile(SettingsReader settings, - String profile, String key) + public static String getConnectorValueFromProfile(SettingsReader settings, String profile, String key) { String value = settings.getValueFromKey("sig_obj." + profile + "." + key); //$NON-NLS-1$//$NON-NLS-2$ if (value == null) diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/EnvelopingBase64MOAConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/EnvelopingBase64MOAConnector.java index aedb7e3..c8a8717 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/EnvelopingBase64MOAConnector.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/EnvelopingBase64MOAConnector.java @@ -3,11 +3,6 @@ */ package at.knowcenter.wag.egov.egiz.sig.connectors.moa; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.IOException; import java.security.cert.X509Certificate; import java.util.Properties; @@ -20,7 +15,6 @@ import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; import at.knowcenter.wag.egov.egiz.sig.SignatureData; import at.knowcenter.wag.egov.egiz.sig.SignatureResponse; import at.knowcenter.wag.egov.egiz.sig.connectors.Connector; -import at.knowcenter.wag.egov.egiz.sig.connectors.ConnectorChooser; import at.knowcenter.wag.egov.egiz.sig.connectors.TemplateReplaces; import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUHelper; import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection; @@ -84,7 +78,6 @@ public class EnvelopingBase64MOAConnector implements Connector log.debug("response_string = " + response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY));; //$NON-NLS-1$ SignSignatureObject sso = analyzeSignResponse(response_properties); - // TODO this could be made more generic sso.response_properties = response_properties; log.debug("doSign finished."); //$NON-NLS-1$ diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapConnection.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapConnection.java index 11e7d2f..73ef71b 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapConnection.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapConnection.java @@ -129,7 +129,7 @@ public final class MOASoapConnection } catch (Exception e) { - throw new WebException(330, e); + throw new WebException(e); } // serialize signature only diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedLocRefMOAIdFormatter.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedLocRefMOAIdFormatter.java index 460694d..89f9503 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedLocRefMOAIdFormatter.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedLocRefMOAIdFormatter.java @@ -8,7 +8,6 @@ import org.apache.log4j.Logger; import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; -import at.knowcenter.wag.egov.egiz.sig.ConnectorFactory; /** * @author wprinz diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/tools/CodingHelper.java b/src/main/java/at/knowcenter/wag/egov/egiz/tools/CodingHelper.java index 7908486..fe0cfcb 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/tools/CodingHelper.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/tools/CodingHelper.java @@ -17,12 +17,17 @@ */ package at.knowcenter.wag.egov.egiz.tools; +import java.io.IOException; +import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.apache.commons.codec.binary.Base64; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper; + /** * This class provides encoding and decoding methods and other coding methods. * All methods are static! @@ -215,6 +220,13 @@ public class CodingHelper } } + public static byte[] buildDigest(DataSource input) throws IOException + { + // PERF: digesting needs data source. + byte [] data = DataSourceHelper.convertDataSourceToByteArray(input); + return buildDigest(data); + } + /** * This method escapes a given string with HTML entities. * diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/tools/Normalizer.java b/src/main/java/at/knowcenter/wag/egov/egiz/tools/Normalizer.java index 7420b18..397f910 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/tools/Normalizer.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/tools/Normalizer.java @@ -139,9 +139,7 @@ public class Normalizer implements Serializable { if (logger_.isEnabledFor(Level.FATAL)) { logger_.fatal("Class not found:" + class_name); } - NormalizeException ne = new NormalizeException(400, "Can not load normalizer library"); - ne.setErrorCode(400); - throw ne; + throw new NormalizeException("Can not load normalizer library"); } try { normalize_ = (Normalize) normalize_class.newInstance(); @@ -149,16 +147,12 @@ public class Normalizer implements Serializable { if (logger_.isEnabledFor(Level.FATAL)) { logger_.fatal("Can not instantiate:" + class_name); } - NormalizeException ne = new NormalizeException(400, "Can not load normalizer library"); - ne.setErrorCode(400); - throw ne; + throw new NormalizeException("Can not load normalizer library"); } catch (IllegalAccessException e) { if (logger_.isEnabledFor(Level.FATAL)) { logger_.fatal("Can not access:" + class_name); } - NormalizeException ne = new NormalizeException(400, "Can not load normalizer library"); - ne.setErrorCode(400); - throw ne; + throw new NormalizeException("Can not load normalizer library"); } } @@ -271,7 +265,7 @@ public class Normalizer implements Serializable { } catch (SettingsException e) { String log_message = "Can not load normalizer settings. Cause:\n" + e.getMessage(); logger_.error(log_message); - throw new NormalizeException(400, log_message, e); + throw new NormalizeException(log_message, e); } } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousDataResponder.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousDataResponder.java index 52846f5..7bba97b 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousDataResponder.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousDataResponder.java @@ -42,6 +42,8 @@ import at.knowcenter.wag.egov.egiz.sig.connectors.BKUPostConnection; * Servlet that responds to the data post requests of the local service (e.g. * BKU). * + * @deprecated + * * @author wprinz */ public class AsynchronousDataResponder extends HttpServlet @@ -52,123 +54,123 @@ public class AsynchronousDataResponder extends HttpServlet */ private static final long serialVersionUID = -4992297156381763174L; - /** - * The logger definition. - */ - private static final Logger logger_ = ConfigLogger.getLogger(AsynchronousDataResponder.class); - - protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException - { - logger_.debug("AsyncDataResp GET REQUEST."); - super.doGet(arg0, arg1); - } - - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException - { - logger_.debug("AsyncDataResp !!!!!!!!!!!!!!!!!!!!!!"); - - HttpSession session = request.getSession(false); - if (session == null) - { - throw new ServletException("There is no session associated with this request."); - } - - // String session_id_string = request.getParameter("session"); - // if (session_id_string == null) - // { - // throw new ServletException("The session parameter is missing."); - // } - - SessionInformation si = (SessionInformation) session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); - // long session_id = Long.parseLong(session_id_string); - // SessionInformation si = SessionTable.get(session_id); - if (si == null) - { - throw new ServletException("The session is not found or no longer valid."); - } - - // InputStream is = request.getInputStream(); - // byte [] data = new byte[request.getContentLength()]; - // is.read(data); - // is.close(); - // String enc = request.getCharacterEncoding(); - // String ct = request.getContentType(); - // Enumeration enum = request.getHeaderNames(); - // - // String dat = new String(data, "US-ASCII"); - // // dat looks like: XMLResponse=blablabla ... - // // so the actual XMLResponse begins after the = - // String resp = URLDecoder.decode(dat, "UTF-8"); - - logger_.debug("Answer from local service: content-type = '" + request.getContentType() + "', character encoding = '" + request.getCharacterEncoding() + "'"); - - // .getParameter will use the character encoding specified by the - // content-type header. - // Unfortunately BKU forgets to specify a chatacter encoding. - // Therefor, .getParameter will assume US-ASCII or something. - // ==> we explicitely set UTF-8 - if (request.getCharacterEncoding() == null) - { - request.setCharacterEncoding("UTF-8"); - logger_.debug(" no character encoding specified - set to UTF-8"); - } - - logger_.debug("AsyncDataResponder: si.current_operation = " + si.current_operation); - - String resp_string = request.getParameter("XMLResponse"); - if (resp_string == null) - { - logger_.debug("response String is null => trying multipart form"); - - DiskFileItemFactory fif = new DiskFileItemFactory(); - fif.setRepository(SettingsReader.getTemporaryDirectory()); - ServletFileUpload sfu = new ServletFileUpload(fif); - - try - { - List items = sfu.parseRequest(request); - - for (int i = 0; i < items.size(); i++) - { - FileItem item = (FileItem) items.get(i); - logger_.debug("item = " + item.getFieldName()); - - if (item.getFieldName().equals("XMLResponse")) - { - resp_string = item.getString("UTF-8"); - } - } - } - catch (FileUploadException e) - { - throw new ServletException("File Upload exception. cannot parse POST data"); - } - - } - - // TODO hotfix - if (logger_.isDebugEnabled()) - { - Enumeration header_names = request.getHeaderNames(); - while (header_names.hasMoreElements()) - { - String header_name = (String)header_names.nextElement(); - String header_value = request.getHeader(header_name); - logger_.debug("header: name = " + header_name + ", value = " +header_value); - } - } - String user_agent = request.getHeader("User-Agent"); - logger_.debug("User-Agent header = " + user_agent); - Properties response_properties = new Properties(); - BKUPostConnection.parseBKUVersion(user_agent, response_properties); - response_properties.setProperty("response_string", resp_string); - si.response_properties[si.current_operation] = response_properties; //request.getParameter("XMLResponse"); - //logger_.debug("AsyncDataResponder: si.response_string[si.current_operation] = " + si.response_string[si.current_operation]); - - si.current_operation++; - - si.finished = true; - - LocalRequestHelper.formatBKUOkResponse(response); - } +// /** +// * The logger definition. +// */ +// private static final Logger logger_ = ConfigLogger.getLogger(AsynchronousDataResponder.class); +// +// protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException +// { +// logger_.debug("AsyncDataResp GET REQUEST."); +// super.doGet(arg0, arg1); +// } +// +// protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException +// { +// logger_.debug("AsyncDataResp !!!!!!!!!!!!!!!!!!!!!!"); +// +// HttpSession session = request.getSession(false); +// if (session == null) +// { +// throw new ServletException("There is no session associated with this request."); +// } +// +// // String session_id_string = request.getParameter("session"); +// // if (session_id_string == null) +// // { +// // throw new ServletException("The session parameter is missing."); +// // } +// +// SessionInformation si = (SessionInformation) session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); +// // long session_id = Long.parseLong(session_id_string); +// // SessionInformation si = SessionTable.get(session_id); +// if (si == null) +// { +// throw new ServletException("The session is not found or no longer valid."); +// } +// +// // InputStream is = request.getInputStream(); +// // byte [] data = new byte[request.getContentLength()]; +// // is.read(data); +// // is.close(); +// // String enc = request.getCharacterEncoding(); +// // String ct = request.getContentType(); +// // Enumeration enum = request.getHeaderNames(); +// // +// // String dat = new String(data, "US-ASCII"); +// // // dat looks like: XMLResponse=blablabla ... +// // // so the actual XMLResponse begins after the = +// // String resp = URLDecoder.decode(dat, "UTF-8"); +// +// logger_.debug("Answer from local service: content-type = '" + request.getContentType() + "', character encoding = '" + request.getCharacterEncoding() + "'"); +// +// // .getParameter will use the character encoding specified by the +// // content-type header. +// // Unfortunately BKU forgets to specify a chatacter encoding. +// // Therefor, .getParameter will assume US-ASCII or something. +// // ==> we explicitely set UTF-8 +// if (request.getCharacterEncoding() == null) +// { +// request.setCharacterEncoding("UTF-8"); +// logger_.debug(" no character encoding specified - set to UTF-8"); +// } +// +// logger_.debug("AsyncDataResponder: si.current_operation = " + si.current_operation); +// +// String resp_string = request.getParameter("XMLResponse"); +// if (resp_string == null) +// { +// logger_.debug("response String is null => trying multipart form"); +// +// DiskFileItemFactory fif = new DiskFileItemFactory(); +// fif.setRepository(SettingsReader.getTemporaryDirectory()); +// ServletFileUpload sfu = new ServletFileUpload(fif); +// +// try +// { +// List items = sfu.parseRequest(request); +// +// for (int i = 0; i < items.size(); i++) +// { +// FileItem item = (FileItem) items.get(i); +// logger_.debug("item = " + item.getFieldName()); +// +// if (item.getFieldName().equals("XMLResponse")) +// { +// resp_string = item.getString("UTF-8"); +// } +// } +// } +// catch (FileUploadException e) +// { +// throw new ServletException("File Upload exception. cannot parse POST data"); +// } +// +// } +// +// // TODO hotfix - already deprecated +// if (logger_.isDebugEnabled()) +// { +// Enumeration header_names = request.getHeaderNames(); +// while (header_names.hasMoreElements()) +// { +// String header_name = (String)header_names.nextElement(); +// String header_value = request.getHeader(header_name); +// logger_.debug("header: name = " + header_name + ", value = " +header_value); +// } +// } +// String user_agent = request.getHeader("User-Agent"); +// logger_.debug("User-Agent header = " + user_agent); +// Properties response_properties = new Properties(); +// BKUPostConnection.parseBKUVersion(user_agent, response_properties); +// response_properties.setProperty("response_string", resp_string); +// si.response_properties[si.current_operation] = response_properties; //request.getParameter("XMLResponse"); +// //logger_.debug("AsyncDataResponder: si.response_string[si.current_operation] = " + si.response_string[si.current_operation]); +// +// si.current_operation++; +// +// si.finished = true; +// +// LocalRequestHelper.formatBKUOkResponse(response); +// } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java index 58d0773..695b95c 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java @@ -17,188 +17,168 @@ */ package at.knowcenter.wag.egov.egiz.web; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.apache.log4j.Logger; - -import at.knowcenter.wag.egov.egiz.PdfASID; -import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger; -import at.knowcenter.wag.egov.egiz.exceptions.ErrorCodeException; -import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; -import at.knowcenter.wag.egov.egiz.framework.Signator; -import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; -import at.knowcenter.wag.egov.egiz.sig.ConnectorFactory; -import at.knowcenter.wag.egov.egiz.sig.SignatureResponse; -import at.knowcenter.wag.egov.egiz.sig.connectors.BKUConnector; -import at.knowcenter.wag.egov.egiz.web.servlets.SignServlet; /** * Servlet that responds to the redirect requests of the local service (e.g. * BKU). * + * @deprecated remove this + * * @author wprinz */ public class AsynchronousRedirectResponder extends HttpServlet { - + /** * SVUID. */ private static final long serialVersionUID = -682360466333727236L; - /** - * The logger definition. - */ - private static final Logger logger_ = ConfigLogger.getLogger(AsynchronousRedirectResponder.class); - - protected void dispatch(HttpServletRequest request, - HttpServletResponse response, String resource) throws ServletException, IOException - { - response.setContentType("text/html"); - response.setCharacterEncoding("UTF-8"); - - RequestDispatcher disp = getServletContext().getRequestDispatcher(resource); - disp.forward(request, response); - } - - protected void dispatchToResults(List results, HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException - { - request.setAttribute("results", results); - dispatch(request, response, "/jsp/results.jsp"); - } - - protected void dispatchToRedirectRefreshPage (HttpServletRequest request, - HttpServletResponse response, String refresh_url) throws ServletException, IOException - { - request.setAttribute("refresh_url", refresh_url); - dispatch(request, response, LocalRequestHelper.REDIRECT_REFRESH_PAGE_JSP); - } - - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException - { - logger_.debug("AsyncRedirResp"); - - SessionInformation si = null; - - HttpSession session = null; - try - { - session = request.getSession(false); - //String session_id_string = request.getParameter("session"); - if (session == null) - { - throw new ErrorCodeException(600, "The session is missing."); - } - - si = (SessionInformation) session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); -// long session_id = Long.parseLong(session_id_string); -// si = SessionTable.get(session_id); - if (si == null) - { - throw new ErrorCodeException(600, "The session is not found or is no longer valid."); - } - - } - catch (PresentableException e) - { - e.printStackTrace(); - SignServlet.prepareDispatchToErrorPage(e, request); - dispatch(request, response, "/jsp/error.jsp"); - - return; - } - - try - { - if (si.finished == false) - { - String url = request.getRequestURL().toString(); - logger_.debug("RequestURL = " + url); - String refresh_url = response.encodeURL(url); - logger_.debug("RefreshURL = " + refresh_url); - dispatchToRedirectRefreshPage(request, response, refresh_url); - return; - } - - // si.finished is true, but maybe there are more requests to process. - if (si.current_operation < si.requests.length) - { - si.finished = false; - - LocalRequestHelper.prepareDispatchToLocalConnectionPage(si.requests[si.current_operation], request, response); - dispatch(request, response, LocalRequestHelper.LOCAL_CONNECTION_PAGE_JSP); - return; - } - - // all requests have been carried out. - - BKUConnector local_conn = (BKUConnector) ConnectorFactory.createConnector(si.connector); - - if (si.application.equals("verify")) - { - List results = new ArrayList(); - - for (int i = 0; i < si.response_properties.length; i++) - { - SignatureResponse sig_resp = local_conn.analyzeVerifyResponse(si.response_properties[i]); - results.add(sig_resp); - } - - dispatchToResults(results, request, response); - } - else - { - //logger_.debug("AsyncRedirResponder: si.response_string[0] = " + si.response_string[0]); - logger_.debug("AsyncRedirResponder: si.current_op = " + si.current_operation); - - // The response string must not be null here - otherwise finished mustn't have been set! -// if (si.response_string[0] == null) +// /** +// * The logger definition. +// */ +// private static final Logger logger_ = ConfigLogger.getLogger(AsynchronousRedirectResponder.class); +// +// protected void dispatch(HttpServletRequest request, +// HttpServletResponse response, String resource) throws ServletException, IOException +// { +// response.setContentType("text/html"); +// response.setCharacterEncoding("UTF-8"); +// +// RequestDispatcher disp = getServletContext().getRequestDispatcher(resource); +// disp.forward(request, response); +// } +// +// protected void dispatchToResults(List results, HttpServletRequest request, +// HttpServletResponse response) throws ServletException, IOException +// { +// request.setAttribute("results", results); +// dispatch(request, response, "/jsp/results.jsp"); +// } +// +// protected void dispatchToRedirectRefreshPage (HttpServletRequest request, +// HttpServletResponse response, String refresh_url) throws ServletException, IOException +// { +// request.setAttribute("refresh_url", refresh_url); +// dispatch(request, response, LocalRequestHelper.REDIRECT_REFRESH_PAGE_JSP); +// } +// +// protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException +// { +// logger_.debug("AsyncRedirResp"); +// +// SessionInformation si = null; +// +// HttpSession session = null; +// try +// { +// session = request.getSession(false); +// //String session_id_string = request.getParameter("session"); +// if (session == null) +// { +// throw new ErrorCodeException(600, "The session is missing."); +// } +// +// si = (SessionInformation) session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); +//// long session_id = Long.parseLong(session_id_string); +//// si = SessionTable.get(session_id); +// if (si == null) +// { +// throw new ErrorCodeException(600, "The session is not found or is no longer valid."); +// } +// +// } +// catch (PresentableException e) +// { +// e.printStackTrace(); +// SignServlet.prepareDispatchToErrorPage(e, request); +// dispatch(request, response, "/jsp/error.jsp"); +// +// return; +// } +// +// try +// { +// if (si.finished == false) +// { +// String url = request.getRequestURL().toString(); +// logger_.debug("RequestURL = " + url); +// String refresh_url = response.encodeURL(url); +// logger_.debug("RefreshURL = " + refresh_url); +// dispatchToRedirectRefreshPage(request, response, refresh_url); +// return; +// } +// +// // si.finished is true, but maybe there are more requests to process. +// if (si.current_operation < si.requests.length) +// { +// si.finished = false; +// +// LocalRequestHelper.prepareDispatchToLocalConnectionPage(si.requests[si.current_operation], request, response); +// dispatch(request, response, LocalRequestHelper.LOCAL_CONNECTION_PAGE_JSP); +// return; +// } +// +// // all requests have been carried out. +// +// BKUConnector local_conn = (BKUConnector) ConnectorFactory.createConnector(si.connector); +// +// if (si.application.equals("verify")) +// { +// List results = new ArrayList(); +// +// for (int i = 0; i < si.response_properties.length; i++) // { -// String url = request.getRequestURL().toString(); -// logger_.debug("RequestURL = " + url); -// String refresh_url = response.encodeURL(url); -// logger_.debug("RefreshURL = " + refresh_url); -// dispatchToRedirectRefreshPage(request, response, refresh_url); -// return ; +// SignatureResponse sig_resp = local_conn.analyzeVerifyResponse(si.response_properties[i]); +// results.add(sig_resp); // } - - // A download blocker may have blocked the first download. - // So, if the user asks for the document a second time and the sign_result - // has already been computed - don't recompute it. - if (si.sign_result == null) - { - //FIXME refactor WEB - si.iui.signed_signature_object = null; //local_conn.analyzeSignResponse(si.response_properties[0], si.type); - - PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); - Signator signator = SignatorFactory.createSignator(algorithm); - - si.sign_result = signator.finishSign(si.iui); - } - - SignServlet.returnSignResponse(si, response); - } - - } - catch (PresentableException e) - { - session.removeAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); - //SessionTable.remove(si.session_id); - - e.printStackTrace(); - SignServlet.prepareDispatchToErrorPage(e, request); - dispatch(request, response, "/jsp/error.jsp"); - } - - } +// +// dispatchToResults(results, request, response); +// } +// else +// { +// //logger_.debug("AsyncRedirResponder: si.response_string[0] = " + si.response_string[0]); +// logger_.debug("AsyncRedirResponder: si.current_op = " + si.current_operation); +// +// // The response string must not be null here - otherwise finished mustn't have been set! +//// if (si.response_string[0] == null) +//// { +//// String url = request.getRequestURL().toString(); +//// logger_.debug("RequestURL = " + url); +//// String refresh_url = response.encodeURL(url); +//// logger_.debug("RefreshURL = " + refresh_url); +//// dispatchToRedirectRefreshPage(request, response, refresh_url); +//// return ; +//// } +// +// // A download blocker may have blocked the first download. +// // So, if the user asks for the document a second time and the sign_result +// // has already been computed - don't recompute it. +// if (si.sign_result == null) +// { +// // refactor WEB +// si.iui.signed_signature_object = null; //local_conn.analyzeSignResponse(si.response_properties[0], si.type); +// +// PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); +// Signator signator = SignatorFactory.createSignator(algorithm); +// +// si.sign_result = signator.finishSign(si.iui); +// } +// +// SignServlet.returnSignResponse(si, response); +// } +// +// } +// catch (PresentableException e) +// { +// session.removeAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); +// //SessionTable.remove(si.session_id); +// +// e.printStackTrace(); +// SignServlet.prepareDispatchToErrorPage(e, request); +// dispatch(request, response, "/jsp/error.jsp"); +// } +// +// } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java index fd47cca..8ee09dc 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java @@ -20,20 +20,26 @@ package at.knowcenter.wag.egov.egiz.web; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; -import java.util.ArrayList; import java.util.List; import java.util.Properties; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - +import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.web.CurrentLocalOperation; +import at.gv.egiz.pdfas.web.SignSessionInformation; +import at.gv.egiz.pdfas.web.VerifySessionInformation; +import at.knowcenter.wag.egov.egiz.PdfAS; +import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; import at.knowcenter.wag.egov.egiz.exceptions.ConnectorFactoryException; import at.knowcenter.wag.egov.egiz.exceptions.NormalizeException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; +import at.knowcenter.wag.egov.egiz.pdf.BinarySignatureHolder; import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; import at.knowcenter.wag.egov.egiz.sig.SignatureData; import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl; @@ -42,8 +48,6 @@ import at.knowcenter.wag.egov.egiz.sig.connectors.ConnectorChooser; import at.knowcenter.wag.egov.egiz.sig.connectors.LocalConnector; import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject; import at.knowcenter.wag.egov.egiz.sig.signatureobject.SignatureObjectHelper; -import at.knowcenter.wag.egov.egiz.tools.CodingHelper; -import at.knowcenter.wag.egov.egiz.web.servlets.SignServlet; /** * Contains commonly used helper functions for the local request procedure. @@ -66,8 +70,6 @@ public abstract class LocalRequestHelper * The resource of the redirect refresh page jsp. */ public static final String REDIRECT_REFRESH_PAGE_JSP = "/jsp/redirect_refresh_page.jsp"; - - private static Log log = LogFactory.getLog(LocalRequestHelper.class); /** * Sets up the local sign procedure. @@ -79,40 +81,35 @@ public abstract class LocalRequestHelper * @throws PresentableException * Forwarded exception. */ - public static String processLocalSign(SessionInformation si, - HttpServletRequest request, HttpServletResponse response) throws IOException, PresentableException + public static String processLocalSign(SignSessionInformation si, HttpServletRequest request, HttpServletResponse response) throws IOException, PresentableException { String host = request.getServerName(); // "129.27.153.77" URL loc_ref_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/RetrieveSignatureData"); String loc_ref_url = response.encodeURL(loc_ref_URL.toString()); - + LocalConnector c = ConnectorChooser.chooseLocalConnectorForSign(si.connector, si.type, loc_ref_url); - String sign_request = c.prepareSignRequest(si.iui.signature_data); + String sign_request = c.prepareSignRequest(si.si.getSignatureData()); - // TODO local URL - String local_request_url = "http://127.0.0.1:3495/http-security-layer-request"; - si.requests = new LocalRequest[1]; - si.requests[0] = new LocalRequest(local_request_url, sign_request); - si.current_operation = 0; - si.response_properties = new Properties[1]; - si.response_properties[0] = null; + String local_request_url = getLocalServiceAddress(si.type, si.connector); + si.localRequest = new LocalRequest(local_request_url, sign_request); + si.outputAvailable = false; + si.response_properties = null; URL data_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/DataURL"); String data_url = response.encodeURL(data_URL.toString()); request.setAttribute("local_request_url", local_request_url); request.setAttribute("data_url", data_url); - + return NULL_REQUEST_PAGE_JSP; - - - // TODO make better + + // TODO old code - remove // // LocalConnector local_conn = (LocalConnector) // ConnectorFactory.createConnector(si.connector); // // - // // FIXME refactor WEB + // // refactor WEB // String document_text = "fixme"; //si.iui.document_text; // String request_string = local_conn.prepareSignRequest(si.user_name, // document_text, si.type); @@ -162,39 +159,45 @@ public abstract class LocalRequestHelper * Forwarded exception. * @throws ConnectorFactoryException * Forwarded exception. + * @throws SettingsException + * @throws ConnectorException */ - public static String processLocalVerify(SessionInformation si, - List holders_to_verify, HttpServletRequest request, - HttpServletResponse response) throws SignatureException, NormalizeException, IOException, ConnectorFactoryException + public static String processLocalVerify(VerifySessionInformation si, List holders_to_verify, HttpServletRequest request, HttpServletResponse response) throws SignatureException, NormalizeException, + IOException, ConnectorFactoryException, SettingsException, ConnectorException { - si.requests = new LocalRequest[holders_to_verify.size()]; - si.response_properties = new Properties[si.requests.length]; - si.current_operation = 0; - si.finished = false; + si.currentLocalOperation = new CurrentLocalOperation(); + si.currentLocalOperation.holders_to_be_verified = holders_to_verify; + + si.currentLocalOperation.requests = new LocalRequest[holders_to_verify.size()]; + si.currentLocalOperation.response_properties = new Properties[si.currentLocalOperation.requests.length]; + + si.currentLocalOperation.current_operation = 0; +// si.finished = false; String host = request.getServerName(); URL loc_ref_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/RetrieveSignatureData"); String loc_ref_url = response.encodeURL(loc_ref_URL.toString()); - for (int i = 0; i < si.requests.length; i++) + for (int i = 0; i < si.currentLocalOperation.requests.length; i++) { SignatureHolder holder = (SignatureHolder) holders_to_verify.get(i); SignatureObject s = holder.getSignatureObject(); - // TODO This whole processing is unnecessary here because only the mime - // type is used. - String text_to_be_verified = holder.getSignedText(); - SignatureData sd = null; - if (holder.getSignatureObject().isBinary()) - { - byte[] data = CodingHelper.decodeBase64(text_to_be_verified); - sd = new SignatureDataImpl(data, "application/pdf"); - } - else - { - sd = new SignatureDataImpl(text_to_be_verified.getBytes("UTF-8"), "text/plain", "UTF-8"); - } + SignatureData sd = PdfAS.convertSignatureHolderToSignatureData(holder); +// if (holder.getSignatureObject().isBinary()) +// { +// BinarySignatureHolder bsh = (BinarySignatureHolder) holder; +// // byte[] data = CodingHelper.decodeBase64(text_to_be_verified); +// // TODO what about the length of the PDF? is this correct - already deprecated +// sd = new SignatureDataImpl(bsh.getSignedPdf(), "application/pdf"); +// } +// else +// { +// String text_to_be_verified = holder.getSignedText(); +// DataSource ds = new TextDataSourceImpl(text_to_be_verified); +// sd = new SignatureDataImpl(ds, "text/plain", "UTF-8"); +// } SignSignatureObject so = SignatureObjectHelper.convertSignatureObjectToSignSignatureObject(s); @@ -202,16 +205,15 @@ public abstract class LocalRequestHelper String request_string = local_conn.prepareVerifyRequest(sd, so); LocalRequest local_request = new LocalRequest("not-needed", request_string); - si.requests[i] = local_request; - si.response_properties[i] = null; + si.currentLocalOperation.requests[i] = local_request; + si.currentLocalOperation.response_properties[i] = null; } - - // TODO read from config - String local_request_url = "http://127.0.0.1:3495/http-security-layer-request"; + + String local_request_url = getLocalServiceAddress(si.type, si.connector); URL data_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/DataURL"); String data_url = response.encodeURL(data_URL.toString()); - + request.setAttribute("local_request_url", local_request_url); request.setAttribute("data_url", data_url); @@ -259,75 +261,78 @@ public abstract class LocalRequestHelper // // prepareDispatchToLocalConnectionPage(si.requests[0], request, response); } - - /** - * Sets up the local verify procedure. - * - * @param response - * The HttpServletResponse the local request page is written to. - * @return Returns the JSP location where the calling servlet should dispatch - * to. - * @throws SignatureException - * Forwarded exception. - * @throws NormalizeException - * Forwarded exception. - * @throws IOException - * Forwarded exception. - * @throws ConnectorFactoryException - * Forwarded exception. - */ - public static String processLocalVerifyForSingleSignature(SessionInformation si, - List holders_to_verify, HttpServletRequest request, - HttpServletResponse response) throws SignatureException, NormalizeException, IOException, ConnectorFactoryException - { - si.requests = new LocalRequest[1]; - si.response_properties = new Properties[1]; - si.current_operation = 0; - si.finished = false; - - String host = request.getServerName(); - URL loc_ref_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/RetrieveSignatureData"); - String loc_ref_url = response.encodeURL(loc_ref_URL.toString()); - - SignatureHolder holder = (SignatureHolder) holders_to_verify.get(0); - - SignatureObject s = holder.getSignatureObject(); - - // TODO This whole processing is unnecessary here because only the mime - // type is used. - String text_to_be_verified = holder.getSignedText(); - SignatureData sd = null; - - if (holder.getSignatureObject().isBinary()) - { - byte[] data = CodingHelper.decodeBase64(text_to_be_verified); - sd = new SignatureDataImpl(data, "application/pdf"); - } - else - { - sd = new SignatureDataImpl(text_to_be_verified.getBytes("UTF-8"), "text/plain", "UTF-8"); - } - - SignSignatureObject so = SignatureObjectHelper.convertSignatureObjectToSignSignatureObject(s); - - LocalConnector local_conn = ConnectorChooser.chooseLocalConnectorForVerify(si.connector, s.getKZ(), so.id, si.type, loc_ref_url); - String request_string = local_conn.prepareVerifyRequest(sd, so); - - LocalRequest local_request = new LocalRequest("not-needed", request_string); - si.requests[0] = local_request; - si.response_properties[0] = null; - - // TODO read from config - String local_request_url = "http://127.0.0.1:3495/http-security-layer-request"; - - URL data_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/DataURL"); - String data_url = response.encodeURL(data_URL.toString()); - - request.setAttribute("local_request_url", local_request_url); - request.setAttribute("data_url", data_url); - return NULL_REQUEST_PAGE_JSP; - } + // what is this for? +// /** +// * Sets up the local verify procedure. +// * +// * @param response +// * The HttpServletResponse the local request page is written to. +// * @return Returns the JSP location where the calling servlet should dispatch +// * to. +// * @throws SignatureException +// * Forwarded exception. +// * @throws NormalizeException +// * Forwarded exception. +// * @throws IOException +// * Forwarded exception. +// * @throws ConnectorFactoryException +// * Forwarded exception. +// * @throws SettingsException Forwarded exception. +// */ +// public static String processLocalVerifyForSingleSignature(VerifySessionInformation si, List holders_to_verify, HttpServletRequest request, HttpServletResponse response) throws SignatureException, +// NormalizeException, IOException, ConnectorFactoryException, SettingsException +// { +// si.requests = new LocalRequest[1]; +// si.response_properties = new Properties[1]; +// si.current_operation = 0; +// si.finished = false; +// +// String host = request.getServerName(); +// URL loc_ref_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/RetrieveSignatureData"); +// String loc_ref_url = response.encodeURL(loc_ref_URL.toString()); +// +// SignatureHolder holder = (SignatureHolder) holders_to_verify.get(0); +// +// SignatureObject s = holder.getSignatureObject(); +// +// // TODO This whole processing is unnecessary here because only the mime type is used. - already deprecated +// // String text_to_be_verified = holder.getSignedText(); +// SignatureData sd = null; +// +// if (holder.getSignatureObject().isBinary()) +// { +// BinarySignatureHolder bsh = (BinarySignatureHolder) holder; +// // byte[] data = CodingHelper.decodeBase64(text_to_be_verified); +// sd = new SignatureDataImpl(bsh.getSignedPdf(), "application/pdf"); +// } +// else +// { +// String text_to_be_verified = holder.getSignedText(); +// DataSource ds = new TextDataSourceImpl(text_to_be_verified); +// sd = new SignatureDataImpl(ds, "text/plain", "UTF-8"); +// } +// +// SignSignatureObject so = SignatureObjectHelper.convertSignatureObjectToSignSignatureObject(s); +// +// LocalConnector local_conn = ConnectorChooser.chooseLocalConnectorForVerify(si.connector, s.getKZ(), so.id, si.type, loc_ref_url); +// String request_string = local_conn.prepareVerifyRequest(sd, so); +// +// LocalRequest local_request = new LocalRequest("not-needed", request_string); +// si.requests[0] = local_request; +// si.response_properties[0] = null; +// +// // TODO read from config - already deprecated +// String local_request_url = getLocalServiceAddress(si.type, si.connector); +// +// URL data_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/DataURL"); +// String data_url = response.encodeURL(data_URL.toString()); +// +// request.setAttribute("local_request_url", local_request_url); +// request.setAttribute("data_url", data_url); +// +// return NULL_REQUEST_PAGE_JSP; +// } /** * Formats the OK response from the web application back to the local BKU. @@ -370,9 +375,8 @@ public abstract class LocalRequestHelper * @throws NormalizeException * Forwarded exception. */ - public static void prepareDispatchToLocalConnectionPage( - LocalRequest local_request, HttpServletRequest request, - HttpServletResponse response) throws IOException, SignatureException, NormalizeException + public static void prepareDispatchToLocalConnectionPage(LocalRequest local_request, HttpServletRequest request, HttpServletResponse response) throws IOException, SignatureException, + NormalizeException { response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); @@ -403,19 +407,71 @@ public abstract class LocalRequestHelper output = output.replaceAll(">", ">"); return output; } - + public static String getLocalServerAddress(HttpServletRequest request, HttpServletResponse response) { - String host = request.getServerName(); - URL local_server = null; - try { - local_server = new URL(request.getScheme(), host, request.getServerPort(), "/"); - } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - String loc_server = response.encodeURL(local_server.toString()); - - return loc_server; + String host = request.getServerName(); + URL local_server = null; + try + { + local_server = new URL(request.getScheme(), host, request.getServerPort(), "/"); + } + catch (MalformedURLException e) + { + e.printStackTrace(); + } + String loc_server = response.encodeURL(local_server.toString()); + + return loc_server; } + + /** + * Returns the URL for accessing the local service. + *

+ * This information is taken from the profile and if not defined from the + * defaults. + *

+ *

+ * E.g. http://127.0.0.1:3495/http-security-layer-request + *

+ * + * @param profile + * The profile to take the data from. + * @param device + * The service device to be accessed. E.g. bku. + * @return Returns the URL for accessing the local service. + * @throws SettingsException F.e. + */ + public static String getLocalServiceAddress(String profile, String device) throws SettingsException + { + SettingsReader settings = SettingsReader.getInstance(); + + String url = getConnectorValueFromProfile(settings, profile, device + ".sign.url"); + + return url; //"http://127.0.0.1:3495/http-security-layer-request"; + } + + /** + * Reads the configuration entry given by the key, first from the given + * profile, if not found from the defaults. + * + * @param settings + * The settings. + * @param profile + * The profile. + * @param key + * The configuration key. + * @return Returns the configuration entry. + */ + public static String getConnectorValueFromProfile(SettingsReader settings, + String profile, String key) + { + String value = settings.getValueFromKey("sig_obj." + profile + "." + key); //$NON-NLS-1$//$NON-NLS-2$ + if (value == null) + { + value = settings.getValueFromKey(key); + } + return value; + } + } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/PdfASServletContextListener.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/PdfASServletContextListener.java index 954bcce..0e0c625 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/PdfASServletContextListener.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/PdfASServletContextListener.java @@ -58,15 +58,15 @@ public class PdfASServletContextListener implements ServletContextListener String base_dir = sce.getServletContext().getRealPath("/"); //$NON-NLS-1$ logger.info("PDF-AS real path = " + base_dir); //$NON-NLS-1$ - try - { - logger.info("PDF-AS work directory = " + new File(work_dir).getCanonicalPath()); //$NON-NLS-1$ - logger.info("PDF-AS base directory = " + new File(base_dir).getCanonicalPath()); //$NON-NLS-1$ - } - catch (IOException e) - { - e.printStackTrace(); - } +// try +// { +// logger.info("PDF-AS work directory = " + new File(work_dir).getCanonicalPath()); //$NON-NLS-1$ +// logger.info("PDF-AS base directory = " + new File(base_dir).getCanonicalPath()); //$NON-NLS-1$ +// } +// catch (IOException e) +// { +// e.printStackTrace(); +// } if (work_dir != null && work_dir.length() > 0) { diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/SessionInformation.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/SessionInformation.java index acf4416..3eb08f5 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/SessionInformation.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/SessionInformation.java @@ -21,6 +21,10 @@ import java.io.Serializable; import java.util.List; import java.util.Properties; +import at.gv.egiz.pdfas.impl.output.FileBasedDataSink; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.signator.SignatorInformation; + import at.knowcenter.wag.egov.egiz.framework.SignResult; import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation; import at.knowcenter.wag.egov.egiz.pdf.TablePos; @@ -63,7 +67,8 @@ public class SessionInformation implements Serializable /** * The original, uploaded pdf. */ - public byte[] pdf = null; + //public byte[] pdf = null; + public PdfDataSource pdfDataSource = null; /** * The type/profile of the signature. @@ -106,6 +111,10 @@ public class SessionInformation implements Serializable */ public IncrementalUpdateInformation iui; + public SignatorInformation si = null; + + public FileBasedDataSink output = null; + /** * The signature holders. */ @@ -127,10 +136,12 @@ public class SessionInformation implements Serializable */ public boolean download_inline; - /** - * The sign result to be passed back to the user. - */ - public SignResult sign_result; +// /** +// * The sign result to be passed back to the user. +// */ +// public SignResult sign_result; + + public boolean isSignFinished = false; diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/DataURLServlet.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/DataURLServlet.java index 72f7c2d..2844c6d 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/DataURLServlet.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/DataURLServlet.java @@ -4,11 +4,11 @@ package at.knowcenter.wag.egov.egiz.web.servlets; import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; @@ -16,26 +16,31 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; + +import at.gv.egiz.pdfas.exceptions.framework.SignatorException; +import at.gv.egiz.pdfas.framework.SignatorFactory; +import at.gv.egiz.pdfas.framework.signator.Signator; +import at.gv.egiz.pdfas.web.SignSessionInformation; +import at.gv.egiz.pdfas.web.VerifySessionInformation; +import at.gv.egiz.pdfas.web.helper.SessionHelper; +import at.gv.egiz.pdfas.web.helper.SignServletHelper; +import at.gv.egiz.pdfas.web.helper.TempDirHelper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import at.knowcenter.wag.egov.egiz.PdfASID; +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; +import at.knowcenter.wag.egov.egiz.exceptions.InvalidIDException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; -import at.knowcenter.wag.egov.egiz.framework.Signator; -import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; +import at.knowcenter.wag.egov.egiz.exceptions.SignatorFactoryException; import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; import at.knowcenter.wag.egov.egiz.sig.SignatureResponse; import at.knowcenter.wag.egov.egiz.sig.connectors.ConnectorChooser; import at.knowcenter.wag.egov.egiz.sig.connectors.LocalConnector; import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection; -import at.knowcenter.wag.egov.egiz.sig.connectors.bku.EnvelopedBase64BKUConnector; -import at.knowcenter.wag.egov.egiz.sig.connectors.bku.LocRefDetachedBKUConnector; import at.knowcenter.wag.egov.egiz.web.FormFields; import at.knowcenter.wag.egov.egiz.web.LocalRequest; -import at.knowcenter.wag.egov.egiz.web.SessionAttributes; -import at.knowcenter.wag.egov.egiz.web.SessionInformation; /** * @author wprinz @@ -71,9 +76,10 @@ public class DataURLServlet extends HttpServlet } protected void dispatchToResults(List results, HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException + HttpServletResponse response, String backToListURL) throws ServletException, IOException { request.setAttribute("results", results); + request.setAttribute("btlurl", backToListURL); dispatch(request, response, "/jsp/results.jsp"); } @@ -85,122 +91,171 @@ public class DataURLServlet extends HttpServlet { log.debug("Data URL is accessed."); //$NON-NLS-1$ - HttpSession session = request.getSession(false); - if (session == null) + try { - String msg = "There is no session associated with this request."; //$NON-NLS-1$ - log.error(msg); - throw new ServletException(msg); - } + Object sessionObject = SessionHelper.getSession(request); + + checkRequestCharacterEncoding(request); + + if (sessionObject instanceof SignSessionInformation) + { + SignSessionInformation si = (SignSessionInformation)sessionObject; + processSign(request, response, si); + } + else + { + VerifySessionInformation si = (VerifySessionInformation) sessionObject; + processVerify(request, response, si); + } - SessionInformation si = (SessionInformation) session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); - if (si == null) + } + catch (PresentableException e) { - String msg = "The session is not found or no longer valid."; //$NON-NLS-1$ - log.error(msg); - throw new ServletException(msg); + log.error(e); + SignServlet.prepareDispatchToErrorPage(e, request); + dispatch(request, response, "/jsp/error.jsp"); } - try + log.debug("DataURL access finished."); //$NON-NLS-1$ + } + + protected void checkRequestCharacterEncoding(HttpServletRequest request) throws UnsupportedEncodingException + { + log.debug("Request character encoding = " + request.getCharacterEncoding()); //$NON-NLS-1$ +// if (request.getCharacterEncoding() == null || request.getCharacterEncoding().equals("UTF-8")) //$NON-NLS-1$ + if (request.getCharacterEncoding() == null || request.getCharacterEncoding().length() <= 0) //$NON-NLS-1$ + { + log.error("The BKU didn't set a character encoding for the request."); //$NON-NLS-1$ + + log.warn("Manually setting character encoding to UTF-8"); //$NON-NLS-1$ + request.setCharacterEncoding("UTF-8"); //$NON-NLS-1$ + } + } + + protected boolean isNullResponse(String xml_response) + { + return xml_response.indexOf("NullOperationResponse") >= 0; + } + + protected void processSign(HttpServletRequest request, HttpServletResponse response, SignSessionInformation si) throws ServletException, IOException, ConnectorException, SignatorException, SignatorFactoryException + { + log.trace("processSign"); + + String xml_response = request.getParameter("XMLResponse"); //$NON-NLS-1$ + log.debug("xml_response = " + xml_response); //$NON-NLS-1$ + + if (isNullResponse(xml_response)) { - log.debug("Request character encoding = " + request.getCharacterEncoding()); //$NON-NLS-1$ - if (request.getCharacterEncoding() == null || request.getCharacterEncoding().equals("UTF-8")) //$NON-NLS-1$ - { - log.error("The BKU didn't set a character encoding for the request."); //$NON-NLS-1$ + log.debug("Received a NullOperationResponse -> answering with the first request."); //$NON-NLS-1$ - log.warn("Manually setting character encoding to UTF-8"); //$NON-NLS-1$ - request.setCharacterEncoding("UTF-8"); //$NON-NLS-1$ - } + assert si.outputAvailable == false; + assert si.response_properties == null; + + log.debug("There are still requests to be performed -> answering with request."); //$NON-NLS-1$ - String xml_response = request.getParameter("XMLResponse"); //$NON-NLS-1$ - log.debug("xml_response = " + xml_response); //$NON-NLS-1$ + LocalRequest local_request = si.localRequest; - if (isNullResponse(xml_response)) - { - log.debug("Received a NullOperationResponse -> answering with the first request."); //$NON-NLS-1$ + String request_string = local_request.getRequestString(); - assert si.current_operation == 0; - } - else + response.setContentType("text/xml"); + response.setCharacterEncoding("UTF-8"); + response.getWriter().println(request_string); + } + else + { + log.debug("Recieved a normal response -> storing the response."); //$NON-NLS-1$ + + Properties response_properties = new Properties(); + response_properties.setProperty(BKUPostConnection.RESPONSE_STRING_KEY, xml_response); + si.response_properties = response_properties; + + log.debug("All requests have been processed -> processing the responses."); //$NON-NLS-1$ + + // Sign + + if (!si.outputAvailable) { - log.debug("Recieved a normal response -> storing the response."); //$NON-NLS-1$ + LocalConnector c = ConnectorChooser.chooseLocalConnectorForSign(si.connector, si.type, "loc ref content not needed here"); //$NON-NLS-1$ + + si.si.setSignSignatureObject(c.analyzeSignResponse(si.response_properties)); - Properties response_properties = new Properties(); - response_properties.setProperty(BKUPostConnection.RESPONSE_STRING_KEY, xml_response); - si.response_properties[si.current_operation] = response_properties; + PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); + Signator signator = SignatorFactory.createSignator(algorithm); - si.current_operation++; + si.output = TempDirHelper.createTempDataSink(si.filename + "_signed.pdf"); + + signator.finishSign(si.si, si.output); + + si.outputAvailable = true; } - if (si.current_operation < si.requests.length) - { - log.debug("There are still requests to be performed -> answering with request #" + si.current_operation); //$NON-NLS-1$ + SignServletHelper.returnSignResponse(si, response); - LocalRequest local_request = si.requests[si.current_operation]; + } + } + + protected void processVerify(HttpServletRequest request, HttpServletResponse response, VerifySessionInformation si) throws ServletException, IOException, ConnectorException, InvalidIDException + { + log.trace("processVerify"); + + String xml_response = request.getParameter("XMLResponse"); //$NON-NLS-1$ + log.debug("xml_response = " + xml_response); //$NON-NLS-1$ - String request_string = local_request.getRequestString(); + if (isNullResponse(xml_response)) + { + log.debug("Received a NullOperationResponse -> answering with the first request."); //$NON-NLS-1$ - response.setContentType("text/xml"); - response.setCharacterEncoding("UTF-8"); - response.getWriter().println(request_string); - } - else - { - log.debug("All requests have been processed -> processing the responses."); //$NON-NLS-1$ + assert si.currentLocalOperation.current_operation == 0; + } + else + { + log.debug("Recieved a normal response -> storing the response."); //$NON-NLS-1$ - if (si.application.equals("sign")) - { - // Sign - - if (si.sign_result == null) - { - LocalConnector c = ConnectorChooser.chooseLocalConnectorForSign(si.connector, si.type, "loc ref content not needed here"); //$NON-NLS-1$ + Properties response_properties = new Properties(); + response_properties.setProperty(BKUPostConnection.RESPONSE_STRING_KEY, xml_response); - si.iui.signed_signature_object = c.analyzeSignResponse(si.response_properties[0]); + si.currentLocalOperation.finishCurrentOperation(response_properties); + } - PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); - Signator signator = SignatorFactory.createSignator(algorithm); + if (!si.currentLocalOperation.isFinished()) + { + log.debug("There are still requests to be performed -> answering with request #" + si.currentLocalOperation.current_operation); //$NON-NLS-1$ - si.sign_result = signator.finishSign(si.iui); - } + LocalRequest local_request = si.currentLocalOperation.getCurrentLocalRequest(); - SignServlet.returnSignResponse(si, response); - } - else + String request_string = local_request.getRequestString(); + + response.setContentType("text/xml"); + response.setCharacterEncoding("UTF-8"); + response.getWriter().println(request_string); + } + else + { + log.debug("All requests have been processed -> processing the responses."); //$NON-NLS-1$ + + + List results = new ArrayList(); + + for (int i = 0; i < si.currentLocalOperation.response_properties.length; i++) { - // Verify + SignatureHolder sh = (SignatureHolder) si.currentLocalOperation.holders_to_be_verified.get(i); + + PdfASID sig_kz = sh.getSignatureObject().getKZ(); + String sig_id = sh.getSignatureObject().getSignationIds(); - List results = new ArrayList(); - - for (int i = 0; i < si.response_properties.length; i++) - { - SignatureHolder sh = (SignatureHolder) si.signature_holders.get(i); - - PdfASID sig_kz = sh.getSignatureObject().getKZ(); - String sig_id = sh.getSignatureObject().getSignationIds(); - - LocalConnector c = ConnectorChooser.chooseLocalConnectorForVerify(si.connector, sig_kz, sig_id, si.type, "loc ref content not needed here"); //$NON-NLS-1$ - - SignatureResponse sig_resp = c.analyzeVerifyResponse(si.response_properties[i]); - results.add(sig_resp); - } - - dispatchToResults(results, request, response); + LocalConnector c = ConnectorChooser.chooseLocalConnectorForVerify(si.connector, sig_kz, sig_id, si.type, "loc ref content not needed here"); //$NON-NLS-1$ + + SignatureResponse sig_resp = c.analyzeVerifyResponse(si.currentLocalOperation.response_properties[i]); + results.add(sig_resp); } - } - } - catch (PresentableException e) - { - log.error(e); - SignServlet.prepareDispatchToErrorPage(e, request); - dispatch(request, response, "/jsp/error.jsp"); - } + + si.currentLocalOperation = null; - log.debug("DataURL access finished."); //$NON-NLS-1$ - } + URL btlURL = new URL(request.getScheme(), request.getServerName(), request.getServerPort(), request.getContextPath() + "/jsp/verifylist.jsp"); + String backToListURL = response.encodeURL(btlURL.toString()); + + dispatchToResults(results, request, response, backToListURL); + } - protected boolean isNullResponse(String xml_response) - { - return xml_response.indexOf("NullOperationResponse") >= 0; } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/RetrieveSignatureDataServlet.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/RetrieveSignatureDataServlet.java index 402170c..6653a60 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/RetrieveSignatureDataServlet.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/RetrieveSignatureDataServlet.java @@ -5,22 +5,29 @@ package at.knowcenter.wag.egov.egiz.web.servlets; import java.io.IOException; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; + +import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl; +import at.gv.egiz.pdfas.exceptions.web.SessionExpiredException; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.web.SignSessionInformation; +import at.gv.egiz.pdfas.web.VerifySessionInformation; +import at.gv.egiz.pdfas.web.helper.SessionHelper; +import at.gv.egiz.pdfas.utils.StreamUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import at.knowcenter.wag.egov.egiz.PdfAS; +import at.knowcenter.wag.egov.egiz.pdf.BinarySignatureHolder; import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; import at.knowcenter.wag.egov.egiz.sig.SignatureData; import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl; -import at.knowcenter.wag.egov.egiz.sig.SignatureObject; -import at.knowcenter.wag.egov.egiz.tools.CodingHelper; -import at.knowcenter.wag.egov.egiz.web.SessionAttributes; -import at.knowcenter.wag.egov.egiz.web.SessionInformation; /** * Retrieves the Signature Data from the session and returns it. @@ -40,61 +47,103 @@ public class RetrieveSignatureDataServlet extends HttpServlet */ private static Log log = LogFactory.getLog(RetrieveSignatureDataServlet.class); + protected void dispatch(HttpServletRequest request, + HttpServletResponse response, String resource) throws ServletException, IOException + { + dispatch(request, response, resource, getServletContext()); + } + + protected static void dispatch(HttpServletRequest request, + HttpServletResponse response, String resource, ServletContext context) throws ServletException, IOException + { + response.setContentType("text/html"); + response.setCharacterEncoding("UTF-8"); + + RequestDispatcher disp = context.getRequestDispatcher(resource); + disp.forward(request, response); + } + /** - * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { log.debug("Request for receiving signature data."); //$NON-NLS-1$ - - HttpSession session = request.getSession(false); - if (session == null) + + try { - String msg = "There is no session associated with this request."; //$NON-NLS-1$ - log.error(msg); - throw new ServletException(msg); + Object sessionObject = SessionHelper.getSession(request); + + if (sessionObject instanceof SignSessionInformation) + { + SignSessionInformation si = (SignSessionInformation) sessionObject; + processSign(request, response, si); } - - SessionInformation si = (SessionInformation) session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); - if (si == null) + else { - String msg = "The session is not found or no longer valid."; //$NON-NLS-1$ - log.error(msg); - throw new ServletException(msg); + VerifySessionInformation si = (VerifySessionInformation) sessionObject; + processVerify(request, response, si); } - + } + catch (SessionExpiredException e) + { + log.error(e); + SignServlet.prepareDispatchToErrorPage(e, request); + dispatch(request, response, "/jsp/error.jsp"); + } + } + + protected void processSign(HttpServletRequest request, HttpServletResponse response, SignSessionInformation si) throws ServletException, IOException + { + writeSignatureData(si.si.getSignatureData(), response); + } + + protected void processVerify(HttpServletRequest request, HttpServletResponse response, VerifySessionInformation si) throws ServletException, IOException + { SignatureData sd = null; - if (si.application.equals("sign")) + + SignatureHolder holder = null; + + if (si.currentLocalOperation != null) { - sd = si.iui.signature_data; + holder = si.currentLocalOperation.getCurrentSignatureHolder(); } else { - SignatureHolder holder = (SignatureHolder) si.signature_holders.get(si.current_operation); - SignatureObject s = holder.getSignatureObject(); - - // TODO make better - String text_to_be_verified = holder.getSignedText(); - if (holder.getSignatureObject().isBinary()) - { - byte[] data = CodingHelper.decodeBase64(text_to_be_verified); - sd = new SignatureDataImpl(data, "application/pdf"); - } - else - { - sd = new SignatureDataImpl(text_to_be_verified.getBytes("UTF-8"), "text/plain", "UTF-8"); - } - + holder = si.moa_holder; } + + log.debug("holder = " + holder.toString()); - log.debug("Writing " + sd.getMimeType() + " data:"); //$NON-NLS-1$ //$NON-NLS-2$ + sd = PdfAS.convertSignatureHolderToSignatureData(holder); +// if (holder.getSignatureObject().isBinary()) +// { +// BinarySignatureHolder bsh = (BinarySignatureHolder) holder; +// // byte[] data = CodingHelper.decodeBase64(text_to_be_verified); +// sd = new SignatureDataImpl(bsh.getSignedPdf(), "application/pdf"); +// } +// else +// { +// String text_to_be_verified = holder.getSignedText(); +// DataSource ds = new TextDataSourceImpl(text_to_be_verified); +// sd = new SignatureDataImpl(ds, "text/plain", "UTF-8"); +// } + log.debug("sd = " + sd.toString() + ", " + sd.getDataSource().getClass().getName() + ", " + sd.getDataSource().getLength() + ", " + sd.getMimeType() + ", " + sd.getCharacterEncoding()); + + writeSignatureData(sd, response); + } + + protected void writeSignatureData(SignatureData sd, HttpServletResponse response) throws IOException + { + log.trace("Writing " + sd.getMimeType() + " data:"); //$NON-NLS-1$ //$NON-NLS-2$ + response.setContentType(sd.getMimeType()); response.setCharacterEncoding(sd.getCharacterEncoding()); - response.getOutputStream().write(sd.getData()); - - log.debug("Writing SignatureData finished."); //$NON-NLS-1$ - } + StreamUtils.writeInputStreamToOutputStream(sd.getDataSource().createInputStream(), response.getOutputStream()); + // response.getOutputStream().write(sd.getData()); - + log.trace("Writing SignatureData finished."); //$NON-NLS-1$ + } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/SignPreviewServlet.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/SignPreviewServlet.java index 1d8ee0b..aec4f25 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/SignPreviewServlet.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/SignPreviewServlet.java @@ -24,13 +24,11 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import at.knowcenter.wag.egov.egiz.exceptions.ErrorCodeException; +import at.gv.egiz.pdfas.web.SignSessionInformation; +import at.gv.egiz.pdfas.web.helper.SessionHelper; +import at.gv.egiz.pdfas.web.helper.SignServletHelper; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; -import at.knowcenter.wag.egov.egiz.web.FormFields; -import at.knowcenter.wag.egov.egiz.web.SessionAttributes; -import at.knowcenter.wag.egov.egiz.web.SessionInformation; /** * @author wprinz @@ -55,34 +53,13 @@ public class SignPreviewServlet extends HttpServlet protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - SessionInformation si = null; try { - HttpSession session = request.getSession(false); - if (session == null) - { - throw new ErrorCodeException(600, "The session is missing."); - } - - si = (SessionInformation) session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); - if (si == null) - { - throw new ErrorCodeException(600, "The session is not found or is no longer valid."); - } - - } - catch (PresentableException e) - { - e.printStackTrace(); - SignServlet.prepareDispatchToErrorPage(e, request); - dispatch(request, response, "/jsp/error.jsp"); - - return; - } - - try - { - SignServlet.finishSign(si, request, response, getServletContext()); + Object sessionObject = SessionHelper.getSession(request); + + SignSessionInformation si = (SignSessionInformation) sessionObject; + + SignServletHelper.finishSign(si, request, response, getServletContext()); } catch (PresentableException e) { diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/SignServlet.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/SignServlet.java index 54be8df..3f1342d 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/SignServlet.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/SignServlet.java @@ -22,12 +22,10 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.net.URL; import java.util.Iterator; import java.util.List; -import java.util.Properties; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; @@ -35,7 +33,14 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; + +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.gv.egiz.pdfas.exceptions.ErrorCodeHelper; +import at.gv.egiz.pdfas.exceptions.external.ExternalErrorException; +import at.gv.egiz.pdfas.impl.input.FileBasedPdfDataSourceImpl; +import at.gv.egiz.pdfas.web.SignSessionInformation; +import at.gv.egiz.pdfas.web.helper.SignServletHelper; +import at.gv.egiz.pdfas.web.helper.TempDirHelper; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; @@ -43,39 +48,16 @@ import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.log4j.Logger; import at.knowcenter.wag.egov.egiz.PdfAS; -import at.knowcenter.wag.egov.egiz.PdfASID; -import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; -import at.knowcenter.wag.egov.egiz.exceptions.ErrorCodeException; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; import at.knowcenter.wag.egov.egiz.exceptions.PlaceholderException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; -import at.knowcenter.wag.egov.egiz.framework.SignResult; -import at.knowcenter.wag.egov.egiz.framework.Signator; -import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; -import at.knowcenter.wag.egov.egiz.framework.signators.DetachedSignator_1_0_0; import at.knowcenter.wag.egov.egiz.pdf.TablePos; -import at.knowcenter.wag.egov.egiz.sig.ConnectorFactory; -import at.knowcenter.wag.egov.egiz.sig.SignatureData; -import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl; -import at.knowcenter.wag.egov.egiz.sig.connectors.Connector; -import at.knowcenter.wag.egov.egiz.sig.connectors.ConnectorChooser; -import at.knowcenter.wag.egov.egiz.sig.connectors.LocalConnector; -import at.knowcenter.wag.egov.egiz.sig.connectors.bku.DetachedBKUConnector; -import at.knowcenter.wag.egov.egiz.sig.connectors.bku.EnvelopedBase64BKUConnector; -import at.knowcenter.wag.egov.egiz.sig.connectors.bku.LocRefDetachedBKUConnector; -import at.knowcenter.wag.egov.egiz.sig.connectors.moa.DetachedLocRefMOAConnector; -import at.knowcenter.wag.egov.egiz.tools.CodingHelper; import at.knowcenter.wag.egov.egiz.web.ExternAppInformation; import at.knowcenter.wag.egov.egiz.web.FormFields; -import at.knowcenter.wag.egov.egiz.web.LocalRequest; -import at.knowcenter.wag.egov.egiz.web.LocalRequestHelper; -import at.knowcenter.wag.egov.egiz.web.PDFContainer; import at.knowcenter.wag.egov.egiz.web.SessionAttributes; -import at.knowcenter.wag.egov.egiz.web.SessionInformation; /** * This method is the sign servlet for the pdf-as web application. It takes get @@ -97,15 +79,13 @@ public class SignServlet extends HttpServlet * The log. */ private static Log log = LogFactory.getLog(SignServlet.class); - - protected void dispatch(HttpServletRequest request, - HttpServletResponse response, String resource) throws ServletException, IOException + + protected void dispatch(HttpServletRequest request, HttpServletResponse response, String resource) throws ServletException, IOException { dispatch(request, response, resource, getServletContext()); } - protected static void dispatch(HttpServletRequest request, - HttpServletResponse response, String resource, ServletContext context) throws ServletException, IOException + protected static void dispatch(HttpServletRequest request, HttpServletResponse response, String resource, ServletContext context) throws ServletException, IOException { response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); @@ -181,10 +161,11 @@ public class SignServlet extends HttpServlet UploadedData ud = null; ExternAppInformation exappinf = null; TablePos pos = null; - + // check if pdf-as has been called by external webapp - if(request.getParameter(FormFields.FIELD_PDF_URL) != null) { - + if (request.getParameter(FormFields.FIELD_PDF_URL) != null) + { + String preview = (String) request.getParameter(FormFields.FIELD_PREVIEW); String sig_type = (String) request.getParameter(FormFields.FIELD_SIGNATURE_TYPE); String sig_app = (String) request.getParameter(FormFields.FIELD_CONNECTOR); @@ -197,65 +178,74 @@ public class SignServlet extends HttpServlet String session_id = (String) request.getParameter(FormFields.FIELD_SESSION_ID); String sig_pos_y = (String) request.getParameter(FormFields.FIELD_SIGPOS_Y); String sig_pos_p = (String) request.getParameter(FormFields.FIELD_SIGPOS_P); - - try { - pos = new TablePos("y:" + sig_pos_y +";p:" + sig_pos_p); - } catch (PDFDocumentException e) { + + try + { + pos = new TablePos("y:" + sig_pos_y + ";p:" + sig_pos_p); + } + catch (PDFDocumentException e) + { log.warn("Uanable to create signature position object: " + e.getMessage()); } - - String query = pdf_url + "&" + FormFields.FIELD_PDF_ID + "=" + pdf_id; - - byte[] extern_pdf = new byte[Integer.parseInt(pdf_length)]; + + String query = pdf_url + "&" + FormFields.FIELD_PDF_ID + "=" + pdf_id; + + // wprinz: rem: this allocation is useless + // byte[] extern_pdf = new byte[Integer.parseInt(pdf_length)]; URL source_url = new URL(query); InputStream is = source_url.openStream(); - extern_pdf = toByteArray(is); - - // set UploadedData object... + // extern_pdf = toByteArray(is); + + // set UploadedData object... UploadedData ud_extern = new UploadedData(); ud_extern.file_name = filename; - ud_extern.pdf = extern_pdf; + ud_extern.pdfDataSource = TempDirHelper.placePdfIntoTempDir(is, filename); + // ud_extern.pdf = extern_pdf; ud_extern.preview = preview.equalsIgnoreCase("true") ? true : false; ud_extern.sig_app = sig_app; ud_extern.sig_mode = sig_mode; ud_extern.sig_type = sig_type; - + ud = ud_extern; - - exappinf = new ExternAppInformation(invoke_url,pdf_id, session_id); + + exappinf = new ExternAppInformation(invoke_url, pdf_id, session_id); } - else { - + else + { + try { // tzefferer: modified - //UploadedData ud = retrieveUploadedDataFromRequest(request); + // UploadedData ud = retrieveUploadedDataFromRequest(request); UploadedData ud_form = retrieveUploadedDataFromRequest(request); ud = ud_form; // end modify - - } catch(Exception e) { + + } + catch (Exception e) + { // Error retrieving data request.setAttribute("error", "Fehler beim Upload der Daten"); request.setAttribute("cause", "Beim Upload der Daten ist ein Fehler aufgetreten."); dispatch(request, response, "/jsp/error.jsp"); } } - try { + try + { - PdfAS.applyStrictMode(ud.pdf); + PdfAS.applyStrictMode(ud.pdfDataSource); - SessionInformation si = new SessionInformation(); // SessionTable.generateSessionInformationObject(); + SignSessionInformation si = new SignSessionInformation(); // SessionTable.generateSessionInformationObject(); si.connector = ud.sig_app; si.application = "sign"; si.mode = ud.sig_mode; - si.pdf = ud.pdf; + si.pdfDataSource = ud.pdfDataSource; si.type = ud.sig_type; si.filename = formatFileName(ud.file_name); si.download_inline = ud.download_inline; - + // added tzefferer: si.exappinf = exappinf; si.pos = pos; @@ -270,7 +260,7 @@ public class SignServlet extends HttpServlet // si.user_name = user_name; // si.user_password = user_password; - prepareSign(si); + SignServletHelper.prepareSign(si); if (ud.preview) { @@ -285,7 +275,7 @@ public class SignServlet extends HttpServlet return; } - finishSign(si, request, response, getServletContext()); + SignServletHelper.finishSign(si, request, response, getServletContext()); } catch (PresentableException e) { @@ -296,13 +286,13 @@ public class SignServlet extends HttpServlet } // tzefferer:added - public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { doPost(request, response); } // end add - - protected UploadedData retrieveUploadedDataFromRequest( - HttpServletRequest request) throws ServletException, UnsupportedEncodingException, FileUploadException, PDFDocumentException + + protected UploadedData retrieveUploadedDataFromRequest(HttpServletRequest request) throws ServletException, UnsupportedEncodingException, FileUploadException, PDFDocumentException { DiskFileItemFactory fif = new DiskFileItemFactory(); fif.setRepository(SettingsReader.getTemporaryDirectory()); @@ -413,12 +403,22 @@ public class SignServlet extends HttpServlet throw new PDFDocumentException(201, "The provided file '" + doc_file_name + "' doesn't have the PDF extension (.pdf)."); //$NON-NLS-1$//$NON-NLS-2$ } - byte[] pdf = file_upload_fi.get(); if (file_upload_fi.getSize() <= 0) { throw new PDFDocumentException(250, "The document is empty."); //$NON-NLS-1$ } + FileBasedPdfDataSourceImpl pdfDataSource = null; + try + { + pdfDataSource = TempDirHelper.placePdfIntoTempDir(file_upload_fi.getInputStream(), doc_file_name); + } + catch (IOException e) + { + throw new PDFDocumentException(201, "Couldn't store the file in the temp dir."); + } + // byte[] pdf = file_upload_fi.get(); + UploadedData ud = new UploadedData(); ud.preview = preview; @@ -427,129 +427,55 @@ public class SignServlet extends HttpServlet ud.sig_app = sig_app; ud.sig_mode = mode; ud.file_name = doc_file_name; - ud.pdf = pdf; + ud.pdfDataSource = pdfDataSource; return ud; } - /** - * Prepares the sign. - * - *

- * This prepares the data for both being signed or being previewed. - *

- * - * @param si - * The SessionInformation to be prepared. - * @throws PresentableException - * f.e. - */ - public static void prepareSign(SessionInformation si) throws PresentableException - { - log.debug("prepareSign:"); //$NON-NLS-1$ - - PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); - Signator signator = SignatorFactory.createSignator(algorithm); - - //tzefferer: modified - //si.iui = signator.prepareSign(si.pdf, si.type, null, ConnectorFactory.needsSIG_ID(si.connector)); - si.iui = signator.prepareSign(si.pdf, si.type, si.pos, ConnectorFactory.needsSIG_ID(si.connector)); - // end modify - log.debug("prepareSign finished."); //$NON-NLS-1$ - } - - /** - * Finishes the sign. - * - *

- * For non local connectors this concludes the sign process, signs the - * document and returns the result. For local connectors this initializes the - * local sign process and redirects to following servlets. - *

- * - * @param si - * The SessionInformation. - * @param request - * The servlet request for dispatching. - * @param response - * The servlet response for dispatching. - * @param context - * The servlet context for dispatching. - * @throws PresentableException - * f.e. - * @throws IOException - * f. e. - * @throws ServletException - * f. e. - */ - public static void finishSign(SessionInformation si, - HttpServletRequest request, HttpServletResponse response, - ServletContext context) throws PresentableException, IOException, ServletException - { - log.debug("finishSign:"); //$NON-NLS-1$ - - log.debug("connector = " + si.connector); //$NON-NLS-1$ - if (ConnectorFactory.isConnectorLocal(si.connector)) - { - log.debug("Connector is local -> dispatching to local processing."); //$NON-NLS-1$ - - String dispatch_to = LocalRequestHelper.processLocalSign(si, request, response); - dispatch(request, response, dispatch_to, context); - return; - } - log.debug("Connector is not local -> finishing the sign."); //$NON-NLS-1$ - - PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); - Signator signator = SignatorFactory.createSignator(algorithm); - log.debug("RequestURL = " + request.getRequestURL()); - log.debug("ContextPath = " + request.getContextPath()); - String host = request.getServerName(); - URL signature_data_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/RetrieveSignatureData"); - String signature_data_url = response.encodeURL(signature_data_URL.toString()); - Connector c = ConnectorChooser.chooseWebConnectorForSign(si.connector, si.type, signature_data_url); - si.iui.signed_signature_object = c.doSign(si.iui.signature_data); - si.sign_result = signator.finishSign(si.iui); - returnSignResponse(si, response); - - log.debug("finishSign finished."); //$NON-NLS-1$ - } - - public static void prepareDispatchToErrorPage(PresentableException pe, - HttpServletRequest request) + public static void prepareDispatchToErrorPage(PresentableException pe, HttpServletRequest request) { - if (pe instanceof ErrorCodeException) - { - ErrorCodeException ece = (ErrorCodeException) pe; - request.setAttribute("error", "Fehler " + ece.getErrorCode()); + request.setAttribute("PresentableException", pe); +// if (pe instanceof ErrorCodeException) +// { + request.setAttribute("error", "Fehler " + pe.getErrorCode()); - String cause = ece.getErrorCodeMessage(); - if (ece.hasExternalErrorMessage()) + String cause = ErrorCodeHelper.getMessageForErrorCode(pe.getErrorCode()); + + if (pe instanceof ExternalErrorException) { - cause = ece.getExternalErrorCode() + ": " + ece.getExternalErrorMessage(); + ExternalErrorException eee = (ExternalErrorException) pe; + cause = eee.getExternalErrorCode() + ": " + eee.getExternalErrorMessage(); } request.setAttribute("cause", cause); - if (pe instanceof PlaceholderException) + if (pe.getErrorCode() == ErrorCode.PLACEHOLDER_EXCEPTION) { - PlaceholderException phe = (PlaceholderException) ece; + PlaceholderException phe = null; + if (pe instanceof PlaceholderException) + { + phe = (PlaceholderException) pe; + } + else + { + phe = (PlaceholderException) pe.getCause(); + } - request.setAttribute("cause", "Der Platzhalter des Feldes " + phe.getField() + " ist um " + phe.getMissing() + " Bytes zu kurz. " + ece.getErrorCodeMessage()); + request.setAttribute("cause", "Der Platzhalter des Feldes " + phe.getField() + " ist um " + phe.getMissing() + " Bytes zu kurz. " + cause); } - } - else - { - request.setAttribute("error", "PresentableException"); - request.setAttribute("cause", pe.toString()); - } +// } +// else +// { +// request.setAttribute("error", "PresentableException"); +// request.setAttribute("cause", pe.toString()); +// } } - public void dispatchToPreview(String document_text, String connector, - String mode, String signature_type, String submit_url, - HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + public void dispatchToPreview(String document_text, String connector, String mode, String signature_type, String submit_url, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { request.setAttribute("document_text", document_text); request.setAttribute("connector", connector); @@ -576,112 +502,40 @@ public class SignServlet extends HttpServlet return file_name_only; } - /** - * Formats the file name according to the SignResult. - * - * @param file_name - * The file name. - * @param sign_result - * The sign result. - * @return Returns the formatted file name. - */ - public static String formatFileNameForSignResult(String file_name, - SignResult sign_result) - { - String output = file_name + "_signed"; - if (sign_result.getMimeType().equals(DetachedSignator_1_0_0.MIME_TYPE)) - { - output += ".xml"; - } - else - { - output += ".pdf"; - } - return output; - } - /** - * Returns the data in the SignResult with proper content disposition. - * - * @param si - * SessionInformation. - * @param response - * The servlet response. - * @throws IOException - * The IO Exception. - */ - public static void returnSignResponse(SessionInformation si, - HttpServletResponse response) throws IOException - { - SignResult sign_result = si.sign_result; - - String file_name = formatFileNameForSignResult(si.filename, sign_result); - - // tzefferer: added condition - if (si.exappinf == null) { - - // The name parameter is actually deprecated in favour of - // Content-Disposition filename - // Unfortunately Acrobat reader does recognize neither of these parameters - // with its inline save-as. It always takes the page name. - response.setContentType(sign_result.getMimeType() + "; name=\"" + file_name + "\""); - if (si.download_inline) - { - response.addHeader("Content-Disposition", "inline; filename=\"" + file_name + "\""); - } - else - { - response.addHeader("Content-Disposition", "attachment; filename=\"" + file_name + "\""); - } - response.getOutputStream().write(sign_result.getData()); - // tzefferer: added else-block - } else { - SignResult sr = si.sign_result; - byte[] signed_pdf = sr.getData(); - PDFContainer entry = new PDFContainer(signed_pdf, si.exappinf.pdf_id); - ProvidePDFServlet.signedDocuments.add(entry); - - // notify webapp... - String invoke_url = si.exappinf.invoke_url; - - String providePDFServlet = "ProvidePDF"; - String pdf_id = String.valueOf(si.exappinf.pdf_id); - String session_id = si.exappinf.session_id; - - // build URL - int ind = invoke_url.indexOf("?"); - String query = invoke_url.substring(0, ind) + ";jsessionid=" + session_id + invoke_url.substring(ind) + "&" + FormFields.FIELD_PDF_URL + "=" + providePDFServlet + "&" + FormFields.FIELD_PDF_ID + "=" + pdf_id + "&" + FormFields.FIELD_FILE_LENGTH + "=" + signed_pdf.length; - response.sendRedirect(query); - - } - } - - // tzefferer: added - public static byte[] toByteArray(InputStream inputStream) throws IOException { - - if(inputStream == null) { + public static byte[] toByteArray(InputStream inputStream) throws IOException + { + + if (inputStream == null) + { return null; } - + ByteArrayOutputStream out = new ByteArrayOutputStream(8192); int n; byte[] buffer = new byte[2048]; BufferedInputStream bufIn = new BufferedInputStream(inputStream); - try { - while ((n = bufIn.read(buffer)) != -1) { + try + { + while ((n = bufIn.read(buffer)) != -1) + { out.write(buffer, 0, n); } - } finally { - if(bufIn != null) { + } + finally + { + if (bufIn != null) + { bufIn.close(); } } return out.toByteArray(); } + // end add protected static class UploadedData @@ -698,6 +552,7 @@ public class SignServlet extends HttpServlet protected String file_name = null; - protected byte[] pdf = null; + protected FileBasedPdfDataSourceImpl pdfDataSource = null; + // protected byte[] pdf = null; } } \ No newline at end of file diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyPreviewServlet.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyPreviewServlet.java index 150b592..732e6cc 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyPreviewServlet.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyPreviewServlet.java @@ -20,6 +20,7 @@ package at.knowcenter.wag.egov.egiz.web.servlets; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; +import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; @@ -30,19 +31,22 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; -import org.apache.log4j.Logger; - +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.framework.input.TextDataSource; +import at.gv.egiz.pdfas.utils.StreamUtils; +import at.gv.egiz.pdfas.web.VerifySessionInformation; +import at.gv.egiz.pdfas.web.helper.SessionHelper; +import at.gv.egiz.pdfas.web.helper.TempDirHelper; import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.PdfASID; -import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; -import at.knowcenter.wag.egov.egiz.exceptions.ErrorCodeException; import at.knowcenter.wag.egov.egiz.exceptions.InvalidIDException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; @@ -55,8 +59,6 @@ import at.knowcenter.wag.egov.egiz.sig.SignatureObject; import at.knowcenter.wag.egov.egiz.sig.SignatureTypes; import at.knowcenter.wag.egov.egiz.web.FormFields; import at.knowcenter.wag.egov.egiz.web.LocalRequestHelper; -import at.knowcenter.wag.egov.egiz.web.SessionAttributes; -import at.knowcenter.wag.egov.egiz.web.SessionInformation; /** * @author wprinz @@ -71,7 +73,7 @@ public class VerifyPreviewServlet extends HttpServlet /** * The logger. */ - private static final Logger logger_ = ConfigLogger.getLogger(VerifyPreviewServlet.class); + private static final Log logger_ = LogFactory.getLog(VerifyPreviewServlet.class); protected void dispatch(HttpServletRequest request, HttpServletResponse response, String resource) throws ServletException, IOException @@ -82,7 +84,29 @@ public class VerifyPreviewServlet extends HttpServlet RequestDispatcher disp = getServletContext().getRequestDispatcher(resource); disp.forward(request, response); } + + protected void dispatchToPreview(HttpServletRequest request, HttpServletResponse response, int verify_which)throws ServletException, IOException + { + request.setAttribute(FormFields.FIELD_VERIFY_WHICH, new Integer(verify_which)); + request.setAttribute("btlurl", formBackToListURL(request, response)); + dispatch(request, response, "/jsp/verifypreview.jsp"); + + } + protected void dispatchToDataOk(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException + { + request.setAttribute("btlurl", formBackToListURL(request, response)); + dispatch(request, response, "/jsp/dataok.jsp"); + } + + protected String formBackToListURL(HttpServletRequest request, HttpServletResponse response) throws MalformedURLException + { + URL btlURL = new URL(request.getScheme(), request.getServerName(), request.getServerPort(), request.getContextPath() + "/jsp/verifylist.jsp"); + String backToListURL = response.encodeURL(btlURL.toString()); + + return backToListURL; + } + protected static String generateNamePrefix(int num) { return SIG_INPUT_PREFIX + num + "_"; @@ -249,6 +273,10 @@ public class VerifyPreviewServlet extends HttpServlet { continue; } + if (SignatureTypes.SIG_KZ.equals(key) && value == null) + { + continue; + } value = value.replaceAll("\\s", " "); value = value.replaceAll("\\\"", "\\\""); @@ -281,6 +309,10 @@ public class VerifyPreviewServlet extends HttpServlet { continue; } + if (SignatureTypes.SIG_KZ.equals(key) && value == null) + { + continue; + } writer.println(" "); writer.println(" " + caption + ":"); @@ -355,10 +387,11 @@ public class VerifyPreviewServlet extends HttpServlet } protected void dispatchToResults(List results, HttpServletRequest request, - HttpServletResponse response, boolean backbutton) throws ServletException, IOException + HttpServletResponse response, boolean backbutton, String backToListURL) throws ServletException, IOException { request.setAttribute("results", results); request.setAttribute("backbutton", backbutton ? "true" : "false"); + request.setAttribute("btlurl", backToListURL); dispatch(request, response, "/jsp/results.jsp"); } @@ -459,37 +492,12 @@ public class VerifyPreviewServlet extends HttpServlet protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - SessionInformation si = null; - HttpSession session = null; - try - { - session = request.getSession(false); - // String session_id_string = request.getParameter("session"); - if (session == null) - { - throw new ErrorCodeException(600, "The session is missing."); - } - - si = (SessionInformation) session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); - // long session_id = Long.parseLong(session_id_string); - // si = SessionTable.get(session_id); - if (si == null) - { - throw new ErrorCodeException(600, "The session is not found or is no longer valid."); - } - - } - catch (PresentableException e) - { - e.printStackTrace(); - SignServlet.prepareDispatchToErrorPage(e, request); - dispatch(request, response, "/jsp/error.jsp"); - - return; - } - try { + Object sessionObject = SessionHelper.getSession(request); + + VerifySessionInformation si = (VerifySessionInformation)sessionObject; + int verify_which = -1; boolean preview = false; @@ -526,7 +534,7 @@ public class VerifyPreviewServlet extends HttpServlet } SignatureHolder holder = (SignatureHolder) si.signature_holders.get(verify_which); - si.current_operation = verify_which; +// si.current_operation = verify_which; holders_to_verify = new ArrayList(); holders_to_verify.add(holder); @@ -536,15 +544,17 @@ public class VerifyPreviewServlet extends HttpServlet { BinarySignatureHolder binary_holder = (BinarySignatureHolder) holder; response.setContentType("application/pdf"); - response.getOutputStream().write(binary_holder.getSignedPdf(), 0, binary_holder.getSignedPdfLength()); + StreamUtils.writeInputStreamToOutputStream(binary_holder.getSignedPdf().createInputStream(), response.getOutputStream()); +// response.getOutputStream().write(binary_holder.getSignedPdf(), 0, binary_holder.getSignedPdfLength()); } else // if (holder.getSignatureObject().isTextual()) { // formatPreview(holders_to_verify, si.connector, request, // response); - request.setAttribute(FormFields.FIELD_VERIFY_WHICH, new Integer(verify_which)); - dispatch(request, response, "/jsp/verifypreview.jsp"); +// request.setAttribute(FormFields.FIELD_VERIFY_WHICH, new Integer(verify_which)); + + dispatchToPreview(request, response, verify_which); } return; @@ -554,10 +564,12 @@ public class VerifyPreviewServlet extends HttpServlet if (ConnectorFactory.isConnectorLocal(si.connector)) { - List temp_holder = new ArrayList(si.signature_holders); - - si.copy_of_signature_holders = temp_holder; - si.signature_holders = holders_to_verify; + // what is this for? si.signature_holders must not be modified after extraction + // TODO this seems to be buggy bug fixing - remove +// List temp_holder = new ArrayList(si.signature_holders); +// +// si.copy_of_signature_holders = temp_holder; +// si.signature_holders = holders_to_verify; String dispatch_to = LocalRequestHelper.processLocalVerify(si, holders_to_verify, request, response); dispatch(request, response, dispatch_to); @@ -575,7 +587,9 @@ public class VerifyPreviewServlet extends HttpServlet { backbutton = false; } - dispatchToResults(results, request, response, backbutton); + URL btlURL = new URL(request.getScheme(), request.getServerName(), request.getServerPort(), request.getContextPath() + "/jsp/verifylist.jsp"); + String backToListURL = response.encodeURL(btlURL.toString()); + dispatchToResults(results, request, response, backbutton, backToListURL); } catch (PresentableException e) @@ -588,41 +602,17 @@ public class VerifyPreviewServlet extends HttpServlet protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - SessionInformation si = null; - HttpSession session = null; - try - { - session = request.getSession(false); - // String session_id_string = request.getParameter("session"); - if (session == null) - { - throw new ErrorCodeException(600, "The session is missing."); - } - - si = (SessionInformation) session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); - // long session_id = Long.parseLong(session_id_string); - // si = SessionTable.get(session_id); - if (si == null) - { - throw new ErrorCodeException(600, "The session is not found or is no longer valid."); - } - - } - catch (PresentableException e) - { - e.printStackTrace(); - SignServlet.prepareDispatchToErrorPage(e, request); - dispatch(request, response, "/jsp/error.jsp"); - - return; - } - DiskFileItemFactory fif = new DiskFileItemFactory(); fif.setRepository(SettingsReader.getTemporaryDirectory()); ServletFileUpload sfu = new ServletFileUpload(fif); try { + Object sessionObject = SessionHelper.getSession(request); + + VerifySessionInformation si = (VerifySessionInformation)sessionObject; + + String text_to_be_verified = null; SignatureObject signature_object = new SignatureObject(); @@ -671,13 +661,17 @@ public class VerifyPreviewServlet extends HttpServlet logger_.debug("sig_obj_number" + key + " = " + value); } - SignatureHolder new_holder = new TextualSignatureHolder(text_to_be_verified, signature_object); + SignatureHolder old_holder = (SignatureHolder) si.signature_holders.get(verify_which); + TempDirHelper.deleteDataSourceIfFileBased(old_holder.getDataSource()); + + TextDataSource tds = TempDirHelper.placeTextIntoTempDir(text_to_be_verified, "_previewholder.utf8.txt"); + SignatureHolder new_holder = new TextualSignatureHolder(tds, signature_object); si.signature_holders.set(verify_which, new_holder); if (verify == false) { - dispatch(request, response, "/dataok.html"); + dispatchToDataOk(request, response); return; } @@ -707,7 +701,10 @@ public class VerifyPreviewServlet extends HttpServlet String loc_ref_url = response.encodeURL(loc_ref_URL.toString()); List results = PdfAS.verifySignatureHoldersWeb(holders_to_verify, si, loc_ref_url); - dispatchToResults(results, request, response, true); + + URL btlURL = new URL(request.getScheme(), request.getServerName(), request.getServerPort(), request.getContextPath() + "/jsp/verifylist.jsp"); + String backToListURL = response.encodeURL(btlURL.toString()); + dispatchToResults(results, request, response, true, backToListURL); } catch (FileUploadException e) { diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyServlet.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyServlet.java index b53a9a1..bb6a13f 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyServlet.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyServlet.java @@ -36,16 +36,22 @@ import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import at.gv.egiz.pdfas.framework.config.SettingsHelper; +import at.gv.egiz.pdfas.framework.input.DataSource; +import at.gv.egiz.pdfas.framework.input.ExtractionStage; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.input.TextDataSource; +import at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters; +import at.gv.egiz.pdfas.web.VerifySessionInformation; +import at.gv.egiz.pdfas.web.helper.TempDirHelper; import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; -import at.knowcenter.wag.egov.egiz.framework.VerificationFilter; import at.knowcenter.wag.egov.egiz.sig.ConnectorFactory; import at.knowcenter.wag.egov.egiz.web.FormFields; import at.knowcenter.wag.egov.egiz.web.LocalRequestHelper; import at.knowcenter.wag.egov.egiz.web.SessionAttributes; -import at.knowcenter.wag.egov.egiz.web.SessionInformation; /** * This method is the verify servlet for the pdf-as web application. It takes @@ -68,8 +74,7 @@ public class VerifyServlet extends HttpServlet */ private static Log log = LogFactory.getLog(SignServlet.class); - protected void dispatch(HttpServletRequest request, - HttpServletResponse response, String resource) throws ServletException, IOException + protected void dispatch(HttpServletRequest request, HttpServletResponse response, String resource) throws ServletException, IOException { response.setContentType("text/html"); //$NON-NLS-1$ response.setCharacterEncoding("UTF-8"); //$NON-NLS-1$ @@ -78,8 +83,7 @@ public class VerifyServlet extends HttpServlet disp.forward(request, response); } - protected void dispatchToResults(List results, HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException + protected void dispatchToResults(List results, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("results", results); //$NON-NLS-1$ dispatch(request, response, "/jsp/results.jsp"); //$NON-NLS-1$ @@ -97,16 +101,20 @@ public class VerifyServlet extends HttpServlet { UploadedData ud = retrieveUploadedDataFromRequest(request); - List signature_holders = extractSignatureHoldersFromFile(ud.file_name, ud.file_data); - - SessionInformation si = new SessionInformation(); // SessionTable.generateSessionInformationObject(); + VerifySessionInformation si = new VerifySessionInformation(); si.connector = ud.sig_app; si.application = "verify"; si.mode = null; - si.pdf = null; + si.inputDataSource = ud.dataSource; si.type = null; - si.user_name = null; - si.user_password = null; +// si.user_name = null; +// si.user_password = null; + + // List signature_holders = extractSignatureHoldersFromFile(ud.file_name, + // ud.file_data); + List signature_holders = extractSignatureHolders(ud.dataSource); + + TempDirHelper.storeTextSignatureHoldersIfApplicable(signature_holders, "_textholder.utf8.txt"); si.signature_holders = signature_holders; @@ -123,7 +131,7 @@ public class VerifyServlet extends HttpServlet if (ConnectorFactory.isConnectorLocal(si.connector)) { String dispatch_to = LocalRequestHelper.processLocalVerify(si, si.signature_holders, request, response); - + dispatch(request, response, dispatch_to); return; } @@ -151,9 +159,8 @@ public class VerifyServlet extends HttpServlet } } - - protected UploadedData retrieveUploadedDataFromRequest( - HttpServletRequest request) throws ServletException, UnsupportedEncodingException, FileUploadException, PDFDocumentException + + protected UploadedData retrieveUploadedDataFromRequest(HttpServletRequest request) throws ServletException, UnsupportedEncodingException, FileUploadException, PDFDocumentException { DiskFileItemFactory fif = new DiskFileItemFactory(); fif.setRepository(SettingsReader.getTemporaryDirectory()); @@ -165,6 +172,9 @@ public class VerifyServlet extends HttpServlet FileItem connector_fi = null; // FileItem mode_fi = null; FileItem preview_fi = null; + + String characterEncoding = request.getCharacterEncoding(); + log.debug("request character encoding = " + characterEncoding); { Iterator it = items.iterator(); @@ -229,7 +239,7 @@ public class VerifyServlet extends HttpServlet String preview_str = preview_fi.getString("UTF-8"); //$NON-NLS-1$ if (!preview_str.equals(FormFields.VALUE_TRUE) && !preview_str.equals(FormFields.VALUE_FALSE)) { - throw new ServletException("The preview '" + preview_str + "' is unrecognized."); //$NON-NLS-1$//$NON-NLS-2$ + throw new ServletException("The preview '" + preview_str + "' is unrecognized."); //$NON-NLS-1$//$NON-NLS-2$ } boolean preview = false; if (preview_str.equals(FormFields.VALUE_TRUE)) @@ -238,40 +248,59 @@ public class VerifyServlet extends HttpServlet } // process the request - log.debug("file content type =" + upload_fi.getContentType()); //$NON-NLS-1$ - log.debug("file size = " + upload_fi.getSize()); //$NON-NLS-1$ - if (upload_fi.getSize() <= 0) - { - throw new PDFDocumentException(250, "The document is empty."); //$NON-NLS-1$ - } - byte[] document_bytes = upload_fi.get(); + DataSource dataSource = convertUploadToDataSource(upload_fi); UploadedData ud = new UploadedData(); ud.preview = preview; ud.sig_app = connector; ud.file_name = upload_fi.getName(); - ud.file_data = document_bytes; + ud.dataSource = dataSource; + // ud.file_data = document_bytes; return ud; } - - protected List extractSignatureHoldersFromFile (String file_name, byte [] data) throws UnsupportedEncodingException, PresentableException + + protected DataSource convertUploadToDataSource(FileItem upload_fi) throws PDFDocumentException { - VerificationFilter vf = new VerificationFilter(); - List signature_holders = null; + log.debug("file content type =" + upload_fi.getContentType()); //$NON-NLS-1$ + log.debug("file size = " + upload_fi.getSize()); //$NON-NLS-1$ + if (upload_fi.getSize() <= 0) + { + throw new PDFDocumentException(250, "The document is empty."); //$NON-NLS-1$ + } - String extension = extractExtension(file_name); + if (upload_fi.getContentType() != null && upload_fi.getContentType().equals("application/pdf")) + { + try + { + PdfDataSource pdfDataSource = TempDirHelper.placePdfIntoTempDir(upload_fi.getInputStream(), upload_fi.getName()); + return pdfDataSource; + } + catch (IOException e) + { + throw new PDFDocumentException(201, "The document could not be placed in the temp dir.", e); //$NON-NLS-1$ + } + // byte[] document_bytes = upload_fi.get(); + } - String raw_text = null; - if (file_name == null || (extension != null && extension.equals("txt"))) //$NON-NLS-1$ + try { - raw_text = new String(data, "UTF-8"); //$NON-NLS-1$ - signature_holders = vf.extractSignaturesFromPlainText(raw_text); + String text = new String(upload_fi.get(), "UTF-8"); //$NON-NLS-1$ + TextDataSource textDataSource = TempDirHelper.placeTextIntoTempDir(text, upload_fi.getName()); + return textDataSource; } - else + catch (IOException e) { - signature_holders = vf.extractSignaturesFromPdf(data); + throw new PDFDocumentException(201, e); } + } + + protected List extractSignatureHolders(DataSource dataSource) throws PresentableException + { + VerificationFilterParameters parameters = SettingsHelper.readVerificationFilterParametersFromSettings(); + + ExtractionStage es = new ExtractionStage(); + List signature_holders = es.extractSignatureHolders(dataSource, parameters); if (signature_holders.size() == 0) { @@ -281,6 +310,45 @@ public class VerifyServlet extends HttpServlet return signature_holders; } + // TODO obsolete method - remove + // protected List extractSignatureHoldersFromFile(String file_name, byte[] + // data) throws UnsupportedEncodingException, PresentableException + // { + // VerificationFilterParameters parameters = new + // VerificationFilterParametersImpl(false, false, true); + // ExtractionStage es = new ExtractionStage(); + // // VerificationFilter vf = new VerificationFilter(); + // List signature_holders = null; + // + // String extension = extractExtension(file_name); + // + // String raw_text = null; + // if (file_name == null || (extension != null && extension.equals("txt"))) + // //$NON-NLS-1$ + // { + // raw_text = new String(data, "UTF-8"); //$NON-NLS-1$ + // + // signature_holders = es.extractSignatureHolders(new + // TextDataSourceImpl(raw_text), parameters); + // // signature_holders = vf.extractSignaturesFromPlainText(raw_text); + // } + // else + // { + // signature_holders = es.extractSignatureHolders(new + // ByteArrayPdfDataSourceImpl(data), parameters); + // + // // signature_holders = vf.extractSignaturesFromPdf(data); + // } + // + // if (signature_holders.size() == 0) + // { + // throw new PDFDocumentException(206, "PDF document not signed."); + // //$NON-NLS-1$ + // } + // + // return signature_holders; + // } + /** * Extracts the extension from a file name string. * @@ -317,6 +385,7 @@ public class VerifyServlet extends HttpServlet protected String file_name = null; - protected byte[] file_data = null; + protected DataSource dataSource = null; + // protected byte[] file_data = null; } } \ No newline at end of file diff --git a/src/main/java/at/knowcenter/wag/exactparser/parsing/PDFUtils.java b/src/main/java/at/knowcenter/wag/exactparser/parsing/PDFUtils.java index 9a2f738..1387fb2 100644 --- a/src/main/java/at/knowcenter/wag/exactparser/parsing/PDFUtils.java +++ b/src/main/java/at/knowcenter/wag/exactparser/parsing/PDFUtils.java @@ -710,7 +710,7 @@ public abstract class PDFUtils // // // unrecognized type // // skip to next delimiter - // // TODO: this will not work with nested dicts. + // // TODO: this will not work with nested dicts. - already deprecated // while (pdf[cur_index] != PDFNames.DELIMITER_NAME) { // cur_index++; // } -- cgit v1.2.3