001 /* 002 * Cumulus4j - Securing your data in the cloud - http://cumulus4j.org 003 * Copyright (C) 2011 NightLabs Consulting GmbH 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 package org.cumulus4j.store.crypto; 019 020 import java.util.Date; 021 022 import org.cumulus4j.crypto.Cipher; 023 import org.datanucleus.NucleusContext; 024 025 /** 026 * <p> 027 * A <code>CryptoSession</code> is a session managed by a client to decrypt/encrypt data. 028 * </p> 029 * <p> 030 * Data can only be decrypted (or encrypted) within the scope of a valid session. That means, 031 * the client must open a <code>CryptoSession</code> prior to persisting/querying data. 032 * </p> 033 * <p> 034 * There exists one <code>CryptoSession</code> instance for each unique combination of 035 * {@link NucleusContext}, {@link CryptoManager#getCryptoManagerID() cryptoManagerID} and 036 * {@link #getCryptoSessionID() cryptoSessionID}. Therefore, it can happen, that multiple 037 * <code>PersistenceManager</code>/<code>EntityManager</code> instances access the same 038 * <code>CryptoSession</code> from multiple threads. 039 * </p> 040 * <p> 041 * Thus all implementations of CryptoSession must be thread-safe! In this context, it is important 042 * to know that {@link Cipher} is <b>not</b> thread-safe! You should thus always synchronize on the <code>Cipher</code> 043 * instance before using it (if you share them, which you probably do due to the expensiveness of key-initialisations). 044 * </p> 045 * <p> 046 * A <code>CryptoSession</code> must not be instantiated directly, but instead obtained via 047 * {@link CryptoManager#getCryptoSession(String)}. In other words, a new instance of 048 * <code>CryptoSession</code> must only be created within the {@link CryptoManager} 049 * implementation. 050 * </p> 051 * <p> 052 * <b>Important:</b> It is strongly recommended to subclass {@link AbstractCryptoSession} 053 * instead of directly implementing this interface! 054 * </p> 055 * 056 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de 057 */ 058 public interface CryptoSession 059 { 060 /** 061 * <p> 062 * Property-name used to pass the {@link #getCryptoSessionID() cryptoSessionID} to the Cumulus4j-core. 063 * </p> 064 * <p> 065 * The property must be passed to the Cumulus4j-core via 066 * {@link javax.jdo.PersistenceManager#setProperty(String, Object)} or 067 * {@link javax.persistence.EntityManager#setProperty(String, Object)}. 068 * </p> 069 */ 070 static final String PROPERTY_CRYPTO_SESSION_ID = "cumulus4j.cryptoSessionID"; 071 072 /** 073 * <p> 074 * Set the {@link CryptoManager} to which this session belongs. 075 * </p> 076 * <p> 077 * If you subclass {@link AbstractCryptoManager} (instead of directly implementing the {@link CryptoManager} interface) 078 * you must never call this method. Otherwise, it is expected, that you call this method once in {@link CryptoManager#getCryptoSession(String)} 079 * after creating a new <code>CryptoSession</code>, before returning it. 080 * </p> 081 * 082 * @param cryptoManager the <code>CryptoManager</code> to which this session belongs. 083 * @see #getCryptoManager() 084 */ 085 void setCryptoManager(CryptoManager cryptoManager); 086 087 /** 088 * <p> 089 * Get the {@link CryptoManager} to which this session belongs. 090 * </p> 091 * @return the <code>CryptoManager</code> to which this session belongs. 092 */ 093 CryptoManager getCryptoManager(); 094 095 /** 096 * <p> 097 * Set the {@link #getCryptoSessionID() cryptoSessionID}. 098 * </p> 099 * <p> 100 * If you subclass {@link AbstractCryptoManager} (instead of directly implementing the {@link CryptoManager} interface) 101 * you must never call this method. Otherwise, it is expected, that you call this method once in {@link CryptoManager#getCryptoSession(String)} 102 * after creating a new <code>CryptoSession</code>, before returning it. 103 * </p> 104 * 105 * @param cryptoSessionID the identifier of this session. 106 * @see #getCryptoSessionID() 107 */ 108 void setCryptoSessionID(String cryptoSessionID); 109 110 String getCryptoSessionID(); 111 112 Date getCreationTimestamp(); 113 114 /** 115 * <p> 116 * Get the timestamp of the last call to {@link #release()}. 117 * If {@link #release()} was not yet called, get the time when this 118 * instance was created (just like {@link #getCreationTimestamp()} does). 119 * </p> 120 * <p> 121 * Therefore, this method always returns the time when the session was stopped being used 122 * the last time. 123 * </p> 124 * <p> 125 * This timestamp is used for automatic closing of expired sessions. 126 * </p> 127 * 128 * @return the timestamp of the last usage of this session. 129 */ 130 Date getLastUsageTimestamp(); 131 132 /** 133 * <p> 134 * Set the {@link #getLastUsageTimestamp() lastUsageTimestamp} to <i>now</i>, i.e. <code>new Date()</code>. 135 * </p> 136 * <p> 137 * This method should be called by {@link CryptoManager#getCryptoSession(String)}. 138 * </p> 139 * 140 * @see #getLastUsageTimestamp() 141 */ 142 void updateLastUsageTimestamp(); 143 144 /** 145 * <p> 146 * Encrypt the given <a target="_blank" href="http://en.wikipedia.org/wiki/Plaintext">plaintext</a>. 147 * </p> 148 * <p> 149 * This method is thread-safe. Thus, implementors should keep in mind that {@link Cipher} is not thread-safe! 150 * </p> 151 * @param cryptoContext context used to encrypt or decrypt data. 152 * @param plaintext the unencrypted information (aka <a target="_blank" href="http://en.wikipedia.org/wiki/Plaintext">plaintext</a>) to be encrypted. 153 * 154 * @return the encrypted information (aka <a target="_blank" href="http://en.wikipedia.org/wiki/Ciphertext">ciphertext</a>). 155 */ 156 Ciphertext encrypt(CryptoContext cryptoContext, Plaintext plaintext); 157 158 /** 159 * <p> 160 * Decrypt the given <a target="_blank" href="http://en.wikipedia.org/wiki/Ciphertext">ciphertext</a>. 161 * </p> 162 * <p> 163 * This method is thread-safe. Thus, implementors should keep in mind that {@link Cipher} is not thread-safe! 164 * </p> 165 * @param cryptoContext context used to encrypt or decrypt data. 166 * @param ciphertext the encrypted information (aka <a target="_blank" href="http://en.wikipedia.org/wiki/Ciphertext">ciphertext</a>) to be decrypted. 167 * 168 * @return the unencrypted information (aka <a target="_blank" href="http://en.wikipedia.org/wiki/Plaintext">plaintext</a>). 169 */ 170 Plaintext decrypt(CryptoContext cryptoContext, Ciphertext ciphertext); 171 172 /** 173 * <p>Close the session.</p> 174 * <p> 175 * After closing, the <code>CryptoSession</code> cannot be used for encryption/decryption anymore, i.e. 176 * {@link #encrypt(CryptoContext, Plaintext)} and {@link #decrypt(CryptoContext, Ciphertext)} very likely throw an exception. The other 177 * methods might still work. 178 * </p> 179 * <p> 180 * This method can be called multiple times - every following call will be silently ignored. 181 * </p> 182 */ 183 void close(); 184 185 /** 186 * Indicate, whether the session was already {@link #close() closed}. 187 * @return <code>true</code>, if {@link #close()} was already called; <code>false</code> otherwise. 188 */ 189 boolean isClosed(); 190 }