diff --git a/pki/.classpath b/pki/.classpath
new file mode 100644
index 0000000..000d5a0
--- /dev/null
+++ b/pki/.classpath
@@ -0,0 +1,31 @@
+
+
+ * This class is intentionally limited to process bootstrap concerns only: + *
+ *+ * No cryptography, persistence, or domain/business logic is performed here. The + * public PKI API resides under {@code zeroecho.pki.api.*} and is not modified + * by this bootstrap. + *
+ */ +public final class PkiApplication { + + private static final Logger LOG = Logger.getLogger(PkiApplication.class.getName()); + + private PkiApplication() { + throw new AssertionError("No instances."); + } + + /** + * Starts the PKI process. + * + *+ * Security note: command-line arguments are not logged because they can contain + * sensitive material (paths, tokens, passphrases). + *
+ * + * @param args command-line arguments (never logged) + */ + public static void main(String[] args) { + Objects.requireNonNull(args, "args"); + + PkiLogging.configureIfPresent(); + PkiLogging.installUncaughtExceptionHandler(); + + LOG.info("ZeroEcho PKI starting."); + + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + Logger shutdownLogger = Logger.getLogger(PkiApplication.class.getName()); + PkiLogging.emitShutdownMessage(shutdownLogger, "ZeroEcho PKI stopping."); + }, "zeroecho-pki-shutdown")); + + try { + // Intentionally no business logic yet. Bootstrap only. + LOG.info("ZeroEcho PKI started (bootstrap only)."); + } catch (RuntimeException ex) { + // Do not include user-provided inputs in the message; log the exception object. + LOG.log(Level.SEVERE, "Fatal error during PKI bootstrap.", ex); + throw ex; + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/PkiLogging.java b/pki/src/main/java/zeroecho/pki/PkiLogging.java new file mode 100644 index 0000000..0e8b58a --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/PkiLogging.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.Thread.UncaughtExceptionHandler; +import java.util.Objects; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.Logger; + +/** + * Internal bootstrap utilities for JUL configuration in the {@code pki} module. + * + *+ * This helper intentionally avoids logging any potentially sensitive material. + * In particular, it never logs: + *
+ *+ * Configuration strategy: + *
+ *+ * This method is idempotent and safe to call multiple times. + *
+ */ + static void configureIfPresent() { + if (configured) { + return; + } + synchronized (PkiLogging.class) { + if (configured) { + return; + } + + InputStream in = PkiLogging.class.getResourceAsStream(LOGGING_PROPERTIES_RESOURCE); + if (in == null) { + configured = true; + return; + } + + try (InputStream is = in) { + LogManager.getLogManager().readConfiguration(is); + configured = true; + LOG.info("JUL configured from classpath resource."); + } catch (IOException ex) { + configured = true; + // Keep message generic; do not leak environment specifics. + LOG.log(Level.WARNING, "Failed to load JUL configuration; continuing with defaults.", ex); + } + } + } + + /** + * Installs a process-wide uncaught exception handler that logs failures via + * JUL. + * + *+ * The handler emits a generic message and includes the throwable. It + * deliberately does not serialize additional contextual data that might contain + * secrets. + *
+ */ + static void installUncaughtExceptionHandler() { + UncaughtExceptionHandler handler = (Thread thread, Throwable throwable) -> { + Objects.requireNonNull(thread, "thread"); + Objects.requireNonNull(throwable, "throwable"); + Logger logger = Logger.getLogger(PkiApplication.class.getName()); + logger.log(Level.SEVERE, "Uncaught exception in thread: " + thread.getName(), throwable); + }; + + Thread.setDefaultUncaughtExceptionHandler(handler); + } + + /** + * Emits a shutdown message in a way that remains visible even during late JVM + * teardown. + * + *+ * The primary path is JUL. As a fallback, a constant message is written to + * {@code System.err}. This avoids logging any secrets and improves reliability + * in environments where JUL output may be lost during shutdown. + *
+ * + * @param logger logger to use for the primary JUL emission + * @param message message to emit; must not contain secrets + * @throws NullPointerException if {@code logger} or {@code message} is + * {@code null} + */ + static void emitShutdownMessage(Logger logger, String message) { + Objects.requireNonNull(logger, "logger"); + Objects.requireNonNull(message, "message"); + + // Primary path: JUL + logger.info(message); + + // Flush root handlers (covers parent-handler delegation). + Logger root = Logger.getLogger(""); + for (java.util.logging.Handler handler : root.getHandlers()) { + try { + handler.flush(); + } catch (RuntimeException ignored) { + // Never throw during shutdown + } + } + + // Fallback: direct stderr write + try { + System.err.println(message); + System.err.flush(); + } catch (RuntimeException ignored) { + // Never throw during shutdown + } + } + +} \ No newline at end of file diff --git a/pki/src/main/java/zeroecho/pki/api/BackupService.java b/pki/src/main/java/zeroecho/pki/api/BackupService.java new file mode 100644 index 0000000..07cbe75 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/BackupService.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api; + +import zeroecho.pki.api.backup.BackupArtifact; +import zeroecho.pki.api.backup.BackupRequest; +import zeroecho.pki.api.backup.BackupVerificationReport; +import zeroecho.pki.api.backup.RestoreReport; +import zeroecho.pki.api.backup.RestoreRequest; + +/** + * Backup/restore operations for PKI state. + * + *+ * Backups must not implicitly include private keys. Private keys are referenced + * via {@link KeyRef} and may be managed by separate components. + *
+ */ +public interface BackupService { + + /** + * Creates a backup of PKI state. + * + * @param request backup request + * @return backup artifact + * @throws IllegalArgumentException if {@code request} is invalid + * @throws PkiException if backup creation fails + */ + BackupArtifact createBackup(BackupRequest request); + + /** + * Restores PKI state from a backup artifact. + * + * @param request restore request + * @return restore report + * @throws IllegalArgumentException if {@code request} is invalid + * @throws PkiException if restore fails + */ + RestoreReport restoreBackup(RestoreRequest request); + + /** + * Verifies a backup artifact for structural validity and integrity. + * + * @param artifact backup artifact + * @return verification report + * @throws IllegalArgumentException if {@code artifact} is null + * @throws PkiException if verification fails due to IO/backend + * errors + */ + BackupVerificationReport verifyBackup(BackupArtifact artifact); +} diff --git a/pki/src/main/java/zeroecho/pki/api/CaService.java b/pki/src/main/java/zeroecho/pki/api/CaService.java new file mode 100644 index 0000000..70dd46f --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/CaService.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api; + +import java.util.List; + +import zeroecho.pki.api.ca.CaCreateCommand; +import zeroecho.pki.api.ca.CaImportCommand; +import zeroecho.pki.api.ca.CaKeyRotationCommand; +import zeroecho.pki.api.ca.CaQuery; +import zeroecho.pki.api.ca.CaRecord; +import zeroecho.pki.api.ca.CaRolloverCommand; +import zeroecho.pki.api.ca.CaState; +import zeroecho.pki.api.ca.IntermediateCertIssueCommand; +import zeroecho.pki.api.ca.IntermediateCreateCommand; +import zeroecho.pki.api.credential.Credential; + +/** + * Manages Certificate Authority (CA) entities and their lifecycle. + * + *+ * A CA entity represents an administrative unit capable of issuing credentials. + * A CA entity may own multiple CA credentials over time to support + * cross-signing, rollover, and key rotation. + *
+ * + *+ * Private key material is never handled directly by the PKI module; the CA key + * is referenced by {@link KeyRef} and resolved by runtime wiring. + *
+ */ +public interface CaService { + + /** + * Creates a new root CA entity and issues its initial CA credential. + * + * @param command create command defining subject/profile and optional key + * reference + * @return created CA identifier + * @throws IllegalArgumentException if {@code command} is invalid + * @throws PkiException if creation fails due to policy, storage, or + * framework backend error + */ + PkiId createRoot(CaCreateCommand command); + + /** + * Imports an existing root CA into the PKI inventory. + * + *+ * This registers a CA entity, associates it with a {@link KeyRef}, and persists + * the existing CA credential. Import does not automatically imply trust; trust + * anchor selection is a consumer decision. + *
+ * + * @param command import command including CA credential payload and key + * reference + * @return imported CA identifier + * @throws IllegalArgumentException if {@code command} is invalid + * @throws PkiException if import fails (e.g., inconsistent + * metadata, storage failure) + */ + PkiId importRoot(CaImportCommand command); + + /** + * Creates a new intermediate CA entity and issues its initial intermediate CA + * credential. + * + * @param command intermediate creation command + * @return created intermediate CA identifier + * @throws IllegalArgumentException if {@code command} is invalid + * @throws PkiException if creation fails + */ + PkiId createIntermediate(IntermediateCreateCommand command); + + /** + * Issues a new CA credential for an existing intermediate CA entity. + * + *+ * This operation enables cross-signing and renewal scenarios. + *
+ * + * @param command issuance command specifying issuer and subject CA entity + * @return newly issued CA credential + * @throws IllegalArgumentException if {@code command} is invalid + * @throws PkiException if issuance fails due to policy or backend + * errors + */ + Credential issueIntermediateCertificate(IntermediateCertIssueCommand command); + + /** + * Performs a CA credential rollover while keeping the same key reference. + * + * @param command rollover command + * @return CA identifier (same CA id expected; returned for convenience) + * @throws IllegalArgumentException if {@code command} is invalid + * @throws PkiException if rollover fails + */ + PkiId rolloverCaCertificate(CaRolloverCommand command); + + /** + * Rotates the CA key reference and issues new corresponding CA credentials. + * + * @param command key rotation command + * @return CA identifier (same CA id expected; returned for convenience) + * @throws IllegalArgumentException if {@code command} is invalid + * @throws PkiException if rotation fails + */ + PkiId rotateCaKey(CaKeyRotationCommand command); + + /** + * Updates CA operational state. + * + * @param caId CA identifier + * @param state new CA state + * @param reason non-empty operator-readable reason suitable for audit + * @throws IllegalArgumentException if inputs are invalid + * @throws PkiException if CA does not exist or update fails + */ + void setCaState(PkiId caId, CaState state, String reason); + + /** + * Retrieves a CA record. + * + * @param caId CA identifier + * @return CA record + * @throws IllegalArgumentException if {@code caId} is invalid + * @throws PkiException if CA does not exist + */ + CaRecord getCa(PkiId caId); + + /** + * Lists CA records matching query constraints. + * + * @param query query constraints + * @return list of CA records + * @throws IllegalArgumentException if {@code query} is invalid + * @throws PkiException if listing fails + */ + List+ * This service provides request fingerprinting, parsing, proof-of-possession + * verification, and optional persistence for correlation and auditing. Request + * transport protocols such as ACME are expected to use this service as the core + * processing layer. + *
+ */ +public interface CertificationRequestService { + + /** + * Computes a stable identifier (fingerprint) for the given request payload. + * + * @param request certification request + * @return stable request identifier + * @throws IllegalArgumentException if {@code request} is null + * @throws PkiException if fingerprinting fails + */ + PkiId fingerprint(CertificationRequest request); + + /** + * Parses and normalizes a certification request. + * + * @param request certification request + * @return parsed request + * @throws IllegalArgumentException if {@code request} is null + * @throws PkiException if parsing fails (invalid request, + * unsupported format, backend failure) + */ + ParsedCertificationRequest parse(CertificationRequest request); + + /** + * Verifies proof-of-possession (PoP) for the private key corresponding to the + * requested public key. + * + * @param parsed parsed request + * @param policy verification policy + * @return PoP verification result + * @throws IllegalArgumentException if inputs are null + * @throws PkiException if verification fails due to backend failure + */ + ProofOfPossessionResult verifyProofOfPossession(ParsedCertificationRequest parsed, VerificationPolicy policy); + + /** + * Stores a parsed request for later correlation and audit. + * + * @param parsed parsed request + * @param policy storage policy + * @return stored request id + * @throws IllegalArgumentException if inputs are null + * @throws PkiException if persistence fails + */ + PkiId store(ParsedCertificationRequest parsed, RequestStorePolicy policy); + + /** + * Retrieves a stored request. + * + * @param requestId request id + * @return parsed request if present + * @throws IllegalArgumentException if {@code requestId} is null + * @throws PkiException if retrieval fails + */ + Optional+ * This type intentionally carries only the {@link Encoding} and raw bytes. It + * does not carry a media type, because DER/PEM/BINARY do not uniquely determine + * the semantic meaning (a DER payload may represent a certificate, CSR, CRL, + * etc.). The semantic meaning is carried by the surrounding API context. + *
+ * + *+ * Security note: implementations must never log the raw bytes in full. + *
+ * + * @param encoding encoding kind + * @param bytes non-empty payload bytes + */ +public record EncodedObject(Encoding encoding, byte[] bytes) { + + /** + * Creates an encoded object. + * + * @param encoding encoding kind + * @param bytes non-empty payload bytes + * @throws IllegalArgumentException if {@code encoding} is null or {@code bytes} + * is null/empty + */ + public EncodedObject { + if (encoding == null) { + throw new IllegalArgumentException("encoding must not be null"); + } + if (bytes == null || bytes.length == 0) { + throw new IllegalArgumentException("bytes must not be null/empty"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/Encoding.java b/pki/src/main/java/zeroecho/pki/api/Encoding.java new file mode 100644 index 0000000..7c4203d --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/Encoding.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api; + +/** + * Specifies the encoding of a binary artifact payload. + * + *+ * The encoding indicates how the {@code bytes} inside {@link EncodedObject} + * should be interpreted. The logical meaning of the payload (certificate vs CSR + * vs CRL vs backup) is defined by the surrounding API context and record types. + *
+ */ +public enum Encoding { + + /** + * ASN.1 Distinguished Encoding Rules (DER). + * + *+ * Common for X.509 certificates, CRLs, and PKCS#10 certification requests. + *
+ */ + DER, + + /** + * PEM armored textual representation. + * + *+ * Typically base64-wrapped DER with header/footer lines. + *
+ */ + PEM, + + /** + * Raw binary blob without implying ASN.1 DER or PEM semantics. + * + *+ * Use for non-ASN.1 frameworks (e.g., COSE/JWS) or container payloads (e.g., + * backup archives). + *
+ */ + BINARY +} diff --git a/pki/src/main/java/zeroecho/pki/api/FormatId.java b/pki/src/main/java/zeroecho/pki/api/FormatId.java new file mode 100644 index 0000000..ce17abb --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/FormatId.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api; + +/** + * Identifier of a credential framework/format handled by the PKI core. + * + *+ * Examples: {@code "x509"}, {@code "ssh"}, {@code "cose"}, {@code "jws"}. + *
+ * + *+ * This identifier is used to dispatch operations to a framework backend + * implementation. + *
+ * + * @param value non-empty format identifier string + */ +public record FormatId(String value) { + + /** + * Creates a format identifier. + * + * @param value non-empty format identifier string + * @throws IllegalArgumentException if {@code value} is null or blank + */ + public FormatId { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException("value must not be null/blank"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/ImportExportService.java b/pki/src/main/java/zeroecho/pki/api/ImportExportService.java new file mode 100644 index 0000000..f7f1479 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/ImportExportService.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api; + +import zeroecho.pki.api.revocation.RevokedRecord; +import zeroecho.pki.api.transfer.ExportArtifact; +import zeroecho.pki.api.transfer.ExportFormat; +import zeroecho.pki.api.transfer.ExportQuery; +import zeroecho.pki.api.transfer.ImportPolicy; + +/** + * Import and export operations for migration and interoperability. + * + *+ * Import does not imply trust; it is a controlled operation governed by policy. + * Import/export is expected to be auditable. + *
+ */ +public interface ImportExportService { + + /** + * Imports an issued credential payload into inventory. + * + * @param formatId credential format id + * @param credential encoded credential payload + * @param policy import policy + * @return imported credential id + * @throws IllegalArgumentException if inputs are invalid + * @throws PkiException if import fails + */ + PkiId importCredential(FormatId formatId, EncodedObject credential, ImportPolicy policy); + + /** + * Imports a CA certificate payload into an existing CA entity's credential set. + * + * @param caId CA entity id + * @param caCertificate CA certificate payload + * @param policy import policy + * @return imported credential id + * @throws IllegalArgumentException if inputs are invalid + * @throws PkiException if import fails + */ + PkiId importCaCertificate(PkiId caId, EncodedObject caCertificate, ImportPolicy policy); + + /** + * Imports a revocation record. + * + * @param record revocation record + * @param policy import policy + * @return imported revocation record id (implementation-defined) + * @throws IllegalArgumentException if inputs are invalid + * @throws PkiException if import fails + */ + PkiId importRevocation(RevokedRecord record, ImportPolicy policy); + + /** + * Exports credentials matching the query constraints in the requested export + * format. + * + * @param query export query + * @param format export format + * @return export artifact + * @throws IllegalArgumentException if inputs are invalid + * @throws PkiException if export fails + */ + ExportArtifact exportCredentials(ExportQuery query, ExportFormat format); + + /** + * Exports revocation records matching the query constraints in the requested + * export format. + * + * @param query export query + * @param format export format + * @return export artifact + * @throws IllegalArgumentException if inputs are invalid + * @throws PkiException if export fails + */ + ExportArtifact exportRevocations(ExportQuery query, ExportFormat format); + + /** + * Exports CA materials for a given CA entity in the requested export format. + * + * @param caId CA entity id + * @param format export format + * @return export artifact + * @throws IllegalArgumentException if inputs are invalid + * @throws PkiException if export fails + */ + ExportArtifact exportCa(PkiId caId, ExportFormat format); +} diff --git a/pki/src/main/java/zeroecho/pki/api/IssuanceService.java b/pki/src/main/java/zeroecho/pki/api/IssuanceService.java new file mode 100644 index 0000000..f54d5bf --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/IssuanceService.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api; + +import zeroecho.pki.api.credential.CredentialBundle; +import zeroecho.pki.api.issuance.BundleCommand; +import zeroecho.pki.api.issuance.IssueEndEntityCommand; +import zeroecho.pki.api.issuance.ReissueCommand; +import zeroecho.pki.api.issuance.RenewCommand; +import zeroecho.pki.api.issuance.ReplaceCommand; + +/** + * Issues, renews, replaces, and reissues credentials, and builds distributable + * bundles. + * + *+ * This service is framework-agnostic: concrete credential formats are + * implemented by framework backends. The PKI runtime applies policy and profile + * constraints before calling issuance backends. + *
+ */ +public interface IssuanceService { + + /** + * Issues a new end-entity credential. + * + * @param command issuance command + * @return credential bundle (credential plus supporting artifacts) + * @throws IllegalArgumentException if {@code command} is invalid + * @throws PkiException if issuance fails + */ + CredentialBundle issueEndEntity(IssueEndEntityCommand command); + + /** + * Renews an existing credential according to policy-defined continuity + * semantics. + * + * @param command renewal command + * @return renewed credential bundle + * @throws IllegalArgumentException if {@code command} is invalid + * @throws PkiException if renewal fails + */ + CredentialBundle renew(RenewCommand command); + + /** + * Replaces an existing credential (e.g., after compromise or attribute + * changes). + * + * @param command replacement command + * @return replacement credential bundle + * @throws IllegalArgumentException if {@code command} is invalid + * @throws PkiException if replacement fails + */ + CredentialBundle replace(ReplaceCommand command); + + /** + * Reissues based on a stored issuance record. + * + * @param command reissue command + * @return reissued credential bundle + * @throws IllegalArgumentException if {@code command} is invalid + * @throws PkiException if reissue fails + */ + CredentialBundle reissue(ReissueCommand command); + + /** + * Builds a distributable bundle for an existing credential using chain + * selection rules. + * + * @param command bundle command + * @return bundle + * @throws IllegalArgumentException if {@code command} is invalid + * @throws PkiException if bundle building fails + */ + CredentialBundle buildBundle(BundleCommand command); +} diff --git a/pki/src/main/java/zeroecho/pki/api/IssuerRef.java b/pki/src/main/java/zeroecho/pki/api/IssuerRef.java new file mode 100644 index 0000000..d959334 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/IssuerRef.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api; + +/** + * References an issuing CA entity. + * + * @param caId identifier of the CA entity acting as issuer + */ +public record IssuerRef(PkiId caId) { + + /** + * Creates an issuer reference. + * + * @param caId CA identifier + * @throws IllegalArgumentException if {@code caId} is null + */ + public IssuerRef { + if (caId == null) { + throw new IllegalArgumentException("caId must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/KeyRef.java b/pki/src/main/java/zeroecho/pki/api/KeyRef.java new file mode 100644 index 0000000..4a47ab3 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/KeyRef.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api; + +/** + * Opaque reference to private key material. + * + *+ * The PKI module never handles private key bytes. A {@link KeyRef} is resolved + * by runtime wiring, e.g., by a crypto component, an HSM adapter, or a remote + * signer. Implementations must treat this reference as sensitive metadata and + * avoid logging it unnecessarily. + *
+ * + * @param value non-empty key reference token + */ +public record KeyRef(String value) { + + /** + * Creates a key reference. + * + * @param value non-empty key reference token + * @throws IllegalArgumentException if {@code value} is null or blank + */ + public KeyRef { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException("value must not be null/blank"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/PkiException.java b/pki/src/main/java/zeroecho/pki/api/PkiException.java new file mode 100644 index 0000000..adb3723 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/PkiException.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api; + +/** + * Base runtime exception for PKI domain failures. + * + *+ * This exception is used to report policy violations, storage failures, + * framework backend errors, and other domain-level problems not representable + * as {@link IllegalArgumentException}. + *
+ * + *+ * Security note: exception messages must not contain secrets (private keys, + * plaintext, shared secrets, or other sensitive cryptographic material). + *
+ */ +public class PkiException extends RuntimeException { + + private static final long serialVersionUID = 759504279718537161L; + + /** + * Creates a PKI exception with a message. + * + * @param message non-empty message describing the failure in a non-sensitive + * manner + */ + public PkiException(String message) { + super(requireNonBlank(message, "message")); + } + + /** + * Creates a PKI exception with a message and cause. + * + * @param message non-empty message describing the failure in a non-sensitive + * manner + * @param cause underlying cause + */ + public PkiException(String message, Throwable cause) { + super(requireNonBlank(message, "message"), cause); + } + + private static String requireNonBlank(String value, String name) { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException(name + " must not be null/blank"); + } + return value; + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/PkiId.java b/pki/src/main/java/zeroecho/pki/api/PkiId.java new file mode 100644 index 0000000..eaaf42b --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/PkiId.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api; + +/** + * Opaque identifier for PKI-managed entities. + * + *+ * Instances of this type are used as stable references for CA entities, + * credentials, certification requests, status objects, backups, publications, + * exports, and policy/audit records. + *
+ * + *+ * The value must be treated as an opaque token and persisted verbatim. + *
+ * + * @param value non-empty identifier string + */ +public record PkiId(String value) { + + /** + * Creates an opaque PKI identifier. + * + * @param value non-empty identifier string + * @throws IllegalArgumentException if {@code value} is null or blank + */ + public PkiId { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException("value must not be null/blank"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/PolicyService.java b/pki/src/main/java/zeroecho/pki/api/PolicyService.java new file mode 100644 index 0000000..df34697 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/PolicyService.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api; + +import zeroecho.pki.api.issuance.IssuanceInputs; +import zeroecho.pki.api.policy.PolicyDecision; +import zeroecho.pki.api.policy.PolicyTrace; +import zeroecho.pki.api.revocation.RevocationInputs; + +/** + * Policy evaluation and explainability. + * + *+ * Policy decisions must be deterministic, auditable, and explainable. + * Implementations are expected to provide traces suitable for operator + * troubleshooting and compliance evidence. + *
+ */ +public interface PolicyService { + + /** + * Evaluates an issuance request against policy and profile constraints. + * + * @param inputs normalized issuance inputs + * @return policy decision + * @throws IllegalArgumentException if {@code inputs} is null + * @throws PkiException if evaluation fails + */ + PolicyDecision evaluateIssuance(IssuanceInputs inputs); + + /** + * Evaluates a revocation request against policy constraints. + * + * @param inputs normalized revocation inputs + * @return policy decision + * @throws IllegalArgumentException if {@code inputs} is null + * @throws PkiException if evaluation fails + */ + PolicyDecision evaluateRevocation(RevocationInputs inputs); + + /** + * Retrieves a trace explaining a previous decision. + * + * @param decisionId decision id + * @return decision trace + * @throws IllegalArgumentException if {@code decisionId} is null + * @throws PkiException if trace retrieval fails + */ + PolicyTrace explain(PkiId decisionId); +} diff --git a/pki/src/main/java/zeroecho/pki/api/ProfileService.java b/pki/src/main/java/zeroecho/pki/api/ProfileService.java new file mode 100644 index 0000000..eb5a02e --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/ProfileService.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api; + +import java.util.List; + +import zeroecho.pki.api.profile.CertificateProfile; +import zeroecho.pki.api.profile.ProfileQuery; + +/** + * Profile registry for credential issuance. + * + *+ * Profiles define required/optional attributes, validity limits, and other + * constraints used by policy and framework mapping. Profiles are referenced by + * id during issuance. + *
+ */ +public interface ProfileService { + + /** + * Registers or updates a profile. + * + * @param profile profile definition + * @throws IllegalArgumentException if {@code profile} is null + * @throws PkiException if registration fails + */ + void register(CertificateProfile profile); + + /** + * Retrieves a profile by id. + * + * @param profileId profile id + * @return profile + * @throws IllegalArgumentException if {@code profileId} is null/blank + * @throws PkiException if not found or retrieval fails + */ + CertificateProfile get(String profileId); + + /** + * Lists profiles matching query constraints. + * + * @param query query constraints + * @return list of profiles + * @throws IllegalArgumentException if {@code query} is null + * @throws PkiException if listing fails + */ + List+ * Publishing is an explicit operation enabling parity with established PKI + * systems. Implementations may publish credentials, CA materials, and status + * objects to configured targets such as filesystem mirrors, LDAP directories, + * HTTP endpoints, or object stores. + *
+ */ +public interface PublicationService { + + /** + * Publishes an issued credential to the specified target. + * + * @param credentialId credential id + * @param target publication target + * @return publication result + * @throws IllegalArgumentException if inputs are invalid + * @throws PkiException if publication fails + */ + PublicationResult publishCredential(PkiId credentialId, PublicationTarget target); + + /** + * Publishes CA materials (e.g., CA certificate sets) for the given CA entity to + * the specified target. + * + * @param caId CA entity id + * @param target publication target + * @return publication result + * @throws IllegalArgumentException if inputs are invalid + * @throws PkiException if publication fails + */ + PublicationResult publishCaMaterials(PkiId caId, PublicationTarget target); + + /** + * Publishes a status object to the specified target. + * + * @param statusObjectId status object id + * @param target publication target + * @return publication result + * @throws IllegalArgumentException if inputs are invalid + * @throws PkiException if publication fails + */ + PublicationResult publishStatusObject(PkiId statusObjectId, PublicationTarget target); + + /** + * Lists publication records matching query constraints. + * + * @param query publication query + * @return publication records + * @throws IllegalArgumentException if {@code query} is invalid + * @throws PkiException if listing fails + */ + List+ * Status objects include CRLs, delta CRLs, OCSP responses, or + * framework-specific revocation lists. + *
+ */ +public interface StatusObjectService { + + /** + * Generates a new status object for an issuer CA. + * + * @param command generation command + * @return generated status object + * @throws IllegalArgumentException if {@code command} is invalid + * @throws PkiException if generation fails + */ + StatusObject generate(StatusObjectGenerateCommand command); + + /** + * Retrieves the latest status object of a given type for an issuer CA. + * + * @param issuerCaId issuer CA id + * @param type status object type + * @return latest status object if present + * @throws IllegalArgumentException if inputs are invalid + * @throws PkiException if retrieval fails + */ + Optional+ * This identifier is used for policy evaluation, inventory queries, and audit + * correlation. Framework backends may map it to a distinguished name (DN), a + * claims subject, or a service identity, depending on the credential framework. + *
+ * + * @param value non-empty subject reference + */ +public record SubjectRef(String value) { + + /** + * Creates a subject reference. + * + * @param value non-empty subject reference + * @throws IllegalArgumentException if {@code value} is null or blank + */ + public SubjectRef { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException("value must not be null/blank"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/Validity.java b/pki/src/main/java/zeroecho/pki/api/Validity.java new file mode 100644 index 0000000..24b9569 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/Validity.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api; + +import java.time.Instant; + +/** + * Validity interval for an issued credential. + * + *+ * The PKI core requires {@code notAfter} to be strictly after + * {@code notBefore}. Framework-specific interpretations (inclusive/exclusive) + * are resolved by the framework backend. + *
+ * + *+ * Policy and profile constraints (maximum lifetime, not-before skew) must be + * enforced by the PKI runtime. + *
+ * + * @param notBefore start of validity interval (inclusive) + * @param notAfter end of validity interval (must be after {@code notBefore}) + */ +public record Validity(Instant notBefore, Instant notAfter) { + + /** + * Creates a validity interval. + * + * @param notBefore start of validity interval (inclusive) + * @param notAfter end of validity interval + * @throws IllegalArgumentException if inputs are null or the interval is + * invalid + */ + public Validity { + if (notBefore == null || notAfter == null) { + throw new IllegalArgumentException("notBefore/notAfter must not be null"); + } + if (!notAfter.isAfter(notBefore)) { + throw new IllegalArgumentException("notAfter must be after notBefore"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/attr/AttributeAccessPolicy.java b/pki/src/main/java/zeroecho/pki/api/attr/AttributeAccessPolicy.java new file mode 100644 index 0000000..b88cd76 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/attr/AttributeAccessPolicy.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.attr; + +import java.util.Set; + +/** + * Governance hints controlling auditing and exportability of an attribute. + * + *+ * This model is intentionally minimal. Implementations may interpret it via a + * richer policy decision point (roles, purposes, tenants), but the presence of + * these hints allows consistent enforcement and auditing. + *
+ * + * @param auditOnAllow if true, successful accesses should be audited + * @param auditOnDeny if true, denied accesses should be audited + * @param exportTargets allowed export targets + */ +public record AttributeAccessPolicy(boolean auditOnAllow, boolean auditOnDeny, + Set+ * The catalogue is the shared vocabulary across credential frameworks. + * Identifiers must never be reused with a different meaning. Definitions should + * be versioned under a controlled process. + *
+ */ +public interface AttributeCatalogue { + + /** + * Finds a definition by id. + * + * @param id attribute id + * @return definition if present + * @throws IllegalArgumentException if {@code id} is null + */ + Optional+ * The definition includes a stable identifier, type information, documentation + * metadata, and governance hints. Frameworks map universal attributes into + * framework-specific fields and extensions. + *
+ * + * @param id stable attribute identifier + * @param displayName human-readable name + * @param valueType logical value type + * @param multiValued whether multiple values are allowed + * @param sensitivity sensitivity classification + * @param stability lifecycle maturity + * @param accessPolicy governance hints + * @param meta structured documentation metadata + */ +public record AttributeDefinition(AttributeId id, String displayName, AttributeValueType valueType, boolean multiValued, + AttributeSensitivity sensitivity, AttributeStability stability, AttributeAccessPolicy accessPolicy, + AttributeMeta meta) { + + /** + * Creates an attribute definition. + * + * @throws IllegalArgumentException if inputs are invalid + */ + public AttributeDefinition { + if (id == null) { + throw new IllegalArgumentException("id must not be null"); + } + if (displayName == null || displayName.isBlank()) { + throw new IllegalArgumentException("displayName must not be null/blank"); + } + if (valueType == null || sensitivity == null || stability == null || accessPolicy == null || meta == null) { + throw new IllegalArgumentException("non-null fields must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/attr/AttributeExportTarget.java b/pki/src/main/java/zeroecho/pki/api/attr/AttributeExportTarget.java new file mode 100644 index 0000000..b9a8d8d --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/attr/AttributeExportTarget.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.attr; + +/** + * Named export targets used by governance and publication pipelines. + */ +public enum AttributeExportTarget { + + /** + * Export via a programmatic API. + */ + API, + + /** + * Export for UI rendering. + */ + UI, + + /** + * Export to LDAP directory. + */ + LDAP, + + /** + * Export to backups. + */ + BACKUP, + + /** + * Export to diagnostics/debugging channels (typically heavily redacted). + */ + DIAGNOSTICS +} diff --git a/pki/src/main/java/zeroecho/pki/api/attr/AttributeId.java b/pki/src/main/java/zeroecho/pki/api/attr/AttributeId.java new file mode 100644 index 0000000..3d8e8fd --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/attr/AttributeId.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.attr; + +/** + * Stable attribute identifier used by the attribute catalogue. + * + *+ * Identifiers should be globally stable (recommended as OIDs under a project or + * enterprise arc). Identifiers must never be reused with a different semantic + * meaning. + *
+ * + * @param value non-empty identifier string + */ +public record AttributeId(String value) { + + /** + * Creates an attribute identifier. + * + * @param value non-empty identifier string + * @throws IllegalArgumentException if {@code value} is null or blank + */ + public AttributeId { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException("value must not be null/blank"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/attr/AttributeMeta.java b/pki/src/main/java/zeroecho/pki/api/attr/AttributeMeta.java new file mode 100644 index 0000000..6856602 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/attr/AttributeMeta.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.attr; + +import java.util.List; +import java.util.Map; + +/** + * Structured, human-facing documentation metadata for an attribute definition. + * + *+ * This metadata is intended to be rendered in operator tooling, APIs, and UI. + * It must not contain secrets. + *
+ * + * @param description normative description of meaning and usage + * @param notes additional guidance and security considerations + * @param examples example values (must not contain secrets) + * @param tags classification tags (e.g., "identity", "x509", "san") + * @param extra additional annotations for future extensions + * (non-sensitive) + */ +public record AttributeMeta(String description, List+ * Sensitivity influences default auditing/export/redaction behavior. + * Implementations must ensure that SECRET and SENSITIVE values are not exposed + * to logs or unauthorized channels. + *
+ */ +public enum AttributeSensitivity { + + /** + * Public value; can be disclosed broadly. + */ + PUBLIC, + + /** + * Internal operational value; restricted to internal components and operators. + */ + INTERNAL, + + /** + * Sensitive value; disclosure may create security or privacy risk. + */ + SENSITIVE, + + /** + * Secret value; must not be disclosed outside the strictest trust boundary. + */ + SECRET +} diff --git a/pki/src/main/java/zeroecho/pki/api/attr/AttributeSet.java b/pki/src/main/java/zeroecho/pki/api/attr/AttributeSet.java new file mode 100644 index 0000000..1a451ea --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/attr/AttributeSet.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.attr; + +import java.util.List; +import java.util.Optional; +import java.util.Set; + +/** + * Immutable set of typed attributes. + * + *+ * This is a passive container. Production code is expected to mediate + * read/write/export/derive operations through a governance/enforcement layer + * that performs ACL checks and emits audit events. + *
+ */ +public interface AttributeSet { + + /** + * Returns all attribute identifiers present in this set. + * + * @return set of attribute ids + */ + Set+ * If the attribute is multi-valued, implementations may return empty or one + * chosen value; callers should prefer {@link #getAll(AttributeId)} when + * multi-valued is expected. + *
+ * + * @param id attribute id + * @return attribute value if present + * @throws IllegalArgumentException if {@code id} is null + */ + Optional+ * Values are modeled as a sealed hierarchy for type safety and deterministic + * mapping. Implementations must treat values as potentially sensitive and apply + * redaction where required. + *
+ */ +public sealed interface AttributeValue permits AttributeValue.StringValue, AttributeValue.BooleanValue, + AttributeValue.IntegerValue, AttributeValue.InstantValue, AttributeValue.BytesValue { + + /** + * String value. + * + * @param value string content (may be empty depending on attribute definition) + */ + record StringValue(String value) implements AttributeValue { + + /** + * Creates a string value. + * + * @param value string content + * @throws IllegalArgumentException if {@code value} is null + */ + public StringValue { + if (value == null) { + throw new IllegalArgumentException("value must not be null"); + } + } + } + + /** + * Boolean value. + * + * @param value boolean content + */ + record BooleanValue(boolean value) implements AttributeValue { + } + + /** + * Integer/long value. + * + * @param value numeric content + */ + record IntegerValue(long value) implements AttributeValue { + } + + /** + * Instant value. + * + * @param value timestamp content + */ + record InstantValue(Instant value) implements AttributeValue { + + /** + * Creates an instant value. + * + * @param value timestamp + * @throws IllegalArgumentException if {@code value} is null + */ + public InstantValue { + if (value == null) { + throw new IllegalArgumentException("value must not be null"); + } + } + } + + /** + * Byte string value. + * + *+ * Byte values should be treated as potentially sensitive. Implementations must + * not log full contents. + *
+ * + * @param value non-empty byte array + */ + record BytesValue(byte[] value) implements AttributeValue { + + /** + * Creates a byte string value. + * + * @param value byte array (non-empty) + * @throws IllegalArgumentException if {@code value} is null or empty + */ + public BytesValue { + if (value == null || value.length == 0) { + throw new IllegalArgumentException("value must not be null/empty"); + } + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/attr/AttributeValueType.java b/pki/src/main/java/zeroecho/pki/api/attr/AttributeValueType.java new file mode 100644 index 0000000..4607bb6 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/attr/AttributeValueType.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.attr; + +/** + * Declares the logical value type of an attribute. + * + *+ * Framework backends map these logical types into framework-specific constructs + * (e.g., X.509 extensions, claims, or other credential fields). + *
+ */ +public enum AttributeValueType { + + /** + * UTF-8 string value. + */ + STRING, + + /** + * Boolean value. + */ + BOOLEAN, + + /** + * Integer/long value. + */ + INTEGER, + + /** + * Timestamp value. + */ + INSTANT, + + /** + * Raw byte string. + */ + BYTES, + + /** + * Object identifier string. + */ + OID, + + /** + * Distinguished Name representation (string form with normalization rules + * defined by profile/policy). + */ + DN, + + /** + * GeneralName-like identity (DNS/IP/URI/email/etc.) represented in a canonical + * structured form. + */ + GENERAL_NAME, + + /** + * Public key information representation (e.g., SPKI). + */ + KEY_INFO, + + /** + * Structured composite value. + */ + STRUCT +} diff --git a/pki/src/main/java/zeroecho/pki/api/attr/package-info.java b/pki/src/main/java/zeroecho/pki/api/attr/package-info.java new file mode 100644 index 0000000..7e56d51 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/attr/package-info.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +/** + * Attribute catalogue and attribute-level modeling. + * + *+ * This package defines a typed attribute system used across the PKI API and + * independent of any specific credential framework. Attributes are described + * through definitions and metadata and carried in structured containers to + * support safe reuse and deterministic mapping into concrete frameworks (e.g., + * via a framework attribute mapper SPI). + *
+ * + *+ * Access control and governance for attribute access is described in + * {@code zeroecho.pki.api.audit}. + *
+ * + * @since 1.0 + */ +package zeroecho.pki.api.attr; diff --git a/pki/src/main/java/zeroecho/pki/api/audit/AccessAction.java b/pki/src/main/java/zeroecho/pki/api/audit/AccessAction.java new file mode 100644 index 0000000..700e1e6 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/audit/AccessAction.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.audit; + +/** + * Action performed on an attribute for access governance. + */ +public enum AccessAction { + + /** + * Read an attribute value. + */ + READ, + + /** + * Write or modify an attribute value. + */ + WRITE, + + /** + * Export attribute value to an external channel (e.g., UI, LDAP, backups). + */ + EXPORT, + + /** + * Derive/computed attribute value from other sources. + */ + DERIVE +} diff --git a/pki/src/main/java/zeroecho/pki/api/audit/AccessContext.java b/pki/src/main/java/zeroecho/pki/api/audit/AccessContext.java new file mode 100644 index 0000000..eed766e --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/audit/AccessContext.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.audit; + +import java.util.Optional; + +import zeroecho.pki.api.FormatId; +import zeroecho.pki.api.PkiId; + +/** + * Context used for attribute ACL checks and audit correlation. + * + * @param principal actor requesting access + * @param purpose declared purpose of access + * @param objectId optional object id being accessed (credential id, request + * id, etc.) + * @param formatId optional format id relevant to the object being accessed + */ +public record AccessContext(Principal principal, Purpose purpose, Optional+ * This interface decides whether an attribute action is permitted given the + * attribute definition and the access context. A separate enforcement layer is + * expected to record audit events. + *
+ */ +@FunctionalInterface +public interface AttributeAccessController { + + /** + * Evaluates an access request. + * + * @param definition attribute definition + * @param action access action + * @param context access context + * @return allow/deny decision + * @throws IllegalArgumentException if inputs are null + */ + AccessDecision decide(AttributeDefinition definition, AccessAction action, AccessContext context); +} diff --git a/pki/src/main/java/zeroecho/pki/api/audit/AttributeGovernanceService.java b/pki/src/main/java/zeroecho/pki/api/audit/AttributeGovernanceService.java new file mode 100644 index 0000000..85d87eb --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/audit/AttributeGovernanceService.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.audit; + +import java.util.Optional; + +import zeroecho.pki.api.attr.AttributeCatalogue; +import zeroecho.pki.api.attr.AttributeId; +import zeroecho.pki.api.attr.AttributeSet; +import zeroecho.pki.api.attr.AttributeValue; + +/** + * Policy enforcement point for attribute access with mandatory auditing. + * + *+ * All attribute read/write/export/derive operations should be performed through + * this service to ensure: (1) consistent ACL evaluation and (2) consistent + * audit event emission. + *
+ */ +public interface AttributeGovernanceService { + + /** + * Reads an attribute value after applying access control. + * + * @param catalogue attribute catalogue used to resolve definitions + * @param set attribute set being accessed + * @param id attribute id + * @param context access context + * @return value if present and access is allowed; empty otherwise + * @throws IllegalArgumentException if inputs are null + */ + Optional+ * Export may imply redaction. The exact redaction rules are + * implementation-defined and should take attribute sensitivity and export + * target into account. + *
+ * + * @param catalogue attribute catalogue used to resolve definitions + * @param set attribute set being exported from + * @param id attribute id + * @param context access context + * @return exported value if present and allowed; empty otherwise + * @throws IllegalArgumentException if inputs are null + */ + Optional+ * Derivation may be used to compute attributes such as fingerprints or + * normalized identity fields. + *
+ * + * @param catalogue attribute catalogue used to resolve definitions + * @param set attribute set being modified + * @param id attribute id + * @param context access context + * @return new attribute set instance containing the derived value + * (implementation-defined) + * @throws IllegalArgumentException if inputs are null + */ + AttributeSet derive(AttributeCatalogue catalogue, AttributeSet set, AttributeId id, AccessContext context); +} diff --git a/pki/src/main/java/zeroecho/pki/api/audit/AuditEvent.java b/pki/src/main/java/zeroecho/pki/api/audit/AuditEvent.java new file mode 100644 index 0000000..1a55561 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/audit/AuditEvent.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.audit; + +import java.time.Instant; +import java.util.Map; +import java.util.Optional; + +import zeroecho.pki.api.FormatId; +import zeroecho.pki.api.PkiId; + +/** + * Auditable event emitted by the PKI core. + * + *+ * Audit events may represent high-level PKI operations (issuance, revocation, + * publication, backup) and attribute access governance outcomes. + * Implementations must ensure no secrets appear in {@code details}. + *
+ * + * @param time event time (server time) + * @param category non-empty category (e.g., "ISSUANCE", "REVOCATION", + * "ATTRIBUTE_ACCESS") + * @param action non-empty action string (e.g., "ISSUE_END_ENTITY", "REVOKE", + * "READ") + * @param principal actor responsible for the event + * @param purpose purpose of the operation/access + * @param objectId optional subject object id (credential id, request id, etc.) + * @param formatId optional format id related to the object + * @param details additional non-sensitive key/value details + */ +public record AuditEvent(Instant time, String category, String action, Principal principal, Purpose purpose, + Optional+ * Implementations must ensure sensitive data is never stored or logged in clear + * text. + *
+ */ +public interface AuditService { + + /** + * Records an audit event. + * + * @param event audit event + * @throws IllegalArgumentException if {@code event} is null + * @throws RuntimeException if recording fails (implementation-defined) + */ + void record(AuditEvent event); + + /** + * Searches audit events by query constraints. + * + * @param query query constraints + * @return matching audit events + * @throws IllegalArgumentException if {@code query} is null + * @throws RuntimeException if search fails + */ + List+ * A principal may represent a human user, service account, subsystem component, + * or a scheduled job. + *
+ * + * @param type principal type (e.g., "USER", "SERVICE", "COMPONENT") + * @param name principal name/identifier + */ +public record Principal(String type, String name) { + + /** + * Creates a principal. + * + * @throws IllegalArgumentException if inputs are null/blank + */ + public Principal { + if (type == null || type.isBlank()) { + throw new IllegalArgumentException("type must not be null/blank"); + } + if (name == null || name.isBlank()) { + throw new IllegalArgumentException("name must not be null/blank"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/audit/Purpose.java b/pki/src/main/java/zeroecho/pki/api/audit/Purpose.java new file mode 100644 index 0000000..776233b --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/audit/Purpose.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.audit; + +/** + * Declares the purpose of an operation/access for governance and auditing. + * + *+ * Examples: {@code ISSUANCE}, {@code VALIDATION}, {@code UI_RENDER}, + * {@code BACKUP_EXPORT}, {@code LDAP_PUBLISH}. + *
+ * + * @param value non-empty purpose string + */ +public record Purpose(String value) { + + /** + * Creates a purpose. + * + * @throws IllegalArgumentException if {@code value} is null/blank + */ + public Purpose { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException("value must not be null/blank"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/audit/package-info.java b/pki/src/main/java/zeroecho/pki/api/audit/package-info.java new file mode 100644 index 0000000..c8f3da7 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/audit/package-info.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +/** + * Audit and governance API. + * + *+ * This package defines audit events, principals, purposes, queries, and + * attribute-access governance abstractions used to support compliance and + * operational forensics. + *
+ * + *+ * The persistence and routing of audit events is an SPI concern (e.g., + * {@code zeroecho.pki.spi.AuditSink}). + *
+ * + * @since 1.0 + */ +package zeroecho.pki.api.audit; diff --git a/pki/src/main/java/zeroecho/pki/api/backup/BackupArtifact.java b/pki/src/main/java/zeroecho/pki/api/backup/BackupArtifact.java new file mode 100644 index 0000000..ba2cf4d --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/backup/BackupArtifact.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.backup; + +import zeroecho.pki.api.BackupService; +import zeroecho.pki.api.EncodedObject; +import zeroecho.pki.api.Encoding; +import zeroecho.pki.api.PkiId; + +/** + * Opaque backup artifact produced by {@link BackupService}. + * + *+ * The payload is typically {@link Encoding#BINARY}. The internal structure is + * implementation-defined (e.g., tar/zip-like). Consumers should treat it as + * opaque. + *
+ * + * @param backupId backup identifier + * @param payload backup payload bytes + */ +public record BackupArtifact(PkiId backupId, EncodedObject payload) { + + /** + * Creates a backup artifact. + * + * @throws IllegalArgumentException if inputs are null + */ + public BackupArtifact { + if (backupId == null) { + throw new IllegalArgumentException("backupId must not be null"); + } + if (payload == null) { + throw new IllegalArgumentException("payload must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/backup/BackupRequest.java b/pki/src/main/java/zeroecho/pki/api/backup/BackupRequest.java new file mode 100644 index 0000000..7700bd8 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/backup/BackupRequest.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.backup; + +import zeroecho.pki.api.KeyRef; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Requests creation of a PKI backup. + * + *+ * Backups are expected to contain PKI state (CAs, credentials, requests, + * revocations, profiles, publication records, policy traces). Private keys are + * excluded and referenced via {@link KeyRef}. + *
+ * + * @param label operator-provided label for human identification + * @param attributes optional backup metadata (may be empty but not null) + */ +public record BackupRequest(String label, AttributeSet attributes) { + + /** + * Creates a backup request. + * + * @throws IllegalArgumentException if {@code label} is null/blank or + * {@code attributes} is null + */ + public BackupRequest { + if (label == null || label.isBlank()) { + throw new IllegalArgumentException("label must not be null/blank"); + } + if (attributes == null) { + throw new IllegalArgumentException("attributes must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/backup/BackupVerificationReport.java b/pki/src/main/java/zeroecho/pki/api/backup/BackupVerificationReport.java new file mode 100644 index 0000000..972b488 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/backup/BackupVerificationReport.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.backup; + +import java.util.List; + +/** + * Verification results for a backup artifact. + * + * @param valid true if the artifact is structurally valid and integrity checks + * passed + * @param issues list of issues found (non-sensitive) + */ +public record BackupVerificationReport(boolean valid, List+ * This package provides request/response and artifact model types used for + * backing up and restoring PKI state. The intent is to support offline escrow, + * migration, disaster recovery, and integrity verification workflows. + *
+ * + *+ * Concrete serialization formats and transport mechanisms are handled by + * services and the transfer layer. + *
+ * + * @since 1.0 + */ +package zeroecho.pki.api.backup; diff --git a/pki/src/main/java/zeroecho/pki/api/ca/CaCreateCommand.java b/pki/src/main/java/zeroecho/pki/api/ca/CaCreateCommand.java new file mode 100644 index 0000000..0984bf2 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/ca/CaCreateCommand.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.ca; + +import java.util.Optional; + +import zeroecho.pki.api.FormatId; +import zeroecho.pki.api.KeyRef; +import zeroecho.pki.api.SubjectRef; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Command to create a new root CA entity and issue its initial CA credential. + * + *+ * If {@code keyRef} is absent, the runtime may generate a new key pair + * depending on policy and runtime wiring. This command carries universal + * {@code attributes} used by policy and mapping. + *
+ * + * @param formatId target credential format + * @param subjectRef normalized CA subject reference + * @param profileId profile id governing issuance and mapping + * @param keyRef optional existing key reference; empty requests key + * generation + * @param attributes universal attributes (may be empty but not null) + */ +public record CaCreateCommand(FormatId formatId, SubjectRef subjectRef, String profileId, Optional+ * This operation registers a CA entity and associates it with an externally + * managed key reference. + *
+ * + * @param formatId credential format id + * @param subjectRef normalized CA subject reference + * @param profileId profile id for mapping/constraints + * @param keyRef reference to private key material + * @param existingCaCredential existing CA credential payload (certificate-like) + * @param attributes universal attributes (may be empty but not null) + */ +public record CaImportCommand(FormatId formatId, SubjectRef subjectRef, String profileId, KeyRef keyRef, + EncodedObject existingCaCredential, AttributeSet attributes) { + + /** + * Creates a CA import command. + * + * @throws IllegalArgumentException if inputs are invalid + */ + public CaImportCommand { + if (formatId == null) { + throw new IllegalArgumentException("formatId must not be null"); + } + if (subjectRef == null) { + throw new IllegalArgumentException("subjectRef must not be null"); + } + if (profileId == null || profileId.isBlank()) { + throw new IllegalArgumentException("profileId must not be null/blank"); + } + if (keyRef == null) { + throw new IllegalArgumentException("keyRef must not be null"); + } + if (existingCaCredential == null) { + throw new IllegalArgumentException("existingCaCredential must not be null"); + } + if (attributes == null) { + throw new IllegalArgumentException("attributes must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/ca/CaKeyRotationCommand.java b/pki/src/main/java/zeroecho/pki/api/ca/CaKeyRotationCommand.java new file mode 100644 index 0000000..6905a43 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/ca/CaKeyRotationCommand.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.ca; + +import java.util.Optional; + +import zeroecho.pki.api.KeyRef; +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Command to rotate a CA key reference and issue new corresponding CA + * credentials. + * + *+ * Key rotation changes the underlying key material. Historical key references + * and credentials must remain discoverable for audit and validation of + * previously issued credentials. + *
+ * + * @param caId CA entity id + * @param newKeyRef optional new key reference; empty requests key generation + * via runtime wiring + * @param issuerCaId optional issuer CA id (required for intermediate rotation; + * empty for root depending on policy) + * @param attributes universal attributes (may be empty but not null) + */ +public record CaKeyRotationCommand(PkiId caId, Optional+ * A CA entity may have multiple CA credentials to support: + *
+ *+ * Rollover issues a new CA credential for the CA entity without changing the + * underlying key material. Historical credentials remain accessible for audit + * and chain selection. + *
+ * + * @param caId CA entity id + * @param issuerCaId optional issuer CA id (empty for self-issued root + * rollover where applicable) + * @param requestedValidity optional requested validity + * @param attributes universal attributes (may be empty but not null) + */ +public record CaRolloverCommand(PkiId caId, Optional+ * Historical credentials remain available for validation and audit until they + * expire or are revoked. + *
+ */ + RETIRED, + + /** + * CA is compromised and must not be used for issuance. + * + *+ * Operators should perform incident response, publish updated status objects, + * and rotate trust anchors. + *
+ */ + COMPROMISED, + + /** + * CA is administratively disabled. + * + *+ * This state is distinct from retirement and may be reversible. + *
+ */ + DISABLED +} diff --git a/pki/src/main/java/zeroecho/pki/api/ca/IntermediateCertIssueCommand.java b/pki/src/main/java/zeroecho/pki/api/ca/IntermediateCertIssueCommand.java new file mode 100644 index 0000000..e48d201 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/ca/IntermediateCertIssueCommand.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.ca; + +import java.util.Optional; + +import zeroecho.pki.api.FormatId; +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.Validity; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Command to issue a new CA credential for an existing intermediate CA entity. + * + *+ * This command supports cross-signing (issuing with a different issuer CA) and + * renewal scenarios. + *
+ * + * @param formatId credential format id + * @param issuerCaId issuer CA entity id + * @param subjectCaId subject CA entity id (the intermediate being + * certified) + * @param profileId profile id governing issuance + * @param requestedValidity optional requested validity (policy may + * override/deny) + * @param attributes universal attributes (may be empty but not null) + */ +public record IntermediateCertIssueCommand(FormatId formatId, PkiId issuerCaId, PkiId subjectCaId, String profileId, + Optional+ * This package contains CA records, lifecycle state, CA kinds, and CA-related + * commands and queries. It models root and intermediate CA management, + * including creation, import, rollover, and key rotation operations. + *
+ * + *+ * Concrete certificate framework specifics are delegated to framework + * integrations. + *
+ * + * @since 1.0 + */ +package zeroecho.pki.api.ca; diff --git a/pki/src/main/java/zeroecho/pki/api/credential/Credential.java b/pki/src/main/java/zeroecho/pki/api/credential/Credential.java new file mode 100644 index 0000000..71c1c36 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/credential/Credential.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.credential; + +import zeroecho.pki.api.EncodedObject; +import zeroecho.pki.api.FormatId; +import zeroecho.pki.api.IssuerRef; +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.SubjectRef; +import zeroecho.pki.api.Validity; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Issued credential with mandatory core metadata and universal attributes. + * + *+ * The PKI core does not assume X.509 semantics. The {@code serialOrUniqueId} + * field maps to X.509 serial numbers when applicable, but can represent another + * framework's unique identifier. + *
+ * + *+ * The {@code publicKeyId} is intended to group multiple credentials for the + * same key (e.g., cross-signing, migrations, or parallel classical/PQC chains). + *
+ * + * @param credentialId stable identifier for the credential (typically a + * fingerprint of encoded bytes) + * @param formatId framework identifier + * @param issuerRef issuing CA reference + * @param subjectRef normalized subject reference + * @param validity validity interval + * @param serialOrUniqueId framework-specific unique identifier (serial for + * X.509) + * @param publicKeyId stable identifier derived from the subject public key + * @param profileId profile governing issuance + * @param status inventory status + * @param encoded encoded credential bytes + * @param attributes universal attribute set + */ +public record Credential(PkiId credentialId, FormatId formatId, IssuerRef issuerRef, SubjectRef subjectRef, + Validity validity, String serialOrUniqueId, PkiId publicKeyId, String profileId, CredentialStatus status, + EncodedObject encoded, AttributeSet attributes) { + + /** + * Creates a credential record. + * + * @throws IllegalArgumentException if mandatory inputs are invalid + */ + public Credential { + if (credentialId == null) { + throw new IllegalArgumentException("credentialId must not be null"); + } + if (formatId == null) { + throw new IllegalArgumentException("formatId must not be null"); + } + if (issuerRef == null) { + throw new IllegalArgumentException("issuerRef must not be null"); + } + if (subjectRef == null) { + throw new IllegalArgumentException("subjectRef must not be null"); + } + if (validity == null) { + throw new IllegalArgumentException("validity must not be null"); + } + if (serialOrUniqueId == null || serialOrUniqueId.isBlank()) { + throw new IllegalArgumentException("serialOrUniqueId must not be null/blank"); + } + if (publicKeyId == null) { + throw new IllegalArgumentException("publicKeyId must not be null"); + } + if (profileId == null || profileId.isBlank()) { + throw new IllegalArgumentException("profileId must not be null/blank"); + } + if (status == null) { + throw new IllegalArgumentException("status must not be null"); + } + if (encoded == null) { + throw new IllegalArgumentException("encoded must not be null"); + } + if (attributes == null) { + throw new IllegalArgumentException("attributes must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/credential/CredentialBundle.java b/pki/src/main/java/zeroecho/pki/api/credential/CredentialBundle.java new file mode 100644 index 0000000..04c3fb9 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/credential/CredentialBundle.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.credential; + +import java.util.List; + +import zeroecho.pki.api.EncodedObject; + +/** + * Bundle of a primary credential and supporting objects. + * + *+ * Supporting objects enable distribution and validation. For X.509 these are + * typically chain certificates. Frameworks may define additional supporting + * artifacts. + *
+ * + * @param credential primary credential + * @param supportingObjects supporting artifacts (framework-defined ordering) + */ +public record CredentialBundle(Credential credential, List+ * Status may be computed from validity and revocation state or stored directly + * depending on implementation. + *
+ */ +public enum CredentialStatus { + + /** + * Credential is issued and not revoked. Validity may still expire later. + */ + ISSUED, + + /** + * Credential is revoked. + */ + REVOKED, + + /** + * Credential validity interval has ended. + */ + EXPIRED +} diff --git a/pki/src/main/java/zeroecho/pki/api/credential/package-info.java b/pki/src/main/java/zeroecho/pki/api/credential/package-info.java new file mode 100644 index 0000000..001befb --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/credential/package-info.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +/** + * Credential inventory domain model. + * + *+ * This package defines the model types representing issued credentials and + * their inventory view, including status tracking and query objects. It is used + * by {@link zeroecho.pki.api.CredentialInventoryService}. + *
+ * + *+ * Bundles are constructed using chain selection rules, trust anchor selection, + * and optional compatibility profiles. This is especially relevant for + * cross-signing and migration scenarios. + *
+ * + * @param credentialId credential id + * @param preferredTrustAnchorId optional preferred trust anchor id + * (implementation-defined) + * @param compatibilityProfileId optional compatibility profile id influencing + * chain selection + */ +public record BundleCommand(PkiId credentialId, Optional+ * The meaning of "issuance record" is implementation-defined (it may be derived + * from audit/store metadata). Reissue is useful for reproducing issuance under + * controlled changes. + *
+ * + * @param issuanceRecordId issuance record id + * @param overrides universal attribute overrides (policy-validated; may + * be empty but not null) + */ +public record ReissueCommand(PkiId issuanceRecordId, AttributeSet overrides) { + + /** + * Creates a reissue command. + * + * @throws IllegalArgumentException if inputs are invalid + */ + public ReissueCommand { + if (issuanceRecordId == null) { + throw new IllegalArgumentException("issuanceRecordId must not be null"); + } + if (overrides == null) { + throw new IllegalArgumentException("overrides must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/issuance/RenewCommand.java b/pki/src/main/java/zeroecho/pki/api/issuance/RenewCommand.java new file mode 100644 index 0000000..0a8ab8b --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/issuance/RenewCommand.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.issuance; + +import java.util.Optional; + +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.Validity; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Command to renew an existing credential. + * + *+ * Renewal typically retains continuity (same identity and key constraints) + * under policy-defined semantics. The implementation decides what "renew" means + * for a given framework and profile. + *
+ * + * @param existingCredentialId credential id to renew + * @param validityOverride optional validity override (policy-validated) + * @param overrides universal attribute overrides (policy-validated; + * may be empty but not null) + */ +public record RenewCommand(PkiId existingCredentialId, Optional+ * Replacement is used for scenarios such as compromise or identity attribute + * changes. Policy determines whether replacement is permitted and what + * continuity constraints apply. + *
+ * + * @param existingCredentialId existing credential id + * @param newRequest new parsed request for the replacement credential + * @param profileId profile id governing issuance + * @param overrides universal attribute overrides (policy-validated; + * may be empty but not null) + */ +public record ReplaceCommand(PkiId existingCredentialId, ParsedCertificationRequest newRequest, String profileId, + AttributeSet overrides) { + + /** + * Creates a replacement command. + * + * @throws IllegalArgumentException if inputs are invalid + */ + public ReplaceCommand { + if (existingCredentialId == null) { + throw new IllegalArgumentException("existingCredentialId must not be null"); + } + if (newRequest == null) { + throw new IllegalArgumentException("newRequest must not be null"); + } + if (profileId == null || profileId.isBlank()) { + throw new IllegalArgumentException("profileId must not be null/blank"); + } + if (overrides == null) { + throw new IllegalArgumentException("overrides must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/issuance/VerificationPolicy.java b/pki/src/main/java/zeroecho/pki/api/issuance/VerificationPolicy.java new file mode 100644 index 0000000..11db632 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/issuance/VerificationPolicy.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.issuance; + +import java.util.Optional; + +/** + * Constraints for certification request verification. + * + *+ * This policy controls proof-of-possession requirements and may carry + * framework-specific verification modes via optional hints. + *
+ * + * @param requireProofOfPossession whether proof-of-possession is required + * @param compatibilityProfileId optional compatibility profile hint for + * parsers/verifiers + */ +public record VerificationPolicy(boolean requireProofOfPossession, Optional+ * This package contains command objects and input types used to issue, renew, + * replace, and reissue credentials, as well as optional issuance verification + * policies. The operations are executed through + * {@link zeroecho.pki.api.IssuanceService}. + *
+ * + *+ * Requests may originate from the request domain + * ({@code zeroecho.pki.api.request}) and issuance outcomes may be published + * and/or recorded in inventory. + *
+ * + * @since 1.0 + */ +package zeroecho.pki.api.issuance; diff --git a/pki/src/main/java/zeroecho/pki/api/package-info.java b/pki/src/main/java/zeroecho/pki/api/package-info.java new file mode 100644 index 0000000..a9877a9 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/package-info.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +/** + * Public, framework-agnostic PKI API. + * + *+ * This package provides stable entry points and core value types for operating + * a PKI instance. The API is intentionally independent of any concrete + * certificate framework (for example X.509), allowing multiple frameworks to be + * integrated via SPIs in {@code zeroecho.pki.spi.*}. + *
+ * + *+ * Subpackages further organize domain models: {@code ca}, {@code issuance}, + * {@code request}, {@code revocation}, {@code status}, {@code publication}, + * {@code profile}, {@code policy}, {@code transfer}, plus attribute and audit + * domains in {@code attr} and {@code audit}. + *
+ * + * @since 1.0 + */ +package zeroecho.pki.api; diff --git a/pki/src/main/java/zeroecho/pki/api/policy/PolicyDecision.java b/pki/src/main/java/zeroecho/pki/api/policy/PolicyDecision.java new file mode 100644 index 0000000..d23ceee --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/policy/PolicyDecision.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.policy; + +import java.util.List; + +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Policy decision including optional modifications to be applied to an + * operation. + * + *+ * The {@code appliedOverrides} attribute set is used to communicate + * policy-enforced adjustments (e.g., constrained validity, normalized + * attributes). It must not contain secrets. + *
+ * + * @param decisionId stable decision identifier for correlation and + * explainability + * @param status decision outcome status + * @param messages non-sensitive operator-readable messages + * @param appliedOverrides policy-enforced overrides to be applied downstream + */ +public record PolicyDecision(PkiId decisionId, PolicyDecisionStatus status, List+ * This package defines the core policy decision objects and trace structures + * used to explain and audit policy evaluation outcomes. It is consumed via + * {@link zeroecho.pki.api.PolicyService}. + *
+ * + *+ * Policy traces are intended to provide human- and machine-readable reasoning + * without exposing sensitive data. Trace steps must remain deterministic and + * stable for audit retention. + *
+ * + * @since 1.0 + */ +package zeroecho.pki.api.policy; diff --git a/pki/src/main/java/zeroecho/pki/api/profile/CertificateProfile.java b/pki/src/main/java/zeroecho/pki/api/profile/CertificateProfile.java new file mode 100644 index 0000000..f6e5a2d --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/profile/CertificateProfile.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.profile; + +import java.time.Duration; +import java.util.List; +import java.util.Optional; + +import zeroecho.pki.api.FormatId; +import zeroecho.pki.api.attr.AttributeId; + +/** + * Defines issuance constraints and mapping hints for a class of credentials. + * + *+ * A profile is referenced by {@code profileId} during issuance. It defines + * which universal attributes are required or allowed, and provides limits such + * as maximum validity. Framework backends may use the profile as a source of + * mapping hints when translating universal attributes into framework-specific + * fields/extensions. + *
+ * + *+ * Profiles must not include secrets. + *
+ * + * @param profileId stable profile identifier + * @param formatId framework/format supported by the profile + * @param displayName human-readable name + * @param requiredAttributes list of required attribute identifiers + * @param optionalAttributes list of optional attribute identifiers + * @param maxValidity optional maximum validity allowed by the profile + * @param active whether the profile is active for issuance + */ +public record CertificateProfile(String profileId, FormatId formatId, String displayName, + List+ * This package contains profile model objects and query types describing + * constraints and defaults used during issuance. Profiles are managed through + * {@link zeroecho.pki.api.ProfileService}. + *
+ * + *+ * Profiles are framework-agnostic by design and are mapped into concrete + * framework constructs during credential creation. + *
+ * + * @since 1.0 + */ +package zeroecho.pki.api.profile; diff --git a/pki/src/main/java/zeroecho/pki/api/publication/PublicationQuery.java b/pki/src/main/java/zeroecho/pki/api/publication/PublicationQuery.java new file mode 100644 index 0000000..4ee348d --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/publication/PublicationQuery.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.publication; + +import java.time.Instant; +import java.util.Optional; + +/** + * Query constraints for listing publication records. + * + * @param targetType optional target type filter + * @param after optional lower bound for time + * @param before optional upper bound for time + * @param objectKind optional object kind filter + */ +public record PublicationQuery(Optional+ * Publication records support operational troubleshooting, auditability, and + * re-publication workflows. + *
+ * + * @param publicationId publication id + * @param time time when publication was attempted + * @param target publication target + * @param objectId published object id (credential, CA materials, status + * object) + * @param objectKind non-empty logical kind string (e.g., "CREDENTIAL", + * "CA_MATERIALS", "STATUS_OBJECT") + * @param status publication outcome + */ +public record PublicationRecord(PkiId publicationId, Instant time, PublicationTarget target, PkiId objectId, + String objectKind, PublicationStatus status) { + + /** + * Creates a publication record. + * + * @throws IllegalArgumentException if inputs are invalid + */ + public PublicationRecord { + if (publicationId == null) { + throw new IllegalArgumentException("publicationId must not be null"); + } + if (time == null) { + throw new IllegalArgumentException("time must not be null"); + } + if (target == null) { + throw new IllegalArgumentException("target must not be null"); + } + if (objectId == null) { + throw new IllegalArgumentException("objectId must not be null"); + } + if (objectKind == null || objectKind.isBlank()) { + throw new IllegalArgumentException("objectKind must not be null/blank"); + } + if (status == null) { + throw new IllegalArgumentException("status must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/publication/PublicationResult.java b/pki/src/main/java/zeroecho/pki/api/publication/PublicationResult.java new file mode 100644 index 0000000..0cc408d --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/publication/PublicationResult.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.publication; + +import java.util.List; + +import zeroecho.pki.api.PkiId; + +/** + * Result of a publish operation. + * + * @param publicationId publication record id + * @param status outcome status + * @param notes non-sensitive operator-readable notes + */ +public record PublicationResult(PkiId publicationId, PublicationStatus status, List+ * The {@code targetId} identifies a configured target instance. Additional + * configuration is carried in {@code attributes}. Secrets must not be carried + * in attributes intended for publication. + *
+ * + * @param type destination type + * @param targetId target identifier (implementation-defined) + * @param attributes target configuration/hints (may be empty but not null) + */ +public record PublicationTarget(PublicationTargetType type, String targetId, AttributeSet attributes) { + + /** + * Creates a publication target. + * + * @throws IllegalArgumentException if inputs are invalid + */ + public PublicationTarget { + if (type == null) { + throw new IllegalArgumentException("type must not be null"); + } + if (targetId == null || targetId.isBlank()) { + throw new IllegalArgumentException("targetId must not be null/blank"); + } + if (attributes == null) { + throw new IllegalArgumentException("attributes must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/publication/PublicationTargetType.java b/pki/src/main/java/zeroecho/pki/api/publication/PublicationTargetType.java new file mode 100644 index 0000000..5dba7fc --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/publication/PublicationTargetType.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.publication; + +/** + * Classifies the publication destination type. + */ +public enum PublicationTargetType { + + /** + * Publish to a filesystem location. + */ + FILESYSTEM, + + /** + * Publish to an LDAP directory. + */ + LDAP, + + /** + * Publish via an HTTP(S) endpoint. + */ + HTTP, + + /** + * Publish to an object store (S3-like). + */ + OBJECT_STORE, + + /** + * Custom target type implemented by a publisher plugin. + */ + CUSTOM +} diff --git a/pki/src/main/java/zeroecho/pki/api/publication/package-info.java b/pki/src/main/java/zeroecho/pki/api/publication/package-info.java new file mode 100644 index 0000000..14174cb --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/publication/package-info.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +/** + * Publication domain model. + * + *+ * This package defines publication targets and records describing how PKI + * artifacts are distributed to relying parties or infrastructure components + * (repositories, directories, endpoints, etc.). Publication is orchestrated + * through {@link zeroecho.pki.api.PublicationService}. + *
+ * + *+ * Publication may include certificates, chains, status objects, and related + * metadata. The concrete transport is framework- and deployment-specific. + *
+ * + * @since 1.0 + */ +package zeroecho.pki.api.publication; diff --git a/pki/src/main/java/zeroecho/pki/api/request/CertificationRequest.java b/pki/src/main/java/zeroecho/pki/api/request/CertificationRequest.java new file mode 100644 index 0000000..639d34a --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/request/CertificationRequest.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.request; + +import zeroecho.pki.api.EncodedObject; +import zeroecho.pki.api.FormatId; + +/** + * Opaque certification request container. + * + *+ * This type transports a request payload and declares the request format via + * {@link FormatId}. A framework backend parses and normalizes the payload into + * {@link ParsedCertificationRequest}. + *
+ * + *+ * For X.509, the request is typically a PKCS#10 CSR. Other frameworks may + * define different request syntaxes. + *
+ * + * @param formatId request/credential framework id + * @param encoded encoded request payload + */ +public record CertificationRequest(FormatId formatId, EncodedObject encoded) { + + /** + * Creates a certification request. + * + * @param formatId request format id + * @param encoded encoded request payload + * @throws IllegalArgumentException if inputs are null + */ + public CertificationRequest { + if (formatId == null) { + throw new IllegalArgumentException("formatId must not be null"); + } + if (encoded == null) { + throw new IllegalArgumentException("encoded must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/request/ParsedCertificationRequest.java b/pki/src/main/java/zeroecho/pki/api/request/ParsedCertificationRequest.java new file mode 100644 index 0000000..262d658 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/request/ParsedCertificationRequest.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.request; + +import java.util.Optional; + +import zeroecho.pki.api.EncodedObject; +import zeroecho.pki.api.FormatId; +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.SubjectRef; +import zeroecho.pki.api.Validity; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Normalized representation of a certification request. + * + *+ * This record is produced by a framework-specific request parser. It contains a + * minimal set of mandatory core fields required by the PKI runtime, plus a + * universal typed {@link AttributeSet} that carries additional request + * attributes in a framework-neutral manner. + *
+ * + *+ * The PKI runtime is expected to apply policy and profile constraints before + * issuance. + *
+ * + * @param requestId stable identifier for the request (typically + * derived from the request payload fingerprint) + * @param formatId framework/format identifier + * @param subjectRef normalized subject reference for policy and + * inventory correlation + * @param publicKeyInfo requested public key information (SPKI DER + * preferred where applicable) + * @param requestedValidity optional validity requested by the subject; policy + * may override or deny + * @param requestedProfileId optional profile hint; policy may override or deny + * @param attributes universal typed attributes extracted from the + * request + */ +public record ParsedCertificationRequest(PkiId requestId, FormatId formatId, SubjectRef subjectRef, + EncodedObject publicKeyInfo, Optional+ * The {@code details} field is intended for operator diagnostics and must not + * contain secrets. + *
+ * + * @param status verification outcome status + * @param details optional non-sensitive diagnostic information + */ +public record ProofOfPossessionResult(ProofOfPossessionStatus status, Optional+ * This is acceptable only if policy allows it. + *
+ */ + NOT_PRESENT, + + /** + * Proof-of-possession evidence is present but invalid. + */ + FAILED, + + /** + * Proof-of-possession verification is not supported for the given request type + * or framework. + */ + NOT_SUPPORTED +} diff --git a/pki/src/main/java/zeroecho/pki/api/request/RequestQuery.java b/pki/src/main/java/zeroecho/pki/api/request/RequestQuery.java new file mode 100644 index 0000000..6048b8a --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/request/RequestQuery.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.request; + +import java.time.Instant; +import java.util.Optional; + +import zeroecho.pki.api.FormatId; +import zeroecho.pki.api.SubjectRef; + +/** + * Query constraints for searching stored certification requests. + * + * @param formatId optional framework filter + * @param subjectRef optional subject filter + * @param createdAfter optional lower bound (inclusive) for request creation + * time + * @param createdBefore optional upper bound (exclusive) for request creation + * time + * @param profileId optional profile filter (requested or resolved profile + * id depending on implementation) + */ +public record RequestQuery(Optional+ * Use only when explicit request persistence is not required by operational + * needs. + *
+ */ + DO_NOT_STORE +} diff --git a/pki/src/main/java/zeroecho/pki/api/request/package-info.java b/pki/src/main/java/zeroecho/pki/api/request/package-info.java new file mode 100644 index 0000000..23cd5b2 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/request/package-info.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +/** + * Certification request domain model. + * + *+ * This package defines models and query types for certification requests and + * their parsed, normalized form. Requests are managed through + * {@link zeroecho.pki.api.CertificationRequestService} and may be consumed by + * issuance operations. + *
+ * + *+ * The request workflow may include proof-of-possession evaluation. The request + * domain models the outcome and status without imposing a specific + * cryptographic proof mechanism. + *
+ * + * @since 1.0 + */ +package zeroecho.pki.api.request; diff --git a/pki/src/main/java/zeroecho/pki/api/revocation/HoldCommand.java b/pki/src/main/java/zeroecho/pki/api/revocation/HoldCommand.java new file mode 100644 index 0000000..5e62986 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/revocation/HoldCommand.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.revocation; + +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Command to place a credential on hold. + * + *+ * Frameworks may map this to X.509 {@code certificateHold} or equivalent + * semantics. + *
+ * + * @param credentialId credential identifier + * @param attributes optional additional attributes (may be empty but not + * null) + */ +public record HoldCommand(PkiId credentialId, AttributeSet attributes) { + + /** + * Creates a hold command. + * + * @throws IllegalArgumentException if inputs are null + */ + public HoldCommand { + if (credentialId == null) { + throw new IllegalArgumentException("credentialId must not be null"); + } + if (attributes == null) { + throw new IllegalArgumentException("attributes must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/revocation/RevocationInputs.java b/pki/src/main/java/zeroecho/pki/api/revocation/RevocationInputs.java new file mode 100644 index 0000000..6d1721a --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/revocation/RevocationInputs.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.revocation; + +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Normalized inputs for revocation policy evaluation. + * + * @param credentialId credential id to revoke/hold/unhold + * @param reason revocation reason + * @param attributes additional revocation attributes (may be empty but not + * null) + */ +public record RevocationInputs(PkiId credentialId, RevocationReason reason, AttributeSet attributes) { + + /** + * Creates revocation inputs. + * + * @throws IllegalArgumentException if inputs are invalid + */ + public RevocationInputs { + if (credentialId == null) { + throw new IllegalArgumentException("credentialId must not be null"); + } + if (reason == null) { + throw new IllegalArgumentException("reason must not be null"); + } + if (attributes == null) { + throw new IllegalArgumentException("attributes must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/revocation/RevocationQuery.java b/pki/src/main/java/zeroecho/pki/api/revocation/RevocationQuery.java new file mode 100644 index 0000000..2b5e3ea --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/revocation/RevocationQuery.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.revocation; + +import java.time.Instant; +import java.util.Optional; + +import zeroecho.pki.api.PkiId; + +/** + * Query constraints for searching revocation records. + * + * @param issuerCaId optional issuer CA filter + * @param reason optional reason filter + * @param revokedAfter optional lower bound (inclusive) for revocation time + * @param revokedBefore optional upper bound (exclusive) for revocation time + */ +public record RevocationQuery(Optional+ * Framework backends may map these reasons to framework-native reason codes. + *
+ */ +public enum RevocationReason { + + /** + * Reason not specified. + */ + UNSPECIFIED, + + /** + * Subject private key is compromised. + */ + KEY_COMPROMISE, + + /** + * CA private key is compromised. + */ + CA_COMPROMISE, + + /** + * Subject affiliation has changed. + */ + AFFILIATION_CHANGED, + + /** + * Credential has been superseded by a newer one. + */ + SUPERSEDED, + + /** + * Subject has ceased operation. + */ + CESSATION_OF_OPERATION, + + /** + * Credential is temporarily on hold. + */ + CERTIFICATE_HOLD, + + /** + * Remove the credential from status list (unhold semantics). + */ + REMOVE_FROM_CRL, + + /** + * Privileges granted to the subject have been withdrawn. + */ + PRIVILEGE_WITHDRAWN, + + /** + * Attribute authority is compromised. + */ + AA_COMPROMISE +} diff --git a/pki/src/main/java/zeroecho/pki/api/revocation/RevokeCommand.java b/pki/src/main/java/zeroecho/pki/api/revocation/RevokeCommand.java new file mode 100644 index 0000000..f20ad92 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/revocation/RevokeCommand.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.revocation; + +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Command to revoke a credential. + * + *+ * Additional revocation metadata (e.g., invalidity date) may be conveyed via + * {@code attributes} using universal attribute definitions. + *
+ * + * @param credentialId credential identifier to revoke + * @param reason revocation reason + * @param attributes additional revocation attributes (may be empty but not + * null) + */ +public record RevokeCommand(PkiId credentialId, RevocationReason reason, AttributeSet attributes) { + + /** + * Creates a revoke command. + * + * @throws IllegalArgumentException if inputs are null + */ + public RevokeCommand { + if (credentialId == null) { + throw new IllegalArgumentException("credentialId must not be null"); + } + if (reason == null) { + throw new IllegalArgumentException("reason must not be null"); + } + if (attributes == null) { + throw new IllegalArgumentException("attributes must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/revocation/RevokedRecord.java b/pki/src/main/java/zeroecho/pki/api/revocation/RevokedRecord.java new file mode 100644 index 0000000..252915f --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/revocation/RevokedRecord.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.revocation; + +import java.time.Instant; + +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Persisted revocation record. + * + *+ * This record is the authoritative input for generating status objects (CRLs, + * OCSP responses, or framework-specific revocation lists). + *
+ * + * @param credentialId revoked credential id + * @param revocationTime server time when revocation was recorded + * @param reason revocation reason + * @param attributes additional revocation attributes (e.g., invalidity + * date), must not contain secrets + */ +public record RevokedRecord(PkiId credentialId, Instant revocationTime, RevocationReason reason, + AttributeSet attributes) { + + /** + * Creates a revocation record. + * + * @throws IllegalArgumentException if inputs are null + */ + public RevokedRecord { + if (credentialId == null) { + throw new IllegalArgumentException("credentialId must not be null"); + } + if (revocationTime == null) { + throw new IllegalArgumentException("revocationTime must not be null"); + } + if (reason == null) { + throw new IllegalArgumentException("reason must not be null"); + } + if (attributes == null) { + throw new IllegalArgumentException("attributes must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/revocation/UnholdCommand.java b/pki/src/main/java/zeroecho/pki/api/revocation/UnholdCommand.java new file mode 100644 index 0000000..5321f8b --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/revocation/UnholdCommand.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.revocation; + +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Command to remove a hold from a credential. + * + *+ * Frameworks may map this to X.509 {@code removeFromCRL} or equivalent + * semantics. + *
+ * + * @param credentialId credential identifier + * @param attributes optional additional attributes (may be empty but not + * null) + */ +public record UnholdCommand(PkiId credentialId, AttributeSet attributes) { + + /** + * Creates an unhold command. + * + * @throws IllegalArgumentException if inputs are null + */ + public UnholdCommand { + if (credentialId == null) { + throw new IllegalArgumentException("credentialId must not be null"); + } + if (attributes == null) { + throw new IllegalArgumentException("attributes must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/revocation/package-info.java b/pki/src/main/java/zeroecho/pki/api/revocation/package-info.java new file mode 100644 index 0000000..52f4fb1 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/revocation/package-info.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +/** + * Revocation and suspension domain model. + * + *+ * This package defines revocation and hold/unhold command objects, revocation + * reasons, revocation inputs, and query types. Revocation operations are + * executed via {@link zeroecho.pki.api.RevocationService}. + *
+ * + *+ * Revocation records serve as authoritative inputs for generating status + * objects in {@code zeroecho.pki.api.status}. + *
+ * + * @since 1.0 + */ +package zeroecho.pki.api.revocation; diff --git a/pki/src/main/java/zeroecho/pki/api/status/StatusObject.java b/pki/src/main/java/zeroecho/pki/api/status/StatusObject.java new file mode 100644 index 0000000..3414eff --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/status/StatusObject.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.status; + +import java.time.Instant; +import java.util.Optional; + +import zeroecho.pki.api.EncodedObject; +import zeroecho.pki.api.FormatId; +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Generated status object used for revocation distribution. + * + *+ * For X.509 this represents CRLs or delta CRLs. For other frameworks it can + * represent analogous revocation lists. OCSP representation is + * implementation-defined but still transported using this container for + * uniformity. + *
+ * + * @param statusObjectId stable identifier of the status object + * @param formatId framework format id + * @param issuerCaId issuer CA entity id + * @param type status object type + * @param thisUpdate time of issuance/publication baseline + * @param nextUpdate optional next update timestamp + * @param encoded encoded payload + * @param attributes universal attributes describing the object (must not + * contain secrets) + */ +public record StatusObject(PkiId statusObjectId, FormatId formatId, PkiId issuerCaId, StatusObjectType type, + Instant thisUpdate, Optional+ * Framework backends may use {@code attributes} to control generation details + * (e.g., CRL number, distribution point partitioning, delta CRL settings). + *
+ * + * @param issuerCaId issuer CA entity id + * @param type status object type + * @param formatId framework format id + * @param attributes generation hints (may be empty but not null) + */ +public record StatusObjectGenerateCommand(PkiId issuerCaId, StatusObjectType type, FormatId formatId, + AttributeSet attributes) { + + /** + * Creates a status generation command. + * + * @throws IllegalArgumentException if inputs are null + */ + public StatusObjectGenerateCommand { + if (issuerCaId == null) { + throw new IllegalArgumentException("issuerCaId must not be null"); + } + if (type == null) { + throw new IllegalArgumentException("type must not be null"); + } + if (formatId == null) { + throw new IllegalArgumentException("formatId must not be null"); + } + if (attributes == null) { + throw new IllegalArgumentException("attributes must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/status/StatusObjectQuery.java b/pki/src/main/java/zeroecho/pki/api/status/StatusObjectQuery.java new file mode 100644 index 0000000..4c42a6a --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/status/StatusObjectQuery.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.status; + +import java.time.Instant; +import java.util.Optional; + +import zeroecho.pki.api.PkiId; + +/** + * Query constraints for listing status objects. + * + * @param issuerCaId issuer CA entity id + * @param type optional type filter + * @param createdAfter optional lower bound for creation time + * @param createdBefore optional upper bound for creation time + */ +public record StatusObjectQuery(PkiId issuerCaId, Optional+ * This package defines status objects and related types used to communicate + * credential validity information to relying parties (for example, CRL- or + * OCSP-like artifacts depending on the integrated framework). Status objects + * are generated and managed through + * {@link zeroecho.pki.api.StatusObjectService}. + *
+ * + *+ * The package intentionally models status artifacts abstractly; concrete + * encodings and semantics are framework-specific and provided by integrations. + *
+ * + * @since 1.0 + */ +package zeroecho.pki.api.status; diff --git a/pki/src/main/java/zeroecho/pki/api/transfer/ExportArtifact.java b/pki/src/main/java/zeroecho/pki/api/transfer/ExportArtifact.java new file mode 100644 index 0000000..fe4732b --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/transfer/ExportArtifact.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.transfer; + +import zeroecho.pki.api.EncodedObject; +import zeroecho.pki.api.PkiId; + +/** + * Opaque export artifact containing exported objects. + * + * @param exportId export identifier + * @param payload export payload + */ +public record ExportArtifact(PkiId exportId, EncodedObject payload) { + + /** + * Creates an export artifact. + * + * @throws IllegalArgumentException if inputs are null + */ + public ExportArtifact { + if (exportId == null) { + throw new IllegalArgumentException("exportId must not be null"); + } + if (payload == null) { + throw new IllegalArgumentException("payload must not be null"); + } + } +} diff --git a/pki/src/main/java/zeroecho/pki/api/transfer/ExportFormat.java b/pki/src/main/java/zeroecho/pki/api/transfer/ExportFormat.java new file mode 100644 index 0000000..22c971f --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/transfer/ExportFormat.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.transfer; + +/** + * Controls export representation. + */ +public enum ExportFormat { + + /** + * Export as PEM bundle where applicable (e.g., certificate + chain). + */ + PEM_BUNDLE, + + /** + * Export as DER artifacts where applicable. + */ + DER, + + /** + * Export as a binary archive (tar/zip-like). + */ + BINARY_ARCHIVE +} diff --git a/pki/src/main/java/zeroecho/pki/api/transfer/ExportQuery.java b/pki/src/main/java/zeroecho/pki/api/transfer/ExportQuery.java new file mode 100644 index 0000000..dd383cd --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/api/transfer/ExportQuery.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.api.transfer; + +import java.time.Instant; +import java.util.Optional; + +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.SubjectRef; +import zeroecho.pki.api.credential.CredentialStatus; + +/** + * Query constraints for exporting credentials and revocations. + * + * @param issuerCaId optional issuer CA filter + * @param subjectRef optional subject filter + * @param issuedAfter optional lower bound for issuance time + * (implementation-defined) + * @param issuedBefore optional upper bound for issuance time + * (implementation-defined) + * @param status optional credential status filter + */ +public record ExportQuery(Optional+ * This package defines export artifacts, formats, policies, and queries used + * for transferring PKI objects between systems, environments, or storage + * backends. Transfer operations are executed via + * {@link zeroecho.pki.api.ImportExportService}. + *
+ * + *+ * Implementations must apply appropriate redaction policies and must never + * write secrets. + *
+ */ +@FunctionalInterface +public interface AuditSink { + + /** + * Persists an audit event. + * + * @param event audit event + * @throws IllegalArgumentException if {@code event} is null + * @throws RuntimeException if persistence fails + */ + void record(AuditEvent event); +} diff --git a/pki/src/main/java/zeroecho/pki/spi/framework/CertificationRequestParser.java b/pki/src/main/java/zeroecho/pki/spi/framework/CertificationRequestParser.java new file mode 100644 index 0000000..8f747a4 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/spi/framework/CertificationRequestParser.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.spi.framework; + +import zeroecho.pki.api.request.CertificationRequest; +import zeroecho.pki.api.request.ParsedCertificationRequest; + +/** + * Parses and normalizes framework-specific certification requests into the core + * request model. + */ +@SuppressWarnings("PMD.ImplicitFunctionalInterface") +public interface CertificationRequestParser { + + /** + * Parses and normalizes a certification request. + * + * @param request certification request + * @return parsed request + * @throws IllegalArgumentException if {@code request} is null + * @throws RuntimeException if parsing fails (invalid syntax, + * unsupported features) + */ + ParsedCertificationRequest parse(CertificationRequest request); +} diff --git a/pki/src/main/java/zeroecho/pki/spi/framework/CredentialFramework.java b/pki/src/main/java/zeroecho/pki/spi/framework/CredentialFramework.java new file mode 100644 index 0000000..4537465 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/spi/framework/CredentialFramework.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.spi.framework; + +import zeroecho.pki.api.FormatId; + +/** + * Pluggable credential framework implementation. + * + *+ * A framework implementation provides request parsing, proof-of-possession + * verification (if applicable), credential issuance backend, and status object + * generation for a particular {@link FormatId}. + *
+ */ +public interface CredentialFramework { + + /** + * Returns the format id supported by this framework. + * + * @return format id + */ + FormatId formatId(); + + /** + * Returns the request parser for this framework. + * + * @return request parser + */ + CertificationRequestParser requestParser(); + + /** + * Returns the proof-of-possession verifier for this framework. + * + * @return PoP verifier + */ + ProofOfPossessionVerifier proofOfPossessionVerifier(); + + /** + * Returns the issuer backend for this framework. + * + * @return issuer backend + */ + CredentialIssuerBackend issuerBackend(); + + /** + * Returns the status object generator for this framework. + * + * @return status object generator + */ + StatusObjectGenerator statusObjectGenerator(); + + /** + * Returns the framework attribute mapper. + * + * @return mapper + */ + FrameworkAttributeMapper attributeMapper(); +} diff --git a/pki/src/main/java/zeroecho/pki/spi/framework/CredentialIssuerBackend.java b/pki/src/main/java/zeroecho/pki/spi/framework/CredentialIssuerBackend.java new file mode 100644 index 0000000..a78eef2 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/spi/framework/CredentialIssuerBackend.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.spi.framework; + +import zeroecho.pki.api.ca.IntermediateCertIssueCommand; +import zeroecho.pki.api.credential.Credential; +import zeroecho.pki.api.credential.CredentialBundle; +import zeroecho.pki.api.issuance.IssueEndEntityCommand; + +/** + * Issues credentials for a credential framework. + * + *+ * This backend assembles framework-specific "to-be-signed" structures and + * produces encoded credentials. Actual signing operations are expected to be + * delegated to runtime wiring (e.g., crypto providers/HSM) and not hard-coded + * into this interface. + *
+ */ +public interface CredentialIssuerBackend { + + /** + * Issues an end-entity credential. + * + * @param command issuance command + * @return credential bundle + * @throws IllegalArgumentException if {@code command} is invalid + * @throws RuntimeException if issuance fails + */ + CredentialBundle issueEndEntity(IssueEndEntityCommand command); + + /** + * Issues a CA credential for an existing CA entity (e.g., intermediate issuance + * or cross-sign). + * + * @param command intermediate CA credential issuance command + * @return CA credential + * @throws IllegalArgumentException if {@code command} is invalid + * @throws RuntimeException if issuance fails + */ + Credential issueIntermediateCertificate(IntermediateCertIssueCommand command); +} diff --git a/pki/src/main/java/zeroecho/pki/spi/framework/FrameworkAttributeMapper.java b/pki/src/main/java/zeroecho/pki/spi/framework/FrameworkAttributeMapper.java new file mode 100644 index 0000000..95e8492 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/spi/framework/FrameworkAttributeMapper.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.spi.framework; + +import zeroecho.pki.api.attr.AttributeSet; + +/** + * Maps universal attributes to framework-specific constructs and optionally + * back. + * + *+ * This interface intentionally does not expose framework-specific types. + * Implementations typically map attributes into internal builder structures or + * encoded extension sets. + *
+ */ +@SuppressWarnings("PMD.ImplicitFunctionalInterface") +public interface FrameworkAttributeMapper { + + /** + * Normalizes and validates universal attributes for framework consumption. + * + * @param input attribute set + * @return normalized attribute set (may be the same instance depending on + * implementation) + * @throws IllegalArgumentException if {@code input} is null + * @throws RuntimeException if normalization fails + */ + AttributeSet normalize(AttributeSet input); +} diff --git a/pki/src/main/java/zeroecho/pki/spi/framework/ProofOfPossessionVerifier.java b/pki/src/main/java/zeroecho/pki/spi/framework/ProofOfPossessionVerifier.java new file mode 100644 index 0000000..26d72f4 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/spi/framework/ProofOfPossessionVerifier.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.spi.framework; + +import zeroecho.pki.api.issuance.VerificationPolicy; +import zeroecho.pki.api.request.ParsedCertificationRequest; +import zeroecho.pki.api.request.ProofOfPossessionResult; + +/** + * Verifies proof-of-possession (PoP) for a parsed request in a + * framework-specific manner. + */ +@SuppressWarnings("PMD.ImplicitFunctionalInterface") +public interface ProofOfPossessionVerifier { + + /** + * Verifies proof-of-possession for the requested public key. + * + * @param request parsed request + * @param policy verification policy + * @return PoP verification result + * @throws IllegalArgumentException if inputs are null + * @throws RuntimeException if verification fails due to backend errors + */ + ProofOfPossessionResult verify(ParsedCertificationRequest request, VerificationPolicy policy); +} diff --git a/pki/src/main/java/zeroecho/pki/spi/framework/StatusObjectGenerator.java b/pki/src/main/java/zeroecho/pki/spi/framework/StatusObjectGenerator.java new file mode 100644 index 0000000..8972c34 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/spi/framework/StatusObjectGenerator.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.spi.framework; + +import zeroecho.pki.api.status.StatusObject; +import zeroecho.pki.api.status.StatusObjectGenerateCommand; + +/** + * Generates status objects for a credential framework (e.g., CRL/delta CRL/OCSP + * for X.509). + */ +@SuppressWarnings("PMD.ImplicitFunctionalInterface") +public interface StatusObjectGenerator { + + /** + * Generates a status object. + * + * @param command generation command + * @return generated status object + * @throws IllegalArgumentException if {@code command} is invalid + * @throws RuntimeException if generation fails + */ + StatusObject generate(StatusObjectGenerateCommand command); +} diff --git a/pki/src/main/java/zeroecho/pki/spi/framework/package-info.java b/pki/src/main/java/zeroecho/pki/spi/framework/package-info.java new file mode 100644 index 0000000..8bc89be --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/spi/framework/package-info.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +/** + * Credential framework SPI. + * + *+ * Framework implementations (e.g., X.509) provide request parsing, issuance, + * and status object generation while mapping universal attributes into + * framework-specific fields. Framework-specific types must not leak into the + * public API. + *
+ */ +package zeroecho.pki.spi.framework; diff --git a/pki/src/main/java/zeroecho/pki/spi/package-info.java b/pki/src/main/java/zeroecho/pki/spi/package-info.java new file mode 100644 index 0000000..3a5670f --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/spi/package-info.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +/** + * Service Provider Interfaces (SPIs) for the PKI module. + * + *+ * SPIs are used to plug in persistence, audit sinks, publishing targets, and + * credential framework implementations. Public API types remain + * framework-agnostic. + *
+ */ +package zeroecho.pki.spi; diff --git a/pki/src/main/java/zeroecho/pki/spi/publish/Publisher.java b/pki/src/main/java/zeroecho/pki/spi/publish/Publisher.java new file mode 100644 index 0000000..ba5aa12 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/spi/publish/Publisher.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.spi.publish; + +import zeroecho.pki.api.EncodedObject; +import zeroecho.pki.api.publication.PublicationTarget; + +/** + * Publishes an encoded artifact to a configured publication target. + */ +@SuppressWarnings("PMD.ImplicitFunctionalInterface") +public interface Publisher { + + /** + * Publishes the given payload to the specified target. + * + * @param target publication target + * @param payload payload to publish + * @throws IllegalArgumentException if inputs are null + * @throws RuntimeException if publishing fails + */ + void publish(PublicationTarget target, EncodedObject payload); +} diff --git a/pki/src/main/java/zeroecho/pki/spi/publish/package-info.java b/pki/src/main/java/zeroecho/pki/spi/publish/package-info.java new file mode 100644 index 0000000..8aef3c7 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/spi/publish/package-info.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +/** + * Publishing SPI for distributing PKI artifacts. + * + *+ * Publishers implement target-specific distribution (filesystem, LDAP, HTTP, + * object stores). + *
+ */ +package zeroecho.pki.spi.publish; \ No newline at end of file diff --git a/pki/src/main/java/zeroecho/pki/spi/store/PkiStore.java b/pki/src/main/java/zeroecho/pki/spi/store/PkiStore.java new file mode 100644 index 0000000..a02f6d5 --- /dev/null +++ b/pki/src/main/java/zeroecho/pki/spi/store/PkiStore.java @@ -0,0 +1,304 @@ +/******************************************************************************* + * Copyright (C) 2025, Leo Galambos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: + * This product includes software developed by the Egothor project. + * + * 4. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +package zeroecho.pki.spi.store; + +import java.util.List; +import java.util.Optional; + +import zeroecho.pki.api.PkiId; +import zeroecho.pki.api.ca.CaRecord; +import zeroecho.pki.api.credential.Credential; +import zeroecho.pki.api.policy.PolicyTrace; +import zeroecho.pki.api.profile.CertificateProfile; +import zeroecho.pki.api.publication.PublicationRecord; +import zeroecho.pki.api.request.ParsedCertificationRequest; +import zeroecho.pki.api.revocation.RevokedRecord; +import zeroecho.pki.api.status.StatusObject; + +/** + * Persistence abstraction for PKI state. + * + *+ * This Service Provider Interface (SPI) defines the authoritative storage + * contract for all PKI-managed state, including CA entities, issued + * credentials, certification requests, revocations, status objects, profiles, + * publications, and policy traces. + *
+ * + *+ * The interface is intentionally coarse-grained and framework-agnostic. + * Implementations are responsible for providing appropriate durability, + * consistency, and concurrency guarantees according to the deployment model + * (filesystem, embedded storage, RDBMS, distributed store, etc.). + *
+ * + *+ * Security requirements: + *
+ *+ * Implementations must ensure that CA records are stored atomically. Replacing + * an existing CA record must preserve historical integrity (e.g., previously + * issued credentials must remain resolvable). + *
+ * + * @param record CA record to persist + * @throws IllegalArgumentException if {@code record} is null + * @throws RuntimeException if persistence fails + */ + void putCa(CaRecord record); + + /** + * Retrieves a CA record by its identifier. + * + * @param caId CA identifier + * @return CA record if present, otherwise {@link Optional#empty()} + * @throws IllegalArgumentException if {@code caId} is null + * @throws RuntimeException if retrieval fails + */ + Optional+ * No filtering is applied at this level; higher layers are expected to perform + * query-based filtering. + *
+ * + * @return list of CA records (never null) + * @throws RuntimeException if listing fails + */ + List+ * Credentials are immutable once stored. Re-inserting an existing credential + * identifier should either be idempotent or rejected, depending on + * implementation policy. + *
+ * + * @param credential credential to persist + * @throws IllegalArgumentException if {@code credential} is null + * @throws RuntimeException if persistence fails + */ + void putCredential(Credential credential); + + /** + * Retrieves an issued credential by its identifier. + * + * @param credentialId credential identifier + * @return credential if present + * @throws IllegalArgumentException if {@code credentialId} is null + * @throws RuntimeException if retrieval fails + */ + Optional+ * Stored requests are used for audit, correlation, re-issuance, and ACME-like + * workflows. + *
+ * + * @param request parsed certification request + * @throws IllegalArgumentException if {@code request} is null + * @throws RuntimeException if persistence fails + */ + void putRequest(ParsedCertificationRequest request); + + /** + * Retrieves a stored certification request. + * + * @param requestId request identifier + * @return parsed request if present + * @throws IllegalArgumentException if {@code requestId} is null + * @throws RuntimeException if retrieval fails + */ + Optional+ * Revocation records are authoritative inputs for generating revocation status + * objects (CRLs, OCSP, etc.). + *
+ * + * @param record revocation record + * @throws IllegalArgumentException if {@code record} is null + * @throws RuntimeException if persistence fails + */ + void putRevocation(RevokedRecord record); + + /** + * Retrieves the revocation record for a credential. + * + * @param credentialId credential identifier + * @return revocation record if present + * @throws IllegalArgumentException if {@code credentialId} is null + * @throws RuntimeException if retrieval fails + */ + Optional+ * Status objects include CRLs, delta CRLs, OCSP responses, or + * framework-specific revocation lists. + *
+ * + * @param object status object to persist + * @throws IllegalArgumentException if {@code object} is null + * @throws RuntimeException if persistence fails + */ + void putStatusObject(StatusObject object); + + /** + * Retrieves a status object by its identifier. + * + * @param statusObjectId status object identifier + * @return status object if present + * @throws IllegalArgumentException if {@code statusObjectId} is null + * @throws RuntimeException if retrieval fails + */ + Optional+ * Publication records provide traceability and operational diagnostics for + * artifact distribution. + *
+ * + * @param record publication record + * @throws IllegalArgumentException if {@code record} is null + * @throws RuntimeException if persistence fails + */ + void putPublicationRecord(PublicationRecord record); + + /** + * Lists all publication records. + * + * @return list of publication records (never null) + * @throws RuntimeException if listing fails + */ + List+ * Policy traces are used for explainability, audit, and compliance evidence. + * They must never contain sensitive data. + *
+ * + * @param trace policy trace + * @throws IllegalArgumentException if {@code trace} is null + * @throws RuntimeException if persistence fails + */ + void putPolicyTrace(PolicyTrace trace); + + /** + * Retrieves a policy trace by decision identifier. + * + * @param decisionId policy decision identifier + * @return policy trace if present + * @throws IllegalArgumentException if {@code decisionId} is null + * @throws RuntimeException if retrieval fails + */ + Optional+ * Implementations persist CA entities, credentials, requests, revocations, + * status objects, profiles, policy traces, publication records, and optionally + * audit events. Storage must be deterministic and suitable for backup/restore. + *
+ */ +package zeroecho.pki.spi.store; diff --git a/pki/src/main/resources/zeroecho-pki-logging.properties b/pki/src/main/resources/zeroecho-pki-logging.properties new file mode 100644 index 0000000..e4a4a29 --- /dev/null +++ b/pki/src/main/resources/zeroecho-pki-logging.properties @@ -0,0 +1,42 @@ +############################################################################### +# ZeroEcho PKI \u2013 JUL logging configuration +# +# This configuration is intentionally conservative: +# - console logging only +# - no sensitive data +# - readable, timestamped output +# - suitable for bootstrap and early lifecycle phases +############################################################################### + +# Global handlers +handlers=java.util.logging.ConsoleHandler + +# Default global level +.level=INFO + +############################################################################### +# Console handler +############################################################################### + +java.util.logging.ConsoleHandler.level=INFO +java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter + +# ISO-like timestamp, level, logger, message +java.util.logging.SimpleFormatter.format=%1$tF %1$tT %4$s [%3$s] %5$s%6$s%n + +############################################################################### +# Package-specific levels +############################################################################### + +# PKI bootstrap and internals +zeroecho.pki.level=INFO + +# Public API (defensive: do not accidentally enable verbose logging) +zeroecho.pki.api.level=INFO + +############################################################################### +# Hard safety defaults +############################################################################### + +# Never enable FINE/FINER/FINEST globally by default. +# If needed for diagnostics, raise levels explicitly and temporarily. diff --git a/settings.gradle b/settings.gradle index fc8f320..abc7cb0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -11,4 +11,4 @@ plugins { rootProject.name = 'ZeroEcho' -include('app', 'lib', 'samples') +include('app', 'lib', 'pki', 'samples')