---
title: "Validating certificates"
description: "Validating certificates with PKI SDK by passing an ITrustArbitrator, with arbitrators for Windows trusted roots, ICP-Brasil and PKI-Italy roots."
canonical: "https://docs.lacunasoftware.com/en-us/articles/pki-sdk/certificates/validation"
locale: "en"
product: "PKI SDK"
last_updated: "2026-10-19"
---

# Validating certificates

To perform certificate validation, you must pass a @Lacuna.Pki.ITrustArbitrator

The `ITrustArbitrator` defines a way to arbitrate if the certification root is reliable. The SDK, through the static class @Lacuna.Pki.TrustArbitrators, has arbitrator implementations to validate trusted Windows, ICP-Brazil and 
PKI-Italy roots.

## Validating certificate

In the following code we will, as an example, validate an ICP-Brasil certificate in a standard way.

```cs
// Carregando um certificado ICP-Brasil
PKCertificate cert = ...

// Validando com árbitro ICP-Brasil
var vr = cert.Validate(TrustArbitrators.PkiBrazil);

if (vr.IsValid) {
    // Certificado é válido
} else {
    // Certificado é inválido
}

// Exibe detalhes da validação
Console.WriteLine(vr);
```

Previous example validating with Windows referee:

```cs
// Validando com árbitro raízes confiáveis do Windows
var vr = cert.Validate(TrustArbitrators.Windows);
```

## Reading the validation results

`Validate` doesn't throw when the certificate is invalid: it returns a [`ValidationResults`](https://docs.lacunasoftware.com/api/Lacuna.Pki/ValidationResults). Its `Errors` make `IsValid` false; its `Warnings`, such as a check you lowered with `SetFailureLevel`, don't. 
Each entry is a [`ValidationItem`](https://docs.lacunasoftware.com/api/Lacuna.Pki/ValidationItem): `Type` says which check failed as a [`ValidationItemTypes`](https://docs.lacunasoftware.com/api/Lacuna.Pki/ValidationItemTypes) value, such as `CertificateExpired`, `CertificateRevoked` or `CertificateChainRootNotTrusted`, and `Message` describes it; `Detail` and `InnerValidationResults` (the results of an inner validation) may add more. 
`ToString()` returns the whole report as text, which the samples show to the user. 

```cs
var vr = cert.Validate(TrustArbitrators.PkiBrazil);

if (!vr.IsValid) {
    // Errors made the validation fail
    foreach (var error in vr.Errors) {
        Console.WriteLine("Error {0}: {1}", error.Type, error.Message);
    }
    // Warnings are reported but don't make it fail
    foreach (var warning in vr.Warnings) {
        Console.WriteLine("Warning {0}: {1}", warning.Type, warning.Message);
    }

    // React to a specific failure, also looking in inner validations
    if (vr.ContainsFailure(ValidationItemTypes.CertificateRevoked, true)) {
        // The certificate is revoked
    }

    // Whole report as text
    Console.WriteLine(vr.ToString());
}
```

## Validating certificates with combined referee

In the following code we will perform a standard certificate validation with a set of trusted arbitrators containing ICP-Brasil, Windows and private test roots.

Thus, if the certificate is valid and belongs to any of the certification chains (ICP-Brasil, Windows roots or private roots), the validation will be successful.

```cs
// Carregando um certificado
PKCertificate cert = ...

// Criando conjunto de árbitros
var arbitrator = new LinkedTrustArbitrator();
arbitrator.Add(TrustArbitrators.PkiBrazil);                // Adiciona árbitro ICP-Brasil     
arbitrator.Add(TrustArbitrators.Windows);                  // Adiciona árbitro Windows
arbitrator.Add(new TrustedRoots(rootTest1, rootTest2));    // Adiciona árbitro com raízes privadas de teste

// Validando
var vr = cert.Validate(arbitrator);
```

You can also create the referee set through the builder `Lacuna.Pki.LinkedTrustArbitrator.%23ctor(Lacuna.Pki.ITrustArbitrator[])` or also using the extension method @Lacuna.Pki.LinkedTrustArbitratorExtension.GetLinkedWith(Lacuna.Pki.ITrustArbitrator,Lacuna.Pki.ITrustArbitrator[]) 
as shown in the code below:

```cs
// Outra maneira de criar o conjunto de árbitros
// através do construtor
var arbitrator = new LinkedTrustArbitrator(TrustArbitrators.PkiBrazil, TrustArbitrators.Windows, new TrustedRoots(rootTest1, rootTest2));

// Outra maneira de criar o conjunto de árbitros
// atrvés do método de extensão GetLinkedWith
var arbitrator = TrustArbitrators.PkiBrazil.GetLinkedWith(TrustArbitrators.Windows, new TrustedRoots(rootTest1, rootTest2));
```

## Changing validation options

If you need to make changes to the options or certificate validation mode, you can instantiate the class @Lacuna.Pki.CertificateValidationOptions with a referee and then set the validation properties.

In the following code we will, as an example, validate a certificate without validating its issuer signature and in case of unknown revocation state, Warning will be assigned instead of Error in the validation results.

```cs
// Carregando um certificado
PKCertificate cert = ...

// Criando opções de validação com árbitro raízes confiáveis do Windows
var options = new CertificateValidationOptions(TrustArbitrators.Windows);
options.ValidateIssuerSignature = false;
options.SetFailureLevel(ValidationItemTypes.CertificateRevocationStatusUnknown, ValidationFailureLevels.Warning);

// Validando com opções alteradas
var vr = cert.Validate(options);

// Exibe detalhes da validação
Console.WriteLine(vr);
```

For more information on certificate validation options methods and properties check the API guide:

## See too

* @Lacuna.Pki.ITrustArbitrator
* @Lacuna.Pki.TrustArbitrators
* @Lacuna.Pki.LinkedTrustArbitrator
* @Lacuna.Pki.CertificateValidationOptions
