From af90012c848711a4c9010dbcf71694dbfbca0e86 Mon Sep 17 00:00:00 2001 From: Andreas Fitzek Date: Thu, 10 Jul 2014 12:09:05 +0200 Subject: Integrity verification of Signature after Signature creation to ensure correct signed Document --- .../common/exceptions/PdfAsSignatureException.java | 4 + .../at/gv/egiz/pdfas/common/utils/PDFUtils.java | 27 ++++++ .../at/gv/egiz/pdfas/common/utils/StreamUtils.java | 44 +++++---- .../java/at/gv/egiz/pdfas/wrapper/PdfAsObject.java | 15 ++- .../gv/egiz/pdfas/lib/api/sign/IPlainSigner.java | 3 +- .../java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java | 29 +++--- .../lib/impl/signing/pdfbox/PADESPDFBOXSigner.java | 3 +- .../impl/signing/pdfbox/PdfboxSignerWrapper.java | 10 +- .../at/gv/egiz/pdfas/lib/util/SignatureUtils.java | 105 ++++++++++++++++++++- .../at/gv/egiz/sl/util/ISignatureConnector.java | 3 +- .../egiz/sl/util/ISignatureConnectorSLWrapper.java | 68 +++---------- .../main/java/at/gv/egiz/sl/util/MOAConnector.java | 19 +++- .../at/gv/egiz/pdfas/sigs/pades/PAdESSigner.java | 6 +- .../egiz/pdfas/sigs/pades/PAdESSignerKeystore.java | 3 +- .../sigs/pkcs7detached/PKCS7DetachedSigner.java | 4 +- 15 files changed, 239 insertions(+), 104 deletions(-) diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSignatureException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSignatureException.java index 759a9ec8..f701bffc 100644 --- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSignatureException.java +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSignatureException.java @@ -33,4 +33,8 @@ public class PdfAsSignatureException extends PdfAsException { public PdfAsSignatureException(String msgId, Throwable e) { super(msgId, e); } + + public PdfAsSignatureException(String msgId) { + super(msgId); + } } 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 8eb2e8bb..68cfd80a 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 @@ -99,6 +99,33 @@ public class PDFUtils { return data; } + public static byte[] extractSignatureData(byte[] signatureData, int[] byteRange) throws PDFIOException { + if(byteRange.length % 2 != 0) { + throw new PDFIOException("error.pdf.io.09"); + } + + int lastOffset = byteRange[byteRange.length - 2]; + int lastSize = byteRange[byteRange.length - 1]; + + int dataSize = lastOffset + lastSize; + + byte[] data = new byte[dataSize]; + int currentdataOff = 0; + + Arrays.fill(data, (byte)0x0); + + for(int i = 0; i < byteRange.length; i = i + 2) { + int offset = byteRange[i]; + int size = byteRange[i+1]; + + for(int j = 0; j < size; j++) { + data[offset + j] = signatureData[currentdataOff]; + currentdataOff++; + } + } + return data; + } + private static int extractASCIIInteger(byte[] data, int offset) { int nextsepp = nextSeperator(data, offset); diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java index 579099f0..50ec444c 100644 --- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java @@ -28,24 +28,36 @@ import java.io.IOException; import java.io.InputStream; /** - * Created with IntelliJ IDEA. - * User: afitzek - * Date: 8/29/13 - * Time: 9:54 AM - * To change this template use File | Settings | File Templates. + * Created with IntelliJ IDEA. User: afitzek Date: 8/29/13 Time: 9:54 AM To + * change this template use File | Settings | File Templates. */ public class StreamUtils { - public static byte[] inputStreamToByteArray(InputStream stream) throws IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - byte[] buffer = new byte[4096]; - int readBytes = 0; + public static byte[] inputStreamToByteArray(InputStream stream) + throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] buffer = new byte[4096]; + int readBytes = 0; - while((readBytes = stream.read(buffer)) != -1) { - bos.write(buffer, 0, readBytes); - } - stream.close(); - bos.close(); - return bos.toByteArray(); - } + while ((readBytes = stream.read(buffer)) != -1) { + bos.write(buffer, 0, readBytes); + } + stream.close(); + bos.close(); + return bos.toByteArray(); + } + + public static boolean dataCompare(byte[] a, byte[] b) { + if (a != null && b != null) { + if (a.length == b.length) { + for(int i = 0; i < a.length; i++) { + if(a[i] != b[i]) { + return false; + } + } + return true; + } + } + return false; + } } diff --git a/pdf-as-legacy/src/main/java/at/gv/egiz/pdfas/wrapper/PdfAsObject.java b/pdf-as-legacy/src/main/java/at/gv/egiz/pdfas/wrapper/PdfAsObject.java index 9ed02053..bef3b01f 100644 --- a/pdf-as-legacy/src/main/java/at/gv/egiz/pdfas/wrapper/PdfAsObject.java +++ b/pdf-as-legacy/src/main/java/at/gv/egiz/pdfas/wrapper/PdfAsObject.java @@ -59,6 +59,7 @@ import at.gv.egiz.pdfas.lib.api.sign.SignParameter; import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter; import at.gv.egiz.pdfas.lib.api.verify.VerifyResult; import at.gv.egiz.pdfas.lib.impl.SignaturePositionImpl; +import at.gv.egiz.pdfas.lib.impl.StatusRequestImpl; public class PdfAsObject implements PdfAs { @@ -82,14 +83,22 @@ public class PdfAsObject implements PdfAs { } SignatureDetailInformationWrapper sdi = (SignatureDetailInformationWrapper) signatureDetailInformation; - StatusRequest request = sdi.getStatus(); + StatusRequest statusRequest = sdi.getStatus(); + + if (!(statusRequest instanceof StatusRequestImpl)) { + throw new PdfAsException(ErrorCode.SIGNATURE_COULDNT_BE_CREATED, + "Invalid state"); + } + StatusRequestImpl request = (StatusRequestImpl) statusRequest; + if (request.needSignature()) { try { byte[] signature = sdi.wrapper.getSignParameter4().getPlainSigner().sign( - request.getSignatureData(), request.getSignatureDataByteRange(), sdi.wrapper.getSignParameter4()); + request.getSignatureData(), request.getSignatureDataByteRange(), sdi.wrapper.getSignParameter4(), + request.getStatus().getRequestedSignature()); request.setSigature(signature); - request = this.pdfas4.process(request); + request = (StatusRequestImpl) this.pdfas4.process(request); if(request.isReady()) { at.gv.egiz.pdfas.lib.api.sign.SignResult result = this.pdfas4.finishSign(request); sdi.wrapper.syncNewToOld(); diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/IPlainSigner.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/IPlainSigner.java index 903b9630..a167c596 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/IPlainSigner.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/IPlainSigner.java @@ -25,6 +25,7 @@ package at.gv.egiz.pdfas.lib.api.sign; import iaik.x509.X509Certificate; import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; /** * Signer interface @@ -48,7 +49,7 @@ public interface IPlainSigner { * @return * @throws PdfAsException */ - public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter) throws PdfAsException; + public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter, RequestedSignature requestedSignature) throws PdfAsException; /** * Gets the PDF Subfilter for this signer 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 28bd9151..7dcdca2b 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 @@ -31,15 +31,12 @@ import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Calendar; import java.util.List; -import javax.imageio.ImageIO; - import org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSBase; import org.apache.pdfbox.cos.COSDictionary; @@ -47,14 +44,13 @@ import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.cos.COSString; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.PDPageable; -import org.apache.pdfbox.util.PDFImageWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import at.gv.egiz.pdfas.common.exceptions.PDFIOException; 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; @@ -87,6 +83,7 @@ import at.gv.egiz.pdfas.lib.impl.status.PDFObject; import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; import at.gv.egiz.pdfas.lib.impl.verify.IVerifyFilter; import at.gv.egiz.pdfas.lib.impl.verify.VerifierDispatcher; +import at.gv.egiz.pdfas.lib.util.SignatureUtils; import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; import at.knowcenter.wag.egov.egiz.pdf.TablePos; import at.knowcenter.wag.egov.egiz.table.Table; @@ -193,18 +190,11 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants { IPdfSigner signer = PdfSignerFactory.createPdfSigner(); signer.signPDF(status.getPdfObject(), requestedSignature, new PdfboxSignerWrapper(status.getSignParamter() - .getPlainSigner(), parameter)); + .getPlainSigner(), parameter, requestedSignature)); // ================================================================ // Create SignResult - SignResultImpl result = new SignResultImpl(status.getSignParamter() - .getOutput()); - OutputStream outputStream = result.getOutputDocument() - .createOutputStream(); - - outputStream.write(status.getPdfObject().getSignedDocument()); - - outputStream.close(); + SignResult result = createSignResult(status); return result; } catch (Throwable e) { @@ -424,7 +414,16 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants { String signature = new COSString(request.getSignature()) .getHexString(); byte[] pdfSignature = signature.getBytes(); - + //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(), + verifyResult.getSignerCertificate().getFingerprintSHA())) { + throw new PdfAsSignatureException("Certificates missmatch!"); + } + for (int i = 0; i < pdfSignature.length; i++) { status.getPdfObject().getSignedDocument()[offset + i] = pdfSignature[i]; } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java index 4e82efa5..c8c4eeb4 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java @@ -35,7 +35,6 @@ import java.util.List; import org.apache.pdfbox.cos.COSBase; import org.apache.pdfbox.cos.COSDictionary; import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.cos.COSObject; import org.apache.pdfbox.exceptions.COSVisitorException; import org.apache.pdfbox.exceptions.SignatureException; import org.apache.pdfbox.pdmodel.PDDocument; @@ -343,7 +342,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { sigFieldName = "PDF-AS Signatur"; } - int count = SignatureUtils.countSignatures(doc); + int count = SignatureUtils.countSignatures(doc, sigFieldName); sigFieldName = sigFieldName + count; diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java index faa49148..44915a42 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java @@ -39,6 +39,7 @@ import at.gv.egiz.pdfas.common.utils.StreamUtils; import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner; import at.gv.egiz.pdfas.lib.api.sign.SignParameter; import at.gv.egiz.pdfas.lib.impl.signing.sig_interface.PDFASSignatureInterface; +import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; public class PdfboxSignerWrapper implements PDFASSignatureInterface { @@ -46,16 +47,17 @@ public class PdfboxSignerWrapper implements PDFASSignatureInterface { .getLogger(PdfboxSignerWrapper.class); private IPlainSigner signer; - @SuppressWarnings("unused") - private PDSignature signature; + private PDSignature signature; private int[] byteRange; private Calendar date; private SignParameter parameters; + private RequestedSignature requestedSignature; - public PdfboxSignerWrapper(IPlainSigner signer, SignParameter parameters) { + public PdfboxSignerWrapper(IPlainSigner signer, SignParameter parameters, RequestedSignature requestedSignature) { this.signer = signer; this.date = Calendar.getInstance(); this.parameters = parameters; + this.requestedSignature = requestedSignature; } public byte[] sign(InputStream inputStream) throws SignatureException, @@ -66,7 +68,7 @@ public class PdfboxSignerWrapper implements PDFASSignatureInterface { logger.info("Byte Range 2: " + byteRange2); try { logger.info("Signing with Pdfbox Wrapper"); - byte[] signature = signer.sign(data, byteRange, this.parameters); + byte[] signature = signer.sign(data, byteRange, this.parameters, this.requestedSignature); return signature; } catch (PdfAsException e) { throw new PdfAsWrappedIOException(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 28713e1a..4527b92b 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 @@ -1,13 +1,31 @@ package at.gv.egiz.pdfas.lib.util; +import iaik.cms.CMSException; +import iaik.cms.SignedData; +import iaik.cms.SignerInfo; +import iaik.x509.X509Certificate; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.SignatureException; + import org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSDictionary; import org.apache.pdfbox.cos.COSName; 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.lib.api.verify.VerifyResult; +import at.gv.egiz.pdfas.lib.impl.verify.VerifyResultImpl; public class SignatureUtils { - public static int countSignatures(PDDocument doc) { + private static final Logger logger = LoggerFactory + .getLogger(SignatureUtils.class); + + public static int countSignatures(PDDocument doc, String sigName) { int count = 0; COSDictionary trailer = doc.getDocument().getTrailer(); COSDictionary root = (COSDictionary) trailer @@ -20,10 +38,93 @@ public class SignatureUtils { COSDictionary field = (COSDictionary) fields.getObject(i); String type = field.getNameAsString("FT"); if ("Sig".equals(type)) { - count++; + String name = field.getString(COSName.T); + if (name != null) { + logger.debug("Found Sig: " + name); + try { + if (name.startsWith(sigName)) { + String numberString = name.replace(sigName, ""); + + logger.debug("Found Number: " + numberString); + + int SigIDX = Integer.parseInt(numberString); + if(SigIDX > count) { + count = SigIDX; + } + } + } catch (Throwable e) { + logger.error("Failed to extract Signature Name!", e); + } + } } + } + + count++; + + logger.debug("Returning sig number: " + count); return count; } + + + public static VerifyResult verifySignature(byte[] signature, byte[] input) throws PdfAsSignatureException { + //List results = new ArrayList(); + try { + SignedData signedData = new SignedData(new ByteArrayInputStream( + signature)); + + signedData.setContent(input); + + // get the signer infos + SignerInfo[] signerInfos = signedData.getSignerInfos(); + if (signerInfos.length == 0) { + throw new PdfAsSignatureException("Invalid Signature (no signer info created!)", null); + } + + if (signerInfos.length != 1) { + throw new PdfAsSignatureException("Invalid Signature (multiple signer infos found!)", null); + } + // verify the signatures + //for (int i = 0; i < signerInfos.length; i++) { + VerifyResultImpl verifyResult = new VerifyResultImpl(); + //results.add(verifyResult); + try { + logger.info("Signature Algo: {}, Digest {}", signedData + .getSignerInfos()[0].getSignatureAlgorithm(), + signedData.getSignerInfos()[0].getDigestAlgorithm()); + // verify the signature for SignerInfo at index i + X509Certificate signer_cert = signedData.verify(0); + // if the signature is OK the certificate of the + // signer is returned + logger.info("Signature OK from signer: " + + signer_cert.getSubjectDN()); + verifyResult.setSignerCertificate(signer_cert); + + } catch (SignatureException ex) { + // if the signature is not OK a SignatureException + // is thrown + logger.error( + "Signature ERROR from signer: " + + signedData.getCertificate( + signerInfos[0] + .getSignerIdentifier()) + .getSubjectDN(), ex); + + verifyResult.setSignerCertificate(signedData + .getCertificate(signerInfos[0] + .getSignerIdentifier())); + throw new PdfAsSignatureException("error.pdf.sig.08", ex); + } + + return verifyResult; + //} + } catch (CMSException e) { + throw new PdfAsSignatureException("error.pdf.sig.08", e); + } catch (IOException e) { + throw new PdfAsSignatureException("error.pdf.sig.08", e); + } + + + } } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnector.java b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnector.java index fdb95f49..24a1b84d 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnector.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnector.java @@ -26,8 +26,9 @@ package at.gv.egiz.sl.util; import iaik.x509.X509Certificate; import at.gv.egiz.pdfas.common.exceptions.PdfAsException; import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; public interface ISignatureConnector { public X509Certificate getCertificate(SignParameter parameter) throws PdfAsException; - public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter) throws PdfAsException; + public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter, RequestedSignature requestedSignature) throws PdfAsException; } 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 b564c215..077f2f9b 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 @@ -23,24 +23,23 @@ ******************************************************************************/ package at.gv.egiz.sl.util; -import iaik.cms.CMSException; -import iaik.cms.SignedData; -import iaik.cms.SignerInfo; import iaik.x509.X509Certificate; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.security.SignatureException; 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.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.impl.verify.VerifyResultImpl; +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; import at.gv.egiz.sl.schema.InfoboxAssocArrayPairType; import at.gv.egiz.sl.schema.InfoboxReadRequestType; @@ -84,59 +83,20 @@ public class ISignatureConnectorSLWrapper implements ISignatureConnector { return certificate; } - public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter) throws PdfAsException { + public byte[] sign(byte[] input, int[] byteRange, + SignParameter parameter, RequestedSignature requestedSignature) throws PdfAsException { RequestPackage pack = connector.createCMSRequest( input, byteRange, parameter); CreateCMSSignatureResponseType response = connector .sendCMSRequest(pack, parameter); - try { - SignedData signedData = new SignedData(new ByteArrayInputStream( - response.getCMSSignature())); - - signedData.setContent(input); - - // get the signer infos - SignerInfo[] signerInfos = signedData.getSignerInfos(); - if (signerInfos.length == 0) { - throw new PdfAsSignatureException("Invalid Signature (no signer info created!)", null); - } - // verify the signatures - for (int i = 0; i < signerInfos.length; i++) { - VerifyResultImpl verifyResult = new VerifyResultImpl(); - try { - logger.info("Signature Algo: {}, Digest {}", signedData - .getSignerInfos()[i].getSignatureAlgorithm(), - signedData.getSignerInfos()[i].getDigestAlgorithm()); - // verify the signature for SignerInfo at index i - X509Certificate signer_cert = signedData.verify(i); - // if the signature is OK the certificate of the - // signer is returned - logger.info("Signature OK from signer: " - + signer_cert.getSubjectDN()); - verifyResult.setSignerCertificate(signer_cert); + + VerifyResult verifyResult = SignatureUtils.verifySignature(response.getCMSSignature(), input); - } catch (SignatureException ex) { - // if the signature is not OK a SignatureException - // is thrown - logger.error( - "Signature ERROR from signer: " - + signedData.getCertificate( - signerInfos[i] - .getSignerIdentifier()) - .getSubjectDN(), ex); - - verifyResult.setSignerCertificate(signedData - .getCertificate(signerInfos[i] - .getSignerIdentifier())); - throw new PdfAsSignatureException("error.pdf.sig.08", ex); - } - } - } catch (CMSException e) { - throw new PdfAsSignatureException("error.pdf.sig.08", e); - } catch (IOException e) { - throw new PdfAsSignatureException("error.pdf.sig.08", e); + if(!StreamUtils.dataCompare(requestedSignature.getCertificate().getFingerprintSHA(), + verifyResult.getSignerCertificate().getFingerprintSHA())) { + throw new PdfAsSignatureException("Certificates missmatch!"); } - + return response.getCMSSignature(); } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/MOAConnector.java b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/MOAConnector.java index 73de30cf..1059dba1 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/MOAConnector.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/MOAConnector.java @@ -55,10 +55,15 @@ import org.xml.sax.SAXException; import at.gv.egiz.pdfas.common.exceptions.PdfAsException; import at.gv.egiz.pdfas.common.exceptions.PdfAsMOAException; +import at.gv.egiz.pdfas.common.exceptions.PdfAsSignatureException; import at.gv.egiz.pdfas.common.exceptions.PdfAsWrappedIOException; import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.common.utils.StreamUtils; import at.gv.egiz.pdfas.lib.api.Configuration; 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.status.RequestedSignature; +import at.gv.egiz.pdfas.lib.util.SignatureUtils; public class MOAConnector implements ISignatureConnector { @@ -135,7 +140,8 @@ public class MOAConnector implements ISignatureConnector { return builder.build(); } - public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter) throws PdfAsException { + public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter + , RequestedSignature requestedSignature) throws PdfAsException { CloseableHttpClient client = null; try { client = buildHttpClient(); @@ -220,7 +226,16 @@ public class MOAConnector implements ISignatureConnector { if (cmsSignature != null) { try { - return base64.decode(cmsSignature); + byte[] cmsSignatureData = base64.decode(cmsSignature); + + VerifyResult verifyResult = SignatureUtils.verifySignature(cmsSignatureData, input); + + if(!StreamUtils.dataCompare(requestedSignature.getCertificate().getFingerprintSHA(), + verifyResult.getSignerCertificate().getFingerprintSHA())) { + throw new PdfAsSignatureException("Certificates missmatch!"); + } + + return cmsSignatureData; } catch(Exception e) { throw new PdfAsException("error.pdf.io.07", e); } diff --git a/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSigner.java b/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSigner.java index 67b17783..07d3b66c 100644 --- a/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSigner.java +++ b/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSigner.java @@ -30,6 +30,7 @@ import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; import at.gv.egiz.pdfas.common.exceptions.PdfAsException; import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner; import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; import at.gv.egiz.sl.util.ISignatureConnector; import at.gv.egiz.sl.util.ISignatureConnectorSLWrapper; import at.gv.egiz.sl.util.ISLConnector; @@ -50,8 +51,9 @@ public class PAdESSigner implements IPlainSigner { return this.plainSigner.getCertificate(parameter); } - public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter) throws PdfAsException { - return this.plainSigner.sign(input, byteRange, parameter); + public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter + , RequestedSignature requestedSignature) throws PdfAsException { + return this.plainSigner.sign(input, byteRange, parameter, requestedSignature); } public String getPDFSubFilter() { diff --git a/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSignerKeystore.java b/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSignerKeystore.java index 7f62b294..758e98dd 100644 --- a/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSignerKeystore.java +++ b/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSignerKeystore.java @@ -59,6 +59,7 @@ import at.gv.egiz.pdfas.common.exceptions.PdfAsException; import at.gv.egiz.pdfas.common.exceptions.PdfAsSignatureException; import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner; import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; import at.gv.egiz.pdfas.lib.util.CertificateUtils; public class PAdESSignerKeystore implements IPlainSigner { @@ -134,7 +135,7 @@ public class PAdESSignerKeystore implements IPlainSigner { signerInfo.setSignedAttributes(attributeArray); } - public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter) throws PdfAsException { + public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter, RequestedSignature requestedSignature) throws PdfAsException { try { logger.info("Creating PAdES signature."); IssuerAndSerialNumber issuer = new IssuerAndSerialNumber(cert); diff --git a/signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedSigner.java b/signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedSigner.java index 802b7590..5dbf6bac 100644 --- a/signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedSigner.java +++ b/signature-standards/sigs-pkcs7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedSigner.java @@ -51,6 +51,7 @@ import at.gv.egiz.pdfas.common.exceptions.PdfAsException; import at.gv.egiz.pdfas.common.exceptions.PdfAsSignatureException; import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner; import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; /** * Creates a PKCS7 detached PDF signature @@ -80,7 +81,8 @@ public class PKCS7DetachedSigner implements IPlainSigner { return cert; } - public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter) throws PdfAsException { + public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter + , RequestedSignature requestedSignature) throws PdfAsException { try { logger.info("Creating PKCS7 signature."); IssuerAndSerialNumber issuer = new IssuerAndSerialNumber(cert); -- cgit v1.2.3