Example usage for com.lowagie.text.pdf PdfName CONTENTS

List of usage examples for com.lowagie.text.pdf PdfName CONTENTS

Introduction

In this page you can find the example usage for com.lowagie.text.pdf PdfName CONTENTS.

Prototype

PdfName CONTENTS

To view the source code for com.lowagie.text.pdf PdfName CONTENTS.

Click Source Link

Document

A name

Usage

From source file:eu.europa.ec.markt.dss.signature.pdf.itext.ITextPDFDocTimeSampService.java

License:Open Source License

@SuppressWarnings({ "unchecked", "rawtypes" })
private PdfStamper prepareStamper(InputStream pdfData, OutputStream output, SignatureParameters parameters)
        throws IOException {

    try {/* w w  w . ja va2  s . co  m*/
        PdfReader reader = new PdfReader(pdfData);
        PdfStamper stamper = PdfStamper.createSignature(reader, output, '\0', null, true);

        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
        appearance.setAcro6Layers(true);
        appearance.setRender(PdfSignatureAppearance.SignatureRenderDescription);

        PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("ETSI.RFC3161"));
        // defined in ETSI TS 102 778-4 A.2
        dic.put(PdfName.TYPE, new PdfName("DocTimeStamp"));

        Calendar cal = Calendar.getInstance();
        if (parameters.getSigningDate() != null) {
            cal.setTime(parameters.getSigningDate());
            appearance.setSignDate(cal);
        }
        dic.setDate(new PdfDate(cal));

        appearance.setCryptoDictionary(dic);

        int csize = getSignatureSize();
        HashMap exc = new HashMap();
        exc.put(PdfName.CONTENTS, new Integer(csize * 2 + 2));

        appearance.preClose(exc);

        return stamper;
    } catch (DocumentException e) {
        throw new IOException(e);
    }

}

From source file:eu.europa.ec.markt.dss.signature.pdf.itext.ITextPDFDocTimeSampService.java

License:Open Source License

@Override
public void sign(InputStream pdfData, byte[] signatureValue, OutputStream signedStream,
        SignatureParameters parameters) throws IOException {

    try {//from  w w  w  . j  a  v a2 s .com
        PdfStamper stp = prepareStamper(pdfData, signedStream, parameters);
        PdfSignatureAppearance sap = stp.getSignatureAppearance();

        byte[] pk = signatureValue;

        int csize = getSignatureSize();
        byte[] outc = new byte[csize];

        PdfDictionary dic2 = new PdfDictionary();

        System.arraycopy(pk, 0, outc, 0, pk.length);

        dic2.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true));
        sap.close(dic2);
    } catch (DocumentException e) {
        throw new IOException(e);
    }

}

From source file:eu.europa.ec.markt.dss.signature.pdf.itext.ITextPDFSignatureService.java

License:Open Source License

@SuppressWarnings({ "unchecked", "rawtypes" })
private PdfStamper prepareStamper(InputStream pdfData, OutputStream output, SignatureParameters parameters)
        throws IOException, DocumentException {

    PdfReader reader = new PdfReader(pdfData);
    PdfStamper stp = PdfStamper.createSignature(reader, output, '\0', null, true);

    PdfSignatureAppearance sap = stp.getSignatureAppearance();
    sap.setAcro6Layers(true);//from   w w  w .j  a v  a  2 s.  c o m
    sap.setRender(PdfSignatureAppearance.SignatureRenderDescription);

    PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("ETSI.CAdES.detached"));
    Calendar cal = Calendar.getInstance();
    cal.setTime(parameters.getSigningDate());
    sap.setSignDate(cal);
    dic.setDate(new PdfDate(cal));

    if (parameters.getReason() != null) {
        dic.setReason(parameters.getReason());
    }
    if (parameters.getLocation() != null) {
        dic.setLocation(parameters.getLocation());
    }
    if (parameters.getContactInfo() != null) {
        dic.setContact(parameters.getContactInfo());
    }

    sap.setCryptoDictionary(dic);

    int csize = getSignatureSize();
    HashMap exc = new HashMap();
    exc.put(PdfName.CONTENTS, new Integer(csize * 2 + 2));

    sap.preClose(exc);

    return stp;
}

