Online Revocation Plugin — API Reference
@trexolab/verifykit-plugin-revocation
Overview
The revocation plugin adds online CRL (Certificate Revocation List) and OCSP (Online Certificate Status Protocol) checking to the VerifyKit verification engine. After the core WASM engine validates a PDF signature, this plugin contacts external CRL/OCSP endpoints to determine whether the signer's certificate has been revoked.
The plugin operates in two modes:
- Proxy mode (browser) — sends revocation requests to your server handler, which fetches CRL/OCSP data on behalf of the browser. Required because browsers cannot directly reach most CRL/OCSP endpoints due to CORS and mixed-content restrictions.
- Direct mode (Node.js) — fetches CRL/OCSP endpoints directly from the running process. No server needed.
Mode detection is automatic: if endpoint is provided, the plugin uses proxy mode; if omitted, it uses direct mode.
The package exposes four import paths, each targeting a different runtime context.
Import Paths
| Path | Exports | When to use |
|---|---|---|
@trexolab/verifykit-plugin-revocation | revocationPlugin, types | Browser or Node.js client — creates the plugin instance |
@trexolab/verifykit-plugin-revocation/handler | handleRevocation | Server handler using Web Standard Request/Response (Next.js, Hono, Bun, Deno, Cloudflare Workers) |
@trexolab/verifykit-plugin-revocation/handler/express | expressHandler | Server handler for Express |
@trexolab/verifykit-plugin-revocation/handler/core | processRevocation | Raw data-in/data-out function for custom frameworks, testing, or Fastify |
revocationPlugin(options?)
Creates a revocation checking plugin that conforms to the VerifyKitPlugin interface.
import { revocationPlugin } from '@trexolab/verifykit-plugin-revocation'
function revocationPlugin(options?: RevocationPluginOptions): VerifyKitPluginParameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options | RevocationPluginOptions | No | Plugin configuration. See RevocationPluginOptions for all fields. |
Returns: VerifyKitPlugin — a plugin object with name: 'revocation' and a revocation property containing checkCRL and/or checkOCSP methods.
Mode detection:
endpointpresent in options --> proxy mode (browser-safe)endpointabsent --> direct mode (Node.js)
The returned plugin object has this shape:
{
name: 'revocation',
revocation: {
checkCRL?: (cert: CertificateInfo, urls: string[]) => Promise<RevocationCheckResult>,
checkOCSP?: (cert: CertificateInfo, issuer: CertificateInfo, urls: string[]) => Promise<RevocationCheckResult>,
}
}If crl is set to false, the checkCRL method is omitted. If ocsp is set to false, the checkOCSP method is omitted.
Proxy Mode (Browser)
When endpoint is provided, every CRL or OCSP check is sent as a JSON POST request to that URL.
const plugin = revocationPlugin({ endpoint: '/api/revocation' })Internal flow:
- The core engine calls
checkOCSP(cert, issuer, urls)orcheckCRL(cert, urls). - The plugin builds a
RevocationRequestJSON payload:json{ "type": "ocsp", "cert": { "serialNumber": "...", "authorityKeyId": "...", ... }, "issuer": { "subjectNameHash": "...", ... }, "urls": ["http://ocsp.example.com"] } - The plugin sends
POST <endpoint>withContent-Type: application/jsonand the JSON body. - Custom headers (static or dynamic) are merged into the request if configured.
- An
AbortControllerenforces the configuredtimeout(default: 10 seconds). - The server handler returns a
RevocationCheckResultJSON response. - If the request fails (network error, timeout, non-2xx status), the
onErrorcallback is invoked (if configured), and the plugin returns{ status: 'unknown', source: 'proxy error (<endpoint>)' }.
Request format:
interface RevocationRequest {
type: 'crl' | 'ocsp'
cert: CertificateInfo
issuer?: CertificateInfo // present for OCSP, absent for CRL
urls: string[]
}Response format:
interface RevocationCheckResult {
status: 'good' | 'revoked' | 'revokedAfterSigning' | 'revokedNoTimestamp' | 'unknown'
revocationDate?: Date
reason?: string
source?: string
}Timeout handling:
The plugin creates an AbortController and aborts the fetch after timeout milliseconds (default: 10000). On abort, the onError callback fires and the result falls back to { status: 'unknown' }.
Custom headers:
Static headers:
revocationPlugin({
endpoint: '/api/revocation',
headers: { 'Authorization': 'Bearer my-token' },
})Dynamic headers (evaluated on each request):
revocationPlugin({
endpoint: '/api/revocation',
headers: () => ({ 'Authorization': `Bearer ${getToken()}` }),
})Headers are merged into the request after the default Content-Type: application/json header.
Error handling and the onError callback:
When a proxy request fails, the plugin:
- Catches the error.
- Wraps it as an
Errorif it is not already one. - Calls
onError(error, { type, url })if the callback is configured. - Returns
{ status: 'unknown', source: 'proxy error (<endpoint>)' }.
The verification still completes — only the revocation field is affected.
revocationPlugin({
endpoint: '/api/revocation',
onError: (err, ctx) => {
console.warn(`Revocation ${ctx.type} failed for ${ctx.url}:`, err.message)
// ctx.type is 'crl' or 'ocsp'
// ctx.url is the endpoint URL
},
})Direct Mode (Node.js)
When endpoint is omitted, the plugin fetches CRL and OCSP endpoints directly using fetch().
const plugin = revocationPlugin()
// or with options:
const plugin = revocationPlugin({ timeout: 15000, maxCrlSize: 5 * 1024 * 1024 })Internal flow:
- For CRL: fetches the CRL file (DER-encoded) from each URL in
cert.crlDistributionPoints, parses the ASN.1 structure, and checks whether the certificate's serial number appears in therevokedCertificateslist. - For OCSP: builds a minimal DER-encoded OCSP request using
cert.authorityKeyId(asissuerKeyHash),issuer.subjectNameHash(asissuerNameHash), andcert.serialNumber, then POSTs it to each OCSP responder URL and parses the DER response. - The
maxCrlSizeoption (default: 10 MB) limits the maximum CRL download size. - No server handler is needed.
handleRevocation(options?)
Creates a Web Standard request handler for revocation checking. Compatible with any framework that uses the Web Standard Request/Response API.
import { handleRevocation } from '@trexolab/verifykit-plugin-revocation/handler'
function handleRevocation(options?: HandlerOptions): (req: Request) => Promise<Response>Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options | HandlerOptions | No | Server handler configuration. See HandlerOptions. |
Returns: An async function (req: Request) => Promise<Response>.
Request validation:
The handler parses the request body as JSON and checks for the presence of type, cert, and urls. If any are missing, it returns a 400 response.
SSRF protection:
Before fetching any URL, the handler applies the urlFilter function (or the default filter) to each URL in the request. URLs that do not pass the filter are excluded. If no URLs remain, the result is { status: 'unknown', source: 'no allowed URLs' }.
Response format:
| HTTP Status | Body | When |
|---|---|---|
200 | RevocationCheckResult JSON | Check completed (any status including unknown) |
400 | { "error": "Invalid request" } | Missing type, cert, or urls in request body |
500 | { "status": "unknown", "source": "handler error" } | Unhandled exception |
Next.js App Router
// app/api/revocation/route.ts
import { handleRevocation } from '@trexolab/verifykit-plugin-revocation/handler'
export const POST = handleRevocation()Hono
import { Hono } from 'hono'
import { handleRevocation } from '@trexolab/verifykit-plugin-revocation/handler'
const app = new Hono()
const handler = handleRevocation()
app.post('/api/revocation', (c) => handler(c.req.raw))
export default appBun
import { handleRevocation } from '@trexolab/verifykit-plugin-revocation/handler'
const handler = handleRevocation()
Bun.serve({
port: 3000,
async fetch(req) {
const url = new URL(req.url)
if (url.pathname === '/api/revocation' && req.method === 'POST') {
return handler(req)
}
return new Response('Not found', { status: 404 })
},
})Deno
import { handleRevocation } from '@trexolab/verifykit-plugin-revocation/handler'
const handler = handleRevocation()
Deno.serve({ port: 3000 }, async (req) => {
const url = new URL(req.url)
if (url.pathname === '/api/revocation' && req.method === 'POST') {
return handler(req)
}
return new Response('Not found', { status: 404 })
})expressHandler(options?)
Creates an Express-compatible request handler for revocation checking.
import { expressHandler } from '@trexolab/verifykit-plugin-revocation/handler/express'
function expressHandler(options?: HandlerOptions): (req: any, res: any) => Promise<void>Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options | HandlerOptions | No | Server handler configuration. See HandlerOptions. |
Returns: An Express middleware function (req, res) => Promise<void>.
Prerequisite: The express.json() middleware must be applied before this handler so that req.body is parsed. Without it, req.body will be undefined and the handler will return a 400 error.
Example
import express from 'express'
import { expressHandler } from '@trexolab/verifykit-plugin-revocation/handler/express'
const app = express()
app.use(express.json())
app.post('/api/revocation', expressHandler())
app.listen(3000, () => {
console.log('Revocation handler listening on port 3000')
})Example with options
import express from 'express'
import { expressHandler } from '@trexolab/verifykit-plugin-revocation/handler/express'
const app = express()
app.use(express.json())
app.post('/api/revocation', expressHandler({
timeout: 15000,
maxCrlSize: 5 * 1024 * 1024,
urlFilter: (url) => {
const u = new URL(url)
return u.hostname.endsWith('.example-ca.com')
},
}))
app.listen(3000)processRevocation(payload, options?)
Framework-agnostic core function. Takes a plain RevocationRequest object and returns a plain RevocationCheckResult. No Request/Response objects involved.
import { processRevocation } from '@trexolab/verifykit-plugin-revocation/handler/core'
function processRevocation(
payload: RevocationRequest,
options?: HandlerOptions,
): Promise<RevocationCheckResult>Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
payload | RevocationRequest | Yes | The revocation check request containing type, cert, optional issuer, and urls. |
options | HandlerOptions | No | Handler configuration. See HandlerOptions. |
Returns: Promise<RevocationCheckResult>
Behavior:
- Applies the
urlFilterto all URLs inpayload.urls. If no URLs pass, returns{ status: 'unknown', source: 'no allowed URLs' }. - For
type: 'crl': calls the internal CRL checker with the filtered URLs. - For
type: 'ocsp': verifies thatpayload.issueris present (returns{ status: 'unknown', source: 'OCSP requires issuer certificate' }if missing), then calls the internal OCSP checker.
When to use:
- Custom frameworks that don't use Web Standard
Request/Responseor Express (e.g., Fastify, Koa, tRPC) - Testing and scripting
- Building your own handler wrapper
Fastify example
import Fastify from 'fastify'
import { processRevocation } from '@trexolab/verifykit-plugin-revocation/handler/core'
const fastify = Fastify()
fastify.post('/api/revocation', async (request, reply) => {
const result = await processRevocation(request.body as any, {
timeout: 15000,
})
reply.send(result)
})
await fastify.listen({ port: 3000 })Testing example
import { processRevocation } from '@trexolab/verifykit-plugin-revocation/handler/core'
const result = await processRevocation({
type: 'crl',
cert: {
serialNumber: 'aa:bb:cc:dd',
subject: 'CN=Test',
issuer: 'CN=Root',
// ... other CertificateInfo fields
} as any,
urls: ['http://crl.example.com/root.crl'],
})
console.log(result.status) // 'good', 'revoked', or 'unknown'Types
RevocationPluginOptions
Options passed to revocationPlugin(options?).
interface RevocationPluginOptions {
endpoint?: string
timeout?: number
crl?: boolean
ocsp?: boolean
maxCrlSize?: number
headers?: Record<string, string> | (() => Record<string, string>)
onError?: (error: Error, context: { type: 'crl' | 'ocsp'; url: string }) => void
}| Option | Type | Default | Description |
|---|---|---|---|
endpoint | string | undefined | Server handler URL for proxy mode. When provided, the plugin sends POST requests to this URL instead of fetching CRL/OCSP directly. Omit for direct mode (Node.js). |
timeout | number | 10000 | HTTP request timeout in milliseconds. In proxy mode, this is the timeout for the POST request to the server handler. In direct mode, this is the timeout for each individual CRL/OCSP fetch. |
crl | boolean | true | Enable CRL (Certificate Revocation List) checking. Set to false to disable CRL checks entirely. |
ocsp | boolean | true | Enable OCSP (Online Certificate Status Protocol) checking. Set to false to disable OCSP checks entirely. |
maxCrlSize | number | 10485760 | Maximum CRL download size in bytes (default: 10 MB). Only applies in direct mode. In proxy mode, the server handler's maxCrlSize option controls this. |
headers | Record<string, string> | () => Record<string, string> | undefined | Custom headers for proxy requests (browser mode only). Pass a static object or a function that returns headers dynamically (useful for auth tokens that expire). Headers are merged after the default Content-Type: application/json. |
onError | (error: Error, context: { type: 'crl' | 'ocsp'; url: string }) => void | undefined | Error callback invoked when a proxy request fails (timeout, network error, non-2xx response). context.type is 'crl' or 'ocsp'. context.url is the endpoint URL. |
HandlerOptions
Options passed to handleRevocation(options?), expressHandler(options?), and processRevocation(payload, options?).
interface HandlerOptions {
timeout?: number
maxCrlSize?: number
urlFilter?: (url: string) => boolean
}| Option | Type | Default | Description |
|---|---|---|---|
timeout | number | 10000 | Timeout in milliseconds for each outgoing CRL/OCSP fetch. If a CRL endpoint or OCSP responder does not respond within this time, the request is aborted. |
maxCrlSize | number | 10485760 | Maximum CRL download size in bytes (default: 10 MB). If the CRL response exceeds this size (checked via Content-Length header and actual body length), the download is aborted. |
urlFilter | (url: string) => boolean | See SSRF Protection | Filter function for SSRF protection. Called for each URL in the request. Return true to allow the URL, false to block it. |
RevocationRequest
The payload sent from the browser plugin to the server handler. Also the first parameter of processRevocation().
interface RevocationRequest {
type: 'crl' | 'ocsp'
cert: CertificateInfo
issuer?: CertificateInfo
urls: string[]
}| Field | Type | Required | Description |
|---|---|---|---|
type | 'crl' | 'ocsp' | Yes | The type of revocation check to perform. |
cert | CertificateInfo | Yes | The signer's certificate. Must include serialNumber. For OCSP, must also include authorityKeyId. |
issuer | CertificateInfo | For OCSP | The issuer certificate (second certificate in the chain). Must include subjectNameHash for OCSP. Not required for CRL. |
urls | string[] | Yes | CRL distribution point URLs (for type: 'crl') or OCSP responder URLs (for type: 'ocsp'). Extracted from the signer certificate's extensions. |
RevocationCheckResult
Returned by all revocation functions. Defined in @trexolab/verifykit-core.
interface RevocationCheckResult {
status: 'good' | 'revoked' | 'revokedAfterSigning' | 'revokedNoTimestamp' | 'unknown'
revocationDate?: Date
reason?: string
source?: string
}| Status | Meaning | Effect on signature |
|---|---|---|
'good' | Certificate is not revoked. The serial number was not found in the CRL, or the OCSP responder returned "good". | revocationCheck.status set to 'valid'. overallStatus unchanged. |
'revoked' | Certificate is revoked. | revocationCheck.status set to 'invalid'. overallStatus set to 'invalid'. overallMessage updated to indicate revocation. |
'revokedAfterSigning' | Certificate was revoked, but the revocation date is after the signature's trusted timestamp. The signature was valid when created. | revocationCheck.status set to 'valid'. overallStatus unchanged. Timestamp protects the signature. |
'revokedNoTimestamp' | Certificate is revoked and the signature has no trusted timestamp to prove it was signed before revocation. | revocationCheck.status set to 'invalid'. overallStatus set to 'invalid'. |
'unknown' | Revocation status could not be determined. This happens when: no CRL/OCSP URLs are in the certificate, all endpoints are unreachable, the response cannot be parsed, or both CRL and OCSP are disabled. | revocationCheck left unchanged (stays 'unknown'). overallStatus unchanged. |
The optional fields:
| Field | Type | Description |
|---|---|---|
revocationDate | Date | When the certificate was revoked. Present when status is 'revoked', 'revokedAfterSigning', or 'revokedNoTimestamp'. |
reason | string | CRL revocation reason code (e.g., 'keyCompromise', 'cessationOfOperation'). |
source | string | Human-readable description of where the result came from. Examples: 'online CRL (http://crl.example.com/root.crl)', 'online OCSP (http://ocsp.example.com)', 'proxy error (/api/revocation)'. |
CertificateInfo
Defined in @trexolab/verifykit-core. Key fields used by the revocation plugin:
interface CertificateInfo {
serialNumber: string // e.g. "aa:bb:cc:dd:ee"
authorityKeyId?: string // hex, used as OCSP issuerKeyHash
subjectNameHash?: string // SHA-1 of DER-encoded subject name (hex)
crlDistributionPoints?: string[] // CRL URLs from the certificate
ocspUrls?: string[] // OCSP responder URLs from the certificate
// ... other fields omitted for brevity
}How CRL Checking Works
Step-by-step internal process:
- Normalize serial number. Strip colon separators from
cert.serialNumberand convert to lowercase hex. - Fetch CRL. For each URL in the CRL distribution points list, send an HTTP GET request with the configured timeout and maximum size.
- Parse ASN.1 DER. The CRL is DER-encoded ASN.1. Parse the outer
SEQUENCE, then thetbsCertList SEQUENCEinside it. - Locate
revokedCertificates. Walk the fields oftbsCertListto find therevokedCertificatesfield (aSEQUENCE OFentries, typically the 5th or 6th field). - Match serial number. For each entry in
revokedCertificates, read theuserCertificate INTEGERfield and compare its hex value (with leading zeros stripped) against the target serial. - Return result. If the serial is found, return
{ status: 'revoked' }. If the serial is not found, return{ status: 'good' }. If all URLs fail, return{ status: 'unknown' }.
How OCSP Checking Works
Step-by-step internal process:
- Validate inputs. Check that
cert.authorityKeyIdandcert.serialNumberare present. Check thatissuer.subjectNameHashis present. If any are missing, return{ status: 'unknown' }. - Prepare OCSP data.
issuerKeyHash= bytes fromcert.authorityKeyId(hex-decoded). This is the SHA-1 hash of the issuer's public key.issuerNameHash= bytes fromissuer.subjectNameHash(hex-decoded). This is the SHA-1 hash of the issuer's DER-encoded subject distinguished name.serialNumber= bytes fromcert.serialNumber(hex-decoded).
- Build OCSP request. Construct a minimal DER-encoded
OCSPRequeststructure:OCSPRequest -> SEQUENCE { tbsRequest -> SEQUENCE { requestList -> SEQUENCE OF { Request -> SEQUENCE { reqCert -> CertID -> SEQUENCE { hashAlgorithm: SHA-1 (OID 1.3.14.3.2.26) issuerNameHash: OCTET STRING issuerKeyHash: OCTET STRING serialNumber: INTEGER } } } } } - POST to OCSP responder. Send the DER bytes with
Content-Type: application/ocsp-requestto each OCSP URL. - Parse OCSP response. Read the response DER:
- Check that
responseStatusis0(successful). - Scan for
certStatuscontext tags in theSingleResponse:0x80 0x00= good (certificate is not revoked)0xA1 ...= revoked (certificate is revoked; containsrevocationTime)0x82 0x00= unknown (OCSP responder does not know this certificate)
- Check that
- Return result. First successful non-unknown result wins. If all URLs fail, return
{ status: 'unknown' }.
Check Priority
The core engine calls revocation plugin methods in this order:
- OCSP first — if
ocspis enabled and the signer certificate hasocspUrls, the engine callscheckOCSP(). OCSP is preferred because it is faster (small request/response) and provides real-time status. - CRL fallback — if OCSP returns
'unknown'or throws, andcrlis enabled and the certificate hascrlDistributionPoints, the engine callscheckCRL(). - First non-unknown result wins. If either OCSP or CRL returns
'good'or'revoked', that result is applied immediately and no further checks are performed for that signature. - If both methods fail or return
'unknown', the revocation status remains'unknown'.
This order is hardcoded in the core engine's runRevocationPlugins() function and is not configurable from the plugin options.
Error Handling
| Scenario | Behavior | Plugin returns | How to debug |
|---|---|---|---|
| Proxy request times out | AbortController aborts the fetch. onError is called. | { status: 'unknown', source: 'proxy error (<endpoint>)' } | Increase timeout. Check server handler logs. |
| Proxy returns non-2xx HTTP status | Error is thrown. onError is called. | { status: 'unknown', source: 'proxy error (<endpoint>)' } | Check server handler response. Ensure handler is mounted at the correct path. |
| Proxy network error (server down, DNS failure) | Fetch throws. onError is called. | { status: 'unknown', source: 'proxy error (<endpoint>)' } | Verify server is running. Check network connectivity. |
| CRL endpoint unreachable | Direct fetch throws. Plugin tries next URL. | { status: 'unknown', source: 'online CRL (all URLs failed)' } if all URLs fail | Check firewall rules. Try fetching the URL with curl. |
CRL response exceeds maxCrlSize | Error thrown. Plugin tries next URL. | { status: 'unknown' } if all URLs fail | Increase maxCrlSize option. |
| CRL ASN.1 parse error | Caught internally. Treated as "serial not found" (safe default). | { status: 'good' } (may be inaccurate) | Check that the CRL URL returns valid DER data. |
| OCSP responder returns non-zero status | OCSP response skipped. Plugin tries next URL. | { status: 'unknown' } if all URLs fail | OCSP responder may be overloaded or rate-limiting. |
OCSP missing issuer.subjectNameHash | Check aborted immediately. | { status: 'unknown', source: 'OCSP (issuer subjectNameHash not available)' } | Ensure you are using a recent version of @trexolab/verifykit-core which computes subjectNameHash in the WASM core. |
OCSP missing cert.authorityKeyId | Check aborted immediately. | { status: 'unknown', source: 'OCSP (insufficient cert info)' } | Certificate may not have the AKI extension. CRL fallback should still work. |
| All URLs filtered by SSRF protection | No fetch attempted. | { status: 'unknown', source: 'no allowed URLs' } | Customize urlFilter to allow the CA's endpoints. |
req.body missing fields (server handler) | Handler returns 400. | N/A (HTTP 400 error) | Ensure express.json() is applied. Check client payload. |
| Unhandled server exception | Handler returns 500. | N/A (HTTP 500 error) | Check server logs. |
In all error cases, the verification still completes. Only the revocationCheck field on the affected signature is impacted.
SSRF Protection
The server handlers (handleRevocation, expressHandler, processRevocation) apply a URL filter before fetching any external endpoint. This prevents attackers from using the revocation handler as an open proxy to access internal services.
Default filter rules:
The default urlFilter function applies a layered check. A URL is blocked if any of these conditions are true:
- The URL does not parse successfully (
new URL(url)throws). - The protocol is not
http:orhttps:. - The hostname resolves to a private or loopback address:
localhost,127.0.0.1,::1,0.0.0.0- RFC 1918 private ranges:
10.x.x.x,172.16-31.x.x,192.168.x.x .localor.internalTLDs
If the URL passes the above checks, it is allowed if it matches any of these patterns (fast-path for known PKI URLs):
- Hostname or path contains
crl,ocsp,pki,ca., orcert - Path ends with
.crl,.cer, or.der - Path contains
/crl,/ocsp,/ca/,/revocation, or/repository - Hostname belongs to a government domain (
.gov,.mil,.gov.in,.nic.in)
If none of the above patterns match, the URL is still allowed by default (the filter falls through to return true). This means the default filter is permissive for all public URLs and only blocks private/loopback addresses. If you need stricter filtering, provide a custom urlFilter.
Custom filter:
handleRevocation({
urlFilter: (url) => {
try {
const u = new URL(url)
// Allow only specific CA domains
return u.hostname.endsWith('.digicert.com') ||
u.hostname.endsWith('.globalsign.com') ||
u.hostname.endsWith('.letsencrypt.org')
} catch {
return false
}
},
})Permissive filter (allow all HTTP/HTTPS URLs):
handleRevocation({
urlFilter: (url) => {
try {
const u = new URL(url)
return u.protocol === 'http:' || u.protocol === 'https:'
} catch {
return false
}
},
})UI Integration
When the revocation plugin updates a signature's revocationCheck field, the React viewer components (@trexolab/verifykit-react) automatically reflect the result.
DocumentMessageBar
The bar at the top of the viewer. If any signature's overallStatus becomes 'invalid' due to revocation, the bar displays: "At least one signature is INVALID." with a red background.
SignatureListPanel
In the expanded details for each signature, a revocation bullet point appears:
| Plugin result | Bullet text | Status icon |
|---|---|---|
'good' | "Certificate is not revoked" | Green checkmark |
'revoked' / 'revokedNoTimestamp' | "Certificate has been revoked" | Red X |
'unknown' | "Revocation status unknown" | Gray question mark |
Signature Properties Dialog (ValidityChecklist)
The full checklist in the properties dialog shows a "Revocation Status" row:
| Plugin result | Check text | Detail |
|---|---|---|
'good' | "Certificate is not revoked (verified via online OCSP)." or "Certificate is not revoked (verified via online CRL)." | Source URL |
'revoked' | "The signer's certificate has been revoked." | Revocation date and reason if available |
'revokedAfterSigning' | "Certificate is not revoked (verified via revoked after signing, timestamp protects)." | Source |
'unknown' | "Certificate revocation status is unknown." | Detail from revocationCheck.detail |
LTV Status
A signature is considered "LTV enabled" when it has a verified timestamp (timestampCheck.status === 'valid') and valid revocation data (revocationCheck.status === 'valid'). The SignatureListPanel displays "Signature is LTV enabled." when both conditions are met.