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 The Apache MINA Project (dev@mina.apache.org)
40   * @version $Rev: 611323 $, $Date: 2008-01-11 23:40:46 +0100 (ven, 11 jan 2008) $
41   */
42  public class KeyStoreFactory {
43      
44      private String type = "JKS";
45      private String provider = null;
46      private char[] password = null;
47      private byte[] data = null;
48  
49      /**
50       * Creates a new {@link KeyStore}. This method will be called
51       * by the base class when Spring creates a bean using this FactoryBean.
52       *
53       * @return a new {@link KeyStore} instance.
54       */
55      public KeyStore newInstance() throws KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException, CertificateException, IOException {
56          if (data == null) {
57              throw new IllegalStateException("data property is not set.");
58          }
59  
60          KeyStore ks;
61          if (provider == null) {
62              ks = KeyStore.getInstance(type);
63          } else {
64              ks = KeyStore.getInstance(type, provider);
65          }
66  
67          InputStream is = new ByteArrayInputStream(data);
68          try {
69              ks.load(is, password);
70          } finally {
71              try {
72                  is.close();
73              } catch (IOException ignored) {
74              }
75          }
76  
77          return ks;
78      }
79  
80      /**
81       * Sets the type of key store to create. The default is to create a
82       * JKS key store.
83       *
84       * @param type the type to use when creating the key store.
85       * @throws IllegalArgumentException if the specified value is
86       *         <code>null</code>.
87       */
88      public void setType(String type) {
89          if (type == null) {
90              throw new NullPointerException("type");
91          }
92          this.type = type;
93      }
94  
95      /**
96       * Sets the key store password. If this value is <code>null</code> no
97       * password will be used to check the integrity of the key store.
98       *
99       * @param password the password or <code>null</code> if no password is
100      *        needed.
101      */
102     public void setPassword(String password) {
103         if (password != null) {
104             this.password = password.toCharArray();
105         } else {
106             this.password = null;
107         }
108     }
109 
110     /**
111      * Sets the name of the provider to use when creating the key store. The
112      * default is to use the platform default provider.
113      *
114      * @param provider the name of the provider, e.g. <tt>"SUN"</tt>.
115      */
116     public void setProvider(String provider) {
117         this.provider = provider;
118     }
119 
120     /**
121      * Sets the data which contains the key store.
122      *
123      * @param data the byte array that contains the key store
124      */
125     public void setData(byte[] data) {
126         byte[] copy = new byte[data.length];
127         System.arraycopy(data, 0, copy, 0, data.length);
128         this.data = copy;
129     }
130     
131     /**
132      * Sets the data which contains the key store.
133      *
134      * @param dataStream the {@link InputStream} that contains the key store
135      */
136     private void setData(InputStream dataStream) throws IOException {
137         ByteArrayOutputStream out = new ByteArrayOutputStream();
138         try {
139             for (;;) {
140                 int data = dataStream.read();
141                 if (data < 0) {
142                     break;
143                 }
144                 out.write(data);
145             }
146             setData(out.toByteArray());
147         } finally {
148             try {
149                 dataStream.close();
150             } catch (IOException e) {
151                 // Ignore.
152             }
153         }
154     }
155     
156     /**
157      * Sets the data which contains the key store.
158      *
159      * @param dataFile the {@link File} that contains the key store
160      */
161     public void setDataFile(File dataFile) throws IOException {
162         setData(new BufferedInputStream(new FileInputStream(dataFile)));
163     }
164     
165     /**
166      * Sets the data which contains the key store.
167      *
168      * @param dataUrl the {@link URL} that contains the key store.
169      */
170     public void setDataUrl(URL dataUrl) throws IOException {
171         setData(dataUrl.openStream());
172     }
173 }