pdfbox-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andreas Lehmkuehler <andr...@lehmi.de>
Subject Re: PDF digital signature is no longer valid using BC 1.51
Date Sun, 26 Oct 2014 12:52:04 GMT
Hi David,

Am 25.10.2014 um 21:10 schrieb David Wall:
> Should anybody care, David at BC found the bug that managed to work for prior BC
> versions, but no longer does under 1.51.  We changed to this method in
> CMSTypedDataInputStream to return 'in' instead of 'null' and it works under 1.50
> as well as 1.51:
>
>          @Override
>          public Object getContent()
>          {
>              return in;
>          }
>
I've applied the fix to our codebase as well, see PDFBOX-2458 for further details.

Thanks for the contribution!

BR
Andreas Lehmkühler
>
> On 10/24/2014 3:06 PM, David Wall wrote:
>> I'm now getting an invalid digital signature that I created on PDFs we
>> generate (via wkhtmltopdf and PDFBox 1.8.7).  It says "At least one signature
>> is invalid" but I previously could create them with valid signatures.  This
>> occurred when going from BouncyCastle 1.50 to 1.51, and if I go back to 1.50,
>> it works fine.
>>
>> The invalid signature complains that the "Document has been altered or
>> corrupted since it was signed".
>>
>> Here's a link to an existing PDF that has an invalid signature:
>> http://open.esignforms.com/pdfboxlist/MyDocumentsGOOD.pdf (using BC 1.50)
>> http://open.esignforms.com/pdfboxlist/MyDocumentsBAD.pdf (using BC 1.51)
>>
>> I am using Java 7.
>>
>> Here are the relevant Java code:
>>
>>     boolean signPdf(File pdfFile, File signedPdfFile)
>>     {
>>         FileInputStream fis = null;
>>         FileOutputStream fos = null;
>>         PDDocument doc = null;
>>
>>         try
>>         {
>>             fis = new FileInputStream(pdfFile);
>>             fos = new FileOutputStream(signedPdfFile);
>>
>>             int readCount;
>>             byte[] buffer = new byte[8 * 1024];
>>             while ((readCount = fis.read(buffer)) != -1)
>>             {
>>               fos.write(buffer, 0, readCount);
>>             }
>>             fis.close();
>>             fis = new FileInputStream(signedPdfFile);
>>
>>             doc = PDDocument.load(pdfFile);
>>             PDSignature signature = new PDSignature();
>> signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
>> signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
>>             signature.setName("Open eSignForms Export PDF Integrity Lock");
>> signature.setLocation(Application.getInstance().getExternalContextPath());
>>             signature.setReason("Used to ensure that an exported PDF has not
>> been tampered with since its generation by Open eSignForms deployment id: " +
>>  Application.getInstance().getDeployId());
>>             signature.setSignDate(Calendar.getInstance());
>>             doc.addSignature(signature, this);
>>             doc.saveIncremental(fis, fos);
>>             return true;
>>         }
>>         catch( Exception e )
>>         {
>>             _logger.error("signPdf() - Failed to sign the PDF",e);
>>             return false;
>>         }
>>         finally
>>         {
>>             if ( fis != null ) try { fis.close(); } catch( Exception e ) {}
>>             if ( fos != null ) try { fos.close(); } catch( Exception e ) {}
>>             if ( doc != null ) try { doc.close(); } catch( Exception e ) {}
>>         }
>>     }
>>
>>     @Override
>>     public byte[] sign(InputStream is) throws SignatureException, IOException
>>     {
>>         Application app = Application.getInstance();
>>         try
>>         {
>>             String provider = app.getPublicKeyGenerator().getProvider();
>>             SignatureKey signatureKey = app.getSignatureKey();
>>             X509Certificate cert = signatureKey.getX509Certificate();
>>             Store certStore = new JcaCertStore(Arrays.asList(cert));
>>
>>             CMSTypedDataInputStream input = new CMSTypedDataInputStream(is);
>>             CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
>>             ContentSigner sha512Signer = new
>> JcaContentSignerBuilder(PublicKeyGenerator.SIGNATURE_ALGORITHM).setProvider(provider).build(signatureKey.getPrivateKey());
>>
>>
>>             gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
>>                     new
>> JcaDigestCalculatorProviderBuilder().setProvider(provider).build()).build(sha512Signer,
>> cert));
>>             gen.addCertificates(certStore);
>>             CMSSignedData signedData = gen.generate(input, false);
>>
>>             return signedData.getEncoded();
>>         }
>>         catch (Exception e)
>>         {
>>             _logger.error("sign() - Problem while preparing PDF signature",e);
>>             return null;
>>         }
>>     }
>>
>>     class CMSTypedDataInputStream implements CMSTypedData
>>     {
>>
>>         InputStream in;
>>
>>         public CMSTypedDataInputStream(InputStream is)
>>         {
>>             in = is;
>>         }
>>
>>         @Override
>>         public ASN1ObjectIdentifier getContentType()
>>         {
>>             return PKCSObjectIdentifiers.data;
>>         }
>>
>>         @Override
>>         public Object getContent()
>>         {
>>             return null;
>>         }
>>
>>          @Override
>>          public void write(OutputStream out) throws IOException, CMSException
>>          {
>>              byte[] buffer = new byte[8 * 1024];
>>              int read;
>>              while( (read = in.read(buffer)) != -1 )
>>              {
>>                  out.write(buffer, 0, read);
>>             }
>>             in.close();
>>          }
>>     }
>>
>


Mime
View raw message