001/*
002 * Copyright 2023 the original author or authors.
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * https://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.cuioss.tools.net.ssl;
017
018import java.io.Serializable;
019import java.util.Base64;
020
021import lombok.Builder;
022import lombok.EqualsAndHashCode;
023import lombok.Getter;
024import lombok.NonNull;
025import lombok.ToString;
026
027/**
028 * Runtime representation of key-material. The actual key is provided as byte[].
029 * An optional keyPassword is available as well.
030 *
031 * @author Oliver Wolff
032 *
033 */
034@Builder
035@EqualsAndHashCode(exclude = { "keyMaterial", "keyPassword" }, doNotUseGetters = true)
036@ToString(exclude = { "keyMaterial", "keyPassword" }, doNotUseGetters = true)
037public final class KeyMaterialHolder implements Serializable {
038
039    private static final long serialVersionUID = -3125499798220509939L;
040
041    @Getter
042    @NonNull
043    private final byte[] keyMaterial;
044
045    /**
046     * (Optional) password for the key, or in case of
047     * {@link KeyHolderType#KEY_STORE} for the store.
048     */
049    @Getter
050    private final String keyPassword;
051
052    /**
053     * Optional: An arbitrary name for displaying the key in an ui or logging
054     * context.
055     */
056    @Getter
057    private final String name;
058
059    /** Optional: additional information transporting some context-information. */
060    @Getter
061    private final String description;
062
063    /** Optional: An alias name for a given key. */
064    @Getter
065    private final String keyAlias;
066
067    @Getter
068    @Builder.Default
069    @SuppressWarnings("squid:S1170") // owolff: False positive: This is input for @Builder, no
070    // constant, especially not public
071    private final KeyHolderType keyHolderType = KeyHolderType.SINGLE_KEY;
072
073    @Getter
074    @Builder.Default
075    @SuppressWarnings("squid:S1170") // owolff: False positive: This is input for @Builder, no
076    // constant, especially not public
077    private final KeyAlgorithm keyAlgorithm = KeyAlgorithm.UNDEFINED;
078
079    /**
080     * @return NPE-safe char-array representation of {@link #getKeyPassword()}. If
081     *         keyPassword is {@code null} or empty it returns an empty char[],
082     *         never {@code null}
083     */
084    public char[] getKeyPasswordAsCharArray() {
085        return KeyStoreProvider.toCharArray(keyPassword);
086    }
087
088    /**
089     * @param serializedKeyMaterial the Base64 encoded key material
090     *
091     * @return Raw i.e. original key material
092     * @throws IllegalArgumentException if serializedKeyMaterial is not Base64
093     *                                  encoded
094     */
095    public static byte[] deserializeKeyMaterial(final String serializedKeyMaterial) {
096        return Base64.getDecoder().decode(serializedKeyMaterial);
097    }
098
099    /**
100     * @param keyMaterial Raw i.e. original key material
101     *
102     * @return Base64 encoded key material
103     */
104    public static String serializeKeyMaterial(final byte[] keyMaterial) {
105        return Base64.getEncoder().encodeToString(keyMaterial);
106    }
107}