|
|
package org.openslx.satellitedaemon;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import org.apache.log4j.Logger;
public class AsymKeyHolder
{
private static final Logger LOG = Logger.getLogger( AsymKeyHolder.class );
private static PrivateKey privKey = null;
private static PublicKey pubKey = null;
public AsymKeyHolder(BigInteger privExp, BigInteger pubExp, BigInteger mod)
throws InvalidKeySpecException, NoSuchAlgorithmException {
final KeyFactory keyFact;
try {
keyFact = KeyFactory.getInstance( "RSA" );
} catch ( NoSuchAlgorithmException e ) {
throw new NoSuchAlgorithmException(e.getMessage());
}
if (privExp == null) {
// private exponent == null. Generate public key.
if (mod != null) {
try {
RSAPublicKeySpec keySpec = new RSAPublicKeySpec( mod, pubExp );
synchronized ( keyFact ) {
pubKey = keyFact.generatePublic( keySpec );
}
} catch ( InvalidKeySpecException e ) {
LOG.error( "Not able to build key with given numbers.", e );
throw new InvalidKeySpecException( e.getMessage() );
} catch ( NumberFormatException e ) {
LOG.error( "Invalid number format.", e );
throw new NumberFormatException( e.toString() );
}
}
} else if (pubExp == null) {
// public exponent == null. Generate private key.
if (mod != null) {
try {
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec( mod, privExp );
synchronized ( keyFact ) {
privKey = keyFact.generatePrivate( keySpec );
}
} catch ( InvalidKeySpecException e ) {
LOG.error( "Not able to build key with given numbers.", e );
throw new InvalidKeySpecException( e.getMessage() );
} catch ( NumberFormatException e ) {
LOG.error( "Invalid number format.", e );
throw new NumberFormatException( e.toString() );
}
}
} else {
// create both keys.
if (mod != null) {
try {
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( mod, pubExp );
RSAPrivateKeySpec privkeySpec = new RSAPrivateKeySpec( mod, privExp );
synchronized ( keyFact ) {
privKey = keyFact.generatePrivate( privkeySpec );
pubKey = keyFact.generatePublic( pubKeySpec );
}
} catch ( InvalidKeySpecException e ) {
LOG.error( "Not able to build key with given numbers.", e );
throw new InvalidKeySpecException( e.getMessage() );
} catch ( NumberFormatException e ) {
LOG.error( "Invalid number format.", e );
throw new NumberFormatException( e.toString() );
}
}
}
}
public AsymKeyHolder() throws NoSuchAlgorithmException {
generateKey();
}
/**
* Get private key for this server. If none exists yet, create a new one.
*
* @return
*/
public PrivateKey getPrivateKey()
{
if (privKey == null) {
if (!generateKey()) {
LOG.warn( "Could not load or generate keypair for communication with masterserver" );
}
}
return privKey;
}
public PublicKey getPublicKey()
{
if (pubKey == null) {
if (!generateKey()) {
LOG.warn( "Could not generate keypair for communication with masterserver" );
}
}
return pubKey;
}
// private boolean loadKey()
// {
// BufferedReader br = null;
// String modulus, exponent;
// KeyFactory keyFact;
//
// try {
// keyFact = KeyFactory.getInstance( "RSA" );
// } catch ( NoSuchAlgorithmException e ) {
// LOG.warn( "Could not get a KeyFactory to load the key from disk", e );
// return false;
// }
//
// try {
// br = new BufferedReader( new FileReader( "config/private.key" ) );
// modulus = br.readLine();
// exponent = br.readLine();
// } catch ( FileNotFoundException e ) {
// LOG.error( "File 'private.key' not found!", e );
// return false;
// } catch ( IOException e ) {
// LOG.error( "File 'private.key' not correct readable.", e );
// return false;
// } finally {
// try {
// br.close();
// } catch ( IOException e ) {
// }
// }
// if ( modulus == null || exponent == null ) {
// return false;
// }
//
// try {
// BigInteger mod = new BigInteger( modulus );
// BigInteger exp = new BigInteger( exponent );
//
// RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec( mod, exp );
// synchronized ( keyFact ) {
// privKey = keyFact.generatePrivate( keySpec );
// }
// return privKey != null;
// } catch ( InvalidKeySpecException e ) {
// LOG.error( "Not able to build key with given numbers.", e );
// } catch ( NumberFormatException e ) {
// LOG.error( "Invalid number format.", e );
// }
// return false;
// }
private boolean generateKey()
{
KeyPairGenerator kpg;
try {
kpg = KeyPairGenerator.getInstance("RSA");
} catch ( NoSuchAlgorithmException e ) {
LOG.error( "NoSuchAlgorithmException", e );
return false;
}
kpg.initialize(4096);
KeyPair kp = kpg.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();
RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
BigInteger pubMod = publicKey.getModulus();
BigInteger privMod = privateKey.getModulus();
assert(pubMod == privMod);
BigInteger pubExp = publicKey.getPublicExponent();
BigInteger privExp = privateKey.getPrivateExponent();
RSAPrivateKeySpec privKeySpec = new RSAPrivateKeySpec( privMod, privExp );
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( pubMod, pubExp );
KeyFactory keyFact;
try {
keyFact = KeyFactory.getInstance( "RSA" );
} catch ( NoSuchAlgorithmException e ) {
LOG.error( "NoSuchAlgorithmException", e );
return false;
}
synchronized ( keyFact ) {
try {
privKey = keyFact.generatePrivate( privKeySpec );
pubKey = keyFact.generatePublic( pubKeySpec );
} catch ( InvalidKeySpecException e ) {
LOG.error( "InvalidKeySpecException", e );
return false;
}
}
return true;
}
}
|