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            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 (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    public static TrustStoreConfiguration createKeyStoreConfiguration(
119            // @formatter:off
120            final String location,
121            final char[] password,
122            final String keyStoreType,
123            final String trustManagerFactoryAlgorithm) throws StoreConfigurationException {
124        // @formatter:on
125        return createKeyStoreConfiguration(location, password, null, null, keyStoreType, trustManagerFactoryAlgorithm);
126    }
127
128    /**
129     * Creates a KeyStoreConfiguration.
130     *
131     * @param location The location of the KeyStore, a file path, URL or resource.
132     * @param password The password to access the KeyStore.
133     * @param keyStoreType The KeyStore type, null defaults to {@code "JKS"}.
134     * @param trustManagerFactoryAlgorithm The standard name of the requested trust management algorithm. See the Java
135     * Secure Socket Extension Reference Guide for information these names.
136     * @return a new TrustStoreConfiguration
137     * @throws StoreConfigurationException Thrown if this instance cannot load the KeyStore.
138     * @deprecated Use createKeyStoreConfiguration(String, char[], String, String)
139     */
140    @Deprecated
141    public static TrustStoreConfiguration createKeyStoreConfiguration(
142            // @formatter:off
143            final String location,
144            final String password,
145            final String keyStoreType,
146            final String trustManagerFactoryAlgorithm) throws StoreConfigurationException {
147            // @formatter:on
148        return createKeyStoreConfiguration(location, (password == null ? null : password.toCharArray()),
149                null, null, keyStoreType, trustManagerFactoryAlgorithm);
150    }
151
152    public TrustManagerFactory initTrustManagerFactory() throws NoSuchAlgorithmException, KeyStoreException {
153        final TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(this.trustManagerFactoryAlgorithm);
154        tmFactory.init(this.getKeyStore());
155        return tmFactory;
156    }
157
158    @Override
159    public int hashCode() {
160        final int prime = 31;
161        int result = super.hashCode();
162        result = prime * result
163                + ((trustManagerFactoryAlgorithm == null) ? 0 : trustManagerFactoryAlgorithm.hashCode());
164        return result;
165    }
166
167    @Override
168    public boolean equals(final Object obj) {
169        if (this == obj) {
170            return true;
171        }
172        if (!super.equals(obj)) {
173            return false;
174        }
175        if (getClass() != obj.getClass()) {
176            return false;
177        }
178        final TrustStoreConfiguration other = (TrustStoreConfiguration) obj;
179        if (trustManagerFactoryAlgorithm == null) {
180            if (other.trustManagerFactoryAlgorithm != null) {
181                return false;
182            }
183        } else if (!trustManagerFactoryAlgorithm.equals(other.trustManagerFactoryAlgorithm)) {
184            return false;
185        }
186        return true;
187    }
188
189    public String getTrustManagerFactoryAlgorithm() {
190        return trustManagerFactoryAlgorithm;
191    }
192}