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

org.refcodes.forwardsecrecy.PublicKeyDecryptionService Maven / Gradle / Ivy

The newest version!
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// =============================================================================
// This code is copyright (c) by Siegfried Steiner, Munich, Germany, distributed
// on an "AS IS" BASIS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, and licen-
// sed 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/TEXT-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;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.refcodes.exception.Trap;
import org.refcodes.forwardsecrecy.SignatureException.SignatureRuntimeException;

import edu.vt.middleware.crypt.CryptException;
import edu.vt.middleware.crypt.asymmetric.AsymmetricAlgorithm;
import edu.vt.middleware.crypt.asymmetric.RSA;
import edu.vt.middleware.crypt.digest.SHA512;
import edu.vt.middleware.crypt.signature.RSASignature;
import edu.vt.middleware.crypt.signature.SignatureAlgorithm;
import edu.vt.middleware.crypt.util.Base64Converter;

/**
 * The {@link DecryptionService} retrieves {@link CipherVersion} instances from
 * the {@link DecryptionServer} and is decrypting the ciphers contained in the
 * {@link CipherVersion} instances with a private key.
 */
public class PublicKeyDecryptionService extends AbstractDecryptionService {

	// /////////////////////////////////////////////////////////////////////////
	// STATICS:
	// /////////////////////////////////////////////////////////////////////////

	private static final Logger LOGGER = Logger.getLogger( PublicKeyDecryptionService.class.getName() );

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

	private CipherVersionFactory _cipherVersionFactory;
	private final AsymmetricAlgorithm _decryptAlgorithm = new RSA();
	private final Base64Converter _base64Converter = new Base64Converter();
	private final SignatureAlgorithm _signatureAlgorithm = new RSASignature( new SHA512() );
	private String _privateKeyPath; /* For logging purposes only */

	// /////////////////////////////////////////////////////////////////////////
	// CONSTRUCTORS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * Constructs the service with the required services and configuration.
	 * {@inheritDoc}
	 * 
	 * @param aPrivateKeyPath The path on the file system to the private key to
	 *        be used for decrypting any ciphers passed by the decryption server
	 *        in CipherVersions retrieved from a storage.
	 * @param aDecryptionServer The decryption server for accessing the cipher
	 *        versions
	 * @param aCipherVersionFactory The factory to be used for creating
	 *        {@link CipherVersion} instances.
	 * 
	 * @throws IOException in case of I/O problems
	 * @throws CryptException in case the cryptography algorithm had problems.
	 * @throws NoSuchAlgorithmException thrown in case the cryptographic
	 *         algorithm was not found.
	 * @throws InvalidKeySpecException thrown in case an invalid key spec has
	 *         been encountered.
	 */
	public PublicKeyDecryptionService( String aNamespece, String aPrivateKeyPath, DecryptionServer aDecryptionServer, CipherVersionFactory aCipherVersionFactory ) throws CryptException, IOException, InvalidKeySpecException, NoSuchAlgorithmException {
		this( aNamespece, aPrivateKeyPath, null, aDecryptionServer, aCipherVersionFactory, EXPIRE_TIME_IMMEDIATELY );
	}

	/**
	 * Constructs the service with the required services and configuration.
	 * {@inheritDoc}
	 * 
	 * @param aPrivateKeyPath The path on the file system to the private key to
	 *        be used for decrypting any ciphers passed by the decryption server
	 *        in CipherVersions retrieved from a storage.
	 * @param aDecryptionServer The decryption server for accessing the cipher
	 *        versions
	 * 
	 * @throws IOException in case of I/O problems
	 * @throws CryptException in case the cryptography algorithm had problems.
	 * @throws NoSuchAlgorithmException thrown in case the cryptographic
	 *         algorithm was not found.
	 * @throws InvalidKeySpecException thrown in case an invalid key spec has
	 *         been encountered.
	 */
	public PublicKeyDecryptionService( String aNamespece, String aPrivateKeyPath, DecryptionServer aDecryptionServer ) throws CryptException, IOException, InvalidKeySpecException, NoSuchAlgorithmException {
		this( aNamespece, aPrivateKeyPath, null, aDecryptionServer, new CipherVersionFactoryImpl(), EXPIRE_TIME_IMMEDIATELY );
	}

