0

I am using a smart card device used to sign pdf document. I already know how to sign the pdf using itext.

I have a 20 byte sha-1 hash, 256 byte signature (rsa encrypted by smart card private key) and a public key (.cer certificate)

Is there a way to create a pkcs#7 binary object in C, using a free library such as cryptlib?

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
GLC
  • 3
  • 3
  • Probably, but you would need access to the smart card for private key ops. The old signature is useless. "cryptlib can make use of the crypto capabilities of a variety of external crypto devices such as hardware crypto accelerators, Fortezza cards, PKCS #11 devices, hardware security modules (HSMs), and crypto smart cards. It can be used with a variety of crypto devices that have received FIPS 140 or ITSEC/Common Criteria certification. The crypto device interface also provides a general-purpose plug-in capability for adding new functionality that can be used by cryptlib." – Maarten Bodewes Jun 19 '17 at 18:46
  • Note that SHA-1 is not considered secure anymore, especially not for long term signature storage for non-repudiation. – Maarten Bodewes Jun 19 '17 at 18:49
  • I already have the signed bytes from the card and the hash of the file. All I have left is to create the PKCS#7 Object. I could not find any where how to programmatically create a PKCS#7 binary object. – GLC Jun 20 '17 at 09:18

1 Answers1

0

You seem to want to generate a PKCS#7 / CMS (cryptographic message syntax) signature using a pre-calculated signature.

This is - to my surprise - possible but for a very big IF. That IF is that the CMS message doesn't contain any additional meta data that needs to be signed. In the badly phrased words of the CMS RFC:

...
When the signedAttrs field is absent, only the octets comprising the
value of the SignedData encapContentInfo eContent OCTET STRING (e.g.,
the contents of a file) are input to the message digest calculation.
This has the advantage that the length of the content being signed
need not be known in advance of the signature generation process.
...

You can exclude the signedAtrrs in for instance OpenSSL using the -noattr command line option. Unfortunately I did not find a direct way to include the signature value itself, but this is very likely to be possible using the C API of OpenSSL - and as OpenSSL is Open Source, it would of course be possible to amend this problem if it isn't.


Notes:

  • A good hack would be to create a signature over a zero byte value using a different key when performing CMS, then look up that value (by binary search or by parsing the ASN.1 CMS structures) and then replace that signature with the one you've generated;
  • CryptLib and SHA-1 are only useful when you are planning to travel back in time. I strongly recommend to use well maintained libraries and - of course - secure hash.
Community
  • 1
  • 1
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • byte[] hash = DigestAlgorithms.Digest(data, hashAlgorithm); byte[] ocsp = null; byte[] extSignature = externalSignature.Sign(sh); sgn.SetExternalDigest(extSignature, null, externalSignature.GetEncryptionAlgorithm()); byte[] sh = sgn.getAuthenticatedAttributeBytes(hash,.., sigtype); byte[] encodedSig = sgn.GetEncodedPKCS7(hash, tsaClient, ocsp, crlBytes, sigtype); I wrote all the steps in C except GetEncodedPKCS7 method. This method requires only 3 arguments: the hash bytes, the external signatures bytes and the *.cer certificate. Is there a way to implement GetEncodedPKCS7 in C? – GLC Jun 20 '17 at 13:23