iTextSharp not rendering digital signature - pdf

I've read the I-TEXT digital signature e-text, and also previous posts answered by MKL (who seems to be the authority along with Bruno on this topic).
essentially I have an Azure app service that gets the digital sig (base 64) and certificate chain from the company's signing API. The company's signing API returns a signature in Base64 along with a certificate chain.
I just want the to insert a signature object/container into the pdf so it will show in the signature panel when an end user opens up the pdf. I prefer to use deferred signing.
I've shifted from chapter 4's "clientseversigning example" to instead Deferred Signing in MKL's "How to create a PDF signature without knowing the signer certificate early".
The Company API returns a "plain" signature, that I am pretty sure, and also returns a chain of 3 string certificates.
I should note I do have the root and sub certs in advance (2 .cer files) but I am not using them in "prepping" the pdf for hashing right now since the deferred signing example doesn't make use of them obviously. For the container construction code (after getting the response from the Company API), I use the 3 certs chain returned from the company API, but I also tried it with the 2 .cer files, to no avail.
The only difference between my code and the one in the example is instead of byte[] certificateBytes = THE_RETRIEVED_CERTIFICATE_BYTES; X509Certificate x509Certificate = new X509CertificateParser().ReadCertificate(certificateBytes); I build 3 x509Certificates (one for each string in the chain returned from the Company API.
Sadly things wont work, I get these errors in Acrobat: Signature is invalid, There are errors in the formatting or information contained in this signature, signature's identity has not yet been verified, signing time is from the clock on the signer's computer...also if I click Certificate details just below of this error in Acrobat it is blank. This was pretty much the errors I was getting when trying the "clientserversigning example"
I am trying really hard and wondering what it could be... should I try modifying the estimated size from 12000 and bump it up? or the errors I am getting in Acrobat, maybe they are hinting the certificate chain from the Company API is not being picked up by the signing deferral container construction code ... I am struggling but any tips would be so greatly appreciated
Evan
Just to clarify, I am following chapter 4's clientserversigningexample but I am getting the following once my pdf is recreated with the signature from the company API
Its saying 1) there are errors in the formatting of information
2) signer's identity has not been verified
3) signing time is from the clock on the signer's computer
now as far as "prepping" the pdf before hashing it to send for signing...I don't see anything in the ClientSigning example that specifically preps it, can I assume the IText library is prepping it under the hood?

