aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas <>2023-01-12 14:50:17 +0100
committerThomas <>2023-01-12 14:50:17 +0100
commit061129ed699a214818e7f62e2850fbe3b8b7b0ab (patch)
treef353ff2dfa1425f505a8a26fae6c2cfa45b151d6
parentbb091b59b99e5c4f0f365f7515f4b6095462b626 (diff)
downloadpdf-as-4-061129ed699a214818e7f62e2850fbe3b8b7b0ab.tar.gz
pdf-as-4-061129ed699a214818e7f62e2850fbe3b8b7b0ab.tar.bz2
pdf-as-4-061129ed699a214818e7f62e2850fbe3b8b7b0ab.zip
chore(sl): check Security-Layer error-codes to distinguish between critical and non-critical errors
Issue: #71
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/SLPdfAsException.java15
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java1009
2 files changed, 529 insertions, 495 deletions
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/SLPdfAsException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/SLPdfAsException.java
index a0ee44d9..e7aa6099 100644
--- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/SLPdfAsException.java
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/SLPdfAsException.java
@@ -23,8 +23,13 @@
******************************************************************************/
package at.gv.egiz.pdfas.common.exceptions;
+import java.util.Arrays;
+import java.util.List;
+
public class SLPdfAsException extends PdfAsException {
+ private static final List<Integer> ERRORCODES_ON_INFO_LEVEL = Arrays.asList(6001);
+
/**
*
*/
@@ -47,6 +52,16 @@ public class SLPdfAsException extends PdfAsException {
return info;
}
+ /**
+ * Classify SL error between critical and non-critical types.
+ *
+ * @return <code>true</code> in case of a critical error, otherwise <code>false</code>
+ */
+ public boolean isCriticalError() {
+ return !ERRORCODES_ON_INFO_LEVEL.contains(code);
+
+ }
+
protected String localizeMessage(String msgId) {
return String.format("%d : %s", code, info);
}
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 bca1ff2b..47e46bcf 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
@@ -3,19 +3,19 @@
* 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
@@ -23,9 +23,6 @@
******************************************************************************/
package at.gv.egiz.pdfas.lib.impl;
-import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
-import iaik.x509.X509Certificate;
-
import java.awt.Image;
import java.io.File;
import java.io.IOException;
@@ -40,6 +37,7 @@ 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.SLPdfAsException;
import at.gv.egiz.pdfas.common.settings.ISettings;
import at.gv.egiz.pdfas.common.utils.PDFUtils;
import at.gv.egiz.pdfas.common.utils.StreamUtils;
@@ -59,504 +57,525 @@ import at.gv.egiz.pdfas.lib.impl.preprocessor.PreProcessorLoader;
import at.gv.egiz.pdfas.lib.impl.signing.IPdfSigner;
import at.gv.egiz.pdfas.lib.impl.signing.PDFASSignatureExtractor;
import at.gv.egiz.pdfas.lib.impl.status.OperationStatus;
+import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;
import at.gv.egiz.pdfas.lib.settings.Settings;
import at.gv.egiz.pdfas.lib.util.SignatureUtils;
import at.gv.egiz.sl.util.BKUHeader;
+import iaik.x509.X509Certificate;
public class PdfAsImpl implements PdfAs, IConfigurationConstants,
- ErrorConstants {
+ ErrorConstants {
- private static final Logger logger = LoggerFactory
- .getLogger(PdfAsImpl.class);
+ private static final Logger logger = LoggerFactory
+ .getLogger(PdfAsImpl.class);
- private ISettings settings;
+ private final ISettings settings;
- public PdfAsImpl(File cfgFile) {
- logger.debug("Initializing PDF-AS with config: " + cfgFile.getPath());
- this.settings = new Settings(cfgFile);
- }
+ public PdfAsImpl(File cfgFile) {
+ logger.debug("Initializing PDF-AS with config: " + cfgFile.getPath());
+ this.settings = new Settings(cfgFile);
+ }
- public PdfAsImpl(ISettings cfgObject) {
- logger.info("Initializing PDF-AS with config: "
- + cfgObject.getClass().getName());
- this.settings = cfgObject;
- }
+ public PdfAsImpl(ISettings cfgObject) {
+ logger.info("Initializing PDF-AS with config: "
+ + cfgObject.getClass().getName());
+ this.settings = cfgObject;
+ }
- private void verifySignParameter(SignParameter parameter) throws PDFASError {
- // Status initialization
- if (!(parameter.getConfiguration() instanceof ISettings)) {
- throw new PDFASError(ERROR_SET_INVALID_SETTINGS_OBJ);
- }
-
- ISettings settings = (ISettings) parameter.getConfiguration();
-
- String signatureProfile = parameter.getSignatureProfileId();
- if (signatureProfile != null) {
- if (!settings.hasPrefix("sig_obj." + signatureProfile)) {
- throw new PDFASError(ERROR_SIG_INVALID_PROFILE,
- PDFASError.buildInfoString(ERROR_SIG_INVALID_PROFILE,
- signatureProfile));
- }
- }
-
- if (parameter.getDataSource() == null) {
- throw new PDFASError(ERROR_NO_INPUT);
- }
-
- }
-
- private void verifyVerifyParameter(VerifyParameter parameter)
- throws PDFASError {
- // Status initialization
- if (!(parameter.getConfiguration() instanceof ISettings)) {
- throw new PDFASError(ERROR_SET_INVALID_SETTINGS_OBJ);
- }
-
- if (parameter.getDataSource() == null) {
- throw new PDFASError(ERROR_NO_INPUT);
- }
- }
-
- public SignResult sign(SignParameter parameter) throws PDFASError {
-
- logger.trace("sign started");
-
- verifySignParameter(parameter);
- OperationStatus status = null;
- try {
- // Status initialization
- if (!(parameter.getConfiguration() instanceof ISettings)) {
- throw new PdfAsSettingsException("Invalid settings object!");
- }
-
- // execute pre Processors
- signPreProcessing(parameter);
-
- // allocated Backend
- PDFASBackend backend = BackendLoader.getPDFASBackend(parameter.getConfiguration());
-
- if (backend == null) {
- throw new PDFASError(ERROR_NO_BACKEND);
- }
-
- ISettings settings = (ISettings) parameter.getConfiguration();
- status = new OperationStatus(settings, parameter, backend);
-
- IPdfSigner signer = backend.getPdfSigner();
-
-
- PDFObject pdfObject = signer.buildPDFObject(status);
-
- status.setPdfObject(pdfObject);
-
- // set Original PDF Document Data
- status.getPdfObject()
- .setOriginalDocument(parameter.getDataSource());
-
- // Check PDF Permissions
- signer.checkPDFPermissions(status.getPdfObject());
-
- // PlaceholderConfiguration placeholderConfiguration = status
- // .getPlaceholderConfiguration();
-
- RequestedSignature requestedSignature = new RequestedSignature(
- status);
-
- status.setRequestedSignature(requestedSignature);
-
- try {
- requestedSignature.setCertificate(status.getSignParamter()
- .getPlainSigner().getCertificate(parameter));
- } finally {
- if (parameter instanceof BKUHeaderHolder) {
- BKUHeaderHolder holder = (BKUHeaderHolder) parameter;
-
- Iterator<BKUHeader> bkuHeaderIt = holder.getProcessInfo()
- .iterator();
-
- while (bkuHeaderIt.hasNext()) {
- BKUHeader header = bkuHeaderIt.next();
- if ("Server".equalsIgnoreCase(header.getName())) {
- requestedSignature
- .getStatus()
- .getMetaInformations()
- .put(ErrorConstants.STATUS_INFO_SIGDEVICEVERSION,
- header.getValue());
- } else if (ErrorConstants.STATUS_INFO_SIGDEVICE.equalsIgnoreCase(header.getName())) {
- requestedSignature
- .getStatus()
- .getMetaInformations()
- .put(ErrorConstants.STATUS_INFO_SIGDEVICE,
- header.getValue());
- }
- }
- }
- }
- // Only use this profileID because validation was done in
- // RequestedSignature
- String signatureProfileID = requestedSignature
- .getSignatureProfileID();
-
- logger.info("Selected signature Profile: " + signatureProfileID);
-
- // SignatureProfileConfiguration signatureProfileConfiguration =
- // status
- // .getSignatureProfileConfiguration(signatureProfileID);
-
- // this.stampPdf(status);
-
- // Create signature
- try {
- signer.signPDF(status.getPdfObject(), requestedSignature, signer
- .buildSignaturInterface(status.getSignParamter()
- .getPlainSigner(), parameter, requestedSignature));
- } finally {
- if (parameter instanceof BKUHeaderHolder) {
- BKUHeaderHolder holder = (BKUHeaderHolder) parameter;
-
- Iterator<BKUHeader> bkuHeaderIt = holder.getProcessInfo()
- .iterator();
-
- while (bkuHeaderIt.hasNext()) {
- BKUHeader header = bkuHeaderIt.next();
- if ("Server".equalsIgnoreCase(header.getName())) {
- requestedSignature
- .getStatus()
- .getMetaInformations()
- .put(ErrorConstants.STATUS_INFO_SIGDEVICEVERSION,
- header.getValue());
- } else if (ErrorConstants.STATUS_INFO_SIGDEVICE.equalsIgnoreCase(header.getName())) {
- requestedSignature
- .getStatus()
- .getMetaInformations()
- .put(ErrorConstants.STATUS_INFO_SIGDEVICE,
- header.getValue());
- }
- }
- }
- }
- // ================================================================
- // Create SignResult
- SignResult result = createSignResult(status);
-
- return result;
- } catch (Throwable e) {
- logger.warn("Failed to create signature [" + e.getMessage() + "]",
- e);
- throw ErrorExtractor.searchPdfAsError(e, status);
- } finally {
- if (status != null) {
- status.clear();
- }
- logger.trace("sign done");
- }
- }
-
- public List<VerifyResult> verify(VerifyParameter parameter)
- throws PDFASError {
-
- verifyVerifyParameter(parameter);
-
- // execute pre Processors
- verifyPreProcessing(parameter);
-
- // allocated Backend
- PDFASBackend backend = BackendLoader.getPDFASBackend(parameter.getConfiguration());
-
- if (backend == null) {
- throw new PDFASError(ERROR_NO_BACKEND);
- }
-
- try {
- return backend.getVerifier().verify(parameter);
- } catch (Throwable e) {
- throw ErrorExtractor.searchPdfAsError(e, null);
- }
- }
-
- public Configuration getConfiguration() {
- return new ConfigurationImpl(this.settings);
- }
-
- public StatusRequest startSign(SignParameter parameter) throws PDFASError {
-
- verifySignParameter(parameter);
-
- StatusRequestImpl request = new StatusRequestImpl();
- OperationStatus status = null;
- try {
- // Status initialization
- if (!(parameter.getConfiguration() instanceof ISettings)) {
- throw new PdfAsSettingsException("Invalid settings object!");
- }
-
- // execute pre Processors
- signPreProcessing(parameter);
-
- // allocated Backend
- PDFASBackend backend = BackendLoader.getPDFASBackend(parameter.getConfiguration());
-
- if (backend == null) {
- throw new PDFASError(ERROR_NO_BACKEND);
- }
-
- ISettings settings = (ISettings) parameter.getConfiguration();
- status = new OperationStatus(settings, parameter,
- backend);
-
- IPdfSigner signer = backend.getPdfSigner();
-
- status.setPdfObject(signer.buildPDFObject(status));
-
- RequestedSignature requestedSignature = new RequestedSignature(
- status);
-
- status.setRequestedSignature(requestedSignature);
-
- request.setStatus(status);
-
- request.setNeedCertificate(true);
-
- return request;
- } catch (Throwable e) {
- logger.warn("startSign", e);
- throw ErrorExtractor.searchPdfAsError(e, status);
- }
- }
-
- public StatusRequest process(StatusRequest statusRequest) throws PDFASError {
- if (!(statusRequest instanceof StatusRequestImpl)) {
- throw new PDFASError(ERROR_SIG_INVALID_STATUS);
- }
-
- StatusRequestImpl request = (StatusRequestImpl) statusRequest;
- OperationStatus status = request.getStatus();
-
- if (request.needCertificate()) {
- try {
- status.getRequestedSignature().setCertificate(
- request.getCertificate());
-
- // set Original PDF Document Data
- status.getPdfObject().setOriginalDocument(
- status.getSignParamter().getDataSource());
-
- // STAMPER!
- // stampPdf(status);
- request.setNeedCertificate(false);
-
- status.setSigningDate(Calendar.getInstance());
-
- // GET Signature DATA
- String pdfFilter = status.getSignParamter().getPlainSigner()
- .getPDFFilter();
- String pdfSubFilter = status.getSignParamter().getPlainSigner()
- .getPDFSubFilter();
-
- IPdfSigner signer = status.getBackend().getPdfSigner();
-
- PDFASSignatureExtractor signatureDataExtractor = signer
- .buildBlindSignaturInterface(request.getCertificate(),
- pdfFilter, pdfSubFilter,
- status.getSigningDate());
-
- signer.signPDF(status.getPdfObject(),
- status.getRequestedSignature(), signatureDataExtractor);
-
- StringBuilder sb = new StringBuilder();
-
- int[] byteRange = PDFUtils
- .extractSignatureByteRange(signatureDataExtractor
- .getSignatureData());
-
- for (int i = 0; i < byteRange.length; i++) {
- sb.append(" " + byteRange[i]);
- }
- logger.debug("ByteRange: " + sb.toString());
-
- request.setSignatureData(signatureDataExtractor
- .getSignatureData());
- request.setByteRange(byteRange);
- request.setNeedSignature(true);
-
- } catch (Throwable e) {
- logger.warn("process", e);
- throw ErrorExtractor.searchPdfAsError(e, status);
- }
- } else if (request.needSignature()) {
- request.setNeedSignature(false);
- // Inject signature byte[] into signedDocument
- int offset = request.getSignatureDataByteRange()[1] + 1;
-
- byte[] pdfSignature = status.getBackend().getPdfSigner()
- .rewritePlainSignature(request.getSignature());
- // byte[] input =
- // PDFUtils.blackOutSignature(status.getPdfObject().getSignedDocument(),
- // request.getSignatureDataByteRange());
- VerifyResult verifyResult = SignatureUtils.verifySignature(
- request.getSignature(), request.getSignatureData());
- RequestedSignature requestedSignature = request.getStatus()
- .getRequestedSignature();
-
- if (!StreamUtils.dataCompare(requestedSignature.getCertificate()
- .getFingerprintSHA(), ((X509Certificate) verifyResult
- .getSignerCertificate()).getFingerprintSHA())) {
- throw new PDFASError(ERROR_SIG_CERTIFICATE_MISSMATCH);
- }
-
- for (int i = 0; i < pdfSignature.length; i++) {
- status.getPdfObject().getSignedDocument()[offset + i] = pdfSignature[i];
- }
- request.setIsReady(true);
- } else {
- throw new PDFASError(ERROR_SIG_INVALID_STATUS);
- }
-
- return request;
- }
-
- public SignResult finishSign(StatusRequest statusRequest) throws PDFASError {
- if (!(statusRequest instanceof StatusRequestImpl)) {
- throw new PDFASError(ERROR_SIG_INVALID_STATUS);
- }
-
- StatusRequestImpl request = (StatusRequestImpl) statusRequest;
- OperationStatus status = request.getStatus();
-
- if (!request.isReady()) {
- throw new PDFASError(ERROR_SIG_INVALID_STATUS);
- }
-
- try {
- return createSignResult(status);
- } catch (IOException e) {
- // new PdfAsException("error.pdf.sig.06", e);
- throw ErrorExtractor.searchPdfAsError(e, status);
- } finally {
- if (status != null) {
- status.clear();
- }
- }
- }
-
- private void listPreProcessors(List<PreProcessor> preProcessors) {
- logger.debug("--------------");
- logger.debug("Listing PreProcessors:");
-
- Iterator<PreProcessor> preProcessorsIterator = preProcessors.iterator();
- int idx = 0;
- while (preProcessorsIterator.hasNext()) {
- PreProcessor preProcessor = preProcessorsIterator.next();
- logger.debug("{}: {} [{}]", idx, preProcessor.getName(),
- preProcessor.getClass().getName());
- idx++;
- }
- logger.debug("--------------");
- }
-
- private void verifyPreProcessing(VerifyParameter parameter)
- throws PDFASError {
- List<PreProcessor> preProcessors = PreProcessorLoader
- .getPreProcessors(parameter.getConfiguration());
-
- listPreProcessors(preProcessors);
-
- logger.debug("executing PreProcessors for verifing:");
- Iterator<PreProcessor> preProcessorsIterator = preProcessors.iterator();
-
- while (preProcessorsIterator.hasNext()) {
- PreProcessor preProcessor = preProcessorsIterator.next();
- logger.debug("executing: {} [{}]", preProcessor.getName(),
- preProcessor.getClass().getName());
- preProcessor.verify(parameter);
- logger.debug("done executing: {} [{}]", preProcessor.getName(),
- preProcessor.getClass().getName());
- }
-
- logger.debug("executing PreProcessors for verifing done");
- }
-
- private void signPreProcessing(SignParameter parameter) throws PDFASError {
- List<PreProcessor> preProcessors = PreProcessorLoader
- .getPreProcessors(parameter.getConfiguration());
-
- listPreProcessors(preProcessors);
-
- logger.debug("executing PreProcessors for signing:");
- Iterator<PreProcessor> preProcessorsIterator = preProcessors.iterator();
-
- while (preProcessorsIterator.hasNext()) {
- PreProcessor preProcessor = preProcessorsIterator.next();
- logger.debug("executing: {} [{}]", preProcessor.getName(),
- preProcessor.getClass().getName());
- preProcessor.sign(parameter);
- logger.debug("done executing: {} [{}]", preProcessor.getName(),
- preProcessor.getClass().getName());
- }
-
- logger.debug("executing PreProcessors for signing done");
- }
-
- private SignResult createSignResult(OperationStatus status)
- throws IOException {
- // ================================================================
- // Create SignResult
- SignResultImpl result = new SignResultImpl();
- status.getSignParamter().getSignatureResult().write(status.getPdfObject().getSignedDocument());
- status.getSignParamter().getSignatureResult().flush();
- result.setSignerCertificate(status.getRequestedSignature()
- .getCertificate());
- result.setSignaturePosition(status.getRequestedSignature()
- .getSignaturePosition());
- result.getProcessInformations().putAll(status.getMetaInformations());
- return result;
- }
-
- public Image generateVisibleSignaturePreview(SignParameter parameter,
- java.security.cert.X509Certificate cert, int resolution)
- throws PDFASError {
-
- OperationStatus status = null;
- try {
- // Status initialization
- if (!(parameter.getConfiguration() instanceof ISettings)) {
- throw new PDFASError(ERROR_SET_INVALID_SETTINGS_OBJ);
- }
- X509Certificate iaikCert;
- if (!(cert instanceof X509Certificate)) {
- iaikCert = new X509Certificate(cert.getEncoded());
- } else {
- iaikCert = (X509Certificate) cert;
- }
- // allocated Backend
- PDFASBackend backend = BackendLoader.getPDFASBackend(parameter.getConfiguration());
-
- ISettings settings = (ISettings) parameter.getConfiguration();
- status = new OperationStatus(settings, parameter, backend);
-
- IPdfSigner signer = backend.getPdfSigner();
-
- status.setPdfObject(signer.buildPDFObject(status));
-
- RequestedSignature requestedSignature = new RequestedSignature(
- status);
- requestedSignature.setCertificate(iaikCert);
-
- if (!requestedSignature.isVisual()) {
- logger.warn("Profile is invisible so not block image is generated");
- return null;
- }
-
- return signer.generateVisibleSignaturePreview(parameter, iaikCert,
- resolution, status, requestedSignature);
- } catch (PdfAsException e) {
- logger.warn("PDF-AS Exception", e);
- throw ErrorExtractor.searchPdfAsError(e, status);
- } catch (Throwable e) {
- logger.warn("Throwable Exception", e);
- throw ErrorExtractor.searchPdfAsError(e, status);
- }
-
- }
+ private void verifySignParameter(SignParameter parameter) throws PDFASError {
+ // Status initialization
+ if (!(parameter.getConfiguration() instanceof ISettings)) {
+ throw new PDFASError(ERROR_SET_INVALID_SETTINGS_OBJ);
+ }
+
+ final ISettings settings = (ISettings) parameter.getConfiguration();
+
+ final String signatureProfile = parameter.getSignatureProfileId();
+ if (signatureProfile != null) {
+ if (!settings.hasPrefix("sig_obj." + signatureProfile)) {
+ throw new PDFASError(ERROR_SIG_INVALID_PROFILE,
+ PDFASError.buildInfoString(ERROR_SIG_INVALID_PROFILE,
+ signatureProfile));
+ }
+ }
+
+ if (parameter.getDataSource() == null) {
+ throw new PDFASError(ERROR_NO_INPUT);
+ }
+
+ }
+
+ private void verifyVerifyParameter(VerifyParameter parameter)
+ throws PDFASError {
+ // Status initialization
+ if (!(parameter.getConfiguration() instanceof ISettings)) {
+ throw new PDFASError(ERROR_SET_INVALID_SETTINGS_OBJ);
+ }
+
+ if (parameter.getDataSource() == null) {
+ throw new PDFASError(ERROR_NO_INPUT);
+ }
+ }
+
+ @Override
+ public SignResult sign(SignParameter parameter) throws PDFASError {
+
+ logger.trace("sign started");
+
+ verifySignParameter(parameter);
+ OperationStatus status = null;
+ try {
+ // Status initialization
+ if (!(parameter.getConfiguration() instanceof ISettings)) {
+ throw new PdfAsSettingsException("Invalid settings object!");
+ }
+
+ // execute pre Processors
+ signPreProcessing(parameter);
+
+ // allocated Backend
+ final PDFASBackend backend = BackendLoader.getPDFASBackend(parameter.getConfiguration());
+
+ if (backend == null) {
+ throw new PDFASError(ERROR_NO_BACKEND);
+ }
+
+ final ISettings settings = (ISettings) parameter.getConfiguration();
+ status = new OperationStatus(settings, parameter, backend);
+
+ final IPdfSigner signer = backend.getPdfSigner();
+
+ final PDFObject pdfObject = signer.buildPDFObject(status);
+
+ status.setPdfObject(pdfObject);
+
+ // set Original PDF Document Data
+ status.getPdfObject()
+ .setOriginalDocument(parameter.getDataSource());
+
+ // Check PDF Permissions
+ signer.checkPDFPermissions(status.getPdfObject());
+
+ // PlaceholderConfiguration placeholderConfiguration = status
+ // .getPlaceholderConfiguration();
+
+ final RequestedSignature requestedSignature = new RequestedSignature(
+ status);
+
+ status.setRequestedSignature(requestedSignature);
+
+ try {
+ requestedSignature.setCertificate(status.getSignParamter().getPlainSigner().getCertificate(parameter));
+
+ } finally {
+ if (parameter instanceof BKUHeaderHolder) {
+ final BKUHeaderHolder holder = (BKUHeaderHolder) parameter;
+
+ final Iterator<BKUHeader> bkuHeaderIt = holder.getProcessInfo()
+ .iterator();
+
+ while (bkuHeaderIt.hasNext()) {
+ final BKUHeader header = bkuHeaderIt.next();
+ if ("Server".equalsIgnoreCase(header.getName())) {
+ requestedSignature
+ .getStatus()
+ .getMetaInformations()
+ .put(ErrorConstants.STATUS_INFO_SIGDEVICEVERSION,
+ header.getValue());
+ } else if (ErrorConstants.STATUS_INFO_SIGDEVICE.equalsIgnoreCase(header.getName())) {
+ requestedSignature
+ .getStatus()
+ .getMetaInformations()
+ .put(ErrorConstants.STATUS_INFO_SIGDEVICE,
+ header.getValue());
+ }
+ }
+ }
+ }
+ // Only use this profileID because validation was done in
+ // RequestedSignature
+ final String signatureProfileID = requestedSignature
+ .getSignatureProfileID();
+
+ logger.info("Selected signature Profile: " + signatureProfileID);
+
+ // SignatureProfileConfiguration signatureProfileConfiguration =
+ // status
+ // .getSignatureProfileConfiguration(signatureProfileID);
+
+ // this.stampPdf(status);
+
+ // Create signature
+ try {
+ signer.signPDF(status.getPdfObject(), requestedSignature, signer
+ .buildSignaturInterface(status.getSignParamter()
+ .getPlainSigner(), parameter, requestedSignature));
+ } finally {
+ if (parameter instanceof BKUHeaderHolder) {
+ final BKUHeaderHolder holder = (BKUHeaderHolder) parameter;
+
+ final Iterator<BKUHeader> bkuHeaderIt = holder.getProcessInfo()
+ .iterator();
+
+ while (bkuHeaderIt.hasNext()) {
+ final BKUHeader header = bkuHeaderIt.next();
+ if ("Server".equalsIgnoreCase(header.getName())) {
+ requestedSignature
+ .getStatus()
+ .getMetaInformations()
+ .put(ErrorConstants.STATUS_INFO_SIGDEVICEVERSION,
+ header.getValue());
+ } else if (ErrorConstants.STATUS_INFO_SIGDEVICE.equalsIgnoreCase(header.getName())) {
+ requestedSignature
+ .getStatus()
+ .getMetaInformations()
+ .put(ErrorConstants.STATUS_INFO_SIGDEVICE,
+ header.getValue());
+ }
+ }
+ }
+ }
+ // ================================================================
+ // Create SignResult
+ final SignResult result = createSignResult(status);
+
+ return result;
+
+ } catch (final SLPdfAsException e) {
+ if (e.isCriticalError()) {
+ logger.warn("Failed to create signature [" + e.getMessage() + "]", e);
+
+ } else {
+ logger.info("Failed to create signature [" + e.getMessage() + "]", e);
+
+ }
+ throw ErrorExtractor.searchPdfAsError(e, status);
+
+ } catch (final Throwable e) {
+ logger.warn("Failed to create signature [" + e.getMessage() + "]", e);
+ throw ErrorExtractor.searchPdfAsError(e, status);
+
+
+ } finally {
+ if (status != null) {
+ status.clear();
+
+ }
+ logger.trace("sign done");
+ }
+ }
+
+ @Override
+ public List<VerifyResult> verify(VerifyParameter parameter)
+ throws PDFASError {
+
+ verifyVerifyParameter(parameter);
+
+ // execute pre Processors
+ verifyPreProcessing(parameter);
+
+ // allocated Backend
+ final PDFASBackend backend = BackendLoader.getPDFASBackend(parameter.getConfiguration());
+
+ if (backend == null) {
+ throw new PDFASError(ERROR_NO_BACKEND);
+ }
+
+ try {
+ return backend.getVerifier().verify(parameter);
+ } catch (final Throwable e) {
+ throw ErrorExtractor.searchPdfAsError(e, null);
+ }
+ }
+
+ @Override
+ public Configuration getConfiguration() {
+ return new ConfigurationImpl(this.settings);
+ }
+
+ @Override
+ public StatusRequest startSign(SignParameter parameter) throws PDFASError {
+
+ verifySignParameter(parameter);
+
+ final StatusRequestImpl request = new StatusRequestImpl();
+ OperationStatus status = null;
+ try {
+ // Status initialization
+ if (!(parameter.getConfiguration() instanceof ISettings)) {
+ throw new PdfAsSettingsException("Invalid settings object!");
+ }
+
+ // execute pre Processors
+ signPreProcessing(parameter);
+
+ // allocated Backend
+ final PDFASBackend backend = BackendLoader.getPDFASBackend(parameter.getConfiguration());
+
+ if (backend == null) {
+ throw new PDFASError(ERROR_NO_BACKEND);
+ }
+
+ final ISettings settings = (ISettings) parameter.getConfiguration();
+ status = new OperationStatus(settings, parameter,
+ backend);
+
+ final IPdfSigner signer = backend.getPdfSigner();
+
+ status.setPdfObject(signer.buildPDFObject(status));
+
+ final RequestedSignature requestedSignature = new RequestedSignature(
+ status);
+
+ status.setRequestedSignature(requestedSignature);
+
+ request.setStatus(status);
+
+ request.setNeedCertificate(true);
+
+ return request;
+ } catch (final Throwable e) {
+ logger.warn("startSign", e);
+ throw ErrorExtractor.searchPdfAsError(e, status);
+ }
+ }
+
+ @Override
+ public StatusRequest process(StatusRequest statusRequest) throws PDFASError {
+ if (!(statusRequest instanceof StatusRequestImpl)) {
+ throw new PDFASError(ERROR_SIG_INVALID_STATUS);
+ }
+
+ final StatusRequestImpl request = (StatusRequestImpl) statusRequest;
+ final OperationStatus status = request.getStatus();
+
+ if (request.needCertificate()) {
+ try {
+ status.getRequestedSignature().setCertificate(
+ request.getCertificate());
+
+ // set Original PDF Document Data
+ status.getPdfObject().setOriginalDocument(
+ status.getSignParamter().getDataSource());
+
+ // STAMPER!
+ // stampPdf(status);
+ request.setNeedCertificate(false);
+
+ status.setSigningDate(Calendar.getInstance());
+
+ // GET Signature DATA
+ final String pdfFilter = status.getSignParamter().getPlainSigner()
+ .getPDFFilter();
+ final String pdfSubFilter = status.getSignParamter().getPlainSigner()
+ .getPDFSubFilter();
+
+ final IPdfSigner signer = status.getBackend().getPdfSigner();
+
+ final PDFASSignatureExtractor signatureDataExtractor = signer
+ .buildBlindSignaturInterface(request.getCertificate(),
+ pdfFilter, pdfSubFilter,
+ status.getSigningDate());
+
+ signer.signPDF(status.getPdfObject(),
+ status.getRequestedSignature(), signatureDataExtractor);
+
+ final StringBuilder sb = new StringBuilder();
+
+ final int[] byteRange = PDFUtils
+ .extractSignatureByteRange(signatureDataExtractor
+ .getSignatureData());
+
+ for (final int element : byteRange) {
+ sb.append(" " + element);
+ }
+ logger.debug("ByteRange: " + sb.toString());
+
+ request.setSignatureData(signatureDataExtractor
+ .getSignatureData());
+ request.setByteRange(byteRange);
+ request.setNeedSignature(true);
+
+ } catch (final Throwable e) {
+ logger.warn("process", e);
+ throw ErrorExtractor.searchPdfAsError(e, status);
+ }
+ } else if (request.needSignature()) {
+ request.setNeedSignature(false);
+ // Inject signature byte[] into signedDocument
+ final int offset = request.getSignatureDataByteRange()[1] + 1;
+
+ final byte[] pdfSignature = status.getBackend().getPdfSigner()
+ .rewritePlainSignature(request.getSignature());
+ // byte[] input =
+ // PDFUtils.blackOutSignature(status.getPdfObject().getSignedDocument(),
+ // request.getSignatureDataByteRange());
+ final VerifyResult verifyResult = SignatureUtils.verifySignature(
+ request.getSignature(), request.getSignatureData());
+ final RequestedSignature requestedSignature = request.getStatus()
+ .getRequestedSignature();
+
+ if (!StreamUtils.dataCompare(requestedSignature.getCertificate()
+ .getFingerprintSHA(), ((X509Certificate) verifyResult
+ .getSignerCertificate()).getFingerprintSHA())) {
+ throw new PDFASError(ERROR_SIG_CERTIFICATE_MISSMATCH);
+ }
+
+ for (int i = 0; i < pdfSignature.length; i++) {
+ status.getPdfObject().getSignedDocument()[offset + i] = pdfSignature[i];
+ }
+ request.setIsReady(true);
+ } else {
+ throw new PDFASError(ERROR_SIG_INVALID_STATUS);
+ }
+
+ return request;
+ }
+
+ @Override
+ public SignResult finishSign(StatusRequest statusRequest) throws PDFASError {
+ if (!(statusRequest instanceof StatusRequestImpl)) {
+ throw new PDFASError(ERROR_SIG_INVALID_STATUS);
+ }
+
+ final StatusRequestImpl request = (StatusRequestImpl) statusRequest;
+ final OperationStatus status = request.getStatus();
+
+ if (!request.isReady()) {
+ throw new PDFASError(ERROR_SIG_INVALID_STATUS);
+ }
+
+ try {
+ return createSignResult(status);
+ } catch (final IOException e) {
+ // new PdfAsException("error.pdf.sig.06", e);
+ throw ErrorExtractor.searchPdfAsError(e, status);
+ } finally {
+ if (status != null) {
+ status.clear();
+ }
+ }
+ }
+
+ private void listPreProcessors(List<PreProcessor> preProcessors) {
+ logger.debug("--------------");
+ logger.debug("Listing PreProcessors:");
+
+ final Iterator<PreProcessor> preProcessorsIterator = preProcessors.iterator();
+ int idx = 0;
+ while (preProcessorsIterator.hasNext()) {
+ final PreProcessor preProcessor = preProcessorsIterator.next();
+ logger.debug("{}: {} [{}]", idx, preProcessor.getName(),
+ preProcessor.getClass().getName());
+ idx++;
+ }
+ logger.debug("--------------");
+ }
+
+ private void verifyPreProcessing(VerifyParameter parameter)
+ throws PDFASError {
+ final List<PreProcessor> preProcessors = PreProcessorLoader
+ .getPreProcessors(parameter.getConfiguration());
+
+ listPreProcessors(preProcessors);
+
+ logger.debug("executing PreProcessors for verifing:");
+ final Iterator<PreProcessor> preProcessorsIterator = preProcessors.iterator();
+
+ while (preProcessorsIterator.hasNext()) {
+ final PreProcessor preProcessor = preProcessorsIterator.next();
+ logger.debug("executing: {} [{}]", preProcessor.getName(),
+ preProcessor.getClass().getName());
+ preProcessor.verify(parameter);
+ logger.debug("done executing: {} [{}]", preProcessor.getName(),
+ preProcessor.getClass().getName());
+ }
+
+ logger.debug("executing PreProcessors for verifing done");
+ }
+
+ private void signPreProcessing(SignParameter parameter) throws PDFASError {
+ final List<PreProcessor> preProcessors = PreProcessorLoader
+ .getPreProcessors(parameter.getConfiguration());
+
+ listPreProcessors(preProcessors);
+
+ logger.debug("executing PreProcessors for signing:");
+ final Iterator<PreProcessor> preProcessorsIterator = preProcessors.iterator();
+
+ while (preProcessorsIterator.hasNext()) {
+ final PreProcessor preProcessor = preProcessorsIterator.next();
+ logger.debug("executing: {} [{}]", preProcessor.getName(),
+ preProcessor.getClass().getName());
+ preProcessor.sign(parameter);
+ logger.debug("done executing: {} [{}]", preProcessor.getName(),
+ preProcessor.getClass().getName());
+ }
+
+ logger.debug("executing PreProcessors for signing done");
+ }
+
+ private SignResult createSignResult(OperationStatus status)
+ throws IOException {
+ // ================================================================
+ // Create SignResult
+ final SignResultImpl result = new SignResultImpl();
+ status.getSignParamter().getSignatureResult().write(status.getPdfObject().getSignedDocument());
+ status.getSignParamter().getSignatureResult().flush();
+ result.setSignerCertificate(status.getRequestedSignature()
+ .getCertificate());
+ result.setSignaturePosition(status.getRequestedSignature()
+ .getSignaturePosition());
+ result.getProcessInformations().putAll(status.getMetaInformations());
+ return result;
+ }
+
+ @Override
+ public Image generateVisibleSignaturePreview(SignParameter parameter,
+ java.security.cert.X509Certificate cert, int resolution)
+ throws PDFASError {
+
+ OperationStatus status = null;
+ try {
+ // Status initialization
+ if (!(parameter.getConfiguration() instanceof ISettings)) {
+ throw new PDFASError(ERROR_SET_INVALID_SETTINGS_OBJ);
+ }
+ X509Certificate iaikCert;
+ if (!(cert instanceof X509Certificate)) {
+ iaikCert = new X509Certificate(cert.getEncoded());
+ } else {
+ iaikCert = (X509Certificate) cert;
+ }
+ // allocated Backend
+ final PDFASBackend backend = BackendLoader.getPDFASBackend(parameter.getConfiguration());
+
+ final ISettings settings = (ISettings) parameter.getConfiguration();
+ status = new OperationStatus(settings, parameter, backend);
+
+ final IPdfSigner signer = backend.getPdfSigner();
+
+ status.setPdfObject(signer.buildPDFObject(status));
+
+ final RequestedSignature requestedSignature = new RequestedSignature(
+ status);
+ requestedSignature.setCertificate(iaikCert);
+
+ if (!requestedSignature.isVisual()) {
+ logger.warn("Profile is invisible so not block image is generated");
+ return null;
+ }
+
+ return signer.generateVisibleSignaturePreview(parameter, iaikCert,
+ resolution, status, requestedSignature);
+ } catch (final PdfAsException e) {
+ logger.warn("PDF-AS Exception", e);
+ throw ErrorExtractor.searchPdfAsError(e, status);
+ } catch (final Throwable e) {
+ logger.warn("Throwable Exception", e);
+ throw ErrorExtractor.searchPdfAsError(e, status);
+ }
+
+ }
}