Skip to content

cavoq/PCL

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

115 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ” PCL - Policy-based Certificate Linter

CI codecov Go Report Card License: GPL-3.0

A flexible X.509 certificate linter that validates certificates against configurable YAML-based policies. Ensure compliance with RFC 5280, organizational standards, or industry best practices.

πŸš€ Quick Start

go install github.com/cavoq/PCL/cmd/pcl@latest
pcl --policy <path> --cert <path> [--crl <path>] [--ocsp <path>] [--output text|json|yaml]

By default, only failed rules are shown. Use -v to include passed rules and -vv to include skipped rules.

You can also fetch a TLS certificate chain from HTTPS URLs:

pcl --policy <path> --cert-url https://example.test --cert-url-timeout 10s --cert-url-save-dir ./downloads

πŸ“ Policy Configuration

Policies are YAML files defining validation rules with a simple declarative syntax.

id: rfc5280
rules:
  - id: version-v3
    target: certificate.version
    operator: eq
    operands: [3]
    severity: error

  - id: signature-algorithm-secure
    target: certificate.signatureAlgorithm.algorithm
    operator: in
    operands:
      - SHA256-RSA
      - SHA384-RSA
      - ECDSA-SHA256
    severity: error

  # Conditional rule using "when" clause
  - id: rsa-key-size-minimum
    when:
      target: certificate.subjectPublicKeyInfo.algorithm
      operator: eq
      operands: [RSA]
    target: certificate.subjectPublicKeyInfo.publicKey.keySize
    operator: gte
    operands: [2048]
    severity: error

  - id: ca-basic-constraints
    target: certificate.basicConstraints.cA
    operator: eq
    operands: [true]
    severity: error
    appliesTo: [root, intermediate]

  # Optional document reference (used by text output)
  - id: key-usage-leaf
    reference: RFC5280 4.2.1.3
    target: certificate.keyUsage
    operator: keyUsageLeaf
    severity: error

πŸ›οΈ Supported Policies

  • RFC 5280 - Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile

βž• Supported Operators

Comparison Operators

Operator Description
eq Equality check
neq Not equal check
gt, gte Greater than (or equal)
lt, lte Less than (or equal)
in Value in allowed list
notIn Value not in disallowed list
contains String/array contains value
matches Compare two field paths for equality

Presence & Value Operators

Operator Description
present Field existence check
absent Field does not exist
isEmpty, notEmpty Value emptiness check
positive Value is a positive number
odd Value is an odd number (for RSA exponent validation)
maxLength, minLength String/array length constraints
regex, notRegex Regular expression pattern matching

Date Operators

Operator Description
before Date is before current time
after Date is after current time
validityOrderCorrect Validates notBefore < notAfter
validityDays Certificate validity period check

Extension Operators

Operator Description
isCritical, notCritical Extension criticality check
noUnknownCriticalExtensions No unhandled critical extensions

Certificate Chain Operators

Operator Description
signatureValid Cryptographic signature verification
signatureAlgorithmMatchesTBS Signature algorithm matches TBS certificate
issuedBy Issuer DN matches issuer's subject DN
akiMatchesSki Authority Key ID matches issuer's Subject Key ID
pathLenValid Path length constraint validation
serialNumberUnique Serial number uniqueness in chain

Key Usage & Constraints Operators

Operator Description
sanRequiredIfEmptySubject SAN required when subject is empty
keyUsageCA, keyUsageLeaf Key usage validation by cert type
ekuContains, ekuNotContains Extended key usage checks
ekuServerAuth, ekuClientAuth TLS authentication EKU checks
noUniqueIdentifiers Absence of issuer/subject unique IDs

CRL Operators

Operator Description
crlValid CRL is within thisUpdate/nextUpdate window
crlNotExpired CRL nextUpdate is in the future
crlSignedBy CRL signature verification against chain
notRevoked Certificate not in CRL revoked list

OCSP Operators

Operator Description
ocspValid OCSP response is within validity window and signature is valid
notRevokedOCSP Certificate not revoked according to OCSP
ocspGood Certificate has explicit Good status in OCSP response

Path Validation Operators

Operator Description
nameConstraintsValid Validates names against permitted/excluded subtrees from chain
certificatePolicyValid Validates policy OIDs through chain with mappings and constraints

πŸ”€ Conditional Rules

Rules can include a when clause to apply only when certain conditions are met:

- id: rsa-exponent-valid
  when:
    target: certificate.subjectPublicKeyInfo.algorithm
    operator: eq
    operands: [RSA]
  target: certificate.subjectPublicKeyInfo.publicKey.exponent
  operator: odd
  severity: error

This rule only validates RSA exponent when the certificate uses RSA. If the condition is not met, the rule is skipped.

Certificate Chain Support

PCL automatically builds and validates certificate chains, applying rules based on certificate position:

  • leaf: End-entity certificates
  • intermediate: CA certificates in the chain
  • root: Self-signed root CA certificates

Use appliesTo in rules to target specific certificate types.

πŸ”§ Development

go build -o pcl ./cmd/pcl
go test -v -race ./...
golangci-lint run ./...