Repository: https://github.com/hglabplh-tech/unichorn-project
Plan date: 31 August 2026
Target: A modular, provider-neutral Java platform with independent desktop applications for mail, signature operations, certificate operations, OCSP/revocation and trust management.
Unichorn should be modernized as a modular monolith with multiple independently packaged applications. The first implementation step is to split the current mixed core and GUI into stable domain, API and adapter modules. Only after those boundaries exist should the libraries be upgraded and IAIK be replaced, because IAIK types currently occur across core, GUI, responder and PKCS#11 code.
The principal technology decisions are:
SunPKCS11 provider, DSS token support and the card vendor's native PKCS#11 driver or OpenSC.The current Maven reactor contains four modules:
unichorn-coreunichorn-gui-fxunichorn-pkcs11unichorn-responderThe modernization must address these concrete issues:
unichorn-core combines signatures, certificates, trust lists, OCSP/CRL, mail, HTTP, password management and general utilities.unichorn-gui-fx combines mail, signature, certificate, trust, smart-card and unrelated screens in one JavaFX application.iaik.* types are spread through all principal modules.unichorn-gui-fx references unichorn-isearch, which is not part of the reactor.| Module | Responsibility | May depend on |
|---|---|---|
unichorn-domain |
Immutable domain records, identifiers, policies, status models and errors | JDK only where practical |
unichorn-application-api |
Public use-case interfaces and provider-neutral DTOs | unichorn-domain |
unichorn-application |
Use-case orchestration and transaction/workflow logic | domain and API ports |
unichorn-config |
Typed configuration, profiles, migration and validation | domain |
unichorn-audit |
Structured audit events and evidence manifests | domain |
unichorn-test-support |
Generated certificates, deterministic clocks, fixtures and test adapters | test scope only |
| Module | Responsibility |
|---|---|
unichorn-crypto-bc |
Bouncy Castle provider bootstrap and low-level cryptographic primitives |
unichorn-signature-dss |
DSS adapter for AdES creation, validation, augmentation, qualification and reports |
unichorn-signature-create |
Signature creation workflow and signing-key selection |
unichorn-signature-validate |
Signature format detection, validation and report generation |
unichorn-signature-security |
Malformed-input, algorithm, wrapping, PDF/XML/archive and resource-limit checks |
unichorn-signature-maintenance |
B-T, B-LT and B-LTA augmentation and archival timestamp renewal |
unichorn-certificate-create |
Key pair, CSR, certificate and private/customer CA operations |
unichorn-certificate-validate |
X.509 path, name, usage, policy, time and revocation validation |
unichorn-token-api |
Provider-neutral smart-card/HSM/QSCD interfaces |
unichorn-token-pkcs11 |
SunPKCS11/DSS implementation backed by native vendor middleware or OpenSC |
| Module | Responsibility |
|---|---|
unichorn-mail-core |
Account, folder, message, attachment and address-book model |
unichorn-mail-transport |
IMAP/SMTP through Jakarta Mail/Angus Mail |
unichorn-mail-smime |
RFC 5751 signing, encryption, verification and decryption through Bouncy Castle |
unichorn-revocation |
OCSP-first evaluation, CRL fallback, caching and evidence |
unichorn-customer-trust |
Tenant-scoped customer root lists, versions, signing, activation and audit |
unichorn-eu-trust |
DSS LOTL/national TLv6 synchronization and eIDAS qualification |
unichorn-trust-policy |
Customer-first routing and final trust classification |
unichorn-network |
Restricted HTTP/LDAP retrieval, caching, timeouts, limits and SSRF controls |
| Module/application | Responsibility |
|---|---|
unichorn-ui-common |
Shared JavaFX components, accessibility, localization and report display only |
unichorn-app-mail |
Independent mail client GUI |
unichorn-app-signature-create |
Independent signature-creation GUI |
unichorn-app-signature-validate |
Signature validation and vulnerability-analysis GUI |
unichorn-app-signature-maintenance |
Signature augmentation/update GUI |
unichorn-app-certificate-create |
Certificate, key pair, CSR, keystore and customer-CA GUI |
unichorn-app-certificate-validate |
Certificate-path, policy and revocation-validation GUI |
unichorn-app-trust-center |
Customer trust lists, EU LOTL/TLv6, OCSP and CRL GUI |
unichorn-app-token-manager |
Optional card/token inspection GUI if token management cannot remain embedded in certificate/signature applications |
unichorn-cli |
Scriptable commands over the same application interfaces |
unichorn-responder |
Optional TSA/OCSP server adapter; no desktop dependencies |
unichorn-network; crypto libraries and GUI controllers do not retrieve arbitrary URLs directly.unichorn-ui-common must not become another business-logic module.Versions below are the verified baseline on the plan date. At implementation time, select the latest compatible stable release and rerun the full interoperability/security suite.
| Function | Recommended component | Baseline | License/notes |
|---|---|---|---|
| Java runtime | OpenJDK | Prefer JDK 21 first; evaluate JDK 25 after DSS/plugin compatibility tests | GPL-2.0 with Classpath Exception for OpenJDK builds |
| AdES/eIDAS | European Commission DSS | 6.4 stable; test 6.5.RC1 only in compatibility CI | LGPL-2.1; DSS 6.4 is the production baseline on 31 August 2026 |
| Crypto/PKI/CMS/S/MIME | Bouncy Castle bcprov-jdk18on, bcpkix-jdk18on, bcmail-jdk18on, bctls-jdk18on only if needed |
1.85 | MIT-style Bouncy Castle license |
| Mail/MIME | Jakarta Mail API + Eclipse Angus Mail | Jakarta Mail 2.1.5 / Angus 2.0.5 | EPL-2.0 or GPL-2.0 with Classpath Exception, depending artifact |
| PKCS#11 JCA provider | JDK SunPKCS11 |
Selected JDK | Included in JDK; use supported provider configuration APIs |
| DSS token signing | DSS Pkcs11SignatureToken |
Same DSS version | Use for DSS signing workflows behind TokenService |
| Native card middleware | Vendor PKCS#11 module or OpenSC | Current supported release | OpenSC LGPL-2.1; support depends on card/token model |
| Desktop GUI | OpenJFX | JavaFX 21 with JDK 21, or JavaFX 25 with JDK 23+ after compatibility approval | GPL-2.0 with Classpath Exception |
| HTTP | Apache HttpComponents Client 5 | Current stable compatible version | Apache-2.0 |
| MIME hardening, optional | Apache James Mime4j | Current stable compatible version | Apache-2.0; add only for malformed/hostile MIME analysis |
| Logging | tinylog 2 or SLF4J 2 + Logback | One stack only | Do not retain tinylog 1 and 2 together |
| JSON | Jackson or Gson | One selected current stable line | Avoid multiple JSON models without need |
| Tests | JUnit Jupiter, AssertJ, Mockito Core | Current stable compatible versions | Replace JUnit 4, mockito-all and old PowerMock bundles |
| SBOM | CycloneDX Maven plugin | Current stable | Generate at every release |
PKCS#11 itself is not an IAIK library and should not be removed. It is the standard interface between Java and a token's native middleware. What must be replaced is:
iaik-pkcs11-wrapperiaik-pkcs11provider-*The preferred replacement stack is:
unichorn-token-api defines TokenService, TokenSession, TokenIdentity, TokenCertificate, TokenCapabilities and domain exceptions.unichorn-token-pkcs11 uses the JDK SunPKCS11 provider and KeyStore.getInstance("PKCS11") through supported JCA/JCE APIs.Pkcs11SignatureToken internally within the DSS adapter..dll, .so or .dylib; OpenSC is an alternative only for supported cards.Cipher/key-unwrapping through the configured provider when the card and driver expose the required mechanisms.sun.security.pkcs11.* classes. Do not expose DSS token classes outside the adapter.The following interfaces form the stable boundary for GUIs, CLI commands and responder endpoints:
public interface MailService {
MessageId send(SendMailCommand command);
MailMessage read(ReadMailQuery query);
}
public interface MimeSecurityService {
SecuredMimeMessage sign(SignMimeCommand command);
SecuredMimeMessage encrypt(EncryptMimeCommand command);
SecuredMimeMessage signThenEncrypt(SignEncryptMimeCommand command);
DecryptedMimeMessage decrypt(DecryptMimeCommand command);
MailSecurityReport verify(VerifyMimeCommand command);
}
public interface SignatureCreationService {
SigningPreparation prepare(CreateSignatureCommand command);
SignedArtifact complete(CompleteSignatureCommand command);
}
public interface SignatureValidationService {
SignatureValidationReport validate(ValidateSignatureCommand command);
}
public interface SignatureSecurityAnalysisService {
SecurityAnalysisReport inspect(InspectArtifactCommand command);
}
public interface SignatureMaintenanceService {
SignedArtifact augment(AugmentSignatureCommand command);
}
public interface CertificateCreationService {
KeyReference createKey(CreateKeyCommand command);
CertificationRequest createCsr(CreateCsrCommand command);
CertificateBundle issue(IssueCertificateCommand command);
}
public interface CertificateValidationService {
CertificateValidationReport validate(ValidateCertificateCommand command);
}
public interface TokenService extends AutoCloseable {
List<TokenDescriptor> discover();
List<TokenIdentity> identities(TokenId tokenId, PinCallback pinCallback);
SignatureValue sign(TokenSignCommand command, PinCallback pinCallback);
DecryptedKeyMaterial decryptOrUnwrap(TokenDecryptCommand command, PinCallback pinCallback);
}
public interface RevocationService {
RevocationReport check(RevocationRequest request);
}
public interface CustomerTrustListService {
CustomerTrustListVersion publish(PublishCustomerTrustListCommand command);
Optional<CustomerTrustList> activeList(TenantId tenantId, Instant validationTime);
}
public interface EuTrustService {
EuTrustReport evaluate(EuTrustRequest request);
}
public interface TrustPolicyService {
CombinedTrustReport evaluate(TrustEvaluationCommand command);
}
These signatures are architectural examples, not a requirement to preserve the exact names. The critical rule is that no IAIK, Bouncy Castle, DSS, JavaFX or native-driver type appears in them.
CryptoProviderBootstrap: deterministic provider registration and startup diagnostics.AlgorithmPolicy: allowed, deprecated and forbidden algorithms, key sizes and dates.SecureClock: injected validation/signing time for repeatable tests.DocumentSource/DocumentSink: bounded streaming instead of unrestricted byte arrays.MimeCanonicalizer: RFC 5751-compatible MIME canonicalization and transfer encoding.SafeNetworkClient: HTTP/LDAP allow rules, proxy support, TLS, redirect limits, timeouts, maximum sizes and SSRF protection.EvidenceStore: content-addressed OCSP, CRL, TL/LOTL, timestamp and policy snapshots.SecretProvider: OS keychain/secret-store abstraction; no credentials in properties files.PolicyRegistry: versioned validation, trust, algorithm and customer policies.ResultRenderer: machine-readable JSON/XML and human-readable HTML/PDF summaries.AuditTrail: correlation IDs, actor, operation, policy version, evidence hashes and outcome.CancellationToken/progress reporting for JavaFX background operations.EnvelopedData encryption for one or more recipients.PASSED, FAILED and INDETERMINATE outcomes; never reduce all validation to a boolean.CUSTOMER_QUALIFIED — qualified by customer policy, not eIDAS-qualified;EIDAS_QUALIFIED;CUSTOMER_AND_EIDAS_QUALIFIED;TRUSTED_NON_QUALIFIED;UNTRUSTED;INDETERMINATE.GOOD or REVOKED as conclusive according to policy.UNKNOWN, retrieve the issuer's CRL from the X.509 CRL Distribution Point.Although module separation is the first product change, a short safety phase is required before moving code.
Tasks
unichorn-isearch dependency.Exit criteria
Tasks
unichorn-application-api interfaces around current implementations.unichorn-mail-core/unichorn-mail-transport without rewriting them yet.unichorn-core-legacy temporarily so the old GUI continues to run.Exit criteria
Tasks
mockito-all, old PowerMock and ASM 3.Exit criteria
Migration order
Rules
Exit criteria
Tasks
unichorn-token-api contract and threat model.sun.* APIs.Pkcs11SignatureToken behind the DSS adapter.Exit criteria
Tasks
Exit criteria
Tasks
Exit criteria
Tasks
unichorn-mail-core, unichorn-mail-transport and unichorn-mail-smime independently buildable.unichorn-app-mail with its own launcher, configuration and package.Exit criteria
Build in this order so reusable components stabilize early:
unichorn-app-signature-validateunichorn-app-certificate-validateunichorn-app-trust-centerunichorn-app-signature-createunichorn-app-certificate-createunichorn-app-signature-maintenanceunichorn-app-mailunichorn-app-token-managerGUI requirements
jlink/jpackage runtime image.Exit criteria
Tasks
Exit criteria
Tasks
Exit criteria
| Milestone | Result | Phase duration | Cumulative range |
|---|---|---|---|
| M0 | Reproducible baseline and migration inventory | 1–2 weeks | 2 weeks |
| M1 | Module separation with legacy behavior preserved | 3–5 weeks | 5–7 weeks |
| M2 | Modern JDK/build/dependencies | 2–4 weeks | 7–11 weeks |
| M3 | IAIK replaced by BC/DSS vertical slices | 5–8 weeks | 12–19 weeks |
| M4 | PKCS#11/token abstraction working | 3–5 weeks | 15–24 weeks |
| M5 | Utilities and provider-neutral services complete | 4–6 weeks | 19–30 weeks |
| M6 | Customer/EU trust and revocation routing complete | 3–5 weeks | 22–35 weeks |
| M7 | Independent mail client complete | 3–5 weeks | 25–40 weeks |
| M8 | Separate GUI applications packaged | 6–9 weeks | 31–49 weeks |
| M9 | CLI/optional REST/responder interfaces | 3–5 weeks | 34–54 weeks |
| M10 | Hardened release | 2–4 weeks | 36–58 weeks |
The cumulative figure assumes mostly sequential execution by a small team. After Phase 3, GUI, trust, token and mail workstreams can run partly in parallel if interface contracts and test fixtures are stable. Re-estimate after Phase 0 and again after the first DSS/PKCS#11 vertical slice.
A feature is complete only when:
| Risk | Consequence | Mitigation |
|---|---|---|
| Large IAIK surface | Hidden behavioral differences | Complete import map, characterization corpus and vertical-slice migration |
| Simultaneous module/library/provider rewrite | Untraceable regressions | Preserve the phase order and keep every phase green |
| DSS/BC version incompatibility | Provider or validation failures | Pin compatible versions; use DSS BOM/dependency tree; compatibility CI |
| Card-driver differences | Token works on one OS/card only | Hardware compatibility matrix, simulator CI and real-card release gate |
| Incorrect “qualified” terminology | Customer trust mistaken for eIDAS status | Separate status enum and explicit UI/report wording |
| OCSP outage | False failure or unsafe acceptance | Policy-controlled CRL fallback and auditable INDETERMINATE outcome |
| Stale CRL/TL evidence | Incorrect historical/current result | Freshness rules, signed snapshots, validation-time model and cache metadata |
| Malicious documents/mail | Parser exploits or resource exhaustion | Bounded streaming, isolation, fuzzing, MIME/archive/PDF/XML limits |
| GUI split duplicates logic | Divergent behavior | Shared application services and contract tests; ui-common contains no business rules |
| Scope expansion | Release delay | Freeze promised formats/cards/GUIs per milestone and place additions in backlog |
ValidationEvidenceBundle so results can be replayed offline.The first actionable backlog should be:
unichorn-isearch.unichorn-domain and unichorn-application-api dependency rules.CryptoProviderBootstrap with Bouncy Castle 1.85.European Commission DSS 6.4: https://ec.europa.eu/digital-building-blocks/sites/spaces/DIGITAL/pages/952471879/DSS+v6.4
DSS 6.5.RC1 compatibility target: https://ec.europa.eu/digital-building-blocks/sites/spaces/DIGITAL/pages/973932532/DSS+v6.5.RC1
DSS Pkcs11SignatureToken API: https://ec.europa.eu/digital-building-blocks/DSS/webapp-demo/apidocs/eu/europa/esig/dss/token/Pkcs11SignatureToken.html
Bouncy Castle Java 1.85: https://www.bouncycastle.org/resources/new-release-bouncy-castle-java-1-85/
Java PKCS#11 Reference Guide: https://docs.oracle.com/en/java/javase/26/security/pkcs11-reference-guide1.html
Eclipse Angus Mail: https://github.com/eclipse-ee4j/angus-mail
OpenJFX: https://openjfx.io/
RFC 5751, S/MIME 3.2: https://www.rfc-editor.org/rfc/rfc5751
RFC 8551, S/MIME 4.0: https://www.rfc-editor.org/rfc/rfc8551
Harald Glab-Plhak
Computer Science since 1992
© Harald Glab-Plhak (2026)