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; } }