Pular para o conteúdo principal

Security contexts and signature policies - Rest PKI Core

When it signs or validates, Rest PKI Core answers two independent questions:

Security contextSignature policy
QuestionWhom to trust?How must the signature be made, or have been made?
DecidesWhich roots the signer's certificate chain must end atThe format (PAdES, CAdES, XML), the required and forbidden attributes, the accepted algorithms, the timestamp and the LTV data
ExamplesPkiBrazil, GovBR, PkiBrazilWithGovBrAndENotariado, a security context created on the dashboardPAdES basic, ICP-Brasil AD-RB, Adobe Reader
ParametersecurityContextIdsignaturePolicyId, defaultSignaturePolicyId and acceptableExplicitPolicies, on the Rest PKI routes only

A signature is valid only when both checks pass: the certificate must be trusted in the security context, and the signature must follow the policy. Neither replaces the other. Changing the policy doesn't make Rest PKI Core trust more certificates, and changing the security context doesn't make it accept a format the policy rejects.

Whether a signature is qualified doesn't depend on the policy either: it depends on the certificate. A signature made with an ICP-Brasil certificate is qualified even if it doesn't follow the ICP-Brasil PAdES standard. The policy only decides whether that format is accepted.

See Security contexts for the standard security contexts and for creating your own.

An example: a signature made in Adobe Acrobat​

A PDF signed in Adobe Acrobat with an ICP-Brasil certificate, validated with the PAdES basic policy and the PkiBrazil security context, may come back with this error:

"errors": [
{
"type": "RequiredSignedAttributeMissing",
"message": "A required signed attribute is missing",
"detail": "signing-certificate",
"innerValidationResults": null
}
]

The certificate is fine: its chain ends at the ICP-Brasil root, which the PkiBrazil security context trusts. The format is what fails. PAdES requires the signing-certificate signed attribute, and Acrobat's default signature format (adbe.pkcs7.detached) doesn't include it. To accept this PDF, keep the security context and switch the policy to Adobe Reader.

How they work together in each API​

Rest PKI routes​

On the Rest PKI routes that Rest PKI Core serves, you choose the policy. That applies to starting a PAdES signature (Api/PadesSignatures) and to validation (Api/PadesSignatures/Open, which the client libraries' PadesSignatureExplorer calls):

  • With securityContextId: the security context decides whom to trust, and the policy decides the rest. The security context replaces the roots the policy brings, the ICP-Brasil policies included.
  • Without securityContextId: the policy's trust applies. The ICP-Brasil policies trust ICP-Brasil. The others trust no root, and the call fails with SecurityContextRequired.

Rest PKI Core APIs​

Signature sessions, two-step signatures and signature inspection take no policy:

  • When signing, the instance settings choose the policy. General:DefaultSignaturePolicy (Basic, the default, or WithTime) says whether the signature gets a timestamp. With General:UseBrazilianPdfSigningPolicies on, PDF signatures follow ICP-Brasil (AD-RB or AD-RT). With it off, the default, they follow PAdES basic (or PAdES-T).
  • When validating, inspection uses the basic policy of the format, PAdES basic for PDF. It rejects signatures in Adobe's format with the error in the example above. To accept them, validate through the Api/PadesSignatures/Open route with the Adobe Reader policy.
  • Trust always comes from the security context: the one given in the call or, without it, the subscription's or the instance's default.

Policies for PDF​

These are the PAdES policies. In .NET they're in StandardPadesSignaturePolicies (namespace Lacuna.RestPki.Api). In Python, the StandardSignaturePolicies constants (package restpki_client) don't include Adobe Reader or the one without LTV: pass the ID.

PolicyIDWhat it definesWithout a security context, trusts
Basic78d20b33-014d-440e-ad07-929f05d00cdfPAdES basic, with LTV dataNo root: requires a security context
BasicWithoutLtved93a777-ad5a-49a0-8b67-5aa5dfad1c98PAdES basic, without LTV dataNo root: requires a security context
AdobeReaderaaed831b-fa9d-4732-82fc-8d25f2c16c57PAdES basic without the attribute and algorithm requirements; accepts Adobe's format (see below)No root: requires a security context
PkiBrazil.AdrBasica531d5012-4c0d-4b6f-89e8-ebdcc605d7c2ICP-Brasil AD-RB (explicit policy)ICP-Brasil
PkiBrazil.AdrTempo10f0d9a5-a0a9-42e9-9523-e181ce05a25bICP-Brasil AD-RT, with a timestamp (explicit policy)ICP-Brasil
PkiBrazil.BasicWithPkiBrazilCerts3fec800c-366c-49bf-82c5-2e72154e70f6PAdES basicICP-Brasil
PkiBrazil.PadesTWithPkiBrazilCerts6a39aeea-a2d0-4754-bf8c-19da15296ddbPAdES-T, with a timestampICP-Brasil

The policies with a timestamp use the security context's timestamp plan (see Settings of a security context).

StandardPadesSignaturePolicies.PkiBrazil also has AdrCompleta and AdrArquivamento, but the server doesn't accept them: the call fails with SignaturePolicyNotFound.

Default policy and explicit policies​

On validation, the PDF may declare an explicit policy (ICP-Brasil AD-RB or AD-RT) or none. Two parameters decide how each signature is validated:

  • acceptableExplicitPolicies lists the explicit policies to accept. Only PkiBrazil.AdrBasica and PkiBrazil.AdrTempo can be on the list. The others are implicit, and the call fails with InvalidRequest.
  • defaultSignaturePolicyId validates the signatures that declare no policy and those that declare a policy not on the list. Without it, those signatures fail validation.

With Adobe Reader as the defaultSignaturePolicyId, ICP-Brasil PAdES signatures pass too, because Adobe Reader requires less than AD-RB. To require the ICP-Brasil standard, use acceptableExplicitPolicies without defaultSignaturePolicyId (see the example).

The Adobe Reader policy​

The Adobe Reader policy (aaed831b-fa9d-4732-82fc-8d25f2c16c57) starts from PAdES basic and relaxes the format checks:

  • It doesn't require the mandatory signed attributes, such as signing-certificate.
  • It accepts unknown attributes and attributes PAdES forbids, such as signing-time inside the CMS signature.
  • It accepts any hash and signature algorithm.

The rest of the validation is unchanged: the document's integrity, the certificate chain, revocation and trust in the security context. That's why the policy requires a security context, and a certificate outside it is still rejected.

It's an implicit policy: use it as defaultSignaturePolicyId, never in acceptableExplicitPolicies.

When signing, Adobe Reader produces the signature in Adobe's format (subfilter adbe.pkcs7.detached) and without LTV data. That works on Rest PKI Core 4.1.2 and later, through the Rest PKI PAdES signature start route. On Rest PKI, Adobe Reader is for validation only.

What Adobe Reader shows

The policy's name has nothing to do with what Adobe Reader shows when it opens the PDF. Adobe Reader validates with Adobe's own list of roots (AATL) and its settings, not with the Rest PKI Core security context. A signature valid on Rest PKI Core may show as not verified in Adobe Reader. See Certificates trusted by Adobe and Adobe Reader validation.

Examples​

The examples validate through the Api/PadesSignatures/Open route. In the Rest PKI client libraries, which work with a Rest PKI Core key, the PadesSignatureExplorer calls it (see Moving from Rest PKI).

Accepting Adobe signatures from several hierarchies​

A PDF has signatures from ICP-Brasil (some made in Adobe Acrobat), gov.br and e-Notariado, and you want to validate all of them. Use the PkiBrazilWithGovBrAndENotariado security context, which trusts the three hierarchies, and the Adobe Reader policy as the default.

Python​

With the restpki-client package:

from restpki_client import PadesSignatureExplorer, RestPkiClient

ADOBE_READER = 'aaed831b-fa9d-4732-82fc-8d25f2c16c57'
PKI_BRAZIL_WITH_GOVBR_AND_ENOTARIADO = '4bf4409f-db45-4aab-91bf-2c73930ca556'

client = RestPkiClient('https://your-instance.example.com/', 'YOUR_API_KEY')

explorer = PadesSignatureExplorer(client)
explorer.signature_file_path = 'signed-document.pdf'
explorer.validate = True
explorer.default_signature_policy_id = ADOBE_READER
explorer.security_context_id = PKI_BRAZIL_WITH_GOVBR_AND_ENOTARIADO

signature = explorer.open()
for signer in signature.signers:
name = signer.certificate.subject_name.common_name
results = signer.validation_results
if results is None:
print(name, '- not validated')
elif results.is_valid:
print(name, '- valid')
else:
print(name, '- invalid')
for error in results.errors:
print(' ', error.item_type, error.message, error.detail)

.NET​

With the Lacuna.RestPkiCore.Client package, which brings Lacuna.RestPki.Client:

var client = new RestPkiClient("https://your-instance.example.com/", "YOUR_API_KEY");

var explorer = new PadesSignatureExplorer(client) {
Validate = true,
DefaultSignaturePolicyId = StandardPadesSignaturePolicies.AdobeReader,
SecurityContextId = StandardSecurityContexts.PkiBrazilWithGovBrAndENotariado,
};
explorer.SetSignatureFile("signed-document.pdf");

var signature = await explorer.OpenAsync();
foreach (var signer in signature.Signers) {
var name = signer.Certificate.SubjectName.CommonName;
if (signer.ValidationResults == null) {
Console.WriteLine($"{name} - not validated");
} else if (signer.ValidationResults.IsValid) {
Console.WriteLine($"{name} - valid");
} else {
Console.WriteLine($"{name} - invalid");
Console.WriteLine(signer.ValidationResults);
}
}

REST​

curl -X POST "https://your-instance.example.com/Api/PadesSignatures/Open" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"file": { "content": "<PDF in Base64>", "mimeType": "application/pdf" },
"validate": true,
"defaultSignaturePolicyId": "aaed831b-fa9d-4732-82fc-8d25f2c16c57",
"securityContextId": "4bf4409f-db45-4aab-91bf-2c73930ca556"
}'

