All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.helidon.common.pki.Keys Maven / Gradle / Ivy

There is a newer version: 4.1.1
Show newest version
/*
 * Copyright (c) 2024 Oracle and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.helidon.common.pki;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;

import io.helidon.builder.api.Prototype;
import io.helidon.common.Generated;
import io.helidon.common.config.Config;

/**
 * Configuration of keys. If a key is defined in multiple places (keystore, pem, or explicit), the order of preference is:
 * 
    *
  • Explicit instance will be used
  • *
  • Keystore will be used
  • *
  • PEM will be used
  • *
* So if a Private key is defined both explicitly and through PEM, the explicitly defined key would be used. * * @see #builder() * @see #create() */ @Generated(value = "io.helidon.builder.codegen.BuilderCodegen", trigger = "io.helidon.common.pki.KeysBlueprint") public interface Keys extends KeysBlueprint, Prototype.Api { /** * Create a new fluent API builder to customize configuration. * * @return a new builder */ static Keys.Builder builder() { return new Keys.Builder(); } /** * Create a new fluent API builder from an existing instance. * * @param instance an existing instance used as a base for the builder * @return a builder based on an instance */ static Keys.Builder builder(Keys instance) { return Keys.builder().from(instance); } /** * Create a new instance from configuration. * * @param config used to configure the new instance * @return a new instance configured from configuration */ static Keys create(Config config) { return Keys.builder().config(config).buildPrototype(); } /** * Create a new instance with default values. * * @return a new instance */ static Keys create() { return Keys.builder().buildPrototype(); } /** * Fluent API builder base for {@link Keys}. * * @param type of the builder extending this abstract builder * @param type of the prototype interface that would be built by {@link #buildPrototype()} */ abstract class BuilderBase, PROTOTYPE extends Keys> implements Prototype.ConfiguredBuilder { private final List certChain = new ArrayList<>(); private final List certs = new ArrayList<>(); private boolean isCertChainMutated; private boolean isCertsMutated; private Config config; private KeystoreKeys keystore; private PemKeys pem; private PrivateKey privateKey; private PublicKey publicKey; private X509Certificate publicCert; /** * Protected to support extensibility. */ protected BuilderBase() { } /** * Update this builder from an existing prototype instance. This method disables automatic service discovery. * * @param prototype existing prototype to update this builder from * @return updated builder instance */ public BUILDER from(Keys prototype) { keystore(prototype.keystore()); pem(prototype.pem()); publicKey(prototype.publicKey()); privateKey(prototype.privateKey()); publicCert(prototype.publicCert()); if (!isCertChainMutated) { certChain.clear(); } addCertChain(prototype.certChain()); if (!isCertsMutated) { certs.clear(); } addCerts(prototype.certs()); return self(); } /** * Update this builder from an existing prototype builder instance. * * @param builder existing builder prototype to update this builder from * @return updated builder instance */ public BUILDER from(Keys.BuilderBase builder) { builder.keystore().ifPresent(this::keystore); builder.pem().ifPresent(this::pem); builder.publicKey().ifPresent(this::publicKey); builder.privateKey().ifPresent(this::privateKey); builder.publicCert().ifPresent(this::publicCert); if (isCertChainMutated) { if (builder.isCertChainMutated) { addCertChain(builder.certChain); } } else { certChain.clear(); addCertChain(builder.certChain); } if (isCertsMutated) { if (builder.isCertsMutated) { addCerts(builder.certs); } } else { certs.clear(); addCerts(builder.certs); } return self(); } /** * Update builder from configuration (node of this type). * If a value is present in configuration, it would override currently configured values. * * @param config configuration instance used to obtain values to update this builder * @return updated builder instance */ @Override public BUILDER config(Config config) { Objects.requireNonNull(config); this.config = config; config.get("keystore").map(KeystoreKeys::create).ifPresent(this::keystore); config.get("pem").map(PemKeys::create).ifPresent(this::pem); return self(); } /** * Clear existing value of this property. * * @return updated builder instance * @see #keystore() */ public BUILDER clearKeystore() { this.keystore = null; return self(); } /** * Configure keys from a keystore. * Once the config object is built, this option will ALWAYS be empty. All keys from the keystore will be * populated to {@link #privateKey()}, {@link #publicKey()}, {@link #publicCert()} etc. * * @param keystore keystore configuration * @return updated builder instance * @see #keystore() */ public BUILDER keystore(KeystoreKeys keystore) { Objects.requireNonNull(keystore); this.keystore = keystore; return self(); } /** * Configure keys from a keystore. * Once the config object is built, this option will ALWAYS be empty. All keys from the keystore will be * populated to {@link #privateKey()}, {@link #publicKey()}, {@link #publicCert()} etc. * * @param consumer keystore configuration * @return updated builder instance * @see #keystore() */ public BUILDER keystore(Consumer consumer) { Objects.requireNonNull(consumer); var builder = KeystoreKeys.builder(); consumer.accept(builder); this.keystore(builder.build()); return self(); } /** * Clear existing value of this property. * * @return updated builder instance * @see #pem() */ public BUILDER clearPem() { this.pem = null; return self(); } /** * Configure keys from pem file(s). * Once the config object is built, this option will ALWAYS be empty. All keys from the keystore will be * populated to {@link #privateKey()}, {@link #publicKey()}, {@link #publicCert()} etc. * * @param pem pem based definition * @return updated builder instance * @see #pem() */ public BUILDER pem(PemKeys pem) { Objects.requireNonNull(pem); this.pem = pem; return self(); } /** * Configure keys from pem file(s). * Once the config object is built, this option will ALWAYS be empty. All keys from the keystore will be * populated to {@link #privateKey()}, {@link #publicKey()}, {@link #publicCert()} etc. * * @param consumer pem based definition * @return updated builder instance * @see #pem() */ public BUILDER pem(Consumer consumer) { Objects.requireNonNull(consumer); var builder = PemKeys.builder(); consumer.accept(builder); this.pem(builder.build()); return self(); } /** * Clear existing value of this property. * * @return updated builder instance * @see #publicKey() */ public BUILDER clearPublicKey() { this.publicKey = null; return self(); } /** * The public key of this config if configured. * * @param publicKey the public key of this config or empty if not configured * @return updated builder instance * @see #publicKey() */ public BUILDER publicKey(PublicKey publicKey) { Objects.requireNonNull(publicKey); this.publicKey = publicKey; return self(); } /** * Clear existing value of this property. * * @return updated builder instance * @see #privateKey() */ public BUILDER clearPrivateKey() { this.privateKey = null; return self(); } /** * The private key of this config if configured. * * @param privateKey the private key of this config or empty if not configured * @return updated builder instance * @see #privateKey() */ public BUILDER privateKey(PrivateKey privateKey) { Objects.requireNonNull(privateKey); this.privateKey = privateKey; return self(); } /** * Clear existing value of this property. * * @return updated builder instance * @see #publicCert() */ public BUILDER clearPublicCert() { this.publicCert = null; return self(); } /** * The public X.509 Certificate if configured. * * @param publicCert the public certificate of this config or empty if not configured * @return updated builder instance * @see #publicCert() */ public BUILDER publicCert(X509Certificate publicCert) { Objects.requireNonNull(publicCert); this.publicCert = publicCert; return self(); } /** * The X.509 Certificate Chain. * * @param certChain the certificate chain or empty list if not configured * @return updated builder instance * @see #certChain() */ public BUILDER certChain(List certChain) { Objects.requireNonNull(certChain); isCertChainMutated = true; this.certChain.clear(); this.certChain.addAll(certChain); return self(); } /** * The X.509 Certificate Chain. * * @param certChain the certificate chain or empty list if not configured * @return updated builder instance * @see #certChain() */ public BUILDER addCertChain(List certChain) { Objects.requireNonNull(certChain); isCertChainMutated = true; this.certChain.addAll(certChain); return self(); } /** * The X.509 Certificate Chain. * * @param certChain the certificate chain or empty list if not configured * @return updated builder instance * @see #certChain() */ public BUILDER addCertChain(X509Certificate certChain) { Objects.requireNonNull(certChain); this.certChain.add(certChain); isCertChainMutated = true; return self(); } /** * The X.509 Certificates. * * @param certs the certificates configured or empty list if none configured * @return updated builder instance * @see #certs() */ public BUILDER certs(List certs) { Objects.requireNonNull(certs); isCertsMutated = true; this.certs.clear(); this.certs.addAll(certs); return self(); } /** * The X.509 Certificates. * * @param certs the certificates configured or empty list if none configured * @return updated builder instance * @see #certs() */ public BUILDER addCerts(List certs) { Objects.requireNonNull(certs); isCertsMutated = true; this.certs.addAll(certs); return self(); } /** * The X.509 Certificates. * * @param cert the certificates configured or empty list if none configured * @return updated builder instance * @see #certs() */ public BUILDER addCert(X509Certificate cert) { Objects.requireNonNull(cert); this.certs.add(cert); isCertsMutated = true; return self(); } /** * Configure keys from a keystore. * Once the config object is built, this option will ALWAYS be empty. All keys from the keystore will be * populated to {@link #privateKey()}, {@link #publicKey()}, {@link #publicCert()} etc. * * @return the keystore */ public Optional keystore() { return Optional.ofNullable(keystore); } /** * Configure keys from pem file(s). * Once the config object is built, this option will ALWAYS be empty. All keys from the keystore will be * populated to {@link #privateKey()}, {@link #publicKey()}, {@link #publicCert()} etc. * * @return the pem */ public Optional pem() { return Optional.ofNullable(pem); } /** * The public key of this config if configured. * * @return the public key */ public Optional publicKey() { return Optional.ofNullable(publicKey); } /** * The private key of this config if configured. * * @return the private key */ public Optional privateKey() { return Optional.ofNullable(privateKey); } /** * The public X.509 Certificate if configured. * * @return the public cert */ public Optional publicCert() { return Optional.ofNullable(publicCert); } /** * The X.509 Certificate Chain. * * @return the cert chain */ public List certChain() { return certChain; } /** * The X.509 Certificates. * * @return the certs */ public List certs() { return certs; } /** * If this instance was configured, this would be the config instance used. * * @return config node used to configure this builder, or empty if not configured */ public Optional config() { return Optional.ofNullable(config); } @Override public String toString() { return "KeysBuilder{" + "keystore=" + keystore + "," + "pem=" + pem + "," + "publicKey=" + publicKey + "," + "privateKey=" + privateKey + "," + "publicCert=" + publicCert + "," + "certChain=" + certChain + "," + "certs=" + certs + "}"; } /** * Handles providers and decorators. */ protected void preBuildPrototype() { new KeysBuilderDecorator().decorate(this); } /** * Validates required properties. */ protected void validatePrototype() { } /** * Configure keys from a keystore. * Once the config object is built, this option will ALWAYS be empty. All keys from the keystore will be * populated to {@link #privateKey()}, {@link #publicKey()}, {@link #publicCert()} etc. * * @param keystore keystore configuration * @return updated builder instance * @see #keystore() */ BUILDER keystore(Optional keystore) { Objects.requireNonNull(keystore); this.keystore = keystore.map(KeystoreKeys.class::cast).orElse(this.keystore); return self(); } /** * Configure keys from pem file(s). * Once the config object is built, this option will ALWAYS be empty. All keys from the keystore will be * populated to {@link #privateKey()}, {@link #publicKey()}, {@link #publicCert()} etc. * * @param pem pem based definition * @return updated builder instance * @see #pem() */ BUILDER pem(Optional pem) { Objects.requireNonNull(pem); this.pem = pem.map(PemKeys.class::cast).orElse(this.pem); return self(); } /** * The public key of this config if configured. * * @param publicKey the public key of this config or empty if not configured * @return updated builder instance * @see #publicKey() */ BUILDER publicKey(Optional publicKey) { Objects.requireNonNull(publicKey); this.publicKey = publicKey.map(java.security.PublicKey.class::cast).orElse(this.publicKey); return self(); } /** * The private key of this config if configured. * * @param privateKey the private key of this config or empty if not configured * @return updated builder instance * @see #privateKey() */ BUILDER privateKey(Optional privateKey) { Objects.requireNonNull(privateKey); this.privateKey = privateKey.map(java.security.PrivateKey.class::cast).orElse(this.privateKey); return self(); } /** * The public X.509 Certificate if configured. * * @param publicCert the public certificate of this config or empty if not configured * @return updated builder instance * @see #publicCert() */ BUILDER publicCert(Optional publicCert) { Objects.requireNonNull(publicCert); this.publicCert = publicCert.map(java.security.cert.X509Certificate.class::cast).orElse(this.publicCert); return self(); } /** * Generated implementation of the prototype, can be extended by descendant prototype implementations. */ protected static class KeysImpl implements Keys { private final List certChain; private final List certs; private final Optional keystore; private final Optional pem; private final Optional privateKey; private final Optional publicKey; private final Optional publicCert; /** * Create an instance providing a builder. * * @param builder extending builder base of this prototype */ protected KeysImpl(Keys.BuilderBase builder) { this.keystore = builder.keystore(); this.pem = builder.pem(); this.publicKey = builder.publicKey(); this.privateKey = builder.privateKey(); this.publicCert = builder.publicCert(); this.certChain = List.copyOf(builder.certChain()); this.certs = List.copyOf(builder.certs()); } @Override public Optional keystore() { return keystore; } @Override public Optional pem() { return pem; } @Override public Optional publicKey() { return publicKey; } @Override public Optional privateKey() { return privateKey; } @Override public Optional publicCert() { return publicCert; } @Override public List certChain() { return certChain; } @Override public List certs() { return certs; } @Override public String toString() { return "Keys{" + "keystore=" + keystore + "," + "pem=" + pem + "," + "publicKey=" + publicKey + "," + "privateKey=" + privateKey + "," + "publicCert=" + publicCert + "," + "certChain=" + certChain + "," + "certs=" + certs + "}"; } @Override public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof Keys other)) { return false; } return Objects.equals(keystore, other.keystore()) && Objects.equals(pem, other.pem()) && Objects.equals(publicKey, other.publicKey()) && Objects.equals(privateKey, other.privateKey()) && Objects.equals(publicCert, other.publicCert()) && Objects.equals(certChain, other.certChain()) && Objects.equals(certs, other.certs()); } @Override public int hashCode() { return Objects.hash(keystore, pem, publicKey, privateKey, publicCert, certChain, certs); } } } /** * Fluent API builder for {@link Keys}. */ class Builder extends Keys.BuilderBase implements io.helidon.common.Builder { private Builder() { } @Override public Keys buildPrototype() { preBuildPrototype(); validatePrototype(); return new KeysImpl(this); } @Override public Keys build() { return buildPrototype(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy