package org.openslx.imagemaster.serversession; import java.nio.ByteBuffer; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.log4j.Logger; import org.apache.thrift.TException; import org.openslx.bwlp.thrift.iface.AuthorizationError; import org.openslx.bwlp.thrift.iface.TAuthorizationException; import org.openslx.encryption.AsymEncryptionHandler; import org.openslx.imagemaster.db.models.LocalSatellite; import org.openslx.imagemaster.util.RandomString; /** * Authenticating a server with message signing. */ public class ServerAuthenticator { private static Logger log = Logger.getLogger( ServerAuthenticator.class ); /** * Servers currently doing authentication. Maps from organization to the challenge we sent. */ private static Map authenticatingServers = new ConcurrentHashMap<>(); /** * Start the server authentification. * * @param satelliteId * the organization of the server * @return encrypted random string */ public static ByteBuffer startServerAuthentication( int satelliteId ) { byte[] secret = RandomString.generateBinary( 100 ); authenticatingServers.put( satelliteId, secret ); log.info( "Server of organinzation '" + satelliteId + "' starts to authenticate. And got string: '" + secret.length + "'" ); return ByteBuffer.wrap( secret ); } /** * Authenticate with the challengeResponse. * * @param organizationId Is already verified. * @param address * @param challengeResponse * @throws ServerAuthenticationException * @throws TException */ public static void serverAuthenticate( LocalSatellite satellite, ByteBuffer challengeResponse ) throws TAuthorizationException { byte[] encryptedBytes = new byte[ challengeResponse.remaining() ]; challengeResponse.get( encryptedBytes ); AsymEncryptionHandler verifier = new AsymEncryptionHandler( satellite.getPubkey() ); if ( !verifier.verifyMessage( encryptedBytes, authenticatingServers.get( satellite.satelliteId ) ) ) { throw new TAuthorizationException( AuthorizationError.CHALLENGE_FAILED, "You failed the encryption challenge. private and public key don't seem to match." ); } log.info( "Server '" + satellite.satelliteName + "' (" + satellite.organizationId + ") authenticated." ); authenticatingServers.remove( satellite.organizationId ); } }