Sometimes you have to perform some kind of operations on the files the user downloads from your site, for example you might need to put a watermark on the documents or images.
In this particular case we are going to sign a pdf file to prevent users modifying the file without being noticed. This is a very useful feature when you distribute legal documents, since it adds an additional level of security (if the document is modified, the signature will not be verified).
Usually it’s not a good idea to store the documents already signed, if you decide to change your certificate (a revocation or so) you will have to recreate all of them (imagine the work of re-signing GBs of document). It also will require that all the docs uploaded will be signed prior to the upload.
So what we will do is to implement a HttpHandler that takes care of all the Http requests regarding pdf files, so you won’t have to touch a single line of code in your application, only installing the dll and modifying the web.config file.
An HttpHandler is a class, that implements IHttpHandler interface and processes Http requests, MOSS for example implements some of them to process the requests.
So we will create a class library project called PdfSigner with a class called PdfSignerHelper that will “transparently” sign all the pdfs downloaded from our site.
We will add a reference to System.Web and since we will store the Pdfs in MOSS,will add also a reference to Microsoft.Sharepoint.dll (C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI):
You also need to sign the dll, so go to the project properties, click on the signing tab and check the “Sign the assembly” option:
In the dropdown select “New…” and create the new key:
We will make our class implement the System.Web.IHttpHandler interface, and create the property IsReusable and the method ProcessRequest.
Now compile the project, since we need to insert the line in the web.config to make IIS use our code we need the assembly to be generated to get its strong name.
Once compiled you must look for the web.config file of your application (usually located in “c:\inetpub\wwwroot\wss\80”) to insert the line that registers the HttpHandler. So open it and look for the httpHandlers section…
At the end of that section we will introduce our configuration line:
Note that we only register the handler for pdf files and the GET verb, since we only need our code run when the pdfs are downloaded. To get the type attribute use Reflector:
Remember that when you insert that line in the web.config, the dll for your class must be accessible to the IIS, so you can place it in the GAC or in the bin directory.
No let’s start coding:
In the IsReusable property we will simply return true:
In the process request method we will get the request for the file, obtain it, sign it and the return the signed file to the user, so the first thing will be to get the file and it’s bytes:
The we will test if everything is ok, so we will attach to the w3wp.exe process hosting our MOSS site, set a breakpoint in our code and try to download a pdf file:
I added the int to check that the bytes are actually read.
Now we have to process the pdf to sign it. I’ll use the ITextSharp library because it’s free and allows signing and verifying pdf files.
I will use the class PdfReader to read the pdf directly from the file.OpenBinaryStream() method, and then I will create a separate method to process the pdf, I’ll call it ProcessPdf.
First of all I will get the key and the certificate chain from the certificate (note: since this is a test I will read the certificate from disk, in a serious environment, you should read it from the certificate store):
After that create a PdfStamper object which will take as source the PdfReader and as destination the ResponseStream.
I will set the signature info with some test values, and finally close the stamper, which sends the modified pdf to the response.
When the user opens the pdf in their reader they see this:
The signature is not perfect since we have used a self issued certificate to sign the pdf and the reader does not recognize it, but you can see the info we inserted into the pdf is recognized by the reader.
You can download the source code from here.