Pular para o conteúdo principal

Validate signatures - Rest PKI

Legacy product

Rest PKI is a legacy product: it still receives bug and security fixes, but new cloud integrations should use Rest PKI Core, which also serves most Rest PKI APIs. This page is for existing Rest PKI integrations. See the Rest PKI quick reference.

Your backend sends a signed file to Rest PKI, which opens it, lists its signers and validates each signature. There is no browser step. Rest PKI opens PDF signatures (PAdES), CMS/CAdES files (.p7s) and XML signatures.

The code on this page is C#, from the ASP.NET MVC samples project, which uses Lacuna.RestPki.Client 1.24.1. The same samples exist for other languages: see Samples availability.

Flow​

  1. Create the RestPkiClient with your endpoint and access token (see the quick reference).
  2. Create a PadesSignatureExplorer, CadesSignatureExplorer or XmlSignatureExplorer, and set Validate = true, the signature policy and the security context.
  3. Pass the signed file with SetSignatureFile().
  4. Call OpenAsync() (for CAdES, OpenAndExtractContentAsync() to also get the signed content).
  5. Read each signer's certificate, signing time and ValidationResults.
ExplorerEndpointResponse
PadesSignatureExplorerPOST Api/PadesSignatures/OpenPadesSignatureModel
CadesSignatureExplorerPOST Api/CadesSignatures/OpenCadesSignatureModel
XmlSignatureExplorerPOST Api/XmlSignatures/Opena list of XmlSignatureModel

PDF signatures (PAdES)​

The sample accepts any PAdES signature (StandardPadesSignaturePolicies.Basic) whose certificate the security context trusts:

var sigExplorer = new PadesSignatureExplorer(Util.GetRestPkiClient()) {
Validate = true,
DefaultSignaturePolicyId = StandardPadesSignaturePolicies.Basic,
SecurityContextId = Util.GetSecurityContextId()
};
sigExplorer.SetSignatureFile(userfilePath);
var signature = await sigExplorer.OpenAsync();

CAdES signatures​

The CAdES sample accepts the ICP-Brasil CAdES policies in SignaturePolicyCatalog.GetPkiBrazilCades() (AD-RB, AD-RT and AD-RC), and also gets the signed content when the file carries it:

var sigExplorer = new CadesSignatureExplorer(Util.GetRestPkiClient()) {
Validate = true,
AcceptableExplicitPolicies = SignaturePolicyCatalog.GetPkiBrazilCades(),
SecurityContextId = Util.GetSecurityContextId(),
};
sigExplorer.SetSignatureFile(userfilePath);
var data = await sigExplorer.OpenAndExtractContentAsync();
var signature = data.Signature;
var encapsulatedContent = data.Signature.HasEncapsulatedContent ? data.EncapsulatedContent : null;
  • OpenAndExtractContentAsync() sets extractEncapsulatedContent in the request. Rest PKI keeps the extracted content for one hour, and the client returns it as a file you can read with GetContent() or save with WriteToFile().
  • Rest PKI doesn't report the content's file type: the sample assumes a PDF.
  • For a detached signature, the client also has SetDataFile(). TODO(docs): no sample shows how to validate a detached CAdES signature.

XML signatures​

The XML sample accepts any XmlDSig signature (StandardXmlSignaturePolicies.XmlDSigBasic) whose certificate the security context trusts. OpenAsync() returns a list, one item per signature in the document:

var sigExplorer = new XmlSignatureExplorer(Util.GetRestPkiClient()) {
Validate = true,
DefaultSignaturePolicyId = StandardXmlSignaturePolicies.XmlDSigBasic,
SecurityContextId = Util.GetSecurityContextId()
};
sigExplorer.SetSignatureFile(userfilePath);
var signatures = await sigExplorer.OpenAsync();

Each XML signature also has a Type (FullXml, XmlElement or DetachedResource) and the SignedElement.

Signature policies​

Each signature is validated against a signature policy:

  • DefaultSignaturePolicyId validates the signatures that have no explicit policy, and those whose explicit policy is not in AcceptableExplicitPolicies. To accept only a list of explicit policies, leave it out.
  • AcceptableExplicitPolicies lists the explicit policies to accept, such as the ICP-Brasil ones.
  • A signature with no explicit policy, when no default is given, fails validation.

Standard policies are in StandardPadesSignaturePolicies (Basic, BasicWithoutLtv, AdobeReader), StandardCadesSignaturePolicies (CadesBes, CadesBesWithSigningTimeAndNoCrls, CmsPermissive) and StandardXmlSignaturePolicies (XadesBes, XmlDSigBasic, CodSha1, CodSha256), each with the ICP-Brasil policies nested under PkiBrazil; SignaturePolicyCatalog groups the ICP-Brasil ones.

Security context​

The security context decides which root certificates are trusted. The PAdES Basic, CAdES CadesBes and XML XmlDSigBasic and XadesBes policies need one, or the call fails with SecurityContextRequired; the ICP-Brasil policies bring their own, which a security context you pass replaces.

Security contextTrustsId
StandardSecurityContexts.PkiBrazilICP-Brasil roots201856ce-273c-4058-a872-8937bd547d36
StandardSecurityContexts.PkiItalyItalian PKI rootsc438b17e-4862-446b-86ad-6f85734f0bfe
StandardSecurityContexts.WindowsServerRoots trusted by Windows3881384c-a54d-45c5-bbe9-976b674f5ec7
StandardSecurityContexts.LacunaTestICP-Brasil, Windows and Lacuna test roots; development only803517ad-3bbc-4169-b085-60053a8f6dbf

The samples use LacunaTest in debug builds, to accept the test certificates, and PkiBrazil otherwise. On an on-premises instance, LacunaTest may have to be created first (see Enabling Lacuna Test Security Context).

public static Guid GetSecurityContextId() {
#if DEBUG
return StandardSecurityContexts.LacunaTest;
#else
return Lacuna.RestPki.Api.StandardSecurityContexts.PkiBrazil;
#endif
}

Two more options relax validation: IgnoreRevocationStatusUnknown ignores errors due to an unknown revocation status (default false, since Rest PKI 1.16.0), and TrustUncertifiedSigningTime takes the signer's signing time as the validation date reference (since 1.22.0). None of the samples sets them.

Read the results​

  • A PAdES or CAdES signature has Signers; each signer has its Certificate, SigningTime, MessageDigest, SignaturePolicy, Timestamps and ValidationResults. A PAdES signer also has IsDocumentTimestamp and SignatureFieldName. An XML signature has the same fields, without MessageDigest.
  • ValidationResults has IsValid, Errors, Warnings, PassedChecks and Summary, and ToString() lists every check. It is filled only when Validate is true.

The sample's page shows, for each signer, the subject's common name, a "valid" or "invalid" badge from ValidationResults.IsValid, the signing time, the message digest, the policy, the ICP-Brasil certificate fields and the full ValidationResults.ToString().

Errors​

  • A file that is not a valid PDF, CAdES or XML fails with InvalidPdf, InvalidCades or InvalidXml (HTTP 422). See Return codes.
  • When an account limit is set and exceeded, Rest PKI answers HTTP 429 with the headers X-RateLimit-Limit and X-RateLimit-Remaining.
  • TODO(docs): how a signature with no acceptable policy is reported.

See also​

View as Markdown