Example usage for org.apache.pdfbox.pdmodel.interactive.digitalsignature PDSignature getSubFilter

List of usage examples for org.apache.pdfbox.pdmodel.interactive.digitalsignature PDSignature getSubFilter

Introduction

In this page you can find the example usage for org.apache.pdfbox.pdmodel.interactive.digitalsignature PDSignature getSubFilter.

Prototype

public String getSubFilter() 

Source Link

Document

Returns the subfilter.

Usage

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

License:Open Source License

/**
 * @param validationCertPool//from  w w w. j a  va  2 s . co  m
 * @param byteRangeMap
 * @param outerCatalog       the PdfDictionary of the document that enclose the document stored in the input InputStream
 * @param input              the Pdf bytes to open as a PDF
 * @return
 * @throws DSSException
 */
private Set<PdfSignatureOrDocTimestampInfo> validateSignatures(CertificatePool validationCertPool,
        Map<String, Set<PdfSignatureOrDocTimestampInfo>> byteRangeMap, PdfDict outerCatalog, InputStream input)
        throws DSSException {
    Set<PdfSignatureOrDocTimestampInfo> signaturesFound = new LinkedHashSet<PdfSignatureOrDocTimestampInfo>();
    final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    PDDocument doc = null;
    try {
        DSSUtils.copy(input, buffer);

        doc = PDDocument.load(new ByteArrayInputStream(buffer.toByteArray()));
        final PdfDict catalog = new PdfBoxDict(doc.getDocumentCatalog().getCOSDictionary(), doc);

        final List<PDSignature> signatureDictionaries = doc.getSignatureDictionaries();
        if (LOG.isDebugEnabled()) {
            LOG.debug("Found {} signatures in PDF dictionary of PDF sized {} bytes",
                    signatureDictionaries.size(), buffer.size());
        }
        for (int i = 0; i < signatureDictionaries.size(); i++) {
            final PDSignature signature = signatureDictionaries.get(i);
            /**
             * SubFilter Name (Required) The value of SubFilter identifies the format of the data contained in the stream.
             * A conforming reader may use any conforming signature handler that supports the specified format.
             * When the value of Type is DocTimestamp, the value of SubFilter shall be ETSI.RFC3161.
             */
            final String subFilter = signature.getSubFilter();

            byte[] cms = new PdfBoxDict(signature.getDictionary(), doc).get("Contents");

            PdfSignatureOrDocTimestampInfo signatureInfo;
            try {
                if (PdfBoxDocTimeStampService.SUB_FILTER_ETSI_RFC3161.getName().equals(subFilter)) {
                    signatureInfo = PdfSignatureFactory.createPdfTimestampInfo(validationCertPool, outerCatalog,
                            doc, signature, cms, buffer);
                } else {
                    signatureInfo = PdfSignatureFactory.createPdfSignatureInfo(validationCertPool, outerCatalog,
                            doc, signature, cms, buffer);
                }
            } catch (PdfSignatureOrDocTimestampInfo.DSSPadesNoSignatureFound e) {
                LOG.debug("No signature found in signature Dictionary:Content", e);
                continue;
            }

            signatureInfo = signatureAlreadyInListOrSelf(signaturesFound, signatureInfo);

            // should store in memory this byte range with a list of signature found there
            final String byteRange = Arrays.toString(signature.getByteRange());
            Set<PdfSignatureOrDocTimestampInfo> innerSignaturesFound = byteRangeMap.get(byteRange);
            if (innerSignaturesFound == null) {
                // Recursive call to find inner signatures in the byte range covered by this signature. Deep first search.
                final byte[] originalBytes = signatureInfo.getOriginalBytes();
                if (LOG.isDebugEnabled()) {
                    LOG.debug(
                            "Searching signature in the previous revision of the document, size of revision is {} bytes",
                            originalBytes.length);
                }
                innerSignaturesFound = validateSignatures(validationCertPool, byteRangeMap, catalog,
                        new ByteArrayInputStream(originalBytes));
                byteRangeMap.put(byteRange, innerSignaturesFound);
            }

            // need to mark a signature as included inside another one. It's needed to link timestamp signature with the signatures covered by the timestamp.
            for (PdfSignatureOrDocTimestampInfo innerSignature : innerSignaturesFound) {
                innerSignature = signatureAlreadyInListOrSelf(signaturesFound, innerSignature);
                signaturesFound.add(innerSignature);
                innerSignature.addOuterSignature(signatureInfo);
            }

            signaturesFound.add(signatureInfo);
        }
        return signaturesFound;
    } catch (IOException up) {
        LOG.error("Error loading buffer of size {}", buffer.size(), up);
        // ignore error when loading signatures
        return signaturesFound;
    } finally {
        DSSPDFUtils.close(doc);
    }
}

From source file:eu.europa.esig.dss.pades.signature.PAdESLevelBWithContentTimestampTest.java

License:Open Source License

@Override
protected void onDocumentSigned(byte[] byteArray) {
    super.onDocumentSigned(byteArray);

    try (PDDocument doc = PDDocument.load(byteArray)) {
        List<PDSignature> signatureDictionaries = doc.getSignatureDictionaries();
        assertEquals(1, signatureDictionaries.size());
        PDSignature pdSignature = signatureDictionaries.get(0);
        assertNotNull(pdSignature.getName());
        assertNotNull(pdSignature.getReason());
        assertNotNull(pdSignature.getLocation());
        assertNotNull(pdSignature.getContactInfo());
        assertNotNull(pdSignature.getSignDate()); // M
        assertEquals("Adobe.PPKLite", pdSignature.getFilter());
        assertEquals("ETSI.CAdES.detached", pdSignature.getSubFilter());
    } catch (IOException e) {
        throw new DSSException(e);
    }// w ww  .jav a 2  s . co m
}

From source file:eu.europa.esig.dss.pdf.pdfbox.PdfBoxCMSInfo.java

License:Open Source License

/**
 *
 * @param signature The signature object
 * @param dssDictionary the DSS dictionary
 * @param cms the signature binary/*from w w  w. j av a 2s  .c  om*/
 * @param signedContent the signed content
 */
PdfBoxCMSInfo(PDSignature signature, PdfDssDict dssDictionary, byte[] cms, byte[] signedContent) {
    this.cms = cms;
    this.location = signature.getLocation();
    this.reason = signature.getReason();
    this.contactInfo = signature.getContactInfo();
    this.subFilter = signature.getSubFilter();
    this.signingDate = signature.getSignDate() != null ? signature.getSignDate().getTime() : null;
    this.signatureByteRange = signature.getByteRange();
    this.dssDictionary = dssDictionary;
    this.signedBytes = signedContent;
}

From source file:eu.europa.esig.dss.pdf.pdfbox.PdfBoxSignatureService.java

License:Open Source License

private List<PdfSignatureOrDocTimestampInfo> getSignatures(CertificatePool validationCertPool,
        byte[] originalBytes) {
    List<PdfSignatureOrDocTimestampInfo> signatures = new ArrayList<PdfSignatureOrDocTimestampInfo>();
    ByteArrayInputStream bais = null;
    PDDocument doc = null;/* w  w w .j  av  a  2  s  .  c  o m*/
    try {

        bais = new ByteArrayInputStream(originalBytes);
        doc = PDDocument.load(bais);

        List<PDSignature> pdSignatures = doc.getSignatureDictionaries();
        if (CollectionUtils.isNotEmpty(pdSignatures)) {
            logger.debug("{} signature(s) found", pdSignatures.size());

            PdfDict catalog = new PdfBoxDict(doc.getDocumentCatalog().getCOSDictionary(), doc);
            PdfDssDict dssDictionary = PdfDssDict.extract(catalog);

            for (PDSignature signature : pdSignatures) {
                String subFilter = signature.getSubFilter();
                byte[] cms = signature.getContents(originalBytes);

                if (StringUtils.isEmpty(subFilter) || ArrayUtils.isEmpty(cms)) {
                    logger.warn("Wrong signature with empty subfilter or cms.");
                    continue;
                }

                byte[] signedContent = signature.getSignedContent(originalBytes);
                int[] byteRange = signature.getByteRange();

                PdfSignatureOrDocTimestampInfo signatureInfo = null;
                if (PdfBoxDocTimeStampService.SUB_FILTER_ETSI_RFC3161.getName().equals(subFilter)) {
                    boolean isArchiveTimestamp = false;

                    // LT or LTA
                    if (dssDictionary != null) {
                        // check is DSS dictionary already exist
                        if (isDSSDictionaryPresentInPreviousRevision(
                                getOriginalBytes(byteRange, signedContent))) {
                            isArchiveTimestamp = true;
                        }
                    }

                    signatureInfo = new PdfBoxDocTimestampInfo(validationCertPool, signature, dssDictionary,
                            cms, signedContent, isArchiveTimestamp);
                } else {
                    signatureInfo = new PdfBoxSignatureInfo(validationCertPool, signature, dssDictionary, cms,
                            signedContent);
                }

                if (signatureInfo != null) {
                    signatures.add(signatureInfo);
                }
            }
            Collections.sort(signatures, new PdfSignatureOrDocTimestampInfoComparator());
            linkSignatures(signatures);

            for (PdfSignatureOrDocTimestampInfo sig : signatures) {
                logger.debug("Signature " + sig.uniqueId() + " found with byteRange "
                        + Arrays.toString(sig.getSignatureByteRange()) + " (" + sig.getSubFilter() + ")");
            }
        }

    } catch (Exception e) {
        logger.warn("Cannot analyze signatures : " + e.getMessage(), e);
    } finally {
        IOUtils.closeQuietly(bais);
        IOUtils.closeQuietly(doc);
    }

    return signatures;
}

