From 1949083bec8c238d38683d4755a0a4a4fe11b111 Mon Sep 17 00:00:00 2001 From: Björn Hagemeister Date: Wed, 15 Oct 2014 15:12:48 +0200 Subject: Implemented --genId command line option. --- TODO.txt | 2 +- src/main/java/org/openslx/satellitedaemon/App.java | 107 +++++++++--------- .../java/org/openslx/satellitedaemon/Identity.java | 124 ++++++++++++++++++--- 3 files changed, 162 insertions(+), 71 deletions(-) diff --git a/TODO.txt b/TODO.txt index 56968c4..b8fa8fe 100644 --- a/TODO.txt +++ b/TODO.txt @@ -12,7 +12,7 @@ Befehlszeilenoptionen: gesetzt, gültiger ladbarer Private+Public key. Wenn ja, System.exit(0), sonst System.exit(>0) -[ ] * Option --genid +[x] * Option --genid Generiert eine neue Identity mit dem übergebenen Organization-Name, und generiert ein neues Schlüsselpaar. Alles in die identity.properties speichern und bei Erfolg System.exit(0), sonst >0. diff --git a/src/main/java/org/openslx/satellitedaemon/App.java b/src/main/java/org/openslx/satellitedaemon/App.java index 6a4ebf4..34d61ed 100644 --- a/src/main/java/org/openslx/satellitedaemon/App.java +++ b/src/main/java/org/openslx/satellitedaemon/App.java @@ -29,30 +29,30 @@ public class App String organizationName; String modulus, privExp, pubExp; String ipAddress; - + // Check if there are arguments available and if they start with "--". - if (i < args.length && args[i].startsWith( "--" )) { + if ( i < args.length && args[i].startsWith( "--" ) ) { // Arguments available, take the first one. arg = args[i++]; - if (arg.equals( "--checkconfig" )) { - if (checkConfig()) { + if ( arg.equals( "--checkconfig" ) ) { + if ( checkConfig() ) { System.exit( 0 ); } System.exit( 2 ); - } else if (arg.equals( "--genid" )) { - if (i < args.length) { + } else if ( arg.equals( "--genid" ) ) { + if ( i < args.length ) { organizationName = args[i++]; - if (genId(organizationName)) { + if ( genId( organizationName ) ) { System.exit( 0 ); } - else + else System.exit( 2 ); } else { log.error( "--genid requires an organization name" ); System.exit( 2 ); } - } else if (arg.equals( "--import" )) { - if ((i + 3) < args.length) { + } else if ( arg.equals( "--import" ) ) { + if ( ( i + 3 ) < args.length ) { log.error( "Illelgal option: '--import' requires 4 arguments, " ); System.exit( 2 ); } else { @@ -60,41 +60,41 @@ public class App modulus = args[i++]; privExp = args[i++]; pubExp = args[i++]; - if (importId(organizationName, modulus, privExp, pubExp)) { + if ( importId( organizationName, modulus, privExp, pubExp ) ) { System.exit( 0 ); } else System.exit( 2 ); } - } else if (arg.equals( "--submitkey")) { - if (i < args.length) { + } else if ( arg.equals( "--submitkey" ) ) { + if ( i < args.length ) { ipAddress = args[i++]; - if (submitKey(ipAddress)) + if ( submitKey( ipAddress ) ) System.exit( 0 ); - else + else System.exit( 2 ); } else { log.error( "--submitkey requires " ); System.exit( 2 ); } - } else if (arg.equals( "--updateaddress" )) { - if (i < args.length) { + } else if ( arg.equals( "--updateaddress" ) ) { + if ( i < args.length ) { ipAddress = args[i++]; - if (updateAddress(ipAddress)) { + if ( updateAddress( ipAddress ) ) { System.exit( 0 ); - } else + } else System.exit( 2 ); } else { log.error( "--updateaddress requires " ); System.exit( 2 ); } } - } else if (args.length == 0) { + } else if ( args.length == 0 ) { // No Option choosed, try to load existing identity. - if (!tryLoadIdentity()) { + if ( !tryLoadIdentity() ) { System.exit( 2 ); } } - + if ( !Globals.masterServerSslContextInit() ) { log.error( "Problem with initializing the SSLContext" ); System.exit( 1 ); @@ -105,53 +105,48 @@ public class App Thread downloadWorker = new Thread( new FileDownloadWorker() ); downloadWorker.start(); } - - private static boolean checkConfig() { - if (Identity.getOrganizationName() == null) - return false; - // First check existing members (modulus, privExp, pubExp) of Identity. - if (!Identity.checkMembers()) + + private static boolean checkConfig() + { + if ( Identity.getOrganizationName() == null ) 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(); - if (Identity.keySize() != -1) { - int size = rnd.nextInt(Identity.keySize() - 1); - BigInteger text = new BigInteger(size,rnd); - RSAPublicKey pub = (RSAPublicKey) Identity.getPublicKey(); - RSAPrivateKey priv = (RSAPrivateKey) Identity.getPrivateKey(); - // Encrypt. - BigInteger cipher = text.modPow(pub.getPublicExponent(), pub.getModulus()); - // Decrypt again. - BigInteger decrypted = cipher.modPow(priv.getPrivateExponent(), priv.getModulus()); - boolean isPassed = text.equals(decrypted); - return isPassed; - } - return false; + RSAPublicKey pub = (RSAPublicKey)Identity.getPublicKey(); + RSAPrivateKey priv = (RSAPrivateKey)Identity.getPrivateKey(); + assert ( pub.getModulus() == priv.getModulus() ); + BigInteger modulus = pub.getModulus(); + return Identity.isValidKeyPair( + modulus, + priv.getPrivateExponent(), + pub.getPublicExponent() ); } - - private static boolean genId(String organizationName) { - // TODO. + + private static boolean genId( String organizationName ) + { + if ( Identity.generateIdentity( organizationName ) ) + return true; return false; } - - private static boolean importId(String organizationName, String modulus, String privExp, String pubExp) { + + private static boolean importId( String organizationName, String modulus, String privExp, String pubExp ) + { // TODO. return false; } - - private static boolean submitKey(String ipAddress) { + + private static boolean submitKey( String ipAddress ) + { // TODO. return false; } - - private static boolean updateAddress(String ipAddress) { + + private static boolean updateAddress( String ipAddress ) + { // TODO. return false; } - - private static boolean tryLoadIdentity() { + + private static boolean tryLoadIdentity() + { // TODO. return false; } diff --git a/src/main/java/org/openslx/satellitedaemon/Identity.java b/src/main/java/org/openslx/satellitedaemon/Identity.java index 92bf425..6e5c877 100644 --- a/src/main/java/org/openslx/satellitedaemon/Identity.java +++ b/src/main/java/org/openslx/satellitedaemon/Identity.java @@ -1,6 +1,9 @@ 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; @@ -10,6 +13,7 @@ import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.util.Properties; +import java.util.Random; import org.apache.log4j.Logger; import org.openslx.encryption.AsymKeyHolder; @@ -20,26 +24,31 @@ public class Identity private static Logger log = Logger.getLogger( Identity.class ); private static final Properties properties = new Properties(); + private static String organizationName = null; + private static BigInteger privExponent = null; + private static BigInteger pubExponent = null; + private static BigInteger modulus = null; + private static AsymKeyHolder akh = null; public static String getOrganizationName() { - return properties.getProperty( "ORGANIZATION_NAME" ); + return organizationName = properties.getProperty( "ORGANIZATION_NAME" ); } private static BigInteger getModulus() { - return toBigInt( properties.getProperty( "MODULUS" ) ); + return modulus = toBigInt( properties.getProperty( "MODULUS" ) ); } private static BigInteger getPublicExponent() { - return toBigInt( properties.getProperty( "PUBLIC_EXPONENT" ) ); + return pubExponent = toBigInt( properties.getProperty( "PUBLIC_EXPONENT" ) ); } private static BigInteger getPrivateExponent() { - return toBigInt( properties.getProperty( "PRIVATE_EXPONENT" ) ); + return privExponent = toBigInt( properties.getProperty( "PRIVATE_EXPONENT" ) ); } /** @@ -99,22 +108,109 @@ public class Identity /** * Get bit - length of key. + * * @return */ - public static int keySize() { - if (getModulus() != null) - return getModulus().bitLength(); - return -1; + public static int keySize( BigInteger modulus ) + { + return modulus.bitLength(); } - - public static boolean checkMembers() { - return ( - (getModulus() != null) && - (getPrivateExponent() != null) && - (getPublicExponent() != null)); + + /** + * 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; + } + + public static boolean generateIdentity( String organizationName ) + { + Identity.organizationName = organizationName; + // generate new key pair. + Identity.akh = new AsymKeyHolder(); + Identity.modulus = akh.getModulus(); + Identity.privExponent = akh.getPrivateExponent(); + Identity.pubExponent = akh.getPublicExponent(); + + return writeIdToFile( + Identity.organizationName, + Identity.modulus, + Identity.privExponent, + Identity.pubExponent ); } + + 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 */ -- cgit v1.2.3-55-g7522