diff options
| author | netconomy <netconomy@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c> | 2007-11-29 12:00:22 +0000 | 
|---|---|---|
| committer | netconomy <netconomy@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c> | 2007-11-29 12:00:22 +0000 | 
| commit | 61a2d23ef72630934c603fe9ffb96ebebff6ee09 (patch) | |
| tree | ce05c4470d3a7a2743b4956f512288d6d0d62187 /src/main | |
| parent | 00809217ec7c890a844f9a7c667c71b550ad92a6 (diff) | |
| download | pdf-as-3-61a2d23ef72630934c603fe9ffb96ebebff6ee09.tar.gz pdf-as-3-61a2d23ef72630934c603fe9ffb96ebebff6ee09.tar.bz2 pdf-as-3-61a2d23ef72630934c603fe9ffb96ebebff6ee09.zip | |
PDF-AS API
git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@233 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c
Diffstat (limited to 'src/main')
78 files changed, 5380 insertions, 114 deletions
| diff --git a/src/main/java/at/gv/egiz/pdfas/PdfAsFactory.java b/src/main/java/at/gv/egiz/pdfas/PdfAsFactory.java new file mode 100644 index 0000000..bc6f89d --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/PdfAsFactory.java @@ -0,0 +1,39 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas;
 +
 +import java.io.File;
 +
 +import at.gv.egiz.pdfas.api.PdfAs;
 +import at.gv.egiz.pdfas.api.exceptions.PdfAsException;
 +import at.gv.egiz.pdfas.impl.api.PdfAsObject;
 +
 +/**
 + * Main factory for creating a PDF-AS API Instance (PdfAs Interface).
 + * 
 + * @see PdfAs
 + * 
 + * @author wprinz
 + */
 +public class PdfAsFactory
 +{
 +  /**
 +   * Creates a PDF-AS API instance for the given work directory.
 +   * 
 +   * @param workDirectory
 +   *          The work directory.
 +   * 
 +   * @return Returns an instance of the PDF-AS API.
 +   * @throws IllegalArgumentException
 +   *           Thrown, if the workDirectory doesn't exist.
 +   * @throws PdfAsException
 +   *           Thrown, if the work directory does not meet its requirements, or
 +   *           if the config file is invalid.
 +   */
 +  public static PdfAs createPdfAs(File workDirectory) throws PdfAsException
 +  {
 +    return new PdfAsObject(workDirectory);
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/PdfAs.java b/src/main/java/at/gv/egiz/pdfas/api/PdfAs.java new file mode 100644 index 0000000..4a8a0e0 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/PdfAs.java @@ -0,0 +1,123 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api;
 +
 +import java.util.List;
 +
 +import at.gv.egiz.pdfas.api.analyze.AnalyzeParameters;
 +import at.gv.egiz.pdfas.api.analyze.AnalyzeResult;
 +import at.gv.egiz.pdfas.api.commons.SignatureProfile;
 +import at.gv.egiz.pdfas.api.exceptions.PdfAsException;
 +import at.gv.egiz.pdfas.api.sign.SignParameters;
 +import at.gv.egiz.pdfas.api.sign.SignResult;
 +import at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters;
 +import at.gv.egiz.pdfas.api.verify.VerifyParameters;
 +import at.gv.egiz.pdfas.api.verify.VerifyResult;
 +import at.gv.egiz.pdfas.api.verify.VerifyResults;
 +
 +/**
 + * The PDF-AS API main interface.
 + * 
 + * <p>
 + * Create an Object implementing this interface using the proper factory.
 + * </p>
 + * 
 + * @author wprinz
 + */
 +public interface PdfAs
 +{
 +
 +  /**
 +   * Signs a PDF document using PDF-AS.
 +   * 
 +   * @param signParameters
 +   *          The sign parameters.
 +   * @return Returns the signed document plus additional information.
 +   * @throws PdfAsException
 +   *           Thrown, if an error occurs.
 +   * 
 +   * @see SignParameters
 +   * @see SignResult
 +   */
 +  public SignResult sign(SignParameters signParameters) throws PdfAsException;
 +
 +  /**
 +   * Verifies a document with (potentially multiple) PDF-AS signatures.
 +   * 
 +   * @param verifyParameters
 +   *          The verify parameters.
 +   * @return Returns the verification results.
 +   * @throws PdfAsException
 +   *           Thrown, if an error occurs.
 +   * 
 +   * @see VerifyParameters
 +   * @see VerifyResults
 +   * @see VerifyResult
 +   */
 +  public VerifyResults verify(VerifyParameters verifyParameters) throws PdfAsException;
 +
 +  /**
 +   * Analyzes a document for signatures and returns a verify-able list of such.
 +   * 
 +   * @param analyzeParameters
 +   *          The analyzation parameters.
 +   * @return Returns a list of verify-able signatures that were found in the
 +   *         document.
 +   * @throws PdfAsException
 +   *           Thrown on error.
 +   * 
 +   * @see AnalyzeParameters
 +   * @see AnalyzeResult
 +   * @see {@link #verify(AnalyzeResult)}
 +   */
 +  public AnalyzeResult analyze(AnalyzeParameters analyzeParameters) throws PdfAsException;
 +
 +  /**
 +   * Verifies a list of signatures that have been analyzed previously.
 +   * 
 +   * @param verifyAfterAnalysisParameters The parameters.
 +   * 
 +   * @return Returns the verification results.
 +   * @throws PdfAsException
 +   *           Thrown on error.
 +   * 
 +   * @see AnalyzeResult
 +   * @see VerifyAfterAnalysisParameters
 +   * @see VerifyResults
 +   * @see VerifyResult
 +   * @see {@link #analyze(AnalyzeParameters)}
 +   */
 +  public VerifyResults verify(VerifyAfterAnalysisParameters verifyAfterAnalysisParameters) throws PdfAsException;
 +
 +  /**
 +   * Reloads the configuration from the work directory.
 +   * 
 +   * @throws PdfAsException
 +   *           Thrown, if an error occurs.
 +   */
 +  public void reloadConfig() throws PdfAsException;
 +
 +  /**
 +   * Returns the list of information objects about the profiles available in the
 +   * configuration.
 +   * 
 +   * <p>
 +   * Note: Currently the profile information consists of the profile Id and the
 +   * MOA Key Id only.
 +   * </p>
 +   * <p>
 +   * Note: In near future the profile management will be moved out of the config
 +   * file into an API class representation of the profiles which may render this
 +   * (and related) methods obsolete.
 +   * </p>
 +   * 
 +   * @return Returns the list of {@link SignatureProfile} objects with
 +   *         information about the profiles available in the configuration.
 +   * @throws PdfAsException
 +   *           Thrown on error.
 +   * 
 +   * @see SignatureProfile
 +   */
 +  public List getProfileInformation() throws PdfAsException;
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/analyze/AnalyzeParameters.java b/src/main/java/at/gv/egiz/pdfas/api/analyze/AnalyzeParameters.java new file mode 100644 index 0000000..0ab854c --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/analyze/AnalyzeParameters.java @@ -0,0 +1,69 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.analyze;
 +
 +import at.gv.egiz.pdfas.api.commons.Constants;
 +import at.gv.egiz.pdfas.api.io.DataSource;
 +
 +/**
 + * Parameter object that holds the analyze parameters.
 + * 
 + * @author wprinz
 + */
 +public class AnalyzeParameters
 +{
 +
 +  /**
 +   * The document to be analyzed.
 +   */
 +  protected DataSource document = null;
 +
 +  /**
 +   * The mode of operation how the document is analyzed.
 +   * 
 +   * <p>
 +   * May be {@link Constants#VERIFY_MODE_BINARY_ONLY} to check the document for
 +   * binary signatures only (very fast). Or may be
 +   * {@link Constants#VERIFY_MODE_SEMI_CONSERVATIVE} to perform a semi
 +   * conservative (optimized) text and binary verification (slow). Or may be
 +   * {@link Constants#VERIFY_MODE_FULL_CONSERVATIVE} to perform a full
 +   * conservative text and binary verification (very slow).
 +   * </p>
 +   */
 +  protected String verifyMode = Constants.VERIFY_MODE_FULL_CONSERVATIVE;
 +
 +  /**
 +   * @return the document
 +   */
 +  public DataSource getDocument()
 +  {
 +    return this.document;
 +  }
 +
 +  /**
 +   * @param document the document to set
 +   */
 +  public void setDocument(DataSource document)
 +  {
 +    this.document = document;
 +  }
 +
 +  /**
 +   * @return the verifyMode
 +   */
 +  public String getVerifyMode()
 +  {
 +    return this.verifyMode;
 +  }
 +
 +  /**
 +   * @param verifyMode the verifyMode to set
 +   */
 +  public void setVerifyMode(String verifyMode)
 +  {
 +    this.verifyMode = verifyMode;
 +  }
 +
 +  
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/analyze/AnalyzeResult.java b/src/main/java/at/gv/egiz/pdfas/api/analyze/AnalyzeResult.java new file mode 100644 index 0000000..098f309 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/analyze/AnalyzeResult.java @@ -0,0 +1,30 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.analyze;
 +
 +import java.util.List;
 +
 +import at.gv.egiz.pdfas.api.commons.SignatureInformation;
 +import at.gv.egiz.pdfas.api.exceptions.PdfAsException;
 +
 +/**
 + * The result of an analyze operation, which is a list of verifyable signatures.
 + * 
 + * @author wprinz
 + * 
 + */
 +public interface AnalyzeResult
 +{
 +  /**
 +   * Returns the list of found signatures.
 +   * 
 +   * @return Returns a list of {@link SignatureInformation} objects representing all
 +   *         found signatures.
 +   * @throws PdfAsException
 +   *           Thrown on error.
 +   * 
 +   * @see SignatureInformation
 +   */
 +  public List getSignatures() throws PdfAsException;
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/commons/Constants.java b/src/main/java/at/gv/egiz/pdfas/api/commons/Constants.java new file mode 100644 index 0000000..e8ebc16 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/commons/Constants.java @@ -0,0 +1,77 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.commons;
 +
 +/**
 + * Contains commonly used constants.
 + * 
 + * @author wprinz
 + */
 +public final class Constants
 +{
 +
 +  /**
 +   * Hidden default constructor.
 +   */
 +  private Constants()
 +  {
 +    // empty
 +  }
 +
 +  /**
 +   * A binary signature.
 +   */
 +  public static String SIGNATURE_TYPE_BINARY = "binary";
 +
 +  /**
 +   * A textual signature.
 +   */
 +  public static String SIGNATURE_TYPE_TEXTUAL = "textual";
 +
 +  /**
 +   * A "detached" textual signature.
 +   * 
 +   * <p>
 +   * The document text is signed, but instead of returning the pdf with the signature block,
 +   * the sign result XML of the connector is returned.
 +   * </p>
 +   */
 +  public static String SIGNATURE_TYPE_DETACHEDTEXTUAL = "detachedtextual";
 +
 +  /**
 +   * The signature device moa.
 +   */
 +  public static String SIGNATURE_DEVICE_MOA = "moa";
 +
 +  /**
 +   * The signature device bku.
 +   */
 +  public static String SIGNATURE_DEVICE_BKU = "bku";
 +
 +  /**
 +   * Only binary signatures are verified.
 +   */
 +  public static String VERIFY_MODE_BINARY_ONLY = "binaryOnly";
 +
 +  /**
 +   * Binary and textual signatures are verified with time optimization.
 +   * 
 +   * <p>
 +   * This mode of operation tries to minimize the numbers of text extractions,
 +   * which are very time intensive, at the cost of some rare cases, in which some
 +   * signatures may not be found.
 +   * </p>
 +   */
 +  public static String VERIFY_MODE_SEMI_CONSERVATIVE = "semiConservative";
 +
 +  /**
 +   * Binary and textual signatures are verified.
 +   */
 +  public static String VERIFY_MODE_FULL_CONSERVATIVE = "fullConservative";
 +
 +  /**
 +   * All signatures are verified.
 +   */
 +  public static int VERIFY_ALL = -1;
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureInformation.java b/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureInformation.java new file mode 100644 index 0000000..d8c2a34 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureInformation.java @@ -0,0 +1,97 @@ +/**
 + * <copyright> Copyright (c) 2006 by Know-Center, Graz, Austria </copyright>
 + * 
 + * 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: SignatureHolder.java,v 1.3 2006/10/11 07:57:58 wprinz Exp $
 + */
 +package at.gv.egiz.pdfas.api.commons;
 +
 +import java.security.cert.X509Certificate;
 +import java.util.Date;
 +
 +import at.gv.egiz.pdfas.api.io.DataSource;
 +
 +/**
 + * Holds the information of one found signature block, which is the signed data
 + * and the corresponding signature information.
 + * 
 + * @author wprinz
 + */
 +public interface SignatureInformation
 +{
 +  /**
 +   * Returns the type of this signature (binary/textual).
 +   * 
 +   * <p>
 +   * May be {@link Constants#SIGNATURE_TYPE_BINARY} or
 +   * {@link Constants#SIGNATURE_TYPE_TEXTUAL}.
 +   * </p>
 +   * 
 +   * @return Returns the type of this signature (binary/textual).
 +   */
 +  public String getSignatureType();
 +
 +  /**
 +   * Returns the DataSource providing the data that was signed.
 +   * 
 +   * <p>
 +   * Note that this is the signed data as sent to the verification device by
 +   * PDF-AS. The verification device (e.g. MOA) may perform several other
 +   * transformations on the data before feeding it to the signature hash
 +   * function. To get the actual hashed data use the ReturnHashInputData mechanism (which is very slow).
 +   * </p>
 +   * 
 +   * @return Returns the DataSource providing the data that was signed.
 +   * 
 +   * @see at.gv.egiz.pdfas.api.verify.VerifyParameters#setReturnHashInputData(boolean)
 +   * @see at.gv.egiz.pdfas.api.verify.VerifyResult#getHashInputData()
 +   * 
 +   */
 +  public DataSource getSignedData();
 +
 +  /**
 +   * Returns the certificate of the signer.
 +   * 
 +   * <p>
 +   * Information like subject name, issuer name or serial number can be
 +   * retrieved form this certificate.
 +   * </p>
 +   * 
 +   * @return Returns the certificate of the signer.
 +   */
 +  public X509Certificate getSignerCertificate();
 +
 +  /**
 +   * Returns the signing time, which is the time when the signature was created.
 +   * 
 +   * @return Returns the signing time, which is the time when the signature was
 +   *         created.
 +   */
 +  public Date getSigningTime();
 +
 +  /**
 +   * Returns additional, internal information about the found signature.
 +   * 
 +   * <p>
 +   * Note that this provides a way for developers to gather core information
 +   * about the signature. What information is returned strongly depends on the
 +   * core implementation.
 +   * </p>
 +   * 
 +   * @return Returns additional, internal information about the signature. Null
 +   *         means that no additional information is available.
 +   */
 +  public Object getInternalSignatureInformation();
 +
 +}
\ No newline at end of file diff --git a/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureProfile.java b/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureProfile.java new file mode 100644 index 0000000..52bd27f --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureProfile.java @@ -0,0 +1,29 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.commons;
 +
 +/**
 + * Definition of a signature profile.
 + * 
 + * @author wprinz
 + */
 +public interface SignatureProfile
 +{
 +  // TODO: the full profile information will be implemented in future
 +
 +  /**
 +   * Returns the profile id.
 +   * 
 +   * @return Returns the profile id.
 +   */
 +  public String getProfileId();
 +
 +  /**
 +   * Returns the MOA KeyIdentifier.
 +   * 
 +   * @return Returns the MOA KeyIdentifier.
 +   */
 +  public String getMOAKeyIdentifier();
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/exceptions/PdfAsException.java b/src/main/java/at/gv/egiz/pdfas/api/exceptions/PdfAsException.java new file mode 100644 index 0000000..2986f81 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/exceptions/PdfAsException.java @@ -0,0 +1,78 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.exceptions;
 +
 +/**
 + * This exception is the base for all PDF-AS exceptions.
 + * 
 + * <p>
 + * Every PDF-AS Exception has an error code.
 + * </p>
 + * 
 + * @author wprinz
 + */
 +public abstract class PdfAsException extends Exception
 +{
 +  /**
 +   * The error code.
 +   */
 +  protected int errorCode = -1;
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param errorCode
 +   *          The error code.
 +   * @param message
 +   *          The detail message.
 +   */
 +  public PdfAsException(int errorCode, String message)
 +  {
 +    super(message);
 +
 +    this.errorCode = errorCode;
 +  }
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param errorCode
 +   *          The error code.
 +   * @param message
 +   *          The detail message.
 +   * @param cause
 +   *          The cause.
 +   */
 +  public PdfAsException(int errorCode, String message, Throwable cause)
 +  {
 +    super(message, cause);
 +
 +    this.errorCode = errorCode;
 +  }
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param errorCode
 +   *          The error code.
 +   * @param cause
 +   *          The cause.
 +   */
 +  public PdfAsException(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/gv/egiz/pdfas/api/io/DataSink.java b/src/main/java/at/gv/egiz/pdfas/api/io/DataSink.java new file mode 100644 index 0000000..0136cf7 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/io/DataSink.java @@ -0,0 +1,75 @@ +package at.gv.egiz.pdfas.api.io;
 +
 +import java.io.IOException;
 +import java.io.OutputStream;
 +
 +/**
 + * Output document data sink.
 + * 
 + * <p>
 + * Actually, the DataSink can be seen as a factory for creating OutputStreams
 + * with mime type and character encoding provided. This allows the API user to
 + * decide how data is to be stored (e.g. in a file, in a byte array, etc.).
 + * </p>
 + * 
 + * @author wprinz
 + */
 +public interface DataSink
 +{
 +  /**
 +   * Creates an OutputStream for binary data.
 +   * 
 +   * <p>
 +   * Note that the stream may be written only once. Creating another stream
 +   * overwrites the existing one.
 +   * </p>
 +   * 
 +   * @param mimeType
 +   *          The mime type of the output data.
 +   * @return Returns the created output stream.
 +   * @throws IOException
 +   *           Thrown if the stream cannot be created.
 +   */
 +  public OutputStream createOutputStream(String mimeType) throws IOException;
 +
 +  /**
 +   * Creates an OutputStream for character data.
 +   * 
 +   * <p>
 +   * This is basically the same as {@link #createOutputStream(String)}, but
 +   * allows to specify the character encoding.
 +   * </p>
 +   * 
 +   * @param mimeType
 +   *          The mime type of the output data.
 +   * @param characterEncoding
 +   *          The character encoding of the data.
 +   * @return Returns the created output stream.
 +   * @throws IOException
 +   *           Thrown if the stream cannot be created.
 +   */
 +  public OutputStream createOutputStream(String mimeType, String characterEncoding) throws IOException;
 +
 +  /**
 +   * Returns the mime type of the data stream.
 +   * 
 +   * <p>
 +   * This is only valid after a stream has been created.
 +   * </p>
 +   * 
 +   * @return Returns the mime type of the data stream.
 +   */
 +  public String getMimeType();
 +
 +  /**
 +   * Returns the character encoding of the data stream.
 +   * 
 +   * <p>
 +   * This is only valid after a stream has been created. Null means that no
 +   * character encoding was specified for the data (e.g. if the data is binary).
 +   * </p>
 +   * 
 +   * @return Returns the character encoding of the data stream.
 +   */
 +  public String getCharacterEncoding();
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/io/DataSource.java b/src/main/java/at/gv/egiz/pdfas/api/io/DataSource.java new file mode 100644 index 0000000..bd8e0db --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/io/DataSource.java @@ -0,0 +1,74 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.io;
 +
 +import java.io.InputStream;
 +
 +/**
 + * Input document data source.
 + * 
 + * <p>
 + * This allows the holder of the data to decide how the data is to be stored (e.g. in a File or in a byte array).
 + * </p>
 + * 
 + * @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();
 +
 +  /**
 +   * Returns the data of this DataSource as a byte array for random read only access.
 +   * 
 +   * <p>
 +   * Calling this method indicates that you need a byte array for random
 +   * <strong>read only</strong> access. The DataSource implementation should of
 +   * course cache this byte array to avoid too much memory usage.
 +   * </p>
 +   * <p>
 +   * Performance analysis has shown that the libraries internally convert the
 +   * streams to byte arrays and that file system access is very slow.
 +   * </p>
 +   * <p>
 +   * Never write to this byte array!
 +   * </p>
 +   * 
 +   * @return Returns the data of this DataSource as a byte array for random read only access.
 +   */
 +  public byte[] getAsByteArray();
 +
 +  /**
 +   * Returns the mime type of the data.
 +   * 
 +   * @return Returns the mime type of the data.
 +   */
 +  public String getMimeType();
 +
 +  /**
 +   * Returns the character encoding of the data.
 +   * 
 +   * <p>
 +   * This makes only sense for character based mime types.
 +   * </p>
 +   * 
 +   * @return Returns the character encoding of the data or null if no encoding
 +   *         is applicable (e.g. if the data is binary).
 +   */
 +  public String getCharacterEncoding();
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/io/FileBased.java b/src/main/java/at/gv/egiz/pdfas/api/io/FileBased.java new file mode 100644 index 0000000..555b630 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/io/FileBased.java @@ -0,0 +1,31 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.io;
 +
 +import java.io.File;
 +
 +/**
 + * Tells that the IO element (DataSink or DataSource) is backed by a file in the local file system.
 + * 
 + * <p>
 + * This is a hint that may be used by PDF-AS to optimize data access.
 + * </p>
 + * 
 + * @author wprinz
 + */
 +public interface FileBased
 +{
 +  
 +  /**
 +   * Returns the File "behind" this io element.
 +   * 
 +   * <p>
 +   * This is usually used to determine the file name itself.
 +   * </p>
 +   * 
 +   * @return Returns the File "behind" this io element.
 +   */
 +  public File getFile ();
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/io/TextBased.java b/src/main/java/at/gv/egiz/pdfas/api/io/TextBased.java new file mode 100644 index 0000000..68b5729 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/io/TextBased.java @@ -0,0 +1,30 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.io;
 +
 +/**
 + * Tells, that the IO Element (DataSink - but mostly DataSource) is based upon
 + * character data.
 + * 
 + * <p>
 + * This can be used to retrieve the character text directly with the correct
 + * encoding etc.
 + * </p>
 + * <p>
 + * This makes most sense for text DataSources.
 + * </p>
 + * 
 + * @author wprinz
 + */
 +public interface TextBased
 +{
 +
 +  /**
 +   * Returns the text.
 +   * 
 +   * @return Returns the text.
 +   */
 +  public String getText();
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/sign/SignParameters.java b/src/main/java/at/gv/egiz/pdfas/api/sign/SignParameters.java new file mode 100644 index 0000000..cc59cbd --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/sign/SignParameters.java @@ -0,0 +1,173 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.sign;
 +
 +import at.gv.egiz.pdfas.api.commons.Constants;
 +import at.gv.egiz.pdfas.api.io.DataSink;
 +import at.gv.egiz.pdfas.api.io.DataSource;
 +import at.gv.egiz.pdfas.api.sign.pos.SignaturePositioning;
 +
 +/**
 + * Parameter object that holds the sign parameters.
 + * 
 + * @author wprinz
 + */
 +public class SignParameters
 +{
 +  /**
 +   * The document to be signed.
 +   * 
 +   * <p>
 +   * The DataSource implementation encapsulates the actual representaion of the
 +   * data. E.g. the DataSource may be File based or byte array based. See
 +   * package at.gv.egiz.pdfas.framework.input and at.gv.pdfas.impl.input
 +   * </p>
 +   */
 +  protected DataSource document = null;
 +
 +  /**
 +   * The type of the signature.
 +   * 
 +   * <p>
 +   * May be {@link Constants#SIGNATURE_TYPE_BINARY} or
 +   * {@link Constants#SIGNATURE_TYPE_TEXTUAL}.
 +   * </p>
 +   */
 +  protected String signatureType = Constants.SIGNATURE_TYPE_BINARY;
 +
 +  /**
 +   * The signature device to perform the actual signature.
 +   * 
 +   * <p>
 +   * May be {@link Constants#SIGNATURE_DEVICE_MOA} or
 +   * {@link Constants#SIGNATURE_DEVICE_BKU}.
 +   * </p>
 +   */
 +  protected String signatureDevice = Constants.SIGNATURE_DEVICE_MOA;
 +
 +  /**
 +   * The signature profile identifier identifying the profile to be used in the
 +   * config file.
 +   * 
 +   * <p>
 +   * Note: In near future it will be possible to provide a full specified
 +   * profile here instead of the profile id.
 +   * </p>
 +   */
 +  protected String signatureProfileId = null;;
 +
 +  /**
 +   * The signature position. Consult the PDF-AS documentation section
 +   * Commandline.
 +   */
 +  protected SignaturePositioning signaturePositioning = null;
 +
 +  /**
 +   * The output DataSink that will receive the signed document.
 +   */
 +  protected DataSink output = null;
 +
 +  /**
 +   * @return the document
 +   */
 +  public DataSource getDocument()
 +  {
 +    return document;
 +  }
 +
 +  /**
 +   * @param document
 +   *          the document to set
 +   */
 +  public void setDocument(DataSource document)
 +  {
 +    this.document = document;
 +  }
 +
 +  /**
 +   * @return the signatureType
 +   */
 +  public String getSignatureType()
 +  {
 +    return signatureType;
 +  }
 +
 +  /**
 +   * @param signatureType
 +   *          the signatureType to set
 +   */
 +  public void setSignatureType(String signatureType)
 +  {
 +    this.signatureType = signatureType;
 +  }
 +
 +  /**
 +   * @return the signatureDevice
 +   */
 +  public String getSignatureDevice()
 +  {
 +    return signatureDevice;
 +  }
 +
 +  /**
 +   * @param signatureDevice
 +   *          the signatureDevice to set
 +   */
 +  public void setSignatureDevice(String signatureDevice)
 +  {
 +    this.signatureDevice = signatureDevice;
 +  }
 +
 +  /**
 +   * @return the signatureProfileId
 +   */
 +  public String getSignatureProfileId()
 +  {
 +    return signatureProfileId;
 +  }
 +
 +  /**
 +   * @param signatureProfileId
 +   *          the signatureProfileId to set
 +   */
 +  public void setSignatureProfileId(String signatureProfileId)
 +  {
 +    this.signatureProfileId = signatureProfileId;
 +  }
 +
 +  /**
 +   * @return the signaturePositioning
 +   */
 +  public SignaturePositioning getSignaturePositioning()
 +  {
 +    return this.signaturePositioning;
 +  }
 +
 +  /**
 +   * @param signaturePositioning
 +   *          the signaturePositioning to set
 +   */
 +  public void setSignaturePositioning(SignaturePositioning signaturePositioning)
 +  {
 +    this.signaturePositioning = signaturePositioning;
 +  }
 +
 +  /**
 +   * @return the output
 +   */
 +  public DataSink getOutput()
 +  {
 +    return output;
 +  }
 +
 +  /**
 +   * @param output
 +   *          the output to set
 +   */
 +  public void setOutput(DataSink output)
 +  {
 +    this.output = output;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/sign/SignResult.java b/src/main/java/at/gv/egiz/pdfas/api/sign/SignResult.java new file mode 100644 index 0000000..519a9e1 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/sign/SignResult.java @@ -0,0 +1,49 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.sign;
 +
 +import java.security.cert.X509Certificate;
 +
 +import at.gv.egiz.pdfas.api.io.DataSink;
 +import at.gv.egiz.pdfas.api.sign.pos.SignaturePosition;
 +
 +/**
 + * The result of a sign operation.
 + * 
 + * @author wprinz
 + */
 +public interface SignResult
 +{
 +
 +  /**
 +   * Returns the filled output data sink.
 +   * 
 +   * @return Returns the filled output data sink.
 +   */
 +  public DataSink getOutputDocument();
 +
 +  /**
 +   * Returns the certificate of the signer.
 +   * 
 +   * @return Returns the certificate of the signer.
 +   */
 +  public X509Certificate getSignerCertificate();
 +
 +  /**
 +   * Returns the position where the signature is finally placed.
 +   * 
 +   * <p>
 +   * This information can be useful for post-processing the document.
 +   * </p>
 +   * 
 +   * <p>
 +   * Consult the PDF-AS documentation section Commandline for further
 +   * information about positioning.
 +   * </p>
 +   * 
 +   * @return Returns the position where the signature is finally placed. May
 +   *         return null if no position information is available.
 +   */
 +  public SignaturePosition getSignaturePosition();
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/sign/pos/SignaturePosition.java b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/SignaturePosition.java new file mode 100644 index 0000000..8dc6b6c --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/SignaturePosition.java @@ -0,0 +1,52 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.sign.pos;
 +
 +/**
 + * Holds the actual, absolute signature position where a signature was placed.
 + * 
 + * <p>
 + * This is usually returned after signing.
 + * </p>
 + * 
 + * @author wprinz
 + */
 +public interface SignaturePosition
 +{
 +  /**
 +   * Returns the page on which the signature was placed.
 +   * 
 +   * @return Returns the page on which the signature was placed.
 +   */
 +  public int getPage();
 +
 +  /**
 +   * Returns the x position.
 +   * 
 +   * @return Returns the x position.
 +   */
 +  public float getX();
 +
 +  /**
 +   * Returns the y position.
 +   * 
 +   * @return Returns the y position.
 +   */
 +  public float getY();
 +
 +  /**
 +   * Returns the width of the signature.
 +   * 
 +   * @return Returns the width of the signature.
 +   */
 +  public float getWidth();
 +
 +  /**
 +   * Returns the height of the signature.
 +   * 
 +   * @return Returns the height of the signature.
 +   */
 +  public float getHeight();
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/sign/pos/SignaturePositioning.java b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/SignaturePositioning.java new file mode 100644 index 0000000..b9e2c8a --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/SignaturePositioning.java @@ -0,0 +1,189 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.sign.pos;
 +
 +import at.gv.egiz.pdfas.api.sign.pos.axis.AbsoluteAxisAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.axis.AutoAxisAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.axis.AxisAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.page.AbsolutePageAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.page.AutoPageAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.page.NewPageAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.page.PageAlgorithm;
 +
 +/**
 + * Defines how the signature positioning is to be performed.
 + * 
 + * <p>
 + * This positioning allows to select the location where the signature block is
 + * placed in the document.
 + * </p>
 + * 
 + * @author wprinz
 + */
 +public class SignaturePositioning
 +{
 +  /**
 +   * The x axis algorithm.
 +   * 
 +   * <p>
 +   * May be {@link AutoAxisAlgorithm} or {@link AbsoluteAxisAlgorithm}
 +   * </p>
 +   */
 +  protected AxisAlgorithm xAlgorithm = new AutoAxisAlgorithm();
 +
 +  /**
 +   * The y axis algorithm.
 +   * 
 +   * <p>
 +   * May be {@link AutoAxisAlgorithm} or {@link AbsoluteAxisAlgorithm}
 +   * </p>
 +   */
 +  protected AxisAlgorithm yAlgorithm = new AutoAxisAlgorithm();
 +
 +  /**
 +   * The width algorithm.
 +   * 
 +   * <p>
 +   * May be {@link AutoAxisAlgorithm} or {@link AbsoluteAxisAlgorithm}
 +   * </p>
 +   */
 +  protected AxisAlgorithm widthAlgorithm = new AutoAxisAlgorithm();
 +
 +  /**
 +   * The page algorithm.
 +   * 
 +   * <p>
 +   * May be {@link AutoPageAlgorithm}, {@link AbsolutePageAlgorithm} or
 +   * {@link NewPageAlgorithm}
 +   * </p>
 +   */
 +  protected PageAlgorithm pageAlgorithm = new AutoPageAlgorithm();
 +
 +  /**
 +   * Provides the position of the footline.
 +   * 
 +   * <p>
 +   * Only used if the pageAlgorithm is {@link AutoPageAlgorithm} and the
 +   * yAlgorithm is {@link AutoAxisAlgorithm}
 +   * </p>
 +   */
 +  protected float footerLine = 0.0f;
 +
 +  protected void checkAxisAlgorithm(AxisAlgorithm algorithm)
 +  {
 +    if (algorithm == null)
 +    {
 +      throw new IllegalArgumentException("The algorithm must not be null.");
 +    }
 +    if (!(algorithm instanceof AutoAxisAlgorithm) && !(algorithm instanceof AbsoluteAxisAlgorithm))
 +    {
 +      throw new IllegalArgumentException("The algorithm must be either Auto or Absolute.");
 +    }
 +  }
 +
 +  protected void checkPageAlgorithm(PageAlgorithm algorithm)
 +  {
 +    if (algorithm == null)
 +    {
 +      throw new IllegalArgumentException("The algorithm must not be null.");
 +    }
 +    if (!(algorithm instanceof AutoPageAlgorithm) && !(algorithm instanceof AbsolutePageAlgorithm) && !(algorithm instanceof NewPageAlgorithm))
 +    {
 +      throw new IllegalArgumentException("The algorithm must be either Auto or Absolute.");
 +    }
 +
 +  }
 +
 +  /**
 +   * @return the xAlgorithm
 +   */
 +  public AxisAlgorithm getXAlgorithm()
 +  {
 +    return this.xAlgorithm;
 +  }
 +
 +  /**
 +   * @param algorithm
 +   *          the xAlgorithm to set
 +   */
 +  public void setXAlgorithm(AxisAlgorithm algorithm)
 +  {
 +    checkAxisAlgorithm(algorithm);
 +    xAlgorithm = algorithm;
 +  }
 +
 +  /**
 +   * @return the yAlgorithm
 +   */
 +  public AxisAlgorithm getYAlgorithm()
 +  {
 +    return this.yAlgorithm;
 +  }
 +
 +  /**
 +   * @param algorithm
 +   *          the yAlgorithm to set
 +   */
 +  public void setYAlgorithm(AxisAlgorithm algorithm)
 +  {
 +    checkAxisAlgorithm(algorithm);
 +
 +    yAlgorithm = algorithm;
 +  }
 +
 +  /**
 +   * @return the widthAlgorithm
 +   */
 +  public AxisAlgorithm getWidthAlgorithm()
 +  {
 +    return this.widthAlgorithm;
 +  }
 +
 +  /**
 +   * @param widthAlgorithm
 +   *          the widthAlgorithm to set
 +   */
 +  public void setWidthAlgorithm(AxisAlgorithm widthAlgorithm)
 +  {
 +    checkAxisAlgorithm(widthAlgorithm);
 +
 +    this.widthAlgorithm = widthAlgorithm;
 +  }
 +
 +  /**
 +   * @return the pageAlgorithm
 +   */
 +  public PageAlgorithm getPageAlgorithm()
 +  {
 +    return this.pageAlgorithm;
 +  }
 +
 +  /**
 +   * @param pageAlgorithm
 +   *          the pageAlgorithm to set
 +   */
 +  public void setPageAlgorithm(PageAlgorithm pageAlgorithm)
 +  {
 +    checkPageAlgorithm(pageAlgorithm);
 +    this.pageAlgorithm = pageAlgorithm;
 +  }
 +
 +  /**
 +   * @return the footerLine
 +   */
 +  public float getFooterLine()
 +  {
 +    return this.footerLine;
 +  }
 +
 +  /**
 +   * @param footerLine
 +   *          the footerLine to set
 +   */
 +  public void setFooterLine(float footerLine)
 +  {
 +    this.footerLine = footerLine;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/sign/pos/axis/AbsoluteAxisAlgorithm.java b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/axis/AbsoluteAxisAlgorithm.java new file mode 100644 index 0000000..234484c --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/axis/AbsoluteAxisAlgorithm.java @@ -0,0 +1,35 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.sign.pos.axis;
 +
 +/**
 + * An absolute positioned element.
 + * @author wprinz
 + */
 +public class AbsoluteAxisAlgorithm extends AxisAlgorithm
 +{
 +
 +  /**
 +   * The absolute positioning value on the axis.
 +   */
 +  protected float absoluteValue = 0.0f;
 +  
 +  /**
 +   * Constructor.
 +   * @param absoluteValue The absolute positioning value on the axis.
 +   */
 +  public AbsoluteAxisAlgorithm (float absoluteValue)
 +  {
 +    this.absoluteValue = absoluteValue;
 +  }
 +
 +  /**
 +   * Returns absolute positioning value on the axis.
 +   * @return the absoluteValue Returns absolute positioning value on the axis.
 +   */
 +  public float getAbsoluteValue()
 +  {
 +    return this.absoluteValue;
 +  }
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/sign/pos/axis/AutoAxisAlgorithm.java b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/axis/AutoAxisAlgorithm.java new file mode 100644 index 0000000..4c5459f --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/axis/AutoAxisAlgorithm.java @@ -0,0 +1,14 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.sign.pos.axis;
 +
 +/**
 + * Auto positioning for this element.
 + * 
 + * @author wprinz
 + */
 +public class AutoAxisAlgorithm extends AxisAlgorithm
 +{
 +// empty
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/sign/pos/axis/AxisAlgorithm.java b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/axis/AxisAlgorithm.java new file mode 100644 index 0000000..a4baac6 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/axis/AxisAlgorithm.java @@ -0,0 +1,14 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.sign.pos.axis;
 +
 +/**
 + * Determines how a certain position is chosen on the axis (x, y, width).
 + * 
 + * @author wprinz
 + */
 +public abstract class AxisAlgorithm
 +{
 +// base class
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/sign/pos/page/AbsolutePageAlgorithm.java b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/page/AbsolutePageAlgorithm.java new file mode 100644 index 0000000..206aa19 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/page/AbsolutePageAlgorithm.java @@ -0,0 +1,37 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.sign.pos.page;
 +
 +/**
 + * The page is selected absolutely by giving the page number directly.
 + * 
 + * @author wprinz
 + */
 +public class AbsolutePageAlgorithm extends PageAlgorithm
 +{
 +  /**
 +   * The page.
 +   */
 +  protected int page = -1;
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param page
 +   *          The page.
 +   */
 +  public AbsolutePageAlgorithm(int page)
 +  {
 +    this.page = page;
 +  }
 +
 +  /**
 +   * @return the page
 +   */
 +  public int getPage()
 +  {
 +    return this.page;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/sign/pos/page/AutoPageAlgorithm.java b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/page/AutoPageAlgorithm.java new file mode 100644 index 0000000..0070d5e --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/page/AutoPageAlgorithm.java @@ -0,0 +1,20 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.sign.pos.page;
 +
 +/**
 + * The page for placing the signature is selected automatically.
 + * 
 + * <p>
 + * The algorithm first tries to place the signature on the free space of the
 + * last page (considering the footer). If there is not enough space on the last
 + * page, a new page is appended and the signature is placed there.
 + * </p>
 + * 
 + * @author wprinz
 + */
 +public class AutoPageAlgorithm extends PageAlgorithm
 +{
 +// empty
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/sign/pos/page/NewPageAlgorithm.java b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/page/NewPageAlgorithm.java new file mode 100644 index 0000000..2a8f67c --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/page/NewPageAlgorithm.java @@ -0,0 +1,14 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.sign.pos.page;
 +
 +/**
 + * Places the signature on a new Page.
 + * 
 + * @author wprinz
 + */
 +public class NewPageAlgorithm extends PageAlgorithm
 +{
 +  // empty block
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/sign/pos/page/PageAlgorithm.java b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/page/PageAlgorithm.java new file mode 100644 index 0000000..9b0fe8a --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/sign/pos/page/PageAlgorithm.java @@ -0,0 +1,14 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.sign.pos.page;
 +
 +/**
 + * Determines how the page on which the signature is to be placed is selected.
 + * 
 + * @author wprinz
 + */
 +public abstract class PageAlgorithm
 +{
 +  // empty
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/verify/SignatureCheck.java b/src/main/java/at/gv/egiz/pdfas/api/verify/SignatureCheck.java new file mode 100644 index 0000000..df29570 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/verify/SignatureCheck.java @@ -0,0 +1,31 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.verify;
 +
 +/**
 + * The result of a signature check performed by a verification device.
 + * 
 + * @see VerifyResult
 + * 
 + * @author wprinz
 + */
 +public interface SignatureCheck
 +{
 +  /**
 +   * Returns the response code of the check.
 +   * 
 +   * @return Returns the response code of the check.
 +   */
 +  public int getCode();
 +
 +  /**
 +   * Returns the textual response message of the check (corresponding to the
 +   * code).
 +   * 
 +   * @return Returns the textual response message of the check (corresponding to
 +   *         the code).
 +   */
 +  public String getMessage();
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/verify/VerifyAfterAnalysisParameters.java b/src/main/java/at/gv/egiz/pdfas/api/verify/VerifyAfterAnalysisParameters.java new file mode 100644 index 0000000..dd50d79 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/verify/VerifyAfterAnalysisParameters.java @@ -0,0 +1,117 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.verify;
 +
 +import java.util.Date;
 +
 +import at.gv.egiz.pdfas.api.analyze.AnalyzeResult;
 +import at.gv.egiz.pdfas.api.commons.Constants;
 +
 +/**
 + * Parameter object that holds the verify after analysis parameters.
 + * 
 + * @author wprinz
 + */
 +public class VerifyAfterAnalysisParameters
 +{
 +
 +  /**
 +   * The list of signatures to be verified.
 +   */
 +  protected AnalyzeResult analyzeResult = null;
 +
 +  /**
 +   * The signature device to perform the actual signature.
 +   * 
 +   * <p>
 +   * May be {@link Constants#SIGNATURE_DEVICE_MOA} or
 +   * {@link Constants#SIGNATURE_DEVICE_BKU}.
 +   * </p>
 +   */
 +  protected String signatureDevice = Constants.SIGNATURE_DEVICE_MOA;
 +
 +  /**
 +   * Allows to pass a VerificationTime to the signature device.
 +   */
 +  protected Date verificationTime = null;
 +
 +  /**
 +   * Tells the signature device (e.g. MOA) to return the signature hash input
 +   * data (which is the probably transformed signed data).
 +   * 
 +   * <p>
 +   * Note that this forces MOA to return the potentially large signature data to
 +   * be returned in the result XML, which may result in very bad performance.
 +   * </p>
 +   */
 +  protected boolean returnHashInputData = false;
 +
 +  /**
 +   * @return the analyzeResult
 +   */
 +  public AnalyzeResult getAnalyzeResult()
 +  {
 +    return this.analyzeResult;
 +  }
 +
 +  /**
 +   * @param analyzeResult
 +   *          the analyzeResult to set
 +   */
 +  public void setAnalyzeResult(AnalyzeResult analyzeResult)
 +  {
 +    this.analyzeResult = analyzeResult;
 +  }
 +
 +  /**
 +   * @return the signatureDevice
 +   */
 +  public String getSignatureDevice()
 +  {
 +    return this.signatureDevice;
 +  }
 +
 +  /**
 +   * @param signatureDevice
 +   *          the signatureDevice to set
 +   */
 +  public void setSignatureDevice(String signatureDevice)
 +  {
 +    this.signatureDevice = signatureDevice;
 +  }
 +
 +  /**
 +   * @return the verificationTime
 +   */
 +  public Date getVerificationTime()
 +  {
 +    return this.verificationTime;
 +  }
 +
 +  /**
 +   * @param verificationTime the verificationTime to set
 +   */
 +  public void setVerificationTime(Date verificationTime)
 +  {
 +    this.verificationTime = verificationTime;
 +  }
 +
 +  /**
 +   * @return the returnHashInputData
 +   */
 +  public boolean isReturnHashInputData()
 +  {
 +    return this.returnHashInputData;
 +  }
 +
 +  /**
 +   * @param returnHashInputData
 +   *          the returnHashInputData to set
 +   */
 +  public void setReturnHashInputData(boolean returnHashInputData)
 +  {
 +    this.returnHashInputData = returnHashInputData;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/verify/VerifyParameters.java b/src/main/java/at/gv/egiz/pdfas/api/verify/VerifyParameters.java new file mode 100644 index 0000000..fb3b8b8 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/verify/VerifyParameters.java @@ -0,0 +1,183 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.verify;
 +
 +import java.util.Date;
 +
 +import at.gv.egiz.pdfas.api.commons.Constants;
 +import at.gv.egiz.pdfas.api.io.DataSource;
 +
 +/**
 + * Parameter object that holds the verify parameters.
 + * 
 + * @author wprinz
 + */
 +public class VerifyParameters
 +{
 +  // This would be a perfect point for multiple inheritance in Java.
 +  // VerifyParameters extends AnalyzeParameters, VerifyAfterAnalysisParameters
 +  // Then a lot of code could be easily reused in the PdfAsObject's check*Parameters methods.
 +
 +  /**
 +   * The document to be verified.
 +   */
 +  protected DataSource document = null;
 +
 +  /**
 +   * The signature device to perform the actual signature.
 +   * 
 +   * <p>
 +   * May be {@link Constants#SIGNATURE_DEVICE_MOA} or
 +   * {@link Constants#SIGNATURE_DEVICE_BKU}.
 +   * </p>
 +   */
 +  protected String signatureDevice = Constants.SIGNATURE_DEVICE_MOA;
 +
 +  /**
 +   * The mode of operation how the document is analyzed.
 +   * 
 +   * <p>
 +   * May be {@link Constants#VERIFY_MODE_BINARY_ONLY} to check the document for
 +   * binary signatures only (very fast). Or may be
 +   * {@link Constants#VERIFY_MODE_SEMI_CONSERVATIVE} to perform a semi
 +   * conservative (optimized) text and binary verification (slow). Or may be
 +   * {@link Constants#VERIFY_MODE_FULL_CONSERVATIVE} to perform a full
 +   * conservative text and binary verification (very slow).
 +   * </p>
 +   */
 +  protected String verifyMode = Constants.VERIFY_MODE_FULL_CONSERVATIVE;
 +
 +  /**
 +   * The (zero based) index of the signature to verify.
 +   * 
 +   * <p>
 +   * This allows to verify only one found signature instead of all. {@link Constants#VERIFY_ALL} means to
 +   * verify all found signatures.
 +   * </p>
 +   */
 +  protected int signatureToVerify = Constants.VERIFY_ALL;
 +
 +  /**
 +   * Allows to pass a VerificationTime to the verification device.
 +   * 
 +   * <p>
 +   * Note that the actual usage of this parameter depends on the verification device.
 +   * </p>
 +   */
 +  protected Date verificationTime = null;
 +
 +  /**
 +   * Tells the signature device (e.g. MOA) to return the signature hash input
 +   * data (which is the probably transformed signed data).
 +   * 
 +   * <p>
 +   * Note that this forces MOA to return the potentially large signature data to
 +   * be returned in the result XML, which may result in very bad performance.
 +   * </p>
 +   */
 +  protected boolean returnHashInputData = false;
 +
 +  /**
 +   * @return the document
 +   */
 +  public DataSource getDocument()
 +  {
 +    return this.document;
 +  }
 +
 +  /**
 +   * @param document
 +   *          the document to set
 +   */
 +  public void setDocument(DataSource document)
 +  {
 +    this.document = document;
 +  }
 +
 +  /**
 +   * @return the signatureDevice
 +   */
 +  public String getSignatureDevice()
 +  {
 +    return this.signatureDevice;
 +  }
 +
 +  /**
 +   * @param signatureDevice
 +   *          the signatureDevice to set
 +   */
 +  public void setSignatureDevice(String signatureDevice)
 +  {
 +    this.signatureDevice = signatureDevice;
 +  }
 +
 +  /**
 +   * @return the verifyMode
 +   */
 +  public String getVerifyMode()
 +  {
 +    return this.verifyMode;
 +  }
 +
 +  /**
 +   * @param verifyMode
 +   *          the verifyMode to set
 +   */
 +  public void setVerifyMode(String verifyMode)
 +  {
 +    this.verifyMode = verifyMode;
 +  }
 +
 +  /**
 +   * @return the signatureToVerify
 +   */
 +  public int getSignatureToVerify()
 +  {
 +    return this.signatureToVerify;
 +  }
 +
 +  /**
 +   * @param signatureToVerify
 +   *          the signatureToVerify to set
 +   */
 +  public void setSignatureToVerify(int signatureToVerify)
 +  {
 +    this.signatureToVerify = signatureToVerify;
 +  }
 +
 +  /**
 +   * @return the verificationTime
 +   */
 +  public Date getVerificationTime()
 +  {
 +    return this.verificationTime;
 +  }
 +
 +  /**
 +   * @param verificationTime
 +   *          the verificationTime to set
 +   */
 +  public void setVerificationTime(Date verificationTime)
 +  {
 +    this.verificationTime = verificationTime;
 +  }
 +
 +  /**
 +   * @return the returnHashInputData
 +   */
 +  public boolean isReturnHashInputData()
 +  {
 +    return this.returnHashInputData;
 +  }
 +
 +  /**
 +   * @param returnHashInputData
 +   *          the returnHashInputData to set
 +   */
 +  public void setReturnHashInputData(boolean returnHashInputData)
 +  {
 +    this.returnHashInputData = returnHashInputData;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/verify/VerifyResult.java b/src/main/java/at/gv/egiz/pdfas/api/verify/VerifyResult.java new file mode 100644 index 0000000..be5a88f --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/verify/VerifyResult.java @@ -0,0 +1,97 @@ +package at.gv.egiz.pdfas.api.verify;
 +
 +import java.util.Date;
 +import java.util.List;
 +
 +import at.gv.egiz.pdfas.api.commons.SignatureInformation;
 +
 +/**
 + * Encapsulates the data of a verification of one signature.
 + * 
 + * @author wprinz
 + */
 +public interface VerifyResult extends SignatureInformation
 +{
 +  /**
 +   * Returns the result of the certificate check.
 +   * 
 +   * @return Returns the result of the certificate check.
 +   */
 +  public SignatureCheck getCertificateCheck();
 +
 +  /**
 +   * Returns the result of the value (and hash) check.
 +   * 
 +   * @return Returns the result of the value (and hash) check.
 +   */
 +  public SignatureCheck getValueCheckCode();
 +
 +  /**
 +   * Returns the result of the manifest check.
 +   * 
 +   * @return Returns the result of the manifest check.
 +   */
 +  public SignatureCheck getManifestCheckCode();
 +
 +  /**
 +   * Returns true, if the signer's certificate is a qualified certificate.
 +   * 
 +   * @return Returns true, if the signer's certificate is a qualified
 +   *         certificate.
 +   */
 +  public boolean isQualifiedCertificate();
 +
 +  /**
 +   * Returns a list of Strings each stating one public property of the
 +   * certificate.
 +   * 
 +   * <p>
 +   * Such public properties are certificate extensions each being assigned an
 +   * own OID. For example the public property "Verwaltungseigenschaft" has the
 +   * OID "1.2.40.0.10.1.1.1".
 +   * </p>
 +   * 
 +   * @return Returns the list of Strings representing the public properties of
 +   *         this certificate, if any.
 +   */
 +  public List getPublicProperties();
 +
 +  /**
 +   * Returns the verification time, which is the time when the signature was
 +   * verified.
 +   * 
 +   * <p>
 +   * Note that this is actually the Date passed to the verify methods over
 +   * {@link VerifyParameters#setVerificationTime(Date)} or
 +   * {@link VerifyAfterAnalysisParameters#setVerificationTime(Date)}. The
 +   * signature devices don't respond the actual verification time so there is no
 +   * guarantee that the set verification time was actually used as time of
 +   * verification. Please consult the device's documentation for more
 +   * information.
 +   * </p>
 +   * 
 +   * @return Returns the verification time, which is the time when the signature
 +   *         was verified.
 +   */
 +  public Date getVerificationTime();
 +
 +  /**
 +   * Returns the hash input data as returned by MOA.
 +   * 
 +   * <p>
 +   * This will only return a value other than null if the corresponding
 +   * VerifyParameter was set to true.
 +   * </p>
 +   * <p>
 +   * Note that the HashInputData does not necessarily have to be exactly the
 +   * same as the signed date return by the
 +   * {@link SignatureInformation#getSignedData()} method.
 +   * </p>
 +   * 
 +   * @return Returns the hash input data as returned by MOA.
 +   * 
 +   * @see SignatureInformation#getSignedData()
 +   */
 +  public String getHashInputData();
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/api/verify/VerifyResults.java b/src/main/java/at/gv/egiz/pdfas/api/verify/VerifyResults.java new file mode 100644 index 0000000..abda1fe --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/api/verify/VerifyResults.java @@ -0,0 +1,27 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.api.verify;
 +
 +import java.util.List;
 +
 +/**
 + * The result of the verification of a document.
 + * 
 + * <p>
 + * Currently, this is not more than a list of VerifyResult objects, one for each
 + * verified signature. There may be additional items in future PDF-AS versions.
 + * </p>
 + * 
 + * @author wprinz
 + */
 +public interface VerifyResults
 +{
 +  /**
 +   * Returns the List of VerifyResult objects, one for each verified signature.
 +   * 
 +   * @return Returns the List of VerifyResult objects, one for each verified
 +   *         signature.
 +   */
 +  public List getResults();
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/commandline/Main.java b/src/main/java/at/gv/egiz/pdfas/commandline/Main.java new file mode 100644 index 0000000..415c1fd --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/commandline/Main.java @@ -0,0 +1,1071 @@ +/**
 + * <copyright> Copyright (c) 2006 by Know-Center, Graz, Austria </copyright>
 + * 
 + * 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: Main.java,v 1.5 2006/10/31 08:06:56 wprinz Exp $
 + */
 +package at.gv.egiz.pdfas.commandline;
 +
 +import java.io.File;
 +import java.io.FileInputStream;
 +import java.io.IOException;
 +import java.io.PrintStream;
 +import java.io.PrintWriter;
 +import java.io.UnsupportedEncodingException;
 +import java.util.Iterator;
 +import java.util.List;
 +
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.log4j.PropertyConfigurator;
 +
 +import at.gv.egiz.pdfas.PdfAsFactory;
 +import at.gv.egiz.pdfas.api.PdfAs;
 +import at.gv.egiz.pdfas.api.commons.Constants;
 +import at.gv.egiz.pdfas.api.exceptions.PdfAsException;
 +import at.gv.egiz.pdfas.api.io.DataSink;
 +import at.gv.egiz.pdfas.api.io.DataSource;
 +import at.gv.egiz.pdfas.api.sign.SignParameters;
 +import at.gv.egiz.pdfas.api.sign.pos.SignaturePositioning;
 +import at.gv.egiz.pdfas.api.sign.pos.axis.AbsoluteAxisAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.page.AbsolutePageAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.page.NewPageAlgorithm;
 +import at.gv.egiz.pdfas.api.verify.VerifyParameters;
 +import at.gv.egiz.pdfas.api.verify.VerifyResult;
 +import at.gv.egiz.pdfas.api.verify.VerifyResults;
 +import at.gv.egiz.pdfas.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.vfilter.VerificationFilterParameters;
 +import at.gv.egiz.pdfas.io.FileBasedDataSink;
 +import at.gv.egiz.pdfas.io.FileBasedDataSource;
 +import at.gv.egiz.pdfas.io.StringTextBasedDataSource;
 +import at.knowcenter.wag.egov.egiz.PdfAS;
 +import at.knowcenter.wag.egov.egiz.PdfASID;
 +import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
 +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorFactoryException;
 +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.SignatureTypesException;
 +import at.knowcenter.wag.egov.egiz.framework.SignatorFactory;
 +import at.knowcenter.wag.egov.egiz.pdf.TablePos;
 +import at.knowcenter.wag.egov.egiz.sig.ConnectorFactory;
 +import at.knowcenter.wag.egov.egiz.sig.ConnectorInformation;
 +import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
 +import at.knowcenter.wag.egov.egiz.web.servlets.VerifyServlet;
 +
 +/**
 + * The main program entry point of the commandline tool.
 + * 
 + * <p>
 + * The commandline uses the PDF-AS API.
 + * </p>
 + * 
 + * @author wprinz
 + */
 +public abstract class Main
 +{
 +  /**
 +   * Command line parameter setting the application mode sign|verify
 +   */
 +  protected static final String PARAMETER_MODE = "-mode";
 +
 +  /**
 +   * Command line parameter setting the application to connect
 +   */
 +  protected static final String PARAMETER_CONNECTOR = "-connector";
 +
 +  /**
 +   * Command line parameter setting the signature mode.
 +   */
 +  protected static final String PARAMETER_SIGNATURE_MODE = "-sigmode";
 +
 +  /**
 +   * Command line parameter setting the signature type.
 +   */
 +  protected static final String PARAMETER_SIGNATURE_TYPE = "-sigtype";
 +
 +  /**
 +   * Command line parameter setting the username
 +   */
 +  protected static final String PARAMETER_USER_NAME = "-username";
 +
 +  /**
 +   * Command line parameter setting the users password
 +   */
 +  protected static final String PARAMETER_USER_PASSWORD = "-password";
 +
 +  /**
 +   * Command line parameter selecting the position of the signature.
 +   */
 +  protected static final String PARAMETER_POS = "-pos";
 +
 +  /**
 +   * Command line parameter selecting the signature which is going to be
 +   * verified.
 +   */
 +  protected static final String PARAMETER_VERIFY_WHICH = "-verify_which";
 +
 +  /**
 +   * The application mode sign
 +   */
 +  public static final String VALUE_MODE_SIGN = "sign";
 +
 +  /**
 +   * The application mode verify
 +   */
 +  public static final String VALUE_MODE_VERIFY = "verify";
 +
 +  /**
 +   * The application mode sign
 +   */
 +  public static final String VALUE_SIGNATURE_MODE_BINARY = "binary";
 +
 +  /**
 +   * The application mode verify
 +   */
 +  public static final String VALUE_SIGNATURE_MODE_TEXTUAL = "textual";
 +
 +  /**
 +   * The application mode verify
 +   */
 +  public static final String VALUE_SIGNATURE_MODE_DETACHED = "detached";
 +
 +  /**
 +   * The application mode verify
 +   */
 +  public static final String VALUE_SIGNATURE_MODE_DETACHED_TEXT = "detachedtextual";
 +
 +  /**
 +   * The log.
 +   */
 +  private static final Log logger_ = LogFactory.getLog(Main.class);
 +
 +  /**
 +   * Main program entry point.
 +   * 
 +   * @param args
 +   *          The commandline arguments.
 +   * @throws IOException
 +   */
 +  public static void main(String[] args) throws IOException
 +  {
 +    // ConfigLogger.setLevel(Level.DEBUG);
 +
 +    SettingsReader.initializeForCommandLine();
 +    PropertyConfigurator.configure(SettingsReader.CONFIG_PATH + "log4j.properties");
 +
 +    // printUsage(System.out);
 +
 +    String mode = null;
 +    String signature_mode = null;
 +    String connector = null;
 +
 +    String signature_type = null;
 +    String user_name = null;
 +    String user_password = null;
 +    String pos_string = null;
 +
 +    int verify_which = -1;
 +
 +    String input = null;
 +    String output = null;
 +
 +    try
 +    {
 +
 +      // for (int i = 0; i < args.length; i++)
 +      // {
 +      // logger_.debug("arg[" + i + "] = " + args[i]);
 +      // }
 +
 +      for (int i = 0; i < args.length; i++)
 +      {
 +        String cur_arg = args[i].trim();
 +
 +        if (cur_arg.equals(PARAMETER_MODE))
 +        {
 +          i++;
 +          if (i >= args.length)
 +          {
 +            printNoValue(PARAMETER_MODE);
 +            return;
 +          }
 +          mode = args[i];
 +          if (!checkMode(mode))
 +          {
 +            printUnrecognizedValue(PARAMETER_MODE, mode);
 +            return;
 +          }
 +          continue;
 +        }
 +
 +        if (cur_arg.equals(PARAMETER_CONNECTOR))
 +        {
 +          i++;
 +          if (i >= args.length)
 +          {
 +            printNoValue(PARAMETER_CONNECTOR);
 +            return;
 +          }
 +          connector = args[i];
 +          if (!checkConnector(connector))
 +          {
 +            printUnrecognizedValue(PARAMETER_CONNECTOR, connector);
 +            return;
 +          }
 +          continue;
 +        }
 +
 +        if (cur_arg.equals(PARAMETER_SIGNATURE_MODE))
 +        {
 +          i++;
 +          if (i >= args.length)
 +          {
 +            printNoValue(PARAMETER_SIGNATURE_MODE);
 +            return;
 +          }
 +          signature_mode = args[i];
 +          if (!checkSignatureMode(signature_mode))
 +          {
 +            printUnrecognizedValue(PARAMETER_SIGNATURE_MODE, signature_mode);
 +            return;
 +          }
 +          continue;
 +        }
 +
 +        if (cur_arg.equals(PARAMETER_SIGNATURE_TYPE))
 +        {
 +          i++;
 +          if (i >= args.length)
 +          {
 +            printNoValue(PARAMETER_SIGNATURE_TYPE);
 +            return;
 +          }
 +          signature_type = args[i];
 +          if (!checkSignatureType(signature_type))
 +          {
 +            printUnrecognizedValue(PARAMETER_SIGNATURE_TYPE, signature_type);
 +            return;
 +          }
 +          continue;
 +        }
 +
 +        if (cur_arg.equals(PARAMETER_USER_NAME))
 +        {
 +          i++;
 +          if (i >= args.length)
 +          {
 +            printNoValue(PARAMETER_USER_NAME);
 +            return;
 +          }
 +          user_name = args[i];
 +          continue;
 +        }
 +
 +        if (cur_arg.equals(PARAMETER_USER_PASSWORD))
 +        {
 +          i++;
 +          if (i >= args.length)
 +          {
 +            printNoValue(PARAMETER_USER_PASSWORD);
 +            return;
 +          }
 +          user_password = args[i];
 +          continue;
 +        }
 +
 +        if (cur_arg.equals(PARAMETER_POS))
 +        {
 +          i++;
 +          if (i >= args.length)
 +          {
 +            printNoValue(PARAMETER_POS);
 +            return;
 +          }
 +          pos_string = args[i];
 +          continue;
 +        }
 +
 +        if (cur_arg.equals(PARAMETER_VERIFY_WHICH))
 +        {
 +          i++;
 +          if (i >= args.length)
 +          {
 +            printNoValue(PARAMETER_VERIFY_WHICH);
 +            return;
 +          }
 +          String str_verify_which = args[i];
 +          try
 +          {
 +            verify_which = Integer.parseInt(str_verify_which);
 +          }
 +          catch (NumberFormatException e)
 +          {
 +            printUnrecognizedValue(PARAMETER_VERIFY_WHICH, str_verify_which);
 +            return;
 +          }
 +
 +          continue;
 +        }
 +
 +        if (cur_arg.charAt(0) == '-')
 +        {
 +          printUnrecognizedOption(cur_arg);
 +          return;
 +        }
 +
 +        if (input == null)
 +        {
 +          input = cur_arg;
 +          continue;
 +        }
 +
 +        if (output == null)
 +        {
 +          output = cur_arg;
 +          continue;
 +        }
 +
 +        printUnrecognizedAdditionalCommandlineArgument(cur_arg);
 +        return;
 +      }
 +
 +      if (mode == null)
 +      {
 +        printMissingParameter("a mode", PARAMETER_MODE);
 +        return;
 +      }
 +      if (connector == null)
 +      {
 +        printMissingParameter("a connector", PARAMETER_CONNECTOR);
 +        return;
 +      }
 +      if (mode.equals(VALUE_MODE_SIGN))
 +      {
 +        if (signature_mode == null)
 +        {
 +          printMissingParameter("a signature mode", PARAMETER_SIGNATURE_MODE);
 +          return;
 +        }
 +        if (signature_type == null)
 +        {
 +          SettingsReader settings = SettingsReader.getInstance();
 +          String default_type = settings.getValueFromKey(SignatureTypes.DEFAULT_TYPE);
 +          signature_type = default_type;
 +        }
 +        if (user_name == null)
 +        {
 +          user_name = "";
 +          // printMissingParameter("a user name", PARAMETER_USER_NAME);
 +          // return;
 +        }
 +        if (user_password == null)
 +        {
 +          user_password = "";
 +          // printMissingParameter("a user password", PARAMETER_USER_PASSWORD);
 +          // return;
 +        }
 +      }
 +
 +      if (input == null)
 +      {
 +        printMissing("an input document");
 +        return;
 +      }
 +
 +      File file = new File(input);
 +      if (!file.exists())
 +      {
 +        System.err.println("The input file '" + input + "' doesn't exist.");
 +        return;
 +      }
 +
 +      if (mode.equals(VALUE_MODE_SIGN) && output == null)
 +      {
 +        output = generateOutputFileNameFromInput(input, signature_mode);
 +      }
 +
 +      carryOutCommand(mode, signature_mode, connector, signature_type, user_name, user_password, verify_which, input, output, pos_string);
 +
 +    }
 +    catch (PdfAsException e)
 +    {
 +      printPresentableException(e);
 +
 +      if (output != null)
 +      {
 +        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
 +    {
 +      SettingsReader.clearTemporaryDirectory();
 +    }
 +  }
 +
 +  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 PdfAsException
 +  {
 +    // 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.flush();
 +  }
 +
 +  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 PdfAsException
 +  {
 +    messageOutput.println("Signing...");
 +
 +    // for performance measurement
 +    long startTime = 0;
 +    long fileSize = 0;
 +    if (logger_.isInfoEnabled())
 +    {
 +      startTime = System.currentTimeMillis();
 +    }
 +
 +    DataSource dataSource = null;
 +    try
 +    {
 +      File file = new File(input);
 +      dataSource = new FileBasedDataSource(file, "application/pdf");
 +      if (logger_.isDebugEnabled())
 +      {
 +        fileSize = file.length();
 +      }
 +    }
 +    catch (IOException e)
 +    {
 +      throw new PDFDocumentException(201, e);
 +    }
 +
 +    DataSink dataSink = null;
 +    try
 +    {
 +      File outputFile = new File(output);
 +
 +      dataSink = new FileBasedDataSink(outputFile);
 +    }
 +    catch (IOException e)
 +    {
 +      throw new PDFDocumentException(ErrorCode.CANNOT_WRITE_PDF, e);
 +    }
 +
 +    processSign(dataSource, connector, signature_mode, signature_type, pos_string, dataSink);
 +
 +    // for performance measurement
 +    if (logger_.isInfoEnabled())
 +    {
 +      long endTime = System.currentTimeMillis();
 +      String toReport = "SIGN;" + signature_mode + ";" + input + ";" + fileSize + ";" + (endTime - startTime);
 +      logger_.info(toReport);
 +    }
 +
 +    messageOutput.println("Signing was successful.");
 +  }
 +
 +  public static void carryOutVerify(String input, String connector, int verify_which, PrintWriter messageOutput) throws PdfAsException
 +  {
 +    messageOutput.println("Verifying...");
 +
 +    // for performance measurement
 +    long startTime = 0;
 +    long fileSize = 0;
 +    if (logger_.isInfoEnabled())
 +    {
 +      startTime = System.currentTimeMillis();
 +    }
 +
 +    DataSource dataSource = null;
 +    try
 +    {
 +      File file = new File(input);
 +      if (logger_.isDebugEnabled())
 +      {
 +        fileSize = file.length();
 +      }
 +      String extension = VerifyServlet.extractExtension(input);
 +      if (extension != null && extension.equals("txt"))
 +      {
 +        try
 +        {
 +          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 StringTextBasedDataSource(text);
 +        }
 +        catch (UnsupportedEncodingException e)
 +        {
 +          throw new RuntimeException("Very strange: UTF-8 character encoding not supported.", e);
 +        }
 +      }
 +      else
 +      {
 +        dataSource = new FileBasedDataSource(file, "application/pdf");
 +      }
 +    }
 +    catch (IOException e)
 +    {
 +      throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e);
 +    }
 +
 +    VerifyResults results = processVerify(dataSource, connector, verify_which);
 +
 +    messageOutput.println("Verification results:");
 +    formatVerifyResults(results, messageOutput);
 +
 +    // for performance measurement
 +    if (logger_.isInfoEnabled())
 +    {
 +      long endTime = System.currentTimeMillis();
 +      String toReport = "VERIFY;" + input + ";" + fileSize + ";" + (endTime - startTime) + ";" + debugVerifyResults(results);
 +      logger_.info(toReport);
 +    }
 +
 +  }
 +
 +  public static void processSign(DataSource dataSource, String connector, String signature_mode, String signature_type, String pos_string, DataSink dataSink) throws PdfAsException
 +  {
 +    // FIXME implement this
 +    // TODO this will change soon due to the document-cleaning change request.
 +    //PdfAS.applyStrictMode(pdfDataSource);
 +
 +    TablePos pos = null;
 +    if (pos_string != null)
 +    {
 +      try
 +      {
 +        pos = PdfAS.parsePositionFromPosString(pos_string);
 +      }
 +      catch (PDFDocumentException e)
 +      {
 +        printUnrecognizedValue(PARAMETER_POS, pos_string);
 +        return;
 +
 +      }
 +    }
 +    SignaturePositioning posi = null;
 +    if (pos != null)
 +    {
 +      posi = new SignaturePositioning();
 +      if (!pos.isXauto())
 +      {
 +        posi.setXAlgorithm(new AbsoluteAxisAlgorithm(pos.getPosX()));
 +      }
 +      if (!pos.isYauto())
 +      {
 +        posi.setYAlgorithm(new AbsoluteAxisAlgorithm(pos.getPosY()));
 +      }
 +      if (!pos.isWauto())
 +      {
 +        posi.setWidthAlgorithm(new AbsoluteAxisAlgorithm(pos.getWidth()));
 +      }
 +      if (pos.isNewPage())
 +      {
 +        posi.setPageAlgorithm(new NewPageAlgorithm());
 +      }
 +      if (!pos.isPauto())
 +      {
 +        posi.setPageAlgorithm(new AbsolutePageAlgorithm(pos.getPage()));
 +      }
 +      posi.setFooterLine(pos.getFooterLine());
 +    }
 +
 +    PdfAs pdfAs = PdfAsFactory.createPdfAs(new File(SettingsReader.RESOURCES_PATH));
 +
 +    SignParameters sp = new SignParameters();
 +    sp.setDocument(dataSource);
 +    sp.setOutput(dataSink);
 +    sp.setSignatureType(signature_mode); // TODO detached signaturen!
 +    sp.setSignatureDevice(connector);
 +    sp.setSignatureProfileId(signature_type);
 +    sp.setSignaturePositioning(posi);
 +    pdfAs.sign(sp);
 +
 +  }
 +
 +  public static VerifyResults processVerify(DataSource dataSource, String connector, int verify_which) throws PdfAsException
 +  {
 +    String verifyMode = Constants.VERIFY_MODE_FULL_CONSERVATIVE;
 +    VerificationFilterParameters parameters = SettingsHelper.readVerificationFilterParametersFromSettings();
 +    if (parameters.extractBinarySignaturesOnly())
 +    {
 +      verifyMode = Constants.VERIFY_MODE_BINARY_ONLY;
 +    }
 +    else
 +    {
 +      if (parameters.assumeOnlySignatureUpdateBlocks())
 +      {
 +        verifyMode = Constants.VERIFY_MODE_SEMI_CONSERVATIVE;
 +      }
 +      else
 +      {
 +        verifyMode = Constants.VERIFY_MODE_FULL_CONSERVATIVE;
 +      }
 +    }
 +
 +    PdfAs pdfAs = PdfAsFactory.createPdfAs(new File(SettingsReader.RESOURCES_PATH));
 +
 +    VerifyParameters vp = new VerifyParameters();
 +    vp.setDocument(dataSource);
 +    vp.setVerifyMode(verifyMode);
 +    vp.setSignatureDevice(connector);
 +    vp.setReturnHashInputData(false);
 +    vp.setVerificationTime(null);
 +    vp.setSignatureToVerify(verify_which);
 +    VerifyResults vrs = pdfAs.verify(vp);
 +
 +    return vrs;
 +  }
 +
 +  protected static String generateOutputFileNameFromInput(String input, String sig_mode)
 +  {
 +    String output = input + "_out";
 +    if (sig_mode.startsWith("detached"))
 +    {
 +      output += ".xml";
 +    }
 +    else
 +    {
 +      output += ".pdf";
 +    }
 +
 +    return output;
 +  }
 +
 +  /**
 +   * Prints that the provided option was unrecognized.
 +   * 
 +   * @param option
 +   *          The unrecognized option.
 +   * @throws PresentableException
 +   *           Forwarded exception.
 +   */
 +  protected static void printUnrecognizedOption(final String option) throws PresentableException
 +  {
 +    System.err.println("Unrecognized option '" + option + "'.");
 +    printUsage(System.out);
 +  }
 +
 +  /**
 +   * Prints that the provided value was unrecognized.
 +   * 
 +   * @param parameter
 +   *          The parameter, which is missing a value.
 +   * @throws PresentableException
 +   *           Forwarded exception.
 +   */
 +  protected static void printNoValue(final String parameter) throws PresentableException
 +  {
 +    System.err.println("The parameter " + parameter + " requires a value as next argument.");
 +    printUsage(System.out);
 +  }
 +
 +  /**
 +   * Prints that the provided value was unrecognized.
 +   * 
 +   * @param value
 +   *          The unrecognized value.
 +   * @throws PresentableException
 +   *           Forwarded exception.
 +   */
 +  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);
 +  }
 +
 +  /**
 +   * Prints that the provided additional commandline argument was unrecognized.
 +   * 
 +   * @param argument
 +   *          The unrecognized argument.
 +   * @throws PresentableException
 +   *           Forwarded exception.
 +   */
 +  protected static void printUnrecognizedAdditionalCommandlineArgument(final String argument) throws PresentableException
 +  {
 +    System.err.println("Unrecognized additional commandline argument '" + argument + "'.");
 +    printUsage(System.out);
 +  }
 +
 +  /**
 +   * Prints that a certain parameter was missing.
 +   * 
 +   * @param missing_term
 +   *          A description of the missing parameter ("e.g. a mode").
 +   * @param parameter
 +   *          The missing parameter itself (e.g. "-mode").
 +   * @throws PresentableException
 +   *           Forwarded exception.
 +   */
 +  protected static void printMissingParameter(final String missing_term, final String parameter) throws PresentableException
 +  {
 +    printMissing(missing_term + " ('" + parameter + "' parameter)");
 +  }
 +
 +  /**
 +   * Prints that something is missing.
 +   * 
 +   * @param missing_term
 +   *          A descriptive message of the missing thing.
 +   * @throws PresentableException
 +   *           Forwarded exception.
 +   */
 +  protected static void printMissing(final String missing_term) throws PresentableException
 +  {
 +    System.err.println("Please specify " + missing_term + ".");
 +    printUsage(System.out);
 +  }
 +
 +  /**
 +   * Prints out the ErrorCodeException in a descriptive form.
 +   * 
 +   * @param ece
 +   *          The ErrorCodeException to be printed.
 +   */
 +  protected static void printPresentableException(final PdfAsException e)
 +  {
 +    if (e.getErrorCode() == ErrorCode.PLACEHOLDER_EXCEPTION)
 +    {
 +      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 " + e.getErrorCode() + ": " + ErrorCodeHelper.getMessageForErrorCode(e.getErrorCode()));
 +
 +    if (e instanceof ExternalErrorException)
 +    {
 +      ExternalErrorException eee = (ExternalErrorException) e;
 +      System.err.println("Externer Fehlergrund: " + eee.getExternalErrorCode() + ": " + eee.getExternalErrorMessage());
 +    }
 +
 +    logger_.error(e);
 +  }
 +
 +  /**
 +   * Prints the usage text.
 +   * 
 +   * @param writer
 +   *          The writer to print the text to.
 +   * @throws PresentableException
 +   *           Forwarded exception.
 +   */
 +  public static void printUsage(PrintStream writer) throws PresentableException
 +  {
 +    writer.println("Usage: pdf-as [OPTIONS] <input file> [output file]");
 +    writer.println("  Required OPTIONS:");
 +
 +    writer.println("    " + PARAMETER_MODE + " <" + VALUE_MODE_SIGN + "|" + VALUE_MODE_VERIFY + ">");
 +    writer.println("      " + VALUE_MODE_SIGN + " ... signs a document");
 +    writer.println("      " + VALUE_MODE_VERIFY + " ... verifies a document");
 +
 +    writer.print("    " + PARAMETER_CONNECTOR + " ");
 +    ConnectorInformation[] ci = ConnectorFactory.getConnectorInformationArray();
 +    for (int i = 0; i < ci.length; i++)
 +    {
 +      String id = ci[i].getIdentifier();
 +      if (!ConnectorFactory.isAvailableForCommandline(id))
 +      {
 +        continue;
 +      }
 +      writer.print(id);
 +      if (i < ci.length - 1)
 +      {
 +        writer.print("|");
 +      }
 +    }
 +    writer.println();
 +    for (int i = 0; i < ci.length; i++)
 +    {
 +      String id = ci[i].getIdentifier();
 +      if (!ConnectorFactory.isAvailableForCommandline(id))
 +      {
 +        continue;
 +      }
 +      writer.println("      " + id + " ... " + ci[i].getDescription());
 +    }
 +
 +    writer.println("  OPTIONS for signation:");
 +
 +    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");
 +    // @iaik: why is this commented out?
 +    //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();
 +    SettingsReader settings = SettingsReader.getInstance();
 +    List types_array = sig_types.getSignatureTypes();
 +    Iterator it = types_array.iterator();
 +    while (it.hasNext())
 +    {
 +      String type = (String) it.next();
 +      writer.print(type);
 +      if (it.hasNext())
 +      {
 +        writer.print("|");
 +      }
 +    }
 +    writer.println(">");
 +    writer.println("      ... [optional] the profile to be used. If omitted, the default");
 +    writer.println("          profile is used.");
 +    String default_type = settings.getValueFromKey(SignatureTypes.DEFAULT_TYPE);
 +    it = types_array.iterator();
 +    while (it.hasNext())
 +    {
 +      String type = (String) it.next();
 +      String descr_key = SignatureTypes.SIG_OBJ + type + "." + SignatureTypes.SIG_DESCR;
 +      String type_descr = settings.getValueFromKey(descr_key);
 +
 +      writer.println("      " + type + " ... " + (type.equals(default_type) ? "(default) " : "") + type_descr);
 +    }
 +
 +    writer.println("    " + PARAMETER_USER_NAME + " <user_name> ... [optional] the user name");
 +    writer.println("    " + PARAMETER_USER_PASSWORD + " <password> ... [optional] the user password");
 +
 +    writer.println("    " + PARAMETER_POS + " <position> ... [optional] the position of the signature block");
 +    writer.println("      position has the format [x:x_algo];[y:y_algo];[w:w_algo][p:p_algo];[f:f_algo]");
 +    writer.println("      if not present default is set to  x:auto;y:auto;w:auto;p:auto;f:0");
 +    writer.println("      x_algo:='auto'     ... automatic positioning x");
 +    writer.println("              floatvalue ... absolute x must be >= 0");
 +    writer.println("      y_algo:='auto'     ... automatic positioning y");
 +    writer.println("              floatvalue ... absolute y must be >= 0");
 +    writer.println("      w_algo:='auto'     ... automatic width");
 +    writer.println("              floatvalue ... absolute width must be > 0");
 +    writer.println("      p_algo:='auto'     ... automatic last page");
 +    writer.println("              'new'      ... new page");
 +    writer.println("              intvalue   ... pagenumber must be > 0 if p>number of pages in document p-->handled like p:'new'");
 +    writer.println("      f_algo  floatvalue ... consider footerline must be >= 0 (only if y_algo is auto and p_algo is not 'new')");
 +
 +    writer.println("  OPTIONS for verification:");
 +    writer.println("    " + PARAMETER_VERIFY_WHICH + " <number> ... [optional] zero based number of the signature");
 +    writer.println("      to be verified. If omitted, all signatures are verified.");
 +
 +    writer.println("  Example usage:");
 +    writer.println("    pdf-as " + PARAMETER_MODE + " " + VALUE_MODE_SIGN + " " + PARAMETER_CONNECTOR + " moa some_document.pdf");
 +    writer.println("    pdf-as " + PARAMETER_MODE + " " + VALUE_MODE_VERIFY + " some_document.pdf_out.pdf");
 +  }
 +
 +  /**
 +   * Checks the value for correctness.
 +   * 
 +   * @param mode
 +   *          The parameter's value.
 +   * @return Returns true, if the value is correct, false otherwise.
 +   */
 +  protected static boolean checkMode(String mode)
 +  {
 +    return mode.equals(VALUE_MODE_SIGN) || mode.equals(VALUE_MODE_VERIFY);
 +  }
 +
 +  /**
 +   * Checks the value for correctness.
 +   * 
 +   * @param signature_mode
 +   *          The parameter's value.
 +   * @return Returns true, if the value is correct, false otherwise.
 +   */
 +  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);
 +  }
 +
 +  /**
 +   * Checks the value for correctness.
 +   * 
 +   * @param connector
 +   *          The parameter's value.
 +   * @return Returns true, if the value is correct, false otherwise.
 +   * @throws ConnectorFactoryException
 +   *           F.e.
 +   */
 +  protected static boolean checkConnector(String connector) throws ConnectorFactoryException
 +  {
 +    return ConnectorFactory.isValidConnectorIdentifier(connector) && ConnectorFactory.isAvailableForCommandline(connector);
 +  }
 +
 +  /**
 +   * Checks the value for correctness.
 +   * 
 +   * @param signature_type
 +   *          The parameter's value.
 +   * @return Returns true, if the value is correct, false otherwise.
 +   */
 +  protected static boolean checkSignatureType(String signature_type) throws SignatureTypesException
 +  {
 +    SignatureTypes sig_types = SignatureTypes.getInstance();
 +    List types_array = sig_types.getSignatureTypes();
 +    Iterator it = types_array.iterator();
 +    while (it.hasNext())
 +    {
 +      String type = (String) it.next();
 +      if (type.equals(signature_type))
 +      {
 +        return true;
 +      }
 +    }
 +    return false;
 +  }
 +
 +  /**
 +   * Translates the commandline argument to a PDF-AS-ID.
 +   * 
 +   * @param signature_mode
 +   *          The signator mode commandline argument.
 +   * @return Returns the corresponding PDFASID.
 +   */
 +  protected static PdfASID translateSignatureModeToPdfASID(String signature_mode)
 +  {
 +    if (signature_mode.equals(VALUE_SIGNATURE_MODE_BINARY))
 +    {
 +      return SignatorFactory.MOST_RECENT_BINARY_SIGNATOR_ID;
 +    }
 +    if (signature_mode.equals(VALUE_SIGNATURE_MODE_TEXTUAL))
 +    {
 +      return SignatorFactory.MOST_RECENT_TEXTUAL_SIGNATOR_ID;
 +    }
 +    if (signature_mode.equals(VALUE_SIGNATURE_MODE_DETACHED))
 +    {
 +      return SignatorFactory.MOST_RECENT_DETACHED_SIGNATOR_ID;
 +    }
 +    if (signature_mode.equals(VALUE_SIGNATURE_MODE_DETACHED_TEXT))
 +    {
 +      return SignatorFactory.MOST_RECENT_DETACHEDTEXT_SIGNATOR_ID;
 +    }
 +    return null;
 +  }
 +
 +  /**
 +   * Formats the verification results.
 +   * 
 +   * @param results
 +   *          The List of SignatureResponse verification results.
 +   * @param writer
 +   *          The output sink to write the formatted text to.
 +   * @throws SettingNotFoundException
 +   *           Forwarded exception.
 +   */
 +  protected static void formatVerifyResults(VerifyResults results, PrintWriter writer) throws SettingNotFoundException
 +  {
 +    Iterator it = results.getResults().iterator();
 +    while (it.hasNext())
 +    {
 +      VerifyResult result = (VerifyResult) it.next();
 +      formatVerifyResult(result, writer);
 +
 +      if (it.hasNext())
 +      {
 +        writer.println();
 +      }
 +    }
 +  }
 +
 +  /**
 +   * Formats the verification results for debugging. Returns 0 if no error
 +   * occurs or the sum of all error-codes.
 +   * 
 +   * @param results
 +   * 
 +   * @param writer
 +   *          The output sink to write the formatted text to.
 +   * @throws SettingNotFoundException
 +   *           Forwarded exception.
 +   */
 +  protected static int debugVerifyResults(VerifyResults results) throws SettingNotFoundException
 +  {
 +    int toreturn = 0;
 +    Iterator it = results.getResults().iterator();
 +    while (it.hasNext())
 +    {
 +      VerifyResult result = (VerifyResult) it.next();
 +
 +      toreturn += result.getValueCheckCode().getCode();
 +    }
 +    return toreturn;
 +  }
 +
 +  public static void formatVerifyResult(VerifyResult result, PrintWriter writer) throws SettingNotFoundException
 +  {
 +
 +    writer.println("  Zertifikat:");
 +    writer.println("    Signator:     " + result.getSignerCertificate().getSubjectDN().getName());
 +    writer.println("    Aussteller:   " + result.getSignerCertificate().getIssuerDN().getName());
 +    writer.println("    Seriennummer: " + result.getSignerCertificate().getSerialNumber());
 +    List public_properties = result.getPublicProperties();
 +    Iterator it = public_properties.iterator();
 +    while (it.hasNext())
 +    {
 +      String public_property = (String) it.next();
 +      writer.println("    Eigenschaft:  " + public_property);
 +    }
 +
 +    writer.println("  Zertifikat-Check:");
 +    writer.println("    " + result.getCertificateCheck().getCode() + " - " + result.getCertificateCheck().getMessage());
 +    writer.println("  Signatur-Check:");
 +    writer.println("    " + result.getValueCheckCode().getCode() + " - " + result.getValueCheckCode().getMessage());
 +    writer.println("  Manifest-Check:");
 +    writer.println("    " + result.getManifestCheckCode().getCode() + " - " + result.getManifestCheckCode().getMessage());
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/framework/ConnectorFactory.java b/src/main/java/at/gv/egiz/pdfas/framework/ConnectorFactory.java index b42c8ed..99d692e 100644 --- a/src/main/java/at/gv/egiz/pdfas/framework/ConnectorFactory.java +++ b/src/main/java/at/gv/egiz/pdfas/framework/ConnectorFactory.java @@ -33,34 +33,34 @@ public class ConnectorFactory -  public static Connector createConnector (String connectorId, String profile, String locRef) throws ConnectorFactoryException, ConnectorException
 +  public static Connector createConnector (String connectorId, ConnectorParameters connectorParameters) throws ConnectorFactoryException, ConnectorException
    {
      if (connectorId.equals(DETACHED_MULTIPART_BKU_CONNECTOR))
      {
 -      return new MultipartDetachedBKUConnector(profile);
 +      return new MultipartDetachedBKUConnector(connectorParameters);
      }
      if (connectorId.equals(ENVELOPING_BASE64_BKU_CONNECTOR))
      {
 -      return new EnvelopedBase64BKUConnector(profile);
 +      return new EnvelopedBase64BKUConnector(connectorParameters.getProfileId());
      }
      if (connectorId.equals(OLD_ENVELOPING_BASE64_BKU_CONNECTOR))
      {
 -      return new OldEnvelopingBase64BKUConnector(profile);
 +      return new OldEnvelopingBase64BKUConnector(connectorParameters.getProfileId());
      }
      if (connectorId.equals(DETACHED_LOCREF_MOA_CONNECTOR))
      {
  //    	TODO Hier wird der neue Connector verwendet
  //      return new DetachedLocRefMOAConnector(profile, locRef);
 -      return new MOASoapWithAttachmentConnector(profile);
 +      return new MOASoapWithAttachmentConnector(connectorParameters);
      }
      if (connectorId.equals(ENVELOPING_BASE64_MOA_CONNECTOR))
      {
  //    	TODO Hier wird NICHT der neue Connector verwendet
 -      return new EnvelopingBase64MOAConnector(profile);
 +      return new EnvelopingBase64MOAConnector(connectorParameters.getProfileId());
  //      return new MOASoapWithAttachmentConnector(profile);
      }
 diff --git a/src/main/java/at/gv/egiz/pdfas/framework/ConnectorParameters.java b/src/main/java/at/gv/egiz/pdfas/framework/ConnectorParameters.java new file mode 100644 index 0000000..618624d --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/framework/ConnectorParameters.java @@ -0,0 +1,85 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.framework;
 +
 +import java.util.Date;
 +
 +/**
 + * Parameters passed to the constructor of the Connector.
 + * 
 + * <p>
 + * Each Connector must have a constructor accepting this parameter class as an
 + * argument.
 + * </p>
 + * 
 + * @author wprinz
 + */
 +public class ConnectorParameters
 +{
 +  /**
 +   * The profile Id to get the connector parameters from.
 +   * 
 +   * <p>
 +   * The there are no explicit parameters for the connector in the profile, the
 +   * default parameters are used.
 +   * </p>
 +   */
 +  protected String profileId = null;
 +
 +  /**
 +   * Tells, if the connector should ask the device to return the hash input
 +   * data.
 +   * 
 +   * <p>
 +   * Note that not all connectors support to return the hash input data - so
 +   * there is no guarantee that the hash value will actually be returned.
 +   * </p>
 +   */
 +  protected boolean returnHashInputData = false;
 +
 +  /**
 +   * Allows to specify an explicit time of verification.
 +   * 
 +   * <p>
 +   * If null, the device's default behaviour determines the time of
 +   * verification, which is usually the current time.
 +   * </p>
 +   * <p>
 +   * The time of verification usually influences the certificate check. E.g. the
 +   * certificate may not be valid at the time of verification.
 +   * </p>
 +   */
 +  protected Date verificationTime = null;
 +
 +  public String getProfileId()
 +  {
 +    return this.profileId;
 +  }
 +
 +  public void setProfileId(String profileId)
 +  {
 +    this.profileId = profileId;
 +  }
 +
 +  public boolean isReturnHashInputData()
 +  {
 +    return this.returnHashInputData;
 +  }
 +
 +  public void setReturnHashInputData(boolean returnHashInputData)
 +  {
 +    this.returnHashInputData = returnHashInputData;
 +  }
 +
 +  public Date getVerificationTime()
 +  {
 +    return this.verificationTime;
 +  }
 +
 +  public void setVerificationTime(Date verificationTime)
 +  {
 +    this.verificationTime = verificationTime;
 +  }
 +
 +}
 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 index da81e87..9abf509 100644 --- a/src/main/java/at/gv/egiz/pdfas/framework/signator/SignatorInformation.java +++ b/src/main/java/at/gv/egiz/pdfas/framework/signator/SignatorInformation.java @@ -3,6 +3,7 @@   */
  package at.gv.egiz.pdfas.framework.signator;
 +import at.knowcenter.wag.egov.egiz.pdf.ActualTablePos;
  import at.knowcenter.wag.egov.egiz.sig.SignatureData;
  import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject;
 @@ -40,4 +41,23 @@ public interface SignatorInformation     *          The SignSignatureObject.
     */
    public void setSignSignatureObject(SignSignatureObject signSignatureObject);
 +
 +  /**
 +   * Returns the SignSignatureObject.
 +   * 
 +   * <p>
 +   * After signation, this is used by the framework/API to get additional
 +   * information about the signature.
 +   * </p>
 +   * 
 +   * @return Returns the SignSignatureObject.
 +   */
 +  public SignSignatureObject getSignSignatureObject();
 +
 +  /**
 +   * Returns the position where the signature table was actually placed.
 +   * 
 +   * @return Returns the position where the signature table was actually placed.
 +   */
 +  public ActualTablePos getActualTablePos();
  }
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/CheckHelper.java b/src/main/java/at/gv/egiz/pdfas/impl/api/CheckHelper.java new file mode 100644 index 0000000..467113f --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/CheckHelper.java @@ -0,0 +1,213 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api;
 +
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +
 +import at.gv.egiz.pdfas.api.analyze.AnalyzeParameters;
 +import at.gv.egiz.pdfas.api.commons.Constants;
 +import at.gv.egiz.pdfas.api.io.DataSource;
 +import at.gv.egiz.pdfas.api.sign.SignParameters;
 +import at.gv.egiz.pdfas.api.sign.pos.SignaturePositioning;
 +import at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters;
 +import at.gv.egiz.pdfas.api.verify.VerifyParameters;
 +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException;
 +import at.knowcenter.wag.egov.egiz.exceptions.SignatureTypesException;
 +import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
 +
 +/**
 + * Contains check methods frequently used by the {@link PdfAsObject} to check
 + * input parameters.
 + * 
 + * @author wprinz
 + * 
 + */
 +public final class CheckHelper
 +{
 +  /**
 +   * The log.
 +   */
 +  private static Log log = LogFactory.getLog(CheckHelper.class);
 +
 +  /**
 +   * Hidden default constructor.
 +   */
 +  private CheckHelper()
 +  {
 +    // empty block
 +  }
 +
 +  /**
 +   * Checks the SignParameters for integrity.
 +   * 
 +   * @param sp
 +   *          The {@link SignParameters}
 +   */
 +  public static void checkSignParameters(SignParameters sp)
 +  {
 +    if (sp == null)
 +    {
 +      throw new IllegalArgumentException("The signParameters must not be null.");
 +    }
 +
 +    checkDocument(sp.getDocument());
 +    if (sp.getOutput() == null)
 +    {
 +      throw new IllegalArgumentException("The output DataSink must not be null.");
 +    }
 +    checkSignatureType(sp.getSignatureType());
 +    checkSignatureDevice(sp.getSignatureDevice());
 +    if (sp.getSignatureProfileId() != null)
 +    {
 +      checkProfileId(sp.getSignatureProfileId());
 +    }
 +    if (sp.getSignaturePositioning() != null)
 +    {
 +      checkSignaturePositioning(sp.getSignaturePositioning());
 +    }
 +  }
 +
 +  /**
 +   * Checks the VerifyParameters for integrity.
 +   * 
 +   * @param vp
 +   *          The {@link VerifyParameters}
 +   */
 +  public static void checkVerifyParameters(VerifyParameters vp)
 +  {
 +    if (vp == null)
 +    {
 +      throw new IllegalArgumentException("The verifyParameters must not be null.");
 +    }
 +
 +    checkDocument(vp.getDocument());
 +    checkVerifyMode(vp.getVerifyMode());
 +    checkSignatureDevice(vp.getSignatureDevice());
 +    if (vp.getSignatureToVerify() < Constants.VERIFY_ALL)
 +    {
 +      throw new IllegalArgumentException("The signatureToVerify parameter is incorrect. " + vp.getSignatureToVerify());
 +    }
 +  }
 +
 +  /**
 +   * Checks the AnalyzeParameters for integrity.
 +   * 
 +   * @param ap
 +   *          The {@link AnalyzeParameters}
 +   */
 +  public static void checkAnalyzeParameters(AnalyzeParameters ap)
 +  {
 +    if (ap == null)
 +    {
 +      throw new IllegalArgumentException("The analyzeParameters must not be null.");
 +    }
 +
 +    checkDocument(ap.getDocument());
 +    checkVerifyMode(ap.getVerifyMode());
 +  }
 +
 +  /**
 +   * Checks the VerifyAfterAnalysisParameters for integrity.
 +   * 
 +   * @param vaap
 +   *          The {@link VerifyAfterAnalysisParameters}
 +   */
 +  public static void checkVerifyAfterAnalysisParameters(VerifyAfterAnalysisParameters vaap)
 +  {
 +    if (vaap == null)
 +    {
 +      throw new IllegalArgumentException("The analyzeParameters must not be null.");
 +    }
 +
 +    if (vaap.getAnalyzeResult() == null)
 +    {
 +      throw new IllegalArgumentException("The analyzeResult must not be null.");
 +    }
 +    checkSignatureDevice(vaap.getSignatureDevice());
 +  }
 +
 +  protected static void checkDocument(DataSource document)
 +  {
 +    if (document == null)
 +    {
 +      throw new IllegalArgumentException("The document DataSource must not be null.");
 +    }
 +  }
 +
 +  protected static void checkSignatureType(String signatureType)
 +  {
 +    if (signatureType == null)
 +    {
 +      throw new IllegalArgumentException("The signatureType must not be null.");
 +    }
 +    if (!(signatureType.equals(Constants.SIGNATURE_TYPE_BINARY) || signatureType.equals(Constants.SIGNATURE_TYPE_TEXTUAL) || signatureType.equals(Constants.SIGNATURE_TYPE_DETACHEDTEXTUAL)))
 +    {
 +      throw new IllegalArgumentException("The signatureType must be one of the Constants.SIGNATURE_TYPE_* constants. " + signatureType);
 +    }
 +  }
 +
 +  protected static void checkProfileId(String profileId)
 +  {
 +    if (profileId == null)
 +    {
 +      throw new IllegalArgumentException("The profileId must not be null.");
 +    }
 +    try
 +    {
 +      if (!SignatureTypes.getInstance().getSignatureTypes().contains(profileId))
 +      {
 +        throw new IllegalArgumentException("The profileId must be defined in the configuration file. " + profileId);
 +      }
 +    }
 +    catch (SignatureTypesException e)
 +    {
 +      String msg = "Error while checking the profileId parameter - cannot get list of valid profiles. " + profileId;
 +      log.error(msg, e);
 +      throw new IllegalArgumentException(msg);
 +    }
 +  }
 +
 +  protected static void checkSignaturePositioning(SignaturePositioning signaturePositioning)
 +  {
 +    if (signaturePositioning == null)
 +    {
 +      throw new IllegalArgumentException("The signaturePosition must not be null.");
 +    }
 +    try
 +    {
 +      PosHelper.formTablePos(signaturePositioning);
 +    }
 +    catch (PDFDocumentException e)
 +    {
 +      String msg = "The signaturePosition string is not valid. " + signaturePositioning;
 +      log.error(msg, e);
 +      throw new IllegalArgumentException(msg);
 +    }
 +  }
 +
 +  protected static void checkVerifyMode(String verifyMode)
 +  {
 +    if (verifyMode == null)
 +    {
 +      throw new IllegalArgumentException("The verifyMode must not be null.");
 +    }
 +    if (!(verifyMode.equals(Constants.VERIFY_MODE_BINARY_ONLY) || verifyMode.equals(Constants.VERIFY_MODE_SEMI_CONSERVATIVE) || verifyMode.equals(Constants.VERIFY_MODE_FULL_CONSERVATIVE)))
 +    {
 +      throw new IllegalArgumentException("The verifyMode must be one of the Constants.VERIFY_MODE_* constants. " + verifyMode);
 +    }
 +  }
 +
 +  protected static void checkSignatureDevice(String signatureDevice)
 +  {
 +    if (signatureDevice == null)
 +    {
 +      throw new IllegalArgumentException("The signatureDevice must not be null.");
 +    }
 +    if (!(signatureDevice.equals(Constants.SIGNATURE_DEVICE_BKU) || signatureDevice.equals(Constants.SIGNATURE_DEVICE_MOA)))
 +    {
 +      throw new IllegalArgumentException("The signatureDevice must be one of the Constants.SIGNATURE_DEVICE_* constants. " + signatureDevice);
 +    }
 +  }
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java b/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java new file mode 100644 index 0000000..a343de8 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java @@ -0,0 +1,317 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api;
 +
 +import java.io.File;
 +import java.io.UnsupportedEncodingException;
 +import java.util.ArrayList;
 +import java.util.Iterator;
 +import java.util.List;
 +
 +import at.gv.egiz.pdfas.api.PdfAs;
 +import at.gv.egiz.pdfas.api.analyze.AnalyzeParameters;
 +import at.gv.egiz.pdfas.api.analyze.AnalyzeResult;
 +import at.gv.egiz.pdfas.api.commons.Constants;
 +import at.gv.egiz.pdfas.api.commons.SignatureInformation;
 +import at.gv.egiz.pdfas.api.commons.SignatureProfile;
 +import at.gv.egiz.pdfas.api.exceptions.PdfAsException;
 +import at.gv.egiz.pdfas.api.sign.SignParameters;
 +import at.gv.egiz.pdfas.api.sign.SignResult;
 +import at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters;
 +import at.gv.egiz.pdfas.api.verify.VerifyParameters;
 +import at.gv.egiz.pdfas.api.verify.VerifyResult;
 +import at.gv.egiz.pdfas.api.verify.VerifyResults;
 +import at.gv.egiz.pdfas.commandline.CommandlineConnectorChooser;
 +import at.gv.egiz.pdfas.exceptions.ErrorCode;
 +import at.gv.egiz.pdfas.framework.config.SettingsHelper;
 +import at.gv.egiz.pdfas.framework.input.ExtractionStage;
 +import at.gv.egiz.pdfas.framework.signator.SignatorInformation;
 +import at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters;
 +import at.gv.egiz.pdfas.impl.api.analyze.AnalyzeResultImpl;
 +import at.gv.egiz.pdfas.impl.api.commons.DataSinkAdapter;
 +import at.gv.egiz.pdfas.impl.api.commons.PdfDataSourceAdapter;
 +import at.gv.egiz.pdfas.impl.api.commons.SignatureInformationAdapter;
 +import at.gv.egiz.pdfas.impl.api.commons.SignatureProfileImpl;
 +import at.gv.egiz.pdfas.impl.api.commons.TextDataSourceAdapter;
 +import at.gv.egiz.pdfas.impl.api.sign.ActualSignaturePositionAdapter;
 +import at.gv.egiz.pdfas.impl.api.sign.SignResultImpl;
 +import at.gv.egiz.pdfas.impl.api.verify.VerifyResultAdapter;
 +import at.gv.egiz.pdfas.impl.api.verify.VerifyResultsImpl;
 +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.SettingsReader;
 +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException;
 +import at.knowcenter.wag.egov.egiz.exceptions.SignatureException;
 +import at.knowcenter.wag.egov.egiz.framework.SignatorFactory;
 +import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder;
 +import at.knowcenter.wag.egov.egiz.pdf.TablePos;
 +import at.knowcenter.wag.egov.egiz.sig.SignatureResponse;
 +import at.knowcenter.wag.egov.egiz.sig.SignatureTypeDefinition;
 +import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
 +
 +/**
 + * Implementation of the {@link PdfAs} interface.
 + * 
 + * @author wprinz
 + */
 +public class PdfAsObject implements PdfAs
 +{
 +  /**
 +   * The work directory.
 +   */
 +  protected File workDirectory = null;
 +
 +  /**
 +   * This constructor is for internal use only - use
 +   * {@link at.gv.egiz.pdfas.PdfAsFactory} instead.
 +   * 
 +   * @param workDirectory
 +   *          The work directory.
 +   * @throws PdfAsException
 +   *           Thrown, if the configuration cannot be processed.
 +   */
 +  public PdfAsObject(File workDirectory) throws PdfAsException
 +  {
 +    if (workDirectory == null)
 +    {
 +      throw new IllegalArgumentException("The work directory must not be null.");
 +    }
 +    if (!workDirectory.isDirectory())
 +    {
 +      throw new IllegalArgumentException("The work directory does not exist or is not a directory. " + workDirectory.getPath());
 +    }
 +
 +    this.workDirectory = workDirectory;
 +
 +    SettingsReader.initialize(workDirectory.getPath());
 +    reloadConfig();
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.PdfAs#reloadConfig()
 +   */
 +  public void reloadConfig() throws PdfAsException
 +  {
 +    SettingsReader.createInstance();
 +    SignatureTypes.createInstance();
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.PdfAs#getProfileInformation()
 +   */
 +  public List getProfileInformation() throws PdfAsException
 +  {
 +    final String MOA_SIGN_KEY_IDENTIFIER_KEY = "moa.sign.KeyIdentifier";
 +
 +    SettingsReader settings = SettingsReader.getInstance();
 +    final String defaultMoaKeyIdentifiert = settings.getSetting(MOA_SIGN_KEY_IDENTIFIER_KEY, null);
 +
 +    SignatureTypes types = SignatureTypes.getInstance();
 +    List profiles = types.getSignatureTypeDefinitions();
 +
 +    List profileInformation = new ArrayList(profiles.size());
 +
 +    Iterator it = profiles.iterator();
 +    while (it.hasNext())
 +    {
 +      SignatureTypeDefinition profile = (SignatureTypeDefinition) it.next();
 +
 +      final String profileId = profile.getType();
 +      final String moaKeyIdentifier = settings.getSetting("sig_obj." + profileId + "." + MOA_SIGN_KEY_IDENTIFIER_KEY, defaultMoaKeyIdentifiert);
 +
 +      SignatureProfile signatureProfile = new SignatureProfileImpl(profileId, moaKeyIdentifier);
 +      profileInformation.add(signatureProfile);
 +    }
 +
 +    return profileInformation;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.PdfAs#sign(at.gv.egiz.pdfas.api.sign.SignParameters)
 +   */
 +  public SignResult sign(SignParameters signParameters) throws PdfAsException
 +  {
 +    CheckHelper.checkSignParameters(signParameters);
 +
 +    PdfASID signatorId = null;
 +    if (signParameters.getSignatureType().equals(Constants.SIGNATURE_TYPE_BINARY))
 +    {
 +      signatorId = SignatorFactory.MOST_RECENT_BINARY_SIGNATOR_ID;
 +    }
 +    if (signParameters.getSignatureType().equals(Constants.SIGNATURE_TYPE_TEXTUAL))
 +    {
 +      signatorId = SignatorFactory.MOST_RECENT_TEXTUAL_SIGNATOR_ID;
 +    }
 +    if (signParameters.getSignatureType().equals(Constants.SIGNATURE_TYPE_DETACHEDTEXTUAL))
 +    {
 +      signatorId = SignatorFactory.MOST_RECENT_DETACHEDTEXT_SIGNATOR_ID;
 +    }
 +
 +    TablePos pos = PosHelper.formTablePos(signParameters.getSignaturePositioning());
 +
 +    String connectorId = CommandlineConnectorChooser.chooseCommandlineConnectorForSign(signParameters.getSignatureDevice());
 +
 +    SignatorInformation si = PdfAS
 +        .signCommandline(new PdfDataSourceAdapter(signParameters.getDocument()), new DataSinkAdapter(signParameters.getOutput()), signatorId, connectorId, signParameters.getSignatureProfileId(), pos);
 +
 +    return new SignResultImpl(signParameters.getOutput(), si.getSignSignatureObject().getX509Certificate(), new ActualSignaturePositionAdapter(si.getActualTablePos()));
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.PdfAs#verify(at.gv.egiz.pdfas.api.verify.VerifyParameters)
 +   */
 +  public VerifyResults verify(VerifyParameters verifyParameters) throws PdfAsException
 +  {
 +    CheckHelper.checkVerifyParameters(verifyParameters);
 +
 +    AnalyzeParameters ap = new AnalyzeParameters();
 +    fillAnalyzeParametersWithVerifyParameters(ap, verifyParameters);
 +    AnalyzeResult analyzeResult = analyze(ap);
 +
 +    if (verifyParameters.getSignatureToVerify() != Constants.VERIFY_ALL)
 +    {
 +      if (verifyParameters.getSignatureToVerify() >= analyzeResult.getSignatures().size())
 +      {
 +        throw new SignatureException(312, "The selected signature to be verified doesn't exist. " + verifyParameters.getSignatureToVerify());
 +      }
 +
 +      Object stv = analyzeResult.getSignatures().get(verifyParameters.getSignatureToVerify());
 +      List selectedSignature = new ArrayList(1);
 +      selectedSignature.add(stv);
 +      analyzeResult = new AnalyzeResultImpl(selectedSignature);
 +    }
 +
 +    VerifyAfterAnalysisParameters vaap = new VerifyAfterAnalysisParameters();
 +    vaap.setAnalyzeResult(analyzeResult);
 +    fillVerifyAfterAnalysisParametersWithVerifyParameters(vaap, verifyParameters);
 +    return verify(vaap);
 +  }
 + 
 +
 +  /**
 +   * Copies all adequate parameters from the {@link VerifyParameters} to the
 +   * {@link AnalyzeParameters}.
 +   * 
 +   * @param ap
 +   *          The {@link AnalyzeParameters}.
 +   * @param vp
 +   *          The {@link VerifyParameters}.
 +   */
 +  protected void fillAnalyzeParametersWithVerifyParameters(AnalyzeParameters ap, VerifyParameters vp)
 +  {
 +    ap.setDocument(vp.getDocument());
 +    ap.setVerifyMode(vp.getVerifyMode());
 +  }
 +
 +  /**
 +   * Copies all adequate parameters from the {@link VerifyParameters} to the
 +   * {@link VerifyAfterAnalysisParameters}.
 +   * 
 +   * @param vaap
 +   *          The {@link VerifyAfterAnalysisParameters}.
 +   * @param vp
 +   *          The {@link VerifyParameters}.
 +   */
 +  protected void fillVerifyAfterAnalysisParametersWithVerifyParameters(VerifyAfterAnalysisParameters vaap, VerifyParameters vp)
 +  {
 +    vaap.setSignatureDevice(vp.getSignatureDevice());
 +    vaap.setVerificationTime(vp.getVerificationTime());
 +    vaap.setReturnHashInputData(vp.isReturnHashInputData());
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.PdfAs#analyze(at.gv.egiz.pdfas.api.analyze.AnalyzeParameters)
 +   */
 +  public AnalyzeResult analyze(AnalyzeParameters analyzeParameters) throws PdfAsException
 +  {
 +    CheckHelper.checkAnalyzeParameters(analyzeParameters);
 +
 +    VerificationFilterParameters parametersConfig = SettingsHelper.readVerificationFilterParametersFromSettings();
 +    boolean binaryOnly = parametersConfig.extractBinarySignaturesOnly();
 +    if (analyzeParameters.getVerifyMode().equals(Constants.VERIFY_MODE_BINARY_ONLY))
 +    {
 +      binaryOnly = true;
 +    }
 +    boolean assumeOnlySB = parametersConfig.assumeOnlySignatureUpdateBlocks();
 +    if (analyzeParameters.getVerifyMode().equals(Constants.VERIFY_MODE_SEMI_CONSERVATIVE))
 +    {
 +      assumeOnlySB = true;
 +    }
 +    if (analyzeParameters.getVerifyMode().equals(Constants.VERIFY_MODE_FULL_CONSERVATIVE))
 +    {
 +      assumeOnlySB = false;
 +    }
 +    VerificationFilterParameters parameters = new VerificationFilterParametersImpl(binaryOnly, assumeOnlySB, parametersConfig.scanForOldSignatures());
 +    
 +    at.gv.egiz.pdfas.framework.input.DataSource inputDataSource = null;
 +    if (analyzeParameters.getDocument().getMimeType().equals("application/pdf"))
 +    {
 +      inputDataSource = new PdfDataSourceAdapter(analyzeParameters.getDocument());
 +    }
 +    else
 +    {
 +      try
 +      {
 +        inputDataSource = new TextDataSourceAdapter(analyzeParameters.getDocument());
 +      }
 +      catch (UnsupportedEncodingException e)
 +      {
 +        throw new PresentableException(ErrorCode.DOCUMENT_CANNOT_BE_READ, "The characterEncoding is not supported." + analyzeParameters.getDocument().getCharacterEncoding(), e);
 +      }
 +    }
 +    assert inputDataSource != null;
 +    
 +    ExtractionStage es = new ExtractionStage();
 +    List signature_holders = es.extractSignatureHolders(inputDataSource, parameters);
 +
 +    List sigInfs = new ArrayList(signature_holders.size());
 +    Iterator it = signature_holders.iterator();
 +    while (it.hasNext())
 +    {
 +      SignatureHolder sh = (SignatureHolder)it.next();
 +      SignatureInformation si = new SignatureInformationAdapter(sh);
 +      sigInfs.add(si);
 +    }
 +    
 +    return new AnalyzeResultImpl(sigInfs);
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.PdfAs#verify(at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters)
 +   */
 +  public VerifyResults verify(VerifyAfterAnalysisParameters verifyAfterAnalysisParameters) throws PdfAsException
 +  {
 +    CheckHelper.checkVerifyAfterAnalysisParameters(verifyAfterAnalysisParameters);
 +
 +    List signatures = verifyAfterAnalysisParameters.getAnalyzeResult().getSignatures();
 +    List signature_holders = new ArrayList(signatures.size());
 +    Iterator it = signatures.iterator();
 +    while (it.hasNext())
 +    {
 +      SignatureInformation si = (SignatureInformation) it.next();
 +      SignatureHolder sh = (SignatureHolder) si.getInternalSignatureInformation();
 +      signature_holders.add(sh);
 +    }
 +    assert signature_holders.size() == signatures.size();
 +    
 +    List results = PdfAS.verifySignatureHolders(signature_holders, verifyAfterAnalysisParameters.getSignatureDevice(), verifyAfterAnalysisParameters.isReturnHashInputData(), verifyAfterAnalysisParameters.getVerificationTime());
 +    
 +    List vrs = new ArrayList(results.size());
 +    
 +    assert signature_holders.size() == results.size() : "Not all signatures were verified.";
 +
 +    for (int i = 0; i < signature_holders.size(); i++)
 +    {
 +      SignatureResponse response = (SignatureResponse) results.get(i);
 +      SignatureHolder holder = (SignatureHolder) signature_holders.get(i);
 +      
 +      VerifyResult vr = new VerifyResultAdapter(response, holder, verifyAfterAnalysisParameters.getVerificationTime());
 +      vrs.add(vr);
 +    }
 +
 +    return new VerifyResultsImpl(vrs);
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/PosHelper.java b/src/main/java/at/gv/egiz/pdfas/impl/api/PosHelper.java new file mode 100644 index 0000000..14f081f --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/PosHelper.java @@ -0,0 +1,79 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api;
 +
 +import at.gv.egiz.pdfas.api.sign.pos.SignaturePositioning;
 +import at.gv.egiz.pdfas.api.sign.pos.axis.AbsoluteAxisAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.axis.AutoAxisAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.axis.AxisAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.page.AbsolutePageAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.page.AutoPageAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.page.NewPageAlgorithm;
 +import at.gv.egiz.pdfas.api.sign.pos.page.PageAlgorithm;
 +import at.knowcenter.wag.egov.egiz.PdfAS;
 +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException;
 +import at.knowcenter.wag.egov.egiz.pdf.TablePos;
 +
 +/**
 + * @author wprinz
 + * 
 + */
 +public final class PosHelper
 +{
 +  /**
 +   * Hidden default constructor.
 +   */
 +  private PosHelper()
 +  {
 +    // empty block
 +  }
 +
 +  public static TablePos formTablePos(SignaturePositioning signaturePositioning) throws PDFDocumentException
 +  {
 +    if (signaturePositioning == null)
 +    {
 +      return null;
 +    }
 +
 +    String positioningString = formPositioningString(signaturePositioning);
 +    TablePos pos = PdfAS.parsePositionFromPosString(positioningString);
 +
 +    return pos;
 +  }
 +
 +  protected static String formPositioningString(SignaturePositioning sp)
 +  {
 +    String x_algo = formAxisAlgoString(sp.getXAlgorithm());
 +    String y_algo = formAxisAlgoString(sp.getYAlgorithm());
 +    String w_algo = formAxisAlgoString(sp.getWidthAlgorithm());
 +    String p_algo = formPageAlgoString(sp.getPageAlgorithm());
 +    String positioning = "x:" + x_algo + ";y:" + y_algo + ";w:" + w_algo + ";p:" + p_algo + ";f:" + sp.getFooterLine();
 +    return positioning;
 +  }
 +
 +  protected static String formAxisAlgoString(AxisAlgorithm algorithm)
 +  {
 +    if (algorithm instanceof AutoAxisAlgorithm)
 +    {
 +      return "auto";
 +    }
 +    AbsoluteAxisAlgorithm aaa = (AbsoluteAxisAlgorithm) algorithm;
 +    return Float.toString(aaa.getAbsoluteValue());
 +  }
 +
 +  protected static String formPageAlgoString(PageAlgorithm algorithm)
 +  {
 +    if (algorithm instanceof AutoPageAlgorithm)
 +    {
 +      return "auto";
 +    }
 +    if (algorithm instanceof NewPageAlgorithm)
 +    {
 +      return "new";
 +    }
 +    AbsolutePageAlgorithm apa = (AbsolutePageAlgorithm) algorithm;
 +    return Integer.toString(apa.getPage());
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/analyze/AnalyzeResultImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/api/analyze/AnalyzeResultImpl.java new file mode 100644 index 0000000..87a14f0 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/analyze/AnalyzeResultImpl.java @@ -0,0 +1,47 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api.analyze;
 +
 +import java.util.List;
 +
 +import at.gv.egiz.pdfas.api.analyze.AnalyzeResult;
 +import at.gv.egiz.pdfas.api.exceptions.PdfAsException;
 +
 +/**
 + * Holds the result of an analyzation.
 + * 
 + * @author wprinz
 + */
 +public class AnalyzeResultImpl implements AnalyzeResult
 +{
 +  /**
 +   * The found signatures.
 +   */
 +  protected List signatures = null;
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param signatures
 +   *          The found signatures.
 +   */
 +  public AnalyzeResultImpl(List signatures)
 +  {
 +    if (signatures == null)
 +    {
 +      throw new IllegalArgumentException("The list of found signatures must not be null.");
 +    }
 +
 +    this.signatures = signatures;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.analyze.AnalyzeResult#getSignatures()
 +   */
 +  public List getSignatures() throws PdfAsException
 +  {
 +    return this.signatures;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSinkAdapter.java b/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSinkAdapter.java new file mode 100644 index 0000000..5744a21 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSinkAdapter.java @@ -0,0 +1,83 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api.commons;
 +
 +import java.io.IOException;
 +import java.io.OutputStream;
 +
 +import at.gv.egiz.pdfas.api.io.DataSink;
 +
 +/**
 + * Adapter that converts an API DataSink to a framework DataSink.
 + * 
 + * @author wprinz
 + */
 +public class DataSinkAdapter implements at.gv.egiz.pdfas.framework.output.DataSink
 +{
 +  /**
 +   * The API DataSink to be adapted to a framework DataSink.
 +   */
 +  protected at.gv.egiz.pdfas.api.io.DataSink apiDataSink = null;
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param apiDataSink
 +   *          The API DataSink to be adapted to a framework DataSink.
 +   */
 +  public DataSinkAdapter(DataSink apiDataSink)
 +  {
 +    this.apiDataSink = apiDataSink;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.framework.output.DataSink#createOutputStream(java.lang.String)
 +   */
 +  public OutputStream createOutputStream(String mimeType)
 +  {
 +    try
 +    {
 +      return this.apiDataSink.createOutputStream(mimeType);
 +    }
 +    catch (IOException e)
 +    {
 +      e.printStackTrace();
 +      throw new RuntimeException(e);
 +    }
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.framework.output.DataSink#createOutputStream(java.lang.String,
 +   *      java.lang.String)
 +   */
 +  public OutputStream createOutputStream(String mimeType, String characterEncoding)
 +  {
 +    try
 +    {
 +      return this.apiDataSink.createOutputStream(mimeType, characterEncoding);
 +    }
 +    catch (IOException e)
 +    {
 +      e.printStackTrace();
 +      throw new RuntimeException(e);
 +    }
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.framework.output.DataSink#getCharacterEncoding()
 +   */
 +  public String getCharacterEncoding()
 +  {
 +    return this.apiDataSink.getCharacterEncoding();
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.framework.output.DataSink#getMimeType()
 +   */
 +  public String getMimeType()
 +  {
 +    return this.apiDataSink.getMimeType();
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSourceApiAdapter.java b/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSourceApiAdapter.java new file mode 100644 index 0000000..9e5495c --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSourceApiAdapter.java @@ -0,0 +1,85 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api.commons;
 +
 +import java.io.InputStream;
 +
 +import at.gv.egiz.pdfas.framework.input.PdfDataSource;
 +import at.gv.egiz.pdfas.framework.input.TextDataSource;
 +
 +/**
 + * Adapter that converts a framework DataSource to an API PdfDataSource.
 + * 
 + * @author wprinz
 + */
 +public class DataSourceApiAdapter implements at.gv.egiz.pdfas.api.io.DataSource
 +{
 +  /**
 +   * The framework DataSource to be adapted to an API DataSource.
 +   */
 +  protected at.gv.egiz.pdfas.framework.input.DataSource frameworkDataSource = null;
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param frameworkDataSource
 +   *          The framework DataSource to be adapted to an API DataSource.
 +   */
 +  public DataSourceApiAdapter(at.gv.egiz.pdfas.framework.input.DataSource frameworkDataSource)
 +  {
 +    this.frameworkDataSource = frameworkDataSource;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#createInputStream()
 +   */
 +  public InputStream createInputStream()
 +  {
 +    return this.frameworkDataSource.createInputStream();
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getAsByteArray()
 +   */
 +  public byte[] getAsByteArray()
 +  {
 +    return this.frameworkDataSource.getAsByteArray();
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getLength()
 +   */
 +  public int getLength()
 +  {
 +    return this.frameworkDataSource.getLength();
 +  }
 +
 +  public String getCharacterEncoding()
 +  {
 +    if (this.frameworkDataSource instanceof PdfDataSource)
 +    {
 +      return null;
 +    }
 +    if (this.frameworkDataSource instanceof TextDataSource)
 +    {
 +      return "UTF-8";
 +    }
 +    return null;
 +  }
 +
 +  public String getMimeType()
 +  {
 +    if (this.frameworkDataSource instanceof PdfDataSource)
 +    {
 +      return "application/pdf";
 +    }
 +    if (this.frameworkDataSource instanceof TextDataSource)
 +    {
 +      return "text/plain";
 +    }
 +
 +    return null;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/commons/PdfDataSourceAdapter.java b/src/main/java/at/gv/egiz/pdfas/impl/api/commons/PdfDataSourceAdapter.java new file mode 100644 index 0000000..fbafafe --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/commons/PdfDataSourceAdapter.java @@ -0,0 +1,52 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api.commons;
 +
 +import java.io.InputStream;
 +
 +/**
 + * Adapter that converts an API DataSource to a framework PdfDataSource.
 + * 
 + * @author wprinz
 + */
 +public class PdfDataSourceAdapter implements at.gv.egiz.pdfas.framework.input.PdfDataSource
 +{
 +  /**
 +   * The API DataSource to be adapted to a framework PdfDataSource.
 +   */
 +  protected at.gv.egiz.pdfas.api.io.DataSource apiDataSource = null;
 +
 +  /**
 +   * Constructor.
 +   * @param apiDataSource The API DataSource to be adapted to a framework PdfDataSource.
 +   */
 +  public PdfDataSourceAdapter(at.gv.egiz.pdfas.api.io.DataSource apiDataSource)
 +  {
 +    this.apiDataSource = apiDataSource;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.framework.input.DataSource#createInputStream()
 +   */
 +  public InputStream createInputStream()
 +  {
 +    return this.apiDataSource.createInputStream();
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.framework.input.DataSource#getAsByteArray()
 +   */
 +  public byte[] getAsByteArray()
 +  {
 +    return this.apiDataSource.getAsByteArray();
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.framework.input.DataSource#getLength()
 +   */
 +  public int getLength()
 +  {
 +    return this.apiDataSource.getLength();
 +  }
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureInformationAdapter.java b/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureInformationAdapter.java new file mode 100644 index 0000000..875c3d9 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureInformationAdapter.java @@ -0,0 +1,87 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api.commons;
 +
 +import java.security.cert.X509Certificate;
 +import java.util.Date;
 +
 +import at.gv.egiz.pdfas.api.commons.Constants;
 +import at.gv.egiz.pdfas.api.commons.SignatureInformation;
 +import at.gv.egiz.pdfas.api.io.DataSource;
 +import at.knowcenter.wag.egov.egiz.pdf.EGIZDate;
 +import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder;
 +
 +/**
 + * Adapter that converts a framework SignatureHolder to an API
 + * SignatureInformation.
 + * 
 + * @author wprinz
 + */
 +public class SignatureInformationAdapter implements SignatureInformation
 +{
 +  /**
 +   * The framework SignatureHolder to be adapted to an API SignatureInformation.
 +   */
 +  protected SignatureHolder signatureHolder = null;
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param signatureHolder
 +   *          The framework SignatureHolder to be adapted to an API
 +   *          SignatureInformation.
 +   */
 +  public SignatureInformationAdapter(SignatureHolder signatureHolder)
 +  {
 +    this.signatureHolder = signatureHolder;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.commons.SignatureInformation#getSignedData()
 +   */
 +  public DataSource getSignedData()
 +  {
 +    return new DataSourceApiAdapter(this.signatureHolder.getDataSource());
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.commons.SignatureInformation#getInternalSignatureInformation()
 +   */
 +  public Object getInternalSignatureInformation()
 +  {
 +    return this.signatureHolder;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.commons.SignatureInformation#getSignatureType()
 +   */
 +  public String getSignatureType()
 +  {
 +    if (this.signatureHolder.getSignatureObject().isBinary())
 +    {
 +      return Constants.SIGNATURE_TYPE_BINARY;
 +    }
 +    return Constants.SIGNATURE_TYPE_TEXTUAL;
 +  }
 +
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.commons.SignatureInformation#getSignerCertificate()
 +   */
 +  public X509Certificate getSignerCertificate()
 +  {
 +    return this.signatureHolder.getSignatureObject().getX509Cert().getX509Certificate();
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.commons.SignatureInformation#getSigningTime()
 +   */
 +  public Date getSigningTime()
 +  {
 +    String date_value = this.signatureHolder.getSignatureObject().getSignationDate();
 +    Date date = EGIZDate.parseDateFromString(date_value);
 +    return date;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureProfileImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureProfileImpl.java new file mode 100644 index 0000000..0d2bfdd --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureProfileImpl.java @@ -0,0 +1,56 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api.commons;
 +
 +import at.gv.egiz.pdfas.api.commons.SignatureProfile;
 +
 +/**
 + * Holds the data of a signature profile.
 + * 
 + * @author wprinz
 + */
 +public class SignatureProfileImpl implements SignatureProfile
 +{
 +
 +  /**
 +   * The profile identifier.
 +   */
 +  protected String profileId = null;
 +
 +  /**
 +   * The MOA key identifiert of this profile.
 +   */
 +  protected String moaKeyIdentifier = null;
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param profileId
 +   *          The profile identifier.
 +   * @param moaKeyIdentifier
 +   *          The MOA key identifiert of this profile.
 +   */
 +  public SignatureProfileImpl(String profileId, String moaKeyIdentifier)
 +  {
 +    this.profileId = profileId;
 +    this.moaKeyIdentifier = moaKeyIdentifier;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.commons.SignatureProfile#getProfileId()
 +   */
 +  public String getProfileId()
 +  {
 +    return this.profileId;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.commons.SignatureProfile#getMOAKeyIdentifier()
 +   */
 +  public String getMOAKeyIdentifier()
 +  {
 +    return this.moaKeyIdentifier;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/commons/TextDataSourceAdapter.java b/src/main/java/at/gv/egiz/pdfas/impl/api/commons/TextDataSourceAdapter.java new file mode 100644 index 0000000..4b34d6f --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/commons/TextDataSourceAdapter.java @@ -0,0 +1,52 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api.commons;
 +
 +import java.io.UnsupportedEncodingException;
 +
 +import at.gv.egiz.pdfas.api.io.TextBased;
 +import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl;
 +
 +/**
 + * Adapter that converts an API DataSource to a framework TextDataSource.
 + * 
 + * @author wprinz
 + */
 +public class TextDataSourceAdapter extends TextDataSourceImpl
 +{
 +  /**
 +   * The API DataSource to be adapted to a framework TextDataSource.
 +   */
 +  protected at.gv.egiz.pdfas.api.io.DataSource apiDataSource = null;
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param apiDataSource
 +   *          The API DataSource to be adapted to a framework TextDataSource.
 +   * @throws UnsupportedEncodingException
 +   */
 +  public TextDataSourceAdapter(at.gv.egiz.pdfas.api.io.DataSource apiDataSource) throws UnsupportedEncodingException
 +  {
 +    super(null);
 +    this.apiDataSource = apiDataSource;
 +
 +    if (this.apiDataSource instanceof TextBased)
 +    {
 +      TextBased tb = (TextBased) this.apiDataSource;
 +      this.text = tb.getText();
 +    }
 +    else
 +    {
 +      byte[] data = this.apiDataSource.getAsByteArray();
 +      String characterEncoding = this.apiDataSource.getCharacterEncoding();
 +      if (characterEncoding == null)
 +      {
 +        throw new UnsupportedEncodingException("The characterEncoding must not be null. Specify a correct encoding.");
 +      }
 +      this.text = new String(data, characterEncoding);
 +    }
 +    assert this.text != null;
 +  }
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/sign/ActualSignaturePositionAdapter.java b/src/main/java/at/gv/egiz/pdfas/impl/api/sign/ActualSignaturePositionAdapter.java new file mode 100644 index 0000000..a0c32aa --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/sign/ActualSignaturePositionAdapter.java @@ -0,0 +1,73 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api.sign;
 +
 +import at.gv.egiz.pdfas.api.sign.pos.SignaturePosition;
 +import at.knowcenter.wag.egov.egiz.pdf.ActualTablePos;
 +
 +/**
 + * Adapter that converts from a framework ActualTablePos to an API
 + * ActualSignaturePosition.
 + * 
 + * @author wprinz
 + * 
 + */
 +public class ActualSignaturePositionAdapter implements SignaturePosition
 +{
 +  /**
 +   * The framework ActualTablePos.
 +   */
 +  protected ActualTablePos atp = null;
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param actualTablePos
 +   *          The framework ActualTablePos.
 +   */
 +  public ActualSignaturePositionAdapter(ActualTablePos actualTablePos)
 +  {
 +    this.atp = actualTablePos;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.sign.pos.SignaturePosition#getPage()
 +   */
 +  public int getPage()
 +  {
 +    return this.atp.page;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.sign.pos.SignaturePosition#getX()
 +   */
 +  public float getX()
 +  {
 +    return this.atp.x;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.sign.pos.SignaturePosition#getY()
 +   */
 +  public float getY()
 +  {
 +    return this.atp.y;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.sign.pos.SignaturePosition#getWidth()
 +   */
 +  public float getWidth()
 +  {
 +    return this.atp.width;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.sign.pos.SignaturePosition#getHeight()
 +   */
 +  public float getHeight()
 +  {
 +    return this.atp.height;
 +  }
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/sign/SignResultImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/api/sign/SignResultImpl.java new file mode 100644 index 0000000..7161f5b --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/sign/SignResultImpl.java @@ -0,0 +1,75 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api.sign;
 +
 +import java.security.cert.X509Certificate;
 +
 +import at.gv.egiz.pdfas.api.io.DataSink;
 +import at.gv.egiz.pdfas.api.sign.SignResult;
 +import at.gv.egiz.pdfas.api.sign.pos.SignaturePosition;
 +
 +/**
 + * Implementation of the SignResult interface.
 + * 
 + * @author wprinz
 + */
 +public class SignResultImpl implements SignResult
 +{
 +  /**
 +   * The filled output DataSink.
 +   */
 +  protected DataSink outputDocument = null;
 +
 +  /**
 +   * The signer certificate.
 +   */
 +  protected X509Certificate signerCertificate = null;
 +
 +  /**
 +   * The signature position.
 +   */
 +  protected SignaturePosition signaturePosition = null;
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param outputDocument
 +   *          The filled output DataSink.
 +   * @param signerCertificate
 +   *          The signer certificate.
 +   * @param signaturePosition
 +   *          The signature position.
 +   */
 +  public SignResultImpl(DataSink outputDocument, X509Certificate signerCertificate, SignaturePosition signaturePosition)
 +  {
 +    this.outputDocument = outputDocument;
 +    this.signerCertificate = signerCertificate;
 +    this.signaturePosition = signaturePosition;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.sign.SignResult#getOutputDocument()
 +   */
 +  public DataSink getOutputDocument()
 +  {
 +    return this.outputDocument;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.sign.SignResult#getSignaturePosition()
 +   */
 +  public SignaturePosition getSignaturePosition()
 +  {
 +    return this.signaturePosition;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.sign.SignResult#getSignerCertificate()
 +   */
 +  public X509Certificate getSignerCertificate()
 +  {
 +    return this.signerCertificate;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/verify/SignatureCheckImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/api/verify/SignatureCheckImpl.java new file mode 100644 index 0000000..d5803f8 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/verify/SignatureCheckImpl.java @@ -0,0 +1,51 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api.verify;
 +
 +import at.gv.egiz.pdfas.api.verify.SignatureCheck;
 +
 +/**
 + * @author wprinz
 + */
 +public class SignatureCheckImpl implements SignatureCheck
 +{
 +  /**
 +   * The check code.
 +   */
 +  protected int code = -1;
 +  
 +  /**
 +   * The check code message.
 +   */
 +  protected String message = null;
 +  
 +  
 +
 +  /**
 +   * @param code The check code.
 +   * @param message The check code message.
 +   */
 +  public SignatureCheckImpl(int code, String message)
 +  {
 +    this.code = code;
 +    this.message = message;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.verify.SignatureCheck#getCode()
 +   */
 +  public int getCode()
 +  {
 +    return this.code;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.verify.SignatureCheck#getMessage()
 +   */
 +  public String getMessage()
 +  {
 +    return this.message;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/verify/VerifyResultAdapter.java b/src/main/java/at/gv/egiz/pdfas/impl/api/verify/VerifyResultAdapter.java new file mode 100644 index 0000000..d66097a --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/verify/VerifyResultAdapter.java @@ -0,0 +1,126 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api.verify;
 +
 +import java.security.cert.X509Certificate;
 +import java.util.ArrayList;
 +import java.util.Date;
 +import java.util.List;
 +
 +import at.gv.egiz.pdfas.api.verify.SignatureCheck;
 +import at.gv.egiz.pdfas.api.verify.VerifyResult;
 +import at.gv.egiz.pdfas.impl.api.commons.SignatureInformationAdapter;
 +import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException;
 +import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder;
 +import at.knowcenter.wag.egov.egiz.sig.SignatureResponse;
 +
 +/**
 + * Implements the VerifyResult interface.
 + * 
 + * @author wprinz
 + */
 +public class VerifyResultAdapter extends SignatureInformationAdapter implements VerifyResult
 +{
 +  protected SignatureResponse sigRes = null;
 +
 +  protected Date vTime = null;
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param sigRes
 +   *          The SignatureResponse.
 +   * @param sh
 +   *          The SignatureHolder.
 +   * @param verificationTime
 +   *          The time of verification. This is directly returned by {@link #getVerificationTime()}
 +   */
 +  public VerifyResultAdapter(SignatureResponse sigRes, SignatureHolder sh, Date verificationTime)
 +  {
 +    super(sh);
 +    this.sigRes = sigRes;
 +    this.vTime = verificationTime;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.verify.VerifyResult#getCertificateCheck()
 +   */
 +  public SignatureCheck getCertificateCheck()
 +  {
 +    return new SignatureCheckImpl(Integer.parseInt(this.sigRes.getCertificateCheckCode()), this.sigRes.getCertificateCheckInfo());
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.verify.VerifyResult#getManifestCheckCode()
 +   */
 +  public SignatureCheck getManifestCheckCode()
 +  {
 +    return new SignatureCheckImpl(Integer.parseInt(this.sigRes.getSignatureManifestCheckCode()), this.sigRes.getSignatureManifestCheckInfo());
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.verify.VerifyResult#getValueCheckCode()
 +   */
 +  public SignatureCheck getValueCheckCode()
 +  {
 +    return new SignatureCheckImpl(Integer.parseInt(this.sigRes.getSignatureCheckCode()), this.sigRes.getSignatureCheckInfo());
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.verify.VerifyResult#getVerificationTime()
 +   */
 +  public Date getVerificationTime()
 +  {
 +    return this.vTime;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.verify.VerifyResult#isQualifiedCertificate()
 +   */
 +  public boolean isQualifiedCertificate()
 +  {
 +    return this.sigRes.isQualifiedCertificate();
 +  }
 +  
 +  /**
 +   * @see at.gv.egiz.pdfas.api.verify.VerifyResult#getPublicProperties()
 +   */
 +  public List getPublicProperties()
 +  {
 +    try
 +    {
 +      return this.sigRes.getPublicProperties();
 +    }
 +    catch (SettingNotFoundException e)
 +    {
 +      e.printStackTrace();
 +      return new ArrayList();
 +    }
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.commons.SignatureInformation#getInternalSignatureInformation()
 +   */
 +  public Object getInternalSignatureInformation()
 +  {
 +    return null;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.commons.SignatureInformation#getSignerCertificate()
 +   */
 +  public X509Certificate getSignerCertificate()
 +  {
 +    // TODO this should be the same as the signature holder's cert.
 +    return this.sigRes.getCertificate().getX509Certificate();
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.verify.VerifyResult#getHashInputData()
 +   */
 +  public String getHashInputData()
 +  {
 +    return this.sigRes.getHashInputData();
 +  }
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/verify/VerifyResultsImpl.java b/src/main/java/at/gv/egiz/pdfas/impl/api/verify/VerifyResultsImpl.java new file mode 100644 index 0000000..e7cc79d --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/verify/VerifyResultsImpl.java @@ -0,0 +1,38 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.impl.api.verify;
 +
 +import java.util.List;
 +
 +import at.gv.egiz.pdfas.api.verify.VerifyResults;
 +
 +/**
 + * @author wprinz
 + */
 +public class VerifyResultsImpl implements VerifyResults
 +{
 +  /**
 +   * The results.
 +   */
 +  protected List results = null;
 +
 +  /**
 +   * Constructor.
 +   * 
 +   * @param results
 +   *          The results.
 +   */
 +  public VerifyResultsImpl(List results)
 +  {
 +    this.results = results;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.verify.VerifyResults#getResults()
 +   */
 +  public List getResults()
 +  {
 +    return this.results;
 +  }
 +}
 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 index 138b269..2a3fedd 100644 --- 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 @@ -75,6 +75,17 @@ public class DataSourceHelper    {
      try
      {
 +      return convertInputStreamToByteArrayIOEx(inputStream);
 +    }
 +    catch (IOException e)
 +    {
 +      log.error(e);
 +      throw new RuntimeException(e);
 +    }
 +  }
 +  
 +  public static byte [] convertInputStreamToByteArrayIOEx(InputStream inputStream) throws IOException
 +  {
        PerformanceCounters.byteArrays.increment();
        ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
 @@ -92,12 +103,6 @@ public class DataSourceHelper        byte [] data = baos.toByteArray();
        return data;
 -    }
 -    catch (IOException e)
 -    {
 -      log.error(e);
 -      throw new RuntimeException(e);
 -    }
    }
    public static void debugDataSourceToFile(DataSource dataSource, File file)
 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 index a95cdc6..f308e30 100644 --- a/src/main/java/at/gv/egiz/pdfas/impl/signator/IncrementalUpdateHelper.java +++ b/src/main/java/at/gv/egiz/pdfas/impl/signator/IncrementalUpdateHelper.java @@ -32,14 +32,14 @@ public final class IncrementalUpdateHelper      return iui;
    }
 -  public static void writeIncrementalUpdateToDataSink(PdfDataSource pdfDataSource, DataSink dataSink, PdfPTable pdf_table, PositioningInstruction pi) throws PresentableException
 +  public static IncrementalUpdateInformation writeIncrementalUpdateToDataSink(PdfDataSource pdfDataSource, DataSink dataSink, PdfPTable pdf_table, PositioningInstruction pi) throws PresentableException
    {
 -    writeIncrementalUpdateToDataSink(pdfDataSource, dataSink, pdf_table, pi, null, null);
 +    return 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,
 +  public static IncrementalUpdateInformation 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);
 +    return 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/binary/BinarySignatorInformation.java b/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignatorInformation.java index 916abf4..0ed3699 100644 --- 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 @@ -5,6 +5,7 @@ package at.gv.egiz.pdfas.impl.signator.binary;  import java.util.List;
 +import at.knowcenter.wag.egov.egiz.pdf.ActualTablePos;
  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;
 @@ -31,6 +32,8 @@ public class BinarySignatorInformation implements SignatorInformation    protected int enc_length = -1;
    protected SignSignatureObject signSignatureObject = null;
 +  
 +  protected ActualTablePos atp = null;
    /**
     * @see at.gv.egiz.pdfas.framework.signator.SignatorInformation#getSignatureData()
 @@ -48,4 +51,20 @@ public class BinarySignatorInformation implements SignatorInformation      this.signSignatureObject = signSignatureObject;
    }
 +  /**
 +   * @see at.gv.egiz.pdfas.framework.signator.SignatorInformation#getSignSignatureObject()
 +   */
 +  public SignSignatureObject getSignSignatureObject()
 +  {
 +    return this.signSignatureObject;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.framework.signator.SignatorInformation#getActualTablePos()
 +   */
 +  public ActualTablePos getActualTablePos()
 +  {
 +    return this.atp;
 +  }
 +
  }
 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 index b1f1cea..73d4866 100644 --- 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 @@ -296,6 +296,7 @@ public class BinarySignator_1_0_0 implements Signator      bsi.cert_length = iui.cert_length;
      bsi.enc_start = iui.enc_start;
      bsi.enc_length = iui.enc_length;
 +    bsi.atp = iui.actualTablePos;
      return bsi;
    }
 @@ -312,6 +313,7 @@ public class BinarySignator_1_0_0 implements Signator      iui.cert_length = bsi.cert_length;
      iui.enc_start = bsi.enc_start;
      iui.enc_length = bsi.enc_length;
 +    iui.actualTablePos = bsi.atp;
      iui.signed_signature_object = bsi.signSignatureObject;
 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 index c5b18ff..9e5ebb6 100644 --- 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 @@ -3,6 +3,7 @@   */
  package at.gv.egiz.pdfas.impl.signator.textual;
 +import at.knowcenter.wag.egov.egiz.pdf.ActualTablePos;
  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;
 @@ -24,6 +25,8 @@ public class TextualSignatorInformation implements SignatorInformation    protected TablePos pos = null;
    public SignSignatureObject signSignatureObject = null;
 +  
 +  protected ActualTablePos atp = null;
    /**
     * @see at.gv.egiz.pdfas.framework.signator.SignatorInformation#getSignatureData()
 @@ -34,7 +37,6 @@ public class TextualSignatorInformation implements SignatorInformation    }
    /**
 -   * 
     * @see at.gv.egiz.pdfas.framework.signator.SignatorInformation#setSignSignatureObject(at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject)
     */
    public void setSignSignatureObject(SignSignatureObject signSignatureObject)
 @@ -42,4 +44,19 @@ public class TextualSignatorInformation implements SignatorInformation      this.signSignatureObject = signSignatureObject;
    }
 +  /**
 +   * @see at.gv.egiz.pdfas.framework.signator.SignatorInformation#getSignSignatureObject()
 +   */
 +  public SignSignatureObject getSignSignatureObject()
 +  {
 +    return this.signSignatureObject;
 +  }
 +  
 +  /**
 +   * @see at.gv.egiz.pdfas.framework.signator.SignatorInformation#getActualTablePos()
 +   */
 +  public ActualTablePos getActualTablePos()
 +  {
 +    return this.atp;
 +  }
  }
 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 index 1714afc..b49803c 100644 --- 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 @@ -29,6 +29,7 @@ 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.IncrementalUpdateInformation;
  import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
  import at.knowcenter.wag.egov.egiz.pdf.TablePos;
  import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl;
 @@ -127,7 +128,8 @@ public class TextualSignator_1_0_0 implements Signator        PositioningInstruction pi = PdfAS.determineTablePositioning(tsi.pos, tsi.profile, tsi.originalDocument, pdf_table);
 -      IncrementalUpdateHelper.writeIncrementalUpdateToDataSink(tsi.originalDocument, dataSink, pdf_table, pi);
 +      IncrementalUpdateInformation iui = IncrementalUpdateHelper.writeIncrementalUpdateToDataSink(tsi.originalDocument, dataSink, pdf_table, pi);
 +      tsi.atp = iui.actualTablePos;
  //      OutputStream os = dataSink.createOutputStream(PdfAS.PDF_MIME_TYPE);
  //      os.write(signed_iui.signed_pdf);
 diff --git a/src/main/java/at/gv/egiz/pdfas/io/ByteArrayDataSink.java b/src/main/java/at/gv/egiz/pdfas/io/ByteArrayDataSink.java new file mode 100644 index 0000000..bf74ed5 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/io/ByteArrayDataSink.java @@ -0,0 +1,87 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.io;
 +
 +import java.io.ByteArrayOutputStream;
 +import java.io.IOException;
 +import java.io.OutputStream;
 +
 +import at.gv.egiz.pdfas.api.io.DataSink;
 +
 +/**
 + * @author wprinz
 + * 
 + */
 +public class ByteArrayDataSink implements DataSink
 +{
 +  /**
 +   * The byte output stream.
 +   */
 +  ByteArrayOutputStream baos = null;
 +
 +  /**
 +   * The mime type.
 +   */
 +  protected String mimeType = null;
 +
 +  /**
 +   * The character encoding.
 +   */
 +  protected String characterEncoding = null;
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSink#createOutputStream(java.lang.String)
 +   */
 +  public OutputStream createOutputStream(String mimeType) throws IOException
 +  {
 +    return createOutputStream(mimeType, null);
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSink#createOutputStream(java.lang.String,
 +   *      java.lang.String)
 +   */
 +  public OutputStream createOutputStream(String mimeType, String characterEncoding) throws IOException
 +  {
 +    this.mimeType = mimeType;
 +    this.characterEncoding = characterEncoding;
 +    this.baos = new ByteArrayOutputStream();
 +    return this.baos;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSink#getMimeType()
 +   */
 +  public String getMimeType()
 +  {
 +    return this.mimeType;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSink#getCharacterEncoding()
 +   */
 +  public String getCharacterEncoding()
 +  {
 +    return this.characterEncoding;
 +  }
 +
 +  /**
 +   * Returns the byte data, or null if none available.
 +   * 
 +   * <p>
 +   * Note that internally, this just calls the {@link ByteArrayOutputStream#toByteArray()} method.
 +   * </p>
 +   * 
 +   * @return Returns the byte data, or null if none available.
 +   */
 +  public byte [] getData()
 +  {
 +    if (this.baos == null)
 +    {
 +      return null;
 +    }
 +    return this.baos.toByteArray();
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/io/ByteArrayDataSource.java b/src/main/java/at/gv/egiz/pdfas/io/ByteArrayDataSource.java new file mode 100644 index 0000000..37726df --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/io/ByteArrayDataSource.java @@ -0,0 +1,95 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.io;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.InputStream;
 +
 +import at.gv.egiz.pdfas.api.io.DataSource;
 +
 +/**
 + * A byte array backed DataSource.
 + * 
 + * @author wprinz
 + */
 +public class ByteArrayDataSource implements DataSource
 +{
 +
 +  /**
 +   * The byte array.
 +   */
 +  protected byte[] data = null;
 +
 +  /**
 +   * The mime type.
 +   */
 +  protected String mimeType = null;
 +
 +  /**
 +   * The character encoding.
 +   */
 +  protected String characterEncoding = null;
 +
 +  /**
 +   * @param data
 +   * @param mimeType
 +   */
 +  public ByteArrayDataSource(byte[] data, String mimeType)
 +  {
 +    this(data, mimeType, null);
 +  }
 +
 +  /**
 +   * @param data
 +   * @param mimeType
 +   * @param characterEncoding
 +   */
 +  public ByteArrayDataSource(byte[] data, String mimeType, String characterEncoding)
 +  {
 +    this.data = data;
 +    this.mimeType = mimeType;
 +    this.characterEncoding = characterEncoding;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#createInputStream()
 +   */
 +  public InputStream createInputStream()
 +  {
 +    return new ByteArrayInputStream(this.data);
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getAsByteArray()
 +   */
 +  public byte[] getAsByteArray()
 +  {
 +    return this.data;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getCharacterEncoding()
 +   */
 +  public String getCharacterEncoding()
 +  {
 +    return this.characterEncoding;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getMimeType()
 +   */
 +  public String getMimeType()
 +  {
 +    return this.mimeType;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getLength()
 +   */
 +  public int getLength()
 +  {
 +    return this.data.length;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/io/FileBasedDataSink.java b/src/main/java/at/gv/egiz/pdfas/io/FileBasedDataSink.java new file mode 100644 index 0000000..184dd09 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/io/FileBasedDataSink.java @@ -0,0 +1,96 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.io;
 +
 +import java.io.File;
 +import java.io.FileNotFoundException;
 +import java.io.FileOutputStream;
 +import java.io.IOException;
 +import java.io.OutputStream;
 +
 +import at.gv.egiz.pdfas.api.io.DataSink;
 +import at.gv.egiz.pdfas.api.io.FileBased;
 +
 +/**
 + * @author wprinz
 + * 
 + */
 +public class FileBasedDataSink implements DataSink, FileBased
 +{
 +  protected File file = null;
 +
 +  protected String mimeType = null;
 +
 +  protected String characterEncoding = null;
 +
 +  
 +  
 +  /**
 +   * @param file
 +   * @throws IOException 
 +   */
 +  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.file = file;
 +  }
 +
 +  /**
 +   * @throws FileNotFoundException
 +   * @see at.gv.egiz.pdfas.api.io.DataSink#createOutputStream(java.lang.String)
 +   */
 +  public OutputStream createOutputStream(String mimeType) throws FileNotFoundException
 +  {
 +    return createOutputStream(mimeType, null);
 +  }
 +
 +  /**
 +   * @throws FileNotFoundException
 +   * @see at.gv.egiz.pdfas.api.io.DataSink#createOutputStream(java.lang.String,
 +   *      java.lang.String)
 +   */
 +  public OutputStream createOutputStream(String mimeType, String characterEncoding) throws FileNotFoundException
 +  {
 +    this.mimeType = mimeType;
 +    this.characterEncoding = characterEncoding;
 +    return new FileOutputStream(this.file);
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSink#getMimeType()
 +   */
 +  public String getMimeType()
 +  {
 +    return this.mimeType;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSink#getCharacterEncoding()
 +   */
 +  public String getCharacterEncoding()
 +  {
 +    return this.characterEncoding;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.FileBased#getFile()
 +   */
 +  public File getFile()
 +  {
 +    return this.file;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/io/FileBasedDataSource.java b/src/main/java/at/gv/egiz/pdfas/io/FileBasedDataSource.java new file mode 100644 index 0000000..fd56bfe --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/io/FileBasedDataSource.java @@ -0,0 +1,121 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.io;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.File;
 +import java.io.FileInputStream;
 +import java.io.FileNotFoundException;
 +import java.io.IOException;
 +import java.io.InputStream;
 +
 +import at.gv.egiz.pdfas.api.io.DataSource;
 +import at.gv.egiz.pdfas.api.io.FileBased;
 +import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper;
 +
 +/**
 + * A FileBased DataSource implementation.
 + * 
 + * @author wprinz
 + */
 +public class FileBasedDataSource implements DataSource, FileBased
 +{
 +  protected File file = null;
 +
 +  protected String mimeType = null;
 +
 +  protected String characterEncoding = null;
 +
 +  protected byte[] cache = null;
 +
 +  /**
 +   * @param file
 +   * @param mimeType
 +   * @throws IOException
 +   */
 +  public FileBasedDataSource(File file, String mimeType) throws IOException
 +  {
 +    this(file, mimeType, null);
 +  }
 +
 +  /**
 +   * @param file
 +   * @param mimeType
 +   * @param characterEncoding
 +   * @throws IOException
 +   */
 +  public FileBasedDataSource(File file, String mimeType, String characterEncoding) throws IOException
 +  {
 +    if (file == null)
 +    {
 +      throw new IllegalArgumentException("The file must not be null.");
 +    }
 +    if (mimeType == null)
 +    {
 +      throw new IllegalArgumentException("The mimeType must not be null.");
 +    }
 +    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.mimeType = mimeType;
 +    this.characterEncoding = characterEncoding;
 +    this.cache = DataSourceHelper.convertInputStreamToByteArrayIOEx(new FileInputStream(this.file));
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#createInputStream()
 +   */
 +  public InputStream createInputStream()
 +  {
 +    return new ByteArrayInputStream(this.cache);
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getAsByteArray()
 +   */
 +  public byte[] getAsByteArray()
 +  {
 +    return this.cache;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getLength()
 +   */
 +  public int getLength()
 +  {
 +    return this.cache.length;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getMimeType()
 +   */
 +  public String getMimeType()
 +  {
 +    return this.mimeType;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getCharacterEncoding()
 +   */
 +  public String getCharacterEncoding()
 +  {
 +    return this.characterEncoding;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.FileBased#getFile()
 +   */
 +  public File getFile()
 +  {
 +    return this.file;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/io/FileBasedTextBasedDataSource.java b/src/main/java/at/gv/egiz/pdfas/io/FileBasedTextBasedDataSource.java new file mode 100644 index 0000000..5be2148 --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/io/FileBasedTextBasedDataSource.java @@ -0,0 +1,103 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.io;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.File;
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.io.UnsupportedEncodingException;
 +
 +import at.gv.egiz.pdfas.api.io.TextBased;
 +
 +/**
 + * FileBased DataSource that is TextBased.
 + * 
 + * @author wprinz
 + */
 +public class FileBasedTextBasedDataSource extends FileBasedDataSource implements TextBased
 +{
 +  protected String text = null;
 +
 +  /**
 +   * @param file
 +   * @param mimeType
 +   * @param characterEncoding
 +   * @throws IOException
 +   */
 +  public FileBasedTextBasedDataSource(File file, String mimeType, String characterEncoding) throws IOException
 +  {
 +    super(file, mimeType, characterEncoding);
 +    if (characterEncoding == null)
 +    {
 +      throw new IllegalArgumentException("The characterEncoding must not be null.");
 +    }
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#createInputStream()
 +   */
 +  public InputStream createInputStream()
 +  {
 +    return new ByteArrayInputStream(this.cache);
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getAsByteArray()
 +   */
 +  public byte[] getAsByteArray()
 +  {
 +    return this.cache;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getLength()
 +   */
 +  public int getLength()
 +  {
 +    return this.cache.length;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getMimeType()
 +   */
 +  public String getMimeType()
 +  {
 +    return this.mimeType;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getCharacterEncoding()
 +   */
 +  public String getCharacterEncoding()
 +  {
 +    return this.characterEncoding;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.FileBased#getFile()
 +   */
 +  public File getFile()
 +  {
 +    return this.file;
 +  }
 +
 +  public String getText()
 +  {
 +    if (this.text == null)
 +    {
 +      try
 +      {
 +        this.text = new String(this.cache, this.characterEncoding);
 +      }
 +      catch (UnsupportedEncodingException e)
 +      {
 +        e.printStackTrace();
 +        throw new RuntimeException(e);
 +      }
 +    }
 +    return this.text;
 +  }
 +
 +}
 diff --git a/src/main/java/at/gv/egiz/pdfas/io/StringTextBasedDataSource.java b/src/main/java/at/gv/egiz/pdfas/io/StringTextBasedDataSource.java new file mode 100644 index 0000000..d8b879f --- /dev/null +++ b/src/main/java/at/gv/egiz/pdfas/io/StringTextBasedDataSource.java @@ -0,0 +1,96 @@ +/**
 + * 
 + */
 +package at.gv.egiz.pdfas.io;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.InputStream;
 +import java.io.UnsupportedEncodingException;
 +
 +import at.gv.egiz.pdfas.api.io.DataSource;
 +import at.gv.egiz.pdfas.api.io.TextBased;
 +
 +/**
 + * A String TextBased DataSource.
 + * 
 + * @author wprinz
 + * 
 + */
 +public class StringTextBasedDataSource implements DataSource, TextBased
 +{
 +  /**
 +   * The text.
 +   */
 +  protected String text = null;
 +
 +  protected byte[] cache = null;
 +
 +  /**
 +   * @param text
 +   */
 +  public StringTextBasedDataSource(String text)
 +  {
 +    this.text = text;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#createInputStream()
 +   */
 +  public InputStream createInputStream()
 +  {
 +    return new ByteArrayInputStream(getAsByteArray());
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getAsByteArray()
 +   */
 +  public byte[] getAsByteArray()
 +  {
 +    if (cache == null)
 +    {
 +      try
 +      {
 +        this.cache = this.text.getBytes("UTF-8");
 +      }
 +      catch (UnsupportedEncodingException e)
 +      {
 +        e.printStackTrace();
 +        throw new RuntimeException(e);
 +      }
 +    }
 +    return this.cache;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getLength()
 +   */
 +  public int getLength()
 +  {
 +    return getAsByteArray().length;
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getMimeType()
 +   */
 +  public String getMimeType()
 +  {
 +    return "text/plain";
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.DataSource#getCharacterEncoding()
 +   */
 +  public String getCharacterEncoding()
 +  {
 +    return "UTF-8";
 +  }
 +
 +  /**
 +   * @see at.gv.egiz.pdfas.api.io.TextBased#getText()
 +   */
 +  public String getText()
 +  {
 +    return this.text;
 +  }
 +
 +}
 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 6fc7b84..9aef071 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java @@ -17,31 +17,27 @@   */
  package at.knowcenter.wag.egov.egiz;
 -import java.io.ByteArrayInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Comparator;
 +import java.util.Date;
  import java.util.List;
  import java.util.Vector;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +
  import at.gv.egiz.pdfas.commandline.CommandlineConnectorChooser;
  import at.gv.egiz.pdfas.exceptions.ErrorCode;
 -import at.gv.egiz.pdfas.impl.input.ByteArrayPdfDataSourceImpl;
 -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.ConnectorParameters;
  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.impl.input.ByteArrayPdfDataSourceImpl;
 +import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper;
  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;
 @@ -62,7 +58,6 @@ import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder;  import at.knowcenter.wag.egov.egiz.pdf.TablePos;
  import at.knowcenter.wag.egov.egiz.pdf.TextualSignature;
  import at.knowcenter.wag.egov.egiz.pdf.TextualSignatureHolder;
 -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.SignatureObject;
 @@ -740,7 +735,7 @@ public abstract class PdfAS      return true;
    }
 -  public static List verifySignatureHolders(List signature_holders, String connectorType) throws PDFDocumentException, NormalizeException, SignatureException, ConnectorException, ConnectorFactoryException
 +  public static List verifySignatureHolders(List signature_holders, String connectorType, boolean returnHashInputData, Date verificationTime) throws PDFDocumentException, NormalizeException, SignatureException, ConnectorException, ConnectorFactoryException
    {
      List results = new ArrayList();
      for (int i = 0; i < signature_holders.size(); i++)
 @@ -757,7 +752,7 @@ public abstract class PdfAS        // (holder.signature_object.isTextual() ? "textual" : "binary"));
        // logger_.debug(holder.signature_object.toString());
 -      SignatureResponse result = verify(holder, connectorType);
 +      SignatureResponse result = verify(holder, connectorType, returnHashInputData, verificationTime);
        results.add(result);
        // logger_.debug();
 @@ -809,7 +804,7 @@ public abstract class PdfAS     * @throws ConnectorException 
     * @throws ConnectorFactoryException 
     */
 -  public static SignatureResponse verify(SignatureHolder signature_holder, String connectorType) throws NormalizeException, PDFDocumentException, SignatureException, ConnectorException, ConnectorFactoryException
 +  public static SignatureResponse verify(SignatureHolder signature_holder, String connectorType, boolean returnHashInputData, Date verificationTime) throws NormalizeException, PDFDocumentException, SignatureException, ConnectorException, ConnectorFactoryException
    {
      // String text_to_be_verified = signature_holder.getSignedText();
      // logger_.debug("verify text_to_be_verified"+text_to_be_verified);
 @@ -844,10 +839,14 @@ public abstract class PdfAS      String profile = so_to_be_verified.getSignatureTypeDefinition().getType();
  //    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);
 +    
 +    ConnectorParameters cp = new ConnectorParameters();
 +    cp.setProfileId(profile);
 +    cp.setReturnHashInputData(returnHashInputData);
 +    cp.setVerificationTime(verificationTime);
 +    Connector c = at.gv.egiz.pdfas.framework.ConnectorFactory.createConnector(connectorId, cp);
      return c.doVerify(sd, so);
 -
    }
    public static SignatureResponse verifyWeb(SignatureHolder signature_holder, String connector, String loc_ref) throws NormalizeException, PDFDocumentException, SignatureException, ConnectorException
 @@ -992,11 +991,13 @@ public abstract class PdfAS  //    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
 +  public static SignatorInformation signCommandline(PdfDataSource pdfDataSource, DataSink dataSink, PdfASID signatorId, String connectorId, final String profile, TablePos pos) throws PresentableException
    {
      at.gv.egiz.pdfas.framework.signator.Signator signator = at.gv.egiz.pdfas.framework.SignatorFactory.createSignator(signatorId);
 -    Connector c = at.gv.egiz.pdfas.framework.ConnectorFactory.createConnector(connectorId, profile, null);
 +    ConnectorParameters cp = new ConnectorParameters();
 +    cp.setProfileId(profile);
 +    Connector c = at.gv.egiz.pdfas.framework.ConnectorFactory.createConnector(connectorId, cp);
      // SignatorInformation si = signator.prepareSign(pdfDataSource, profile, pos, ConnectorFactory.needsSIG_ID(connector));
      SignatorInformation si = signator.prepareSign(pdfDataSource, profile, pos, CommandlineConnectorChooser.needsSigId(connectorId));
 @@ -1006,6 +1007,8 @@ public abstract class PdfAS      si.setSignSignatureObject(sso);
      signator.finishSign(si, dataSink);
 +    
 +    return si;
    }
    /**
 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 97929af..054da24 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 @@ -344,6 +344,21 @@ public class SettingsReader implements Serializable    {
      return getInstance(null);
    }
 +  
 +  /**
 +   * Reloads the Settings file.
 +   * 
 +   * <p>
 +   * Subsequent calls to getInstance will return the new settings.
 +   * </p>
 +   * 
 +   * @throws SettingsException f.e.
 +   */
 +  public synchronized static void createInstance () throws SettingsException
 +  {
 +    instance_ = null;
 +    getInstance();
 +  }
    /**
     * This method returns an synchronized instance of this class. The settings
 @@ -663,6 +678,13 @@ public class SettingsReader implements Serializable      }
    }
 +  public static void initialize(String base_dir)
 +  {
 +    RESOURCES_PATH = base_dir + FILE_SEP; //CATALINA_HOME + FILE_SEP + WEB_APPL_DIR;
 +    CONFIG_PATH = RESOURCES_PATH + CFG + FILE_SEP;
 +    CERT_PATH = RESOURCES_PATH + CERT + FILE_SEP;
 +  }
 +  
    /**
     * Initializes the paths of the SettingsReader for web application usage.
     * 
 @@ -672,9 +694,10 @@ public class SettingsReader implements Serializable     */
    public static void initializeForWeb(String base_dir)
    {
 -    RESOURCES_PATH = base_dir + FILE_SEP; //CATALINA_HOME + FILE_SEP + WEB_APPL_DIR;
 -    CONFIG_PATH = RESOURCES_PATH + CFG + FILE_SEP;
 -    CERT_PATH = RESOURCES_PATH + CERT + FILE_SEP;
 +    initialize(base_dir);
 +//    RESOURCES_PATH = base_dir + FILE_SEP; //CATALINA_HOME + FILE_SEP + WEB_APPL_DIR;
 +//    CONFIG_PATH = RESOURCES_PATH + CFG + FILE_SEP;
 +//    CERT_PATH = RESOURCES_PATH + CERT + FILE_SEP;
    }
    /**
 @@ -682,9 +705,10 @@ public class SettingsReader implements Serializable     */
    public static void initializeForCommandLine()
    {
 -    RESOURCES_PATH = USER_DIR + FILE_SEP;
 -    CONFIG_PATH = RESOURCES_PATH + CFG + FILE_SEP;
 -    CERT_PATH = RESOURCES_PATH + CERT + FILE_SEP;
 +    initialize(USER_DIR);
 +//    RESOURCES_PATH = USER_DIR + FILE_SEP;
 +//    CONFIG_PATH = RESOURCES_PATH + CFG + FILE_SEP;
 +//    CERT_PATH = RESOURCES_PATH + CERT + FILE_SEP;
    }
    static {
 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 72565d9..11bd0e0 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 @@ -156,6 +156,8 @@ public abstract class Main     * @param args
     *          The commandline arguments.
     * @throws IOException
 +   * 
 +   * @deprecated use {@link at.gv.egiz.pdfas.commandline.Main} instead
     */
    public static void main(String[] args) throws IOException
    {
 @@ -639,7 +641,7 @@ public abstract class Main        holders_to_verify.add(holder);
      }
 -    List results = PdfAS.verifySignatureHolders(holders_to_verify, connector);
 +    List results = PdfAS.verifySignatureHolders(holders_to_verify, connector, false, null);
      return results;
    }
 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 218109d..e8ef988 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 @@ -17,6 +17,8 @@   */
  package at.knowcenter.wag.egov.egiz.exceptions;
 +import at.gv.egiz.pdfas.api.exceptions.PdfAsException;
 +
  /**
   * This exception should be the base for all exceptions that are to be presented
   * to the user.
 @@ -27,56 +29,32 @@ package at.knowcenter.wag.egov.egiz.exceptions;   * can present according texts.
   * </p>
   * 
 + * @see PdfAsException
 + * 
   * @author wprinz
   */
 -public class PresentableException extends Exception
 +public class PresentableException extends PdfAsException
  {
    /**
     * SVUID.
     */
    private static final long serialVersionUID = -102406558526000792L;
 -  
 -  protected int errorCode = -1;
 -  /**
 -   * @param message
 -   */
 -  public PresentableException(int errorCode, String message)
 +  public PresentableException(int errorCode, String message, Throwable cause)
    {
 -    super(message);
 -    
 -    this.errorCode = errorCode;
 +    super(errorCode, message, cause);
    }
 -  /**
 -   * @param message
 -   * @param cause
 -   */
 -  public PresentableException(int errorCode, String message, Throwable cause)
 +  public PresentableException(int errorCode, String message)
    {
 -    super(message, cause);
 -    
 -    this.errorCode = errorCode;
 +    super(errorCode, message);
    }
 -  /**
 -   * @param cause
 -   */
    public PresentableException(int errorCode, Throwable cause)
    {
 -    super(cause);
 -    
 -    this.errorCode = errorCode;
 +    super(errorCode, cause);
    }
 -  /**
 -   * 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/pdf/AbsoluteTextSignature.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java index 4219475..4b9a2aa 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 @@ -537,6 +537,14 @@ public class AbsoluteTextSignature    {
      int block_start_index = ((FoundKey) block.found_keys.get(0)).getStartIndex();
      int block_end_index = block.end_index;
 +    
 +    if (block_start_index == 0 && block_end_index == text.length())
 +    {
 +      // the block is the whole text - the rest text is empty.
 +      // This may happen if a (no-text) empty document contains a binary signature.
 +      // Then the "signed text" of the binary signature is empty.
 +      return "";
 +    }
      if (block_end_index == text.length())
      {
 diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/ActualTablePos.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/ActualTablePos.java new file mode 100644 index 0000000..f58e9f8 --- /dev/null +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/ActualTablePos.java @@ -0,0 +1,22 @@ +/**
 + * 
 + */
 +package at.knowcenter.wag.egov.egiz.pdf;
 +
 +/**
 + * The actual table position where the signature was placed after signation.
 + * @author wprinz
 + */
 +public class ActualTablePos
 +{
 +  public int page;
 +  
 +  public float x;
 +  
 +  public float y;
 +  
 +  public float width;
 +  
 +  public float height;
 +
 +}
 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 677990b..7a5af6b 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 @@ -737,6 +737,14 @@ public abstract class BinarySignature        // table_position, content);
        content.addTemplate(table_template, pi.getX(), pi.getY() - pdf_table.getTotalHeight());
 +      
 +      ActualTablePos atp = new ActualTablePos();
 +      atp.page = pi.getPage();
 +      atp.x = pi.getX();
 +      atp.y = pi.getY(); // TODO is this correct or flipped?
 +      atp.width = pdf_table.getTotalWidth();
 +      atp.height = pdf_table.getTotalHeight();
 +      iui.actualTablePos = atp;
        // For debugging print a 100x100 grid
        // {
 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 f818f59..77f1150 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 @@ -172,5 +172,10 @@ public class IncrementalUpdateInformation implements Serializable     * For signing: the profile.
     */
    public String signProfile;
 +  
 +  /**
 +   * The actual position where the table was written.
 +   */
 +  public ActualTablePos actualTablePos;
  }
 diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureResponse.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureResponse.java index 603e0fe..deedb6d 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureResponse.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureResponse.java @@ -102,6 +102,8 @@ public class SignatureResponse    private boolean qualifiedCertificate = false;
    // [tknall] stop qualified certificate
 +  protected String hashInputData = null;
 +  
    // /**
    // * Flag the marks that the response is an error response
    // */
 @@ -423,6 +425,16 @@ public class SignatureResponse      this.certificate_ = certificate;
    }
 +  public String getHashInputData()
 +  {
 +    return this.hashInputData;
 +  }
 +
 +  public void setHashInputData(String hashInputData)
 +  {
 +    this.hashInputData = hashInputData;
 +  }
 +
    /**
     * Returns a list of Strings each stating one public property of the
     * certificate.
 diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureTypes.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureTypes.java index 19b28e7..13fdf2f 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureTypes.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureTypes.java @@ -319,6 +319,16 @@ public class SignatureTypes      }
      return instance_;
    }
 +  
 +  /**
 +   * Reloads the instance.
 +   * @throws SignatureTypesException
 +   */
 +  public static void createInstance() throws SignatureTypesException
 +  {
 +    instance_ = null;
 +    getInstance();
 +  }
    /**
     * This method load the signature definitions
 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 5b16211..cbdee42 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 @@ -6,6 +6,7 @@ package at.knowcenter.wag.egov.egiz.sig.connectors;  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
 +import at.gv.egiz.pdfas.framework.ConnectorParameters;
  import at.knowcenter.wag.egov.egiz.PdfASID;
  import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException;
  import at.knowcenter.wag.egov.egiz.framework.SignatorFactory;
 @@ -46,7 +47,9 @@ public final class ConnectorChooser      }
      log.debug("choosing locref detached BKU connector.");
 -    return new LocRefDetachedBKUConnector(profile, loc_ref_url);
 +    ConnectorParameters cp = new ConnectorParameters();
 +    cp.setProfileId(profile);
 +    return new LocRefDetachedBKUConnector(cp, loc_ref_url);
    }
    public static Connector chooseWebConnectorForSign(String connector,
 @@ -67,7 +70,9 @@ public final class ConnectorChooser      // Loc_Ref-Connector
  //    return new DetachedLocRefMOAConnector(profile, loc_ref_url);
      // SwA-Connector
 -    return new MOASoapWithAttachmentConnector(profile);
 +    ConnectorParameters cp = new ConnectorParameters();
 +    cp.setProfileId(profile);
 +    return new MOASoapWithAttachmentConnector(cp);
    }
  //  public static Connector chooseCommandlineConnectorForSign(String connector,
 @@ -147,7 +152,9 @@ public final class ConnectorChooser      {
        log.debug("sig_kz version is 1.1.0 -> choosing detached (loc ref) connector.");
 -      return new LocRefDetachedBKUConnector(profile, loc_ref_url);
 +      ConnectorParameters cp = new ConnectorParameters();
 +      cp.setProfileId(profile);
 +      return new LocRefDetachedBKUConnector(cp, loc_ref_url);
      }
      throw new ConnectorException(310, "The SIG_KZ version '" + sig_kz.getVersion() + "' is unknown.");
 @@ -183,7 +190,9 @@ public final class ConnectorChooser        // the following line is used in connection with LocRef-Connector
  //      return new DetachedLocRefMOAConnector(profile, loc_ref_url);
        // the following line is uesed in connection with SwA-Connector
 -      return new MOASoapWithAttachmentConnector(profile);
 +      ConnectorParameters cp = new ConnectorParameters();
 +      cp.setProfileId(profile);
 +      return new MOASoapWithAttachmentConnector(cp);
      }
      throw new ConnectorException(310, "The SIG_KZ version '" + sig_kz.getVersion() + "' is unknown.");
 @@ -293,7 +302,9 @@ public final class ConnectorChooser      {
        log.debug("sig_app is BKU ==> DetachedMultipartBKUConnector"); //$NON-NLS-1$
 -      return new MultipartDetachedBKUConnector(profile);
 +      ConnectorParameters cp = new ConnectorParameters();
 +      cp.setProfileId(profile);
 +      return new MultipartDetachedBKUConnector(cp);
      }
      if (sig_app.equals(MOA))
      {
 diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/TemplateReplaces.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/TemplateReplaces.java index 18cf76d..149065c 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/TemplateReplaces.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/TemplateReplaces.java @@ -117,6 +117,16 @@ public final class TemplateReplaces     * The placeholder text in the template to be replaced by the trust profile ID.
     */
    public static final String TRUST_PROFILE_ID_REPLACE = "TrustProfileIDReplace"; //$NON-NLS-1$
 +
 +  /**
 +   * The placeholder text in the template to be replaced by the return hash input data element.
 +   */
 +  public static final String RETURN_HASH_INPUT_DATA_REPLACE = "ReturnHashInputDataReplace"; //$NON-NLS-1$
 +
 +  /**
 +   * The placeholder text in the template to be replaced by the dateTime element.
 +   */
 +  public static final String DATE_TIME_REPLACE = "DateTimeReplace"; // $NON-NLS-1$
    /**
     * The placeholder text in the template to be replaced by the Base64 content.
 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 8f0b79e..1ddd327 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 @@ -7,12 +7,17 @@ import java.io.UnsupportedEncodingException;  import java.security.cert.CertificateException;
  import java.security.cert.CertificateFactory;
  import java.security.cert.X509Certificate;
 +import java.text.DateFormat;
 +import java.text.SimpleDateFormat;
 +import java.util.Date;
 +import java.util.TimeZone;
  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.lang.StringUtils;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
 @@ -421,12 +426,35 @@ public final class BKUHelper      Matcher cert_m_s = cert_p_s.matcher(xmlResponse);
      Matcher cert_m_e = cert_p_e.matcher(xmlResponse);
 +    Pattern hash_data_p_s = Pattern.compile("<HashInputData PartOf=\"SignedInfo\">"); //$NON-NLS-1$
 +    Pattern hash_data_p_e = Pattern.compile("</HashInputData>"); //$NON-NLS-1$
 +    Matcher hash_data_m_s = hash_data_p_s.matcher(xmlResponse);
 +    Matcher hash_data_m_e = hash_data_p_e.matcher(xmlResponse);
 +
 +
      SignatureResponse sig_res = new SignatureResponse();
      // [tknall] start qualified certificate
      sig_res.setQualifiedCertificate(cert_qualified_m.find());
      // [tknall] stop qualified certificate
 +    if (hash_data_m_s.find() && hash_data_m_e.find())
 +    {
 +      String hashInputData = xmlResponse.substring(hash_data_m_s.end(), hash_data_m_e.start());
 +      
 +      Pattern b64_p_s = Pattern.compile("<Base64Content>"); //$NON-NLS-1$
 +      Pattern b64_p_e = Pattern.compile("</Base64Content>"); //$NON-NLS-1$
 +      Matcher b64_m_s = b64_p_s.matcher(hashInputData);
 +      Matcher b64_m_e = b64_p_e.matcher(hashInputData);
 +
 +      b64_m_s.find();
 +      b64_m_e.find();
 +      
 +      String b64 = hashInputData.substring(b64_m_s.end(), b64_m_e.start());
 +
 +      sig_res.setHashInputData(b64);
 +    }
 +
      if (sub_nam_m_s.find() && sub_nam_m_e.find())
      {
        String sub_nam = xmlResponse.substring(sub_nam_m_s.end(), sub_nam_m_e.start());
 @@ -508,4 +536,27 @@ public final class BKUHelper      return sig_res;
    }
 +  public static String formDateTimeElement(Date verificationTime)
 +  {
 +    return formDateTimeElement(verificationTime, null);
 +  }
 +
 +  public static String formDateTimeElement(Date verificationTime, String namespace)
 +  {
 +    String nsPrefix = StringUtils.isBlank(namespace) ? "" : (namespace + ":");
 +    
 +    String dateTimeElement = "";
 +    if (verificationTime != null)
 +    {
 +      log.debug("VerificationTime = " + verificationTime);
 +
 +      DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
 +      df.setTimeZone(TimeZone.getTimeZone("UTC"));
 +      String dateTime = df.format(verificationTime) + "Z";
 +      log.debug("DateTime (VerificationTime in UTC) = " + dateTime);
 +      
 +      dateTimeElement = "<" + nsPrefix + "DateTime>" + dateTime + "</" + nsPrefix + "DateTime>";
 +    };
 +    return dateTimeElement;
 +  }
  }
 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 c84ce8a..f1896d7 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 @@ -11,6 +11,7 @@ import org.apache.commons.logging.Log;  import org.apache.commons.logging.LogFactory;
  import at.gv.egiz.pdfas.exceptions.ErrorCode;
 +import at.gv.egiz.pdfas.framework.ConnectorParameters;
  import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
  import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException;
  import at.knowcenter.wag.egov.egiz.exceptions.SettingsException;
 @@ -43,6 +44,11 @@ public class DetachedBKUConnector implements Connector, LocalConnector    private static Log log = LogFactory.getLog(DetachedBKUConnector.class);
    /**
 +   * The connector parameters.
 +   */
 +  protected ConnectorParameters params = null;
 +
 +  /**
     * The environemnt configuration of this connector containing templates and
     * other configurable elements.
     */
 @@ -57,14 +63,15 @@ public class DetachedBKUConnector implements Connector, LocalConnector     * parameters defined in the configuration are used.
     * </p>
     * 
 -   * @param profile
 -   *          The profile from which the Environment should be assembled.
 +   * @param connectorParameters
 +   *          The connectot parameters.
     * @throws ConnectorException
     *           f.e.
     */
 -  public DetachedBKUConnector(String profile, String loc_ref_content) throws ConnectorException
 +  public DetachedBKUConnector(ConnectorParameters connectorParameters, String loc_ref_content) throws ConnectorException
    {
 -    this.environment = new Environment(profile, loc_ref_content);
 +    this.params = connectorParameters;
 +    this.environment = new Environment(this.params.getProfileId(), loc_ref_content);
    }
    /**
 @@ -119,6 +126,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector      BKUHelper.checkResponseForError(response_string);
      SignSignatureObject so = BKUHelper.parseCreateXMLResponse(response_string, new DetachedIdFormatter());
 +    so.response_properties = response_properties;
      log.debug("analyzeSignResponse finished."); //$NON-NLS-1$
      return so;
 @@ -309,6 +317,7 @@ public class DetachedBKUConnector implements Connector, LocalConnector      String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
      verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.LOC_REF_CONTENT_REPLACE, this.environment.getLocRefContent());
 +    verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.DATE_TIME_REPLACE, BKUHelper.formDateTimeElement(this.params.getVerificationTime(), "sl"));
      return verify_request_xml;
    }
 diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/LocRefDetachedBKUConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/LocRefDetachedBKUConnector.java index 92b7b91..fc29457 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/LocRefDetachedBKUConnector.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/LocRefDetachedBKUConnector.java @@ -3,6 +3,7 @@   */
  package at.knowcenter.wag.egov.egiz.sig.connectors.bku;
 +import at.gv.egiz.pdfas.framework.ConnectorParameters;
  import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException;
  /**
 @@ -13,13 +14,13 @@ public class LocRefDetachedBKUConnector extends DetachedBKUConnector  {
    /**
 -   * @param profile
 +   * @param connectorParameters
     * @param loc_ref_content
     * @throws ConnectorException
     */
 -  public LocRefDetachedBKUConnector(String profile, String loc_ref_content) throws ConnectorException
 +  public LocRefDetachedBKUConnector(ConnectorParameters connectorParameters, String loc_ref_content) throws ConnectorException
    {
 -    super(profile, loc_ref_content);
 +    super(connectorParameters, loc_ref_content);
    }
  }
 diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/MultipartDetachedBKUConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/MultipartDetachedBKUConnector.java index a2d4dc0..6f189af 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/MultipartDetachedBKUConnector.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/MultipartDetachedBKUConnector.java @@ -3,6 +3,7 @@   */
  package at.knowcenter.wag.egov.egiz.sig.connectors.bku;
 +import at.gv.egiz.pdfas.framework.ConnectorParameters;
  import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException;
  /**
 @@ -13,9 +14,9 @@ public class MultipartDetachedBKUConnector extends DetachedBKUConnector  {
    protected static final String MULTIPART_LOC_REF_CONTENT = "formdata:fileupload"; //$NON-NLS-1$
 -  public MultipartDetachedBKUConnector(String profile) throws ConnectorException
 +  public MultipartDetachedBKUConnector(ConnectorParameters connectorParameters) throws ConnectorException
    {
 -    super(profile, MULTIPART_LOC_REF_CONTENT);
 +    super(connectorParameters, MULTIPART_LOC_REF_CONTENT);
    }
  }
 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 3bf0719..b31d1ec 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 @@ -10,6 +10,7 @@ import org.apache.commons.logging.Log;  import org.apache.commons.logging.LogFactory;
  import at.gv.egiz.pdfas.exceptions.ErrorCode;
 +import at.gv.egiz.pdfas.framework.ConnectorParameters;
  import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
  import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException;
  import at.knowcenter.wag.egov.egiz.exceptions.SettingsException;
 @@ -173,7 +174,9 @@ public class DetachedLocRefMOAConnector implements Connector      String xml_content = null;
      if (!SigKZIDHelper.isMOASigned(so))
      {
 -      DetachedBKUConnector bku_connector = new DetachedBKUConnector(this.environment.getProfile(), "not needed here");
 +      ConnectorParameters cp = new ConnectorParameters();
 +      cp.setProfileId(this.environment.getProfile());
 +      DetachedBKUConnector bku_connector = new DetachedBKUConnector(cp, "not needed here");
        xml_content = bku_connector.prepareXMLContent(data, so);
      }
      else
 diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java index 34bcdc6..4cb4ec2 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/MOASoapWithAttachmentConnector.java @@ -4,12 +4,19 @@  package at.knowcenter.wag.egov.egiz.sig.connectors.moa;
  import java.security.cert.X509Certificate;
 +import java.text.DateFormat;
 +import java.text.ParseException;
 +import java.text.SimpleDateFormat;
 +import java.util.Date;
  import java.util.Properties;
 +import java.util.SimpleTimeZone;
 +import java.util.TimeZone;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import at.gv.egiz.pdfas.exceptions.ErrorCode;
 +import at.gv.egiz.pdfas.framework.ConnectorParameters;
  import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
  import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException;
  import at.knowcenter.wag.egov.egiz.exceptions.SettingsException;
 @@ -25,7 +32,6 @@ import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject;  import at.knowcenter.wag.egov.egiz.sig.sigid.DetachedLocRefMOAIdFormatter;
  import at.knowcenter.wag.egov.egiz.sig.sigkz.SigKZIDHelper;
  import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
 -import at.knowcenter.wag.egov.egiz.tools.DebugHelper;
  import at.knowcenter.wag.egov.egiz.tools.FileHelper;
  /**
 @@ -46,12 +52,20 @@ public class MOASoapWithAttachmentConnector implements Connector    protected static final String MULTIPART_LOC_REF_CONTENT = "formdata:fileupload"; //$NON-NLS-1$
 +  protected static final String RETURN_HASH_INPUT_DATA = "<ReturnHashInputData/>"; //$NON-NLS-1$
 +  
 +  /**
 +   * The connector parameters.
 +   */
 +  protected ConnectorParameters params = null;
 +
    /**
     * The environemnt configuration of this connector containing templates and
     * other configurable elements.
     */
    protected Environment environment = null;
 -
 +  
 +   
    /**
     * Constructor that builds the configuration environment for this connector
     * according to the given profile.
 @@ -61,17 +75,15 @@ public class MOASoapWithAttachmentConnector implements Connector     * parameters defined in the configuration are used.
     * </p>
     * 
 -   * @param profile
 -   *          The profile from which the Environment should be assembled.
 -   * @throws SettingsException
 -   *           f.e.
 -   * @throws SignatureException
 +   * @param connectorParameters
 +   *          The parameters for this connector.
 +   * @throws ConnectorException
     *           f.e.
     */
 -  public MOASoapWithAttachmentConnector(String profile) throws ConnectorException
 +  public MOASoapWithAttachmentConnector(ConnectorParameters connectorParameters) throws ConnectorException
    {
 -	  
 -    this.environment = new Environment(profile, MULTIPART_LOC_REF_CONTENT);
 +    this.params = connectorParameters;
 +    this.environment = new Environment(this.params.getProfileId(), MULTIPART_LOC_REF_CONTENT);
    }
    protected String prepareSignRequest(SignatureData data) throws ConnectorException
 @@ -176,7 +188,7 @@ public class MOASoapWithAttachmentConnector implements Connector      String xml_content = null;
      if (!SigKZIDHelper.isMOASigned(so))
      {
 -      DetachedBKUConnector bku_connector = new DetachedBKUConnector(this.environment.getProfile(), "not needed here");
 +      DetachedBKUConnector bku_connector = new DetachedBKUConnector(this.params, "not needed here");
        xml_content = bku_connector.prepareXMLContent(data, so);
      }
      else
 @@ -187,12 +199,22 @@ public class MOASoapWithAttachmentConnector implements Connector      String verify_request_xml = verify_request_template.replaceFirst(TemplateReplaces.XML_CONTENT_REPLACE, xml_content);
      verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.TRUST_PROFILE_ID_REPLACE, this.environment.getVerifyTrustProfileId());
      verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.LOC_REF_CONTENT_REPLACE, this.environment.getSignatureDataUrl());
 +    
 +    String returnHashInputDataElement = "";
 +    if (this.params.isReturnHashInputData())
 +    {
 +      returnHashInputDataElement = RETURN_HASH_INPUT_DATA;
 +    }
 +    verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.RETURN_HASH_INPUT_DATA_REPLACE, returnHashInputDataElement);
 +    
 +    verify_request_xml = verify_request_xml.replaceFirst(TemplateReplaces.DATE_TIME_REPLACE, BKUHelper.formDateTimeElement(this.params.getVerificationTime()));
 +    
      log.debug("\r\n\r\n" + verify_request_xml + "\r\n\r\n");
      return verify_request_xml;
    }
 -
 +  
    /**
     * Analyzes the verify response string.
     * 
 @@ -297,20 +319,20 @@ public class MOASoapWithAttachmentConnector implements Connector      try
      {
  	    // for performance measurement
 -	    long startTime = 0; 
 -	    if (log.isInfoEnabled()) {
 -	    	startTime = System.currentTimeMillis();    	
 -	    }
 +//	    long startTime = 0; 
 +//	    if (log.isInfoEnabled()) {
 +//	    	startTime = System.currentTimeMillis();    	
 +//	    }
  //      Properties response_properties = MOASoapConnection.connectMOA(request_string, MOASoapConnection.SERVICE_SIGN, url);
        Properties response_properties = MOASoapConnection.doPostRequestMultipart(url,mode, request_string, data );
        // for performance measurement
 -      if (log.isInfoEnabled()) {
 -      	long endTime = System.currentTimeMillis();
 -      	String toReport = "MOA-PROCESSING;-;-;" + (endTime - startTime) + ";"; 
 -      	log.info(toReport);
 -      }
 +//      if (log.isInfoEnabled()) {
 +//      	long endTime = System.currentTimeMillis();
 +//      	String toReport = "MOA-PROCESSING;-;-;" + (endTime - startTime) + ";"; 
 +//      	log.info(toReport);
 +//      }
        return response_properties;
      }
 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 ed4fc7a..01e60fa 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 @@ -188,8 +188,23 @@ public class DataURLServlet extends HttpServlet          si.outputAvailable = true;
        }
 -      SignServletHelper.returnSignResponse(si, response);
 -
 +      if (si.output.getMimeType().equals("text/xml") && si.outputAvailable)
 +      {
 +        // For "detached" signatures, the return value (data sink) is the response xml,
 +        // but when passed through the BKU it is interpreted as another request
 +        // which will generate a return code 1501
 +        // Then PDF-AS would answer with the response as well generating
 +        // another 1501 and so forth.
 +        // Therefor return it as TXT.
 +        response.setContentType("text/plain");
 +        response.setCharacterEncoding("UTF-8");
 +        response.getWriter().println("Das detached XML kann nicht direkt durch die BKU geschliffen werden, weil diese es als Request interpretieren würde. Daher das XML als Text:");
 +        response.getWriter().println(si.si.getSignSignatureObject().response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY));
 +      }
 +      else
 +      {
 +        SignServletHelper.returnSignResponse(si, response);
 +      }
      }
    }
 | 
