/**
* Copyright (C) 2010-2017 Structr GmbH
*
* This file is part of Structr <http://structr.org>.
*
* Structr 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.
*
* Structr 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 Structr. If not, see <http://www.gnu.org/licenses/>.
*/
package org.structr.net.common;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class KeyHelper {
private static final Logger logger = LoggerFactory.getLogger(KeyHelper.class.getName());
public static KeyPair getOrCreateKeyPair(final String algorithm, final int keyLength) {
return fromFile(algorithm, keyLength, "/tmp/privatekey.bin", "/tmp/publickey.bin");
}
public static KeyPair fromFile(final String algorithm, final int keyLength, final String privateKeyFileName, final String publicKeyFileName) {
final File privateKeyFile = new File(privateKeyFileName);
final File publicKeyFile = new File(publicKeyFileName);
if (privateKeyFile.exists() && publicKeyFile.exists()) {
final PrivateKey privateKey = getPrivateKey(algorithm, privateKeyFile);
final PublicKey publicKey = getPublicKey(algorithm, publicKeyFile);
return new KeyPair(publicKey, privateKey);
} else {
return createKeyPair(algorithm, keyLength, privateKeyFileName, publicKeyFileName);
}
}
public static KeyPair fromBytes(final String algorithm, final byte[] privateKeyBytes, final byte[] publicKeyBytes) {
final PrivateKey privateKey = getPrivateKeyFromBytes(algorithm, privateKeyBytes);
final PublicKey publicKey = getPublicKeyFromBytes(algorithm, publicKeyBytes);
return new KeyPair(publicKey, privateKey);
}
// ----- private methods -----
private static PrivateKey getPrivateKey(final String algorithm, final File privateKeyFile) {
return getPrivateKeyFromBytes(algorithm, readBytes(privateKeyFile));
}
private static PublicKey getPublicKey(final String algorithm, final File publicKeyFile) {
return getPublicKeyFromBytes(algorithm, readBytes(publicKeyFile));
}
private static PrivateKey getPrivateKeyFromBytes(final String algorithm, final byte[] privateKeyBytes) {
try {
final KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
final PKCS8EncodedKeySpec spec2 = new PKCS8EncodedKeySpec(privateKeyBytes);
return keyFactory.generatePrivate(spec2);
} catch (Throwable t) {
logger.warn("", t);
}
return null;
}
private static PublicKey getPublicKeyFromBytes(final String algorithm, final byte[] publicKeyBytes) {
try {
final KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
final X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyBytes);
return keyFactory.generatePublic(spec);
} catch (Throwable t) {
logger.warn("", t);
}
return null;
}
private static KeyPair createKeyPair(final String algorithm, final int keyLength, final String privateKeyFileName, final String publicKeyFileName) {
try {
final File publicKeyFile = new File(publicKeyFileName);
final File privateKeyFile = new File(privateKeyFileName);
final KeyPairGenerator kpg = KeyPairGenerator.getInstance(algorithm);
kpg.initialize(keyLength);
final KeyPair keyPair = kpg.genKeyPair();
final PublicKey publicKey = keyPair.getPublic();
final PrivateKey privateKey = keyPair.getPrivate();
if (!publicKeyFile.exists() || !privateKeyFile.exists()) {
try (final FileOutputStream fos = new FileOutputStream(publicKeyFile)) {
fos.write(publicKey.getEncoded());
fos.flush();
}
try (final FileOutputStream fos = new FileOutputStream(privateKeyFile)) {
fos.write(privateKey.getEncoded());
fos.flush();
}
}
return keyPair;
} catch (Throwable t) {
logger.warn("", t);
}
return null;
}
private static byte[] readBytes(final File file) {
try {
return Files.readAllBytes(file.toPath());
} catch (Throwable t) {
logger.warn("", t);
}
return null;
}
}