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.19.5.0 (3.19.5.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 (Inherited from Object.)
Protected methodFinalize (Inherited from Object.)
Public methodGetHashCode (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 (Inherited from Object.)
Protected methodMemberwiseClone (Inherited from Object.)
Public methodToString (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