From source file:pdfbox.SignatureVerifier.java

License:Apache License

public Map<String, SignatureResult> extractSignatures(File infile) throws IOException, CertificateException,
        NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException {
    Map<String, SignatureResult> result = new HashMap<>();

    try (PDDocument document = PDDocument.load(infile)) {
        for (PDSignature sig : document.getSignatureDictionaries()) {
            COSDictionary sigDict = sig.getCOSObject();
            COSString contents = (COSString) sigDict.getDictionaryObject(COSName.CONTENTS);

            // download the signed content
            byte[] buf;
            try (FileInputStream fis = new FileInputStream(infile)) {
                buf = sig.getSignedContent(fis);
            }/*from  w  ww. j  ava  2 s  .c  o m*/

            System.out.println("Signature found");
            System.out.println("Name:     " + sig.getName());
            System.out.println("Modified: " + sdf.format(sig.getSignDate().getTime()));
            String subFilter = sig.getSubFilter();
            if (subFilter != null) {
                switch (subFilter) {
                case "adbe.pkcs7.detached": // COSName.ADBE_PKCS7_DETACHED
                    result.put(sig.getName(), verifyPKCS7(buf, contents, sig));

                    //TODO check certificate chain, revocation lists, timestamp...
                    break;
                case "adbe.pkcs7.sha1": // COSName.ADBE_PKCS7_SHA1
                {
                    // example: PDFBOX-1452.pdf
                    //COSString certString = (COSString) sigDict.getDictionaryObject(
                    //        COSName.CONTENTS);
                    byte[] certData = contents.getBytes();
                    Collection<? extends Certificate> certs = getCertificates(certData);
                    System.out.println("certs=" + certs);
                    byte[] hash = MessageDigest.getInstance("SHA1").digest(buf);
                    result.put(sig.getName(), verifyPKCS7(hash, contents, sig));

                    //TODO check certificate chain, revocation lists, timestamp...
                    break;
                }
                case "adbe.x509.rsa_sha1": // COSName.ADBE_PKCS7_SHA1
                {
                    // example: PDFBOX-2693.pdf
                    COSString certString = (COSString) sigDict.getDictionaryObject(COSName.getPDFName("Cert"));
                    byte[] certData = certString.getBytes();
                    Collection<? extends Certificate> certs = getCertificates(certData);
                    System.out.println("certs=" + certs);

                    //TODO verify signature
                    throw new IOException(subFilter + " verification not supported");
                    //break;
                }
                default:
                    throw new IOException("Unknown certificate type: " + subFilter);
                    //break;
                }
            } else {
                throw new IOException("Missing subfilter for cert dictionary");
            }
        }
    } catch (CMSException | OperatorCreationException ex) {
        throw new IOException(ex);
    }

    return result;
}