View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.net.ssl;
18  
19  import java.io.FileNotFoundException;
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.security.KeyStore;
23  import java.security.KeyStoreException;
24  import java.security.NoSuchAlgorithmException;
25  import java.security.cert.CertificateException;
26  import java.util.Arrays;
27  
28  import org.apache.logging.log4j.core.config.ConfigurationSource;
29  import org.apache.logging.log4j.core.util.NetUtils;
30  
31  /**
32   * Configuration of the KeyStore
33   */
34  public class AbstractKeyStoreConfiguration extends StoreConfiguration<KeyStore> {
35      private final KeyStore keyStore;
36      private final String keyStoreType;
37  
38      public AbstractKeyStoreConfiguration(final String location, final PasswordProvider passwordProvider, final String keyStoreType)
39              throws StoreConfigurationException {
40          super(location, passwordProvider);
41          this.keyStoreType = keyStoreType == null ? SslConfigurationDefaults.KEYSTORE_TYPE : keyStoreType;
42          this.keyStore = this.load();
43      }
44  
45      /**
46       * @deprecated Use {@link #AbstractKeyStoreConfiguration(String, PasswordProvider, String)} instead
47       */
48      @Deprecated
49      public AbstractKeyStoreConfiguration(final String location, final char[] password, final String keyStoreType)
50              throws StoreConfigurationException {
51          this(location, new MemoryPasswordProvider(password), keyStoreType);
52      }
53  
54      /**
55       * @deprecated Use {@link #AbstractKeyStoreConfiguration(String, PasswordProvider, String)} instead
56       */
57      @Deprecated
58      public AbstractKeyStoreConfiguration(final String location, final String password, final String keyStoreType)
59              throws StoreConfigurationException {
60          this(location, new MemoryPasswordProvider(password == null ? null : password.toCharArray()), keyStoreType);
61      }
62  
63      @Override
64      protected KeyStore load() throws StoreConfigurationException {
65          final String loadLocation = this.getLocation();
66          LOGGER.debug("Loading keystore from location {}", loadLocation);
67          try {
68              if (loadLocation == null) {
69                  throw new IOException("The location is null");
70              }
71              try (final InputStream fin = openInputStream(loadLocation)) {
72                  final KeyStore ks = KeyStore.getInstance(this.keyStoreType);
73                  final char[] password = this.getPasswordAsCharArray();
74                  try {
75                      ks.load(fin, password);
76                  } finally {
77                      if (password != null) {
78                          Arrays.fill(password, '\0');
79                      }
80                  }
81                  LOGGER.debug("KeyStore successfully loaded from location {}", loadLocation);
82                  return ks;
83              }
84          } catch (final CertificateException e) {
85              LOGGER.error("No Provider supports a KeyStoreSpi implementation for the specified type {} for location {}", this.keyStoreType, loadLocation, e);
86              throw new StoreConfigurationException(loadLocation, e);
87          } catch (final NoSuchAlgorithmException e) {
88              LOGGER.error("The algorithm used to check the integrity of the keystore cannot be found for location {}", loadLocation, e);
89              throw new StoreConfigurationException(loadLocation, e);
90          } catch (final KeyStoreException e) {
91              LOGGER.error("KeyStoreException for location {}", loadLocation, e);
92              throw new StoreConfigurationException(loadLocation, e);
93          } catch (final FileNotFoundException e) {
94              LOGGER.error("The keystore file {} is not found", loadLocation, e);
95              throw new StoreConfigurationException(loadLocation, e);
96          } catch (final IOException e) {
97              LOGGER.error("Something is wrong with the format of the keystore or the given password for location", loadLocation, e);
98              throw new StoreConfigurationException(loadLocation, e);
99          }
100     }
101 
102     private InputStream openInputStream(final String filePathOrUri) {
103         return ConfigurationSource.fromUri(NetUtils.toURI(filePathOrUri)).getInputStream();
104     }
105 
106     public KeyStore getKeyStore() {
107         return this.keyStore;
108     }
109 
110     @Override
111     public int hashCode() {
112         final int prime = 31;
113         int result = super.hashCode();
114         result = prime * result + ((keyStore == null) ? 0 : keyStore.hashCode());
115         result = prime * result + ((keyStoreType == null) ? 0 : keyStoreType.hashCode());
116         return result;
117     }
118 
119     @Override
120     public boolean equals(final Object obj) {
121         if (this == obj) {
122             return true;
123         }
124         if (!super.equals(obj)) {
125             return false;
126         }
127         if (getClass() != obj.getClass()) {
128             return false;
129         }
130         final AbstractKeyStoreConfiguration other = (AbstractKeyStoreConfiguration) obj;
131         if (keyStore == null) {
132             if (other.keyStore != null) {
133                 return false;
134             }
135         } else if (!keyStore.equals(other.keyStore)) {
136             return false;
137         }
138         if (keyStoreType == null) {
139             if (other.keyStoreType != null) {
140                 return false;
141             }
142         } else if (!keyStoreType.equals(other.keyStoreType)) {
143             return false;
144         }
145         return true;
146     }
147 
148     public String getKeyStoreType() {
149         return keyStoreType;
150     }
151 
152 }