View Javadoc

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 }