	/**
	 * Constructs the service with the required services and configuration.
	 * {@inheritDoc}
	 * 
	 * @param aPrivateKeyPath The path on the file system to the private key to
	 *        be used for decrypting any ciphers passed by the decryption server
	 *        in CipherVersions retrieved from a storage.
	 * @param aPrivateKeyPassPhrase The pass phrase for decrypting the private
	 *        key.
	 * @param aDecryptionServer The decryption server for accessing the cipher
	 *        versions
	 * 
	 * @throws IOException in case of I/O problems
	 * @throws CryptException in case the cryptography algorithm had problems.
	 * @throws NoSuchAlgorithmException thrown in case the cryptographic
	 *         algorithm was not found.
	 * @throws InvalidKeySpecException thrown in case an invalid key spec has
	 *         been encountered.
	 */
	public PublicKeyDecryptionService( String aNamespece, String aPrivateKeyPath, String aPrivateKeyPassPhrase, DecryptionServer aDecryptionServer ) throws CryptException, IOException, InvalidKeySpecException, NoSuchAlgorithmException {
		this( aNamespece, aPrivateKeyPath, aPrivateKeyPassPhrase, aDecryptionServer, new CipherVersionFactoryImpl(), EXPIRE_TIME_IMMEDIATELY );
	}

	/**
	 * Constructs the service with the required services and configuration.
	 * {@inheritDoc}
	 * 
	 * @param aPrivateKeyPath The path on the file system to the private key to
	 *        be used for decrypting any ciphers passed by the decryption server
	 *        in CipherVersions retrieved from a storage.
	 * @param aDecryptionServer The decryption server for accessing the cipher
	 *        versions
	 * @param aCipherVersionFactory The factory to be used for creating
	 *        {@link CipherVersion} instances.
	 * @param aCipherVersionsExpireTimeMillis 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
	 *        (default). A value of -1 indicate that them cipher versions expire
	 *        never.
	 * 
	 * @throws IOException in case of I/O problems
	 * @throws CryptException in case the cryptography algorithm had problems.
	 * @throws NoSuchAlgorithmException thrown in case the cryptographic
	 *         algorithm was not found.
	 * @throws InvalidKeySpecException thrown in case an invalid key spec has
	 *         been encountered.
	 */
	public PublicKeyDecryptionService( String aNamespece, String aPrivateKeyPath, DecryptionServer aDecryptionServer, CipherVersionFactory aCipherVersionFactory, long aCipherVersionsExpireTimeMillis ) throws CryptException, IOException, InvalidKeySpecException, NoSuchAlgorithmException {
		this( aNamespece, aPrivateKeyPath, null, aDecryptionServer, aCipherVersionFactory, aCipherVersionsExpireTimeMillis );
	}

	/**
	 * Constructs the service with the required services and configuration.
	 * {@inheritDoc}
	 * 
	 * @param aPrivateKeyPath The path on the file system to the private key to
	 *        be used for decrypting any ciphers passed by the decryption server
	 *        in CipherVersions retrieved from a storage.
	 * @param aDecryptionServer The decryption server for accessing the cipher
	 *        versions
	 * @param aCipherVersionsExpireTimeMillis 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
	 *        (default). A value of -1 indicate that them cipher versions expire
	 *        never.
	 * 
	 * @throws IOException in case of I/O problems
	 * @throws CryptException in case the cryptography algorithm had problems.
	 * @throws NoSuchAlgorithmException thrown in case the cryptographic
	 *         algorithm was not found.
	 * @throws InvalidKeySpecException thrown in case an invalid key spec has
	 *         been encountered.
	 */
	public PublicKeyDecryptionService( String aNamespece, String aPrivateKeyPath, DecryptionServer aDecryptionServer, long aCipherVersionsExpireTimeMillis ) throws CryptException, IOException, InvalidKeySpecException, NoSuchAlgorithmException {
		this( aNamespece, aPrivateKeyPath, null, aDecryptionServer, new CipherVersionFactoryImpl(), aCipherVersionsExpireTimeMillis );
	}

	/**
	 * Constructs the service with the required services and configuration.
	 * {@inheritDoc}
	 * 
	 * @param aPrivateKeyPath The path on the file system to the private key to
	 *        be used for decrypting any ciphers passed by the decryption server
	 *        in CipherVersions retrieved from a storage.
	 * @param aPrivateKeyPassPhrase The pass phrase for decrypting the private
	 *        key.
	 * @param aDecryptionServer The decryption server for accessing the cipher
	 *        versions
	 * @param aCipherVersionsExpireTimeMillis 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
	 *        (default). A value of -1 indicate that them cipher versions expire
	 *        never.
	 * 
	 * @throws IOException in case of I/O problems
	 * @throws CryptException in case the cryptography algorithm had problems.
	 * @throws NoSuchAlgorithmException thrown in case the cryptographic
	 *         algorithm was not found.
	 * @throws InvalidKeySpecException thrown in case an invalid key spec has
	 *         been encountered.
	 */
	public PublicKeyDecryptionService( String aNamespece, String aPrivateKeyPath, String aPrivateKeyPassPhrase, DecryptionServer aDecryptionServer, long aCipherVersionsExpireTimeMillis ) throws CryptException, IOException, InvalidKeySpecException, NoSuchAlgorithmException {
		this( aNamespece, aPrivateKeyPath, aPrivateKeyPassPhrase, aDecryptionServer, new CipherVersionFactoryImpl(), aCipherVersionsExpireTimeMillis );
	}

