All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.refcodes.forwardsecrecy.impls.AbstractDecryptionService Maven / Gradle / Ivy

There is a newer version: 3.3.9
Show newest version
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// =============================================================================
// This code is copyright (c) by Siegfried Steiner, Munich, Germany and licensed
// under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
// licenses:
// =============================================================================
// GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
// together with the GPL linking exception applied; as being applied by the GNU
// Classpath ("http://www.gnu.org/software/classpath/license.html")
// =============================================================================
// Apache License, v2.0 ("http://www.apache.org/licenses/LICENSE-2.0")
// =============================================================================
// Please contact the copyright holding author(s) of the software artifacts in
// question for licensing issues not being covered by the above listed licenses,
// also regarding commercial licensing models or regarding the compatibility
// with other open source licenses.
// /////////////////////////////////////////////////////////////////////////////

package org.refcodes.forwardsecrecy.impls;

import java.util.ArrayList;
import java.util.List;

import org.refcodes.exception.traps.HiddenException;
import org.refcodes.forwardsecrecy.CipherVersion;
import org.refcodes.forwardsecrecy.DecryptionServer;
import org.refcodes.forwardsecrecy.DecryptionService;
import org.refcodes.forwardsecrecy.traps.SignatureVerificationException;

/**
 * Abstract base implementation for non abstract {@link DecryptionService}
 * implementations.
 */
public abstract class AbstractDecryptionService implements DecryptionService {

	// /////////////////////////////////////////////////////////////////////////
	// CONSTANTS:
	// /////////////////////////////////////////////////////////////////////////

	private static long EXPIRE_TIME_NEVER = -1;
	private static long EXPIRE_TIME_IMMEDIAGTELY = 0;

	// /////////////////////////////////////////////////////////////////////////
	// VARIABLES:
	// /////////////////////////////////////////////////////////////////////////

	private DecryptionServer _decryptionServer;
	private String _namespace;
	private long _cipherVersionsExpireTimeInMs;
	private long _cipherVersionsLastLoadedTime = EXPIRE_TIME_IMMEDIAGTELY;
	private List _cipherVersions;

	// /////////////////////////////////////////////////////////////////////////
	// CONSTRUCTOR:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * Constructs the service with the required services and configuration. The
	 * cipher versions expire time is set to 0 (expire immediately). See
	 * {@link #setCipherVersionsExpireTimeMilliSeconds(long)}.
	 * 
	 * @param aNamespace The name space to which service belongs
	 * 
	 * @param aDecryptionServer The server to which the service is being
	 *        "connected"
	 */
	public AbstractDecryptionService( String aNamespace, DecryptionServer aDecryptionServer ) {
		_namespace = aNamespace;
		_decryptionServer = aDecryptionServer;
	}

	// /////////////////////////////////////////////////////////////////////////
	// METHODS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List getCipherVersions() {
		if ( _cipherVersionsExpireTimeInMs == EXPIRE_TIME_NEVER && _cipherVersions != null ) { return _cipherVersions; }
		long theCurrentTimeMs = System.currentTimeMillis();
		// Determine whether to reload the cipher versions:
		if ( isLoadEncryptedCipherVersions( theCurrentTimeMs ) ) {
			synchronized ( this ) {
				// In case of thread race conditions:
				if ( isLoadEncryptedCipherVersions( theCurrentTimeMs ) ) {

					List theEncryptedCipherVersions;
					try {
						String theMessage = createMessage();
						String theSignature = toSignature( theMessage );

						// @formatter:off
						// ------------------------------------------
						// Remove log in productive environment:
						// ------------------------------------------
						// System.out.println( "Message = " + theMessage );
						// System.out.println( "Signature = " + theSignature );
						// ------------------------------------------
						// @formatter:on

						theEncryptedCipherVersions = _decryptionServer.getCipherVersions( _namespace, theMessage, theSignature );
					}
					catch ( SignatureVerificationException e ) {
						throw new HiddenException( e );
					}

					List theCipherVersions = new ArrayList();

					// @formatter:off
					// -------------------------------------------------
					// Remove these log messages when done implementing!
					// -------------------------------------------------
					// LOGGER.info( "=== ENCRYPTED cipher versions FROM LIST ===" );
					// for ( CipherVersion eCipherVersion : theEncryptedCipherVersions ) {
					//	LOGGER.debug( eCipherVersion.getUniversalId() + " --> " + TextUtility.toFixedLength( eCipherVersion.getCipher(), 10, '.', TextUtility.Direction.FROM_RIGHT_TO_LEFT ) + " (with length <" + eCipherVersion.getCipher().length() + ">) ..." );
					// }
					// -------------------------------------------------
					// @formatter:on

					for ( CipherVersion eCipherVersion : theEncryptedCipherVersions ) {
						theCipherVersions.add( toDecryptedCipherVersion( eCipherVersion ) );
					}

					// Update cipher versions:
					_cipherVersions = theCipherVersions;
					_cipherVersionsLastLoadedTime = System.currentTimeMillis();
				}
			}
		}
		return _cipherVersions;
	}

	// /////////////////////////////////////////////////////////////////////////
	// HELPER:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * Determine whether to load the encrypted cipher versions from the
	 * decryption server.
	 * 
	 * @param aCurrentTimeMillis The current time to use when determining
	 *        whether to load or not.
	 * 
	 * @return True in case the cipher versions are to be loaded, else false.
	 */
	private boolean isLoadEncryptedCipherVersions( long aCurrentTimeMillis ) {
		// @formatter:off
		return (_cipherVersionsExpireTimeInMs == EXPIRE_TIME_IMMEDIAGTELY) || _cipherVersions == null || (_cipherVersionsExpireTimeInMs > 0 && aCurrentTimeMillis - _cipherVersionsExpireTimeInMs > _cipherVersionsLastLoadedTime);
		// @formatter:on
	}

	/**
	 * Injection method for setting the the expire time (in milliseconds) after
	 * which once loaded cipher versions expire. A value of 0 indicates that
	 * them cipher versions are always reloaded upon accessing the cipher
	 * versions. A value of -1 indicates that the cipher versions are just
	 * loaded once and then never reloaded (them never expire).
	 * 
	 * @param aCipherVersionsExpireTimeInMs The time in milliseconds after which
	 *        them loaded cipher versions expire and are reloaded. A value of 0
	 *        indicates that them cipher versions expire immediately. A value of
	 *        -1 indicate that them cipher versions expire never.
	 */
	public void setCipherVersionsExpireTimeInMs( long aCipherVersionsExpireTimeInMs ) {
		_cipherVersionsExpireTimeInMs = aCipherVersionsExpireTimeInMs;
	}

	// /////////////////////////////////////////////////////////////////////////
	// HOOK METHODS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * Creates a signature for the given message.
	 * 
	 * @param aMessage The message for which a signature is to be generated
	 * 
	 * @return The signature for the message
	 */
	protected abstract String toSignature( String aMessage );

	/**
	 * Creates a message for which a signature is to be created in order to
	 * authenticate for the retrieval of the cipher versions. A decryption
	 * server should deny any requests to get cipher versions in case the same
	 * message is used twice.
	 * 
	 * @return The message
	 */
	protected abstract String createMessage();

	/**
	 * Hook factory method to be implemented by subclasses. The provided cipher
	 * is to be decrypted (e.g. with the private key of an asymmetric encryption
	 * approach) so that an decryption server only receives encrypted data.
	 * 
	 * @param  The type of the {@link CipherVersion} to be used.
	 * 
	 * @param aEncyrptedCipherVersion The {@link CipherVersion} to be decrypted.
	 * 
	 * @return The decrypted {@link CipherVersion}.
	 */
	protected abstract  CV toDecryptedCipherVersion( CV aEncyrptedCipherVersion );
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy