From 0b663afa4d0167df1e838e1f37bb5862e8951037 Mon Sep 17 00:00:00 2001
From: Andreas Fitzek <andreas.fitzek@iaik.tugraz.at>
Date: Wed, 15 Oct 2014 18:07:20 +0200
Subject: PDF-AS Errorhandling redesign only PDFASError Exceptions are returned
 !

---
 .../main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java  | 15 ++--
 .../at/gv/egiz/pdfas/lib/impl/ErrorExtractor.java  | 65 ++++++++++++++++
 .../java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java  | 88 +++++++++++-----------
 .../at/gv/egiz/pdfas/lib/util/SignatureUtils.java  | 19 +++--
 .../egiz/sl/util/ISignatureConnectorSLWrapper.java | 11 ++-
 5 files changed, 138 insertions(+), 60 deletions(-)
 create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/ErrorExtractor.java

(limited to 'pdf-as-lib/src')

diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java
index 2ac02a18..1d23c070 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java
@@ -23,11 +23,12 @@
  ******************************************************************************/
 package at.gv.egiz.pdfas.lib.api;
 
-import iaik.x509.X509Certificate;
+import java.security.cert.X509Certificate;
 
 import java.awt.Image;
 import java.util.List;
 
+import at.gv.egiz.pdfas.common.exceptions.PDFASError;
 import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
 import at.gv.egiz.pdfas.lib.api.sign.SignParameter;
 import at.gv.egiz.pdfas.lib.api.sign.SignResult;
@@ -41,7 +42,7 @@ public interface PdfAs {
 	 * @param parameter
 	 * @return
 	 */
-	public SignResult sign(SignParameter parameter) throws PdfAsException;
+	public SignResult sign(SignParameter parameter) throws PDFASError;
 	
 	/**
 	 * Verifies a document with (potentially multiple) PDF-AS signatures.
@@ -49,7 +50,7 @@ public interface PdfAs {
 	 * @param parameter The verification parameter
 	 * @return A list of verification Results
 	 */
-	public List<VerifyResult> verify(VerifyParameter parameter) throws PdfAsException;
+	public List<VerifyResult> verify(VerifyParameter parameter) throws PDFASError;
 	
 	/**
 	 * Gets a copy of the PDF-AS configuration, to allow the application to 
@@ -68,7 +69,7 @@ public interface PdfAs {
 	 * @return A status request
 	 * @throws PdfAsException
 	 */
-	public StatusRequest startSign(SignParameter parameter) throws PdfAsException;
+	public StatusRequest startSign(SignParameter parameter) throws PDFASError;
 	
 	/**
 	 * Continues an ongoing signature process 
@@ -77,7 +78,7 @@ public interface PdfAs {
 	 * @return A status request
 	 * @throws PdfAsException
 	 */
-	public StatusRequest process(StatusRequest statusRequest) throws PdfAsException;
+	public StatusRequest process(StatusRequest statusRequest) throws PDFASError;
 	
 	/**
 	 * Finishes a signature process
@@ -86,7 +87,7 @@ public interface PdfAs {
 	 * @return A signature result
 	 * @throws PdfAsException
 	 */
-	public SignResult    finishSign(StatusRequest statusRequest) throws PdfAsException;
+	public SignResult    finishSign(StatusRequest statusRequest) throws PDFASError;
 	
 	/**
 	 * Generates a Image of the visual signatur block as Preview
@@ -97,5 +98,5 @@ public interface PdfAs {
 	 * @return
 	 * @throws PdfAsException
 	 */
-	public Image generateVisibleSignaturePreview(SignParameter parameter, X509Certificate cert, int resolution) throws PdfAsException;
+	public Image generateVisibleSignaturePreview(SignParameter parameter, X509Certificate cert, int resolution) throws PDFASError;
 }
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/ErrorExtractor.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/ErrorExtractor.java
new file mode 100644
index 00000000..90a4e9e8
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/ErrorExtractor.java
@@ -0,0 +1,65 @@
+package at.gv.egiz.pdfas.lib.impl;
+
+import at.gv.egiz.pdfas.common.exceptions.ErrorConstants;
+import at.gv.egiz.pdfas.common.exceptions.PDFASError;
+import at.gv.egiz.pdfas.common.exceptions.SLPdfAsException;
+
+public class ErrorExtractor implements ErrorConstants {
+
+	private static final int MAX_CAUSE_DEPTH = 30;
+
+	private static PDFASError convertPdfAsError(Throwable e) {
+		if (e instanceof SLPdfAsException) {
+			SLPdfAsException ex = (SLPdfAsException) e;
+			if (ex.getInfo() != null) {
+				return new PDFASError(ex.getCode(), ex.getInfo(), e);
+			} else {
+				return new PDFASError(ex.getCode(), e);
+			}
+		} // TODO: Handle more exceptions
+
+		return null;
+	}
+
+	public static PDFASError searchPdfAsError(Throwable e) {
+		Throwable cur = e;
+		PDFASError err = null;
+
+		// Search PDFASError
+		for (int i = 0; i < MAX_CAUSE_DEPTH; i++) {
+			if (cur instanceof PDFASError) {
+				err = (PDFASError) cur;
+			}
+			if (err != null) {
+				break;
+			}
+
+			cur = cur.getCause();
+			if (cur == null) {
+				break;
+			}
+		}
+		cur = e;
+		// Search other reasons
+		for (int i = 0; i < MAX_CAUSE_DEPTH; i++) {
+
+			if (cur == null) {
+				break;
+			}
+
+			err = convertPdfAsError(cur);
+
+			if (err != null) {
+				break;
+			}
+
+			cur = cur.getCause();
+		}
+
+		if (err != null) {
+			return err;
+		}
+
+		return new PDFASError(ERROR_GENERIC, e);
+	}
+}
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 c853f7eb..a94f63ad 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
@@ -32,7 +32,6 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.List;
@@ -48,11 +47,10 @@ import org.apache.pdfbox.pdmodel.PDPage;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import at.gv.egiz.pdfas.common.exceptions.PDFIOException;
+import at.gv.egiz.pdfas.common.exceptions.ErrorConstants;
+import at.gv.egiz.pdfas.common.exceptions.PDFASError;
 import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
 import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsException;
-import at.gv.egiz.pdfas.common.exceptions.PdfAsSignatureException;
-import at.gv.egiz.pdfas.common.exceptions.PdfAsValidationException;
 import at.gv.egiz.pdfas.common.settings.ISettings;
 import at.gv.egiz.pdfas.common.settings.Settings;
 import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;
@@ -91,7 +89,8 @@ import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
 import at.knowcenter.wag.egov.egiz.pdf.TablePos;
 import at.knowcenter.wag.egov.egiz.table.Table;
 
-public class PdfAsImpl implements PdfAs, IConfigurationConstants {
+public class PdfAsImpl implements PdfAs, IConfigurationConstants,
+		ErrorConstants {
 
 	private static final Logger logger = LoggerFactory
 			.getLogger(PdfAsImpl.class);
@@ -109,11 +108,10 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 		this.settings = cfgObject;
 	}
 
-	private void verifySignParameter(SignParameter parameter)
-			throws PdfAsException {
+	private void verifySignParameter(SignParameter parameter) throws PDFASError {
 		// Status initialization
 		if (!(parameter.getConfiguration() instanceof ISettings)) {
-			throw new PdfAsSettingsException("Invalid settings object!");
+			throw new PDFASError(ERROR_SET_INVALID_SETTINGS_OBJ);
 		}
 
 		ISettings settings = (ISettings) parameter.getConfiguration();
@@ -121,30 +119,31 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 		String signatureProfile = parameter.getSignatureProfileId();
 		if (signatureProfile != null) {
 			if (!settings.hasPrefix("sig_obj." + signatureProfile)) {
-				throw new PdfAsValidationException("error.pdf.sig.09",
-						signatureProfile);
+				throw new PDFASError(ERROR_SIG_INVALID_PROFILE,
+						PDFASError.buildInfoString(ERROR_SIG_INVALID_PROFILE,
+								signatureProfile));
 			}
 		}
 
 		if (parameter.getDataSource() == null) {
-			throw new PdfAsValidationException("error.pdf.sig.10", null);
+			throw new PDFASError(ERROR_NO_INPUT);
 		}
 
 	}
 
 	private void verifyVerifyParameter(VerifyParameter parameter)
-			throws PdfAsException {
+			throws PDFASError {
 		// Status initialization
 		if (!(parameter.getConfiguration() instanceof ISettings)) {
-			throw new PdfAsSettingsException("Invalid settings object!");
+			throw new PDFASError(ERROR_SET_INVALID_SETTINGS_OBJ);
 		}
 
 		if (parameter.getDataSource() == null) {
-			throw new PdfAsValidationException("error.pdf.verify.01", null);
+			throw new PDFASError(ERROR_NO_INPUT);
 		}
 	}
 
-	public SignResult sign(SignParameter parameter) throws PdfAsException {
+	public SignResult sign(SignParameter parameter) throws PDFASError {
 
 		logger.trace("sign started");
 
@@ -204,7 +203,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 		} catch (Throwable e) {
 			logger.error("Failed to create signature [" + e.getMessage() + "]",
 					e);
-			throw new PdfAsException("error.pdf.sig.01", e);
+			throw ErrorExtractor.searchPdfAsError(e);
 		} finally {
 			if (status != null) {
 				status.clear();
@@ -214,7 +213,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 	}
 
 	public List<VerifyResult> verify(VerifyParameter parameter)
-			throws PdfAsException {
+			throws PDFASError {
 
 		verifyVerifyParameter(parameter);
 
@@ -262,7 +261,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 
 			byte[] inputData = IOUtils.toByteArray(parameter.getDataSource()
 					.getInputStream());
-			
+
 			for (int i = 0; i < fields.size(); i++) {
 				COSDictionary field = (COSDictionary) fields.getObject(i);
 				String type = field.getNameAsString("FT");
@@ -303,7 +302,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 
 						COSString content = (COSString) dict
 								.getDictionaryObject("Contents");
-	
+
 						ByteArrayOutputStream contentData = new ByteArrayOutputStream();
 						for (int j = 0; j < bytes.length; j = j + 2) {
 							int offset = bytes[j];
@@ -339,10 +338,10 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 			return result;
 		} catch (IOException e) {
 			logger.error("Failed to verify document", e);
-			throw new PDFIOException("error.pdf.verify.02", e);
+			throw ErrorExtractor.searchPdfAsError(e);
 		} catch (PdfAsException e) {
 			logger.error("Failed to verify document", e);
-			throw new PdfAsException("error.pdf.verify.02", e);
+			throw ErrorExtractor.searchPdfAsError(e);
 		} finally {
 			if (doc != null) {
 				try {
@@ -358,8 +357,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 		return new ConfigurationImpl(this.settings);
 	}
 
-	public StatusRequest startSign(SignParameter parameter)
-			throws PdfAsException {
+	public StatusRequest startSign(SignParameter parameter) throws PDFASError {
 
 		verifySignParameter(parameter);
 
@@ -386,14 +384,13 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 			return request;
 		} catch (Throwable e) {
 			logger.error("startSign", e);
-			throw new PdfAsException("error.pdf.sig.03", e);
+			throw ErrorExtractor.searchPdfAsError(e);
 		}
 	}
 
-	public StatusRequest process(StatusRequest statusRequest)
-			throws PdfAsException {
+	public StatusRequest process(StatusRequest statusRequest) throws PDFASError {
 		if (!(statusRequest instanceof StatusRequestImpl)) {
-			throw new PdfAsException("error.pdf.sig.04");
+			throw new PDFASError(ERROR_SIG_INVALID_STATUS);
 		}
 
 		StatusRequestImpl request = (StatusRequestImpl) statusRequest;
@@ -446,7 +443,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 
 			} catch (Throwable e) {
 				logger.error("process", e);
-				throw new PdfAsException("error.pdf.sig.05", e);
+				throw ErrorExtractor.searchPdfAsError(e);
 			}
 		} else if (request.needSignature()) {
 			request.setNeedSignature(false);
@@ -467,7 +464,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 			if (!StreamUtils.dataCompare(requestedSignature.getCertificate()
 					.getFingerprintSHA(), ((X509Certificate) verifyResult
 					.getSignerCertificate()).getFingerprintSHA())) {
-				throw new PdfAsSignatureException("Certificates missmatch!");
+				throw new PDFASError(ERROR_SIG_CERTIFICATE_MISSMATCH);
 			}
 
 			for (int i = 0; i < pdfSignature.length; i++) {
@@ -475,29 +472,29 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 			}
 			request.setIsReady(true);
 		} else {
-			throw new PdfAsException("error.pdf.sig.04");
+			throw new PDFASError(ERROR_SIG_INVALID_STATUS);
 		}
 
 		return request;
 	}
 
-	public SignResult finishSign(StatusRequest statusRequest)
-			throws PdfAsException {
+	public SignResult finishSign(StatusRequest statusRequest) throws PDFASError {
 		if (!(statusRequest instanceof StatusRequestImpl)) {
-			throw new PdfAsException("error.pdf.sig.04");
+			throw new PDFASError(ERROR_SIG_INVALID_STATUS);
 		}
 
 		StatusRequestImpl request = (StatusRequestImpl) statusRequest;
 		OperationStatus status = request.getStatus();
 
 		if (!request.isReady()) {
-			throw new PdfAsException("error.pdf.sig.04");
+			throw new PDFASError(ERROR_SIG_INVALID_STATUS);
 		}
 
 		try {
 			return createSignResult(status);
 		} catch (IOException e) {
-			throw new PdfAsException("error.pdf.sig.06", e);
+			// new PdfAsException("error.pdf.sig.06", e);
+			throw ErrorExtractor.searchPdfAsError(e);
 		} finally {
 			if (status != null) {
 				status.clear();
@@ -521,21 +518,27 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 	}
 
 	public Image generateVisibleSignaturePreview(SignParameter parameter,
-			X509Certificate cert, int resolution) throws PdfAsException {
+			java.security.cert.X509Certificate cert, int resolution) throws PDFASError {
 
 		OperationStatus status = null;
 		try {
 			// Status initialization
 			if (!(parameter.getConfiguration() instanceof ISettings)) {
-				throw new PdfAsSettingsException("Invalid settings object!");
+				throw new PDFASError(ERROR_SET_INVALID_SETTINGS_OBJ);
 			}
-
+			X509Certificate iaikCert;
+			if(!(cert instanceof X509Certificate)) {
+				iaikCert = new X509Certificate(cert.getEncoded());
+			} else {
+				iaikCert = (X509Certificate)cert;
+			}
+			
 			ISettings settings = (ISettings) parameter.getConfiguration();
 			status = new OperationStatus(settings, parameter);
 
 			RequestedSignature requestedSignature = new RequestedSignature(
 					status);
-			requestedSignature.setCertificate(cert);
+			requestedSignature.setCertificate(iaikCert);
 
 			if (!requestedSignature.isVisual()) {
 				logger.warn("Profile is invisible so not block image is generated");
@@ -550,7 +553,8 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 			origDoc.save(baos);
 			baos.close();
 
-			pdfObject.setOriginalDocument(new ByteArrayDataSource(baos.toByteArray()));
+			pdfObject.setOriginalDocument(new ByteArrayDataSource(baos
+					.toByteArray()));
 
 			SignatureProfileSettings signatureProfileSettings = TableFactory
 					.createProfile(requestedSignature.getSignatureProfileID(),
@@ -630,10 +634,10 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 			return cutOut;
 		} catch (PdfAsException e) {
 			logger.error("PDF-AS  Exception", e);
-			throw e;
+			throw ErrorExtractor.searchPdfAsError(e);
 		} catch (Throwable e) {
 			logger.error("Throwable  Exception", e);
-			throw new PdfAsException("", e);
+			throw ErrorExtractor.searchPdfAsError(e);
 		}
 
 	}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/util/SignatureUtils.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/util/SignatureUtils.java
index 608818f9..3b992e46 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/util/SignatureUtils.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/util/SignatureUtils.java
@@ -16,11 +16,12 @@ import org.apache.pdfbox.pdmodel.PDDocument;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import at.gv.egiz.pdfas.common.exceptions.PdfAsSignatureException;
+import at.gv.egiz.pdfas.common.exceptions.ErrorConstants;
+import at.gv.egiz.pdfas.common.exceptions.PDFASError;
 import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
 import at.gv.egiz.pdfas.lib.impl.verify.VerifyResultImpl;
 
-public class SignatureUtils {
+public class SignatureUtils implements ErrorConstants {
 
 	private static final Logger logger = LoggerFactory
 			.getLogger(SignatureUtils.class);
@@ -68,7 +69,7 @@ public class SignatureUtils {
 	}
 
 	
-	public static VerifyResult verifySignature(byte[] signature, byte[] input) throws PdfAsSignatureException {
+	public static VerifyResult verifySignature(byte[] signature, byte[] input) throws PDFASError {
 		//List<VerifyResult> results = new ArrayList<VerifyResult>();
 		try {
 			SignedData signedData = new SignedData(new ByteArrayInputStream(
@@ -79,11 +80,13 @@ public class SignatureUtils {
 			// get the signer infos
 			SignerInfo[] signerInfos = signedData.getSignerInfos();
 			if (signerInfos.length == 0) {
-				throw new PdfAsSignatureException("Invalid Signature (no signer info created!)", null);
+				logger.error("Invalid signature (no signer information)");
+				throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG);
 			}
 			
 			if (signerInfos.length != 1) {
-				throw new PdfAsSignatureException("Invalid Signature (multiple signer infos found!)", null);
+				logger.error("Invalid signature (multiple signer information)");
+				throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG);
 			}
 			// verify the signatures
 			//for (int i = 0; i < signerInfos.length; i++) {
@@ -114,15 +117,15 @@ public class SignatureUtils {
 					verifyResult.setSignerCertificate(signedData
 							.getCertificate(signerInfos[0]
 									.getSignerIdentifier()));
-					throw new PdfAsSignatureException("error.pdf.sig.08", ex);
+					throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG, ex);
 				}
 				
 				return verifyResult;
 			//}
 		} catch (CMSException e) {
-			throw new PdfAsSignatureException("error.pdf.sig.08", e);
+			throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG, e);
 		} catch (IOException e) {
-			throw new PdfAsSignatureException("error.pdf.sig.08", e);
+			throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG, e);
 		}
 		
 		
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java
index 82dc0602..19dc3d76 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java
@@ -27,17 +27,17 @@ import iaik.x509.X509Certificate;
 
 import java.security.cert.CertificateException;
 import java.util.Iterator;
-import java.util.List;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import at.gv.egiz.pdfas.common.exceptions.PDFASError;
+import at.gv.egiz.pdfas.common.exceptions.PdfAsErrorCarrier;
 import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
 import at.gv.egiz.pdfas.common.exceptions.PdfAsSignatureException;
 import at.gv.egiz.pdfas.common.utils.StreamUtils;
 import at.gv.egiz.pdfas.lib.api.sign.SignParameter;
 import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
-import at.gv.egiz.pdfas.lib.impl.SignResultImpl;
 import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;
 import at.gv.egiz.pdfas.lib.util.SignatureUtils;
 import at.gv.egiz.sl.schema.CreateCMSSignatureResponseType;
@@ -90,7 +90,12 @@ public class ISignatureConnectorSLWrapper implements ISignatureConnector {
 		CreateCMSSignatureResponseType response = connector
 				.sendCMSRequest(pack, parameter);
 		
-		VerifyResult verifyResult = SignatureUtils.verifySignature(response.getCMSSignature(), input);
+		VerifyResult verifyResult;
+		try {
+			verifyResult = SignatureUtils.verifySignature(response.getCMSSignature(), input);
+		} catch (PDFASError e) {
+			throw new PdfAsErrorCarrier(e);
+		}
 
 		if(!StreamUtils.dataCompare(requestedSignature.getCertificate().getFingerprintSHA(),
 				((X509Certificate)verifyResult.getSignerCertificate()).getFingerprintSHA())) {
-- 
cgit v1.2.3