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 }