From source file:eu.europa.ec.markt.dss.signature.pdf.ITextPDFDocTimeSampService.java

License:Open Source License

@SuppressWarnings({ "unchecked", "rawtypes" })
private PdfStamper prepareStamper(InputStream pdfData, OutputStream output, SignatureParameters parameters)
        throws IOException, DocumentException {

    PdfReader reader = new PdfReader(pdfData);
    PdfStamper stp = PdfStamper.createSignature(reader, output, '\0', null, true);

    PdfSignatureAppearance sap = stp.getSignatureAppearance();
    sap.setAcro6Layers(true);//from ww  w. j  a  v a  2 s  . c om
    sap.setRender(PdfSignatureAppearance.SignatureRenderDescription);

    PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("ETSI.RFC3161"));
    // defined in ETSI TS 102 778-4 A.2
    dic.put(PdfName.TYPE, new PdfName("DocTimeStamp"));

    Calendar cal = Calendar.getInstance();
    if (parameters.getSigningDate() != null) {
        cal.setTime(parameters.getSigningDate());
        sap.setSignDate(cal);
    }
    dic.setDate(new PdfDate(cal));

    sap.setCryptoDictionary(dic);

    int csize = getSignatureSize();
    HashMap exc = new HashMap();
    exc.put(PdfName.CONTENTS, new Integer(csize * 2 + 2));

    sap.preClose(exc);

    return stp;
}

From source file:eu.europa.ec.markt.dss.signature.pdf.ITextPDFDocTimeSampService.java

License:Open Source License

@Override
public void sign(InputStream pdfData, byte[] signatureValue, OutputStream signedStream,
        SignatureParameters parameters) throws IOException, DocumentException {

    PdfStamper stp = prepareStamper(pdfData, signedStream, parameters);
    PdfSignatureAppearance sap = stp.getSignatureAppearance();

    byte[] pk = signatureValue;

    int csize = getSignatureSize();
    byte[] outc = new byte[csize];

    PdfDictionary dic2 = new PdfDictionary();

    System.arraycopy(pk, 0, outc, 0, pk.length);

    dic2.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true));
    sap.close(dic2);//from  w ww .j  a va  2 s . c  o  m
}

From source file:eu.europa.ec.markt.dss.signature.pdf.StatefulITextPDFSignatureService.java

License:Open Source License

@SuppressWarnings({ "unchecked", "rawtypes" })
private PdfStamper prepareStamper(InputStream pdfData, OutputStream output, SignatureParameters parameters)
        throws IOException, DocumentException {

    if (stp != null) {
        return stp;
    }/* w w  w.j a va 2  s  .  c o m*/

    PdfReader reader = new PdfReader(pdfData);
    stp = PdfStamper.createSignature(reader, output, '\0', null, true);

    PdfSignatureAppearance sap = stp.getSignatureAppearance();
    sap.setAcro6Layers(true);
    sap.setLayer2Text("");
    if (parameters.getSignatureAppearance() != null) {
        sap.setRender(PdfSignatureAppearance.SignatureRenderGraphic);
        sap.setImage(null);
        PdfReader stampReader = new PdfReader(parameters.getSignatureAppearance());
        PdfTemplate stamp = stp.getWriter().getImportedPage(stampReader, 1);
        //stamp.setBoundingBox(new Rectangle(200, 100));
        sap.setTemplate(stamp);
        sap.setSignatureGraphic(Image.getInstance(stamp));

        float[] pos = parameters.getSignaturePosition();
        Rectangle rect = new Rectangle(pos[0], pos[1], pos[2], pos[3]);
        sap.setVisibleSignature(rect, 1, parameters.getSignatureName());
    } else {
        sap.setRender(PdfSignatureAppearance.SignatureRenderDescription);
    }

    PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("ETSI.CAdES.detached"));
    Calendar cal = Calendar.getInstance();
    cal.setTime(parameters.getSigningDate());
    sap.setSignDate(cal);
    dic.setDate(new PdfDate(cal));

    if (parameters.getReason() != null) {
        dic.setReason(parameters.getReason());
    }
    if (parameters.getLocation() != null) {
        dic.setLocation(parameters.getLocation());
    }
    if (parameters.getContactInfo() != null) {
        dic.setContact(parameters.getContactInfo());
    }

    sap.setCryptoDictionary(dic);

    int csize = getSignatureSize();
    HashMap exc = new HashMap();
    exc.put(PdfName.CONTENTS, new Integer(csize * 2 + 2));

    sap.preClose(exc);

    return stp;
}