In your question and in your comments to it you appear to be in particular interested in
whether or not one can use a signature API that returns the certificates only together with the signature, and
when to to deferred signing.
Can You Use a Signature API That Provides the User Certificate Only After Signing
To answer this one first has to clarify what kind of signatures the signature API in question creates, plain signature values (e.g. PKCS#1 RSA signatures) or full-fledged CMS signature containers.
If it creates full-fledged CMS signature containers, you can create signatures following arbitrary signature profiles as long as the signature containers follow the requirements for them (which they often do). They only restriction you have is that you cannot have information from the signer certificate in the signature visualization because that visualization is defined in the signed data of the PDF.
If it only creates plain signature values, the best you can do is create and embed simple CMS containers that don't contain pointers to the signer certificate in the signed attributes (if they have any signed attributes as all to start with). Many signature policies of interest do require such pointers, but at least Adobe Reader accepts signatures without.
If you are in this situation and want to try creating signatures with such simple signature containers, you may want to use the code from this answer, section "How to create a PDF signature without knowing the signer certificate early".
When to Use Deferred Signing
The difference between deferred signing and other iText signing calls is not that deferred signing requires less information (compared to ExternalContainer signing).
In contrast to the other iText signing methods, signDeferred re-uses the outermost existing, filled signature field of the PDF to sign and merely replaces the signature container therein.
The method name is derived from the most common use case it’s used for:
In a first step a signature field is (probably first created and then) filled using signExternalContainer with an IExternalSignatureContainer implementation that calculates the document hash to be signed but does not return the final CMS container yet, merely some (usually) empty array. The generated PDF with a filled signature field (albeit without the final signature container) is then temporarily stored (in the file system or a database).
In a second step a signature container for the determined document hash is requested and (probably asynchronously) awaited.
In a final step signDeferred is used to inject the retrieved signature container into the PDF prepared in the first step.
This deferred signing process usually is preferred in setups in which the second step, the signature container creation and retrieval, can take longer than one wants to keep the resources blocked which are required for the document in signing. This includes in particular signatures generated by remote servers or clients, especially if that signing process awaits some third party clearance or activation.

Related

Digital Signature/ eSign verification fails

I have a eSigned / Digitally signed PDF, the document is signed using iText lib in detached signature. I am having issue while verifying the signature, getting message "signers identity is invalid because it has expired or not yet valid" and in signer info "There were errors building the path from signers certificate to an issuer certificate."
I have tried many ways to validate the signature but couldn't get any success. If I explicitly add signers certificate as trusted certificate then I get a green check and able to verify the signature but I think thats not the correct way to do it.
Adobe Signature setting are as follow:-
digitally signed pdf can be found heredigitally signed document
can anyone please help to resolve this issue.
I have tried many ways to validate the signature but couldn't get any success.
That is not surprising: Your signature is not valid. In the PDF signature field value there is a signing time 2020/06/11 09:28:35 GMT but your signer certificate is valid not before 2020/06/11 09:29:44 GMT and not after 2020/06/11 09:59:44 GMT. At the claimed signing time, therefore, your signer certificate was not valid yet and could not create a valid signature.
Apparently you sign using a signing service that creates a short-time certificate just in time when your signature request to it arrives. Unfortunately that is after the time iText stored as signing time in the PDF at the beginning of the signing process.
Thus, one way to resolve the issue is to tell iText to use a time slightly (e.g. two minutes) in the future.
You can do that by means of the PdfSignatureAppearance method setSignDate.
Your signature actually also violates a recommendation from the specification: The afore mentioned signing time stored in the signature field value dictionary should be used only when the time of signing is not available in the signature (the embedded signature container). In your case, though, the embedded signature container does contain a signingTime signed attribute with value 11/06/2020 09:29:44 GMT which is not before the start of certificate validity.
As that only is a recommendation, your PDF signature is not made invalid by having two signing time values. But as the values differ, this can result in different verification results by different validators, using either one or the other value.
Thus, another way to resolve the issue is to make sure no signing time value is added to the signature value dictionary at all. This additionally makes your signed PDF follow the recommendation above and so be more precise.
Unfortunately using the PdfSignatureAppearance method setSignDate to set a null value does not work, later on in the signing process this results in NullPointerException occurrence. But if you use a custom ExternalSignatureContainer implementation in your signing code (and not an ExternalSignature implementation), you can remove that entry in your modifySigningDictionary implementation. The key is PdfName.M.
As an aside, as your signing certificate is only valid for half an hour, validators may also reject it if their validation policy only trusts digital time stamps, not unsecured date-time values.
Thus, you should add revocation information and digitally time stamp the whole construct during the life time of the certificate to guarantee long term validation.
I understand what your issue is. There's a whole new way of solving it, in 3 steps.
Open in Adobe Acrobat DC or any Adobe pdf editor software you have.
In Edit, go to Preferences, in the end come to Signatures. Click on verification, more, in verification time section, select current time. Same location, verification information section, select never.
In Windows integration, tick validating signatures and validating certified documents. Click ok.
Close all popups. Come back to signature area and right click to select, validate signature.
Done ✅

Simple Electronic Signature: "Signing" PDF Without Certificate for Post-Signature Tamper-Protection

First of all, a bit of background - the actual questions are at the bottom.
I'm currently working on a web-based app (sort of SaaS) which allows users to send forms to their own customers.
These forms are simple, small contracts for small jobs where their customers say "Yeah sure, I'll do this and here's my confirmation".
The sort of thing that is being "signed" does not require a fully qualified digital signature and an electronic signature will suffice.
While, in this case, a simple checkbox saying "Yeah, I'll do this" would legally be sufficient, I'm keen to implement it with a signature pad. To be honest, it's just for the factor of being seemingly more binding and, well, "neat".
The current workflow looks like this:
User's customer opens web-form (the party being asked to sign is the only person in the universe to know the direct link)
Ticks a few boxes and enters text
Clicks "Sign" which opens an HTML5 signature pad (mobile) or a simple input (PC) to type their name
Clicks "Accept"
A PDF is generated for download and stored on the server (along with timestamp, IP, and a couple of other bits of information)
As you can see, the agreement in its entirety constitutes a simple electronic signature - even without the bells and whistles.
What I would like to do
As with any simple electronic signature, it's easy for any party to say that a document may have been tampered with.
So what I did is properly sign the PDF according to the specifications (using tcpdf): that entailed first generating the PDF and then adding the signature to the /Sig dictionary, then generating a digest across all byte-ranges (excluding the signature), linking it up with a .crt file and voilá: the document is signed with the lovely benefit of the signature becoming invalid if even a single byte is changed.
Now to the questions:
Is it possible to benefit from the "tamper-validation" without using a certificate? Like I say, these are not supposed to be digital signatures but rather simple, electronic signatures. Still, I'd like to benefit from any post-signature changes being highlighted.
Alternatively, I could also simply use a proper certificate for the signing process. But this certificate would be mine rather than my users' or even my users' customers'. In that sense, would it do more harm than good? I.e. the certificate belongs to the wrong party and therefore becomes meaningless; I, rather than the signatory vouches; "The document was changed and re-signed after I signed"; etc.
Is it possible to benefit from the "tamper-validation" without using a certificate? Like I say, these are not supposed to be digital signatures but rather simple, electronic signatures. Still, I'd like to benefit from any post-signature changes being highlighted.
No, at least as long as you want to do this in an interoperable way.
You can of course invent your own security system, create a PDF viewer or at least plugins for the commonly used PDF viewers to support your system, and roll these programs out to your users.
But if you want existing Adobe Reader as-is to verify the signature, you've got to go the X509 PKI way.
Alternatively, I could also simply use a proper certificate for the signing process. But this certificate would be mine rather than my users' or even my users' customers'. In that sense, would it do more harm than good? I.e. the certificate belongs to the wrong party and therefore becomes meaningless; I, rather than the signatory vouches; "The document was changed and re-signed after I signed"; etc.
When using your own certificate for signing, don't forget to properly fill the reason field so it indicates that your signature is applied as a counter signature to guarantee validatability.
With that in place I don't see your signature doing any harm.
The question is how much good it does, though.
Obviously the user still can claim that he signed something different... because he did! He signed the web form, not the PDF. Thus, you might have to provide proof that the PDF reflects exactly what the web form showed anyways, that the user signed something equivalent.
If you want actual non-repudiation by the user, you need to make him sign personally in a manner that is commonly accepted to not allow tampering. In other words, your user needs to apply proper digital signatures himself. Everything else is open to claims of forgery.
You can use trusted time-stamp (defined in RFC3161) instead of signature created by the customer or by your server. Time-stamp protects document integrity and proves that your document existed before a particular time. Technically speaking it is a digital signature created by a trusted 3rd party.

PDF Signature digest

I have a quick question about calculating the digest of a PDF document to use for a digital signature (somewhat related to one of my earlier questions, I'm trying to figure out why you would need to know a client's certificate to create the correct digest).
In Adobe's documentation about the PDF format the following is specified:
A byte range digest shall be computed over a range of bytes in the file, that shall be indicated by the
ByteRange entry in the signature dictionary. This range should be the entire file, including the signature
dictionary but excluding the signature value itself (the Contents entry).
So at this point things seem fairly simple, just digest everything except the /Contents entry in the /Sig dictionary. The actual data in the /Contents entry is specified as followed:
For public-key signatures, Contents should be either a DER-encoded
PKCS#1 binary data object or a DER-encoded PKCS#7 binary data
object.
So still no problems, I can (probably) generate the digest, reserve space for the /Contents entry and attach this PKCS#7 object later on. The confusion starts when I read the following:
Revocation information is a signed attribute, which means that the
signing software must capture the revocation information before signing. A similar requirement applies to the
chain of certificates. The signing software must capture and validate the certificate's chain before signing.
So the thing I'm not quite getting: Apparently the /Contents entry (containing the certificate and signed digest) is not digested, yet the chain of certificates is a signed attribute (and thus needs to be digested?).
I would appreciate it if someone could further specify exactly what is digested, and perhaps better explain the signed attributes to me. The main question that I want to answer is: Can I actually create a signable digest without knowing someone's certificate beforehand? (I'm working with a pkcs7 detached signature)
In short:
Can I actually create a signable digest without knowing someone's certificate beforehand?
In case of SubFilter ETSI.CAdES.detached or adbe.pkcs7.detached you can create the document digest without knowing someone's certificate beforehand.
You usually, though, have to know the signer certificate before starting to generate the CMS signature container to embed into the PDF.
In detail:
(Beware, the following is somewhat simplified.)
I can (probably) generate the digest, reserve space for the /Contents entry and attach this PKCS#7 object later on.
If you first reserve space and thereafter generate the digest, this indeed is how things are done.
The confusion starts when I read the following:
Revocation information is a signed attribute, which means that the signing software must capture the revocation information before signing. A similar requirement applies to the chain of certificates. The signing software must capture and validate the certificate's chain before signing.
So the thing I'm not quite getting: Apparently the /Contents entry (containing the certificate and signed digest) is not digested, yet the chain of certificates is a signed attribute (and thus needs to be digested?).
I would appreciate it if someone could further specify exactly what is digested, and perhaps better explain the signed attributes to me.
The main fact one has to be aware of is that in case of PKCS#7/CMS signature containers signing usually does not merely include one hash calculation but at least two!
The first hash, the document hash, is indeed calculated for the entire file, including the signature dictionary but excluding the signature value itself (the Contents entry) (you might want to read this answer for more details).
But this is not the hash immediately used when applying the signature algorithm.
During the generation of the PKCS#7/CMS signature container (unless in its most primitive form) you create a structure called "signed attributes".
You fill this structure with multiple attributes (name-value-pairs), among them the already calculated document hash but also others, e.g. the Adobe-style revocation information you read about.
When you have finished creating that structure, you hash this structure and generate a signature for it.
You then can put together the PKCS#7/CMS signature container using these signed attributes, the signature, and some more information not signed by this signature, e.g. certificates, signature time stamps, ...
For more details concerning the signature container read this answer.
Finally you embed this signature container into the reserved space in the PDF.
The main question that I want to answer is: Can I actually create a signable digest without knowing someone's certificate beforehand? (I'm working with a pkcs7 detached signature)
In case of SubFilter ETSI.CAdES.detached or adbe.pkcs7.detached you can create the document digest without knowing someone's certificate beforehand.
Depending on the CMS signature profile, though, you usually have to know the signer certificate before starting to generate the signature container because many profiles require the presence of a signed attribute referencing the signer certificate.
Clarifications:
The OP asked some follow-up questions in a comment:
1.: One of the signed attributes is the document hash(without the /contents), so if I understand correctly this is the unsigned hash?
As the "signed attributes" eventually are hashed and signed, that document hash therein is not immediately, directly signed but it is indirectly signed as part of this structure of attributes. So I wouldn't call it unsigned...
In the end when the user really generates a signature, he signs the hash of the PKCS#7 object?
No, the hash of the "Signed attributes" structure which is only a part of the PKCS#7 object, not all of it. There are multiple parts of the PKCS#7/CMS object which are unsigned.
Does the /Contents entry still have a PKCS#7 object that's actually readable for us? (To extract certificates etc for verification)
The Contents entry does contain a full-fledged PKCS#7/CMS signature container object as a binary string. Thus, yes, you can read it (by reading the value of that binary string) and (if you have code that knows how to parse such a signature container) extract information from it.
Beware, though, the signature container may not contain all data required for verification: E.g., if you verify using the chain (not shell) validation model, you might have to extract the signing time from the respective PDF signature dictionary entry.
When verifying a signature, do we simply extract the embedded PKCS#7 object, recalculate the digest, recalculate the digest of the PKCS#7 object and verify this against the signature using the certificate we get from the PKCS#7 object?
You obviously also have to calculate the digest of the signed PDF byte ranges and compare that value with the signed attribute containing the original document digest.(You might have meant that by recalculate the digest.)
As mentioned in the answer to 3, you might have to retrieve additional information from the PDF for use in the PKCS#7 verification.
Furthermore you say the certificate we get from the PKCS#7 object - please be aware that the PKCS#7/CMS signature container may contain multiple certificates. You have to find the correct one. The CMS SignerInfo SignerIdentifier and the ESS signed attributes shall be used for that.
Furthermore you also have to verify validity and trust of the signer certificate.
Is there any good documentation on what authenticated attributes there are?
You can start reading
section 11 "Useful Attributes" of RFC 3852 or RFC 5652: basic CMS
section 12.8 of ISO 32000-1: basic PDF
all of RFC 5126: CAdES
ETSI TS 102778, especially part 2, part 3, and part 4: PAdES

