Skip to main content

Overview

Validation.PackageSigning.ValidateCertificate is a console executable (net472) that runs as a continuously-polling Azure Service Bus subscription processor. Its sole responsibility is to receive CertificateValidationMessage requests, download the target X.509 certificate and its ancestor chain from Azure Blob Storage, execute an online revocation check against the issuing Certificate Authority, and persist the result back to the validation database. When a certificate is found to be revoked or invalid the job also evaluates every dependent PackageSignature and either ignores, warns, or rejects it according to a set of time-based and flag-based rules. This cascade is what ultimately marks NuGet packages as having invalid signatures.
The online revocation check is performed via Windows’ native CryptoAPI (X509Chain + raw CERT_CHAIN_CONTEXT pointer inspection). The executable therefore only runs on Windows and requires <AllowUnsafeBlocks>true</AllowUnsafeBlocks> in the project file.

Role in the NuGetGallery Ecosystem

Upstream trigger

Produced by the package-signing orchestrator when a new certificate requires validation or a periodic re-check is scheduled via CertificateValidationMessage.

Downstream effects

Writes EndCertificateStatus and PackageSignatureStatus changes to the shared IValidationEntitiesContext SQL database, which the gallery reads to decide whether to serve a package.

Queue-back integration

Optionally sends a CheckValidator message to the package validation queue after a successful validation so the orchestrator can advance the overall validation state machine.

Telemetry

Emits Application Insights metrics for message lag, handler duration, lock-lost events, and per-signature invalidation alerts under the ValidateCertificate.* prefix.

Key Files and Classes


Dependencies

Internal Project References

NuGet Packages (resolved transitively)


Message Flow


Notable Patterns and Implementation Details

Batch signature updates. When a certificate is revoked or invalidated, CertificateValidationService.ProcessDependentSignaturesAsync updates dependent PackageSignature rows in pages of 500 (MaxSignatureUpdatesPerTransaction) to avoid oversized EF change-tracker transactions. Each page is committed before the next is fetched.
Unknown-status retry loop. If the CA’s revocation endpoint is offline or returns an ambiguous result, the certificate status is set to Unknown and HandleAsync returns false, leaving the Service Bus message unacknowledged for automatic redelivery. After DefaultMaximumValidationFailures (10) consecutive failures the certificate is promoted to Invalid and a telemetry alert fires, requiring manual NuGet Admin investigation.
Revoked certificate re-validation requires an explicit flag. The message handler silently completes (drops) any message that tries to re-validate a known-revoked certificate unless CertificateValidationMessage.RevalidateRevokedCertificate is true. This is intentional: CAs are not required to retain revocation records indefinitely, so re-checking a revoked cert could produce a spuriously “Good” result.
Windows-only binary. OnlineCertificateVerifier uses unsafe pointer arithmetic against the native SafeX509ChainHandle to read CERT_REVOCATION_INFO* directly from memory. This depends on the Windows CryptoAPI and will not function on Linux or macOS. The project targets net472 with <AllowUnsafeBlocks>true</AllowUnsafeBlocks>.
Signature decision policy nuances. SignatureDeciderFactory encodes several non-obvious rules:
  • A revoked code-signing cert invalidates only signatures whose trusted timestamp post-dates the revocation time. Signatures timestamped before revocation survive (Ignore). If revocation time is unknown, all dependent signatures are rejected.
  • A revoked timestamping cert triggers Warn on already-accepted signatures and Reject on signatures still at ingestion (Unknown status).
  • NotTimeNested alone is a no-op (Ignore) to avoid false positives from minor clock skew.
  • HasWeakSignature | NotSignatureValid only rejects signatures at ingestion; existing valid signatures are left intact.
The Scripts/ folder contains NSSM-based PowerShell deployment scripts (PreDeploy.ps1, PostDeploy.ps1, Functions.ps1) and the nssm.exe service wrapper binary. In production this job is installed as a Windows Service rather than run as a one-off scheduled task.