1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *
19 */
20 package org.apache.mina.filter.ssl;
21
22 import java.io.BufferedInputStream;
23 import java.io.ByteArrayInputStream;
24 import java.io.ByteArrayOutputStream;
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.net.URL;
30 import java.security.KeyStore;
31 import java.security.KeyStoreException;
32 import java.security.NoSuchAlgorithmException;
33 import java.security.NoSuchProviderException;
34 import java.security.cert.CertificateException;
35
36 /**
37 * A factory that creates and configures a new {@link KeyStore} instance.
38 *
39 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
40 */
41 public class KeyStoreFactory {
42
43 private String type = "JKS";
44
45 private String provider = null;
46
47 private char[] password = null;
48
49 private byte[] data = null;
50
51 /**
52 * Creates a new {@link KeyStore}. This method will be called
53 * by the base class when Spring creates a bean using this FactoryBean.
54 *
55 * @return a new {@link KeyStore} instance.
56 */
57 public KeyStore newInstance() throws KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException,
58 CertificateException, IOException {
59 if (data == null) {
60 throw new IllegalStateException("data property is not set.");
61 }
62
63 KeyStore ks;
64 if (provider == null) {
65 ks = KeyStore.getInstance(type);
66 } else {
67 ks = KeyStore.getInstance(type, provider);
68 }
69
70 InputStream is = new ByteArrayInputStream(data);
71 try {
72 ks.load(is, password);
73 } finally {
74 try {
75 is.close();
76 } catch (IOException ignored) {
77 // Do nothing
78 }
79 }
80
81 return ks;
82 }
83
84 /**
85 * Sets the type of key store to create. The default is to create a
86 * JKS key store.
87 *
88 * @param type the type to use when creating the key store.
89 * @throws IllegalArgumentException if the specified value is
90 * <code>null</code>.
91 */
92 public void setType(String type) {
93 if (type == null) {
94 throw new IllegalArgumentException("type");
95 }
96 this.type = type;
97 }
98
99 /**
100 * Sets the key store password. If this value is <code>null</code> no
101 * password will be used to check the integrity of the key store.
102 *
103 * @param password the password or <code>null</code> if no password is
104 * needed.
105 */
106 public void setPassword(String password) {
107 if (password != null) {
108 this.password = password.toCharArray();
109 } else {
110 this.password = null;
111 }
112 }
113
114 /**
115 * Sets the name of the provider to use when creating the key store. The
116 * default is to use the platform default provider.
117 *
118 * @param provider the name of the provider, e.g. <tt>"SUN"</tt>.
119 */
120 public void setProvider(String provider) {
121 this.provider = provider;
122 }
123
124 /**
125 * Sets the data which contains the key store.
126 *
127 * @param data the byte array that contains the key store
128 */
129 public void setData(byte[] data) {
130 byte[] copy = new byte[data.length];
131 System.arraycopy(data, 0, copy, 0, data.length);
132 this.data = copy;
133 }
134
135 /**
136 * Sets the data which contains the key store.
137 *
138 * @param dataStream the {@link InputStream} that contains the key store
139 */
140 private void setData(InputStream dataStream) throws IOException {
141 ByteArrayOutputStream out = new ByteArrayOutputStream();
142 try {
143 for (;;) {
144 int data = dataStream.read();
145 if (data < 0) {
146 break;
147 }
148 out.write(data);
149 }
150 setData(out.toByteArray());
151 } finally {
152 try {
153 dataStream.close();
154 } catch (IOException e) {
155 // Ignore.
156 }
157 }
158 }
159
160 /**
161 * Sets the data which contains the key store.
162 *
163 * @param dataFile the {@link File} that contains the key store
164 */
165 public void setDataFile(File dataFile) throws IOException {
166 setData(new BufferedInputStream(new FileInputStream(dataFile)));
167 }
168
169 /**
170 * Sets the data which contains the key store.
171 *
172 * @param dataUrl the {@link URL} that contains the key store.
173 */
174 public void setDataUrl(URL dataUrl) throws IOException {
175 setData(dataUrl.openStream());
176 }
177 }