Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion API-Changes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
NEXT MAJOR VERSION - LITE PKI VALIDATION

This release is deliberately source- and binary-incompatible with 2.x. The
behavioral contract and migration rules are in
docs/changes/0003-lite-pki-contract.md.

Planned removals include all proxy-certificate APIs, namespace-policy APIs,
legacy OpenSSL subject hashes, and the detailed copied-reviewer validation
error catalogue. Validator constructors and parameter objects will no longer
accept proxy or namespace settings.

Certificate-array validation treats the first certificate as the target and
the rest as path-building candidates. Successful results contain the resolved
chain and selected trust anchor. Invalid results report one primary native-PKIX
failure with its cause, stage, and certificate position. Error listeners can
observe failures but can no longer suppress them.

OCSP remains supported. Core native OCSP and CRL modes are migrated first;
responder configuration, ordering, nonce, and cache behavior follow in
separately reviewed changes. No OCSP capability is removed silently.

The exact removed and replacement Java symbols will be appended by the PR that
changes each part of the API.


2.x HISTORICAL CHANGES

1) changed semantics of the DN compare methods operating on the string representation.
2) changed ParseException to (runtime) IllegalArgumentException in X500NameUtils.
3) changed slightly X500NameUtils.getAttributeValues description
Expand Down Expand Up @@ -44,4 +71,3 @@ two trusted v1 certificates with the same subject but different keys) is not sup

