Click or drag to resize

PdfTimeStamper Class

Defines an abstract class which can be implemented to specify settings and provide resources needed to time stamp a digital signature used when certifying a document.
Inheritance Hierarchy
SystemObject
  RadPdf.IntegrationPdfTimeStamper

Namespace:  RadPdf.Integration
Assembly:  RadPdf (in RadPdf.dll) Version: 3.21.0.0 (3.21.0.0)
Syntax
public abstract class PdfTimeStamper

The PdfTimeStamper type exposes the following members.

Constructors
  NameDescription
Public methodPdfTimeStamper
Create a new time stamp provider using a callback function.
Top
Methods
  NameDescription
Public methodEquals
Determines whether the specified Object is equal to the current Object.
(Inherited from Object.)
Protected methodFinalize
Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
(Inherited from Object.)
Public methodGetHashCode
Serves as a hash function for a particular type.
(Inherited from Object.)
Public methodCode exampleGetTimeStamp
An abstract method which will be called by RAD PDF to time stamp a certificate based signature created to certify the output PDF.
Public methodGetType
Gets the type of the current instance.
(Inherited from Object.)
Protected methodMemberwiseClone
Creates a shallow copy of the current Object.
(Inherited from Object.)
Public methodToString
Returns a string that represents the current object.
(Inherited from Object.)
Top
Examples

In this example, the open source library Bouncy Castle (https://www.bouncycastle.org/csharp/) and its classes TimeStampRequest and TimeStampResponse are used time stamp a signature.

C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography; // requires a project reference to System.Security
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;
using System.Text; 

using Org.BouncyCastle.Math; //requires Bouncy Castle (https://www.bouncycastle.org/csharp/)
using Org.BouncyCastle.Tsp;

using RadPdf.Integration;

public class MyTimeStamper : PdfTimeStamper
{
    public override byte[] GetTimeStamp(SignerInfo signer)
    {
        byte[] digest;
        using (SHA256CryptoServiceProvider sha = new SHA256CryptoServiceProvider())
        {
            digest = sha.ComputeHash(signer.GetSignature());
        }

        TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
        reqGen.SetCertReq(true);

        TimeStampRequest tsReq = reqGen.Generate(TspAlgorithms.Sha256, digest, BigInteger.ValueOf(DateTime.UtcNow.Ticks));

        HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://timestamp.digicert.com");
        req.Method = "POST";
        req.ContentType = "application/timestamp-query";
        req.ContentLength = tsData.Length;

        byte[] reqData = tsReq.GetEncoded();
        Stream reqStream = req.GetRequestStream();
        reqStream.Write(reqData, 0, reqData.Length);
        reqStream.Close();

        byte[] resData;

        using (HttpWebResponse res = (HttpWebResponse)req.GetResponse())
        {
            using (MemoryStream ms = new MemoryStream())
            {
                Stream resStream = res.GetResponseStream();
                resStream.CopyTo(ms);
                resStream.Close();

                resData = ms.ToArray();
            }
        }

        TimeStampResponse tsRes = new TimeStampResponse(resRaw);

        tsRes.Validate(tsReq);

        return tsRes.TimeStampToken.ToCmsSignedData().GetEncoded();
    }
}

If using ASP.NET Core, the native classes Rfc3161TimestampRequest and Rfc3161TimestampToken can be used:

C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;
using System.Text; 

using RadPdf.Integration;

public class MyTimeStamper : PdfTimeStamper
{
    public override byte[] GetTimeStamp(SignerInfo signer)
    {
        byte[] nonce = new byte[8];
        using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(nonce);
        }

        Rfc3161TimestampRequest request = Rfc3161TimestampRequest.CreateFromSignerInfo(
            signer, 
            HashAlgorithmName.SHA256,
            requestSignerCertificates: true, 
            nonce: nonce);

        byte[] tsData = request.Encode();

        HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://timestamp.digicert.com");
        req.Method = "POST";
        req.ContentType = "application/timestamp-query";
        req.ContentLength = tsData.Length;

        Stream reqStream = req.GetRequestStream();
        reqStream.Write(tsData, 0, tsData.Length);
        reqStream.Close();

        byte[] resRaw;

        using (HttpWebResponse res = (HttpWebResponse)req.GetResponse())
        {
            using (MemoryStream ms = new MemoryStream())
            {
                Stream resStream = res.GetResponseStream();
                resStream.CopyTo(ms);
                resStream.Close();

                resRaw = ms.ToArray();
            }
        }

        Rfc3161TimestampToken token = request.ProcessResponse(resRaw, out _);

        return token.AsSignedCms().Encode();
    }
}

Use a custom PdfIntegrationProvider implementation to use your time stamper when certifying a document:

C#
using System;
using System.Web;

using RadPdf.Integration;

public class CustomPdfIntegrationProvider : PdfIntegrationProvider
{
    public override void OnDocumentSaving(DocumentSavingEventArgs e)
    {
        base.OnDocumentSaving(e);

        e.CertifyUsing = new PdfCertifier(@"C:\path\to\cert.pfx", "password");
        e.CertifyUsing.TimeStampUsing = new MyTimeStamper();
    }
}
See Also