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:org.opensignature.opensignpdf.PDFSigner.java

License:Open Source License

/**
 * Allow you to sign a PDF File with a PKCS11 session opened.
 * //from  www  . jav  a  2  s  .  co  m
 * @param mySign
 * @param session
 * @param pdfFiles
 * @param suffix
 * @param reason
 * @param signatureVisibility
 * @param cal
 * @throws OpenSignatureException
 * @throws TokenException
 * @throws IOException
 * @throws CertificateException
 * @throws OpenSignatureException
 * @throws KeyStoreException
 * @throws UnrecoverableKeyException
 * @throws NoSuchAlgorithmException
 * @throws FileNotFoundException
 * @throws DocumentException
 * @throws NoSuchAlgorithmException
 * @throws ExceptionConverter
 */
public void signPDFwithKS(KeyStore ks, String alias, String pwd, File[] pdfFiles, String suffix, String reason,
        boolean signatureVisibility, Calendar cal)
        throws OpenSignatureException, KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {

    if (pdfFiles == null || ks == null) {
        throw new OpenSignatureException("Invalid parameters.");
    }

    // -- System's date by default 
    if (cal == null) {
        cal = Calendar.getInstance();
    }

    logger.info("[signPDFwithKS.in]:: " + Arrays.asList(new Object[] { "<ks>", alias, Arrays.asList(pdfFiles),
            suffix, reason, Boolean.valueOf(signatureVisibility) }));

    if (alias == null) {

        Enumeration aliases = ks.aliases();
        while (aliases.hasMoreElements()) {
            String alTmp = (String) aliases.nextElement();
            logger.debug("[signPDFwithKS]:: alTmp: " + alTmp);

            X509Certificate x509certificate = (X509Certificate) ks.getCertificate(alTmp);
            boolean[] keyUsage = x509certificate.getKeyUsage();
            if (keyUsage != null && (keyUsage[1] || keyUsage[0])) {
                alias = alTmp;
                break;
            }

        }
    }

    logger.debug("\n\n[signPDFwithKS]:: alias: " + alias + "\n\n");
    PrivateKey key = (PrivateKey) ks.getKey(alias, pwd.toCharArray());
    Certificate[] certs = ks.getCertificateChain(alias);

    for (int i = 0; i < pdfFiles.length; i++) {

        logger.info("[signPDFwithKS]:: Signing the file: " + pdfFiles[i].getAbsolutePath());

        try {

            // -- Check the access to the PDF
            if (!pdfFiles[i].exists() || !pdfFiles[i].canRead()) {
                throw new FileNotFoundException(
                        "The file '" + pdfFiles[i].getAbsolutePath() + "' doesn't exist.");
            }

            byte signatureBytes[] = new byte[128];

            // -- Creating the OutputStream overwritting the file if it exists
            // previously
            File fOut = FileUtils.addSuffix(pdfFiles[i], suffix, true);
            FileOutputStream fos = new FileOutputStream(fOut);
            BufferedOutputStream bos = new BufferedOutputStream(fos);

            // -- Creating the reader
            PdfReader reader = createPDFReader(pdfFiles[i]);

            PdfStamperOSP stamper;

            if ("countersigner".equals(typeSignatureSelected)) {
                stamper = PdfStamperOSP.createSignature(reader, bos, '\0', null, true);
            } else {
                stamper = PdfStamperOSP.createSignature(reader, bos, '\0');
            }

            PdfSignatureAppearanceOSP sap = stamper.getSignatureAppearance();
            sap.setCrypto(null, certs, null, PdfSignatureAppearance.WINCER_SIGNED);
            sap.setReason(reason);

            if (signatureVisibility) {
                if ("countersigner".equals(typeSignatureSelected)) {
                    sap.setCertified(0);
                    sap.setVisibleSignature(fieldName);
                } else {
                    sap.setCertified(2);
                    if (!"".equals(fieldName)) {
                        sap.setVisibleSignature(fieldName);
                    } else {
                        sap.setVisibleSignature(new com.lowagie.text.Rectangle(llx, lly, urx, ury), 1, null);
                    }
                }

            }

            sap.setExternalDigest(new byte[128], new byte[20], "RSA");

            PdfDictionary dic = new PdfDictionary();
            dic.put(PdfName.FT, PdfName.SIG);
            dic.put(PdfName.FILTER, new PdfName("Adobe.PPKLite"));
            dic.put(PdfName.SUBFILTER, new PdfName("adbe.pkcs7.detached"));
            if (cal != null) {
                dic.put(PdfName.M, new PdfDate(cal));
            } else {
                dic.put(PdfName.M, new PdfNull());
            }
            dic.put(PdfName.NAME,
                    new PdfString(PdfPKCS7.getSubjectFields((X509Certificate) certs[0]).getField("CN")));
            dic.put(PdfName.REASON, new PdfString(reason));

            sap.setCryptoDictionary(dic);

            HashMap exc = new HashMap();
            exc.put(PdfName.CONTENTS, new Integer(0x5002));
            sap.preClose(exc);

            byte[] content = IOUtils.streamToByteArray(sap.getRangeStream());
            //SHA256, alias CMSSignedDataGenerator.DIGEST_SHA256,
            //        alias NISTObjectIdentifiers.id_sha256.getId(),
            //        alias "2.16.840.1.101.3.4.2.1"
            byte[] hash = MessageDigest.getInstance("2.16.840.1.101.3.4.2.1", "BC").digest(content);

            // costruzione degli authenticated attributes
            ASN1EncodableVector signedAttributes = buildSignedAttributes(hash, cal);
            byte[] bytesForSecondHash = IOUtils.toByteArray(new DERSet(signedAttributes));

            // -- Signature generated with the private key of the KS
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(key);
            signature.update(bytesForSecondHash);
            signatureBytes = signature.sign();

            byte[] encodedPkcs7 = null;
            try {

                // Create the set of Hash algorithms
                DERConstructedSet digestAlgorithms = new DERConstructedSet();

                // Creo manualmente la sequenza di digest algos
                ASN1EncodableVector algos = new ASN1EncodableVector();
                //algos.add(new DERObjectIdentifier("1.3.14.3.2.26")); // SHA1
                //SHA-256
                algos.add(new DERObjectIdentifier("2.16.840.1.101.3.4.2.1"));
                algos.add(new DERNull());
                digestAlgorithms.addObject(new DERSequence(algos));

                // Create the contentInfo.
                ASN1EncodableVector ev = new ASN1EncodableVector();
                ev.add(new DERObjectIdentifier("1.2.840.113549.1.7.1")); // PKCS7SignedData

                DERSequence contentinfo = new DERSequence(ev);

                // Get all the certificates
                //
                ASN1EncodableVector v = new ASN1EncodableVector();
                for (int c = 0; c < certs.length; c++) {
                    ASN1InputStream tempstream = new ASN1InputStream(
                            new ByteArrayInputStream(certs[c].getEncoded()));
                    v.add(tempstream.readObject());
                }

                DERSet dercertificates = new DERSet(v);

                // Create signerinfo structure.
                //
                ASN1EncodableVector signerinfo = new ASN1EncodableVector();

                // Add the signerInfo version
                //
                signerinfo.add(new DERInteger(1));

                v = new ASN1EncodableVector();
                v.add(CertUtil.getIssuer((X509Certificate) certs[0]));
                v.add(new DERInteger(((X509Certificate) certs[0]).getSerialNumber()));
                signerinfo.add(new DERSequence(v));

                // Add the digestAlgorithm
                v = new ASN1EncodableVector();
                //v.add(new DERObjectIdentifier("1.3.14.3.2.26")); // SHA1
                //SHA-256
                v.add(new DERObjectIdentifier("1.2.840.113549.1.7.1"));
                v.add(new DERNull());
                signerinfo.add(new DERSequence(v));

                // add the authenticated attribute if present
                signerinfo.add(new DERTaggedObject(false, 0, new DERSet(signedAttributes)));

                // Add the digestEncryptionAlgorithm
                v = new ASN1EncodableVector();
                v.add(new DERObjectIdentifier("1.2.840.113549.1.1.1"));// RSA
                v.add(new DERNull());
                signerinfo.add(new DERSequence(v));

                // Add the encrypted digest
                signerinfo.add(new DEROctetString(signatureBytes));

                // Add unsigned attributes (timestamp)
                if (serverTimestamp != null && !"".equals(serverTimestamp.toString())) {
                    byte[] timestampHash = MessageDigest.getInstance("SHA-256").digest(signatureBytes);
                    ASN1EncodableVector unsignedAttributes = buildUnsignedAttributes(timestampHash,
                            serverTimestamp, usernameTimestamp, passwordTimestamp);
                    if (unsignedAttributes != null) {
                        signerinfo.add(new DERTaggedObject(false, 1, new DERSet(unsignedAttributes)));
                    }
                }

                // Finally build the body out of all the components above
                ASN1EncodableVector body = new ASN1EncodableVector();
                body.add(new DERInteger(1)); // pkcs7 version, always 1
                body.add(digestAlgorithms);
                body.add(contentinfo);
                body.add(new DERTaggedObject(false, 0, dercertificates));

                // Only allow one signerInfo
                body.add(new DERSet(new DERSequence(signerinfo)));

                // Now we have the body, wrap it in it's PKCS7Signed shell
                // and return it
                //
                ASN1EncodableVector whole = new ASN1EncodableVector();
                whole.add(new DERObjectIdentifier("1.2.840.113549.1.7.2"));// PKCS7_SIGNED_DATA
                whole.add(new DERTaggedObject(0, new DERSequence(body)));

                encodedPkcs7 = IOUtils.toByteArray(new DERSequence(whole));

            } catch (Exception e) {
                throw new ExceptionConverter(e);
            }

            PdfDictionary dic2 = new PdfDictionary();

            byte out[] = new byte[0x5000 / 2];
            System.arraycopy(encodedPkcs7, 0, out, 0, encodedPkcs7.length);

            dic2.put(PdfName.CONTENTS, new PdfString(out).setHexWriting(true));
            sap.close(dic2);

            bos.close();
            fos.close();

        } catch (Exception e) {
            logger.warn("[signPDFwithKS]:: ", e);
        }

    }

    logger.info("[signPDFwithKS.out]:: ");

}

