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.security.UnrecoverableKeyException; 022import java.util.Arrays; 023 024import javax.net.ssl.KeyManagerFactory; 025 026import org.apache.logging.log4j.core.Core; 027import org.apache.logging.log4j.core.config.plugins.Plugin; 028import org.apache.logging.log4j.core.config.plugins.PluginAttribute; 029import org.apache.logging.log4j.core.config.plugins.PluginFactory; 030 031/** 032 * Configuration of the KeyStore 033 */ 034@Plugin(name = "KeyStore", category = Core.CATEGORY_NAME, printObject = true) 035public class KeyStoreConfiguration extends AbstractKeyStoreConfiguration { 036 037 private final String keyManagerFactoryAlgorithm; 038 039 /** 040 * 041 * @throws StoreConfigurationException Thrown if this instance cannot load the KeyStore. 042 */ 043 public KeyStoreConfiguration(final String location, 044 final PasswordProvider passwordProvider, 045 final String keyStoreType, 046 final String keyManagerFactoryAlgorithm) throws StoreConfigurationException { 047 super(location, passwordProvider, keyStoreType); 048 this.keyManagerFactoryAlgorithm = keyManagerFactoryAlgorithm == null ? KeyManagerFactory.getDefaultAlgorithm() 049 : keyManagerFactoryAlgorithm; 050 } 051 052 /** 053 * 054 * @throws StoreConfigurationException Thrown if this instance cannot load the KeyStore. 055 * @deprecated use {@link #KeyStoreConfiguration(String, PasswordProvider, String, String)} instead 056 */ 057 @Deprecated 058 public KeyStoreConfiguration(final String location, 059 final char[] password, 060 final String keyStoreType, 061 final String keyManagerFactoryAlgorithm) throws StoreConfigurationException { 062 this(location, new MemoryPasswordProvider(password), keyStoreType, keyManagerFactoryAlgorithm); 063 if (password != null) { 064 Arrays.fill(password, '\0'); 065 } 066 } 067 068 /** 069 * 070 * @throws StoreConfigurationException Thrown if this instance cannot load the KeyStore. 071 * @deprecated Use {@link #KeyStoreConfiguration(String, PasswordProvider, String, String)} instead 072 */ 073 @Deprecated 074 public KeyStoreConfiguration(final String location, final String password, final String keyStoreType, 075 final String keyManagerFactoryAlgorithm) throws StoreConfigurationException { 076 this(location, new MemoryPasswordProvider(password == null ? null : password.toCharArray()), keyStoreType, 077 keyManagerFactoryAlgorithm); 078 } 079 080 /** 081 * Creates a KeyStoreConfiguration. 082 * 083 * @param location 084 * The location of the KeyStore, a file path, URL or resource. 085 * @param password 086 * The password to access the KeyStore. 087 * @param keyStoreType 088 * The KeyStore type, null defaults to {@code "JKS"}. 089 * @param keyManagerFactoryAlgorithm 090 * The standard name of the requested algorithm. See the Java Secure Socket Extension Reference Guide for information about these names. 091 * @return a new KeyStoreConfiguration 092 * @throws StoreConfigurationException Thrown if this call cannot load the KeyStore. 093 */ 094 @PluginFactory 095 public static KeyStoreConfiguration createKeyStoreConfiguration( 096 // @formatter:off 097 @PluginAttribute("location") final String location, 098 @PluginAttribute(value = "password", sensitive = true) final char[] password, 099 @PluginAttribute("passwordEnvironmentVariable") final String passwordEnvironmentVariable, 100 @PluginAttribute("passwordFile") final String passwordFile, 101 @PluginAttribute("type") final String keyStoreType, 102 @PluginAttribute("keyManagerFactoryAlgorithm") final String keyManagerFactoryAlgorithm) throws StoreConfigurationException { 103 // @formatter:on 104 105 if (password != null && passwordEnvironmentVariable != null && passwordFile != null) { 106 throw new StoreConfigurationException("You MUST set only one of 'password', 'passwordEnvironmentVariable' or 'passwordFile'."); 107 } 108 try { 109 // @formatter:off 110 final PasswordProvider provider = passwordFile != null 111 ? new FilePasswordProvider(passwordFile) 112 : passwordEnvironmentVariable != null 113 ? new EnvironmentPasswordProvider(passwordEnvironmentVariable) 114 // the default is memory char[] array, which may be null 115 : new MemoryPasswordProvider(password); 116 // @formatter:on 117 if (password != null) { 118 Arrays.fill(password, '\0'); 119 } 120 return new KeyStoreConfiguration(location, provider, keyStoreType, keyManagerFactoryAlgorithm); 121 } catch (final Exception ex) { 122 throw new StoreConfigurationException("Could not configure KeyStore", ex); 123 } 124 } 125 126 /** 127 * @deprecated use {@link #createKeyStoreConfiguration(String, char[], String, String, String, String)} 128 */ 129 @Deprecated 130 public static KeyStoreConfiguration createKeyStoreConfiguration( 131 // @formatter:off 132 final String location, 133 final char[] password, 134 final String keyStoreType, 135 final String keyManagerFactoryAlgorithm) throws StoreConfigurationException { 136 // @formatter:on 137 return createKeyStoreConfiguration(location, password, null, null, keyStoreType, keyManagerFactoryAlgorithm); 138 } 139 140 /** 141 * Creates a KeyStoreConfiguration. 142 * 143 * @param location The location of the KeyStore, a file path, URL or resource. 144 * @param password The password to access the KeyStore. 145 * @param keyStoreType The KeyStore type, null defaults to {@code "JKS"}. 146 * @param keyManagerFactoryAlgorithm The standard name of the requested algorithm. See the Java Secure Socket 147 * Extension Reference Guide for information about these names. 148 * @return a new KeyStoreConfiguration 149 * @throws StoreConfigurationException Thrown if this call cannot load the KeyStore. 150 * @deprecated Use createKeyStoreConfiguration(String, char[], String, String) 151 */ 152 @Deprecated 153 public static KeyStoreConfiguration createKeyStoreConfiguration( 154 // @formatter:off 155 final String location, 156 final String password, 157 final String keyStoreType, 158 final String keyManagerFactoryAlgorithm) throws StoreConfigurationException { 159 // @formatter:on 160 return createKeyStoreConfiguration(location, 161 (password == null ? null : password.toCharArray()), 162 keyStoreType, 163 keyManagerFactoryAlgorithm); 164 } 165 166 public KeyManagerFactory initKeyManagerFactory() throws NoSuchAlgorithmException, UnrecoverableKeyException, 167 KeyStoreException { 168 final KeyManagerFactory kmFactory = KeyManagerFactory.getInstance(this.keyManagerFactoryAlgorithm); 169 final char[] password = this.getPasswordAsCharArray(); 170 try { 171 kmFactory.init(this.getKeyStore(), password); 172 } finally { 173 if (password != null) { 174 Arrays.fill(password, '\0'); 175 } 176 } 177 return kmFactory; 178 } 179 180 @Override 181 public int hashCode() { 182 final int prime = 31; 183 int result = super.hashCode(); 184 result = prime * result + ((keyManagerFactoryAlgorithm == null) ? 0 : keyManagerFactoryAlgorithm.hashCode()); 185 return result; 186 } 187 188 @Override 189 public boolean equals(final Object obj) { 190 if (this == obj) { 191 return true; 192 } 193 if (!super.equals(obj)) { 194 return false; 195 } 196 if (getClass() != obj.getClass()) { 197 return false; 198 } 199 final KeyStoreConfiguration other = (KeyStoreConfiguration) obj; 200 if (keyManagerFactoryAlgorithm == null) { 201 if (other.keyManagerFactoryAlgorithm != null) { 202 return false; 203 } 204 } else if (!keyManagerFactoryAlgorithm.equals(other.keyManagerFactoryAlgorithm)) { 205 return false; 206 } 207 return true; 208 } 209 210 public String getKeyManagerFactoryAlgorithm() { 211 return keyManagerFactoryAlgorithm; 212 } 213}