From ad806535da32c317abba16d29326e65b7c10bf13 Mon Sep 17 00:00:00 2001 From: tknall Date: Thu, 12 Aug 2010 07:50:58 +0000 Subject: more logging new errorcode for invalid signature dictionary (232) detect invalid signature dictionary detect errors (invalid glyph mappings) when extracting text remove useless certificate digest calculation remove invocation of erroneous getCertDigest method webapp: hotfix for NPE adjustments for new mocca (applet) version (layout) POM: removed deprecated maven elements git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@587 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- pom.xml | 9 ++-- .../java/at/gv/egiz/pdfas/commandline/Main.java | 1 + .../at/gv/egiz/pdfas/exceptions/ErrorCode.java | 1 + .../helper/VerificationFilterBinaryHelper.java | 4 +- .../java/at/knowcenter/wag/egov/egiz/PdfAS.java | 2 +- .../java/at/knowcenter/wag/egov/egiz/PdfASID.java | 6 +-- .../wag/egov/egiz/pdf/AbsoluteTextSignature.java | 11 ++++ .../wag/egov/egiz/pdf/BinarySignature.java | 3 ++ .../wag/egov/egiz/pdf/PDFSignatureObjectIText.java | 1 - .../wag/egov/egiz/pdf/TextualSignature.java | 7 ++- .../wag/egov/egiz/sig/SignatureObject.java | 61 +++++++++++++++++++--- .../at/knowcenter/wag/egov/egiz/sig/X509Cert.java | 2 +- .../wag/egov/egiz/tools/CodingHelper.java | 1 - .../egiz/web/servlets/VerifyPreviewServlet.java | 11 +++- src/main/resources/config/help_text.properties | 1 + src/main/webapp/jsp/null_request_page.jsp | 4 +- 16 files changed, 101 insertions(+), 24 deletions(-) diff --git a/pom.xml b/pom.xml index 7d36203..ae023aa 100644 --- a/pom.xml +++ b/pom.xml @@ -98,7 +98,7 @@ - ${artifactId}-${version} + ${project.artifactId}-${project.version} @@ -140,6 +140,7 @@ src/main/assembly/assemble_distribution_cl.xml --> src/main/assembly/assemble_distribution_cl.xml + src/main/assembly/assemble_repository.xml @@ -157,8 +158,8 @@ . development - ${pom.url} - ${pom.version} + ${project.url} + ${project.version} @@ -179,7 +180,7 @@ 1.4 false true - ${pom.name} v${pom.version} API + ${project.name} v${project.version} API diff --git a/src/main/java/at/gv/egiz/pdfas/commandline/Main.java b/src/main/java/at/gv/egiz/pdfas/commandline/Main.java index 2e0e674..161dee8 100644 --- a/src/main/java/at/gv/egiz/pdfas/commandline/Main.java +++ b/src/main/java/at/gv/egiz/pdfas/commandline/Main.java @@ -547,6 +547,7 @@ public abstract class Main if (e instanceof PresentableException) { throw (PresentableException)e; } else { + logger_.error(e); throw new PresentableException(ErrorCode.UNKNOWN_ERROR, e); } } diff --git a/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java b/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java index 9c2e440..bf98c85 100644 --- a/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java +++ b/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java @@ -31,6 +31,7 @@ public final class ErrorCode public static final int SIGNATURE_TYPES_EXCEPTION = 223; public static final int FONT_NOT_FOUND = 230; public static final int DOCUMENT_IS_PROTECTED = 231; + public static final int INVALID_SIGNATURE_DICTIONARY = 232; public static final int INVALID_SIGNATURE_POSITION = 224; diff --git a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java index 3ee5da0..33a5ca3 100644 --- a/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java +++ b/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java @@ -137,10 +137,12 @@ public final class VerificationFilterBinaryHelper int linesToProcess = (kz_apr.elements.size() / 2); log.trace("Lines to process for KZ: " + linesToProcess); + /* if (linesToProcess > 1) { - log.debug("HOTFIX: forcing single line to process"); + log.debug("Multiple KZHOTFIX: forcing single line to process"); linesToProcess = 1; } + */ for (int i = 0; i < linesToProcess; i++) { NumberParseResult start_npr = (NumberParseResult) kz_apr.elements.get(i * 2); 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 424aad1..59c6b93 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java @@ -100,7 +100,7 @@ public abstract class PdfAS * The current version of the pdf-as library. This version string is logged on every invocation * of the api or the web application. */ - public static final String PDFAS_VERSION = "3.1.1-snapshot (20100408)"; + public static final String PDFAS_VERSION = "3.1.1-snapshot (20100812)"; /** * The key of the strict mode setting. diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/PdfASID.java b/src/main/java/at/knowcenter/wag/egov/egiz/PdfASID.java index 7e4b9c0..79591bd 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/PdfASID.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/PdfASID.java @@ -90,17 +90,17 @@ public class PdfASID implements Serializable if (tokens.length != 5) { - throw new InvalidIDException(ErrorCode.UNABLE_TO_PARSE_ID, "The doesn't have enough tokens (" + id + ")"); + throw new InvalidIDException(ErrorCode.UNABLE_TO_PARSE_ID, "The method doesn't have enough tokens (" + id + ")"); } if (!tokens[0].equals(URN)) { - throw new InvalidIDException(ErrorCode.UNABLE_TO_PARSE_ID, "The id must start with " + URN + " (" + id + ")"); + throw new InvalidIDException(ErrorCode.UNABLE_TO_PARSE_ID, "The method must start with " + URN + " (" + id + ")"); } if (!tokens[1].equals(NAMESPACE)) { - throw new InvalidIDException(ErrorCode.UNABLE_TO_PARSE_ID, "The namespace of the id must be " + NAMESPACE + " (" + id + ")"); + throw new InvalidIDException(ErrorCode.UNABLE_TO_PARSE_ID, "The namespace of the method must be " + NAMESPACE + " (" + id + ")"); } set(tokens[2], tokens[3], tokens[4]); 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 a036772..817eb20 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 @@ -311,6 +311,17 @@ public class AbsoluteTextSignature { potential_block_end = findEndOfValue(text, potential_block_end); } + + // FIXME: complete HOTFIX + /* + int extendedValueEnd = potential_block_end; + String cv; + do { + extendedValueEnd = findEndOfValue(text, extendedValueEnd); + cv = text.substring(last_caption_index + current_last_caption.length()+1, extendedValueEnd); + } while (extendedValueEnd < text.length()); + */ + logger.debug("potential_block_end = " + potential_block_end); List found_keys = PdfAS.findBlockInText(text.substring(0, potential_block_end), block_type, old_style); // findRestKeys(text, // keys, 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 32871e8..ec6f567 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 @@ -1940,6 +1940,9 @@ public abstract class BinarySignature if (cur_ri == null || !ByteArrayUtils.compareByteArrays(cur_ri.brev, 0, brevs[cur])) { + if (cur >= encodings.length) { + throw new PDFDocumentException(ErrorCode.INVALID_SIGNATURE_DICTIONARY, "Invalid EGIZ signature dictionary."); + } cur_ri = new ReplaceInfo(); cur_ri.replaces = new ArrayList(); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureObjectIText.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureObjectIText.java index a843369..39b5daf 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureObjectIText.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFSignatureObjectIText.java @@ -496,7 +496,6 @@ public class PDFSignatureObjectIText implements PDFSignatureObject { pdf_cell.setColspan(cell.getColSpan()); } - // TODO[tknall]: Check if cell nowrap may be used to prevent wrapping of cells containing keys. if (cell.isNoWrap()) { pdf_cell.setNoWrap(true); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignature.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignature.java index 85bc4fd..4a9814d 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignature.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TextualSignature.java @@ -167,7 +167,12 @@ public class TextualSignature // stripper.setStartPage(4); // stripper.setEndPage(4); logger_.debug("TextualSignator extractTextTextual: Begin stripping text"); - String text = stripper.getText(doc, encoding); + String text; + try { + text = stripper.getText(doc, encoding); + } catch (Exception e) { + throw new PDFDocumentException(ErrorCode.TEXT_EXTRACTION_EXCEPTION, "Unable to extract textual content.", e); + } logger_.debug("TextualSignator extractTextTextual: Stripping text ended"); doc.close(); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java index 66daf57..0b39a5b 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java @@ -570,7 +570,7 @@ public class SignatureObject implements Serializable { setSigValue(SignatureTypes.SIG_ISSUER, cert.getIssuerName()); setSigValue(SIG_CER, cert.getCertString()); - setSigValue(SIG_CER_DIG, cert.getCertDigest()); + // setSigValue(SIG_CER_DIG, cert.getCertDigest()); x509Cert_ = cert; } issuer = getSigValue(SignatureTypes.SIG_ISSUER); @@ -670,13 +670,13 @@ public class SignatureObject implements Serializable { setSigValue(SignatureTypes.SIG_ISSUER, cert.getIssuerName()); setSigValue(SIG_CER, cert.getCertString()); - setSigValue(SIG_CER_DIG, cert.getCertDigest()); + // setSigValue(SIG_CER_DIG, cert.getCertDigest()); x509Cert_ = cert; } } /** - * @return the current X509CertificateDigest value. + * @return the current X509CertificateDigest value (as SHA1 digest). */ public String getX509CertificateDigest() { @@ -684,7 +684,10 @@ public class SignatureObject implements Serializable if (dig == null) { loadCurrentCert(); - dig = getSigValue(SIG_CER_DIG); + byte[] cert_b64 = CodingHelper.decodeBase64(x509Cert_.getCertString()); + byte[] cert_hash = CodingHelper.buildDigest(cert_b64, "SHA"); + dig = new String(CodingHelper.encodeBase64(cert_hash)); + setSigValue(SIG_CER_DIG, dig); } return dig; } @@ -710,7 +713,7 @@ public class SignatureObject implements Serializable public void setX509Certificate(String x509Certificate) { setSigValue(SIG_CER, x509Certificate); - storeCertificate(getSignationSerialNumber(), getSignationIssuer(), x509Certificate, getX509CertificateDigest()); + storeCertificate(getSignationSerialNumber(), getSignationIssuer(), x509Certificate); } public void setX509Certificate(X509Certificate cert) @@ -722,7 +725,7 @@ public class SignatureObject implements Serializable // setX509Certificate(certStr); X509Cert knowcenterCert = X509Cert.initByX509Certificate(cert); setSigValue(SIG_CER, knowcenterCert.getCertString()); - storeCertificate(cert.getSerialNumber().toString(), knowcenterCert.getIssuerName(), knowcenterCert.getCertString(), knowcenterCert.getCertDigest()); + storeCertificate(cert.getSerialNumber().toString(), knowcenterCert.getIssuerName(), knowcenterCert.getCertString()); } catch (CertificateEncodingException e) { @@ -1339,9 +1342,51 @@ public class SignatureObject implements Serializable * @param x509Digest * the digest value of the given x509Certificate * @return true the certificate is stored completely, false otherwise + * @deprecated Use {@link #storeCertificate(String, String, String)} instead. */ private boolean storeCertificate(String serialNumber, String issuer, - String x509Certificate, String x509Digest) + String x509Certificate, String x509Digest) + { + return storeCertificate(serialNumber, issuer, x509Certificate); + } + + /** + * This method stores a X509v3 certificate to the filesystem. The reference to + * the stored certificate is build by the serialNumber and the issuer string. + * The issuer string is normalized because if getting this value from a pdf + * extraction it can be splited into more sections or necessary spaces are + * removed. The real issuer value is stored in the certificates meta file. The + * certficate is devided into two files: certificate.der (the binary value) + * and the meta information used in SignatureObjects as well in + * SignatureImages of a signed pdf-document. The storing path of the + * certificate is build by: + *
    + *
  1. normalize the issuer string
  2. + *
  3. reduce all white spaces in the normalized issuer string
  4. + *
  5. build a hash value of this reduced string
  6. + *
  7. code this hash value as base64 value
  8. + *
  9. add the base64 normalized issuer hash value to the certificate base + * store path
  10. + *
  11. add the serialNumber to the cert path
  12. + *
  13. add the .der extension to get the certificate binary
  14. + *
  15. add the .txt extension to get the meta information of + * the certificate
  16. + *
+ * + * The certificate meta file is build by the base64 coded issuer string and + * the cert digest value devided by the @ char. + * + * @param serialNumber + * the file name of the certificate .der|.txt + * @param issuer + * the issuer string for the file path value of the certificate and + * for metainformation + * @param x509Certificate + * the x509v3 binary string + * @return true the certificate is stored completely, false otherwise + */ + private boolean storeCertificate(String serialNumber, String issuer, + String x509Certificate) { boolean store_complete = false; if (issuer != null && serialNumber != null) @@ -1377,7 +1422,7 @@ public class SignatureObject implements Serializable } return store_complete; } - + /** * @return Returns the AbstractTable. * @see at.knowcenter.wag.egov.egiz.table.Table diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java index fbd89fa..3e230c5 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java @@ -316,6 +316,7 @@ public class X509Cert implements Serializable /** * @return Returns the certificate digest value. + * @deprecated Should not be used any more. */ public String getCertDigest() { @@ -324,7 +325,6 @@ public class X509Cert implements Serializable if (certString_ != null) { byte[] cert_b64 = CodingHelper.decodeBase64(certString_); - // dferbas: read digest method from certificate String sigAlgName = this.x509Cert_.getSigAlgName(); String digestAlg = sigAlgName.split("/")[0]; if (sigAlgName.toLowerCase().indexOf("with") != -1 ) { diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/tools/CodingHelper.java b/src/main/java/at/knowcenter/wag/egov/egiz/tools/CodingHelper.java index 8d05960..bed1cb3 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/tools/CodingHelper.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/tools/CodingHelper.java @@ -18,7 +18,6 @@ package at.knowcenter.wag.egov.egiz.tools; import java.io.IOException; -import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyPreviewServlet.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyPreviewServlet.java index 0eb417b..11f9db4 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyPreviewServlet.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyPreviewServlet.java @@ -341,12 +341,21 @@ public class VerifyPreviewServlet extends HttpServlet writer.println(""); // just render useful information - String[] rkeys = { SignatureTypes.SIG_NAME, SignatureTypes.SIG_DATE, SignatureTypes.SIG_ISSUER, SignatureTypes.SIG_NUMBER}; // SignatureTypes.REQUIRED_SIG_KEYS; + // FIXME: NPE in case SignatureTypes.SIG_NAME is not used (in case of friendly signer name) + // Problem: SignatureTypes.SIG_NAME is defined as Signer-RFC2253Name, but there is not certain + // key for friendly name (e.g. SIG_SUBJECT or SIG_FOO), therefore we do not know which key contains + // the friendly signer name + + // workaround: include "SIG_SUBJECT" since it is usually used + String[] rkeys = { SignatureTypes.SIG_NAME, "SIG_SUBJECT", SignatureTypes.SIG_DATE, SignatureTypes.SIG_ISSUER, SignatureTypes.SIG_NUMBER}; // SignatureTypes.REQUIRED_SIG_KEYS; for (int key_idx = 0; key_idx < rkeys.length; key_idx++) { String key = rkeys[key_idx]; SignatureEntry entry = signature_object.getSigEntry(key); + if (entry == null) { + continue; + } String caption = entry.getCaption(); String value = entry.getValue(); if (caption == null || value == null) { diff --git a/src/main/resources/config/help_text.properties b/src/main/resources/config/help_text.properties index d6e6608..8ebabe5 100644 --- a/src/main/resources/config/help_text.properties +++ b/src/main/resources/config/help_text.properties @@ -37,6 +37,7 @@ error.code.228=Der angegebene Wert f error.code.229=Der angegebene Wert für die y-Position in der absoluten Position darf nicht kleiner gleich 0 sein. error.code.230=Die Schriftart konnte nicht geladen werden. error.code.231=Das Dokument kann nicht verarbeitet werden, da es geschützt ist. +error.code.232=Die Signatur konnte nicht überprüft werden, da das Dokument unvollständige Signaturinformationen enthält. error.code.250=Das angegebene Dokument ist leer. error.code.251=Das angegebene Dokument enthält keinen extrahierbaren Text. Falls sich der Inhalt ausschließlich aus Bildern zusammensetzt, wird die Verwendung einer binären Signatur empfohlen. diff --git a/src/main/webapp/jsp/null_request_page.jsp b/src/main/webapp/jsp/null_request_page.jsp index 28ff188..07331d6 100644 --- a/src/main/webapp/jsp/null_request_page.jsp +++ b/src/main/webapp/jsp/null_request_page.jsp @@ -69,9 +69,9 @@ <% if (!isExternalInvocation) { %>
- + <% } else { // end if %> - + <% } // end if %> <% } else { %> -- cgit v1.2.3