From source file:org.opensignature.opensignpdf.PDFSigner.java

License:Open Source License

/**
 * @param mySign/* w w  w. j  ava2 s  . c  om*/
 * @param session
 * @param reason
 * @param signCertKeyObject
 * @param certs
 * @param stamper
 * @throws IOException
 * @throws DocumentException
 * @throws NoSuchAlgorithmException
 * @throws TokenException
 * @throws ExceptionConverter
* @throws NoSuchProviderException 
 */
private void createSignatureAppearance(MyPkcs11 mySign, Session session, String reason, Key signCertKeyObject,
        X509Certificate[] certs, PdfStamperOSP stamper, boolean signatureVisible, Calendar cal)
        throws IOException, DocumentException, NoSuchAlgorithmException, TokenException, ExceptionConverter,
        NoSuchProviderException {

    logger.info("[createSignatureAppearance.in]:: ");

    byte[] signatureBytes = new byte[128];

    PdfSignatureAppearanceOSP sap = stamper.getSignatureAppearance();

    sap.setCrypto(null, certs, null, PdfSignatureAppearance.WINCER_SIGNED);
    sap.setReason(reason);

    if (signatureVisible) {
        if ("countersigner".equals(typeSignatureSelected)) {
            sap.setCertified(0);
            sap.setVisibleSignature(fieldName);
        } else {
            sap.setCertified(0);
            if ((fieldName != null) && (!"".equals(fieldName))) {
                sap.setVisibleSignature(fieldName);
            } else {
                sap.setVisibleSignature(new com.lowagie.text.Rectangle(llx, lly, urx, ury), 1, null);
            }
        }

    }

    //aggiunta di grafico per la firma
    if ("true".equals(graphicSignSelected)) {
        sap.setSignatureGraphic(Image.getInstance(fileImgfirma));
        sap.setRender(2);
    } else {
        sap.setRender(0);
    }
    sap.setExternalDigest(new byte[128], new byte[20], "RSA");

    PdfDictionary dic = new PdfDictionary();
    dic.put(PdfName.FT, PdfName.SIG);
    dic.put(PdfName.FILTER, new PdfName("Adobe.PPKLite"));
    dic.put(PdfName.SUBFILTER, new PdfName("adbe.pkcs7.detached"));
    if (cal != null) {
        dic.put(PdfName.M, new PdfDate(cal));
    } else {
        dic.put(PdfName.M, new PdfNull());
    }
    dic.put(PdfName.NAME, new PdfString(PdfPKCS7.getSubjectFields((X509Certificate) certs[0]).getField("CN")));
    dic.put(PdfName.REASON, new PdfString(reason));

    sap.setCryptoDictionary(dic);

    HashMap exc = new HashMap();
    exc.put(PdfName.CONTENTS, new Integer(0x5002));
    sap.preClose(exc);

    byte[] content = IOUtils.streamToByteArray(sap.getRangeStream());
    byte[] hash = MessageDigest.getInstance("2.16.840.1.101.3.4.2.1", "BC").digest(content);

    // costruzione degli authenticated attributes
    ASN1EncodableVector signedAttributes = buildSignedAttributes(hash, cal);
    byte[] bytesForSecondHash = IOUtils.toByteArray(new DERSet(signedAttributes));

    byte[] secondHash = MessageDigest.getInstance("2.16.840.1.101.3.4.2.1").digest(bytesForSecondHash);

    // -- Generatting the signature
    signatureBytes = mySign.sign(session, secondHash, signCertKeyObject);

    byte[] encodedPkcs7 = null;
    try {

        // Create the set of Hash algorithms
        DERConstructedSet digestAlgorithms = new DERConstructedSet();

        // Creo manualmente la sequenza di digest algos
        ASN1EncodableVector algos = new ASN1EncodableVector();
        //algos.add(new DERObjectIdentifier("1.3.14.3.2.26")); // SHA1
        //SHA256
        algos.add(new DERObjectIdentifier("2.16.840.1.101.3.4.2.1"));
        algos.add(new DERNull());
        digestAlgorithms.addObject(new DERSequence(algos));

        // Create the contentInfo.
        ASN1EncodableVector ev = new ASN1EncodableVector();
        ev.add(new DERObjectIdentifier("1.2.840.113549.1.7.1")); // PKCS7SignedData

        DERSequence contentinfo = new DERSequence(ev);

        // Get all the certificates
        //
        ASN1EncodableVector v = new ASN1EncodableVector();
        for (int c = 0; c < certs.length; c++) {
            ASN1InputStream tempstream = new ASN1InputStream(new ByteArrayInputStream(certs[c].getEncoded()));
            v.add(tempstream.readObject());
        }

        DERSet dercertificates = new DERSet(v);

        // Create signerinfo structure.
        //
        ASN1EncodableVector signerinfo = new ASN1EncodableVector();

        // Add the signerInfo version
        //
        signerinfo.add(new DERInteger(1));

        v = new ASN1EncodableVector();
        v.add(CertUtil.getIssuer(certs[0]));
        v.add(new DERInteger(certs[0].getSerialNumber()));
        signerinfo.add(new DERSequence(v));

        // Add the digestAlgorithm
        v = new ASN1EncodableVector();
        //v.add(new DERObjectIdentifier("1.3.14.3.2.26")); // SHA1
        //SHA-256
        v.add(new DERObjectIdentifier("2.16.840.1.101.3.4.2.1"));
        v.add(new DERNull());
        signerinfo.add(new DERSequence(v));

        // add the authenticated attribute if present
        signerinfo.add(new DERTaggedObject(false, 0, new DERSet(signedAttributes)));

        // Add the digestEncryptionAlgorithm
        v = new ASN1EncodableVector();
        v.add(new DERObjectIdentifier("1.2.840.113549.1.1.1"));// RSA
        v.add(new DERNull());
        signerinfo.add(new DERSequence(v));

        // Add the encrypted digest
        signerinfo.add(new DEROctetString(signatureBytes));

        // Add unsigned attributes (timestamp)
        if (serverTimestamp != null && !"".equals(serverTimestamp.toString())) {
            byte[] timestampHash = MessageDigest.getInstance("2.16.840.1.101.3.4.2.1", "BC")
                    .digest(signatureBytes);
            ASN1EncodableVector unsignedAttributes = buildUnsignedAttributes(timestampHash, serverTimestamp,
                    usernameTimestamp, passwordTimestamp);
            if (unsignedAttributes != null) {
                signerinfo.add(new DERTaggedObject(false, 1, new DERSet(unsignedAttributes)));
            }
        }

        // Finally build the body out of all the components above
        ASN1EncodableVector body = new ASN1EncodableVector();
        body.add(new DERInteger(1)); // pkcs7 version, always 1
        body.add(digestAlgorithms);
        body.add(contentinfo);
        body.add(new DERTaggedObject(false, 0, dercertificates));

        // Only allow one signerInfo
        body.add(new DERSet(new DERSequence(signerinfo)));

        // Now we have the body, wrap it in it's PKCS7Signed shell
        // and return it
        //
        ASN1EncodableVector whole = new ASN1EncodableVector();
        whole.add(new DERObjectIdentifier("1.2.840.113549.1.7.2"));// PKCS7_SIGNED_DATA
        whole.add(new DERTaggedObject(0, new DERSequence(body)));

        encodedPkcs7 = IOUtils.toByteArray(new DERSequence(whole));

    } catch (Exception e) {
        throw new ExceptionConverter(e);
    }

    PdfDictionary dic2 = new PdfDictionary();

    byte out[] = new byte[0x5000 / 2];
    System.arraycopy(encodedPkcs7, 0, out, 0, encodedPkcs7.length);

    dic2.put(PdfName.CONTENTS, new PdfString(out).setHexWriting(true));
    sap.close(dic2);

    logger.info("[createSignatureAppearance.retorna]:: ");

}

