package org.cumulus4j.keymanager.api; import java.io.IOException; /** *

* A CryptoSession is a session in which key transfers can be performed. *

* Use {@link KeyManagerAPI#getCryptoSession(String)} to get a CryptoSession instance. * This instance is a proxy which can be kept and never expires (though the underlying real session will expire if * not used for some time). If the underlying real * session expired, a new underlying session with a new cryptoSessionID * will be created and bound to this CryptoSession instance. *

* CryptoSessions are thread-safe. *

* * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de */ public interface CryptoSession { /** * Get the identifier of the application server. This denotes a logical application server, which * can be composed of many physical machines (in a cluster/cloud). * @return the application server's ID; never null. */ String getAppServerID(); /** * Get the base-url of the app-server-key-manager-channel. This is the part of the URL before the "/KeyManagerChannel" - * e.g. if the REST URL of the KeyManagerChannel-service is * "https://serverUsingCumulus4j.mydomain.org/org.cumulus4j.keymanager.back.webapp/KeyManagerChannel", then this must be * "https://serverUsingCumulus4j.mydomain.org/org.cumulus4j.keymanager.back.webapp". * @return the base-URL before the "/KeyManagerChannel". */ String getAppServerBaseURL(); /** *

* Acquire an unlocked underlying real session. *

* The application server is only able to request keys from the key manager, while a crypto-session is * acquired. It thus needs to be acquired, first, before it can be used for key transfers. *

* Important: It is essential that you call {@link #release()} once for every time you called acquire(). * You should therefore use a try-finally-block like this: *

*
	 * String cryptoSessionID = session.acquire();
	 * try {
	 *
	 * 	// Do some operation that requires key access. For example
	 * 	// call an EJB method or perform a SOAP/REST request which
	 * 	// will make your app server read/write data.
	 *
	 * } finally {
	 * 	session.release();
	 * }
	 * 
*

* If multiple threads use the same CryptoSession (recommended!), the underlying real session will be * acquired (unlocked) when the first thread requires it and it will be locked again when the last thread calls * release(). * However, releasing (locking) does not need to happen immediately. Instead it can be deferred a few seconds, in * case a new acquire() would happen quickly again. This * strategy is usually used with a remote key server (when latency makes acquiring/releasing a pretty expensive * operation). *

* @return the cryptoSessionID to be used within the acquire-release-block for key-management. This ID must be * passed to your application server in order to allow it perform database operations. * @throws AuthenticationException if the authentication fails. This might happen for example, when * a session was created and then the password was modified by another instance of {@link KeyManagerAPI}. * Calling {@link KeyManagerAPI#putUser(String, char[])} automatically updates the authentication information * of the current KeyManagerAPI if the current user's password was changed. But if the password * is changed by another instance, this instance is locked out due to its outdated password. * @throws IOException if communication with the key-store failed. This might be a socket error between * client and remote key server or it might be a problem when reading/writing data in the local file system. * @see #release() */ String acquire() throws AuthenticationException, IOException; /** *

* Release the session, after it was previously {@link #acquire() acquired}. *

* For every call to {@link #acquire()}, there must be exactly one call to {@link #release()}. You should * therefore use a try-finally-block! *

* See {@link #acquire()} for further details. *

* * @throws AuthenticationException if the authentication fails. This might happen for example, when * a session was created and then the password was modified by another instance of {@link KeyManagerAPI}. * Calling {@link KeyManagerAPI#putUser(String, char[])} automatically updates the authentication information * of the current KeyManagerAPI if the current user's password was changed. But if the password * is changed by another instance, this instance is locked out due to its outdated password. * @throws IOException if communication with the key-store failed. This might be a socket error between * client and remote key server or it might be a problem when reading/writing data in the local file system. * @see #acquire() */ void release() throws AuthenticationException, IOException; }