[ https://issues.apache.org/jira/browse/PDFBOX-5568?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17691275#comment-17691275 ]
Tilman Hausherr commented on PDFBOX-5568: ----------------------------------------- Please add a result PDF > Document getting corrupted on adding Signed Attributes > ------------------------------------------------------ > > Key: PDFBOX-5568 > URL: https://issues.apache.org/jira/browse/PDFBOX-5568 > Project: PDFBox > Issue Type: Bug > Reporter: Piyush > Priority: Major > > While trying to digitally sign document using *filter* as > *_FILTER_ADOBE_PPKLITE_* and *subfilter* as > {*}_SUBFILTER_ETSI_CADES_DETACHED_{*}. For {*}ETSI_CADES_Detached{*}, a > signing attribute is needs to be added. I am fetching signed hash and > certificates from CSC. But after adding signing attribute, it is making the > document corrupt. Below is the screenshot for the reference . Seems like hash > is getting changed. > !https://i.stack.imgur.com/KKgRh.png! > > *Code snippet for reference:* > {code:java} > PDDocument document = PDDocument.load(inputStream); > outFile = File.createTempFile("signedFIle", ".pdf"); > Certificate[] certificateChain = //retrieve certificate chain from CSC > integration > setCertificateChain(certificateChain); > // sign > FileOutputStream output = new FileOutputStream(outFile); > IOUtils.copy(inputStream, output); > // create signature dictionary > PDSignature signature = new PDSignature(); > int accessPermissions = SigUtils.getMDPPermission(document); > if (accessPermissions == 1) > { > throw new IllegalStateException("No changes to the document are permitted due > to DocMDP transform parameters dictionary"); > } > signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); > signature.setSubFilter(PDSignature.SUBFILTER_ETSI_CADES_DETACHED); > signature.setName("Test Name"); > signature.setLocation("Bucharest, RO"); > signature.setReason("PDFBox Signing"); > signature.setSignDate(Calendar.getInstance()); > Rectangle2D humanRect = new Rectangle2D.Float(location.getLeft(), > location.getBottom(), location.getRight(), location.getTop()); > PDRectangle rect = createSignatureRectangle(document, humanRect); > SignatureOptions signatureOptions = new SignatureOptions(); > signatureOptions.setVisualSignature(createVisualSignatureTemplate(document, > 0, rect, signature)); > signatureOptions.setPage(0); > document.addSignature(signature, signatureOptions); > ExternalSigningSupport externalSigning = > document.saveIncrementalForExternalSigning(output); > InputStream content = externalSigning.getContent(); > CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); > X509Certificate cert = (X509Certificate) certificateChain[0]; > gen.addCertificates(new JcaCertStore(Arrays.asList(certificateChain))); > MessageDigest digest = MessageDigest.getInstance("SHA-256"); > // Use a buffer to read the input stream in chunks > byte[] buffer = new byte[4096]; > int bytesRead; > while ((bytesRead = content.read(buffer)) != -1) { > digest.update(buffer, 0, bytesRead); > } > byte[] hashBytes = digest.digest(); > ESSCertIDv2 certid = new ESSCertIDv2( > new AlgorithmIdentifier(new ASN1ObjectIdentifier("*****")), > MessageDigest.getInstance("SHA-256").digest(cert.getEncoded()) > ); > SigningCertificateV2 sigcert = new SigningCertificateV2(certid); > final DERSet attrValues = new DERSet(sigcert); > Attribute attr = new > Attribute(PKCSObjectIdentifiers.id_aa_signingCertificateV2, attrValues); > ASN1EncodableVector v = new ASN1EncodableVector(); > v.add(attr); > AttributeTable atttributeTable = new AttributeTable(v); > //Create a standard attribute table from the passed in parameters - certhash > CMSAttributeTableGenerator attrGen = new > DefaultSignedAttributeTableGenerator(atttributeTable); > final byte[] signedHash = // Retrieve signed hash from CSC. > ContentSigner nonSigner = new ContentSigner() { > @Override > public byte[] getSignature() > { return signedHash; } > @Override > public OutputStream getOutputStream() { > return new ByteArrayOutputStream(); > } > @Override > public AlgorithmIdentifier getAlgorithmIdentifier() { > return new DefaultSignatureAlgorithmIdentifierFinder().find( "SHA256WithRSA" > ); > } > }; > org.bouncycastle.asn1.x509.Certificate cert2 = > org.bouncycastle.asn1.x509.Certificate.getInstance(ASN1Primitive.fromByteArray(cert.getEncoded())); > JcaSignerInfoGeneratorBuilder sigb = new JcaSignerInfoGeneratorBuilder(new > JcaDigestCalculatorProviderBuilder().build()); > sigb.setSignedAttributeGenerator(attrGen); > gen.addSignerInfoGenerator(sigb.build(nonSigner, new > X509CertificateHolder(cert2))); > CMSTypedData msg = new CMSProcessableInputStream( inputStream); > CMSSignedData signedData = gen.generate((CMSTypedData)msg, false); > byte[] cmsSignature = signedData.getEncoded(); > inputStream.close(); > externalSigning.setSignature(cmsSignature); > IOUtils.closeQuietly(signatureOptions); > return new FileInputStream(outFile); > {code} > If I use subfilter as SUBFILTER_ADBE_PKCS7_DETACHED and don’t add > addtibutesTable, then it works fine. But for SUBFILTER_ETSI_CADES_DETACHED, > attributes needs to be added. -- This message was sent by Atlassian Jira (v8.20.10#820010) --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@pdfbox.apache.org For additional commands, e-mail: dev-h...@pdfbox.apache.org