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 String getKeyStoreID(); 113 114 Date getCreationTimestamp(); 115 116 /** 117 * <p> 118 * Get the timestamp of the last call to {@link #release()}. 119 * If {@link #release()} was not yet called, get the time when this 120 * instance was created (just like {@link #getCreationTimestamp()} does). 121 * </p> 122 * <p> 123 * Therefore, this method always returns the time when the session was stopped being used 124 * the last time. 125 * </p> 126 * <p> 127 * This timestamp is used for automatic closing of expired sessions. 128 * </p> 129 * 130 * @return the timestamp of the last usage of this session. 131 */ 132 Date getLastUsageTimestamp(); 133 134 /** 135 * <p> 136 * Set the {@link #getLastUsageTimestamp() lastUsageTimestamp} to <i>now</i>, i.e. <code>new Date()</code>. 137 * </p> 138 * <p> 139 * This method should be called by {@link CryptoManager#getCryptoSession(String)}. 140 * </p> 141 * 142 * @see #getLastUsageTimestamp() 143 */ 144 void updateLastUsageTimestamp(); 145 146 /** 147 * <p> 148 * Encrypt the given <a target="_blank" href="http://en.wikipedia.org/wiki/Plaintext">plaintext</a>. 149 * </p> 150 * <p> 151 * This method is thread-safe. Thus, implementors should keep in mind that {@link Cipher} is not thread-safe! 152 * </p> 153 * @param cryptoContext context used to encrypt or decrypt data. 154 * @param plaintext the unencrypted information (aka <a target="_blank" href="http://en.wikipedia.org/wiki/Plaintext">plaintext</a>) to be encrypted. 155 * 156 * @return the encrypted information (aka <a target="_blank" href="http://en.wikipedia.org/wiki/Ciphertext">ciphertext</a>). 157 */ 158 Ciphertext encrypt(CryptoContext cryptoContext, Plaintext plaintext); 159 160 /** 161 * <p> 162 * Decrypt the given <a target="_blank" href="http://en.wikipedia.org/wiki/Ciphertext">ciphertext</a>. 163 * </p> 164 * <p> 165 * This method is thread-safe. Thus, implementors should keep in mind that {@link Cipher} is not thread-safe! 166 * </p> 167 * @param cryptoContext context used to encrypt or decrypt data. 168 * @param ciphertext the encrypted information (aka <a target="_blank" href="http://en.wikipedia.org/wiki/Ciphertext">ciphertext</a>) to be decrypted. 169 * 170 * @return the unencrypted information (aka <a target="_blank" href="http://en.wikipedia.org/wiki/Plaintext">plaintext</a>). 171 */ 172 Plaintext decrypt(CryptoContext cryptoContext, Ciphertext ciphertext); 173 174 /** 175 * <p>Close the session.</p> 176 * <p> 177 * After closing, the <code>CryptoSession</code> cannot be used for encryption/decryption anymore, i.e. 178 * {@link #encrypt(CryptoContext, Plaintext)} and {@link #decrypt(CryptoContext, Ciphertext)} very likely throw an exception. The other 179 * methods might still work. 180 * </p> 181 * <p> 182 * This method can be called multiple times - every following call will be silently ignored. 183 * </p> 184 */ 185 void close(); 186 187 /** 188 * Indicate, whether the session was already {@link #close() closed}. 189 * @return <code>true</code>, if {@link #close()} was already called; <code>false</code> otherwise. 190 */ 191 boolean isClosed(); 192 }