From source file:eu.europa.ec.markt.dss.signature.pdf.StatefulITextPDFSignatureService.java

License:Open Source License

@Override
public void sign(InputStream pdfData, byte[] signatureValue, OutputStream signedStream,
        SignatureParameters parameters) throws IOException, DocumentException {

    PdfStamper stp = prepareStamper(pdfData, signedStream, parameters);
    PdfSignatureAppearance sap = stp.getSignatureAppearance();

    byte[] pk = signatureValue;

    int csize = getSignatureSize();
    byte[] outc = new byte[csize];

    PdfDictionary dic2 = new PdfDictionary();

    System.arraycopy(pk, 0, outc, 0, pk.length);

    dic2.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true));
    sap.close(dic2);/*  w  w  w.  j av  a 2s  .co m*/

    signedStream.write(out.toByteArray());
    signedStream.close();
}

From source file:eu.europa.ec.markt.dss.validation.pades.PAdESSignature.java

License:Open Source License

/**
 * /*from  ww  w  . j a  va2s  .c  o  m*/
 * The default constructor for PAdESSignature.
 * 
 * @param reader The PdfReader that enable to access the document that contains the PAdES signature.
 */
public PAdESSignature(PdfReader reader, PdfDictionary outerCatalog, PdfDictionary signatureDictionary,
        PdfPKCS7 pk) throws CMSException {
    this.pdfReader = reader;
    this.outerCatalog = outerCatalog;
    this.signatureDictionary = signatureDictionary;
    cadesSignature = new CAdESSignature(signatureDictionary.getAsString(PdfName.CONTENTS).getOriginalBytes());
    this.pk = pk;
}

From source file:eu.europa.ec.markt.dss.validation.pades.PDFDocumentValidator.java

License:Open Source License