	/**
	 * Constructs the service with the required services and configuration.
	 * {@inheritDoc}
	 * 
	 * @param aPrivateKeyPath The path on the file system to the private key to
	 *        be used for decrypting any ciphers passed by the decryption server
	 *        in CipherVersions retrieved from a storage.
	 * @param aPrivateKeyPassPhrase The pass phrase for decrypting the private
	 *        key.
	 * @param aDecryptionServer The decryption server for accessing the cipher
	 *        versions
	 * @param aCipherVersionFactory The factory to be used for creating
	 *        {@link CipherVersion} instances.
	 * 
	 * @throws IOException in case of I/O problems
	 * @throws CryptException in case the cryptography algorithm had problems.
	 * @throws NoSuchAlgorithmException thrown in case the cryptographic
	 *         algorithm was not found.
	 * 
	 * @param aCipherVersionsExpireTimeMillis 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
	 *        (default). A value of -1 indicate that them cipher versions expire
	 *        never.
	 * 
	 * @throws InvalidKeySpecException thrown in case an invalid key spec has
	 *         been encountered.
	 */
	public PublicKeyDecryptionService( String aNamespece, String aPrivateKeyPath, String aPrivateKeyPassPhrase, DecryptionServer aDecryptionServer, CipherVersionFactory aCipherVersionFactory, long aCipherVersionsExpireTimeMillis ) throws CryptException, IOException, InvalidKeySpecException, NoSuchAlgorithmException {
		super( aNamespece, aDecryptionServer, aCipherVersionsExpireTimeMillis );
		_cipherVersionFactory = aCipherVersionFactory;
		_privateKeyPath = aPrivateKeyPath;
		final File thePrivateKeyFile = new File( aPrivateKeyPath );
		LOGGER.log( Level.FINE, "Loading private key from file \"" + thePrivateKeyFile.getAbsolutePath() + "\"..." );
		try {
			final PrivateKey thePrivateKey;
			thePrivateKey = ForwardSecrecyUtility.readPrivateKey( thePrivateKeyFile, aPrivateKeyPassPhrase );
			_decryptAlgorithm.setKey( thePrivateKey );
			_decryptAlgorithm.initDecrypt();
			_signatureAlgorithm.setSignKey( thePrivateKey );
			_signatureAlgorithm.initSign();
		}
		catch ( FileNotFoundException e ) {
			LOGGER.log( Level.SEVERE, "Unable to load private key from file \"" + thePrivateKeyFile.getAbsolutePath() + "\" as of: " + Trap.asMessage( e ), e );
			throw e;
		}
		catch ( CryptException e ) {
			LOGGER.log( Level.SEVERE, "Unable to instantiate private key from file   \"" + thePrivateKeyFile.getAbsolutePath() + " possibly due to a \"Java Cryptography Extension (JCE)\" with limited Strength (in that case please update to \"Java Cryptography Extension (JCE) Unlimited Strength\") \" as of: " + Trap.asMessage( e ), e );
			throw e;
		}
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected String toSignature( String aMessage ) {
		LOGGER.log( Level.FINE, "Using private key \"" + _privateKeyPath + "\" for signing a aMessage used to identify a public key ..." );
		try {
			return _signatureAlgorithm.sign( aMessage.getBytes(), _base64Converter );
		}
		catch ( CryptException e ) {
			throw new SignatureRuntimeException( "Cannot create signature for message!", e );
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected String createMessage() {
		return ForwardSecrecyUtility.createMessage();
	}

	/**
	 * To decrypted cipher version.
	 *
	 * @param  the generic type
	 * @param aEncyrptedCipherVersion the encyrpted cipher version
	 * 
	 * @return the cv
	 */
	@SuppressWarnings("unchecked")
	@Override
	protected  CV toDecryptedCipherVersion( CV aEncyrptedCipherVersion ) {
		LOGGER.log( Level.FINE, "Using private key \"" + _privateKeyPath + "\" for decrypting a cipher ..." );
		try {
			return (CV) _cipherVersionFactory.create( aEncyrptedCipherVersion.getUniversalId(), new String( _decryptAlgorithm.decrypt( aEncyrptedCipherVersion.getCipher(), _base64Converter ) ) );
		}
		catch ( CryptException e ) {
			throw new DecryptCipherRuntimeException( "Cannot create decrypted cipher version from encrypted cipher version!", aEncyrptedCipherVersion.getUniversalId(), e );
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy