digitalbazaar / forge

A native implementation of TLS in Javascript and tools to write crypto-based and network-heavy webapps
https://digitalbazaar.com/
Other
5.09k stars 785 forks source link

Allow providing a custom message digest to PKCS7 #978

Open nanndoj opened 2 years ago

nanndoj commented 2 years ago

I have a huge PDF file to be signed (280Mb) and I am struggling to find a way to generate a PKCS7 signature without loading everything to the memory. I am able to calculate the MessageDigest for that file using streams:

const digest = forge.md.sha256.create();
stream.open();
stream.onData(chunk => {
   digest.update(chunk, 'raw');
});

ifstream.onEnd(() => {
  return digest;
});

but I am not able to provide it to the pkcs7 signer. Per docs:

The message digest attribute value will be auto-calculated during signing and will be ignored if provided.

This won't work:

   const p7 = forge.pkcs7.createSignedData();

    p7.addCertificate("CERTIFICATE_PEM");

   p7.content = undefined; // The content is too big to be loaded into the memory

   p7.addSigner({
      key: pki.privateKeyToPem(privateKey),
      certificate: certificatePEM,
      digestAlgorithm: pki.oids.sha256,
      authenticatedAttributes: [
        {
          type: pki.oids.contentType,
          value: pki.oids.data,
        },
        {
          type: pki.oids.messageDigest,
          value: messageDigest, // This will be ignored :(
        },
        {
          type: pki.oids.signingTime,
          // value will also be auto-populated at signing time
        },
      ],
    });

    p7.sign({detached});

Is there a way I can provide an already calculated messageDigest to the signer and improve the performance instead of providing a huge file content buffer? If not... would that feature request be considered?

nanndoj commented 2 years ago

See https://github.com/digitalbazaar/forge/pull/661