View Javadoc

1   /**
2    * This file is part of GoldenGate Project (named also GoldenGate or GG).
3    * 
4    * Copyright 2009, Frederic Bregier, and individual contributors by the @author
5    * tags. See the COPYRIGHT.txt in the distribution for a full listing of
6    * individual contributors.
7    * 
8    * All GoldenGate Project is free software: you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License, or (at your
11   * option) any later version.
12   * 
13   * GoldenGate is distributed in the hope that it will be useful, but WITHOUT ANY
14   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Public License along with
18   * GoldenGate . If not, see <http://www.gnu.org/licenses/>.
19   */
20  package goldengate.common.crypto;
21  
22  import goldengate.common.exception.CryptoException;
23  
24  import java.io.File;
25  import java.io.FileInputStream;
26  import java.io.FileNotFoundException;
27  import java.io.FileOutputStream;
28  import java.io.IOException;
29  import java.util.Enumeration;
30  import java.util.LinkedList;
31  import java.util.List;
32  
33  /**
34   * 
35   * Can implements AES, ARCFOUR, Blowfish, DES, DESede, RC2, RC4<br>
36   * <br>
37   * The time ratio are: RC4,ARCFOUR=1; AES,RC2=1,5; DES=2; Blowfish,DESede=4<br>
38   * <b>AES is the best compromise in term of security and efficiency.</b>
39   * 
40   * @author frederic bregier
41   * 
42   */
43  public class DynamicKeyManager extends KeyManager {
44      /**
45       * Manager of Dynamic Key
46       */
47      public static final DynamicKeyManager dynamicKeyManager = new DynamicKeyManager();
48      /**
49       * Extra information file extension
50       */
51      public static final String INFEXTENSION = ".inf";
52  
53      /*
54       * (non-Javadoc)
55       * 
56       * @see goldengate.common.crypto.KeyManager#createKeyObject()
57       */
58      @Override
59      public KeyObject createKeyObject() {
60          throw new InstantiationError(
61                  "DynamicKeyManager does not implement this function");
62      }
63  
64      @Override
65      public List<String> initFromList(List<String> keys, String extension) {
66          LinkedList<String> wrong = new LinkedList<String>();
67          for (String filename: keys) {
68              File file = new File(filename);
69              if (file.canRead()) {
70                  String basename = file.getName();
71                  int lastpos = basename.lastIndexOf(extension);
72                  if (lastpos <= 0) {
73                      wrong.add(filename);
74                      continue;
75                  }
76                  String firstname = basename.substring(0, lastpos - 1);
77                  int len = (int) file.length();
78                  byte[] key = new byte[len];
79                  FileInputStream inputStream = null;
80                  try {
81                      inputStream = new FileInputStream(file);
82                  } catch (FileNotFoundException e) {
83                      // should not be
84                      wrong.add(filename);
85                      continue;
86                  }
87                  int read = 0;
88                  int offset = 0;
89                  while (read > 0) {
90                      try {
91                          read = inputStream.read(key, offset, len);
92                      } catch (IOException e) {
93                          wrong.add(filename);
94                          read = -2;
95                          break;
96                      }
97                      offset += read;
98                      if (offset < len) {
99                          len -= read;
100                     } else {
101                         break;
102                     }
103                 }
104                 try {
105                     inputStream.close();
106                 } catch (IOException e) {
107                 }
108                 if (read < -1) {
109                     // wrong
110                     continue;
111                 }
112                 String infFilename = filename + INFEXTENSION;
113                 File infFile = new File(infFilename);
114                 inputStream = null;
115                 try {
116                     inputStream = new FileInputStream(infFile);
117                 } catch (FileNotFoundException e) {
118                     // should not be
119                     wrong.add(filename);
120                     continue;
121                 }
122                 KeyObject keyObject;
123                 try {
124                     int keySize = inputStream.read();
125                     String algo = readString(inputStream);
126                     if (algo == null) {
127                         wrong.add(filename);
128                         continue;
129                     }
130                     String instance = readString(inputStream);
131                     if (instance == null) {
132                         wrong.add(filename);
133                         continue;
134                     }
135                     keyObject = new DynamicKeyObject(keySize, algo, instance,
136                             extension);
137                 } catch (IOException e1) {
138                     wrong.add(filename);
139                     continue;
140                 } finally {
141                     try {
142                         inputStream.close();
143                     } catch (IOException e) {
144                     }
145                 }
146                 keyObject.setSecretKey(key);
147                 this.setKey(firstname, keyObject);
148             } else {
149                 wrong.add(filename);
150             }
151         }
152         this.isInitialized.set(true);
153         return wrong;
154     }
155     /**
156      * Specific functions to ease the process of reading the "inf" file
157      * @param inputStream
158      * @return the String that should be read
159      */
160     private String readString(FileInputStream inputStream) {
161         int len;
162         try {
163             len = inputStream.read();
164         } catch (IOException e1) {
165             return null;
166         }
167         byte[] readbyte = new byte[len];
168         for (int i = 0; i < len; i ++) {
169             try {
170                 readbyte[i] = (byte) inputStream.read();
171             } catch (IOException e) {
172                 return null;
173             }
174         }
175         return new String(readbyte);
176     }
177 
178     @Override
179     public void saveToFiles(String extension) throws CryptoException,
180             IOException {
181         Enumeration<String> names = keysConcurrentHashMap.keys();
182         while (names.hasMoreElements()) {
183             String name = names.nextElement();
184             KeyObject key = keysConcurrentHashMap.get(name);
185             key.saveSecretKey(new File(name + "." + extension));
186             FileOutputStream outputStream = new FileOutputStream(new File(name +
187                     "." + extension + INFEXTENSION));
188             try {
189                 outputStream.write(key.getKeySize());
190                 String algo = key.getAlgorithm();
191                 String instance = key.getInstance();
192                 outputStream.write(algo.length());
193                 outputStream.write(algo.getBytes());
194                 outputStream.write(instance.length());
195                 outputStream.write(instance.getBytes());
196                 outputStream.close();
197             } finally {
198                 outputStream.close();
199             }
200         }
201     }
202 
203 }