/** * This file is part of Waarp Project. * * Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the * COPYRIGHT.txt in the distribution for a full listing of individual contributors. * * All Waarp Project is free software: you can redistribute it and/or modify it under the terms of * the GNU General Public License as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * You should have received a copy of the GNU General Public License along with Waarp . If not, see * <http://www.gnu.org/licenses/>. */ package org.waarp.common.crypto; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import org.waarp.common.exception.CryptoException; import org.waarp.common.utility.WaarpStringUtils; /** * * Can implements AES, ARCFOUR, Blowfish, DES, DESede, RC2, RC4<br> * <br> * The time ratio are: RC4,ARCFOUR=1; AES,RC2=1,5; DES=2; Blowfish,DESede=4<br> * <b>AES is the best compromise in term of security and efficiency.</b> * * @author frederic bregier * */ public class DynamicKeyManager extends KeyManager { /** * Manager of Dynamic Key */ private static final DynamicKeyManager manager = new DynamicKeyManager(); /** * Extra information file extension */ private static final String INFEXTENSION = ".inf"; /** * * @return the current KeyManager */ public static final KeyManager getInstance() { return manager; } @Override public KeyObject createKeyObject() { throw new InstantiationError( "DynamicKeyManager does not implement this function"); } @Override public List<String> initFromList(List<String> keys) { LinkedList<String> wrong = new LinkedList<String>(); for (String filename : keys) { File file = new File(filename); if (file.canRead()) { String basename = file.getName(); int lastpos = basename.lastIndexOf('.'); if (lastpos <= 0) { wrong.add(filename); continue; } String firstname = basename.substring(0, lastpos); String extension = basename.substring(lastpos + 1); int len = (int) file.length(); byte[] key = new byte[len]; FileInputStream inputStream = null; try { inputStream = new FileInputStream(file); } catch (FileNotFoundException e) { // should not be wrong.add(filename); continue; } int read = 0; int offset = 0; while (read > 0) { try { read = inputStream.read(key, offset, len); } catch (IOException e) { wrong.add(filename); read = -2; break; } offset += read; if (offset < len) { len -= read; } else { break; } } try { inputStream.close(); } catch (IOException e) { } if (read < -1) { // wrong continue; } String infFilename = filename + INFEXTENSION; File infFile = new File(infFilename); inputStream = null; try { inputStream = new FileInputStream(infFile); } catch (FileNotFoundException e) { // should not be wrong.add(filename); continue; } KeyObject keyObject; try { int keySize = inputStream.read(); String algo = readString(inputStream); if (algo == null) { wrong.add(filename); continue; } String instance = readString(inputStream); if (instance == null) { wrong.add(filename); continue; } keyObject = new DynamicKeyObject(keySize, algo, instance, extension); } catch (IOException e1) { wrong.add(filename); continue; } finally { try { inputStream.close(); } catch (IOException e) { } } keyObject.setSecretKey(key); this.setKey(firstname, keyObject); } else { wrong.add(filename); } } this.isInitialized.set(true); return wrong; } /** * Specific functions to ease the process of reading the "inf" file * * @param inputStream * @return the String that should be read */ private String readString(FileInputStream inputStream) { int len; try { len = inputStream.read(); } catch (IOException e1) { return null; } byte[] readbyte = new byte[len]; for (int i = 0; i < len; i++) { try { readbyte[i] = (byte) inputStream.read(); } catch (IOException e) { return null; } } return new String(readbyte, WaarpStringUtils.UTF8); } @Override public void saveToFiles() throws CryptoException, IOException { Enumeration<String> names = keysConcurrentHashMap.keys(); while (names.hasMoreElements()) { String name = names.nextElement(); KeyObject key = keysConcurrentHashMap.get(name); key.saveSecretKey(new File(name + "." + key.getFileExtension())); FileOutputStream outputStream = new FileOutputStream(new File(name + "." + key.getFileExtension() + INFEXTENSION)); try { outputStream.write(key.getKeySize()); String algo = key.getAlgorithm(); String instance = key.getInstance(); outputStream.write(algo.length()); outputStream.write(algo.getBytes(WaarpStringUtils.UTF8)); outputStream.write(instance.length()); outputStream.write(instance.getBytes(WaarpStringUtils.UTF8)); outputStream.close(); } finally { outputStream.close(); } } } }