From source file:org.opensignature.opensignpdf.tools.Pkcs7Extractor.java

License:Open Source License

/**
 * @param args//  w  w w.  ja  v a 2s . com
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub

    try {
        if (args.length < 1) {
            System.out.println("Usage: EstraiPkcs7 <pdf file relative to current dir>");
            System.exit(1);
        }
        String filename = args[0];

        PdfReader reader = new PdfReader(filename);
        AcroFields af = reader.getAcroFields();
        ArrayList names = af.getSignatureNames();
        for (int k = 0; k < names.size(); ++k) {
            String name = (String) names.get(k);
            System.out.println("Signature name: " + name);
            System.out.println("Signature covers whole document: " + af.signatureCoversWholeDocument(name));
            System.out.println("Document revision: " + af.getRevision(name) + " of " + af.getTotalRevisions());
            // Start revision extraction
            // FileOutputStream out = new FileOutputStream("revision_" +
            // af.getRevision(name) + ".pdf");
            // byte bb[] = new byte[8192];
            // InputStream ip = af.extractRevision(name);
            // int n = 0;
            // while ((n = ip.read(bb)) > 0)
            // out.write(bb, 0, n);
            // out.close();
            // ip.close();
            // End revision extraction

            // PdfPKCS7 pk = af.verifySignature(name);

            PdfDictionary v = af.getSignatureDictionary(name);

            PdfString contents = (PdfString) PdfReader.getPdfObject(v.get(PdfName.CONTENTS));

            // Start pkcs7 extraction
            FileOutputStream fos = new FileOutputStream(filename + "_signeddata_" + name + ".pk7");
            System.out.println(k + ") Estrazione pkcs7: " + filename + "_signeddata_" + name + ".pk7");
            fos.write(contents.getOriginalBytes());
            fos.flush();
            fos.close();
            // End pkcs7 extraction

            /* Commentato per evitare dipendenze da BC
            Security.insertProviderAt(new BouncyCastleProvider(), 3);
                    
            // nota: dipendenza da provider BC per "SHA1withRSA"
            PdfPKCS7 pk = new PdfPKCS7(contents.getOriginalBytes(), "BC");
                    
                    
                    
            Calendar cal = pk.getSignDate();
            Certificate pkc[] = pk.getCertificates();
            System.out.println("Got " + pkc.length
                + " certificates from pdf");
            System.out
                .println("Subject of signer: "
                        + PdfPKCS7.getSubjectFields(pk
                                .getSigningCertificate()));
            // System.out.println("Document modified: " + !pk.verify());
            // Object fails[] = PdfPKCS7.verifyCertificates(pkc, kall, null,
            // cal);
            // if (fails == null)
            // System.out.println("Certificates verified against the
            // KeyStore");
            // else
            // System.out.println("Certificate failed: " + fails[1]);
                     
            */
        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();

    }

    /* decommentare se si riabilita la parte relativa a PdfPKCS7 nel main
            
    catch (InvalidKeyException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (SecurityException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (CRLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (CertificateException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (NoSuchProviderException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    */

}

