KeyManager.java
/*
* This file is part of Waarp Project (named also Waarp or GG).
*
* Copyright (c) 2019, Waarp SAS, 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 org.waarp.common.exception.CryptoException;
import org.waarp.common.file.FileUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* This class implements a simple Key Manager from name
*/
public abstract class KeyManager {
final ConcurrentHashMap<String, KeyObject> keysConcurrentHashMap =
new ConcurrentHashMap<String, KeyObject>();
final AtomicBoolean isInitialized = new AtomicBoolean(false);
public abstract KeyObject createKeyObject();
/**
* Init the Manager from a list of filename Key, the key name is the
* basename
* minus the extension of the key's
* type
*
* @param keys
*
* @return the list of wrong keys
*/
public List<String> initFromList(final List<String> keys) {
final LinkedList<String> wrong = new LinkedList<String>();
for (final String filename : keys) {
final File file = new File(filename);
if (file.canRead()) {
final String basename = file.getName();
final int lastpos = basename.lastIndexOf('.');
if (lastpos <= 0) {
wrong.add(filename);
continue;
}
final String firstname = basename.substring(0, lastpos);
int len = (int) file.length();
final byte[] key = new byte[len];
final FileInputStream inputStream;
try {
inputStream = new FileInputStream(file);
} catch (final FileNotFoundException e) {
// should not be
wrong.add(filename);
continue;
}
int read = 1;
int offset = 0;
while (read > 0) {
try {
read = inputStream.read(key, offset, len);
} catch (final IOException e) {
wrong.add(filename);
read = -2;
break;
}
offset += read;
if (offset < len) {
len -= read;
} else {
break;
}
}
FileUtils.close(inputStream);
if (read < -1) {
// wrong
continue;
}
final KeyObject keyObject = createKeyObject();
keyObject.setSecretKey(key);
setKey(firstname, keyObject);
} else {
wrong.add(filename);
}
}
isInitialized.set(true);
return wrong;
}
public void saveToFiles() throws CryptoException, IOException {
final Enumeration<String> names = keysConcurrentHashMap.keys();
while (names.hasMoreElements()) {
final String name = names.nextElement();
final KeyObject key = keysConcurrentHashMap.get(name);
key.saveSecretKey(new File(name + '.' + key.getFileExtension()));
}
}
/**
* Add or set a new key associated to the given name
*
* @param name
* @param keyObject
*/
public final void setKey(final String name, final KeyObject keyObject) {
keysConcurrentHashMap.put(name, keyObject);
}
/**
* @param name
*
* @return the key associated to the given name
*/
public final KeyObject getKey(final String name) {
return keysConcurrentHashMap.get(name);
}
/**
* One method to get the crypted String from the given string and key
*
* @param keyName
* @param toBeCrypted
*
* @return the crypted String
*
* @throws Exception
*/
public final String crypt(final String keyName, final String toBeCrypted)
throws Exception {
final KeyObject keyObject = getKey(keyName);
if (keyObject == null) {
throw new NoSuchAlgorithmException("Key does not exist: " + keyName);
}
return keyObject.cryptToHex(toBeCrypted);
}
/**
* One method to get the uncrypted String from the given crypted string and
* key
*
* @param keyName
* @param toBeDecrypted
*
* @return the uncrypted String
*
* @throws Exception
*/
public final String decrypt(final String keyName, final String toBeDecrypted)
throws Exception {
final KeyObject keyObject = getKey(keyName);
if (keyObject == null) {
throw new NoSuchAlgorithmException("Key does not exist: " + keyName);
}
return keyObject.decryptHexInString(toBeDecrypted);
}
}