summaryrefslogblamecommitdiffstats
path: root/src/main/java/org/openslx/satellitedaemon/Identity.java
blob: 947d90adf77d5fd5eef2d58b873f948a6aa50cf5 (plain) (tree)
1
2
3
4
5
6

                                    
                    
                               

                                     






                                              

                                              

                                                  
                        

                               
                                            
                                                                 






                                                                       
                                                


                                                  
                                                                     

         
                                              
         
                                                                       

         
                                                     
         
                                                                               

         
                                                      
         
                                                                                





                          
                                                

                                                                              
                                                       



                                                                                                                      
                                                                                    
                                         

                                                   
                 
 
                                                                                                           
                     
                                                                                                           
                                                       
                                                                  


                                                                   








                                                                                 
                                    
                                                   
                 
                                          
                                           








                                                                                
                                  
                                                  



                                          

                                   
           

                  


                                                       
         































                                                                                                                    






                                                                               

                                                                         

                                                   
                                                                                                                              
         
 











                                                                                                                                        


                                                                                         





                                                                                    















                                                                        
         









                                                                            










                                                                                 









                                                                                                                                        
 

































                                                                                                      

                                                
           


                     

                                                        
                     

                                                     
                                    
                 

         
package org.openslx.satellitedaemon;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
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.util.Properties;
import java.util.Random;

import org.apache.log4j.Logger;
import org.openslx.encryption.AsymKeyHolder;
import org.openslx.satellitedaemon.filetransfer.ThriftConnection;
import org.openslx.satellitedaemon.util.Util;

public class Identity
{
	private static Logger log = Logger.getLogger( Identity.class );
	private static final Properties properties = new Properties();

	private static AsymKeyHolder akh = null;

	public static String getOrganizationName()
	{
		return properties.getProperty( "ORGANIZATION_NAME" );
	}

	private static BigInteger getModulus()
	{
		return toBigInt( properties.getProperty( "MODULUS" ) );
	}

	private static BigInteger getPublicExponent()
	{
		return toBigInt( properties.getProperty( "PUBLIC_EXPONENT" ) );
	}

	private static BigInteger getPrivateExponent()
	{
		return toBigInt( properties.getProperty( "PRIVATE_EXPONENT" ) );
	}

	/**
	 * Load properties
	 */
	static {
		InputStreamReader stream = null;
		try {
			// Load all entries of the config file into properties
			stream = new InputStreamReader(
					new FileInputStream( "config/identity.properties" ), StandardCharsets.UTF_8 );
			properties.load( stream );
			stream.close();
		} catch ( IOException e ) {
			log.error( "Could not load identity.properties. Exiting." );
			System.exit( 2 );
		} finally {
			Util.streamClose( stream );
		}

		Util.notNullOrEmptyFatal( getOrganizationName(), "Organiziation Name must not be empty!" );
		try {
			akh = new AsymKeyHolder( getPrivateExponent(), getPublicExponent(), getModulus() );
		} catch ( InvalidKeySpecException e ) {
			log.error( "InvalidKeySpecException", e );
		} catch ( NoSuchAlgorithmException e ) {
			log.error( "NoSuchAlgorithmException", e );
		}
	}

	/**
	 * Get private key for this server. If none exists yet, create a new one.
	 * 
	 * @return
	 */
	public static PrivateKey getPrivateKey()
	{
		if ( akh != null ) {
			return akh.getPrivateKey();
		}
		akh = new AsymKeyHolder();
		return akh.getPrivateKey();
	}

	/**
	 * Get public key for this server. If none exists yet, create a new one.
	 * 
	 * @return
	 */
	public static PublicKey getPublicKey()
	{
		if ( akh != null )
			return akh.getPublicKey();
		akh = new AsymKeyHolder();
		return akh.getPublicKey();
	}

	/**
	 * Get bit - length of key.
	 * 
	 * @return
	 */
	public static int keySize( BigInteger modulus )
	{
		return modulus.bitLength();
	}

	/**
	 * Checks if given modulus, private exponent and public exponent are valid
	 * values for key pair. Idea is to encrypt and decrypt random text and compare
	 * the result with initial text.
	 * 
	 * @param mod
	 * @param privExp
	 * @param pubExp
	 * @return True, if mod, privExp and pubExp are valid values.
	 */
	public static boolean isValidKeyPair( BigInteger mod, BigInteger privExp, BigInteger pubExp )
	{
		// First check given values (modulus, privExp, pubExp).
		if ( ( mod == null ) || ( privExp == null ) || ( pubExp == null ) ) {
			log.error( "Given arguments not valid: got NULL for modulus, private or public exponent." );
			return false;
		}

		// Testing encryption and description with given public and private key.
		// Idea: creating random text for encrypting and decrypting again.
		Random rnd = new Random();
		int size = rnd.nextInt( keySize( mod ) - 1 );
		BigInteger text = new BigInteger( size, rnd );
		// Encrypt.
		BigInteger cipher = text.modPow( pubExp, mod );
		// Decrypt again.
		BigInteger decrypted = cipher.modPow( privExp, mod );
		boolean isPassed = text.equals( decrypted );
		return isPassed;
	}

