001 package org.cumulus4j.keymanager.api; 002 003 import java.io.IOException; 004 005 /** 006 * <p> 007 * A <code>CryptoSession</code> is a session in which key transfers can be performed. 008 * </p><p> 009 * Use {@link KeyManagerAPI#getCryptoSession(String)} to get a <code>CryptoSession</code> instance. 010 * This instance is a proxy which can be kept and never expires (though the underlying real session will expire if 011 * not used for some time). If the underlying real 012 * session expired, a new underlying session with a new <code>cryptoSessionID</code> 013 * will be created and bound to this <code>CryptoSession</code> instance. 014 * </p><p> 015 * <code>CryptoSession</code>s are thread-safe. 016 * </p> 017 * 018 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de 019 */ 020 public interface CryptoSession 021 { 022 /** 023 * Get the identifier of the application server. This denotes a logical application server, which 024 * can be composed of many physical machines (in a cluster/cloud). 025 * @return the application server's ID; never <code>null</code>. 026 */ 027 String getAppServerID(); 028 029 /** 030 * Get the base-url of the app-server-key-manager-channel. This is the part of the URL before the "/KeyManagerChannel" - 031 * e.g. if the REST URL of the KeyManagerChannel-service is 032 * "https://serverUsingCumulus4j.mydomain.org/org.cumulus4j.keymanager.back.webapp/KeyManagerChannel", then this must be 033 * "https://serverUsingCumulus4j.mydomain.org/org.cumulus4j.keymanager.back.webapp". 034 * @return the base-URL before the "/KeyManagerChannel". 035 */ 036 String getAppServerBaseURL(); 037 038 /** 039 * <p> 040 * Acquire an unlocked underlying real session. 041 * </p><p> 042 * The application server is only able to request keys from the key manager, while a crypto-session is 043 * acquired. It thus needs to be acquired, first, before it can be used for key transfers. 044 * </p><p> 045 * <b>Important:</b> It is essential that you call {@link #release()} once for every time you called <code>acquire()</code>. 046 * You should therefore use a try-finally-block like this: 047 * </p> 048 * <pre> 049 * String cryptoSessionID = session.acquire(); 050 * try { 051 * 052 * // Do some operation that requires key access. For example 053 * // call an EJB method or perform a SOAP/REST request which 054 * // will make your app server read/write data. 055 * 056 * } finally { 057 * session.release(); 058 * } 059 * </pre> 060 * <p> 061 * If multiple threads use the same <code>CryptoSession</code> (recommended!), the underlying real session will be 062 * acquired (unlocked) when the first thread requires it and it will be locked again when the last thread calls 063 * <code>release()</code>. 064 * However, releasing (locking) does not need to happen immediately. Instead it can be deferred a few seconds, in 065 * case a new <code>acquire()</code> would happen quickly again. This 066 * strategy is usually used with a remote key server (when latency makes acquiring/releasing a pretty expensive 067 * operation). 068 * </p> 069 * @return the cryptoSessionID to be used within the acquire-release-block for key-management. This ID must be 070 * passed to your application server in order to allow it perform database operations. 071 * @throws AuthenticationException if the authentication fails. This might happen for example, when 072 * a session was created and then the password was modified by another instance of {@link KeyManagerAPI}. 073 * Calling {@link KeyManagerAPI#putUser(String, char[])} automatically updates the authentication information 074 * of the current <code>KeyManagerAPI</code> if the current user's password was changed. But if the password 075 * is changed by another instance, this instance is locked out due to its outdated password. 076 * @throws IOException if communication with the key-store failed. This might be a socket error between 077 * client and remote key server or it might be a problem when reading/writing data in the local file system. 078 * @see #release() 079 */ 080 String acquire() throws AuthenticationException, IOException; 081 082 /** 083 * <p> 084 * Release the session, after it was previously {@link #acquire() acquired}. 085 * </p><p> 086 * For every call to {@link #acquire()}, there must be exactly one call to {@link #release()}. You should 087 * therefore use a try-finally-block! 088 * </p><p> 089 * See {@link #acquire()} for further details. 090 * </p> 091 * 092 * @throws AuthenticationException if the authentication fails. This might happen for example, when 093 * a session was created and then the password was modified by another instance of {@link KeyManagerAPI}. 094 * Calling {@link KeyManagerAPI#putUser(String, char[])} automatically updates the authentication information 095 * of the current <code>KeyManagerAPI</code> if the current user's password was changed. But if the password 096 * is changed by another instance, this instance is locked out due to its outdated password. 097 * @throws IOException if communication with the key-store failed. This might be a socket error between 098 * client and remote key server or it might be a problem when reading/writing data in the local file system. 099 * @see #acquire() 100 */ 101 void release() throws AuthenticationException, IOException; 102 }