View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.net.ssl;
15  
16  import java.io.FileNotFoundException;
17  import java.io.IOException;
18  import java.io.InputStream;
19  import java.net.URL;
20  import java.security.KeyStore;
21  import java.security.KeyStoreException;
22  import java.security.NoSuchAlgorithmException;
23  import java.security.NoSuchProviderException;
24  
25  import ch.qos.logback.core.util.LocationUtil;
26  
27  /**
28   * A factory bean for a JCA {@link KeyStore}.
29   * <p>
30   * This object holds the configurable properties of a key store and uses them to
31   * create and load a {@link KeyStore} instance.
32   *
33   * @author Carl Harris
34   */
35  public class KeyStoreFactoryBean {
36  
37      private String location;
38      private String provider;
39      private String type;
40      private String password;
41  
42      /**
43       * Creates a new {@link KeyStore} using the receiver's configuration.
44       * 
45       * @return key store
46       * @throws NoSuchProviderException  if the provider specified by
47       *                                  {@link #setProvider(String)} is not known to
48       *                                  the platform
49       * @throws NoSuchAlgorithmException if the key store type specified by
50       *                                  {@link #setType(String)} is not known to the
51       *                                  specified provider (or the platform's
52       *                                  default provider if the provider isn't
53       *                                  specified)
54       * @throws KeyStoreException        if some other error occurs in loading the
55       *                                  key store from the resource specified by
56       *                                  {@link #setLocation(String)}
57       */
58      public KeyStore createKeyStore() throws NoSuchProviderException, NoSuchAlgorithmException, KeyStoreException {
59  
60          if (getLocation() == null) {
61              throw new IllegalArgumentException("location is required");
62          }
63  
64          InputStream inputStream = null;
65          try {
66              URL url = LocationUtil.urlForResource(getLocation());
67              inputStream = url.openStream();
68              KeyStore keyStore = newKeyStore();
69              keyStore.load(inputStream, getPassword().toCharArray());
70              return keyStore;
71          } catch (NoSuchProviderException ex) {
72              throw new NoSuchProviderException("no such keystore provider: " + getProvider());
73          } catch (NoSuchAlgorithmException ex) {
74              throw new NoSuchAlgorithmException("no such keystore type: " + getType());
75          } catch (FileNotFoundException ex) {
76              throw new KeyStoreException(getLocation() + ": file not found");
77          } catch (Exception ex) {
78              throw new KeyStoreException(getLocation() + ": " + ex.getMessage(), ex);
79          } finally {
80              try {
81                  if (inputStream != null) {
82                      inputStream.close();
83                  }
84              } catch (IOException ex) {
85                  ex.printStackTrace(System.err);
86              }
87          }
88      }
89  
90      /**
91       * Invokes the appropriate JCE factory method to obtain a new {@link KeyStore}
92       * object.
93       */
94      private KeyStore newKeyStore() throws NoSuchAlgorithmException, NoSuchProviderException, KeyStoreException {
95  
96          return getProvider() != null ? KeyStore.getInstance(getType(), getProvider()) : KeyStore.getInstance(getType());
97      }
98  
99      /**
100      * Gets the location of the key store resource.
101      * 
102      * @return a String containing a URL for the resource
103      */
104     public String getLocation() {
105         return location;
106     }
107 
108     /**
109      * Sets the location of the key store resource.
110      * 
111      * @param location a String containing a URL for the resource; if the URL string
112      *                 isn't prefixed by a scheme, the path is assumed to be
113      *                 relative to the root of the classpath.
114      */
115     public void setLocation(String location) {
116         this.location = location;
117     }
118 
119     /**
120      * Gets the type of key store to load.
121      * 
122      * @return a key store type name (e.g. {@code JKS}); the
123      *         {@link SSL#DEFAULT_KEYSTORE_TYPE} is returned if no type has been
124      *         configured
125      */
126     public String getType() {
127         if (type == null) {
128             return SSL.DEFAULT_KEYSTORE_TYPE;
129         }
130         return type;
131     }
132 
133     /**
134      * Sets the type of key store to load.
135      * 
136      * @param type a key store type name (e.g. {@code JKS}, {@code PKCS12}); the
137      *             type specified must be supported by the provider specified by
138      *             {@link #setProvider(String)} or by the platform's default
139      *             provider if no provider is specified
140      */
141     public void setType(String type) {
142         this.type = type;
143     }
144 
145     /**
146      * Gets the JCA key store provider name.
147      * 
148      * @return provider name or {@code null} if no provider has been configured
149      */
150     public String getProvider() {
151         return provider;
152     }
153 
154     /**
155      * Sets the JCA key store provider name.
156      * 
157      * @param provider name of the JCA provider to utilize in creating the key store
158      */
159     public void setProvider(String provider) {
160         this.provider = provider;
161     }
162 
163     /**
164      * Gets the password to use to access the key store.
165      * 
166      * @return password string; the {@link SSL#DEFAULT_KEYSTORE_PASSWORD} is
167      *         returned if no password has been configured
168      */
169     public String getPassword() {
170         if (password == null) {
171             return SSL.DEFAULT_KEYSTORE_PASSWORD;
172         }
173         return password;
174     }
175 
176     /**
177      * Sets the password to use to access the keystore.
178      * 
179      * @param password the password to set
180      */
181     public void setPassword(String password) {
182         this.password = password;
183     }
184 
185 }