Each signer comes back with its own validation results. A signer whose certificate doesn't end at any of the three roots fails with CertificateChainRootNotTrusted, without affecting the others.

Validating one hierarchy only​

To check only the signatures of one hierarchy, use a security context that trusts only that one, such as GovBR (5d323217-c031-4eed-9001-1cd82d86a8b5) or PkiBrazil (201856ce-273c-4058-a872-8937bd547d36), and keep the policy. With GovBR, the gov.br signatures pass, and the ICP-Brasil ones in the same PDF come back with CertificateChainRootNotTrusted. That's expected: the security context doesn't trust them.

To tell the signatures apart by hierarchy in a single call, use the security context that trusts all of them and look at each signer's certificate issuer.

Requiring the ICP-Brasil PAdES standard​

To accept only signatures that follow the ICP-Brasil AD-RB or AD-RT policies, list them in acceptableExplicitPolicies and leave out defaultSignaturePolicyId. A signature made in Adobe, which declares no policy, fails.

var explorer = new PadesSignatureExplorer(client) {
Validate = true,
AcceptableExplicitPolicies = SignaturePolicyCatalog.GetPkiBrazilPades(),
SecurityContextId = StandardSecurityContexts.PkiBrazil,
};

In the REST API, send "acceptableExplicitPolicies": ["531d5012-4c0d-4b6f-89e8-ebdcc605d7c2", "10f0d9a5-a0a9-42e9-9523-e181ce05a25b"].

Signing in Adobe's format​

To produce a signature in Adobe's format, without LTV data, start the PAdES signature with the Adobe Reader policy and a security context:

var starter = new PadesSignatureStarter(client) {
SignaturePolicyId = StandardPadesSignaturePolicies.AdobeReader,
SecurityContextId = StandardSecurityContexts.PkiBrazil,
};

The rest of the flow is that of a Rest PKI PAdES signature (see Using Rest PKI on .NET). Prefer the PAdES basic or AD-RB policy unless a system requires Adobe's format.

Common errors​

ErrorCauseWhat to do
SecurityContextRequiredThe policy trusts no root (Basic, BasicWithoutLtv, AdobeReader) and the call gave no securityContextIdPass the security context
InvalidRequest (implicit policy)An implicit policy, such as Adobe Reader, was passed in acceptableExplicitPoliciesPass it in defaultSignaturePolicyId
SignaturePolicyNotFoundThe ID isn't a policy the server accepts, such as AD-RC or AD-RA for PDFUse a policy from the table
RequiredSignedAttributeMissing (signing-certificate)The signature doesn't follow PAdES, like those made in Adobe AcrobatValidate with the Adobe Reader policy
CertificateChainRootNotTrustedThe certificate doesn't end at a root of the security contextUse a security context that trusts the certificate's hierarchy

Validation covers only the first signers of each file (10 by default; see Signature inspection). The rest come back without validation results. And a file signed on the instance itself comes back as stored when it was signed, without a new validation: the call's security context and policy aren't used.

On Rest PKI​

On Rest PKI the relationship is the same, with these differences:

  • The Adobe Reader policy is for validation only.
  • The standard security contexts are only PkiBrazil, PkiItaly, WindowsServer and LacunaTest, without the gov.br and e-Notariado ones.

See also​

View as Markdown