Vanilla.PDF  2.2.0
Cross-platform toolkit for creating and modifying PDF documents
Signature Verification Guide

This guide explains how to verify digital signatures in PDF documents using the Vanilla.PDF C API.

For a complete working example, see verify.c.

Overview

PDF digital signatures use PKCS#7 (CMS) format to store cryptographic signatures. Verification involves:

  1. Cryptographic verification - Verify the signature matches the document content
  2. Certificate chain validation - Validate the signer's certificate against trusted roots
  3. Algorithm strength check - Detect weak algorithms (MD5, SHA-1, small keys)
  4. Time validation - Optionally validate certificate at signing time

Verification Status Codes

The verification result includes a status code indicating the outcome:

Status Description
SignatureStatus_Valid Signature is cryptographically valid and certificate chain is trusted
SignatureStatus_Invalid Signature verification failed (content modified or wrong key)
SignatureStatus_CertificateExpired Signing certificate has expired
SignatureStatus_CertificateNotYetValid Certificate not yet valid (future start date)
SignatureStatus_CertificateUntrusted Certificate chain does not lead to a trusted root
SignatureStatus_WeakAlgorithm Weak cryptographic algorithm detected
SignatureStatus_DocumentModified Document modified after signing

Weak Algorithm Detection

The verifier detects the following weak algorithms:

Weak Digest Algorithms:**

  • MD2, MD4, MD5, SHA-1, MD5-SHA1

    Weak Signature Algorithms:**

  • MD2/MD4/MD5 with RSA
  • SHA-0 with RSA/DSA
  • SHA-1 with RSA/DSA/ECDSA
  • RIPEMD-160 with RSA, MDC2 with RSA

    Weak Key Sizes:**

  • RSA keys < 2048 bits
  • DSA keys < 2048 bits
  • EC keys < 256 bits

Creating a Trust Store

Create a trusted certificate store and load certificates:

// Create or load trusted certificate store
RETURN_ERROR_IF_NOT_SUCCESS(TrustedCertificateStore_Create(&trust_store));
if (certs_path != NULL) {
printf("Loading trusted certificates from: %s\n", certs_path);
RETURN_ERROR_IF_NOT_SUCCESS(TrustedCertificateStore_LoadFromDirectory(trust_store, certs_path));
} else {
printf("Loading system default trusted certificates\n");
RETURN_ERROR_IF_NOT_SUCCESS(TrustedCertificateStore_LoadSystemDefaults(trust_store));
}

Configuring Verification Settings

Configure verification behavior with custom settings:

// Configure verification settings
RETURN_ERROR_IF_NOT_SUCCESS(SignatureVerificationSettings_Create(&settings));
if (skip_certificate_validation) {
printf("WARNING: Skipping certificate chain validation (insecure)\n");
RETURN_ERROR_IF_NOT_SUCCESS(SignatureVerificationSettings_SetSkipCertificateValidation(settings, VANILLAPDF_RV_TRUE));
}
if (allow_weak_algorithms) {
printf("Allowing weak cryptographic algorithms\n");
RETURN_ERROR_IF_NOT_SUCCESS(SignatureVerificationSettings_SetAllowWeakAlgorithmsFlag(settings, VANILLAPDF_RV_TRUE));
}
if (check_signing_time) {
printf("Checking certificate validity at signing time\n");
RETURN_ERROR_IF_NOT_SUCCESS(SignatureVerificationSettings_SetCheckSigningTimeFlag(settings, VANILLAPDF_RV_TRUE));
}
/* TODO: CRL/OCSP revocation checking (https://github.com/vanillapdf/vanillapdf/issues/157)
if (check_revocation) {
printf("Checking certificate revocation status\n");
RETURN_ERROR_IF_NOT_SUCCESS(SignatureVerificationSettings_SetCheckRevocationFlag(settings, VANILLAPDF_RV_TRUE));
}
*/
const boolean_type VANILLAPDF_RV_TRUE
Represents the boolean true value.

Available settings:

  • SetSkipCertificateValidation - Skip X509 chain validation (testing only)
  • SetAllowWeakAlgorithmsFlag - Allow MD5, SHA-1, small keys
  • SetCheckSigningTimeFlag - Validate cert at signing time instead of current time

Verifying a Signature

Call the verification API and inspect the results:

// Verify signature using DigitalSignatureExtensions
RETURN_ERROR_IF_NOT_SUCCESS(DigitalSignatureExtensions_Verify(digital_signature, document, trust_store, settings, &result));
// Get verification status
RETURN_ERROR_IF_NOT_SUCCESS(SignatureVerificationResult_GetStatus(result, &status));
// Get verification flags
boolean_type is_signature_valid = VANILLAPDF_RV_FALSE;
boolean_type is_document_intact = VANILLAPDF_RV_FALSE;
boolean_type is_cert_trusted = VANILLAPDF_RV_FALSE;
RETURN_ERROR_IF_NOT_SUCCESS(SignatureVerificationResult_IsSignatureValid(result, &is_signature_valid));
RETURN_ERROR_IF_NOT_SUCCESS(SignatureVerificationResult_IsDocumentIntact(result, &is_document_intact));
RETURN_ERROR_IF_NOT_SUCCESS(SignatureVerificationResult_IsCertificateTrusted(result, &is_cert_trusted));
// Get signer common name
BufferHandle* signer_name = NULL;
RETURN_ERROR_IF_NOT_SUCCESS(SignatureVerificationResult_GetSignerCommonName(result, &signer_name));
// Get verification message
BufferHandle* message_buffer = NULL;
RETURN_ERROR_IF_NOT_SUCCESS(SignatureVerificationResult_GetMessage(result, &message_buffer));
error_type CALLING_CONVENTION DigitalSignatureExtensions_Verify(DigitalSignatureHandle *signature, DocumentHandle *document, TrustedCertificateStoreHandle *trusted_store, SignatureVerificationSettingsHandle *settings, SignatureVerificationResultHandle **result)
Verify the digital signature in a PDF document.
Represents memory stored data.
const boolean_type VANILLAPDF_RV_FALSE
Represents the boolean false value.
int8_t boolean_type
Boolean type supported in C.
Definition c_types.h:31
SignatureVerificationStatusType
Overall status of signature verification.
Definition c_signature_verifier.h:37

Command Line Usage

The vanillapdf.tools CLI provides signature verification:

# Basic verification (uses system trust store)
vanillapdf.tools verify -f document.pdf
# Skip certificate validation (for self-signed certificates)
vanillapdf.tools verify -f document.pdf --skip-certificate-validation
# Allow weak algorithms (for legacy documents)
vanillapdf.tools verify -f document.pdf --allow-weak-algorithms
# Check certificate at signing time
vanillapdf.tools verify -f document.pdf --check-signing-time
# Use custom certificate directory
vanillapdf.tools verify -f document.pdf -c /path/to/trusted/certs
# Combine options
vanillapdf.tools verify -f document.pdf \
--allow-weak-algorithms \
--check-signing-time

Security Recommendations

  1. Always use system trust store - Let the OS manage trusted root certificates
  2. Avoid --skip-certificate-validation - Only use for testing self-signed certificates
  3. Avoid --allow-weak-algorithms - Only enable when absolutely necessary for legacy documents
  4. Use --check-signing-time - For old documents where certificates may have expired
  5. Keep certificates updated - Ensure your system's certificate store is current
See also
verify.c
TrustedCertificateStore_Create
SignatureVerificationSettings_Create
SignatureVerifier_Verify