001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017package org.apache.logging.log4j.core.net.ssl;
018
019import java.security.KeyStoreException;
020import java.security.NoSuchAlgorithmException;
021import java.util.Arrays;
022
023import javax.net.ssl.TrustManagerFactory;
024
025import org.apache.logging.log4j.core.Core;
026import org.apache.logging.log4j.core.config.plugins.Plugin;
027import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
028import org.apache.logging.log4j.core.config.plugins.PluginFactory;
029
030/**
031 * Configuration of the TrustStore
032 */
033@Plugin(name = "TrustStore", category = Core.CATEGORY_NAME, printObject = true)
034public class TrustStoreConfiguration extends AbstractKeyStoreConfiguration {
035
036    private final String trustManagerFactoryAlgorithm;
037
038    public TrustStoreConfiguration(final String location,
039                                   final PasswordProvider passwordProvider,
040                                   final String keyStoreType,
041                                   final String trustManagerFactoryAlgorithm) throws StoreConfigurationException {
042        super(location, passwordProvider, keyStoreType);
043        this.trustManagerFactoryAlgorithm = trustManagerFactoryAlgorithm == null ? TrustManagerFactory
044                .getDefaultAlgorithm() : trustManagerFactoryAlgorithm;
045    }
046
047    /**
048     * @deprecated Use {@link #TrustStoreConfiguration(String, PasswordProvider, String, String)} instead
049     */
050    @Deprecated
051    public TrustStoreConfiguration(final String location, final char[] password, final String keyStoreType,
052            final String trustManagerFactoryAlgorithm) throws StoreConfigurationException {
053        this(location, new MemoryPasswordProvider(password), keyStoreType, trustManagerFactoryAlgorithm);
054        if (password != null) {
055            Arrays.fill(password, '\0');
056        }
057    }
058
059    /**
060     * @deprecated Use {@link #TrustStoreConfiguration(String, PasswordProvider, String, String)} instead
061     */
062    @Deprecated
063    public TrustStoreConfiguration(final String location, final String password, final String keyStoreType,
064            final String trustManagerFactoryAlgorithm) throws StoreConfigurationException {
065        this(location, new MemoryPasswordProvider(password == null ? null : password.toCharArray()), keyStoreType,
066                trustManagerFactoryAlgorithm);
067    }
068
069    /**
070     * Creates a KeyStoreConfiguration.
071     *
072     * @param location
073     *        The location of the KeyStore, a file path, URL or resource.
074     * @param password
075     *        The password to access the KeyStore.
076     * @param keyStoreType
077     *        The KeyStore type, null defaults to {@code "JKS"}.
078     * @param trustManagerFactoryAlgorithm
079     *        The standard name of the requested trust management algorithm. See the Java Secure Socket Extension Reference Guide for information these names.
080     * @return a new TrustStoreConfiguration
081     * @throws StoreConfigurationException Thrown if this instance cannot load the KeyStore.
082     */
083    @PluginFactory
084    public static TrustStoreConfiguration createKeyStoreConfiguration(
085            // @formatter:off
086            @PluginAttribute("location") final String location,
087            @PluginAttribute(value = "password", sensitive = true) final char[] password,
088            @PluginAttribute("passwordEnvironmentVariable") final String passwordEnvironmentVariable,
089            @PluginAttribute("passwordFile") final String passwordFile,
090            @PluginAttribute("type") final String keyStoreType,
091            @PluginAttribute("trustManagerFactoryAlgorithm") final String trustManagerFactoryAlgorithm) throws StoreConfigurationException {
092            // @formatter:on
093
094        if (password != null && passwordEnvironmentVariable != null && passwordFile != null) {
095            throw new IllegalStateException("You MUST set only one of 'password', 'passwordEnvironmentVariable' or 'passwordFile'.");
096        }
097        try {
098            // @formatter:off
099            final PasswordProvider provider = passwordFile != null
100                    ? new FilePasswordProvider(passwordFile)
101                    : passwordEnvironmentVariable != null
102                            ? new EnvironmentPasswordProvider(passwordEnvironmentVariable)
103                            // the default is memory char[] array, which may be null
104                            : new MemoryPasswordProvider(password);
105            // @formatter:on
106            if (password != null) {
107                Arrays.fill(password, '\0');
108            }
109            return new TrustStoreConfiguration(location, provider, keyStoreType, trustManagerFactoryAlgorithm);
110        } catch (final Exception ex) {
111            throw new StoreConfigurationException("Could not configure TrustStore", ex);
112        }
113    }
114
115    /**
116     * @deprecated Use {@link #createKeyStoreConfiguration(String, char[], String, String, String, String)}
117     */
118    @Deprecated
119    public static TrustStoreConfiguration createKeyStoreConfiguration(
120            // @formatter:off
121            final String location,
122            final char[] password,
123            final String keyStoreType,
124            final String trustManagerFactoryAlgorithm) throws StoreConfigurationException {
125        // @formatter:on
126        return createKeyStoreConfiguration(location, password, null, null, keyStoreType, trustManagerFactoryAlgorithm);
127    }
128
129    /**
130     * Creates a KeyStoreConfiguration.
131     *
132     * @param location The location of the KeyStore, a file path, URL or resource.
133     * @param password The password to access the KeyStore.
134     * @param keyStoreType The KeyStore type, null defaults to {@code "JKS"}.
135     * @param trustManagerFactoryAlgorithm The standard name of the requested trust management algorithm. See the Java
136     * Secure Socket Extension Reference Guide for information these names.
137     * @return a new TrustStoreConfiguration
138     * @throws StoreConfigurationException Thrown if this instance cannot load the KeyStore.
139     * @deprecated Use createKeyStoreConfiguration(String, char[], String, String)
140     */
141    @Deprecated
142    public static TrustStoreConfiguration createKeyStoreConfiguration(
143            // @formatter:off
144            final String location,
145            final String password,
146            final String keyStoreType,
147            final String trustManagerFactoryAlgorithm) throws StoreConfigurationException {
148            // @formatter:on
149        return createKeyStoreConfiguration(location, (password == null ? null : password.toCharArray()),
150                null, null, keyStoreType, trustManagerFactoryAlgorithm);
151    }
152
153    public TrustManagerFactory initTrustManagerFactory() throws NoSuchAlgorithmException, KeyStoreException {
154        final TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(this.trustManagerFactoryAlgorithm);
155        tmFactory.init(this.getKeyStore());
156        return tmFactory;
157    }
158
159    @Override
160    public int hashCode() {
161        final int prime = 31;
162        int result = super.hashCode();
163        result = prime * result
164                + ((trustManagerFactoryAlgorithm == null) ? 0 : trustManagerFactoryAlgorithm.hashCode());
165        return result;
166    }
167
168    @Override
169    public boolean equals(final Object obj) {
170        if (this == obj) {
171            return true;
172        }
173        if (!super.equals(obj)) {
174            return false;
175        }
176        if (getClass() != obj.getClass()) {
177            return false;
178        }
179        final TrustStoreConfiguration other = (TrustStoreConfiguration) obj;
180        if (trustManagerFactoryAlgorithm == null) {
181            if (other.trustManagerFactoryAlgorithm != null) {
182                return false;
183            }
184        } else if (!trustManagerFactoryAlgorithm.equals(other.trustManagerFactoryAlgorithm)) {
185            return false;
186        }
187        return true;
188    }
189
190    public String getTrustManagerFactoryAlgorithm() {
191        return trustManagerFactoryAlgorithm;
192    }
193}