	/**
	 * Generate new identity with given organization name and new key pair.
	 * Write new identity to "config/identity.properties".
	 * 
	 * @param organizationName
	 * @return true, if successful.
	 */
	public static boolean generateIdentity( String organizationName )
	{
		// generate new key pair.
		Identity.akh = new AsymKeyHolder();
		return writeIdToFile( organizationName, akh.getModulus(), akh.getPrivateExponent(), akh.getPublicExponent() );
	}

	/**
	 * Import given identity with organization name, modulus, private and public
	 * exponent and store this identity to "config/identity.properties".
	 * 
	 * @param organizationName
	 * @param modulus
	 * @param privateExp
	 * @param publicExp
	 * @return true, if successful.
	 */
	public static boolean importIdentity( String organizationName, BigInteger modulus, BigInteger privateExp, BigInteger publicExp )
	{
		return writeIdToFile( organizationName, modulus, privateExp, publicExp );
	}

	/**
	 * Submit new satellite - ipAddress to master with organizationId, ipAddress
	 * and key - information.
	 * @param ipAddress
	 * @return true, if successful.
	 */
	public static boolean submitKey( String ipAddress )
	{
		RSAPublicKey pubKey = (RSAPublicKey)getPublicKey();
		RSAPrivateKey privKey = (RSAPrivateKey)getPrivateKey();
		assert ( pubKey.getModulus() == privKey.getModulus() );

		if ( !Identity.isValidKeyPair(
				privKey.getModulus(),
				privKey.getPrivateExponent(),
				pubKey.getPublicExponent() ) )
			return false;
		return ThriftConnection.registerSatellite(
				getOrganizationName(),
				ipAddress,
				pubKey.getModulus().toString(),
				pubKey.getPublicExponent().toString() );
	}
	
	/**
	 * Update already existing satellite - ipAddress in master - Db.
	 * @param ipAddress
	 * @return true, if successful.
	 */
	public static boolean updateAddress( String ipAddress )
	{
		return ThriftConnection.updateSatelliteAddress( ipAddress );
	}

	/**
	 * Write given organization name, modulus, public and private exponent to
	 * "config/identity.properties".
	 * 
	 * @param organizationName
	 * @param modulus
	 * @param privateExp
	 * @param publicExp
	 * @return true, if successful.
	 */
	private static boolean writeIdToFile( String organizationName, BigInteger modulus, BigInteger privateExp, BigInteger publicExp )
	{
		File configFile = new File( "config/identity.properties" );
		FileOutputStream stream = null;
		try {
			stream = new FileOutputStream( configFile );
		} catch ( FileNotFoundException e ) {
			log.error( "FileNotFoundException", e );
			return false;
		}

		// create strings for writing to file. 
		String orgNameString = "ORGANIZATION_NAME=" + organizationName + "\n";
		String modString = "MODULUS=" + modulus.toString() + "\n";
		String privExpString = "PRIVATE_EXPONENT=" + privateExp.toString() + "\n";
		String pubExpString = "PUBLIC_EXPONENT=" + publicExp.toString() + "\n";

		try {
			stream.write( orgNameString.getBytes() );
			stream.write( modString.getBytes() );
			stream.write( privExpString.getBytes() );
			stream.write( pubExpString.getBytes() );
			return true;
		} catch ( IOException e ) {
			log.error( "IOException", e );
			return false;
		} finally {
			try {
				stream.close();
			} catch ( IOException e ) {
			}
		}
	}

	/**
	 * Check modulus, privExp and pubExp for not being null.
	 * 
	 * @return
	 */
	private static boolean checkMembers()
	{
		return ( ( getModulus() != null ) &&
				( getPrivateExponent() != null ) && ( getPublicExponent() != null ) );
	}

	/**
	 * Get BigInteger of read String number.
	 * 
	 * @param str
	 * @return
	 */
	private static BigInteger toBigInt( String str )
	{
		try {
			return new BigInteger( str );
		} catch ( Exception e ) {
			return null;
		}
	}
}