From source file:org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.internal.PdfLogicalPageDrawable.java

License:Open Source License

protected void drawImageMap(final RenderableReplacedContentBox content) {
    if (version < '6') {
        return;/*  w w  w . j  av  a2 s . co  m*/
    }

    final ImageMap imageMap = RenderUtility.extractImageMap(content);
    // only generate a image map, if the user does not specify their own onw via the override.
    // Of course, they would have to provide the map by other means as well.

    if (imageMap == null) {
        return;
    }

    final ImageMapEntry[] imageMapEntries = imageMap.getMapEntries();
    for (int i = 0; i < imageMapEntries.length; i++) {
        final ImageMapEntry imageMapEntry = imageMapEntries[i];
        final String link = imageMapEntry.getAttribute(LibXmlInfo.XHTML_NAMESPACE, "href");
        final String tooltip = imageMapEntry.getAttribute(LibXmlInfo.XHTML_NAMESPACE, "title");
        if (StringUtils.isEmpty(tooltip)) {
            continue;
        }

        final AffineTransform affineTransform = getGraphics().getTransform();
        final float translateX = (float) affineTransform.getTranslateX();
        final int x = (int) (translateX + StrictGeomUtility.toExternalValue(content.getX()));
        final int y = (int) StrictGeomUtility.toExternalValue(content.getY());
        final float[] translatedCoords = translateCoordinates(imageMapEntry.getAreaCoordinates(), x, y);

        final PolygonAnnotation polygonAnnotation = new PolygonAnnotation(writer, translatedCoords);
        polygonAnnotation.put(PdfName.CONTENTS, new PdfString(tooltip, PdfObject.TEXT_UNICODE));
        writer.addAnnotation(polygonAnnotation);
    }
}