@Override
protected SignatureLevelLTV verifyLevelLTV(AdvancedSignature signature, Date referenceTime,
        ValidationContext ctx) {//w w  w .  j a  v a2s. c  o  m
    try {
        PAdESSignature pades = (PAdESSignature) signature;
        LOG.info("Starting LTV validation of signature: " + pades.getPdfPkcs7().getSignName() + " / "
                + PdfPKCS7.getSubjectFields(pades.getPdfPkcs7().getSigningCertificate()));

        PdfDictionary catalog = pades.getOuterCatalog();
        if (catalog == null) {
            catalog = pades.getPdfReader().getCatalog();
        }

        PdfDictionary dss = catalog.getAsDict(new PdfName("DSS"));

        if (dss == null) {
            LOG.info("No DSS dictionary!");
            return new SignatureLevelLTV(new Result(ResultStatus.INVALID, "no.dss.dictionary"), null, null);
        }

        LOG.info("DSS dictionary found");

        PdfName sigType = pades.getSignatureDictionary().getAsName(PdfName.TYPE);
        // PdfName subfilter = pades.getSignatureDictionary().getAsName(PdfName.SUBFILTER);

        TimestampVerificationResult docTimestampCheck = null;

        boolean dssCertsVerificationResult = everyCertificateValueAreThere(ctx,
                pades.getExtendedCertificateSource().getCertificates(), pades.getSigningCertificate());
        boolean dssRevocationVerificationResult = true;
        dssRevocationVerificationResult &= everyCRLValueOrRefAreThere(ctx, pades.getCRLs());
        dssRevocationVerificationResult &= everyOCSPValueOrRefAreThere(ctx, pades.getOCSPs());
        boolean vriVerificationresult = true;

        if (sigType != null) {
            if (sigType.equals(new PdfName("Sig"))) {
                // Standard signature

                PdfDictionary vri = dss.getAsDict(new PdfName("VRI"));

                if (vri == null) {
                    LOG.info("No VRI dictionary, this is optional but required by Adobe Acrobat");
                    return new SignatureLevelLTV(new Result(ResultStatus.INVALID, "no.vri.dictionary"), null,
                            null);
                }

                // Verify the VRI
                MessageDigest _md = MessageDigest.getInstance("SHA1");
                String hexHash = Hex
                        .encodeHexString(
                                _md.digest(pades.getSignatureDictionary().get(PdfName.CONTENTS).getBytes()))
                        .toUpperCase();

            } else if (sigType.equals(new PdfName("DocTimeStamp"))) {

            } else {
                throw new RuntimeException("Unknown signature dictionary type");
            }
        }

        Result levelReached = null;
        if (dssCertsVerificationResult && dssRevocationVerificationResult) {
            levelReached = new Result(ResultStatus.VALID, null);
        } else {
            levelReached = new Result();
            if (!dssCertsVerificationResult) {
                levelReached.setStatus(ResultStatus.INVALID, "dss.certs.verification.result.error");
            } else if (!dssRevocationVerificationResult) {
                levelReached.setStatus(ResultStatus.INVALID, "dss.revocation.verification.result.error");
            } else if (!vriVerificationresult) {
                levelReached.setStatus(ResultStatus.INVALID, "vri.verification.result.error");
            }
        }

        return new SignatureLevelLTV(levelReached,
                new Result((dssCertsVerificationResult) ? ResultStatus.VALID : ResultStatus.INVALID, null),
                new Result((dssRevocationVerificationResult) ? ResultStatus.VALID : ResultStatus.INVALID,
                        null));

    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}

From source file:net.sf.jsignpdf.SignerLogic.java

License:Mozilla Public License

/**
 * Signs a single file.//from w ww  . j  a  va  2s.  co m
 * 
 * @return true when signing is finished succesfully, false otherwise
 */
public boolean signFile() {
    final String outFile = options.getOutFileX();
    if (!validateInOutFiles(options.getInFile(), outFile)) {
        LOGGER.info(RES.get("console.skippingSigning"));
        return false;
    }

    boolean finished = false;
    Throwable tmpException = null;
    FileOutputStream fout = null;
    try {
        SSLInitializer.init(options);

        final PrivateKeyInfo pkInfo = KeyStoreUtils.getPkInfo(options);
        final PrivateKey key = pkInfo.getKey();
        final Certificate[] chain = pkInfo.getChain();
        if (ArrayUtils.isEmpty(chain)) {
            // the certificate was not found
            LOGGER.info(RES.get("console.certificateChainEmpty"));
            return false;
        }
        LOGGER.info(RES.get("console.createPdfReader", options.getInFile()));
        PdfReader reader;
        try {
            reader = new PdfReader(options.getInFile(), options.getPdfOwnerPwdStrX().getBytes());
        } catch (Exception e) {
            try {
                reader = new PdfReader(options.getInFile(), new byte[0]);
            } catch (Exception e2) {
                // try to read without password
                reader = new PdfReader(options.getInFile());
            }
        }

        LOGGER.info(RES.get("console.createOutPdf", outFile));
        fout = new FileOutputStream(outFile);

        final HashAlgorithm hashAlgorithm = options.getHashAlgorithmX();

        LOGGER.info(RES.get("console.createSignature"));
        char tmpPdfVersion = '\0'; // default version - the same as input
        if (reader.getPdfVersion() < hashAlgorithm.getPdfVersion()) {
            // this covers also problems with visible signatures (embedded
            // fonts) in PDF 1.2, because the minimal version
            // for hash algorithms is 1.3 (for SHA1)
            if (options.isAppendX()) {
                // if we are in append mode and version should be updated
                // then return false (not possible)
                LOGGER.info(RES.get("console.updateVersionNotPossibleInAppendMode"));
                return false;
            }
            tmpPdfVersion = hashAlgorithm.getPdfVersion();
            LOGGER.info(RES.get("console.updateVersion",
                    new String[] { String.valueOf(reader.getPdfVersion()), String.valueOf(tmpPdfVersion) }));
        }

        final PdfStamper stp = PdfStamper.createSignature(reader, fout, tmpPdfVersion, null,
                options.isAppendX());
        if (!options.isAppendX()) {
            // we are not in append mode, let's remove existing signatures
            // (otherwise we're getting to troubles)
            final AcroFields acroFields = stp.getAcroFields();
            @SuppressWarnings("unchecked")
            final List<String> sigNames = acroFields.getSignatureNames();
            for (String sigName : sigNames) {
                acroFields.removeField(sigName);
            }
        }
        if (options.isAdvanced() && options.getPdfEncryption() != PDFEncryption.NONE) {
            LOGGER.info(RES.get("console.setEncryption"));
            final int tmpRight = options.getRightPrinting().getRight()
                    | (options.isRightCopy() ? PdfWriter.ALLOW_COPY : 0)
                    | (options.isRightAssembly() ? PdfWriter.ALLOW_ASSEMBLY : 0)
                    | (options.isRightFillIn() ? PdfWriter.ALLOW_FILL_IN : 0)
                    | (options.isRightScreanReaders() ? PdfWriter.ALLOW_SCREENREADERS : 0)
                    | (options.isRightModifyAnnotations() ? PdfWriter.ALLOW_MODIFY_ANNOTATIONS : 0)
                    | (options.isRightModifyContents() ? PdfWriter.ALLOW_MODIFY_CONTENTS : 0);
            switch (options.getPdfEncryption()) {
            case PASSWORD:
                stp.setEncryption(true, options.getPdfUserPwdStr(), options.getPdfOwnerPwdStrX(), tmpRight);
                break;
            case CERTIFICATE:
                final X509Certificate encCert = KeyStoreUtils
                        .loadCertificate(options.getPdfEncryptionCertFile());
                if (encCert == null) {
                    LOGGER.error(RES.get("console.pdfEncError.wrongCertificateFile",
                            StringUtils.defaultString(options.getPdfEncryptionCertFile())));
                    return false;
                }
                if (!KeyStoreUtils.isEncryptionSupported(encCert)) {
                    LOGGER.error(RES.get("console.pdfEncError.cantUseCertificate",
                            encCert.getSubjectDN().getName()));
                    return false;
                }
                stp.setEncryption(new Certificate[] { encCert }, new int[] { tmpRight },
                        PdfWriter.ENCRYPTION_AES_128);
                break;
            default:
                LOGGER.error(RES.get("console.unsupportedEncryptionType"));
                return false;
            }
        }

        final PdfSignatureAppearance sap = stp.getSignatureAppearance();
        sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
        final String reason = options.getReason();
        if (StringUtils.isNotEmpty(reason)) {
            LOGGER.info(RES.get("console.setReason", reason));
            sap.setReason(reason);
        }
        final String location = options.getLocation();
        if (StringUtils.isNotEmpty(location)) {
            LOGGER.info(RES.get("console.setLocation", location));
            sap.setLocation(location);
        }
        final String contact = options.getContact();
        if (StringUtils.isNotEmpty(contact)) {
            LOGGER.info(RES.get("console.setContact", contact));
            sap.setContact(contact);
        }
        LOGGER.info(RES.get("console.setCertificationLevel"));
        sap.setCertificationLevel(options.getCertLevelX().getLevel());

        if (options.isVisible()) {
            // visible signature is enabled
            LOGGER.info(RES.get("console.configureVisible"));
            LOGGER.info(RES.get("console.setAcro6Layers", Boolean.toString(options.isAcro6Layers())));
            sap.setAcro6Layers(options.isAcro6Layers());

            final String tmpImgPath = options.getImgPath();
            if (tmpImgPath != null) {
                LOGGER.info(RES.get("console.createImage", tmpImgPath));
                final Image img = Image.getInstance(tmpImgPath);
                LOGGER.info(RES.get("console.setSignatureGraphic"));
                sap.setSignatureGraphic(img);
            }
            final String tmpBgImgPath = options.getBgImgPath();
            if (tmpBgImgPath != null) {
                LOGGER.info(RES.get("console.createImage", tmpBgImgPath));
                final Image img = Image.getInstance(tmpBgImgPath);
                LOGGER.info(RES.get("console.setImage"));
                sap.setImage(img);
            }
            LOGGER.info(RES.get("console.setImageScale"));
            sap.setImageScale(options.getBgImgScale());
            LOGGER.info(RES.get("console.setL2Text"));
            final String signer = PdfPKCS7.getSubjectFields((X509Certificate) chain[0]).getField("CN");
            final String timestamp = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z")
                    .format(sap.getSignDate().getTime());
            if (options.getL2Text() != null) {
                final Map<String, String> replacements = new HashMap<String, String>();
                replacements.put(L2TEXT_PLACEHOLDER_SIGNER, StringUtils.defaultString(signer));
                replacements.put(L2TEXT_PLACEHOLDER_TIMESTAMP, timestamp);
                replacements.put(L2TEXT_PLACEHOLDER_LOCATION, StringUtils.defaultString(location));
                replacements.put(L2TEXT_PLACEHOLDER_REASON, StringUtils.defaultString(reason));
                replacements.put(L2TEXT_PLACEHOLDER_CONTACT, StringUtils.defaultString(contact));
                final String l2text = StrSubstitutor.replace(options.getL2Text(), replacements);
                sap.setLayer2Text(l2text);
            } else {
                final StringBuilder buf = new StringBuilder();
                buf.append(RES.get("default.l2text.signedBy")).append(" ").append(signer).append('\n');
                buf.append(RES.get("default.l2text.date")).append(" ").append(timestamp);
                if (StringUtils.isNotEmpty(reason))
                    buf.append('\n').append(RES.get("default.l2text.reason")).append(" ").append(reason);
                if (StringUtils.isNotEmpty(location))
                    buf.append('\n').append(RES.get("default.l2text.location")).append(" ").append(location);
                sap.setLayer2Text(buf.toString());
            }
            if (FontUtils.getL2BaseFont() != null) {
                sap.setLayer2Font(new Font(FontUtils.getL2BaseFont(), options.getL2TextFontSize()));
            }
            LOGGER.info(RES.get("console.setL4Text"));
            sap.setLayer4Text(options.getL4Text());
            LOGGER.info(RES.get("console.setRender"));
            RenderMode renderMode = options.getRenderMode();
            if (renderMode == RenderMode.GRAPHIC_AND_DESCRIPTION && sap.getSignatureGraphic() == null) {
                LOGGER.warn(
                        "Render mode of visible signature is set to GRAPHIC_AND_DESCRIPTION, but no image is loaded. Fallback to DESCRIPTION_ONLY.");
                LOGGER.info(RES.get("console.renderModeFallback"));
                renderMode = RenderMode.DESCRIPTION_ONLY;
            }
            sap.setRender(renderMode.getRender());
            LOGGER.info(RES.get("console.setVisibleSignature"));
            int page = options.getPage();
            if (page < 1 || page > reader.getNumberOfPages()) {
                page = reader.getNumberOfPages();
            }
            sap.setVisibleSignature(new Rectangle(options.getPositionLLX(), options.getPositionLLY(),
                    options.getPositionURX(), options.getPositionURY()), page, null);
        }

        LOGGER.info(RES.get("console.processing"));
        final PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached"));
        if (!StringUtils.isEmpty(reason)) {
            dic.setReason(sap.getReason());
        }
        if (!StringUtils.isEmpty(location)) {
            dic.setLocation(sap.getLocation());
        }
        if (!StringUtils.isEmpty(contact)) {
            dic.setContact(sap.getContact());
        }
        dic.setDate(new PdfDate(sap.getSignDate()));
        sap.setCryptoDictionary(dic);

        final Proxy tmpProxy = options.createProxy();

        final CRLInfo crlInfo = new CRLInfo(options, chain);

        // CRLs are stored twice in PDF c.f.
        // PdfPKCS7.getAuthenticatedAttributeBytes
        final int contentEstimated = (int) (Constants.DEFVAL_SIG_SIZE + 2L * crlInfo.getByteCount());
        final Map<PdfName, Integer> exc = new HashMap<PdfName, Integer>();
        exc.put(PdfName.CONTENTS, new Integer(contentEstimated * 2 + 2));
        sap.preClose(exc);

        PdfPKCS7 sgn = new PdfPKCS7(key, chain, crlInfo.getCrls(), hashAlgorithm.getAlgorithmName(), null,
                false);
        InputStream data = sap.getRangeStream();
        final MessageDigest messageDigest = MessageDigest.getInstance(hashAlgorithm.getAlgorithmName());
        byte buf[] = new byte[8192];
        int n;
        while ((n = data.read(buf)) > 0) {
            messageDigest.update(buf, 0, n);
        }
        byte hash[] = messageDigest.digest();
        Calendar cal = Calendar.getInstance();
        byte[] ocsp = null;
        if (options.isOcspEnabledX() && chain.length >= 2) {
            LOGGER.info(RES.get("console.getOCSPURL"));
            String url = PdfPKCS7.getOCSPURL((X509Certificate) chain[0]);
            if (StringUtils.isEmpty(url)) {
                // get from options
                LOGGER.info(RES.get("console.noOCSPURL"));
                url = options.getOcspServerUrl();
            }
            if (!StringUtils.isEmpty(url)) {
                LOGGER.info(RES.get("console.readingOCSP", url));
                final OcspClientBouncyCastle ocspClient = new OcspClientBouncyCastle((X509Certificate) chain[0],
                        (X509Certificate) chain[1], url);
                ocspClient.setProxy(tmpProxy);
                ocsp = ocspClient.getEncoded();
            }
        }
        byte sh[] = sgn.getAuthenticatedAttributeBytes(hash, cal, ocsp);
        sgn.update(sh, 0, sh.length);

        TSAClientBouncyCastle tsc = null;
        if (options.isTimestampX() && !StringUtils.isEmpty(options.getTsaUrl())) {
            LOGGER.info(RES.get("console.creatingTsaClient"));
            if (options.getTsaServerAuthn() == ServerAuthentication.PASSWORD) {
                tsc = new TSAClientBouncyCastle(options.getTsaUrl(),
                        StringUtils.defaultString(options.getTsaUser()),
                        StringUtils.defaultString(options.getTsaPasswd()));
            } else {
                tsc = new TSAClientBouncyCastle(options.getTsaUrl());

            }
            final String tsaHashAlg = options.getTsaHashAlgWithFallback();
            LOGGER.info(RES.get("console.settingTsaHashAlg", tsaHashAlg));
            tsc.setHashAlgorithm(tsaHashAlg);
            tsc.setProxy(tmpProxy);
            final String policyOid = options.getTsaPolicy();
            if (StringUtils.isNotEmpty(policyOid)) {
                LOGGER.info(RES.get("console.settingTsaPolicy", policyOid));
                tsc.setPolicy(policyOid);
            }
        }
        byte[] encodedSig = sgn.getEncodedPKCS7(hash, cal, tsc, ocsp);

        if (contentEstimated + 2 < encodedSig.length) {
            System.err.println(
                    "SigSize - contentEstimated=" + contentEstimated + ", sigLen=" + encodedSig.length);
            throw new Exception("Not enough space");
        }

        byte[] paddedSig = new byte[contentEstimated];
        System.arraycopy(encodedSig, 0, paddedSig, 0, encodedSig.length);

        PdfDictionary dic2 = new PdfDictionary();
        dic2.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true));
        LOGGER.info(RES.get("console.closeStream"));
        sap.close(dic2);
        fout.close();
        fout = null;
        finished = true;
    } catch (Exception e) {
        LOGGER.error(RES.get("console.exception"), e);
    } catch (OutOfMemoryError e) {
        LOGGER.fatal(RES.get("console.memoryError"), e);
    } finally {
        if (fout != null) {
            try {
                fout.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        LOGGER.info(RES.get("console.finished." + (finished ? "ok" : "error")));
        options.fireSignerFinishedEvent(tmpException);
    }
    return finished;
}