You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@pdfbox.apache.org by "Tilman Hausherr (Jira)" <ji...@apache.org> on 2023/02/20 19:25:00 UTC

[jira] [Comment Edited] (PDFBOX-5568) Document getting corrupted on adding Signed Attributes

    [ https://issues.apache.org/jira/browse/PDFBOX-5568?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17691275#comment-17691275 ] 

Tilman Hausherr edited comment on PDFBOX-5568 at 2/20/23 7:24 PM:
------------------------------------------------------------------

Please add a result PDF, and mention what version you are using.


was (Author: tilman):
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
>          Components: Signing
>            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-unsubscribe@pdfbox.apache.org
For additional commands, e-mail: dev-help@pdfbox.apache.org