- Known issue: due to bug in BC (http://www.bouncycastle.org/jira/browse/BJA-370) only masks
8, 16, 24 and 32 are working correctly in Proxy certificate target/source restrictions.

8 changes: 5 additions & 3 deletions docs/changes/0001-lite-pki-validation-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Native Bouncy Castle `CertPathBuilder` and `CertPathValidator` are to be the val
- Treat the first certificate in an array as the target and the remainder as path-building candidates.
- Accept an exact trusted self-signed input and keep trust anchors outside PKIX path validation.
- Use native revocation behavior for the modes that BC represents accurately. Do not emulate optional behavior through exception-message matching.
- Retain OCSP validation. Migrate its core validation to native BC first, then preserve responder configuration, fallback and ordering, caching, and nonce behavior in separately reviewed layers wherever each feature can be implemented precisely and tested deterministically.
- Remove residual gLite/Grid compatibility utilities, test corpora, documentation, and obsolete build metadata while preserving required attribution for retained derived code.

## Sequence
Expand Down Expand Up @@ -78,9 +79,10 @@ Exit condition: invalid TLS and direct-validation calls provide an actionable pr
### 6. Implement the retained native revocation modes

- Implement revocation-disabled and strict native CRL behavior.
- If OCSP is retained, expose only behavior that maps clearly to native BC, such as required OCSP or native preferred-mechanism fallback.
- Remove custom responder ordering, cache, nonce, and multi-mechanism semantics unless they are separately justified and tested.
- Add focused tests for missing, expired, malformed, badly signed, and revoking CRLs, plus equivalent OCSP outcomes for any retained OCSP modes.
- Implement required OCSP and native preferred-mechanism fallback.
- Preserve certificate AIA responder discovery and explicitly configured responders.
- Migrate responder ordering, cache, nonce, and multi-mechanism semantics in separate changes. Retain each behavior that can be specified precisely and tested without replacing native BC as the validation authority.
- Add focused tests for missing, expired, malformed, badly signed, and revoking CRLs, plus equivalent OCSP outcomes.

Exit condition: every advertised revocation mode has precise tests and no mode claims optional/soft-fail semantics that BC does not actually provide.

Expand Down
51 changes: 51 additions & 0 deletions docs/changes/0002-validation-baseline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Validation baseline

This records the test-suite baseline before the lite PKI validation refactor.
It is a comparison point, not a statement that every legacy behavior will be
retained.

## Source and environment

- Source commit: `89762d4` (`master`, "The grand refactoring plan")
- Recorded: 2026-08-21
- Maven: 3.9.12
- Java: OpenJDK 25.0.3

## Default suite

Command:

```console
mvn clean test
```

Result: **BUILD SUCCESS**

```text
Tests run: 274, Failures: 0, Errors: 0, Skipped: 1
```

The skipped test is in `ProxyGenerationTest`; its existing skip reason is
`TODO: test certificates have expired`.

## Opt-in risky integration suite

Command:

```console
mvn test -PriskyTests
```

Result: **BUILD FAILURE**

```text
Tests run: 8, Failures: 1, Errors: 0, Skipped: 3
```

The failure is `CRLTest.testLoadPlain`, which expects one CRL but loads none
from an external fixture URL. The three skipped tests are the existing OCSP
integration/cache/client tests. The OpenSSL validator stress tests pass.

The risky profile depends on external services and fixtures. Its failure is
therefore preserved as part of the baseline rather than treated as a failure
introduced by the refactor.
142 changes: 142 additions & 0 deletions docs/changes/0003-lite-pki-contract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Lite PKI behavioral and migration contract

This document freezes the intended externally observable behavior before the
implementation is replaced. It describes the final target. Intermediate
branches may deliberately support a smaller subset while the stacked changes
are under review, but each such limitation must be stated in that branch.

## Compatibility boundary

Compatibility is defined by validation verdicts and actionable primary error
reporting. The new implementation is not required to reproduce the legacy
reviewer's complete list or ordering of errors.

The refactor deliberately removes:

- proxy certificate generation, inspection, configuration, and validation;
- Globus `.signing_policy` and EUGridPMA `.namespaces` processing;
- pre-OpenSSL-1.0 subject hashes;
- copied Bouncy Castle path-validation code and its detailed error catalogue;
- gLite/Grid-specific utilities that have no retained callers.

The corresponding public packages, types, constructor arguments, flags,
listeners, and error codes will be removed rather than retained as no-ops.
Removal PRs must extend the migration notes with the exact symbols they delete.

Standard X.509 path validation, TLS trust management, OpenSSL-style hashed CA
and CRL stores, CRL revocation, and OCSP revocation are retained.

## Certificate input and path contract

- For an `X509Certificate[]`, element zero is the target. Remaining elements
are unordered path-building candidates; their supplied order is not treated
as an asserted path.
- A `CertPath` is an asserted coherent path and is validated directly.
- Trust anchors are configured separately and are never validated as path
certificates.
- If an asserted or built path contains its trust anchor certificate, that
certificate is removed from the path passed to native validation.
- An input consisting of an exact trusted self-signed certificate is valid.
- Successful results contain the resolved target-to-anchor chain, including
the selected trust-anchor certificate.
- Native Bouncy Castle `CertPathBuilder` and `CertPathValidator`, selected with
the BC provider explicitly, are the path-building and validation authority.

## Validation result contract

A result contains:

- the validation verdict;
- no validation errors for a valid result;
- one primary error for an invalid result;
- unresolved critical-extension OIDs when the provider exposes them without a
second validation implementation;
- the resolved chain only for a valid result.

`getErrors()` remains as a compatibility convenience, but returns an immutable
empty or single-element list. `getPrimaryError()` returns the single error or
`null` for a valid result. The public `ValidationResult` constructors,
`addErrors()`, and `setErrors()` are removed from the consumer API.

The primary error contains:

- a stable error code and broad category;
- the validation stage (`INPUT`, `PATH_BUILDING`, `PATH_VALIDATION`, or
`REVOCATION`);
- a zero-based certificate index and certificate when a position is known;
- the original provider message;
- the original exception as its cause.

Index zero denotes the target. An unknown or whole-path position is `-1`.
Provider-specific text is diagnostic data and is not a stable API value.

The stable error-code set is limited to standard reasons:

- `INVALID_INPUT`;
- `PATH_BUILDING_FAILED` and `NO_TRUST_ANCHOR`;
- `CERTIFICATE_EXPIRED` and `CERTIFICATE_NOT_YET_VALID`;
- `INVALID_SIGNATURE` and `ALGORITHM_CONSTRAINED`;
- `INVALID_NAME_CHAINING`;
- `INVALID_KEY_USAGE`, `NOT_CA`, and `PATH_TOO_LONG`;
- `INVALID_NAME_CONSTRAINT` and `INVALID_POLICY`;
- `UNRESOLVED_CRITICAL_EXTENSION`;
- `CERTIFICATE_REVOKED` and `UNDETERMINED_REVOCATION_STATUS`;
- `PKIX_FAILURE` for all unspecified/provider-specific reasons.

The retained broad categories are `INPUT`, `PATH`, `CERTIFICATE`,
`NAME_CONSTRAINT`, `POLICY`, `REVOCATION`, and `OTHER`.

Validation-error listeners are notification-only. A listener cannot suppress
an error, change an invalid verdict, or mutate the primary error. TLS-facing
`CertificateException`s preserve the primary validation exception as their
cause.

## Revocation contract

OCSP is required retained functionality. The implementation will be migrated
in layers so that custom mechanics do not remain entangled with path
validation.

The required core modes are:

- disabled revocation;
- strict CRL validation;
- strict OCSP validation;
- native OCSP-first fallback to CRL;
- native CRL-first fallback to OCSP;
- native soft-fail OCSP-first fallback for compatibility with the current
default.

The compatibility default is OCSP first, followed by CRL, with native
soft-fail behavior when status cannot be obtained. A definitive revoked status
always fails. Malformed, forged, badly signed, or otherwise invalid revocation
data is not converted into success by soft-fail handling.

The following OCSP capabilities are migration requirements, each implemented
and reviewed separately after core native OCSP validation:

- responder discovery from certificate AIA;
- explicitly configured responder URL and trusted responder certificate;
- preference and ordering between configured and discovered responders;
- connection timeout;
- request nonce generation and response nonce enforcement;
- bounded in-memory response caching and configured cache TTL;
- optional persistent response caching;
- ordering between OCSP and CRL mechanisms;
- the existing require-all-enabled-mechanisms behavior where it can be layered
around independent native validation without weakening either result.

No item in this compatibility list is silently dropped. If a capability cannot
be retained without copied validation code, provider-message matching, or a
security regression, its dedicated PR must demonstrate that limitation and
make the final decision explicit.

The legacy CRL `IF_VALID` name is not retained. If its present-but-enforced
behavior passes the separate decision gate, it is exposed as `IF_PRESENT`.

## Review and verification rule

Every behavior-changing branch must state which contract clauses it implements
or intentionally defers. Valid/invalid verdict comparisons use the recorded
baseline where the behavior remains in scope. New native revocation behavior
uses deterministic local CRL and OCSP fixtures rather than public responders.