From source file:org.signserver.module.pdfsigner.PDFSigner.java

License:Open Source License

protected byte[] calculateSignature(PdfPKCS7 sgn, int size, MessageDigest messageDigest, Calendar cal,
        PDFSignerParameters params, Certificate[] certChain, TSAClient tsc, byte[] ocsp,
        PdfSignatureAppearance sap) throws IOException, DocumentException, SignServerException {

    final HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>();
    exc.put(PdfName.CONTENTS, Integer.valueOf(size * 2 + 2));
    sap.preClose(exc);/*from   w  w  w  .ja  v  a  2  s  .  com*/

    InputStream data = sap.getRangeStream();

    byte buf[] = new byte[8192];
    int n;
    while ((n = data.read(buf)) > 0) {
        messageDigest.update(buf, 0, n);
    }
    byte hash[] = messageDigest.digest();

    byte sh[] = sgn.getAuthenticatedAttributeBytes(hash, cal, ocsp);
    try {
        sgn.update(sh, 0, sh.length);
    } catch (SignatureException e) {
        throw new SignServerException("Error calculating signature", e);
    }

    byte[] encodedSig = sgn.getEncodedPKCS7(hash, cal, tsc, ocsp);

    return encodedSig;
}

From source file:org.signserver.module.pdfsigner.PDFSigner.java

License:Open Source License