Expiration of a digitally signed PDF with multiple signatures

Context
My overall goal is to make a set of PDFs available, in such a way that users can be assured of the provenance of the documents (i.e., they came from the origin that they are expected to come from). I'm thinking about doing this by digitally signing the PDFs on the server. These signatures won't be in risk of expiring, because the server can just reissue new signed PDFs when the certificate is updated. Using SSL to serve the documents wouldn't be enough, because the files can be passed on to third parties, who don't want/need to access the server.
Problem
The expiration issue arises because some of these PDFs will already have one or more digital signatures (e.g., created for legal purposes). My question is, if the server signs the PDFs, will it also be ensuring the continued validity of the previous signatures, even after they expire, as long as the latest signature is valid?
I'm asking more on the theoretical side, although I plan to implement what I describe using iText, so any pointers on how to use it for my purpose are also welcome.
No, in a PDF all signatures should be validated independently. If you open a PDF with multiple signatures In Adbobe Reader all signatures are validated and you are going to get a warning message if one of the signature validations fails.
If you want to prevent against signature validation issues (for instance a validation failure due to signing certificate expiration) you should look at the PAdES standard (PDF Advanced Electronic Signature) Part #4 (PAdES-LTV Profile - PAdES Long Term Validation). This section of the standard deals with maintaining a proof of the validation across time in order to be able to revalidate the signatures in the future.
I don't know iText very much but it seems that PAdES-LTV is supported since I found this code sample : How to apply verification according to PAdES-LTV

