aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2014-02-04 08:36:05 +0100
committerAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2014-02-04 08:36:05 +0100
commit6b692931c81fd0e09d8d21eb81e05a5f08af8342 (patch)
tree9ee012c549cf0e4e4af05de4ff28920bb603e7e2
parent09dfbe9ba1b1f4469044b4bf1004df3740a8ae9d (diff)
downloadpdf-as-4-6b692931c81fd0e09d8d21eb81e05a5f08af8342.tar.gz
pdf-as-4-6b692931c81fd0e09d8d21eb81e05a5f08af8342.tar.bz2
pdf-as-4-6b692931c81fd0e09d8d21eb81e05a5f08af8342.zip
Implemented PDF Document permission check
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsValidationException.java5
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java179
-rw-r--r--pdf-as-common/src/main/resources/resources/messages/common.properties1
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java9
4 files changed, 110 insertions, 84 deletions
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsValidationException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsValidationException.java
index b8a5fc62..95380794 100644
--- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsValidationException.java
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsValidationException.java
@@ -16,6 +16,11 @@ public class PdfAsValidationException extends PdfAsException {
this.parameter = parameter;
}
+ public PdfAsValidationException(String msgId, String parameter, Throwable e) {
+ super(msgId, e);
+ this.parameter = parameter;
+ }
+
@Override
protected String localizeMessage(String msgId) {
if(parameter != null) {
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java
index 155f9cfb..8b649034 100644
--- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java
@@ -1,94 +1,105 @@
package at.gv.egiz.pdfas.common.utils;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
-import java.util.List;
-
+import at.gv.egiz.pdfas.common.exceptions.PdfAsValidationException;
public class PDFUtils {
- private static final Logger logger = LoggerFactory.getLogger(PDFUtils.class);
-
-
- private static final byte[] signature_pattern = new byte[] {
- (byte) 0x0A, (byte) 0x2F, (byte) 0x43, (byte) 0x6F, // ./Co
- (byte) 0x6E, (byte) 0x74, (byte) 0x65, (byte) 0x6E, // nten
- (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x0A, // ts .
- (byte) 0x2F, (byte) 0x42, (byte) 0x79, (byte) 0x74, // /Byt
- (byte) 0x65, (byte) 0x52, (byte) 0x61, (byte) 0x6E, // eRan
- (byte) 0x67, (byte) 0x65, (byte) 0x20, (byte) 0x5B, // ge [
-
- };
-
- private static final byte range_seperation = (byte) 0x20;
- private static final byte range_end = (byte) 0x5D;
-
- private static int extractASCIIInteger(byte[] data, int offset) {
- int nextsepp = nextSeperator(data, offset);
-
- if(nextsepp < offset) {
- return -1;
- }
-
- String asciiString = new String(data, offset, nextsepp - offset);
-
- logger.debug("Extracted " + asciiString);
-
- return Integer.parseInt(asciiString);
- }
-
- private static int nextSeperator(byte[] data, int offset) {
- for(int i = offset; i < data.length; i++) {
- if(data[i] == range_seperation) {
- return i;
- } else if(data[i] == range_end) {
- return i;
- }
- }
- return -2;
- }
-
- public static int[] extractSignatureByteRange(byte[] rawPdfData) {
- int i = 0;
- for(i = rawPdfData.length - 1; i >= 0; i--) {
- if(rawPdfData[i] == signature_pattern[0] &&
- i+signature_pattern.length < rawPdfData.length) {
- boolean match = true;
- for(int j = 0; j < signature_pattern.length; j++) {
-
- if(rawPdfData[i+j] != signature_pattern[j]) {
- match = false;
- break;
- }
- }
-
- if(match) {
-
- int offset = i + signature_pattern.length;
- List<Integer> byteRange = new ArrayList<Integer>();
- while(offset > 0) {
- byteRange.add(extractASCIIInteger(rawPdfData, offset));
- offset = nextSeperator(rawPdfData, offset);
- if(rawPdfData[offset] == range_end) {
- break;
- }
- offset++;
- }
- int[] range = new int[byteRange.size()];
- for(int j = 0; j < byteRange.size(); j++) {
- range[j] = byteRange.get(j);
- }
- return range;
- }
- }
- }
- return null;
- }
-
- public static void checkPDFPermissions(PDDocument doc) {
- // TODO: Check permission for document
- }
+ private static final Logger logger = LoggerFactory
+ .getLogger(PDFUtils.class);
+
+ private static final byte[] signature_pattern = new byte[] { (byte) 0x0A,
+ (byte) 0x2F, (byte) 0x43, (byte) 0x6F, // ./Co
+ (byte) 0x6E, (byte) 0x74, (byte) 0x65, (byte) 0x6E, // nten
+ (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x0A, // ts .
+ (byte) 0x2F, (byte) 0x42, (byte) 0x79, (byte) 0x74, // /Byt
+ (byte) 0x65, (byte) 0x52, (byte) 0x61, (byte) 0x6E, // eRan
+ (byte) 0x67, (byte) 0x65, (byte) 0x20, (byte) 0x5B, // ge [
+
+ };
+
+ private static final byte range_seperation = (byte) 0x20;
+ private static final byte range_end = (byte) 0x5D;
+
+ private static int extractASCIIInteger(byte[] data, int offset) {
+ int nextsepp = nextSeperator(data, offset);
+
+ if (nextsepp < offset) {
+ return -1;
+ }
+
+ String asciiString = new String(data, offset, nextsepp - offset);
+
+ logger.debug("Extracted " + asciiString);
+
+ return Integer.parseInt(asciiString);
+ }
+
+ private static int nextSeperator(byte[] data, int offset) {
+ for (int i = offset; i < data.length; i++) {
+ if (data[i] == range_seperation) {
+ return i;
+ } else if (data[i] == range_end) {
+ return i;
+ }
+ }
+ return -2;
+ }
+
+ public static int[] extractSignatureByteRange(byte[] rawPdfData) {
+ int i = 0;
+ for (i = rawPdfData.length - 1; i >= 0; i--) {
+ if (rawPdfData[i] == signature_pattern[0]
+ && i + signature_pattern.length < rawPdfData.length) {
+ boolean match = true;
+ for (int j = 0; j < signature_pattern.length; j++) {
+
+ if (rawPdfData[i + j] != signature_pattern[j]) {
+ match = false;
+ break;
+ }
+ }
+
+ if (match) {
+
+ int offset = i + signature_pattern.length;
+ List<Integer> byteRange = new ArrayList<Integer>();
+ while (offset > 0) {
+ byteRange.add(extractASCIIInteger(rawPdfData, offset));
+ offset = nextSeperator(rawPdfData, offset);
+ if (rawPdfData[offset] == range_end) {
+ break;
+ }
+ offset++;
+ }
+ int[] range = new int[byteRange.size()];
+ for (int j = 0; j < byteRange.size(); j++) {
+ range[j] = byteRange.get(j);
+ }
+ return range;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static void checkPDFPermissions(PDDocument doc) throws PdfAsValidationException {
+
+ AccessPermission accessPermission = doc.getCurrentAccessPermission();
+ if (doc.isEncrypted()) {
+ throw new PdfAsValidationException("error.pdf.sig.12", null);
+ }
+
+ if (!accessPermission.isOwnerPermission()) {
+ throw new PdfAsValidationException("error.pdf.sig.12", null);
+ }
+
+ }
}
diff --git a/pdf-as-common/src/main/resources/resources/messages/common.properties b/pdf-as-common/src/main/resources/resources/messages/common.properties
index 0191bdd9..bdae59ca 100644
--- a/pdf-as-common/src/main/resources/resources/messages/common.properties
+++ b/pdf-as-common/src/main/resources/resources/messages/common.properties
@@ -36,6 +36,7 @@ error.pdf.sig.08=Signature created by the BKU is not valid
error.pdf.sig.09=Signature profile %s not available
error.pdf.sig.10=No signature data available
error.pdf.sig.11=No data sink available
+error.pdf.sig.12=Document is protected
#Signature verification errors
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java
index 540fd572..2553ccf3 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java
@@ -16,6 +16,7 @@ import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSString;
import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -95,6 +96,14 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
throw new PdfAsValidationException("error.pdf.sig.11", null);
}
+ try {
+ PDDocument doc = PDDocument.load(new ByteArrayInputStream(parameter.getDataSource().getByteData()));
+ PDFUtils.checkPDFPermissions(doc);
+ doc.close();
+ } catch(IOException e) {
+ throw new PdfAsValidationException("error.pdf.sig.12", null, e);
+ }
+
// TODO: verify Sign Parameter
}