diff --git a/ph-security/src/main/java/com/helger/security/keystore/IKeyStoreAndKeyDescriptor.java b/ph-security/src/main/java/com/helger/security/keystore/IKeyStoreAndKeyDescriptor.java new file mode 100644 index 000000000..a522f9ba6 --- /dev/null +++ b/ph-security/src/main/java/com/helger/security/keystore/IKeyStoreAndKeyDescriptor.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2014-2024 Philip Helger (www.helger.com) + * philip[at]helger[dot]com + * + * 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 com.helger.security.keystore; + +import java.security.KeyStore.PrivateKeyEntry; + +import javax.annotation.Nonnull; + +import com.helger.commons.annotation.Nonempty; + +/** + * Interface describing the parameters needed to reference a key store with a + * private key. + * + * @author Philip Helger + * @since 11.1.10 + */ +public interface IKeyStoreAndKeyDescriptor extends IKeyStoreDescriptor +{ + /** + * Note: the case sensitivity of the key alias depends on the key store type. + * + * @return The alias of the key inside a key store. May neither be + * null nor empty. + */ + @Nonnull + @Nonempty + String getKeyAlias (); + + /** + * @return The password required to access the key inside the key store. May + * not be null but may be empty. + */ + @Nonnull + char [] getKeyPassword (); + + /** + * @return The loaded key based on the loaded key store and the parameters in + * this descriptor. + */ + @Nonnull + LoadedKey loadKey (); +} diff --git a/ph-security/src/main/java/com/helger/security/keystore/IKeyStoreDescriptor.java b/ph-security/src/main/java/com/helger/security/keystore/IKeyStoreDescriptor.java new file mode 100644 index 000000000..f1d02ca6e --- /dev/null +++ b/ph-security/src/main/java/com/helger/security/keystore/IKeyStoreDescriptor.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014-2024 Philip Helger (www.helger.com) + * philip[at]helger[dot]com + * + * 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 com.helger.security.keystore; + +import java.security.Provider; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.helger.commons.annotation.Nonempty; + +/** + * Interface describing the parameters needed to reference a key store (without + * a private key). + * + * @author Philip Helger + * @since 11.1.10 + */ +public interface IKeyStoreDescriptor +{ + /** + * @return The type of the key store. May not be null. + */ + @Nonnull + IKeyStoreType getKeyStoreType (); + + /** + * @return The path to the key store. May neither be null nor + * empty. The interpretation of the path is implementation dependent. + */ + @Nonnull + @Nonempty + String getKeyStorePath (); + + /** + * @return The password required to open the key store. May not be + * null but may be empty. + */ + @Nonnull + char [] getKeyStorePassword (); + + /** + * @return The Java security provider for loading the key store. May be + * null. + */ + @Nullable + Provider getProvider (); + + /** + * @return The loaded key store based on the parameters in this descriptor. + * Never null. + */ + @Nonnull + LoadedKeyStore loadKeyStore (); +} diff --git a/ph-security/src/main/java/com/helger/security/keystore/ITrustStoreDescriptor.java b/ph-security/src/main/java/com/helger/security/keystore/ITrustStoreDescriptor.java new file mode 100644 index 000000000..7a2f89af5 --- /dev/null +++ b/ph-security/src/main/java/com/helger/security/keystore/ITrustStoreDescriptor.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2014-2024 Philip Helger (www.helger.com) + * philip[at]helger[dot]com + * + * 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 com.helger.security.keystore; + +import java.security.Provider; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.helger.commons.annotation.Nonempty; + +/** + * Interface describing the parameters needed to reference a trust store. + * + * @author Philip Helger + * @since 11.1.10 + */ +public interface ITrustStoreDescriptor +{ + /** + * @return The type of the trust store. May not be null. + */ + @Nonnull + IKeyStoreType getTrustStoreType (); + + /** + * @return The path to the trust store. May neither be null nor + * empty. The interpretation of the path is implementation dependent. + */ + @Nonnull + @Nonempty + String getTrustStorePath (); + + /** + * @return The password required to open the trust store. May not be + * null but may be empty. + */ + @Nonnull + char [] getTrustStorePassword (); + + /** + * @return The Java security provider for loading the trust store. May be + * null. + */ + @Nullable + Provider getProvider (); + + /** + * @return The loaded trust store based on the parameters in this descriptor. + * Never null. + */ + @Nonnull + LoadedKeyStore loadTrustStore (); +} diff --git a/ph-security/src/main/java/com/helger/security/keystore/KeyStoreAndKeyDescriptor.java b/ph-security/src/main/java/com/helger/security/keystore/KeyStoreAndKeyDescriptor.java new file mode 100644 index 000000000..7b67e98d5 --- /dev/null +++ b/ph-security/src/main/java/com/helger/security/keystore/KeyStoreAndKeyDescriptor.java @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2014-2024 Philip Helger (www.helger.com) + * philip[at]helger[dot]com + * + * 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 com.helger.security.keystore; + +import java.security.KeyStore.PrivateKeyEntry; +import java.security.Provider; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.helger.commons.ValueEnforcer; +import com.helger.commons.annotation.Nonempty; +import com.helger.commons.annotation.ReturnsMutableObject; +import com.helger.commons.builder.IBuilder; +import com.helger.commons.string.StringHelper; +import com.helger.commons.string.ToStringGenerator; + +/** + * The default implementation of {@link IKeyStoreAndKeyDescriptor}. + * + * @author Philip Helger + * @since 11.1.10 + */ +public class KeyStoreAndKeyDescriptor implements IKeyStoreAndKeyDescriptor +{ + private final IKeyStoreType m_aType; + private final String m_sPath; + private final char [] m_aPassword; + private final Provider m_aProvider; + private final String m_sKeyAlias; + private final char [] m_aKeyPassword; + // Lazily initialized + private LoadedKeyStore m_aLKS; + private LoadedKey m_aLK; + + public KeyStoreAndKeyDescriptor (@Nonnull final IKeyStoreType aType, + @Nonnull @Nonempty final String sPath, + @Nonnull final char [] aPassword, + @Nullable final Provider aProvider, + @Nonnull @Nonempty final String sKeyAlias, + @Nonnull final char [] aKeyPassword) + { + ValueEnforcer.notNull (aType, "Type"); + ValueEnforcer.notEmpty (sPath, "Path"); + ValueEnforcer.notNull (aPassword, "Password"); + ValueEnforcer.notEmpty (sKeyAlias, "KeyAlias"); + ValueEnforcer.notNull (aKeyPassword, "KeyPassword"); + m_aType = aType; + m_sPath = sPath; + m_aPassword = aPassword; + m_aProvider = aProvider; + m_sKeyAlias = sKeyAlias; + m_aKeyPassword = aKeyPassword; + } + + @Nonnull + public final IKeyStoreType getKeyStoreType () + { + return m_aType; + } + + @Nonnull + @Nonempty + public final String getKeyStorePath () + { + return m_sPath; + } + + @Nonnull + @ReturnsMutableObject + public final char [] getKeyStorePassword () + { + return m_aPassword; + } + + @Nullable + public final Provider getProvider () + { + return m_aProvider; + } + + @Nonnull + public LoadedKeyStore loadKeyStore () + { + LoadedKeyStore ret = m_aLKS; + if (ret == null) + ret = m_aLKS = KeyStoreHelper.loadKeyStore (m_aType, m_sPath, m_aPassword, m_aProvider); + return ret; + } + + @Nonnull + @Nonempty + public final String getKeyAlias () + { + return m_sKeyAlias; + } + + @Nonnull + @ReturnsMutableObject + public final char [] getKeyPassword () + { + return m_aKeyPassword; + } + + @Nonnull + public LoadedKey loadKey () + { + LoadedKey ret = m_aLK; + if (ret == null) + { + ret = m_aLK = KeyStoreHelper.loadPrivateKey (loadKeyStore ().getKeyStore (), + m_sPath, + m_sKeyAlias, + m_aKeyPassword); + } + return ret; + } + + @Override + public String toString () + { + return new ToStringGenerator (null).append ("Type", m_aType) + .append ("Path", m_sPath) + .appendPassword ("Password") + .appendIfNotNull ("Provider", m_aProvider) + .append ("KeyAlias", m_sKeyAlias) + .appendPassword ("KeyPassword") + .getToString (); + } + + /** + * @return A new builder for {@link KeyStoreAndKeyDescriptor} objects. Never + * null. + */ + @Nonnull + public static KeyStoreAndKeyDescriptorBuilder builder () + { + return new KeyStoreAndKeyDescriptorBuilder (); + } + + /** + * Create a new builder using the provided descriptor. + * + * @param a + * The existing descriptor. May not be null. + * @return A new builder for {@link KeyStoreAndKeyDescriptor} objects. Never + * null. + */ + @Nonnull + public static KeyStoreAndKeyDescriptorBuilder builder (@Nonnull final KeyStoreAndKeyDescriptor a) + { + return new KeyStoreAndKeyDescriptorBuilder (a); + } + + /** + * Builder class for class {@link KeyStoreAndKeyDescriptor}. + * + * @author Philip Helger + */ + public static class KeyStoreAndKeyDescriptorBuilder implements IBuilder + { + private IKeyStoreType m_aType; + private String m_sPath; + private char [] m_aPassword; + private Provider m_aProvider; + private String m_sKeyAlias; + private char [] m_aKeyPassword; + + public KeyStoreAndKeyDescriptorBuilder () + {} + + public KeyStoreAndKeyDescriptorBuilder (@Nonnull final KeyStoreAndKeyDescriptor aSrc) + { + type (aSrc.m_aType).path (aSrc.m_sPath) + .password (aSrc.m_aPassword) + .provider (aSrc.m_aProvider) + .keyAlias (aSrc.m_sKeyAlias) + .keyPassword (aSrc.m_aKeyPassword); + } + + @Nonnull + public final KeyStoreAndKeyDescriptorBuilder type (@Nullable final IKeyStoreType a) + { + m_aType = a; + return this; + } + + @Nonnull + public final KeyStoreAndKeyDescriptorBuilder path (@Nullable final String s) + { + m_sPath = s; + return this; + } + + @Nonnull + public final KeyStoreAndKeyDescriptorBuilder password (@Nullable final String s) + { + return password (s == null ? null : s.toCharArray ()); + } + + @Nonnull + public final KeyStoreAndKeyDescriptorBuilder password (@Nullable final char [] a) + { + m_aPassword = a; + return this; + } + + @Nonnull + public final KeyStoreAndKeyDescriptorBuilder provider (@Nullable final Provider a) + { + m_aProvider = a; + return this; + } + + @Nonnull + public final KeyStoreAndKeyDescriptorBuilder keyAlias (@Nullable final String s) + { + m_sKeyAlias = s; + return this; + } + + @Nonnull + public final KeyStoreAndKeyDescriptorBuilder keyPassword (@Nullable final String s) + { + return keyPassword (s == null ? null : s.toCharArray ()); + } + + @Nonnull + public final KeyStoreAndKeyDescriptorBuilder keyPassword (@Nullable final char [] a) + { + m_aKeyPassword = a; + return this; + } + + @Nonnull + public KeyStoreAndKeyDescriptor build () throws IllegalStateException + { + if (m_aType == null) + throw new IllegalStateException ("Type is missing"); + if (StringHelper.hasNoText (m_sPath)) + throw new IllegalStateException ("Path is empty"); + if (m_aPassword == null) + throw new IllegalStateException ("Password is missing"); + // Provider may be null + if (StringHelper.hasNoText (m_sKeyAlias)) + throw new IllegalStateException ("KeyAlias is empty"); + if (m_aKeyPassword == null) + throw new IllegalStateException ("KeyPassword is missing"); + + return new KeyStoreAndKeyDescriptor (m_aType, m_sPath, m_aPassword, m_aProvider, m_sKeyAlias, m_aKeyPassword); + } + } +} diff --git a/ph-security/src/main/java/com/helger/security/keystore/KeyStoreDescriptor.java b/ph-security/src/main/java/com/helger/security/keystore/KeyStoreDescriptor.java new file mode 100644 index 000000000..c26dbadb7 --- /dev/null +++ b/ph-security/src/main/java/com/helger/security/keystore/KeyStoreDescriptor.java @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2014-2024 Philip Helger (www.helger.com) + * philip[at]helger[dot]com + * + * 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 com.helger.security.keystore; + +import java.security.Provider; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.helger.commons.ValueEnforcer; +import com.helger.commons.annotation.Nonempty; +import com.helger.commons.annotation.ReturnsMutableObject; +import com.helger.commons.builder.IBuilder; +import com.helger.commons.string.StringHelper; +import com.helger.commons.string.ToStringGenerator; + +/** + * The default implementation of {@link IKeyStoreDescriptor}. + * + * @author Philip Helger + * @since 11.1.10 + */ +public class KeyStoreDescriptor implements IKeyStoreDescriptor +{ + private final IKeyStoreType m_aType; + private final String m_sPath; + private final char [] m_aPassword; + private final Provider m_aProvider; + // Lazily initialized + private LoadedKeyStore m_aLKS; + + public KeyStoreDescriptor (@Nonnull final IKeyStoreType aType, + @Nonnull @Nonempty final String sPath, + @Nonnull final char [] aPassword, + @Nullable final Provider aProvider) + { + ValueEnforcer.notNull (aType, "Type"); + ValueEnforcer.notEmpty (sPath, "Path"); + ValueEnforcer.notNull (aPassword, "Password"); + m_aType = aType; + m_sPath = sPath; + m_aPassword = aPassword; + m_aProvider = aProvider; + } + + @Nonnull + public final IKeyStoreType getKeyStoreType () + { + return m_aType; + } + + @Nonnull + @Nonempty + public final String getKeyStorePath () + { + return m_sPath; + } + + @Nonnull + @ReturnsMutableObject + public final char [] getKeyStorePassword () + { + return m_aPassword; + } + + @Nullable + public final Provider getProvider () + { + return m_aProvider; + } + + @Nonnull + public LoadedKeyStore loadKeyStore () + { + LoadedKeyStore ret = m_aLKS; + if (ret == null) + ret = m_aLKS = KeyStoreHelper.loadKeyStore (m_aType, m_sPath, m_aPassword, m_aProvider); + return ret; + } + + @Override + public String toString () + { + return new ToStringGenerator (null).append ("Type", m_aType) + .append ("Path", m_sPath) + .appendPassword ("Password") + .appendIfNotNull ("Provider", m_aProvider) + .getToString (); + } + + /** + * @return A new builder for {@link KeyStoreDescriptor} objects. Never + * null. + */ + @Nonnull + public static KeyStoreDescriptorBuilder builder () + { + return new KeyStoreDescriptorBuilder (); + } + + /** + * Create a new builder using the provided descriptor. + * + * @param a + * The existing descriptor. May not be null. + * @return A new builder for {@link KeyStoreDescriptor} objects. Never + * null. + */ + @Nonnull + public static KeyStoreDescriptorBuilder builder (@Nonnull final KeyStoreDescriptor a) + { + return new KeyStoreDescriptorBuilder (a); + } + + /** + * Builder class for class {@link KeyStoreDescriptor}. + * + * @author Philip Helger + */ + public static class KeyStoreDescriptorBuilder implements IBuilder + { + private IKeyStoreType m_aType; + private String m_sPath; + private char [] m_aPassword; + private Provider m_aProvider; + + public KeyStoreDescriptorBuilder () + {} + + public KeyStoreDescriptorBuilder (@Nonnull final KeyStoreDescriptor aSrc) + { + type (aSrc.m_aType).path (aSrc.m_sPath).password (aSrc.m_aPassword).provider (aSrc.m_aProvider); + } + + @Nonnull + public final KeyStoreDescriptorBuilder type (@Nullable final IKeyStoreType a) + { + m_aType = a; + return this; + } + + @Nonnull + public final KeyStoreDescriptorBuilder path (@Nullable final String s) + { + m_sPath = s; + return this; + } + + @Nonnull + public final KeyStoreDescriptorBuilder password (@Nullable final String s) + { + return password (s == null ? null : s.toCharArray ()); + } + + @Nonnull + public final KeyStoreDescriptorBuilder password (@Nullable final char [] a) + { + m_aPassword = a; + return this; + } + + @Nonnull + public final KeyStoreDescriptorBuilder provider (@Nullable final Provider a) + { + m_aProvider = a; + return this; + } + + @Nonnull + public KeyStoreDescriptor build () throws IllegalStateException + { + if (m_aType == null) + throw new IllegalStateException ("Type is missing"); + if (StringHelper.hasNoText (m_sPath)) + throw new IllegalStateException ("Path is empty"); + if (m_aPassword == null) + throw new IllegalStateException ("Password is missing"); + // Provider may be null + + return new KeyStoreDescriptor (m_aType, m_sPath, m_aPassword, m_aProvider); + } + } +} diff --git a/ph-security/src/main/java/com/helger/security/keystore/KeyStoreHelper.java b/ph-security/src/main/java/com/helger/security/keystore/KeyStoreHelper.java index e27e7f553..79ad1665b 100644 --- a/ph-security/src/main/java/com/helger/security/keystore/KeyStoreHelper.java +++ b/ph-security/src/main/java/com/helger/security/keystore/KeyStoreHelper.java @@ -25,6 +25,7 @@ import java.security.KeyStoreException; import java.security.Provider; import java.security.UnrecoverableKeyException; +import java.util.Enumeration; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -37,6 +38,7 @@ import com.helger.commons.ValueEnforcer; import com.helger.commons.annotation.PresentForCodeCoverage; import com.helger.commons.concurrent.SimpleReadWriteLock; +import com.helger.commons.functional.IThrowingConsumer; import com.helger.commons.io.resourceprovider.ClassPathResourceProvider; import com.helger.commons.io.resourceprovider.FileSystemResourceProvider; import com.helger.commons.io.resourceprovider.IReadableResourceProvider; @@ -625,4 +627,34 @@ public static LoadedKey loadTrustedCertificat aKeyStoreKeyPassword, KeyStore.TrustedCertificateEntry.class); } + + /** + * Helper method to iterate all aliases of a key store + * + * @param aKeyStore + * The key store to be iterated. May not be null. + * @param aAliasConsumer + * The consumer for each alias. May not be null. + * @since 11.1.10 + */ + public static void iterateKeyStore (@Nonnull final KeyStore aKeyStore, + @Nonnull final IThrowingConsumer aAliasConsumer) + { + ValueEnforcer.notNull (aKeyStore, "KeyStore"); + ValueEnforcer.notNull (aAliasConsumer, "AliasConsumer"); + + try + { + final Enumeration aAliases = aKeyStore.aliases (); + while (aAliases.hasMoreElements ()) + { + final String sAlias = aAliases.nextElement (); + aAliasConsumer.accept (sAlias); + } + } + catch (final KeyStoreException ex) + { + LOGGER.warn ("Failed to iterate key store", ex); + } + } } diff --git a/ph-security/src/main/java/com/helger/security/keystore/TrustStoreDescriptor.java b/ph-security/src/main/java/com/helger/security/keystore/TrustStoreDescriptor.java new file mode 100644 index 000000000..cd09477ce --- /dev/null +++ b/ph-security/src/main/java/com/helger/security/keystore/TrustStoreDescriptor.java @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2014-2024 Philip Helger (www.helger.com) + * philip[at]helger[dot]com + * + * 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 com.helger.security.keystore; + +import java.security.Provider; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.helger.commons.ValueEnforcer; +import com.helger.commons.annotation.Nonempty; +import com.helger.commons.annotation.ReturnsMutableObject; +import com.helger.commons.builder.IBuilder; +import com.helger.commons.string.StringHelper; +import com.helger.commons.string.ToStringGenerator; + +/** + * The default implementation of {@link ITrustStoreDescriptor}. + * + * @author Philip Helger + * @since 11.1.10 + */ +public class TrustStoreDescriptor implements ITrustStoreDescriptor +{ + private final IKeyStoreType m_aType; + private final String m_sPath; + private final char [] m_aPassword; + private final Provider m_aProvider; + // Lazily initialized + private LoadedKeyStore m_aLTS; + + public TrustStoreDescriptor (@Nonnull final IKeyStoreType aType, + @Nonnull @Nonempty final String sPath, + @Nonnull final char [] aPassword, + @Nullable final Provider aProvider) + { + ValueEnforcer.notNull (aType, "Type"); + ValueEnforcer.notEmpty (sPath, "Path"); + ValueEnforcer.notNull (aPassword, "Password"); + m_aType = aType; + m_sPath = sPath; + m_aPassword = aPassword; + m_aProvider = aProvider; + } + + @Nonnull + public final IKeyStoreType getTrustStoreType () + { + return m_aType; + } + + @Nonnull + @Nonempty + public final String getTrustStorePath () + { + return m_sPath; + } + + @Nonnull + @ReturnsMutableObject + public final char [] getTrustStorePassword () + { + return m_aPassword; + } + + @Nullable + public final Provider getProvider () + { + return m_aProvider; + } + + @Nonnull + public LoadedKeyStore loadTrustStore () + { + LoadedKeyStore ret = m_aLTS; + if (ret == null) + ret = m_aLTS = KeyStoreHelper.loadKeyStore (m_aType, m_sPath, m_aPassword, m_aProvider); + return ret; + } + + @Override + public String toString () + { + return new ToStringGenerator (null).append ("Type", m_aType) + .append ("Path", m_sPath) + .appendPassword ("Password") + .appendIfNotNull ("Provider", m_aProvider) + .getToString (); + } + + /** + * @return A new builder for {@link TrustStoreDescriptor} objects. Never + * null. + */ + @Nonnull + public static TrustStoreDescriptorBuilder builder () + { + return new TrustStoreDescriptorBuilder (); + } + + /** + * Create a new builder using the provided descriptor. + * + * @param a + * The existing descriptor. May not be null. + * @return A new builder for {@link TrustStoreDescriptor} objects. Never + * null. + */ + @Nonnull + public static TrustStoreDescriptorBuilder builder (@Nonnull final TrustStoreDescriptor a) + { + return new TrustStoreDescriptorBuilder (a); + } + + /** + * Builder class for class {@link TrustStoreDescriptor}. + * + * @author Philip Helger + */ + public static class TrustStoreDescriptorBuilder implements IBuilder + { + private IKeyStoreType m_aType; + private String m_sPath; + private char [] m_aPassword; + private Provider m_aProvider; + + public TrustStoreDescriptorBuilder () + {} + + public TrustStoreDescriptorBuilder (@Nonnull final TrustStoreDescriptor aSrc) + { + type (aSrc.m_aType).path (aSrc.m_sPath).password (aSrc.m_aPassword).provider (aSrc.m_aProvider); + } + + @Nonnull + public final TrustStoreDescriptorBuilder type (@Nullable final IKeyStoreType a) + { + m_aType = a; + return this; + } + + @Nonnull + public final TrustStoreDescriptorBuilder path (@Nullable final String s) + { + m_sPath = s; + return this; + } + + @Nonnull + public final TrustStoreDescriptorBuilder password (@Nullable final String s) + { + return password (s == null ? null : s.toCharArray ()); + } + + @Nonnull + public final TrustStoreDescriptorBuilder password (@Nullable final char [] a) + { + m_aPassword = a; + return this; + } + + @Nonnull + public final TrustStoreDescriptorBuilder provider (@Nullable final Provider a) + { + m_aProvider = a; + return this; + } + + @Nonnull + public TrustStoreDescriptor build () throws IllegalStateException + { + if (m_aType == null) + throw new IllegalStateException ("Type is missing"); + if (StringHelper.hasNoText (m_sPath)) + throw new IllegalStateException ("Path is empty"); + if (m_aPassword == null) + throw new IllegalStateException ("Password is missing"); + // Provider may be null + + return new TrustStoreDescriptor (m_aType, m_sPath, m_aPassword, m_aProvider); + } + } +} diff --git a/ph-security/src/test/java/com/helger/security/keystore/KeyStoreAndKeyDescriptorTest.java b/ph-security/src/test/java/com/helger/security/keystore/KeyStoreAndKeyDescriptorTest.java new file mode 100644 index 000000000..c4b351f5b --- /dev/null +++ b/ph-security/src/test/java/com/helger/security/keystore/KeyStoreAndKeyDescriptorTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2014-2024 Philip Helger (www.helger.com) + * philip[at]helger[dot]com + * + * 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 com.helger.security.keystore; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.junit.Test; + +/** + * Test class for class {@link KeyStoreAndKeyDescriptor}. + * + * @author Philip Helger + */ +public final class KeyStoreAndKeyDescriptorTest +{ + @Test + public void testBasic () + { + final KeyStoreAndKeyDescriptor aKD = KeyStoreAndKeyDescriptor.builder () + .type (EKeyStoreType.BKS) + .path ("keystores/keystore-pw-test.bks") + .password ("test") + .provider (new BouncyCastleProvider ()) + .keyAlias ("alias") + .keyPassword ("test") + .build (); + assertNotNull (aKD); + assertNotNull (aKD.loadKeyStore ()); + assertTrue (aKD.loadKeyStore ().isSuccess ()); + assertNotNull (aKD.loadKey ()); + assertTrue (aKD.loadKey ().isSuccess ()); + assertNotNull (aKD.toString ()); + + // Copy + final KeyStoreAndKeyDescriptor aKD2 = KeyStoreAndKeyDescriptor.builder (aKD).build (); + assertNotNull (aKD2); + assertNotNull (aKD2.loadKeyStore ()); + assertTrue (aKD2.loadKeyStore ().isSuccess ()); + assertNotNull (aKD2.loadKey ()); + assertTrue (aKD2.loadKey ().isSuccess ()); + } +} diff --git a/ph-security/src/test/java/com/helger/security/keystore/KeyStoreDescriptorTest.java b/ph-security/src/test/java/com/helger/security/keystore/KeyStoreDescriptorTest.java new file mode 100644 index 000000000..619540038 --- /dev/null +++ b/ph-security/src/test/java/com/helger/security/keystore/KeyStoreDescriptorTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2014-2024 Philip Helger (www.helger.com) + * philip[at]helger[dot]com + * + * 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 com.helger.security.keystore; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Test class for class {@link KeyStoreDescriptor}. + * + * @author Philip Helger + */ +public final class KeyStoreDescriptorTest +{ + @Test + public void testBasic () + { + final KeyStoreDescriptor aKD = KeyStoreDescriptor.builder () + .type (EKeyStoreType.JKS) + .path ("keystores/keystore-no-pw.jks") + .password ("") + .build (); + assertNotNull (aKD); + assertNotNull (aKD.loadKeyStore ()); + assertTrue (aKD.loadKeyStore ().isSuccess ()); + assertNotNull (aKD.toString ()); + + // Copy + final KeyStoreDescriptor aKD2 = KeyStoreDescriptor.builder (aKD).build (); + assertNotNull (aKD2); + assertNotNull (aKD2.loadKeyStore ()); + assertTrue (aKD2.loadKeyStore ().isSuccess ()); + } +} diff --git a/ph-security/src/test/java/com/helger/security/keystore/TrustStoreDescriptorTest.java b/ph-security/src/test/java/com/helger/security/keystore/TrustStoreDescriptorTest.java new file mode 100644 index 000000000..2714f0cfb --- /dev/null +++ b/ph-security/src/test/java/com/helger/security/keystore/TrustStoreDescriptorTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2014-2024 Philip Helger (www.helger.com) + * philip[at]helger[dot]com + * + * 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 com.helger.security.keystore; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Test class for class {@link TrustStoreDescriptor}. + * + * @author Philip Helger + */ +public final class TrustStoreDescriptorTest +{ + @Test + public void testBasic () + { + final TrustStoreDescriptor aTD = TrustStoreDescriptor.builder () + .type (EKeyStoreType.JKS) + .path ("keystores/truststore-peppol-pilot.jks") + .password ("peppol") + .build (); + assertNotNull (aTD); + assertNotNull (aTD.loadTrustStore ()); + assertTrue (aTD.loadTrustStore ().isSuccess ()); + assertNotNull (aTD.toString ()); + + // Copy + final TrustStoreDescriptor aTD2 = TrustStoreDescriptor.builder (aTD).build (); + assertNotNull (aTD2); + assertNotNull (aTD2.loadTrustStore ()); + assertTrue (aTD2.loadTrustStore ().isSuccess ()); + } +}