protected byte[] addSignatureToPDFDocument(final ICryptoInstance crypto, PDFSignerParameters params,
        byte[] pdfbytes, byte[] password, int contentEstimated, final ProcessRequest request,
        final RequestContext context) throws IOException, DocumentException, CryptoTokenOfflineException,
        SignServerException, IllegalRequestException {
    // when given a content length (i.e. non-zero), it means we are running a second try
    boolean secondTry = contentEstimated != 0;

    // get signing cert certificate chain and private key
    final List<Certificate> certs = getSigningCertificateChain(crypto);
    if (certs == null) {
        throw new SignServerException("Null certificate chain. This signer needs a certificate.");
    }/*w ww  . j  a  v  a  2  s.com*/
    final List<Certificate> includedCerts = includedCertificates(certs);
    Certificate[] certChain = includedCerts.toArray(new Certificate[includedCerts.size()]);
    PrivateKey privKey = crypto.getPrivateKey();

    // need to check digest algorithms for DSA private key at signing
    // time since we can't be sure what key a configured alias selector gives back
    if (privKey instanceof DSAPrivateKey) {
        if (!"SHA1".equals(digestAlgorithm)) {
            throw new IllegalRequestException(
                    "Only SHA1 is permitted as digest algorithm for DSA private keys");
        }
    }

    PdfReader reader = new PdfReader(pdfbytes, password);
    boolean appendMode = true; // TODO: This could be good to have as a property in the future

    int pdfVersion;

    try {
        pdfVersion = Integer.parseInt(Character.toString(reader.getPdfVersion()));
    } catch (NumberFormatException e) {
        pdfVersion = 0;
    }

    if (LOG.isDebugEnabled()) {
        LOG.debug("PDF version: " + pdfVersion);
    }

    // Don't certify already certified documents
    if (reader.getCertificationLevel() != PdfSignatureAppearance.NOT_CERTIFIED
            && params.getCertification_level() != PdfSignatureAppearance.NOT_CERTIFIED) {
        throw new IllegalRequestException("Will not certify an already certified document");
    }

    // Don't sign documents where the certification does not allow it
    if (reader.getCertificationLevel() == PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED
            || reader.getCertificationLevel() == PdfSignatureAppearance.CERTIFIED_FORM_FILLING) {
        throw new IllegalRequestException("Will not sign a certified document where signing is not allowed");
    }

    Permissions currentPermissions = Permissions.fromInt(reader.getPermissions());

    if (params.getSetPermissions() != null && params.getRemovePermissions() != null) {
        throw new SignServerException("Signer " + workerId + " missconfigured. Only one of " + SET_PERMISSIONS
                + " and " + REMOVE_PERMISSIONS + " should be specified.");
    }

    Permissions newPermissions;
    if (params.getSetPermissions() != null) {
        newPermissions = params.getSetPermissions();
    } else if (params.getRemovePermissions() != null) {
        newPermissions = currentPermissions.withRemoved(params.getRemovePermissions());
    } else {
        newPermissions = null;
    }

    Permissions rejectPermissions = Permissions.fromSet(params.getRejectPermissions());
    byte[] userPassword = reader.computeUserPassword();
    int cryptoMode = reader.getCryptoMode();
    if (LOG.isDebugEnabled()) {
        StringBuilder buff = new StringBuilder();
        buff.append("Current permissions: ").append(currentPermissions).append("\n")
                .append("Remove permissions: ").append(params.getRemovePermissions()).append("\n")
                .append("Reject permissions: ").append(rejectPermissions).append("\n")
                .append("New permissions: ").append(newPermissions).append("\n").append("userPassword: ")
                .append(userPassword == null ? "null" : "yes").append("\n").append("ownerPassword: ")
                .append(password == null ? "no" : (isUserPassword(reader, password) ? "no" : "yes"))
                .append("\n").append("setOwnerPassword: ")
                .append(params.getSetOwnerPassword() == null ? "no" : "yes").append("\n").append("cryptoMode: ")
                .append(cryptoMode);
        LOG.debug(buff.toString());
    }

    if (appendMode && (newPermissions != null || params.getSetOwnerPassword() != null)) {
        appendMode = false;
        if (LOG.isDebugEnabled()) {
            LOG.debug("Changing appendMode to false to be able to change permissions");
        }
    }

    ByteArrayOutputStream fout = new ByteArrayOutputStream();

    // increase PDF version if needed by digest algorithm
    final char updatedPdfVersion;
    if (minimumPdfVersion > pdfVersion) {
        updatedPdfVersion = Character.forDigit(minimumPdfVersion, 10);
        if (LOG.isDebugEnabled()) {
            LOG.debug("Need to upgrade PDF to version 1." + updatedPdfVersion);
        }

        // check that the document isn't already signed 
        // when trying to upgrade version
        final AcroFields af = reader.getAcroFields();
        final List<String> sigNames = af.getSignatureNames();

        if (!sigNames.isEmpty()) {
            // TODO: in the future we might want to support
            // a fallback option in this case to allow re-signing using the same version (using append)
            throw new IllegalRequestException(
                    "Can not upgrade an already signed PDF and a higher version is required to support the configured digest algorithm");
        }

        appendMode = false;
    } else {
        updatedPdfVersion = '\0';
    }

    PdfStamper stp = PdfStamper.createSignature(reader, fout, updatedPdfVersion, null, appendMode);
    PdfSignatureAppearance sap = stp.getSignatureAppearance();

    // Set the new permissions
    if (newPermissions != null || params.getSetOwnerPassword() != null) {
        if (cryptoMode < 0) {
            cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128;
            if (LOG.isDebugEnabled()) {
                LOG.debug("Setting default encryption algorithm");
            }
        }
        if (newPermissions == null) {
            newPermissions = currentPermissions;
        }
        if (params.getSetOwnerPassword() != null) {
            password = params.getSetOwnerPassword().getBytes("ISO-8859-1");
        } else if (isUserPassword(reader, password)) {
            // We do not have an owner password so lets use a random one
            password = new byte[16];
            random.nextBytes(password);
            if (LOG.isDebugEnabled()) {
                LOG.debug("Setting random owner password");
            }
        }
        stp.setEncryption(userPassword, password, newPermissions.asInt(), cryptoMode);
        currentPermissions = newPermissions;
    }

    // Reject if any permissions are rejected and the document does not use a permission password
    // or if it contains any of the rejected permissions
    if (rejectPermissions.asInt() != 0) {
        if (cryptoMode < 0 || currentPermissions.containsAnyOf(rejectPermissions)) {
            throw new IllegalRequestException("Document contains permissions not allowed by this signer");
        }
    }

    // include signer certificate crl inside cms package if requested
    CRL[] crlList = null;
    if (params.isEmbed_crl()) {
        crlList = getCrlsForChain(certs);
    }
    sap.setCrypto(null, certChain, crlList, PdfSignatureAppearance.SELF_SIGNED);

    // add visible signature if requested
    if (params.isAdd_visible_signature()) {
        int signaturePage = getPageNumberForSignature(reader, params);
        sap.setVisibleSignature(new com.lowagie.text.Rectangle(params.getVisible_sig_rectangle_llx(),
                params.getVisible_sig_rectangle_lly(), params.getVisible_sig_rectangle_urx(),
                params.getVisible_sig_rectangle_ury()), signaturePage, null);

        // set custom image if requested
        if (params.isUse_custom_image()) {
            sap.setAcro6Layers(true);
            PdfTemplate n2 = sap.getLayer(2);
            params.getCustom_image().setAbsolutePosition(0, 0);
            n2.addImage(params.getCustom_image());
        }
    }

    // Certification level
    sap.setCertificationLevel(params.getCertification_level());

    PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached"));
    dic.setReason(params.getReason());
    dic.setLocation(params.getLocation());
    dic.setDate(new PdfDate(Calendar.getInstance()));

    sap.setCryptoDictionary(dic);

    // add timestamp to signature if requested
    TSAClient tsc = null;
    if (params.isUse_timestamp()) {
        final String tsaUrl = params.getTsa_url();

        if (tsaUrl != null) {
            tsc = getTimeStampClient(params.getTsa_url(), params.getTsa_username(), params.getTsa_password());
        } else {
            tsc = new InternalTSAClient(getWorkerSession(), params.getTsa_worker(), params.getTsa_username(),
                    params.getTsa_password());
        }
    }

    // embed ocsp response in cms package if requested
    // for ocsp request to be formed there needs to be issuer certificate in
    // chain
    byte[] ocsp = null;
    if (params.isEmbed_ocsp_response() && certChain.length >= 2) {
        String url;
        try {
            url = PdfPKCS7.getOCSPURL((X509Certificate) certChain[0]);
            if (url != null && url.length() > 0) {
                ocsp = new OcspClientBouncyCastle((X509Certificate) certChain[0],
                        (X509Certificate) certChain[1], url).getEncoded();
            }
        } catch (CertificateParsingException e) {
            throw new SignServerException("Error getting OCSP URL from certificate", e);
        }

    }

    PdfPKCS7 sgn;
    try {
        sgn = new PdfPKCS7(privKey, certChain, crlList, digestAlgorithm, null, false);
    } catch (InvalidKeyException e) {
        throw new SignServerException("Error constructing PKCS7 package", e);
    } catch (NoSuchProviderException e) {
        throw new SignServerException("Error constructing PKCS7 package", e);
    } catch (NoSuchAlgorithmException e) {
        throw new SignServerException("Error constructing PKCS7 package", e);
    }

    MessageDigest messageDigest;
    try {
        messageDigest = MessageDigest.getInstance(digestAlgorithm);
    } catch (NoSuchAlgorithmException e) {
        throw new SignServerException("Error creating " + digestAlgorithm + " digest", e);
    }

    Calendar cal = Calendar.getInstance();

    // calculate signature size
    if (contentEstimated == 0) {
        contentEstimated = calculateEstimatedSignatureSize(certChain, tsc, ocsp, crlList);
    }

    byte[] encodedSig = calculateSignature(sgn, contentEstimated, messageDigest, cal, params, certChain, tsc,
            ocsp, sap);

    if (LOG.isDebugEnabled()) {
        LOG.debug("Estimated size: " + contentEstimated);
        LOG.debug("Encoded length: " + encodedSig.length);
    }

    if (contentEstimated + 2 < encodedSig.length) {
        if (!secondTry) {
            int contentExact = encodedSig.length;
            LOG.warn(
                    "Estimated signature size too small, usinging accurate calculation (resulting in an extra signature computation).");

            if (LOG.isDebugEnabled()) {
                LOG.debug("Estimated size: " + contentEstimated + ", actual size: " + contentExact);
            }

            // try signing again
            return addSignatureToPDFDocument(crypto, params, pdfbytes, password, contentExact, request,
                    context);
        } else {
            // if we fail to get an accurate signature size on the second attempt, bail out (this shouldn't happen)
            throw new SignServerException("Failed to calculate signature size");
        }
    }

    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));
    sap.close(dic2);
    reader.close();

    fout.close();
    return fout.toByteArray();
}

From source file:org.webpki.pdf.PDFSigner.java

License:Apache License

public byte[] addDocumentSignature(byte[] indoc, boolean certified) throws IOException {
    try {/*ww  w.  j  a  v a 2s .  c o  m*/
        PdfReader reader = new PdfReader(indoc);
        ByteArrayOutputStream bout = new ByteArrayOutputStream(8192);
        PdfStamper stp = PdfStamper.createSignature(reader, bout, '\0', null, true);

        for (Attachment file : attachments) {
            stp.addFileAttachment(file.description, file.data, "dummy", file.filename);
        }

        PdfSignatureAppearance sap = stp.getSignatureAppearance();
        sap.setCrypto(null, signer.getCertificatePath(), null, PdfSignatureAppearance.WINCER_SIGNED);

        if (reason != null) {
            sap.setReason(reason);
        }
        if (location != null) {
            sap.setLocation(location);
        }

        if (enable_signature_graphics) {
            sap.setVisibleSignature(new Rectangle(100, 100, 400, 130), reader.getNumberOfPages(), null);
        }

        sap.setCertified(certified);

        //           sap.setExternalDigest (new byte[128], new byte[20], "RSA");
        sap.setExternalDigest(new byte[512], new byte[20], "RSA");
        sap.preClose();
        MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
        byte buf[] = new byte[8192];
        int n;
        InputStream inp = sap.getRangeStream();
        while ((n = inp.read(buf)) > 0) {
            messageDigest.update(buf, 0, n);
        }
        byte hash[] = messageDigest.digest();
        PdfSigGenericPKCS sg = sap.getSigStandard();
        PdfLiteral slit = (PdfLiteral) sg.get(PdfName.CONTENTS);
        byte[] outc = new byte[(slit.getPosLength() - 2) / 2];
        PdfPKCS7 sig = sg.getSigner();
        sig.setExternalDigest(signer.signData(hash, AsymSignatureAlgorithms.RSA_SHA1), hash, "RSA");
        PdfDictionary dic = new PdfDictionary();
        byte[] ssig = sig.getEncodedPKCS7();
        System.arraycopy(ssig, 0, outc, 0, ssig.length);
        dic.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true));
        sap.close(dic);

        return bout.toByteArray();
    } catch (NoSuchAlgorithmException nsae) {
        throw new IOException(nsae.getMessage());
    } catch (DocumentException de) {
        throw new IOException(de.getMessage());
    }
}

