summaryrefslogblamecommitdiffstats
path: root/src/main/java/org/openslx/satellitedaemon/AsymKeyHolder.java
blob: d69ce76b120e7dad1898ba591c249006d002a464 (plain) (tree)
1
2
3
4
5
6
7
8
9
10







                                     

                                      


                                              

                                              

                                                  
                                           









                                                                                  

































































                                                                                                              




                                                                                 
                                         

                                      
                                             





                                                                                                                     

                                       
         



                                                                                                             
                 

                              
 




















































                                                                                              
                     


                                                                   
                                     
                 




















                                                                                          

                                     







                                                                                 
                         
                                



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

}