Document signed and timestamped locally and then uploaded to the server, does it have same characteristics?

Immagine a web application that lets you digitally sign (with personal digital certificates pkcs12 released by trusted CAs) and timestamp PDF documents with a Java applet or Active X. This must obviously happen on the machine of the user because the private key of the certificate is stored locally.
So once the PDF is signed and timestamped it is uploaded on the server.
Does the uploaded file have the same features of the one created locally? Does it have sense to talk about "the original version of the file"?
I'm a bit confused on this.
Correction:
i mean digitally sign a document with the private key of a personal digital certificate (should be pkcs7, pkcs12) to ensure that it has really been signed by someone and not someone else.
If by "the original version of the file" you mean that you intend to "freeze" the document so that nobody can ever make changes to it again - that is neither possible nor the purpose of a digital signature. Anyone could simply "cut out" the a signature embedded within a document, nobody would notice.
Protecting a document from subsequent modification involves some kind of DRM mechanism. For example, "watermarking" involving steganography is used to protect photos so that noone should be able to claim ownership of a photo, even after having modified it. But the technology is not very advanced yet, most algorithms can be easily broken.
This implies that the notion of "the original version of the file" in let's say a legal dispute is something that the involved parties have to agree upon in consent. There's no way to prove origin without either consent or a trusted third party that will attest the integrity of a document, e.g. if they have an independent copy of the document.
Apart from that, uploading a file should not change its contents. The file will have the exact same properties than the local one including the signature that was added on the client side.
The signature will only attest authenticity and integrity of the document. If it is vital for your application to be able to tell that the signed document received is actually the one that was expected, then I'd advise you to do the following:
Create the PDF on the server
Create a hash of the document (same algorithm that will be used by the signature applet)
Send the PDF to the client
Let the client sign it and send it back
Compare the client's hash with the one previously computed on the server
Validate the signature
Validating the signature will ensure integrity and authenticity, comparing the hashes will guarantee you that the signed document you received on the server is indeed a signed version of the original document previously created.
Concerning timestamps using local clocks: they're worthless, it's very easy to cheat. What you actually should use there is RFC 3161-compliant cryptographically secured timestamps, issued by a trusted third party. Currently that's the only reliable way to include the notion of time in PDF signatures. There's also built-in support for this in Adobe Reader for example. As these services are generally not available for free, it would make sense to add such a timestamp on the server after receiving the signed document. They are added as an unsigned attribute to the CMS (Adobe still speaks of PKCS7) signature, so it won't break the signature and can safely be added after signature creation.
Okay, let's try to answer your question (as I understand it).
You have some software which uses some private key (and a clock) to add a signature to a file.
This signature is depending on the contents of the file, and thus makes sure that the signer knew (or could have known) the contents of the file at the time it signed it. (There are some ways to have "blind signatures", but I assume this is not the case here.)
Uploading the signed file anywhere does not change anything here.
About the timestamp: The key holder can put in any timestamp it wants - so this only helps if you want to prove knowledge of the document at some point in time against the key holder, not if you are the key holder and want to prove that you signed at some point in time and not earlier or later. (Also, are you sure his clock is not skewed?)
About whether this is legally relevant, you will have to ask your lawyer. It might depend on
the jurisdiction in which the signature happened, and the one in which you want the signed document to be valid
whether the owner of the key had a chance to actually read the document before signing
whether the owner of the key had actually a choice of signing or not.
If you use some applet or ActiveX control in the user's browser, I would not be totally sure that the last two points really hold.