Asynchronous signature finishing
Asynchronous signature finishing is an approach PKI SDK offers for a more reliable and efficient signature process. It has the following advantages:
- It withstands failures in the distribution of CRLs/OCSPs and of timestamps.
- The synchronous part of the process is faster, because it no longer waits for the responses of CRL, OCSP or timestamp requests.
- It allows signature policies with a grace period.
The client's signature is requested only once and saved, which ends the process for the user. Later, in a background worker for instance, the online or cached requests and checks are performed and the signature is finished. If this second step has problems, there is no need to ask the client to sign again.
Signature finisher
The @Lacuna.Pki.Cades.CadesSignatureFinisher class handles signature finishing. Below is an example of the finisher, followed by a description of the methods it uses.
First, we create an unfinished signature:
// Basic CAdES signature
var signer = new CadesSigner();
signer.SetSigningCertificate(signingCert);
signer.SetDataToSign(toSign);
signer.SetPolicy(policy);
// Before calling ComputeSignature(),
// set the signature not to be finished
signer.SetFinishSignature(false);
signer.ComputeSignature();
var cadesSig = signer.GetSignature(); // returns the unfinished signature package
// Save the unfinished signature and end the process
Later, in a background worker (a Windows service or a scheduled task), we finish the signature:
// Loading the unfinished signature
byte[] cadesSig = ...
// Instantiating the finisher with the unfinished signature
var finisher = new CadesSignatureFinisher(CadesSignature.Open(cadesSig));
finisher.SetPolicy(policy);
finisher.SetTimestampRequester(tsRequester); // timestamp requester (if the policy requires a timestamp)
finisher.UseOnlyCrlsIssuedAfterGracePeriod = true; // use only revocation values issued after the grace period ends
finisher.PerformStep();
if (finisher.IsSignatureFinished) {
// Signature finished
// Returns the BER-encoded bytes of the finished signature
var finishedCadesSig = finisher.GetSignatureEncoded();
} else {
// Returns the suggested delay before calling the finishing service again with PerformStep()
var delay = finisher.NextStepDelay.Value;
// or
// Returns the suggested time for the next call to the finishing service with PerformStep()
var time = finisher.NextStepTime.Value;
}
-
@Lacuna.Pki.Cades.CadesSignatureFinisher.SetPolicy(Lacuna.Pki.Cades.CadesPolicySpec) / @Lacuna.Pki.Cades.CadesSignatureFinisher.SetPolicyMapper(Lacuna.Pki.Cades.ICadesPolicyMapper) / @Lacuna.Pki.Cades.CadesSignatureFinisher.SetPolicyMapper(Lacuna.Pki.Cades.ICadesPolicyMapperBySignerInfo) - Set the signature policy for finishing. Ideally it is the same policy used on the signer, but at this second stage only its timestamp, revocation value and reference, and certificate properties are used.
-
@Lacuna.Pki.Cades.CadesSignatureFinisher.SetTimestampRequester(Lacuna.Pki.ITimestampRequester) - Used if the signature policy requires a timestamp.
-
@Lacuna.Pki.Cades.CadesSignatureFinisher.UseOnlyCrlsIssuedAfterGracePeriod - Requires the revocation values checked to have been issued after the grace period. For more information on grace periods, see Policies with a grace period.
-
@Lacuna.Pki.Cades.CadesSignatureFinisher.PerformStep - The engine of the signature finisher: it fetches what is needed to finish the signature and, if the policy has a grace period that has not ended yet, tells when to run it again.
See also
- @Lacuna.Pki.Cades.CadesSignatureFinisher