List of usage examples for org.apache.pdfbox.pdmodel.interactive.digitalsignature PDSignature getByteRange
public int[] getByteRange()
From source file:eu.europa.ec.markt.dss.signature.pdf.pdfbox.PdfBoxCMSInfo.java
License:Open Source License
/** * @param validationCertPool//from w ww.j a v a2 s. c o m * @param outerCatalog the PDF Dict of the outer document, if the PDFDocument in a enclosed revision. Can be null. * @param document the signed PDFDocument * @param cms the CMS bytes (CAdES signature) * @param inputStream the stream of the whole signed document * @throws IOException */ PdfBoxCMSInfo(CertificatePool validationCertPool, PdfDict outerCatalog, PDDocument document, PDSignature signature, byte[] cms, InputStream inputStream) throws DSSException, IOException { this.validationCertPool = validationCertPool; this.outerCatalog = PdfDssDict.build(outerCatalog); this.cms = cms; this.location = signature.getLocation(); this.signingDate = signature.getSignDate() != null ? signature.getSignDate().getTime() : null; this.signatureByteRange = signature.getByteRange(); final COSDictionary cosDictionary = document.getDocumentCatalog().getCOSDictionary(); final PdfBoxDict documentDict = new PdfBoxDict(cosDictionary, document); documentDictionary = PdfDssDict.build(documentDict); try { if (cms == null) { // due to not very good revision extracting throw new DSSPadesNoSignatureFound(); } signedBytes = signature.getSignedContent(inputStream); } catch (IOException e) { throw new DSSException(e); } }
From source file:eu.europa.ec.markt.dss.signature.pdf.pdfbox.PdfBoxSignatureService.java
License:Open Source License
/** * @param validationCertPool/*from w w w .ja v a 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.ejusticeportal.dss.controller.signature.PdfUtils.java
License:EUPL
private static byte[] getOriginalBytes(PDDocument doc, byte[] signedBytes) throws IOException { PDSignature signature = doc.getSignatureDictionaries().get(0); final int length = signature.getByteRange()[1]; final byte[] result = new byte[length]; System.arraycopy(signedBytes, 0, result, 0, length); return result; }
From source file:eu.europa.esig.dss.pades.InfiniteLoopDSS621Test.java
License:Open Source License
/** * These signatures are invalid because of non ordered signed attributes *///from w w w . j a va2s.c o m @Test public void manualTest() throws Exception { File pdfFile = new File(FILE_PATH); FileInputStream fis = new FileInputStream(pdfFile); byte[] pdfBytes = IOUtils.toByteArray(fis); PDDocument document = PDDocument.load(pdfFile); List<PDSignature> signatures = document.getSignatureDictionaries(); assertEquals(6, signatures.size()); int idx = 0; for (PDSignature pdSignature : signatures) { byte[] contents = pdSignature.getContents(pdfBytes); byte[] signedContent = pdSignature.getSignedContent(pdfBytes); logger.info("Byte range : " + Arrays.toString(pdSignature.getByteRange())); IOUtils.write(contents, new FileOutputStream("target/sig" + (idx++) + ".p7s")); ASN1InputStream asn1sInput = new ASN1InputStream(contents); ASN1Sequence asn1Seq = (ASN1Sequence) asn1sInput.readObject(); logger.info("SEQ : " + asn1Seq.toString()); ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(asn1Seq.getObjectAt(0)); assertEquals(PKCSObjectIdentifiers.signedData, oid); SignedData signedData = SignedData .getInstance(DERTaggedObject.getInstance(asn1Seq.getObjectAt(1)).getObject()); ASN1Set digestAlgorithmSet = signedData.getDigestAlgorithms(); ASN1ObjectIdentifier oidDigestAlgo = ASN1ObjectIdentifier .getInstance(ASN1Sequence.getInstance(digestAlgorithmSet.getObjectAt(0)).getObjectAt(0)); DigestAlgorithm digestAlgorithm = DigestAlgorithm.forOID(oidDigestAlgo.getId()); logger.info("DIGEST ALGO : " + digestAlgorithm); ContentInfo encapContentInfo = signedData.getEncapContentInfo(); ASN1ObjectIdentifier contentTypeOID = encapContentInfo.getContentType(); logger.info("ENCAPSULATED CONTENT INFO TYPE : " + contentTypeOID); if (!PKCSObjectIdentifiers.id_ct_TSTInfo.equals(contentTypeOID)) { // If not timestamp assertEquals(PKCSObjectIdentifiers.data, contentTypeOID); ASN1Encodable content = encapContentInfo.getContent(); logger.info("ENCAPSULATED CONTENT INFO CONTENT : " + content); assertNull(content); List<X509Certificate> certificates = extractCertificates(signedData); ASN1Set signerInfosAsn1 = signedData.getSignerInfos(); logger.info("SIGNER INFO ASN1 : " + signerInfosAsn1.toString()); SignerInfo signedInfo = SignerInfo .getInstance(ASN1Sequence.getInstance(signerInfosAsn1.getObjectAt(0))); ASN1Set authenticatedAttributeSet = signedInfo.getAuthenticatedAttributes(); logger.info("AUTHENTICATED ATTR : " + authenticatedAttributeSet); Attribute attributeDigest = null; for (int i = 0; i < authenticatedAttributeSet.size(); i++) { Attribute attribute = Attribute.getInstance(authenticatedAttributeSet.getObjectAt(i)); if (PKCSObjectIdentifiers.pkcs_9_at_messageDigest.equals(attribute.getAttrType())) { attributeDigest = attribute; break; } } assertNotNull(attributeDigest); ASN1OctetString asn1ObjString = ASN1OctetString .getInstance(attributeDigest.getAttrValues().getObjectAt(0)); String embeddedDigest = Base64.encodeBase64String(asn1ObjString.getOctets()); logger.info("MESSAGE DIGEST : " + embeddedDigest); byte[] digestSignedContent = DSSUtils.digest(digestAlgorithm, signedContent); String computedDigestSignedContentEncodeBase64 = Base64.encodeBase64String(digestSignedContent); logger.info("COMPUTED DIGEST SIGNED CONTENT BASE64 : " + computedDigestSignedContentEncodeBase64); assertEquals(embeddedDigest, computedDigestSignedContentEncodeBase64); SignerIdentifier sid = signedInfo.getSID(); logger.info("SIGNER IDENTIFIER : " + sid.getId()); IssuerAndSerialNumber issuerAndSerialNumber = IssuerAndSerialNumber .getInstance(signedInfo.getSID()); ASN1Integer signerSerialNumber = issuerAndSerialNumber.getSerialNumber(); logger.info("ISSUER AND SN : " + issuerAndSerialNumber.getName() + " " + signerSerialNumber); BigInteger serial = issuerAndSerialNumber.getSerialNumber().getValue(); X509Certificate signerCertificate = null; for (X509Certificate x509Certificate : certificates) { if (serial.equals(x509Certificate.getSerialNumber())) { signerCertificate = x509Certificate; } } assertNotNull(signerCertificate); String algorithm = signerCertificate.getPublicKey().getAlgorithm(); EncryptionAlgorithm encryptionAlgorithm = EncryptionAlgorithm.forName(algorithm); ASN1OctetString encryptedInfoOctedString = signedInfo.getEncryptedDigest(); String signatureValue = Hex.toHexString(encryptedInfoOctedString.getOctets()); logger.info("SIGNATURE VALUE : " + signatureValue); Cipher cipher = Cipher.getInstance(encryptionAlgorithm.getName()); cipher.init(Cipher.DECRYPT_MODE, signerCertificate); byte[] decrypted = cipher.doFinal(encryptedInfoOctedString.getOctets()); ASN1InputStream inputDecrypted = new ASN1InputStream(decrypted); ASN1Sequence seqDecrypt = (ASN1Sequence) inputDecrypted.readObject(); logger.info("DECRYPTED : " + seqDecrypt); DigestInfo digestInfo = new DigestInfo(seqDecrypt); assertEquals(oidDigestAlgo, digestInfo.getAlgorithmId().getAlgorithm()); String decryptedDigestEncodeBase64 = Base64.encodeBase64String(digestInfo.getDigest()); logger.info("DECRYPTED BASE64 : " + decryptedDigestEncodeBase64); byte[] encoded = authenticatedAttributeSet.getEncoded(); byte[] digest = DSSUtils.digest(digestAlgorithm, encoded); String computedDigestFromSignatureEncodeBase64 = Base64.encodeBase64String(digest); logger.info("COMPUTED DIGEST FROM SIGNATURE BASE64 : " + computedDigestFromSignatureEncodeBase64); assertEquals(decryptedDigestEncodeBase64, computedDigestFromSignatureEncodeBase64); IOUtils.closeQuietly(inputDecrypted); } IOUtils.closeQuietly(asn1sInput); } IOUtils.closeQuietly(fis); document.close(); }
From source file:eu.europa.esig.dss.pades.signature.PAdESLevelBTest.java
License:Open Source License
@Override protected void onDocumentSigned(byte[] byteArray) { try {//from ww w . j ava2 s . c o m InputStream inputStream = new ByteArrayInputStream(byteArray); PDDocument document = PDDocument.load(inputStream); List<PDSignature> signatures = document.getSignatureDictionaries(); assertEquals(1, signatures.size()); for (PDSignature pdSignature : signatures) { byte[] contents = pdSignature.getContents(byteArray); byte[] signedContent = pdSignature.getSignedContent(byteArray); logger.info("Byte range : " + Arrays.toString(pdSignature.getByteRange())); // IOUtils.write(contents, new FileOutputStream("sig.p7s")); ASN1InputStream asn1sInput = new ASN1InputStream(contents); ASN1Sequence asn1Seq = (ASN1Sequence) asn1sInput.readObject(); logger.info("SEQ : " + asn1Seq.toString()); ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(asn1Seq.getObjectAt(0)); assertEquals(PKCSObjectIdentifiers.signedData, oid); SignedData signedData = SignedData .getInstance(DERTaggedObject.getInstance(asn1Seq.getObjectAt(1)).getObject()); ASN1Set digestAlgorithmSet = signedData.getDigestAlgorithms(); ASN1ObjectIdentifier oidDigestAlgo = ASN1ObjectIdentifier .getInstance(ASN1Sequence.getInstance(digestAlgorithmSet.getObjectAt(0)).getObjectAt(0)); DigestAlgorithm digestAlgorithm = DigestAlgorithm.forOID(oidDigestAlgo.getId()); logger.info("DIGEST ALGO : " + digestAlgorithm); ContentInfo encapContentInfo = signedData.getEncapContentInfo(); ASN1ObjectIdentifier contentTypeOID = encapContentInfo.getContentType(); logger.info("ENCAPSULATED CONTENT INFO TYPE : " + contentTypeOID); assertEquals(PKCSObjectIdentifiers.data, contentTypeOID); ASN1Encodable content = encapContentInfo.getContent(); logger.info("ENCAPSULATED CONTENT INFO CONTENT : " + content); assertNull(content); List<X509Certificate> certificates = extractCertificates(signedData); ASN1Set signerInfosAsn1 = signedData.getSignerInfos(); logger.info("SIGNER INFO ASN1 : " + signerInfosAsn1.toString()); SignerInfo signedInfo = SignerInfo .getInstance(ASN1Sequence.getInstance(signerInfosAsn1.getObjectAt(0))); ASN1Set authenticatedAttributeSet = signedInfo.getAuthenticatedAttributes(); logger.info("AUTHENTICATED ATTR : " + authenticatedAttributeSet); List<ASN1ObjectIdentifier> attributeOids = new ArrayList<ASN1ObjectIdentifier>(); int previousSize = 0; for (int i = 0; i < authenticatedAttributeSet.size(); i++) { Attribute attribute = Attribute.getInstance(authenticatedAttributeSet.getObjectAt(i)); ASN1ObjectIdentifier attrTypeOid = attribute.getAttrType(); attributeOids.add(attrTypeOid); int size = attrTypeOid.getEncoded().length + attribute.getEncoded().length; assertTrue(size >= previousSize); previousSize = size; } logger.info("List of OID for Auth Attrb : " + attributeOids); Attribute attributeDigest = Attribute.getInstance(authenticatedAttributeSet.getObjectAt(1)); assertEquals(PKCSObjectIdentifiers.pkcs_9_at_messageDigest, attributeDigest.getAttrType()); ASN1OctetString asn1ObjString = ASN1OctetString .getInstance(attributeDigest.getAttrValues().getObjectAt(0)); String embeddedDigest = Base64.encodeBase64String(asn1ObjString.getOctets()); logger.info("MESSAGE DIGEST : " + embeddedDigest); byte[] digestSignedContent = DSSUtils.digest(digestAlgorithm, signedContent); String computedDigestSignedContentEncodeBase64 = Base64.encodeBase64String(digestSignedContent); logger.info("COMPUTED DIGEST SIGNED CONTENT BASE64 : " + computedDigestSignedContentEncodeBase64); assertEquals(embeddedDigest, computedDigestSignedContentEncodeBase64); SignerIdentifier sid = signedInfo.getSID(); logger.info("SIGNER IDENTIFIER : " + sid.getId()); IssuerAndSerialNumber issuerAndSerialNumber = IssuerAndSerialNumber .getInstance(signedInfo.getSID()); ASN1Integer signerSerialNumber = issuerAndSerialNumber.getSerialNumber(); logger.info("ISSUER AND SN : " + issuerAndSerialNumber.getName() + " " + signerSerialNumber); BigInteger serial = issuerAndSerialNumber.getSerialNumber().getValue(); X509Certificate signerCertificate = null; for (X509Certificate x509Certificate : certificates) { if (serial.equals(x509Certificate.getSerialNumber())) { signerCertificate = x509Certificate; } } assertNotNull(signerCertificate); String algorithm = signerCertificate.getPublicKey().getAlgorithm(); EncryptionAlgorithm encryptionAlgorithm = EncryptionAlgorithm.forName(algorithm); ASN1OctetString encryptedInfoOctedString = signedInfo.getEncryptedDigest(); String signatureValue = Hex.toHexString(encryptedInfoOctedString.getOctets()); logger.info("SIGNATURE VALUE : " + signatureValue); Cipher cipher = Cipher.getInstance(encryptionAlgorithm.getName()); cipher.init(Cipher.DECRYPT_MODE, signerCertificate); byte[] decrypted = cipher.doFinal(encryptedInfoOctedString.getOctets()); ASN1InputStream inputDecrypted = new ASN1InputStream(decrypted); ASN1Sequence seqDecrypt = (ASN1Sequence) inputDecrypted.readObject(); logger.info("DECRYPTED : " + seqDecrypt); DigestInfo digestInfo = new DigestInfo(seqDecrypt); assertEquals(oidDigestAlgo, digestInfo.getAlgorithmId().getAlgorithm()); String decryptedDigestEncodeBase64 = Base64.encodeBase64String(digestInfo.getDigest()); logger.info("DECRYPTED BASE64 : " + decryptedDigestEncodeBase64); byte[] encoded = authenticatedAttributeSet.getEncoded(); byte[] digest = DSSUtils.digest(digestAlgorithm, encoded); String computedDigestFromSignatureEncodeBase64 = Base64.encodeBase64String(digest); logger.info("COMPUTED DIGEST FROM SIGNATURE BASE64 : " + computedDigestFromSignatureEncodeBase64); assertEquals(decryptedDigestEncodeBase64, computedDigestFromSignatureEncodeBase64); IOUtils.closeQuietly(inputDecrypted); IOUtils.closeQuietly(asn1sInput); } IOUtils.closeQuietly(inputStream); document.close(); } catch (Exception e) { logger.error(e.getMessage(), e); fail(e.getMessage()); } }
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 a va2 s . co m*/ * @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;/* www. ja va 2 s . co 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; }