/** * Copyright 2006 by Know-Center, Graz, Austria * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a * joint initiative of the Federal Chancellery Austria and Graz University of * Technology. * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * http://www.osor.eu/eupl/ * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. */ package at.gv.egiz.pdfas.impl.vfilter.helper; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import at.gv.egiz.pdfas.exceptions.ErrorCode; import at.knowcenter.wag.egov.egiz.PdfASID; import at.knowcenter.wag.egov.egiz.exceptions.InvalidIDException; import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; import at.knowcenter.wag.egov.egiz.pdf.BinarySignature; import at.knowcenter.wag.egov.egiz.pdf.Placeholder; import at.knowcenter.wag.egov.egiz.pdf.StringInfo; import at.knowcenter.wag.exactparser.parsing.IndirectObjectReference; import at.knowcenter.wag.exactparser.parsing.PDFUtils; import at.knowcenter.wag.exactparser.parsing.results.ArrayParseResult; import at.knowcenter.wag.exactparser.parsing.results.DictionaryParseResult; import at.knowcenter.wag.exactparser.parsing.results.FooterParseResult; import at.knowcenter.wag.exactparser.parsing.results.IndirectObjectReferenceParseResult; import at.knowcenter.wag.exactparser.parsing.results.NumberParseResult; import at.knowcenter.wag.exactparser.parsing.results.ObjectParseResult; /** * Contains helpful methods used by the VerificationFilter to analyze the PDF for binary signatures. * * @author wprinz */ public final class VerificationFilterBinaryHelper { /** * The name of the egiz dict key. */ public static final byte[] EGIZ_DICT_NAME = { 'E', 'G', 'I', 'Z', 'S', 'i', 'g', 'D', 'i', 'c', 't' }; /** * The name of the ID (SIG_KZ) property in the egiz dict. */ public static final byte[] EGIZ_KZ_NAME = { 'I', 'D' }; /** * The log. */ private static final Log log = LogFactory.getLog(VerificationFilterBinaryHelper.class); /** * Tells, if the given incremental update block contains a binary signature. * *

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

* * @param block * The incremental update block. * @return Returns true, if this block is a binary signature block, false * otherwise. */ public static boolean containsEGIZDict(final byte[] pdf, final FooterParseResult block) { int dict_index = PDFUtils.indexOfName(pdf, block.tpr.dpr.names, EGIZ_DICT_NAME); if (dict_index <= 0) { return false; } return true; } /** * Extracts the PDF AS ID of the egiz block. * * @param pdf * The pdf. * @param block * The IU block. * @return Returns the extracted PDF AS ID. * @throws PDFDocumentException * Forwarded exception. * @throws InvalidIDException * Forwarded exception. */ public static PdfASID extractKZFromEGIZBlock(final byte[] pdf, final FooterParseResult block) throws PDFDocumentException, InvalidIDException { int egiz_index = PDFUtils.indexOfName(pdf, block.tpr.dpr.names, EGIZ_DICT_NAME); if (egiz_index < 0) { throw new PDFDocumentException(301, "egiz_index = " + egiz_index); } IndirectObjectReferenceParseResult egiz_dict_iorpr = (IndirectObjectReferenceParseResult) block.tpr.dpr.values.get(egiz_index); // logger_.debug("egiz_dict_ir = " + egiz_dict_iorpr.ior.object_number // + " " + egiz_dict_iorpr.ior.generation_number); IndirectObjectReference ior = egiz_dict_iorpr.ior; final int egiz_dict_offset = PDFUtils.getObjectOffsetFromXRefByIndirectObjectReference(block.xpr, ior); // logger_.debug("egiz_dict_offset = " + egiz_dict_offset); ObjectParseResult obj = PDFUtils.parseObject(pdf, egiz_dict_offset); DictionaryParseResult egiz_dict = (DictionaryParseResult) obj.object; int kz_index = PDFUtils.indexOfName(pdf, egiz_dict.names, EGIZ_KZ_NAME); if (kz_index < 0) { throw new PDFDocumentException(301, "kz_index = " + kz_index); } ArrayParseResult kz_apr = (ArrayParseResult) egiz_dict.values.get(kz_index); String kz_string = restoreKZ(pdf, kz_apr); PdfASID kz = new PdfASID(kz_string); return kz; } /** * Restores the Kennzeichnung String from an Array. * * @param pdf * The PDF. * @param kz_apr * The Array, as parsed from the EGIZ Dict. * @return Returns the restored KZ. * @throws PDFDocumentException * Forwarded exception. */ public static String restoreKZ(byte[] pdf, ArrayParseResult kz_apr) throws PDFDocumentException { try { List partition = new ArrayList(); int linesToProcess = (kz_apr.elements.size() / 2); log.trace("Lines to process for KZ: " + linesToProcess); /* if (linesToProcess > 1) { 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); NumberParseResult length_npr = (NumberParseResult) kz_apr.elements.get(i * 2 + 1); StringInfo si = new StringInfo(); si.string_start = start_npr.number; si.string_length = length_npr.number; si.pdf = pdf; log.trace("Adding KZ: " + si.toString()); partition.add(si); } String KZ = Placeholder.reconstructStringFromPartition(pdf, partition, BinarySignature.ENCODING_WIN); return KZ; } catch (IOException e1) { throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e1); } } }