From 84a9465b14154f3e56a6b772d21e70f1c60bdf47 Mon Sep 17 00:00:00 2001 From: Jakob Heher Date: Mon, 8 Aug 2022 13:31:47 +0200 Subject: synchronize pdf-as profile hackery to avoid potential race conditions --- .../signer/pdfas/PdfAs4SignatureParameter.java | 73 ++++----- .../at/asit/pdfover/signer/pdfas/PdfAs4Signer.java | 164 +++++++++++---------- 2 files changed, 122 insertions(+), 115 deletions(-) diff --git a/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4SignatureParameter.java b/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4SignatureParameter.java index 12b617e3..4356f1e0 100644 --- a/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4SignatureParameter.java +++ b/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4SignatureParameter.java @@ -91,43 +91,46 @@ public class PdfAs4SignatureParameter { try { X509Certificate cert = new X509Certificate(PdfAs4SignatureParameter.class.getResourceAsStream("/example.cer")); - PdfAs pdfas = PdfAs4Helper.getPdfAs(); - Configuration conf = pdfas.getConfiguration(); - if (sigEmblem != null && !sigEmblem.trim().equals("")) { - conf.setValue("sig_obj." + sigProfile + ".value.SIG_LABEL", sigEmblem); - } - if (sigNote != null) { - conf.setValue("sig_obj." + sigProfile + ".value.SIG_NOTE", sigNote); - } - if (this.signatureProfile == Profile.BASE_LOGO) - { - int emblemWidth = (this.emblem != null) ? this.emblem.getWidth() : 65; - int emblemHeight = (this.emblem != null) ? this.emblem.getHeight() : 65; - double aspectRatio = ((double)emblemWidth) / emblemHeight; - double targetWidth = 65.0; - double targetHeight = 65.0; - if (aspectRatio < 1) - targetWidth = 65.0 * aspectRatio; - else - targetHeight = 65.0 / aspectRatio; - conf.setValue("sig_obj." + sigProfile + ".table.main.Style.padding", "0"); - conf.setValue("sig_obj." + sigProfile + ".pos", "w:"+targetWidth+";f:0"); - conf.setValue("sig_obj." + sigProfile + ".table.main.Style.imagescaletofit", targetWidth+";"+targetHeight); - } - SignParameter param = PdfAsFactory.createSignParameter(conf, null, null); - param.setSignatureProfileId(sigProfile); - Image placeholder = pdfas.generateVisibleSignaturePreview(param, cert, 72 * 4); - - // WORKAROUND for #110, manually paint a black border - if (!this.signatureProfile.equals(Profile.BASE_LOGO)) - { - Graphics2D ctx = (Graphics2D)placeholder.getGraphics(); - ctx.setColor(Color.BLACK); - ctx.drawRect(0, 0, placeholder.getWidth(null)-1, placeholder.getHeight(null)-1); + PdfAs pdfas = PdfAs4Helper.getPdfAs(); + synchronized (PdfAs4Helper.class) { + Configuration conf = pdfas.getConfiguration(); + if (sigEmblem != null && !sigEmblem.trim().equals("")) { + conf.setValue("sig_obj." + sigProfile + ".value.SIG_LABEL", sigEmblem); + } + if (sigNote != null) { + conf.setValue("sig_obj." + sigProfile + ".value.SIG_NOTE", sigNote); + } + if (this.signatureProfile == Profile.BASE_LOGO) + { + int emblemWidth = (this.emblem != null) ? this.emblem.getWidth() : 65; + int emblemHeight = (this.emblem != null) ? this.emblem.getHeight() : 65; + double aspectRatio = ((double)emblemWidth) / emblemHeight; + double targetWidth = 65.0; + double targetHeight = 65.0; + if (aspectRatio < 1) + targetWidth = 65.0 * aspectRatio; + else + targetHeight = 65.0 / aspectRatio; + conf.setValue("sig_obj." + sigProfile + ".table.main.Style.padding", "0"); + conf.setValue("sig_obj." + sigProfile + ".pos", "w:"+targetWidth+";f:0"); + conf.setValue("sig_obj." + sigProfile + ".table.main.Style.imagescaletofit", targetWidth+";"+targetHeight); + } + SignParameter param = PdfAsFactory.createSignParameter(conf, null, null); + param.setSignatureProfileId(sigProfile); + + Image placeholder = pdfas.generateVisibleSignaturePreview(param, cert, 72 * 4); + + // WORKAROUND for #110, manually paint a black border + if (!this.signatureProfile.equals(Profile.BASE_LOGO)) + { + Graphics2D ctx = (Graphics2D)placeholder.getGraphics(); + ctx.setColor(Color.BLACK); + ctx.drawRect(0, 0, placeholder.getWidth(null)-1, placeholder.getHeight(null)-1); + } + + return placeholder; } - - return placeholder; } catch (Exception e) { log.error("Failed to get signature placeholder", e); return new BufferedImage(229, 77, BufferedImage.TYPE_INT_RGB); diff --git a/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4Signer.java b/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4Signer.java index 51e36037..628b5c11 100644 --- a/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4Signer.java +++ b/pdf-over-signer/src/main/java/at/asit/pdfover/signer/pdfas/PdfAs4Signer.java @@ -52,52 +52,55 @@ public class PdfAs4Signer { if (parameter.signaturePosition != null) { sigPos = parameter.getPdfAsSignaturePosition(); } + PdfAs pdfas = PdfAs4Helper.getPdfAs(); - Configuration config = pdfas.getConfiguration(); - if (sigEmblem != null && !sigEmblem.trim().isEmpty()) { - config.setValue("sig_obj." + sigProfile + ".value.SIG_LABEL", sigEmblem); - } + synchronized (PdfAs4Helper.class) { + Configuration config = pdfas.getConfiguration(); + if (sigEmblem != null && !sigEmblem.trim().isEmpty()) { + config.setValue("sig_obj." + sigProfile + ".value.SIG_LABEL", sigEmblem); + } - if(sigNote != null) { - config.setValue("sig_obj." + sigProfile + ".value.SIG_NOTE", sigNote); - } + if(sigNote != null) { + config.setValue("sig_obj." + sigProfile + ".value.SIG_NOTE", sigNote); + } - // TODO encapsulate this parameter magic in PdfAs4SignatureParameter - if (parameter.signatureProfile == Profile.BASE_LOGO) - { - int emblemWidth = (parameter.emblem != null) ? parameter.emblem.getWidth() : 65; - int emblemHeight = (parameter.emblem != null) ? parameter.emblem.getHeight() : 65; - double aspectRatio = ((double)emblemWidth) / emblemHeight; - double targetWidth = 65.0; - double targetHeight = 65.0; - if (aspectRatio < 1) - targetWidth = 65.0 * aspectRatio; - else - targetHeight = 65.0 / aspectRatio; - config.setValue("sig_obj." + sigProfile + ".table.main.Style.padding", "0"); - config.setValue("sig_obj." + sigProfile + ".pos", "w:"+targetWidth+";f:0"); - config.setValue("sig_obj." + sigProfile + ".table.main.Style.imagescaletofit", targetWidth+";"+targetHeight); - } + // TODO encapsulate this parameter magic in PdfAs4SignatureParameter + if (parameter.signatureProfile == Profile.BASE_LOGO) + { + int emblemWidth = (parameter.emblem != null) ? parameter.emblem.getWidth() : 65; + int emblemHeight = (parameter.emblem != null) ? parameter.emblem.getHeight() : 65; + double aspectRatio = ((double)emblemWidth) / emblemHeight; + double targetWidth = 65.0; + double targetHeight = 65.0; + if (aspectRatio < 1) + targetWidth = 65.0 * aspectRatio; + else + targetHeight = 65.0 / aspectRatio; + config.setValue("sig_obj." + sigProfile + ".table.main.Style.padding", "0"); + config.setValue("sig_obj." + sigProfile + ".pos", "w:"+targetWidth+";f:0"); + config.setValue("sig_obj." + sigProfile + ".table.main.Style.imagescaletofit", targetWidth+";"+targetHeight); + } - PdfAs4SigningState state = new PdfAs4SigningState(); - ByteArrayOutputStream output = new ByteArrayOutputStream(); - DataSource input = new ByteArrayDataSource(parameter.inputDocument.getByteArray()); - SignParameter param = PdfAsFactory.createSignParameter(config, input, output); - if (sigPos != null) { - param.setSignaturePosition(sigPos); - } - param.setSignatureProfileId(sigProfile); - String id = UUID.randomUUID().toString(); - param.setTransactionId(id); + PdfAs4SigningState state = new PdfAs4SigningState(); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + DataSource input = new ByteArrayDataSource(parameter.inputDocument.getByteArray()); + SignParameter param = PdfAsFactory.createSignParameter(config, input, output); + if (sigPos != null) { + param.setSignaturePosition(sigPos); + } + param.setSignatureProfileId(sigProfile); + String id = UUID.randomUUID().toString(); + param.setTransactionId(id); - if (parameter.searchForPlaceholderSignatures) { - param.getConfiguration().setValue(IConfigurationConstants.PLACEHOLDER_MODE, "1"); - param.getConfiguration().setValue(IConfigurationConstants.PLACEHOLDER_SEARCH_ENABLED, IConfigurationConstants.TRUE); - } + if (parameter.searchForPlaceholderSignatures) { + param.getConfiguration().setValue(IConfigurationConstants.PLACEHOLDER_MODE, "1"); + param.getConfiguration().setValue(IConfigurationConstants.PLACEHOLDER_SEARCH_ENABLED, IConfigurationConstants.TRUE); + } - state.signParameter = param; - state.output = output; - return state; + state.signParameter = param; + state.output = output; + return state; + } } public static SignResult sign(PdfAs4SigningState state) throws SignatureException { @@ -106,48 +109,49 @@ public class PdfAs4Signer { throw new SignatureException("Incorrect SigningState!"); } - // Retrieve objects PdfAs pdfas = PdfAs4Helper.getPdfAs(); - - SignParameter param = state.signParameter; - - Configuration config = param.getConfiguration(); - config.setValue(IConfigurationConstants.SL_REQUEST_TYPE, - state.useBase64Request ? - IConfigurationConstants.SL_REQUEST_TYPE_BASE64 : - IConfigurationConstants.SL_REQUEST_TYPE_UPLOAD); - - IPlainSigner signer; - if (state.bkuConnector != null) { - ISLConnector connector = new PdfAs4BKUSLConnector(state.bkuConnector); - signer = new PAdESSigner(connector); - } else if (state.hasKeystoreSigner()) { - signer = state.getKeystoreSigner(); - } else { - throw new SignatureException("SigningState doesn't have a signer"); - } - param.setPlainSigner(signer); - - pdfas.sign(param); - - SignResult result = new SignResult(); - - if (param.getSignaturePosition() != null) { - TablePos tp = new TablePos(param.getSignaturePosition()); - SignaturePosition sp; - if (tp.isXauto() && tp.isYauto()) - sp = new SignaturePosition(); - else if (tp.isPauto()) - sp = new SignaturePosition(tp.getPosX(), tp.getPosY()); - else if (param.getSignatureProfileId().contains(Profile.AMTSSIGNATURBLOCK.name())) - sp = new SignaturePosition(); - else - sp = new SignaturePosition(tp.getPosX(), tp.getPosY(), tp.getPage()); - result.setSignaturePosition(sp); + synchronized (PdfAs4Helper.class) { + // Retrieve objects + SignParameter param = state.signParameter; + + Configuration config = param.getConfiguration(); + config.setValue(IConfigurationConstants.SL_REQUEST_TYPE, + state.useBase64Request ? + IConfigurationConstants.SL_REQUEST_TYPE_BASE64 : + IConfigurationConstants.SL_REQUEST_TYPE_UPLOAD); + + IPlainSigner signer; + if (state.bkuConnector != null) { + ISLConnector connector = new PdfAs4BKUSLConnector(state.bkuConnector); + signer = new PAdESSigner(connector); + } else if (state.hasKeystoreSigner()) { + signer = state.getKeystoreSigner(); + } else { + throw new SignatureException("SigningState doesn't have a signer"); + } + param.setPlainSigner(signer); + + pdfas.sign(param); + + SignResult result = new SignResult(); + + if (param.getSignaturePosition() != null) { + TablePos tp = new TablePos(param.getSignaturePosition()); + SignaturePosition sp; + if (tp.isXauto() && tp.isYauto()) + sp = new SignaturePosition(); + else if (tp.isPauto()) + sp = new SignaturePosition(tp.getPosX(), tp.getPosY()); + else if (param.getSignatureProfileId().contains(Profile.AMTSSIGNATURBLOCK.name())) + sp = new SignaturePosition(); + else + sp = new SignaturePosition(tp.getPosX(), tp.getPosY(), tp.getPage()); + result.setSignaturePosition(sp); + } + + result.setSignedDocument(new ByteArrayDocumentSource(state.output.toByteArray())); + return result; } - - result.setSignedDocument(new ByteArrayDocumentSource(state.output.toByteArray())); - return result; } catch (PdfAsException | PDFASError e) { throw new SignatureException(e); } -- cgit v1.2.3