From source file:si.vsrs.cif.svev.example.utils.PDFSignature.java

License:EUPL

public File signPDF(File document, InputStream keystore, String password, String keyPassord,
        String keystoreType, String alias, boolean bshowVisualization) {
    if (document == null || !document.exists()) {
        throw new RuntimeException("Error reading pdf");
    }//from  ww  w .j  a v a  2  s  .c o  m

    String name = document.getName();
    String substring = name.substring(0, name.lastIndexOf("."));

    File outputDocument = new File(document.getParent(), substring + "_signed.pdf");

    try (FileInputStream fis = new FileInputStream(document);
            FileOutputStream fout = new FileOutputStream(outputDocument)) {

        KeyStore ks = KeyStore.getInstance(keystoreType);
        ks.load(keystore, password.toCharArray());
        PrivateKey key = (PrivateKey) ks.getKey(alias, keyPassord.toCharArray());
        Certificate[] chain = ks.getCertificateChain(alias);
        X509Certificate xcert = (X509Certificate) chain[0];
        PdfReader reader = new PdfReader(fis);

        char tmpPdfVersion = '\0'; // default version - the same as input
        final PdfStamper stp = PdfStamper.createSignature(reader, fout, tmpPdfVersion, null, true);
        final PdfSignatureAppearance sap = stp.getSignatureAppearance();
        sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
        sap.setReason("Testni podpis");
        sap.setLocation("Maribor");
        sap.setContact(xcert.getSubjectDN().getName());

        //            sap.setLayer2Text("");
        //          sap.setLayer4Text("");
        sap.setAcro6Layers(true); // --:> 

        Rectangle rc = reader.getPageSize(1);
        if (bshowVisualization) {
            sap.setVisibleSignature(new Rectangle(5, rc.getHeight() - 40, 240, rc.getHeight() - 5), 1, null);
        }

        final PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached"));

        dic.setReason(sap.getReason());
        dic.setLocation(sap.getLocation());
        dic.setContact(sap.getContact());
        dic.setDate(new PdfDate(sap.getSignDate()));
        sap.setCryptoDictionary(dic);
        final int contentEstimated = 15000;
        final HashMap<PdfName, Integer> exc = new HashMap<>();
        exc.put(PdfName.CONTENTS, contentEstimated * 2 + 2);
        sap.preClose(exc);

        PdfPKCS7 sgn = new PdfPKCS7(key, chain, null, "SHA-256", null, false);
        InputStream data = sap.getRangeStream();
        final MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
        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 sh[] = sgn.getAuthenticatedAttributeBytes(hash, cal, null);
        sgn.update(sh, 0, sh.length);

        byte[] encodedSig = sgn.getEncodedPKCS7(hash, cal, null, null);

        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));

        sap.close(dic2);
    } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException
            | UnrecoverableKeyException | DocumentException | InvalidKeyException | NoSuchProviderException
            | SignatureException ex) {
        throw new RuntimeException(ex.getMessage(), ex);
    }

    return outputDocument;
}